Icon representing a recipe

Recipe: Acid Tweeker V2.5.2 Filter

created by Bruno Kestemont

Profile


Name
Acid Tweeker V2.5.2 Filter
ID
49343
Shared with
Public
Parent
Acid Tweeker V2.4
Children
Created on
February 23, 2015 at 19:26 PM UTC
Updated on
February 23, 2015 at 19:26 PM UTC
Description

bug fixed on sidechain manipulate and on wiggle selected. Filters management. Adding most options of original AT 1.78 by Steven Pletsch. Filters adapted.

Best for


Code


--Acid Tweaker v2.5 --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) 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 segCount=structure.GetCount() segStart=1 segEnd=segCount -- will try to tweek ligands also (to verify) segCnt2=segCount -- later for ligands OriginalFilterSetting = behavior.GetSlowFiltersDisabled() -- new BK 8/4/2013 FILTERMANAGEMENT=false CENTROID=false -- new BK 20/10/2013 badpuzzle={'999'} -- list of not implemented puzzles - to be edited on each bug with puzzle nb --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")) then PROBABLEFILTER=true GENERICFILTER=true FILTERMANAGEMENT=false 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 behavior.GetSlowFiltersDisabled() then behavior.SetSlowFiltersDisabled(false) end end function FiltersOff() if behavior.GetSlowFiltersDisabled()==false then behavior.SetSlowFiltersDisabled(true) end end -- function to overload a funtion function mutFunction(func) local currentfunc = func local function mutate(func, newfunc) local lastfunc = currentfunc currentfunc = function(...) return newfunc(lastfunc, ...) end end local wrapper = function(...) return currentfunc(...) end return wrapper, mutate 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, mutate = mutFunction(mycl[orig_key]) if filters==true then mutate(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 mutate(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, false) 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() 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")) then PROBABLEFILTER=true 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 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) if pose==nil then pose=current end local total=8000 for i=segStart, segCnt2 do 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 function ds(val) if mutate==true then if FILTERMANAGEMENT then behavior.SetSlowFiltersDisabled(OriginalFilterSetting) end -- new BK 8/4/2013, always back to user settings structure.MutateSidechainsSelected(val+1) 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 behavior.SetSlowFiltersDisabled(true) 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) 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 behavior.SetSlowFiltersDisabled(OriginalFilterSetting) 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 --Start score management and report --better to enable filter during setup => these scores will be reset after dialog bestScore=Score() -- for savebest, I'll reset it after knowing the parameters startenergypersegment=(SegScore()-8000)/segCnt2-- 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) -- NEW BK 9/10/2013 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,"/",segCnt2,". 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 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() 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() SaveBest(seg) return false end end return true end function sidechain_tweak() p("Pass 1 of 3: Sidechain tweak") for i=segStart, segEnd do if usableAA(i) then selection.DeselectAll() selection.Select(i) local ss=Score() g_total_score = Score() CI(0) --ds(2) WiggleSimple(1,"s") -- new function BK 8/4/2013 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() p("Pass 2 of 3: Sidechain tweak around") for i=segStart, segEnd do 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(1,"s") -- new function BK 8/4/2013 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() -- 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 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() puzzleprop()-- new BK 21/10/2013 CI(1.00) recentbest.Restore() save.Quicksave(3)--in save 3 always best solution. Load in case of crash. s1=Score() StartChrono=os.clock () sidechain_tweak() s2=Score() p("Tweak gain: ",round(s2-s1)) StartChrono=os.clock () sidechain_tweak_around() s3=Score() p("Around gain: ",round(s3-s2)) if manipulate==true then StartChrono=os.clock () sidechain_manipulate() s4=Score() if s4-s3 <0 then recentbest.Restore() 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() 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 manipulate=true -- test rottamers function GetParam() local dlg = dialog.CreateDialog("Acid Tweeker 2.2") 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.sphere_worst = dialog.AddCheckbox("Include worst segments in sphere", false) dlg.rebuild = dialog.AddCheckbox("Rebuild before search rotts, for very end only", true) dlg.segStart=dialog.AddTextbox("From seg ", segStart) dlg.segEnd=dialog.AddTextbox("To seg ", segEnd) 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) dlg.GENERICFILTER=dialog.AddCheckbox("Always disable filter, unless for scoring", GENERICFILTER) 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 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 end if GENERICFILTER then FILTERMANAGEMENT=false --(because reduntant and to avoid enabling filters after wiggles) MutClass(structure, false) 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 return true end return false end if GetParam()==false then return end recentbest.Save() ini_score=Score() print("Acid Tweeker starting at score: "..ini_score) if behavior.GetSlowFiltersDisabled() then print("... without the filters !") end bestScore=Score() -- for savebest, reset with default filter 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 hop ==1 then if not manipulate then manipulate = true print("Upgrading options: Adding manipulate-----") else hop=hop+1 end end if hop ==2 then if not fix_band then fix_band = true print("Upgrading options: Adding Fixing bands----------") else hop=hop+1 end end if hop ==3 then if fast then fast = false print("Upgrading options: Disabling fast----------") else hop=hop+1 end end if hop ==4 then if not rebuild then rebuild = true print("Upgrading options: Adding Rebuild before manipulate---------") else hop=hop+1 end end if hop ==5 then if not sphere_worst then sphere_worst=true print("Upgrading options: Adding sphere-----------") else hop=hop+1 end end if hop ==6 then if fix_band then fix_band = false print("Upgrading options: No Fixing bands----------") else hop=hop+1 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") 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() CI(1) behavior.SetSlowFiltersDisabled(OriginalFilterSetting) end --MAINAT() xpcall(MAINAT, DumpErr) --end

Comments


Bruno Kestemont Lv 1

AT is perfect for end and very end, actually for the ultimate day. I won puzzles with this, gaining the 1 point that makes the difference. I also simply evolved intermediate solutions with this, just to be named in the evolvers list. But after AT infinite run, the protein is perfectly stiffed ! So don't run overnight in mid game ! and if you share with your group after AT infinite run, say it to your team members so that they won't loose time to try evolve this gift.

Default options are the best options for this very end.

AT scans each segment and optimizes side chain and rotamer positions for the current primary structure. Therefore, it's not interesting for begin or middle game (even if you'll always get points). Moreover, AT is very good for best scoring segments; it does not help for worst scoring segments (you'll verify this in the log). That's why it's good for the end, when worst segment strategies finished to fail.

However, you can change options if you want:
-Fast mode gains less but is quick. Good for middle game, when you just want to move the protein a little bit. In further loops, this fast mode disappears.
-Fix geometry with bands when score breaks down: it's added in latest loops in order to change context. It could be also useful on beginning games, but I did not test this.
-Brute force in phase 3: this is typically only good for best scoring segments. Do not use this in mid game, you'll loose precious time. After few loops in infinite run, this is activated if not checked on start.
-Rebuild before search rotts, for very end only: roots = rotamers (in phase 3). This option in order to disturb a little bit and find ultimate micro points. Also activate in further loops.
-From seg … To seg: Default is all protein from 1 to end = 1 loop. Then second loop adds an option, reduces the min pts/seg by 10 pts, and start again from 1 to end. You can select one preferred zone here in order to save time (do select the best green zone).
Skip segments scoring less than: min pts/seg: This NEW option really gains a huge time! 10 is a very good choice at end puzzle (on each loop, it will be reduced by then, thus 0 on second loop, -10 next loop etc until infinite). I use 30 to save time at very very end, when my score is high on the board. If you don't trust me, try to start with -100 and look in the log: you'll see that AT does not help you to fix ultimate bad segments.

Thanks to Steven Pletsch who originated Acid Tweaker and most options I implemented here.

New to 2.4.5: bug fixed for CASP symmetric puzzles

Bruno Kestemont Lv 1

Debugged for ligand puzzles

3 filter options (2 in dialog):

1-disable filter during wiggle, then return to starting filter setting
1-if recipe starts with filter enabled, scores and everything else is done including filters
2-if recipe starts with filter disabled, filters will stay disabled all the time (scores are given without filters)
3-always disable filters, always enable them for scoring

Bruno Kestemont Lv 1

Debugged, sorry for the inconvenience and thanks again for reporting.
Now it's quite powerful on all types puzzles that I know. End game only !

Tweedle Dumb Lv 1

Different error now, first error nooticed was around line 300 with a call I no longer remmember. Present error is with line 29 attempt to call field GetExplorationMultiplier

Tweedle Dumb Lv 1

Noticing errors in most every recipe using calls similar to GetExplorationMultipler. And the only difference I have made recently was the most recent DP update.