Icon representing a recipe

Recipe: Acid Tweeker V2.8.2

created by Bruno Kestemont

Profile


Name
Acid Tweeker V2.8.2
ID
109093
Shared with
Public
Parent
Acid Tweeker V2.8.1
Children
None
Created on
July 04, 2025 at 18:57 PM UTC
Updated on
January 09, 2026 at 13:05 PM UTC
Description

Adding most options of original AT 1.78 by Steven Pletsch. Filters and Ligand friendly.

Best for


Code


--Acid Tweaker v2.8 --Acid Tweaker v1.78 by Steven Pletsch --modded by rav3n_pl;] -- modded by BitSpawn, March 2012 -- v2.00: LUAV2, thanks Timo -- modded by B.Kestemont, March 2013 -- v2.1: bug fixed on rotamers, set default as in v1.78 -- v2.2 Bug fixed on structure.WiggleAll (replaced by structure.WiggleSelected) -- management of slow filters and cleaned BK 8/4/2013 --adding starting score in the log BK 20 Sept 2013 --v2.2.1 adding range of seg in user inputs BK 20 Sept 2013 --v2.3.0 adding sphere_worst and automatic improvement on further loops in order to get the --full power of original Acid Tweaker v1.78 by Steven Pletsch for long run. BK 8 Oct 2013 --adding report with zone of substantial gains. --reducing info in log to only gaining segments --adding successive loops management with more and more desperate options --adapted for exploration puzzle scores 18/10/2013 --added puzzleprop for later & draft adapted for centroid 25/10/2013 --8/4/2013 loops of 2 wiggles in place of 1 end each loop (susume says to wiggle by 2, I obey) --v2.4.0 public --v2.4.5 debugged line 73 --v2.5 filters and some small changes for optimisation --v2.5.1 GENERICFILTER only after dialog (test), FILTERMANAGEMENT in dialog --v2.5.2 debugged in detectligand (secCnt2 problem) --v2.5.3 changed default filter management (filters are not always so slow) -- and I think it's better to keep filters for Contacts and H-Bonds --v2.6.0 added different walkers (random, reverse etc) --v2.6.1 fixed MixInwardTable bug on impair puzzles --v2.6.2 fixed unideal loop GENERICFILTER bug --v2.6.3 tried to fix GENERICFILTER bug again and added mutate option --v2.6.4 and tried again to fix GENERICFILTER on recentbest (see feedback discussion, Foldit Bug) -- replaced by FakeRecentBestSave() and FakeRecentBestRestore() 29/8/2017 --v2.6.5 Ligand detection in dialog --v2.7 dialog to limit to rotamers (like in pauldun versions of AT). --v2.7.1 fixed MixInwardTable bug again, thanks to robgee -- filters to bonuses or objectives recognition --v2.8 GRRR adapted filter setting to new lua commands: return2GlobalOriginalFilterSetting() --v2.8.1 original filter setting on start --v2.8.2 don't work on locked segments + specific settings for ligand puzzles -- Remembering that before dialog, generic filter doesn't work, so filters are on or off for initial scores. -- If still BUG, add lines 927-928 ? --Slots--------------- --3 = best --4 = best temp rotamer --5 = recent best archive (for dbugging recentbest Foldit BUG on filtered puzzles) recipename="Acid Tweaker 2.8.2" g_segments = structure.GetCount() -- total number of segments in puzzle g_total_score = 0 -- recent best to compare to and see if score was improved g_score = {} -- array of segment scores for comparisons (total for segment) normal= (current.GetExplorationMultiplier() == 0) startRecTime=os.clock () -- New BK 23/10/13 p=print --a short OriginalFilterSetting = filter.AreAllEnabled() --Start MIX TABLE inits segCnt=structure.GetCount() flagligand=false segCnt2=segCnt -- ligands while structure.GetSecondaryStructure(segCnt2)=="M" do segCnt2=segCnt2-1 end segStart=1 --start from segEnd=segCnt2 --end seg --WORKON={{segStart,segCnt2}} WORKONBIS={} -- the table to use is a simple list of segments in any order NOTONLOCKED=true --sidechains locked compteur=0 for i = segStart, segEnd do -- basic list of segments (init of WORKONBIS) local bb, sc = structure.IsLocked (i) -- backbones, sidechains if NOTONLOCKED and not sc then -- new to save time on ligand puzzles compteur=compteur+1 WORKONBIS[compteur]=i end end mixtables=1 randomly=false --End MIX TABLE inits segCount=segCnt --TO DO: some wiggle in order to activate the filter bug ? --check for filter bug 24/8/2018 if not OriginalFilterSetting then print("Filter disabled on start, is that intended ?") local function CheckUserFilterPrefDIALOG() local dlg = dialog.CreateDialog("Are you sure ?") dlg.L1=dialog.AddLabel("Filter disabled on start, is that intended ?!?") dlg.ok = dialog.AddButton("YES", 0) dlg.cancel = dialog.AddButton("NO !", 1) if dialog.Show(dlg) > 0 then print("Enabling filter by default") filter.EnableAll() end end CheckUserFilterPrefDIALOG() end FILTERMANAGEMENT=false CENTROID=false -- new BK 20/10/2013 CONTACTS = false HBONDS= false badpuzzle={'999'} -- list of not implemented puzzles - to be edited on each bug with puzzle nb function return2GlobalOriginalFilterSetting() if OriginalFilterSetting then -- if true, all filters are default enabled filter.EnableAll() --Enables all filters else filter.DisableAll() --Disables all filters end end --START Generic Filter Management by BitSpawn 21/12/2014 --Source: http://fold.it/portal/node/1998917 PROBABLEFILTER=false GENERICFILTER=false --identifying filtered puzzles function detectfilter() local descrTxt=puzzle.GetDescription() if #descrTxt>0 and (descrTxt:find("filter") or descrTxt:find("filters") or descrTxt:find("Bonus") or descrTxt:find("bonuses") or descrTxt:find("bonus") or descrTxt:find("Objectives") or descrTxt:find("Filters")) then PROBABLEFILTER=true print("Bonus active") end return end detectfilter() -- function to copy class/table function CopyTable(orig) local copy = {} for orig_key, orig_value in pairs(orig) do copy[orig_key] = orig_value end return copy end -- functions for filters function FiltersOn() if filter.AreAllEnabled() then filter.EnableAll() end end function FiltersOff() if not filter.AreAllEnabled() then filter.DisableAll() end end -- function to overload a funtion function mutFunction(func) local currentfunc = func local function mutateFunc(func, newfunc) local lastfunc = currentfunc currentfunc = function(...) return newfunc(lastfunc, ...) end end local wrapper = function(...) return currentfunc(...) end return wrapper, mutateFunc end -- function to overload a class -- to do: set the name of function classes_copied = 0 myclcp = {} function MutClass(cl, filters) classes_copied = classes_copied+1 myclcp[classes_copied] = CopyTable(cl) local mycl =myclcp[classes_copied] for orig_key, orig_value in pairs(cl) do myfunc, mutateFunc = mutFunction(mycl[orig_key]) if filters==true then mutateFunc(myfunc, function(...) FiltersOn() if table.getn(arg)>1 then -- first arg is self (function pointer), we pack from second argument local arguments = {} for i=2,table.getn(arg) do arguments[i-1]=arg[i] end return mycl[orig_key](unpack(arguments)) else --print("No arguments") return mycl[orig_key]() end end) cl[orig_key] = myfunc else mutateFunc(myfunc, function(...) FiltersOff() if table.getn(arg)>1 then local arguments = {} for i=2, table.getn(arg) do arguments[i-1]=arg[i] end return mycl[orig_key](unpack(arguments)) else return mycl[orig_key]() end end) cl[orig_key] = myfunc end end end -- how to use: --setting default options if filters BK 4/2/2015 --MutClass(structure, false) --MutClass(band, false) --MutClass(current, true) --[[ it does not work good here, testing it in dialog if GENERICFILTER then MutClass(structure, false) MutClass(band, true) MutClass(current, true) MutClass(recentbest, true) MutClass(save, true) print("Disabling filters always but for scoring") end ]]-- --STOP Generic Filter Management indexligand={} -- not used here yet --Detect ligands (from Jean-Bob) function DetectLigand() local lastSeg1=structure.GetCount() local lastSeg2=lastSeg1 while structure.GetSecondaryStructure(lastSeg1)=="M" do flagligand=true lastSeg1=lastSeg1-1 end if lastSeg1+1==lastSeg2 then indexligand={lastSeg2} else indexligand={lastSeg1, lastSeg2} end segCnt2=lastSeg1 end DetectLigand() if flagligand then mixtables=2 end -- init for the dialog function puzzleprop() -- by Bruno Kestemont 20/10/2013, Simplified for AT local descrTxt=puzzle.GetDescription() --p(true,descrTxt) local puzzletitle=puzzle.GetName() --p(true,puzzletitle) if #puzzletitle>0 then for i=1,#badpuzzle do if puzzletitle:find(i) then -- check if not bizarre puzzle NOTIMPLEMENTED=true end end if (puzzletitle:find("Sym") or puzzletitle:find("Symmetry") or puzzletitle:find("Symmetric") or puzzletitle:find("Dimer") or puzzletitle:find("Trimer") or puzzletitle:find("Tetramer") or puzzletitle:find("Pentamer")) then PROBABLESYM=true if puzzletitle:find("Dimer") and not puzzletitle:find("Dimer of Dimers") then sym=2 elseif puzzletitle:find("Trimer") or puzzletitle:find("Tetramer") then sym=3 elseif puzzletitle:find("Dimer of Dimers") or puzzletitle:find("Tetramer") then sym=4 elseif puzzletitle:find("Pentamer") then sym=5 else --SymetryFinder() debugged 03/06/2014 end end end if #descrTxt>0 and (descrTxt:find("Sym") or descrTxt:find("Symmetry") or descrTxt:find("Symmetric") or descrTxt:find("sym") or descrTxt:find("symmetry") or descrTxt:find("symmetric")) then PROBABLESYM=true if (descrTxt:find("Dimer") or descrTxt:find("dimer")) and not (descrTxt:find("Dimer of Dimers") or descrTxt:find("dimer of dimers")) then sym=2 elseif descrTxt:find("Trimer") or descrTxt:find("trimer") then sym=3 elseif (descrTxt:find("Dimer of Dimers") or descrTxt:find("Tetramer")) and not (descrTxt:find("dimer of dimers") or descrTxt:find("tetramer"))then sym=4 elseif descrTxt:find("Pentamer") or descrTxt:find("pentamer") then sym=5 end end if #descrTxt>0 and (descrTxt:find("filter") or descrTxt:find("filters") or descrTxt:find("Bonus") or descrTxt:find("bonuses") or descrTxt:find("bonus") or descrTxt:find("Objectives") or descrTxt:find("Filters")) then PROBABLEFILTER=true print("Bonus active") end if #puzzletitle>0 and puzzletitle:find("Sepsis") then -- new BK 17/6/2013 SEPSIS=true end if #puzzletitle>0 and puzzletitle:find("Electron Density") then -- for Electron Density ELECTRON=true end if #puzzletitle>0 and puzzletitle:find("Centroid") then -- New BK 20/10/2013 --p(true,"-Centroid") CENTROID=true end if #puzzletitle>0 and puzzletitle:find("Contacts") then -- New BK 20/10/2013 CONTACTS=true end if #puzzletitle>0 and puzzletitle:find("H-Bonds") then -- New BK 20/10/2013 HBONDS=true end return end -- Score functions -- NEW from tvd for exploration puzzles function Score(pose) if pose==nil then pose=current end local total= pose.GetEnergyScore() -- FIX for big negatives if total < -999999 and total > -1000001 then total=SegScore(pose) end if normal then return total else return total*pose.GetExplorationMultiplier() end end function SegScore(pose) -- only used for big negatives and at init (for maximo setting) if pose==nil then pose=current end local total=8000 for i=segStart, segEnd do -- all segments (only used at start recipe) total=total+pose.GetSegmentEnergyScore(i) end return total end function RBScore() -- not used yet return Score(recentbest) end --[[function Score() return current.GetEnergyScore() end]]-- -- END score functions --START Debugging Recentbest Foldit Bug Temporary solution of Foldit bug (BK 29/8/2017) function FakeRecentBestSave() if PROBABLEFILTER then -- trying to solve the Foldit bug save.Quicksave(5) else recentbest.Save() end end function FakeRecentBestRestore() if PROBABLEFILTER then -- trying to solve the Foldit bug local ss=Score() recentbest.Restore() -- filter disabled (bug) local se=Score() -- now with the filter if se > ss then save.Quicksave(5) end save.Quickload(5) else recentbest.Restore() end end --END Debugging Recentbest Foldit Bug function ds(val) if MUTATE==true then if FILTERMANAGEMENT then filter.EnableAll() end-- 24/8/2017, always enable filter for mutate structure.MutateSidechainsSelected(val+1) -- Note: on GENERICFILTER, it will always be without filters !! else structure.ShakeSidechainsSelected(val) end end global_ci=1 function CI(val) global_ci=val behavior.SetClashImportance(global_ci) end function WiggleSimple(val,how) if FILTERMANAGEMENT then filter.DisableAll() end-- new BK 8/4/2013, always disable filter here if CENTROID then -- new BK 20/10/2013 if how=="s" or how=="ws" then how="wa" end end if how == "s" then ds(1) -- NB: filter always will be on for mutate, see ds() elseif how == "wb" then structure.WiggleSelected(val, true, false) -- backbones elseif how == "ws" then structure.WiggleSelected(val, false, true) -- sidechains elseif how == "wa" then structure.WiggleSelected(val, true, true) -- all elseif how== "lw" then structure.LocalWiggleSelected(val) -- new elseif how=="rb" then structure.RebuildSelected(1) -- don't use, it's chaotic end if FILTERMANAGEMENT then return2GlobalOriginalFilterSetting() end -- new BK 10/10/2013, always back to user settings end function WiggleAT(ss, how, iters, minppi) local valiter=2 local val=1 if fast==true then valiter=1 end if how==nil then how="wa" end if CENTROID then -- new BK 20/10/2013 if how=="s" or how=="ws" then how="wa" end end if iters==nil then iters=6 end minppi=(g_total_score-Score())/100 if ((minppi==nil) or (minppi<0.001)) then minppi=0.001 end if global_ci==1.00 then val=valiter end if iters>0 then iters=iters-1 local sp=Score() WiggleSimple(val,how)-- new function BK 8/4/2013 local ep = Score() local ig=ep-sp if how~="s" then if ig > minppi then WiggleAT(ss, how, iters, minppi) end end end end function SelectSphere(sg,radius,nodeselect) if nodeselect~=true then selection.DeselectAll() end for i=1, segCount do if structure.GetDistance(sg,i)<radius then selection.Select(i) end if sphere_worst==true then if current.GetSegmentEnergyScore(i)<sphere_worst_value then selection.Select(i) end end end end function Fix(sg) if fix_band==false then return end -- selection.DeselectAll() local nb=1 for i=1, segCount do dist=structure.GetDistance(sg,i) if (dist<12 and dist>6) then local cband=band.GetCount() band.AddBetweenSegments(sg, i) if cband<band.GetCount() then band.SetGoalLength(nb,dist) nb=nb+1 end -- else if dist>12 then -- selection.Select(i) -- end end end -- freeze.FreezeSelected(true,true) -- selection.DeselectAll() -- SelectSphere(sg,esfera) --structure.WiggleSelected(1,true,true) WiggleSimple(1,"wa") -- new function BK 8/4/2013 band.DeleteAll() -- freeze.UnfreezeAll() end function round(x)--cut all afer 3-rd place return x-x%0.001 end --calculate REALLY good seed for the pseudorandom in random (avoids to always have the same sequence) return2GlobalOriginalFilterSetting() -- 24/8/2017 any time score is calcultated on first read, this is verified (for filter bug) seed=os.time()/math.abs(Score()) seed=seed%0.001 seed=1/seed while seed<10000000 do seed=seed*1000 end seed=seed-seed%1 p("Seed is: "..seed) math.randomseed(seed) --REALLY good seed made by rav3n_pl :P --START MIX TABLE subroutine by Bruno Kestemont 16/11/2015, idea by Puxatudo & Jeff101 from Go Science function down(x) return x-x%1 end function ShuffleTable(tab) --randomize order of elements local cnt=#tab for i=1,cnt do local r=math.random(cnt) -- not very convincing ! it gives always the same number on same puzzle tab[i],tab[r]=tab[r],tab[i] end return tab end function MixInwardTable(tab) -- 1234567 = 7254361 WARNING: if done twice, it returns to the original table local cnt=#tab -- 1234567 = 7254361; 123456 = 624351 local mid=down(cnt/2) --local adjust=1 -- case of pair number of segments --local result={} local result=tab -- in order to avoid any nil seg numbers (fixing a bug) local pair=true --if mid<cnt/2 or mid==1 then adjust=0 end -- case of impair number of segments --for i=1,mid-adjust do -- mid remains untouched if impair cnt for i=1,mid do pair = not pair if pair then result[i],result[cnt+1-i]=tab[i],tab[cnt+1-i] -- pair segs are kept untouched else result[i],result[cnt+1-i]=tab[cnt+1-i],tab[i] -- impairs segs are shifted (loop starts with last seg) end end return result end function InwardTable(tab) -- 1234567 = 7162534 WARNING: if done twice, it mixes everything like a feuillete bakery local cnt=#tab -- 1234567 = 7162534 local cntup=1 local result={} local pair=true for i=1,#tab do pair = not pair if pair then result[i]=tab[cntup] -- pairs segments are taken from bottom cntup=cntup+1 else result[i]=tab[cnt] -- impairs segs are taken from end (loop starts with last seg) cnt=cnt-1 end end return result end function Reverselist(tab) -- 1234567=7654321 local cnt=#tab local result={} for i=1,#tab do -- simply inverts the table 7162534=4536271 result[i]=tab[cnt+1-i] end return result end function OutwardTable(tab) --1234567=4352617 local result={} result=Reverselist(InwardTable(tab)) return result end --END MIX TABLE --Start score management and report --better to enable filter during setup => these scores will be reset after dialog return2GlobalOriginalFilterSetting() -- 24/8/2017 any time score is calcultated on first read, this is verified (for filter bug) bestScore=Score() -- for savebest, I'll reset it after knowing the parameters startenergypersegment=(SegScore()-8000)/segEnd-- NEW BK 18/10/2013 for maximo settings winnerseg=2 -- arbitrary function SaveBest(seg) local s=Score() local g=s-bestScore local WaitingTime=os.clock ()--StartChrono if g>0 then --local sscore=current.GetSegmentEnergyScore(seg) -- it's global now if g>=0.001 then p("Gained another ",round(g)," pts on seg ",seg, " scoring: ", round(sscore), ". Total score:",s) elseif WaitingTime > 300 then-- in sec, every 5 minutes, show something to make patience StartChrono=os.clock () p("No gain up to seg",seg,"/",segEnd,". Score:", s) end bestScore=s save.Quicksave(3) if g>bestg then -- NEW BK 9/10/2013 bestg=g winnerseg=seg end end end --End score management and report function usableAA(sn) local usable=false -- a priori, aucun segment n'est utilisable sauf s'il rpond une des conditions ci-dessous sscore=current.GetSegmentEnergyScore(sn)-- NEW BK 9/10/2013 global to print in savebest --------------------------------------------- if sscore>minimo then return usable -- donc false ici (true si score > minimo = 600) end if sscore<maximo then -- NEW BK 8/10/2013 return usable -- donc false ici (true si score < maximo) end if rebuild==true then -- tous ceux qui restent si rebuild incl. ligands selection.DeselectAll() selection.Select(sn) structure.RebuildSelected(2) usable=true return usable end --if one of the above condition is met, we verify not further --------------------------------------------- if #useThat>0 then for i=1,#useThat do if sn==useThat[i] then usable=true break end end else if #useOnly > 0 then for i=1,#useOnly do local ss=useOnly[i][1] local se=useOnly[i][2] for s=ss,se do if s==sn then usable=true break end end end else usable=true -- each segment usable by default if #doNotUse>0 then for i=1,#doNotUse do local ss=doNotUse[i][1] local se=doNotUse[i][2] for s=ss,se do if s==sn then usable=false break end end if usable==false then break end end end if #skipAA>0 then local aa=structure.GetAminoAcid(sn) for i=1,#skipAA do if aa==skipAA[i] then usable=false break end end end end end local se=segCount if ATend~=nil then se=ATend end if sn<ATstart or sn>se then usable=false end return usable end function wiggle_out(seg) CI(.6) --structure.WiggleSelected(1,true,true) WiggleSimple(2,"wa") -- new function BK 8/4/2013 CI(1.) WiggleAT(seg) WiggleAT(seg,"s",1) --selection.SelectAll() CI(.6) WiggleAT(seg) CI(1.) WiggleAT(seg) --recentbest.Restore() FakeRecentBestRestore() SaveBest(seg) end function getNear(seg) if(Score() < g_total_score-1000) then selection.Deselect(seg) CI(.75) --ds(1) WiggleSimple(1,"s") -- new function BK 8/4/2013 --structure.WiggleSelected(1,false,true) WiggleSimple(1,"ws") -- new function BK 8/4/2013 selection.Select(seg) CI(1) end if(Score() < g_total_score-1000) then if fix_band==true then Fix(seg) else --recentbest.Restore() FakeRecentBestRestore() SaveBest(seg) return false end end return true end function sidechain_tweak(worklist) p("Pass 1 of 3: Sidechain tweak") worklist=worklist or WORKONBIS --for i=segStart, segEnd do for j=1,#worklist do local i=worklist[j] if usableAA(i) then selection.DeselectAll() selection.Select(i) local ss=Score() g_total_score = Score() CI(0) --ds(2) WiggleSimple(2,"s") -- changed to original 2 24/8/2017 CI(1.) --p("Try sgmnt ", i) SelectSphere(i, esfera) if (getNear(i)==true) then wiggle_out(i) end end end end function sidechain_tweak_around(worklist) p("Pass 2 of 3: Sidechain tweak around") --for i=segStart, segEnd do worklist=worklist or WORKONBIS --for i=segStart, segEnd do for j=1,#worklist do local i=worklist[j] if usableAA(i) then selection.DeselectAll() for n=1, g_segments do g_score[n] = current.GetSegmentEnergyScore(n) end selection.Select(i) local ss=Score() g_total_score = Score() CI(0) --ds(2) WiggleSimple(2,"s") -- changed to original 2 24/8/2017 CI(1. ) --p("Try sgmnt ", i) SelectSphere(i,esfera) if(Score() > g_total_score - 30) then wiggle_out(i) else selection.DeselectAll() for n=1, g_segments do if(current.GetSegmentEnergyScore(n) < g_score[n] - 1) then selection.Select(n) end end selection.Deselect(i) CI(0.1) --ds(1) WiggleSimple(1,"s") -- new function BK 8/4/2013 SelectSphere(i,esfera,true) CI(1.0) if (getNear(i)==true) then wiggle_out(i) end end end end end -- debugged: function sidechain_manipulate(worklist) -- negative scores avoided --p("Dernire chance: manipulateur brutal des chaines latrales") p("Last chance: bruteforce sidechain manipulate on best segments") maximo=maximo+10 -- new BK 14/12/13 because rotamers need best segments --for i=segStart, segEnd do worklist=worklist or WORKONBIS --for i=segStart, segEnd do for j=1,#worklist do local i=worklist[j] if usableAA(i) then selection.DeselectAll() rotamers = rotamer.GetCount(i) save.Quicksave(4) if(rotamers > 1) then local ss=Score() --p("Sgmnt: ", i," rotamers: ",rotamers, " Score= ", ss) for r=1, rotamers do --p("Sgmnt: ", i," position: ",r, " Score= ", ss) save.Quickload(4) g_total_score = Score() rotamer.SetRotamer(i,r) CI(1.) if(Score() > g_total_score - 30) then SelectSphere(i,esfera) wiggle_out(i) -- this can change the number of rotamers end if rotamers > rotamer.GetCount(i) then break end --if nb of rotamers changed end end end recentbest.Restore()-- because rotamers can puzzle everything end maximo=maximo-10 -- new BK 14/12/13 einitiaization of current maximo end -- end debugged --To BE IMPLEMENTED VIA DIALOG BOX useThat={ --only segments what have to be used OVERRIDES all below --18,150,151,205,320,322,359,361,425,432,433 --382 } useOnly={ --ranges what have to be used OVERRIDES BOTH LOWER OPTIONS --{12,24}, --{66,66}, } doNotUse={ --ranges that should be skipped --{55,58}, --{12,33}, } skipAA={ --aa codes to skip 'a', 'g', } -- default skiping these 2 AAs that have no rotamer --option to easy set start and end of AT work to-- to be implemented in dialog ATstart=1 --1st segment ATend=nil --end of protein if nil --END TO BE IMPLEMENTED VIA DIALOG BOX sphere_worst=false -- include worst segments in sphere sphere_worst_value=0 function Run() -- this is the MAIN puzzleprop()-- new BK 21/10/2013 CI(1.00) --recentbest.Restore() FakeRecentBestRestore() save.Quicksave(3)--in save 3 always best solution. Load in case of crash. s1=Score() if tweek == true then StartChrono=os.clock () sidechain_tweak() s2=Score() p("Tweak gain: ",round(s2-s1)) end if tweekaround == true then s2=Score() StartChrono=os.clock () sidechain_tweak_around() s3=Score() p("Around gain: ",round(s3-s2)) end if manipulate==true then StartChrono=os.clock () s3=Score() sidechain_manipulate() s4=Score() if s4-s3 <0 then FakeRecentBestRestore() end --against the bug !!! p("Manipulate gain: ",round(s4-s3)) end selection.SelectAll() -- or 2 lines in one structure.WiggleAll(4,true,true) WiggleSimple(2,"wa") -- new function BK 8/4/2013 BK 15/01/2013 changed 1 to 2 WiggleSimple(2,"ws") -- new function BK 8/4/2013 BK 15/01/2013 changed 1 to 2 selection.SelectAll() WiggleSimple(2,"wa") -- new function BK 8/4/2013 BK 15/01/2013 changed 1 to 2 --recentbest.Restore() FakeRecentBestRestore() s5=Score() --p("Start score Loop ",loop,": ",round(s1)) --p("Tweak gain: ",round(s2-s1)) --p("Around gain: ",round(s3-s2)) --p("Manipulate gain: ",round(s4-s3)) p("Total Acid gain Loop ",loop,": ",round(s5-s1)) --p("End score: ",round(s5)) end esfera=8 minimo=600 -- score for working with worst segments. Don't use, usually worst segs have no rotts if startenergypersegment<-100 then maximo=-100 -- NEW BK 8/10/2013 (filters not considered here before dialog) elseif startenergypersegment<-5 then maximo=-50 elseif startenergypersegment<10 then maximo=-10 else maximo=10 end MUTATE=false -- Don't use, very bad results yet (TODO) rebuild=true -- for very end in a puzzle, rebuild segment before tweak fix_band=false -- if you want to try with the worst segments fast=false phases= 7 --Mode: (1)Tweek (2)Tweek around (3)Rotamers (4)1&2 (5)2&3 (6)1&3 (7)All tweek=false tweekaround=false manipulate=false -- test rottamers if PROBABLEFILTER and not CONTACTS and not HBONDS then FILTERMANAGEMENT=true end function GetParam() local dlg = dialog.CreateDialog(recipename) dlg.fast = dialog.AddCheckbox("Fast mode (gain 25% less)", false) dlg.fix_band = dialog.AddCheckbox("Fix geometry with bands when score breaks down", false) --dlg.manipulate = dialog.AddCheckbox("Brute force in phase 3", true) dlg.label0=dialog.AddLabel("Mode: (1) Tweek (2) Tweek around (3) Rotamers") dlg.label01=dialog.AddLabel(" (4) 1&2 (5) 2&3 (6) 1&3 (7) All") dlg.phases = dialog.AddSlider("Mode: ", phases, 0, 7, 0) dlg.sphere_worst = dialog.AddCheckbox("Include worst segments in sphere", false) dlg.segStart=dialog.AddTextbox("From seg ", segStart) dlg.segEnd=dialog.AddTextbox("To seg ", segEnd) if flagligand then dlg.segEnd=dialog.AddTextbox("To seg ", segEnd+1) textligand= ("Ligand is seg nb. " .. segEnd+1) dlg.l1aaaa=dialog.AddLabel(textligand) dlg.l1aaa=dialog.AddLabel("1=up; 2=back; 3=random; 4=out; 5=in; 6=slice") dlg.mixtables = dialog.AddSlider("Order: ", mixtables, 1, 6, 0) dlg.rebuild = dialog.AddCheckbox("Rebuild before search rotts, for very end only", false) else dlg.segEnd=dialog.AddTextbox("To seg ", segEnd) dlg.l1aaa=dialog.AddLabel("1=up; 2=back; 3=random; 4=out; 5=in; 6=slice") dlg.mixtables = dialog.AddSlider("Order: ", mixtables, 1, 6, 0) dlg.rebuild = dialog.AddCheckbox("Rebuild before search rotts, for very end only", true) end dlg.label1=dialog.AddLabel("Skip segments scoring less than: ") dlg.maximo = dialog.AddSlider("min pts/seg: ",maximo,-100,30,0) --dlg.minimo = dialog.AddSlider("more than",minimo,30,600,0) if PROBABLEFILTER then dlg.FILTERMANAGEMENT=dialog.AddCheckbox("Disable filter during wiggle", FILTERMANAGEMENT) -- default true dlg.GENERICFILTER=dialog.AddCheckbox("Always disable filter, unless for scoring", GENERICFILTER) -- default false dlg.MUTATE= dialog.AddCheckbox("Mutate, no shake", MUTATE) -- default false (it's not recommended) end dlg.ok = dialog.AddButton("OK", 1) dlg.cancel = dialog.AddButton("Cancel", 0) if dialog.Show(dlg) > 0 then fast = dlg.fast.value fix_band = dlg.fix_band.value --manipulate = dlg.manipulate.value phases=dlg.phases.value print("Mode ="..phases) sphere_worst=dlg.sphere_worst.value rebuild = dlg.rebuild.value segStart= dlg.segStart.value segEnd= dlg.segEnd.value --minimo=dlg.minimo.value maximo=dlg.maximo.value if PROBABLEFILTER then GENERICFILTER=dlg.GENERICFILTER.value FILTERMANAGEMENT=dlg.FILTERMANAGEMENT.value MUTATE=dlg.MUTATE.value end if GENERICFILTER then FILTERMANAGEMENT=false --(because reduntant and to avoid enabling filters after wiggles) MutClass(structure, false) -- GENERICFILTER bug: should be turned true again asap !! MutClass(band, false) MutClass(current, true) MutClass(recentbest, true) MutClass(save, true) print("Always disable filter, unless for scoring") end if FILTERMANAGEMENT then print("Disable filter during wiggle") end --actions if phases== 1 or phases== 4 or phases>5 then tweek=true end if phases== 2 or phases== 4 or phases==5 or phase==7 then tweekaround=true end if phases== 3 or phases>4 then manipulate=true end --For MIXTABLES mixtables=dlg.mixtables.value WORKONBIS={} -- reset / the table to use is a simple list of segments in any order local compteur=0 for i = segStart, segEnd do -- basic list of segments (reset of WORKONBIS) local bb, sc = structure.IsLocked (i) -- backbones, sidechains if NOTONLOCKED and not sc then -- new to save time on ligand puzzles compteur=compteur+1 WORKONBIS[compteur]=i end end if mixtables==2 then WORKONBIS=Reverselist(WORKONBIS) print("Backward walk") elseif mixtables==3 then randomly=true WORKONBIS=ShuffleTable(WORKONBIS) print("Random walk") elseif mixtables==4 then WORKONBIS=OutwardTable(WORKONBIS) print("Outward walk") elseif mixtables==5 then WORKONBIS=InwardTable(WORKONBIS) print("Inward walk") elseif mixtables==6 then WORKONBIS=MixInwardTable(WORKONBIS) print("Slice walk") end -- else normal from first to last in the list return true end return false end --It's only here that GENERICFILTER starts to make effect !! if GetParam()==false then return end --recentbest.Save() -- filter enabled ? NO because of Foldit BUG. FakeRecentBestSave() -- should work properly on all situations ini_score=Score() -- ok filter enabled here print("Acid Tweeker starting at score: "..ini_score) -- note: if GENERICFILTER, always on !! if filter.AreAllEnabled() then print("... without the filters !") end bestScore=Score() -- for savebest, reset with default GENERICFILTER parameters (filter enabled or not) loop=0 hop=0 function MAINAT() while(true) do print("################################") local startlooptime=os.clock () local startloopscore=Score() loop=loop+1 if loop ==2 then if not manipulate then manipulate = true print("Upgrading options: Adding manipulate-----") end end if loop ==3 then if not fix_band then fix_band = true print("Upgrading options: Adding Fixing bands----------") end end if loop ==4 then if fast then fast = false print("Upgrading options: Disabling fast----------") end if PROBABLEFILTER and MUTATE then MUTATE = false print("Upgrading options: Disabling mutate----------") end end if loop ==5 then if not rebuild then rebuild = true print("Upgrading options: Adding Rebuild before manipulate---------") end end if loop ==6 then if not sphere_worst then sphere_worst=true print("Upgrading options: Adding sphere-----------") end end if loop ==7 then if fix_band then fix_band = false print("Upgrading options: No Fixing bands----------") end end --hop=hop+1 print("Loop ",loop, "Options:") print("fast=",fast,", fix_band=",fix_band,", manipulate=",manipulate) print(", rebuild=",rebuild, ", sphere=", sphere_worst, ", segs =",segStart,"-",segEnd) print("Use only segments scoring at least",maximo,"pts") if PROBABLEFILTER then print("MUTATE=",MUTATE,"GENERICFILTER=",GENERICFILTER) print("FILTERMANAGEMENT=",FILTERMANAGEMENT) end print("-------------------------------") bestg=0 Run() print("Best gain this loop: ",bestg," pts on seg ",winnerseg) local stoplooptime=os.clock () local stoploopscore=Score() print("This loop gained",round(stoploopscore-startloopscore),"in",round(stoplooptime-startlooptime)/60,"minutes") --if minimo<600 then minimo=minimo+10 end -- good scoring segs will gain much with at maximo=maximo-10 -- worst scoring segs will not gain with at, but if you've so much time, ok we try print(">>>Total Gain: ", round(Score()-ini_score), "Score:", round(Score()),"Start score: ", round(ini_score)) print("CPU time =",round((stoplooptime-startRecTime)/60),"minutes") end end function DumpErr(err) start,stop,line,msg=err:find(":(%d+):%s()") err=err:sub(msg,#err) p('---') if err:find('Cancelled')~=nil then p("User stop.") else p("unexpected error detected.") p("Error line:", line) p("Error:", err) end LastWish() end function LastWish() --recentbest.Restore() FakeRecentBestRestore() CI(1) return2GlobalOriginalFilterSetting() end --MAINAT() xpcall(MAINAT, DumpErr) --end

Comments