Difference between revisions of "User:Remig/plico/plicoCommon"
< User:Remig | plico
Jump to navigation
Jump to search
(Add more) |
(Avoid "axis," a newly reserved word) |
||
(11 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | This script contains routines used by other scripts of the Plico suite. It must be located in the same directory as any script that uses these routines. | + | This script contains routines used by other scripts of the Plico suite. It must be located in the same directory as any script that uses these routines. |
+ | Copy and paste the following into a text editor and save in your scripts folder as plicoCommon.spt. | ||
<pre># plicoCommon - Jmol script by Ron Mignery | <pre># plicoCommon - Jmol script by Ron Mignery | ||
− | # v1. | + | # v1.12 beta 4/12/2016 -axis is now a reserved word |
# | # | ||
# Routines and values common to all Plico suite scripts | # Routines and values common to all Plico suite scripts | ||
# Must be present in the same directory as other Plico scripts that use it | # Must be present in the same directory as other Plico scripts that use it | ||
− | kCommon = | + | kCommon = 7 |
kDtolerance = 0.1 | kDtolerance = 0.1 | ||
− | |||
kCtolerance = 1.85 | kCtolerance = 1.85 | ||
− | |||
gMouseX = 0 | gMouseX = 0 | ||
gMouseY = 0 | gMouseY = 0 | ||
gMinNo = 1 | gMinNo = 1 | ||
gMaxNo = 9999 | gMaxNo = 9999 | ||
− | gOK = | + | gOK = true # global return value to work around jmol *feature* |
− | gOk2 = | + | gOk2 = true # " " |
gScheme = "Jmol" | gScheme = "Jmol" | ||
gAltScheme = "Rasmol" | gAltScheme = "Rasmol" | ||
+ | gBusy = false | ||
+ | gEcho = "" | ||
+ | gMenuMin = false | ||
# Return L tetrahedron point if i1<i2<i3, else R point | # Return L tetrahedron point if i1<i2<i3, else R point | ||
− | + | function get_tet_idx(i1, i2, i3, dist) { | |
− | function | ||
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 | ||
− | var | + | var caxis = cross(v1, v2) |
var pma = ({atomIndex=i1}.xyz + {atomIndex=i3}.xyz)/2 | var pma = ({atomIndex=i1}.xyz + {atomIndex=i3}.xyz)/2 | ||
var pmo = {atomIndex=i2}.xyz + {atomIndex=i2}.xyz - pma | var pmo = {atomIndex=i2}.xyz + {atomIndex=i2}.xyz - pma | ||
− | var pt = pmo + ( | + | var pt = pmo + (caxis/caxis) |
var v = pt - {atomIndex=i2}.xyz | var v = pt - {atomIndex=i2}.xyz | ||
Line 38: | Line 39: | ||
} | } | ||
− | + | function get_trigonal_idx(i1, i2, i3, dist) { | |
− | function | ||
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 52: | Line 52: | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
# Selected must include second parameter but not the first | # Selected must include second parameter but not the first | ||
− | function | + | # Static may be just a point |
+ | function set_distance_atoms( static, mobile, desired) { | ||
try { | try { | ||
− | var v = mobile.xyz - | + | var s = ((static.type == "point") ? static : static.xyz) |
− | var dist = distance( | + | var v = mobile.xyz - s |
− | translateSelected @{ | + | var dist = distance(s, mobile) |
+ | translateSelected @{(v * (desired/dist)) - v} | ||
} | } | ||
catch { | catch { | ||
} | } | ||
} | } | ||
− | function | + | function set_distance_idx( staticIdx, mobileIdx, desired) { |
− | + | set_distance_atoms({atomIndex=staticIdx}, {atomIndex=mobileIdx}, desired) | |
} | } | ||
− | |||
# Selected must include third parameter but not the first | # Selected must include third parameter but not the first | ||
− | function | + | # Stator and pivot may be just points |
+ | function set_angle_atoms( stator, pivot, rotor, toangle) { | ||
try { | try { | ||
− | var | + | var s = ((stator.type == "point") ? stator : stator.xyz) |
− | var v2=rotor.xyz - | + | var p = ((pivot.type == "point") ? pivot : pivot.xyz) |
− | var | + | var v1=s - p |
+ | var v2=rotor.xyz - p | ||
+ | var caxis = cross(v1, v2) + p | ||
var curangle = angle(stator, pivot, rotor) | var curangle = angle(stator, pivot, rotor) | ||
− | rotateselected @ | + | rotateselected @caxis @pivot @{curangle-toangle} |
} | } | ||
catch { | catch { | ||
+ | print format("unable to set_angle_atoms( stator=%s, pivot=%s, rotor=%s, toangle=%f)", | ||
+ | stator, pivot, rotor, toangle) | ||
} | } | ||
} | } | ||
− | function | + | function set_angle_idx( statorIdx, pivotIdx, rotorIdx, toangle) { |
− | + | set_angle_atoms({atomIndex=statorIdx}, {atomIndex=pivotIdx}, | |
{atomIndex=rotorIdx}, toangle) | {atomIndex=rotorIdx}, toangle) | ||
− | |||
− | |||
− | |||
− | |||
} | } | ||
# Selected must include fourth parameter but not the first | # Selected must include fourth parameter but not the first | ||
− | function | + | function set_dihedral_atoms( stator, pivot1, pivot2, rotor, toangle) { |
try { | try { | ||
var curangle = angle(stator, pivot1, pivot2, rotor) | var curangle = angle(stator, pivot1, pivot2, rotor) | ||
Line 103: | Line 99: | ||
} | } | ||
} | } | ||
− | function | + | function set_dihedral_idx( statorIdx, pivot1idx, pivot2idx, rotorIdx, toangle) { |
− | + | set_dihedral_atoms({atomIndex = statorIdx}, {atomIndex = pivot1idx}, | |
{atomIndex = pivot2idx}, {atomIndex = rotorIdx}, toangle) | {atomIndex = pivot2idx}, {atomIndex = rotorIdx}, toangle) | ||
} | } | ||
− | function | + | function angle_idx_4( a1idx, a2idx, a3idx, a4idx) { |
return angle({atomIndex=a1idx}, {atomIndex=a2idx}, | return angle({atomIndex=a1idx}, {atomIndex=a2idx}, | ||
{atomIndex=a3idx}, {atomIndex=a4idx}) | {atomIndex=a3idx}, {atomIndex=a4idx}) | ||
} | } | ||
− | # | + | # First and last are BB atoms |
− | function | + | # Any side atoms in the range are also selected |
+ | function select_nward_idx (firstIdx, lastIdx) { | ||
+ | var firstno = ((firstIdx < 0) ? {atomIndex=lastIdx}.atomno : {atomIndex=firstIdx}.atomno) | ||
+ | var lastno = ((lastIdx < 0) ? firstno : {atomIndex=lastIdx}.atomno) | ||
+ | var iChain = ((firstIdx < 0) | ||
+ | ? {atomIndex=lastIdx}.chain : {atomIndex=firstIdx}.chain) | ||
+ | |||
+ | select ((atomno <= firstno) and (atomno >= lastno) and (chain = iChain) | ||
+ | and thisModel) | ||
+ | if ({(atomno=firstno) and (chain=gChain) | ||
+ | and thisModel}.atomName == "C") { # if psi | ||
+ | add_sc_to_select(firstno-1, true, true, iChain) | ||
+ | var a = {(atomno=@{firstno+1}) and (chain=iChain) and thisModel} | ||
+ | a.selected = true # add O | ||
+ | } | ||
+ | if ({(atomno=firstno) and (chain=iChain) | ||
+ | and thisModel}.atomName == "CA") { | ||
+ | add_sc_to_select(firstno, true, false, iChain) | ||
+ | } | ||
+ | if ({(atomno=lastno) and (chain=iChain) | ||
+ | and thisModel}.atomName == "C") { # if psi | ||
+ | add_sc_to_select(lastno-1, false, false, iChain) | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function add_sc_to_select(CAno, isAdd, addOXT, iChain) { | ||
+ | var res = {(atomno=CaNo) and (chain=iChain) and thisModel}.resno | ||
+ | var scset = {(resno=res) and (chain=iChain) and thisModel and sidechain} | ||
+ | if (addOXT) { | ||
+ | scset = scset or get_atom_rcn(res, iChain, "OXT") | ||
+ | } | ||
+ | if (isAdd) { | ||
+ | select add scset | ||
+ | } | ||
+ | else { | ||
+ | select remove scset | ||
+ | } | ||
+ | } | ||
+ | |||
+ | # First and last are BB atoms | ||
+ | # Any side atoms in the range are also selected | ||
+ | function select_cward_idx (firstIdx, lastIdx) { | ||
+ | var firstno = ((firstIdx < 0) ? gMaxNo : {atomIndex=firstIdx}.atomno) | ||
+ | var lastno = ((lastIdx < 0) ? 1 : {atomIndex=lastIdx}.atomno) | ||
+ | var iChain = ((firstIdx < 0) | ||
+ | ? {atomIndex=lastIdx}.chain : {atomIndex=firstIdx}.chain) | ||
+ | |||
+ | # If nWard anchor in range, begin selection with it | ||
+ | if ((gNanchorIdx >= 0) and ({atomIndex=gNanchorIdx}.chain == iChain)) { | ||
+ | var aNo = {atomIndex=gNanchorIdx}.atomno | ||
+ | if (aNo > firstNo) { | ||
+ | firstno = aNo | ||
+ | } | ||
+ | } | ||
+ | |||
+ | # If cWard anchor in range, end selection with it | ||
+ | if ((gCanchorIdx >= 0) and ({atomIndex=gCanchorIdx}.chain == iChain)) { | ||
+ | var aNo = {atomIndex=gCanchorIdx}.atomno | ||
+ | if (aNo < lastNo) { | ||
+ | lastno = aNo | ||
+ | } | ||
+ | } | ||
+ | |||
+ | select ((atomno >= firstno) and (atomno <= lastno) and (chain = iChain) | ||
+ | and thisModel) | ||
+ | |||
+ | if ({(atomno=firstno) and (chain=iChain) | ||
+ | and thisModel}.atomName == "C") { # if psi | ||
+ | add_sc_to_select(firstno-1, false, false, iChain) | ||
+ | } | ||
+ | if ({(atomno=lastno) and (chain=iChain) | ||
+ | and thisModel}.atomName == "CA") { | ||
+ | add_sc_to_select(lastno, true, false, iChain) | ||
+ | } | ||
+ | if ({(atomno=lastno) and (chain=iChain) | ||
+ | and thisModel}.atomName == "C") { # if psi | ||
+ | add_sc_to_select(lastno-1, true, true, iChain) | ||
+ | var a = {(atomno=@{lastno+1}) and (chain=iChain) and thisModel} | ||
+ | a.selected = true # add O | ||
+ | } | ||
+ | } | ||
+ | |||
+ | # tug.spt needed to handle collisions | ||
+ | function to_handle_collisions( idx) { | ||
+ | # Load tug functions | ||
+ | if (kTug < 3) { | ||
+ | script $SCRIPT_PATH$tug.spt | ||
+ | if (kTug < 3) { | ||
+ | prompt ("A newer version of tug.SPT is required") | ||
+ | quit | ||
+ | } | ||
+ | } | ||
+ | handle_collisions( idx) | ||
+ | } | ||
+ | |||
+ | function count_collisions(rc) { | ||
var cAtoms = ({}) | var cAtoms = ({}) | ||
− | for (var idx = { | + | for (var idx = {thisModel}.min.atomIndex; |
− | if ({atomIndex=idx} | + | idx <= {thisModel}.max.atomIndex; idx++) { |
− | var lcAtoms = (within(kCtolerance, | + | if ({atomIndex=idx} and {element!="H"}) { |
− | and {atomIndex > idx} | + | var lcAtoms = (within(kCtolerance, false, {atomIndex=idx}) |
− | + | and {atomIndex > idx} and {element!="H"} | |
and not connected({atomIndex=idx})) | and not connected({atomIndex=idx})) | ||
− | if (lcAtoms | + | if (lcAtoms) { |
cAtoms = cAtoms or lcAtoms or {atomIndex=idx} | cAtoms = cAtoms or lcAtoms or {atomIndex=idx} | ||
− | + | for (var i = 1; i <= lcAtoms.size; i++) { | |
− | print format("Collision of | + | print format("Collision of ({%d}) with %s", idx, lcAtoms[i]) |
+ | if (rc == true) { | ||
+ | measure {atomindex=idx} {@{lcAtoms[i]}} | ||
+ | } | ||
} | } | ||
} | } | ||
Line 133: | Line 227: | ||
} | } | ||
− | # | + | # Utility |
− | function | + | function get_atom_rcn( iResno, iChain, iName) { |
− | + | return {(resno=iResno) and (chain=iChain) and (atomName=iName) | |
+ | and thisModel} | ||
+ | } | ||
+ | |||
+ | # Utility | ||
+ | function atom_noc( iNo, iChain) { | ||
+ | return {(atomno=iNo) and (chain=iChain) and thisModel} | ||
} | } | ||
# A handy debug routine | # A handy debug routine | ||
function hi { | function hi { | ||
− | var | + | hover "%D %U" |
− | + | } | |
− | + | ||
− | + | function plico_menu_toggle() { | |
+ | var yr = _height-25 | ||
+ | if ((_mouseY > (_height-25)) and (_mouseX < 300)) { | ||
+ | if (gMenuMin) { | ||
+ | echo @gEcho | ||
+ | } | ||
+ | else { | ||
+ | var p = gEcho.find("|") | ||
+ | if (p > 0) { | ||
+ | echo @{gEcho[1][p-1]} | ||
+ | } | ||
+ | else { | ||
+ | echo | ||
+ | } | ||
+ | } | ||
+ | gMenuMin = !gMenuMin | ||
+ | } | ||
+ | gBusy = false | ||
} | } | ||
− | function | + | function plico_prelim(repair, backup) { |
# Push selected | # Push selected | ||
gSelSaves = {selected} | gSelSaves = {selected} | ||
− | select | + | select (thisModel) |
− | + | gBusy=false | |
+ | |||
# Bad idea to proceed when collisions present | # Bad idea to proceed when collisions present | ||
− | while ( | + | while (repair) { |
− | var cc = | + | var cc = count_collisions(({})).size |
if (cc > 0) { | if (cc > 0) { | ||
var p = prompt(format("%d collision%s present!\nProceed anyway?", | var p = prompt(format("%d collision%s present!\nProceed anyway?", | ||
− | cc, ((cc > 1) ? "s" : "")), "OK|Cancel|Repair", | + | cc, ((cc > 1) ? "s" : "")), "OK|Cancel|Repair", true) |
if (p == "Cancel") { | if (p == "Cancel") { | ||
quit | quit | ||
} | } | ||
else if (p == "Repair") { | else if (p == "Repair") { | ||
− | select | + | select (thisModel) |
allSet = {selected} | allSet = {selected} | ||
gChain = "XX" | gChain = "XX" | ||
Line 169: | Line 287: | ||
if ({atomIndex=idx}.chain != gChain) { | if ({atomIndex=idx}.chain != gChain) { | ||
gChain = {atomIndex=idx}.chain | gChain = {atomIndex=idx}.chain | ||
− | select {chain=gChain} | + | select {(chain=gChain) and thisModel} |
− | + | to_handle_collisions( idx) | |
} | } | ||
} | } | ||
Line 185: | Line 303: | ||
gZoom = script("show zoom") | gZoom = script("show zoom") | ||
gRotate = script("show rotation") | gRotate = script("show rotation") | ||
− | write | + | if (backup) { |
+ | write plico_save.pdb | ||
+ | } | ||
select none | select none | ||
− | + | ||
gScheme = defaultColorScheme | gScheme = defaultColorScheme | ||
gAltScheme = ((gScheme == "jmol") ? "rasmol" : "jmol") | gAltScheme = ((gScheme == "jmol") ? "rasmol" : "jmol") | ||
Line 193: | Line 313: | ||
background ECHO yellow | background ECHO yellow | ||
gChain = "" | gChain = "" | ||
+ | gMenuMin = false | ||
unbind | unbind | ||
} | } | ||
− | function | + | # gPlicoRecord is maintained by the macro plicoRecord |
+ | function plico_record(s) { | ||
+ | var g = format("show file \"%s\"", gPlicoRecord) | ||
+ | var ls = script(g) | ||
+ | if (ls.find("FileNotFoundException") > 0) { | ||
+ | ls = "" | ||
+ | } | ||
+ | ls += s | ||
+ | write var ls @gPlicoRecord | ||
+ | } | ||
+ | |||
+ | function plico_exit(undo) { | ||
var p = "" | var p = "" | ||
− | if (gPlico | + | var done = false |
− | p = prompt(format("Exit %s?", gPlico), "Yes|No|Undo", | + | if (gPlico) { |
− | if (p == "Undo") { | + | p = prompt(format("Exit %s?", gPlico), |
− | load | + | "Yes|No"+(undo ? "|Undo all" : ""), true) |
+ | if (p == "Undo all") { | ||
+ | load plico_save.pdb | ||
script inline gZoom | script inline gZoom | ||
rotate @gRotate | rotate @gRotate | ||
− | echo | + | echo Session undone |
if (gPlicoRecord != "") { | if (gPlicoRecord != "") { | ||
− | + | plico_record("load plico_save.pdb;") | |
} | } | ||
+ | reset gPlotEcho | ||
+ | set AnimFrameCallback NONE | ||
} | } | ||
} | } | ||
Line 213: | Line 349: | ||
unbind | unbind | ||
halo off | halo off | ||
− | + | select (thisModel) | |
− | select | ||
halo off | halo off | ||
star off | star off | ||
color {selected} @gScheme | color {selected} @gScheme | ||
draw gSCcircle DELETE | draw gSCcircle DELETE | ||
− | gBusy = | + | gBusy = false |
+ | gEcho = "" | ||
+ | set echo TOP LEFT | ||
background ECHO yellow | background ECHO yellow | ||
+ | echo @gEcho | ||
+ | gMenuMin = false | ||
+ | done = true | ||
# Pop selected | # Pop selected | ||
select gSelSaves | select gSelSaves | ||
+ | } | ||
+ | return done | ||
+ | } | ||
+ | |||
+ | function add_hydrogens(addh) { | ||
+ | delete hydrogen | ||
+ | connect {*} {*} aromatic modify | ||
+ | if (addh) { | ||
+ | calculate hydrogens | ||
+ | } | ||
+ | calculate aromatic | ||
+ | } | ||
+ | |||
+ | # Prevents minimization from disrespecting planar elements | ||
+ | # and allows calculate hydrogens to place hydrogens correctly | ||
+ | function double_bond_planars(iChain, undo) { | ||
+ | print format("double_bond_planars(%s, %s)", iChain, undo) | ||
+ | for (var i = get_resno_min(iChain); i <= get_resno_max(iChain); i++) { | ||
+ | var aa = {resno=i}.group[0] | ||
+ | var bps = ["O","C"] | ||
+ | switch (aa) { | ||
+ | case 'ARG' : | ||
+ | bps += ["CZ","NH1"] | ||
+ | break | ||
+ | case 'ASN' : | ||
+ | case 'ASP' : | ||
+ | bps += ["OD1","CG"] | ||
+ | break | ||
+ | case 'GLN' : | ||
+ | case 'GLU' : | ||
+ | bps += ["OE1","CD"] | ||
+ | break | ||
+ | case 'HIS' : | ||
+ | bps += ["CG","CD2","CE1","NE2"] | ||
+ | break | ||
+ | case 'PHE' : | ||
+ | case 'TYR' : | ||
+ | bps += ["CG","CD1","CD2","CE2","CE1","CZ"] | ||
+ | break | ||
+ | case 'TRP' : | ||
+ | bps += ["CG","CD1","CD2","CE2","CE3","CZ3","CZ2","CH2"] | ||
+ | break | ||
+ | case 'A' : | ||
+ | case 'G' : | ||
+ | case 'DA' : | ||
+ | case 'DG' : | ||
+ | bps = ["N7","C8","C4","C5","N3","C2", ((aa = "A") ? "N1" : "O6"), "C6"] | ||
+ | break | ||
+ | case 'C' : | ||
+ | case 'U' : | ||
+ | case 'T' : | ||
+ | case 'DC' : | ||
+ | case 'DT' : | ||
+ | case 'DU' : | ||
+ | bps = ["C5","C6","C2","O2","C4","CZ",((aa = "C") ? "N3" : "O4")] | ||
+ | break | ||
+ | } | ||
+ | for (var j = 1; j <= bps.size; j += 2) { | ||
+ | var a1 = get_atom_rcn( i, iChain, bps[j]) | ||
+ | var a2 = get_atom_rcn( i, iChain, bps[j+1]) | ||
+ | if (undo) { | ||
+ | connect @a1 @a2 single | ||
+ | } | ||
+ | else { | ||
+ | connect @a1 @a2 double | ||
+ | } | ||
+ | } | ||
+ | var a1 = get_atom_rcn(get_resno_max(iChain), iChain, "O") | ||
+ | var a2 = get_atom_rcn(get_resno_max(iChain), iChain, "C") | ||
+ | if (undo) { | ||
+ | connect @a1 @a2 single | ||
+ | } | ||
+ | else { | ||
+ | connect @a1 @a2 double | ||
+ | } | ||
+ | } # endfor | ||
+ | |||
+ | if (_version > 1402015) { | ||
+ | set multipleBondBananas true | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function get_resno_max( iChain) { | ||
+ | return {not hoh and not ligand and (chain=iChain) and thisModel}.resno.max | ||
+ | } | ||
+ | |||
+ | function get_resno_min( iChain) { | ||
+ | return {not hoh and not ligand and (chain=iChain) and thisModel}.resno.min | ||
+ | } | ||
+ | |||
+ | function plico_minimize( aset) { | ||
+ | try { | ||
+ | var savemt = useMinimizationThread | ||
+ | set useMinimizationThread false | ||
+ | var ms = minimizationSilent | ||
+ | set minimizationSilent true | ||
+ | minimize @aset | ||
+ | |||
+ | set useMinimizationThread savemt | ||
+ | set minimizationSilent ms | ||
+ | } | ||
+ | catch { | ||
+ | print "minimization error" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function p(s) { | ||
+ | print s | ||
+ | } | ||
+ | |||
+ | function delete_from_array( a, item) { | ||
+ | for (var i = 1; i <= a.size; i++) { | ||
+ | if (a[i] = item) { | ||
+ | if (i == 1) { | ||
+ | a = a[i+1][0] | ||
+ | } | ||
+ | else { | ||
+ | a = a[1][i-1]+a[i+1][0] | ||
+ | } | ||
+ | } | ||
} | } | ||
} | } | ||
+ | |||
# end of plicocommon.spt</pre> | # end of plicocommon.spt</pre> |
Latest revision as of 17:08, 12 April 2016
This script contains routines used by other scripts of the Plico suite. It must be located in the same directory as any script that uses these routines.
Copy and paste the following into a text editor and save in your scripts folder as plicoCommon.spt.
# plicoCommon - Jmol script by Ron Mignery # v1.12 beta 4/12/2016 -axis is now a reserved word # # Routines and values common to all Plico suite scripts # Must be present in the same directory as other Plico scripts that use it kCommon = 7 kDtolerance = 0.1 kCtolerance = 1.85 gMouseX = 0 gMouseY = 0 gMinNo = 1 gMaxNo = 9999 gOK = true # global return value to work around jmol *feature* gOk2 = true # " " gScheme = "Jmol" gAltScheme = "Rasmol" gBusy = false gEcho = "" gMenuMin = false # Return L tetrahedron point if i1<i2<i3, else R point function get_tet_idx(i1, i2, i3, dist) { var v1 = {atomIndex=i3}.xyz - {atomIndex=i2}.xyz var v2 = {atomIndex=i1}.xyz - {atomIndex=i2}.xyz var caxis = cross(v1, v2) var pma = ({atomIndex=i1}.xyz + {atomIndex=i3}.xyz)/2 var pmo = {atomIndex=i2}.xyz + {atomIndex=i2}.xyz - pma var pt = pmo + (caxis/caxis) 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 get_trigonal_idx(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 } # Selected must include second parameter but not the first # Static may be just a point function set_distance_atoms( static, mobile, desired) { try { var s = ((static.type == "point") ? static : static.xyz) var v = mobile.xyz - s var dist = distance(s, mobile) translateSelected @{(v * (desired/dist)) - v} } catch { } } function set_distance_idx( staticIdx, mobileIdx, desired) { set_distance_atoms({atomIndex=staticIdx}, {atomIndex=mobileIdx}, desired) } # Selected must include third parameter but not the first # Stator and pivot may be just points function set_angle_atoms( stator, pivot, rotor, toangle) { try { var s = ((stator.type == "point") ? stator : stator.xyz) var p = ((pivot.type == "point") ? pivot : pivot.xyz) var v1=s - p var v2=rotor.xyz - p var caxis = cross(v1, v2) + p var curangle = angle(stator, pivot, rotor) rotateselected @caxis @pivot @{curangle-toangle} } catch { print format("unable to set_angle_atoms( stator=%s, pivot=%s, rotor=%s, toangle=%f)", stator, pivot, rotor, toangle) } } function set_angle_idx( statorIdx, pivotIdx, rotorIdx, toangle) { set_angle_atoms({atomIndex=statorIdx}, {atomIndex=pivotIdx}, {atomIndex=rotorIdx}, toangle) } # Selected must include fourth parameter but not the first function set_dihedral_atoms( stator, pivot1, pivot2, rotor, toangle) { try { var curangle = angle(stator, pivot1, pivot2, rotor) rotateselected {pivot2} {pivot1} @{curangle-toangle} } catch { } } function set_dihedral_idx( statorIdx, pivot1idx, pivot2idx, rotorIdx, toangle) { set_dihedral_atoms({atomIndex = statorIdx}, {atomIndex = pivot1idx}, {atomIndex = pivot2idx}, {atomIndex = rotorIdx}, toangle) } function angle_idx_4( a1idx, a2idx, a3idx, a4idx) { return angle({atomIndex=a1idx}, {atomIndex=a2idx}, {atomIndex=a3idx}, {atomIndex=a4idx}) } # First and last are BB atoms # Any side atoms in the range are also selected function select_nward_idx (firstIdx, lastIdx) { var firstno = ((firstIdx < 0) ? {atomIndex=lastIdx}.atomno : {atomIndex=firstIdx}.atomno) var lastno = ((lastIdx < 0) ? firstno : {atomIndex=lastIdx}.atomno) var iChain = ((firstIdx < 0) ? {atomIndex=lastIdx}.chain : {atomIndex=firstIdx}.chain) select ((atomno <= firstno) and (atomno >= lastno) and (chain = iChain) and thisModel) if ({(atomno=firstno) and (chain=gChain) and thisModel}.atomName == "C") { # if psi add_sc_to_select(firstno-1, true, true, iChain) var a = {(atomno=@{firstno+1}) and (chain=iChain) and thisModel} a.selected = true # add O } if ({(atomno=firstno) and (chain=iChain) and thisModel}.atomName == "CA") { add_sc_to_select(firstno, true, false, iChain) } if ({(atomno=lastno) and (chain=iChain) and thisModel}.atomName == "C") { # if psi add_sc_to_select(lastno-1, false, false, iChain) } } function add_sc_to_select(CAno, isAdd, addOXT, iChain) { var res = {(atomno=CaNo) and (chain=iChain) and thisModel}.resno var scset = {(resno=res) and (chain=iChain) and thisModel and sidechain} if (addOXT) { scset = scset or get_atom_rcn(res, iChain, "OXT") } if (isAdd) { select add scset } else { select remove scset } } # First and last are BB atoms # Any side atoms in the range are also selected function select_cward_idx (firstIdx, lastIdx) { var firstno = ((firstIdx < 0) ? gMaxNo : {atomIndex=firstIdx}.atomno) var lastno = ((lastIdx < 0) ? 1 : {atomIndex=lastIdx}.atomno) var iChain = ((firstIdx < 0) ? {atomIndex=lastIdx}.chain : {atomIndex=firstIdx}.chain) # If nWard anchor in range, begin selection with it if ((gNanchorIdx >= 0) and ({atomIndex=gNanchorIdx}.chain == iChain)) { var aNo = {atomIndex=gNanchorIdx}.atomno if (aNo > firstNo) { firstno = aNo } } # If cWard anchor in range, end selection with it if ((gCanchorIdx >= 0) and ({atomIndex=gCanchorIdx}.chain == iChain)) { var aNo = {atomIndex=gCanchorIdx}.atomno if (aNo < lastNo) { lastno = aNo } } select ((atomno >= firstno) and (atomno <= lastno) and (chain = iChain) and thisModel) if ({(atomno=firstno) and (chain=iChain) and thisModel}.atomName == "C") { # if psi add_sc_to_select(firstno-1, false, false, iChain) } if ({(atomno=lastno) and (chain=iChain) and thisModel}.atomName == "CA") { add_sc_to_select(lastno, true, false, iChain) } if ({(atomno=lastno) and (chain=iChain) and thisModel}.atomName == "C") { # if psi add_sc_to_select(lastno-1, true, true, iChain) var a = {(atomno=@{lastno+1}) and (chain=iChain) and thisModel} a.selected = true # add O } } # tug.spt needed to handle collisions function to_handle_collisions( idx) { # Load tug functions if (kTug < 3) { script $SCRIPT_PATH$tug.spt if (kTug < 3) { prompt ("A newer version of tug.SPT is required") quit } } handle_collisions( idx) } function count_collisions(rc) { var cAtoms = ({}) for (var idx = {thisModel}.min.atomIndex; idx <= {thisModel}.max.atomIndex; idx++) { if ({atomIndex=idx} and {element!="H"}) { var lcAtoms = (within(kCtolerance, false, {atomIndex=idx}) and {atomIndex > idx} and {element!="H"} and not connected({atomIndex=idx})) if (lcAtoms) { cAtoms = cAtoms or lcAtoms or {atomIndex=idx} for (var i = 1; i <= lcAtoms.size; i++) { print format("Collision of ({%d}) with %s", idx, lcAtoms[i]) if (rc == true) { measure {atomindex=idx} {@{lcAtoms[i]}} } } } } } return cAtoms } # Utility function get_atom_rcn( iResno, iChain, iName) { return {(resno=iResno) and (chain=iChain) and (atomName=iName) and thisModel} } # Utility function atom_noc( iNo, iChain) { return {(atomno=iNo) and (chain=iChain) and thisModel} } # A handy debug routine function hi { hover "%D %U" } function plico_menu_toggle() { var yr = _height-25 if ((_mouseY > (_height-25)) and (_mouseX < 300)) { if (gMenuMin) { echo @gEcho } else { var p = gEcho.find("|") if (p > 0) { echo @{gEcho[1][p-1]} } else { echo } } gMenuMin = !gMenuMin } gBusy = false } function plico_prelim(repair, backup) { # Push selected gSelSaves = {selected} select (thisModel) gBusy=false # Bad idea to proceed when collisions present while (repair) { var cc = count_collisions(({})).size if (cc > 0) { var p = prompt(format("%d collision%s present!\nProceed anyway?", cc, ((cc > 1) ? "s" : "")), "OK|Cancel|Repair", true) if (p == "Cancel") { quit } else if (p == "Repair") { select (thisModel) allSet = {selected} gChain = "XX" for (var idx = {allSet}.atomIndex.min; idx <= {allSet}.atomIndex.max; idx++) { if ({atomIndex=idx}.chain != gChain) { gChain = {atomIndex=idx}.chain select {(chain=gChain) and thisModel} to_handle_collisions( idx) } } } else { break } } else { break } } # endwhile gZoom = script("show zoom") gRotate = script("show rotation") if (backup) { write plico_save.pdb } select none gScheme = defaultColorScheme gAltScheme = ((gScheme == "jmol") ? "rasmol" : "jmol") set echo TOP LEFT background ECHO yellow gChain = "" gMenuMin = false unbind } # gPlicoRecord is maintained by the macro plicoRecord function plico_record(s) { var g = format("show file \"%s\"", gPlicoRecord) var ls = script(g) if (ls.find("FileNotFoundException") > 0) { ls = "" } ls += s write var ls @gPlicoRecord } function plico_exit(undo) { var p = "" var done = false if (gPlico) { p = prompt(format("Exit %s?", gPlico), "Yes|No"+(undo ? "|Undo all" : ""), true) if (p == "Undo all") { load plico_save.pdb script inline gZoom rotate @gRotate echo Session undone if (gPlicoRecord != "") { plico_record("load plico_save.pdb;") } reset gPlotEcho set AnimFrameCallback NONE } } if (p != "No") { unbind halo off select (thisModel) halo off star off color {selected} @gScheme draw gSCcircle DELETE gBusy = false gEcho = "" set echo TOP LEFT background ECHO yellow echo @gEcho gMenuMin = false done = true # Pop selected select gSelSaves } return done } function add_hydrogens(addh) { delete hydrogen connect {*} {*} aromatic modify if (addh) { calculate hydrogens } calculate aromatic } # Prevents minimization from disrespecting planar elements # and allows calculate hydrogens to place hydrogens correctly function double_bond_planars(iChain, undo) { print format("double_bond_planars(%s, %s)", iChain, undo) for (var i = get_resno_min(iChain); i <= get_resno_max(iChain); i++) { var aa = {resno=i}.group[0] var bps = ["O","C"] switch (aa) { case 'ARG' : bps += ["CZ","NH1"] break case 'ASN' : case 'ASP' : bps += ["OD1","CG"] break case 'GLN' : case 'GLU' : bps += ["OE1","CD"] break case 'HIS' : bps += ["CG","CD2","CE1","NE2"] break case 'PHE' : case 'TYR' : bps += ["CG","CD1","CD2","CE2","CE1","CZ"] break case 'TRP' : bps += ["CG","CD1","CD2","CE2","CE3","CZ3","CZ2","CH2"] break case 'A' : case 'G' : case 'DA' : case 'DG' : bps = ["N7","C8","C4","C5","N3","C2", ((aa = "A") ? "N1" : "O6"), "C6"] break case 'C' : case 'U' : case 'T' : case 'DC' : case 'DT' : case 'DU' : bps = ["C5","C6","C2","O2","C4","CZ",((aa = "C") ? "N3" : "O4")] break } for (var j = 1; j <= bps.size; j += 2) { var a1 = get_atom_rcn( i, iChain, bps[j]) var a2 = get_atom_rcn( i, iChain, bps[j+1]) if (undo) { connect @a1 @a2 single } else { connect @a1 @a2 double } } var a1 = get_atom_rcn(get_resno_max(iChain), iChain, "O") var a2 = get_atom_rcn(get_resno_max(iChain), iChain, "C") if (undo) { connect @a1 @a2 single } else { connect @a1 @a2 double } } # endfor if (_version > 1402015) { set multipleBondBananas true } } function get_resno_max( iChain) { return {not hoh and not ligand and (chain=iChain) and thisModel}.resno.max } function get_resno_min( iChain) { return {not hoh and not ligand and (chain=iChain) and thisModel}.resno.min } function plico_minimize( aset) { try { var savemt = useMinimizationThread set useMinimizationThread false var ms = minimizationSilent set minimizationSilent true minimize @aset set useMinimizationThread savemt set minimizationSilent ms } catch { print "minimization error" } } function p(s) { print s } function delete_from_array( a, item) { for (var i = 1; i <= a.size; i++) { if (a[i] = item) { if (i == 1) { a = a[i+1][0] } else { a = a[1][i-1]+a[i+1][0] } } } } # end of plicocommon.spt