Icon representing a recipe

Recipe: Helix Rebuild 4.0

created by spvincent

Profile


Name
Helix Rebuild 4.0
ID
48811
Shared with
Public
Parent
None
Children
Created on
April 07, 2014 at 20:42 PM UTC
Updated on
April 07, 2014 at 20:42 PM UTC
Description

See first comment

Best for


Code


-- Globals original_secondary_structure = {} fixed_residues = {} helix_starts = {} helix_ends = {} use_helix = {} n_helices = 0 n_residues = 0 loop_spacer = 3 n_rebuilds = 6 mutate_not_shake = false test_for_credit = false -- Quicksave slots kOriginalStructureOrNewBest = 1 -- the starting structure, or any subsequent improvement, will be stored in this quicksave slot kBestPostRebuild_a = 2 kBestPostRebuild_b = 3 kBestPostRebuild_a_post_wiggle = 4 kWiggleDuration = 12 inner_cylinder = {} outer_cylinder = {} inner_cylinder_radius = 12 outer_cylinder_radius = 16 function r3 ( 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 ) 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 GetListOfFixedResidues () for i = 1 , n_residues do fixed_residues [ i ] = false end for i = 1 , n_residues do seg_backbone_frozen, seg_sidechain_frozen = freeze.IsFrozen ( i ) if ( seg_backbone_frozen == true ) then fixed_residues [ i ] = true end s = structure.IsLocked ( i ) if ( s == true ) then fixed_residues [ i ] = true end end end function IsHelixFrozen ( start_idx , end_idx ) for i = start_idx , end_idx do if ( fixed_residues [ i ] == true ) then return true end end return false end function ConstructListOfResiduesWithinInnerCylinder ( start_idx , end_idx ) for i = 1 , n_residues do inner_cylinder [ i ] = false end for i = 1 , n_residues do for j = start_idx , end_idx do if ( structure.GetDistance ( i , j ) < inner_cylinder_radius ) then inner_cylinder [ i ] = true end end end end function SelectInnerCylinder () selection.DeselectAll () for i = 1 , n_residues do if ( inner_cylinder [ i ] == true ) then selection.Select ( i ) end end end function ConstructListOfResiduesWithinOuterCylinder ( start_idx , end_idx ) for i = 1 , n_residues do outer_cylinder [ i ] = false end for i = 1 , n_residues do for j = start_idx , end_idx do if ( structure.GetDistance ( i , j ) < outer_cylinder_radius ) then outer_cylinder [ i ] = true end end end end function SelectOuterCylinder () selection.DeselectAll () for i = 1 , n_residues do if ( outer_cylinder [ i ] == true ) then selection.Select ( i ) end end end function WiggleNIN () -- NIN = Nudge If Necessary aa_score = GetScore () structure.WiggleSelected ( kWiggleDuration ) score = GetScore () if ( ( score - aa_score ) < 1 ) then recentbest.Save () behavior.SetClashImportance ( 0.1 ) structure.WiggleSelected ( 1 ) behavior.SetClashImportance ( 1 ) structure.WiggleSelected ( kWiggleDuration ) recentbest.Restore () end end function SelectBestPostRebuildNew () save.Quickload ( kBestPostRebuild_a ) structure.WiggleSelected ( kWiggleDuration ) score_a = GetScore () save.Quicksave ( kBestPostRebuild_a_post_wiggle ) save.Quickload ( kBestPostRebuild_b ) structure.WiggleSelected ( kWiggleDuration ) score_b = GetScore () if ( score_a > score_b ) then save.Quickload ( kBestPostRebuild_a_post_wiggle ) end init_score = GetScore () if ( mutate_not_shake == true ) then structure.MutateSidechainsSelected ( 1 ) else structure.ShakeSidechainsSelected ( 1 ) end score_after_shake = GetScore () if ( score_after_shake > init_score ) then WiggleNIN () score_after_end_wiggle = GetScore () if ( math.abs ( score_after_end_wiggle - score_after_shake ) < 1 ) then -- Unstick recentbest.Save () behavior.SetClashImportance ( 0.4 ) structure.WiggleSelected ( 1 ) behavior.SetClashImportance ( 1 ) structure.WiggleSelected ( kWiggleDuration ) recentbest.Restore () end end end function ConstructSpacers ( start_helix , end_helix ) local i local ok start_idx = start_helix - loop_spacer if ( start_idx < 1 ) then start_idx = 1 end i = start_helix - 1 ok = true while ( i >= start_idx and ok == true ) do if ( structure.IsLocked ( i ) == true ) then ok = false start_idx = i + 1 else i = i -1 end 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 i = end_helix + 1 ok = true while ( i <= end_idx and ok == true ) do if ( structure.IsLocked ( i ) == true ) then ok = false end_idx = i - 1 else i = i +1 end end if ( end_helix < n_residues ) then ConvertToLoop ( end_helix + 1 , end_idx ) end return start_idx , end_idx end function RebuildHelix ( helix_index , start_helix , end_helix ) best_score_after_rebuild_and_shake_a = -99999 best_score_after_rebuild_and_shake_b = -99999 improvement_made = false rb = rb + 1 start_idx , end_idx = ConstructSpacers ( start_helix , end_helix ) ConstructListOfResiduesWithinInnerCylinder ( start_idx , end_idx ) ConstructListOfResiduesWithinOuterCylinder ( start_idx , end_idx ) print ( "rb : " .. rb .. " (" .. start_helix .. "-" .. end_helix .. ")" ) for i = 1 , n_rebuilds do save.Quickload ( kOriginalStructureOrNewBest ) selection.DeselectAll () selection.SelectRange ( start_idx , end_idx ) structure.RebuildSelected ( 1 ) score_after_rebuild = GetScore () SelectInnerCylinder () structure.ShakeSidechainsSelected ( 1 ) structure.WiggleSelected ( 1 ) score_after_shake_wiggle = GetScore () if ( score_after_shake_wiggle > math.min ( best_score_after_rebuild_and_shake_a , best_score_after_rebuild_and_shake_b ) ) then if ( best_score_after_rebuild_and_shake_b < best_score_after_rebuild_and_shake_a ) then best_score_after_rebuild_and_shake_b = score_after_shake_wiggle save.Quicksave ( kBestPostRebuild_b ) else best_score_after_rebuild_and_shake_a = score_after_shake_wiggle save.Quicksave ( kBestPostRebuild_a ) end end end SelectOuterCylinder () SelectBestPostRebuildNew () curr_score = GetScore () print ( " " .. r3 ( best_score - curr_score ) ) if ( ( curr_score > best_score ) and ( test_for_credit == false or creditbest.AreConditionsMet () == true ) ) then improvement_made = true best_score = curr_score save.LoadSecondaryStructure () save.Quicksave ( kOriginalStructureOrNewBest ) print ( "Improvement to " .. r3 ( best_score ) ) end save.LoadSecondaryStructure () end function get_parameters () local dlog = dialog.CreateDialog ( "Helix rebuild 4" ) 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.n_rebuilds = dialog.AddSlider ( "Rebuilds" , n_rebuilds , 1 , 20 , 0 ) design_puzzle = IsPuzzleMutable () if ( design_puzzle == true ) then dlog.mutate= dialog.AddCheckbox ( "Mutate not shake" , false ) end dlog.credit_check = dialog.AddCheckbox ( "Check conditions met " , test_for_credit ) 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 if ( design_puzzle == true ) then mutate_not_shake = dlog.mutate.value end test_for_credit = dlog.credit_check.value n_rebuilds = dlog.n_rebuilds.value return true else return false end end function main () print ( "Helix rebuild 4" ) 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 : " .. r3 ( best_score ) ) get_helices () GetListOfFixedResidues () -- Delete locked/frozen helices for i = n_helices , 1 , -1 do if ( IsHelixFrozen ( helix_starts [ i ] , helix_ends [ i ] ) == true ) then table.remove ( helix_starts , i ) table.remove ( helix_ends , i ) end end print ( n_helices .. " helices" ) qs10_best_score = 0 if ( get_parameters () == false ) then print ( "error" ) error () end -- Delete unused helices for i = n_helices , 1 , -1 do if ( use_helix [ i ] == false ) then table.remove ( helix_starts , i ) table.remove ( helix_ends , i ) end end n_helices = #helix_starts if ( n_helices == 0 ) then print ( "No helix selected" ) error () end for i = 1 , n_helices do print ( "Helix " .. i .. " : (" .. helix_starts [ i ] .. "-" .. helix_ends [ i ] .. ")" ) end print ( "Loop spacer " .. loop_spacer ) print ( n_rebuilds .. " rebuilds" ) rb = 0 save.Quicksave ( kOriginalStructureOrNewBest ) while ( true ) do for i = 1 , n_helices do RebuildHelix ( i , helix_starts [ i ] , helix_ends [ i ] ) 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). Best used at Low Wiggle Power I think: the script never terminates.

Algorithm outline

For each helix
    For however many rebuilds specified
        Bracket it with a loop on either end
        Rebuild once
        Shake and wiggle briefly
        Record score
    end
    Take two best poses from above
    Wiggle each
    Take the best scoring of those two, shake and wiggle.
    Nudge if appropriate
    Record any gain
end


Selection is restricted to the local vicinity of the helix for the sake of efficiency.
See values of inner_cylinder_radius and outer_cylinder_radius, which are probably unnecessarily conservative.

Loop spacer

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

Helix List

Initially all are selected. Helices with locked or frozen backbones will not appear in this list: frozen sidechains are allowable though.

Rebuilds

How many times to rebuild each helix

Mutate not shake

For puzzles with mutable residues only

Check conditions met:

If set, check that conditions are met before accepting any improvement. For puzzles with RMSD conditions, etc.

Primalsoul Lv 1

I really like turning off the blue fuze option just to see if the rebuild is going to give good points. Then I can either go with that rebuild or rebuild with the fuze from the last best.