Icon representing a recipe

Recipe: Loop explorer 1.0

created by spvincent

Profile


Name
Loop explorer 1.0
ID
44410
Shared with
Public
Parent
None
Children
Created on
October 24, 2012 at 21:23 PM UTC
Updated on
October 24, 2012 at 21:23 PM UTC
Description

See first comment

Best for


Code


-- Repeatedly rebuild/shake/wiggle a particular segment -- Constants kWorstAllowableAngle = 75 -- ignore rebuilds with backbone angles less than this (degrees) kMaxSphereDistance = 13 -- Residues further than this away won't be shaken -- 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 best_post_rebuild_weighted_score_delta_1 = 999999 best_post_rebuild_weighted_score_delta_2 = 999999 -- Difference heuristic variables weight_by_difference = false closest_to_mid = -1 init_differences = {} curr_differences = {} -- Quicksave slots kOriginalStructureOrNewBest = 1 kTemp = 2 kPostRebuild_1 = 11 kPostRebuild_2 = 12 function r3 ( x ) -- Round to 3 decimal places t = 10 ^ 3 return math.floor ( x*t + 0.5 ) / t end function GetScore () score = current.GetEnergyScore () return score end function FindResidueClosestToMidRebuild ( start_idx , end_idx ) mid_x = ( start_idx + end_idx ) / 2 closest_to_mid = -1 cv = 999999 for i = 1 , n_residues do if ( i < start_idx or i > end_idx ) then d = structure.GetDistance ( i , mid_x ) if ( d < cv ) then closest_to_mid = i cv = d end end end end function FindDifferenceValues ( table , start_idx , end_idx ) for i = start_idx , end_idx do table [ i ] = structure.GetDistance ( i , mid_x ) end end function ComputeDifferenceHeuristic ( start_idx , end_idx ) d = 0 for i = start_idx , end_idx do d = d + ( init_differences [ i ] - curr_differences [ i ] ) * ( init_differences [ i ] - curr_differences [ i ] ) end return ( math.sqrt ( d ) ) end function ComputeWeightedDifference ( score , dh ) if ( dh < 1e-5 ) then return 1e10 else return ( best_score - score ) / dh end 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 get_parameters () local dlog = dialog.CreateDialog ( "Loop explorer" ) 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.weight_difference = dialog.AddCheckbox ( "Weight according to difference" , weight_by_difference ) 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 weight_by_difference = dlog.weight_difference.value return true else return false end end function NudgeWiggle () selection.SelectAll () score_in_kTemp = GetScore () save.Quicksave ( kTemp) behavior.SetClashImportance ( 0.7 ) structure.WiggleSelected ( 1 ) behavior.SetClashImportance ( 1 ) structure.WiggleSelected ( 6 ) score = GetScore () if ( score < score_in_kTemp ) then save.Quickload ( kTemp ) end end function rebuild_section ( start_idx , end_idx ) save.Quickload ( kOriginalStructureOrNewBest ) selection.DeselectAll () selection.SelectRange ( start_idx , end_idx ) structure.RebuildSelected ( 1 ) score_after_rebuild_shake = GetScore () SelectSphere () structure.ShakeSidechainsSelected ( 1 ) score_after_rebuild_shake = GetScore () selection.SelectAll () structure.WiggleSelected ( 10 ) score_after_wiggle = GetScore () if ( score_after_wiggle - score_after_rebuild_shake < 10 ) then -- The wiggle got stuck and didn't achieve anything NudgeWiggle () score_after_wiggle = GetScore () end if ( weight_by_difference == true ) then FindDifferenceValues ( curr_differences , min_residue , max_residue ) dh = ComputeDifferenceHeuristic ( start_idx , end_idx ) wd = ComputeWeightedDifference ( score_after_wiggle , dh ) else wd = best_score - score_after_wiggle dh = 1 end if ( score_after_wiggle > best_score ) then best_score = score_after_wiggle save.Quicksave ( kOriginalStructureOrNewBest ) print ( "rb : " .. rb .. " Improvement to " .. r3 ( score_after_wiggle ) ) --print ( " dh " , r3 ( dh ) ) elseif ( wd < math.max ( best_post_rebuild_weighted_score_delta_1 , best_post_rebuild_weighted_score_delta_2 ) ) then if ( best_post_rebuild_weighted_score_delta_1 > best_post_rebuild_weighted_score_delta_2 ) then slot = kPostRebuild_1 best_post_rebuild_weighted_score_delta_1 = wd else slot = kPostRebuild_2 best_post_rebuild_weighted_score_delta_2 = wd end save.Quicksave ( slot ) print ( "rb : " .. rb .. " Storing " .. r3 ( score_after_wiggle ) .. " in quicksave " .. slot ) --print ( " dh " , r3 ( dh ) ) --print ( " wd " , r3 ( wd ) ) else print ( "rb : " .. rb ) --print ( "rb : " .. rb .. " dh " , r3 ( dh ) ) end end function main() band.DisableAll () n_residues = structure.GetCount () rb = 0 save.Quicksave ( kOriginalStructureOrNewBest ) behavior.SetClashImportance ( 1 ) if ( get_parameters () == false ) then return -- graceful exit end best_score = GetScore () print ( "Start score : " .. r3 ( best_score ) ) 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 print ( "Rebuilding " .. min_residue .. " to " .. max_residue ) ConstructListOfResiduesWithinRange ( min_residue , max_residue ) cos_worst_allowable_angle = math.cos ( math.rad ( kWorstAllowableAngle ) ) FindResidueClosestToMidRebuild ( min_residue , max_residue ) FindDifferenceValues ( init_differences , min_residue , max_residue ) store_next_post_rebuild_in_1 = true while true do rb = rb + 1 rebuild_section ( min_residue , max_residue ) end save.Quickload ( kOriginalStructureOrNewBest ) band.EnableAll () end function cleanup () print ( "Cleaning up" ) behavior.SetClashImportance ( 1.0 ) save.Quickload ( kOriginalStructureOrNewBest ) band.EnableAll () end --main () xpcall ( main , cleanup )

Comments


spvincent Lv 1

Repeatedly rebuilds, shakes and wiggles a selected area, 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 as a late game script to explore new configurations of an existing loop,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.

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.

Weight according to difference

If unchecked, new configurations are saved according to best score in two Quicksave slots (11 and 12 by default). If checked a weighting function (based on differences between the position of each side chain between the new configuration and the original) is applied such that new configurations that are significantly different from the original will be preferred, even though their score may be lower.