Profile
- Name
- Make Multiple Helix 1.0.0
- ID
- 103495
- Shared with
- Public
- Parent
- None
- Children
- None
- Created on
- May 14, 2020 at 15:29 PM UTC
- Updated on
- May 14, 2020 at 15:29 PM UTC
- Description
An initial phase script to divide a blank protein into n helix structures.
Best for
Code
-- How to use this script to make an n-helix block
-- This is meant for a docking type puzzle like 1831 Corona Virus Bind
-- Step 1: Set k_pass to 1 and run the script
-- This will start the puzzle over and try to make 4 evenly spaced
-- helix structures.
--
-- Step 2: Go to each of the helix structures and do "IdealizeSS". This can't
-- be done in the script for whatever reason, so need to do this by hand.
-- If this is a docking puzzle, you might want to move the user_residue_count
-- portion away from docking point for now.
-- If you are not setting the helix 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 helix structures
--
-- Step 4: Run wiggle until the desired shape forms.
-- Sometimes a shape will not form as the helix 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 helix structures so they can change shape too.
-- Also at some point, move the user structure back into place to dock it.
--
-- Note: You can always run the script with k_pass set to 2 to setup the bonds and freezing again.
k_pass = 1
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_helix_count = 3 -- how many helix to make
k_loop_size = 3 -- how big to make intervening loops
start_time = 0
function FindFirstAvailable()
local seg_idx
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()
local seg_idx
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()
local seg_idx
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()
local seg_idx
for seg_idx = from_seg_idx, to_seg_idx do
selection.Select(seg_idx)
end
structure.SetAminoAcidSelected (aa1)
selection.DeselectAll()
end
function MakeMultipleHelixTable(helix_count, loop_size)
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)
local non_end_loops = helix_count - 1
local length_non_end_loops = non_end_loops * loop_size
print("Non-end loops will be " .. length_non_end_loops .. " residues")
local helix_size = math.floor((user_residue_count - length_non_end_loops) / helix_count)
print("Make four helix of length " .. helix_size)
local helix = {}
local loop = {}
local last_idx = user_residue_start - 1
local idx
for idx = 1, helix_count do
if idx > 1 then
this_loop = {start = last_idx + 1, finish = last_idx + loop_size}
print("Loop start: " .. this_loop.start .. " finish: " .. this_loop.finish)
table.insert(loop, this_loop)
last_idx = last_idx + k_loop_size
end
local this_helix = {start = last_idx + 1, finish = last_idx + helix_size}
print("Helix start: " .. this_helix.start .. " finish: " .. this_helix.finish)
table.insert(helix, this_helix)
last_idx = this_helix.finish
end
if (last_idx + 1 < structure.GetCount()) then
local this_loop = {start = last_idx + 1, finish = last_idx + loop_size}
print("Loop start: " .. this_loop.start .. " finish: " .. this_loop.finish)
table.insert(loop, this_loop)
end
return helix, loop
end
function MakeMultipleHelix(helix, loop)
print("Start puzzle over")
puzzle.StartOver()
local idx
for idx = 1, #helix do
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, #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 IsEven(an_integer)
return math.floor(an_integer/2) == an_integer/2
end
function AddBand(start_idx, finish_idx, separation)
local band_idx = band.AddBetweenSegments(start_idx, finish_idx)
print( "Band: " .. band_idx .. " from " .. start_idx .. " to " .. finish_idx)
band.SetGoalLength(band_idx, separation)
band.SetStrength(band_idx, 5)
end
function PlaceBands(helix)
band.DeleteAll()
local length_helix = structure.GetDistance(helix[1].start, helix[1].finish)
local separation = length_helix
local helix_idx
for helix_idx = 1, k_helix_count do
local flip = true
local first_helix = helix_idx
local second_helix = helix_idx + 1
if (second_helix > k_helix_count) then
second_helix = 1
flip = IsEven(#helix)
end
if (flip) then
AddBand(helix[first_helix].start, helix[second_helix].finish, separation)
AddBand(helix[first_helix].finish, helix[second_helix].start, separation)
else
AddBand(helix[first_helix].finish, helix[second_helix].finish, separation)
AddBand(helix[first_helix].start, helix[second_helix].start, separation)
end
end
-- Need to have more than 4 helix structures to need more bands
if (#helix < 4) then
return
end
-- This logic assumes we are trying to make two sets of helix structures across from each other
-- like in a six-pack
if (IsEven(#helix)) then
print("Connecting Even Number of Helix")
local corner_sep = math.sqrt(2) * separation
local half = math.floor(#helix/2)
for helix_idx = 1, half do
local other_helix_id = #helix + 1 - helix_idx
AddBand(helix[helix_idx].start, helix[other_helix_id].finish, corner_sep)
AddBand(helix[helix_idx].finish, helix[other_helix_id].start, corner_sep)
end
else
print("Connecting Odd Number of Helix")
local half = math.floor(#helix/2) + 1
for helix_idx = 2, half - 1 do
local other_helix_id = #helix + 1 - helix_idx
if (other_helix_id <= #helix and other_helix_id ~= helix_idx) then
AddBand(helix[helix_idx].start, helix[other_helix_id].start, separation)
AddBand(helix[helix_idx].finish, helix[other_helix_id].finish, separation)
end
other_helix_id = #helix + 2 - helix_idx
if (other_helix_id <= #helix and other_helix_id ~= helix_idx) then
AddBand(helix[helix_idx].start, helix[other_helix_id].finish, separation)
AddBand(helix[helix_idx].finish, helix[other_helix_id].start, separation)
end
end
end
end
function FreezeHelix(helix)
freeze.UnfreezeAll()
local helix_idx
for helix_idx = 1, #helix do
FreezeRange(helix[helix_idx].start, helix[helix_idx].finish)
end
end
function Main()
start_time = os.time()
local n_residues = structure.GetCount()
print("Residue Count: " .. n_residues)
local helix, loop = MakeMultipleHelixTable(k_helix_count, k_loop_size)
if (k_pass == 1) then
print("First Pass")
MakeMultipleHelix(helix, loop)
IdealizeAll()
save.SaveSecondaryStructure()
print("First Pass done - Do IdealizeSS from the GUI")
else
print("Second Pass")
PlaceBands(helix)
FreezeHelix(helix)
end
print("End")
Cleanup()
end
-- Cleanup for regular run or error
function Cleanup()
print( "Cleaning up" )
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
xpcall(Main, ErrorHandler)