Icon representing a recipe

Recipe: Loop Remix/Rebuild 12.5

created by ZeroLeak7

Profile


Name
Loop Remix/Rebuild 12.5
ID
109090
Shared with
Public
Parent
Loop Remix/Rebuild 12.0
Children
Created on
July 02, 2025 at 20:45 PM UTC
Updated on
July 03, 2025 at 21:43 PM UTC
Description

See first comment + added rebuild worst segments + for Density Puzzles with many residues

Best for


Code


-- Copyright notice. -- You may copy and paste at will. Plagiarize shamelessly! -- End copyright notice -- ========================================================================================= -- Adapted by jeff101 11/13/17 from spvincent's public 11/04/16 "Loop rebuild 8.0" recipe: -- 8.0a.txt = Original "Loop rebuild 8.0" code -- copy/pasted by 848am 10/05/17 from Foldit client 10b. -- Should be <Foldit:MacroID>102235</Foldit:MacroID> -- and <Foldit:MacroRevisionID>203034</Foldit:MacroRevisionID> -- code as used for scriptlog1445h14.txt. -- 8.0b.txt = Remove blank lines, replace some tabs w/spaces, -- make indenting & comments more uniform. -- Ideally all changes are superficial not functional. -- 9.0a.txt = Let user specify residues to rebuild & mutate. -- Last updated 11/17/17 303pm -- 12.0.txt = + added rebuild worst segments + settings in the gui and how many worst segments to rebuild -- Last updated 06/23/25 530am -- 12.5.txt = changed max_residue = structure.GetCount() -- max segments/residues like the current puzzle has! -- "for the next very large Puzzles" -- ========================================================================================= -- Below sets the globals prog_name='Loop Remix/Rebuild 12.5' -- Mostly user-configurable globals number_of_rebuilds = 8 -- It'll look for the best score from this number of rebuilds. ss_criterion = 4 -- Controls whether to rebuild a section based on secondary structure convert_to_loop = false -- If true, any non-loop residues will be temporarily converted to loops test_for_credit = true -- If true, test that all conditions are satisfied before registering an improvement keep_bands = true min_residue = 1 max_residue = structure.GetCount() -- max segments/residues like the current puzzle has! kInvalidScore = -99999 rebuild_worst = true -- Rebuild Worst Segments = true -- How many Worst segments to remix/rebuild (default value 30% from the number of residues of the entire Protein) howmany = (structure.GetCount() / 100) * 30 run_remix = true fidealize = false -- Final Idealize = false (default) inner_sphere = {} outer_sphere = {} kInnerSphereRadius = 10 kOuterSphereRadius = 18 kDefaultWiggleDuration = 12 kLowCiWiggle = 0.2 pw_threshold_value = 80 score_type = 1 rebuild_str="" rebuild_list={} -- will be a list of 1's & 0's for each residue. 1 means can rebuild. 0 means don't rebuild. mutate_str="" mutate_list={} -- will be a list of 1's & 0's for each residue. 1 means can mutate. 0 means don't mutate. -- Use of quicksave slots kOriginalStructureOrNewBest = 1 kBestPostRebuild_a = 2 kBestPostRebuild_b = 3 kBestPostRebuild_a_post_wiggle = 4 kTemp = 5 kRemixQuicksaveStart = 30 -- Globals original_secondary_structure = {} fixed_residues = {} original_slow_filters_setting = 0 n_bands = 0 orig_enabled_bands = {} n_residues = 0 best_score = 0 start_score = 0 score_after_bc_wiggle = 0 rb = 0 rb1 = 0 rx1 = 0 rb_last_gain = 0 rx_last_gain = 0 -- Controls whether we should do a mini-fuze -- (Shake at Low CI, Wiggle at CI of 1) after -- completion of the Rebuild sequence. -- A value of 0 means do it iff there's an overall improvement: -- a high negative value would mean do it always: -- a high positive value would mean do it always. post_rebuild_threshold = 2 -- For design mutate_not_shake = 0 -- 0 = shake only. default if not design -- 1 = mutate then shake -- 2 = mutate only. default for design -- For monitoring loss_from_low_ci_wiggle = {} original_residues = {} new_residues = {} start_time = os.time() -- Amino acids. Hydrophobics first. single_letter_codes={ "g", "a", "v", "l", "i", "m", "f", "w", "p", "s", "t", "c", "y", "n", "q", "d", "e", "k", "r", "h"} three_letter_codes={"Gly","Ala","Val","Leu","Ile", "Met","Phe","Trp","Pro","Ser", "Thr","Cys","Tyr","Asn","Gln", "Asp","Glu","Lys","Arg","His"} -- Above sets the globals -- ========================================================================================= -- Below defines the functions function r0 ( x ) -- Round to 0 decimal places return math.floor ( x + 0.5 ) -- x = -2.5 to -1.5001 becomes -2.0 -- x = -1.5 to -0.5001 becomes -1.0 -- x = -0.5 to 0.4999 becomes 0.0 -- x = 0.5 to 1.4999 becomes 1.0 -- x = 1.5 to 2.4999 becomes 2.0 -- x = 2.5 to 3.4999 becomes 3.0 end function r3 ( x ) -- Round to 3 decimal places t = 10 ^ 3 return math.floor ( x*t + 0.5 ) / t end function trunc3 (x) -- truncates to 3 decimal places -- as for the scores listed in Foldit GUI return math.floor(x*1000)/1000 end function GetScore () if ( score_type == 1 ) then score = current.GetScore () elseif ( score_type == 2 ) then score = current.GetEnergyScore () elseif ( score_type == 3 ) then score = current.GetScore () score = score * current.GetExplorationMultiplier () elseif ( score_type == 4 ) then score = 0 for i = 1 , n_residues do score = score + current.GetSegmentEnergySubscore ( i , "hiding" ) end elseif ( score_type == 5 ) then score = 0 for i = 1 , n_residues do score = score + current.GetSegmentEnergySubscore ( i , "bonding" ) end elseif ( score_type == 6 ) then behavior.SetSlowFiltersDisabled ( false ) score_with_filters = current.GetScore () behavior.SetSlowFiltersDisabled ( true ) score_without_filters = current.GetScore () score = score_with_filters - score_without_filters elseif ( score_type == 7 ) then behavior.SetSlowFiltersDisabled ( false ) score = current.GetScore () behavior.SetSlowFiltersDisabled ( true ) end return score end function IsPuzzleMutable () for i = 1 , n_residues do if ( structure.IsMutable ( i ) ) then return true end end return false end function aa1_to_aa3 ( k ) for j = 1, 20 do if ( k == single_letter_codes [ j ] ) then return three_letter_codes [ j ] end end return "Unk" 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 Coprime ( n ) -- 11/15/17 http://primes.utm.edu/lists/small/1000.txt -- lists the following plus many more prime numbers: 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, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997,1009,1013} 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 SegmentComposition ( first, last ) -- Returns number of residues of each secondary structure type n_loop_residues = 0 n_helix_residues = 0 n_sheet_residues = 0 for i = first, last do ss = structure.GetSecondaryStructure ( i ) if ( ss == "L" ) then n_loop_residues = n_loop_residues + 1 elseif ( ss == "H" ) then n_helix_residues = n_helix_residues + 1 elseif ( ss == "E" ) then n_sheet_residues = n_sheet_residues + 1 end end return n_loop_residues, n_helix_residues, n_sheet_residues end function IsSegmentRebuildable ( first, last ) local i,tot tot = 0 for i = first, last do tot = tot + rebuild_list[i] end if tot < rebuild_length then return false end -- Above checks if enough residues in the segment are in the rebuild_list. -- Below checks if the segment is rebuildable in the sense that its -- secondary structure satisfies the specified criteria. n_loop_residues,n_helix_residues,n_sheet_residues=SegmentComposition(first,last) if ( ss_criterion == 1 ) then -- Loops only if ( n_helix_residues > 0 or n_sheet_residues > 0 ) then return false else return true end elseif ( ss_criterion == 2 ) then -- Loops with one non-loop residue if ( n_helix_residues + n_sheet_residues > 1 ) then return false else return true end elseif ( ss_criterion == 3 ) then -- Loops or sheets if ( n_helix_residues > 0 ) then return false else return true end elseif ( ss_criterion == 4 ) then return true end end function ConvertToLoop ( first , last ) -- Slightly inefficient to call SegmentComposition twice n_loop_residues,n_helix_residues,n_sheet_residues=SegmentComposition(first,last) if ( n_helix_residues + n_sheet_residues > 0 ) then selection.DeselectAll ( ) selection.SelectRange ( first , last ) structure.SetSecondaryStructureSelected ( "L" ) 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 ) -- what to do if just the sidechains are frozen? 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 DoesSectionContainFixedResidues ( 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 ShakeLowCIWiggle ( c_score ) save.Quicksave ( kTemp ) behavior.SetClashImportance ( 0.10 ) structure.ShakeSidechainsSelected ( 1 ) behavior.SetClashImportance ( 1 ) structure.WiggleSelected ( kDefaultWiggleDuration ) score = GetScore () if ( score < c_score ) then save.Quickload ( kTemp ) score = c_score end end function FinalIdealize ( c_score , start_idx , end_idx ) kFallApartThreshold = 1000 save.Quicksave ( kTemp ) selection.DeselectAll () selection.SelectRange ( start_idx , end_idx ) structure.IdealizeSelected () score_after_idealize = GetScore () selection.SelectAll () if ( ( c_score - score_after_idealize ) > kFallApartThreshold ) then structure.WiggleAll ( 1, false , true ) -- wiggle sidechains end if ( math.abs ( score - c_score ) > 1e-3 ) then structure.WiggleSelected ( 12 ) score = GetScore () if ( score < c_score ) then save.Quickload ( kTemp ) score = c_score end end end function WiggleNudge ( c_score ) save.Quicksave ( kTemp ) structure.WiggleSelected ( kDefaultWiggleDuration ) aa_score = GetScore () if ( aa_score < c_score ) then save.Quickload ( kTemp ) aa_score = c_score -- Cater to filter-induced score decrease end save.Quicksave ( kTemp ) behavior.SetClashImportance ( kLowCiWiggle ) structure.WiggleSelected ( 1 ) table.insert ( loss_from_low_ci_wiggle , aa_score - GetScore () ) behavior.SetClashImportance ( 1 ) structure.WiggleSelected ( kDefaultWiggleDuration ) score = GetScore () if ( score < aa_score ) then save.Quickload ( kTemp ) end end function WiggleTwoBestCandidatesAndSelectBest () save.Quickload ( kBestPostRebuild_a ) structure.WiggleSelected ( kDefaultWiggleDuration ) score_a = GetScore () save.Quicksave ( kBestPostRebuild_a_post_wiggle ) if ( best_score_after_rebuild_and_shake_b > kInvalidScore ) then -- To cater for single rebuild save.Quickload ( kBestPostRebuild_b ) structure.WiggleSelected ( kDefaultWiggleDuration ) score_b = GetScore () if ( score_a > score_b ) then save.Quickload ( kBestPostRebuild_a_post_wiggle ) end end end function PostWiggle () local i local mutstr='' local selstr='' local swapsel = {} init_score = GetScore () save.Quicksave ( kTemp ) if ( score_type == 4 or score_type == 5 or score_type == 6 ) then return 1 -- Hiding or bonding elseif ( best_score - init_score < pw_threshold_value ) then if ( mutate_not_shake >= 1) then -- 1 or 2 do mutate for i = 1, n_residues do swapsel[i]=0 if selection.IsSelected(i) == true then selstr=(selstr..i..' ') if mutate_list[i]==0 then selection.Deselect(i) swapsel[i]=1 else mutstr=(mutstr..i..' ') end end end print('Trying to mutate residues '..mutstr) structure.MutateSidechainsSelected ( 1 ) for i = 1, n_residues do if swapsel[i]==1 then selection.Select(i) end end end if (mutate_not_shake <= 1) then -- 0 or 1 do shake print('Shaking residues '..selstr) structure.ShakeSidechainsSelected ( 1 ) end score = GetScore () if ( score < init_score ) then save.Quickload ( kTemp ) -- Cater for filters causing a decrease score = init_score end WiggleNudge ( score ) return 1 else return 0 end end function FinalFuse ( start_x , end_x ) -- After rebuilding, if we've got a new best score -- (tweakable by adjusting post_rebuild_threshold), -- do a shake at low CI followed by a wiggle init_score = GetScore () score_below_best = best_score - init_score if ( score_type == 4 or score_type == 5 or score_type == 6 ) then return -- Hiding or bonding elseif ( score_below_best < post_rebuild_threshold ) then if (fidealize == true) then FinalIdealize ( init_score , start_x , end_x ) else ShakeLowCIWiggle ( init_score ) end return else return end end function RecordImprovement () curr_score = GetScore () if ( ( test_for_credit == false ) or ( creditbest.AreConditionsMet () == true ) ) then rb_last_gain = rb rx_last_gain = rx new_gain = curr_score - best_score all_gain = curr_score - start_score best_score = curr_score save.LoadSecondaryStructure () save.Quicksave ( kOriginalStructureOrNewBest ) print(string.format("Improvement to %.3f (%.3f/%.3f)\n=%d%% of gain so far.", trunc3(best_score),r3(new_gain),r3(all_gain),r0(100*new_gain/all_gain) )) return 1 else return 0 end end function ConstructListOfResiduesWithinInnerSphere ( start_idx , end_idx ) for i = 1 , n_residues do inner_sphere [ i ] = false end for i = 1 , n_residues do for j = start_idx , end_idx do if ( structure.GetDistance ( i , j ) < kInnerSphereRadius ) then inner_sphere [ i ] = true end end end end function SelectInnerSphere () selection.DeselectAll () for i = 1 , n_residues do if ( inner_sphere [ i ] == true ) then selection.Select ( i ) end end end function ConstructListOfResiduesWithinOuterSphere ( start_idx , end_idx ) for i = 1 , n_residues do outer_sphere [ i ] = false end for i = 1 , n_residues do for j = start_idx , end_idx do if ( structure.GetDistance ( i , j ) < kOuterSphereRadius ) then outer_sphere [ i ] = true end end end end function SelectOuterSphere () selection.DeselectAll () for i = 1 , n_residues do if ( outer_sphere [ i ] == true ) then selection.Select ( i ) end end end function RebuildPreamble ( start_idx , end_idx ) save.Quickload ( kOriginalStructureOrNewBest ) if ( convert_to_loop == true ) then ConvertToLoop ( start_idx , end_idx ) end selection.DeselectAll () selection.SelectRange ( start_idx , end_idx ) end function RebuildSeg ( start_idx , end_idx) local i local n_rebuilds local n_good_rebuilds = 0 best_score_after_rebuild_and_shake_a = kInvalidScore best_score_after_rebuild_and_shake_b = kInvalidScore ConstructListOfResiduesWithinInnerSphere ( start_idx , end_idx ) ConstructListOfResiduesWithinOuterSphere ( start_idx , end_idx ) use_remix = run_remix if ( use_remix == true ) then RebuildPreamble ( start_idx , end_idx ) n_remix = structure.RemixSelected ( kRemixQuicksaveStart , number_of_rebuilds ) if (n_remix == 0) then n_rebuilds = number_of_rebuilds use_remix = false rx = 0 else use_remix = true rx = 1 end else n_rebuilds = number_of_rebuilds end if (rx >= 1) then rx=n_remix else rx=n_rebuilds end for i = 1 , rx do if ( use_remix == true ) then save.Quickload ( kRemixQuicksaveStart -1 + i ) rx = n_remix else RebuildPreamble ( start_idx , end_idx ) structure.RebuildSelected ( 1 ) rb = n_rebuilds end score_after_rebuild = GetScore () if ( math.abs ( score_after_rebuild - best_score ) >= 1e-5 ) then n_good_rebuilds = n_good_rebuilds + 1 SelectInnerSphere () structure.ShakeSidechainsSelected ( 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 end -- for i if (rb == n_rebuilds) then rb1 = rb1 + 1 print("rb "..rb1.." rb_number: "..rb.." "..start_idx.."-"..end_idx.." ("..start_idx.."/"..max_residue..")") else rx1 = rx1 + 1 print("rx "..rx1.." rx_found: "..rx.." "..start_idx.."-"..end_idx.." ("..start_idx.."/"..max_residue..")") end return n_good_rebuilds end -- below is main part of main loop function RebuildAllAtSpecifiedLength ( rebuild_length ) local inc max_possible_residue = max_residue - rebuild_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 ) -- increment used for start_idx -- 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-24, 53-57, 3-6 -- or something like that candidate_section_found = false print("Starting a new cycle thru the protein at:\n"..os.date()..".") print("==============="..prog_name.. "===============") for i = 1 , n_possible_segs do end_idx = start_idx + rebuild_length - 1 assert ( start_idx >= min_residue and end_idx <= max_residue , "Range error" ) save.LoadSecondaryStructure () if ( ( DoesSectionContainFixedResidues ( start_idx , end_idx ) == false ) and ( IsSegmentRebuildable ( start_idx , end_idx ) == true ) ) then candidate_section_found = true print("("..i.."/"..n_possible_segs..")") print(n_possible_segs+1-i, " segments left to do.") if ( RebuildSeg ( start_idx , end_idx ) > 0 ) then print('1') SelectOuterSphere () print('2') WiggleTwoBestCandidatesAndSelectBest () print('3') score_after_bc_wiggle = GetScore () if ( PostWiggle () == 1 ) then score_after_post_wiggle = GetScore () print('4') FinalFuse ( start_idx , end_idx ) print('5') score_after_final_fuse = GetScore () if ( score_after_final_fuse > best_score ) then print ( " " .. r3 ( score_after_bc_wiggle - best_score ) .. " " .. r3 ( score_after_post_wiggle - score_after_bc_wiggle ) .. " " .. r3 ( score_after_final_fuse - score_after_post_wiggle ) ) RecordImprovement () -- prints new score else print ( " " .. r3 ( score_after_bc_wiggle - best_score ) .. " " .. r3 ( score_after_post_wiggle - score_after_bc_wiggle ) ) end -- if(score else print ( " " .. r3 ( score_after_bc_wiggle - best_score ) ) end -- if(PostWiggle else print ( "Skipped" ) end -- if(RebuildSeg end -- if((DoesSectionContainFixedResidues print('6') start_idx = start_idx + inc if ( start_idx > max_possible_residue ) then start_idx = start_idx - n_possible_segs end end -- for i print('7') if ( candidate_section_found == false ) then print ( "No rebuildable sections found" ) exit (0) end end -- above is main part of main loop -- -- the function Sort is taken from http://fold.it/portal/recipe/49233 -- "Tvdl enhanced DRW 3.0.1" by Timo van der Laan -- function Sort ( tab, items ) --BACKWARD bubble sorting - lowest on top, only needed items for xx = 1, items do --items do for yy = xx + 1, #tab do if tab [ xx ] [ 1 ] > tab [ yy ] [ 1 ] then tab [ xx ], tab [ yy ] = tab [ yy ], tab [ xx ] end end end return tab end function Rebuild_Worst(howmany, rebuild_length) segCnt = structure.GetCount() -- -- get the score of each segment, store it in a table -- scoreTab = {} -- a new, empty table for ii = 1, segCnt do scoreTab [ #scoreTab + 1 ] = current.GetSegmentEnergyScore ( ii ) end -- -- now get the worst sections of the specified length -- worstTab = {} -- another new empty table for ii = 1, segCnt - rebuild_length + 1 do local partScore = 0 for jj = ii, ii + rebuild_length - 1 do partScore = partScore + scoreTab [ jj ] end worstTab [ #worstTab + 1 ] = { partScore, ii, ii + rebuild_length - 1 } end buildWorst = howmany worstTab = Sort ( worstTab, buildWorst ) max_possible_residue = max_residue n_possible_segs = max_possible_residue - min_residue + 1 candidate_section_found = false print("Starting a new cycle of Remix/Rebuild Worst Segments:\n"..os.date()..".") print("============= Remix/Rebuild Worst =============") for i = 1 , howmany do print(howmany+1-i, " segments left to do.") seg = worstTab [ i ] [ 2 ] end_idx = worstTab [ i ] [ 3 ] save.LoadSecondaryStructure () if ( ( DoesSectionContainFixedResidues ( seg , end_idx ) == false ) and ( IsSegmentRebuildable ( seg , end_idx ) == true ) ) then candidate_section_found = true if ( RebuildSeg ( seg , end_idx ) > 0 ) then print('1') SelectOuterSphere () print('2') WiggleTwoBestCandidatesAndSelectBest () print('3') score_after_bc_wiggle = GetScore () if ( PostWiggle () == 1 ) then score_after_post_wiggle = GetScore () print('4') FinalFuse ( seg , end_idx ) print('5') score_after_final_fuse = GetScore () if ( score_after_final_fuse > best_score ) then print ( " " .. r3 ( score_after_bc_wiggle - best_score ) .. " " .. r3 ( score_after_post_wiggle - score_after_bc_wiggle ) .. " " .. r3 ( score_after_final_fuse - score_after_post_wiggle ) ) RecordImprovement () -- prints new score else print ( " " .. r3 ( score_after_bc_wiggle - best_score ) .. " " .. r3 ( score_after_post_wiggle - score_after_bc_wiggle ) ) end -- if(score else print ( " " .. r3 ( score_after_bc_wiggle - best_score ) ) end -- if(PostWiggle else print ( "Skipped" ) end -- if(RebuildSeg end -- if((DoesSectionContainFixedResidues end -- for i print('7') if ( candidate_section_found == false ) then print ( "No rebuildable sections found" ) exit (0) end end function PrintParameters () if ( score_type == 1 ) then print ( "Score type : Normal" ) elseif ( score_type == 2 ) then print ( "Score type : Energy" ) elseif ( score_type == 3 ) then print ( "Score type : Exploration" ) elseif ( score_type == 4 ) then print ( "Score type : Hiding" ) elseif ( score_type == 5 ) then print ( "Score type : Bonding" ) elseif ( score_type == 6 ) then print ( "Score type : Filters" ) elseif ( score_type == 7 ) then print ( "Score type : Normal/Slow Filters" ) end -- if score_type print(string.format("Start score: %.3f",trunc3(best_score))) print ( "Rebuild length: " .. rebuild_length ) if ( ss_criterion == 1 ) then print ( "Loops only" ) elseif ( ss_criterion == 2 ) then print ( "Loops + 1" ) elseif ( ss_criterion == 3 ) then print ( "Loops + sheets" ) elseif ( ss_criterion == 4 ) then print ( "Any" ) end -- ss_criterion if ( convert_to_loop == true ) then print ( "Converting to loops" ) end if ( run_remix == true ) then print ( "Using remix" ) end if ( rebuild_worst == true ) then print ( "Run Rebuild Worst Segments" ) end if ( fidealize == true) then print ( "Run Final Idealize in Final Fuze" ) else print ( "Run ShakeLowCIWiggle in Final Fuze" ) end if ( design_puzzle == true ) then print('Mutate_list = \"'..mutate_str..'\" = \"'..printlist(mutate_list)..'\"') if (mutate_not_shake==0) then print("Shake not mutate") elseif(mutate_not_shake==1) then print("Mutate then shake") elseif(mutate_not_shake==2) then print("Mutate not shake") else print('MSflag='..mutate_not_shake..' is not in range (0-2)') end end -- if design_puzzle print('Rebuild_list = \"'..rebuild_str..'\" = \"'..printlist(rebuild_list)..'\"') print ( "Rebuild range " .. min_residue .. " to " .. max_residue ) print ( "N rebuilds " .. number_of_rebuilds ) if ( keep_bands == true) then print('Won\'t disable bands') end end -- http://www.lua.org/manual/5.2/manual.html#6.4 -- helped make this function 11/16/17 function getlist(liststr) local newlist={} local i,ilo,ihi,idir,substr for i=1,n_residues do newlist[i]=0 end -- for i -- below reads from liststr a series of substr's -- where each substr contains an integer -- followed by one or more '-' signs -- followed by an integer for substr in string.gmatch(liststr,"(%d+%-+%d+)") do -- substr includes one or more '-' characters in a row -- below gets ilo & ihi from substr ilo=string.gsub(substr,"(%d+)%-+(%d+)","%1")+0 ihi=string.gsub(substr,"(%d+)%-+(%d+)","%2")+0 -- above gets ilo & ihi from substr idir=1 -- the increment to use from ilo to ihi if ilo>ihi then idir= -1 end -- if ilo for i=ilo,ihi,idir do -- for i=ilo to ihi step idir if i>=1 and i<=n_residues then newlist[i]=1 end -- if i end -- for i end -- for substr -- below reads from liststr a series of substr's -- where each substr contains an integer for substr in string.gmatch(liststr,"(%d+)") do i=substr+0 -- converts substr into the number i if i>=1 and i<=n_residues then newlist[i]=1 end -- if i end -- for substr return newlist end function checklist() local i,resinrow,maxresinrow min_residue=0 max_residue=0 resinrow=0 maxresinrow=0 for i=1,n_residues do if rebuild_list[i]==1 then resinrow=resinrow+1 max_residue=i if min_residue==0 then min_residue=i end else if resinrow>maxresinrow then maxresinrow=resinrow end resinrow=0 end -- if rebuild_list end -- for i if resinrow>maxresinrow then maxresinrow=resinrow end if maxresinrow<rebuild_length then print("Rebuild range error.") print("The list of residues to rebuild (\""..rebuild_str.."\" input above)") print("has at most "..maxresinrow.." of the desired "..rebuild_length.." residues in a row.") return 0 else return 1 end -- if maxresinrow end -- http://www.lua.org/manual/5.2/manual.html#6.4 -- helped make this function 11/16/17 function printlist(templist) local outstr='' local i,gotone,strlen gotone=0 for i=1,n_residues do if templist[i]==1 then gotone=gotone+1 if gotone==1 then outstr=(outstr..i) end -- if gotone else -- templist[i]==0 if gotone>1 then outstr=(outstr..'-'..(i-1)..' ') elseif gotone==1 then outstr=(outstr..' ') end -- if gotone gotone=0 end -- if templist end -- for i if gotone>1 then outstr=(outstr..'-'..n_residues) end -- if gotone strlen=string.len(outstr) if string.sub(outstr,strlen,strlen)==' ' then -- if outstr ends with a blank space, -- then remove that blank space outstr=string.sub(outstr,1,strlen-1) end return outstr end function GetOptionalParameters () local dlog = dialog.CreateDialog("Options") dlog.pw_threshold = dialog.AddSlider("Post sw threshold", pw_threshold_value, 0, 200, 0) dlog.cnvt_loops = dialog.AddCheckbox("Convert to loops", convert_to_loop) dlog.keep_bands = dialog.AddCheckbox("Keep bands", keep_bands) dlog.ok = dialog.AddButton ( "OK" , 1 ) dlog.cancel = dialog.AddButton ( "Cancel" , 0 ) if ( dialog.Show ( dlog ) > 0 ) then pw_threshold_value = dlog.pw_threshold.value convert_to_loop = dlog.cnvt_loops.value keep_bands = dlog.keep_bands.value return true else return false end end function GetParameters () local dlog = dialog.CreateDialog (prog_name) dlog.f_idealize = dialog.AddCheckbox ("Final Idealize" , fidealize) dlog.rb_worst_howmany = dialog.AddSlider ( "How many worst" , howmany , 3 , structure.GetCount() , 0 ) dlog.rb_worst = dialog.AddCheckbox ( "Rebuild worst segments" , rebuild_worst ) dlog.rb_length = dialog.AddSlider ( "Rebuild length" , 6 , 3 , 9 , 0 ) dlog.rlabel_list = dialog.AddLabel("Rebuild Segments:") dlog.rebuild_list = dialog.AddTextbox ( "Rebuild Segs" , rebuild_str ) dlog.rlabela = dialog.AddLabel('List segs to rebuild like 1-3,6,19-30,45-62') if design_puzzle == true then dlog.mutate_list = dialog.AddTextbox ( "Mutate segments" , mutate_str ) dlog.mlabela = dialog.AddLabel('List segs to mutate like 1-3,6,19-30,45-62') end -- if design_puzzle dlog.rebuild_criterion = dialog.AddSlider ( "Rebuild criterion" , ss_criterion , 1 , 4 , 0 ) dlog.rc = dialog.AddLabel ( "1 = L only : 2 = L only + 1 : 3 = L + E : 4 = Any" ) dlog.n_rebuilds = dialog.AddSlider ( "N rebuilds" , number_of_rebuilds , 1 , 40 , 0 ) dlog.run_remix = dialog.AddCheckbox ( "Use remix" , run_remix ) dlog.div_1 = dialog.AddLabel ( "__________________________________________" ) if ( design_puzzle == true ) then dlog.mutate = dialog.AddSlider ( "MSflag" , mutate_not_shake, 0, 2, 0 ) dlog.mlabelb = dialog.AddLabel ( "0=Shake only, 1=Mutate then Shake, 2=Mutate only" ) end if ( DoesPuzzleHaveSlowFilters () == true ) then score_type = 7 end dlog.score_type = dialog.AddSlider ( "Score type" , score_type , 1 , 7 , 0 ) dlog.tp = dialog.AddLabel ( "1 = Normal : 2 = Energy : 3 = Explore : 4 = Hiding" ) dlog.tp_2 = dialog.AddLabel ( "5 = Bonding : 6 = Filters : 7 = Normal for Slow Filters" ) dlog.credit_check = dialog.AddCheckbox ( "Check conditions met " , test_for_credit ) dlog.ok = dialog.AddButton ( "OK" , 1 ) dlog.cancel = dialog.AddButton ( "Cancel" , 0 ) dlog.other_options = dialog.AddButton ( "Other options" , 2 ) return_code = dialog.Show ( dlog ) if ( return_code > 0 ) then fidealize = dlog.f_idealize.value howmany = dlog.rb_worst_howmany.value rebuild_worst = dlog.rb_worst.value rebuild_length = dlog.rb_length.value rebuild_list = getlist(dlog.rebuild_list.value) rebuild_str = printlist(rebuild_list) ss_criterion = dlog.rebuild_criterion.value number_of_rebuilds = dlog.n_rebuilds.value run_remix = dlog.run_remix.value if ( design_puzzle == true ) then mutate_list = getlist(dlog.mutate_list.value) mutate_str = printlist(mutate_list) mutate_not_shake = dlog.mutate.value end score_type = dlog.score_type.value test_for_credit = dlog.credit_check.value end return return_code end function main() local n_enabled, n_disabled, templist n_bands = band.GetCount () n_enabled = 0 n_disabled = 0 for i = 1, n_bands do orig_enabled_bands [i] = 0 if band.IsEnabled(i) == true then orig_enabled_bands [i] = 1 n_enabled = n_enabled + 1 else n_disabled = n_disabled + 1 end end n_residues = structure.GetCount () for i = 1, n_residues do original_secondary_structure [ i ] = structure.GetSecondaryStructure ( i ) end save.SaveSecondaryStructure () templist = string.format('1-%d',n_residues) rebuild_str=templist rebuild_list=getlist(templist) design_puzzle = IsPuzzleMutable () if design_puzzle == true then mutate_not_shake = 2 mutate_str=templist mutate_list=getlist(templist) else mutate_not_shake = 0 end rb = 0 rb_last_gain = 0 save.Quicksave ( kOriginalStructureOrNewBest ) behavior.SetClashImportance ( 1 ) if ( current.GetExplorationMultiplier () > 0 ) then score_type = 3 end original_slow_filters_setting = behavior.GetSlowFiltersDisabled () -- below gets player input repeat dialog_code = GetParameters () if ( dialog_code == 2 ) then GetOptionalParameters () end until ( dialog_code < 2 ) if ( dialog_code == 0 ) then return end best_score = GetScore () start_score = best_score print(string.format('Running %s on %s for\nPuzzle %s \n (%s) with', prog_name, ui.GetPlatform(), puzzle.GetPuzzleID(), puzzle.GetName() )) print(string.format('%d residues, %d bands (%d enabled, %d disabled),\nand Score %.3f.', n_residues, n_bands, n_enabled, n_disabled, start_score)) if checklist() == 0 then return end -- above gets player input PrintParameters () start_time = os.time () if ( keep_bands == false ) then band.DisableAll () -- turns all bands gray end GetListOfFixedResidues () if ( mutate_not_shake >= 1 ) then for i = 1 , n_residues do original_residues [ i ] = structure.GetAminoAcid ( i ) end end -- main loop is below & endless while true do if (rebuild_worst == true) then Rebuild_Worst(howmany,rebuild_length) end RebuildAllAtSpecifiedLength ( rebuild_length ) end -- main loop is above & endless print('This line should never be reached') cleanup() end function cleanup (errmsg) if CLEANUPENTRY ~= nil then return end CLEANUPENTRY = true print ( "---" ) local reason local start, stop, line, msg if errmsg == nil then reason = "complete" else start, stop, line, msg = errmsg:find ( ":(%d+):%s()" ) if msg ~= nil then errmsg = errmsg:sub ( msg, #errmsg ) end if errmsg:find ( "Cancelled" ) ~= nil then reason = "cancelled" else reason = "error" end end print ( prog_name .. " " .. reason .. " " .. os.date ( "%x %X" )) if reason == "error" then print ( "Unexpected error detected" ) print ( "Error line: " .. line ) print ( "Error: \"" .. errmsg .. "\"" ) end local tot print ( "Cleaning up" ) behavior.SetClashImportance ( 1.0 ) save.Quickload ( kOriginalStructureOrNewBest ) best_score = GetScore() if ( convert_to_loop == true ) then save.LoadSecondaryStructure () end selection.SelectAll () if ( keep_bands == false ) then for i=1,n_bands do -- turn certain bands purple again if orig_enabled_bands[i]==1 then band.Enable(i) end end -- for i end -- if keep_bands behavior.SetSlowFiltersDisabled ( original_slow_filters_setting ) end_time = os.time () print(os.date()) print("Elapsed time : "..os.difftime(end_time,start_time).." secs") print("Final Score "..trunc3(best_score)) if ( #loss_from_low_ci_wiggle > 1 ) then table.sort ( loss_from_low_ci_wiggle ) mid_pt = math.ceil ( #loss_from_low_ci_wiggle / 2 ) print("Median loss from low ci ("..kLowCiWiggle..") wiggle "..r3(loss_from_low_ci_wiggle[mid_pt])) end if ( mutate_not_shake >= 1 ) then tot=0 for i = 1 , n_residues do new_residues [ i ] = structure.GetAminoAcid ( i ) if ( new_residues [ i ] ~= original_residues [ i ] ) then tot=tot+1 end end -- for i if tot>0 then print('Did '..tot..' mutations as below:') for i = 1 , n_residues do if ( new_residues [ i ] ~= original_residues [ i ] ) then print (i.." : "..aa1_to_aa3(original_residues[i]).." to "..aa1_to_aa3(new_residues[i])) end end -- for i end -- if tot end -- if mutate_not_shake end -- Above defines the functions -- ========================================================================================= -- Below runs the program -- main () xpcall ( main , cleanup )

Comments