Icon representing a recipe

Recipe: Datacute Compressor v1.5

created by spdenne

Profile


Name
Datacute Compressor v1.5
ID
103405
Shared with
Public
Parent
Datacute Compressor v1.5
Children
Created on
April 14, 2020 at 04:52 AM UTC
Updated on
April 14, 2020 at 04:52 AM UTC
Description

Lua V2 version of Rav3n_pl's compressor and derivatives, including mutating options. Only bands unlocked segments. Retains existing bands.

Best for


Code


--[[ Datacute Conversion of Rav3n_pl Compressor v2 trying to compress/decompress protein accepting loss of points between pulls Altered by Timo van der Laan to only band to mutatable segments Rewritten by Datacute in Lua Version 2, to add options dialogs, and incorporate mutating Quick Load slots: 3: best score found so far, or starting location if no gain has been found. 4: temporary use while saving best, and while fuzing 5: attempting to record previous best for when repeating last bands gives no gain 7: second best score found so far ]]-- local ver = "v1.5" normal= (current.GetExplorationMultiplier() == 0) print("Datacute Compressor "..ver) print("Very heavily based on various Rav3n_pl Compressors") CI=behavior.SetClashImportance segCnt=structure.GetCount() segCnt2=segCnt while structure.GetSecondaryStructure(segCnt2)=="M" do segCnt=segCnt-1 end 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 if total < 0 then return total/pose.GetExplorationMultiplier() else return total*pose.GetExplorationMultiplier() end 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 round(x)--cut all after 3-rd place return x-x%0.001 end function Wiggle(how, iters, minppi) --score conditioned recursive wiggle/shake if how==nil then how="wa" end if iters==nil then iters=6 end if minppi==nil then minppi=0.1 end if iters>0 then iters=iters-1 local sp=Score() if how == "s" then structure.ShakeSidechainsAll(1) -- todo select & shake less? 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) end if Score()-sp > minppi then return Wiggle(how, iters, minppi) end end end function AllLoop() --turning entire structure to loops local ok=false for i=1, segCnt do local s=structure.GetSecondaryStructure(i) if s~="L" then save.SaveSecondaryStructure() ok=true break end end if ok then selection.SelectAll() structure.SetSecondaryStructureSelected("L") end end function qStab() CI(0.1) Wiggle("s",1) selection.SelectAll() if fastQstab==false then CI(0.4) Wiggle("wa",1) CI(1) Wiggle("s",1) end CI(1) Wiggle() end function FuzeEnd() CI(1) Wiggle("wa",1) Wiggle("s",1) Wiggle() SaveBest() end function Fuze1(ci1,ci2) CI(ci1) Wiggle("s",1) CI(ci2) Wiggle("wa",1) end function Fuze2(ci1,ci2) CI(ci1) Wiggle("wa",1) CI(1) Wiggle("wa",1) CI(ci2) Wiggle("wa",1) 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) local scr=Score() save.Quicksave(slot) selection.SelectAll() Fuze1(0.3,0.6) FuzeEnd() scr=reFuze(scr,slot) Fuze2(0.3,1) SaveBest() scr=reFuze(scr,slot) Fuze1(0.05,1) SaveBest() scr=reFuze(scr,slot) Fuze2(0.7,0.5) FuzeEnd() scr=reFuze(scr,slot) Fuze1(0.07,1) SaveBest() reFuze(scr,slot) end bestScore=Score() function SaveBest() local g=Score()-bestScore if g>0 then print("Gained another "..round(g).." pts.") bestScore=Score() save.Quicksave(3) end end function MakeBands(num) local done=false local s1=math.random(segCnt) local s2=math.random(segCnt) if s1>s2 then s1,s2=s2,s1 end local d=structure.GetDistance(s1,s2) if s2-s1>=minSkip and d>=minDist and d<=maxDist then done=true end if (done and #useRegions>0) then done=false for a=1,#useRegions do local ss=useRegions[a][1] local se=useRegions[a][2] if (s1>=ss and s1<=se) or (s2>=ss and s2<=se) then done=true break end end end local ss1=structure.GetSecondaryStructure(s1) local ss2=structure.GetSecondaryStructure(s2) if (done and noLoops) then if ss1=="L" or ss2=="L" then done=false end end if (done and bandStructure) then if ss1=="L" and ss2=="L" then done=false end end if (done and S2H) then if (ss1=="E" or ss2=="E") and (ss1=="H" or ss2=="H") and (ss1~=ss2) then done=true else done=false end end if done then num=num-1 mkBand(s1,s2) bands[#bands+1]={s1,s2} end if num>0 then return MakeBands(num) end --tail call end function mkBand(s1,s2) band.AddBetweenSegments(s1,s2) local len=structure.GetDistance(s1,s2) if decomp==true then len=len+compressFrac else len=len-compressFrac end if len<3.5 then len=3.5 end if len>20 then len=20 end band.SetGoalLength(band.GetCount(),len) end n_existing_bands=band.GetCount() bands={} function Repeat_bands(bands) my_band_delete() for i=1,#bands do local s1=bands[i][1] local s2=bands[i][2] mkBand(s1,s2) end end function Bandstr(str) --set all band strengt if str<0.1 then str=0.1 end if str>10 then str=10 end for i=n_existing_bands + 1, band.GetCount() do band.SetStrength(i, str) end end function my_band_delete() n_all_bands=band.GetCount() if delete_existing_bands==true then band.DeleteAll() n_existing_bands=0 else --p(n_all_bands,",",n_existing_bands) while n_all_bands>n_existing_bands do band.Delete(n_all_bands) n_all_bands=band.GetCount() end end end function SaveRB(slot) save.Quicksave(slot) recentbest.Restore() SaveBest() save.Quickload(slot) end sscore=Score() --starting score function Compressor() if mutate then FindMutable() end FindUnlocked() if n_existing_bands>0 and delete_existing_bands==true then band.DeleteAll() n_existing_bands=0 end if normal==false then print("Using exploration options") end if decomp==true then minDist=7 maxDist=20-compressFrac else minDist=10 --minimum spatial distance between banding segments maxDist=20+compressFrac --maximum spatial distance between banding segments end if allLoop then AllLoop() end save.Quicksave(3) save.Quicksave(7) --save state for losing badOnes=0 recentbest.Save() local best=false for i=1,numTries do -- TODO take off 8000, and range limit loss loss=Score()*percLoss/100 --pulling till we lost some points my_band_delete() local repeatingBest=false if best==true and repeatGood==true then print("Repeating last bands.") if modulator==true then --switch decomp= not decomp end Repeat_bands(bands) repeatingBest=true save.Quicksave(5) else bands={} MakeBands(numBands) end local ls=Score() print("Loop "..i.." of "..numTries.." started. Current score: "..round(ls)) CI(pullingCI) selection.SelectAll() recentbest.Save() if slowBands then -- TODO check lastBands usage for str=lastBands,bandStr,0.07 do--search enough band strength to move if normal==true then recentbest.Restore() end--because sometimes it makes points during pull :D local ss=Score() Bandstr(str) Wiggle("wb",1) if ss-Score()>loss then lastBands=str-0.1 break end end else Bandstr(bandStr) Wiggle("wb",1) end if mutate then structure.MutateSidechainsAll(1) end SaveRB(4) --because sometimes it missing fractions my_band_delete() qStab() SaveBest() if useFuze and Score()> (bestScore-fuzeScore) then Fuze(4) end if maxLoss>0 then if Score()>bestScore-maxLoss then save.Quicksave(7) --save actual "best" solution else if repeatingBest then save.Quickload(5) else badOnes=badOnes+1 if badOnes >=reloadBest then badOnes=0 save.Quickload(3) else save.Quickload(7) --load "second best" end end end else save.Quickload(3) end local es=Score() if es>ls then best=true else best=false end --and es==bestScore --repeating all bands making points print("Loop "..i.." gain "..round(es-ls).." ;total gain "..round(bestScore-sscore)) if modulator==true then --switch decomp= not decomp end end cleanup() print("Total gain: "..round(Score()-sscore)) end useRegions={ --set regions that have to be used in all bands --{1,20} --{25,55} --{100,210} } function FindMutable() for i=1,segCnt do if structure.IsMutable(i) then return end end mutate = false end function FindUnlocked() local unlocked={} print("Finding Unlocked Segments") for i=1,segCnt do if not structure.IsLocked(i) then if mutableRegions then if structure.IsMutable(i) then unlocked[#unlocked+1]=i end else unlocked[#unlocked+1]=i end end end print(#unlocked.." unlocked found") if #unlocked > 0 then local inregion=false local segfirst=0 local seglast=0 for i=1,#unlocked do if not inregion then segfirst=unlocked[i] seglast=unlocked[i] inregion=true elseif seglast+1==unlocked[i] then seglast=unlocked[i] else useRegions[#useRegions+1]={segfirst,seglast} segfirst=unlocked[i] seglast=unlocked[i] end end useRegions[#useRegions+1]={segfirst,seglast} end end function SetDefaultOptions() --brow42's seed method seed = (os.time() * 5779) % 10000 numTries=9999 numBands=8 --how many bands use at once minSkip=15 --minimum segment distance between banded segments compressFrac=5 --make bands shorter by that much points fastQstab=true --only 1 shake and 1 wiggle when true useFuze=true -- use Fuze after qStab fuzeScore=-1 --how close we have to be to run Fuze allLoop=true --work in all-loop mode. sometimes work better than structure mode :) S2H=false --all bands are between sheets and helixes bandStructure=false --all bands have at least one end on structure (not loop) noLoops=false --band can't have any end on loop mutate=true --all bands have at least one end on a mutable segment mutableRegions=false --all bands have at least one end on a mutable segment lastBands=0.3 --starting band str bandStr=1.0 -- max band strength slowBands=true --bands strength are raised few times till score drops by % percLoss=1 --pulling stops when score drops by that percent (ie 2=200pts when 10k pts) repeatGood=false --repeating good bands pullingCI=0.67 --clash importance during pull maxLoss=30 --maximum acceptable LOSS after pull/stabilize reloadBest=5 --reload best solution after that many worst ones decomp=false --true --true for DeCompression instead of compression modulator=false --true --changing compression/decompression each loop delete_existing_bands = false -- set to true when you want to delete any existing bands at starttime, -- if you set it to false, the bands aren't deleted and aren't changed -- the bands will stay enabled or disabled like at starttime of script end --http://fold.it/portal/recipe/17939 Team AD - Rav3n_pl Compressor v1.9 --Author: Rav3n_pl function SetPreset17939Options() allLoop=false numBands=13 minSkip=15 compressFrac=4 --minDist=10 --maxDist=24 fastQstab=false --usePF=true --useBF=false2 lastBands=0.4 bandStr=1.0 slowBands=true percLoss=2 repeatGood=true pullingCI=0.9 maxLoss=50 reloadBest=5 end --http://fold.it/portal/recipe/26524 Rav3n_pl Compressor v2.0 --Author: Rav3n_pl function SetPreset26524Options() allLoop=false numBands=9 minSkip=15 compressFrac=4 fastQstab=false lastBands=0.3 bandStr=1.0 slowBands=true percLoss=2 repeatGood=true pullingCI=0.9 maxLoss=50 reloadBest=5 end --http://fold.it/portal/recipe/27351 Rav3n_pl Compressor v2.2 loss --Author: Rav3n_pl function SetPreset27351Options() allLoop=true numBands=8 minSkip=15 compressFrac=5 --minDist=7 fastQstab=true lastBands=0.3 bandStr=1.0 slowBands=true percLoss=1 repeatGood=false pullingCI=1 maxLoss=30 reloadBest=5 end --http://fold.it/portal/recipe/31617 Rav3n_pl Compressor v2.2 loss Modified --Author: Mike Cassidy function SetPreset31617Options() allLoop=true numBands=21 minSkip=11 compressFrac=7 --minDist=7 fastQstab=true lastBands=0.3 bandStr=1.0 slowBands=true percLoss=2.8 repeatGood=true pullingCI=1 maxLoss=30 reloadBest=5 end --http://fold.it/portal/recipe/38926 Rav3n_pl Compressor v5 mutate --Author: TheGUmmer function SetPreset38926Options() allLoop=true numBands=30 minSkip=5 compressFrac=11 --minDist=3 fastQstab=true lastBands=0.6 bandStr=1.8 slowBands=true percLoss=1.9 repeatGood=true pullingCI=0.67 maxLoss=30 reloadBest=5 end function ChangeCompressorOptions() local opt = dialog.CreateDialog("Compressor Options") opt.seed = dialog.AddTextbox("Random Seed", seed) opt.numTries = dialog.AddSlider("Number of Loops", numTries, 1, 9999, 0) opt.minSkip = dialog.AddSlider("Min. Skip", minSkip, 2, 30, 0) --minimum segment distance between banded segments opt.slowBands = dialog.AddCheckbox("Slowly raise band strengths", slowBands) --bands strength are raised few times till score drops by % opt.lastBands = dialog.AddSlider("Start Strength", lastBands, 0, 10, 2) --starting band str opt.bandStr = dialog.AddSlider("Max Strength", bandStr, 0, 10, 2) --max band strength opt.decomp = dialog.AddCheckbox("Decompression instead of compression", decomp) opt.allLoop = dialog.AddCheckbox("All-Loop Mode",allLoop) --work in all-loop mode. sometimes work better than structure mode :) opt.delete_bands = dialog.AddCheckbox("Delete Existing Bands",delete_existing_bands) opt.S2H = dialog.AddCheckbox("Only band sheets to helixes", S2H) --all bands are between sheets and helixes opt.bandStructure = dialog.AddCheckbox("Always band to structure (not loop)", bandStructure) --all bands have at least one end on structure (not loop) opt.noLoops = dialog.AddCheckbox("Band between structures (no loops)", noLoops) --band can't have any end on loop opt.mutableRegions= dialog.AddCheckbox("Band mutable regions", mutableRegions) --all bands have at least one end on a mutable segment opt.mutate = dialog.AddCheckbox("Mutate", mutate) opt.fastQstab = dialog.AddCheckbox("Fast qStab", fastQstab) --only 1 shake and 1 wiggle when true opt.useFuze = dialog.AddCheckbox("Use Fuze after qStab", useFuze) -- use Fuze after qStab opt.fuzeScoreLbl = dialog.AddLabel("How close we have to be to run Fuze") opt.fuzeScore = dialog.AddSlider("Score Diff.", fuzeScore, -10, 100, 0) --how close we have to be to run Fuze opt.repeatGood = dialog.AddCheckbox("Repeat good bands", repeatGood) opt.maxLoss = dialog.AddSlider("Max Loss", maxLoss, 0, 1000, 0) --maximum acceptable LOSS after pull/stabilize opt.reloadBest = dialog.AddSlider("Max Losses", reloadBest, 1, 100, 0) --reload best solution after that many worst ones opt.OK = dialog.AddButton("OK",1) opt.Cancel = dialog.AddButton("Cancel",0) if dialog.Show(opt) <= 0 then return end seed=opt.seed.value numTries=opt.numTries.value minSkip=opt.minSkip.value slowBands=opt.slowBands.value lastBands=opt.lastBands.value bandStr=opt.bandStr.value decomp=opt.decomp.value allLoop=opt.allLoop.value delete_existing_bands=opt.delete_bands.value S2H=opt.S2H.value bandStructure=opt.bandStructure.value noLoops=opt.noLoops.value mutableRegions=opt.mutableRegions.value mutate=opt.mutate.value fastQstab=opt.fastQstab.value useFuze=opt.useFuze.value fuzeScore=opt.fuzeScore.value repeatGood=opt.repeatGood.value maxLoss=opt.maxLoss.value reloadBest=opt.reloadBest.value end function SelectCompressorPresets() local opt = dialog.CreateDialog("Compressor Presets") opt.r17939 = dialog.AddButton("1.9",1) opt.r26524 = dialog.AddButton("2.0",2) opt.r27351 = dialog.AddButton("2.2 loss",3) opt.r31617 = dialog.AddButton("Mike's",4) opt.r38926 = dialog.AddButton("GU's",5) opt.Cancel = dialog.AddButton("Cancel",0) local btn = dialog.Show(opt) if btn == 1 then SetPreset17939Options() elseif btn == 2 then SetPreset26524Options() elseif btn == 3 then SetPreset27351Options() elseif btn == 4 then SetPreset31617Options() elseif btn == 5 then SetPreset38926Options() end end function ChangeOptions() local opt = dialog.CreateDialog("Compressor "..ver) opt.numBands = dialog.AddSlider("Num. Bands", numBands, 0, 60, 0) --how many bands use at once opt.compressFrac = dialog.AddSlider("Length Change", compressFrac, 0, 15, 2) --make bands shorter by that much points opt.percLoss = dialog.AddSlider("Percent Loss", percLoss, 0, 10, 2) --pulling stops when score drops by that percent (ie 2=200pts when 10k pts) opt.pullingCI = dialog.AddSlider("Pulling CI", pullingCI, 0, 1, 2) --clash importance during pull opt.modulator = dialog.AddCheckbox("Modulator - switch Compression / Decompression", modulator) opt.Start = dialog.AddButton("Start",1) opt.ChangeOptions = dialog.AddButton("Options",2) opt.SelectPresets = dialog.AddButton("Presets",3) opt.Cancel = dialog.AddButton("Cancel",0) local btn = 0 while btn ~= 1 do btn = dialog.Show(opt) numBands=opt.numBands.value compressFrac=opt.compressFrac.value percLoss=opt.percLoss.value pullingCI=opt.pullingCI.value modulator=opt.modulator.value if btn <= 0 then error("Cancelled") elseif btn == 2 then ChangeCompressorOptions() elseif btn == 3 then SelectCompressorPresets() end end end function ReportOptions() print("+--- Selected Options ---+") print("Number of Bands:", numBands) print("Compression Fraction:", compressFrac) print("Percent Loss:", percLoss) print("Pulling CI:", pullingCI) print("Modulator:", modulator) print("+--- Other Options ---+") print("Random Seed:", seed) print("Minimum Segment Distance:", minSkip) print("Slowly raise band strengths:", slowBands) print("Start Strength:", lastBands) print("Max Strength:", bandStr) print("Decompression instead of compression:", decomp) print("All-Loop Mode:", allLoop) print("Only band sheets to helixes:", S2H) print("Always band to structure (not loop):", bandStructure) print("Band between structures (no loops):", noLoops) print("Band mutable regions:", mutableRegions) print("Mutate:", mutate) print("Fast qStab:", fastQstab) print("Use Fuze:", useFuze) print("Fuze Score Diff:", fuzeScore) print("Repeat good bands:", repeatGood) print("Max Loss:", maxLoss) print("Max Losses:", reloadBest) print("+--- --- ---+") end SetDefaultOptions() ChangeOptions() ReportOptions() math.randomseed(seed) function cleanup(err) print("Setting Clashing Importance to 1.0") behavior.SetClashImportance(1.00) print("Loading best solution from script") save.Quickload(3) if allLoop then print("Restoring secondary structures") save.LoadSecondaryStructure() end print(err) end xpcall(Compressor, cleanup)

Comments