Icon representing a recipe

Recipe: MicroIdealize 4.0

created by spvincent

Profile


Name
MicroIdealize 4.0
ID
102027
Shared with
Public
Parent
None
Children
Created on
April 30, 2016 at 17:20 PM UTC
Updated on
April 30, 2016 at 17:20 PM UTC
Description

See first comment

Best for


Code


kOriginalStructureOrNewBest = 1 -- the starting structure, or any subsequent improvement, will be stored in this quicksave slot best_score = 0 idealize_length = 3 min_residue = 1 max_residue = 999 worst_first = true score_type = 1 original_slow_filters_setting = 0 kDefaultWiggle = 12 sphere = {} kSphereRadius = 10 function r3 ( i ) -- printing convenience return i - i % 0.001 end function GetScore () if ( score_type == 1 ) then score = current.GetEnergyScore () elseif ( score_type == 2 ) then behavior.SetSlowFiltersDisabled ( false ) score = current.GetScore () behavior.SetSlowFiltersDisabled ( true ) end return score end function DoesPuzzleHaveSlowFilters () init_setting = behavior.GetSlowFiltersDisabled () if ( init_setting == false ) then score_without_sf = current.GetScore () behavior.SetSlowFiltersDisabled ( true ) score_with_sf = current.GetScore () else score_with_sf = current.GetScore () behavior.SetSlowFiltersDisabled ( false ) score_without_sf = current.GetScore () end behavior.SetSlowFiltersDisabled ( init_setting ) if ( math.abs ( score_without_sf - score_with_sf ) > 1e-3 ) then return true else return false end end function SphereSelect ( start_idx , end_idx ) for i = 1 , n_residues do sphere [ i ] = false end for i = 1 , n_residues do for j = start_idx , end_idx do if ( structure.GetDistance ( i , j ) < kSphereRadius ) then sphere [ i ] = true end end end selection.DeselectAll () for i = 1 , n_residues do if ( sphere [ i ] == true ) then selection.Select ( i ) end end end function GoSegment ( start_idx , end_idx ) save.Quickload ( kOriginalStructureOrNewBest ) if ( start_idx > 1 ) then structure.InsertCut ( start_idx ) end if ( end_idx < n_residues ) then structure.InsertCut ( end_idx ) end selection.DeselectAll () selection.SelectRange ( start_idx , end_idx ) structure.IdealizeSelected () if ( start_idx > 1 ) then structure.DeleteCut ( start_idx ) end if ( end_idx < n_residues ) then structure.DeleteCut ( end_idx ) end SphereSelect ( start_idx , end_idx ) structure.WiggleSelected ( kDefaultWiggle ) score = GetScore () if ( score > best_score ) then best_score = score print ( "Improvement to ".. r3 ( best_score ) ) save.Quicksave ( kOriginalStructureOrNewBest ) end end function Coprime ( n ) local primes = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101} i = #primes -- find the highest prime < 70% of the residue count and which is coprime with the number of residues while ( i >= 1 ) do if ( primes [ i ] < n*0.7 and n % primes [ i ] ~= 0 ) then return primes [ i ] end i = i - 1 end return 1 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 Go () local inc max_possible_residue = max_residue - idealize_length + 1 n_possible_segs = max_possible_residue - min_residue + 1 r = pseudorandom ( best_score ) start_idx = min_residue + n_possible_segs * r start_idx = start_idx - start_idx % 1 inc = Coprime ( n_possible_segs ) for i = 1 , n_possible_segs do print ( start_idx .. "-" .. start_idx + idealize_length - 1 .. " (" .. i .. "/" .. n_possible_segs .. ")" ) GoSegment ( start_idx , start_idx + idealize_length - 1 ) start_idx = start_idx + inc if ( start_idx > max_possible_residue ) then start_idx = start_idx - n_possible_segs end end end function ShellSort ( ids , sequence_scores , n ) -- Adapted from Numerical Recipes in C local inc = 1 repeat inc = inc * 3 + 1 until inc > n repeat inc = inc / 3 inc = inc - inc % 1 for i = inc + 1 , n do v = sequence_scores [ i ] w = ids [ i ] j = i flag = false while ( flag == false and sequence_scores [ j - inc ] > v ) do sequence_scores [ j ] = sequence_scores [ j - inc ] ids [ j ] = ids [ j - inc ] j = j - inc if ( j <= inc ) then flag = true end end sequence_scores [ j ] = v ids [ j ] = w end until inc <= 1 end function GoWorstFirst () ideality_scores = {} sequence_scores = {} ids = {} max_possible_residue = max_residue - idealize_length + 1 n_possible_segs = max_possible_residue - min_residue + 1 for i = min_residue , max_residue do ideality_scores [ i ] = current.GetSegmentEnergySubscore ( i , "ideality" ) --print ( i .. " " .. r3 ( ideality_scores [ i ] ) ) end idx = 1 for i = min_residue , max_residue - idealize_length + 1 do total = 0 for j = i , i + idealize_length - 1 do total = total + ideality_scores [ j ] end sequence_scores [ idx ] = total ids [ idx ] = i --print ( idx .. " " .. ids [ idx ] .. " " .. r3 ( sequence_scores [ idx ] ) ) idx = idx + 1 end ShellSort ( ids , sequence_scores , max_possible_residue - min_residue + 1 ) for i = 1 , n_possible_segs do --print ( i .. " " .. ids [ i ] .. " " .. r3 ( sequence_scores [ i ] ) ) print ( ids [ i ] .. "-" .. ids [ i ] + idealize_length - 1 .. " (" .. i .. "/" .. n_possible_segs .. ")" ) GoSegment ( ids [ i ] , ids [ i ] + idealize_length - 1 ) end end function GetParameters () local dlog = dialog.CreateDialog ( "MicroIdealize 4.0" ) dlog.idealize_length = dialog.AddSlider ( "Idealize length" , idealize_length , 1 , 20 , 0 ) 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.worst_first = dialog.AddCheckbox ( "Worst first" , worst_first ) if ( DoesPuzzleHaveSlowFilters () == true ) then score_type = 2 end dlog.score_type = dialog.AddSlider ( "Score type" , score_type , 1 , 2 , 0 ) dlog.ok = dialog.AddButton ( "OK" , 1 ) dlog.cancel = dialog.AddButton ( "Cancel" , 0 ) if ( dialog.Show ( dlog ) > 0 ) then idealize_length = dlog.idealize_length.value min_residue = dlog.min_residue.value max_residue = dlog.max_residue.value worst_first = dlog.worst_first.value score_type = dlog.score_type.value return true else return false end end function main () print ( "MicroIdealize 4.0" ) save.Quicksave ( kOriginalStructureOrNewBest ) best_score = GetScore () print ( "Start score " .. r3 ( best_score ) ) n_residues = structure.GetCount () original_slow_filters_setting = behavior.GetSlowFiltersDisabled () if ( GetParameters () == false ) then return -- graceful exit end if ( score_type == 2 ) then behavior.SetSlowFiltersDisabled ( true ) end print ( "Length " .. idealize_length ) if ( worst_first == false ) then Go () else GoWorstFirst () end cleanup () end function cleanup () print ( "Cleaning up" ) behavior.SetClashImportance ( 1.0 ) save.Quickload ( kOriginalStructureOrNewBest ) behavior.SetSlowFiltersDisabled ( original_slow_filters_setting ) end --main () xpcall ( main , cleanup )

Comments


spvincent Lv 1

Added a "Worst First" option which is enabled by default. If checked, segment sequences are sorted according to the sum of their ideality scores and the worst ones are processed first. This enables you to run the script and kill it after a few iterations (typically 10) when the script is no longer producing gains in the reasonable expectation that the script has gained whatever points is going to.

Algorithm outline

For each section (default length 3) in the selected range (default = whole protein)
    Isolate that section with cut points (prevents the structure from blowing apart)
    Idealize the section
    Close cutpoints
    Wiggle

angeltrouble Lv 1

Thank you so much, this recipe is fantastic.
I was reluctant to use cuts when aligning / setting up proteins because I never seemed to be able to solve the ideality issues without it blowing up, but not anymore!

LociOiling Lv 1

Score type 1 is normal scoring for puzzles without filters.

Score type 2 is for puzzles with filters. Score type 2 means filters are disabled during wiggle, but enabled before current.GetEnergyScore is called.

Score type 2 is selected by default if the recipe detects a filter bonus.