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

From Jmol
Jump to navigation Jump to search
(Do not var globals)
(lc all functions)
Line 5: Line 5:
 
'''Modify''' is a member of the Plico suite of protein folding tools described [[User:Remig/plico|here]]. It may be installed and accessed as a macro with the file:
 
'''Modify''' is a member of the Plico suite of protein folding tools described [[User:Remig/plico|here]]. It may be installed and accessed as a macro with the file:
 
<pre>Title=PLICO Modify
 
<pre>Title=PLICO Modify
Script=script <path to your scripts directory>/modify.spt;plicoModify
+
Script=script <path to your scripts directory>/modify.spt;plico_modify
 
</pre>
 
</pre>
 
saved as plicoModify.macro in your .jmol/macros directory as described in [[Macro]].
 
saved as plicoModify.macro in your .jmol/macros directory as described in [[Macro]].
Line 11: Line 11:
 
Copy and paste the following to a text editor and save to your scripts directory as modify.spt:
 
Copy and paste the following to a text editor and save to your scripts directory as modify.spt:
 
<pre>#  modify - Jmol script by Ron Mignery
 
<pre>#  modify - Jmol script by Ron Mignery
#  v1.2 beta    4/3/2014 for Jmol 14 -do not var globals for Jmol 14.0.13+
+
#  v1.3 beta    5/16/2014 -lc all functions
 
#
 
#
 
# See atom hover text for options:
 
# See atom hover text for options:
Line 29: Line 29:
  
 
# Return L tetrahedron point if i1<i2<i3, else R point
 
# Return L tetrahedron point if i1<i2<i3, else R point
function getTet(i1, i2, i3, dist) {
+
function get_tet(i1, i2, i3, dist) {
 
     var v1 = {atomIndex=i3}.xyz - {atomIndex=i2}.xyz
 
     var v1 = {atomIndex=i3}.xyz - {atomIndex=i2}.xyz
 
     var v2 = {atomIndex=i1}.xyz - {atomIndex=i2}.xyz
 
     var v2 = {atomIndex=i1}.xyz - {atomIndex=i2}.xyz
Line 46: Line 46:
  
 
# return vector parallel to previous bond
 
# return vector parallel to previous bond
function getTet1(pIdx, idx) {
+
function get_tet_1(pIdx, idx) {
 
     var cset = connected({atomIndex=pIdx}) and not {atomIndex=idx}
 
     var cset = connected({atomIndex=pIdx}) and not {atomIndex=idx}
 
     return {atomIndex=idx}.xyz + {atomIndex=pIdx}.xyz - cset[1].xyz
 
     return {atomIndex=idx}.xyz + {atomIndex=pIdx}.xyz - cset[1].xyz
 
}
 
}
  
function getTrigonal(i1, i2, i3, dist) {
+
function get_trigonal(i1, i2, i3, dist) {
 
     var v1 = {atomIndex=i1}.xyz - {atomIndex=i2}.xyz
 
     var v1 = {atomIndex=i1}.xyz - {atomIndex=i2}.xyz
 
     var v2 = {atomIndex=i3}.xyz - {atomIndex=i2}.xyz
 
     var v2 = {atomIndex=i3}.xyz - {atomIndex=i2}.xyz
Line 64: Line 64:
 
}
 
}
  
function addToIdx(idx, aElement, greek, addOs) {
+
function add_to_idx(idx, aElement, greek, addOs) {
 
     var iGroup = {atomIndex=idx}.group
 
     var iGroup = {atomIndex=idx}.group
 
     var iResno = {atomIndex=idx}.resno
 
     var iResno = {atomIndex=idx}.resno
Line 75: Line 75:
 
     if  ((iGroup = "HIS") or ((({atomIndex=idx} and {amino}).size == 0)  
 
     if  ((iGroup = "HIS") or ((({atomIndex=idx} and {amino}).size == 0)  
 
         and (iAtomName[1][2] != "OP") and (iAtomName[3] != "\'"))) {
 
         and (iAtomName[1][2] != "OP") and (iAtomName[3] != "\'"))) {
         pt = getTrigonal(cSet[1].atomIndex, idx, cSet[2].atomIndex, 1.5)  
+
         pt = get_trigonal(cSet[1].atomIndex, idx, cSet[2].atomIndex, 1.5)  
 
     }
 
     }
 
     else {
 
     else {
 
         if ((cSet.size == 2) and not greek.find("\'")) {
 
         if ((cSet.size == 2) and not greek.find("\'")) {
             pt = getTet(cSet[1].atomIndex, idx, cSet[2].atomIndex, 1.5)  
+
             pt = get_tet(cSet[1].atomIndex, idx, cSet[2].atomIndex, 1.5)  
 
         }
 
         }
 
         else if (cSet.size > 2) {
 
         else if (cSet.size > 2) {
             pt = getTet(cSet[2].atomIndex, idx, cSet[1].atomIndex, 1.5)  
+
             pt = get_tet(cSet[2].atomIndex, idx, cSet[1].atomIndex, 1.5)  
 
         }
 
         }
 
         else {
 
         else {
             pt = getTet1(cSet[1].atomIndex, idx)  
+
             pt = get_tet_1(cSet[1].atomIndex, idx)  
 
         }
 
         }
 
     }
 
     }
Line 110: Line 110:
 
             }
 
             }
 
             else if (addOs == 2) {
 
             else if (addOs == 2) {
                 pt = getTrigonal(ccSet[1].atomIndex, aIdx, ccSet[2].atomIndex, 1.5)  
+
                 pt = get_trigonal(ccSet[1].atomIndex, aIdx, ccSet[2].atomIndex, 1.5)  
 
             }
 
             }
 
             else {
 
             else {
 
                 if (ccSet.size == 2) {
 
                 if (ccSet.size == 2) {
                     pt = getTet(ccSet[1].atomIndex, aIdx, ccSet[2].atomIndex, 1.5)  
+
                     pt = get_tet(ccSet[1].atomIndex, aIdx, ccSet[2].atomIndex, 1.5)  
 
                 }
 
                 }
 
                 else if (ccSet.size == 3) {
 
                 else if (ccSet.size == 3) {
                     pt = getTet(ccSet[2].atomIndex, aIdx, ccSet[1].atomIndex, 1.5)  
+
                     pt = get_tet(ccSet[2].atomIndex, aIdx, ccSet[1].atomIndex, 1.5)  
 
                 }
 
                 }
 
                 else {
 
                 else {
                     pt = getTet1(ccSet[1].atomIndex, aIdx)  
+
                     pt = get_tet_1(ccSet[1].atomIndex, aIdx)  
 
                 }
 
                 }
 
             }
 
             }
Line 134: Line 134:
 
         }
 
         }
 
     }
 
     }
     setHoverLabels()
+
     set_hover_labels()
 
}
 
}
  
function removeFromIdx(idx) {
+
function remove_from_idx(idx) {
 
     var cSet = connected({atomIndex=idx})
 
     var cSet = connected({atomIndex=idx})
 
     if ({atomIndex=idx}.atomName[2] != "M") {
 
     if ({atomIndex=idx}.atomName[2] != "M") {
Line 148: Line 148:
 
}
 
}
  
function toXidx(idx, newElement, newGroup) {
+
function to_x_idx(idx, newElement, newGroup) {
 
     var cSet = {resno=@{{atomIndex=idx}.resno}}
 
     var cSet = {resno=@{{atomIndex=idx}.resno}}
 
     var ls = "data \"append toX\"\n"
 
     var ls = "data \"append toX\"\n"
Line 167: Line 167:
 
}
 
}
  
function toPUidx(idx, undoIt) {
+
function to_pu_idx(idx, undoIt) {
 
     var iResno = {atomIndex=idx}.resno
 
     var iResno = {atomIndex=idx}.resno
 
     var a1idx = {(resno=iResno) and (atomName="O2")}.atomIndex     
 
     var a1idx = {(resno=iResno) and (atomName="O2")}.atomIndex     
Line 192: Line 192:
 
      
 
      
 
     if (undoit) {
 
     if (undoit) {
         toXidx(idx, "C", "U")
+
         to_x_idx(idx, "C", "U")
 
     }
 
     }
 
     else {
 
     else {
         toXidx(idx, "N", "PU")
+
         to_x_idx(idx, "N", "PU")
 
     }
 
     }
 
}
 
}
  
function toDidx(idx) {
+
function to_d_idx(idx) {
 
     delay
 
     delay
 
     gIsPlanar = FALSE
 
     gIsPlanar = FALSE
Line 291: Line 291:
 
}
 
}
  
function setHoverLabels() {
+
function set_hover_labels() {
 
     select all
 
     select all
 
     set hoverLabel "%U"
 
     set hoverLabel "%U"
Line 351: Line 351:
 
  }
 
  }
  
function addWaterMB() {
+
function add_water_mb() {
 
     var idx = _atomPicked
 
     var idx = _atomPicked
 
     var iChain = {atomIndex=idx}.chain
 
     var iChain = {atomIndex=idx}.chain
Line 357: Line 357:
 
     var cSet = connected({atomIndex=idx})
 
     var cSet = connected({atomIndex=idx})
 
     if (cSet.size == 2) {
 
     if (cSet.size == 2) {
         pt = getTet(cSet[1].atomIndex, idx, cSet[2].atomIndex, 2.3)  
+
         pt = get_tet(cSet[1].atomIndex, idx, cSet[2].atomIndex, 2.3)  
 
     }
 
     }
 
     else if (cSet.size == 3) {
 
     else if (cSet.size == 3) {
         pt = getTet(cSet[2].atomIndex, idx, cSet[1].atomIndex, 2.3)  
+
         pt = get_tet(cSet[2].atomIndex, idx, cSet[1].atomIndex, 2.3)  
 
     }
 
     }
 
     else {
 
     else {
Line 373: Line 373:
 
         ls += "end \"append addto\""
 
         ls += "end \"append addto\""
 
         script inline @{ls}
 
         script inline @{ls}
         setHoverLabels()
+
         set_hover_labels()
 
     }
 
     }
 
}
 
}
  
function modify1MB() {
+
function modify_1_mb() {
 
     var idx = _atomPicked
 
     var idx = _atomPicked
 
     var isAmino = ({(atomIndex=idx) and {amino}}.size > 0)
 
     var isAmino = ({(atomIndex=idx) and {amino}}.size > 0)
Line 388: Line 388:
 
      
 
      
 
     else if (iGroup == "D") {
 
     else if (iGroup == "D") {
         toDidx(idx)
+
         to_d_idx(idx)
 
         if(gIsPlanar) {
 
         if(gIsPlanar) {
             toDidx(idx)
+
             to_d_idx(idx)
 
         }
 
         }
 
     }
 
     }
Line 396: Line 396:
 
     else if ((iName[2]="M") or (iName[2]="O")
 
     else if ((iName[2]="M") or (iName[2]="O")
 
         or (isAmino and ((iName[1]="P") or (iName[2]=="P")))) {
 
         or (isAmino and ((iName[1]="P") or (iName[2]=="P")))) {
         removeFromIdx(idx)
+
         remove_from_idx(idx)
 
         delete {atomIndex=idx}
 
         delete {atomIndex=idx}
 
     }
 
     }
Line 403: Line 403:
 
         if ({atomIndex=idx}.element="P") {
 
         if ({atomIndex=idx}.element="P") {
 
             if (isAmino) {
 
             if (isAmino) {
                 removeFromIdx(idx)
+
                 remove_from_idx(idx)
 
             }
 
             }
 
         }
 
         }
Line 409: Line 409:
 
             and ({atomIndex=idx}.atomName!="O")
 
             and ({atomIndex=idx}.atomName!="O")
 
             and ({atomIndex=idx}.bondCount=1)) {
 
             and ({atomIndex=idx}.bondCount=1)) {
             addToIdx(idx, "C", "M", 0)
+
             add_to_idx(idx, "C", "M", 0)
 
         }
 
         }
 
         else if (({atomIndex=idx}.element!="O")
 
         else if (({atomIndex=idx}.element!="O")
 
             and ({atomIndex=idx}.bondCount < 3)) {
 
             and ({atomIndex=idx}.bondCount < 3)) {
             addToIdx(idx, "C", "M", 0)
+
             add_to_idx(idx, "C", "M", 0)
 
         }
 
         }
 
         else if (isAmino) {
 
         else if (isAmino) {
             removeFromIdx(idx)
+
             remove_from_idx(idx)
 
         }
 
         }
 
     }
 
     }
 
}
 
}
  
function modify2MB() {
+
function modify_2_mb() {
 
     var idx = _atomPicked
 
     var idx = _atomPicked
 
     var iGroup = {atomIndex=idx}.group
 
     var iGroup = {atomIndex=idx}.group
Line 431: Line 431:
 
     if ((iGroup="MET") and (iName="N")) {
 
     if ((iGroup="MET") and (iName="N")) {
 
         if ({atomIndex=idx}.bondCount == 1) {
 
         if ({atomIndex=idx}.bondCount == 1) {
             addToIdx(idx, "C", "F", 1)
+
             add_to_idx(idx, "C", "F", 1)
 
         }
 
         }
 
         else {
 
         else {
Line 448: Line 448:
 
         if (({atomIndex=idx}.bondCount == 1)
 
         if (({atomIndex=idx}.bondCount == 1)
 
             or ((iName="ND1") and ({atomIndex=idx}.bondCount == 2))) {
 
             or ((iName="ND1") and ({atomIndex=idx}.bondCount == 2))) {
             addToIdx(idx, "P", "", 3)
+
             add_to_idx(idx, "P", "", 3)
 
         }
 
         }
 
         else {
 
         else {
             removeFromIdx(idx)
+
             remove_from_idx(idx)
 
         }
 
         }
 
     }
 
     }
Line 458: Line 458:
 
     else if ((iGroup="PRO") and (iName="CG")) {
 
     else if ((iGroup="PRO") and (iName="CG")) {
 
         if ({atomIndex=idx}.bondCount == 2) {
 
         if ({atomIndex=idx}.bondCount == 2) {
             addToIdx(idx, "O", "H", 0)
+
             add_to_idx(idx, "O", "H", 0)
 
         }
 
         }
 
         else {
 
         else {
             removeFromIdx(idx)
+
             remove_from_idx(idx)
 
         }
 
         }
 
     }
 
     }
Line 467: Line 467:
 
     # A.N6 I
 
     # A.N6 I
 
     else if ((iGroup="A") and (iName="N6")) {
 
     else if ((iGroup="A") and (iName="N6")) {
         toXidx(idx, "O", "I")
+
         to_x_idx(idx, "O", "I")
 
     }
 
     }
 
     else if ((iGroup="I") and (iName="O6")) {
 
     else if ((iGroup="I") and (iName="O6")) {
         toXidx(idx, "N", "A")
+
         to_x_idx(idx, "N", "A")
 
     }
 
     }
 
      
 
      
 
     # G.N2 X
 
     # G.N2 X
 
     else if ((iGroup="G") and (iName="N2")) {
 
     else if ((iGroup="G") and (iName="N2")) {
         toXidx(idx, "O", "X")
+
         to_x_idx(idx, "O", "X")
 
     }
 
     }
 
     else if ((iGroup="X") and (iName="O2")) {
 
     else if ((iGroup="X") and (iName="O2")) {
         toXidx(idx, "N", "G")
+
         to_x_idx(idx, "N", "G")
 
     }
 
     }
 
      
 
      
 
     # U.N1 PU
 
     # U.N1 PU
 
     else if ((iGroup="U") and (iName="N1")) {
 
     else if ((iGroup="U") and (iName="N1")) {
         toPUidx(idx, FALSE)
+
         to_pu_idx(idx, FALSE)
 
     }
 
     }
 
     else if ((iGroup="PU") and (iName="C5")) {
 
     else if ((iGroup="PU") and (iName="C5")) {
         toPUidx(idx, TRUE)
+
         to_pu_idx(idx, TRUE)
 
     }
 
     }
 
      
 
      
 
     # U.C5 T
 
     # U.C5 T
 
     else if ((iGroup="U") and (iName="C5")) {
 
     else if ((iGroup="U") and (iName="C5")) {
         addToIdx(idx, "C", "7 ", 0)
+
         add_to_idx(idx, "C", "7 ", 0)
         toXidx(idx, "C", "T")
+
         to_x_idx(idx, "C", "T")
 
     }
 
     }
 
     else if ((iGroup="T") and (iName="c5")) {
 
     else if ((iGroup="T") and (iName="c5")) {
 
         delete {(resno=iResno) and (atomName="C7")}
 
         delete {(resno=iResno) and (atomName="C7")}
         toXidx(idx, "C", "U")
+
         to_x_idx(idx, "C", "U")
 
     }
 
     }
 
      
 
      
 
     # U.C6 HU
 
     # U.C6 HU
 
     else if ((iGroup="U") and ((iName="C5") or (iName="C6"))) {
 
     else if ((iGroup="U") and ((iName="C5") or (iName="C6"))) {
         toXidx(idx, "C", "D")
+
         to_x_idx(idx, "C", "D")
         toDidx(idx)
+
         to_d_idx(idx)
 
     }
 
     }
 
     else if ((iGroup="D") and ((iName="C5") or (iName="C6"))) {
 
     else if ((iGroup="D") and ((iName="C5") or (iName="C6"))) {
 
         for (var i = 0; i < 10; i++) {
 
         for (var i = 0; i < 10; i++) {
             toDidx(idx)
+
             to_d_idx(idx)
 
             if (gIsPlanar) {
 
             if (gIsPlanar) {
 
                 break
 
                 break
 
             }
 
             }
 
         }
 
         }
         toXidx(idx, "C", "U")
+
         to_x_idx(idx, "C", "U")
 
     }
 
     }
 
      
 
      
Line 518: Line 518:
 
         var cIdx = connected({atomIndex=idx})[1].atomIndex
 
         var cIdx = connected({atomIndex=idx})[1].atomIndex
 
         delete {atomIndex=idx}
 
         delete {atomIndex=idx}
         toXidx(cIdx, "C", "D"+iGroup)
+
         to_x_idx(cIdx, "C", "D"+iGroup)
 
     }
 
     }
 
      
 
      
Line 525: Line 525:
 
         var ccSet = connected({atomIndex=idx})
 
         var ccSet = connected({atomIndex=idx})
 
         if ((ccSet.size < 3) and (iGroup.size > 1)) {
 
         if ((ccSet.size < 3) and (iGroup.size > 1)) {
             addToIdx(idx, "O", "2\'", 0)
+
             add_to_idx(idx, "O", "2\'", 0)
             toXidx(idx, "C", iGroup[2])
+
             to_x_idx(idx, "C", iGroup[2])
 
         }
 
         }
 
         else if (iGroup.size == 1) {
 
         else if (iGroup.size == 1) {
Line 532: Line 532:
 
                 if (ccSet[i].element == "O") {
 
                 if (ccSet[i].element == "O") {
 
                     delete {atomIndex=@{ccSet[i].atomIndex}}
 
                     delete {atomIndex=@{ccSet[i].atomIndex}}
                     toXidx(idx, "C", "D"+iGroup)
+
                     to_x_idx(idx, "C", "D"+iGroup)
 
                 }
 
                 }
 
             }
 
             }
 
         }
 
         }
 
     }
 
     }
     setHoverLabels()
+
     set_hover_labels()
 
      
 
      
 
}
 
}
  
function selectChainMB() {
+
function select_chain_mb() {
 
     var cset = {atomIndex=_atomPicked}
 
     var cset = {atomIndex=_atomPicked}
 
     select cSet
 
     select cSet
Line 551: Line 551:
 
}
 
}
  
function modifyExitMB() {
+
function modify_exit_mb() {
 
     unbind
 
     unbind
 
     set echo TOP LEFT
 
     set echo TOP LEFT
Line 565: Line 565:
 
      
 
      
 
# Top level of Modify
 
# Top level of Modify
function plicoModify() {
+
function plico_modify() {
 
     gSelsave = {selected}
 
     gSelsave = {selected}
 
     gAllowMoveAtoms = allowMoveAtoms
 
     gAllowMoveAtoms = allowMoveAtoms
Line 588: Line 588:
 
      
 
      
 
     bind "ALT-LEFT-CLICK" "_pickAtom";
 
     bind "ALT-LEFT-CLICK" "_pickAtom";
     bind "ALT-LEFT-CLICK" "+:modify1MB";
+
     bind "ALT-LEFT-CLICK" "+:modify_1_mb";
 
     bind "SHIFT-LEFT-CLICK" "_pickAtom";
 
     bind "SHIFT-LEFT-CLICK" "_pickAtom";
     bind "SHIFT-LEFT-CLICK" "+:modify2MB";
+
     bind "SHIFT-LEFT-CLICK" "+:modify_2_mb";
 
     bind "ALT-SHIFT-LEFT-CLICK" "_pickAtom";
 
     bind "ALT-SHIFT-LEFT-CLICK" "_pickAtom";
     bind "ALT-SHIFT-LEFT-CLICK" "+:selectChainMB";
+
     bind "ALT-SHIFT-LEFT-CLICK" "+:select_chain_mb";
 
     bind "ALT-CTRL-LEFT-CLICK" "_pickAtom";
 
     bind "ALT-CTRL-LEFT-CLICK" "_pickAtom";
     bind "ALT-CTRL-LEFT-CLICK" "+:addWaterMB";
+
     bind "ALT-CTRL-LEFT-CLICK" "+:add_water_mb";
     bind "DOUBLE" "modifyExitMB";
+
     bind "DOUBLE" "modify_exit_mb";
 
      
 
      
 
     set hoverDelay 0.001
 
     set hoverDelay 0.001
 
     hover on
 
     hover on
     setHoverLabels()
+
     set_hover_labels()
 
}
 
}
  
 
# End of MODIFY.SPT
 
# End of MODIFY.SPT
 
</pre>
 
</pre>

Revision as of 16:36, 16 May 2014

Modify allows the user to make common amino acid and nucleotide modification by mouse actions. Hover text above each atom gives the available options including methylation on nucleosides, single-bond oxygens, and nitrogens, hydroxylation of PRO, formylation of MET, ribose/deoxyribose interconversion, phophorylation of SER, THR, TYR and HIS, and conversions to pseudouridine, dihyrouridine, inosine, and xanthine.

Some features unrelated to modification have been placed here as well to serve other Plico functions. Water molecules may be added and moved around to serve as pivot points for Tug when no other atoms are where the pivot point is wanted. Also the Jmol parameters allowMoveAtoms and allowRotateSelected are set true while modify is active to allow free rotation and translation of selected atoms.

Modify 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 Modify
Script=script <path to your scripts directory>/modify.spt;plico_modify

saved as plicoModify.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 modify.spt:

#   modify - Jmol script by Ron Mignery
#   v1.3 beta    5/16/2014 -lc all functions
#
# See atom hover text for options:
# methyl on nucleosides, single-bond oxygens, and terminal N
# OH on ribose and proline, PO3 on SER, THR, TYR and HIS (2)
# pseudouridine and dihyrouridine, inosine, xanthine
# HOH singlet anywhere for phantom pivot and target atoms
# Enable jmol move for duration

kCtolerance = 1.85
gAllowMoveAtoms = allowMoveAtoms
gAllowRotateSelected = allowRotateSelected
gSelsave = ({})
gScheme = defaultColorScheme
gAltScheme = ((gScheme == "Jmol") ? "Rasmol" : "Jmol")
gIsPlanar = FALSE

# Return L tetrahedron point if i1<i2<i3, else R point
function get_tet(i1, i2, i3, dist) {
    var v1 = {atomIndex=i3}.xyz - {atomIndex=i2}.xyz
    var v2 = {atomIndex=i1}.xyz - {atomIndex=i2}.xyz
    var axis = cross(v1, v2)
    var pma = ({atomIndex=i1}.xyz + {atomIndex=i3}.xyz)/2
    var pmo = {atomIndex=i2}.xyz + {atomIndex=i2}.xyz - pma
    var pt = pmo + (axis/axis)

    var v = pt - {atomIndex=i2}.xyz
    var cdist = distance(pt, {atomIndex=i2})
    var factor = (dist/cdist)
    var lpt = v * factor

    return lpt + {atomIndex=i2}.xyz
}

# return vector parallel to previous bond
function get_tet_1(pIdx, idx) {
    var cset = connected({atomIndex=pIdx}) and not {atomIndex=idx}
    return {atomIndex=idx}.xyz + {atomIndex=pIdx}.xyz - cset[1].xyz
}

function get_trigonal(i1, i2, i3, dist) {
    var v1 = {atomIndex=i1}.xyz - {atomIndex=i2}.xyz
    var v2 = {atomIndex=i3}.xyz - {atomIndex=i2}.xyz
    var pt = {atomIndex=i2}.xyz - (v1 + v2)

    var v = pt - {atomIndex=i2}.xyz
    var cdist = distance(pt, {atomIndex=i2})
    var factor = (dist/cdist)
    var lpt = (v * factor)

    return lpt + {atomIndex=i2}.xyz
}

function add_to_idx(idx, aElement, greek, addOs) {
    var iGroup = {atomIndex=idx}.group
    var iResno = {atomIndex=idx}.resno
    var iChain = {atomIndex=idx}.chain
    var iAtomName = {atomIndex=idx}.atomName
    var iAtomno = {atomIndex=idx}.atomno
    var aAtomno = {chain=iChain}.atomno.max + 1
    var cset = connected({atomIndex=idx})
    var pt = {0 0 0}
    if  ((iGroup = "HIS") or ((({atomIndex=idx} and {amino}).size == 0) 
        and (iAtomName[1][2] != "OP") and (iAtomName[3] != "\'"))) {
        pt = get_trigonal(cSet[1].atomIndex, idx, cSet[2].atomIndex, 1.5) 
    }
    else {
        if ((cSet.size == 2) and not greek.find("\'")) {
            pt = get_tet(cSet[1].atomIndex, idx, cSet[2].atomIndex, 1.5) 
        }
        else if (cSet.size > 2) {
            pt = get_tet(cSet[2].atomIndex, idx, cSet[1].atomIndex, 1.5) 
        }
        else {
            pt = get_tet_1(cSet[1].atomIndex, idx) 
        }
    }
    if (greek.size < 2) {
        greek += iAtomName[2]
    }
    var ls = "data \"append addto\"\n"
    ls += format("ATOM  %5d  %-4s%3s ", aAtomno, aElement + greek, iGroup)
    ls += format("%s%4d    %8.3f", iChain, iResno, pt.x)          
    ls += format("%8.3f%8.3f\n", pt.y, pt.z)
    ls += "end \"append addto\""
    script inline @{ls}
        
    var aIdx = {(atomno=aAtomno) and (chain=iChain)}.atomIndex
    connect {atomIndex=idx} {atomIndex=aIdx}

    if (addOs > 0) {    
        for (var i = 1; i <= addOs; i++) {
            aAtomno++
            var ccSet = connected({atomIndex=aIdx})
            if (addOs == 1) {
                pt = ({atomIndex=aIdx}.xyz +
                    ({atomIndex=aIdx}.xyz - {atomIndex=idx}.xyz))
            }
            else if (addOs == 2) {
                pt = get_trigonal(ccSet[1].atomIndex, aIdx, ccSet[2].atomIndex, 1.5) 
            }
            else {
                if (ccSet.size == 2) {
                    pt = get_tet(ccSet[1].atomIndex, aIdx, ccSet[2].atomIndex, 1.5) 
                }
                else if (ccSet.size == 3) {
                    pt = get_tet(ccSet[2].atomIndex, aIdx, ccSet[1].atomIndex, 1.5) 
                }
                else {
                    pt = get_tet_1(ccSet[1].atomIndex, aIdx) 
                }
            }
            ls = "data \"append addto\"\n"
            ls += format("ATOM  %5d  O%s%d ", aAtomno,
                {atomIndex=aIdx}.AtomName[1], i)
            ls += format("%3s %s%4d    ", iGroup, iChain, iResno)          
            ls += format("%8.3f%8.3f%8.3f\n",  pt.x, pt.y, pt.z)
            ls += "end \"append addto\""
            script inline @{ls}
            oIdx = {(atomno=aAtomno) and (chain=iChain)}.atomIndex
            connect {atomIndex=aIdx} {atomIndex=oIdx}
        }
    }
    set_hover_labels()
}

function remove_from_idx(idx) {
    var cSet = connected({atomIndex=idx})
    if ({atomIndex=idx}.atomName[2] != "M") {
        for (var i = 1; i <= cSet.size; i++) {
            if ((cSet[i].atomName[2] == "P") or (cSet[i].atomName[2] == "O")) {
                delete @{cSet[i]}
            }
        }
    }
}

function to_x_idx(idx, newElement, newGroup) {
    var cSet = {resno=@{{atomIndex=idx}.resno}}
    var ls = "data \"append toX\"\n"
    for (var i = 1; i <= cSet.size; i++) {
        var iName = cSet[i].atomName
        if (idx == cSet[i].atomIndex) {
            iName[1] = newElement
        }
        ls += format("ATOM  %5d  %-3s ", cSet[i].atomno, iName)
        ls += format("%3s %s%4d    ", newGroup,
            {atomIndex=idx}.chain, cSet[i].resno)          
        ls += format("%8.3f%8.3f%8.3f\n",  cSet[i].x, cSet[i].y, cSet[i].z)
    }
    ls += "end \"append toX\""
    delete cSet
    script inline @{ls}
    connect
}

function to_pu_idx(idx, undoIt) {
    var iResno = {atomIndex=idx}.resno
    var a1idx = {(resno=iResno) and (atomName="O2")}.atomIndex    
    var a2idx = {(resno=iResno) and (atomName="O4")}.atomIndex
    var xyz = {0 0 0} + {atomIndex=a1idx}.xyz
    {atomIndex=a1idx}.xyz = {0 0 0} + {atomIndex=a2idx}.xyz    
    {atomIndex=a2idx}.xyz = xyz
    
    a1idx = {(resno=iResno) and (atomName="C2")}.atomIndex
    a2idx = {(resno=iResno) and (atomName="C4")}.atomIndex
    xyz = {0 0 0} + {atomIndex=a1idx}.xyz
    {atomIndex=a1idx}.xyz = {0 0 0} + {atomIndex=a2idx}.xyz    
    {atomIndex=a2idx}.xyz = xyz
    
    a1idx = {(resno=iResno) and (atomName="N1")}.atomIndex
    a2idx = {(resno=iResno) and (atomName="C5")}.atomIndex
    xyz = {0 0 0} + {atomIndex=a1idx}.xyz
    {atomIndex=a1idx}.xyz = {0 0 0} + {atomIndex=a2idx}.xyz    
    {atomIndex=a2idx}.xyz = xyz
    
    var a3idx = {(resno=iResno) and (atomName="c1\'")}.atomIndex
    connect (atomIndex=a3idx) (atomindex=a1idx) DELETE
    connect (atomIndex=a3idx) (atomindex=a2idx)
    
    if (undoit) {
        to_x_idx(idx, "C", "U")
    }
    else {
        to_x_idx(idx, "N", "PU")
    }
}

function to_d_idx(idx) {
    delay
    gIsPlanar = FALSE
    var iResno = {atomIndex=idx}.resno
    var iChain = {atomIndex=idx}.chain
    var rSet = {(resno=iResno) and (chain=iChain)}
    var n1 = {rSet and (atomName="N1")}
    var c2 = {rSet and (atomName="C2")}   
    var o2 = {rSet and (atomName="O2")}   
    var n3 = {rSet and (atomName="N3")}
    var c4 = {rSet and (atomName="C4")}   
    var o4 = {rSet and (atomName="O4")}   
    var c5 = {rSet and (atomName="C5")}
    var c6 = {rSet and (atomName="C6")}

    var a1 = angle(n1, c6, c5, c4)\10
    var a2 = angle(c6, c5, c4, n3)\10
    
    # N1-C6-C5-C4 = 0.5     C6-C5-C4-N3 = 0.8
    if ((a1 == 0) or (a1 == -1)) {
        # Planar to Chair 1    
        axis = (c2.xyz - c6.xyz + n1.xyz)
        select c2 or o2 or n3 or c4 or o4 or c5 or c6
        rotateSelected @n1 @axis 40
        select o2 or n3 or c4 or o4 or c5
        rotateSelected @c2 @c6 40
        select c4 or o4
        rotateSelected @c5 @n3 40
    }
    
    # N1-C6-C5-C4 = -41.0     C6-C5-C4-N3 = -46.0
    else if ((a1 == -5) and ((a2 == 5) or (a2 == 4))) {
        # Chair 1 to boat 1 twist 1 `
        select c4 or o4
        rotateSelected @c5 @n3 -80
        select o2 or n3 or c4 or o4 or c5
        rotateSelected @n1 @c4 25
    }
    
    # N1-C6-C5-C4 = 41.6     C6-C5-C4-N3 = 23.3
    else if (((a1 == 3) or (a1 == 4)) and (a2 == -7)) {
        # Boat 1 twist 1 to boat 1 twist 2
        rotateSelected @n1 @c4 -50
    }
    
    # N1-C6-C5-C4 = -40.2     C6-C5-C4-N3 = 70.0
    else if (((a1 == -4) or (a1 == -5)) and ((a2 == -3) or (a2 == -2))) {
        # Boat1 twist 2 to chair 2    
        rotateSelected @n1 @c4 25
        axis = (c2.xyz - c6.xyz + n1.xyz)
        select c2 or o2 or n3 or c4 or o4 or c5 or c6
        rotateSelected @n1 @axis -80
        select o2 or n3 or c4 or o4 or c5
        rotateSelected @c2 @c6 -80
    }
    
    # N1-C6-C5-C4 = 41.8     C6-C5-C4-N3 = -44.10
    else if ((a1 == 4) and (a2 == -5)) {
        # Chair 2 to boat 2 twist 1` `
        select c4 or o4
        rotateSelected @c5 @n3 80
        select o2 or n3 or c4 or o4 or c5
        rotateSelected @n1 @c4 25
    }
    
    # N1-C6-C5-C4 = 41.2     C6-C5-C4-N3 = -68.5
    else if ((a1 == 4) and ((a2 == 1) or (a2 == 2))) {
        # Boat 2 twist 1 to boat 2 twist 2
        rotateSelected @n1 @c4 -50
    }
    
    # N1-C6-C5-C4 = -41.3     C6-C5-C4-N3 = 64.5
    else if ((a1 == -5) and (a2 == 6)) {
        # Boat 2 twist 2 to planar
        rotateSelected @n1 @c4 25
        select c4 or o4
        rotateSelected @c5 @n3 -40
        axis = (c2.xyz - c6.xyz + n1.xyz)
        select c2 or o2 or n3 or c4 or o4 or c5 or c6
#quit        
        rotateSelected @n1 @axis 40
        select o2 or n3 or c4 or o4 or c5
        rotateSelected @c2 @c6 40
        gIsPlanar = TRUE
    }
    
    else {
        print format("a1=%d a2=%d", a1, a2)
    }
    
}

function set_hover_labels() {
    select all
    set hoverLabel "%U"
    
    select ({(atomName="?O?")} or {(atomName="?P?") and {amino}})
    set hoverLabel "%U|1:  -X"
    
    select (oxygen or sulfur) and not *.O and (bondCount = 1)
    select {selected} or (nitrogen and (bondCount < 3))
    set hoverLabel "%U|1:  -CH3"
    select (not {amino} and not oxygen and (bondCount < 3))
    set hoverLabel "%U|1:  -CH3"
    
    select ({(atomName="?M?")} or {group="HOH"})
    set hoverLabel "%U|1:  -X"
    
    # MET N fMET
    select (MET.N and (bondCount == 1))
    set hoverLabel "%U|1:  -CH3|2: -CO"
    select (MET.N and (bondCount == 2))
    set hoverLabel "%U|1:  -CH3|2: -X"
        
    # ASP OD1 OD2 P
    select ASP.OD1 or ASP.OD2 or HIS.ND1 or SER.OG or THR.OG1 OR TYR.OH
    set hoverLabel "%U|1:  -CH3|2:  -PO3"
    
    # PRO CG HYP
    select PRO.CG
    set hoverLabel "%U|1: -CH3|2:  -OH"
    
    # A N6 I
    select [A].N6 or [I].O6
    set hoverLabel "%U|1:  -CH3|2: A <--> I"
    
    # G N2 X
    select [G].N2 or [X].O2
    set hoverLabel "%U|1:  -CH3|2: G <--> X"
    
    # U N1 PU
    select [U].N1 or [PU].C5
    set hoverLabel "%U|1:  -CH3|2: U <--> PU"
    
    # U C5-6 HU
    select [U].C6
    set hoverLabel "%U|1:  -CH3|2: U --> D"
    
    # U C5-6 HU
    select [D].C6
    set hoverLabel "%U|1:  ->Conformers|2: D --> U"
    
    # U C5 M T
    select [U].C5 OR [T].C5
    set hoverLabel "%U|1:  -CH3|2: U <--> T"
    
    # *.?2' -X
    select ??.?2'
    set hoverLabel "%U|1:  -CH3|2: X <--> DX"
    refresh
 }

function add_water_mb() {
    var idx = _atomPicked
    var iChain = {atomIndex=idx}.chain
    var pt = {0 0 0}
    var cSet = connected({atomIndex=idx})
    if (cSet.size == 2) {
        pt = get_tet(cSet[1].atomIndex, idx, cSet[2].atomIndex, 2.3) 
    }
    else if (cSet.size == 3) {
        pt = get_tet(cSet[2].atomIndex, idx, cSet[1].atomIndex, 2.3) 
    }
    else {
        var v = {atomIndex=idx}.xyz - cSet[1].xyz
        pt = {atomIndex=idx}.xyz + v + v
    }
    if (within(kCtolerance, FALSE, pt).size == 0) {
        var ls = "data \"append addto\"\n"
        ls += format("ATOM  %5d  O   HOH %s%4d    ",
             {*}.atomno.max + 1, iChain, {*}.resno.max + 1)          
        ls += format("%8.3f%8.3f%8.3f\n", pt.x, pt.y, pt.z)
        ls += "end \"append addto\""
        script inline @{ls}
        set_hover_labels()
    }
}

function modify_1_mb() {
    var idx = _atomPicked
    var isAmino = ({(atomIndex=idx) and {amino}}.size > 0)
    var iName = {atomIndex=idx}.atomName
    var iGroup = {atomIndex=idx}.group
    
    if (iGroup == "HOH") {
        delete {atomIndex=idx}
    }
    
    else if (iGroup == "D") {
        to_d_idx(idx)
        if(gIsPlanar) {
            to_d_idx(idx)
        }
    }
    
    else if ((iName[2]="M") or (iName[2]="O")
        or (isAmino and ((iName[1]="P") or (iName[2]=="P")))) {
        remove_from_idx(idx)
        delete {atomIndex=idx}
    }
    
    else {
        if ({atomIndex=idx}.element="P") {
            if (isAmino) {
                remove_from_idx(idx)
            }
        }
        else if (({atomIndex=idx}.element="O")
            and ({atomIndex=idx}.atomName!="O")
            and ({atomIndex=idx}.bondCount=1)) {
            add_to_idx(idx, "C", "M", 0)
        }
        else if (({atomIndex=idx}.element!="O")
            and ({atomIndex=idx}.bondCount < 3)) {
            add_to_idx(idx, "C", "M", 0)
        }
        else if (isAmino) {
            remove_from_idx(idx)
        }
    }
}

function modify_2_mb() {
    var idx = _atomPicked
    var iGroup = {atomIndex=idx}.group
    var iName = {atomIndex=idx}.atomName
    var iResno = {atomIndex=idx}.resno
    var iChain = {atomIndex=idx}.chain
    
    # MET.N fMET
    if ((iGroup="MET") and (iName="N")) {
        if ({atomIndex=idx}.bondCount == 1) {
            add_to_idx(idx, "C", "F", 1)
        }
        else {
             delete {(resno=iResno) and (chain=iChain) and (atomName="CF")}
             delete {(resno=iResno) and (chain=iChain) and (atomName="OC1")}
        }
    }
    
    # ASP.OD1 or ASP.O or HIS.ND1 or SER.OG or THR.OG1 OR TYR.OH PO3
    else if (((iGroup="HIS") and (iName="ND1"))
        or ((iGroup="SER") and (iName="OG"))
        or ((iGroup="THR") and (iName="OG1"))
        or ((iGroup="TYR") and (iName="OH"))
        or ((iGroup="ASP") and (iName[1][2]="OD"))) {
        
        if (({atomIndex=idx}.bondCount == 1)
            or ((iName="ND1") and ({atomIndex=idx}.bondCount == 2))) {
            add_to_idx(idx, "P", "", 3)
        }
        else {
            remove_from_idx(idx)
        }
    }
    
    # PRO.CG HYP
    else if ((iGroup="PRO") and (iName="CG")) {
        if ({atomIndex=idx}.bondCount == 2) {
            add_to_idx(idx, "O", "H", 0)
        }
        else {
            remove_from_idx(idx)
        }
    }
    
    # A.N6 I
    else if ((iGroup="A") and (iName="N6")) {
        to_x_idx(idx, "O", "I")
    }
    else if ((iGroup="I") and (iName="O6")) {
        to_x_idx(idx, "N", "A")
    }
    
    # G.N2 X
    else if ((iGroup="G") and (iName="N2")) {
        to_x_idx(idx, "O", "X")
    }
    else if ((iGroup="X") and (iName="O2")) {
        to_x_idx(idx, "N", "G")
    }
    
    # U.N1 PU
    else if ((iGroup="U") and (iName="N1")) {
        to_pu_idx(idx, FALSE)
    }
    else if ((iGroup="PU") and (iName="C5")) {
        to_pu_idx(idx, TRUE)
    }
    
    # U.C5 T
    else if ((iGroup="U") and (iName="C5")) {
        add_to_idx(idx, "C", "7 ", 0)
        to_x_idx(idx, "C", "T")
    }
    else if ((iGroup="T") and (iName="c5")) {
        delete {(resno=iResno) and (atomName="C7")}
        to_x_idx(idx, "C", "U")
    }
    
    # U.C6 HU
    else if ((iGroup="U") and ((iName="C5") or (iName="C6"))) {
        to_x_idx(idx, "C", "D")
        to_d_idx(idx)
    }
    else if ((iGroup="D") and ((iName="C5") or (iName="C6"))) {
        for (var i = 0; i < 10; i++) {
            to_d_idx(idx)
            if (gIsPlanar) {
                break
            }
        }
        to_x_idx(idx, "C", "U")
    }
    
    # O2'
    else if (iName="O2\'") {
        var cIdx = connected({atomIndex=idx})[1].atomIndex
        delete {atomIndex=idx}
        to_x_idx(cIdx, "C", "D"+iGroup)
    }
    
    # C2'
    else if (iName="C2\'") {
        var ccSet = connected({atomIndex=idx})
        if ((ccSet.size < 3) and (iGroup.size > 1)) {
            add_to_idx(idx, "O", "2\'", 0)
            to_x_idx(idx, "C", iGroup[2])
        }
        else if (iGroup.size == 1) {
            for (var i = 1; i <= ccSet.size; i++) {
                if (ccSet[i].element == "O") {
                    delete {atomIndex=@{ccSet[i].atomIndex}}
                    to_x_idx(idx, "C", "D"+iGroup)
                }
            }
        }
    }
    set_hover_labels()
    
}

function select_chain_mb() {
    var cset = {atomIndex=_atomPicked}
    select cSet
    while (cSet.size > 0) {
        cSet = connected({selected}) and not {selected}
        select {selected} or cSet
    }
    color {selected} @gAltScheme
}

function modify_exit_mb() {
    unbind
    set echo TOP LEFT
    echo
    set allowRotateSelected gAllowRotateSelected
    set allowMoveAtoms gAllowMoveAtoms
    set hoverDelay gHoverDelay
    select all
    set hoverLabel = ""
    color {selected} @gScheme
    select {gSelsave}
}
    
# Top level of Modify
function plico_modify() {
    gSelsave = {selected}
    gAllowMoveAtoms = allowMoveAtoms
    gAllowRotateSelected = allowRotateSelected
    gHoverDelay = hoverDelay
    set allowMoveAtoms TRUE    
    set allowRotateSelected TRUE
    
    gPlico = "MODIFY"
    
    gScheme = defaultColorScheme
    gAltScheme = ((gScheme == "Jmol") ? "Rasmol" : "Jmol")
    set echo TOP LEFT
    background ECHO yellow
    
    gEcho = ("________MODIFY________|ALT-CLICK=change 1|SHIFT-CLICK=change 2|" +
        "ALT-SHIFT-CLICK=select chain|ALT-CTRL-CLICK=add water|ALT-DRAG=rotate selected|" +
        "ALT-SHIFT_DRAG=move selected|DOUBLE-CLICK=exit")
    echo @gEcho
    gChain = ""
    unbind
    
    bind "ALT-LEFT-CLICK" "_pickAtom";
    bind "ALT-LEFT-CLICK" "+:modify_1_mb";
    bind "SHIFT-LEFT-CLICK" "_pickAtom";
    bind "SHIFT-LEFT-CLICK" "+:modify_2_mb";
    bind "ALT-SHIFT-LEFT-CLICK" "_pickAtom";
    bind "ALT-SHIFT-LEFT-CLICK" "+:select_chain_mb";
    bind "ALT-CTRL-LEFT-CLICK" "_pickAtom";
    bind "ALT-CTRL-LEFT-CLICK" "+:add_water_mb";
    bind "DOUBLE" "modify_exit_mb";
    
    set hoverDelay 0.001
    hover on
    set_hover_labels()
}

# End of MODIFY.SPT

Contributors

Remig