Icon representing a recipe

Recipe: Loop explorer 3.01

created by spvincent

Profile


Name
Loop explorer 3.01
ID
101630
Shared with
Public
Parent
None
Children
Created on
November 23, 2015 at 02:09 AM UTC
Updated on
November 23, 2015 at 02:09 AM UTC
Description

See first comment

Best for


Code


-- Repeatedly rebuild/shake/wiggle a particular segment -- Constants kMaxSphereDistance = 13 -- Residues further than this away won't be shaken score_type = 1 -- Globals best_score = 0 min_residue = 0 max_residue = 0 n_residues = 0 rb = 0 SphereSegList = {} -- store list of residues within kMaxSphereDistance of any residue in the segment. -- speeds things up when shaking kInvalidScore = -999999 best_post_rebuild_score_1 = kInvalidScore best_post_rebuild_score_2 = kInvalidScore post_rebuild = 2 rebuild_threshold = 100 original_slow_filters_setting = 0 -- Quicksave slots kOriginalStructureOrNewBest = 1 kTemp = 2 kPostRebuild_1 = 11 kPostRebuild_2 = 12 -- Performance monitoring monit = false monit_r_loss = 0 monit_s1_gain = 0 monit_w1_gain = 0 monit_s2_gain = 0 monit_w2_gain = 0 function r3 ( x ) -- Round to 3 decimal places t = 10 ^ 3 return math.floor ( x*t + 0.5 ) / t end function GetScore () if ( score_type == 1 ) then score = current.GetScore () elseif ( score_type == 2 ) then behavior.SetFiltersDisabled ( false ) score = current.GetScore () behavior.SetFiltersDisabled ( true ) end return score end function ConstructListOfResiduesWithinRange ( start_idx , end_idx ) -- Mildly inefficient but it's only done once at startup for i = 1 , n_residues do SphereSegList [ i ] = false end for j = start_idx , end_idx do for i = 1 , n_residues do if ( ( i >= start_idx and i <= end_idx ) or ( structure.GetDistance ( i , j ) < kMaxSphereDistance ) ) then SphereSegList [ i ] = true end end end end function SelectSphere () selection.DeselectAll () for i = 1 , n_residues do if ( SphereSegList [ i ] == true ) then selection.Select ( i ) end end end function NudgeWiggle () selection.SelectAll () score_in_kTemp = GetScore () save.Quicksave ( kTemp) behavior.SetClashImportance ( 0.5 ) structure.WiggleSelected ( 1 ) behavior.SetClashImportance ( 1 ) structure.WiggleSelected ( 6 ) score = GetScore () if ( score < score_in_kTemp ) then save.Quickload ( kTemp ) end end function RebuildSection ( start_idx , end_idx ) save.Quickload ( kOriginalStructureOrNewBest ) selection.DeselectAll () selection.SelectRange ( start_idx , end_idx ) structure.RebuildSelected ( 1 ) score_after_rebuild = GetScore () if ( ( score_after_rebuild > best_score ) or ( best_score - score_after_rebuild > rebuild_threshold ) ) then if ( monit ) then monit_r_loss = score_after_rebuild - best_score monit_s1_gain = 0 monit_w1_gain = 0 monit_s2_gain = 0 monit_w2_gain = 0 end SelectSphere () structure.ShakeSidechainsSelected ( 1 ) if ( monit ) then monit_s1_gain = GetScore () - score_after_rebuild end if ( post_rebuild >= 2 ) then selection.SelectAll () score_before_wiggle = GetScore () structure.WiggleSelected ( 10 ) score_after_wiggle = GetScore () if ( score_after_wiggle - score_before_wiggle < 1 ) then -- The wiggle got stuck and didn't achieve anything NudgeWiggle () end if ( monit ) then monit_w1_gain = GetScore () - score_before_wiggle end if ( post_rebuild >= 3 ) then score_before_sm = GetScore () SelectSphere () if ( post_rebuild == 3 ) then structure.ShakeSidechainsSelected ( 1 ) else structure.MutateSidechainsSelected ( 1 ) end score_after_sm = GetScore () if ( monit ) then monit_s2_gain = score_after_sm - score_before_sm end if ( score_after_sm - score_before_sm > 1e-3 ) then score_before_wiggle = score_after_sm structure.WiggleSelected ( 10 ) score_after_wiggle = GetScore () if ( score_after_wiggle - score_before_wiggle < 1 ) then -- The wiggle got stuck and didn't achieve anything NudgeWiggle () end if ( monit ) then monit_w2_gain = GetScore () - score_before_wiggle end end end -- ( post_rebuild >= 3 ) end -- ( post_rebuild >= 2 ) score = GetScore () if ( monit ) then print ( rb .. " " .. r3 ( monit_r_loss ) .. " " .. r3 ( monit_s1_gain ) .. " " .. r3 ( monit_w1_gain ) .. " " .. r3 ( monit_s2_gain ) .. " " .. r3 ( monit_w2_gain ) .. " " .. r3 ( best_score - score ) .. " " ) end if ( score > best_score ) then best_score = score save.Quicksave ( kOriginalStructureOrNewBest ) print ( "rb : " .. rb .. " Improvement to " .. r3 ( score ) ) elseif ( score > math.min ( best_post_rebuild_score_1 , best_post_rebuild_score_2 ) ) then if ( best_post_rebuild_score_1 < best_post_rebuild_score_2 ) then slot = kPostRebuild_1 best_post_rebuild_score_1 = score else slot = kPostRebuild_2 best_post_rebuild_score_2 = score end save.Quicksave ( slot ) if ( monit == false ) then print ( "rb : " .. rb .. " Storing " .. r3 ( score ) .. " in quicksave " .. slot ) end else print ( "rb : " .. rb ) end else print ( "rb : " .. rb .. " bt" ) -- below threshold end end function GetParameters () local dlog = dialog.CreateDialog ( "Loop explorer 3.1" ) dlog.min_residue = dialog.AddSlider ( "Min residue" , 1 , 1 , n_residues , 0 ) dlog.max_residue = dialog.AddSlider ( "Max residue" , n_residues , 1 , n_residues , 0 ) dlog.post_rebuild = dialog.AddSlider ( "Post rebuild" , post_rebuild , 1 , 4 , 0 ) dlog.pr = dialog.AddLabel ( "1 = Sh : 2 = Sh/W : 3 = Sh/W/Sh/W : 4 = Sh/W/Mu/W" ) dlog.rebuild_threshold = dialog.AddSlider ( "Rebuild threshold" , rebuild_threshold , 0 , 1000 , 0 ) dlog.score_type = dialog.AddSlider ( "Score type" , score_type , 1 , 2 , 0 ) dlog.tp = dialog.AddLabel ( "1 = Normal : 2 = Normal for Filters" ) dlog.ok = dialog.AddButton ( "OK" , 1 ) dlog.cancel = dialog.AddButton ( "Cancel" , 0 ) if ( dialog.Show ( dlog ) > 0 ) then min_residue = dlog.min_residue.value max_residue = dlog.max_residue.value post_rebuild = dlog.post_rebuild.value rebuild_threshold = dlog.rebuild_threshold.value score_type = dlog.score_type.value return true else return false end end function main () n_residues = structure.GetCount () rb = 0 save.Quicksave ( kOriginalStructureOrNewBest ) behavior.SetClashImportance ( 1 ) original_slow_filters_setting = behavior.GetSlowFiltersDisabled () print ( "Loop Explorer 3.1" ) if ( GetParameters () == false ) then return -- graceful exit end best_score = GetScore () if ( max_residue <= min_residue ) then print ( "Rebuild range error." ) print ( "Max residue (" .. max_residue .. ") must be greater than or equal to Min residue (" .. min_residue .. ")" ) return end for i = min_residue , max_residue do seg_backbone_frozen, seg_sidechain_frozen = freeze.IsFrozen ( i ) if ( seg_backbone_frozen == true ) then print ( "Backbone frozen" ) return end end print ( "Start score : " .. r3 ( best_score ) ) print ( "Rebuilding " .. min_residue .. " to " .. max_residue ) if ( post_rebuild == 1 ) then print ( "Post rebuild : Shake" ) elseif ( post_rebuild == 2 ) then print ( "Post rebuild : Shake/Wiggle" ) elseif ( post_rebuild == 3 ) then print ( "Post rebuild : Shake/Wiggle/Shake/Wiggle" ) elseif ( post_rebuild == 4 ) then print ( "Post rebuild : Shake/Wiggle/Mutate/Wiggle" ) end print ( "Threshold " .. r3 ( rebuild_threshold ) ) ConstructListOfResiduesWithinRange ( min_residue , max_residue ) store_next_post_rebuild_in_1 = true while true do rb = rb + 1 RebuildSection ( min_residue , max_residue ) end cleanup () end function cleanup () print ( "Cleaning up" ) behavior.SetClashImportance ( 1.0 ) if ( best_post_rebuild_score_1 ~= kInvalidScore ) then print ( "Loading Quicksave " .. kPostRebuild_1 .. " (" .. r3 ( best_post_rebuild_score_1 ) .. ")" ) save.Quickload ( kPostRebuild_1 ) end if ( best_post_rebuild_score_2 ~= kInvalidScore ) then print ( "Loading Quicksave " .. kPostRebuild_2 .. " (" .. r3 ( best_post_rebuild_score_2 ) .. ")" ) save.Quickload ( kPostRebuild_2 ) end print ( "Loading start" ) save.Quickload ( kOriginalStructureOrNewBest ) if ( score_type == 2 ) then behavior.SetSlowFiltersDisabled ( original_slow_filters_setting ) end end --main () xpcall ( main , cleanup )

Comments


spvincent Lv 1

(Change from 3.0 : on termination load results in Quicksave slots for easy access via Undo as suggested by Bruno)

Repeatedly rebuilds, shakes and wiggles a selected area (not necessarily a loop, the name's a bit misleading); storing the most promising results in Quicksave slots.

This script is not intended to improve your score in itself, although it may have that happy side effect. Its intended use is to explore new configurations of an existing region, which can then be loaded, inspected, and the rebuilder of your choice used to hammer away at the new loop and hopefully produce a better score.

This script never terminates. It's up to the user to stop it after a bit and examine the poses in Quicksave slots 11 and 12 which are loaded on termination prior to restoring the current best pose. Suggest taking the best-looking (not necessarily the higher scoring) of these two poses and proceed from there.

Min residue: max residue

Used to define the area (not necessarily a loop, despite the name of the script) to be rebuilt. A likely candidate would be one 8-12 residues in length with an appearance that displeases you or which you have cause to think may be stuck in a local minimum.

Post rebuild

Specifies the action(s) to be taken after a rebuild. The default is a Shake/Wiggle but other action sequences are provided: they allow the usual trade off between speed and accuracy.

Rebuild threshold

The idea is to reject rebuilds that are too similar to the original. If the score after a rebuild is less than the original score by this value or lower than the rebuild will be rejected. ( "bt" will be printed in the output ). Not entirely sure how well this will works in practise but it struck me as a nice feature when writing the script. Drag slider to zero to effectively remove this feature.

Score type

If set to 2, toggles filters off except when determining the score. For better performance on slow design puzzles.