Code
--Acid Tweaker v2.2.1
--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)
-- managment 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
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()
segStart=1
segEnd=segCount
OriginalFilterSetting = behavior.GetSlowFiltersDisabled() -- new BK 8/4/2013
PROBABLEFILTER=false
--Detect ligands (from Jean-Bob)
function DetectLigand()
local lastSeg=structure.GetCount()
while structure.GetSecondaryStructure(lastSeg)=="M" do
flagligand=true
lastSeg=structure.GetCount()-1 --corrige l'erreur de compte due au ligand-- c'est un duplicat de setlock. A verifier.
segCnt=structure.GetCount()-1
end
indexligand={lastSeg,segEnd}
segEnd=segCount
end
DetectLigand()
function Score()
return current.GetEnergyScore()
end
function ds(val)
if mutate==true then
if PROBABLEFILTER 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 detectfilter()
local descrTxt=puzzle.GetDescription()
if #descrTxt>0 and (descrTxt:find("filter") or descrTxt:find("filters")) then
PROBABLEFILTER=true
end
return
end
detectfilter()
function WiggleSimple(val,how)
if PROBABLEFILTER then behavior.SetSlowFiltersDisabled(true) end-- new BK 8/4/2013, always disable filter here
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
end
if PROBABLEFILTER then behavior.SetSlowFiltersDisabled(true) end-- new BK 8/4/2013, always disable filter here
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 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
--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.WiggleSelected(1,true,true)
WiggleSimple(1,wa) -- new function BK 8/4/2013
CI(1.)
WiggleAT(ss)
WiggleAT(ss,"s",1)
--selection.SelectAll()
CI(.6)
WiggleAT(ss)
CI(1.)
WiggleAT(ss)
recentbest.Restore()
SaveBest()
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()
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(2,s) -- new function BK 8/4/2013
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=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(2,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(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)
WiggleSimple(1,s) -- new function BK 8/4/2013
SelectSphere(i,esfera,true)
CI(1.0)
if (getNear(i)==true) then
wiggle_out(ss)
end
end
end
end
end
-- debugged:
function sidechain_manipulate() -- y a un bug, donne des scores negatifs !
--p("Dernire chance: manipulateur brutal des chaines latrales")
p("Last chance: bruteforce sidechain manipulate")
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(ss) -- ceci peut changer le nombre de rotamers
end
if rotamers > rotamer.GetCount(i) then break end --si nb de rotamer a change
end
end
end
recentbest.Restore()-- car les rotamers ont pu tout casser.
end
end
-- end debugged
--g_segments=g_segments-1 -- uncomment for lingard puzzles only!
--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',
}
--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
sphere_worst=false -- include worst segments in sphere
sphere_worst_value=0
--END TO BE IMPLEMENTED VIA DIALOG BOX
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
s4=Score()
if s4-s3 <0 then recentbest.Restore() end --against the bug !!!
selection.SelectAll() -- or 2 lines in one structure.WiggleAll(4,true,true)
WiggleSimple(4,wa) -- new function BK 8/4/2013
WiggleSimple(2,ws) -- new function BK 8/4/2013
selection.SelectAll()
WiggleSimple(4,wa) -- new function BK 8/4/2013
recentbest.Restore()
s5=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(s5-s1))
p("End score: ",round(s5))
end
esfera=8
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
--segStart=1
--segEnd=structure.GetCount()
fix_band=false -- if you want to try with the worst segments
fast=false
manipulate=true -- test rottamers
recentbest.Save()
ini_score=Score()
print("Acid Tweeker starting at score: "..ini_score)
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.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.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
segStart= dlg.segStart.value
segEnd= dlg.segEnd.value
print("Options:\nfast =",fast,"\nfix_band =",fix_band,"\nmanipulate =",manipulate, "\nrebuild =",rebuild, "\nsegs =",segStart,"-",segEnd)
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