Difference between revisions of "User:Remig/plico/convert"
(Jmol script to convert residues) |
m |
||
(5 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
'''Convert_residue''' allows the user to change polypeptide or polynucleotide residues from one type to another. When the residue to change is selected with a mouse click, the user is prompted for the amino-acid or nucleotide to replace the selected residue. | '''Convert_residue''' allows the user to change polypeptide or polynucleotide residues from one type to another. When the residue to change is selected with a mouse click, the user is prompted for the amino-acid or nucleotide to replace the selected residue. | ||
+ | |||
+ | The script also allows the user to double-bond or single bond all planars (aromatics, amides, etc) in an amino-acid or nucletotide chain by a shift-click or alt-shift-click respectively. Double-bonding is useful to prevent certain distortions introduced by minimization and allows proper placement of hydrogens with the 'calculate hydrogens' command. | ||
'''Convert_residue''' 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: | '''Convert_residue''' 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 10: | Line 12: | ||
<pre># convert_residue - Jmol script by Ron Mignery | <pre># convert_residue - Jmol script by Ron Mignery | ||
− | # v1. | + | # v1.5 beta 4/12/2016 -require latest common includes |
# | # | ||
# Converts a selected residue base from one form to another. | # Converts a selected residue base from one form to another. | ||
− | # Click to select a residue | + | # Alt-Click to select a residue |
# Then enter new residue type: | # Then enter new residue type: | ||
# One of ACDEFGHIKLMNPQRSTUVWXY for polypeptide or | # One of ACDEFGHIKLMNPQRSTUVWXY for polypeptide or | ||
# One of ACGUT for nucleotides | # One of ACGUT for nucleotides | ||
− | gAppendNew = | + | # Or add or remove double bonds from aromatics, amides, and carboxyls |
+ | # Click to select a chain (Shift-Click to add, Alt-Shift-Click to remove) | ||
+ | kConvert = 1 | ||
+ | gAppendNew = true | ||
g1from3 = {"ALA":"A", "GLX":"B","CYS":"C", "ASP":"D","GLU":"E", "PHE":"F", | g1from3 = {"ALA":"A", "GLX":"B","CYS":"C", "ASP":"D","GLU":"E", "PHE":"F", | ||
"GLY":"G", "HIS":"H","ILE":"I", "LYS":"K","LEU":"L", "MET":"M", | "GLY":"G", "HIS":"H","ILE":"I", "LYS":"K","LEU":"L", "MET":"M", | ||
Line 24: | Line 29: | ||
function convert_aa(iResno, iChain, newres) { | function convert_aa(iResno, iChain, newres) { | ||
− | gBusy = | + | gBusy = true |
background ECHO pink | background ECHO pink | ||
refresh | refresh | ||
gCHAIN = iChain | gCHAIN = iChain | ||
− | + | ||
− | # Collect | + | # Collect orientation |
− | var | + | var aO = get_atom_rcn(iResno, iChain, "O") |
− | + | var aC = get_atom_rcn(iResno, iChain, "C") | |
− | + | var aCA = get_atom_rcn(iResno, iChain, "CA") | |
− | + | var aN = get_atom_rcn(iResno, iChain, "N") | |
− | var | + | var aNp = {connected(aC) and (atomname="N")} |
− | + | var aCAp = {connected(aNp) and (atomname="CA")} | |
− | var aCA = | ||
− | var | ||
− | var | ||
− | var | ||
− | |||
var aCxyz = aC.xyz + {0 0 0} | var aCxyz = aC.xyz + {0 0 0} | ||
var aOxyz = aO.xyz + {0 0 0} | var aOxyz = aO.xyz + {0 0 0} | ||
+ | var angC = angle(aNp, aC, aCA) | ||
+ | var dihedralC = angle(aCAp, aNp, aC, aCA) | ||
+ | var psi = angle(aNp, aC, aCA, aN) | ||
gN = aN.atomno | gN = aN.atomno | ||
# Delete the original | # Delete the original | ||
− | delete {(resno=iResno) and (chain=iChain) and | + | delete {(resno=iResno) and (chain=iChain) and thisModel} |
− | # | + | # Make a new AA |
− | |||
− | |||
gA = "data \"append aa\"\n" | gA = "data \"append aa\"\n" | ||
+ | |||
+ | # Call gen_aa in ribozyme.spt | ||
gA += gen_aa(iResno, newres); | gA += gen_aa(iResno, newres); | ||
gA += "end \"append aa\"" | gA += "end \"append aa\"" | ||
+ | gAppendNew = appendNew | ||
+ | set appendNew false | ||
script inline @{gA} | script inline @{gA} | ||
appendNew = gAppendNew | appendNew = gAppendNew | ||
− | + | ||
# Recollect data and move backbone to coords of old aa | # Recollect data and move backbone to coords of old aa | ||
− | + | aO = get_atom_rcn(iResno, iChain, "O") | |
− | + | aC = get_atom_rcn(iResno, iChain, "C") | |
− | + | aCA = get_atom_rcn(iResno, iChain, "CA") | |
− | + | aN = get_atom_rcn(iResno, iChain, "N") | |
− | + | ||
− | + | select {(chain=iChain) and (resno=iResno) and thisModel} | |
− | aCA.xyz | + | var v = aCxyz - aC.xyz |
− | aC.xyz = | + | translate Selected @v |
+ | var v1=aNp.xyz - aC.xyz | ||
+ | var v2=aCA.xyz - aC.xyz | ||
+ | var caxis = cross(v1, v2) + aC.xyz | ||
+ | var curangle = angle(aNp, aC, aCA) | ||
+ | rotateselected @aC @caxis @{angC-curangle} | ||
+ | curangle = angle(aCAp, aNp, aC, aCA) | ||
+ | rotateselected @aNp @aC @{dihedralC-curangle} | ||
+ | curangle = angle(aNp, aC, aCA, aN) | ||
+ | rotateselected @aC @aCA @{psi-curangle} | ||
aO.xyz = aOxyz | aO.xyz = aOxyz | ||
− | + | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
# Connect the new AA | # Connect the new AA | ||
− | var aCm = | + | var aCm = get_atom_rcn(iResno-1, iChain, "C") |
− | |||
connect @aN @aCm | connect @aN @aCm | ||
connect @aC @aNp | connect @aC @aNp | ||
Line 95: | Line 89: | ||
# Update atomnos | # Update atomnos | ||
var topdif = {(resno=iResno) and (chain=iChain) | var topdif = {(resno=iResno) and (chain=iChain) | ||
− | and | + | and thisModel}.atomno.max - topno |
if (topdif != 0) { | if (topdif != 0) { | ||
− | topmax = {(chain=iChain) and | + | topmax = {(chain=iChain) and thisModel}.atomno.max |
for (var i=(topno+1); i <= topmax; i++) { | for (var i=(topno+1); i <= topmax; i++) { | ||
− | {(atomno=i) and (chain=iChain) and | + | {(atomno=i) and (chain=iChain) and thisModel}.atomno += topdif |
} | } | ||
} | } | ||
Line 106: | Line 100: | ||
background ECHO yellow | background ECHO yellow | ||
refresh | refresh | ||
− | gBusy = | + | gBusy = false |
+ | |||
} | } | ||
function atom_rcn_xyz(iResno, iChain, iName, xyz) { | function atom_rcn_xyz(iResno, iChain, iName, xyz) { | ||
− | var a = | + | var a = get_atom_rcn(iResno, iChain, iName) |
a.xyz = xyz | a.xyz = xyz | ||
} | } | ||
function convert_nt(iResno, iChain, newres) { | function convert_nt(iResno, iChain, newres) { | ||
− | |||
− | |||
− | |||
gChain1 = iChain | gChain1 = iChain | ||
− | |||
− | |||
# Collect data | # Collect data | ||
var topno = {(resno=iResno) and (chain=iChain) | var topno = {(resno=iResno) and (chain=iChain) | ||
− | and | + | and thisModel}.atomno.max + 0 |
− | var idmax = { | + | var idmax = {thisModel}.atomIndex.max |
− | var aO4 = | + | var aO4 = get_atom_rcn(iResno, iChain, "O4\'") |
− | var aC1 = | + | if (newres = "") { |
− | var aC4 = | + | newres = aO4.group |
− | var aP = | + | } |
+ | var aC1 = get_atom_rcn(iResno, iChain, "C1\'") | ||
+ | var aC4 = get_atom_rcn(iResno, iChain, "C4\'") | ||
+ | var aP = get_atom_rcn(iResno, iChain, "P") | ||
var aPxyz = aP.xyz + {0 0 0} | var aPxyz = aP.xyz + {0 0 0} | ||
− | var aOP1xyz = | + | var aOP1xyz = get_atom_rcn(iResno, iChain, "OP1").xyz + {0 0 0} |
− | var aOP2xyz = | + | var aOP2xyz = get_atom_rcn(iResno, iChain, "OP2").xyz + {0 0 0} |
var aC1xyz = aC1.xyz + {0 0 0} | var aC1xyz = aC1.xyz + {0 0 0} | ||
var aO4xyz = aO4.xyz + {0 0 0} | var aO4xyz = aO4.xyz + {0 0 0} | ||
− | var aO3xyz = | + | var aO3xyz = get_atom_rcn(iResno, iChain, "O3\'").xyz + {0 0 0} |
− | var aC3xyz = | + | var aC3xyz = get_atom_rcn(iResno, iChain, "C3\'").xyz + {0 0 0} |
− | var aC2xyz = | + | var aC2xyz = get_atom_rcn(iResno, iChain, "C2\'").xyz + {0 0 0} |
− | var aO2xyz = | + | var aO2xyz = get_atom_rcn(iResno, iChain, "O2\'").xyz + {0 0 0} |
var aC4xyz = aC4.xyz + {0 0 0} | var aC4xyz = aC4.xyz + {0 0 0} | ||
− | var aC5xyz = | + | var aC5xyz = get_atom_rcn(iResno, iChain, "C5\'").xyz + {0 0 0} |
− | var aO5xyz = | + | var aO5xyz = get_atom_rcn(iResno, iChain, "O5\'").xyz + {0 0 0} |
− | var isR = | + | var isR = (aC1 and {purine}) |
var N1or9 = (isR ? "N9" : "N1") | var N1or9 = (isR ? "N9" : "N1") | ||
var C6or8 = (isR ? "C8" : "C6") | var C6or8 = (isR ? "C8" : "C6") | ||
− | var aN = | + | if (aC1.group = "PSU") { |
− | var aC = | + | N1or9 = "C5" |
+ | } | ||
+ | var aN = get_atom_rcn(iResno, iChain, N1or9) | ||
+ | var aC = get_atom_rcn(iResno, iChain, C6or8) | ||
var chi = angle(aO4, aC1, aN, aC) | var chi = angle(aO4, aC1, aN, aC) | ||
var dist = distance( aC1, aN) | var dist = distance( aC1, aN) | ||
Line 152: | Line 148: | ||
var bdh = angle( aC4, aO4, aC1, aN) | var bdh = angle( aC4, aO4, aC1, aN) | ||
gNa = aP.atomno | gNa = aP.atomno | ||
− | |||
# Delete the original | # Delete the original | ||
− | delete {(resno=iResno) and (chain=iChain) and | + | delete {(resno=iResno) and (chain=iChain) and thisModel} |
− | + | ||
# Gen NT ================================================== | # Gen NT ================================================== | ||
− | var isRna = ( | + | var isRna = (aO2xyz != -1) |
− | |||
gA = "data \"append nt\"\n" | gA = "data \"append nt\"\n" | ||
− | gA += gen_nt(iResno, newres, isRna, | + | gA += gen_nt(iResno, newres, isRna, false); # CALL |
gA += "end \"append nt\"" | gA += "end \"append nt\"" | ||
+ | gAppendNew = appendNew | ||
+ | set appendNew false | ||
script inline @{gA} | script inline @{gA} | ||
+ | appendNew = gAppendNew | ||
# Recollect data and move new NT to coords of old | # Recollect data and move new NT to coords of old | ||
Line 168: | Line 165: | ||
N1or9 = (isR ? "N9" : "N1") | N1or9 = (isR ? "N9" : "N1") | ||
C6or8 = (isR ? "C8" : "C6") | C6or8 = (isR ? "C8" : "C6") | ||
− | N3or7 = (isR ? "N7" : "N3") | + | var N3or7 = (isR ? "N7" : "N3") |
− | aN = | + | aN = get_atom_rcn(iResno, iChain, N1or9) |
− | aC = | + | aC = get_atom_rcn(iResno, iChain, C6or8) |
− | var aN3or7 = | + | var aN3or7 = get_atom_rcn(iResno, iChain, N3or7) |
− | var aC4 = | + | var aC4 = get_atom_rcn(iResno, iChain, "C4\'") |
− | aO4 = | + | aO4 = get_atom_rcn(iResno, iChain, "O4\'") |
− | aC1 = | + | aC1 = get_atom_rcn(iResno, iChain, "C1\'") |
− | aP = | + | aP = get_atom_rcn(iResno, iChain, "P") |
− | var aO3 = | + | var aO3 = get_atom_rcn(iResno, iChain, "O3\'") |
− | aP.xyz = aPxyz | + | if (aPxyz != -1) { |
− | + | aP.xyz = aPxyz | |
− | + | atom_rcn_xyz(iResno, iChain, "OP1", aOP1xyz) | |
+ | atom_rcn_xyz(iResno, iChain, "OP2", aOP2xyz) | ||
+ | } | ||
+ | else { | ||
+ | delete aP | ||
+ | aP = get_atom_rcn(iResno, iChain, "OP1") | ||
+ | delete aP | ||
+ | aP = get_atom_rcn(iResno, iChain, "OP2") | ||
+ | delete aP | ||
+ | } | ||
aC1.xyz = aC1xyz | aC1.xyz = aC1xyz | ||
aO4.xyz = aO4xyz | aO4.xyz = aO4xyz | ||
Line 189: | Line 195: | ||
atom_rcn_xyz(iResno, iChain, "C5\'", aC5xyz) | atom_rcn_xyz(iResno, iChain, "C5\'", aC5xyz) | ||
atom_rcn_xyz(iResno, iChain, "O5\'", aO5xyz) | atom_rcn_xyz(iResno, iChain, "O5\'", aO5xyz) | ||
− | + | ||
# Reconstruct base position on backbone | # Reconstruct base position on backbone | ||
− | select ((atomIndex > idmax) and base and | + | select ((atomIndex > idmax) and base and thisModel) |
− | color | + | color {selected} @gAltScheme |
set_distance_atoms( aC1, aN, dist) | set_distance_atoms( aC1, aN, dist) | ||
set_angle_atoms( aO4, aC1, aN, bang) | set_angle_atoms( aO4, aC1, aN, bang) | ||
Line 202: | Line 208: | ||
# Connect the new NT | # Connect the new NT | ||
− | var aO3m = | + | var aO3m = get_atom_rcn(iResno-1, iChain, "O3\'") |
− | var aPp = | + | var aPp = get_atom_rcn(iResno+1, iChain, "P") |
connect @aP @aO3m | connect @aP @aO3m | ||
connect @aO3 @aPp | connect @aO3 @aPp | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
refresh | refresh | ||
− | gBusy = | + | |
+ | gBusy = false | ||
} | } | ||
function convert_mb() { | function convert_mb() { | ||
− | + | if (gBusy == false) { | |
− | |||
− | if (gBusy == | ||
var idx = _atomPicked | var idx = _atomPicked | ||
− | var isAmino = | + | var isAmino = ({(atomIndex=idx) and amino} |
or ({atomIndex=idx}.group="SEC") | or ({atomIndex=idx}.group="SEC") | ||
or ({atomIndex=idx}.group="PYL")) | or ({atomIndex=idx}.group="PYL")) | ||
− | var isNT = | + | var isNT = {(atomIndex=idx) and (rna or dna)} |
var iResno = {atomIndex=idx}.resno | var iResno = {atomIndex=idx}.resno | ||
var iGroup = {atomIndex=idx}.group | var iGroup = {atomIndex=idx}.group | ||
var iChain = {atomIndex=idx}.chain | var iChain = {atomIndex=idx}.chain | ||
var sels = "" | var sels = "" | ||
− | select {(resno=iResno) and (chain=iChain) and | + | select {(resno=iResno) and (chain=iChain) and thisModel} |
halo on | halo on | ||
refresh | refresh | ||
if (isAmino) { | if (isAmino) { | ||
− | if (kPHI | + | if (not kPHI) { |
script $SCRIPT_PATH$ribozome.spt | script $SCRIPT_PATH$ribozome.spt | ||
− | if (kPHI | + | if (not kPHI) { |
prompt ("The Plico script ribozome.spt is required") | prompt ("The Plico script ribozome.spt is required") | ||
quit | quit | ||
Line 250: | Line 241: | ||
} | } | ||
sels = "ABCDEFGHIKLMNOPQRSTUVWXYZ" | sels = "ABCDEFGHIKLMNOPQRSTUVWXYZ" | ||
− | selp = " (enter 1 or 3 characters)" | + | var selp = " (enter 1 or 3 characters)" |
} | } | ||
else if (isNT) { | else if (isNT) { | ||
− | if ( | + | if (kPolymeraze < 1) { |
script $SCRIPT_PATH$polymeraze.spt | script $SCRIPT_PATH$polymeraze.spt | ||
− | if ( | + | if (kPolymeraze < 1) { |
− | prompt ("The Plico script polymeraze.spt is required") | + | prompt ("The Plico script polymeraze.spt (1.14+) is required") |
quit | quit | ||
} | } | ||
Line 263: | Line 254: | ||
selp = " (enter A, C, G, T, or U)" | selp = " (enter A, C, G, T, or U)" | ||
} | } | ||
− | if (sels | + | if (sels) { |
var ps = format("Change residue %d from %s to ?\n%s", | var ps = format("Change residue %d from %s to ?\n%s", | ||
iResno, iGroup, selp) | iResno, iGroup, selp) | ||
− | newres = prompt(ps, "")%9999%0 | + | var newres = prompt(ps, "")%9999%0 |
if (isAmino and (newres.size==3)) { | if (isAmino and (newres.size==3)) { | ||
newres = g1from3[newres] | newres = g1from3[newres] | ||
Line 275: | Line 266: | ||
if ((newres != "") and (newres != "NULL")) { | if ((newres != "") and (newres != "NULL")) { | ||
if (sels.find(newres[1]) > 0) { | if (sels.find(newres[1]) > 0) { | ||
+ | gBusy = true | ||
+ | background ECHO pink | ||
+ | refresh | ||
if (isAmino) { | if (isAmino) { | ||
convert_aa(iResno, iChain, newres[1]) | convert_aa(iResno, iChain, newres[1]) | ||
Line 281: | Line 275: | ||
convert_nt(iResno, iChain, newres[1]) | convert_nt(iResno, iChain, newres[1]) | ||
} | } | ||
+ | update_atomnos(iChain) | ||
+ | set echo TOP LEFT | ||
+ | background ECHO yellow | ||
+ | refresh | ||
} | } | ||
else { | else { | ||
Line 290: | Line 288: | ||
prompt("Not a polypeptide or polynucleotide") | prompt("Not a polypeptide or polynucleotide") | ||
} | } | ||
− | select {(resno=iResno) and (chain=iChain) and | + | select {(resno=iResno) and (chain=iChain) and thisModel} |
halo off | halo off | ||
} | } | ||
+ | } | ||
+ | |||
+ | function double_mb() { | ||
+ | var idx = _atomPicked | ||
+ | var iChain = {atomIndex=idx}.chain | ||
+ | background ECHO pink | ||
+ | refresh | ||
+ | double_bond_planars(iChain, false) | ||
+ | background ECHO yellow | ||
+ | refresh | ||
+ | } | ||
+ | |||
+ | function undouble_mb() { | ||
+ | var idx = _atomPicked | ||
+ | var iChain = {atomIndex=idx}.chain | ||
+ | background ECHO pink | ||
+ | refresh | ||
+ | double_bond_planars(iChain, true) | ||
+ | background ECHO yellow | ||
+ | refresh | ||
} | } | ||
function convert_exit_mb() { | function convert_exit_mb() { | ||
− | + | if (plico_exit()) { | |
− | + | set allowRotateSelected gAllowRotateSelected | |
− | + | set allowMoveAtoms gAllowMoveAtoms | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
# Top level of Modify | # Top level of Modify | ||
function plico_convert() { | function plico_convert() { | ||
− | gBusy = | + | gBusy = false |
gSelsave = {selected} | gSelsave = {selected} | ||
gPlico = "CONVERT RESIDUE" | gPlico = "CONVERT RESIDUE" | ||
# Load common functions if not already | # Load common functions if not already | ||
− | if (kCommon < | + | if (kCommon < 7) { |
script $SCRIPT_PATH$plicoCommon.spt | script $SCRIPT_PATH$plicoCommon.spt | ||
− | if (kCommon < | + | if (kCommon < 7) { |
prompt ("A newer version of plicoCommon.SPT is required") | prompt ("A newer version of plicoCommon.SPT is required") | ||
quit | quit | ||
} | } | ||
} | } | ||
− | if (kNTcommon < | + | if (kNTcommon < 6) { |
script $SCRIPT_PATH$plicoNTcommon.spt | script $SCRIPT_PATH$plicoNTcommon.spt | ||
− | if (kNTcommon < | + | if (kNTcommon < 6) { |
prompt ("A newer version of plicoNTcommon.SPT is required") | prompt ("A newer version of plicoNTcommon.SPT is required") | ||
quit | quit | ||
Line 334: | Line 346: | ||
background ECHO yellow | background ECHO yellow | ||
− | gEcho = ("____CONVERT_RESIDUE____|ALT-CLICK=select|DOUBLE-CLICK=exit") | + | gEcho = ("____CONVERT_RESIDUE____|ALT-CLICK=select residue"+ |
+ | "|SHIFT-CLICK=add double bonds to chain"+ | ||
+ | "|ALT-SHIFT-CLICK=remove double bonds|SHIFT-DOUBLE-CLICK=exit") | ||
echo @gEcho | echo @gEcho | ||
gChain = "" | gChain = "" | ||
+ | gMenuMin = false | ||
unbind | unbind | ||
bind "ALT-LEFT-CLICK" "_pickAtom"; | bind "ALT-LEFT-CLICK" "_pickAtom"; | ||
bind "ALT-LEFT-CLICK" "+:convert_mb"; | bind "ALT-LEFT-CLICK" "+:convert_mb"; | ||
− | bind "DOUBLE" "convert_exit_mb"; | + | bind "SHIFT-LEFT-CLICK" "_pickAtom"; |
+ | bind "SHIFT-LEFT-CLICK" "+:double_mb"; | ||
+ | bind "ALT-SHIFT-LEFT-CLICK" "_pickAtom"; | ||
+ | bind "ALT-SHIFT-LEFT-CLICK" "+:undouble_mb"; | ||
+ | bind "ALT-CTRL-LEFT-CLICK" "align_trna"; | ||
+ | bind "SHIFT-DOUBLE" "convert_exit_mb"; | ||
+ | bind "LEFT-CLICK" "+:plico_menu_toggle"; | ||
} | } | ||
+ | function connect_res_nt( r5, r3, iChain, del) { | ||
+ | var aO3 = get_atom_rcn(r5, iChain, "O3\'") | ||
+ | var aP = get_atom_rcn(r3, iChain, "P") | ||
+ | if (del) { | ||
+ | connect @aO3 @aP DELETE | ||
+ | } | ||
+ | else { | ||
+ | connect @aO3 @aP | ||
+ | fix_p_res(r3, iChain, false) | ||
+ | } | ||
+ | } | ||
# End of CONVERT_RESIDUE.SPT | # End of CONVERT_RESIDUE.SPT | ||
</pre> | </pre> |
Latest revision as of 17:28, 12 April 2016
Convert_residue allows the user to change polypeptide or polynucleotide residues from one type to another. When the residue to change is selected with a mouse click, the user is prompted for the amino-acid or nucleotide to replace the selected residue.
The script also allows the user to double-bond or single bond all planars (aromatics, amides, etc) in an amino-acid or nucletotide chain by a shift-click or alt-shift-click respectively. Double-bonding is useful to prevent certain distortions introduced by minimization and allows proper placement of hydrogens with the 'calculate hydrogens' command.
Convert_residue 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 Convert residue Script=script <path to your scripts directory>/convert_residue.spt;plico_convert
saved as plicoConvert.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 convert_residue.spt:
# convert_residue - Jmol script by Ron Mignery # v1.5 beta 4/12/2016 -require latest common includes # # Converts a selected residue base from one form to another. # Alt-Click to select a residue # Then enter new residue type: # One of ACDEFGHIKLMNPQRSTUVWXY for polypeptide or # One of ACGUT for nucleotides # Or add or remove double bonds from aromatics, amides, and carboxyls # Click to select a chain (Shift-Click to add, Alt-Shift-Click to remove) kConvert = 1 gAppendNew = true g1from3 = {"ALA":"A", "GLX":"B","CYS":"C", "ASP":"D","GLU":"E", "PHE":"F", "GLY":"G", "HIS":"H","ILE":"I", "LYS":"K","LEU":"L", "MET":"M", "ASN":"N", "PYL":"O","PRO":"P", "GLN":"Q","ARG":"R", "SER":"S", "THR":"T", "SEC":"U","VAL":"V", "TRP":"W","UNK":"X", "TYR":"Y", "ASX":"Z"} function convert_aa(iResno, iChain, newres) { gBusy = true background ECHO pink refresh gCHAIN = iChain # Collect orientation var aO = get_atom_rcn(iResno, iChain, "O") var aC = get_atom_rcn(iResno, iChain, "C") var aCA = get_atom_rcn(iResno, iChain, "CA") var aN = get_atom_rcn(iResno, iChain, "N") var aNp = {connected(aC) and (atomname="N")} var aCAp = {connected(aNp) and (atomname="CA")} var aCxyz = aC.xyz + {0 0 0} var aOxyz = aO.xyz + {0 0 0} var angC = angle(aNp, aC, aCA) var dihedralC = angle(aCAp, aNp, aC, aCA) var psi = angle(aNp, aC, aCA, aN) gN = aN.atomno # Delete the original delete {(resno=iResno) and (chain=iChain) and thisModel} # Make a new AA gA = "data \"append aa\"\n" # Call gen_aa in ribozyme.spt gA += gen_aa(iResno, newres); gA += "end \"append aa\"" gAppendNew = appendNew set appendNew false script inline @{gA} appendNew = gAppendNew # Recollect data and move backbone to coords of old aa aO = get_atom_rcn(iResno, iChain, "O") aC = get_atom_rcn(iResno, iChain, "C") aCA = get_atom_rcn(iResno, iChain, "CA") aN = get_atom_rcn(iResno, iChain, "N") select {(chain=iChain) and (resno=iResno) and thisModel} var v = aCxyz - aC.xyz translate Selected @v var v1=aNp.xyz - aC.xyz var v2=aCA.xyz - aC.xyz var caxis = cross(v1, v2) + aC.xyz var curangle = angle(aNp, aC, aCA) rotateselected @aC @caxis @{angC-curangle} curangle = angle(aCAp, aNp, aC, aCA) rotateselected @aNp @aC @{dihedralC-curangle} curangle = angle(aNp, aC, aCA, aN) rotateselected @aC @aCA @{psi-curangle} aO.xyz = aOxyz # Connect the new AA var aCm = get_atom_rcn(iResno-1, iChain, "C") connect @aN @aCm connect @aC @aNp # Update atomnos var topdif = {(resno=iResno) and (chain=iChain) and thisModel}.atomno.max - topno if (topdif != 0) { topmax = {(chain=iChain) and thisModel}.atomno.max for (var i=(topno+1); i <= topmax; i++) { {(atomno=i) and (chain=iChain) and thisModel}.atomno += topdif } } set echo TOP LEFT background ECHO yellow refresh gBusy = false } function atom_rcn_xyz(iResno, iChain, iName, xyz) { var a = get_atom_rcn(iResno, iChain, iName) a.xyz = xyz } function convert_nt(iResno, iChain, newres) { gChain1 = iChain # Collect data var topno = {(resno=iResno) and (chain=iChain) and thisModel}.atomno.max + 0 var idmax = {thisModel}.atomIndex.max var aO4 = get_atom_rcn(iResno, iChain, "O4\'") if (newres = "") { newres = aO4.group } var aC1 = get_atom_rcn(iResno, iChain, "C1\'") var aC4 = get_atom_rcn(iResno, iChain, "C4\'") var aP = get_atom_rcn(iResno, iChain, "P") var aPxyz = aP.xyz + {0 0 0} var aOP1xyz = get_atom_rcn(iResno, iChain, "OP1").xyz + {0 0 0} var aOP2xyz = get_atom_rcn(iResno, iChain, "OP2").xyz + {0 0 0} var aC1xyz = aC1.xyz + {0 0 0} var aO4xyz = aO4.xyz + {0 0 0} var aO3xyz = get_atom_rcn(iResno, iChain, "O3\'").xyz + {0 0 0} var aC3xyz = get_atom_rcn(iResno, iChain, "C3\'").xyz + {0 0 0} var aC2xyz = get_atom_rcn(iResno, iChain, "C2\'").xyz + {0 0 0} var aO2xyz = get_atom_rcn(iResno, iChain, "O2\'").xyz + {0 0 0} var aC4xyz = aC4.xyz + {0 0 0} var aC5xyz = get_atom_rcn(iResno, iChain, "C5\'").xyz + {0 0 0} var aO5xyz = get_atom_rcn(iResno, iChain, "O5\'").xyz + {0 0 0} var isR = (aC1 and {purine}) var N1or9 = (isR ? "N9" : "N1") var C6or8 = (isR ? "C8" : "C6") if (aC1.group = "PSU") { N1or9 = "C5" } var aN = get_atom_rcn(iResno, iChain, N1or9) var aC = get_atom_rcn(iResno, iChain, C6or8) var chi = angle(aO4, aC1, aN, aC) var dist = distance( aC1, aN) var bang = angle( aO4, aC1, aN) var bdh = angle( aC4, aO4, aC1, aN) gNa = aP.atomno # Delete the original delete {(resno=iResno) and (chain=iChain) and thisModel} # Gen NT ================================================== var isRna = (aO2xyz != -1) gA = "data \"append nt\"\n" gA += gen_nt(iResno, newres, isRna, false); # CALL gA += "end \"append nt\"" gAppendNew = appendNew set appendNew false script inline @{gA} appendNew = gAppendNew # Recollect data and move new NT to coords of old isR = ((newres="A") or (newres="G")) N1or9 = (isR ? "N9" : "N1") C6or8 = (isR ? "C8" : "C6") var N3or7 = (isR ? "N7" : "N3") aN = get_atom_rcn(iResno, iChain, N1or9) aC = get_atom_rcn(iResno, iChain, C6or8) var aN3or7 = get_atom_rcn(iResno, iChain, N3or7) var aC4 = get_atom_rcn(iResno, iChain, "C4\'") aO4 = get_atom_rcn(iResno, iChain, "O4\'") aC1 = get_atom_rcn(iResno, iChain, "C1\'") aP = get_atom_rcn(iResno, iChain, "P") var aO3 = get_atom_rcn(iResno, iChain, "O3\'") if (aPxyz != -1) { aP.xyz = aPxyz atom_rcn_xyz(iResno, iChain, "OP1", aOP1xyz) atom_rcn_xyz(iResno, iChain, "OP2", aOP2xyz) } else { delete aP aP = get_atom_rcn(iResno, iChain, "OP1") delete aP aP = get_atom_rcn(iResno, iChain, "OP2") delete aP } aC1.xyz = aC1xyz aO4.xyz = aO4xyz aO3.xyz = aO3xyz atom_rcn_xyz(iResno, iChain, "C3\'", aC3xyz) atom_rcn_xyz(iResno, iChain, "C2\'", aC2xyz) atom_rcn_xyz(iResno, iChain, "O2\'", aO2xyz) aC4.xyz = aC4xyz atom_rcn_xyz(iResno, iChain, "C5\'", aC5xyz) atom_rcn_xyz(iResno, iChain, "O5\'", aO5xyz) # Reconstruct base position on backbone select ((atomIndex > idmax) and base and thisModel) color {selected} @gAltScheme set_distance_atoms( aC1, aN, dist) set_angle_atoms( aO4, aC1, aN, bang) set_dihedral_atoms( aC4, aO4, aC1, aN, bdh) set_angle_atoms( aC1, aN, aC, (isR ? 128.5 : 121.4)) set_dihedral_atoms( aC1, aN, aC, aN3or7, 180.0) set_dihedral_atoms( aO4, aC1, aN, aC, chi) # Connect the new NT var aO3m = get_atom_rcn(iResno-1, iChain, "O3\'") var aPp = get_atom_rcn(iResno+1, iChain, "P") connect @aP @aO3m connect @aO3 @aPp refresh gBusy = false } function convert_mb() { if (gBusy == false) { var idx = _atomPicked var isAmino = ({(atomIndex=idx) and amino} or ({atomIndex=idx}.group="SEC") or ({atomIndex=idx}.group="PYL")) var isNT = {(atomIndex=idx) and (rna or dna)} var iResno = {atomIndex=idx}.resno var iGroup = {atomIndex=idx}.group var iChain = {atomIndex=idx}.chain var sels = "" select {(resno=iResno) and (chain=iChain) and thisModel} halo on refresh if (isAmino) { if (not kPHI) { script $SCRIPT_PATH$ribozome.spt if (not kPHI) { prompt ("The Plico script ribozome.spt is required") quit } } sels = "ABCDEFGHIKLMNOPQRSTUVWXYZ" var selp = " (enter 1 or 3 characters)" } else if (isNT) { if (kPolymeraze < 1) { script $SCRIPT_PATH$polymeraze.spt if (kPolymeraze < 1) { prompt ("The Plico script polymeraze.spt (1.14+) is required") quit } } sels = "ACGTU" selp = " (enter A, C, G, T, or U)" } if (sels) { var ps = format("Change residue %d from %s to ?\n%s", iResno, iGroup, selp) var newres = prompt(ps, "")%9999%0 if (isAmino and (newres.size==3)) { newres = g1from3[newres] } else if (newres.size==2) { newres = newres[2] } if ((newres != "") and (newres != "NULL")) { if (sels.find(newres[1]) > 0) { gBusy = true background ECHO pink refresh if (isAmino) { convert_aa(iResno, iChain, newres[1]) } else { convert_nt(iResno, iChain, newres[1]) } update_atomnos(iChain) set echo TOP LEFT background ECHO yellow refresh } else { prompt("Invalid entry") } } } else { prompt("Not a polypeptide or polynucleotide") } select {(resno=iResno) and (chain=iChain) and thisModel} halo off } } function double_mb() { var idx = _atomPicked var iChain = {atomIndex=idx}.chain background ECHO pink refresh double_bond_planars(iChain, false) background ECHO yellow refresh } function undouble_mb() { var idx = _atomPicked var iChain = {atomIndex=idx}.chain background ECHO pink refresh double_bond_planars(iChain, true) background ECHO yellow refresh } function convert_exit_mb() { if (plico_exit()) { set allowRotateSelected gAllowRotateSelected set allowMoveAtoms gAllowMoveAtoms } } # Top level of Modify function plico_convert() { gBusy = false gSelsave = {selected} gPlico = "CONVERT RESIDUE" # Load common functions if not already if (kCommon < 7) { script $SCRIPT_PATH$plicoCommon.spt if (kCommon < 7) { prompt ("A newer version of plicoCommon.SPT is required") quit } } if (kNTcommon < 6) { script $SCRIPT_PATH$plicoNTcommon.spt if (kNTcommon < 6) { prompt ("A newer version of plicoNTcommon.SPT is required") quit } } set echo TOP LEFT background ECHO yellow gEcho = ("____CONVERT_RESIDUE____|ALT-CLICK=select residue"+ "|SHIFT-CLICK=add double bonds to chain"+ "|ALT-SHIFT-CLICK=remove double bonds|SHIFT-DOUBLE-CLICK=exit") echo @gEcho gChain = "" gMenuMin = false unbind bind "ALT-LEFT-CLICK" "_pickAtom"; bind "ALT-LEFT-CLICK" "+:convert_mb"; bind "SHIFT-LEFT-CLICK" "_pickAtom"; bind "SHIFT-LEFT-CLICK" "+:double_mb"; bind "ALT-SHIFT-LEFT-CLICK" "_pickAtom"; bind "ALT-SHIFT-LEFT-CLICK" "+:undouble_mb"; bind "ALT-CTRL-LEFT-CLICK" "align_trna"; bind "SHIFT-DOUBLE" "convert_exit_mb"; bind "LEFT-CLICK" "+:plico_menu_toggle"; } function connect_res_nt( r5, r3, iChain, del) { var aO3 = get_atom_rcn(r5, iChain, "O3\'") var aP = get_atom_rcn(r3, iChain, "P") if (del) { connect @aO3 @aP DELETE } else { connect @aO3 @aP fix_p_res(r3, iChain, false) } } # End of CONVERT_RESIDUE.SPT