Icon representing a recipe

Recipe: TvdL Mutate 1.6.0

created by Timo van der Laan

Profile


Name
TvdL Mutate 1.6.0
ID
45818
Shared with
Public
Parent
TvdL Mutate 1.0.0
Children
Created on
March 28, 2013 at 21:50 PM UTC
Updated on
March 28, 2013 at 21:50 PM UTC
Description

A replacement for the mutate button. Sometimes this will find improvements when normal mutate does not because of all the filters. Now with options and info about progress. More info now and loopnr can be set

Best for


Code


-- -- Tvdl Mutate -- Can be run in several ways: -- 1. Fast hunt for gains -- 2. Same but with a fuze after each gain -- 3. Slow because of qstab after each try -- Module Mutate.lua -- Written because the Lua mutate function does not find the best -- when filters are around -- Added: possible to do afterprocessing after each win or each mutation -- 13-03-2013 Timo van der Laan. -- Handy shorts module normal= (current.GetExplorationMultiplier() == 0) segCnt=structure.GetCount() segCnt2=segCnt while structure.GetSecondaryStructure(segCnt2)=="M" do segCnt2=segCnt2-1 end -- On request of gmn CIfactor=1 function CI(CInr) behavior.SetClashImportance(CInr*CIfactor) end function CheckCI() local ask=dialog.CreateDialog("Clash importance is not 1") ask.l1=dialog.AddLabel("Last change to change it") ask.l2=dialog.AddLabel("CI settings will be multiplied by set CI") ask.continue=dialog.AddButton("Continue",1) dialog.Show(ask) end if behavior.GetClashImportance() < 0.99 then CheckCI() end CIfactor=behavior.GetClashImportance() -- Score functions function Score(pose) if pose==nil then pose=current end local total= pose.GetEnergyScore() -- FIX for big negatives 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=1,segCnt2 do total=total+pose.GetSegmentEnergyScore(i) end return total end function RBScore() return Score(recentbest) end function round3(x)--cut all afer 3-rd place return x-x%0.001 end bestScore=Score() function SaveBest() local g=Score()-bestScore if g>0 then if g>0.01 then print("Gained another "..round3(g).." pts.") end bestScore=Score() save.Quicksave(3) end end -- Wiggle function -- Note the extra parameter to be used if only selected parts must be done function Wiggle(how, iters, minppi,onlyselected) --score conditioned recursive wiggle/shake --fixed a bug, absolute difference is the threshold now if how==nil then how="wa" end if iters==nil then iters=6 end if minppi==nil then minppi=0.1 end if onlyselected==nil then onlyselected=false end if iters>0 then iters=iters-1 local sp=Score() if onlyselected then if how == "s" then -- Shake is not considered to do much in second or more rounds structure.ShakeSidechainsSelected(1) return elseif how == "wb" then structure.WiggleSelected(2,true,false) elseif how == "ws" then structure.WiggleSelected(2,false,true) elseif how == "wa" then structure.WiggleSelected(2,true,true) end else if how == "s" then -- Shake is not considered to do much in second or more rounds structure.ShakeSidechainsAll(1) return elseif how == "wb" then structure.WiggleAll(2,true,false) elseif how == "ws" then structure.WiggleAll(2,false,true) elseif how == "wa" then structure.WiggleAll(2,true,true) end end if math.abs(Score()-sp) > minppi then return Wiggle(how, iters, minppi,onlyselected) end end end -- end of handy shorts module -- Segment set and list module -- Notice that most functions assume that the sets are well formed -- (=ordered and no overlaps) -- 02-05-2012 TvdL Free to use for non commercial purposes function SegmentListToSet(list) local result={} local f=0 local l=-1 table.sort(list) for i=1,#list do if list[i] ~= l+1 and list[i] ~= l then -- note: duplicates are removed if l>0 then result[#result+1]={f,l} end f=list[i] end l=list[i] end if l>0 then result[#result+1]={f,l} end --print("list to set") --SegmentPrintSet(result) return result end function SegmentSetToList(set) local result={} for i=1,#set do --print(set[i][1],set[i][2]) for k=set[i][1],set[i][2] do result[#result+1]=k end end return result end function SegmentCleanSet(set) -- Makes it well formed return SegmentListToSet(SegmentSetToList(set)) end function SegmentInvertSet(set,maxseg) -- Gives back all segments not in the set -- maxseg is added for ligand local result={} if maxseg==nil then maxseg=structure.GetCount() end if #set==0 then return {{1,maxseg}} end if set[1][1] ~= 1 then result[1]={1,set[1][1]-1} end for i=2,#set do result[#result+1]={set[i-1][2]+1,set[i][1]-1} end if set[#set][2] ~= maxseg then result[#result+1]={set[#set][2]+1,maxseg} end return result end function SegmentInList(s,list) table.sort(list) for i=1,#list do if list[i]==s then return true elseif list[i]>s then return false end end return false end function SegmentInSet(set,s) for i=1,#set do if s>=set[i][1] and s<=set[i][2] then return true elseif s<set[i][1] then return false end end return false end function SegmentJoinList(list1,list2) local result=list1 if result == nil then return list2 end for i=1,#list2 do result[#result+1]=list2[i] end table.sort(result) return result end function SegmentJoinSet(set1,set2) return SegmentListToSet(SegmentJoinList(SegmentSetToList(set1),SegmentSetToList(set2))) end function SegmentCommList(list1,list2) local result={} table.sort(list1) table.sort(list2) if #list2==0 then return result end local j=1 for i=1,#list1 do while list2[j]<list1[i] do j=j+1 if j>#list2 then return result end end if list1[i]==list2[j] then result[#result+1]=list1[i] end end return result end function SegmentCommSet(set1,set2) return SegmentListToSet(SegmentCommList(SegmentSetToList(set1),SegmentSetToList(set2))) end function SegmentSetMinus(set1,set2) return SegmentCommSet(set1,SegmentInvertSet(set2)) end function SegmentPrintSet(set) print(SegmentSetToString(set)) end function SegmentSetToString(set) local line = "" for i=1,#set do if i~=1 then line=line..", " end line=line..set[i][1].."-"..set[i][2] end return line end function SegmentSetInSet(set,sub) if sub==nil then return true end -- Checks if sub is a proper subset of set for i=1,#sub do if not SegmentRangeInSet(set,sub[i]) then return false end end return true end function SegmentRangeInSet(set,range) if range==nil or #range==0 then return true end local b=range[1] local e=range[2] for i=1,#set do if b>=set[i][1] and b<=set[i][2] then return (e<=set[i][2]) elseif e<=set[i][1] then return false end end return false end function SegmentSetToBool(set) local result={} for i=1,structure.GetCount() do result[i]=SegmentInSet(set,i) end return result end --- End of Segment Set module -- Module Find Segment Types function FindMutablesList() local result={} for i=1,segCnt2 do if structure.IsMutable(i) then result[#result+1]=i end end return result end function FindMutables() return SegmentListToSet(FindMutablesList()) end function FindFrozenList() local result={} for i=1,segCnt2 do if freeze.IsFrozen(i) then result[#result+1]=i end end return result end function FindFrozen() return SegmentListToSet(FindFrozenList()) end function FindLockedList() local result={} for i=1,segCnt2 do if structure.IsLocked(i) then result[#result+1]=i end end return result end function FindLocked() return SegmentListToSet(FindLockedList()) end function FindSelectedList() local result={} for i=1,segCnt do if selection.IsSelected(i) then result[#result+1]=i end end return result end function FindSelected() return SegmentListToSet(FindSelectedList()) end function FindAAtypeList(aa) local result={} for i=1,segCnt2 do if structure.GetSecondaryStructure(i)== aa then result[#result+1]=i end end return result end function FindAAtype(aa) return SegmentListToSet(FindAAtypeList(aa)) end function FindAminotype(at) --NOTE: only this one gives a list not a set local result={} for i=1,segCnt2 do if structure.GetAminoAcid(i) == at then result[#result+1]=i end end return result end -- end Module Find Segment Types -- Module Random -- Tvdl, 01-11-2012 Randomseed=os.time()%1000000 function Seedrandom() math.randomseed(Randomseed) math.random(100) -- Because the first is not random end Seedrandom() -- Thanks too Rav4pl function ShuffleTable(tab) --randomize order of elements local cnt=#tab for i=1,cnt do local r=math.random(cnt) tab[i],tab[r]=tab[r],tab[i] end return tab end function MutateSeg(segnr,winextra,allextra) local aatypes= {"e","m","a","l","k","f","q","w","i","v","d","h","r","t","s","c","n","y","p","g"} local basescore=Score() local highscore=basescore-100000 local curtype=structure.GetAminoAcid(segnr) local highletter=curtype for i=1,#aatypes do structure.SetAminoAcid(segnr,aatypes[i]) if allextra ~= nil then allextra(segnr,bestScore) end local s=Score() if s>=highscore then highscore=s highletter=aatypes[i] end end structure.SetAminoAcid(segnr,highletter) SaveBest() save.Quickload(3) if recentbest.GetEnergyScore() > Score()+0.001 then print("Unexpected gain found in recentbest") recentbest.Restore() SaveBest() end if structure.GetAminoAcid(segnr) ~= curtype then print("Gain from changing "..curtype.." to "..structure.GetAminoAcid(segnr)) if winextra ~= nil then winextra() end end end function MutateList(list,n,winextra,allextra) local i=1 local max=n if n==nil then max=100 end recentbest.Save() repeat local ss=Score() print("Loop "..i.." Startscore: "..round3(ss)) ShuffleTable(list) for j=1,#list do print("Trying seg "..list[j].." "..j.." from "..#list..". Score: "..round3(Score())) MutateSeg(list[j],winextra,allextra) end i=i+1 print("Loop gained "..round3(Score()-ss).." pts. Current score: "..round3(Score())) until i>max or Score()-ss < 0.1 end function MutateAll(n,winextra,allextra) local Mutables=FindMutablesList() MutateList(Mutables,n,winextra,allextra) end function MutateSelection(n,winextra,allextra) local selection=FindSelectedList() local Mutables=FindMutablesList() local WorkOn=SegmentCommList(selection,Mutables) MutateList(WorkOn,n,winextra,allextra) end -- Standard Fuze module -- Picks up all gains by using recentbest function GetRB(prefun,postfun) if RBScore()> Score() then if prefun ~= nil then prefun() end recentbest.Restore() if postfun ~= nil then postfun() end end end function FuzeEnd(prefun,postfun) if prefun ~= nil then prefun() end CI(1) Wiggle("wa",1) Wiggle("s",1) Wiggle() GetRB(prefun,postfun) if postfun ~= nil then postfun() end SaveBest() end function Fuze1(ci1,ci2,prefun,postfun) if prefun ~=nil then prefun() end CI(ci1) Wiggle("s",1) CI(ci2) Wiggle("wa",1) if postfun ~= nil then postfun() end end function Fuze2(ci1,ci2,prefun,postfun) if prefun ~= nil then prefun() end CI(ci1) Wiggle("wa",1) CI(1) Wiggle("wa",1) CI(ci2) Wiggle("wa",1) if postfun ~= nil then postfun() end end function reFuze(scr,slot) local s=Score() if s<scr then save.Quickload(slot) else scr=s save.Quicksave(slot) end return scr end function Fuze(slot,prefun,postfun) local scr=Score() if slot == nil then slot=4 save.Quicksave(slot) end recentbest.Save() Fuze1(0.3,0.6,prefun,postfun) FuzeEnd(prefun,postfun) scr=reFuze(scr,slot) Fuze2(0.3,1,prefun,postfun) GetRB(prefun,postfun) SaveBest() scr=reFuze(scr,slot) Fuze1(0.05,1,prefun,postfun) GetRB(prefun,postfun) SaveBest() scr=reFuze(scr,slot) Fuze2(0.7,0.5,prefun,postfun) FuzeEnd() scr=reFuze(scr,slot) Fuze1(0.07,1,prefun,postfun) GetRB(prefun,postfun) SaveBest() reFuze(scr,slot) GetRB(prefun,postfun) SaveBest() end -- end standard Fuze module -- Module AskSelections -- 02-05-2012 Timo van der Laan, Free to use for non commercial purposes function AskForSelections(title,mode) local result={{1,structure.GetCount()}} -- All segments if mode == nil then mode={} end if mode.askloops==nil then mode.askloops=true end if mode.asksheets==nil then mode.asksheets=true end if mode.askhelixes==nil then mode.askhelixes=true end if mode.askligands==nil then mode.askligands=false end if mode.askselected==nil then mode.askselected=true end if mode.asknonselected==nil then mode.asknonselected=true end if mode.askmutateonly==nil then mode.askmutateonly=true end if mode.askignorelocks==nil then mode.askignorelocks=true end if mode.askignorefrozen==nil then mode.askignorefrozen=true end if mode.askranges==nil then mode.askranges=true end if mode.defloops==nil then mode.defloops=true end if mode.defsheets==nil then mode.defsheets=true end if mode.defhelixes==nil then mode.defhelixes=true end if mode.defligands==nil then mode.defligands=false end if mode.defselected==nil then mode.defselected=false end if mode.defnonselected==nil then mode.defnonselected=false end if mode.defmutateonly==nil then mode.defmutateonly=false end if mode.defignorelocks==nil then mode.defignorelocks=false end if mode.defignorefrozen==nil then mode.defignorefrozen=false end local Errfound=false repeat local ask = dialog.CreateDialog(title) if Errfound then ask.E1=dialog.AddLabel("Try again, ERRORS found, check output box") result={{1,structure.GetCount()}} --reset start Errfound=false end if mode.askloops then ask.loops = dialog.AddCheckbox("Work on loops",mode.defloops) elseif not mode.defloops then ask.noloops= dialog.AddLabel("Loops will be auto excluded") end if mode.askhelixes then ask.helixes = dialog.AddCheckbox("Work on helixes",mode.defhelixes) elseif not mode.defhelixes then ask.nohelixes= dialog.AddLabel("Helixes will be auto excluded") end if mode.asksheets then ask.sheets = dialog.AddCheckbox("Work on sheets",mode.defsheets) elseif not mode.defsheets then ask.nosheets= dialog.AddLabel("Sheets will be auto excluded") end if mode.askligands then ask.ligands = dialog.AddCheckbox("Work on ligands",mode.defligands) elseif not mode.defligands then ask.noligands= dialog.AddLabel("Ligands will be auto excluded") end if mode.askselected then ask.selected = dialog.AddCheckbox("Work only on selected",mode.defselected) end if mode.asknonselected then ask.nonselected = dialog.AddCheckbox("Work only on nonselected",mode.defnonselected) end if mode.askmutateonly then ask.mutateonly = dialog.AddCheckbox("Work only on mutateonly",mode.defmutateonly) end if mode.askignorelocks then ask.ignorelocks =dialog.AddCheckbox("Dont work on locked ones",true) elseif mode.defignorelocks then ask.nolocks=dialog.AddLabel("Locked ones will be auto excluded") end if mode.askignorefrozen then ask.ignorefrozen = dialog.AddCheckbox("Dont work on frozen",true) elseif mode.defignorefrozen then ask.nofrozen=dialog.AddLabel("Frozen ones will be auto excluded") end if mode.askranges then ask.R1=dialog.AddLabel("Or put in segmentranges. Above selections also count") ask.ranges=dialog.AddTextbox("Ranges","") end ask.OK = dialog.AddButton("OK",1) ask.Cancel = dialog.AddButton("Cancel",0) if dialog.Show(ask) > 0 then -- We start with all the segments including ligands if mode.askloops then mode.defloops=ask.loops.value end if not mode.defloops then result=SegmentSetMinus(result,FindAAtype("L")) end if mode.asksheets then mode.defsheets=ask.sheets.value end if not mode.defsheets then result=SegmentSetMinus(result,FindAAtype("E")) end if mode.askhelixes then mode.defhelixes=ask.helixes.value end if not mode.defhelixes then result=SegmentSetMinus(result,FindAAtype("H")) end if mode.askligands then mode.defligands=ask.ligands.value end if not mode.defligands then result=SegmentSetMinus(result,FindAAtype("M")) end if mode.askignorelocks then mode.defignorelocks=ask.ignorelocks.value end if mode.defignorelocks then result=SegmentSetMinus(result,FindLocked()) end if mode.askignorefrozen then mode.defignorefrozen=ask.ignorefrozen.value end if mode.defignorefrozen then result=SegmentSetMinus(result,FindFrozen()) end if mode.askselected then mode.defselected=ask.selected.value end if mode.defselected then result=SegmentCommSet(result,FindSelected()) end if mode.asknonselected then mode.defnonselected=ask.nonselected.value end if mode.defnonselected then result=SegmentCommSet(result,SegmentInvertSet(FindSelected())) end if mode.askranges and ask.ranges.value ~= "" then local rangetext=ask.ranges.value local function Checknums(nums) -- Now checking if #nums%2 ~= 0 then print("Not an even number of segments found") return false end for i=1,#nums do if nums[i]==0 or nums[i]>structure.GetCount() then print("Number "..nums[i].." is not a segment") return false end end return true end local function ReadSegmentSet(data) local nums = {} local NoNegatives='%d+' -- - is not part of a number local result={} for v in string.gfind(data,NoNegatives) do table.insert(nums, tonumber(v)) end if Checknums(nums) then for i=1,#nums/2 do result[i]={nums[2*i-1],nums[2*i]} end result=SegmentCleanSet(result) else Errfound=true result={} end return result end local rangelist=ReadSegmentSet(rangetext) if not Errfound then result=SegmentCommSet(result,rangelist) end end end until not Errfound return result end -- end of module AskSelections -- Module setsegmentset -- Tvdl, 11-05-2012 Free to use for noncommercial purposes function SetSelection(set) selection.DeselectAll() for i=1,#set do selection.SelectRange(set[i][1],set[i][2]) end end function SelectAround(ss,se,radius,nodeselect) if nodeselect~=true then selection.DeselectAll() end for i=1, segCnt2 do for x=ss,se do if structure.GetDistance(x,i)<radius then selection.Select(i) break end end end end function SetAAtype(set,aa) local saveselected=FindSelected() SetSelection(set) structure.SetSecondaryStructureSelected(aa) SetSelection(saveselected) end Version="1.6.0" function qStab(seg,curbest) SelectAround(seg,seg,12) -- Do not accept qstab losses recentbest.Save() CI(0.1) Wiggle("s",1,nil,true) --shake only selected part if fastQstab==false then CI(0.4) Wiggle("wa",1) CI(1) Wiggle("s",1) end CI(1) Wiggle() recentbest.Restore() end fastQstab=true deltafuze= -1 function QstabFuze(seg,curbest) qStab(seg,curbest) if Score()-bestScore > deltafuze then Fuze() end end function AskMutParams() local ask=dialog.CreateDialog("Tvdl Mutate "..Version) local winfuze=nil local extra=nil save.Quicksave(3) ask.fuze=dialog.AddCheckbox("Fuze best try if a win",false) ask.nogain=dialog.AddCheckbox("Run until no gain",false) ask.nrloop=dialog.AddSlider("Or loopnr",1,1,10,0) ask.qstab=dialog.AddCheckbox("Qstab after each try",false) ask.fastq=dialog.AddCheckbox("If qstab then fast",fastQstab) ask.qfuze=dialog.AddCheckbox("If qstab then fuze if close",false) ask.diff=dialog.AddSlider("Fuze if loss <",deltafuze,-5,5,0) ask.sel=dialog.AddCheckbox("Select where to work",false) ask.OK = dialog.AddButton("OK",1) ask.Cancel = dialog.AddButton("Cancel",0) if dialog.Show(ask) > 0 then if ask.fuze.value then winfuze=Fuze end if ask.qstab.value then if ask.qfuze.value then extra=QstabFuze else extra=qStab end end print("Tvdl Mutate "..Version) local loopnr=ask.nrloop.value if ask.nogain.value then loopnr=nil end fastQstab=ask.fastq.value deltafuze=ask.diff.value if ask.sel.value then SetSelection(AskForSelections("Select where to work on")) MutateSelection(loopnr,winfuze,extra) else MutateAll(loopnr,winfuze,extra) end end end function CleanUp() CI(1) save.Quickload(3) end xpcall(AskMutParams,CleanUp)

Comments


spdenne Lv 1

TvdL Mutate 1.5.0 misses out on a gain
puzzle 691, segment 5 was 60 out of 60 at the end of the first run through
no gain for segment 5 reported
no gain through all of next run including segment 5
script ended with a lower score than I'd gained
restoring best changed segment 5 and restored the 2 missing points