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)