Icon representing a recipe

Recipe: Helix Rebuild 2

created by spvincent

Profile


Name
Helix Rebuild 2
ID
45788
Shared with
Public
Parent
None
Children
Created on
March 21, 2013 at 00:21 AM UTC
Updated on
March 21, 2013 at 00:21 AM UTC
Description

See first comment

Best for


Code


-- Globals original_secondary_structure = {} helix_starts = {} helix_ends = {} use_helix = {} n_helices = 0 n_residues = 0 loop_spacer = 3 co_rebuild = false clash_importance_during_rebuild = 0.3 n_rebuilds = 5 fuze_threshold = 4 -- For design mutate_not_shake = false -- Quicksave slots kOriginalStructureOrNewBest = 1 -- the starting structure, or any subsequent improvement, will be stored in this quicksave slot kTemp = 5 kQs10 = 10 -- the rebuilt structure that comes closest in score to the original without actually exceeding it -- will be stored here function roundto3 ( i ) -- printing convenience return i - i % 0.001 end function GetScore () score = current.GetEnergyScore () return score end function IsPuzzleMutable () for i = 1 , n_residues do if ( structure.IsMutable ( i ) ) then return true end end return false end function get_helices () within_helix = false for i = 1, n_residues do if ( structure.GetSecondaryStructure ( i ) == "H" ) then if ( within_helix == false ) then -- start of a new helix within_helix = true n_helices = n_helices + 1 helix_starts [ n_helices ] = i end elseif ( within_helix == true ) then -- end of a helix within_helix = false helix_ends [ n_helices ] = i -1 end end -- for i if ( within_helix == true ) then helix_ends [ n_helices ] = n_residues end end function IsWithinASelectedHelix ( residue ) -- When for i = 1 , n_helices do if ( use_helix [ i ] == true ) then if ( ( residue >= helix_starts [ i ] ) and ( residue >= helix_ends [ i ] ) ) then return true end end end return false end function ConvertToLoop ( first , last ) for k = first , last do if ( original_secondary_structure [ k ] ~= "L" ) then if ( IsWithinASelectedHelix ( k ) == false ) then selection.SelectRange ( k , k ) structure.SetSecondaryStructureSelected ( "L" ) end end end end function pseudorandom ( score ) -- Returns a pseudorandom number >= 0 and < 1. -- Based on the fractional part of the score if ( score >= 0 ) then return score % 1 else return (-score ) % 1 end end function MiniFuse () selection.SelectAll () score_in_kTemp = GetScore() save.Quicksave ( kTemp) selection.SelectAll () behavior.SetClashImportance ( 0.07 ) structure.ShakeSidechainsSelected ( 1 ) behavior.SetClashImportance ( 1 ) structure.WiggleSelected ( 8 ) score = GetScore() if ( score < score_in_kTemp ) then save.Quickload ( kTemp ) end end function nudge ( score ) selection.SelectAll () recentbest.Save () behavior.SetClashImportance ( 0.2 + 0.2 * pseudorandom ( score ) ) structure.WiggleSelected ( 1 ) behavior.SetClashImportance ( 1 ) structure.WiggleSelected ( 8 ) recentbest.Restore () end function ShakeWiggleShakeNudge () -- returns the score after doing a SWSW: short-circuiting if things don't look promising if ( false ) then structure.MutateSidechainsSelected ( 1 ) else structure.ShakeSidechainsSelected ( 2 ) end score_after_first_shake = GetScore () structure.WiggleSelected ( 12 ) score_after_wiggle = GetScore () if ( score_after_wiggle - score_after_first_shake < 10 and best_score - score_after_wiggle > 30 ) then -- The wiggle got stuck and didn't achieve anything nudge ( score_after_wiggle ) score_after_wiggle = GetScore () end if ( mutate_not_shake == true ) then structure.MutateSidechainsSelected ( 1 ) else structure.ShakeSidechainsSelected ( 1 ) end score_after_second_shake = GetScore () if ( score_after_second_shake - score_after_wiggle > 0.5 ) then nudge ( score_after_second_shake ) score = GetScore () return score else return score_after_second_shake end end function ConstructSpacers ( start_helix , end_helix ) start_idx = start_helix - loop_spacer if ( start_idx < 1 ) then start_idx = 1 end if ( start_helix > 1 ) then ConvertToLoop ( start_idx , start_helix - 1 ) end end_idx = end_helix + loop_spacer if ( end_idx > n_residues ) then end_idx = n_residues end if ( end_helix < n_residues ) then ConvertToLoop ( end_helix + 1 , end_idx ) end return start_idx , end_idx end function rebuild_helix ( start_helix , end_helix ) improvement_made = false save.Quickload ( kOriginalStructureOrNewBest ) rb = rb + 1 best_score = GetScore () selection.DeselectAll () if ( co_rebuild == true ) then print ( "rb : " .. rb ) for i = 1 , n_helices do if ( use_helix [ i ] == true ) then start_idx , end_idx = ConstructSpacers ( helix_starts [ i ] , helix_ends [ i ] ) selection.SelectRange ( start_idx , end_idx ) end end else print ( "rb : " .. rb .. " (" .. start_helix .. "-" .. end_helix .. ")" ) start_idx , end_idx = ConstructSpacers ( start_helix , end_helix ) selection.SelectRange ( start_idx , end_idx ) end behavior.SetClashImportance ( clash_importance_during_rebuild ) recentbest.Save () structure.RebuildSelected ( 1 ) score_after_rebuild = GetScore () recentbest.Save () if ( math.abs ( score_after_rebuild - best_score ) < 1e-5 ) then -- If the scores are still equal we probably have a locked segment return false end structure.RebuildSelected ( 5 ) recentbest.Restore () behavior.SetClashImportance ( 1.0 ) selection.SelectAll () curr_score = ShakeWiggleShakeNudge () if ( curr_score > best_score - fuze_threshold ) then MiniFuse () print ( " Fuze gain : " .. roundto3 ( GetScore () - curr_score ) ) end curr_score = GetScore () if ( curr_score > best_score ) then improvement_made = true best_score = curr_score save.LoadSecondaryStructure () save.Quicksave ( kOriginalStructureOrNewBest ) print ( "Improvement to " .. roundto3 ( best_score ) ) end curr_score = GetScore () if ( curr_score > qs10_best_score and improvement_made == false ) then qs10_best_score = curr_score save.Quicksave ( kQs10 ) print ( "Storing " .. roundto3 ( qs10_best_score ) .. " in " .. kQs10 ) end save.LoadSecondaryStructure () return true end function get_parameters () local dlog = dialog.CreateDialog ( "Helix rebuild 2" ) dlog.loop_spacer = dialog.AddSlider ( "Loop spacer" , loop_spacer , 0 , 6 , 0 ) for i = 1 , n_helices do dlog [ "helix" .. i ] = dialog.AddCheckbox ( helix_starts [ i ] .. "-" .. helix_ends [ i ] , true ) end dlog.co_rebuild = dialog.AddCheckbox ( "Co-rebuild" , co_rebuild ) dlog.n_rebuilds = dialog.AddSlider ( "Rebuilds" , n_rebuilds , 1 , 20 , 0 ) dlog.ci = dialog.AddSlider ( "Clash importance" , clash_importance_during_rebuild , 0 , 1.0 , 2 ) dlog.fzth = dialog.AddSlider ( "Fuze threshold" , fuze_threshold , 0 , 20 , 0 ) design_puzzle = IsPuzzleMutable () if ( design_puzzle == true ) then dlog.mutate= dialog.AddCheckbox ( "Mutate not shake" , false ) end dlog.ok = dialog.AddButton ( "OK" , 1 ) dlog.cancel = dialog.AddButton ( "Cancel" , 0 ) if ( dialog.Show ( dlog ) > 0 ) then loop_spacer = dlog.loop_spacer.value for i = 1 , n_helices do use_helix [ i ] = dlog [ "helix" .. i ].value end co_rebuild = dlog.co_rebuild.value if ( design_puzzle == true ) then mutate_not_shake = dlog.mutate.value end n_rebuilds = dlog.n_rebuilds.value clash_importance_during_rebuild = dlog.ci.value fuze_threshold = dlog.fzth.value return true else return false end end function main () print ( "Helix rebuild 2" ) band.DisableAll () n_residues = structure.GetCount () for i = 1, n_residues do original_secondary_structure [ i ] = structure.GetSecondaryStructure ( i ) end save.SaveSecondaryStructure () behavior.SetClashImportance ( 1 ) best_score = GetScore () print ( "Start score : " .. roundto3 ( best_score ) ) get_helices () for i = 1 , n_helices do print ( "Helix " .. i .." : " .. helix_starts [ i ] .. "-" .. helix_ends [ i ] ) use_helix [ i ] = false end qs10_best_score = 0 if ( get_parameters () == false ) then print ( "error" ) error () end -- Check that at least one helix was selected found = false i = 1 while ( i <= n_helices and found == false ) do if ( use_helix [ i ] == true ) then found = true end i = i + 1 end if ( found == false ) then print ( "No helix selected" ) error () end rb = 0 save.Quicksave ( kOriginalStructureOrNewBest ) while ( true ) do for i = 1 , n_helices do if ( use_helix [ i ] == true ) then rebuild_helix ( helix_starts [ i ] , helix_ends [ i ] ) end end end end function cleanup () print ( "Cleaning up" ) behavior.SetClashImportance ( 1.0 ) save.Quickload ( kOriginalStructureOrNewBest ) band.EnableAll () end --main () xpcall ( main , cleanup )

Comments


spvincent Lv 1

This script is probably most usefully used in the early/middle game (although the chess analogy can be pushed too far).

Algorithm outline

For each helix, bracket it with a loop on either end, rebuild it and the loop spacers several times at low CI, take the highest scoring result and then do Shake, Wiggle, Shake, nudging the protein slightly if the wiggle gets stuck. If the score is reasonably close to the best score, do a Fuze.

Loop spacer

The length of the loops at either end of the helix are to be. The greater the value, the more freedom there is for the helix to adopt new configurations but the less likely you are to get local refinement.

Helix list

A list of check boxes showing the helices in the protein.

Corebuild

If checked, all selected helices will be rebuilt together. this setting was intended for the case where there were two antiparallel helices that might beneficially be rebuilt together but I've yet to see a case where it produces a gain.

Number of rebuilds

How many times to rebuild the helix before Shaking, etc.

Clash Importance

The CI during rebuild

Fuze Threshold

How many points within the original score before attempting a Fuze

Mutate not Shake

For design puzzles only: If set does a Mutate rather a Shake (i.e. does Shake/Wiggle/Mutate)