Code
--[[
Based on Tvdl Rav3n_pl Deep Rebuild v3.x
WARNING!
1) Script uses save slots 3-10!!!
2) Best score are always in slot 3
Description:
This is a long run rebuilder. Idea is to rebuild given/found area so many tyimes to found better position.
Each rebuild is scored on 7 different ways and saved if better.
After rebuild finishes script trying to stabilize and fuze each saved position (up to 7).
Because some positions are best in more than 1 way sometimes it is only 2 positions to stabilize.
Changed by: Timo van der Laan 17-12-2011 till 5-8-2012
Overview:
This version of Rav3n_pl DRW has several new features.
First of all it is made totally V2 and uses option dialogs.
It has an optimised fuze and qStab, and will run a lot faster as the original.
The main optimalisation is that futile shakes are skipped. Another one is that unprommissing fuzes can be skipped.
Feature 1.
Can be used in design puzzles, has mutate options for that.
Feature 2.
It will continue with the next segments of the same length if there is a win unless the gain reaches a threshold (default number of segments/4). Else it will continue with the next length or main cycle.
Feature 3.
It will not try to rebuild the exact same segments for a second time unless the gain reaches a threshold (default number of segments)
Feature 4.
It will not try a fuze if the loss is too great depending on the size of the rebuild
Feature 5.
It will not try to rebuild frozen or locked parts
Feature 6.
You can specify where to work on, based on secondary structure and/or selected or non selected parts.
Feature 7.
If you want it can keep disulfide bridges intact (thanks Brow42)
Feature 8.
If the starting score is negative, default is that no wiggles will be done to avoid exploding the protein.
Feature 9.
If stopped, it will reset CI, best score and secondary structures.
Some of the smaller features:
You can skip cycles, handy after a crash. It breaks off rebuild tries if no chance of success. It works on puzzles even if the score is < -1000000 (but will be slower).
Fuze and qStab can be suppressed (default if score is negative from the start)
You can specify to disable bands when rebuilding and enable them afterwards.
And several minor bugfixes.
Version 1.0.1 Fixed Selections, and minor text changes
Version 1.0.2 Added textbox to selections and a printout of what is selected
and replaced the comment above
Version 1.0.3 Fixed bridgekeeping after fuze
Version 1.0.4 Did some more work on the bridgekeeping feature
Version 1.1.0 Included the BridgeFuze, and rearranged the bridgekeeping
plus some minor changes
Version 1.1.1 Corrected a minor bug (mutating after a rebuild with a big selection gave problems)
Version 1.1.2 Made CI on mutate settable and also the sphere mutate uses
Version 1.1.3 Auto exploration detection
Version 1.1.4 Fixed Score function for exploration when negative
Version 1.2.0 CI is now dependend on the start CI
Version 1.2.1 With running on low CI there is an increased risk of losing best
score during qStab. Fixed that.
Version 1.2.2 Put in a warning when running not on CI 1 and a last chance
]]--
-- Handy shorts module
normal= (current.GetExplorationMultiplier() == 0)
segCnt=structure.GetCount()
segCnt2=segCnt
while structure.GetSecondaryStructure(segCnt2)=="M" do segCnt2=segCnt2-1 end
-- On request of gmn
CIfactor=1
function CI(CInr)
behavior.SetClashImportance(CInr*CIfactor)
end
function CheckCI()
local ask=dialog.CreateDialog("Clash importance is not 1")
ask.l1=dialog.AddLabel("Last change to change it")
ask.l2=dialog.AddLabel("CI settings will be multiplied by set CI")
ask.continue=dialog.AddButton("Continue",1)
dialog.Show(ask)
end
if behavior.GetClashImportance() < 0.99 then CheckCI() end
CIfactor=behavior.GetClashImportance()
-- Score functions
function Score(pose)
if pose==nil then pose=current end
local total= pose.GetEnergyScore()
-- FIX for big negatives
if total < -999999 and total > -1000001 then total=SegScore(pose) end
if normal then
return total
else
return total*pose.GetExplorationMultiplier()
end
end
function SegScore(pose)
if pose==nil then pose=current end
local total=8000
for i=1,segCnt2 do
total=total+pose.GetSegmentEnergyScore(i)
end
return total
end
function RBScore()
return Score(recentbest)
end
function round3(x)--cut all afer 3-rd place
return x-x%0.001
end
bestScore=Score()
function SaveBest()
local g=Score()-bestScore
if g>0 then
if g>0.01 then print("Gained another "..round3(g).." pts.") end
bestScore=Score()
save.Quicksave(3)
end
end
-- Wiggle function
-- Note the extra parameter to be used if only selected parts must be done
function Wiggle(how, iters, minppi,onlyselected)
--score conditioned recursive wiggle/shake
--fixed a bug, absolute difference is the threshold now
if how==nil then how="wa" end
if iters==nil then iters=6 end
if minppi==nil then minppi=0.1 end
if onlyselected==nil then onlyselected=false end
if iters>0 then
iters=iters-1
local sp=Score()
if onlyselected then
if how == "s" then
-- Shake is so slow on big ones, so first try one round
structure.ShakeSidechainsSelected(1)
if math.abs(Score()-sp) > minppi then structure.ShakeSidechainsSelected(1) end
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
else
if how == "s" then
-- Shake is so slow on big ones, so first try one round
structure.ShakeSidechainsAll(1)
if math.abs(Score()-sp) > minppi then structure.ShakeSidechainsAll(1) end
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
end
if math.abs(Score()-sp) > minppi then return Wiggle(how, iters, minppi,onlyselected) end
end
end
-- end of handy shorts module
-- Standard Fuze module
-- Picks up all gains by using recentbest
function FuzeEnd()
CI(1)
Wiggle("wa",1)
Wiggle("s",1)
Wiggle()
if RBScore()> Score() then recentbest.Restore() end
SaveBest()
end
function Fuze1(ci1,ci2)
CI(ci1)
Wiggle("s",1)
CI(ci2)
Wiggle("wa",1)
end
function Fuze2(ci1,ci2)
CI(ci1)
Wiggle("wa",1)
CI(1)
Wiggle("wa",1)
CI(ci2)
Wiggle("wa",1)
end
function reFuze(scr,slot)
local s=Score()
if s<scr then
save.Quickload(slot)
else
scr=s
save.Quicksave(slot)
end
return scr
end
function Fuze(slot)
local scr=Score()
recentbest.Save()
Fuze1(0.3,0.6) FuzeEnd()
scr=reFuze(scr,slot)
Fuze2(0.3,1)
if RBScore()>Score() then recentbest.Restore() end
SaveBest()
scr=reFuze(scr,slot)
Fuze1(0.05,1)
if RBScore()>Score() then recentbest.Restore() end
SaveBest()
scr=reFuze(scr,slot)
Fuze2(0.7,0.5) FuzeEnd()
scr=reFuze(scr,slot)
Fuze1(0.07,1)
if RBScore()>Score() then recentbest.Restore() end
SaveBest()
reFuze(scr,slot)
if RBScore()>Score() then recentbest.Restore() end
SaveBest()
end
-- end standard Fuze module
-- Segment set and list module
-- Notice that most functions assume that the sets are well formed
-- (=ordered and no overlaps)
-- 02-05-2012 TvdL Free to use for non commercial purposes
function SegmentListToSet(list)
local result={}
local f=0
local l=-1
table.sort(list)
for i=1,#list do
if list[i] ~= l+1 and list[i] ~= l then
-- note: duplicates are removed
if l>0 then result[#result+1]={f,l} end
f=list[i]
end
l=list[i]
end
if l>0 then result[#result+1]={f,l} end
--print("list to set")
--SegmentPrintSet(result)
return result
end
function SegmentSetToList(set)
local result={}
for i=1,#set do
--print(set[i][1],set[i][2])
for k=set[i][1],set[i][2] do
result[#result+1]=k
end
end
return result
end
function SegmentCleanSet(set)
-- Makes it well formed
return SegmentListToSet(SegmentSetToList(set))
end
function SegmentInvertSet(set,maxseg)
-- Gives back all segments not in the set
-- maxseg is added for ligand
local result={}
if maxseg==nil then maxseg=structure.GetCount() end
if #set==0 then return {{1,maxseg}} end
if set[1][1] ~= 1 then result[1]={1,set[1][1]-1} end
for i=2,#set do
result[#result+1]={set[i-1][2]+1,set[i][1]-1}
end
if set[#set][2] ~= maxseg then result[#result+1]={set[#set][2]+1,maxseg} end
return result
end
function SegmentInList(s,list)
table.sort(list)
for i=1,#list do
if list[i]==s then return true
elseif list[i]>s then return false
end
end
return false
end
function SegmentInSet(set,s)
for i=1,#set do
if s>=set[i][1] and s<=set[i][2] then return true
elseif s<set[i][1] then return false
end
end
return false
end
function SegmentJoinList(list1,list2)
local result=list1
if result == nil then return list2 end
for i=1,#list2 do result[#result+1]=list2[i] end
table.sort(result)
return result
end
function SegmentJoinSet(set1,set2)
return SegmentListToSet(SegmentJoinList(SegmentSetToList(set1),SegmentSetToList(set2)))
end
function SegmentCommList(list1,list2)
local result={}
table.sort(list1)
table.sort(list2)
if #list2==0 then return result end
local j=1
for i=1,#list1 do
while list2[j]<list1[i] do
j=j+1
if j>#list2 then return result end
end
if list1[i]==list2[j] then result[#result+1]=list1[i] end
end
return result
end
function SegmentCommSet(set1,set2)
return SegmentListToSet(SegmentCommList(SegmentSetToList(set1),SegmentSetToList(set2)))
end
function SegmentSetMinus(set1,set2)
return SegmentCommSet(set1,SegmentInvertSet(set2))
end
function SegmentPrintSet(set)
print(SegmentSetToString(set))
end
function SegmentSetToString(set)
local line = ""
for i=1,#set do
if i~=1 then line=line..", " end
line=line..set[i][1].."-"..set[i][2]
end
return line
end
function SegmentSetInSet(set,sub)
if sub==nil then return true end
-- Checks if sub is a proper subset of set
for i=1,#sub do
if not SegmentRangeInSet(set,sub[i]) then return false end
end
return true
end
function SegmentRangeInSet(set,range)
if range==nil or #range==0 then return true end
local b=range[1]
local e=range[2]
for i=1,#set do
if b>=set[i][1] and b<=set[i][2] then
return (e<=set[i][2])
elseif e<=set[i][1] then return false end
end
return false
end
function SegmentSetToBool(set)
local result={}
for i=1,structure.GetCount() do
result[i]=SegmentInSet(set,i)
end
return result
end
--- End of Segment Set module
-- Module Find Segment Types
function FindMutables()
local result={}
for i=1,structure.GetCount() do if structure.IsMutable(i) then result[#result+1]=i end end
return SegmentListToSet(result)
end
function FindFrozen()
local result={}
for i=1,structure.GetCount() do if freeze.IsFrozen(i) then result[#result+1]=i end end
return SegmentListToSet(result)
end
function FindLocked()
local result={}
for i=1,structure.GetCount() do if structure.IsLocked(i) then result[#result+1]=i end end
return SegmentListToSet(result)
end
function FindSelected()
local result={}
for i=1,structure.GetCount() do if selection.IsSelected(i) then result[#result+1]=i end end
return SegmentListToSet(result)
end
function FindAAtype(aa)
local result={}
for i=1,structure.GetCount() do
if structure.GetSecondaryStructure(i)== aa then result[#result+1]=i end
end
return SegmentListToSet(result)
end
function FindAminotype(at)
-- This one returns a list not a set
local result={}
for i=1,structure.GetCount() do
if structure.GetAminoAcid(i) == at then result[#result+1]=i end
end
return result
end
-- end Module Find Segment Types
-- Start of module for bridgechecking
Cyslist={}
savebridges=false --default no bridgechecking
nrofbridges=0
function setCyslist()
Cyslist=FindAminotype("c")
nrofbridges=CountBridges()
end
function IsBridge(i)
return ''..current.GetSegmentEnergySubscore(i,'disulfides') ~= '-0'
end
function CountBridges()
local count = 0
for i = 1,#Cyslist do
if IsBridge(Cyslist[i]) then count = count + 1 end
end
return count
end
function BridgesBroken()
return savebridges == true and CountBridges() < nrofbridges
end
-- End module bridgechecking
-- Position stack module 1.0
-- uses slot 50 and higher
Stackmin=50
StackMarks={}
StackPos=50
function PushPosition()
if StackPos==100 then
print("Position stack overflow, exiting")
exit()
end
save.Quicksave(StackPos)
StackPos=StackPos+1
end
function PopPosition()
if StackPos==50 then
print("Position stack underflow, exiting")
exit()
end
StackPos=StackPos-1
save.Quickload(StackPos)
end
function PushMarkPosition()
StackMarks[#StackMarks+1]=StackPos
PushPosition()
end
function PopMarkPosition()
if #StackMarks == 0 then
print("No marked position found, just popping")
else
StackPos=StackMarks[#StackMarks]+1
StackMarks[#StackMarks]= nil
end
PopPosition()
end
function ClrTopPosition()
if StackPos > 50 then StackPos=StackPos-1 end
end
-- Bridgekeeping Fuze module
-- Picks up all gains by using recentbest
-- But makes sure no bridges are broken
function BridgeFuzeEnd()
PushPosition()
CI(1)
Wiggle("wa",1)
Wiggle("s",1)
Wiggle()
if RBScore()> Score() then BridgerestoreRB() end
if not BridgesBroken() then
SaveBest()
ClrTopPosition()
else
PopPosition()
end
end
function BridgeFuze1(ci1,ci2)
PushPosition()
CI(ci1)
Wiggle("s",1)
CI(ci2)
Wiggle("wa",1)
if not BridgesBroken() then
ClrTopPosition()
else
PopPosition()
end
end
function BridgeFuze2(ci1,ci2)
PushPosition()
CI(ci1)
Wiggle("wa",1)
CI(1)
Wiggle("wa",1)
CI(ci2)
Wiggle("wa",1)
if not BridgesBroken() then
ClrTopPosition()
else
PopPosition()
end
end
function reBridgeFuze(scr,slot)
local s=Score()
if s<scr then
save.Quickload(slot)
else
scr=s
save.Quicksave(slot)
end
return scr
end
function BridgerestoreRB()
PushPosition()
recentbest.Restore()
if BridgesBroken() then
PopPosition()
else ClrTopPosition() end
end
function BridgeFuze(slot)
local scr=Score()
recentbest.Save()
BridgeFuze1(0.3,0.6) BridgeFuzeEnd()
scr=reBridgeFuze(scr,slot)
BridgeFuze2(0.3,1)
if RBScore()>Score() then BridgerestoreRB() end
SaveBest()
scr=reBridgeFuze(scr,slot)
BridgeFuze1(0.05,1)
if RBScore()>Score() then BridgerestoreRB() end
SaveBest()
scr=reBridgeFuze(scr,slot)
BridgeFuze2(0.7,0.5) BridgeFuzeEnd()
scr=reBridgeFuze(scr,slot)
BridgeFuze1(0.07,1)
if RBScore()>Score() then BridgerestoreRB() end
SaveBest()
reBridgeFuze(scr,slot)
if RBScore()>Score() then BridgerestoreRB() end
SaveBest()
end
-- end bridgekeeping Fuze module
SAVEDstructs=false
function AllLoop() --turning entire structure to loops
local anychange=false
for i=1,segCnt2 do
if structure.GetSecondaryStructure(i)~="L" then
anychange=true
break
end
end
if anychange then
save.SaveSecondaryStructure()
SAVEDstructs=true
selection.SelectAll()
structure.SetSecondaryStructureSelected("L")
end
end
function SelectAround(ss,se,radius,nodeselect)
if nodeselect~=true then selection.DeselectAll() end
for i=1, segCnt2 do
for x=ss,se do
if structure.GetDistance(x,i)<radius then selection.Select(i) break end
end
end
end
function qStab()
recentbest.Save()
CI(0.1)
Wiggle("s",1,nil,true) --shake only selected part
if InQstab then
CI(1)
doMutate()
end
if fastQstab==false then
CI(0.4)
Wiggle("wa",1)
CI(1)
Wiggle("s",1)
end
CI(1)
Wiggle()
recentbest.Restore()
end
function Sort(tab,items) --BACWARD bubble sorting - lowest on top, only needed items
for x=1,items do --items do
for y=x+1,#tab do
if tab[x][1]>tab[y][1] then
tab[x],tab[y]=tab[y],tab[x]
end
end
end
return tab
end
function FindWorst()
if sEnd==nil then sEnd=segCnt2 end
print("Searching worst scoring parts of len "..len)
wrst={}
GetSegmentScores()
local skiplist=""
local nrskip=0
for i=sStart,sEnd-len+1 do
if (not donotrevisit or not donotrevisitlist[i+(i+len-1)*segCnt2])
and MustWorkon(i,i+len-1)
then
if scrPart==nil then scrPart='local' end
s=getAreaScore(i,i+len-1,scrPart)
wrst[#wrst+1]={s,i}
else
if (donotrevisit and donotrevisitlist[i+(i+len-1)*segCnt2])
then
if nrskip==0 then print("Skipping") end
nrskip=nrskip+1
skiplist=skiplist..i.."-"..(i+len-1).." "
if nrskip%7==0 then
print(skiplist)
skiplist=""
end
end
end
end
if nrskip%7 ~= 0 then print(skiplist) end
if nrskip > 0 then print("Number of skips: "..nrskip) end
wrst=Sort(wrst,reBuild)
areas={}
local rb=reBuild
if rb>#wrst then rb=#wrst end
for i=1,rb do
local w=wrst[i]
local ss=w[2]
areas[#areas+1]={ss,ss+len-1}
end
end
function localRebuild(maxiters)
if maxiters==nil then maxiters=3 end
local s=Score()
local i=0
if bandflip then band.DisableAll() end
if savebridges then PushPosition() end
repeat
i=i+1
if i>maxiters then break end
structure.RebuildSelected(i)
until Score()~=s and BridgesBroken() == false
if bandflip then band.EnableAll() end
if savebridges then
if BridgesBroken() then PopPosition() else ClrTopPosition() end
end
if Score()~=s then return true else return false end
end
function ReBuild(ss,se,tries)
Clear() --reset score tables
if ss>se then ss,se=se,ss end --switch if needed
local Foundone=false
for try=1,tries do -- perform loop for number of tries
selection.DeselectAll()
CI(rebuildCI)
selection.SelectRange(ss,se)
local extra_rebuilds = 1
if savebridges then extra_rebuilds=3 end --extra if bridges keep breaking
local done
repeat
done=localRebuild(nil)
extra_rebuilds = extra_rebuilds -1
until done or extra_rebuilds == 0
SaveBest()
if done==true and doShake==true then
CI(shakeCI)
Foundone=true
if savebridges then PushPosition() end
Wiggle("s",1,nil,true)
if savebridges then
if BridgesBroken() then PopPosition() else ClrTopPosition() end
end
end
if done==true and AfterRB then doMutate() end
if done==true then
Foundone=true
Save(ss,se)
SaveBest()
end
if (try > 3 or savebridges) and Foundone==false then
print("No valid rebuild found on this section")
print("After 9 or more rebuild attempts, giving up")
break
end
end
CI(1)
return Foundone
end
function getPartScore(segments,attr)--using partial scoring
local score = 0
for i=1,#attr do
score = score + current.GetSegmentEnergySubscore(segments,attr[i])
end
return score
end
function getAreaScore(ss,se,attr)
local s=0
if attr=='local' then --this one for evaluation of worst scores
for i=ss,se do
s=s+SegmentScores[i]
end
elseif attr~=nil then --local scoring
for i=ss,se do
s=s+getPartScore(i,attr)
end
else --total segment scores
for i=ss,se do
s=s+current.GetSegmentEnergyScore(i)
end
end
return s
end
WORKONbool={}
function InitWORKONbool()
WORKONbool=SegmentSetToBool(WORKON)
end
function MustWorkon(i,j)
for k=i,j do if not WORKONbool[k] then return false end end
return true
end
SegmentScores={}
lastSegScores=0
function GetSegmentScores()
if lastSegScores~=Score() then
lastSegScores=Score()
for i=1,segCnt2 do
if WORKONbool[i] then SegmentScores[i]=current.GetSegmentEnergyScore(i)-current.GetSegmentEnergySubscore(i,'reference') --ignore reference part
end
end
end
end
Scores={} --{save_no,points}
function Clear()
Scores={
{10,-99999999},
{9,-99999999},
{8,-99999999},
{7,-99999999},
{6,-99999999},
{5,-99999999},
{4,-99999999},
}
slotScr={}
end
function Save(ss,se) --there you can change scoring methods for each save
local scr=
{
{10,getAreaScore(ss,se,{'backbone'})},
{9,getAreaScore(ss,se,{'sidechain'})},
{8,getAreaScore(ss,se,{'clashing'})},
{7,getAreaScore(ss,se,{'hiding'})},
{6,getAreaScore(ss,se,{'bonding'})},
{5,getAreaScore(ss,se)},
{4,Score()}
}
for i=1,#Scores do
local s=scr[i][2]
if s>Scores[i][2] then
local slot=scr[i][1]
save.Quicksave(slot) --print("Saved slot ",slot," pts" ,s) --debug
Scores[i][2]=s
end
end
SaveBest()
end
slotScr={}
function ScoresCheck(slot)
save.Quickload(slot)
local s=Score()
local ok=true
if #slotScr > 0 then
for i=1,#slotScr do
if slotScr[i]==s then ok=false break end
end
end
slotScr[#slotScr+1]=s
return ok
end
function PrintAreas()
if #areas<19 then
local a=""
local x=0
for i=1,#areas do
x=x+1
a=a..areas[i][1].."-"..areas[i][2].." "
if x>6 then
print(a)
a=""
x=0
end
end
if x>0 then print(a) end
else
print("It is "..#areas.." places, not listing.")
end
end
function AddLoop(sS)
local ss=sS
local ssStart=structure.GetSecondaryStructure(ss)
local se=ss
for i=ss+1,segCnt2 do
if structure.GetSecondaryStructure(i)==ssStart then se=i
else break end
end
if se-ss+2>minLen and loops==true then
areas[#areas+1]={ss,se}
end
return se
end
function AddOther(sS)
local ss=sS
local ssStart=structure.GetSecondaryStructure(ss)
local se=ss
if ss>1 then
for i=ss-1,1,-1 do --search bacward for start
local sec=structure.GetSecondaryStructure(i)
if sec=="L" then ss=i
else break end
end
end
if se<segCnt2-1 then --now forward to find end
local change=false
repeat
se=se+1
if se==segCnt2 then break end
local sec=structure.GetSecondaryStructure(se)
if change==false then
if sec~=ssStart then change=true end
end
until change==true and sec~="L"
if se<segCnt2 then se=se-1 end
end
if sheets==false and ssStart=="E" then return se end
if helices==false and ssStart=="H" then return se end
if se-ss+2>minLen then
areas[#areas+1]={ss,se}
end
return se
end
function FindAreas()
if loops then
local done=false
local ss=0
repeat--loops
ss=ss+1
local ses=structure.GetSecondaryStructure(ss)
if ses=="L" then
ss=AddLoop(ss)
end
if ss==segCnt2 then done=true end
until done~=false
end
if sheets or helices then
local done=false
local ss=0
repeat--other
ss=ss+1
local ses=structure.GetSecondaryStructure(ss)
if ses~="L" then
ss=AddOther(ss)
end
if ss==segCnt2 then done=true end
until done~=false
end
end
firstRBseg=0
lastRBseg=0
function doMutate()
CI(MutateCI)
if savebridges then PushPosition() end
if MUTRB then
selection.DeselectAll()
selection.SelectRange(firstRBseg,lastRBseg)
structure.MutateSidechainsSelected(1)
elseif MUTSur then
SelectAround(firstRBseg,lastRBseg,MutSphere)
structure.MutateSidechainsSelected(1)
else
structure.MutateSidechainsAll(1)
end
if savebridges then
if BridgesBroken() then PopPosition() else ClrTopPosition() end
end
end
function DeepRebuild()
if sEnd==nil then sEnd=segCnt2 end
local ss=Score()
if struct==false then AllLoop() end
save.Quicksave(3)
recentbest.Save()
print("DeepRebuild started at score: "..round3(ss))
for i=1,#areas do
local ss1=Score()
local s=areas[i][1]
local e=areas[i][2]
firstRBseg=s
lastRBseg=e
save.Quicksave(11) -- for uncaught bridge breaks
if Runnr > nrskip then
print("DR "..Runnr.."."..(e-s+1).."."..i.." "..s.."-"..e.." "..
rebuilds.." times. Wait... Current score: "..round3(Score()))
if ReBuild(s,e,rebuilds) then
for r=1,#Scores do
slot=Scores[r][1]
if ScoresCheck(slot) then
print("Stabilizing slot "..slot)
SelectAround(s,e,12) --local shake after rebuild
if savebridges then PushPosition() end
if not skipqstab then qStab()
else
CI(1)
Wiggle("s",1,nil,true)
Wiggle("ws",1,nil,true)
end
if savebridges then
if BridgesBroken() then
PopPosition()
else ClrTopPosition() end
end
if AfterQstab then doMutate() end
save.Quicksave(slot)
SaveBest()
end
end
save.Quickload(4)
recentbest.Save()
for i=5,10 do
save.Quickload(i)
end
recentbest.Restore()
local scorebeforefuze=Score()
if not skipfuze and ss1-Score() < maxlossbeforefuze*(e-s+1)/3 then
print("Fuzing best position.")
if not AfterQstab and BeFuze then doMutate() end
save.Quicksave(4)
if savebridges then BridgeFuze(4) else Fuze(4) end
end
if AfterFuze then doMutate() end
SaveBest()
save.Quickload(3)
else save.Quickload(3) end
end --skip section
if BridgesBroken() then
-- THIS SHOULD NOT HAPPEN
print("Unexpected bridge broken, pls report\n")
print("Restoring a good position, discarding wins\n")
save.Quickload(11)
save.Quicksave(3)
bestScore=Score()
end
donotrevisitlist[s+e*segCnt2] = true
nrremember=nrremember+1
remembernottorevisit[nrremember] = s+e*segCnt2
if Score()-scorebefore > clearnottorevisitgain then
scorebefore=Score()
clearrevisitlist()
end
if Score()-ss > minGain then break end
end
print("DeepRebuild gain: "..round3(Score()-ss))
if struct==false and SAVEDstructs then save.LoadSecondaryStructure() end
end
function clearrevisitlist()
for i=1,nrremember do
donotrevisitlist[remembernottorevisit[i]] = false
end
nrremember=0
end
function DRcall(how)
if sEnd==nil then sEnd=segCnt2 end
if how=="drw" then
for i=minLen,maxLen do --search from minl to maxl worst segments
len=i
if longfirst then len=maxLen-i+minLen end
FindWorst() --fill areas table. Comment it if you have set them by hand
PrintAreas()
DeepRebuild()
end
elseif how=="fj" then --DRW len cutted on pieces
FindWorst() --add to areas table worst part
areas2={}
for a=1,#areas do
local s=areas[a] --{ss,se}
local ss=s[1] --start segment of worst area
local se=s[2] --end segment of worst area
for i=ss,se do
for x=1,len do
if i+x<=se then
areas2[#areas2+1]={i,i+x}
end
end
end
end
areas=areas2
PrintAreas()
DeepRebuild()
elseif how=="all" then
areas={}
for i=minLen,maxLen do
for x=sStart,sEnd do
if i+x-1<=sEnd then
areas[#areas+1]={x,x+i-1}
end
end
end
PrintAreas()
DeepRebuild()
elseif how=="simple" then
FindWorst()
PrintAreas()
DeepRebuild()
elseif how=="areas" then
areas={}
FindAreas()
PrintAreas()
DeepRebuild()
end
end
function AskMoreOptions()
local ask=dialog.CreateDialog("More DRW options")
ask.l1=dialog.AddLabel("Clear no revisit list if gain is more")
ask.revlist=dialog.AddSlider("Cleargain:",clearnottorevisitgain,0,250,0)
ask.l2=dialog.AddLabel("Number of rebuilds each pass")
ask.nrrebuilds=dialog.AddSlider("Rebuilds:",rebuilds,10,20,0)
ask.l3=dialog.AddLabel("Number of full cycles")
ask.nrcycles=dialog.AddSlider("Cycles:",maxnrofRuns,1,40,0)
ask.l4=dialog.AddLabel("Skip first cycles (crash resume)")
ask.nrskip=dialog.AddSlider("Skip cycles:",nrskip,0,10,0)
ask.reBuild=dialog.AddSlider("# to do in first cycle:",reBuild,1,6,0)
ask.longfirst=dialog.AddCheckbox("Longest rebuild first",longfirst)
ask.doShake=dialog.AddCheckbox("Shake after rebuild (rebuilds only)",doShake)
ask.shakeCI=dialog.AddSlider("Shake CI:",shakeCI,0,1,2)
ask.bandflip=dialog.AddCheckbox("Disable bands before rebuild",bandflip)
ask.skipqstab=dialog.AddCheckbox("Local shake instead of Qstab",skipqstab)
ask.skipfuze=dialog.AddCheckbox("Skip Fuze",skipfuze)
ask.OK = dialog.AddButton("OK",1)
dialog.Show(ask)
clearnottorevisitgain=ask.revlist.value
rebuilds=ask.nrrebuilds.value
maxnrofRuns=ask.nrcycles.value
nrskip=ask.nrskip.value
reBuild=ask.reBuild.value
longfirst=ask.longfirst.value
doShake=ask.doShake.value
shakeCI=ask.shakeCI.value
bandflip=ask.bandflip.value
skipqstab=ask.skipqstab.value
skipfuze=ask.skipfuze.value
end
AfterRB=false
InQstab=false
AfterQstab=false
BeFuze=false
AfterFuze=false
MutateCI=0.9
MutSphere=10
MUTRB=false
MUTSur=false
function AskMutateOptions()
local ask = dialog.CreateDialog("Mutate Options")
ask.AfterRB = dialog.AddCheckbox("Mutate after rebuild",AfterRB)
ask.InQstab = dialog.AddCheckbox("Mutate during Qstab",InQstab)
ask.AfterQstab = dialog.AddCheckbox("Mutate after Qstab",AfterQstab)
ask.BeFuze = dialog.AddCheckbox("Mutate before Fuze",BeFuze)
ask.AfterFuze = dialog.AddCheckbox("Mutate after Fuze",AfterFuze)
ask.l1=dialog.AddLabel("-----What to rebuild or all")
ask.OnlyRB=dialog.AddCheckbox("Mutate only rebuild part",MUTRB)
ask.OnlySur=dialog.AddCheckbox("Mutate rebuild and surround",MUTSur)
ask.l2=dialog.AddLabel("Sphere size to use with surround")
ask.SurSize=dialog.AddSlider("Sphere:",MutSphere,3,15,0)
ask.MutateCI=dialog.AddSlider("MutateCI:",MutateCI,0.1,1,2)
ask.OK = dialog.AddButton("OK",1) ask.Cancel = dialog.AddButton("Cancel",0)
if dialog.Show(ask) > 0 then
AfterRB=ask.AfterRB.value
InQstab=ask.InQstab.value
AfterQstab=ask.AfterQstab.value
BeFuze=ask.BeFuze.value
AfterFuze=ask.AfterFuze.value
MutateCI=ask.MutateCI.value
MutSphere=ask.SurSize.value
MUTRB=ask.OnlyRB.value
MUTSur=ask.OnlySur.value
end
end
function printOptions(title)
print(title)
print("Based on rav4pl DRW 3.4")
print("Length of rebuilds: "..minLen.." until "..maxLen)
print("Rebuild area: "..SegmentSetToString(WORKON))
if AfterRB then print("Mutates after each rebuild") end
if InQstab then print("Mutates inside qStab") end
if AfterQstab then print("Mutates after qStab") end
if BeFuze then print("Mutates before Fuzing") end
if AfterFuze then print("Mutates after Fuzing") end
print("Nr of rebuilds each try: "..rebuilds)
if not struct then print("Convert everything to loops") end
if donotrevisit then
print("Will not retry already tried rebuilds")
print("Clear done list if gain raises above "..clearnottorevisitgain.." pts")
end
if doShake then
print("Do an initial shake on rebuild part after rebuild")
print("With CI="..shakeCI)
end
if skipqstab then print("Local shake instead of qStab") end
if skipfuze then print("Skipping Fuzes") end
print("Nr of full cycles: "..maxnrofRuns)
if nrskip > 0 then print("SKIPPING "..nrskip.." CYCLES") end
end
-- Module AskSelections
-- 02-05-2012 Timo van der Laan, Free to use for non commercial purposes
function AskForSelections(title,mode)
local result={{1,structure.GetCount()}} -- All segments
if mode == nil then mode={} end
if mode.askloops==nil then mode.askloops=true end
if mode.asksheets==nil then mode.asksheets=true end
if mode.askhelixes==nil then mode.askhelixes=true end
if mode.askligands==nil then mode.askligands=false end
if mode.askselected==nil then mode.askselected=true end
if mode.asknonselected==nil then mode.asknonselected=true end
if mode.askmutateonly==nil then mode.askmutateonly=true end
if mode.askignorelocks==nil then mode.askignorelocks=true end
if mode.askignorefrozen==nil then mode.askignorefrozen=true end
if mode.askranges==nil then mode.askranges=true end
if mode.defloops==nil then mode.defloops=true end
if mode.defsheets==nil then mode.defsheets=true end
if mode.defhelixes==nil then mode.defhelixes=true end
if mode.defligands==nil then mode.defligands=false end
if mode.defselected==nil then mode.defselected=false end
if mode.defnonselected==nil then mode.defnonselected=false end
if mode.defmutateonly==nil then mode.defmutateonly=false end
if mode.defignorelocks==nil then mode.defignorelocks=false end
if mode.defignorefrozen==nil then mode.defignorefrozen=false end
local Errfound=false
repeat
local ask = dialog.CreateDialog(title)
if Errfound then
ask.E1=dialog.AddLabel("Try again, ERRORS found, check output box")
result={{1,structure.GetCount()}} --reset start
Errfound=false
end
if mode.askloops then
ask.loops = dialog.AddCheckbox("Work on loops",mode.defloops)
elseif not mode.defloops then
ask.noloops= dialog.AddLabel("Loops will be auto excluded")
end
if mode.askhelixes then
ask.helixes = dialog.AddCheckbox("Work on helixes",mode.defhelixes)
elseif not mode.defhelixes then
ask.nohelixes= dialog.AddLabel("Helixes will be auto excluded")
end
if mode.asksheets then
ask.sheets = dialog.AddCheckbox("Work on sheets",mode.defsheets)
elseif not mode.defsheets then
ask.nosheets= dialog.AddLabel("Sheets will be auto excluded")
end
if mode.askligands then
ask.ligands = dialog.AddCheckbox("Work on ligands",mode.defligands)
elseif not mode.defligands then
ask.noligands= dialog.AddLabel("Ligands will be auto excluded")
end
if mode.askselected then ask.selected = dialog.AddCheckbox("Work only on selected",mode.defselected) end
if mode.asknonselected then ask.nonselected = dialog.AddCheckbox("Work only on nonselected",mode.defnonselected) end
if mode.askmutateonly then ask.mutateonly = dialog.AddCheckbox("Work only on mutateonly",mode.defmutateonly) end
if mode.askignorelocks then
ask.ignorelocks =dialog.AddCheckbox("Dont work on locked ones",true)
elseif mode.defignorelocks then
ask.nolocks=dialog.AddLabel("Locked ones will be auto excluded")
end
if mode.askignorefrozen then
ask.ignorefrozen = dialog.AddCheckbox("Dont work on frozen",true)
elseif mode.defignorefrozen then
ask.nofrozen=dialog.AddLabel("Frozen ones will be auto excluded")
end
if mode.askranges then
ask.R1=dialog.AddLabel("Or put in segmentranges. Above selections also count")
ask.ranges=dialog.AddTextbox("Ranges","")
end
ask.OK = dialog.AddButton("OK",1) ask.Cancel = dialog.AddButton("Cancel",0)
if dialog.Show(ask) > 0 then
-- We start with all the segments including ligands
if mode.askloops then mode.defloops=ask.loops.value end
if not mode.defloops then
result=SegmentSetMinus(result,FindAAtype("L"))
end
if mode.asksheets then mode.defsheets=ask.sheets.value end
if not mode.defsheets then
result=SegmentSetMinus(result,FindAAtype("E"))
end
if mode.askhelixes then mode.defhelixes=ask.helixes.value end
if not mode.defhelixes then
result=SegmentSetMinus(result,FindAAtype("H"))
end
if mode.askligands then mode.defligands=ask.ligands.value end
if not mode.defligands then
result=SegmentSetMinus(result,FindAAtype("M"))
end
if mode.askignorelocks then mode.defignorelocks=ask.ignorelocks.value end
if mode.defignorelocks then
result=SegmentSetMinus(result,FindLocked())
end
if mode.askignorefrozen then mode.defignorefrozen=ask.ignorefrozen.value end
if mode.defignorefrozen then
result=SegmentSetMinus(result,FindFrozen())
end
if mode.askselected then mode.defselected=ask.selected.value end
if mode.defselected then
result=SegmentCommSet(result,FindSelected())
end
if mode.asknonselected then mode.defnonselected=ask.nonselected.value end
if mode.defnonselected then
result=SegmentCommSet(result,SegmentInvertSet(FindSelected()))
end
if mode.askranges and ask.ranges.value ~= "" then
local rangetext=ask.ranges.value
local function Checknums(nums)
-- Now checking
if #nums%2 ~= 0 then
print("Not an even number of segments found")
return false
end
for i=1,#nums do
if nums[i]==0 or nums[i]>structure.GetCount() then
print("Number "..nums[i].." is not a segment")
return false
end
end
return true
end
local function ReadSegmentSet(data)
local nums = {}
local NoNegatives='%d+' -- - is not part of a number
local result={}
for v in string.gfind(data,NoNegatives) do
table.insert(nums, tonumber(v))
end
if Checknums(nums) then
for i=1,#nums/2 do
result[i]={nums[2*i-1],nums[2*i]}
end
result=SegmentCleanSet(result)
else Errfound=true result={} end
return result
end
local rangelist=ReadSegmentSet(rangetext)
if not Errfound then
result=SegmentCommSet(result,rangelist)
end
end
end
until not Errfound
return result
end
-- end of module AskSelections
WORKON={{1,structure.GetCount()}}
function AskDRWOptions()
local askresult
local ask = dialog.CreateDialog("Tvdl enhanced DRW "..DRWVersion)
repeat
ask.l1 = dialog.AddLabel("Minimum length to rebuild")
ask.minLen = dialog.AddSlider("Minimum:",minLen,1,10,0)
ask.l2 = dialog.AddLabel("Maximum length to rebuild")
ask.maxLen = dialog.AddSlider("Maximum:",maxLen,1,10,0)
ask.l3 = dialog.AddLabel("Force next round if gain is more")
ask.minGain = dialog.AddSlider("MinGain:",minGain,0,100,0)
ask.fastQstab=dialog.AddCheckbox("Do a fast qStab",fastQstab)
ask.l4 = dialog.AddLabel("Skip fuze if loss is more")
ask.l5 = dialog.AddLabel("Threshold used is RBlength*threshold/3")
ask.maxLoss = dialog.AddSlider("Skip fuze:",maxlossbeforefuze,-5,200,0)
ask.donotrevisit = dialog.AddCheckbox("Do not things twice",donotrevisit)
ask.SEL= dialog.AddCheckbox("(Re)select where to work on ",false)
ask.MUTS = dialog.AddCheckbox("(Re)set Mutate Options",false)
ask.bridge = dialog.AddCheckbox("Keep sulfide bridges intact",savebridges)
ask.struct = dialog.AddCheckbox("Do not change all to loop",struct)
ask.OK = dialog.AddButton("OK",1) ask.Cancel = dialog.AddButton("Cancel",0)
ask.Options = dialog.AddButton("More options",2)
-- TODO ask.Presets = dialog.AddButton("Presets",3)
askresult=dialog.Show(ask)
if askresult > 0 then
minLen=ask.minLen.value
maxLen=ask.maxLen.value
minGain=ask.minGain.value
fastQstab=ask.fastQstab.value
maxlossbeforefuze=ask.maxLoss.value
donotrevisit=ask.donotrevisit.value
struct=ask.struct.value
savebridges=ask.bridge.value
if ask.SEL.value then
local SelMode={}
SelMode.askignorefrozen=false
SelMode.defignorefrozen=true
SelMode.askignorelocks=false
SelMode.defignorelocks=true
SelMode.askligands=false
SelMode.defligands=false
WORKON=AskForSelections("Tvdl enhanced DRW "..DRWVersion,SelMode)
print("Selection is now, reselect if not oke:")
print(SegmentSetToString(WORKON))
if askresult==1 then askresult=4 end --to force return to main menu
end
-- Do not try to rebuild frozen or locked parts or ligands
WORKON=SegmentSetMinus(WORKON,FindFrozen())
WORKON=SegmentSetMinus(WORKON,FindLocked())
WORKON=SegmentSetMinus(WORKON,FindAAtype("M"))
if ask.MUTS.value then
AskMutateOptions()
if askresult==1 then askresult=4 end --to force return to main menu
end
if askresult==2 then AskMoreOptions() end
--TODO if askresult==3 then AskPresets() end
end
until askresult < 2
return askresult > 0
end
-- Quick fix for failing first rebuild
for i=3,10 do save.Quicksave(i) end
function Cleanup(err)
print("Restoring CI, best result and structures")
CI(1)
save.Quickload(3)
if SAVEDstructs then save.LoadSecondaryStructure() end
print(err)
end
--[[
USAGE
1. 'drw' - need 'minLen' and 'maxLen'; finding worst scores by len betwen that 2
2. 'fj' - need 'len'; searching len then cutting in pieces 2->len and rebuilds pieces
3. 'all' - need 'minLen' and 'maxLen'; rebuilding ENTIRE prorein (from min to max) like in WalkinRebuild script
4. 'simple' - need 'len'; find and rebuild worst scoring parts of that lenght
5. 'areas' - need secondary structure set and 'true' on at least one of structure
]]--
----------------- options below VVVV
areas={ --start segment, end segment. use for last line call
--{1,10},
--{20,30},
--{32,35},
}
scrPart=nil --{'backbone','sidechain','clashing'} --change there to find worst scoring parts by partial scoring
--options for (5)"areas" setting
loops=true --rebuild loops alone
sheets=false --rebuild sheets + surrounding loops
helices=true --false --rebuild helices + surrounding loops
doShake=true --false --shake rebuilded area (only!) every rebuild, slowing down process
shakeCI=0.31 --clash imortance while shaking
struct=false --set in all loop (if true work in structure mode)
fastQstab=true --false --if true faster stabilize, but longer
sStart=1 --start segment to search worsts
sEnd=segCnt2 --end segment to search worst
reBuild=4 --up to worst parts to look at
rebuilds=35 --how many rebuilds to try, set at least 10!
rebuildCI=0 --clash importance while rebuild
len=6 --find worst segments part
minLen=7 --or specify minimum len
maxLen=10 --and maximim len
-- New options
maxnrofRuns=40 -- Set it very high if you want to run forever
Runnr=0
donotrevisitlist={}
remembernottorevisit={}
nrremember=0
donotrevisit=true -- If you do not want a second try at the same part
clearnottorevisitgain=segCnt2 -- If there is enough change clear revisitlist
minGain=(segCnt2-segCnt2%4)/4 -- If less gain then try the next one, else recompute
if minGain < 40 then minGain=40 end
longfirst=true --true -- Reverse the search, long ones first
skipqstab=false
skipfuze=false
bandflip=false
maxlossbeforefuze=(segCnt2-segCnt2%4)/4 -- if loss is more no fuze is done
if maxlossbeforefuze < 30 then maxlossbeforefuze=30 end
scorebefore=Score()
nrskip=0
Cyslist={}
DRWVersion="1.2.3"
-- MAIN PROGRAM
function Doit()
printOptions("Tvdl enhanced DRW "..DRWVersion)
InitWORKONbool()
if savebridges then setCyslist() end
for nrofRuns=1,maxnrofRuns do --uncomment method/s you want to use
Runnr=nrofRuns
print("Main cycle nr ",nrofRuns)
-- DRcall("areas")
DRcall("drw")
-- DRcall("fj")
-- DRcall("all")
-- DRcall("simple")
-- DeepRebuild() --if set "areas" above by hand
if Score()-scorebefore > clearnottorevisitgain then clearrevisitlist() end
reBuild=reBuild+3 --three worst places more every loop
end
end
-- Change defaults if the startscore is negative
if Score() < 0 then
print("Score Negative, adjusting defaults")
print("Now skipping Fuzes, replacing qStab")
print("Can be changed in More options")
skipfuze=true
skipqstab=true
end
if AskDRWOptions() then
xpcall(Doit,Cleanup)
end