Code
-- BridgeFuze 1.0.0 Tvdl
-- A standard fuze but will keep sulfide bridges intact.
-- Handy shorts module
CI=behavior.SetClashImportance
segCnt=structure.GetCount()
while structure.GetSecondaryStructure(segCnt)=="M" do segCnt=segCnt-1 end
-- Score functions
function Score()
if normal==nil or normal==true then
-- FIX for big negatives
local total= current.GetEnergyScore()
return total
else
return current.GetScore()
end
end
function SegScore()
local total=8000
for i=1,segCnt do
total=total+current.GetSegmentEnergyScore(i)
end
return total
end
function RBScore()
if normal==nil or normal==true then
return recentbest.GetEnergyScore()
else
return recentbest.GetScore()
end
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
-- 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
-- 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
--- 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
-- 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()
PushPosition()
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
version="1.0.0"
function main()
local ss=Score()
print("Tvdl BridgeFuze "..version)
print("Starting score: "..round3(ss))
savebridges=true
setCyslist() --Finds the Cys and counts the bridges
print("Nr of Cys: "..#Cyslist.." Bridges: "..nrofbridges/2)
save.Quicksave(3) --Not sure if this is needed
save.Quicksave(4) --Not sure if this is needed
recentbest.Save() --Not sure if this is needed
BridgeFuze(4)
print("End of BridgeFuze.")
print("Endscore: "..round3(Score()).." Total gain: "..round3(Score()-ss))
end
function Cleanup(err)
print("Restoring best position and Class Importance")
print(err)
CI(1)
save.Quickload(3)
end
xpcall(main,Cleanup)