Code
--Acid Tweaker v1.0 by Steven Pletsch
--modded by rav3n_pl ;]
-- modded by BitSpawn, March 2012
-- Best solution in slot 3
-- V1.4: Faster, only best rottamers, only sphere
-- V1.5: New rottamers: tested rottamers near high scores
-- V1.6: Fixed bug with best positions in phase 1
-- V1.70: All segments tested in phase 1.
-- Now backbone doesn't break wiggling with bad scores after shaking (Raven)
-- V1.71: More precise: iters=1 with CI<0, iters=2 with CI=1
-- V1.72: Bands to fix geometry with bad scored segments shaking with CI=0
-- V1.73: Faster: mingain during wiggle proportional to the difference with best score
-- Never more eternal wiggling with bad score
-- V1.74: Bug fixed with variable minppi
-- V1.75: Faster: radius in spheres down to 8 (now in options). Better 8 than 12 in tests.
-- Option to select worst segments only (don't use, usually with no rotts)
-- v1.76: loop 3 -> radius on sphere=12, loop=4 -> rebuild added
-- v1.77: tunned
-- v1.78: bug fixed with best score after rebuild
-- v2.00: LUAV2, thanks Timo
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)
p=print --a short
segCount=structure.GetCount()
function Score()
return current.GetEnergyScore()
end
function ds(val)
if mutate==true then
structure.MutateSidechainsSelected(val+1)
else
structure.ShakeSidechainsSelected(val)
end
end
global_ci=1
function CI(val)
global_ci=val
behavior.SetClashImportance(global_ci)
end
--L47
function Wiggle(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 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()
if how == "s" then ds(1)
elseif how == "wb" then dgwbackbone(val)
elseif how == "ws" then structure.WiggleSelected(val, false, true)
elseif how == "wa" then structure.WiggleSelected(val, true, true)
end
local ep = Score()
local ig=ep-sp
if how~="s" then
if ig > minppi then Wiggle(ss, how, iters, minppi) end
end
end
end
--L74
function SelectSphere(sg, radius,nodeselect)
radius=esfera
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.WiggleAll(1,true,true)
band.DeleteAll()
-- freeze.UnfreezeAll()
end
--L114
function round(x)--cut all afer 3-rd place
return x-x%0.001
end
bestScore=Score()
function SaveBest()
local s=Score()
local g=s-bestScore
if g>0 then
p("Gained another ",round(g)," pts.")
bestScore=s
save.Quicksave(3)
end
end
function usableAA(sn)
local usable=false
---------------------------------------------
if current.GetSegmentEnergyScore(sn)>minimo then
return usable
end
if rebuild==true then
selection.DeselectAll()
selection.Select(sn)
structure.RebuildSelected(2)
usable=true
return usable
end
---------------------------------------------
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
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(ss)
CI(.6)
structure.WiggleAll(1,true,true)
CI(1.)
Wiggle(ss)
Wiggle(ss,"s",1)
---------- selection.SelectAll()
CI(.6)
Wiggle(ss)
CI(1.)
Wiggle(ss)
recentbest.Restore()
SaveBest()
end
function getNear(seg)
if(Score() < g_total_score-1000) then
selection.Deselect(seg)
CI(.75)
ds(1)
structure.WiggleAll(1,false,true)
selection.Select(seg)
CI(1)
end
if(Score() < g_total_score-1000) then
if fix_band==true then
Fix(seg)
else
recentbest.Restore()
SaveBest()
return false
end
end
return true
end
function sidechain_tweak()
p("Pass 1 of 3: Sidechain tweak")
for i=sStart, sEnd do
if usableAA(i) then
selection.DeselectAll()
selection.Select(i)
local ss=Score()
g_total_score = Score()
CI(0)
ds(2)
CI(1.)
p("Try sgmnt ", i)
SelectSphere(i, esfera)
if (getNear(i)==true) then
wiggle_out(ss)
end
end
end
end
function sidechain_tweak_around()
p("Pass 2 of 3: Sidechain tweak around")
for i=sStart, sEnd 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)
CI(1. )
p("Try sgmnt ", i)
SelectSphere(i,esfera)
if(Score() > g_total_score - 30) then
wiggle_out(ss)
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)
SelectSphere(i,esfera,true)
CI(1.0)
if (getNear(i)==true) then
wiggle_out(ss)
end
end
end
end
end
function sidechain_manipulate()
p("Last pass: Brute force sidechain manipulator")
for i=sStart, sEnd do
if usableAA(i) then
selection.DeselectAll()
rotamers = rotamer.GetCount(i)
save.Quicksave(4)
if(rotamers > 1) then
local ss=Score()
p("Sgmnt: ", i," positions: ",rotamers)
for x=1, rotamers do
save.Quickload(4)
g_total_score = Score()
rotamer.SetRotamer(i, x)
CI(1.)
if(Score() > g_total_score - 30) then
SelectSphere(i,esfera)
wiggle_out(ss)
end
end -- for
end
end
end
end
--g_segments=g_segments-1 -- uncomment for lingard puzzles only!
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',
}
--option to easy set start and end of AT work to
ATstart=1 --1st segment
ATend=nil --end of protein if nil
sphere_worst=false -- include worst segments in sphere
sphere_worst_value=0
function Run()
CI(1.00)
recentbest.Restore()
save.Quicksave(3)--in save 3 always best solution. Load in case of crash.
s1=Score()
sidechain_tweak()
s2=Score()
p("Tweak gain: ",round(s2-s1))
sidechain_tweak_around()
s3=Score()
p("Around gain: ",round(s3-s2))
if manipulate==true then
sidechain_manipulate()
end
selection.SelectAll()
structure.WiggleAll(4,true,true)
structure.WiggleAll(2,false,true)
selection.SelectAll()
structure.WiggleAll(4,true,true)
s4=Score()
p("Start score: ",round(s1))
p("Tweak gain: ",round(s2-s1))
p("Around gain: ",round(s3-s2))
p("Manipulate gain: ",round(s4-s3))
p("Total Acid gain: ",round(s4-s1))
p("End score: ",round(s4))
end
esfera=10
minimo=510 -- score for working with worst segments. Don't use, usually worst segs have no rotts
mutate=false -- Don't use, very bad results yet (TODO)
rebuild=true -- for very end in a puzzle, rebuild segment before tweak
sStart=1
sEnd=structure.GetCount()
fix_band=false -- if you want to try with the worst segments
fast=true
manipulate=true -- test rottamers
recentbest.Save()
ini_score=Score()
function GetParam()
local dlg = dialog.CreateDialog("Acid Tweeker 2.00")
dlg.fast = dialog.AddCheckbox("Fast mode (gain 25% less)", true)
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.rebuild = dialog.AddCheckbox("Rebuild before search rotts, for very end only", false)
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
rebuild = dlg.rebuild.value
print("Options:\nfast =",fast,"\nfix_band =",fix_band,"\nmanipulate =",manipulate, "\nrebuild =",rebuild)
return true
end
return false
end
if GetParam()==false then
return
end
while(true) do
Run()
minimo=minimo+0.5
print("Score: ", Score(), " Gain: ", Score()-ini_score)
end
--end