Profile
- Name
- Loop Rebuild V2 1.1
- ID
- 36980
- Shared with
- Public
- Parent
- Loop Rebuild V2 1.0
- Children
- Created on
- December 30, 2011 at 17:21 PM UTC
- Updated on
- December 30, 2011 at 17:21 PM UTC
- Description
Based on spvincent's Loop Rebuild 2.0
Best for
Code
-- This script is based on spvincent's Loop Rebuild 2.0 (http://fold.it/portal/recipe/6985)
-- Converted to V2 by Schleicher
max_rebuild_length = 5 -- Maximum rebuild length.
min_rebuild_length = 5 -- Suggest leaving this at 4. Haven't had much luck with smaller rebuilds but
-- others have. Your mileage may vary.
number_of_rebuilds = 10 -- It'll look for the best score from this number of rebuilds. Change to taste.
-- Irrelevant for rebuild lengths of 2 where this value is coerced to 1
stop_if_close = false -- Set to true to make it interactive and manually explore rebuilds that get close
-- to the highest score
start_idx = 6 -- start residue. Anything between 1 and the number of residues will do
-- Change for a bit of randomness.
loops_only = false -- if false, rebuild helices and sheets also
-- they'll be temporarily converted to loops
loop_forever = true -- just keep going. Good for overnight running.
start_from_best = false -- set to false if you want it to start from the current configuration, not the best
min_residue = 1 -- Change these if you want to rebuild part of a protein only. For example, to
-- rebuild 53-64, set min_residue to 53 and max_residue to 64. To restore, set to
-- 1 and 9999 (or any large number) respectively
max_residue = 9999
refinement_hack = false -- For refinement puzzles with conditions only.
-- if set to true , it'll reset the puzzle to the recent credit best before each rebuild
-- you will always effectively be starting from the best credit solution, so will be -- unable to use this script to explore from lower-scoring solutions. The output -- may be misleading also. As the name implies, its a hack until a cleaner interface
-- comes from the devs.
sidechain_scramble = true -- if true, will do one after a point gain. Trade off: more points from the script but
-- more time-consuming also and possibly fewer subsequent points from walks.
monit = false -- prints debug and performance info.
-- Other changes
-- Tries an alternative post-rebuild strategy if the first one is close
-- Stores the best non-improved structure in Quicksave slot 10. The structure that's saved is the
-- the best before WS etc, so if this script fails to produce (or even if it does) you can load the structure in
-- slot 10 and try WS in different ways.
original_secondary_structure = {}
function Coprime ( n )
-- returns a number that has no common factors with n
-- an ugly hack
if ( n < 31 ) then
return 1
elseif ( n >= 31*37 ) then
return 1
elseif ( n%31 ~= 0 ) then
return 31
else
return 37
end
end
function IsSegmentALoop ( first , last )
non_loop_found = false
for i = first , last do
if ( structure.GetSecondaryStructure ( i ) ~= "L" ) then
non_loop_found= true
end
end
return not non_loop_found
end
function ConvertToLoop ( first , last )
for k = first , last do
if ( original_secondary_structure [ k ] ~= "L" ) then
structure.SetSecondaryStructure ( k,"L" )
end
end
end
function RestoreStructure ( first , last )
for k = first, last do
structure.SetSecondaryStructure ( k,original_secondary_structure [ k ] )
end
end
function nudge ()
if ( monit ) then
c = current.GetEnergyScore ()
end
behavior.SetClashImportance ( 0.3 )
structure.LocalWiggleAll ( 1 )
behavior.SetClashImportance ( 1 )
structure.LocalWiggleAll ( 10 )
if ( monit ) then
print ( "Gain from nudge " , current.GetEnergyScore() - c )
end
end
function BlueFuse_part_1 ( )
if ( monit ) then
c = current.GetEnergyScore ()
end
recentbest.Save ()
behavior.SetClashImportance ( 0.05 )
structure.ShakeSidechainsAll ( 1 )
behavior.SetClashImportance ( 1 )
structure.WiggleAll ( 8 )
recentbest.Restore () -- In case the above machinations made things worse
if ( monit ) then
d = current.GetEnergyScore ()
print ( "Gain from BF1 " , d - c )
end
end
function disable_all_bands ()
band.DisableAll ( )
end
function enable_all_bands ()
band.EnableAll ( )
end
function BlueFuse_part_2 ()
c = current.GetEnergyScore ()
recentbest.Save()
behavior.SetClashImportance ( 0.05 )
structure.ShakeSidechainsAll ( 1 )
behavior.SetClashImportance ( 1 )
structure.WiggleAll ( 8 )
recentbest.Restore ()
behavior.SetClashImportance ( 0.07 )
structure.ShakeSidechainsAll ( 1 )
behavior.SetClashImportance ( 1 )
structure.WiggleAll ( 8 )
recentbest.Restore ()
behavior.SetClashImportance ( 0.3 )
structure.WiggleAll ( 1 )
behavior.SetClashImportance ( 1 )
structure.WiggleAll ( 8 )
recentbest.Restore ()
if ( monit ) then
d = current.GetEnergyScore ()
print ( "Gain from BF2 " , d - c )
end
end
function WiggleShakeWiggle ( start_idx , end_idx )
-- returns the score after doing a WSW: shortcircuiting if things don't look promising
score_a = current.GetEnergyScore ()
structure.WiggleAll ( 15 )
score_after_wiggle = current.GetEnergyScore ()
if ( score_after_wiggle - score_a < 10 and best_score - score_after_wiggle > 30 ) then
-- The wiggle got stuck and didn't achieve anything
nudge ()
score_after_wiggle = current.GetEnergyScore ()
end
if ( monit ) then
--print ( "After first wiggle (bb) : ", best_score - score_after_wiggle )
end
if ( best_score - score_after_wiggle > 100 ) then
-- Not worth continuing
return score_after_wiggle
end
structure.ShakeSidechainsAll ( 1 )
score_after_second_shake = current.GetEnergyScore ()
if ( score_after_second_shake - score_after_wiggle > 0.5 ) then
structure.WiggleAll ( 10 )
score_after_second_wiggle = current.GetEnergyScore ()
if ( score_after_second_wiggle - score_after_second_shake < 1 and best_score - score_after_second_wiggle < 50 ) then
-- The second shake did something but the subsequent wiggle didn't
recentbest.Save ()
nudge ( )
recentbest.Restore ()
score = current.GetEnergyScore ()
return score
else
return score_after_second_wiggle
end
else
return score_after_second_shake
end
end
function post_rebuild ( score_after_rebuild , threshold_a , threshold_b , start_idx , end_idx )
-- Tries to recover after a rebuild.
-- If the first recovery attempt results in a score that is less than the best score by a value
-- of threshold_a or less, then try alternative strategies
if ( best_score - score_after_rebuild > 3000 ) then
structure.ShakeSidechainsAll ( 2 )
initial_shake = true
elseif ( best_score - score_after_rebuild > 1500 ) then
structure.ShakeSidechainsAll ( 1 )
initial_shake = true
else
initial_shake = false
end
-- First try WSW
curr_score = WiggleShakeWiggle ( start_idx , end_idx )
if ( monit ) then
print ( "after wsw bb ", best_score - curr_score )
end
best_recovery_score = curr_score
save.Quicksave ( 3 )
if ( best_score - curr_score < threshold_a ) then
best_recovery_score = curr_score
save.Quicksave ( 3 )
-- Now try shaking at start if we didn't already do so
save.Quickload ( 2 )
if ( initial_shake == false ) then
score_before_shake = current.GetEnergyScore ()
structure.ShakeSidechainsAll ( 1 )
score_after_shake = current.GetEnergyScore ()
if ( score_after_shake - score_before_shake > 0.1 ) then
-- If shaking did nothing then no point duplicating previous WSW
curr_score = WiggleShakeWiggle ( start_idx , end_idx )
if ( monit ) then
print ( "after swsw bb " , best_score - curr_score )
end
if ( curr_score > best_recovery_score ) then
if ( monit ) then
print ( "Second better" )
end
best_recovery_score = curr_score
save.Quicksave ( 3 )
else
if ( monit ) then
print ( "First better" )
end
end
end
end
-- Additional post-rebuild strategies will go here as the API matures
end
if ( best_score - best_recovery_score < threshold_b ) then
save.Quickload ( 3 )
return true
else
return false
end
end
function rebuild ( n , rebuild_length )
n_possible_segs = n - rebuild_length + 1
inc = Coprime ( n_possible_segs )
-- The point of this Coprime, start_idx business is so we go through the protein in a
-- nonuniform way. Rather than rebuilding 1-4, 2-5 , 3-6 for example, we might do 21 4, 53-57, 3-6
-- or something like that
for i = 1 , n_possible_segs do
improvement_made = false
end_idx = start_idx + rebuild_length - 1
if ( start_idx >= min_residue and end_idx <= max_residue and
( loops_only == false or IsSegmentALoop ( start_idx , end_idx ) == true ) ) then
rb = rb + 1
print ( "rb ", rb , " " , start_idx ,"-" , end_idx , " (" ,i , "/" , n_possible_segs , ")" )
if ( refinement_hack == true ) then
creditbest.Restore ()
else
save.Quickload ( 1 )
end
best_score = current.GetEnergyScore ()
if ( loops_only == false ) then
ConvertToLoop ( start_idx , end_idx )
end
selection.DeselectAll ()
selection.SelectRange ( start_idx , end_idx )
-- for some reason, structure.RebuildSelected ( 1) often leaves the protein unchanged
k = 0
repeat
k = k + 1
structure.RebuildSelected ( k )
score_after_rebuild = current.GetEnergyScore ()
until score_after_rebuild ~= best_score or k > 2
if ( score_after_rebuild ~= best_score ) then
-- If the scores are still equal we probably have a locked segment
recentbest.Save ()
if ( number_of_rebuilds > 1 ) then
structure.RebuildSelected ( number_of_rebuilds - 1 )
recentbest.Restore ()
end
score_after_rebuild = current.GetEnergyScore ()
-- Compute a value delta which will be used later to determine if we are
-- "sufficiently" close to our original best score. If it turns out later that
-- we are, then either stop if stop _if_close is true or nudge it around
if ( best_score - score_after_rebuild < 20 ) then
delta = 0.01
elseif ( rebuild_length >= 6 ) then
delta = 10
elseif ( rebuild_length == 5 ) then
delta = 7
elseif ( rebuild_length == 4 ) then
delta = 5
else
delta = 2
end
investigate_alternates_threshold = 2*delta
if ( investigate_alternates_threshold < 10 ) then
investigate_alternates_threshold = 10
end
save.Quicksave ( 2 )
if ( post_rebuild ( score_after_rebuild , investigate_alternates_threshold , delta , start_idx , end_idx ) == true ) then
if ( loops_only == false ) then
save.LoadSecondaryStructure ()
end
if ( stop_if_close == true ) then
return true
end
BlueFuse_part_1 ()
curr_score = current.GetEnergyScore ()
if ( curr_score > best_score ) then
if ( sidechain_scramble == true ) then
BlueFuse_part_2 ( )
end
curr_score = current.GetEnergyScore ()
best_score = curr_score
improvement_made = true
save.Quicksave ( 1 )
print ( "Improvement to ", best_score )
end
end
curr_score = current.GetEnergyScore ()
if ( curr_score > qs10_best_score and improvement_made == false ) then
qs10_best_score = curr_score
save.Quickload ( 2 )
-- Bracket the area with frozen segments for easy recognition
selection.DeselectAll ()
if ( start_idx > 1 ) then
selection.Select ( start_idx - 1 )
end
if ( end_idx < n ) then
selection.Select ( end_idx + 1 )
end
freeze.FreezeSelected ( true , false )
save.Quicksave ( 10 )
end
end -- if first rebuild worked
if ( loops_only == false ) then
-- RestoreStructure ( start_idx , end_idx )
save.LoadSecondaryStructure ()
end
end
start_idx = start_idx + inc
if ( start_idx > n_possible_segs ) then
start_idx = start_idx - n_possible_segs
end
end -- for i
return false
end
if ( start_from_best == true ) then
absolutebest.Restore ()
end
-- Tidy up if necessary
disable_all_bands ()
n_residues = structure.GetCount()
if ( loops_only == false ) then
for i = 1, n_residues do
original_secondary_structure [ i ] = structure.GetSecondaryStructure ( i )
end
end
save.SaveSecondaryStructure ()
rb = 0
save.Quicksave ( 1 )
behavior.SetClashImportance ( 1 )
best_score = current.GetEnergyScore ()
print ( "Start score : " , best_score )
if ( start_score == 0 ) then
print ( "Suggest quitting as starting score < = 0" )
end
if ( loops_only == true ) then
print ( "Loops only" )
else
print ( "Loops, sheets, and helices" )
end
if ( max_residue > n_residues ) then
max_residue = n_residues
end
if ( min_residue < 1 ) then
min_residue = 1
end
if ( max_residue <= min_residue ) then
print ( "Rebuild range error" )
loop_forever = false
end
if ( true ) then -- min_residue > 1 or max_residue < n_residues ) then
print ( "Rebuild range " , min_residue , " to " , max_residue )
else
print ( "Rebuild all" )
end
qs10_best_score = 0
if ( refinement_hack == true ) then
print ( "Refinement hack on" )
end
repeat
for rebuild_length = max_rebuild_length , min_rebuild_length , -1 do
if ( rebuild_length <= 2 ) then
number_of_rebuilds = 1
end
if ( rebuild ( n_residues , rebuild_length ) == true ) then
loop_forever = false
break
end
end
until loop_forever == false
if ( refinement_hack == true ) then
creditbest.Restore ()
else
save.Quickload ( 1 )
end
enable_all_bands ()
-- Version history:
-- 1.0
-- V1 function calls converted to V2
-- 1.1
-- Replaced some *Selected() function calls with *All()