Difference between revisions of "User:Remig/plico/tug"
< User:Remig | plico
Jump to navigation
Jump to search
(Do not var globals) |
(lc all functions) |
||
| Line 7: | Line 7: | ||
Copy and paste the following into a text editor and save in your scripts folder as tug.spt. | Copy and paste the following into a text editor and save in your scripts folder as tug.spt. | ||
| − | <pre># | + | <pre># tug - Jmol script by Ron Mignery |
| − | # v1. | + | # v1.11 beta 5/16/2014 -lc all functions |
# | # | ||
# Translate or rotate a stretch of a polypeptide against itself | # Translate or rotate a stretch of a polypeptide against itself | ||
# or against other chains by mouse actions | # or against other chains by mouse actions | ||
# | # | ||
| − | kTug = | + | kTug = 3 |
gCanchorIdx = -1 | gCanchorIdx = -1 | ||
gCanchorNo = -1 | gCanchorNo = -1 | ||
| Line 29: | Line 29: | ||
gCrotors = array() | gCrotors = array() | ||
gNrotors = array() | gNrotors = array() | ||
| − | |||
| − | |||
gOkCollide = ({}) | gOkCollide = ({}) | ||
gChain = "" | gChain = "" | ||
gMinNo = 1 | gMinNo = 1 | ||
gMaxNo = 9999 | gMaxNo = 9999 | ||
| − | |||
| − | |||
gCargoSet = ({}) | gCargoSet = ({}) | ||
gMovingSet = ({}) | gMovingSet = ({}) | ||
| Line 43: | Line 39: | ||
gSCcircle = -1 | gSCcircle = -1 | ||
gSCpt = {0 0 0} | gSCpt = {0 0 0} | ||
| − | |||
| − | |||
gTargetPt = {0 0 0} | gTargetPt = {0 0 0} | ||
gNewDrag = FALSE | gNewDrag = FALSE | ||
| Line 57: | Line 51: | ||
| − | function | + | function get_cam_no (iNo) { |
while ((iNo > 0) and ({(atomno=iNo) and (chain=gChain)}.atomName != "CA")) { | while ((iNo > 0) and ({(atomno=iNo) and (chain=gChain)}.atomName != "CA")) { | ||
iNo-- | iNo-- | ||
| Line 64: | Line 58: | ||
} | } | ||
| − | function | + | function get_cam_idx (idx) { |
var no = {atomIndex=idx and (chain=gChain)}.atomno | var no = {atomIndex=idx and (chain=gChain)}.atomno | ||
| − | no = | + | no = get_cam_no( no) |
return ({(atomno=no) and (chain=gChain)}.atomIndex) | return ({(atomno=no) and (chain=gChain)}.atomIndex) | ||
} | } | ||
| − | function | + | function get_cap_no (iNo) { |
while ((iNo < gMaxNo) and ({(atomno=iNo) and (chain=gChain)}.atomName != "CA")) { | while ((iNo < gMaxNo) and ({(atomno=iNo) and (chain=gChain)}.atomName != "CA")) { | ||
iNo++ | iNo++ | ||
| Line 77: | Line 71: | ||
} | } | ||
| − | function | + | function getCApIdx (idx) { |
var no = {atomIndex=idx and (chain=gChain)}.atomno | var no = {atomIndex=idx and (chain=gChain)}.atomno | ||
| − | no = | + | no = get_cap_no( no) |
return ({(atomno=no) and (chain=gChain)}.atomIndex) | return ({(atomno=no) and (chain=gChain)}.atomIndex) | ||
} | } | ||
| − | function | + | function get_cp_no (iNo) { |
while ((iNo < gMaxNo) and ({(atomno=iNo) and (chain=gChain)}.atomName != "C")) { | while ((iNo < gMaxNo) and ({(atomno=iNo) and (chain=gChain)}.atomName != "C")) { | ||
iNo++ | iNo++ | ||
| Line 90: | Line 84: | ||
} | } | ||
| − | function | + | function get_cp_idx (idx) { |
var no = {atomIndex=idx and (chain=gChain)}.atomno | var no = {atomIndex=idx and (chain=gChain)}.atomno | ||
| − | no = | + | no = get_cp_no( no) |
return ({(atomno=no) and (chain=gChain)}.atomIndex) | return ({(atomno=no) and (chain=gChain)}.atomIndex) | ||
} | } | ||
| − | function | + | function get_cm_no (iNo) { |
while ((iNo > 0) and ({(atomno=iNo) and (chain=gChain)}.atomName != "C")) { | while ((iNo > 0) and ({(atomno=iNo) and (chain=gChain)}.atomName != "C")) { | ||
iNo-- | iNo-- | ||
| Line 103: | Line 97: | ||
} | } | ||
| − | function | + | function get_cm_idx (idx) { |
var no = {atomIndex=idx and (chain=gChain)}.atomno | var no = {atomIndex=idx and (chain=gChain)}.atomno | ||
| − | no = | + | no = get_cm_no( no) |
return ({(atomno=no) and (chain=gChain)}.atomIndex) | return ({(atomno=no) and (chain=gChain)}.atomIndex) | ||
} | } | ||
| − | function | + | function get_nm_no (iNo) { |
while ((iNo > 0) and ({(atomno=iNo) and (chain=gChain)}.atomName != "N")) { | while ((iNo > 0) and ({(atomno=iNo) and (chain=gChain)}.atomName != "N")) { | ||
iNo-- | iNo-- | ||
| Line 116: | Line 110: | ||
} | } | ||
| − | function | + | function get_nm_idx (idx) { |
var no = {atomIndex=idx and (chain=gChain)}.atomno | var no = {atomIndex=idx and (chain=gChain)}.atomno | ||
| − | no = | + | no = get_nm_no( no) |
return ({(atomno=no) and (chain=gChain)}.atomIndex) | return ({(atomno=no) and (chain=gChain)}.atomIndex) | ||
} | } | ||
| − | function | + | function get_np_no (iNo) { |
while ((iNo < gMaxNo) and ({(atomno=iNo) and (chain=gChain)}.atomName != "N")) { | while ((iNo < gMaxNo) and ({(atomno=iNo) and (chain=gChain)}.atomName != "N")) { | ||
iNo++ | iNo++ | ||
| Line 129: | Line 123: | ||
} | } | ||
| − | function | + | function get_np_idx (idx) { |
var no = {atomIndex=idx}.atomno | var no = {atomIndex=idx}.atomno | ||
| − | no = | + | no = get_np_no( no) |
return ({(atomno=no) and (chain=gChain)}.atomIndex) | return ({(atomno=no) and (chain=gChain)}.atomIndex) | ||
} | } | ||
| − | function | + | function get_cb_idx (BBidx) { |
var no = {atomIndex=BBidx}.atomno | var no = {atomIndex=BBidx}.atomno | ||
var i = 1 | var i = 1 | ||
| Line 146: | Line 140: | ||
} | } | ||
| − | function | + | function get_o_idx (BBidx) { |
var no = {atomIndex=BBidx}.atomno | var no = {atomIndex=BBidx}.atomno | ||
var i = 1 | var i = 1 | ||
| Line 157: | Line 151: | ||
} | } | ||
| − | function | + | function get_nward_bb_no (iNo, iChain) { |
while ((iNo >= 0) and ( | while ((iNo >= 0) and ( | ||
({(atomno=iNo) and (chain=iChain)}.atomName != "N") | ({(atomno=iNo) and (chain=iChain)}.atomName != "N") | ||
| Line 167: | Line 161: | ||
} | } | ||
| − | function | + | function get_nward_bb_idx (idx, iChain) { |
var no = {atomIndex=idx}.atomno - 1 | var no = {atomIndex=idx}.atomno - 1 | ||
| − | no = | + | no = get_nward_bb_no( no, iChain) |
return ((no >= 0) ? ({(atomno=no) and (chain=iChain)}.atomIndex) : -1) | return ((no >= 0) ? ({(atomno=no) and (chain=iChain)}.atomIndex) : -1) | ||
} | } | ||
| − | function | + | function get_cward_bb_no (iNo, iChain) { |
while ((iNo < gMaxNo) and ( | while ((iNo < gMaxNo) and ( | ||
({(atomno=iNo) and (chain=iChain)}.atomName != "N") | ({(atomno=iNo) and (chain=iChain)}.atomName != "N") | ||
| Line 183: | Line 177: | ||
} | } | ||
| − | function | + | function get_cward_bb_idx (idx, iChain) { |
var no = {atomIndex=idx}.atomno + 1 | var no = {atomIndex=idx}.atomno + 1 | ||
| − | no = | + | no = get_cward_bb_no( no, iChain) |
return ((no >= 0) ? ({(atomno=no) and (chain=iChain)}.atomIndex) : -1) | return ((no >= 0) ? ({(atomno=no) and (chain=iChain)}.atomIndex) : -1) | ||
} | } | ||
| − | function | + | function get_sc_set (scIdx, iChain) { |
var scSet = ({}) | var scSet = ({}) | ||
| − | var idx = | + | var idx = get_sc_bb_idx(scIdx, iChain) |
var iNo = {atomIndex=idx}.atomno + 3 | var iNo = {atomIndex=idx}.atomno + 3 | ||
for (var i = 1; i < 20; i++) { | for (var i = 1; i < 20; i++) { | ||
idx = {(atomno=@{iNo+i}) and (chain=iChain)}.atomIndex | idx = {(atomno=@{iNo+i}) and (chain=iChain)}.atomIndex | ||
| − | if ( | + | if (is_bb_idx(idx)) { |
break | break | ||
} | } | ||
| Line 204: | Line 198: | ||
} | } | ||
| − | function | + | function get_sc_bb_idx (idx, iChain) { |
var no = {atomIndex=idx}.atomno | var no = {atomIndex=idx}.atomno | ||
for (; no > 0; no--) { | for (; no > 0; no--) { | ||
| Line 224: | Line 218: | ||
} | } | ||
| − | function | + | function is_bb_idx(aIdx) { |
var ret = FALSE | var ret = FALSE | ||
switch({atomIndex=aIdx}.atomName) { | switch({atomIndex=aIdx}.atomName) { | ||
| Line 236: | Line 230: | ||
} | } | ||
| − | function | + | function is_sc_idx(aIdx) { |
var ret = FALSE | var ret = FALSE | ||
| − | if (not | + | if (not is_bb_idx(aIDx)) { |
ret = TRUE | ret = TRUE | ||
| Line 252: | Line 246: | ||
} | } | ||
| − | function | + | function add_sc_to_select(CAno, isAdd, addOXT, iChain) { |
var iNo = CAno+3 | var iNo = CAno+3 | ||
while ({(atomno=iNo) and (chain=iChain)}.resno == {(atomno=CAno) and (chain=iChain)}.resno) { | while ({(atomno=iNo) and (chain=iChain)}.resno == {(atomno=CAno) and (chain=iChain)}.resno) { | ||
| Line 263: | Line 257: | ||
} | } | ||
| − | function | + | function select_add_sc(fromIdx) { |
var iNo = {atomIndex=fromIdx}.atomno | var iNo = {atomIndex=fromIdx}.atomno | ||
var iChain = {atomIndex=fromIdx}.chain | var iChain = {atomIndex=fromIdx}.chain | ||
| Line 278: | Line 272: | ||
# First and last are BB atoms | # First and last are BB atoms | ||
# Any side atoms in the range are also selected | # Any side atoms in the range are also selected | ||
| − | function | + | function select_nward_idx (firstIdx, lastIdx) { |
var firstno = ((firstIdx < 0) ? {atomIndex=lastIdx}.atomno : {atomIndex=firstIdx}.atomno) | var firstno = ((firstIdx < 0) ? {atomIndex=lastIdx}.atomno : {atomIndex=firstIdx}.atomno) | ||
var lastno = ((lastIdx < 0) ? firstno : {atomIndex=lastIdx}.atomno) | var lastno = ((lastIdx < 0) ? firstno : {atomIndex=lastIdx}.atomno) | ||
| Line 287: | Line 281: | ||
if ({(atomno=firstno) and (chain=gChain)}.atomName == "C") { # if psi | if ({(atomno=firstno) and (chain=gChain)}.atomName == "C") { # if psi | ||
| − | + | add_sc_to_select(firstno-1, TRUE, TRUE, iChain) | |
{(atomno=@{firstno+1}) and (chain=iChain)}.selected = TRUE # add O | {(atomno=@{firstno+1}) and (chain=iChain)}.selected = TRUE # add O | ||
} | } | ||
if ({(atomno=firstno) and (chain=iChain)}.atomName == "CA") { | if ({(atomno=firstno) and (chain=iChain)}.atomName == "CA") { | ||
| − | + | add_sc_to_select(firstno, TRUE, FALSE, iChain) | |
} | } | ||
if ({(atomno=lastno) and (chain=iChain)}.atomName == "C") { # if psi | if ({(atomno=lastno) and (chain=iChain)}.atomName == "C") { # if psi | ||
| − | + | add_sc_to_select(lastno-1, FALSE, FALSE, iChain) | |
} | } | ||
} | } | ||
| Line 300: | Line 294: | ||
# First and last are BB atoms | # First and last are BB atoms | ||
# Any side atoms in the range are also selected | # Any side atoms in the range are also selected | ||
| − | function | + | function select_cward_idx (firstIdx, lastIdx) { |
var firstno = ((firstIdx < 0) ? gMaxNo : {atomIndex=firstIdx}.atomno) | var firstno = ((firstIdx < 0) ? gMaxNo : {atomIndex=firstIdx}.atomno) | ||
var lastno = ((lastIdx < 0) ? 1 : {atomIndex=lastIdx}.atomno) | var lastno = ((lastIdx < 0) ? 1 : {atomIndex=lastIdx}.atomno) | ||
| Line 325: | Line 319: | ||
if ({(atomno=firstno) and (chain=iChain)}.atomName == "C") { # if psi | if ({(atomno=firstno) and (chain=iChain)}.atomName == "C") { # if psi | ||
| − | + | add_sc_to_select(firstno-1, FALSE, FALSE, iChain) | |
} | } | ||
if ({(atomno=lastno) and (chain=iChain)}.atomName == "CA") { | if ({(atomno=lastno) and (chain=iChain)}.atomName == "CA") { | ||
| − | + | add_sc_to_select(lastno, TRUE, FALSE, iChain) | |
} | } | ||
if ({(atomno=lastno) and (chain=iChain)}.atomName == "C") { # if psi | if ({(atomno=lastno) and (chain=iChain)}.atomName == "C") { # if psi | ||
| − | + | add_sc_to_select(lastno-1, TRUE, TRUE, iChain) | |
{(atomno=@{lastno+1}) and (chain=iChain)}.selected = TRUE # add O | {(atomno=@{lastno+1}) and (chain=iChain)}.selected = TRUE # add O | ||
} | } | ||
| Line 338: | Line 332: | ||
# Resolve collisions | # Resolve collisions | ||
| − | function | + | function handle_collisions_2( targetIdx) { |
# For all selected atoms | # For all selected atoms | ||
| Line 353: | Line 347: | ||
# Ignore kinked BB | # Ignore kinked BB | ||
| − | if ( | + | if (is_bb_idx(idx) and angle({atomIndex=@{get_cward_bb_idx(idx, gChain)}}, |
| − | {atomIndex=idx} , {atomIndex=@{ | + | {atomIndex=idx} , {atomIndex=@{get_nward_bb_idx(idx, gChain)}}) < 100) { |
continue | continue | ||
} | } | ||
| Line 368: | Line 362: | ||
# else if it is with side chain not proline, fix it | # else if it is with side chain not proline, fix it | ||
| − | else if ( | + | else if (is_sc_idx(cidx) and ({atomIndex=cidx}.group != "PRO")) { |
| − | + | fix_sc_collision_2(cidx) | |
recollect = TRUE | recollect = TRUE | ||
| Line 379: | Line 373: | ||
# else if it is itself a side chain not proline, fix it | # else if it is itself a side chain not proline, fix it | ||
| − | else if ( | + | else if (is_sc_idx(idx) and ({atomIndex=idx}.group != "PRO")) { |
| − | + | fix_sc_collision_2(idx) | |
recollect = TRUE | recollect = TRUE | ||
| Line 391: | Line 385: | ||
# Else if it is with O, counter-rotate | # Else if it is with O, counter-rotate | ||
else if (lcAtoms[c].atomName = "O") { | else if (lcAtoms[c].atomName = "O") { | ||
| − | + | counter_rotate_2(lcAtoms[c].atomIndex, | |
{atomIndex=idx}.xyz, targetIdx, FALSE) | {atomIndex=idx}.xyz, targetIdx, FALSE) | ||
| Line 402: | Line 396: | ||
# Else if it is itself O, counter-rotate | # Else if it is itself O, counter-rotate | ||
else if ({atomIndex=idx}.atomName = "O") { | else if ({atomIndex=idx}.atomName = "O") { | ||
| − | + | counter_rotate_2(idx, lcAtoms[c].xyz, targetIdx, FALSE) | |
# If not fixed, exit fail | # If not fixed, exit fail | ||
| Line 421: | Line 415: | ||
# Rotate rotor set to move target atom to its proper place | # Rotate rotor set to move target atom to its proper place | ||
| − | function | + | function tug_track_idx(targetIdx, targetPt, nWard, cDetect) { |
gOK = FALSE | gOK = FALSE | ||
var pt = targetPt | var pt = targetPt | ||
| Line 478: | Line 472: | ||
if (nWard) { | if (nWard) { | ||
if ({atomIndex=i2}.atomName="CA") { | if ({atomIndex=i2}.atomName="CA") { | ||
| − | psi = angle({atomIndex=@{ | + | psi = angle({atomIndex=@{get_cward_bb_idx(i1, gChain)}}, {atomIndex=i1}, |
{atomIndex=i2}, {atomIndex=i3}) + dt | {atomIndex=i2}, {atomIndex=i3}) + dt | ||
} | } | ||
else { | else { | ||
phi = angle({atomIndex=i1}, {atomIndex=i2}, | phi = angle({atomIndex=i1}, {atomIndex=i2}, | ||
| − | {atomIndex=i3}, {atomIndex=@{ | + | {atomIndex=i3}, {atomIndex=@{get_nward_bb_idx(i3, gChain)}}) + dt |
} | } | ||
if ({atomIndex=i2}.atomno > {atomIndex=targetIdx}.atomno) { | if ({atomIndex=i2}.atomno > {atomIndex=targetIdx}.atomno) { | ||
movePt = TRUE | movePt = TRUE | ||
| − | + | select_nward_idx(i3, get_cward_bb_idx(targetIdx, gChain)) | |
{atomIndex=targetIdx}.selected = TRUE | {atomIndex=targetIdx}.selected = TRUE | ||
} | } | ||
else { | else { | ||
| − | + | select_cward_idx(i2, targetIdx) | |
} | } | ||
} | } | ||
else { | else { | ||
if (({atomIndex=i2}.atomName="CA")) { | if (({atomIndex=i2}.atomName="CA")) { | ||
| − | phi = angle({atomIndex=@{ | + | phi = angle({atomIndex=@{get_nward_bb_idx(i1, gChain)}}, {atomIndex=i1}, |
{atomIndex=i2}, {atomIndex=i3}) + dt | {atomIndex=i2}, {atomIndex=i3}) + dt | ||
} | } | ||
else { | else { | ||
psi = angle({atomIndex=i2}, {atomIndex=i3}, | psi = angle({atomIndex=i2}, {atomIndex=i3}, | ||
| − | {atomIndex=i4}, {atomIndex=@{ | + | {atomIndex=i4}, {atomIndex=@{get_cward_bb_idx(i4, gChain)}}) + dt |
} | } | ||
if ({atomIndex=i2}.atomno < {atomIndex=targetIdx}.atomno) { | if ({atomIndex=i2}.atomno < {atomIndex=targetIdx}.atomno) { | ||
movePt = TRUE | movePt = TRUE | ||
| − | + | select_cward_idx(i3, get_nward_bb_idx(targetIdx, gChain)) | |
{atomIndex=targetIdx}.selected = TRUE | {atomIndex=targetIdx}.selected = TRUE | ||
} | } | ||
else { | else { | ||
| − | + | select_nward_idx(i2, targetIdx) | |
} | } | ||
} | } | ||
| Line 543: | Line 537: | ||
dt /= 2 | dt /= 2 | ||
} | } | ||
| − | + | handle_collisions_2( targetIdx) | |
if (not gOk2) { | if (not gOk2) { | ||
wasCollision = TRUE | wasCollision = TRUE | ||
| Line 590: | Line 584: | ||
# Counter rotate bonds on either side of a BB O | # Counter rotate bonds on either side of a BB O | ||
| − | function | + | function do_counter_rotate(caPhiIdx, nIdx, cIdx, oIdx, caPsiIdx, dir, nWard) { |
# Rotate psi | # Rotate psi | ||
| Line 605: | Line 599: | ||
} | } | ||
| − | function | + | function counter_rotate(oIdx, dir, nWard) { |
var iChain = {atomIndex=oIdx}.chain | var iChain = {atomIndex=oIdx}.chain | ||
var selsave = {selected} | var selsave = {selected} | ||
| − | var cIdx = | + | var cIdx = get_sc_bb_idx(oIdx, iChain) |
| − | var nIdx = | + | var nIdx = get_cward_bb_idx(cIdx, iChain) |
| − | var caPhiIdx = | + | var caPhiIdx = get_cward_bb_idx(nIdx, iChain) |
| − | var caPsiIdx = | + | var caPsiIdx = get_nward_bb_idx(cIdx, iChain) |
if (nWard) { | if (nWard) { | ||
nNo = {chain=iChain}.atomno.min | nNo = {chain=iChain}.atomno.min | ||
| − | + | select_nward_idx(caPsiIdx, {(atomno=nNo) and (chain=iChain)}.atomIndex) | |
} | } | ||
else { | else { | ||
cNo = {chain=iChain}.atomno.max | cNo = {chain=iChain}.atomno.max | ||
| − | + | select_cward_idx(caPhiIdx, {(atomno=cNo) and (chain=iChain)}.atomIndex) | |
} | } | ||
# Counter-rotate | # Counter-rotate | ||
| − | + | do_counter_rotate(caPhiIdx, nIdx, cIdx, oIdx, caPsiIdx, dir, not nWard) | |
select selsave | select selsave | ||
} | } | ||
| − | function | + | function counter_rotate_2(oIdx, toPt, terminalIdx, oDrag) { |
var iChain = {atomIndex=oIdx}.chain | var iChain = {atomIndex=oIdx}.chain | ||
var selsave = {selected} | var selsave = {selected} | ||
var gOk2 = TRUE | var gOk2 = TRUE | ||
| − | var cIdx = | + | var cIdx = get_sc_bb_idx(oIdx, iChain) |
| − | var nIdx = | + | var nIdx = get_cward_bb_idx(cIdx, iChain) |
| − | var caPhiIdx = | + | var caPhiIdx = get_cward_bb_idx(nIdx, iChain) |
| − | var caPsiIdx = | + | var caPsiIdx = get_nward_bb_idx(cIdx, iChain) |
var nTward = ({atomIndex=oIdx}.atomno < {atomIndex=terminalIdx}.atomno) | var nTward = ({atomIndex=oIdx}.atomno < {atomIndex=terminalIdx}.atomno) | ||
if (nTward) { | if (nTward) { | ||
| − | + | select_cward_idx(cIdx, terminalIdx) | |
} | } | ||
else { | else { | ||
| − | + | select_nward_idx(nIdx, terminalIdx) | |
} | } | ||
| Line 655: | Line 649: | ||
# Counter-rotate | # Counter-rotate | ||
| − | + | do_counter_rotate(caPhiIdx, nIdx, cIdx, oIdx, caPsiIdx, dir, nTward) | |
var newang = angle(toPt, {atomIndex=oIdx}, {atomIndex=cIdx}) | var newang = angle(toPt, {atomIndex=oIdx}, {atomIndex=cIdx}) | ||
# If wrong direction once, undo and reverse | # If wrong direction once, undo and reverse | ||
if (newang > ang) { | if (newang > ang) { | ||
| − | + | do_counter_rotate(caPhiIDx, nIdx, cIdx, oIdx, caPsiIdx, -dir, nTward) | |
# If first time, continue in opposite direction | # If first time, continue in opposite direction | ||
| Line 685: | Line 679: | ||
# Repair proline | # Repair proline | ||
| − | function | + | function repair_proline(BBidx) { |
| − | var cbidx = | + | var cbidx = get_cb_idx(BBidx) |
var cbno = {atomIndex=cbidx}.atomno | var cbno = {atomIndex=cbidx}.atomno | ||
var cgidx = {(atomno=@{cbno+1}) and (chain=gChain)}.atomIndex | var cgidx = {(atomno=@{cbno+1}) and (chain=gChain)}.atomIndex | ||
| Line 694: | Line 688: | ||
select {atomIndex=cbidx} | select {atomIndex=cbidx} | ||
| − | + | set_angle_idx(nidx, caidx, cbidx, 109.5) | |
select {atomIndex=cdidx} | select {atomIndex=cdidx} | ||
| − | + | set_distance_idx(nidx, cdidx, 1.47) | |
| − | + | set_angle_idx(caidx, nidx, cdidx, 102.7) | |
| − | + | set_dihedral_idx(cbidx, caidx, nidx, cdidx, 16.2) | |
select {atomIndex=cgidx} | select {atomIndex=cgidx} | ||
| − | + | set_distance_idx(cdidx, cgidx, 1.51) | |
| − | + | set_angle_idx(nidx, cdidx, cgidx, 106.4) | |
| − | + | set_dihedral_idx(caidx, nidx, cdidx, cgidx, 16.2) | |
} | } | ||
# Repair side chain | # Repair side chain | ||
| − | function | + | function repair_sc(targetIdx, nWard) { |
| − | var idx = (nWard ? | + | var idx = (nWard ? get_cward_bb_idx(targetIdx, gChain) : get_nward_bb_idx(targetIdx, gChain)) |
if (({atomIndex=targetIdx}.atomName == "CA") | if (({atomIndex=targetIdx}.atomName == "CA") | ||
and ({atomIndex=targetIdx}.group != "GLY")) { | and ({atomIndex=targetIdx}.group != "GLY")) { | ||
| − | var cbidx = | + | var cbidx = get_cb_idx(targetIdx) |
select none | select none | ||
| − | + | select_add_sc(cbidx) | |
| − | + | set_angle_idx(idx, targetIdx, cbidx, 110.0) | |
| − | + | set_distance_idx(targetIdx, cbidx, 1.5) | |
if ({atomIndex=targetIdx}.group != "PRO") { | if ({atomIndex=targetIdx}.group != "PRO") { | ||
var colliders = (within(kCtolerance, FALSE, {selected}) | var colliders = (within(kCtolerance, FALSE, {selected}) | ||
| Line 724: | Line 718: | ||
if (colliders.size > 0) { | if (colliders.size > 0) { | ||
if ({atomIndex=targetIdx}.group != "ALA") { | if ({atomIndex=targetIdx}.group != "ALA") { | ||
| − | + | fix_sc_collision_2(cbidx) | |
} | } | ||
} | } | ||
| Line 732: | Line 726: | ||
} | } | ||
else { | else { | ||
| − | + | set_dihedral_idx(get_nward_bb_idx(idx, gChain), idx, targetIdx, cbidx, 174.2) | |
} | } | ||
} | } | ||
| Line 738: | Line 732: | ||
else if ({atomIndex=targetIdx}.atomName == "C") { | else if ({atomIndex=targetIdx}.atomName == "C") { | ||
| − | var oidx = | + | var oidx = get_o_idx(targetIdx) |
select {atomIndex=oidx} | select {atomIndex=oidx} | ||
| − | + | set_angle_idx(idx, targetIdx, oidx, 120.0) | |
| − | + | set_distance_idx(targetIdx, oidx, 1.21) | |
if (nWard) { | if (nWard) { | ||
| − | + | set_dihedral_idx(get_cward_bb_idx(idx, gChain), idx, targetIdx, oidx, 0.0) | |
} | } | ||
if ({atomIndex=idx}.group == "PRO") { | if ({atomIndex=idx}.group == "PRO") { | ||
| − | + | repair_proline(idx) | |
var dNo = {atomIndex=targetIdx}.atomno + 4 | var dNo = {atomIndex=targetIdx}.atomno + 4 | ||
var dIdx = {(atomno=dNO) and (chain=gChain)}.atomIndex | var dIdx = {(atomno=dNO) and (chain=gChain)}.atomIndex | ||
| Line 754: | Line 748: | ||
for (var i = 1; i <= colliders.size; i++) { | for (var i = 1; i <= colliders.size; i++) { | ||
if (colliders[i].atomName == "O") { | if (colliders[i].atomName == "O") { | ||
| − | + | counter_rotate_2(colliders[i].atomIndex, | |
{atomIndex=dIdx}.xyz, targetIdx, FALSE) | {atomIndex=dIdx}.xyz, targetIdx, FALSE) | ||
} | } | ||
| Line 763: | Line 757: | ||
# Rebuild Cward rotors set | # Rebuild Cward rotors set | ||
| − | function | + | function tug_track_c() { |
# For all bb atoms cWard of cargo | # For all bb atoms cWard of cargo | ||
| Line 775: | Line 769: | ||
# Step to next atom | # Step to next atom | ||
| − | targetIdx = | + | targetIdx = get_cward_bb_idx(targetIdx, gChain) |
# No collision with cargo allowed after two atoms placed | # No collision with cargo allowed after two atoms placed | ||
| Line 784: | Line 778: | ||
# Compute targets desired coords | # Compute targets desired coords | ||
| − | var c1idx = | + | var c1idx = get_cward_bb_idx(targetIdx, gChain) |
| − | var n1idx = | + | var n1idx = get_nward_bb_idx(targetIdx, gChain ) |
| − | var n2idx = | + | var n2idx = get_nward_bb_idx(n1Idx, gChain) |
| − | var n3idx = | + | var n3idx = get_nward_bb_idx(n2Idx, gChain) |
var pt = {0 0 0} | var pt = {0 0 0} | ||
if ({atomIndex=targetIdx}.atomName == "N") { | if ({atomIndex=targetIdx}.atomName == "N") { | ||
| − | var oidx = | + | var oidx = get_o_idx(n1idx) |
select {atomIndex=oidx} | select {atomIndex=oidx} | ||
# Desired target location is trigonal O | # Desired target location is trigonal O | ||
| − | + | set_distance_idx(n1idx, oidx, 1.5) | |
| − | pt = | + | pt = get_trigonal_idx(n2idx, n1idx, oidx, 1.37) |
| − | + | set_distance_idx(n1idx, oidx, 1.21) | |
} | } | ||
else if (({atomIndex=targetIdx}.atomName == "C") | else if (({atomIndex=targetIdx}.atomName == "C") | ||
| Line 802: | Line 796: | ||
# Desired target location is tetragonal CB | # Desired target location is tetragonal CB | ||
| − | var cbidx = | + | var cbidx = get_cb_idx(n1idx) |
| − | pt = | + | pt = get_tet_idx(n2idx, n1idx, cbidx, 1.5) |
} | } | ||
else { # CA (or GLY C) | else { # CA (or GLY C) | ||
| Line 812: | Line 806: | ||
# Set target atom at desired distance and angle | # Set target atom at desired distance and angle | ||
select {atomIndex=targetIdx} | select {atomIndex=targetIdx} | ||
| − | + | set_distance_idx(n1idx, targetIdx, 1.5) | |
| − | + | set_angle_idx(n2idx, n1idx, targetIdx, 120.0) | |
if ({atomIndex=targetIdx}.atomName == "CA") { | if ({atomIndex=targetIdx}.atomName == "CA") { | ||
| − | + | set_dihedral_idx(n3idx, n2idx, n1idx, targetIdx, 180) | |
} | } | ||
| Line 832: | Line 826: | ||
# Rotate on cWard rotor set to move it there | # Rotate on cWard rotor set to move it there | ||
| − | + | tug_track_idx(targetIdx, pt, FALSE, FALSE) | |
xcount++ | xcount++ | ||
} | } | ||
| Line 845: | Line 839: | ||
# Adust any side atoms | # Adust any side atoms | ||
| − | + | repair_sc(targetIdx, FALSE) | |
} | } | ||
| Line 861: | Line 855: | ||
# Rebuild Nward rotors set | # Rebuild Nward rotors set | ||
| − | function | + | function tug_track_n() { |
gOK = TRUE | gOK = TRUE | ||
| Line 875: | Line 869: | ||
# Step to next atom | # Step to next atom | ||
| − | targetIdx = | + | targetIdx = get_nward_bb_idx(targetIdx, gChain) |
# No collision with cargo allowed after two atoms placed | # No collision with cargo allowed after two atoms placed | ||
| Line 884: | Line 878: | ||
# Compute targets desired coords | # Compute targets desired coords | ||
| − | var n1idx = | + | var n1idx = get_nward_bb_idx(targetIdx, gChain) |
| − | var c1idx = | + | var c1idx = get_cward_bb_idx(targetIdx, gChain) |
| − | var c2idx = | + | var c2idx = get_cward_bb_idx(c1idx, gChain) |
| − | var c3idx = | + | var c3idx = get_cward_bb_idx(c2idx, gChain) |
var pt = {0 0 0} | var pt = {0 0 0} | ||
if ({atomIndex=targetIdx}.atomName == "CA") { | if ({atomIndex=targetIdx}.atomName == "CA") { | ||
# Desired target location is trigonal O | # Desired target location is trigonal O | ||
| − | var oidx = | + | var oidx = get_o_idx(c1idx) |
select {atomIndex=oidx} | select {atomIndex=oidx} | ||
| − | + | set_distance_idx(c1idx, oidx, 1.39) | |
| − | pt = | + | pt = get_trigonal_idx(c2idx, c1idx, oidx, 1.41) |
| − | + | set_distance_idx(c1idx, oidx, 1.21) | |
} | } | ||
else if (({atomIndex=targetIdx}.atomName == "N") | else if (({atomIndex=targetIdx}.atomName == "N") | ||
| Line 902: | Line 896: | ||
# Desired target location is r-tetragonal CB | # Desired target location is r-tetragonal CB | ||
| − | var cbidx = | + | var cbidx = get_cb_idx(c1idx) |
| − | pt = | + | pt = get_tet_idx(cbidx, c1idx, c2idx, 1.5) |
} | } | ||
else { # C | else { # C | ||
| Line 912: | Line 906: | ||
# Set target atom at desired distance and angle | # Set target atom at desired distance and angle | ||
select {atomIndex=targetIdx} | select {atomIndex=targetIdx} | ||
| − | + | set_distance_idx(c1idx, targetIdx, 1.37) | |
| − | + | set_angle_idx(c2idx, c1idx, targetIdx, 110.0) | |
if ({atomIndex=targetIdx}.group == "PRO") { | if ({atomIndex=targetIdx}.group == "PRO") { | ||
| − | + | set_dihedral_idx(c3idx, c2idx, c1idx, targetIdx, -57.0) | |
} | } | ||
| Line 933: | Line 927: | ||
# Rotate on nWard rotor set to move it there | # Rotate on nWard rotor set to move it there | ||
| − | + | tug_track_idx(targetIdx, pt, TRUE, FALSE) | |
xcount++ | xcount++ | ||
} | } | ||
| Line 946: | Line 940: | ||
# Adust any side atoms | # Adust any side atoms | ||
| − | + | repair_sc(targetIdx, TRUE) | |
} | } | ||
| Line 963: | Line 957: | ||
# gPlicoRecord is maintained by the macro pilcoRecord | # gPlicoRecord is maintained by the macro pilcoRecord | ||
| − | function | + | function plico_record(s) { |
var g = format("show file \"%s\"", gPlicoRecord) | var g = format("show file \"%s\"", gPlicoRecord) | ||
var ls = script(g) | var ls = script(g) | ||
| Line 974: | Line 968: | ||
# gPlicoRecord is maintained by the macro pilcoRecord | # gPlicoRecord is maintained by the macro pilcoRecord | ||
| − | function | + | function translate_selected_record(pt) { |
if (gPlicoRecord != "") { | if (gPlicoRecord != "") { | ||
| − | + | plico_record(format("select %s;translateSelected %s;", {selected}, pt)) | |
} | } | ||
translateSelected @pt | translateSelected @pt | ||
| Line 982: | Line 976: | ||
# gPlicoRecord is maintained by the macro pilcoRecord | # gPlicoRecord is maintained by the macro pilcoRecord | ||
| − | function | + | function rotate_selected_record(pivotIdx, axis, a) { |
if (gPlicoRecord != "") { | if (gPlicoRecord != "") { | ||
| − | + | plico_record(format("select %s;", {selected})) | |
| − | + | plico_record(format("rotateSelected {atomIndex=%d} @%s @%s;", | |
pivotIdx, axis, a)) | pivotIdx, axis, a)) | ||
} | } | ||
| Line 991: | Line 985: | ||
} | } | ||
| − | function | + | function collect_sc_rotors(no, iChain) { |
var scBondIdxs = array() | var scBondIdxs = array() | ||
for (var iNo = no; iNo >= 0; iNo--) { | for (var iNo = no; iNo >= 0; iNo--) { | ||
| Line 1,041: | Line 1,035: | ||
# Drag Side Chain | # Drag Side Chain | ||
| − | function | + | function drag_sc() { |
var iNo = {atomIndex=gSCidx}.atomno | var iNo = {atomIndex=gSCidx}.atomno | ||
| Line 1,048: | Line 1,042: | ||
if ({atomIndex=gSCidx}.group != "PRO") { | if ({atomIndex=gSCidx}.group != "PRO") { | ||
| − | var scBondIdxs = | + | var scBondIdxs = collect_sc_rotors( iNo, iChain) |
var numChi = scBondIdxs.size / 4 | var numChi = scBondIdxs.size / 4 | ||
var dist = distance({atomIndex=gSCidx}.xyz, gSCpt) | var dist = distance({atomIndex=gSCidx}.xyz, gSCpt) | ||
| Line 1,054: | Line 1,048: | ||
var scSet = ({}) | var scSet = ({}) | ||
if (gSCcheck) { | if (gSCcheck) { | ||
| − | scSet = | + | scSet = get_sc_set(gSCidx, iChain) |
} | } | ||
| Line 1,069: | Line 1,063: | ||
for (var j = 0; j < 6; j++) { | for (var j = 0; j < 6; j++) { | ||
rot += 60*j | rot += 60*j | ||
| − | + | select_add_sc(scBondIdxs[1+(4*i)]) | |
| − | + | set_dihedral_idx(scBondIdxs[4+(4*i)], scBondIdxs[3+(4*i)], | |
scBondIdxs[2+(4*i)], scBondIdxs[1+(4*i)], rot) | scBondIdxs[2+(4*i)], scBondIdxs[1+(4*i)], rot) | ||
var newDist = distance({atomIndex=gSCidx}.xyz, gSCpt) | var newDist = distance({atomIndex=gSCidx}.xyz, gSCpt) | ||
| Line 1,096: | Line 1,090: | ||
# Now set the best | # Now set the best | ||
for (var i = 0; i < numChi; i++) { | for (var i = 0; i < numChi; i++) { | ||
| − | + | select_add_sc(scBondIdxs[1+(4*i)]) | |
| − | + | set_dihedral_idx(scBondIdxs[4+(4*i)], scBondIdxs[3+(4*i)], | |
scBondIdxs[2+(4*i)], scBondIdxs[1+(4*i)], dh[i+1]) | scBondIdxs[2+(4*i)], scBondIdxs[1+(4*i)], dh[i+1]) | ||
} | } | ||
| Line 1,110: | Line 1,104: | ||
if (angle({atomIndex=ica}, {atomIndex=in}, | if (angle({atomIndex=ica}, {atomIndex=in}, | ||
{atomIndex=icd}, {atomIndex=gSCidx}) < -10.0) { | {atomIndex=icd}, {atomIndex=gSCidx}) < -10.0) { | ||
| − | + | set_dihedral_idx(ica, in, icd, gSCidx, 8.7) | |
| − | + | set_angle_idx(in, icd, gSCidx, 110.0) | |
| − | + | set_distance_idx(icd, gSCidx, 1.5) | |
} | } | ||
else { | else { | ||
| − | + | set_dihedral_idx(ica, in, icd, gSCidx, -29.5) | |
| − | + | set_angle_idx(in, icd, gSCidx, 108.8) | |
| − | + | set_distance_idx(icd, gSCidx, 1.5) | |
} | } | ||
} | } | ||
| Line 1,126: | Line 1,120: | ||
# Fix side chain collisions | # Fix side chain collisions | ||
| − | function | + | function fix_sc_collision_2(idx) { |
gOk2 = FALSE | gOk2 = FALSE | ||
var iNo = {atomIndex=idx}.atomno | var iNo = {atomIndex=idx}.atomno | ||
| Line 1,146: | Line 1,140: | ||
var cbidx = {(atomno=iBno) and (chain=iChain)}.atomIndex | var cbidx = {(atomno=iBno) and (chain=iChain)}.atomIndex | ||
| − | var scBondIdxs = | + | var scBondIdxs = collect_sc_rotors( iNo, iChain) |
var numChi = scBondIdxs.size / 4 | var numChi = scBondIdxs.size / 4 | ||
| Line 1,154: | Line 1,148: | ||
for (var j = 0; j < 6; j++) { | for (var j = 0; j < 6; j++) { | ||
rot += 60 | rot += 60 | ||
| − | + | select_add_sc(scBondIdxs[1+(4*i)]) | |
| − | + | set_dihedral_idx(scBondIdxs[1+(4*i)], scBondIdxs[2+(4*i)], | |
scBondIdxs[3+(4*i)], scBondIdxs[4+(4*i)], rot) | scBondIdxs[3+(4*i)], scBondIdxs[4+(4*i)], rot) | ||
| Line 1,179: | Line 1,173: | ||
} | } | ||
| − | function | + | function is_moveable_sc(aIdx) { |
var ret = (({atomIndex=aIdx}.group != "PRO") | var ret = (({atomIndex=aIdx}.group != "PRO") | ||
| Line 1,196: | Line 1,190: | ||
} | } | ||
| − | function | + | function is_rotor_avail(i1idx, i2idx) { |
var ret = TRUE | var ret = TRUE | ||
if (i1idx > i2idx) { | if (i1idx > i2idx) { | ||
| Line 1,214: | Line 1,208: | ||
} | } | ||
| − | function | + | function collect_bb_rotors(nWard) { |
var anchorNo = (nWard | var anchorNo = (nWard | ||
? ((gNanchorIdx >= 0) ? {atomIndex=gNanchorIdx}.atomno : gMinNo) | ? ((gNanchorIdx >= 0) ? {atomIndex=gNanchorIdx}.atomno : gMinNo) | ||
| Line 1,227: | Line 1,221: | ||
for (var iNo = cargoNo; iNo <= anchorNo; iNo++) { | for (var iNo = cargoNo; iNo <= anchorNo; iNo++) { | ||
if ({(atomno=iNo) and (chain=gChain)}.atomName == "CA") { | if ({(atomno=iNo) and (chain=gChain)}.atomName == "CA") { | ||
| − | if ( | + | if (is_rotor_avail(iNo)) { |
if (({(atomno=iNo) and (chain=gChain)}.group != "PRO") and (iNo > cargoNo)) { # phi | if (({(atomno=iNo) and (chain=gChain)}.group != "PRO") and (iNo > cargoNo)) { # phi | ||
| − | rotors += [{(atomno=@{ | + | rotors += [{(atomno=@{get_cm_no(iNo-1)}) and (chain=gChain)}.atomIndex, |
{(atomno=@{iNo-1}) and (chain=gChain)}.atomIndex] | {(atomno=@{iNo-1}) and (chain=gChain)}.atomIndex] | ||
rotors += [{(atomno=@{iNo}) and (chain=gChain)}.atomIndex, | rotors += [{(atomno=@{iNo}) and (chain=gChain)}.atomIndex, | ||
| Line 1,238: | Line 1,232: | ||
{(atomno=@{iNo}) and (chain=gChain)}.atomIndex] | {(atomno=@{iNo}) and (chain=gChain)}.atomIndex] | ||
rotors += [{(atomno=@{iNo+1}) and (chain=gChain)}.atomIndex, | rotors += [{(atomno=@{iNo+1}) and (chain=gChain)}.atomIndex, | ||
| − | {(atomno=@{ | + | {(atomno=@{get_np_no(iNo+2)}) and (chain=gChain)}.atomIndex] |
} | } | ||
} | } | ||
| Line 1,248: | Line 1,242: | ||
for (var iNo = cargoNo; iNo >= anchorNo; iNo--) { | for (var iNo = cargoNo; iNo >= anchorNo; iNo--) { | ||
if ({(atomno=iNo) and (chain=gChain)}.atomName == "CA") { | if ({(atomno=iNo) and (chain=gChain)}.atomName == "CA") { | ||
| − | if ( | + | if (is_rotor_avail(iNo)) { |
if ((iNo != (anchorNo-1)) and (iNo < cargoNo)) { # psi | if ((iNo != (anchorNo-1)) and (iNo < cargoNo)) { # psi | ||
| − | rotors += [{(atomno=@{ | + | rotors += [{(atomno=@{get_np_no(iNo+2)}) and (chain=gChain)}.atomIndex, |
{(atomno=@{iNo+1}) and (chain=gChain)}.atomIndex] | {(atomno=@{iNo+1}) and (chain=gChain)}.atomIndex] | ||
rotors += [{(atomno=@{iNo}) and (chain=gChain)}.atomIndex, | rotors += [{(atomno=@{iNo}) and (chain=gChain)}.atomIndex, | ||
| Line 1,259: | Line 1,253: | ||
{(atomno=@{iNo}) and (chain=gChain)}.atomIndex] | {(atomno=@{iNo}) and (chain=gChain)}.atomIndex] | ||
rotors += [{(atomno=@{iNo-1}) and (chain=gChain)}.atomIndex, | rotors += [{(atomno=@{iNo-1}) and (chain=gChain)}.atomIndex, | ||
| − | {(atomno=@{ | + | {(atomno=@{get_cm_no(iNo-1)}) and (chain=gChain)}.atomIndex] |
} | } | ||
} | } | ||
| Line 1,274: | Line 1,268: | ||
} | } | ||
| − | function | + | function collect_rotors() { |
| − | + | collect_bb_rotors(FALSE) | |
| − | + | collect_bb_rotors(TRUE) | |
} | } | ||
| − | function | + | function tug_sc(pt) { |
# If destination atom defined | # If destination atom defined | ||
| Line 1,295: | Line 1,289: | ||
} | } | ||
| − | function | + | function set_colors() { |
select all | select all | ||
color {selected} @gScheme | color {selected} @gScheme | ||
| Line 1,309: | Line 1,303: | ||
} | } | ||
| − | function | + | function clear_atom_idxs() { |
gCcargoIdx = -1 | gCcargoIdx = -1 | ||
gNcargoIdx = -1 | gNcargoIdx = -1 | ||
| Line 1,322: | Line 1,316: | ||
} | } | ||
| − | function | + | function timed_out (s) { |
timeout ID"tug" OFF | timeout ID"tug" OFF | ||
p = prompt(format("%s - Undo?", s), "Yes|No", TRUE) | p = prompt(format("%s - Undo?", s), "Yes|No", TRUE) | ||
| Line 1,336: | Line 1,330: | ||
} | } | ||
| − | function | + | function record_drag() { |
var ls = format("select %s;", {selected}) | var ls = format("select %s;", {selected}) | ||
ls += format("gCanchorIdx = %d;", gCanchorIdx) | ls += format("gCanchorIdx = %d;", gCanchorIdx) | ||
| Line 1,357: | Line 1,351: | ||
ls += format("gSCcircle = %d;", gSCcircle) | ls += format("gSCcircle = %d;", gSCcircle) | ||
ls += format("gSCpt = %s;", gSCpt) | ls += format("gSCpt = %s;", gSCpt) | ||
| − | ls += " | + | ls += "collect_rotors();" |
| − | ls += " | + | ls += "tug_drag_done_mb();" |
| − | + | plico_record(ls) | |
} | } | ||
# Pick call-back for freeze | # Pick call-back for freeze | ||
| − | function | + | function tug_pick_cb() { |
if (_pickInfo[3][6] == "bond") { | if (_pickInfo[3][6] == "bond") { | ||
| Line 1,405: | Line 1,399: | ||
} | } | ||
| − | # Bound to LEFT-UP by | + | # Bound to LEFT-UP by tug_enable_drag |
| − | function | + | function tug_drag_done_mb() { |
if (not gBusy) { | if (not gBusy) { | ||
if (gPlicoRecord != "") { | if (gPlicoRecord != "") { | ||
| − | + | record_drag() | |
} | } | ||
| Line 1,419: | Line 1,413: | ||
# If side chain mode | # If side chain mode | ||
if (gSCidx >= 0) { | if (gSCidx >= 0) { | ||
| − | + | drag_sc() | |
} | } | ||
| Line 1,425: | Line 1,419: | ||
else if (not gTow) { | else if (not gTow) { | ||
gOK = TRUE | gOK = TRUE | ||
| − | timeout ID"tug" 20.0 " | + | timeout ID"tug" 20.0 "timed_out(\"Tug timed out\")" |
if ((gCrotors.size < gNrotors.size) or (gNanchorIdx < 0)) { | if ((gCrotors.size < gNrotors.size) or (gNanchorIdx < 0)) { | ||
if (gCrotors.size > 4) { | if (gCrotors.size > 4) { | ||
| − | + | tug_track_c() | |
} | } | ||
if (gOK and (gNrotors.size > 4)) { | if (gOK and (gNrotors.size > 4)) { | ||
| − | + | tug_track_n() | |
} | } | ||
} | } | ||
else { | else { | ||
if (gNrotors.size > 4) { | if (gNrotors.size > 4) { | ||
| − | + | tug_track_n() | |
} | } | ||
if (gOK and (gCrotors.size > 4)) { | if (gOK and (gCrotors.size > 4)) { | ||
| − | + | tug_track_c() | |
} | } | ||
} | } | ||
| Line 1,447: | Line 1,441: | ||
if (gOK == TRUE) { | if (gOK == TRUE) { | ||
if (gCanchorIdx >= 0) { | if (gCanchorIdx >= 0) { | ||
| − | var ic = | + | var ic = get_cward_bb_idx(gCanchorIdx, gChain) |
| − | var in = | + | var in = get_nward_bb_idx(gCanchorIdx, gChain) |
if ((ic >= 0) and | if ((ic >= 0) and | ||
angle({atomIndex=ic}, {atomIndex=gCanchorIdx}, {atomIndex=in}) | angle({atomIndex=ic}, {atomIndex=gCanchorIdx}, {atomIndex=in}) | ||
| Line 1,456: | Line 1,450: | ||
} | } | ||
if (gNanchorIdx >= 0) { | if (gNanchorIdx >= 0) { | ||
| − | var ic = | + | var ic = get_cward_bb_idx(gNanchorIdx, gChain) |
| − | var in = | + | var in = get_nward_bb_idx(gNanchorIdx, gChain) |
if ((in >= 0) and | if ((in >= 0) and | ||
angle({atomIndex=ic}, {atomIndex=gNanchorIdx}, {atomIndex=in}) | angle({atomIndex=ic}, {atomIndex=gNanchorIdx}, {atomIndex=in}) | ||
| Line 1,468: | Line 1,462: | ||
# If too far | # If too far | ||
if (not gOK) { | if (not gOK) { | ||
| − | + | timed_out("TUG TOO FAR!") | |
} | } | ||
| Line 1,482: | Line 1,476: | ||
var ihc = 0 | var ihc = 0 | ||
for (ihc = 0; ihc < 10; ihc++) { | for (ihc = 0; ihc < 10; ihc++) { | ||
| − | + | handle_collisions_2( idx) | |
| − | if ( | + | if (count_collisions(({})).size == 0) { |
break | break | ||
} | } | ||
} | } | ||
if (ihc == 10) { | if (ihc == 10) { | ||
| − | + | timed_out("Unable to handle all collisions!") | |
} | } | ||
} | } | ||
| Line 1,499: | Line 1,493: | ||
} | } | ||
| − | # Bound to ALT-SHIFT-LEFT-DRAG by | + | # Bound to ALT-SHIFT-LEFT-DRAG by tug_enable_drag |
| − | function | + | function tug_drag_2_mb() { |
| − | + | tug_drag_mb(TRUE) | |
} | } | ||
| − | # Bound to ALT-LEFT-DRAG by | + | # Bound to ALT-LEFT-DRAG by tug_enable_drag |
| − | function | + | function tug_drag_mb(alt) { |
if (not gBusy) { | if (not gBusy) { | ||
gBusy = TRUE | gBusy = TRUE | ||
| Line 1,521: | Line 1,515: | ||
? ((dx < 0) ? 10 : -10) | ? ((dx < 0) ? 10 : -10) | ||
: ((dy < 0) ? 1 : -1)) | : ((dy < 0) ? 1 : -1)) | ||
| − | + | counter_rotate(gSCidx, dir, not alt) | |
} | } | ||
else { | else { | ||
gSCcheck = not alt | gSCcheck = not alt | ||
| − | + | tug_sc(pt) | |
} | } | ||
} | } | ||
| Line 1,568: | Line 1,562: | ||
? ((dx < 0) ? 2 : -2) | ? ((dx < 0) ? 2 : -2) | ||
: ((dy < 0) ? 2 : -2)) | : ((dy < 0) ? 2 : -2)) | ||
| − | + | rotate_selected_record(g1pivotIdx, axis, dir) | |
} | } | ||
| Line 1,574: | Line 1,568: | ||
# Else translate it | # Else translate it | ||
else { | else { | ||
| − | + | translate_selected_record(pt) | |
} | } | ||
| Line 1,598: | Line 1,592: | ||
g1dynamicIdx = cNotSels[i].atomIndex | g1dynamicIdx = cNotSels[i].atomIndex | ||
color {atomIndex=g1pivotIdx} lightgreen | color {atomIndex=g1pivotIdx} lightgreen | ||
| − | + | set_distance_idx(cNotSels[i].atomIndex, | |
cSels[j].atomIndex, | cSels[j].atomIndex, | ||
kCtolerance + kDtolerance) | kCtolerance + kDtolerance) | ||
| Line 1,606: | Line 1,600: | ||
g2dynamicIdx = cNotSels[i].atomIndex | g2dynamicIdx = cNotSels[i].atomIndex | ||
color {atomIndex=g2pivotIdx} lightgreen | color {atomIndex=g2pivotIdx} lightgreen | ||
| − | + | set_distance_idx(cNotSels[i].atomIndex, | |
cSels[j].atomIndex, | cSels[j].atomIndex, | ||
kCtolerance + kDtolerance) | kCtolerance + kDtolerance) | ||
| Line 1,620: | Line 1,614: | ||
var idx = {(atomno=@{{chain=gChain}.atomno.min}) | var idx = {(atomno=@{{chain=gChain}.atomno.min}) | ||
and (chain=gChain)}.atomIndex | and (chain=gChain)}.atomIndex | ||
| − | + | handle_collisions_2( idx) | |
} | } | ||
} | } | ||
| Line 1,636: | Line 1,630: | ||
delay 1 | delay 1 | ||
if (g1pivotIdx >= 0) { | if (g1pivotIdx >= 0) { | ||
| − | + | rotate_selected_record(g1pivotIdx, axis, -a) | |
} | } | ||
else { | else { | ||
| − | + | translate_selected_record(-pt) | |
} | } | ||
background ECHO yellow | background ECHO yellow | ||
| Line 1,673: | Line 1,667: | ||
} | } | ||
| − | # Bound to ALT-LEFT-DOWN by | + | # Bound to ALT-LEFT-DOWN by tug_enable_drag |
| − | function | + | function tug_mark_mb() { |
gMouseX = _mouseX | gMouseX = _mouseX | ||
gMouseY = _mouseY | gMouseY = _mouseY | ||
| Line 1,680: | Line 1,674: | ||
} | } | ||
| − | # Called by | + | # Called by tug_cargo_mb |
| − | function | + | function tug_enable_drag() { |
gEcho = "__________TUG__________|ALT-CLICK=mark block|SHIFT-CLICK=anchors" + | gEcho = "__________TUG__________|ALT-CLICK=mark block|SHIFT-CLICK=anchors" + | ||
"|ALT-CTRL-CLICK=pivots|ALT-SHIFT-CLICK=dest atom|ALT-DRAG=move" + | "|ALT-CTRL-CLICK=pivots|ALT-SHIFT-CLICK=dest atom|ALT-DRAG=move" + | ||
| Line 1,688: | Line 1,682: | ||
# Allow atoms to be dragged | # Allow atoms to be dragged | ||
| − | bind "ALT-LEFT-DOWN" " | + | bind "ALT-LEFT-DOWN" "tug_mark_mb"; |
| − | bind "ALT-LEFT-UP" " | + | bind "ALT-LEFT-UP" "tug_drag_done_mb"; |
| − | bind "ALT-SHIFT-LEFT-DOWN" " | + | bind "ALT-SHIFT-LEFT-DOWN" "tug_mark_mb"; |
| − | bind "ALT-SHIFT-LEFT-UP" " | + | bind "ALT-SHIFT-LEFT-UP" "tug_drag_done_mb"; |
| − | bind "ALT-LEFT-DRAG" " | + | bind "ALT-LEFT-DRAG" "tug_drag_mb"; |
| − | bind "ALT-SHIFT-LEFT-DRAG" " | + | bind "ALT-SHIFT-LEFT-DRAG" "tug_drag_2_mb"; |
unbind "SHIFT-LEFT-CLICK" | unbind "SHIFT-LEFT-CLICK" | ||
bind "SHIFT-LEFT-CLICK" "_pickAtom"; | bind "SHIFT-LEFT-CLICK" "_pickAtom"; | ||
| − | bind "SHIFT-LEFT-CLICK" "+: | + | bind "SHIFT-LEFT-CLICK" "+:tug_anchor_mb"; |
bind "ALT-CTRL-LEFT-CLICK" "_pickAtom"; | bind "ALT-CTRL-LEFT-CLICK" "_pickAtom"; | ||
| − | bind "ALT-CTRL-LEFT-CLICK" "+: | + | bind "ALT-CTRL-LEFT-CLICK" "+:tug_pivot_mb"; |
bind "ALT-SHIFT-LEFT-CLICK" "_pickAtom"; | bind "ALT-SHIFT-LEFT-CLICK" "_pickAtom"; | ||
| − | bind "ALT-SHIFT-LEFT-CLICK" "+: | + | bind "ALT-SHIFT-LEFT-CLICK" "+:tug_dest_atom_mb"; |
} | } | ||
| − | # Bound to SHIFT-LEFT-CLICK by | + | # Bound to SHIFT-LEFT-CLICK by tug_cargo_mb |
| − | function | + | function tug_anchor_mb() { |
if ({atomIndex=_atomPicked}.chain == gChain) { | if ({atomIndex=_atomPicked}.chain == gChain) { | ||
| − | var aPidx = | + | var aPidx = get_sc_bb_idx( _atomPicked, gChain) |
var pno = {atomIndex=aPidx}.atomno | var pno = {atomIndex=aPidx}.atomno | ||
| Line 1,725: | Line 1,719: | ||
halo on | halo on | ||
} | } | ||
| − | + | collect_bb_rotors(FALSE) | |
} | } | ||
else if (pno < {atomIndex=gNcargoIdx}.atomno) { | else if (pno < {atomIndex=gNcargoIdx}.atomno) { | ||
| Line 1,740: | Line 1,734: | ||
halo on | halo on | ||
} | } | ||
| − | + | collect_bb_rotors(TRUE) | |
} | } | ||
else { | else { | ||
| − | + | tow_cargo_mb() | |
} | } | ||
| Line 1,753: | Line 1,747: | ||
} | } | ||
| − | # Bound to ALT-SHIFT-LEFT-CLICK by | + | # Bound to ALT-SHIFT-LEFT-CLICK by tug_cargo_mb |
| − | function | + | function tug_dest_atom_mb() { |
var aOk = TRUE | var aOk = TRUE | ||
if ({atomIndex=_atomPicked}.chain == gChain) { | if ({atomIndex=_atomPicked}.chain == gChain) { | ||
| Line 1,778: | Line 1,772: | ||
} | } | ||
| − | # Bound to CTRL-LEFT-CLICK by | + | # Bound to CTRL-LEFT-CLICK by tug_cargo_mb |
| − | function | + | function tug_pivot_mb() { |
if (g1pivotIdx == _atomPicked) { | if (g1pivotIdx == _atomPicked) { | ||
color {atomIndex=g1pivotIdx} @gScheme | color {atomIndex=g1pivotIdx} @gScheme | ||
| Line 1,814: | Line 1,808: | ||
} | } | ||
| − | # Bound to SHIFT-LEFT-CLICK by | + | # Bound to SHIFT-LEFT-CLICK by plico_tug |
| − | function | + | function tow_cargo_mb() { |
gTow = TRUE | gTow = TRUE | ||
gChain = {atomIndex=_atomPicked}.chain | gChain = {atomIndex=_atomPicked}.chain | ||
| Line 1,831: | Line 1,825: | ||
gCargoSet = {selected} | gCargoSet = {selected} | ||
gMovingSet = {selected} | gMovingSet = {selected} | ||
| − | + | set_colors() | |
# Enable dragging | # Enable dragging | ||
| − | + | tug_enable_drag() | |
select {gCargoSet} | select {gCargoSet} | ||
halo off | halo off | ||
| Line 1,841: | Line 1,835: | ||
unbind "SHIFT-LEFT-CLICK" | unbind "SHIFT-LEFT-CLICK" | ||
bind "SHIFT-LEFT-CLICK" "_pickAtom"; | bind "SHIFT-LEFT-CLICK" "_pickAtom"; | ||
| − | bind "SHIFT-LEFT-CLICK" "+: | + | bind "SHIFT-LEFT-CLICK" "+:tow_cargo_mb"; |
} | } | ||
| − | # Bound to ALT-LEFT-CLICK by | + | # Bound to ALT-LEFT-CLICK by plico_tug or called by plicotoab.toabCargoMB |
| − | function | + | function tug_cargo_mb() { |
# If O or movable side chain atom picked | # If O or movable side chain atom picked | ||
if (({atomIndex=_atomPicked}.atomName = "O") | if (({atomIndex=_atomPicked}.atomName = "O") | ||
| − | or ( | + | or (is_moveable_sc( _atomPicked))) { |
if (gSCidx >= 0) { | if (gSCidx >= 0) { | ||
draw gSCcircle DELETE | draw gSCcircle DELETE | ||
| Line 1,886: | Line 1,880: | ||
gCanchorNo = gMaxNo + 1 | gCanchorNo = gMaxNo + 1 | ||
} | } | ||
| − | var aPidx = | + | var aPidx = get_sc_bb_idx( _atomPicked, gChain) |
gSCidx = -1 | gSCidx = -1 | ||
| Line 1,900: | Line 1,894: | ||
# If nWard cargo exists, mark it as the cWard cargo | # If nWard cargo exists, mark it as the cWard cargo | ||
if (gNcargoIdx != gCcargoIdx) { | if (gNcargoIdx != gCcargoIdx) { | ||
| − | gCcargoIdx = | + | gCcargoIdx = get_cp_idx(gNcargoIdx) |
gCcargoNo = {atomIndex=gCcargoIdx}.atomno | gCcargoNo = {atomIndex=gCcargoIdx}.atomno | ||
} | } | ||
| Line 1,911: | Line 1,905: | ||
select {atomIndex=gNcargoIdx} | select {atomIndex=gNcargoIdx} | ||
halo off | halo off | ||
| − | gNcargoIdx = | + | gNcargoIdx = get_nm_idx(gCcargoIdx) |
gNcargoNo = {atomIndex=gNcargoIdx}.atomno | gNcargoNo = {atomIndex=gNcargoIdx}.atomno | ||
} | } | ||
| Line 1,928: | Line 1,922: | ||
# Set new nWard cargo and highlight it | # Set new nWard cargo and highlight it | ||
| − | gNcargoIdx = | + | gNcargoIdx = get_nm_idx(aPidx) |
gNcargoNo = {atomIndex=gNcargoIdx}.atomno | gNcargoNo = {atomIndex=gNcargoIdx}.atomno | ||
} | } | ||
| Line 1,942: | Line 1,936: | ||
# Set new cWard cargo and highlight | # Set new cWard cargo and highlight | ||
| − | gCcargoIdx = | + | gCcargoIdx = get_cp_idx(aPidx) |
gCcargoNo = {atomIndex=gCcargoIdx}.atomno | gCcargoNo = {atomIndex=gCcargoIdx}.atomno | ||
} | } | ||
| Line 1,951: | Line 1,945: | ||
# Set new cWard cargo and highlight | # Set new cWard cargo and highlight | ||
| − | gCcargoIdx = | + | gCcargoIdx = get_cp_idx(aPidx) |
gCcargoNo = {atomIndex=gCcargoIdx}.atomno | gCcargoNo = {atomIndex=gCcargoIdx}.atomno | ||
| − | gNcargoIdx = | + | gNcargoIdx = get_nm_idx(gCcargoIdx) |
gNcargoNo = {atomIndex=gNcargoIdx}.atomno | gNcargoNo = {atomIndex=gNcargoIdx}.atomno | ||
| Line 1,978: | Line 1,972: | ||
# Highlight cargo cluster | # Highlight cargo cluster | ||
| − | + | select_nward_idx(gCcargoIdx, gNcargoIdx) | |
gCargoSet = {selected} | gCargoSet = {selected} | ||
| − | + | set_colors() | |
# Collect the rotor sets | # Collect the rotor sets | ||
| − | + | collect_rotors() | |
# Get moving atoms set | # Get moving atoms set | ||
| Line 1,995: | Line 1,989: | ||
} | } | ||
else { | else { | ||
| − | + | tug_enable_drag() | |
} | } | ||
| Line 2,002: | Line 1,996: | ||
# Top level of Tug | # Top level of Tug | ||
| − | function | + | function plico_tug() { |
# Load common functions if not already | # Load common functions if not already | ||
| − | if (kCommon < | + | if (kCommon < 2) { |
script $SCRIPT_PATH$plicoCommon.spt | script $SCRIPT_PATH$plicoCommon.spt | ||
| − | if (kCommon < | + | if (kCommon < 2) { |
prompt ("A newer version of plicoCommon.SPT is required") | prompt ("A newer version of plicoCommon.SPT is required") | ||
quit | quit | ||
| Line 2,014: | Line 2,008: | ||
gPlico = "TUG" | gPlico = "TUG" | ||
| − | + | plico_prelim() | |
gBondPicking = bondPicking | gBondPicking = bondPicking | ||
set bondPicking TRUE | set bondPicking TRUE | ||
| − | set PickCallback "jmolscript: | + | set PickCallback "jmolscript:tug_pick_cb" |
gEcho = ("_________TUG_________|ALT-CLICK=mark block|SHIFT-CLICK=mark chain" + | gEcho = ("_________TUG_________|ALT-CLICK=mark block|SHIFT-CLICK=mark chain" + | ||
| Line 2,024: | Line 2,018: | ||
gCrotors = array() | gCrotors = array() | ||
gNrotors = array() | gNrotors = array() | ||
| − | + | clear_atom_idxs() | |
bind "ALT-LEFT-CLICK" "_pickAtom"; | bind "ALT-LEFT-CLICK" "_pickAtom"; | ||
| − | bind "ALT-LEFT-CLICK" "+: | + | bind "ALT-LEFT-CLICK" "+:tug_cargo_mb"; |
bind "SHIFT-LEFT-CLICK" "_pickAtom"; | bind "SHIFT-LEFT-CLICK" "_pickAtom"; | ||
| − | bind "SHIFT-LEFT-CLICK" "+: | + | bind "SHIFT-LEFT-CLICK" "+:tow_cargo_mb"; |
| − | bind "DOUBLE" " | + | bind "DOUBLE" "tug_exit"; |
} | } | ||
| − | # Bound to DOUBLE by | + | # Bound to DOUBLE by plico_tug |
| − | function | + | function tug_exit() { |
set bondPicking gBondPicking | set bondPicking gBondPicking | ||
set PickCallback NONE | set PickCallback NONE | ||
| − | + | plico_exit() | |
} | } | ||
# End of TUG.SPT</pre> | # End of TUG.SPT</pre> | ||
Revision as of 15:07, 16 May 2014
Tug allows the user to pull or push by mouse actions to move or rotate one part of a polypeptide against the rest by rotation on its psi and phi bonds with collision detection and restriction. It also allows the user to move an entire chain to nest against another chain.
Tug is a member of the Plico suite of protein folding tools described in User:Remig/plico . It may be installed and accessed as a macro with the file:
Title=PLICO Tug Script=script <path to your scripts folder>/tug.spt;plicotug
saved as plicotug.macro in your .jmol/macros directory as described in Macro.
Copy and paste the following into a text editor and save in your scripts folder as tug.spt.
# tug - Jmol script by Ron Mignery
# v1.11 beta 5/16/2014 -lc all functions
#
# Translate or rotate a stretch of a polypeptide against itself
# or against other chains by mouse actions
#
kTug = 3
gCanchorIdx = -1
gCanchorNo = -1
gPlico = "TUG"
gNanchorIdx = -1
gNanchorNo = -1
gCcargoIdx = -1
gNcargoIdx = -1
gCcargoNo = -1
gNcargoNo = -1
gDestAtomIdx = -1
g1pivotIdx = -1
g2pivotIdx = -1
gSelSaves = ({})
gCrotors = array()
gNrotors = array()
gOkCollide = ({})
gChain = ""
gMinNo = 1
gMaxNo = 9999
gCargoSet = ({})
gMovingSet = ({})
gBusy = FALSE
gSCidx = -1
gSCcircle = -1
gSCpt = {0 0 0}
gTargetPt = {0 0 0}
gNewDrag = FALSE
gEcho = ""
gZoom = ""
gRotate = ""
gTow = FALSE
g1dynamicIdx = -1
g2dynamicIdx = -1
gSCcheck = TRUE
gBondPicking = FALSE
function get_cam_no (iNo) {
while ((iNo > 0) and ({(atomno=iNo) and (chain=gChain)}.atomName != "CA")) {
iNo--
}
return iNo
}
function get_cam_idx (idx) {
var no = {atomIndex=idx and (chain=gChain)}.atomno
no = get_cam_no( no)
return ({(atomno=no) and (chain=gChain)}.atomIndex)
}
function get_cap_no (iNo) {
while ((iNo < gMaxNo) and ({(atomno=iNo) and (chain=gChain)}.atomName != "CA")) {
iNo++
}
return iNo
}
function getCApIdx (idx) {
var no = {atomIndex=idx and (chain=gChain)}.atomno
no = get_cap_no( no)
return ({(atomno=no) and (chain=gChain)}.atomIndex)
}
function get_cp_no (iNo) {
while ((iNo < gMaxNo) and ({(atomno=iNo) and (chain=gChain)}.atomName != "C")) {
iNo++
}
return iNo
}
function get_cp_idx (idx) {
var no = {atomIndex=idx and (chain=gChain)}.atomno
no = get_cp_no( no)
return ({(atomno=no) and (chain=gChain)}.atomIndex)
}
function get_cm_no (iNo) {
while ((iNo > 0) and ({(atomno=iNo) and (chain=gChain)}.atomName != "C")) {
iNo--
}
return iNo
}
function get_cm_idx (idx) {
var no = {atomIndex=idx and (chain=gChain)}.atomno
no = get_cm_no( no)
return ({(atomno=no) and (chain=gChain)}.atomIndex)
}
function get_nm_no (iNo) {
while ((iNo > 0) and ({(atomno=iNo) and (chain=gChain)}.atomName != "N")) {
iNo--
}
return iNo
}
function get_nm_idx (idx) {
var no = {atomIndex=idx and (chain=gChain)}.atomno
no = get_nm_no( no)
return ({(atomno=no) and (chain=gChain)}.atomIndex)
}
function get_np_no (iNo) {
while ((iNo < gMaxNo) and ({(atomno=iNo) and (chain=gChain)}.atomName != "N")) {
iNo++
}
return iNo
}
function get_np_idx (idx) {
var no = {atomIndex=idx}.atomno
no = get_np_no( no)
return ({(atomno=no) and (chain=gChain)}.atomIndex)
}
function get_cb_idx (BBidx) {
var no = {atomIndex=BBidx}.atomno
var i = 1
for (; i < 5; i++) {
if ({(atomno=@{no+i}) and (chain=gChain)}.atomName == "CB") {
break
}
}
return {(atomno=@{no+i}) and (chain=gChain)}.atomIndex
}
function get_o_idx (BBidx) {
var no = {atomIndex=BBidx}.atomno
var i = 1
for (; i < 4; i++) {
if ({(atomno=@{no+i}) and (chain=gChain)}.atomName == "O") {
break
}
}
return {(atomno=@{no+i}) and (chain=gChain)}.atomIndex
}
function get_nward_bb_no (iNo, iChain) {
while ((iNo >= 0) and (
({(atomno=iNo) and (chain=iChain)}.atomName != "N")
and ({(atomno=iNo) and (chain=iChain)}.atomName != "C")
and ({(atomno=iNo) and (chain=iChain)}.atomName != "CA"))) {
iNo--
}
return iNo
}
function get_nward_bb_idx (idx, iChain) {
var no = {atomIndex=idx}.atomno - 1
no = get_nward_bb_no( no, iChain)
return ((no >= 0) ? ({(atomno=no) and (chain=iChain)}.atomIndex) : -1)
}
function get_cward_bb_no (iNo, iChain) {
while ((iNo < gMaxNo) and (
({(atomno=iNo) and (chain=iChain)}.atomName != "N")
and ({(atomno=iNo) and (chain=iChain)}.atomName != "C")
and ({(atomno=iNo) and (chain=iChain)}.atomName != "CA"))) {
iNo++
}
return iNo
}
function get_cward_bb_idx (idx, iChain) {
var no = {atomIndex=idx}.atomno + 1
no = get_cward_bb_no( no, iChain)
return ((no >= 0) ? ({(atomno=no) and (chain=iChain)}.atomIndex) : -1)
}
function get_sc_set (scIdx, iChain) {
var scSet = ({})
var idx = get_sc_bb_idx(scIdx, iChain)
var iNo = {atomIndex=idx}.atomno + 3
for (var i = 1; i < 20; i++) {
idx = {(atomno=@{iNo+i}) and (chain=iChain)}.atomIndex
if (is_bb_idx(idx)) {
break
}
scSet = scSet or {atomIndex=idx}
}
return scSet
}
function get_sc_bb_idx (idx, iChain) {
var no = {atomIndex=idx}.atomno
for (; no > 0; no--) {
if ({(atomno=no) and (chain=iChain)}.atomName == "CA") {
break
}
else if ({(atomno=no) and (chain=iChain)}.atomName == "C") {
break
}
else if ({(atomno=no) and (chain=iChain)}.atomName == "N") {
break
}
else if ({(atomno=no) and (chain=iChain)}.atomName == "CB") {
no -= 3
break
}
}
return {(atomno=no) and (chain=iChain)}.atomIndex
}
function is_bb_idx(aIdx) {
var ret = FALSE
switch({atomIndex=aIdx}.atomName) {
case "N":
case "CA":
case "C":
ret = TRUE
break
}
return ret
}
function is_sc_idx(aIdx) {
var ret = FALSE
if (not is_bb_idx(aIDx)) {
ret = TRUE
switch({atomIndex=aIdx}.atomName) {
case "O":
case "CB":
ret = FALSE
break
}
}
return ret
}
function add_sc_to_select(CAno, isAdd, addOXT, iChain) {
var iNo = CAno+3
while ({(atomno=iNo) and (chain=iChain)}.resno == {(atomno=CAno) and (chain=iChain)}.resno) {
{(atomno=iNo) and (chain=iChain)}.selected = isAdd
if ({(atomno=iNo) and (chain=iChain)}.atomName == "OXT") {
{(atomno=iNo) and (chain=iChain)}.selected = addOXT
}
iNo++
}
}
function select_add_sc(fromIdx) {
var iNo = {atomIndex=fromIdx}.atomno
var iChain = {atomIndex=fromIdx}.chain
select none
while ({(atomno=iNo) and (chain=iChain)}.atomName != "N") {
{(atomno=iNo) and (chain=iChain)}.selected = TRUE
iNo++
if (iNo > {chain=iChain}.atomno.max) {
break
}
}
}
# 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)
if ({(atomno=firstno) and (chain=gChain)}.atomName == "C") { # if psi
add_sc_to_select(firstno-1, TRUE, TRUE, iChain)
{(atomno=@{firstno+1}) and (chain=iChain)}.selected = TRUE # add O
}
if ({(atomno=firstno) and (chain=iChain)}.atomName == "CA") {
add_sc_to_select(firstno, TRUE, FALSE, iChain)
}
if ({(atomno=lastno) and (chain=iChain)}.atomName == "C") { # if psi
add_sc_to_select(lastno-1, FALSE, FALSE, iChain)
}
}
# 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)
if ({(atomno=firstno) and (chain=iChain)}.atomName == "C") { # if psi
add_sc_to_select(firstno-1, FALSE, FALSE, iChain)
}
if ({(atomno=lastno) and (chain=iChain)}.atomName == "CA") {
add_sc_to_select(lastno, TRUE, FALSE, iChain)
}
if ({(atomno=lastno) and (chain=iChain)}.atomName == "C") { # if psi
add_sc_to_select(lastno-1, TRUE, TRUE, iChain)
{(atomno=@{lastno+1}) and (chain=iChain)}.selected = TRUE # add O
}
}
# Resolve collisions
function handle_collisions_2( targetIdx) {
# For all selected atoms
for (var iNo = {selected}.min.atomno; iNo <= {selected}.max.atomno; iNo++) {
var idx = {(atomno=iNo) and (chain=gchain)}.atomIndex
if ({atomindex=idx}.selected) {
# Collect local colliders
var lcAtoms = (within(kCtolerance, FALSE, {atomIndex=idx})
and not {atomIndex=idx}
and not {gOkCollide}
and not connected({atomIndex=idx}))
if (lcAtoms.size > 0) {
# Ignore kinked BB
if (is_bb_idx(idx) and angle({atomIndex=@{get_cward_bb_idx(idx, gChain)}},
{atomIndex=idx} , {atomIndex=@{get_nward_bb_idx(idx, gChain)}}) < 100) {
continue
}
# For all local colliders
for (var c = 1; c <= lcAtoms.size; c++ ) {
var cidx = lcAtoms[c].atomIndex
# If it is with water, delete it
if (lcAtoms[c].group = "HOH") {
delete {atomIndex=cidx}
}
# else if it is with side chain not proline, fix it
else if (is_sc_idx(cidx) and ({atomIndex=cidx}.group != "PRO")) {
fix_sc_collision_2(cidx)
recollect = TRUE
# If not fixed, exit fail
if (not gOk2) {
return # early exit (break n jmol bug)
}
}
# else if it is itself a side chain not proline, fix it
else if (is_sc_idx(idx) and ({atomIndex=idx}.group != "PRO")) {
fix_sc_collision_2(idx)
recollect = TRUE
# If not fixed, exit fail
if (not gOk2) {
return # early exit (break n jmol bug)
}
}
# Else if it is with O, counter-rotate
else if (lcAtoms[c].atomName = "O") {
counter_rotate_2(lcAtoms[c].atomIndex,
{atomIndex=idx}.xyz, targetIdx, FALSE)
# If not fixed, exit fail
if (not gOk2) {
return # early exit (break n jmol bug)
}
}
# Else if it is itself O, counter-rotate
else if ({atomIndex=idx}.atomName = "O") {
counter_rotate_2(idx, lcAtoms[c].xyz, targetIdx, FALSE)
# If not fixed, exit fail
if (not gOk2) {
return # early exit (break n jmol bug)
}
}
else { # Else not fixed, exit fail
gOk2 = FALSE
return # early exit (break n jmol bug)
}
} # endfor
}
}
} # endfor iNo
}
# Rotate rotor set to move target atom to its proper place
function tug_track_idx(targetIdx, targetPt, nWard, cDetect) {
gOK = FALSE
var pt = targetPt
var dist = distance(pt, {atomIndex=targetIdx}.xyz)
var rotors = (nWard ? gNrotors : gCrotors)
# For a number of passes
for (var pass1 = 0; pass1 < 20; pass1++) {
var blocked = ({})
for (var pass2 = 0; pass2 < (rotors.size/4); pass2++) {
var v1 = {atomIndex=targetIdx}.xyz - pt
# Find the most orthgonal unused rotor
var imax = 0
var smax = 0.5
for (var i = 1; i < rotors.size; i += 4) {
var i2 = rotors[i+1]
var i3 = rotors[i+2]
var i4 = rotors[i+3]
if ((i2 != targetIdx) and (i3 != targetIdx) and (i4 != targetIdx)) {
if ({blocked and {atomIndex=i2}}.count == 0) {
var v2 = {atomIndex=i3}.xyz - {atomIndex=i2}.xyz
var s = sin(abs(angle(v1, {0 0 0}, v2)))
if (s > smax) {
smax = s
imax = i
}
}
}
}
# If no more rotors, break to next full try
if (imax == 0) {
break
}
var i1 = rotors[imax+0]
var i2 = rotors[imax+1]
var i3 = rotors[imax+2]
var i4 = rotors[imax+3]
# Get dihedral of rotor with target point
var dt = angle({atomIndex=targetIdx}, {atomIndex=i2}, {atomIndex=i3}, pt)
var dh = angle({atomIndex=i1}, {atomIndex=i2}, {atomIndex=i3}, {atomIndex=i4})
if (dh == "NaN") {
dh = -50
}
var psi = dh + dt
var phi = dh + dt
# Compute resultant psi and phi
# and select from target atom to first half of rotor
var movePt = FALSE
if (nWard) {
if ({atomIndex=i2}.atomName="CA") {
psi = angle({atomIndex=@{get_cward_bb_idx(i1, gChain)}}, {atomIndex=i1},
{atomIndex=i2}, {atomIndex=i3}) + dt
}
else {
phi = angle({atomIndex=i1}, {atomIndex=i2},
{atomIndex=i3}, {atomIndex=@{get_nward_bb_idx(i3, gChain)}}) + dt
}
if ({atomIndex=i2}.atomno > {atomIndex=targetIdx}.atomno) {
movePt = TRUE
select_nward_idx(i3, get_cward_bb_idx(targetIdx, gChain))
{atomIndex=targetIdx}.selected = TRUE
}
else {
select_cward_idx(i2, targetIdx)
}
}
else {
if (({atomIndex=i2}.atomName="CA")) {
phi = angle({atomIndex=@{get_nward_bb_idx(i1, gChain)}}, {atomIndex=i1},
{atomIndex=i2}, {atomIndex=i3}) + dt
}
else {
psi = angle({atomIndex=i2}, {atomIndex=i3},
{atomIndex=i4}, {atomIndex=@{get_cward_bb_idx(i4, gChain)}}) + dt
}
if ({atomIndex=i2}.atomno < {atomIndex=targetIdx}.atomno) {
movePt = TRUE
select_cward_idx(i3, get_nward_bb_idx(targetIdx, gChain))
{atomIndex=targetIdx}.selected = TRUE
}
else {
select_nward_idx(i2, targetIdx)
}
}
# Relax rules if desperate
if (pass1 > 10) {
phi = -50
}
# If rotation within ramachandran limits
if ((abs(dt) >= 0.1) and
(({atomIndex=i2}.group=="GLY") or (phi < 0))) {
# If moving target point, put the target atom there
var cp = {atomIndex=targetIdx}.xyz
if (movePt) {
dt = -dt
{atomIndex=targetIdx}.xyz = pt
}
# Rotate to minimize vector ====================
rotateSelected {atomIndex=i2} {atomIndex=i3} @dt
# If collision checking
if (cDetect) {
# If collision, back off by eighths
var wasCollision = FALSE
for (var ci = 0; ci < 4; ci++) {
if (ci < 3) {
dt /= 2
}
handle_collisions_2( targetIdx)
if (not gOk2) {
wasCollision = TRUE
rotateSelected {atomIndex=i2} {atomIndex=i3} @{-dt}
}
else if (wasCollision) {
if (ci <3) {
rotateSelected {atomIndex=i2} {atomIndex=i3} @{dt}
}
}
else {
break
}
if (dt < 0.01) {
break
}
} # endfor
}
# If moving target point, put the target atom back
if (movePt) {
pt = {atomIndex=targetIdx}.xyz
{atomIndex=targetIdx}.xyz = cp
}
}
# If close enough, stop
if (distance(pt, {atomIndex=targetIdx}) < kDtolerance) {
gOK = TRUE
gTargetPt = pt
break
}
# Block rotor
blocked |= {atomIndex=i2}
} # endfor num rotors passes
if (gOK) {
break
}
} # endfor 20 passes
}
# Counter rotate bonds on either side of a BB O
function do_counter_rotate(caPhiIdx, nIdx, cIdx, oIdx, caPsiIdx, dir, nWard) {
# Rotate psi
{atomIndex=nIdx}.selected = nWard
{atomIndex=cIdx}.selected = nWard
{atomIndex=oIdx}.selected = nward
rotateSelected {atomIndex=caPsiIdx} {atomIndex=cIdx} @{dir}
# Counter-rotate phi
{atomIndex=nIdx}.selected = not nWard
{atomIndex=cIdx}.selected = not nWard
{atomIndex=oIdx}.selected = not nward
rotateSelected {atomIndex=nIdx} {atomIndex=caPhiIdx} @{-dir}
}
function counter_rotate(oIdx, dir, nWard) {
var iChain = {atomIndex=oIdx}.chain
var selsave = {selected}
var cIdx = get_sc_bb_idx(oIdx, iChain)
var nIdx = get_cward_bb_idx(cIdx, iChain)
var caPhiIdx = get_cward_bb_idx(nIdx, iChain)
var caPsiIdx = get_nward_bb_idx(cIdx, iChain)
if (nWard) {
nNo = {chain=iChain}.atomno.min
select_nward_idx(caPsiIdx, {(atomno=nNo) and (chain=iChain)}.atomIndex)
}
else {
cNo = {chain=iChain}.atomno.max
select_cward_idx(caPhiIdx, {(atomno=cNo) and (chain=iChain)}.atomIndex)
}
# Counter-rotate
do_counter_rotate(caPhiIdx, nIdx, cIdx, oIdx, caPsiIdx, dir, not nWard)
select selsave
}
function counter_rotate_2(oIdx, toPt, terminalIdx, oDrag) {
var iChain = {atomIndex=oIdx}.chain
var selsave = {selected}
var gOk2 = TRUE
var cIdx = get_sc_bb_idx(oIdx, iChain)
var nIdx = get_cward_bb_idx(cIdx, iChain)
var caPhiIdx = get_cward_bb_idx(nIdx, iChain)
var caPsiIdx = get_nward_bb_idx(cIdx, iChain)
var nTward = ({atomIndex=oIdx}.atomno < {atomIndex=terminalIdx}.atomno)
if (nTward) {
select_cward_idx(cIdx, terminalIdx)
}
else {
select_nward_idx(nIdx, terminalIdx)
}
# Until all collisions cancelled
var dir = 5
var ang = angle(toPt, {atomIndex=oIdx}, {atomIndex=cIdx})
var tcount = 0
while (oDrag or (within(kCtolerance, FALSE, {atomIndex=oIdx})
and not {atomIndex=oIdx} and not connected({atomIndex=oIdx})
and not {gOkCollide} > 0)) {
# Counter-rotate
do_counter_rotate(caPhiIdx, nIdx, cIdx, oIdx, caPsiIdx, dir, nTward)
var newang = angle(toPt, {atomIndex=oIdx}, {atomIndex=cIdx})
# If wrong direction once, undo and reverse
if (newang > ang) {
do_counter_rotate(caPhiIDx, nIdx, cIdx, oIdx, caPsiIdx, -dir, nTward)
# If first time, continue in opposite direction
dir *= -1
if (dir < 0) {
continue
}
}
if (oDrag) {
break
}
# If no go, undo and exit
tcount++
if (tcount > (360/abs(dir))) {
gOk2 = FALSE
break
}
} # endwhile
select selsave
}
# Repair proline
function repair_proline(BBidx) {
var cbidx = get_cb_idx(BBidx)
var cbno = {atomIndex=cbidx}.atomno
var cgidx = {(atomno=@{cbno+1}) and (chain=gChain)}.atomIndex
var cdidx = {(atomno=@{cbno+2}) and (chain=gChain)}.atomIndex
var caidx = {(atomno=@{cbno-3}) and (chain=gChain)}.atomIndex
var nidx = {(atomno=@{cbno-4}) and (chain=gChain)}.atomIndex
select {atomIndex=cbidx}
set_angle_idx(nidx, caidx, cbidx, 109.5)
select {atomIndex=cdidx}
set_distance_idx(nidx, cdidx, 1.47)
set_angle_idx(caidx, nidx, cdidx, 102.7)
set_dihedral_idx(cbidx, caidx, nidx, cdidx, 16.2)
select {atomIndex=cgidx}
set_distance_idx(cdidx, cgidx, 1.51)
set_angle_idx(nidx, cdidx, cgidx, 106.4)
set_dihedral_idx(caidx, nidx, cdidx, cgidx, 16.2)
}
# Repair side chain
function repair_sc(targetIdx, nWard) {
var idx = (nWard ? get_cward_bb_idx(targetIdx, gChain) : get_nward_bb_idx(targetIdx, gChain))
if (({atomIndex=targetIdx}.atomName == "CA")
and ({atomIndex=targetIdx}.group != "GLY")) {
var cbidx = get_cb_idx(targetIdx)
select none
select_add_sc(cbidx)
set_angle_idx(idx, targetIdx, cbidx, 110.0)
set_distance_idx(targetIdx, cbidx, 1.5)
if ({atomIndex=targetIdx}.group != "PRO") {
var colliders = (within(kCtolerance, FALSE, {selected})
and not {atomIndex=targetIdx} and not {selected})
if (colliders.size > 0) {
if ({atomIndex=targetIdx}.group != "ALA") {
fix_sc_collision_2(cbidx)
}
}
}
else {
if (nWard) {
}
else {
set_dihedral_idx(get_nward_bb_idx(idx, gChain), idx, targetIdx, cbidx, 174.2)
}
}
}
else if ({atomIndex=targetIdx}.atomName == "C") {
var oidx = get_o_idx(targetIdx)
select {atomIndex=oidx}
set_angle_idx(idx, targetIdx, oidx, 120.0)
set_distance_idx(targetIdx, oidx, 1.21)
if (nWard) {
set_dihedral_idx(get_cward_bb_idx(idx, gChain), idx, targetIdx, oidx, 0.0)
}
if ({atomIndex=idx}.group == "PRO") {
repair_proline(idx)
var dNo = {atomIndex=targetIdx}.atomno + 4
var dIdx = {(atomno=dNO) and (chain=gChain)}.atomIndex
var colliders = (within(kCtolerance, FALSE, {atomIndex=dIdx})
and not connected({atomIndex=dIdx})
and not {atomIndex=dIdx})
for (var i = 1; i <= colliders.size; i++) {
if (colliders[i].atomName == "O") {
counter_rotate_2(colliders[i].atomIndex,
{atomIndex=dIdx}.xyz, targetIdx, FALSE)
}
}
}
}
}
# Rebuild Cward rotors set
function tug_track_c() {
# For all bb atoms cWard of cargo
var targetIdx = gCcargoIdx
var okCount = 0
# Allow collisions with cargo
gOkCollide = gCargoSet
var tcount = 0
while (targetIdx != gCanchorIdx) {
# Step to next atom
targetIdx = get_cward_bb_idx(targetIdx, gChain)
# No collision with cargo allowed after two atoms placed
if (tcount == 2) {
gOkCollide = ({})
}
tcount++
# Compute targets desired coords
var c1idx = get_cward_bb_idx(targetIdx, gChain)
var n1idx = get_nward_bb_idx(targetIdx, gChain )
var n2idx = get_nward_bb_idx(n1Idx, gChain)
var n3idx = get_nward_bb_idx(n2Idx, gChain)
var pt = {0 0 0}
if ({atomIndex=targetIdx}.atomName == "N") {
var oidx = get_o_idx(n1idx)
select {atomIndex=oidx}
# Desired target location is trigonal O
set_distance_idx(n1idx, oidx, 1.5)
pt = get_trigonal_idx(n2idx, n1idx, oidx, 1.37)
set_distance_idx(n1idx, oidx, 1.21)
}
else if (({atomIndex=targetIdx}.atomName == "C")
and ({atomIndex=targetIdx}.group != "GLY")) {
# Desired target location is tetragonal CB
var cbidx = get_cb_idx(n1idx)
pt = get_tet_idx(n2idx, n1idx, cbidx, 1.5)
}
else { # CA (or GLY C)
# Save current target coords
var cp = {atomIndex=targetIdx}.xyz
# Set target atom at desired distance and angle
select {atomIndex=targetIdx}
set_distance_idx(n1idx, targetIdx, 1.5)
set_angle_idx(n2idx, n1idx, targetIdx, 120.0)
if ({atomIndex=targetIdx}.atomName == "CA") {
set_dihedral_idx(n3idx, n2idx, n1idx, targetIdx, 180)
}
# Record and restore target
pt = {atomIndex=targetIdx}.xyz
{atomIndex=targetIdx}.xyz = cp
}
# If target not at desired location
if (distance(pt, {atomIndex=targetIdx}) > kDtolerance) {
okCount = 0
gTargetPt = pt
var xcount = 0
gOK = FALSE
while ((xcount < 20) and (not gOK)) {
# Rotate on cWard rotor set to move it there
tug_track_idx(targetIdx, pt, FALSE, FALSE)
xcount++
}
}
else {
gOK = TRUE
okCount++
}
# If successful
if (gOK == TRUE) {
# Adust any side atoms
repair_sc(targetIdx, FALSE)
}
# Else fail
else {
break
}
# If no movement in 4 tries, we are done
if (okCount > 3) {
break
}
} # endwhile (targetIdx != gCanchorIdx) {
}
# Rebuild Nward rotors set
function tug_track_n() {
gOK = TRUE
# For all bb atoms nWard of cargo
var targetIdx = gNcargoIdx
var okCount = 0
# Allow collisions with cargo
gOkCollide = gCargoSet
var tcount = 0
while (targetIdx != gNanchorIdx) {
# Step to next atom
targetIdx = get_nward_bb_idx(targetIdx, gChain)
# No collision with cargo allowed after two atoms placed
if (tcount == 2) {
gOkCollide = ({})
}
tcount++
# Compute targets desired coords
var n1idx = get_nward_bb_idx(targetIdx, gChain)
var c1idx = get_cward_bb_idx(targetIdx, gChain)
var c2idx = get_cward_bb_idx(c1idx, gChain)
var c3idx = get_cward_bb_idx(c2idx, gChain)
var pt = {0 0 0}
if ({atomIndex=targetIdx}.atomName == "CA") {
# Desired target location is trigonal O
var oidx = get_o_idx(c1idx)
select {atomIndex=oidx}
set_distance_idx(c1idx, oidx, 1.39)
pt = get_trigonal_idx(c2idx, c1idx, oidx, 1.41)
set_distance_idx(c1idx, oidx, 1.21)
}
else if (({atomIndex=targetIdx}.atomName == "N")
and ({atomIndex=targetIdx}.group != "GLY")) {
# Desired target location is r-tetragonal CB
var cbidx = get_cb_idx(c1idx)
pt = get_tet_idx(cbidx, c1idx, c2idx, 1.5)
}
else { # C
# Save current target coords
var cp = {atomIndex=targetIdx}.xyz
# Set target atom at desired distance and angle
select {atomIndex=targetIdx}
set_distance_idx(c1idx, targetIdx, 1.37)
set_angle_idx(c2idx, c1idx, targetIdx, 110.0)
if ({atomIndex=targetIdx}.group == "PRO") {
set_dihedral_idx(c3idx, c2idx, c1idx, targetIdx, -57.0)
}
# Record and restore target
pt = {atomIndex=targetIdx}.xyz
{atomIndex=targetIdx}.xyz = cp
}
# If target not at desired location
if (distance(pt, {atomIndex=targetIdx}) > kDtolerance) {
var okCount = 0
gTargetPt = pt
var xcount = 0
gOK = FALSE
while ((xcount < 20) and (not gOK)) {
# Rotate on nWard rotor set to move it there
tug_track_idx(targetIdx, pt, TRUE, FALSE)
xcount++
}
}
else {
gOK = TRUE
okCount++
}
# If sucessful
if (gOK == TRUE) {
# Adust any side atoms
repair_sc(targetIdx, TRUE)
}
# Else fail
else {
break
}
# If no movement in 4 tries, we are done
if (okCount > 3) {
break
}
} # endwhile (targetIdx != gNanchorIdx) {
}
# gPlicoRecord is maintained by the macro pilcoRecord
function plico_record(s) {
var g = format("show file \"%s\"", gPlicoRecord)
var ls = script(g)
if (ls.find("FileNotFoundException")) {
ls = ""
}
ls += s
write var ls @gPlicoRecord
}
# gPlicoRecord is maintained by the macro pilcoRecord
function translate_selected_record(pt) {
if (gPlicoRecord != "") {
plico_record(format("select %s;translateSelected %s;", {selected}, pt))
}
translateSelected @pt
}
# gPlicoRecord is maintained by the macro pilcoRecord
function rotate_selected_record(pivotIdx, axis, a) {
if (gPlicoRecord != "") {
plico_record(format("select %s;", {selected}))
plico_record(format("rotateSelected {atomIndex=%d} @%s @%s;",
pivotIdx, axis, a))
}
rotateSelected {atomIndex=pivotIdx} @axis @a
}
function collect_sc_rotors(no, iChain) {
var scBondIdxs = array()
for (var iNo = no; iNo >= 0; iNo--) {
var ile = 0
switch ({(atomno=iNo) and (chain=iChain)}.atomName) {
case "CA" :
return scBondIdxs # Early exit since break 1 appears broken
case "CZ" :
if ({(atomno=iNo) and (chain=iChain)}.group == "TYR") {
break
}
case "CE" :
if ({(atomno=iNo) and (chain=iChain)}.group == "MET") {
break
}
case "CG1" :
if ({(atomno=iNo) and (chain=iChain)}.group == "VAL") {
break
}
if ({(atomno=iNo) and (chain=iChain)}.group == "ILE") {
ile = 1
}
case "NE" :
case "CD" :
case "SD" :
case "CG" :
case "CB" :
scBondIdxs += {(atomno=@{iNo+1+ile}) and (chain=iChain)}.atomIndex
scBondIdxs += {(atomno=@{iNo+0}) and (chain=iChain)}.atomIndex
if ({(atomno=iNo) and (chain=iChain)}.atomName%2 == "CG") {
scBondIdxs += {(atomno=@{iNo-1}) and (chain=iChain)}.atomIndex
scBondIdxs += {(atomno=@{iNo-4}) and (chain=iChain)}.atomIndex
}
else if ({(atomno=iNo) and (chain=iChain)}.atomName == "CB") {
scBondIdxs += {(atomno=@{iNo-3}) and (chain=iChain)}.atomIndex
scBondIdxs += {(atomno=@{iNo-4}) and (chain=iChain)}.atomIndex
}
else {
scBondIdxs += {(atomno=@{iNo-1}) and (chain=iChain)}.atomIndex
scBondIdxs += {(atomno=@{iNo-2}) and (chain=iChain)}.atomIndex
}
break
}
}
return scBondIdxs
}
# Drag Side Chain
function drag_sc() {
var iNo = {atomIndex=gSCidx}.atomno
var iChain = {atomIndex=gSCidx}.chain
if ({atomIndex=gSCidx}.group != "PRO") {
var scBondIdxs = collect_sc_rotors( iNo, iChain)
var numChi = scBondIdxs.size / 4
var dist = distance({atomIndex=gSCidx}.xyz, gSCpt)
var scSet = ({})
if (gSCcheck) {
scSet = get_sc_set(gSCidx, iChain)
}
# For all rotor combinations
var dh = array()
for (var i = 0; i < numChi; i++) {
dh += angle({atomIndex=@{scBondIdxs[4+(4*i)]}},
{atomIndex=@{scBondIdxs[3+(4*i)]}},
{atomIndex=@{scBondIdxs[2+(4*i)]}},
{atomIndex=@{scBondIdxs[1+(4*i)]}})
}
for (var i = 0; i < numChi; i++) {
var rot = -120
for (var j = 0; j < 6; j++) {
rot += 60*j
select_add_sc(scBondIdxs[1+(4*i)])
set_dihedral_idx(scBondIdxs[4+(4*i)], scBondIdxs[3+(4*i)],
scBondIdxs[2+(4*i)], scBondIdxs[1+(4*i)], rot)
var newDist = distance({atomIndex=gSCidx}.xyz, gSCpt)
if (gSCcheck) {
var colliders = (within(kCtolerance, FALSE, scSet)
and not connected(scSet) and not {scSet})
if (colliders.size > 0) {
continue
}
}
# Find the best
if (newDist < dist) {
dist = newDist
for (var k = 0; k < numChi; k++) {
dh[k+1] = angle({atomIndex=@{scBondIdxs[4+(4*k)]}},
{atomIndex=@{scBondIdxs[3+(4*k)]}},
{atomIndex=@{scBondIdxs[2+(4*k)]}},
{atomIndex=@{scBondIdxs[1+(4*k)]}})
}
}
}
}
# Now set the best
for (var i = 0; i < numChi; i++) {
select_add_sc(scBondIdxs[1+(4*i)])
set_dihedral_idx(scBondIdxs[4+(4*i)], scBondIdxs[3+(4*i)],
scBondIdxs[2+(4*i)], scBondIdxs[1+(4*i)], dh[i+1])
}
}
else { # PRO - toggle between puckers up and down
var icd = {(atomno=@{iNo+1}) and (chain=iChain)}.atomIndex
var icb = {(atomno=@{iNo-1}) and (chain=iChain)}.atomIndex
var ica = {(atomno=@{iNo-4}) and (chain=iChain)}.atomIndex
var in = {(atomno=@{iNo-5}) and (chain=iChain)}.atomIndex
select {atomIndex=gSCidx}
if (angle({atomIndex=ica}, {atomIndex=in},
{atomIndex=icd}, {atomIndex=gSCidx}) < -10.0) {
set_dihedral_idx(ica, in, icd, gSCidx, 8.7)
set_angle_idx(in, icd, gSCidx, 110.0)
set_distance_idx(icd, gSCidx, 1.5)
}
else {
set_dihedral_idx(ica, in, icd, gSCidx, -29.5)
set_angle_idx(in, icd, gSCidx, 108.8)
set_distance_idx(icd, gSCidx, 1.5)
}
}
draw gSCcircle CIRCLE {atomIndex=gSCidx} MESH NOFILL
gSCpt = {atomIndex=gSCidx}.xyz
}
# Fix side chain collisions
function fix_sc_collision_2(idx) {
gOk2 = FALSE
var iNo = {atomIndex=idx}.atomno
var iChain = {atomIndex=idx}.chain
var resno = {(atomno=iNo) and (chain=iChain)}.resno
# Get SC terminus
while (resno == {(atomno=iNo) and (chain=iChain)}.resno) {
iNo++
}
iNo--
var sc = array()
var iBno = iNo
while ({(atomno=iBno) and (chain=iChain)}.atomName != "CB") {
sc += {(atomno=iBno) and (chain=iChain)}
iBno--
}
var cbidx = {(atomno=iBno) and (chain=iChain)}.atomIndex
var scBondIdxs = collect_sc_rotors( iNo, iChain)
var numChi = scBondIdxs.size / 4
# For all rotor combinations
for (var i = 0; i < numChi; i++) {
var rot = -120
for (var j = 0; j < 6; j++) {
rot += 60
select_add_sc(scBondIdxs[1+(4*i)])
set_dihedral_idx(scBondIdxs[1+(4*i)], scBondIdxs[2+(4*i)],
scBondIdxs[3+(4*i)], scBondIdxs[4+(4*i)], rot)
# If no collision, exit
colliders = (within(kCtolerance, FALSE, {sc})
and not {atomIndex=cbidx} and not {sc})
# If it is with water, delete the water
for (var c = 1; c < colliders.size; c++ ) {
if (colliders[c].group = "HOH") {
delete {atomIndex=@{colliders[c].atomIndex}}
colliders = {colliders and not @{colliders[c]}}
}
}
if (colliders.size == 0) {
gOk2 = TRUE
return # Early exit since break 1 appears broken
}
}
}
}
function is_moveable_sc(aIdx) {
var ret = (({atomIndex=aIdx}.group != "PRO")
or ({atomIndex=aIdx}.atomName == "CG"))
switch({atomIndex=aIdx}.atomName) {
case "N":
case "CA":
case "C":
case "CB":
case "O":
case "O4\'":
ret = FALSE
break
}
return ret
}
function is_rotor_avail(i1idx, i2idx) {
var ret = TRUE
if (i1idx > i2idx) {
var idx = @i1idx
i1idx = @i2idx
i2idx = @idx
}
for (var i = 1; i <= gFreeze.size; i += 2) {
if ((gFreeze[i] == i1idx) and (gFreeze[i+1] == i2idx)) {
ret = FALSE
break
}
}
return ret
}
function collect_bb_rotors(nWard) {
var anchorNo = (nWard
? ((gNanchorIdx >= 0) ? {atomIndex=gNanchorIdx}.atomno : gMinNo)
: ((gCanchorIdx >= 0) ? {atomIndex=gCanchorIdx}.atomno : gMaxNo))
var cargoNo = (nWard
? ((gNcargoIdx >= 0) ? {atomIndex=gNcargoIdx}.atomno
: {atomIndex=gCcargoIdx}.atomno)
: {atomIndex=gCcargoIdx}.atomno)
var rotors = array()
if (cargoNo < anchorNo) {
for (var iNo = cargoNo; iNo <= anchorNo; iNo++) {
if ({(atomno=iNo) and (chain=gChain)}.atomName == "CA") {
if (is_rotor_avail(iNo)) {
if (({(atomno=iNo) and (chain=gChain)}.group != "PRO") and (iNo > cargoNo)) { # phi
rotors += [{(atomno=@{get_cm_no(iNo-1)}) and (chain=gChain)}.atomIndex,
{(atomno=@{iNo-1}) and (chain=gChain)}.atomIndex]
rotors += [{(atomno=@{iNo}) and (chain=gChain)}.atomIndex,
{(atomno=@{iNo+1}) and (chain=gChain)}.atomIndex]
}
if (iNo != (anchorNo-1)) { # psi
rotors += [{(atomno=@{iNo-1}) and (chain=gChain)}.atomIndex,
{(atomno=@{iNo}) and (chain=gChain)}.atomIndex]
rotors += [{(atomno=@{iNo+1}) and (chain=gChain)}.atomIndex,
{(atomno=@{get_np_no(iNo+2)}) and (chain=gChain)}.atomIndex]
}
}
}
}
}
else {
for (var iNo = cargoNo; iNo >= anchorNo; iNo--) {
if ({(atomno=iNo) and (chain=gChain)}.atomName == "CA") {
if (is_rotor_avail(iNo)) {
if ((iNo != (anchorNo-1)) and (iNo < cargoNo)) { # psi
rotors += [{(atomno=@{get_np_no(iNo+2)}) and (chain=gChain)}.atomIndex,
{(atomno=@{iNo+1}) and (chain=gChain)}.atomIndex]
rotors += [{(atomno=@{iNo}) and (chain=gChain)}.atomIndex,
{(atomno=@{iNo-1}) and (chain=gChain)}.atomIndex]
}
if ({(atomno=iNo) and (chain=gChain)}.group != "PRO") { # phi
rotors += [{(atomno=@{iNo+1}) and (chain=gChain)}.atomIndex,
{(atomno=@{iNo}) and (chain=gChain)}.atomIndex]
rotors += [{(atomno=@{iNo-1}) and (chain=gChain)}.atomIndex,
{(atomno=@{get_cm_no(iNo-1)}) and (chain=gChain)}.atomIndex]
}
}
}
}
}
if (nWard) {
gNrotors = rotors
}
else {
gCrotors = rotors
}
}
function collect_rotors() {
collect_bb_rotors(FALSE)
collect_bb_rotors(TRUE)
}
function tug_sc(pt) {
# If destination atom defined
if (gDestAtomIdx >= 0) {
var v = {atomIndex=gDestAtomIdx}.xyz - {atomIndex=gSCidx}.xyz
if (abs(angle({atomIndex=gDestAtomIdx}.xyz, {0 0 0}, pt)) < 90) {
pt = -v/20.0
}
else {
pt = v/20.0
}
}
gSCpt += pt
draw arrow {atomIndex=gSCidx} @gSCpt
}
function set_colors() {
select all
color {selected} @gScheme
color {atomIndex=g1pivotIdx} green
color {atomIndex=g2pivotIdx} green
color @gCargoSet @gAltScheme
select {(atomIndex=gCcargoIdx) or (atomIndex=gNcargoIdx)
or (atomIndex=gCanchorIdx) or (atomIndex=gNanchorIdx)}
halo on
select {atomIndex=gDestAtomIdx}
star on
select none
}
function clear_atom_idxs() {
gCcargoIdx = -1
gNcargoIdx = -1
gCanchorIdx = -1
gNanchorIdx = -1
g1pivotIdx = -1
g2pivotIdx = -1
g1dynamicIdx = -1
g2dynamicIdx = -1
gDestAtomIdx = -1
gSCidx = -1
}
function timed_out (s) {
timeout ID"tug" OFF
p = prompt(format("%s - Undo?", s), "Yes|No", TRUE)
if (p == "Yes") {
gBusy = FALSE
background ECHO yellow
restore state gState
connect
select gCargoSet
refresh
quit
}
}
function record_drag() {
var ls = format("select %s;", {selected})
ls += format("gCanchorIdx = %d;", gCanchorIdx)
ls += format("gCanchorNo = %d;", gCanchorNo)
ls += format("gNanchorIdx = %d;", gNanchorIdx)
ls += format("gNanchorNo = %d;", gNanchorNo)
ls += format("gCcargoIdx = %d;", gCcargoIdx)
ls += format("gNcargoIdx = %d;", gNcargoIdx)
ls += format("gCcargoNo = %d;", gCcargoNo)
ls += format("gNcargoNo = %d;", gNcargoNo)
ls += format("gDestAtomIdx = %d;", gDestAtomIdx)
ls += format("g1pivotIdx = %d;", g1pivotIdx)
ls += format("g2pivotIdx = %d;", g2pivotIdx)
ls += format("gOkCollide = %s;", gOkCollide)
ls += format("gChain = \"%s\";", gChain)
ls += format("gMinNo = %d;", gMinNo)
ls += format("gMaxNo = %d;", gMaxNo)
ls += format("gCargoSet = %s;", gCargoSet)
ls += format("gSCidx = %d;", gSCidx)
ls += format("gSCcircle = %d;", gSCcircle)
ls += format("gSCpt = %s;", gSCpt)
ls += "collect_rotors();"
ls += "tug_drag_done_mb();"
plico_record(ls)
}
# Pick call-back for freeze
function tug_pick_cb() {
if (_pickInfo[3][6] == "bond") {
var sel = {selected}
var i = _pickInfo.find(":")
var iChain = _pickInfo[i+1]
i = _pickInfo.find("#")
var a1no = _pickInfo[i+1][i+3]
j = _pickInfo[i+1][9999].find("#")
var a2no = _pickInfo[i+j+1][i+j+3]
var i1idx = {(atomno=a1no) and (chain=iChain)}.atomIndex
var i2idx = {(atomno=a2no) and (chain=iChain)}.atomIndex
if (({atomIndex=i1idx}.atomName == "CA")
or ({atomIndex=i2idx}.atomName == "CA")) {
if (({atomIndex=i1idx}.atomName != "CB")
and ({atomIndex=i2idx}.atomName != "CB")) {
if (i1idx > i2idx) {
idx = 0 + i1idx
i1idx = 0 + i2idx
i2idx = 0 + idx
}
select {atomIndex=i1idx} or {atomIndex=i2idx}
for (i = 1; i <= gFreeze.size; i += 2) {
if ((gFreeze[i] == i1idx) and (gFreeze[i+1] == i2idx)) {
gFreeze[i] == -1
color bonds NONE
break
}
}
if (i > gFreeze.size) {
gFreeze += i1idx
gFreeze += i2idx
color bonds lightblue
}
}
}
select {sel}
}
}
# Bound to LEFT-UP by tug_enable_drag
function tug_drag_done_mb() {
if (not gBusy) {
if (gPlicoRecord != "") {
record_drag()
}
# Move by rotation on rotor sets, smallest first
gBusy = TRUE
background ECHO pink
refresh
# If side chain mode
if (gSCidx >= 0) {
drag_sc()
}
# Else
else if (not gTow) {
gOK = TRUE
timeout ID"tug" 20.0 "timed_out(\"Tug timed out\")"
if ((gCrotors.size < gNrotors.size) or (gNanchorIdx < 0)) {
if (gCrotors.size > 4) {
tug_track_c()
}
if (gOK and (gNrotors.size > 4)) {
tug_track_n()
}
}
else {
if (gNrotors.size > 4) {
tug_track_n()
}
if (gOK and (gCrotors.size > 4)) {
tug_track_c()
}
}
timeout ID"tug" OFF
# If anchor angles acute, fail
if (gOK == TRUE) {
if (gCanchorIdx >= 0) {
var ic = get_cward_bb_idx(gCanchorIdx, gChain)
var in = get_nward_bb_idx(gCanchorIdx, gChain)
if ((ic >= 0) and
angle({atomIndex=ic}, {atomIndex=gCanchorIdx}, {atomIndex=in})
< 100.0) {
gOK = FALSE
}
}
if (gNanchorIdx >= 0) {
var ic = get_cward_bb_idx(gNanchorIdx, gChain)
var in = get_nward_bb_idx(gNanchorIdx, gChain)
if ((in >= 0) and
angle({atomIndex=ic}, {atomIndex=gNanchorIdx}, {atomIndex=in})
< 100.0) {
gOK = FALSE
}
}
}
# If too far
if (not gOK) {
timed_out("TUG TOO FAR!")
}
# Else OK
else {
select ((atomno >= gNanchorNo) and (atomno <= gCanchorNo)
and (chain = gChain))
var idx = {(atomno=@{{chain=gChain}.atomno.min})
and (chain=gChain)}.atomIndex
var ihc = 0
for (ihc = 0; ihc < 10; ihc++) {
handle_collisions_2( idx)
if (count_collisions(({})).size == 0) {
break
}
}
if (ihc == 10) {
timed_out("Unable to handle all collisions!")
}
}
}
select {gCargoSet}
gBusy = FALSE
background ECHO yellow
refresh
}
}
# Bound to ALT-SHIFT-LEFT-DRAG by tug_enable_drag
function tug_drag_2_mb() {
tug_drag_mb(TRUE)
}
# Bound to ALT-LEFT-DRAG by tug_enable_drag
function tug_drag_mb(alt) {
if (not gBusy) {
gBusy = TRUE
var dx = (40.0 * (_mouseX - gMouseX))/_width
var dy = (40.0 * (_mouseY - gMouseY))/_height
var q = quaternion()
var ptd = {@dx @dy 0}
var pt = (!q)%ptd
var axis = {0 0 0}
if (distance(pt, {0 0 0}) > 0.004) {
# If sidechain mode
if (gSCidx >= 0) {
if ({atomIndex=gSCidx}.atomName == "O") {
dir = ((abs(dx) > abs(dy))
? ((dx < 0) ? 10 : -10)
: ((dy < 0) ? 1 : -1))
counter_rotate(gSCidx, dir, not alt)
}
else {
gSCcheck = not alt
tug_sc(pt)
}
}
# Else
else {
# If new drag
if (gNewDrag) {
gNewDrag = FALSE
save state gState
}
# If destination atom defined
if (gDestAtomIdx >= 0) {
var v = {atomIndex=gDestAtomIdx}.xyz - {selected}.xyz
if (abs(angle({atomIndex=gDestAtomIdx}.xyz, {0 0 0}, pt)) < 90) {
pt = -v/20.0
}
else {
pt = v/20.0
}
}
# Move the cargo
select {gCargoSet}
# If pivots defined, rotate it
if (g1pivotIdx >= 0) {
# If two pivots
if (g2pivotIdx >= 0) {
axis = {atomIndex=g2pivotIdx}
}
# Else
else {
axis = cross(pt, {0 0 0}) + {atomIndex=g1pivotIdx}.xyz
}
dir = ((abs(dx) > abs(dy))
? ((dx < 0) ? 2 : -2)
: ((dy < 0) ? 2 : -2))
rotate_selected_record(g1pivotIdx, axis, dir)
}
# Else translate it
else {
translate_selected_record(pt)
}
# If collisions
var cNotSels = (within(kCtolerance, FALSE, {selected})
and not {gMovingSet})
if ((cNotSels.size > 0) and (not alt)) {
gOk2 = TRUE
for (var i = 1; i <= cNotSels.size; i++) {
# If net collision vector same as move vector
cSels = (within(kCtolerance, FALSE, cNotSels[i]) and {selected})
for (var j = 1; j <= cSels.size; j++) {
var v1 = cNotSels[i].xyz - cSels[j].xyz
if (abs(angle(v1, {0 0 0}, pt)) < 90) {
# If tow mode
if (gTow) {
# Make a dynamic pivot
if (g1pivotIdx < 0) {
g1pivotIdx = cSels[j].atomIndex
g1dynamicIdx = cNotSels[i].atomIndex
color {atomIndex=g1pivotIdx} lightgreen
set_distance_idx(cNotSels[i].atomIndex,
cSels[j].atomIndex,
kCtolerance + kDtolerance)
}
else if (g2pivotIdx < 0) {
g2pivotIdx = cSels[j].atomIndex
g2dynamicIdx = cNotSels[i].atomIndex
color {atomIndex=g2pivotIdx} lightgreen
set_distance_idx(cNotSels[i].atomIndex,
cSels[j].atomIndex,
kCtolerance + kDtolerance)
}
else {
gOk2 = FALSE
}
}
else {
# Try to resolve
select cSels[j]
var idx = {(atomno=@{{chain=gChain}.atomno.min})
and (chain=gChain)}.atomIndex
handle_collisions_2( idx)
}
}
} # endfor
if (not gOk2) {
break
}
} # endfor
# If unable
if (not gOk2) {
# Back off
background ECHO pink
delay 1
if (g1pivotIdx >= 0) {
rotate_selected_record(g1pivotIdx, axis, -a)
}
else {
translate_selected_record(-pt)
}
background ECHO yellow
}
}
}
# If dynamic pivots
if (g1dynamicIdx >= 0) {
var v1 = {atomIndex=g1dynamicIdx}.xyz - {atomIndex=g1pivotIdx}.xyz
if (abs(angle(v1, {0 0 0}, pt)) > 90) {
color {atomIndex=g1pivotIdx} @gAltScheme
g1pivotIdx = -1
g1dynamicIdx = -1
}
}
if (g2dynamicIdx >= 0) {
var v1 = {atomIndex=g2dynamicIdx}.xyz - {atomIndex=g2pivotIdx}.xyz
if (abs(angle(v1, {0 0 0}, pt)) > 90) {
color {atomIndex=g2pivotIdx} @gAltScheme
g2pivotIdx = -1
g2dynamicIdx = -1
}
}
gMouseX = _mouseX
gMouseY = _mouseY
}
select {gCargoSet}
gBusy = FALSE
}
}
# Bound to ALT-LEFT-DOWN by tug_enable_drag
function tug_mark_mb() {
gMouseX = _mouseX
gMouseY = _mouseY
gNewDrag = TRUE
}
# Called by tug_cargo_mb
function tug_enable_drag() {
gEcho = "__________TUG__________|ALT-CLICK=mark block|SHIFT-CLICK=anchors" +
"|ALT-CTRL-CLICK=pivots|ALT-SHIFT-CLICK=dest atom|ALT-DRAG=move" +
"|SHIFT-ALT-DRAG=alt move|CLICK bond=freeze|DOUBLE-CLICK=exit"
echo @gEcho
# Allow atoms to be dragged
bind "ALT-LEFT-DOWN" "tug_mark_mb";
bind "ALT-LEFT-UP" "tug_drag_done_mb";
bind "ALT-SHIFT-LEFT-DOWN" "tug_mark_mb";
bind "ALT-SHIFT-LEFT-UP" "tug_drag_done_mb";
bind "ALT-LEFT-DRAG" "tug_drag_mb";
bind "ALT-SHIFT-LEFT-DRAG" "tug_drag_2_mb";
unbind "SHIFT-LEFT-CLICK"
bind "SHIFT-LEFT-CLICK" "_pickAtom";
bind "SHIFT-LEFT-CLICK" "+:tug_anchor_mb";
bind "ALT-CTRL-LEFT-CLICK" "_pickAtom";
bind "ALT-CTRL-LEFT-CLICK" "+:tug_pivot_mb";
bind "ALT-SHIFT-LEFT-CLICK" "_pickAtom";
bind "ALT-SHIFT-LEFT-CLICK" "+:tug_dest_atom_mb";
}
# Bound to SHIFT-LEFT-CLICK by tug_cargo_mb
function tug_anchor_mb() {
if ({atomIndex=_atomPicked}.chain == gChain) {
var aPidx = get_sc_bb_idx( _atomPicked, gChain)
var pno = {atomIndex=aPidx}.atomno
if (pno > {atomIndex=gCcargoIdx}.atomno) {
select {atomIndex=gCanchorIdx}
halo off
if (gCanchorIdx == aPidx) {
gCanchorIdx = -1
gCanchorNo = gMaxNo + 1
}
else {
gCanchorIdx = aPidx
gCanchorNo = {atomIndex=gCanchorIdx}.atomno
select {atomIndex=gCanchorIdx}
halo on
}
collect_bb_rotors(FALSE)
}
else if (pno < {atomIndex=gNcargoIdx}.atomno) {
select {atomIndex=gNanchorIdx}
halo off
if (gNanchorIdx == aPidx) {
gNanchorIdx = -1
gNanchorNo = gMinNo - 1
}
else {
gNanchorIdx = aPidx
gNanchorNo = {atomIndex=gNanchorIdx}.atomno
select {atomIndex=gNanchorIdx}
halo on
}
collect_bb_rotors(TRUE)
}
else {
tow_cargo_mb()
}
# Get moving atoms set
gMovingSet = {((atomno < gCanchorNo) and (atomno > gNanchorNo)
and (chain=gChain))}
}
select {gCargoSet}
}
# Bound to ALT-SHIFT-LEFT-CLICK by tug_cargo_mb
function tug_dest_atom_mb() {
var aOk = TRUE
if ({atomIndex=_atomPicked}.chain == gChain) {
var pno = {atomIndex=_atomPicked}.atomno
if ((pno <= {atomIndex=gCcargoIdx}.atomno) and (pno >= {atomIndex=gNcargoIdx}.atomno)) {
aOk = FALSE
}
}
if (aOk) {
select {atomIndex=gDestAtomIdx}
star off
if (gDestAtomIdx == _atomPicked) {
gDestAtomIdx = -1
}
else {
gDestAtomIdx = _atomPicked
select {atomIndex=gDestAtomIdx}
star on
}
select {gCargoSet}
}
}
# Bound to CTRL-LEFT-CLICK by tug_cargo_mb
function tug_pivot_mb() {
if (g1pivotIdx == _atomPicked) {
color {atomIndex=g1pivotIdx} @gScheme
if (g2pivotIdx >= 0) {
g1pivotIdx = g2pivotIdx
g2pivotIdx = -1
g2dynamicIdx = -1
}
else {
g1pivotIdx = -1
g1dynamicIdx = -1
}
}
else if (g2pivotIdx == _atomPicked) {
color {atomIndex=g2pivotIdx} @gScheme
g2pivotIdx = -1
g2dynamicIdx = -1
}
else if (g1pivotIdx >= 0) {
if (g2pivotIdx >= 0) {
color {atomIndex=g2pivotIdx} @gScheme
}
g2pivotIdx = _atomPicked
g2dynamicIdx = -1
color {atomIndex=g2pivotIdx} green
}
else {
g1pivotIdx = _atomPicked
g1dynamicIdx = -1
color {atomIndex=g1pivotIdx} green
}
select {gCargoSet}
}
# Bound to SHIFT-LEFT-CLICK by plico_tug
function tow_cargo_mb() {
gTow = TRUE
gChain = {atomIndex=_atomPicked}.chain
gMinNo = {chain=gChain}.atomno.min
gMaxNo = {chain=gChain}.atomno.max
gCcargoIdx = -1
gNcargoIdx = -1
gCanchorIdx = -1
gCanchorNo = gMaxNo + 1
gNanchorIdx = -1
gNanchorNo = gMinNo - 1
# Highlight cargo cluster
select {chain=gChain}
gCargoSet = {selected}
gMovingSet = {selected}
set_colors()
# Enable dragging
tug_enable_drag()
select {gCargoSet}
halo off
var es = gEcho.replace("anchors","mark chain")
echo @es
unbind "SHIFT-LEFT-CLICK"
bind "SHIFT-LEFT-CLICK" "_pickAtom";
bind "SHIFT-LEFT-CLICK" "+:tow_cargo_mb";
}
# Bound to ALT-LEFT-CLICK by plico_tug or called by plicotoab.toabCargoMB
function tug_cargo_mb() {
# If O or movable side chain atom picked
if (({atomIndex=_atomPicked}.atomName = "O")
or (is_moveable_sc( _atomPicked))) {
if (gSCidx >= 0) {
draw gSCcircle DELETE
}
if (gSCidx == _atomPicked) {
gSCidx = -1
}
else {
gSCidx = _atomPicked
gSCpt = {atomIndex=gSCidx}.xyz
draw gSCcircle CIRCLE {atomIndex=gSCidx} MESH NOFILL
}
}
else {
if ({atomIndex=_atomPicked}.chain != gChain) {
if (gTow) {
select {chain=gChain}
color {selected} @gScheme
}
gChain = {atomIndex=_atomPicked}.chain
select ({atomIndex=gCcargoIdx} or {atomIndex=gNcargoIdx}
or {atomIndex=gCanchorIdx} or {atomIndex=gNanchorIdx})
halo off
gCcargoIdx = -1
gNcargoIdx = -1
gCanchorIdx = -1
gNanchorIdx = -1
}
gTow = FALSE
gMinNo = {chain=gChain}.atomno.min
gMaxNo = {chain=gChain}.atomno.max
if (gNanchorIdx < 0) {
gNanchorNo = gMinNo - 1
}
if (gCanchorIdx < 0) {
gCanchorNo = gMaxNo + 1
}
var aPidx = get_sc_bb_idx( _atomPicked, gChain)
gSCidx = -1
draw gSCcircle DELETE
# If existing cWard cargo picked
if (gCcargoIdx == aPidx) {
# Clear the highlight
select {atomIndex=gCcargoIdx}
halo off
# If nWard cargo exists, mark it as the cWard cargo
if (gNcargoIdx != gCcargoIdx) {
gCcargoIdx = get_cp_idx(gNcargoIdx)
gCcargoNo = {atomIndex=gCcargoIdx}.atomno
}
else {
gCcargoIdx = -1
gNcargoIdx = -1
}
}
else if (gNcargoIdx == aPidx) {
select {atomIndex=gNcargoIdx}
halo off
gNcargoIdx = get_nm_idx(gCcargoIdx)
gNcargoNo = {atomIndex=gNcargoIdx}.atomno
}
else if (gCcargoIdx >= 0) {
var no = {atomIndex=aPidx}.atomno
# If pick is nWard of it
if (no < {atomIndex=gCcargoIdx}.atomno) {
# If exists, clear its highlight
if (gNcargoIdx != gCcargoIdx) {
select {atomIndex=gNcargoIdx}
halo off
}
# Set new nWard cargo and highlight it
gNcargoIdx = get_nm_idx(aPidx)
gNcargoNo = {atomIndex=gNcargoIdx}.atomno
}
# Else cWard
else {
# Clear its old highlight
select {atomIndex=gCcargoIdx}
if (gNcargoIdx != gCcargoIdx) {
halo off
}
# Set new cWard cargo and highlight
gCcargoIdx = get_cp_idx(aPidx)
gCcargoNo = {atomIndex=gCcargoIdx}.atomno
}
}
# Else no cWard cargo
else {
# Set new cWard cargo and highlight
gCcargoIdx = get_cp_idx(aPidx)
gCcargoNo = {atomIndex=gCcargoIdx}.atomno
gNcargoIdx = get_nm_idx(gCcargoIdx)
gNcargoNo = {atomIndex=gNcargoIdx}.atomno
# Set default cWard anchor at cWard N
var iNo = gMaxNo
for (; iNo > 0; iNo--) {
if ({(atomno=iNo) and (chain=gChain)}.atomName == "N") {
break;
}
}
gCanchorIdx = {(atomno=iNo) and (chain=gChain)}.atomIndex
gCanchorNo = {atomIndex=gCanchorIdx}.atomno
}
# If any anchor now inside cargo cluster, kill it
if ({atomIndex=gCanchorIdx}.atomno <= {atomIndex=gCcargoIdx}.atomno) {
gCanchorIdx = -1
gCanchorNo = gMaxNo + 1
}
if ({atomIndex=gNanchorIdx}.atomno >= {atomIndex=gNcargoIdx}.atomno) {
gNanchorIdx = -1
gNanchorNo = gMinNo - 1
}
# Highlight cargo cluster
select_nward_idx(gCcargoIdx, gNcargoIdx)
gCargoSet = {selected}
set_colors()
# Collect the rotor sets
collect_rotors()
# Get moving atoms set
gMovingSet = {((atomno < gCanchorNo) and (atomno > gNanchorNo)
and (chain=gChain))}
}
# Enable dragging
if (gToab) {
toabEnableDrag()
}
else {
tug_enable_drag()
}
select {gCargoSet}
}
# Top level of Tug
function plico_tug() {
# Load common functions if not already
if (kCommon < 2) {
script $SCRIPT_PATH$plicoCommon.spt
if (kCommon < 2) {
prompt ("A newer version of plicoCommon.SPT is required")
quit
}
}
gPlico = "TUG"
plico_prelim()
gBondPicking = bondPicking
set bondPicking TRUE
set PickCallback "jmolscript:tug_pick_cb"
gEcho = ("_________TUG_________|ALT-CLICK=mark block|SHIFT-CLICK=mark chain" +
"|CLICK bond=freeze|DOUBLE-CLICK=exit")
echo @gEcho
gCrotors = array()
gNrotors = array()
clear_atom_idxs()
bind "ALT-LEFT-CLICK" "_pickAtom";
bind "ALT-LEFT-CLICK" "+:tug_cargo_mb";
bind "SHIFT-LEFT-CLICK" "_pickAtom";
bind "SHIFT-LEFT-CLICK" "+:tow_cargo_mb";
bind "DOUBLE" "tug_exit";
}
# Bound to DOUBLE by plico_tug
function tug_exit() {
set bondPicking gBondPicking
set PickCallback NONE
plico_exit()
}
# End of TUG.SPT