Code
--BK 08/02/2014 hard wiggle 10 iter, smaller minppi and bigger fall appart threshold
--BK 1/3/2014 idea jobo0502, made recursive + added different lengths
--ver 2.2 BK 3/3/2014 adding deepZones where exceeded threshold
--ver 2.3 added cuts, deleting ideal zones, 05/03/2014 ToDo: deleting ideal subzones
--ver 2.4 added verydeep (comes also quicklier)
--ver 2.5 added repeat success 21/04/2014
--ver 2.6: still to do: delete subzones 29/04/2014
--ver 2.7: revers order from lenght 3 to 1
--ver 2.7.1: added loop info following jeff101
--ver 2.7.2 : debug
recipename="Deep Idealize 2.7.2"
kFallApartThreshold = 1000 -- If Idealize results in a loss greater than this, skip the subsequent wiggle as the protein has probably exploded
kMaxIterations = 10 -- Sanity check for the new wiggle loop
FromLength=3 --length of the idealize zones, if reverse order, check delete options table first
ToLength=1 --all possible length from all starts will be tested !
n_residues = 0
ss_starts = {} -- table with all starts (permanent or decreasing)
ss_ends = {} -- table with the corresponding ends (permanent or decreasing)
ss_startsWorst={} -- worst zones (reinitialized at each loop)
ss_endsWorst= {} -- worst zones ends (reinitialized at each loop)
kOriginalStructureOrNewBest = 8 -- slot number to retrieve best
--new 05/03/2014
sphere = {}
kSphereRadius = 10
allowcuts=true
verydeep=false -- 09/04/2014
iminppi=1 -- 21/04/2014 repeat same zone if gain is more than this
behavior.SetClashImportance ( 1 )
-- Handy shorts module from tvdl 03/02/2014
normal= (current.GetExplorationMultiplier() == 0)
segCnt=structure.GetCount()
segCnt2=segCnt
while structure.GetSecondaryStructure(segCnt2)=="M" do segCnt2=segCnt2-1 end
-- end Handy shorts module
n_residues=segCnt2
function r3 ( i )
-- printing convenience
return i - i % 0.001
end
function GetScore ()
score = current.GetEnergyScore ()
return score
end
function get_structures ( starts , ends )
print("Adding entire secondary structures")
curr_type = 'x'
local loop1=0
for i = 1, n_residues do
if not structure.IsLocked(i) and not freeze.IsFrozen(i) then -- New 01/09/2014
ss_type = structure.GetSecondaryStructure ( i )
loop1=loop1+1
if ( ss_type ~= curr_type ) then
-- start of a new struct
curr_type = ss_type
starts [ #starts + 1 ] = i
if ( loop1 > 1 ) then
ends [ #ends + 1 ] = i -1
end
end
end
end -- for i
ends [ #ends + 1 ] = n_residues
end
function getStartSeg(starts , ends, length) -- BK 1/03/2014
print("Adding all possible zones of length ",length)
for j= 1, length do -- all possible starts for this length
for i = j, n_residues-length+1, length do -- first list of successive zones of this length
if not structure.IsLocked(i) and not freeze.IsFrozen(i) then -- New 01/09/2014
starts [ #starts + 1 ] = i -- note: first start was initialized in get_structure()
ends [ #ends + 1 ] = i+length-1 -- it's the end of this start just above
end
end -- for i
end --for j
end
function Construct_Zones() --constructing a long list of zones to be idealized
get_structures ( ss_starts , ss_ends ) -- classic idealize per entire SS zones
local step=1
if FromLength>ToLength then step=-1 end
for length=FromLength, ToLength, step do
getStartSeg(ss_starts , ss_ends,length) --BK 1/03/2014 adds to existing starts list
end
end
function DeleteFromTable(table1, i) -- delete i from table1 NEW BK 05/03/2014
for j=i, #table1-1 do
table1 [ i ]=table1 [ i+1 ]
end
table1 [ #table1]=nil -- to try to reduce length of the table 05/03/2014
-- will give nil for table1 [#table1], this means that latest will be deleted
end
function Wiggle ( step , threshold )
n_it = 0
new_score = GetScore ()
repeat
prev_score = new_score
structure.WiggleSelected ( step )
new_score = GetScore ()
n_it = n_it + 1
until ( ( math.abs ( new_score - prev_score ) < threshold ) or ( n_it > kMaxIterations ) )
end
function quickfixwiggle() -- 09/04/2014
local ci=0.0625
for i=1, 4 do
ci=ci*2
--for ci in {0.01,0.1,0.25,0.5,0.8,0.99,1} do
--print("DEBUG",ci)
behavior.SetClashImportance ( ci)
structure.WiggleSelected (1)
end
end
function SphereSelect ( start_idx , end_idx ) -- new 05/03/2014
for i = 1 , n_residues do
sphere [ i ] = false
end
for i = 1 , n_residues do
for j = start_idx , end_idx do
if ( structure.GetDistance ( i , j ) < kSphereRadius ) then
sphere [ i ] = true
end
end
end
selection.DeselectAll ()
for i = 1 , n_residues do
if ( sphere [ i ] == true ) then
selection.Select ( i )
end
end
end
function Idealize_Zones(ss_starts,ss_ends) --03/03/2014, 05/03/2014-- hard on 1 segstarts collection
local start_loop_score = GetScore ()
local startsWorst={} -- reinitialized at each loop
local endsWorst={} -- reinitialized at each loop
for i = 1 , #ss_starts do
if ss_starts [ i ]== nil then print("Start is nil") break end --11/04/2014 to protect the end if i deletes thinks in table
save.Quickload ( kOriginalStructureOrNewBest )
selection.DeselectAll ()
selection.SelectRange ( ss_starts [ i ] , ss_ends [ i ] )
print ( "Idealizing " .. ss_starts [ i ] .. "-" .. ss_ends [ i ] )
--new 2.3, 05/03/2014
if allowcuts then
if ( ss_starts [ i ] > 1 ) then
structure.InsertCut ( ss_starts [ i ] )
end
if ( ss_ends [ i ] < n_residues ) then
structure.InsertCut ( ss_ends [ i ])
end
end
--end new
--local scorebefore=GetScore () -- DEBUG
structure.IdealizeSelected ()
--if scorebefore==GetScore () then print("Ideal") end -- DEBUG
--new 2.3, 05/03/2014
if allowcuts then
if ( ss_starts [ i ] > 1 ) then
structure.DeleteCut ( ss_starts [ i ] )
end
if ( ss_ends [ i ] < n_residues ) then
structure.DeleteCut ( ss_ends [ i ])
end
end
--end new
SphereSelect ( ss_starts [ i ] , ss_ends [ i ] )
--structure.WiggleSelected ( 12 ) -- NO ! to do only where it was unideal
score = GetScore ()
if ( ( curr_best_score - score ) > kFallApartThreshold ) then -- build worst list, wiggle good zone
print ( "Loss exceeded threshold" )
startsWorst [ #startsWorst + 1 ] = ss_starts [ i ] -- note: first start was initialized in get_structure()
endsWorst [ #endsWorst + 1 ] = ss_ends [ i ] -- it's the end of this start just above
elseif ( math.abs ( score - curr_best_score ) > 0.001 ) then -- only if there was some change
if verydeep then
quickfixwiggle()
end
selection.SelectAll ()
Wiggle ( 10 , 0.01 )
score = GetScore ()
if ( score > curr_best_score ) then -- if improvement
local improvement=score - curr_best_score -- 21/04/2014
curr_best_score = score
save.Quicksave ( kOriginalStructureOrNewBest )
if improvement>iminppi then i=i-1 --21/04/2014 repeat same
print ( "Improvement to : " .. r3 ( curr_best_score ).." Repeat")
else
print ( "Improvement to : " .. r3 ( curr_best_score ))
end
end
else -- no change means it's ideal. Definitively delete the corresponding zones (and subzones) here. 05/03/2014
--print("old table lenght= ",#ss_starts)
print("Ideal. Deleting this zone from target table")
local ideallenght=ss_ends [ i ]-ss_starts [ i ] -- 11/04/20014
local startidealzone=ss_starts [ i ] -- 11/04/20014
local stopidealzone=ss_ends [ i ] -- 11/04/20014
--for j = startidealzone , stopidealzone do -- 11/04/20014 delete from all subzones after i BUG
DeleteFromTable(ss_starts, i)
DeleteFromTable(ss_ends, i)
--end
print("new table lenght= ",#ss_starts)
end
end
ss_startsWorst=startsWorst -- paste local worst to global table
ss_endsWorst=endsWorst --corresponding bad ends
save.Quickload ( kOriginalStructureOrNewBest )
local stop_loop_score = GetScore ()
gainloop=stop_loop_score-start_loop_score -- global variable initialized on each loop for long run decisions
print ("All zones completed. Loop gain= ", r3(gainloop), "Total gain: ",r3(stop_loop_score-ScriptStartScore))
print("-------------------------------")
end
function Long_Run()
gaingen=ScriptStartScore -- list of gain each generation, for jeff101
repeat
local loopmain=0
repeat
loopmain= loopmain+1
print("Loop "..loopmain)
Idealize_Zones(ss_starts,ss_ends) -- first run on all
if gainloop<5 then --try bruteforce unless gain is huge (then loops everything again)
print("Idealizing Worst zones")
verydeep=true --09/04/2014
iminppi=iminppi/100 --21/04/2014
kFallApartThreshold=kFallApartThreshold*10
Idealize_Zones(ss_startsWorst,ss_endsWorst)
kFallApartThreshold=kFallApartThreshold/4 -- next we'll try again with all zones, higher threshold
verydeep=false --09/04/2014
iminppi=iminppi*100 --21/04/2014 recover normal value
end
print("------------------------------")
until gainloop< 4*loopmain -- obliged increasing return to avoid too long run
if allowcuts then allowcuts=false else allowcuts=true print("Changing cut attitude") end -- then trying other strategy
if gainloop<1 then verydeep=true print("Last chance: very deep") end -- 09/04/2014
ScriptStopScore=GetScore ()
Scriptgain=ScriptStopScore-ScriptStartScore
formerScore=scoreNow
scoreNow=ScriptStopScore
GainThisGen=scoreNow-formerScore
print("Deep Idealize Gain= ",r3(Scriptgain))
-- for jeff101
gaingen=gaingen.." + " round3(GainThisGen)
gaingen2print=gaingen.." = " ..round3(scoreNow)
print(gaingen2print)
print("Generation: ".. loopmain..", score: "..round3(scoreNow)..", gain: "..round3(Scriptgain).." ("..os.date()..")")
print("#######################")
until loopmain> 3 and gainloop<0.001 -- finally stops if too little return (can even stop on second run)
print("Unable to find more gain")
end
function main ()
print (recipename)
print(os.date())
curr_best_score = GetScore ()
ScriptStartScore=GetScore ()
scoreNow=ScriptStartScore -- init
print ( "Init score : " .. r3 ( curr_best_score ) )
save.Quicksave ( kOriginalStructureOrNewBest )
--n_residues = structure.GetCount ()
--behavior.SetClashImportance ( 1 )
print("Building zone list")
Construct_Zones() --constructing a long list of zones to be idealized
print("Starting Idealize")
Long_Run() -- looping the entire list until no gain or 2 full idealizes
save.Quickload ( kOriginalStructureOrNewBest )
recentbest.Restore()
ScriptStopScore=GetScore ()
Scriptgain=ScriptStopScore-ScriptStartScore
print("Total Deep Idealize Gain= ",r3(Scriptgain),"Start score= ",r3(ScriptStartScore), "Score= ",r3(ScriptStopScore))
behavior.SetClashImportance (1)
end
function cleanup ()
recentbest.Restore()
for i=1, segCnt2 do
structure.DeleteCut ( i )
end
recentbest.Save() -- trying to get rid of the cuts
save.Quickload ( kOriginalStructureOrNewBest )
recentbest.Restore()
print("Total DI gain=", r3(GetScore() -ScriptStartScore))
behavior.SetClashImportance (1)
end
--main ()
xpcall ( main , cleanup )