Difference between revisions of "User:Remig/plico/modify"
m |
m |
||
(7 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | '''Modify''' allows the user to make common amino acid and nucleotide | + | '''Modify''' allows the user to make common amino acid and nucleotide modifications by mouse actions. Hover text above each atom gives the available options if any including methylation on nucleosides, single-bond oxygens, and nitrogens, hydroxylation of PRO, formylation of MET, ribose/deoxyribose interconversion, phosphorylation of SER, THR, TYR and HIS, and nucleotide modifications to generate 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. | + | Modifications indicated with 1: are performed with ALT-CLICK on the atom. |
+ | Modifications indicated with 2: are performed with SHIFT-CLICK on the atom. | ||
+ | |||
+ | See [[User:Remig/plico/convert|Convert]] for a script to replace one amino-acid with another or one nucleotide with another. | ||
+ | |||
+ | After a modification adding atoms, the hover text on those atoms includes 'X' to remove the modification. Note also that the desired modification may be presented in the hover text on only just one or a few of the atoms of the residue to be modified and you may have to look around to find it. | ||
+ | |||
+ | Some features unrelated to modification have been placed here as well to serve other Plico functions. Water molecules may be added and moved around perhaps to serve as pivot points for Tug when no other atoms are where the pivot point is wanted. | ||
+ | |||
+ | Also the Jmol parameters allowMoveAtoms, allowRotateSelected, and dragSelected are set true while modify is active to allow free rotation and translation of selected atoms where ALT-DRAG rotates the selection and ALT-SHIFT-DRAG moves it. Note that the ''select chain'' option in Modify selects all atoms connected to the clicked atom, not those sharing the chain label with the clicked atom. | ||
'''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: | ||
Line 11: | Line 20: | ||
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. | + | # v1.11 beta 9/11/2015 -use thisModel |
# | # | ||
# See atom hover text for options: | # See atom hover text for options: | ||
Line 20: | Line 29: | ||
# Enable jmol move for duration | # Enable jmol move for duration | ||
− | |||
gAllowMoveAtoms = allowMoveAtoms | gAllowMoveAtoms = allowMoveAtoms | ||
gAllowRotateSelected = allowRotateSelected | gAllowRotateSelected = allowRotateSelected | ||
+ | gDragSelected = dragSelected | ||
gSelsave = ({}) | gSelsave = ({}) | ||
gScheme = defaultColorScheme | gScheme = defaultColorScheme | ||
gAltScheme = ((gScheme == "Jmol") ? "Rasmol" : "Jmol") | gAltScheme = ((gScheme == "Jmol") ? "Rasmol" : "Jmol") | ||
− | gIsPlanar = | + | gIsPlanar = false |
− | gAppendNew = | + | gAppendNew = false |
− | + | gHoverLabel = "" | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
# return vector parallel to previous bond | # return vector parallel to previous bond | ||
Line 50: | Line 43: | ||
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 add_to_idx(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 73: | Line 51: | ||
var iAtomName = {atomIndex=idx}.atomName | var iAtomName = {atomIndex=idx}.atomName | ||
var iAtomno = {atomIndex=idx}.atomno | var iAtomno = {atomIndex=idx}.atomno | ||
− | var aAtomno = {(chain=iChain) and | + | var aAtomno = {(chain=iChain) and thisModel}.atomno.max + 1 |
var cset = connected({atomIndex=idx}) | var cset = connected({atomIndex=idx}) | ||
var pt = {0 0 0} | var pt = {0 0 0} | ||
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 = | + | and (cset.size > 1))) { |
+ | pt = get_trigonal_idx(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 = | + | pt = get_tet_idx(cSet[1].atomIndex, idx, cSet[2].atomIndex, 1.5) |
} | } | ||
else if (cSet.size > 2) { | else if (cSet.size > 2) { | ||
− | pt = | + | pt = get_tet_idx(cSet[2].atomIndex, idx, cSet[1].atomIndex, 1.5) |
} | } | ||
else { | else { | ||
Line 99: | Line 78: | ||
ls += format("%8.3f%8.3f\n", pt.y, pt.z) | ls += format("%8.3f%8.3f\n", pt.y, pt.z) | ||
ls += "end \"append addto\"" | ls += "end \"append addto\"" | ||
+ | gAppendNew = appendNew | ||
+ | appendNew = false | ||
script inline @{ls} | script inline @{ls} | ||
+ | appendNew = gAppendNew | ||
var aIdx = {(atomno=aAtomno) and (chain=iChain) | var aIdx = {(atomno=aAtomno) and (chain=iChain) | ||
− | and | + | and thisModel}.atomIndex |
connect {atomIndex=idx} {atomIndex=aIdx} | connect {atomIndex=idx} {atomIndex=aIdx} | ||
Line 114: | Line 96: | ||
} | } | ||
else if (addOs == 2) { | else if (addOs == 2) { | ||
− | pt = | + | pt = get_trigonal_idx(ccSet[1].atomIndex, aIdx, ccSet[2].atomIndex, 1.5) |
} | } | ||
else { | else { | ||
if (ccSet.size == 2) { | if (ccSet.size == 2) { | ||
− | pt = | + | pt = get_tet_idx(ccSet[1].atomIndex, aIdx, ccSet[2].atomIndex, 1.5) |
} | } | ||
else if (ccSet.size == 3) { | else if (ccSet.size == 3) { | ||
− | pt = | + | pt = get_tet_idx(ccSet[2].atomIndex, aIdx, ccSet[1].atomIndex, 1.5) |
} | } | ||
else { | else { | ||
Line 134: | Line 116: | ||
ls += "end \"append addto\"" | ls += "end \"append addto\"" | ||
gAppendNew = appendNew | gAppendNew = appendNew | ||
− | appendNew = | + | appendNew = false |
script inline @{ls} | script inline @{ls} | ||
appendNew = gAppendNew | appendNew = gAppendNew | ||
oIdx = {(atomno=aAtomno) and (chain=iChain) | oIdx = {(atomno=aAtomno) and (chain=iChain) | ||
− | and | + | and thisModel}.atomIndex |
connect {atomIndex=aIdx} {atomIndex=oIdx} | connect {atomIndex=aIdx} {atomIndex=oIdx} | ||
} | } | ||
Line 157: | Line 139: | ||
function to_x_idx(idx, newElement, newGroup) { | function to_x_idx(idx, newElement, newGroup) { | ||
− | var | + | var r = {atomIndex=idx}.resno |
+ | var cSet = {(resno=r) and thisModel} | ||
var ls = "data \"append toX\"\n" | var ls = "data \"append toX\"\n" | ||
for (var i = 1; i <= cSet.size; i++) { | for (var i = 1; i <= cSet.size; i++) { | ||
Line 171: | Line 154: | ||
ls += "end \"append toX\"" | ls += "end \"append toX\"" | ||
delete cSet | delete cSet | ||
+ | gAppendNew = appendNew | ||
+ | appendNew = false | ||
script inline @{ls} | script inline @{ls} | ||
− | connect | + | appendNew = gAppendNew |
+ | |||
+ | var aP = get_atom_rcn(r, iChain, "P") | ||
+ | var aO3p = get_atom_rcn(r-1, iChain, "O3\'") | ||
+ | connect @aP @aO3p | ||
+ | var aO3 = get_atom_rcn(r, iChain, "O3\'") | ||
+ | var aPn = get_atom_rcn(r+1, iChain, "P") | ||
+ | connect @aO3 @aPn | ||
} | } | ||
Line 178: | Line 170: | ||
var iResno = {atomIndex=idx}.resno | var iResno = {atomIndex=idx}.resno | ||
var iChain = {atomIndex=idx}.chain | var iChain = {atomIndex=idx}.chain | ||
− | var a1 = | + | var a1 = get_atom_rcn(iResno, iChain, "O2") |
− | var a2 = | + | var a2 = get_atom_rcn(iResno, iChain, "O4") |
var xyz = {0 0 0} + a1.xyz | var xyz = {0 0 0} + a1.xyz | ||
a1.xyz = {0 0 0} + a2.xyz | a1.xyz = {0 0 0} + a2.xyz | ||
a2.xyz = xyz | a2.xyz = xyz | ||
− | a1 = | + | a1 = get_atom_rcn(iResno, iChain, "C2") |
− | a2 = | + | a2 = get_atom_rcn(iResno, iChain, "C4") |
xyz = {0 0 0} + a1.xyz | xyz = {0 0 0} + a1.xyz | ||
a1.xyz = {0 0 0} + a2.xyz | a1.xyz = {0 0 0} + a2.xyz | ||
a2.xyz = xyz | a2.xyz = xyz | ||
− | a1 = | + | a1 = get_atom_rcn(iResno, iChain, "N1") |
− | a2 = | + | a2 = get_atom_rcn(iResno, iChain, "C5") |
xyz = {0 0 0} + a1.xyz | xyz = {0 0 0} + a1.xyz | ||
a1.xyz = {0 0 0} + a2.xyz | a1.xyz = {0 0 0} + a2.xyz | ||
a2.xyz = xyz | a2.xyz = xyz | ||
− | var a3 = | + | var a3 = get_atom_rcn(iResno, iChain, "C1\'") |
− | connect a3 a1 DELETE | + | connect @a3 @a1 DELETE |
− | connect a3 a2 | + | connect @a3 @a2 |
if (undoit) { | if (undoit) { | ||
Line 204: | Line 196: | ||
} | } | ||
else { | else { | ||
− | to_x_idx(idx, "N", " | + | to_x_idx(idx, "N", "PSU") |
} | } | ||
} | } | ||
Line 210: | Line 202: | ||
function to_d_idx(idx) { | function to_d_idx(idx) { | ||
delay | delay | ||
− | gIsPlanar = | + | gIsPlanar = false |
var iResno = {atomIndex=idx}.resno | var iResno = {atomIndex=idx}.resno | ||
var iChain = {atomIndex=idx}.chain | var iChain = {atomIndex=idx}.chain | ||
− | var n1 = | + | var n1 = get_atom_rcn(iResno, iChain, "N1") |
− | var c2 = | + | var c2 = get_atom_rcn(iResno, iChain, "C2") |
− | var o2 = | + | var o2 = get_atom_rcn(iResno, iChain, "O2") |
− | var n3 = | + | var n3 = get_atom_rcn(iResno, iChain, "N3") |
− | var c4 = | + | var c4 = get_atom_rcn(iResno, iChain, "C4") |
− | var o4 = | + | var o4 = get_atom_rcn(iResno, iChain, "O4") |
− | var c5 = | + | var c5 = get_atom_rcn(iResno, iChain, "C5") |
− | var c6 = | + | var c6 = get_atom_rcn(iResno, iChain, "C6") |
var a1 = angle(n1, c6, c5, c4)\10 | var a1 = angle(n1, c6, c5, c4)\10 | ||
Line 286: | Line 278: | ||
axis = (c2.xyz - c6.xyz + n1.xyz) | axis = (c2.xyz - c6.xyz + n1.xyz) | ||
select c2 or o2 or n3 or c4 or o4 or c5 or c6 | select c2 or o2 or n3 or c4 or o4 or c5 or c6 | ||
− | + | ||
rotateSelected @n1 @axis 40 | rotateSelected @n1 @axis 40 | ||
select o2 or n3 or c4 or o4 or c5 | select o2 or n3 or c4 or o4 or c5 | ||
rotateSelected @c2 @c6 40 | rotateSelected @c2 @c6 40 | ||
− | gIsPlanar = | + | gIsPlanar = true |
} | } | ||
Line 300: | Line 292: | ||
function set_hover_labels() { | function set_hover_labels() { | ||
− | + | select (thisModel) | |
− | |||
− | select ( | ||
set hoverLabel "%U" | set hoverLabel "%U" | ||
select ({(atomName="?O?")} or {(atomName="?P?") and {amino}} | select ({(atomName="?O?")} or {(atomName="?P?") and {amino}} | ||
− | and | + | and thisModel) |
set hoverLabel "%U|1: -X" | set hoverLabel "%U|1: -X" | ||
select ((((oxygen or sulfur) and not *.O and (bondCount = 1)) | select ((((oxygen or sulfur) and not *.O and (bondCount = 1)) | ||
− | or (nitrogen and (bondCount < 3))) and | + | or (nitrogen and (bondCount < 3))) and thisModel) |
set hoverLabel "%U|1: -CH3" | set hoverLabel "%U|1: -CH3" | ||
select (not amino and not oxygen and (bondCount < 3) | select (not amino and not oxygen and (bondCount < 3) | ||
− | and | + | and thisModel) |
set hoverLabel "%U|1: -CH3" | set hoverLabel "%U|1: -CH3" | ||
− | select (((atomName="?M?") or (group="HOH")) and | + | select (((atomName="?M?") or (group="HOH")) and thisModel) |
set hoverLabel "%U|1: -X" | set hoverLabel "%U|1: -X" | ||
# MET N fMET | # MET N fMET | ||
− | select (MET.N and (bondCount == 1) and | + | select (MET.N and (bondCount == 1) and thisModel) |
set hoverLabel "%U|1: -CH3|2: -CO" | set hoverLabel "%U|1: -CH3|2: -CO" | ||
− | select (MET.N and (bondCount == 2) and | + | select (MET.N and (bondCount == 2) and thisModel) |
set hoverLabel "%U|1: -CH3|2: -X" | set hoverLabel "%U|1: -CH3|2: -X" | ||
# ASP OD1 OD2 P | # ASP OD1 OD2 P | ||
select ((ASP.OD1 or ASP.OD2 or HIS.ND1 or SER.OG or THR.OG1 OR TYR.OH) | select ((ASP.OD1 or ASP.OD2 or HIS.ND1 or SER.OG or THR.OG1 OR TYR.OH) | ||
− | and | + | and thisModel) |
set hoverLabel "%U|1: -CH3|2: -PO3" | set hoverLabel "%U|1: -CH3|2: -PO3" | ||
# PRO CG HYP | # PRO CG HYP | ||
− | select PRO.CG and | + | select PRO.CG and thisModel |
set hoverLabel "%U|1: -CH3|2: -OH" | set hoverLabel "%U|1: -CH3|2: -OH" | ||
# A N6 I | # A N6 I | ||
− | select ([A].N6 or [I].O6) and | + | select ([A].N6 or [I].O6) and thisModel |
set hoverLabel "%U|1: -CH3|2: A <--> I" | set hoverLabel "%U|1: -CH3|2: A <--> I" | ||
# G N2 X | # G N2 X | ||
− | select ([G].N2 or [X].O2) and | + | select ([G].N2 or [X].O2) and thisModel |
set hoverLabel "%U|1: -CH3|2: G <--> X" | set hoverLabel "%U|1: -CH3|2: G <--> X" | ||
# U N1 PU | # U N1 PU | ||
− | select ([U].N1 or [PU].C5) and | + | select ([U].N1 or [PU].C5) and thisModel |
set hoverLabel "%U|1: -CH3|2: U <--> PU" | set hoverLabel "%U|1: -CH3|2: U <--> PU" | ||
# U C5-6 HU | # U C5-6 HU | ||
− | select [U].C6 and | + | select [U].C6 and thisModel |
set hoverLabel "%U|1: -CH3|2: U --> D" | set hoverLabel "%U|1: -CH3|2: U --> D" | ||
# U C5-6 HU | # U C5-6 HU | ||
− | select [D].C6 and | + | select [D].C6 and thisModel |
set hoverLabel "%U|1: ->Conformers|2: D --> U" | set hoverLabel "%U|1: ->Conformers|2: D --> U" | ||
# U C5 M T | # U C5 M T | ||
− | select ([U].C5 OR [T].C5) and | + | select ([U].C5 OR [T].C5) and thisModel |
set hoverLabel "%U|1: -CH3|2: U <--> T" | set hoverLabel "%U|1: -CH3|2: U <--> T" | ||
# *.?2' -X | # *.?2' -X | ||
− | select ??.?2' and | + | select ??.?2' and thisModel |
set hoverLabel "%U|1: -CH3|2: X <--> DX" | set hoverLabel "%U|1: -CH3|2: X <--> DX" | ||
− | + | select (thisModel) | |
− | select ( | ||
refresh | refresh | ||
} | } | ||
Line 373: | Line 362: | ||
var pt = {0 0 0} | var pt = {0 0 0} | ||
var cSet = connected({atomIndex=idx}) | var cSet = connected({atomIndex=idx}) | ||
− | if (cSet.size == | + | var tri = false |
− | + | if (cSet.size == 1) { | |
+ | var v = {atomIndex=idx}.xyz - cSet[1].xyz | ||
+ | pt = {atomIndex=idx}.xyz + v + v | ||
} | } | ||
− | else | + | else { |
− | pt = | + | pt = get_trigonal_idx(cSet[1].atomIndex, idx, cSet[2].atomIndex, 2.3) |
+ | tri = true | ||
} | } | ||
− | + | ||
− | + | var ls = "data \"append addto\"\n" | |
− | + | ls += format("ATOM %5d O HOH %s%4d ", | |
+ | {(chain=iChain) andthisModel}.atomno.max + 1, iChain, | ||
+ | get_resno_max(iChain) + 1) | ||
+ | ls += format("%8.3f%8.3f%8.3f\n", pt.x, pt.y, pt.z) | ||
+ | ls += "end \"append addto\"" | ||
+ | gAppendNew = appendNew | ||
+ | appendNew = false | ||
+ | script inline @{ls} | ||
+ | appendNew = gAppendNew | ||
+ | |||
+ | var ap = {atomIndex=idx} | ||
+ | var ahoh = {(group="HOH") and within(2.9, ap)} | ||
+ | select @ahoh | ||
+ | color pink | ||
+ | set_distance_atoms(ap, ahoh, 2.3) | ||
+ | |||
+ | if (tri = false) { | ||
+ | var hidx = ahoh.atomIndex | ||
+ | var ccSet = connected(cSet[1]) | ||
+ | set_angle_idx(cSet[1].atomIndex, idx, hidx, 120) | ||
+ | set_dihedral_idx(ccSet[1].atomIndex, cSet[1].atomIndex, idx, hidx, 180) | ||
+ | var xset = within(kCtolerance, ahoh) and not ahoh | ||
+ | if ( xset) { | ||
+ | set_dihedral_idx(ccSet[1].atomIndex, cSet[1].atomIndex, idx, hidx, 0) | ||
+ | } | ||
} | } | ||
− | + | ||
− | + | var i = 0 | |
− | + | for (; i < 360; i += 5) { | |
− | + | var xset = within(kCtolerance, ahoh) and not ahoh | |
− | + | if (xset.size == 0) { | |
− | + | set_hover_labels() | |
− | + | break | |
− | + | } | |
+ | else if ((xset.size == 1) and (xset[1].group == "HOH")) { | ||
+ | print "share it TBD" | ||
+ | i = 360 | ||
+ | break | ||
+ | } | ||
+ | else if (tri) { | ||
+ | i = 360 | ||
+ | break | ||
+ | } | ||
+ | rotateSelected @{cset[1]} {atomIndex=idx} 5 | ||
+ | } # endfor | ||
+ | if ( i >= 360) { | ||
+ | print "no room for water" | ||
+ | delete ahoh | ||
} | } | ||
} | } | ||
Line 396: | Line 426: | ||
function modify_1_mb() { | function modify_1_mb() { | ||
var idx = _atomPicked | var idx = _atomPicked | ||
− | var isAmino = ({(atomIndex=idx) and {amino}} | + | var isAmino = ({(atomIndex=idx) and {amino}}) |
var iName = {atomIndex=idx}.atomName | var iName = {atomIndex=idx}.atomName | ||
var iGroup = {atomIndex=idx}.group | var iGroup = {atomIndex=idx}.group | ||
Line 451: | Line 481: | ||
} | } | ||
else { | else { | ||
− | delete | + | delete get_atom_rcn(iResno, iChain, "CF") |
− | delete | + | delete get_atom_rcn(iResno, iChain, "OC1") |
} | } | ||
} | } | ||
Line 500: | Line 530: | ||
# U.N1 PU | # U.N1 PU | ||
else if ((iGroup="U") and (iName="N1")) { | else if ((iGroup="U") and (iName="N1")) { | ||
− | to_pu_idx(idx, | + | to_pu_idx(idx, false) |
} | } | ||
− | else if ((iGroup=" | + | else if ((iGroup="PSU") and (iName="C5")) { |
− | to_pu_idx(idx, | + | to_pu_idx(idx, true) |
} | } | ||
Line 512: | Line 542: | ||
} | } | ||
else if ((iGroup="T") and (iName="c5")) { | else if ((iGroup="T") and (iName="c5")) { | ||
− | delete | + | delete get_atom_rcn(iResno, iChain, "C7") |
to_x_idx(idx, "C", "U") | to_x_idx(idx, "C", "U") | ||
} | } | ||
Line 561: | Line 591: | ||
var cset = {atomIndex=_atomPicked} | var cset = {atomIndex=_atomPicked} | ||
select cSet | select cSet | ||
− | while (cSet | + | while (cSet) { |
cSet = connected({selected}) and not {selected} | cSet = connected({selected}) and not {selected} | ||
select {selected} or cSet | select {selected} or cSet | ||
} | } | ||
color {selected} @gAltScheme | color {selected} @gAltScheme | ||
+ | color {selected and oxygen} pink | ||
} | } | ||
function modify_exit_mb() { | function modify_exit_mb() { | ||
− | + | ||
− | + | if (plico_exit(true)) { | |
− | + | set allowRotateSelected gAllowRotateSelected | |
− | + | set allowMoveAtoms gAllowMoveAtoms | |
− | + | set dragSelected gDragSelected | |
− | + | set hoverDelay gHoverDelay | |
− | + | set AnimFrameCallback none | |
− | + | hoverLabel = gHoverLabel | |
− | + | set hoverLabel gHoverLabel | |
− | + | } | |
− | |||
− | |||
− | |||
} | } | ||
# Top level of Modify | # Top level of Modify | ||
function plico_modify() { | function plico_modify() { | ||
− | + | ||
+ | # Load common functions if not already | ||
+ | if (kCommon < 6) { | ||
+ | script $SCRIPT_PATH$plicoCommon.spt | ||
+ | if (kCommon < 6) { | ||
+ | prompt ("A newer version of plicoCommon.SPT is required") | ||
+ | quit | ||
+ | } | ||
+ | } | ||
+ | |||
+ | gPlico = "MODIFY" | ||
+ | plico_prelim(false, true) | ||
+ | |||
gAllowMoveAtoms = allowMoveAtoms | gAllowMoveAtoms = allowMoveAtoms | ||
gAllowRotateSelected = allowRotateSelected | gAllowRotateSelected = allowRotateSelected | ||
+ | gDragSelected = dragSelected | ||
gHoverDelay = hoverDelay | gHoverDelay = hoverDelay | ||
− | set allowMoveAtoms | + | gHoverLabel = hoverLabel |
− | set allowRotateSelected | + | set allowMoveAtoms true |
+ | set allowRotateSelected true | ||
+ | set dragSelected true | ||
set AnimFrameCallback "jmolscript:set_hover_labels" | set AnimFrameCallback "jmolscript:set_hover_labels" | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
gEcho = ("________MODIFY________|ALT-CLICK=change 1|SHIFT-CLICK=change 2|" + | 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-CLICK=select chain|ALT-CTRL-CLICK=add water|ALT-DRAG=rotate selected|" + | ||
− | "ALT-SHIFT_DRAG=move selected|DOUBLE-CLICK=exit") | + | "ALT-SHIFT_DRAG=move selected|SHIFT-DOUBLE-CLICK=exit") |
echo @gEcho | echo @gEcho | ||
− | |||
− | |||
bind "ALT-LEFT-CLICK" "_pickAtom"; | bind "ALT-LEFT-CLICK" "_pickAtom"; | ||
Line 616: | Line 650: | ||
bind "ALT-CTRL-LEFT-CLICK" "_pickAtom"; | bind "ALT-CTRL-LEFT-CLICK" "_pickAtom"; | ||
bind "ALT-CTRL-LEFT-CLICK" "+:add_water_mb"; | bind "ALT-CTRL-LEFT-CLICK" "+:add_water_mb"; | ||
− | bind "DOUBLE" "modify_exit_mb"; | + | bind "SHIFT-DOUBLE" "modify_exit_mb"; |
+ | bind "LEFT-CLICK" "+:plico_menu_toggle"; | ||
set hoverDelay 0.001 | set hoverDelay 0.001 |
Latest revision as of 15:12, 11 September 2015
Modify allows the user to make common amino acid and nucleotide modifications by mouse actions. Hover text above each atom gives the available options if any including methylation on nucleosides, single-bond oxygens, and nitrogens, hydroxylation of PRO, formylation of MET, ribose/deoxyribose interconversion, phosphorylation of SER, THR, TYR and HIS, and nucleotide modifications to generate pseudouridine, dihyrouridine, inosine, and xanthine.
Modifications indicated with 1: are performed with ALT-CLICK on the atom. Modifications indicated with 2: are performed with SHIFT-CLICK on the atom.
See Convert for a script to replace one amino-acid with another or one nucleotide with another.
After a modification adding atoms, the hover text on those atoms includes 'X' to remove the modification. Note also that the desired modification may be presented in the hover text on only just one or a few of the atoms of the residue to be modified and you may have to look around to find it.
Some features unrelated to modification have been placed here as well to serve other Plico functions. Water molecules may be added and moved around perhaps to serve as pivot points for Tug when no other atoms are where the pivot point is wanted.
Also the Jmol parameters allowMoveAtoms, allowRotateSelected, and dragSelected are set true while modify is active to allow free rotation and translation of selected atoms where ALT-DRAG rotates the selection and ALT-SHIFT-DRAG moves it. Note that the select chain option in Modify selects all atoms connected to the clicked atom, not those sharing the chain label with the clicked atom.
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.11 beta 9/11/2015 -use thisModel # # 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 gAllowMoveAtoms = allowMoveAtoms gAllowRotateSelected = allowRotateSelected gDragSelected = dragSelected gSelsave = ({}) gScheme = defaultColorScheme gAltScheme = ((gScheme == "Jmol") ? "Rasmol" : "Jmol") gIsPlanar = false gAppendNew = false gHoverLabel = "" # 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 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) and thisModel}.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] != "\'") and (cset.size > 1))) { pt = get_trigonal_idx(cSet[1].atomIndex, idx, cSet[2].atomIndex, 1.5) } else { if ((cSet.size == 2) and not greek.find("\'")) { pt = get_tet_idx(cSet[1].atomIndex, idx, cSet[2].atomIndex, 1.5) } else if (cSet.size > 2) { pt = get_tet_idx(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\"" gAppendNew = appendNew appendNew = false script inline @{ls} appendNew = gAppendNew var aIdx = {(atomno=aAtomno) and (chain=iChain) and thisModel}.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_idx(ccSet[1].atomIndex, aIdx, ccSet[2].atomIndex, 1.5) } else { if (ccSet.size == 2) { pt = get_tet_idx(ccSet[1].atomIndex, aIdx, ccSet[2].atomIndex, 1.5) } else if (ccSet.size == 3) { pt = get_tet_idx(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\"" gAppendNew = appendNew appendNew = false script inline @{ls} appendNew = gAppendNew oIdx = {(atomno=aAtomno) and (chain=iChain) and thisModel}.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 r = {atomIndex=idx}.resno var cSet = {(resno=r) and thisModel} 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 gAppendNew = appendNew appendNew = false script inline @{ls} appendNew = gAppendNew var aP = get_atom_rcn(r, iChain, "P") var aO3p = get_atom_rcn(r-1, iChain, "O3\'") connect @aP @aO3p var aO3 = get_atom_rcn(r, iChain, "O3\'") var aPn = get_atom_rcn(r+1, iChain, "P") connect @aO3 @aPn } function to_pu_idx(idx, undoIt) { var iResno = {atomIndex=idx}.resno var iChain = {atomIndex=idx}.chain var a1 = get_atom_rcn(iResno, iChain, "O2") var a2 = get_atom_rcn(iResno, iChain, "O4") var xyz = {0 0 0} + a1.xyz a1.xyz = {0 0 0} + a2.xyz a2.xyz = xyz a1 = get_atom_rcn(iResno, iChain, "C2") a2 = get_atom_rcn(iResno, iChain, "C4") xyz = {0 0 0} + a1.xyz a1.xyz = {0 0 0} + a2.xyz a2.xyz = xyz a1 = get_atom_rcn(iResno, iChain, "N1") a2 = get_atom_rcn(iResno, iChain, "C5") xyz = {0 0 0} + a1.xyz a1.xyz = {0 0 0} + a2.xyz a2.xyz = xyz var a3 = get_atom_rcn(iResno, iChain, "C1\'") connect @a3 @a1 DELETE connect @a3 @a2 if (undoit) { to_x_idx(idx, "C", "U") } else { to_x_idx(idx, "N", "PSU") } } function to_d_idx(idx) { delay gIsPlanar = false var iResno = {atomIndex=idx}.resno var iChain = {atomIndex=idx}.chain var n1 = get_atom_rcn(iResno, iChain, "N1") var c2 = get_atom_rcn(iResno, iChain, "C2") var o2 = get_atom_rcn(iResno, iChain, "O2") var n3 = get_atom_rcn(iResno, iChain, "N3") var c4 = get_atom_rcn(iResno, iChain, "C4") var o4 = get_atom_rcn(iResno, iChain, "O4") var c5 = get_atom_rcn(iResno, iChain, "C5") var c6 = get_atom_rcn(iResno, iChain, "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 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 (thisModel) set hoverLabel "%U" select ({(atomName="?O?")} or {(atomName="?P?") and {amino}} and thisModel) set hoverLabel "%U|1: -X" select ((((oxygen or sulfur) and not *.O and (bondCount = 1)) or (nitrogen and (bondCount < 3))) and thisModel) set hoverLabel "%U|1: -CH3" select (not amino and not oxygen and (bondCount < 3) and thisModel) set hoverLabel "%U|1: -CH3" select (((atomName="?M?") or (group="HOH")) and thisModel) set hoverLabel "%U|1: -X" # MET N fMET select (MET.N and (bondCount == 1) and thisModel) set hoverLabel "%U|1: -CH3|2: -CO" select (MET.N and (bondCount == 2) and thisModel) 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) and thisModel) set hoverLabel "%U|1: -CH3|2: -PO3" # PRO CG HYP select PRO.CG and thisModel set hoverLabel "%U|1: -CH3|2: -OH" # A N6 I select ([A].N6 or [I].O6) and thisModel set hoverLabel "%U|1: -CH3|2: A <--> I" # G N2 X select ([G].N2 or [X].O2) and thisModel set hoverLabel "%U|1: -CH3|2: G <--> X" # U N1 PU select ([U].N1 or [PU].C5) and thisModel set hoverLabel "%U|1: -CH3|2: U <--> PU" # U C5-6 HU select [U].C6 and thisModel set hoverLabel "%U|1: -CH3|2: U --> D" # U C5-6 HU select [D].C6 and thisModel set hoverLabel "%U|1: ->Conformers|2: D --> U" # U C5 M T select ([U].C5 OR [T].C5) and thisModel set hoverLabel "%U|1: -CH3|2: U <--> T" # *.?2' -X select ??.?2' and thisModel set hoverLabel "%U|1: -CH3|2: X <--> DX" select (thisModel) refresh } function add_water_mb() { f = _frameID/1000000 m = _frameID%1000000 var idx = _atomPicked var iChain = {atomIndex=idx}.chain var pt = {0 0 0} var cSet = connected({atomIndex=idx}) var tri = false if (cSet.size == 1) { var v = {atomIndex=idx}.xyz - cSet[1].xyz pt = {atomIndex=idx}.xyz + v + v } else { pt = get_trigonal_idx(cSet[1].atomIndex, idx, cSet[2].atomIndex, 2.3) tri = true } var ls = "data \"append addto\"\n" ls += format("ATOM %5d O HOH %s%4d ", {(chain=iChain) andthisModel}.atomno.max + 1, iChain, get_resno_max(iChain) + 1) ls += format("%8.3f%8.3f%8.3f\n", pt.x, pt.y, pt.z) ls += "end \"append addto\"" gAppendNew = appendNew appendNew = false script inline @{ls} appendNew = gAppendNew var ap = {atomIndex=idx} var ahoh = {(group="HOH") and within(2.9, ap)} select @ahoh color pink set_distance_atoms(ap, ahoh, 2.3) if (tri = false) { var hidx = ahoh.atomIndex var ccSet = connected(cSet[1]) set_angle_idx(cSet[1].atomIndex, idx, hidx, 120) set_dihedral_idx(ccSet[1].atomIndex, cSet[1].atomIndex, idx, hidx, 180) var xset = within(kCtolerance, ahoh) and not ahoh if ( xset) { set_dihedral_idx(ccSet[1].atomIndex, cSet[1].atomIndex, idx, hidx, 0) } } var i = 0 for (; i < 360; i += 5) { var xset = within(kCtolerance, ahoh) and not ahoh if (xset.size == 0) { set_hover_labels() break } else if ((xset.size == 1) and (xset[1].group == "HOH")) { print "share it TBD" i = 360 break } else if (tri) { i = 360 break } rotateSelected @{cset[1]} {atomIndex=idx} 5 } # endfor if ( i >= 360) { print "no room for water" delete ahoh } } function modify_1_mb() { var idx = _atomPicked var isAmino = ({(atomIndex=idx) and {amino}}) 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 get_atom_rcn(iResno, iChain, "CF") delete get_atom_rcn(iResno, iChain, "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="PSU") 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 get_atom_rcn(iResno, iChain, "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) { cSet = connected({selected}) and not {selected} select {selected} or cSet } color {selected} @gAltScheme color {selected and oxygen} pink } function modify_exit_mb() { if (plico_exit(true)) { set allowRotateSelected gAllowRotateSelected set allowMoveAtoms gAllowMoveAtoms set dragSelected gDragSelected set hoverDelay gHoverDelay set AnimFrameCallback none hoverLabel = gHoverLabel set hoverLabel gHoverLabel } } # Top level of Modify function plico_modify() { # Load common functions if not already if (kCommon < 6) { script $SCRIPT_PATH$plicoCommon.spt if (kCommon < 6) { prompt ("A newer version of plicoCommon.SPT is required") quit } } gPlico = "MODIFY" plico_prelim(false, true) gAllowMoveAtoms = allowMoveAtoms gAllowRotateSelected = allowRotateSelected gDragSelected = dragSelected gHoverDelay = hoverDelay gHoverLabel = hoverLabel set allowMoveAtoms true set allowRotateSelected true set dragSelected true set AnimFrameCallback "jmolscript:set_hover_labels" 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|SHIFT-DOUBLE-CLICK=exit") echo @gEcho 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 "SHIFT-DOUBLE" "modify_exit_mb"; bind "LEFT-CLICK" "+:plico_menu_toggle"; set hoverDelay 0.001 hover on set_hover_labels() } # End of MODIFY.SPT