Difference between revisions of "User:Remig/plico/remapNT"

From Jmol
Jump to navigation Jump to search
(lc all functions)
(handle OMG)
Line 13: Line 13:
 
Copy and paste the following to a text editor and save to your scripts directory as remapNT.spt:
 
Copy and paste the following to a text editor and save to your scripts directory as remapNT.spt:
 
<pre>#  remapNT - Jmol script by Ron Mignery
 
<pre>#  remapNT - Jmol script by Ron Mignery
#  v1.4 beta    5/16/2014 -lc all functions
+
#  v1.beta    2/6/2015 -handle OMG
 
#
 
#
 
#  Calculate or change polynucleotide chain, atom number, residue names
 
#  Calculate or change polynucleotide chain, atom number, residue names
 
#    and/or residue numbers and print the resultant 1 char string
 
#    and/or residue numbers and print the resultant 1 char string
 
#
 
#
 +
gBusy = false
 +
kRemapNT=2
  
 
function find_5_prime(pIdx) {
 
function find_5_prime(pIdx) {
 
     while (pIdx >= 0) {
 
     while (pIdx >= 0) {
   
+
 
 
         # Find C3'
 
         # Find C3'
 
         var c3pIdx = -1
 
         var c3pIdx = -1
Line 32: Line 34:
 
                 for (var k = 1; k <= occSet.size; k++) {
 
                 for (var k = 1; k <= occSet.size; k++) {
 
                     if (connected(occSet[k]).size > 2) {
 
                     if (connected(occSet[k]).size > 2) {
                         c3pIdx = occSet[k].atomIndex
+
                         c3pIdx = 0 + occSet[k].atomIndex
 
                     }
 
                     }
 
                 }
 
                 }
 
             }
 
             }
 
         }
 
         }
       
+
 
 
         if (c3pIdx < 0) {
 
         if (c3pIdx < 0) {
 
             return pIdx
 
             return pIdx
 
         }
 
         }
       
 
 
         # Find C4'
 
         # Find C4'
 
         var endIdx = -1
 
         var endIdx = -1
Line 49: Line 50:
 
             for (var j = 1; j <= ocSet.size; j++) {
 
             for (var j = 1; j <= ocSet.size; j++) {
 
                 if (connected(ocSet[j]).size > 1) {
 
                 if (connected(ocSet[j]).size > 1) {
                     endIdx = cSet[i].atomIndex
+
                     if (endIdx = -1) {
 +
                        endIdx = 0 + cSet[i].atomIndex
 +
                    }
 +
                    else {
 +
                        var Ox = connected(ocSet[j]) and not {atomindex=@{cset[i].atomIndex}}
 +
                        if (connected(Ox) > 1) {
 +
                            endIdx = 0 + cSet[i].atomIndex
 +
                        }
 +
                   
 +
                    }
 
                 }
 
                 }
 
             }
 
             }
 
         }
 
         }
       
+
 
 
         # Find C5'
 
         # Find C5'
 
         var c5idx = -1
 
         var c5idx = -1
Line 59: Line 69:
 
             and not {oxygen})
 
             and not {oxygen})
 
         if (cSet.size > 0) {
 
         if (cSet.size > 0) {
             c5idx = cSet[1].atomIndex
+
             c5idx = 0 + cSet[1].atomIndex
 
         }
 
         }
       
+
 
 
         # Find O5'
 
         # Find O5'
 
         var o5idx = -1
 
         var o5idx = -1
 
         cSet = connected({atomIndex=c5idx}) and {oxygen}
 
         cSet = connected({atomIndex=c5idx}) and {oxygen}
 
         if (cSet.size > 0) {
 
         if (cSet.size > 0) {
             o5idx = cSet[1].atomIndex
+
             o5idx = 0 + cSet[1].atomIndex
 
         }
 
         }
       
+
 
 
         if (o5idx < 0) {
 
         if (o5idx < 0) {
 
             return c5idx
 
             return c5idx
 
         }
 
         }
       
+
 
 
         # Find P
 
         # Find P
 
         pIdx = -1
 
         pIdx = -1
 
         cSet = connected({atomIndex=o5idx}) and {phosphorus}
 
         cSet = connected({atomIndex=o5idx}) and {phosphorus}
 
         if (cSet.size > 0) {
 
         if (cSet.size > 0) {
             Pidx =  cSet[1].atomIndex
+
             Pidx =  0 + cSet[1].atomIndex
 
         }
 
         }
       
+
 
 
         if (Pidx < 0) {
 
         if (Pidx < 0) {
 
             return o5idx
 
             return o5idx
 
         }
 
         }
 
     }
 
     }
   
+
 
     return -1  
+
     return -1
 
}
 
}
  
Line 134: Line 144:
 
# Bound to ALT-LEFT-CLICK by plico_remap_nt
 
# Bound to ALT-LEFT-CLICK by plico_remap_nt
 
function remap_nt_cargo_mb() {
 
function remap_nt_cargo_mb() {
   
 
 
     var idx =_atomPicked
 
     var idx =_atomPicked
 
     if ({atomIndex=idx}.element == "H") {
 
     if ({atomIndex=idx}.element == "H") {
 
         idx = connected({atomIndex=idx})[1].atomIndex
 
         idx = connected({atomIndex=idx})[1].atomIndex
 
     }
 
     }
 +
    delete {hydrogen}
 +
    delete {hoh}
 +
    delete %B
 +
    delete ligands
 +
    connect
 +
 +
    remap_nt( idx, false, 0)
 
      
 
      
 +
    set echo TOP LEFT
 +
    echo @gEcho
 +
    background ECHO yellow
 +
    refresh
 +
    print_1c_chain( newChain)
 +
}
 +
       
 +
function remap_nt(idx, auto, base) {
 +
    var f = (_frameID/1000000)
 +
    var m = (_frameID%1000000)
 +
 
     # If P can be found
 
     # If P can be found
 
     var pIdx = find_p_idx(idx)
 
     var pIdx = find_p_idx(idx)
     var isValid = FALSE
+
     var isValid = false
 
     var newResno = 1
 
     var newResno = 1
 
     var newChain = "A"
 
     var newChain = "A"
Line 148: Line 175:
 
     var t5idx = -1
 
     var t5idx = -1
 
     if (pIdx >= 0) {
 
     if (pIdx >= 0) {
   
+
 
 
         t5idx = find_5_prime(pIdx)
 
         t5idx = find_5_prime(pIdx)
       
 
 
         if (t5idx >= 0) {
 
         if (t5idx >= 0) {
             c5resno = {atomIndex=t5idx}.resno
+
             f = {atomIndex=t5idx}.file
             c5chain = {atomIndex=t5idx}.chain
+
            m = {atomIndex=t5idx}.model
             c5atomno = {atomIndex=t5idx}.atomno
+
            newResno = {atomIndex=t5idx}.resno
             select {atomIndex=t5idx}
+
             newChain = {atomIndex=t5idx}.chain
             halo on
+
             newAtomno = {atomIndex=t5idx}.atomno
 +
             select {(file=f) and (model=m)}
 +
            color {selected} @gScheme
 +
            select {(chain=newChain) and (file=f) and (model=m)}
 +
             color {selected} @gAltScheme
 
             refresh
 
             refresh
 +
 +
            if (auto) {
 +
                newResno = base
 +
                isValid = true
 +
                newChain = gChain1
 +
            }
 +
            else {
 
              
 
              
            # Prompt for new designators
+
                # Prompt for new designators
            var p = prompt(("Enter 5\'-terminal atom designator as\n"
+
                var p = prompt(("Enter 5\'-terminal atom designator as\n"
                + "  <resno>:<chain>#<atomno>"),
+
                    + "  <resno>:<chain>#<atomno>"),
                format("%d:%s#%d", c5resno, c5chain, c5atomno))%0
+
                    format("%d:%s#%d", newResno, newChain, newAtomno))%0
            # If valid
+
                # If valid
            if (p != "null") {
+
                if (p != "null") {
                var iColon = p.find(":")
+
                    var iColon = p.find(":")
                if (iColon > 0) {
+
                    if (iColon > 0) {
                    var iHash = p.find("#")
+
                        var iHash = p.find("#")
                    if (iHash > 0) {
+
                        if (iHash > 0) {
                        newResno = 0 + (p[1][iColon-1])
+
                            newResno = 0 + (p[1][iColon-1])
                        newChain = p[iColon+1][iHash-1]
+
                            newChain = p[iColon+1][iHash-1]
                        newAtomno = 0 + (p[iHash+1][0])
+
                            newAtomno = 0 + (p[iHash+1][0])
                        if ((newResno > 0)
+
                            if ((newResno > 0)
                            and (newChain.size == 1)
+
                                and (newChain.size == 1)
                            and (newAtomno > 0)) {
+
                                and (newAtomno > 0)) {
                                isValid = TRUE
+
                                    isValid = true
 +
                            }
 
                         }
 
                         }
 
                     }
 
                     }
                }
+
                    if (not isValid) {
                if (not isValid) {
+
                        prompt ("Entry not valid!")
                    prompt ("Entry not valid!")
+
                    }
 
                 }
 
                 }
 
             }
 
             }
 
         }
 
         }
 
     }
 
     }
   
+
 
 
     if (isValid) {
 
     if (isValid) {
 
         background ECHO pink
 
         background ECHO pink
 
         refresh
 
         refresh
  
        delete {hydrogen}
 
        delete {hoh}
 
        delete %B
 
        delete ligands
 
        connect
 
       
 
 
         # Build inline pdb file
 
         # Build inline pdb file
         ls = "data \"append remap\"\n"    # global PDB atom record
+
         var ls = "data \"append remapNT\"\n"    # global PDB atom record
 
         var rs = ""
 
         var rs = ""
       
+
 
 
         select {atomIndex=t5idx}
 
         select {atomIndex=t5idx}
 
         var cSet = {selected}
 
         var cSet = {selected}
Line 210: Line 242:
 
         var stopIdx = -1
 
         var stopIdx = -1
 
         var endIdx = -1
 
         var endIdx = -1
         var isRNA = FALSE
+
         var isRNA = false
         var first = TRUE
+
         var first = true
         var psu = FALSE
+
         var psu = false
 
         while (cSet.size > 0) {
 
         while (cSet.size > 0) {
             var s = array(1, 2, 3)
+
             var s = array(1, 2, 3, 4)
 
             var iKeep = -1
 
             var iKeep = -1
 
             var iDrop = -1
 
             var iDrop = -1
Line 231: Line 263:
 
                 var oc5set = ({})
 
                 var oc5set = ({})
 
                 for (var i = 1; i <= cSet.size; i++) {
 
                 for (var i = 1; i <= cSet.size; i++) {
 +
                    newGreek[i] = ""
 
                     if (connected(cSet[i]).size > 1) {
 
                     if (connected(cSet[i]).size > 1) {
                         s[3] = i
+
                         s[cSet.size] = i
                         newGreek[i] = "5\'"
+
                         newGreek[cSet.size] = "5\'"
 
                         oc5set = connected(cSet[i]) and {carbon}
 
                         oc5set = connected(cSet[i]) and {carbon}
 
                         nIdx = cSet[i].atomIndex
 
                         nIdx = cSet[i].atomIndex
 
                     }
 
                     }
 
                 }
 
                 }
                 for (var i = 1; i <= cSet.size; i++) {
+
                 var isP1 = false
                    if (i != s[3]) {
+
                if (cSet.size > 3) {
                        if (abs(angle(cSet[i], {atomIndex=pIdx}, cSet[s[3]],
+
                    newGreek[1] = "P1"
                            oc5set[1])) < 90.0) {
+
                    newGreek[2] = "P2"
                            s[1] = i
+
                    newGreek[3] = "P3"
                            newGreek[i] = "P1"
+
                    s[1] = 1
                        }
+
                    s[2] = 2
                        else {
+
                    s[3] = 3
                            s[2] = i
+
                }               
                            newGreek[i] = "P2"
+
                else {
 +
                    for (var i = 1; i <= cSet.size; i++) {
 +
                        if (i != s[cSet.size]) {
 +
                            if ((isP1 == false)
 +
                                and (abs(angle(cSet[i], {atomIndex=pIdx},
 +
                                cSet[s[cSet.size]], oc5set[1])) < 90.0)) {
 +
                                s[1] = i
 +
                                newGreek[1] = "P1"
 +
                                isP1 = true
 +
                            }
 +
                            else {
 +
                                s[2] = i
 +
                                newGreek[2] = "P2"
 +
                            }
 
                         }
 
                         }
 
                     }
 
                     }
Line 269: Line 315:
 
                         s[1] = i
 
                         s[1] = i
 
                         newGreek[1] = "4\'"
 
                         newGreek[1] = "4\'"
                         cSet[i].selected = FALSE
+
                         cSet[i].selected = false
 
                         stopIdx = cSet[i].atomIndex
 
                         stopIdx = cSet[i].atomIndex
 
                     }
 
                     }
Line 276: Line 322:
 
                         newGreek[2] = "3\'"
 
                         newGreek[2] = "3\'"
 
                         nIdx = cSet[i].atomIndex
 
                         nIdx = cSet[i].atomIndex
                       
+
 
 
                     }
 
                     }
 
                 }
 
                 }
Line 307: Line 353:
 
                 for (var i = 1; i <= cSet.size; i++) {
 
                 for (var i = 1; i <= cSet.size; i++) {
 
                     if (cSet[i].element == "O") {
 
                     if (cSet[i].element == "O") {
                         s[2] = i
+
                         s[1] = i
                         newGreek[2] = "2\'"
+
                         newGreek[1] = "2\'"
                         isRNA = TRUE
+
                         isRNA = true
 
                     }
 
                     }
 
                     else {
 
                     else {
                         s[1] = i
+
                         s[2] = i
                         newGreek[1] = "1\'"
+
                         newGreek[2] = "1\'"
 
                         c1pIdx = cSet[i].atomIndex
 
                         c1pIdx = cSet[i].atomIndex
 
                         nIdx = cSet[i].atomIndex
 
                         nIdx = cSet[i].atomIndex
Line 319: Line 365:
 
                 }
 
                 }
 
                 nextAtomName = "C1\'"
 
                 nextAtomName = "C1\'"
                 break              
+
                 break
 
             case "C1\'" :
 
             case "C1\'" :
 
                 for (var i = 1; i <= cSet.size; i++) {
 
                 for (var i = 1; i <= cSet.size; i++) {
Line 326: Line 372:
 
                         nIdx = cSet[i].atomIndex
 
                         nIdx = cSet[i].atomIndex
 
                     }
 
                     }
                     else if ((cSet[i].element == "C") and  
+
                     else if ((cSet[i].element == "C") and
 
                         ((connected(cSet[i]) and {oxygen}).size == 0)) { #PSU
 
                         ((connected(cSet[i]) and {oxygen}).size == 0)) { #PSU
                         psu = TRUE
+
                         psu = true
 
                         iKeep = i
 
                         iKeep = i
 
                         nIdx = cSet[i].atomIndex
 
                         nIdx = cSet[i].atomIndex
 
                     }
 
                     }
 
                     else {
 
                     else {
                         cSet[i].selected = FALSE
+
                         cSet[i].selected = false
 
                     }
 
                     }
 
                 }
 
                 }
Line 348: Line 394:
 
                     }
 
                     }
 
                 }
 
                 }
                 break              
+
                 break
 
             case "N1y" :
 
             case "N1y" :
 
                 for (var i = 1; i <= cSet.size; i++) {
 
                 for (var i = 1; i <= cSet.size; i++) {
Line 362: Line 408:
 
                 newGreek[1] = "2"
 
                 newGreek[1] = "2"
 
                 nextAtomName = "C2"
 
                 nextAtomName = "C2"
                 break              
+
                 break
 
             case "N9u" :
 
             case "N9u" :
                 # Find N-C-N-C-N
+
                 # Find N-C-N-C-N
 
                 for (var i = 1; i <= cSet.size; i++) {
 
                 for (var i = 1; i <= cSet.size; i++) {
                     n1atom = (connected(cSet[i]) and {nitrogen}
+
                     var n1atom = (connected(cSet[i]) and {nitrogen}
 
                         and not {atomIndex=nIdx})
 
                         and not {atomIndex=nIdx})
                     c2set = connected(n1atom) and {carbon} and not cSet[i]
+
                     var c2set = connected(n1atom) and {carbon} and not cSet[i]
 
                     for (var j = 1; j <= c2set.size; j++) {
 
                     for (var j = 1; j <= c2set.size; j++) {
 
                         if ((connected(c2set[j]) and {nitrogen}) > 1) {
 
                         if ((connected(c2set[j]) and {nitrogen}) > 1) {
Line 380: Line 426:
 
                 newGreek[1] = "8"
 
                 newGreek[1] = "8"
 
                 nextAtomName = "C8"
 
                 nextAtomName = "C8"
                 break              
+
                 break
 
             case "C8" :
 
             case "C8" :
 
                 nIdx = ring_common( cSet, nIdx, s, newGreek, "7")
 
                 nIdx = ring_common( cSet, nIdx, s, newGreek, "7")
 
                 nextAtomName = "N7"
 
                 nextAtomName = "N7"
                 break              
+
                 break
 
             case "N7" :
 
             case "N7" :
 
                 nIdx = ring_common( cSet, nIdx, s, newGreek, "5")
 
                 nIdx = ring_common( cSet, nIdx, s, newGreek, "5")
 
                 nextAtomName = "C5"
 
                 nextAtomName = "C5"
                 break              
+
                 break
 
             case "C5" :
 
             case "C5" :
 
                 if (isRNA and (newGroup == "DU ")) {
 
                 if (isRNA and (newGroup == "DU ")) {
Line 394: Line 440:
 
                     if (angle(c5set[1], c5set[2], c5set[3]) < 114.0) {
 
                     if (angle(c5set[1], c5set[2], c5set[3]) < 114.0) {
 
                         newGroup = "D  "
 
                         newGroup = "D  "
                     }  
+
                     }
                 }              
+
                 }
 
                 nIdx = ring_common( cSet, nIdx, s, newGreek, "6")
 
                 nIdx = ring_common( cSet, nIdx, s, newGreek, "6")
 
                 if ((newGroup == "DU ") and (cSet.size > 1)) {
 
                 if ((newGroup == "DU ") and (cSet.size > 1)) {
Line 401: Line 447:
 
                 }
 
                 }
 
                 nextAtomName = "C6"
 
                 nextAtomName = "C6"
                 break              
+
                 break
 
             case "C6" :
 
             case "C6" :
 
                 if (newGroup == "PU") {
 
                 if (newGroup == "PU") {
Line 410: Line 456:
 
                 else {
 
                 else {
 
                     if (psu) {
 
                     if (psu) {
                         psu = FALSE
+
                         psu = false
 
                         newGroup = "DU "
 
                         newGroup = "DU "
                     }              
+
                     }
 
                     cSet = ({})
 
                     cSet = ({})
 
                 }
 
                 }
                 break              
+
                 break
 
             case "N1" :
 
             case "N1" :
 
                 if (connected({atomIndex=nIdx}).size > 2) { # YG
 
                 if (connected({atomIndex=nIdx}).size > 2) { # YG
                     newGroup = "X  "              
+
                     newGroup = "X  "
 
                 }
 
                 }
 
                 nIdx = ring_common( cSet, nIdx, s, newGreek, "2")
 
                 nIdx = ring_common( cSet, nIdx, s, newGreek, "2")
 
                 nextAtomName = "C2"
 
                 nextAtomName = "C2"
                 break              
+
                 break
 
             case "C2" :
 
             case "C2" :
 
                 nIdx = ring_common( cSet, nIdx, s, newGreek, "3")
 
                 nIdx = ring_common( cSet, nIdx, s, newGreek, "3")
 
                 nextAtomName = "N3"
 
                 nextAtomName = "N3"
 
                 stopIdx = -1
 
                 stopIdx = -1
                 break              
+
                 break
 
             case "N3" :
 
             case "N3" :
 
                 nIdx = ring_common( cSet, nIdx, s, newGreek, "4")
 
                 nIdx = ring_common( cSet, nIdx, s, newGreek, "4")
 
                 nextAtomName = "C4"
 
                 nextAtomName = "C4"
                 break              
+
                 break
 
             case "C4" :
 
             case "C4" :
 
                 if (newGroup != "PY") {
 
                 if (newGroup != "PY") {
Line 443: Line 489:
 
                 break
 
                 break
 
             }
 
             }
             first = FALSE
+
             first = false
           
 
 
             for (var i = 1; i <= cSet.size; i++) {
 
             for (var i = 1; i <= cSet.size; i++) {
 
                 rs += format("ATOM  %5d  %-4sUNK ", newAtomNo,
 
                 rs += format("ATOM  %5d  %-4sUNK ", newAtomNo,
                     (cSet[s[i]].element + newGreek[s[i]]))
+
                     (cSet[i].element + newGreek[s[i]]))
                 rs += format("%s%4d    %8.3f", newChain, newResno, cSet[s[i]].x)        
+
                 rs += format("%s%4d    %8.3f", newChain, newResno, cSet[i].x)
                 rs += format("%8.3f%8.3f\n", cSet[s[i]].y, cSet[s[i]].z)
+
                 rs += format("%8.3f%8.3f\n", cSet[i].y, cSet[i].z)
 
                 newAtomno++
 
                 newAtomno++
 
             }
 
             }
           
+
 
 
             cSet = (connected(cSet and not {atomIndex=stopIdx})
 
             cSet = (connected(cSet and not {atomIndex=stopIdx})
 
                 and not cSet and not {atomIndex=stopIdx} and not {atomIndex=endIdx})
 
                 and not cSet and not {atomIndex=stopIdx} and not {atomIndex=endIdx})
 
             endIdx = nIdx
 
             endIdx = nIdx
           
+
 
 
             if (cSet.size == 0) {
 
             if (cSet.size == 0) {
 
                 if (isRNA) {
 
                 if (isRNA) {
 
                     newGroup = (newGroup.replace("DA ","A  ").replace("DG ","G  ")
 
                     newGroup = (newGroup.replace("DA ","A  ").replace("DG ","G  ")
 
                         .replace("DC ","C  ").replace("DT ","T  ").replace("DU ","U  "))
 
                         .replace("DC ","C  ").replace("DT ","T  ").replace("DU ","U  "))
                 }    
+
                 }
 
                 ls += rs.replace("UNK", newGroup)
 
                 ls += rs.replace("UNK", newGroup)
 
                 rs = ""
 
                 rs = ""
 
                 newResno++
 
                 newResno++
               
+
 
 
                 if (pIdx >= 0) {
 
                 if (pIdx >= 0) {
 
                     cSet = {atomIndex=pIdx}
 
                     cSet = {atomIndex=pIdx}
 
                     nextAtomName = "P"
 
                     nextAtomName = "P"
 
                     newGroup = "UNK"
 
                     newGroup = "UNK"
                    greek = ""
+
                     newGreek[1] = ""
                     newGreek[1] = greek
 
 
                     c1pIdx = -1
 
                     c1pIdx = -1
 
                     stopIdx = o3pIdx
 
                     stopIdx = o3pIdx
 
                     endIdx = -1
 
                     endIdx = -1
                     isRNA = FALSE
+
                     isRNA = false
 
                 }
 
                 }
 
                 else {
 
                 else {
Line 481: Line 525:
 
                 }
 
                 }
 
             }
 
             }
         } # endwhile  
+
         } # endwhile
  
 
         # Replace chain with new chain
 
         # Replace chain with new chain
Line 491: Line 535:
 
         }
 
         }
 
         delete {selected}
 
         delete {selected}
       
+
 
         ls += "end \"append remap\""
+
         ls += "end \"append remapNT\""
 +
        gAppendNew = appendNew
 +
        set appendNew false
 
         script inline @{ls}
 
         script inline @{ls}
        gEcho += format("|Chain %s has been rebuilt", newChain)
+
         set appendNew gAppendNew       
         set echo TOP LEFT
+
    }
        echo @gEcho
+
    else {
        background ECHO yellow
+
         color {selected} @gScheme
        refresh
 
         print_1c_chain( newChain)
 
 
     }
 
     }
 +
    print_1c_chain( newChain)
 
}
 
}
  
 
function print_1c_chain(iChain) {
 
function print_1c_chain(iChain) {
     var resmin = {chain=iChain}.resno.min
+
    var f = (_frameID/1000000)
     var resmax = {chain=iChain}.resno.max
+
    var m = (_frameID%1000000)
     var rchar = (({(resno=resmin) and (chain=iChain)}.group[0].size > 1) ? "" : "R")
+
     var resmin = {(chain=iChain) and (file=f) and (model=m)}.resno.min
     var lcAtoms = (within(3.1, FALSE, {(resno=resmin) and (chain=iChain) and base})
+
     var resmax = {(chain=iChain) and (file=f) and (model=m)}.resno.max
         and not {(resno=resmin) and (chain=iChain)})
+
     var rchar = (({(resno=resmin) and (chain=iChain) and (file=f)
 +
        and (model=m)}.group[0].size > 1) ? "" : "R")
 +
     var lcAtoms = (within(3.1, false, {(resno=resmin) and (chain=iChain)
 +
        and (file=f) and (model=m) and base})
 +
         and not {(resno=resmin) and (chain=iChain) and (file=f) and (model=m)})
 
     var chain2 = ""
 
     var chain2 = ""
 
     var schar = "S"
 
     var schar = "S"
Line 518: Line 567:
 
         }
 
         }
 
         else {
 
         else {
             schar = ""
+
             schar = "S"
 +
            chain2 = ""
 
         }
 
         }
 
     }
 
     }
 
     var ls = format("%s%s:%s", iChain, chain2, format("%s%s", rchar, 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++) {
+
     for (var i = {(chain=iChain) and (file=f) and (model=m)}.resno.min;
         ls += ({(resno=i) and (chain=iChain)}.group[0])[0]
+
        i <= {(chain=iChain) and (file=f) and (model=m)}.resno.max; i++) {
 +
         ls += ({(resno=i) and (chain=iChain) and (file=f) and (model=m)}.group[0])[0]
 
     }
 
     }
 
     print ls
 
     print ls
Line 530: Line 581:
 
# Top level of Remap
 
# Top level of Remap
 
function plico_remap_nt() {
 
function plico_remap_nt() {
   
+
 
 
     # Push selected
 
     # Push selected
 
     gSelSaves = {selected}
 
     gSelSaves = {selected}
   
+
 
 
     gAppendNew = appendNew
 
     gAppendNew = appendNew
     set appendNew FALSE
+
     set appendNew false
 
     gScheme = defaultColorScheme
 
     gScheme = defaultColorScheme
 
     gAltScheme = ((gScheme == "Jmol") ? "Rasmol" : "Jmol")
 
     gAltScheme = ((gScheme == "Jmol") ? "Rasmol" : "Jmol")
Line 554: Line 605:
 
function remap_nt_exit() {
 
function remap_nt_exit() {
 
     unbind
 
     unbind
     halo off  
+
     halo off
 
     echo
 
     echo
     select all
+
    var f = (_frameID/1000000)
 +
    var m = (_frameID%1000000)
 +
     select ((file=f) and (model=m))
 
     color {selected} @gScheme
 
     color {selected} @gScheme
     gBusy = FALSE
+
     gBusy = false
 
     set appendNew gAppendNew
 
     set appendNew gAppendNew
   
+
 
 
     # Pop selected
 
     # Pop selected
 
     select gSelSaves
 
     select gSelSaves

Revision as of 18:58, 13 July 2015

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.

When you click on a polynucleotide chain, it gives the current chain ID, residue, residue number and atom number of the most 5'ward atom in that chain. You may then edit any value (except residue). Remap then remaps the entire chain based on those values by conventional increments and identifies each nucleotide residue.

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;plico_remap_nt

saved as plicoRemapNT.macro in your .jmol/macros directory as described in Macro.

Copy and paste the following to a text editor and save to your scripts directory as remapNT.spt:

#   remapNT - Jmol script by Ron Mignery
#   v1.5  beta    2/6/2015 -handle OMG
#
#   Calculate or change polynucleotide chain, atom number, residue names
#    and/or residue numbers and print the resultant 1 char string
#
gBusy = false
kRemapNT=2

function find_5_prime(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 = 0 + 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) {
                    if (endIdx = -1) {
                        endIdx = 0 + cSet[i].atomIndex
                    }
                    else {
                        var Ox = connected(ocSet[j]) and not {atomindex=@{cset[i].atomIndex}}
                        if (connected(Ox) > 1) {
                            endIdx = 0 + cSet[i].atomIndex
                        }
                    
                    }
                }
            }
        }

        # Find C5'
        var c5idx = -1
        cSet = (connected({atomIndex=endIdx}) and not {atomIndex=c3pIdx}
            and not {oxygen})
        if (cSet.size > 0) {
            c5idx = 0 + cSet[1].atomIndex
        }

        # Find O5'
        var o5idx = -1
        cSet = connected({atomIndex=c5idx}) and {oxygen}
        if (cSet.size > 0) {
            o5idx = 0 + cSet[1].atomIndex
        }

        if (o5idx < 0) {
            return c5idx
        }

        # Find P
        pIdx = -1
        cSet = connected({atomIndex=o5idx}) and {phosphorus}
        if (cSet.size > 0) {
            Pidx =  0 + cSet[1].atomIndex
        }

        if (Pidx < 0) {
            return o5idx
        }
    }

    return -1
}

function find_p_idx(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 ring_common(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 plico_remap_nt
function remap_nt_cargo_mb() {
    var idx =_atomPicked
    if ({atomIndex=idx}.element == "H") {
        idx = connected({atomIndex=idx})[1].atomIndex
    }
    delete {hydrogen}
    delete {hoh}
    delete %B
    delete ligands
    connect

    remap_nt( idx, false, 0)
    
    set echo TOP LEFT
    echo @gEcho
    background ECHO yellow
    refresh
    print_1c_chain( newChain)
}
        
function remap_nt(idx, auto, base) {
    var f = (_frameID/1000000)
    var m = (_frameID%1000000)

    # If P can be found
    var pIdx = find_p_idx(idx)
    var isValid = false
    var newResno = 1
    var newChain = "A"
    var newAtomno = 1
    var t5idx = -1
    if (pIdx >= 0) {

        t5idx = find_5_prime(pIdx)
        if (t5idx >= 0) {
            f = {atomIndex=t5idx}.file
            m = {atomIndex=t5idx}.model
            newResno = {atomIndex=t5idx}.resno
            newChain = {atomIndex=t5idx}.chain
            newAtomno = {atomIndex=t5idx}.atomno
            select {(file=f) and (model=m)}
            color {selected} @gScheme
            select {(chain=newChain) and (file=f) and (model=m)}
            color {selected} @gAltScheme
            refresh

            if (auto) {
                newResno = base
                isValid = true
                newChain = gChain1
            }
            else {
            
                # Prompt for new designators
                var p = prompt(("Enter 5\'-terminal atom designator as\n"
                    + "   <resno>:<chain>#<atomno>"),
                    format("%d:%s#%d", newResno, newChain, newAtomno))%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

        # Build inline pdb file
        var ls = "data \"append remapNT\"\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
        var psu = false
        while (cSet.size > 0) {
            var s = array(1, 2, 3, 4)
            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++) {
                    newGreek[i] = ""
                    if (connected(cSet[i]).size > 1) {
                        s[cSet.size] = i
                        newGreek[cSet.size] = "5\'"
                        oc5set = connected(cSet[i]) and {carbon}
                        nIdx = cSet[i].atomIndex
                    }
                }
                var isP1 = false
                if (cSet.size > 3) {
                    newGreek[1] = "P1"
                    newGreek[2] = "P2"
                    newGreek[3] = "P3"
                    s[1] = 1
                    s[2] = 2
                    s[3] = 3
                }                
                else {
                    for (var i = 1; i <= cSet.size; i++) {
                        if (i != s[cSet.size]) {
                            if ((isP1 == false)
                                and (abs(angle(cSet[i], {atomIndex=pIdx},
                                cSet[s[cSet.size]], oc5set[1])) < 90.0)) {
                                s[1] = i
                                newGreek[1] = "P1"
                                isP1 = true
                            }
                            else {
                                s[2] = i
                                newGreek[2] = "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[1] = i
                        newGreek[1] = "2\'"
                        isRNA = true
                    }
                    else {
                        s[2] = i
                        newGreek[2] = "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 if ((cSet[i].element == "C") and
                        ((connected(cSet[i]) and {oxygen}).size == 0)) { #PSU
                        psu = true
                        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++) {
                    var n1atom = (connected(cSet[i]) and {nitrogen}
                        and not {atomIndex=nIdx})
                    var 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 = ring_common( cSet, nIdx, s, newGreek, "7")
                nextAtomName = "N7"
                break
            case "N7" :
                nIdx = ring_common( cSet, nIdx, s, newGreek, "5")
                nextAtomName = "C5"
                break
            case "C5" :
                if (isRNA and (newGroup == "DU ")) {
                    var c5set = {atomIndex=nIdx} or connected({atomIndex=nIdx})
                    if (angle(c5set[1], c5set[2], c5set[3]) < 114.0) {
                        newGroup = "D  "
                    }
                }
                nIdx = ring_common( cSet, nIdx, s, newGreek, "6")
                if ((newGroup == "DU ") and (cSet.size > 1)) {
                    newGroup = "DT "
                }
                nextAtomName = "C6"
                break
            case "C6" :
                if (newGroup == "PU") {
                    nIdx = ring_common( cSet, nIdx, s, newGreek, "1")
                    newGroup = ((cSet[1].element == "O") ? "DG " : "DA ")
                    nextAtomName = "N1"
                }
                else {
                    if (psu) {
                        psu = false
                        newGroup = "DU "
                    }
                    cSet = ({})
                }
                break
            case "N1" :
                if (connected({atomIndex=nIdx}).size > 2) { # YG
                    newGroup = "X  "
                }
                nIdx = ring_common( cSet, nIdx, s, newGreek, "2")
                nextAtomName = "C2"
                break
            case "C2" :
                nIdx = ring_common( cSet, nIdx, s, newGreek, "3")
                nextAtomName = "N3"
                stopIdx = -1
                break
            case "N3" :
                nIdx = ring_common( cSet, nIdx, s, newGreek, "4")
                nextAtomName = "C4"
                break
            case "C4" :
                if (newGroup != "PY") {
                    cSet = ({})
                }
                else {
                    nIdx = ring_common( 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[i].element + newGreek[s[i]]))
                rs += format("%s%4d    %8.3f", newChain, newResno, cSet[i].x)
                rs += format("%8.3f%8.3f\n", cSet[i].y, cSet[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"
                    newGreek[1] = ""
                    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 remapNT\""
        gAppendNew = appendNew
        set appendNew false
        script inline @{ls}
        set appendNew gAppendNew        
    }
    else {
        color {selected} @gScheme
    }
    print_1c_chain( newChain)
}

function print_1c_chain(iChain) {
    var f = (_frameID/1000000)
    var m = (_frameID%1000000)
    var resmin = {(chain=iChain) and (file=f) and (model=m)}.resno.min
    var resmax = {(chain=iChain) and (file=f) and (model=m)}.resno.max
    var rchar = (({(resno=resmin) and (chain=iChain) and (file=f)
        and (model=m)}.group[0].size > 1) ? "" : "R")
    var lcAtoms = (within(3.1, false, {(resno=resmin) and (chain=iChain)
        and (file=f) and (model=m) and base})
        and not {(resno=resmin) and (chain=iChain) and (file=f) and (model=m)})
    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 = "S"
            chain2 = ""
        }
    }
    var ls = format("%s%s:%s", iChain, chain2, format("%s%s", rchar, schar))
    for (var i = {(chain=iChain) and (file=f) and (model=m)}.resno.min;
        i <= {(chain=iChain) and (file=f) and (model=m)}.resno.max; i++) {
        ls += ({(resno=i) and (chain=iChain) and (file=f) and (model=m)}.group[0])[0]
    }
    print ls
}

# Top level of Remap
function plico_remap_nt() {

    # 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" "+:remap_nt_cargo_mb";
    bind "DOUBLE" "remap_nt_exit";
}

# Bound to DOUBLE by plicoRemap
function remap_nt_exit() {
    unbind
    halo off
    echo
    var f = (_frameID/1000000)
    var m = (_frameID%1000000)
    select ((file=f) and (model=m))
    color {selected} @gScheme
    gBusy = false
    set appendNew gAppendNew

    # Pop selected
    select gSelSaves
}

# End of REMAPNT.SPT

Contributors

Remig