Profile
- Name
- V2 Acid Tweaker R v1.1g
- ID
- 47301
- Shared with
- Public
- Parent
- V2 Acid Tweaker R v1.1f
- Children
- Created on
- November 23, 2013 at 04:16 AM UTC
- Updated on
- November 23, 2013 at 04:16 AM UTC
- Description
Acid Tweaker v1.1g, added AA names, minimum rotamer # option, round down the scores
Best for
Code
-- modified for foldit V2
--Acid Tweaker R v1 - randomatic acid tweaker
-- by rav3n_pl based on
-- Acid Tweaker v1.0 by Steven Pletsch
-- Acid Tweaker v1.1a , added options for the order of segment processing
-- Acid Tweaker v1.1c , added gui, added option to reorder processing, fixed V1 to V2 conversion bug
-- Acid Tweaker v1.1d, added a few more SetNote lines
-- Acid Tweaker v1.1e, modified usableAA function to support puzzles with ligands
-- Acid Tweaker v1.1f, added reverse option, maximum rotamer # option
-- Acid Tweaker v1.1g, 11/19/13 jeff101 adapted V2 Acid Tweaker R v1.1f to
-- add minimum rotamer # option, AA names, rounding down for scores
-- last updated 11/19/13 356pm
--option to easy set start and end of AT work to
ATgui=true -- display gui
ATstart=1 --1st segment
ATend=nil --end of protein if nil
ATpass1=false
ATpass2=false
ATpass3=true
AToption=12 -- set sorting option according to table below
ATalternate=false
ATreverse=false
ATminrotamer=1 -- 1 to 999
ATmaxrotamer=999 -- 1 to 999
-- process segments in order according to 2nd argument where
-- 0 - random
-- 1 - segment number
-- 2 - segment score
-- 3 - clashing score
-- 4 - packing score
-- 5 - hiding score
-- 6 - bonding score
-- 7 - backbone score
-- 8 - sidechain score
-- 9 - reference score
-- 10 - disulfide score
-- 11 - other score
-- 12 - number of sidechain snap locations
function trunc3(res)
return res-res%0.001 -- round res down to nearest 0.001's place
end
function Wiggle(how, iters, minppi)
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=current.GetScore()
if how == "s" then structure.ShakeSidechainsSelected(1)
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
local ep = current.GetScore()
local ig=ep-sp
if how~="s" then
if ig > minppi then Wiggle(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
end
end
function SaveBest()
local s=current.GetScore()
local g=s-bestScore
if g>0 then
print(string.format("Gained another %.3f pts. Current score: %.3f",g,trunc3(s)))
bestScore=s
save.Quicksave(3)
end
end
function usableAA(sn)
local usable=false
if structure.GetSecondaryStructure(sn)=="M" then return false end -- added for puzzles with ligands
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()
behavior.SetClashImportance(.6)
structure.WiggleSelected(1,true,true)
behavior.SetClashImportance(1.)
Wiggle()
Wiggle("s",1)
selection.SelectAll()
behavior.SetClashImportance(.6)
Wiggle()
behavior.SetClashImportance(1.)
Wiggle()
recentbest.Restore()
structure.SetNote(note_number,string.format("(%s) %.3f + Acid Tweaker %.3f (AT(min,max)rotamer=%i,%i)",user.GetPlayerName(),trunc3(AT_starting_score),trunc3(current.GetScore()),ATminrotamer,ATmaxrotamer))
SaveBest()
end
function sidechain_tweak()
print("Pass 1 of 3: Sidechain tweak")
for x=1,#segments do
i=segments[x]
if usableAA(i) then
selection.DeselectAll()
selection.Select(i)
aaname=structure.GetAminoAcid(i)
local ss=current.GetScore()
g_total_score=current.GetScore()
behavior.SetClashImportance(0)
structure.ShakeSidechainsSelected(2)
behavior.SetClashImportance(1.)
if(current.GetScore() > g_total_score -1.) then
recentbest.Restore()
else
print(string.format("Try sgmnt: %s%i %i/%i",aaname,i,x,#segments))
if(current.GetScore() > g_total_score - 30) then
SelectSphere(i, 12)
wiggle_out()
else
SelectSphere(i, 12)
selection.Deselect(i)
behavior.SetClashImportance(.75)
structure.ShakeSidechainsSelected(2)
selection.Select(i)
wiggle_out()
end
end
end
end
end
function sidechain_tweak_around()
print("Pass 2 of 3: Sidechain tweak around")
for x=1,#segments do
i=segments[x]
if usableAA(i) then
selection.DeselectAll()
for n=1, g_segments do
g_score[n] = current.GetSegmentEnergyScore(n)
end
selection.Select(i)
aaname=structure.GetAminoAcid(i)
local ss=current.GetScore()
g_total_score=current.GetScore()
behavior.SetClashImportance(0)
structure.ShakeSidechainsSelected(2)
behavior.SetClashImportance(1.)
if(current.GetScore() > g_total_score -1.) then
recentbest.Restore()
else
print(string.format("Try sgmnt: %s%i %i/%i",aaname,i,x,#segments))
if(current.GetScore() > g_total_score - 30) then
SelectSphere(i,12)
wiggle_out()
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)
behavior.SetClashImportance(0.1)
structure.ShakeSidechainsSelected(2)
SelectSphere(i,12,true)
wiggle_out()
end
end
end
end
end
function sidechain_manipulate()
print("Last pass: Brute force sidechain manipulator")
ATtime=os.time()
for x=1,#segments do
i=segments[x]
if usableAA(i) then
selection.DeselectAll()
rotamers = rotamer.GetCount(i)
aaname=structure.GetAminoAcid(i)
save.Quicksave(4)
if(rotamers > 1) then
local ss=current.GetScore()
-- print(string.format("Sgmnt: %s%i %i/%i positions: %i (%i)",aaname,i,x,#segments,rotamers,os.difftime(os.time(),ATtime)))
print(string.format("Sgmnt: %s%i %i/%i positions: %i (processing positions %i-%i)",aaname,i,x,#segments,rotamers,ATminrotamer,math.min(rotamers,ATmaxrotamer)))
-- below is a 'for x' loop inside another 'for x' loop ... tolerable in LUA ... bad in other languages 11/19/13 jeff101
for x=ATminrotamer,math.min(rotamers,ATmaxrotamer) do
save.Quickload(4)
g_total_score = current.GetScore()
rotamer.SetRotamer(i,x)
behavior.SetClashImportance(1.)
if(current.GetScore() > g_total_score -1.) then
recentbest.Restore()
-- structure.SetNote(note_number,string.format("(%s) %.3f + Acid Tweaker %.3f",user.GetPlayerName(),trunc3(AT_starting_score),trunc3(current.GetScore())))
structure.SetNote(note_number,string.format("(%s) %.3f + Acid Tweaker %.3f (AT(min,max)rotamer=%i,%i)",user.GetPlayerName(),trunc3(AT_starting_score),trunc3(current.GetScore()),ATminrotamer,ATmaxrotamer))
else
if(current.GetScore() > g_total_score - 30) then
SelectSphere(i,12)
wiggle_out()
else
SelectSphere(i,12)
selection.Deselect(i)
behavior.SetClashImportance(.75)
structure.ShakeSidechainsSelected(2)
selection.Select(i)
wiggle_out()
end
end
end
end
end
if os.difftime(os.time(),ATtime) > 600 then -- report the time every 10 minutes
report_time(start_clock,start_time)
ATtime=os.time()
end
end
--structure.SetNote(note_number,string.format("(%s) %.3f + Acid Tweaker %.3f",user.GetPlayerName(),trunc3(AT_starting_score),trunc3(current.GetScore())))
structure.SetNote(note_number,string.format("(%s) %.3f + Acid Tweaker %.3f (AT(min,max)rotamer=%i,%i)",user.GetPlayerName(),trunc3(AT_starting_score),trunc3(current.GetScore()),ATminrotamer,ATmaxrotamer))
end
function sidechain_manipulate2()
print("Last pass: Brute force sidechain manipulator 2")
nrot=ATminrotamer
ATtime=os.time()
repeat
print(string.format(" \nProcessing rotamer position %i",nrot))
max_rotamers=0
for x=1,#segments do
i=segments[x]
if usableAA(i) then
selection.DeselectAll()
rotamers = rotamer.GetCount(i)
aaname=structure.GetAminoAcid(i)
if rotamers>max_rotamers then max_rotamers=rotamers end
save.Quicksave(4)
if(nrot <= rotamers) then
local ss=current.GetScore()
-- print(string.format(" Sgmnt: %s%i %i/%i positions: %i (%i)",aaname,i,x,#segments,rotamers,os.difftime(os.time(),ATtime)))
print(string.format(" Sgmnt: %s%i %i/%i positions: %i",aaname,i,x,#segments,rotamers))
save.Quickload(4)
g_total_score = current.GetScore()
rotamer.SetRotamer(i,nrot)
behavior.SetClashImportance(1.)
if(current.GetScore() > g_total_score -1.) then
recentbest.Restore()
-- structure.SetNote(note_number,string.format("(%s) %.3f + Acid Tweaker %.3f",user.GetPlayerName(),trunc3(AT_starting_score),trunc3(current.GetScore())))
structure.SetNote(note_number,string.format("(%s) %.3f + Acid Tweaker %.3f (AT(min,max)rotamer=%i,%i)",user.GetPlayerName(),trunc3(AT_starting_score),trunc3(current.GetScore()),ATminrotamer,ATmaxrotamer))
else
if(current.GetScore() > g_total_score - 30) then
SelectSphere(i,12)
wiggle_out()
else
SelectSphere(i,12)
selection.Deselect(i)
behavior.SetClashImportance(.75)
structure.ShakeSidechainsSelected(2)
selection.Select(i)
wiggle_out()
end
end
end
end
if os.difftime(os.time(),ATtime) > 600 then -- report the time every 10 minutes
report_time(start_clock,start_time)
ATtime=os.time()
end
end
nrot=nrot+1
until nrot>max_rotamers or nrot>ATmaxrotamer
--structure.SetNote(note_number,string.format("(%s) %.3f + Acid Tweaker %.3f",user.GetPlayerName(),trunc3(AT_starting_score),trunc3(current.GetScore())))
structure.SetNote(note_number,string.format("(%s) %.3f + Acid Tweaker %.3f (AT(min,max)rotamer=%i,%i)",user.GetPlayerName(),trunc3(AT_starting_score),trunc3(current.GetScore()),ATminrotamer,ATmaxrotamer))
end
function get_segment_scores_array(first,last,snap_count)
local array1={}
local seg
local ix,ix2
local attr={"clashing","packing","hiding","bonding","backbone","sidechain","reference","disulfides","other"}
if first==nil then first=1 end
if last==nil then last=structure.GetCount() end
if snap_count==nil then snap_count=false else snap_count=true end
ix2=1
for seg=first,last do
array1[ix2]={}
array1[ix2][1]=seg
array1[ix2][2]=current.GetSegmentEnergyScore(seg)
for ix=1,#attr do
array1[ix2][ix+2]=current.GetSegmentEnergySubscore(seg,attr[ix])
end
if snap_count==true then
array1[ix2][#array1[ix2]+1]=rotamer.GetCount(seg)
end
ix2=ix2+1
end
return array1
end
function sort_by_column(a,b)
if a[sort_column]<b[sort_column] then return true else return false end
end
function Acid(l1,l2,l3,sortidx) -- sortidx begins as AToption
segments={}
if ATend==nil then ATend=g_segments end
for i=ATstart, ATend do
segments[#segments+1]=i
end
if sortidx==nil then sortidx=0 end
if sortidx==0 then
for i=1,#segments do
local r=math.random(#segments)
segments[i],segments[r]=segments[r],segments[i]
end
else
array1=get_segment_scores_array(ATstart,ATend,true)
-- get_segment_scores_array is a function defined above
sort_column=sortidx
table.sort(array1,sort_by_column)
-- sort_by_column is a function (above) that uses the variable sort_column
if ATreverse then
for i=1,#segments do
segments[#segments-i+1]=array1[i][1]
end
else
for i=1,#segments do
segments[i]=array1[i][1]
end
end
end
recentbest.Save()
save.Quicksave(3)--in save 3 always best solution. Load in case of crash.
s1=current.GetScore()
if l1 then sidechain_tweak() end
s2=current.GetScore()
print(string.format("Tweak gain: %.3f",s2-s1))
if l2 then sidechain_tweak_around() end
s3=current.GetScore()
print(string.format("Around gain: %.3f",s3-s2))
if l3 then
if ATalternate then
sidechain_manipulate2()
else
sidechain_manipulate()
end
end
s4=current.GetScore()
print(string.format("Start score: %.3f",trunc3(s1)))
print(string.format("Tweak gain: %.3f",s2-s1))
print(string.format("Tweak gain: %.3f",s2-s1))
print(string.format("Around gain: %.3f",s3-s2))
print(string.format("Manipulate gain: %.3f",s4-s3))
print(string.format("Total Acid gain: %.3f",s4-s1))
print(string.format("End score: %.3f",trunc3(s4)))
end
function report_time(start_clock,start_time,clock_msg,time_msg)
local seconds,minutes,hours,days
if clock_msg==nil then clock_msg="CPU time" end
if time_msg==nil then time_msg="Elasped time" end
print(string.format("%s",os.date()))
days,remainder=math.modf((os.clock()-start_clock)/(24*60*60))
hours,remainder=math.modf(remainder*24)
minutes,remainder=math.modf(remainder*60)
seconds,remainder=math.modf(remainder*60)
print(string.format("%s(%02id:%02ih:%02im:%02is)",clock_msg,days,hours,minutes,seconds))
days,remainder=math.modf(os.difftime(os.time(),start_time)/(24*60*60))
hours,remainder=math.modf(remainder*24)
minutes,remainder=math.modf(remainder*60)
seconds,remainder=math.modf(remainder*60)
print(string.format("%s(%02id:%02ih:%02im:%02is)",time_msg,days,hours,minutes,seconds))
end
function Acid_Tweaker_gui()
ATmenu=dialog.CreateDialog("Acid Tweaker")
ATmenu.pass1=dialog.AddCheckbox("Pass 1",ATpass1)
ATmenu.pass2=dialog.AddCheckbox("Pass 2",ATpass2)
ATmenu.pass3=dialog.AddCheckbox("Pass 3",ATpass3)
ATmenu.option=dialog.AddSlider("Option",AToption,0,12,0)
ATmenu.alternate=dialog.AddCheckbox("Alternate",ATalternate)
ATmenu.reverse=dialog.AddCheckbox("Reverse",ATreverse)
ATmenu.start=dialog.AddTextbox("First seg",ATstart)
if ATend==nil then ATend=structure.GetCount() end
ATmenu.endx=dialog.AddTextbox("Last seg",ATend)
ATmenu.minrotamer=dialog.AddTextbox("Min rotamer #",ATminrotamer)
ATmenu.maxrotamer=dialog.AddTextbox("Max rotamer #",ATmaxrotamer)
ATmenu.run=dialog.AddButton("Run",1)
rc=dialog.Show(ATmenu)
if rc==1 then
ATpass1=ATmenu.pass1.value
ATpass2=ATmenu.pass2.value
ATpass3=ATmenu.pass3.value
AToption=ATmenu.option.value
ATalternate=ATmenu.alternate.value
ATreverse=ATmenu.reverse.value
ATstart=tonumber(ATmenu.start.value)
ATend=tonumber(ATmenu.endx.value)
ATminrotamer=tonumber(ATmenu.minrotamer.value)
ATmaxrotamer=tonumber(ATmenu.maxrotamer.value)
if ATmaxrotamer<1 or ATmaxrotamer>999 then ATmaxrotamer=999 end
if ATminrotamer<1 then ATminrotamer=1 end
if ATminrotamer>ATmaxrotamer then ATminrotamer=ATmaxrotamer end
-- print(string.format("Just got inputs AT(min,max)rotamer=%i,%i.",ATminrotamer,ATmaxrotamer))
end
end
--------------VV options below
--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',
}
note_number=structure.GetCount()
for seg=structure.GetCount(),1,-1 do
if structure.GetNote(seg)~="" then break end
note_number=seg
end
print(string.format("Recording Acid Tweaker results in Note for segment %i",note_number))
AT_starting_score=current.GetScore()
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)
if ATgui then Acid_Tweaker_gui() end
segCount=structure.GetCount()
bestScore=current.GetScore()
start_clock=os.clock()
start_time=os.time()
print('V2 Acid Tweaker R v1.1g')
print(' doing puzzle '..puzzle.GetName())
print(' with puzzle ID '..puzzle.GetPuzzleID()..', '..segCount..' segments,')
print(' ATpass1-3='..tostring(ATpass1)..' '..tostring(ATpass2)..' '..tostring(ATpass3)..',') -- use tostring to print booleans as strings
print(' AToption='..tostring(AToption)..', ATalternate='..tostring(ATalternate)..', ATreverse='..tostring(ATreverse)..',')
print(' ATstart-ATend='..ATstart..'-'..ATend..',')
print('and AT(min,max)rotamer='..ATminrotamer..','..ATmaxrotamer..'.\n ')
print(string.format("Initial score: %.3f (%s)",trunc3(current.GetScore()),os.date()))
Acid(ATpass1,ATpass2,ATpass3,AToption) --all 3 passes
print("--------")
report_time(start_clock,start_time)
print("--------")