Icon representing a recipe

Recipe: Make Multiple Helix 1.0.0

created by Chris Klassen

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)

Comments