Icon representing a recipe

Recipe: Loop rebuild 9.0b

created by jeff101

Profile


Name
Loop rebuild 9.0b
ID
102944
Shared with
Public
Parent
Loop rebuild 9.0a
Children
Created on
November 20, 2018 at 08:42 AM UTC
Updated on
November 20, 2018 at 08:42 AM UTC
Description

*9.0b7.txt 11/19/18 142am code

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. -- 9.0b.txt = Use Density subscore & let user control order that residues are rebuilt. -- Last updated 11/19/18 142am -- ========================================================================================= -- Below sets the globals prog_name='Loop rebuild 9.0b' -- Mostly user-configurable globals rebuild_length = 6 -- Length of sections to rebuild. number_of_rebuilds = 8 -- It'll look for the best score from this number of rebuilds. ss_criterion = 2 -- 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 = false -- If true, test that all conditions are satisfied before registering an improvement keep_bands = true min_residue = 1 max_residue = 999 kInvalidScore = -99999 use_remix = true inner_sphere = {} outer_sphere = {} kInnerSphereRadius = 10 kOuterSphereRadius = 18 kDefaultWiggleDuration = 12 kLowCiWiggle = 0.2 pw_threshold_value = 30 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. rbord=0 -- rebuild order: 0=slices=default, 1=forward, 2=reverse, 3=inward, 4=outward. -- Use of quicksave slots kOriginalStructureOrNewBest = 1 kBestPostRebuild_a = 2 kBestPostRebuild_b = 3 kBestPostRebuild_a_post_wiggle = 4 kTemp = 5 kRemixQuicksaveStart = 20 -- 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 rb_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 ) elseif ( score_type == 8 ) then score = 0 for i = 1 , n_residues do score = score + current.GetSegmentEnergySubscore ( i , "density" ) end 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 or score_type == 8 ) then return 1 -- Hiding or Bonding or Density 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 or score_type == 8 ) then return -- Hiding or Bonding or Density elseif ( score_below_best < post_rebuild_threshold ) then -- ShakeLowCIWiggle ( init_score ) FinalIdealize ( init_score , start_x , end_x ) return else return end end function RecordImprovement () curr_score = GetScore () if ( ( test_for_credit == false ) or ( creditbest.AreConditionsMet () == true ) ) then rb_last_gain = rb 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)=%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 ) if ( use_remix == true ) then RebuildPreamble ( start_idx , end_idx ) n_rebuilds = structure. RemixSelected ( kRemixQuicksaveStart , number_of_rebuilds ) else n_rebuilds = number_of_rebuilds end for i = 1 , n_rebuilds do if ( use_remix == true ) then save.Quickload ( kRemixQuicksaveStart -1 + i ) else RebuildPreamble ( start_idx , end_idx ) structure.RebuildSelected ( 1 ) 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 return n_good_rebuilds end -- below is main part of main loop function RebuildAllAtSpecifiedLength ( rebuild_length ) local inc, aastr, ssstr, aatmp, sstmp, jj max_possible_residue = max_residue - rebuild_length + 1 n_possible_segs = max_possible_residue - min_residue + 1 if (rbord == 0) then -- slices 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 elseif (rbord==1) then -- forward start_idx = min_residue inc = 1 elseif (rbord==2) then -- reverse start_idx = max_possible_residue inc = -1 elseif (rbord==3) then -- inward start_idx = min_residue inc = max_possible_residue - start_idx elseif (rbord==4) then -- outward start_idx = math.floor(0.5*(min_residue+max_possible_residue)) -- truncates average inc = 1 end -- if rbord candidate_section_found = false print("Starting a new cycle thru the protein at:\n"..os.date()..".") 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 rb = rb + 1 -- need to get latest AminoAcid below because mutations can occur ssstr='' aastr='' for jj = start_idx, end_idx do aatmp=structure.GetAminoAcid(jj) sstmp=structure.GetSecondaryStructure(jj) aastr=(aastr..aatmp) ssstr=(ssstr..sstmp) end -- for jj -- need to get latest AminoAcid above because mutations can occur print("rb "..rb.." "..(rb-rb_last_gain).." "..start_idx.."-"..end_idx.."="..aastr.."="..ssstr.." ("..i.."/"..n_possible_segs.."):") 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 (rbord==3) then -- inward inc= -inc + (inc/math.abs(inc)) -- so gives inc = 40 -39 38 -37 36 -35 etc elseif (rbord==4) then -- outward inc= -inc - (inc/math.abs(inc)) -- so gives inc = 1 -2 3 -4 5 -6 etc end -- if rbord if ( start_idx > max_possible_residue ) then -- compensate for overshooting max start_idx = start_idx - n_possible_segs elseif ( start_idx < min_residue ) then -- compensate for undershooting min 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 function PrintParameters () local rbostr = 'Rebuild order ' local rbcstr = 'Rebuild criterion ' 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" ) elseif ( score_type == 8 ) then print ( "Score type : Density" ) end -- if score_type print(string.format("Start score : %.3f",trunc3(best_score))) print ( "Rebuild length : " .. rebuild_length ) rbcstr=(rbcstr..ss_criterion.." : ") if ( ss_criterion == 1 ) then print ( rbcstr.."Loops only" ) elseif ( ss_criterion == 2 ) then print ( rbcstr.."Loops + 1" ) elseif ( ss_criterion == 3 ) then print ( rbcstr.."Loops + sheets" ) elseif ( ss_criterion == 4 ) then print ( rbcstr.."Any" ) end -- if ss_criterion if ( convert_to_loop == true ) then print ( "Converting to loops" ) end if ( use_remix == true ) then print ( "Using remix" ) else print ( "Not using remix" ) end -- if use_remix 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 ) rbostr=(rbostr..rbord..' : ') if(rbord==0) then print(rbostr..'Slices') elseif(rbord==1) then print(rbostr..'Forward') elseif(rbord==2) then print(rbostr..'Reverse') elseif(rbord==3) then print(rbostr..'Inward') elseif(rbord==4) then print(rbostr..'Outward') end -- if rbord 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.rb_length = dialog.AddSlider ( "Rebuild length" , rebuild_length , 3 , 12 , 0 ) dlog.rebuild_list = dialog.AddTextbox ( "Rebuild segments" , 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.use_remix = dialog.AddCheckbox ( "Use remix" , use_remix ) dlog.rbord = dialog.AddSlider ("Rebuild order", rbord, 0, 4, 0) dlog.rbord_label = dialog.AddLabel("0=Slices, 1=Fwd, 2=Rev, 3=Inward, 4=Outward") 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 , 8 , 0 ) dlog.tp = dialog.AddLabel ( "1=Normal, 2=Energy, 3=Explore, 4=Hiding, 5=Bonding" ) dlog.tp_2 = dialog.AddLabel ( "6=Filters, 7=Normal for Slow Filters, 8=Density" ) 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 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 use_remix = dlog.use_remix.value rbord = dlog.rbord.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 (%s)', prog_name, ui.GetPlatform(), puzzle.GetPuzzleID(), puzzle.GetName() )) print(string.format('with %d residues, %d bands (%d enabled, %d disabled),\nand Score %.3f.', n_residues, n_bands, n_enabled, n_disabled, trunc3(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 RebuildAllAtSpecifiedLength ( rebuild_length ) end -- main loop is above & endless print('This line should never be reached') cleanup() end function cleanup () 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