Code
--QuakeR - a randomized Quake
recipeTitle='QuakeR v5.5wmfb '
--[[
Based on "Quake" by Grom
v2.51 -- update 2011-01-15 rav3n_pl
v3.0 -- update 2011-04-18 rav3n_pl
v4.0 -- updated 27 Dec 2014 GaryForbis
v4.5 -- updated 2019-12-30 ZeroLeak7
v5.0 -- updated 2019-12-31
-converted to script v2
-band hydrophobes to beta carbon
-clean up on early exit
-better shake and wiggle ci in Fuze and with mutate now
-updated with a gui
]]
-- variables users probably don't want to play with
USENORMALSCORE = true
InitialScore = 0.0 -- not important: will be reinitialized in InitializePuzzleState( )
StartTime = 0 -- not important: will be reinitialized in InitializePuzzleState( )
CurrentBestScore = 0 -- not important: will be reinitialized in InitializePuzzleState( )
-- Globals
loop_starts = {}
loop_ends = {}
n_loops = 0
n_residues = 0
function residues_range ()
selection.SelectAll()
structure.SetSecondaryStructureSelected("L")
end
function GetLoops ()
within_loop = false
for i = 1, n_residues do
if ( structure.GetSecondaryStructure ( i ) == "L" and structure.IsLocked(i) == false ) then
if ( within_loop == false ) then
-- start of a new loop
within_loop = true
n_loops = n_loops + 1
loop_starts [ n_loops ] = i
end
elseif ( within_loop == true ) then
-- end of a loop
within_loop = false
loop_ends [ n_loops ] = i -1
end
end -- for i
if ( within_loop == true ) then
loop_ends [ n_loops ] = n_residues
end
end
function floor3(x)--cut at 3rd decimal place
return tostring(x-x%0.001)
end
function internalGetScore( wantRB )
if wantRB == nil then wantRB = false end
local s=0.0
if not USENORMALSCORE then
if wantRB then s = recentbest.GetEnergyScore( )
else s=current.GetEnergyScore( )
end
else
if wantRB then s = recentbest.GetScore( )
else s=current.GetScore( )
end
end
return s
end
function getScore( )
return internalGetScore( false )
end
function getRBScore( )
return internalGetScore( true )
end
function SaveBest( )
local score = getScore( )
if score > CurrentBestScore then
print("Gained another "..floor3(score-CurrentBestScore).." points. new Score: "..floor3(score))
CurrentBestScore=score
save.Quicksave(4)
recentbest.Restore()
save.Quicksave(3)
save.Quickload(4)
end
return getScore()-CurrentBestScore
end
function InitializePuzzleState( )
InitialScore = getRBScore( )
CurrentBestScore = InitialScore
StartTime = os.time()
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=getScore()
if how == "s" then structure.ShakeSidechainsAll(1)
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,true,true)
end
if getScore()-sp > minppi then return Wiggle(how, iters, minppi) end
end
end
function qStab()
behavior.SetClashImportance(0.21)
structure.MutateSidechainsSelected(1)
Wiggle("s",1)
if fastQstab==false then
behavior.SetClashImportance(0.4)
Wiggle("wa",1)
behavior.SetClashImportance(1)
Wiggle("s",1)
end
behavior.SetClashImportance(1)
Wiggle()
return SaveBest()
end
function Fuze1(ci1,ci2)
behavior.SetClashImportance(ci1)
Wiggle("s",1)
behavior.SetClashImportance(ci2)
Wiggle("wa",1)
end
function Fuze2(ci1,ci2)
behavior.SetClashImportance(ci1)
Wiggle("wa",1)
behavior.SetClashImportance(1)
Wiggle("wa",1)
behavior.SetClashImportance(ci2)
Wiggle("wa",1)
end
function FuzeEnd()
behavior.SetClashImportance(1)
Wiggle("wa",1)
Wiggle("s",1)
behavior.SetClashImportance(0.9)
structure.MutateSidechainsSelected(1)
behavior.SetClashImportance(0.6)
Wiggle()
behavior.SetClashImportance(1)
Wiggle("wa",1)
SaveBest()
end
function reFuze(scr)
local s=getRBScore()
if s<scr then
recentbest.Restore()
else
scr=s
end
return scr
end
function Fuze()
local scr=getScore()
Fuze1(1,0.6) FuzeEnd()
scr=reFuze(scr)
Fuze2(1,1) SaveBest()
scr=reFuze(scr)
Fuze1(1,0.5) SaveBest()
scr=reFuze(scr)
Fuze2(1,1) FuzeEnd()
scr=reFuze(scr)
Fuze1(1,1) SaveBest()
reFuze(scr)
end
function bandstr(str) --set all band strength
for i=1, band.GetCount() do
band.SetStrength(i, str)
end
end
function calcBandAtom()
bandAtom={}
for x = 1,segCnt do
if (structure.GetAminoAcid(x) == 'g') or not structure.IsHydrophobic(x) then
bandAtom[x] = 2 -- center for Glycine and Hydophiles
elseif x == segCnt then
bandAtom[x] = 6 -- beta carbon for terminal segment
else
bandAtom[x] = 5 -- beta carbon
end
end
end
function QuakeR(ix,iy,ql,rev)
math.randomseed(os.time()) math.random() math.random() math.random()
calcBandAtom()
--freeze.UnfreezeAll()
selection.SelectAll()
StartingScore=getScore()
bestScore=StartingScore
recentbest.Save()
save.Quicksave(4)
print("----------------------------------------------------------------------------")
print("Starting "..recipeTitle..tostring(ql).." passes.")
print("----------------------------------------------------------------------------")
print("Start score: "..floor3(StartingScore))
for x=1, ql do
print("Pass "..tostring(x).." of "..tostring(ql))
local step=math.floor(math.random((iy-ix)/10,((iy-ix)/10)+10))
local step2=math.floor(math.random(((iy-ix)/10)-10,(iy-ix)/10))
band.DeleteAll()
if(rev==true) then
print("----------------------------------------------------------------------------")
print("Bands from segment "..tostring(ix))
print(" of length "..tostring(step2).." every "..tostring(step2).." segments.")
print("----------------------------------------------------------------------------")
print("Pulling..")
for x=ix,iy, step2 do
for y=ix, iy, step2 do
band.AddBetweenSegments(x,y)
end
end
else
print("----------------------------------------------------------------------------")
print("Bands from segment "..tostring(ix))
print(" of length "..tostring(step).." every "..tostring(step).." segments.")
print("----------------------------------------------------------------------------")
print("Pulling..")
for x=ix,iy, step do
for y=ix+step, iy, step do
band.AddBetweenSegments(x,y)
end
end
end
behavior.SetClashImportance(pullingCI)
recentbest.Save()
local gain
for str=minBS,maxBS,0.07 do--search enough band strength to move
bandstr(str)
repeat
structure.WiggleAll(1,true,false)
gain=SaveBest()
if gain > 0 then
recentbest.Restore()
save.Quicksave(4)
end
until gain<=0
break
end
band.DeleteAll()
behavior.SetClashImportance(1)
recentbest.Save() --after pulling
print("Stabilizing...")
if qStab() > doFuze then
print("Fuzing....")
Fuze()
end
gain=SaveBest()
if gain < -0 then save.Quickload(4) end
print("Current score: "..floor3(getScore()).." Total gain: "..floor3(getScore()-StartingScore))
end
print("Total QuakeR gain: "..floor3(getScore()-StartingScore))
return true
end
function GetParameters ()
local dlog = dialog.CreateDialog ( "QuakeR v5 with mutate for binders" )
dlog.iterations = dialog.AddSlider ( "normal iter: " , qLoops , 1 , 1000 , 0 )
dlog.iterationsr = dialog.AddSlider ( "reverse iter: " , qLoops2 , 1 , 1000 , 0 )
dlog.ok = dialog.AddButton ( "OK" , 1 )
dlog.cancel = dialog.AddButton ( "Cancel" , 0 )
if ( dialog.Show ( dlog ) > 0 ) then
qLoops = dlog.iterations.value
qLoops2 = dlog.iterationsr.value
return true
else
return false
end
end
function main ()
if ( GetParameters () == false ) then
return -- graceful exit
end
n_residues = structure.GetCount ()
behavior.SetClashImportance ( 1 )
InitializePuzzleState( )
print("wait! initializing...")
residues_range ()
GetLoops ()
n_loops = #loop_starts
print ( n_loops .. " loops" )
n_loops = #loop_starts
for i = 1 , n_loops do
print ( "Loop " .. i .. " : (" .. loop_starts [ i ] .. "-" .. loop_ends [ i ] .. ")" )
end
local idx_starts = loop_starts[ 1 ]
local idx_ends = loop_ends[ 1 ]
QuakeR(idx_starts, idx_ends, qLoops,false)
print("reverse QuakeR starts:")
QuakeR(idx_ends, idx_starts, qLoops2,true)
CleanUp()
end
function CleanUp(errstr)
undo.SetUndo(true)
if EndCalled then return end -- no infinite recursion please
EndCalled = true
if errstr~=nil then
if string.find ( errstr,"QuakeR Cancelled" )then
print("User cancel")
else
print(errstr)
end
end
behavior.SetClashImportance(1)
band.DeleteAll()
save.Quickload(4)
end
segCnt=structure.GetCount()
while structure.GetSecondaryStructure(segCnt)=="M" do segCnt=segCnt-1 end
--- VVVVVVVVVV OPTIONS
normal=(current.GetExplorationMultiplier()==0)
qLoops=5
qLoops2=5 -- <<<OVER THERE! do more! much more!
minBS=0.3 --starting minimum bands strength
maxBS=1.0 --maximum band strength
pullingCI=1.0 --clash importance while pulling
fastQstab=false --true for 1s1w as stabilize (faster)
doFuze=-10 --run fuze when score after qstabilize is close to best.
xpcall(main,CleanUp)