Icon representing a recipe

Recipe: Ebola Rebuild 1.12.6

created by Bruno Kestemont

Profile


Name
Ebola Rebuild 1.12.6
ID
48385
Shared with
Public
Parent
Ebola Rebuild 1.12.1
Children
Created on
December 01, 2015 at 19:34 PM UTC
Updated on
December 01, 2015 at 19:34 PM UTC
Description

DRW+GAB, NC ready. By Jean-Bob and L'Alliance Francophone.

Best for


Code


--[[ Ebola Rebuild Scripted by Jean-Bob Brainstormed by LAlliance Francophone Based mainly on Rav3n_pl recipes (DRW+GAB) Dialog taken from Timo van der Laan's DRW ------------------------------ GAB - Genetic Algorythm on Bands by Rav3n_pl based on CartoonVillan and Crashguard303 scripts 21/3/2013: corrected bug unwanted negative scores + clarifying user interface BK 10/4/13: multilingual options BK 28/4/2013: bug 'nil value' fixed 10/6/13 Filter optimization+mute desactivation on all prot 8/7/13 Replaced "other" by "density" 13/1/2014 Fixed slot 1 to slot 100 for better yield 31/1/2014 Adapted for NC, ver 1.12.2 02/02/2014 Adapted Qstab ver 1.12.3 nc 02/02/2014 Negative score bug 07/02/2014 added ideality score 09/02/2014 attempt to optimize wiggle for New Chapter 01/03/2014 added reference score 30/03/2014 bug negative score on skip fuze mode hopefully fixed + better GAB dialog 8/11/2014 v1.12.5 Changed Shake by QuickShake + note management 30/11/2015 v1.12.6 added Longer rebuild first ]]-- -- User variables uo={ --user options. Very long table but useful to restore script lang="en", -- New BK 10/4/13 recipeName="EbolaRebuild", numSegs=10, -- Number of segments per zone contSegsMax=6, -- Max number of contiguous segments to analyse contSegsMin=3, -- Min number of contiguous segments to analyse maxContSegs=10, -- Number of contiguous segments to not exceed (loop mode) longfirst=false, --true -- Reverse the search, long ones first wholeProt=false, -- whole protein rebuild zoneWalk=false, -- walk into forceZone in the order of segments instead of scores autoGab=false, -- Run Gab automatically if the fuse gained some points gabThresh=30, -- Threshold for Gab launching rebuildBest=false, -- Best segments rebuild rebuildNum=11, -- Number of rebuilds to do -- reduce this to save time -- NC: rebuid is better, can be reduced now solsPerScore=3, -- Number of best solutions to test after rebuild rebuildCI=0, -- clash importance during rebuild rebuildLoops=true, -- Transfor protein to loop scoreFilter=20, -- Minimum score for launching GAB passGAB=false, -- Do not launch GAB allowLoss=false, -- Allow loss in a complete cycle lossThresh=1, -- Amount of allowed loss -- Etait 100, passe a 1 BK 19/3 fastMode=false, -- Enable fuse minRebuild=1500, -- Minimal score below the maximal score to accept the rebuild maxRebuild=.001, -- Minimal score above the maximal score to accept the rebuild fastFuse=true, -- Use 1 fuse instead of 5 verbose=false, -- More information in the output window if true PROBABLEFILTER=false, -- new BK 8/5/2013 OriginalFilterSetting=behavior.GetSlowFiltersDisabled(), -- new BK 8/5/2013 -- Automatic options used for the script saving resumeScript=false, curSeg=0, segs=0, curArray='', stIndex=2, scoringMode="Backbone", subscores={}, forceZoneStr='', forceZone={}, maxVal=-10, -- Mean maximum score for taking the segments into account -- GAB options: energy = false, -- True to find energy in exploratory puzzles. False works on every puzzles pullCI = 0.55, -- Clash Importance during pull mode maxCI = 1, -- maximum during the script fastQstab = true, -- Only 1 shake and 1 wiggle in pull mode if true -- BK 11/6: default, no option fuzeThresh = 10, -- Launch fuse if next to the highscore qstabThresh = 1, -- Launch qstab if score is lower than otherwise, only wiggle useLigand = false, --Use ligand if true onlyMutable = false, -- If true use ONLY every mutable mutateOnce = false, -- If true use mutate(1) instead of shake in qstab mutateOnceCI = 0.21, -- Mutate with this CI mutateAlways = false, -- If true use mutate(1) instead of each shake -- BK not used 11/6/2013 preciseBands=true, -- If false only use random bands herd= -- options herd { breedBest = 3, --Number of best critters to breed keepBest = 5, -- Number of best critters to keep breedBastards = 2, -- Number of best critters to produce bastards firstGen = 10, -- Number of critters in first generation newRandom = 4, -- Number of random critters added for each generation maxGen= 3, -- Maximum of generations shuffle = true, -- Launch critters in random order --After x generations that dont increase the score : renew=1, -- create a completely random generation maxBadGen=2, -- Stop the script after X generations that dont increase the score }, critter= --critter options { minBands=2, --minimum bands maxBands=5, --maximum bands keepScore = -50 , -- Critters with lower score dont go to the next generation breedScore= -20, -- Minimal score to do some kids. Bastards always breed maxLoss=0, -- Maximum loss per critter totalLoss=0, -- Maximum loss per generation giveUp=200, -- Next critter if under this threshold keepConditions=true, -- Next critter if a condition is lost }, bands= --bands options { minStr=0.3, --minimum band str maxStr=1.1, --maximum band str minChng = 3, -- minimum change of band len according to current distance maxUp = 6.1, -- maximum change up (push) maxDn = 6.9, -- maximum change down (pull) minSkip = 5, --minimum segment distance minDist = 4, --minimum spatial distance minLen = 2, --minimum length of created band } }-- end of userOptions function setlanguage()-- New BK 10/4/13 local player=user.GetPlayerName() local group=user.GetGroupName() if group=="L'Alliance Francophone" or player==("marie_s" or "roukess" or "bruno.kestemont") then uo.lang="fr" else uo.lang="en" end return uo.lang end function multilingual(lang)-- New BK 10/4/13 if lang=="fr" then -- translation table. do NOT replace %-letter combos i18n={ ask={ ok="OK", cancel="Annuler", options={ mainTitle="Options Ebola Rebuild", l1="Zones", contSegsMin="Segments min", contSegsMax="Segments max", numSegs="Test pires", wholeProt="Toute la protine", l2="Reconstructions", rebuildNum="Recons./zone", solsPerScore="Solutions/zone", l3="Dclenchement de GAB", scoreFilter="Filtre GAB", passGAB ="Ne pas lancer GAB", l4="Score", allowLoss="Autoriser la perte", lossThresh="Seuil perte", l5="Autres", rebuildLoops ="Transformer la protine en loops", fastMode ="Pas de Fuze (beaucoup plus rapide)", -- BK 11/6/13 fastFuse="Fuze rapide (plus rapide, moins de points)", mutateOnce="Muter au lieu de secouer", -- BK 11/6/13 was mutate once but we do not use mutate always in this version resumeScript="Reprendre avec options du dernier arrt", -- BK 11/6/13 advanced="Plus", GABOptions="GAB" }, gab={ mainTitle="Options GAB", l1="Gnrations", totalLoss="Perte max GAB", maxGen="Max gnrations", l2="Max gnrations sans gain pour :", renew="Lancer bandes non cibl.", maxBadGen="Stopper", l3="Critters", firstGen="Crits 1r gn.", maxLoss="Perte max/crit", giveUp="Seuil abandon", keepConditions="Conserver les conditions", fuzeThresh="Seuil Fuze", l4="Autre", l5="Utiliser Ligand options : 0-jamais, 1-hasard, 2-toujours", useLigand="Utiliser Ligand" }, advanced={ mainTitle="Options avances", l1="Filtres de reconstruction", minRebuild="Filtre infrieur", maxRebuild="Filtre suprieur", l2="Gestion des sous-scores", l3="Scores : 1-all, 2-backbone 3-sidechain, 4-other", stIndex="Type de score", l4="Forcer zone", l5="Format: Dbut1,Fin1-Dbut2,Fin2...", forceZoneStr="Zone force :", zoneWalk ="Parcourir la zone force dans l'ordre", l6="Lancement automatique de GAB", autoGab="Autoriser GAB se lancer automatiquement", gabThresh ="Seuil lancement", l7="Autres", rebuildCI="Clash recons.", preciseBands="Bandes cibles", rebuildBest="Reconstruire les meilleurs segments", longfirst="Commencer par les plus grands, segments", verbose="Afficher plus d'informations" } }, recipe={ sb=">>> Encore %.3f points gagner. Score : %.3f.", gb1="Sauvegarde des bandes impossible. Dsactivation.", gb2="Bandes sauvegardes. Suppression.", tsc=">> Gain : %.3f points. Score : %.3f.", tso1="Solution %i. Score : %.3f.", tso2a="Lancement automatique de GAB.", tso2b="Gain GAB auto : %.3f. Score : %.3f.", tso3="chec de la solution. Poursuite du script.", tso4="Meilleure solution. Score : %.3f.", tso5="chec de la reconstruction, passage la zone suivante.", dlr="* Reconstruction #%i.", dlr2=">>> Microgain sauvegard.", is1="Aucun segment ne correspond aux critres demands.", is2="Reconstruction de toute la molcule.", is3="tat du script restaur.", e1="Zones de %i segments contigus.", e2="Reconstruction des segments %i-%i.", e3="* Score de la zone : %.3f.", e4="* Donnes :", e5="ATTENTION Perte autorise. Score : %.3f. Total : -%.3f.", -- BK 19/3/2013 e6="Gain total Ebola: %.3f. Score : %.3f.", --- ajoute Ebola BK 19/3/13 e7="Segment gel dtect. Passage la zone suivante.", m1="Reprise du script.", m2="Dbut Ebola Rebuild. Mode : %q. Score : %.3f.", m3a="Traitement des paramtres initiaux termin.", m3b="Parcours systmatique de la protine.", fh="Cration de %i cratures alatoires...", critter="%s : %i bandes.", ab="* Impossible de crer de bandes. Arrt de GAB.", sh1="Lancement de %i cratures...", sh2a="Crature %s : %.3f.", sh2b="Critres non respects. Abandon.", bh="Appariement...", g1="Lancement de GAB.", g2="* Gnration : %i. Score : %.3f. Gain : %.3f", g3="Cration d'une gnration entirement alatoire...", g4="* Score final GAB : %.3f. Gain GAB: %.3f.", -- BK 20/3/13 lw1="Rtablissement du meilleur score.", lw2="Rtablissement de la structure secondaire.", lw3="Rtablissement des bandes.", lw4="Sauvegarde de l'tat du script.", de1="Arrt utilisateur.", de2="Erreur inattendue dtecte.", de3="Ligne d'erreur : %i.", de4="Message d'erreur : %s." } } else i18n={ ask={ ok="OK", cancel="Cancel", options={ mainTitle="Ebola Rebuild options", l1="Zones", contSegsMin="Segments min", contSegsMax="Segments max", numSegs="Try worst", wholeProt="Whole protein", l2="Rebuild", rebuildNum="Rebuild/zone", solsPerScore="Solutions/zone", l3="Threshold for GAB", scoreFilter="GAB Filter", passGAB ="Do not launch GAB", l4="Score", allowLoss="Allow loss", lossThresh="loss threshold", l5="Others", rebuildLoops ="Transform protein to loop", fastMode ="Skip Fuse (much faster)", -- BK 11/6/13 fastFuse="Fast Fuse (faster, less points)", mutateOnce="Mutate instead of shake", -- BK 11/6/13 was mutate once but we do not use mutate always in this version resumeScript="Continue with former options", advanced="More", GABOptions="GAB" }, gab={ mainTitle="GAB Options", l1="Generations", totalLoss="GAB max loss", maxGen="Max generations", l2="Max generations without gain for :", renew="Start full random", maxBadGen="Stop", l3="Critters", firstGen="Crits 1r gen.", maxLoss="Loss max/crit", giveUp="Give up threshold", keepConditions="Keep conditions", fuzeThresh="Fuse threshold", l4="Other", l5="Use Ligand options : 0-Never, 1-Random, 2-Allways", useLigand="Use Ligand" }, advanced={ mainTitle="Advanced options", l1="Rebuild filter", minRebuild="Min filter", maxRebuild="Max filter", l2="Subscore management", l3="Scores : 1-all, 2-backbone 3-sidechain, 4-other", stIndex="Score type", l4="Force zone", l5="Format: Start1,End1-Start2,End2...", forceZoneStr="Forced zone :", zoneWalk ="Walk in the forced zone", l6="Launch automatically GAB", autoGab="Allow GAB to be automatically launched", gabThresh ="Launch threshold", l7="Others", rebuildCI="Clash rebuild", preciseBands="Precise bands", rebuildBest="Rebuild best segments", longfirst="Longest rebuild first", verbose="Display more informations" } }, recipe={ sb=">>> Still %.3f points to gain. Score : %.3f.", gb1="Impossible to save bands. Disabling.", gb2="Bands saved. Deleting.", tsc=">> Gain : %.3f points. Score : %.3f.", tso1="Solution %i. Score : %.3f.", tso2a="Launching GAB.", tso2b="Gain GAB auto : %.3f. Score : %.3f.", tso3="Fail of the solution.", tso4="Best solution. Score : %.3f.", tso5="Fail of the rebuild, next zone.", dlr="* Rebuild #%i.", dlr2=">>> Microgain saved.", is1="No segment fit to the requested critter.", is2="Whole protein rebuild.", is3="Script state loaded.", e1=" %i contiguous segments zone.", e2="Rebuild of segments %i-%i.", e3="* Zone score : %.3f.", e4="* Data :", e5="WARNING: Loss allowed. Score : %.3f. Total : -%.3f.", -- BK 19/3/2013 e6="Total Ebola gain: %.3f. Score : %.3f.", --- ajoute Ebola BK 19/3/13 e7="Frozen segment detected. Next zone.", m1="Script recovered.", m2="Start of Ebola Rebuild. Mode : %q. Score : %.3f.", m3a="Initial parameters treatment completed.", m3b="Whole protein walking.", fh="Creating %i random critters...", critter="%s : %i bands.", ab="* Impossible to create bands. GAB stopped.", sh1="Launching %i critters...", sh2a="Critter %s : %.3f.", sh2b="Unrespected critter. Give up.", bh="Breeding...", g1="Launching GAB.", g2="* Generation : %i. Score : %.3f. Gain : %.3f", g3="Create a completely random generation", g4="* GAB final score : %.3f. Total Gain: %.3f.", -- idem BK lw1="Loading Highscore....", lw2="Loading secondary structure...", lw3="Loading bands...", lw4="Saving script state", -- added BK 21/3/13 de1="User stop.", de2="unexpected error detected.", de3="Error line: %i.", de4="Error : %s." } } end return end -- Zones d'action de GAB DoNotUse={} -- zones qui ne doivent pas recevoir de bandes. utiliser des zones du type {segDebut,segFin} AlwaysUse={} -- zones toujours utilises. utiliser des zones du type {segDebut,segFin} UseSegments={} -- utiliser seulement ces segments. sparer les numros des segments par des virgules -- bands by secondary structure use={ Sheet=true, --set false to not band sheets Helix=true, --set false to not band helices Loop=true, --set false to not band loops } checkBoth=false --check both ends to above, if false only one end need to be true -- variables recette segments=structure.GetCount() --print("DEBUG: segments= "..segments) subscores={ --select given score parts for calculating worst/best areas {"clashing", "packing", "hiding", "bonding", "backbone", "sidechain", "disulfides", "density", "ideality", "reference"}, -- 1:All {"clashing", "packing", "backbone", "ideality"}, -- 2:Backbone 07/02/2014 {"hiding", "bonding", "sidechain"}, -- 3:Sidechain {"density", "reference"}, -- 4:Other mode={"All", "Backbone", "Sidechain", "Other"} } uo.subscores=subscores gabSlot=uo.solsPerScore+2 rbSlot=uo.solsPerScore+4 fuseSlot=uo.solsPerScore+5 score={ --global scores best=current.GetEnergyScore(), start=current.GetEnergyScore(), cycle=0, fuse=0, recentbest=0 } flag={ --global flags mutable=false, ligand=false, gab=false, selected=false, mutate=false, points=false, save=false, recentbest=false, bands=false, locked=false } index={ --global tables mutable={}, ligand={}, frozens={}, bands={}, bndCnt=0, --if bands can't be saved, disable them and store their count score={}, subscore={}, scoreTypes={}, bounds={1, segments} } -- core helpers function GenerateSeed()--calculate REALLY good seed from current score --local seed=recipe.GetRandomSeed() --NOT WORKING on windowz!!! seed=os.time() seed=1/seed while seed<10^9 do seed=seed*10 end seed=math.floor(seed) math.randomseed(seed) s1=structure.GetDistance(math.random(segments),math.random(segments)) s2=structure.GetDistance(math.random(segments),math.random(segments)) s3=structure.GetDistance(math.random(segments),math.random(segments)) seed=s1*seed^(1/s2)/s3 while seed<10^9 do seed=seed*10 end seed=math.floor(seed) --~ p("Seed is: "..seed) math.randomseed(seed) end function round(x)--cut all afer 3-rd place return x-x%0.001 end function tlist(t) --table walk & unpack local i, n=0, #t return function () i=i+1 if i<=n then return unpack(t[i]) end end end function tslice(array, len) local tempArray={} for i=1, len do tempArray[i]=array[i] end return tempArray end function randf(n1,n2) -- returns random float between n1,n2 return math.random()*(n2-n1)+n1 --float between end function trand(arr) return arr[math.random(#arr)] end function tobool(val) local res if type(val)=='number' then if val==0 then res=false elseif val==1 then res=true else res=nil end elseif type(val)=='string' then if val=='false' then res=false elseif val=='true' then res=true else res=nil end else res=nil end return res end function SortL(a, b) return a[2]<b[2] end -- sort lower first function SortH(a, b) return a[2]>b[2] end -- sort higher first function SortC(a, b) if #critters==0 then return false else local ac=critters[a] -- added BK 26/3/13 local bc=critters[b]-- added BK 26/3/13 if ac==nil or bc==nil then return false --added BK 27/4/13 against nil bug else return ac.score<bc.score-- changed BK 26/3/13 -- SILL nil BUG here !! end end end -- sort critters BUG nil BK 26/3/13 function puzzleprop() -- simplified version to identify filtered puzzles-- new BK 8/5/2013 local descrTxt=puzzle.GetDescription() local puzzletitle=puzzle.GetName() if #descrTxt>0 and (descrTxt:find("filter") or descrTxt:find("filters")) then PROBABLEFILTER=true end return end puzzleprop() -- new BK 8/5/2013 -- game helpers segCnt=structure.GetCount() function p(printAlways, fmt, ...) --Lua = thebest, thebest, thebest if not uo.verbose and not printAlways then return end -- more or less details if #arg==0 then print(fmt or '') elseif arg==nil then return--print(fmt or '')-- added BK 23/3/13 -- supressed empty lines 11/6/2013 elseif fmt==nil then return--print('')-- added BK 23/3/13 -- supressed empty lines 11/6/2013 else print(string.format(fmt, unpack(arg))) end end function Score()--return score, exploration too return uo.energy and current.GetEnergyScore() or current.GetScore() end function CI(c) if c>uo.maxCI then c=uo.maxCI end behavior.SetClashImportance(c) end --START Archive in Notes, -- New 8/11/2014 function SelectNote(recipename) store={} store.label=recipename or "" -- edit here the recipe name store.note_number=structure.GetCount() for seg=structure.GetCount(),1,-1 do if structure.GetNote(seg)~="" then break end store.note_number=seg end print(string.format("Recording results in Note for segment %i",store.note_number)) store.starting_score=current.GetScore() --structure.SetNote(store.note_number,string.format("(%s) %.3f + FSP",user.GetPlayerName(),store.starting_score)) end SelectNote(recipename) function WhriteNote(loop_nb) -- all inits are in SelectNote function local loop_count= loop_nb or 1 structure.SetNote(store.note_number,string.format("(%s) %.3f + %s(%i) %.3f",user.GetPlayerName(),store.starting_score,store.label,loop_count,current.GetScore())) end --END Archive in Notes --START quick save algorithm function QuickShake(val) --[[------------------------------------------------------------------------------------------------ -- Algorithm for faster shake REFERENCES 1. N/A Copyright (C) 2014 Seagat2011 <http://fold.it/port/user/1992490> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. $Id$ ------------------------------------------------------------------------------------------------]]-- --[[ v1 - Inception 1.2 - Loops until nogain ]]-- local val= val or 1 local idx = 1 local idx2 = structure.GetCount () local hash = {} local cs = current.GetScore () --print ( 'Quick Shake Algorithm v1.2 SG2011 - Current Score: '..cs ) local function New ( obj ) return obj -- pass-new-obj-by-value end local _gses = New ( current.GetSegmentEnergySubscore ) local function SmartShake ( iters ) local gain = true while (gain) do gain = false for i=idx,idx2 do local ci = _gses ( i,'clashing' ) if ci < _gses ( i,'hiding' ) and ci < _gses ( i,'packing' ) and ci < _gses ( i,'ideality' ) and ci < _gses ( i,'sidechain') and ci < _gses ( i,'bonding' ) and ci < _gses ( i,'other' ) and ci < _gses ( i,'reference') then selection.Select ( i ) end -- test ci -- end -- loop -- if selection.GetCount () then local css = current.GetScore () structure.ShakeSidechainsSelected ( iters ) selection.DeselectAll () if current.GetScore () > css then gain = true end -- test -- end -- test -- end -- loopf -- end structure.SmartShake = SmartShake structure.SmartShake ( val ) --print ( 'Done.' ) end --END quick save algorithm function Wiggle(how, iterW, fminppi) -- recursive wiggle how=how or "wa" iterW=iterW or 2 --nb d'iterations wiggle au debut fminppi=fminppi or 1 -- factor minppi+/-nb de recursive wiggle local cminppi=.005 --constant minppi local ws=0 if flag.selected then ws=ws+1 end if uo.mutateAlways or flag.mutate then ws=ws+10 end function wShake() if ws==0 then structure.ShakeSidechainsAll(1) elseif ws==1 then QuickShake(1) elseif ws==10 then structure.MutateSidechainsAll(1) elseif ws==11 then structure.MutateSidechainsSelected(1) end end function wWiggle() if PROBABLEFILTER then behavior.SetSlowFiltersDisabled(true) end-- new BK 8/5/2013, always disable filter here local b, s= true, true if how=='wb' then s=false end if ws==1 then structure.WiggleSelected(iterW, b, s) else structure.WiggleAll(iterW, b, s) end if PROBABLEFILTER then behavior.SetSlowFiltersDisabled(OriginalFilterSetting) end -- new BK 8/5/2013, always back to user settings end if how=='s' then wShake() else local sp=Score() wWiggle() if (Score()-sp)>(cminppi*(1+fminppi)) then -- minppi de plus en plus severe Wiggle(how, iterW+1, fminppi+1) -- compense par cycles de plus en plus nombreux end end how="wa"--reinitialiser les valeurs globales 09/02/2014 iterW=2 -- fminppi=1 -- end function FuzeEnd() CI(1) Wiggle("s") -- quickshake Wiggle("wa",30,.005) -- 09/02/2014 recentbest.Restore() srb() end function Fuze1(ci1,ci2) save.Quickload(fuseSlot) recentbest.Save() CI(ci1) Wiggle("s") CI(ci2) Wiggle("wa",2,0.5) FuzeEnd() end function Fuze2(ci1,ci2) save.Quickload(fuseSlot) recentbest.Save() CI(ci1) Wiggle("wa",1,0.5) CI(1) Wiggle("wa",6,0.5) recentbest.Restore() CI(ci2) Wiggle("wa",1,0.5) CI(1) Wiggle("wa",10,.01) --09/02/2014 recentbest.Restore() FuzeEnd() end function Fuze() --~ p("*** GAB Fuzing...") score.fuse=Score() --~ selection.SelectAll() save.Quicksave(fuseSlot) if uo.fastFuse then Fuze2(0.25,.55) else Fuze1(0.3,0.6) Fuze1(0.02,1) Fuze2(0.25,.55) Fuze2(0.7,0.5) Fuze2(0.5,0.7) end end function srb() local s=Score() if s<=score.fuse then save.Quickload(fuseSlot) else score.fuse=s save.Quicksave(fuseSlot) if flag.gab then SaveBest() else TestScore(true) --sauver dans 100 end end end function SaveBest() local s=Score() local g=s-bestScore if g>0 then if g>0.01 then if s<=score.best then p(true, i18n.recipe.sb, score.best-s, s) else TestScore(true) end--sauver dans 100 end bestScore=s save.Quicksave(gabSlot) end end function SaveRB() local rb=recentbest.GetScore() if rb>bestScore then save.Quicksave(rbSlot) recentbest.Restore() ManageBands() SaveBest() save.Quickload(rbSlot) recentbest.Save() end end function Qstab() --adapted from tvdl BK 02/02/2014 --selection.SelectAll()--new -- Do not accept qstab losses recentbest.Save()--new if uo.mutateOnce then CI(uo.mutateOnceCI) structure.MutateSidechainsSelected(1) else CI(0.02) Wiggle("s") --structure.ShakeSidechainsSelected(1)--new end if not uo.fastQstab then CI(0.25) Wiggle("wa",1,0.5) CI(1) Wiggle("s") end CI(1) Wiggle("wa",30,.005) recentbest.Restore() --new end function IsFrozen(seg) a, b=freeze.IsFrozen(seg) return a or b end function SetToLoop() save.SaveSecondaryStructure() selection.SelectAll() structure.SetSecondaryStructureSelected("l") selection.DeselectAll() end function DetectLigand() local lastSeg1=structure.GetCount() local lastSeg2=lastSeg1 while structure.GetSecondaryStructure(lastSeg1)=="M" do flag.ligand=true lastSeg1=lastSeg1-1 end if lastSeg1+1==lastSeg2 then index.ligand={lastSeg2} else index.ligand={lastSeg1, lastSeg2} end end function puzzleproblems() local descrTxt=puzzle.GetDescription() --p(descrTxt) local puzzletitle=puzzle.GetName() --p(puzzletitle) if #puzzletitle>0 and puzzletitle:find("713") then PROBLEMATIC=true end end function DetectLock() puzzleproblems() if not PROBLEMATIC then local start, stop=unpack(index.bounds) while structure.IsLocked(start) do start=start+1 flag.locked=true end while structure.IsLocked(stop) do stop=stop-1 flag.locked=true end index.bounds={start, stop} else flag.locked=true EmergencyAsk() end end function EmergencyAsk() local ask=dialog.CreateDialog("Ebola emergency options") repeat ask.l100=dialog.AddLabel("Unable to deal with this strange puzzle") ask.l101=dialog.AddLabel("You should cancel Ebola") ask.l1=dialog.AddLabel("Forcer zone (format: Dbut1,Fin1)") ask.forceZoneStr=dialog.AddTextbox("Zone force :",uo.forceZoneStr) ask.OK = dialog.AddButton("OK",1) ask.Cancel = dialog.AddButton("Cancel",0) askresult=dialog.Show(ask) if askresult > 0 then if ask.forceZoneStr.value~='' then for a,b in ask.forceZoneStr.value:gmatch('(%d+),(%d+)') do table.insert(uo.forceZone,{a,b}) end else uo.forceZone={} end SetAndFlag(ask, 'forceZoneStr') end until askresult<2 return askresult > 0 end function DetectMutables() local muts={} for i=1,segments do if structure.IsMutable(i) then flag.mutable=true table.insert(muts, i) end end index.mutable={muts[1], muts[#muts]} end function DetectFrozens() for i=1, segments do if IsFrozen(i) then table.insert(index.frozens, i) end end end function GetSegFromDist(seg, dist) local hasPassed, len, targetSeg=false, 0, 0 for i=1, segments do hasPassed, len=pcall(structure.GetDistance,i,seg) if not hasPassed then return false else if len==dist then return i end end end end function GetBands() if band.GetCount()==0 then return end local isOK=true for i=1, band.GetCount() do rope=band.AddToBandEndpoint(1,i) len1=band.GetLength(i) len2=band.GetLength(rope) band.Delete(rope) bandEnd1=GetSegFromDist(1, len2) if not bandEnd1 then isOK=false break end bandEnd2=GetSegFromDist(bandEnd1, len1) if not bandEnd2 then isOK=false break end table.insert(index.bands,{bandEnd1, bandEnd2}) end if not isOK then p(true, i18n.recipe.gb1) index.bands={} index.bndCnt=band.GetCount() band.DisableAll() else p(true, i18n.recipe.gb2) band.DeleteAll() end end function RestoreBands() if #index.bands==0 then return end for end1, end2 in tlist(index.bands) do band.AddBetweenSegments(end1, end2) end end function RestoreFrozens() if #index.frozens==0 then return end for i=1, #index.frozens do selection.Select(index.frozens[i]) end freeze.FreezeSelected(true, true) selection.DeselectAll() end function SelectSphere(start, stop, size) size=size or 12 for j=start, stop do for i=1, segments do if structure.GetDistance(j, i)<size then selection.Select(i) end end end end function SetCleanType(val) if tonumber(val)~=nil then return tonumber(val) elseif tobool(val)~=nil then return tobool(val) else return val end end function ConcatArray(array, depth) local s='' local depth=depth or 1 local sep={' ',',','|'} for key, val in pairs(array) do if type(val)=='table' then s=s..key..sep[depth+1]..ConcatArray(val, depth+1)..sep[depth] else s=s..key..':'..tostring(val)..sep[depth] end end return s:sub(1,#s-1) end function RebuildArray(str, depth) local arr={} local depth=depth or 1 local sep={' ',',','|','%^'} local subpat='' for i=1, depth do subpat=subpat..sep[i] end pattern="([^"..subpat.."]+)" for entity in string.gmatch(str, pattern) do if entity:find(sep[depth+1]) then key=string.match(entity,"([^"..sep[depth+1].."]+)") local len=#key key=SetCleanType(key) arr[key]=RebuildArray(entity:sub(len+2,#entity), depth+1) else key, val=string.match(entity,"([%w]+):([^"..subpat.."]+)") if not key then key=string.match(entity,"([%w]+):") val='' end arr[SetCleanType(key)]=SetCleanType(val) end end return arr end -- fin helpers -- dbut Ebola function SubScore(seg, scoreType) scoreType=scoreType or "density" if scoreType=='all' then return current.GetSegmentEnergyScore(seg) else return current.GetSegmentEnergySubscore(seg,scoreType) end end function GenerateScoreTable() index.score={} -- redondant ? BK ecrase ce qu'il y avait avant index.subscore={} -- redondant ? BK ecrase ce qu'il y avait avant local slot=1 local limit=0 if uo.solsPerScore%2==1 then limit=(uo.solsPerScore-1)/2 else limit=uo.solsPerScore/2-1 end for i=1, uo.solsPerScore-limit do slot=slot+1 table.insert(index.score,{slot, -math.huge}) end for i=uo.solsPerScore-limit+2, uo.solsPerScore+1 do slot=slot+1 table.insert(index.subscore,{slot, -math.huge}) end for i=2, fuseSlot do save.Quicksave(i) end end function ReplaceLowest(arr, val) if #arr==0 then return end local flag=false if val>arr[#arr][2] then save.Quicksave(arr[#arr][1]) arr[#arr][2]=val table.sort(arr, SortH) flag=true end return arr, flag end function ScoreArea(seg, scoreType) scoreType=scoreType or "density" local tempScore=0 for i=seg, seg+uo.segs-1 do tempScore=tempScore+SubScore(i, scoreType) end return tempScore end function StoreScore(seg) local yetFlag=false -- don't keep same value twice index.score, yetFlag=ReplaceLowest(index.score, Score()) if not yetFlag and #index.subscore>0 then local mode = uo.stIndex~=4 and "clashing" or "density" index.subscore, yetFlag=ReplaceLowest( index.subscore, ScoreArea(seg, mode) ) end end function TestScore(saveFlag) local s=Score() if s>score.best then p(true, i18n.recipe.tsc, s-score.best, s) score.best=s WhriteNote() -- New 8/11/2014 if saveFlag then save.Quicksave(100) end end end function FilterSegments(start, stop) local isEmpty=true local tempArray={} for seg=start, stop-uo.segs do local segscore=0 local data='' for j, mode in ipairs(index.scoreTypes) do local subscore=ScoreArea(seg, mode) if subscore~=0 then local areaIsGood=false if uo.rebuildBest then areaIsGood=(subscore/uo.segs)>uo.maxVal else areaIsGood=(subscore/uo.segs)<=uo.maxVal end if areaIsGood then segscore=segscore+subscore data=data..'* '..mode..':'..subscore..'\n' end end end if segscore~=0 then table.insert(tempArray,{seg, segscore, data}) isEmpty=false end end local func=uo.rebuildBest and SortH or SortL table.sort(tempArray,func) if #tempArray<uo.numSegs then uo.maxVal=uo.rebuildBest and uo.maxVal-5 or uo.maxVal+5 tempArray=FilterSegments(start, stop) elseif #tempArray>uo.numSegs then tempArray=tslice(tempArray, uo.numSegs) end return isEmpty and false or tempArray end function LaunchGab(seg) if uo.preciseBands then AlwaysUse={} table.insert(AlwaysUse, {seg, seg+uo.segs-1}) end if flag.ligand then if uo.useLigand==0 then segCnt=lastSeg1 -- was lastSeg but gave a nil bug line 1066-- BK 25/3/13 elseif uo.useLigand==2 then table.insert(AlwaysUse, index.ligand) end end GAB() end function TestSolutions(seg) for i=2, uo.solsPerScore+1 do save.Quickload(i) if Score()~=score.cycle then p(true, i18n.recipe.tso1, i-1, Score()) SelectSphere(seg,seg+uo.segs-1) flag.selected=true Wiggle('s') flag.selected=false-- 02/02/2014 --structure.WiggleAll(25) -- BK 01/02/2014 nc Wiggle("wa",30,.005) -- 09/02/2014 all flag.selected=true-- 02/02/2014 local s=Score() Fuze()-- selected TO DO: tester si pas mieux sur toute la prot flag.selected=false if uo.autoGab and Score()-s>uo.gabThresh then p(true, i18n.recipe.tso2a) s=Score() LaunchGab(seg) p(true, i18n.recipe.tso2b, Score()-s, s) end save.Quicksave(i) TestScore(true) -- sauve en 100 si meilleur else p(true, i18n.recipe.tso3) end end save.Quickload(2) recentbest.Save() for i=2, uo.solsPerScore+1 do save.Quickload(i) end if flag.recentbest then save.Quickload(rbSlot) flag.recentbest=false end recentbest.Restore() local s=Score() p(true, i18n.recipe.tso4, s) if s>(score.best-uo.scoreFilter) and not uo.passGAB then LaunchGab(seg) else p(true, i18n.recipe.tso5) end end function DoLocalRebuild(seg) for j=1, uo.rebuildNum do p(false, i18n.recipe.dlr1, j) save.Quickload(100) selection.DeselectAll() selection.SelectRange(seg,seg+uo.segs-1) CI(uo.rebuildCI) structure.RebuildSelected(1) CI(1) SelectSphere(seg,seg+uo.segs-1) if uo.mutateOnce then flag.mutate=true end flag.selected=true Wiggle('s') local sss=Score() -- new BK 02/02/2014 negative score bug save.Quicksave(90) -- new BK 02/02/2014 negative score bug flag.mutate=false if not uo.fastMode then local s=Score() if (score.best-s)<uo.minRebuild or s>score.best then Wiggle("wa",30,.005) --09/02/2014 if uo.mutateOnce then flag.mutate=true Wiggle('s') Wiggle("wa",20,.1) --09/02/2014 flag.mutate=false end flag.selected=false recentbest.Restore() -- added 02/02/2014 to fix negative score bug s=Score() if s<sss then save.Quickload(90) end -- new BK 02/02/2014 negative score bug s=Score() sss=Score()-- new BK 02/02/2014 negative score bug (reinitialisation) save.Quicksave(90)-- new BK 02/02/2014 negative score bug if math.abs(s-score.best)<uo.maxRebuild then --si a bouge dans un sens ou l'autre ? --not an interesting solution, but a cent is a cent if s>score.best and s>score.recentbest then flag.recentbest=true save.Quicksave(rbSlot) p(false, i18n.recipe.dlr2) score.recentbest=s end if s<sss then save.Quickload(90) end -- new BK 02/02/2014 negative score bug else StoreScore(seg) TestScore(false)-- updates score.best , MAIS PAS slot100 ??? si rien n'a bouge end --else -- si solution pas dans les limites --StoreScore(seg)-- BK 02/02/2014, on remplace quand meme une des 3 mauvaises solutions si possible --TestScore(false) -- updates score.best , MAIS PAS slot100-- BK 02/02/2014 end else TestScore(true)-- updates score.best ET slot100 iff improvement --TestScore(false) -- updates score.best , MAIS PAS slot100-- BK 30/03/2014 end end -- Notons qu'a ce stade, on ne sauve rien dans 100, sauf si "rapide" TO DO: il y a un bug negatif en rapide !!! end function InitScript() local start=1 local stop=segments local array={} if flag.mutable then start, stop=unpack(index.mutable) elseif flag.ligand then stop=index.ligand[1] elseif flag.locked then start, stop=unpack(index.bounds) end local rebuildMode=0 -- normal mode if #uo.forceZone>0 then rebuildMode=1 elseif uo.wholeProt then rebuildMode=2 elseif uo.resumeScript then rebuildMode=3 end if rebuildMode==0 or rebuildMode==1 then if rebuildMode==0 then array=FilterSegments(start, stop, true) elseif rebuildMode==1 then for zs, ze in tlist(uo.forceZone) do --zone start, zone end if ze-zs+2-uo.segs>0 then for seg=zs, ze-uo.segs+1 do local subscore=0 for j, mode in ipairs(index.scoreTypes) do subscore=subscore+ScoreArea(seg, mode) end table.insert(array, {seg, subscore, ''}) end end end if not uo.zoneWalk then local func=uo.rebuildBest and SortH or SortL table.sort(array,func) end end if not array or #array<1 then p(true, i18n.recipe.is1) return false end stop=#array elseif rebuildMode==2 then stop=stop-uo.segs+1 for seg=start, stop do table.insert(array, {seg, ScoreArea(seg)}) end p(true, i18n.recipe.is2) elseif rebuildMode==3 then array=uo.curArray start=uo.curSeg if #array~=0 then stop=#array elseif #uo.forceZone~=0 then stop=stop-uo.segs+1 end uo.resumeScript=false p(true, i18n.recipe.is3) end return start, stop, array end function Ebola() p(true, '\n######################') p(true, i18n.recipe.e1, uo.segs) local startSeg, endSeg, lowSeg, areaScore, data startSeg, endSeg, uo.curArray=InitScript() if #uo.curArray<1 then return end flag.points=true for i=startSeg, endSeg do uo.curSeg=i if not uo.wholeProt then lowSeg, areaScore, data=unpack(uo.curArray[i]) else lowSeg=i end local hasLock=false for j=lowSeg, lowSeg+uo.segs-1 do if IsFrozen(j) or structure.IsLocked(j) then hasLock=true end end p(true, '--------') p(true, i18n.recipe.e2, lowSeg, lowSeg+uo.segs-1) if not uo.wholeProt then score.cycle=Score() p(false, i18n.recipe.e3, areaScore) if #data>0 then p(false, i18n.recipe.e4) p(false, data) end p(false, '---') end if not hasLock then GenerateScoreTable() DoLocalRebuild(lowSeg) selection.DeselectAll() if not uo.fastMode then TestSolutions(lowSeg) end TestScore(true) -- Sauver dans 100 ssi meilleur local s=Score() if uo.allowLoss and score.best-s<uo.lossThresh then save.Quicksave(100) -- seul cas ou l'on sauve une perte dans 100 (sans changer score.best) p(true, i18n.recipe.e5, s, score.best-s) else save.Quickload(100) -- reprendre le dernier meilleur recentbest.Restore() -- added 30/03/2014 to fix negative score bug TestScore(true) -- Sauver dans 100 ssi meilleur, added 30/03/2014 to fix negative score bug p(true, i18n.recipe.e6, Score()-score.start, Score()) -- 30/03/2014 to fix negative score bug end else p(true, i18n.recipe.e7) end end end function main() setlanguage()-- New BK 10/4/13 multilingual(uo.lang)-- New BK 10/4/13 CI(1) save.SaveSecondaryStructure() recentbest.Save() -- New BK 24/6/2013 index.scoreTypes=subscores[uo.stIndex] uo.scoringMode=subscores.mode[uo.stIndex] GenerateSeed() DetectLock() DetectFrozens() DetectMutables() DetectLigand() GetBands() local saveTxt=structure.GetNote(1) if #saveTxt>0 and saveTxt:find(uo.recipeName) then flag.save=true structure.SetNote(1,'') end if not AskOptions() then return end if uo.resumeScript then uo=RebuildArray(saveTxt) uo.resumeScript=true p(true, i18n.recipe.m1) end if uo.rebuildLoops then SetToLoop() end save.Quicksave(100) repeat repeat flag.points=false p(true, i18n.recipe.m2, uo.scoringMode, score.best) if not uo.resumeScript then loopStart=uo.contSegsMin else loopStart=uo.segs end for i=loopStart, uo.contSegsMax do uo.segs=i if uo.longfirst then uo.segs=uo.contSegsMax-i+loopStart end Ebola() end until flag.points==false if not uo.wholeProt then p(true, i18n.recipe.m3a) p(true, i18n.recipe.m3b) uo.wholeProt=true flag.points=true end until flag.points==false LastWish() end -- fin Ebola -- debut GAB function ManageBands() --if bands can't be saved, prevent gab from deleting them if index.bndCnt==0 then band.DeleteAll() else local bands=band.GetCount() if bands>index.bndCnt then for i=bands, index.bndCnt+1, -1 do band.Delete(i) end end end band.DisableAll() end function ShuffleHerd() if uo.herd.shuffle then for i=1,#critters do local r=math.random(#critters) if r~=i then critters[i],critters[r]=critters[r],critters[i] end end end end function FillHerd() --fill up herd local n=#critters if n>0 then --fill up n=uo.herd.newRandom else --fresh herd if uo.herd.maxGen~=1 and uo.herd.firstGen<uo.herd.keepBest then n=uo.herd.breedBest + uo.herd.keepBest + uo.herd.breedBastards else n=uo.herd.firstGen end end p(false, i18n.recipe.fs) for i=1,n do AddCritter() end end function AddCritter() --create new random critter local c={} critterID=critterID+1 c.no=critterID c.name=c.no..'-rnd' c.bands={} local r=math.random(uo.critter.minBands, uo.critter.maxBands) for i=1,r do table.insert(c.bands,AddBand()) end table.insert(critters, c) p(false, i18n.recipe.critter, c.name, #c.bands) end function AddBand() --create one random band local cnt=0 local b={} while true do --try till die cnt=cnt+1 local s1=math.random(segCnt) if uo.onlyMutable or #UseSegments>0 then s1=trand(UseSegments) end local s2=math.random(segCnt) if s1>s2 then s1,s2=s2,s1 end --swap local bands=uo.bands if CanBeUsed(s1,s2) then local str=randf(bands.minStr,bands.maxStr) local len=0 while true do --randomize correct distance len=randf(-bands.maxDn,bands.maxUp) if len<-bands.minChng or len>bands.minChng then break end end b={s1,s2,str,len} break end if cnt>100 then p(true, i18n.recipe.ab) BreakScript() --there is no such function, so it crashes script end end return b end function CanBeUsed(sg1,sg2) --checking end of bands function ssCheck(ss) local good=false if use.Sheet and ss=="E" then good=true end if use.Helix and ss=="H" then good=true end if use.Loop and ss=="L" then good=true end if uo.useLigand~=0 and ss=="M" then good=true end return good end function AreGood(s1,s2) --check that s1 and s2 can be used local ok=true if s2-s1<uo.bands.minSkip then ok=false end if ok and structure.GetDistance(s1,s2)<uo.bands.minDist then ok=false end return ok end local ok=AreGood(sg1,sg2) if ok and #DoNotUse>0 then --none of 2 can be in that area for start, stop in tlist(DoNotUse) do for x=start, stop do if x==sg1 or x==sg2 then ok=false break end end if not ok then break end end end if not ok then return false --if false can`t be used else ok=false if #UseSegments>0 then --at least one have to be there for i=1, #UseSegments do local r=UseSegments[i] if r==sg1 or r==sg2 then ok=true break end end else ok=true end end if ok then --check structure ok=false local ss1=structure.GetSecondaryStructure(sg1) local ss2=structure.GetSecondaryStructure(sg2) if checkBoth then if ssCheck(ss1) and ssCheck(ss2) then ok=true end else if ssCheck(ss1) or ssCheck(ss2) then ok=true end end end return ok end function ScoreHerd() --score all critters from herd save.Quickload(gabSlot) p(false, i18n.recipe.sh1, #critters) save.Quicksave(gabSlot+1) local herdScore=Score() for i, crt in ipairs(critters) do ManageBands() local s=Score() --start score for seg1, seg2, str, len in tlist(crt.bands) do local a1=5 local a2=5 if seg1==segments then a1=6 end if seg2==segments then a2=6 end local ss1=structure.GetSecondaryStructure(seg1) local ss2=structure.GetSecondaryStructure(seg2) if ss1=='M' then a1=math.random(structure.GetAtomCount(seg1)) elseif ss2=='M' then a2=math.random(structure.GetAtomCount(seg2)) else if structure.GetAminoAcid(seg1)=='g' then a1=0 end if structure.GetAminoAcid(seg2)=='g' then a2=0 end end local bc=band.AddBetweenSegments(seg1,seg2,a1,a2) band.SetStrength(bc,str) local goalLen=structure.GetDistance(seg1,seg2)+len if goalLen<uo.bands.minLen then goalLen=uo.bands.minLen end band.SetGoalLength(bc,goalLen) end local conditions=current.AreConditionsMet() selection.SelectAll() CI(uo.pullCI) recentbest.Save() Wiggle('wb',2,0.5) ManageBands() SaveRB() CI(1) local test=true if uo.critter.keepConditions then if conditions then test=current.AreConditionsMet() end end local delta=s-Score() test=uo.critter.giveUp>delta and test if test then if math.abs(delta) > uo.qstabThresh then Qstab() else Wiggle("wa",30,.005) --09/02/2014 end SaveRB() if (bestScore-Score())<uo.fuzeThresh then Fuze() end end local s2=Score() p(false, i18n.recipe.sh2a, crt.name, s2-s) if not test then p(false, i18n.recipe.sh2b) end if uo.critter.maxLoss>0 then if s2>herdScore-uo.critter.maxLoss then if s2<bestScore-uo.critter.totalLoss then save.Quickload(gabSlot) else save.Quicksave(gabSlot+1) herdScore=s2 end else save.Quickload(gabSlot+1) end else save.Quickload(gabSlot) end end save.Quickload(gabSlot) end function BreedCritters(mom,dad,t) --breed 2 critters. bands are taken randomly local kid={} critterID=critterID+1 kid.no=critterID kid.name=kid.no.."-"..t..mom.no..'/'..dad.no kid.bands={} local mb=#mom.bands local db=#dad.bands if mb>db then mb,db=db,mb end --kid have bands count between mom and dad bands local bn=math.random(mb,db) for i=1,bn,2 do table.insert(kid.bands, trand(mom.bands)) table.insert(kid.bands, trand(dad.bands)) end p(false, i18n.recipe.critter, kid.name, #kid.bands) return kid end function KeepGood() --copy best scoring critters form last gen if score above local newHerd={} for i=1,uo.herd.keepBest do if critters[i].score==nil then critters[i].score=0 end -- bug nil BK 27/4/2013 if critters[i].score>uo.critter.keepScore and (math.abs(critters[i].score)>0.1 or critters[i].score>0) then table.insert(newHerd, critters[i]) end end return newHerd end function BreedHerd() p(false, i18n.recipe.bh) table.sort(critters, SortC) newHerd=KeepGood() for i=1, uo.herd.breedBest do local mom=critters[i] if mom.score>uo.critter.breedScore or i<2 then --breed only good ones, 1st is always bred anyway for j=i+1, uo.herd.breedBest do local dad=critters[j] table.insert(newHerd, BreedCritters(mom,dad,"kid-")) table.insert(newHerd, BreedCritters(dad,mom,"kid-")) end end end for i=1, uo.herd.breedBastards do --they will always appear ;] local mom=critters[i] local j=math.random(uo.herd.breedBastards+1,#critters) local dad=critters[j] table.insert(newHerd, BreedCritters(mom,dad,"bas-")) table.insert(newHerd, BreedCritters(dad,mom,"bas-")) end critters=newHerd FillHerd() end function GAB() flag.gab=true if uo.onlyMutable then for i=1,segCnt do if structure.IsMutable(i) then table.insert(UseSegments, i) end end end if #AlwaysUse>0 then for ss, se in tlist(AlwaysUse) do --~ if ss>se then ss,se=se,ss end --automated, no check needed if se==nil then table.insert(UseSegments, ss) else for j=ss,se do table.insert(UseSegments, j) end end end AlwaysUse={} --added to list, no need to check later end bestScore=Score() critterID=0 gen=0 ss=Score() save.Quicksave(gabSlot) recentbest.Save() p(true, i18n.recipe.g1) critters={} FillHerd() badGen=0 while true do --this is (almost) endless script ;] genScore=Score() gen=gen+1 ShuffleHerd() -- changed BK 18/3/2013 -- if was redondant: if uo.herd.shuffle then ShuffleHerd() end ScoreHerd() save.Quickload(gabSlot) if gen==uo.herd.maxGen then break end --end of script local genScore2=Score() if genScore>=genScore2 then badGen=badGen+1 if badGen==uo.herd.maxBadGen then break end else badGen=0 end p(true, i18n.recipe.g2, gen, genScore2, genScore2-genScore) if badGen>=uo.herd.renew then p(false, i18n.recipe.g3) critters={} FillHerd() badGen=0 else BreedHerd() end end p(true, i18n.recipe.g4, Score(), Score()-ss) flag.gab=false end -- fin GAB -- dialogues, debug, lancement function MakeFancyHeader(s) return '----- '..s..' '..string.rep('-', 54-#s-7) end function SetAndFlag(dial, var, sub) -- fonction de sauvegarde local val=dial[var].value if not sub then uo[var]=val else uo[sub][var]=val end end function AskOptions() local ask=dialog.CreateDialog(i18n.ask.options.mainTitle) repeat ask.l1=dialog.AddLabel(MakeFancyHeader(i18n.ask.options.l1)) ask.contSegsMin=dialog.AddSlider(i18n.ask.options.contSegsMin, uo.contSegsMin, 1, 20, 0) ask.contSegsMax=dialog.AddSlider(i18n.ask.options.contSegsMax, uo.contSegsMax, 1, 20, 0) ask.numSegs=dialog.AddSlider(i18n.ask.options.numSegs,uo.numSegs, 1, 50, 0) ask.wholeProt=dialog.AddCheckbox(i18n.ask.options.wholeProt, uo.wholeProt) ask.l2=dialog.AddLabel(MakeFancyHeader(i18n.ask.options.l2)) ask.rebuildNum=dialog.AddSlider(i18n.ask.options.rebuildNum, uo.rebuildNum, 1, 200, 0) ask.solsPerScore=dialog.AddSlider(i18n.ask.options.solsPerScore, uo.solsPerScore, 1, 20, 0) ask.l3=dialog.AddLabel(MakeFancyHeader(i18n.ask.options.l3)) ask.scoreFilter=dialog.AddSlider(i18n.ask.options.scoreFilter, uo.scoreFilter, 0, 50, 0) ask.passGAB = dialog.AddCheckbox(i18n.ask.options.passGAB, uo.passGAB) ask.l4=dialog.AddLabel(MakeFancyHeader(i18n.ask.options.l4)) ask.allowLoss=dialog.AddCheckbox(i18n.ask.options.allowLoss, uo.allowLoss) ask.lossThresh=dialog.AddSlider(i18n.ask.options.lossThresh, uo.lossThresh, 1, 200, 0) ask.l5=dialog.AddLabel(MakeFancyHeader(i18n.ask.options.l5)) ask.rebuildLoops = dialog.AddCheckbox(i18n.ask.options.rebuildLoops, uo.rebuildLoops) ask.fastMode = dialog.AddCheckbox(i18n.ask.options.fastMode, uo.fastMode) ask.fastFuse=dialog.AddCheckbox(i18n.ask.options.fastFuse, uo.fastFuse) if flag.mutable then ask.mutateOnce=dialog.AddCheckbox(i18n.ask.options.mutateOnce,uo.mutateOnce) end if flag.save then ask.resumeScript=dialog.AddCheckbox(i18n.ask.options.resumeScript,uo.resumeScript) end ask.ok = dialog.AddButton(i18n.ask.ok, 1) ask.cancel = dialog.AddButton(i18n.ask.cancel, 0) ask.advanced=dialog.AddButton(i18n.ask.options.advanced, 2) ask.GABOptions=dialog.AddButton(i18n.ask.options.GABOptions, 3) askresult=dialog.Show(ask) if askresult > 0 then SetAndFlag(ask, 'contSegsMin') SetAndFlag(ask, 'contSegsMax') SetAndFlag(ask, 'numSegs') SetAndFlag(ask, 'wholeProt') SetAndFlag(ask, 'rebuildNum') SetAndFlag(ask, 'solsPerScore') SetAndFlag(ask, 'scoreFilter') SetAndFlag(ask, 'passGAB') SetAndFlag(ask, 'allowLoss') SetAndFlag(ask, 'lossThresh') SetAndFlag(ask, 'rebuildLoops') SetAndFlag(ask, 'fastMode') SetAndFlag(ask, 'fastFuse') if flag.mutable then SetAndFlag(ask, 'mutateOnce') end if flag.save then SetAndFlag(ask, 'resumeScript') end if askresult==2 then AskAdvanced() elseif askresult==3 then AskGABOptions() end end until askresult<2 return askresult > 0 end function AskGABOptions() local ask=dialog.CreateDialog(i18n.ask.gab.mainTitle) ask.l1=dialog.AddLabel(MakeFancyHeader(i18n.ask.gab.l1)) ask.totalLoss=dialog.AddSlider(i18n.ask.gab.totalLoss,uo.critter.totalLoss,0,100,0) ask.maxGen=dialog.AddSlider(i18n.ask.gab.maxGen,uo.herd.maxGen,1,50,0) ask.l2=dialog.AddLabel(i18n.ask.gab.l2) ask.renew=dialog.AddSlider(i18n.ask.gab.renew,uo.herd.renew,1,50,0) ask.maxBadGen=dialog.AddSlider(i18n.ask.gab.maxBadGen,uo.herd.maxBadGen,1,50,0) ask.l3=dialog.AddLabel(MakeFancyHeader(i18n.ask.gab.l3)) ask.firstGen=dialog.AddSlider(i18n.ask.gab.firstGen,uo.herd.firstGen,1,50,0) ask.maxLoss=dialog.AddSlider(i18n.ask.gab.maxLoss,uo.critter.maxLoss,0,100,0) ask.giveUp=dialog.AddSlider(i18n.ask.gab.giveUp,uo.critter.giveUp,0,500,0) ask.keepConditions=dialog.AddCheckbox(i18n.ask.gab.keepConditions,uo.critter.keepConditions) ask.fuzeThresh=dialog.AddSlider(i18n.ask.gab.fuzeThresh,uo.fuzeThresh,-.001,50,0) if flag.ligand then ask.l4=dialog.AddLabel(MakeFancyHeader(i18n.ask.gab.l4)) ask.l5=dialog.AddLabel(i18n.ask.gab.l5) ask.useLigand=dialog.AddSlider(i18n.ask.gab.useLigand,uo.useLigand,0,2,0) end ask.ok = dialog.AddButton(i18n.ask.ok,1) dialog.Show(ask) SetAndFlag(ask, 'maxGen', 'herd') SetAndFlag(ask, 'firstGen', 'herd') SetAndFlag(ask, 'renew', 'herd') SetAndFlag(ask, 'maxBadGen', 'herd') SetAndFlag(ask, 'maxLoss', 'critter') SetAndFlag(ask, 'totalLoss', 'critter') SetAndFlag(ask, 'giveUp', 'critter') SetAndFlag(ask, 'keepConditions', 'critter') SetAndFlag(ask, 'fuzeThresh') if flag.ligand then SetAndFlag(ask, 'useLigand') end end function AskAdvanced() local ask=dialog.CreateDialog(i18n.ask.advanced.mainTitle) ask.l1=dialog.AddLabel(MakeFancyHeader(i18n.ask.advanced.l1)) ask.minRebuild=dialog.AddSlider(i18n.ask.advanced.minRebuild,uo.minRebuild,0,5000,0) ask.maxRebuild=dialog.AddSlider(i18n.ask.advanced.maxRebuild,uo.maxRebuild,0,1,3) ask.l2=dialog.AddLabel(MakeFancyHeader(i18n.ask.advanced.l2)) ask.l3=dialog.AddLabel(i18n.ask.advanced.l3) ask.stIndex=dialog.AddSlider(i18n.ask.advanced.stIndex,uo.stIndex,1,4,0) ask.l4=dialog.AddLabel(MakeFancyHeader(i18n.ask.advanced.l4)) ask.l5=dialog.AddLabel(i18n.ask.advanced.l5) ask.forceZoneStr=dialog.AddTextbox(i18n.ask.advanced.forceZoneStr, uo.forceZoneStr) ask.zoneWalk = dialog.AddCheckbox(i18n.ask.advanced.zoneWalk, uo.zoneWalk) ask.l6=dialog.AddLabel(MakeFancyHeader(i18n.ask.advanced.l6)) ask.autoGab=dialog.AddCheckbox(i18n.ask.advanced.autoGab,uo.autoGab) ask.gabThresh=dialog.AddSlider(i18n.ask.advanced.gabThresh,uo.gabThresh,0,50,0) ask.l7=dialog.AddLabel(MakeFancyHeader(i18n.ask.advanced.l7)) ask.rebuildCI=dialog.AddSlider(i18n.ask.advanced.rebuildCI,uo.rebuildCI,0,1,2) ask.preciseBands=dialog.AddCheckbox(i18n.ask.advanced.preciseBands,uo.preciseBands) ask.rebuildBest=dialog.AddCheckbox(i18n.ask.advanced.rebuildBest,uo.rebuildBest) ask.longfirst=dialog.AddCheckbox(i18n.ask.advanced.longfirst,uo.longfirst) ask.verbose=dialog.AddCheckbox(i18n.ask.advanced.verbose,uo.verbose) -- desactive (bug) BK 22/3/13 ask.ok = dialog.AddButton(i18n.ask.ok,1) dialog.Show(ask) SetAndFlag(ask, 'minRebuild') SetAndFlag(ask, 'maxRebuild') SetAndFlag(ask, 'stIndex') index.scoreTypes=subscores[ask.stIndex.value] uo.scoringMode=subscores.mode[uo.stIndex] if ask.forceZoneStr.value~='' then for a,b in ask.forceZoneStr.value:gmatch('(%d+),(%d+)') do table.insert(uo.forceZone,{a,b}) end else uo.forceZone={} end SetAndFlag(ask, 'forceZoneStr') SetAndFlag(ask, 'zoneWalk') SetAndFlag(ask, 'autoGab') SetAndFlag(ask, 'gabThresh') SetAndFlag(ask, 'rebuildCI') SetAndFlag(ask, 'preciseBands') SetAndFlag(ask, 'rebuildBest') SetAndFlag(ask, 'longfirst') SetAndFlag(ask, 'verbose') end function DumpErr(err) start,stop,line,msg=err:find(":(%d+):%s()") err=err:sub(msg,#err) p(true, '---') if err:find('Cancelled')~=nil then p(true, i18n.recipe.de1) else p(true, i18n.recipe.de2) p(true, i18n.recipe.de3, line) p(true, i18n.recipe.de4, err) end LastWish() end function LastWish() p(true, i18n.recipe.lw1) recentbest.Save() for i=1, fuseSlot do save.Quickload(i) end save.Quickload(100) if uo.rebuildLoops then p(true, i18n.recipe.lw2) save.LoadSecondaryStructure() end if #index.bands>0 then p(true, i18n.recipe.lw3) RestoreBands() end p(true, i18n.recipe.lw4) WhriteNote() -- New 8/11/2014 structure.SetNote(1,ConcatArray(uo)) CI(1) end xpcall(main, DumpErr) --~ main()

Comments


Bruno Kestemont Lv 1

This recipe combines the power of the rebuilds from DRW with the ability of GAB to increase the score by banding some segments.

Moreover, we made some improvements :
Whole prot : The possibility to rebuild and GAB one by one each segments of the protein, from segment 1 to segment max.
ScoreFilter : Select the minimum score required to launch GAB. Tick "Do not launch GAB" if you only want to rebuild and fuse.
Allow loss : Ebola will not restore the highscore if the score is included in this Loss threshold
FastFuse : Use 1 fuse instead of 5
Saving module : If you tick the "Start again since the last stop" box, Ebola will restart at the same segment as before stopping the last Ebola run. The data from the last run is stored in a note on segment 1
Language : The structure of the script permits to translate very easily the dialogs in many languages.

"More" options :
Rebuild Filter : Skip wiggle after the rebuild if the score is not included between these 2 values compared to the highscore (highscore-Minfilter Subscore management : Consider only one of these subscores to define the worse segments
ForceZone : Rebuild only a selected part of the protein. It is possible to enter many zones. Tick "Walk in the Forcezone" to rebuild from the first to the last segment each zones.
Launch automatically GAB : Launch automatically GAB if the threshold is exceeded
Precise band : Bands from GAB always start from next to the rebuild segments.
Display more information : Display more information in the output of the recipe

"GAB" options :
Number of critters, generations and allowed loss

Nevertheless, it takes a lot of time for each cycle. Excellent recipe for an overnight folding!

ver 1.12.4: Fixed bugs and NC optimized

Note: for sepsis and hotspots, only "whole protein" will work.
Sorry for that. Contextual options will only be implemented later on.

Bruno Kestemont Lv 1

Default: Select zones of Segments min length 3 to Segments max length 6.
For each length, Try worst 10 zones or Whole protein.
For each zone (worst or all), test 15 Rebuild/zone: rebuild + shake or Mutate instead of shake. Here, if the loss is not too big (see second dialog panel), wiggle selected unless Skip Fuse (much faster) is checked.
Of these 15 Rebuild/zone, keep 3 best Solutions/zone and fuse them 5 times or Fast Fuse (faster, less points) 1 time or even Skip Fuse (much faster) if you want to preserve the structure of your protein on early begin game.

If the loss then is less than GAB Filter (default: 20), launch GAB or Do not launch GAB.

Before all of this, you may Transform protein to loop or keep secondary structure (like on early game in order to optimize your design).

Main menu
————-Zones———————
Segments min: number of segments for smaller zones to start with
Segments max: number of segments for bigger zones to end with (then it starts again with small zones)
Try worst: Takes the x worst zones of this length
Whole protein: Takes all possible zones of this length
————-Rebuild——————-
Rebuild/zone: For each zone, rebuild(1)+(shake or mute)+(wiggle selected)
Solutions/zone Keeps this number of best solutions before to fuze and/or GAB
————-Threshold for GAB———
GAB Filter: allowed loss before to launch GAB
Do not launch GAB: never GAB = DRW only
————-Score———————
Allow loss: Keeps the best zone of a specific length, even if it scores less than the best score!
loss threshold: There is a limit of course (otherwise, the recipe will ends to loose only)!
————-Others——————–
Transform protein to loop: it gives more freedom to rebuilds, for end game
Skip Fuse (much faster): good to keep the structure, on begin game
Fast Fuse (faster, less points): 1 fuze instead of 5
Mutate instead of shake: (just after each rebuild), available only on design puzzles
Continue with former options: If Ebola has already been used on this protein, former options are most of the time saved in note from seg 1. Ebola will start again with the same options where it stopped if options are present in note.
Buttons: OK, Cancel, More, GAB

Bruno Kestemont Lv 1

When pushing on "more" button, you get this:

This dialog deals with what happens on the rebuild rounds.

———-Rebuild filter————–
Min filter: Above this loss, after rebuild and shake, the solution will not be wiggled
Max filter: Skip Fuze and GAB if rebuild+shake+wiggle does not move at least by this amount

———-Subscore management————–
Score types:Score for selecting worst scoring zones.
1= All
2= Backbone: clashing + packing + backbone + ideality
3= Sidechain: hiding + bonding + sidechain
4= Other: density + reference

———-Force zone————–
Note: A way to unselect zones is to freeze them.
Forced zone: In order to work only on selected zones, type them here.
Walk in the forced zone: all possible zones of related length, only within this selection (if possible)

———-Launch automatically GAB————–
Allow GAB to be automatically launched after a rebuild+shak+wiggle which gains more than
Launch threshold
(not waiting for further rebuilds, fuzes etc); to save time

———-Others————–
Clash rebuild to change clashing importance when rebuilding
Precise bands bands centered on the selected (e.g. worst) zones, thus not fully random
(this will change after a number of loops, see GAB options)
Rebuild best segments, best zones instead of worst zones (used to stabilize on begin, or at the very end when nothing else moves)
Display more information in the log

Vredeman Lv 1

Bruno
A BIG thanks for making this script understandable. At last I have some understanding of how some of these things work.
Your willingness to share information publicly is commendable. I trust that others will follow your example.
Thanks again.
Porky :)

Bruno Kestemont Lv 1

When pushing on "GAB", you'll see something like this (some options might change depending on the type of puzzle, e.g. ligands see bellow):

The Ebola GAB strategy:

GAB is started if rebuild gave a sufficient score (see first panel), either immediately after a very good rebuild, either on the best solutions found after a number of rebuild on a focused zone. For each GAB generation, there are a number herds and for each herd, a number of critters to be tested (see bellow). GAB was invented before I came to Fold, by rav3pnl I think. We simple copy-past it to Ebola, like we copy-pasted tvdl's eDRW (+simplifying and harmonizing them).

In Ebola, bands are added from and to accepted segments, from worst segments of the zone in consideration (see first panel) to other random segments, including Use Ligand or not or randomly: "Use Ligand options : 0-Never, 1-Random, 2-Allways when relevant.

Personally, I find great this ability to focus Precise bands on selected area ! It's also useful for Hotspot puzzles.

I don't know exactly the complexity of GAB, but I understand it tries bands one after the other within a group of bands called herds. For each herd, it calculates the score change by each band, keeps only the bands scoring Loss max/crit and go to next critter if under Give up threshold.

The default options (embedded in the recipe - you can edit it) are:
Number of best critters to breed: 3 Number of best critters to keep: 5 Number of best critters to produce bastards:2 minimum bands: 2 maximum bands: 5 Critters with score lower than -50 don’t go to the next generation Minimal score to do some kids: -20 Bastards always breed Number of random critters added for each GAB/herd(?) generation: 4

Very important: do you want to Keep conditions (filters etc) before the recipe decides to keep or reject critters?

Fuse threshold determines when to try a Fuze (on, each herd/critter) before to calculate the total GAB generation gain. Remember that here, the Fuze is global (on all protein), thus very slow !!! don't let it to start fuze too often on big proteins ! And use Low Wiggle Power because DRW and GAB need flexibility of the protein.

Don't ask me what all of this represents exactly. I don't know. But it works !

What YOU have to know for Ebola options: full random bands ? or Precise bands centered on the "worst" zones in action? and/or to ligands? Many or few bands (critters) to try? High or low perturbation (critter-accepted loss, GAB accepted loss)?

GAB max loss determines the total loss of GAB that will be accepted before to try a new GAB generation. This is what I change often (big loss takes much more time but it should be advisable on begin or mid game).

This can be endless. that's why we decide to stop GAB after a Max generations without any gain (it's time to try another "worst" zone !). However, if gaining above a certain level, GAB will continue until no gain. When 5-6 "gained another" occur, it's great to see it in the log.
Normal GAB recipe allows an endless number of generations without gain. You may put it high in order to "force" a focused GAB on the latest bad zone on the very end … if you have days and weeks patience.

If you selected the Precise bands default in the "advanced" panel, it's quite interesting to change strategy after some time and go to a "normal" GAB with Start full random after the given number of generation without gain. And to force Stop if no result after these 2 strategies in order to be able to try other worst zones. Remember that the Start full random works on the all protein like a normal GAB, so be patient and use preferably many Precise bands, stopping immediately after one or 2 additional Start full random.

————–GAB Options————-

————–Generations————-
GAB max loss: Maximum loss per generation;
Max generations: Maximum GAB generations

Max generations without gain for :
Start full random: Abandoning precise bands, go for normal GAB, full random bands
Stop: Stop GAB immediately if no gain after this total number of
bad successive generations (precise and random)

————–Critters—————-
Crits 1r gen.: Number of critters in first generation
Loss max/crit
Give up threshold
Keep conditions: Next critter if a condition is lost
Fuse threshold: Launch fuse after this generation if next to the highscore
(sorry it should be under GAB I think, not here in critters)

————–Other——————-
"Use Ligand options : 0-Never, 1-Random, 2-Allways
Use Ligand: on ligand puzzles only

Bruno Kestemont Lv 1

I'll try to update Ebola with the "best known today" options whenever possible.
Simply push on "OK" and it should work for overnight run. This is not a recipe to use on hand fold ! It takes many hours to gain!
We almost never use it with these default on begin game: first try simple edrw (or "skip GAB"), then your preferred normal GAB (or all options in order to have a lot of GAB in the GAB panel), then Ebola with this default options.

I'm working on a version that would give you the best default options out of context. But the first priority is stability and best yield in the New Chapter environment.