Code
--[[
====================================
* Glycine Flipper
* Original Author: Brow42
* Version 1.0.0 Jun. 26 2012 Brow42
* Runs a 1-3 segment rebuld until the glycine carbon-alpha moves
* enough to think it's flipped.
--]]
-- For testing purposes
--save.Quickload(1)
--selection.DeselectAll()
--selection.Select(31) -- debugging, a glycine in Snow Flea
title = 'Glycine Flipper 1.0'
band0 = band.GetCount()
options = {
preceeding = true,
succeeding = false,
bandgly = false, -- actually band neighbors, not gly
helper = false
}
-- ================================== Begin New Dialog Library Functions
--[[
Throws up a dialog containing just text, provided as a string or table
of strings in the first argument. Title and buttons are optional. Return
value is 1 if the first button is clicked and 0 if the second button is clicked
or the window is closed.
--]]
function dialog.MessageBox(msg,title,buttontext1, buttontext0, buttontext2)
title = title or ''
local d = dialog.CreateDialog(title)
if type(msg) == 'string' then d['1'] = dialog.AddLabel(msg)
else for i = 1,#msg do
d[tostring(i)] = dialog.AddLabel(msg[i])
end
end
buttontext1 = buttontext1 or 'Ok'
d.button = dialog.AddButton(buttontext1,1)
if buttontext2 then d.button2 = dialog.AddButton(buttontext2,2) end
if buttontext0 then d.button0 = dialog.AddButton(buttontext0,0) end
return dialog.Show(d)
end
-- ================================== End New Dialog Library Functions
-- ================================== Begin Script Dialogs
function About()
local msg = {
'This executes rebuild on a glycine until it flips.',
'Specify the glycine by selecting or freezing it.',
'If you don\'t, or you have more than one',
'selected/frozen, you get the dialog box (where you',
'can specify other options.',
'The flipped and unflipped positions are left in',
'the undo buffer.',
'Note: helper band may not help, hit \'d\' to',
'turn it off during rebuild.',
'Note: banding side segments may prevent rebuild',
'from doing anything!',
'Note: if it won\'t flip, hit cancel when the Ca',
'column (#2) is big).'
}
dialog.MessageBox(msg,'About '..title,'Back')
end
function Dialog()
local d = dialog.CreateDialog(title)
d.label = dialog.AddLabel('I couldn\'t identify which glycine you wanted to flip.')
d.seg = dialog.AddTextbox('Segment:','')
d.preceeding = dialog.AddCheckbox('Include preceeding segment in rebuild',options.preceeding)
d.succeeding = dialog.AddCheckbox('Include succeeding segment in rebuild',options.succeeding)
d.helper = dialog.AddCheckbox('Helper band',options.helper)
d.bandgly = dialog.AddCheckbox('Band Side segments (recommended for 3 seg)',options.bandgly)
d.label2 = dialog.AddLabel('Open the output window!')
d.okay = dialog.AddButton('Flip!',1)
d.cancel = dialog.AddButton('Cancel',0)
d.about = dialog.AddButton('About',2)
local seg
repeat
local rc = dialog.Show(d)
if rc == 2 then About()
elseif rc == 1 then
seg = tonumber(d.seg.value)
if seg == nil or seg < 1 or seg > structure.GetCount() then
rc = -1
ErrorMessage(string.format('Specify exactly 1 segment from 1 to %d',structure.GetCount()))
elseif not structure.IsGlycine(seg) then
rc = -1
ErrorMessage('Requested segment isn\'t a glycine!')
end
end
until rc == 0 or rc == 1
options.preceeding = d.preceeding.value
options.succeeding = d.succeeding.value
options.helper = d.helper.value
options.bandgly = d.bandgly.value
return seg
end
function ErrorMessage(msg)
dialog.MessageBox(msg,'Error','Okay')
print(msg)
end
-- ================================== Begin Script Dialogs
-- ================================== Begin Utility Functions
function structure.IsGlycine(i)
return structure.GetSecondaryStructure(i) ~= 'M' and structure.GetAminoAcid(i) == 'g'
end
-- Return selected / frozen glycine if there is only 1, else nil
function GetTarget()
local list = {}
for i=1,structure.GetCount() do
if structure.IsGlycine(i) then
if freeze.IsFrozen(i) then list[#list+1] = i end
if selection.IsSelected(i) then list[#list+1] = i end
end
end
if #list == 1 then return list[1] end
return nil
end
-- General band in space function
function Band(iSeg, atom, rho, theta, phi, goal, weight, enable)
local nSeg = structure.GetCount()
local seg2, seg3
if (iSeg == 1) then seg2,seg3 = 2,3
elseif iSeg == nSeg then seg2,seg3 = nSeg-1,nSeg-2
else seg2,seg3 = iSeg-1, iSeg+1 end
local iBand = band.Add(iSeg,seg2,seg3,rho,theta,phi,atom)
if iBand > 0 then
band.SetGoalLength(iBand,goal)
band.SetStrength(iBand,weight)
if not enable then band.Disable(iBand) end
end
return iBand
end
-- last 3 args are optional
function ZeroLengthBand(iSeg,atom,enable,weight)
local minlen = 0.0001
atom = atom or 0
enable = enable or false
weight = weight or 0.1
return Band(iSeg, atom, minlen, 0, 0, minlen, 0.01, enable)
end
-- Routine called on cancel or error
function OnError(err)
if err:find('Cancel') then
print('Cancelled')
CleanUp()
else print('Error: ',err)
end
return err
end
function GetRulerBands(n)
local list = {}
for i = band0+1, band0+n do
list[#list+1] = band.GetLength(i)
end
return list
end
function CleanUp()
while (band.GetCount() > band0) do band.Delete(band.GetCount()) end
selection.DeselectAll()
save.Quicksave(100)
save.Quickload(99)
save.Quickload(100)
end
-- ================================== End Utility Functions
-- ====================== Begin Main
print(title)
print(puzzle.GetName())
print(os.date(),string.format('%9.3f',current.GetScore()))
save.Quicksave(99)
seg = GetTarget()
if seg == nil then seg = Dialog() end
if seg == nil then print('Cancelled.') return end
print('Selected glycine:',seg)
print(band0,'pre-existing bands',band.GetCount())
start,finish = seg,seg
if seg > 1 and options.preceeding then start = seg-1 end
if options.succeeding and seg+1 < structure.GetCount() and structure.GetSecondaryStructure(seg+1) ~= 'M' then finish = seg+1 end
print(string.format('Rebuilding from %d - %d',start,finish))
selection.DeselectAll()
for i = start,finish do freeze.Unfreeze(i,true,true) end
ZeroLengthBand(seg,1)
ZeroLengthBand(seg,2)
ZeroLengthBand(seg,3)
ZeroLengthBand(seg,4)
n_rulers = 4
formatstr = string.rep(' %5.3f',n_rulers)
print(' N =>Ca<= C\' O movement')
iBand = band0 + 1
c = 4
if options.bandgly then
for i = start, finish do
if i ~= seg then ZeroLengthBand(i,2,true,0.5) c = c + 1 end
end
end
-- function Band(seg, atom, rho, theta, phi, goal, weight, enable)
if options.helper then
Band(seg, 2, 1.9, math.pi/2, math.pi/2, 0.0, 1, true)
c = c + 1
end
if band.GetCount() ~= band0+c then
ErrorMessage('Problem making ruler bands, aborting.')
while (band.GetCount() > band0) do band.Delete(band.GetCount()) end
return
end
selection.SelectRange(start,finish)
-- function for error capture
function Rebuild()
local count = 1
while band.GetLength(iBand + 1) < 1.7 do
structure.RebuildSelected(1)
print(count, formatstr:format(unpack(GetRulerBands(n_rulers))))
count = count + 1
end
end
rc,err = xpcall(Rebuild,OnError)
if (rc == true) then print('Done.')
CleanUp()
end