Profile
- Name
- Make 4 Helix Structures
- ID
- 103694
- Shared with
- Public
- Parent
- None
- Children
- None
- Created on
- July 10, 2020 at 14:50 PM UTC
- Updated on
- July 10, 2020 at 14:50 PM UTC
- Description
This will make four crude helix structures.
Best for
Code
-- How to use this script to make some helix structure on one side and some sheet on the other.
-- You can specify zero sheets if you only want helix structures.
-- Step 1: Run the script and set pass to 1
-- This will start the puzzle over and try to make the helix and sheet structures
--
-- Step 2: Go to each of the secondary structures and do "Idealize SS". This can't
-- be done in the script for whatever reason, so you'll need to do this by hand.
-- If this is a docking puzzle, you might want to move the user
-- portion away from docking point for now to avoid pointless collisions.
-- If you are not setting the helix structures to be all A's, then you may want to
-- wiggle a bit just to get rid of clashes inside the helix structures themselves.
--
-- Step 3: Run this script and set pass to 2
-- This freeze the secondary structures and setup bands. If wiggle is true, it will try to
-- wiggle into place as it sets the bands.
--
-- Step 4: Run wiggle until a shape forms with the two helix structures on one side and the
-- sheets on the other.
-- Sometimes this structure will not form as the secondary structures get in each other's way.
-- You might need to do some manual pulling, or selective enabling/disabling bands
-- or simply try again.
--
-- Step 5: Run whatever else you want to improve your score. Usually a mutate run and some stabilization.
-- At some point unfreeze the secondary structures so they can change shape too.
--
-- Note: You can always run the script with pass set to 2 and wiggle off to setup the bonds and freezing again.
k_cut_points = false
start_time = 0
function FindFirstAvailable()
for seg_idx = 1, structure.GetCount() do
if not structure.IsLocked(seg_idx) then
return seg_idx
end
end
return nil
end
function IdealizeAll()
selection.SelectAll()
structure.IdealizeSelected()
selection.DeselectAll()
end
function FreezeRange(from_seg_idx, to_seg_idx)
selection.DeselectAll()
for seg_idx = from_seg_idx, to_seg_idx do
selection.Select(seg_idx)
end
freeze.FreezeSelected(true, true)
selection.DeselectAll()
end
function UnfreezeRange(from_seg_idx, to_seg_idx)
selection.DeselectAll()
for seg_idx = from_seg_idx, to_seg_idx do
selection.Select(seg_idx)
end
freeze.UnfreezeSelected(true, true)
selection.DeselectAll()
end
function SetSecondaryStructureRange(ss, from_seg_idx, to_seg_idx)
selection.DeselectAll()
for seg_idx = from_seg_idx, to_seg_idx do
selection.Select(seg_idx)
end
structure.SetSecondaryStructureSelected (ss)
selection.DeselectAll()
end
function SetAminoAcidRange(aa1, from_seg_idx, to_seg_idx)
selection.DeselectAll()
for seg_idx = from_seg_idx, to_seg_idx do
selection.Select(seg_idx)
end
structure.SetAminoAcidSelected (aa1)
selection.DeselectAll()
end
function CountResidues()
local n_residues = structure.GetCount()
local user_residue_start = FindFirstAvailable()
local user_residue_count = structure.GetCount() - user_residue_start + 1
return user_residue_count
end
function MakeMultipleSSTable(ss_type, ss_count, loop_size, start_idx, residue_count)
local ss = {}
local loop = {}
if (ss_count < 1) then
return ss, loop
end
local non_end_loops = ss_count - 1
-- print("Between " .. ss_type .. " loop count " .. non_end_loops)
local length_non_end_loops = non_end_loops * loop_size
-- print("Between " .. ss_type .. " loops will be " .. length_non_end_loops .. " residues")
ss_size = math.floor((residue_count - length_non_end_loops) / ss_count)
print("Make " .. ss_type .. " of length " .. ss_size)
local last_idx = start_idx - 1
for ss_idx = 1, ss_count do
if ss_idx > 1 then
AddLoopToTable(loop, last_idx + 1, loop_size)
last_idx = last_idx + loop_size
end
local this_ss = {start = last_idx + 1, finish = last_idx + ss_size}
print(ss_type .. " start: " .. this_ss.start .. " finish: " .. this_ss.finish)
table.insert(ss, this_ss)
last_idx = this_ss.finish
end
return ss, loop
end
function AddEndLoopIfNeeded(loop, last_used_idx)
local n_residues = structure.GetCount()
if (last_used_idx < n_residues) then
AddLoopToTable(loop, last_used_idx + 1, n_residues - last_used_idx)
end
end
function MakeMultipleHelixTable(helix_count, loop_size, start_idx, residue_count)
return MakeMultipleSSTable("Helix", helix_count, loop_size, start_idx, residue_count)
end
function MakeMultipleSheetTable(sheet_count, loop_size, start_idx, residue_count)
return MakeMultipleSSTable("Sheet", sheet_count, loop_size, start_idx, residue_count)
end
function AddLoopToTable(loop_table, start_idx, loop_size)
local this_loop = {start = start_idx, finish = start_idx + loop_size - 1}
print("Loop start: " .. this_loop.start .. " finish: " .. this_loop.finish)
table.insert(loop_table, this_loop)
end
function MakeMultipleSS(helix, sheets, loop, helix_amino, loop_amino, sheet_edge_amino, sheet_middle_amino)
print("Start puzzle over")
puzzle.StartOver()
for idx = 1, #helix do
local this_helix = helix[idx]
print("Helix start: " .. this_helix.start .. " finish: " .. this_helix.finish)
SetSecondaryStructureRange("H", this_helix.start, this_helix.finish)
if (helix_amino ~= "") then
print("Set Helix amino acids to " .. helix_amino)
SetAminoAcidRange(helix_amino, this_helix.start, this_helix.finish)
end
end
for idx = 1, #sheets do
local this_sheet = sheets[idx]
print("Sheet start: " .. this_sheet.start .. " finish: " .. this_sheet.finish)
SetSecondaryStructureRange("E", this_sheet.start, this_sheet.finish)
if (sheet_edge_amino ~= "") then
print("Set Sheet edge amino acids to " .. sheet_edge_amino)
structure.SetAminoAcid(this_sheet.start, sheet_edge_amino)
structure.SetAminoAcid(this_sheet.finish, sheet_edge_amino)
end
if (sheet_middle_amino ~= "") then
print("Set Sheet middle amino acids to " .. sheet_middle_amino)
SetAminoAcidRange(sheet_middle_amino, this_sheet.start+1, this_sheet.finish-1)
end
end
for idx = 1, #loop do
print("Loop start: " .. loop[idx].start .. " finish: " .. loop[idx].finish)
SetSecondaryStructureRange("L", loop[idx].start, loop[idx].finish)
if (loop_amino ~= "") then
print("Set Loop amino acids to " .. loop_amino)
SetAminoAcidRange(loop_amino, loop[idx].start, loop[idx].finish)
end
end
end
function AddBand(name, start_idx, finish_idx, separation)
print("Add " .. name .. " band")
local band_idx = band.AddBetweenSegments(start_idx, finish_idx)
print( "Band: " .. band_idx)
band.SetGoalLength(band_idx, separation)
band.SetStrength(band_idx, 5)
end
function WiggleSelected(from_seg_idx, to_seg_idx)
selection.DeselectAll()
for seg_idx = from_seg_idx, to_seg_idx do
selection.Select(seg_idx)
end
structure.LocalWiggleSelected(5, true, false)
end
function PlaceBands(helix, sheets, wiggle)
band.DeleteAll()
local length_helix = structure.GetDistance(helix[1].start, helix[1].finish)
local separation = length_helix --math.floor(length_helix * 2 / 3)
local first_helix, second_helix
for helix_idx = 1, #helix - 1 do
first_helix = helix_idx
second_helix = helix_idx + 1
AddBand("helix anchor", helix[first_helix].start, helix[second_helix].finish, separation)
AddBand("helix end", helix[first_helix].finish, helix[second_helix].start, separation)
if wiggle then
WiggleSelected(helix[first_helix].finish, helix[second_helix].start)
end
end
if (#sheets > 0) then
AddBand("helix to sheet anchor", helix[#helix].start, sheets[1].finish, separation)
AddBand("helix to sheet end", helix[#helix].finish, sheets[1].start, separation)
for sheet_idx = 1, #sheets - 1 do
first_sheet = sheet_idx
second_sheet = sheet_idx + 1
AddBand("sheet anchor", sheets[first_sheet].start, sheets[second_sheet].finish, separation)
AddBand("sheet end", sheets[first_sheet].finish, sheets[second_sheet].start, separation)
if wiggle then
WiggleSelected(sheets[first_sheet].finish, sheets[second_sheet].start)
end
end
AddBand("sheet to helix anchor", sheets[#sheets].start, helix[1].start, separation)
AddBand("helix to sheet end", sheets[#sheets].finish, helix[1].finish, separation)
AddBand("cross band", helix[1].start, sheets[2].finish, separation)
AddBand("cross band", helix[1].finish, sheets[2].start, separation)
AddBand("cross band", helix[2].finish, sheets[2].finish, separation)
AddBand("cross band", helix[2].start, sheets[2].start, separation)
end
-- corner_sep = math.sqrt(2) * separation
end
function FreezeSS(ss1, ss2)
freeze.UnfreezeAll()
for ss_idx = 1, #ss1 do
FreezeRange(ss1[ss_idx].start, ss1[ss_idx].finish)
end
for ss_idx = 1, #ss2 do
FreezeRange(ss2[ss_idx].start, ss2[ss_idx].finish)
end
end
function MergeTable(table1, table2)
local tableMerge = {}
for idx = 1, #table1 do
table.insert(tableMerge, table1[idx])
end
for idx = 1, #table2 do
table.insert(tableMerge, table2[idx])
end
return tableMerge
end
function MakeCutPointsBetweenSS()
local last_ss = ""
for seg_idx = 1, structure.GetCount() do
ss = structure.GetSecondaryStructure(seg_idx)
-- Where secondary structures change, make a cut point
if (last_ss ~= "" and ss ~= last_ss) then
structure.InsertCut(seg_idx - 1)
end
last_ss = ss
end
end
function MakeAnchorBand(origin, x_seg, y_seg)
local rho = 0.01 -- Right where it is
local theta = math.pi/2 -- In the reference plane
local phi = 0
local band_idx = band.Add(origin, x_seg, y_seg, rho, theta, phi)
band.SetGoalLength(band_idx, 0)
band.SetStrength(band_idx, 10) -- Really hold it down
end
function MakeBandToGuideBand(seg_idx, guide_band_idx)
local band_idx = band.AddToBandEndpoint(seg_idx, guide_band_idx)
band.SetGoalLength(band_idx, 0)
band.SetStrength(band_idx, 1) -- Not too strong
--band.Delete(guide_band_idx)
band.Disable(guide_band_idx)
return band_idx
end
function WiggleIntoPlace(bands, wiggle_delta)
wiggle_delta = wiggle_delta or 0.15
local delta
local is_good
local iter = 0
repeat
iter = iter + 1
structure.WiggleAll(1, true, true)
is_good = true
for bidx = 1, #bands do
local bnd = bands[bidx]
print(" Bidx " .. bidx .. " Band " .. bnd)
if (band.IsEnabled(bnd)) then
delta = math.abs(band.GetLength(bnd) - band.GetGoalLength(bnd))
is_good = is_good and delta < wiggle_delta
print(" Band " .. bnd .. " Delta " .. delta)
end
end
print(" Iter is " .. iter .. " Delta is " .. delta .. " Goal is " .. wiggle_delta .. " Good is " .. (is_good and "true" or "false"))
until is_good
end
function PlaceSS(ss1, ss2, wiggle)
band.DeleteAll()
local wiggle_iterations = 5
local start = ss1[1].start
local finish = ss1[1].finish
local y_seg = ss1[2].finish
local desired_distance = structure.GetDistance(ss1[1].finish, ss1[2].start)
-- Pin the start of the first helix
MakeAnchorBand(start, finish, y_seg)
-- Pin the other end
MakeAnchorBand(finish, start, y_seg)
local band_idx = band.Add(start, finish, y_seg, desired_distance, math.pi/2, math.pi/2)
print ("Band A ".. band_idx)
local band1 = MakeBandToGuideBand(ss1[2].finish, band_idx)
print ("Band 1 ".. band1)
band_idx = band.Add(finish, start, y_seg, desired_distance, math.pi/2, math.pi/2)
print ("Band B ".. band_idx)
local band2 = MakeBandToGuideBand(ss1[2].start, band_idx)
print ("Band 2 ".. band2)
if wiggle then
structure.WiggleAll(wiggle_iterations)
-- WiggleIntoPlace({band1, band2}, 1)
FreezeRange(ss1[1].finish+1, ss1[2].start-1)
end
band_idx = band.Add(start, finish, y_seg, desired_distance * math.sqrt(2), 3*math.pi/4, math.pi/2)
MakeBandToGuideBand(ss1[3].start, band_idx)
band_idx = band.Add(finish, start, y_seg, desired_distance * math.sqrt(2), math.pi/4, math.pi/2)
MakeBandToGuideBand(ss1[3].finish, band_idx)
if wiggle then
structure.WiggleAll(wiggle_iterations)
FreezeRange(ss1[2].finish+1, ss1[3].start-1)
end
band_idx = band.Add(start, finish, y_seg, desired_distance, math.pi, math.pi/2)
MakeBandToGuideBand(ss1[4].finish, band_idx)
band_idx = band.Add(finish, start, y_seg, desired_distance, 0, math.pi/2)
MakeBandToGuideBand(ss1[4].start, band_idx)
if wiggle then
structure.WiggleAll(wiggle_iterations * 2)
UnfreezeRange(ss1[1].finish+1, ss1[2].start-1)
UnfreezeRange(ss1[2].finish+1, ss1[3].start-1)
end
end
function MakeTwistyBand(seg_idx, seg_start)
-- Bases at 90/90 makes a helicopter
local rho = 6.67 * (seg_idx - seg_start + 4) / 4
-- Starting angle out. Shrink for each later node.
local start_theta = 15 -- 90 is the reference plane
local theta_deg_rotate = start_theta / ((seg_idx-seg_start+2)/2) -- math.fmod(90 * seg_idx, 360)
local theta_deg = theta_deg_rotate > 180 and theta_deg_rotate - 180 or theta_deg_rotate
local theta = math.rad(theta_deg)
-- Makes four around
local base_phi = 90 -- 340 -- 90 produces a helicopter
local phi_deg = math.fmod(base_phi + 90 * (seg_idx - seg_start), 360)
-- local phi_deg = math.fmod(base_phi + 45 * (seg_idx - 1), 180)
local phi = math.rad(phi_deg)
print ("Twist band seg: " .. seg_idx .. " rho: " .. rho .. " theta: " .. theta_deg .. " phi: " .. phi_deg )
local ref_band_idx = band.Add(seg_start, seg_start+1, seg_start+2, rho, theta, phi, 1)
band.SetStrength(ref_band_idx, 1)
band.Disable(ref_band_idx)
local band_idx = band.AddToBandEndpoint(seg_idx, ref_band_idx, 3)
band.SetGoalLength(band_idx, 0)
band.SetStrength(band_idx, 10)
-- band.Delete(ref_band_idx)
-- print("Disable twist band")
-- band.Disable(band_idx)
band.Enable(band_idx)
return band_idx
end
-- Band on another atom to try to refine twist
function MakeTwistyBandOtherAtom(seg_idx, seg_start)
-- Bases at 90/90 makes a helicopter
local rho = 6.67 * (seg_idx - seg_start + 4) / 4 - 2
-- Starting angle out. Shrink for each later node.
local start_theta = 15 + 1 -- 90 is the reference plane
local theta_deg_rotate = start_theta / ((seg_idx - seg_start + 2)/2) -- math.fmod(90 * seg_idx, 360)
local theta_deg = theta_deg_rotate > 180 and theta_deg_rotate - 180 or theta_deg_rotate
local theta = math.rad(theta_deg)
-- Makes four around
local base_phi = 90 -- 340 -- 90 produces a helicopter
local phi_deg = math.fmod(base_phi + 90 * (seg_idx - seg_start), 360)
-- local phi_deg = math.fmod(base_phi + 45 * (seg_idx - 1), 180)
local phi = math.rad(phi_deg)
print ("Twist band seg: " .. seg_idx .. " rho: " .. rho .. " theta: " .. theta_deg .. " phi: " .. phi_deg )
local ref_band_idx = band.Add(seg_start, seg_start+1, seg_start+2, rho, theta, phi, 1)
band.SetStrength(ref_band_idx, 1)
band.Disable(ref_band_idx)
local band_idx = band.AddToBandEndpoint(seg_idx, ref_band_idx, 1)
band.SetGoalLength(band_idx, 0)
band.SetStrength(band_idx, 10)
-- band.Delete(ref_band_idx)
-- print("Disable twist band")
-- band.Disable(band_idx)
band.Enable(band_idx)
return band_idx
end
function FreezeAllOutsideSS(ss)
freeze.UnfreezeAll()
if (ss.start > 1) then
FreezeRange(1, ss.start-1)
end
FreezeRange(ss.finish, structure.GetCount())
end
function TableConcat(t1,t2)
for idx = 1, #t2 do
table.insert(t1, t2[idx])
end
return t1
end
function MakeTwistyBands(helix)
local twist_bands = {}
local twist_band_alt = {}
for seg_idx = helix.start, helix.finish do
twist_bands[seg_idx] = MakeTwistyBand(seg_idx, helix.start)
twist_band_alt[seg_idx] = MakeTwistyBandOtherAtom(seg_idx, helix.start)
end
local bands = TableConcat(twist_bands, twist_band_alt)
return bands
end
function ShapeSS(helix, sheet)
wiggle_iterations = 10
for ss_idx = 1, #helix do
bands = MakeTwistyBands(helix[ss_idx])
FreezeAllOutsideSS(helix[ss_idx])
-- WiggleIntoPlace(bands)
structure.WiggleAll(wiggle_iterations)
band.DeleteAll()
end
freeze.UnfreezeAll()
end
-- Compute length by finding the length of each distinct SS
-- Would be better if loops were treated as a sum of the lengths of each AA in the loop
function ComputeLength()
local first = FindFirstAvailable()
local last_ss = ""
local last_idx = first
local seg_idx
local length = 0
for seg_idx = first, structure.GetCount() do
local ss = structure.GetSecondaryStructure(seg_idx)
if last_ss ~= ss then
local ss_length = structure.GetDistance(last_idx, seg_idx)
print( "SS " .. ss .. " length " .. ss_length)
length = length + ss_length
last_idx = seg_idx
last_ss = ss
end
end
length = length + structure.GetDistance(last_idx, structure.GetCount())
return length
end
function IdealizeRange(from_seg_idx, to_seg_idx)
print("Idealizing " .. from_seg_idx .. " to " .. to_seg_idx)
selection.DeselectAll()
for seg_idx = from_seg_idx, to_seg_idx do
selection.Select(seg_idx)
end
structure.IdealizeSelected()
selection.DeselectAll()
end
function IdealizeLoops()
local first = FindFirstAvailable()
local last_ss = ""
local last_idx = first
local seg_idx
local length = 0
for seg_idx = first, structure.GetCount() do
local ss = structure.GetSecondaryStructure(seg_idx)
if last_ss ~= ss then
if last_ss == "L" then
IdealizeRange(last_idx, seg_idx)
end
last_idx = seg_idx
last_ss = ss
end
end
if last_ss == "L" then
IdealizeRange(last_idx, structure.GetCount())
end
end
function SetPullStraightBands()
local first = FindFirstAvailable()
local distance_between_aas = structure.GetDistance(first, first+1)
local current_length = structure.GetDistance(first, structure.GetCount())
local residue_count = structure.GetCount() - first
local desired_length = ComputeLength() --residue_count * distance_between_aas -- If everything were straight
local rho = (desired_length - current_length) / 2
print("Desired length " .. desired_length)
print("Current length is " .. current_length)
-- print("Distance between AA is " .. distance_between_aas)
print("Rho is " .. rho)
local theta = math.rad( 90 ) -- In the reference plane
local phi = math.rad( 180 )
local band_idx = band.Add(first, structure.GetCount(), first+1, rho, theta, phi)
band.SetGoalLength(band_idx, 0)
band.SetStrength(band_idx, 1)
band_idx = band.Add(structure.GetCount(), first, first+1, rho, theta, phi)
band.SetGoalLength(band_idx, 0)
band.SetStrength(band_idx, 1)
end
function PullStraight()
band.DeleteAll()
SetPullStraightBands()
structure.WiggleAll(1, true, false)
IdealizeLoops()
band.DeleteAll()
end
function GetParameters ()
local dlog = dialog.CreateDialog("Make Basic Secondary Structure 1.1")
dlog.lb1 = dialog.AddLabel("1 to make SS, idealize SS in UI, then 2 to shape SS.")
dlog.pass = dialog.AddSlider("Pass", 0, 0, 3, 0)
dlog.lb2 = dialog.AddLabel("0 - All, 1 = Build, 2 = Make SS, 3 = Shape")
dlog.configuration = dialog.AddSlider("Configuration", 1, 1, 2, 0)
dlog.lb3a = dialog.AddLabel("1 = 4 Helix Pack") -- 3 Helix Pack, 6 Helix Pack, 3 Helix + 2 Sheet. Others?
dlog.loop_size = dialog.AddSlider("Loop Size", 3, 1, 10, 0)
dlog.helix_amino = dialog.AddTextbox("Helix AA1", "A")
dlog.lb4 = dialog.AddLabel("Helix loving AAs are M,A,L,E,K. Blank = don't change.")
dlog.loop_amino = dialog.AddTextbox("Loop AA1", "G")
dlog.lb5 = dialog.AddLabel("G is most flexible. A is also popular. Blank = don't change.")
dlog.sheet_edge_amino = dialog.AddTextbox("Sheet Edge AA1", "P")
dlog.sheet_middle_amino = dialog.AddTextbox("Sheet Middle AA1", "V")
dlog.lb6 = dialog.AddLabel("Middle sheet options: V, I, T, Y, F, W")
dlog.wiggle = dialog.AddCheckbox("Wiggle", true)
dlog.ok = dialog.AddButton("OK", 1)
dlog.cancel = dialog.AddButton("Cancel", 0)
if (dialog.Show(dlog) > 0) then
return dlog
else
return nil
end
end
function ReadConfig(config_value)
if (config_value > 0) then -- Change this to support more configurations
return 4, 0
end
return nil
end
function Main()
start_time = os.time()
local n_residues = structure.GetCount()
print("Residue Count: " .. n_residues)
local first_avail = FindFirstAvailable()
print("First Editable Residue: " .. first_avail)
parameters = GetParameters()
if ( parameters == nil ) then
return -- graceful exit
end
local helix_count, sheet_count = ReadConfig(parameters.configuration.value)
local loop_size = parameters.loop_size.value
local user_residue_count = CountResidues()
print("User Residue Count: " .. user_residue_count)
local helix_residue_count = sheet_count > 0 and math.floor((user_residue_count - loop_size) / 2) or user_residue_count
print("Helix Residue Count: ".. helix_residue_count)
local helix, loop = MakeMultipleHelixTable(helix_count, loop_size, first_avail, helix_residue_count)
local last_helix_idx = #helix > 0 and helix[#helix].finish or 0
if (sheet_count > 0) then
AddLoopToTable(loop, last_helix_idx + 1, loop_size)
end
local last_loop_idx = last_helix_idx + loop_size
-- Now make sheet tables
local sheet_residue_count = helix_residue_count
local sheets, loop2 = MakeMultipleSheetTable(sheet_count, loop_size, last_loop_idx + 1, sheet_residue_count)
local last_sheet_idx = #sheets > 0 and sheets[#sheets].finish or last_helix_idx
loop = MergeTable(loop, loop2)
AddEndLoopIfNeeded(loop, last_sheet_idx)
local pass = parameters.pass.value
if (pass == 1 or pass == 0) then
print("Set Aminos")
local helix_amino = parameters.helix_amino.value
local loop_amino = parameters.loop_amino.value
local sheet_edge_amino = parameters.sheet_edge_amino.value
local sheet_middle_amino = parameters.sheet_middle_amino.value
MakeMultipleSS(helix, sheets, loop, helix_amino, loop_amino, sheet_edge_amino, sheet_middle_amino)
-- IdealizeAll()
save.SaveSecondaryStructure()
if (k_cut_points) then
MakeCutPointsBetweenSS()
end
print("Set Aminos done")
end
if (pass == 2 or pass == 0) then
print("Shape Secondary Structures")
ShapeSS(helix, sheets)
print("Shape Secondary Structures done")
end
if (pass == 3 or pass == 0) then
print("Place Secondary Structures")
-- FreezeSS(helix, sheets)
-- PullStraight()
PlaceSS(helix, sheets, parameters.wiggle.value)
-- PlaceBands(helix, sheets, parameters.wiggle)
print("Place Secondary Structures done")
end
print("End")
Cleanup()
end
-- Cleanup for regular run or error
function Cleanup()
print( "Cleaning up" )
local end_time = os.time()
print ( "Elapsed time: " .. os.difftime(end_time, start_time) .. " secs" )
end
function ErrorHandler(str)
print( "Error " .. str )
-- Do error handling here
Cleanup()
end
--main ()
xpcall(Main, ErrorHandler)