Code
--(Re)set my structure, by Bruno Kestemont 05 Sep 2013
--[[
===================================
* Reset or set my structure
* Original Author: Bruno Kestemont
* Version 0.1 05 Sep 2013
* Easy way to set and then reset
* secondary structure assignment
--]]
-- ================================== Begin Function Wrappers by Brown42
-- These must always be at the top of a file
-- Remove the problematic molecule e.g. puzzle 471
structure._GetCount = structure.GetCount
function structure.HasMolecule()
return structure.GetSecondaryStructure(structure._GetCount())=='M'
end
function structure.GetCountC()
local n = structure._GetCount()
while structure.GetSecondaryStructure(n) == 'M' do n = n - 1 end
return n
end
-- ================================== End Function Wrappers
structure.HasMolecule()
if structure.HasMolecule() then
print('Note: structure has a molecule, which will be ignored.')
end
n = structure.GetCountC()
first, last = 1,n
sslist = {}
tab2= {}
saveNote19=structure.GetNote(19)
note19libre=true
note19Set=false
SSreset=''
-- ============================== Begin Read Functions
-- Read primary and secondary structure
function ReadStructure()
local tmp = {}
local rc, aa
for i = first,last do
if structure.IsMutable(i) == true then
tmp[#tmp + 1] = structure.GetAminoAcid(i)
else
tmp[#tmp + 1] = ' '
end
sslist[#sslist + 1] = structure.GetSecondaryStructure(i)
end
ConcatenateStructure()
local dontprintlist = {M=true}
dontprintlist[' '] = true
print('Structure read from range:',first,'to',last)
print('Secondary Structure:')
print(SS)
end
-- ============================== End Read Functions
function ConcatenateStructure()
local sstructure=''
for i = first,last do
sstructure=sstructure..sslist[i]
end
SS=sstructure
return
end
-- ============================== Begin Write Functions
function note19free()
if #saveNote19>0 and (saveNote19:find("L") or saveNote19:find("E") or saveNote19:find("H")) then
note19libre=false
note19Set=true
elseif #saveNote19>0 then
note19libre=false
note19Set=false
else
note19libre=true
note19Set=false
end
end
function WriteStructure()
note19free()
if note19libre and not note19Set then
structure.SetNote(19,SS)
end
end
function WriteSecondaryStructure(str) -- by Brown42
local n = structure.GetCount()
local tab ={}
local input = string.upper(str)
print ('input='..input)
local ss = { H='H', E='E', L='L', I='L', B='L', S='L', T='L', M=' ', G='H'}
ss[' '] = ' ' -- table of allowed SS, reduced to 'EHL '
tab = StringToTable(input)
if tab == nil then print ('tab is nil') return false else print('tab n= '..#tab) end
-- Error check SS input
for i = 1,#tab do
local x = tab[i]
if x[2] < 1 or x[2] > n or x[3] < 1 or x[3] > n then
print ('Your secondary structure is out of range')
return false
end
x[1] = ss[x[1]]
if x[1] == nil then
print('Unrecognized AA symbol:',x[1],x[2],'Input Error')
return false
end
-- Set SS
structure.SetSecondaryStructureSelected('L')
end
for i = 1,#tab do
local x = tab[i]
if x[1] ~= ' ' then -- no changes for ' '
if x[2] == x[3] then structure.SetSecondaryStructure(x[2],x[1])
else
selection.DeselectAll()
selection.SelectRange(x[2],x[3])
structure.SetSecondaryStructureSelected(x[1])
end
end
end
return true
end
-- ============================== End Write Functions
-- ============================== Begin Reset Functions
function ResetSS()
if note19Set then
str=structure.GetNote(19)
if str==nil then
print ('str is nil')
else
print(str)
WriteSecondaryStructure(str)
end
end
end
function ParseCompressed(str) -- based on Brown42
-- First turn string into letter - number pairs
local init = 1
local tab = {}
local ranging = false -- true means range extension is disallowed
local lower = 0 -- lower value of range, 0 illegal
local sym = '' -- symbol being compressed, empty illegal
while init <= #str do
local a,b,c,d = string.find(str, ' *([%a%-]?) *(%d+) *',init)
if a == nil then break end
init = b+1
-- continuing a range, check if it's valid
if c == '-' then
if ranging == true then
dialog.ShowMessageBox('Multiple range numbers (a range is number - number)','Input Error')
return nil
end
if sym == '' or lower == 0 then
dialog.ShowMessageBox('Initial range (a range continues a structure number pair)','Input Error')
return nil
end
tab[#tab+1] = {sym, lower, tonumber(d)}
ranging = true
lower = 0
-- starting a new range with explicit symbol
elseif c ~= '' then
ranging = false
if sym ~= '' and lower > 0 then tab[#tab+1] = {sym,lower,lower} end
sym = c
lower = tonumber(d)
ranging = false
-- starting a new range with same symbol
elseif sym ~= '' then
if lower > 0 then tab[#tab+1] = {sym,lower,lower} end
lower = tonumber(d)
ranging = false
else
dialog.ShowMessageBox({'Missing structure symbol (a range starts',
'with a structure number pair'},'Input Error')
end
end
if lower > 0 then tab[#tab+1] = {sym,lower,lower} end
return tab
end
-- is there another way to do this? string.subs I guess
function string.at(str,i) return string.char(string.byte(str,i)) end
-- Group up identical symbols into symbol,range table
function Compress(str,start) ---- based on Brown42
local sym = ''
local count = 0
local result = {}
for i = 1,#str+1 do
if string.at(str,i) == sym then count = count + 1
else
if count > 0 then result[#result+1] = {sym,start+i-1-count,start+i-2} end
count = 1
sym = string.at(str,i)
end
end
return result
end
-- Turn a string that may or may not be compressed into a symbol,range table, by Brown42
function StringToTable(input,startstr)
startstr = startstr or ''
local compressed = string.find(input,'%d') ~= nil
local tab
if compressed then
if startstr ~= '' then
dialog.ShowMessageBox({'Reminder: the start/range value is ignored','when using compressed notation.'},'Info')
end
tab = ParseCompressed(input)
if (tab == nil) then
dialog.ShowMessageBox('Error parsing compressed string.')
return nil
end
else
local start = 1
if startstr ~= '' then start = tonumber(startstr) end
tab = Compress(input,start)
end
return tab
end
-- ============================== End Reset Functions
ReadStructure()
WriteStructure()
ResetSS()