Profile
- Name
- Make 2 Helix 3 Sheets
- ID
- 103476
- Shared with
- Public
- Parent
- None
- Children
- Created on
- May 09, 2020 at 17:21 PM UTC
- Updated on
- May 09, 2020 at 17:21 PM UTC
- Description
Make a structure that has 2 helix in the first half and 3 sheets in the second. Add bands to help them form into a compact structure with helix on one side and sheets on the other.
Best for
Code
-- How to use this script to make two helix structure on one side and a three sheet on the other.
-- Step 1: Set k_pass to 1 and run the script
-- 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: Set k_pass to 2 and run this script again
-- This will setup bands and freeze the secondary structures
--
-- 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.
-- At some point unfreeze the secondary structures so they can change shape too.
--
-- Note: You can always run the script with k_pass set to 2 to setup the bonds and freezing again.
-- Note: You can fiddle with the loop length if you want shorter loops
k_pass = 2
k_helix_amino = "A" -- Helix loving amino acids are M,A,L,E,K. Set to "" to not change
k_loop_amino = "G" -- G is the most flexible amino acid. Set to "" to not change
k_sheet_edge_amino = "P" -- Found on the end of sheets. "P" also works.
k_sheet_middle_amino = "V" -- Other middle sheet options: V, I, T, Y, F, W,
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 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
print("User Residue Start: " .. user_residue_start)
print("User Residue Count: " .. user_residue_count)
return user_residue_count
end
function MakeMultipleSSTable(ss_type, ss_count, loop_size, start_idx, residue_count)
local non_end_loops = ss_count - 1
local length_non_end_loops = non_end_loops * loop_size
print("Non-end 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 ss = {}
local loop = {}
local last_idx = start_idx - 1
for idx = 1, ss_count do
if 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)
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 (k_helix_amino ~= "") then
print("Set Helix amino acids to " .. k_helix_amino)
SetAminoAcidRange(k_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 (k_sheet_edge_amino ~= "") then
print("Set Sheet edge amino acids to " .. k_sheet_edge_amino)
structure.SetAminoAcid(this_sheet.start, k_sheet_edge_amino)
structure.SetAminoAcid(this_sheet.finish, k_sheet_edge_amino)
end
if (k_sheet_middle_amino ~= "") then
print("Set Sheet middle amino acids to " .. k_sheet_middle_amino)
SetAminoAcidRange(k_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 (k_loop_amino ~= "") then
print("Set Loop amino acids to " .. k_helix_amino)
SetAminoAcidRange(k_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 PlaceBands(helix, sheets)
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)
end
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)
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)
-- corner_sep = math.sqrt(2) * 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
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 Main()
start_time = os.time()
local n_residues = structure.GetCount()
print("Residue Count: " .. n_residues)
-- Strategy: Make 2 helix in half the residues
-- Make 3 sheets in the other half, then combine
local k_helix_count = 2
local k_sheet_count = 3
local k_loop_size = 4
local user_residue_count = CountResidues()
local helix_residue_count = math.floor((user_residue_count - k_loop_size) / 2)
print("Helix residue count: ".. helix_residue_count)
local helix, loop = MakeMultipleHelixTable(k_helix_count, k_loop_size, 1, helix_residue_count)
local last_helix_idx = helix[#helix].finish
AddLoopToTable(loop, last_helix_idx + 1, k_loop_size)
local last_loop_idx = last_helix_idx + k_loop_size
-- Now make sheet tables
local sheet_residue_count = helix_residue_count
local sheets, loop2 = MakeMultipleSheetTable(k_sheet_count, k_loop_size, last_loop_idx + 1, sheet_residue_count)
local last_sheet_idx = sheets[#sheets].finish
loop = MergeTable(loop, loop2)
AddEndLoopIfNeeded(loop, last_sheet_idx)
if (k_pass == 1) then
print("First Pass")
MakeMultipleSS(helix, sheets, loop)
IdealizeAll()
save.SaveSecondaryStructure()
print("First Pass done - Do IdealizeSS from the GUI")
else
print("Second Pass")
PlaceBands(helix, sheets)
FreezeSS(helix, sheets)
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)