User:Remig/plico/remapNT
< User:Remig | plico
Jump to navigation
Jump to search
RemapNT allows you to change the chain ID, atom numbers and/or residue numbers of a polynucleotide chain by mouse actions. It also calculates group values [nucleotide names (DU, A, etc.)]. Finally it prints the resultant 1 char string to the console.
Note that it will also remove all waters, ligands, hydrogens and %B alternates when any chain is updated.
RemapNT is a member of the Plico suite of protein folding tools described here. It may be installed and accessed as a macro with the file:
Title=PLICO Remap Polynucleotide Script=script <path to your scripts folder>/remapNT.spt;plicoRemapNT
saved as plicoRemapNT.macro in your .jmol/macros folder as described in Macro.
Copy and paste the following to a text editor and save to your scripts folder as remapNT.spt:
# remapNT - Jmol script by Ron Mignery # v1.2 beta 3/19/2014 for Jmol 14 # # Calculate or change polynucleotide chain, atom number, residue names # and/or residue numbers and print the resultant 1 char string # function find5prime(pIdx) { while (pIdx >= 0) { # Find C3' var c3pIdx = -1 select {atomIndex=pIdx} var cSet = {selected} for (var i = 1; i <= cSet.size; i++) { var ocSet = connected(cSet[i]) for (var j = 1; j <= ocSet.size; j++) { var occSet = connected(ocSet[j]) and not {atomIndex=pIdx} for (var k = 1; k <= occSet.size; k++) { if (connected(occSet[k]).size > 2) { c3pIdx = occSet[k].atomIndex } } } } if (c3pIdx < 0) { return pIdx } # Find C4' var endIdx = -1 cSet = connected({atomIndex=c3pIdx}) and not {oxygen} for (var i = 1; i <= cSet.size; i++) { var ocSet = connected(cSet[i]) and {oxygen} for (var j = 1; j <= ocSet.size; j++) { if (connected(ocSet[j]).size > 1) { endIdx = cSet[i].atomIndex } } } # Find C5' var c5idx = -1 cSet = (connected({atomIndex=endIdx}) and not {atomIndex=c3pIdx} and not {oxygen}) if (cSet.size > 0) { c5idx = cSet[1].atomIndex } # Find O5' var o5idx = -1 cSet = connected({atomIndex=c5idx}) and {oxygen} if (cSet.size > 0) { o5idx = cSet[1].atomIndex } if (o5idx < 0) { return c5idx } # Find P pIdx = -1 cSet = connected({atomIndex=o5idx}) and {phosphorus} if (cSet.size > 0) { Pidx = cSet[1].atomIndex } if (Pidx < 0) { return o5idx } } return -1 } function findPidx(idx) { select {atomIndex=idx} var cSet = {selected} while (cSet.size > 0) { for (var i = 1; i <= cSet.size; i++) { if (cSet[i].element == "P") { return cSet[i].atomIndex } } cSet = connected({selected}) and not {selected} and not {hydrogen} select {selected} or cset } return -1 } # cSet, s, and newGreek are arrays and thus passed by reference function ringCommon(cSet, nIdx, s, newGreek, nextGreek) { if (cSet.size > 2) { print format("Unrecognized structure with set %s", cSet) } var oldGreek = 0 + newGreek[1] newGreek[1] = nextGreek for (var i = 1; i <= cSet.size; i++) { var ccSet = connected(cSet[i]) if (ccSet.size == 1) { if (cSet[i].element == ccSet[1].element) { s[2] = i s[1] = ((i > 1) ? 1 : 2) newGreek[i] = 1 + nextGreek newGreek[s[1]] = nextGreek return cSet[s[1]].atomIndex } else { s[1] = i s[2] = ((i > 1) ? 1 : 2) newGreek[i] = oldGreek newGreek[s[2]] = nextGreek return cSet[s[2]].atomIndex } } } return cSet[1].atomIndex } # Bound to ALT-LEFT-CLICK by plicoRemapNT function remapNTcargoMB() { var idx =_atomPicked if ({atomIndex=idx}.element == "H") { idx = connected({atomIndex=idx})[1].atomIndex } # If P can be found var pIdx = findPidx(idx) var isValid = FALSE var newResno = 1 var newChain = "A" var newAtomno = 1 var t5idx = -1 if (pIdx >= 0) { t5idx = find5prime(pIdx) if (t5idx >= 0) { c5resno = {atomIndex=t5idx}.resno c5chain = {atomIndex=t5idx}.chain c5atomno = {atomIndex=t5idx}.atomno select {atomIndex=t5idx} halo on refresh # Prompt for new designators var p = prompt(("Enter 5\'-terminal atom designator as\n" + " <resno>:<chain>#<atomno>"), format("%d:%s#%d", c5resno, c5chain, c5atomno))%0 # If valid if (p != "null") { var iColon = p.find(":") if (iColon > 0) { var iHash = p.find("#") if (iHash > 0) { newResno = 0 + (p[1][iColon-1]) newChain = p[iColon+1][iHash-1] newAtomno = 0 + (p[iHash+1][0]) if ((newResno > 0) and (newChain.size == 1) and (newAtomno > 0)) { isValid = TRUE } } } if (not isValid) { prompt ("Entry not valid!") } } } } if (isValid) { background ECHO pink refresh delete {hydrogen} delete {hoh} delete %B delete ligands # Build inline pdb file var ls = "data \"append remap\"\n" # global PDB atom record var rs = "" select {atomIndex=t5idx} var cSet = {selected} var nextAtomName = {atomIndex=t5idx}.element var newGroup = "UNK" var newGreek = array() var nIdx = t5idx var c1pIdx = -1 var o3pIdx = -1 var stopIdx = -1 var endIdx = -1 var isRNA = FALSE var first = TRUE while (cSet.size > 0) { var s = array(1, 2, 3) var iKeep = -1 var iDrop = -1 switch( nextAtomName) { case "O" : newGreek[1] = (first ? "5\'" : "P3") nextAtomName = (first ? "C5\'" : "P") nIdx = cSet[1].atomIndex break case "P" : newGreek[1] = "" nextAtomName = "OP" nIdx = cSet[1].atomIndex break case "OP" : var oc5set = ({}) for (var i = 1; i <= cSet.size; i++) { if (connected(cSet[i]).size > 1) { s[3] = i newGreek[i] = "5\'" oc5set = connected(cSet[i]) and {carbon} nIdx = cSet[i].atomIndex } } for (var i = 1; i <= cSet.size; i++) { if (i != s[3]) { if (abs(angle(cSet[i], {atomIndex=pIdx}, cSet[s[3]], oc5set[1])) < 90.0) { s[1] = i newGreek[i] = "P1" } else { s[2] = i newGreek[i] = "P2" } } } #nIdx = pIdx nextAtomName = "C5\'" break case "C5\'" : nIdx = cSet[1].atomIndex newGreek[1] = "5\'" nextAtomName = "C4\'" break case "C4\'" : nIdx = cSet[1].atomIndex newGreek[1] = "4\'" nextAtomName = "C3\'" break case "C3\'" : for (var i = 1; i <= cSet.size; i++) { if (cSet[i].element == "O") { s[1] = i newGreek[1] = "4\'" cSet[i].selected = FALSE stopIdx = cSet[i].atomIndex } else { s[2] = i newGreek[2] = "3\'" nIdx = cSet[i].atomIndex } } nextAtomName = "O3\'" break case "O3\'" : for (var i = 1; i <= cSet.size; i++) { if (cSet[i].element == "O") { s[1] = i newGreek[1] = "3\'" o3pIdx = cSet[i].atomIndex } else { s[2] = i newGreek[2] = "2\'" nIdx = cSet[i].atomIndex } } nextAtomName = "C2\'" break case "C2\'" : pIdx = -1 for (var i = 1; i <= cSet.size; i++) { if (cSet[i].element == "P") { pIdx = cSet[i].atomIndex cSet = cSet and not cSet[i] break } } for (var i = 1; i <= cSet.size; i++) { if (cSet[i].element == "O") { s[2] = i newGreek[2] = "2\'" isRNA = TRUE } else { s[1] = i newGreek[1] = "1\'" c1pIdx = cSet[i].atomIndex nIdx = cSet[i].atomIndex } } nextAtomName = "C1\'" break case "C1\'" : for (var i = 1; i <= cSet.size; i++) { if (cSet[i].element == "N") { iKeep = i nIdx = cSet[i].atomIndex } else { cSet[i].selected = FALSE } } cSet = cSet[iKeep] var ccSet = connected(cSet[1]) and not {atomIndex=c1pIdx} newGreek[1] = "9" nextAtomName = "N9u" newGroup = "PU" for (var j = 1; j <= ccSet.size; j++) { if ((connected(ccSet[j]) and {oxygen}) > 0) { newGreek[1] = "1" nextAtomName = "N1y" newGroup = "PY" } } break case "N1y" : for (var i = 1; i <= cSet.size; i++) { if (connected(cSet[i]) > 2) { iKeep = i nIdx = cSet[i].atomIndex } else { stopIdx = cSet[i].atomIndex } } cSet = cSet[iKeep] newGreek[1] = "2" nextAtomName = "C2" break case "N9u" : # Find N-C-N-C-N for (var i = 1; i <= cSet.size; i++) { n1atom = (connected(cSet[i]) and {nitrogen} and not {atomIndex=nIdx}) c2set = connected(n1atom) and {carbon} and not cSet[i] for (var j = 1; j <= c2set.size; j++) { if ((connected(c2set[j]) and {nitrogen}) > 1) { iDrop = i } } } stopIdx = cSet[iDrop].atomIndex cSet = cSet and not cSet[iDrop] nIdx = cSet[1].atomIndex newGreek[1] = "8" nextAtomName = "C8" break case "C8" : nIdx = ringCommon( cSet, nIdx, s, newGreek, "7") nextAtomName = "N7" break case "N7" : nIdx = ringCommon( cSet, nIdx, s, newGreek, "5") nextAtomName = "C5" break case "C5" : nIdx = ringCommon( cSet, nIdx, s, newGreek, "6") if ((newGroup == "DU ") and (cSet.size > 1)) { newGroup = "DT " } nextAtomName = "C6" break case "C6" : if (newGroup == "PU") { nIdx = ringCommon( cSet, nIdx, s, newGreek, "1") newGroup = ((cSet[1].element == "O") ? "DG " : "DA ") nextAtomName = "N1" } else { cSet = ({}) } break case "N1" : nIdx = ringCommon( cSet, nIdx, s, newGreek, "2") nextAtomName = "C2" break case "C2" : nIdx = ringCommon( cSet, nIdx, s, newGreek, "3") nextAtomName = "N3" stopIdx = -1 break case "N3" : nIdx = ringCommon( cSet, nIdx, s, newGreek, "4") nextAtomName = "C4" break case "C4" : if (newGroup != "PY") { cSet = ({}) } else { nIdx = ringCommon( cSet, nIdx, s, newGreek, "5") newGroup = ((cSet[1].element == "N") ? "DC " : "DU ") nextAtomName = "C5" } break } first = FALSE for (var i = 1; i <= cSet.size; i++) { rs += format("ATOM %5d %-4sUNK ", newAtomNo, (cSet[s[i]].element + newGreek[s[i]])) rs += format("%s%4d %8.3f", newChain, newResno, cSet[s[i]].x) rs += format("%8.3f%8.3f\n", cSet[s[i]].y, cSet[s[i]].z) newAtomno++ } cSet = (connected(cSet and not {atomIndex=stopIdx}) and not cSet and not {atomIndex=stopIdx} and not {atomIndex=endIdx}) endIdx = nIdx if (cSet.size == 0) { if (isRNA) { newGroup = (newGroup.replace("DA ","A ").replace("DG ","G ") .replace("DC ","C ").replace("DT ","T ").replace("DU ","U ")) } ls += rs.replace("UNK", newGroup) rs = "" newResno++ if (pIdx >= 0) { cSet = {atomIndex=pIdx} nextAtomName = "P" newGroup = "UNK" greek = "" newGreek[1] = greek c1pIdx = -1 stopIdx = o3pIdx endIdx = -1 isRNA = FALSE } else { break } } } # endwhile # Replace chain with new chain cset = {atomIndex=idx} select cSet while (cSet.size > 0) { cSet = connected({selected}) and not {selected} select {selected} or cSet } delete {selected} ls += "end \"append remap\"" script inline @{ls} gEcho += format("|Chain %s has been rebuilt", newChain) set echo TOP LEFT echo @gEcho background ECHO yellow refresh print1cChain( newChain) } } function print1cChain(iChain) { var resmin = {chain=iChain}.resno.min var resmax = {chain=iChain}.resno.max var rchar = (({(resno=resmin) and (chain=iChain)}.group[0].size > 1) ? "" : "R") var lcAtoms = (within(3.1, FALSE, {(resno=resmin) and (chain=iChain) and base}) and not {(resno=resmin) and (chain=iChain)}) var chain2 = "" var schar = "S" if (lcAtoms.size > 0) { chain2 = lcAtoms[1].chain if (((rchar == "R") and (lcAtoms[1].group.size > 1)) or ((rchar == "") and (lcAtoms[1].group.size == 1))) { schar = "M" } else { schar = "" } } var ls = format("%s%s:%s", iChain, chain2, format("%s%s", rchar, schar)) for (var i = {chain=iChain}.resno.min; i <= {chain=iChain}.resno.max; i++) { ls += ({(resno=i) and (chain=iChain)}.group[0])[0] } print ls } # Top level of Remap function plicoRemapNT() { # Push selected gSelSaves = {selected} gAppendNew = appendNew set appendNew FALSE gScheme = defaultColorScheme gAltScheme = ((gScheme == "Jmol") ? "Rasmol" : "Jmol") set echo TOP LEFT background ECHO yellow gEcho = "_____REMAP NT_____|ALT-CLICK=select NT chain|DOUBLE-CLICK=exit" echo @gEcho gChain = "" unbind set picking ON bind "ALT-LEFT-CLICK" "_pickAtom"; bind "ALT-LEFT-CLICK" "+:remapNTcargoMB"; bind "DOUBLE" "remapNTexit"; } # Bound to DOUBLE by plicoRemap function remapNTexit() { unbind halo off echo select all color {selected} @gScheme gBusy = FALSE set appendNew gAppendNew # Pop selected select gSelSaves } # End of REMAPNT.SPT