Profile
- Name
- QuakeR v5.1 with mutate and filter disabling
- ID
- 103558
- Shared with
- Public
- Parent
- QuakeR v5.0 with mutate
- Children
- None
- Created on
- June 24, 2020 at 20:35 PM UTC
- Updated on
- June 24, 2020 at 20:35 PM UTC
- Description
Quaker v5.0 now with mutate + better shake and wiggle ci in Fuze + GUI.
Also Disables filters unless scoring
Best for
Code
--QuakeR - a randomized Quake
recipeTitle = "QuakeR v5.0wm"
--[[
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
v5.1 -- updated 2020-06-24
- Added filter disabling when not scoring to improve performance
- Added a heck of a lot of comments to explain what is going on
- Removed exploration multiplier check, as exploration puzzles are no more
- Removed minppi argument from wiggle becasue it was unused
- Changed wiggle default values to use short circuiting or
]]
function floor3(x) --Round down to 3 decimal places
return tostring(x - x % 0.001)
end
function Score() -- Get the current score of the puzzle.
behavior.SetFiltersDisabled(false)
local s = current.GetEnergyScore()
behavior.SetFiltersDisabled(true)
return s
end
function ScoreRB() -- Get the recent best score of the puzzle
behavior.SetFiltersDisabled(false)
local s = recentbest.GetEnergyScore()
behavior.SetFiltersDisabled(true)
return s
end
function SaveBest() -- Save the best score of the puzzle
local g = Score() - bestScore -- Calculate score gain/loss
if g > 0 then -- Save is score has increased
print("Gained another " .. floor3(g) .. " points.")
bestScore = Score()
save.Quicksave(4) -- under normal conditions retain pose even as recording improvement
recentbest.Restore()
save.Quicksave(3)
save.Quickload(4)
end
return Score() - bestScore
end
-- TODO remove recursion and replace with loop
function Wiggle(how, iters) -- Wrapper for Wigglefunction to make it faster to use
-- Set default values for arguments
how = how or "wa"
iters = iters or 6
local minppi = 0.1 -- minimum gain
-- Check if iterations remaining
if iters > 0 then
iters = iters - 1 -- Decrement iterations
local sp = Score() -- Get current score
-- Wiggle or Shake depending on what the argument was for "how"
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 gain was more than minimum gain, repeat the process
if Score() - sp > minppi then
return Wiggle(how, iters, minppi)
end
end
end
function qStab() -- Quick Stabilization of the protein
behavior.SetClashImportance(0.21)
structure.MutateSidechainsSelected(1)
Wiggle("s", 1)
-- Skip low CI wiggle and shake if fastQstab is set
if fastQstab == false then
behavior.SetClashImportance(0.4)
Wiggle("wa", 1)
behavior.SetClashImportance(1)
Wiggle("s", 1)
end
-- Reset Clash Importance
behavior.SetClashImportance(1)
-- Do a generic wiggle out
Wiggle()
-- Save best score
return SaveBest()
end
function Fuze1(ci1, ci2) -- Type 1 fuzing
behavior.SetClashImportance(ci1)
Wiggle("s", 1)
behavior.SetClashImportance(ci2)
Wiggle("wa", 1)
end
function Fuze2(ci1, ci2) -- Tpe 2 Fuzing
behavior.SetClashImportance(ci1)
Wiggle("wa", 1)
behavior.SetClashImportance(1)
Wiggle("wa", 1)
behavior.SetClashImportance(ci2)
Wiggle("wa", 1)
end
function FuzeEnd() -- Fuze to run at end
behavior.SetClashImportance(1)
Wiggle("wa", 1)
Wiggle("s", 1)
behavior.SetClashImportance(0.9)
Wiggle()
behavior.SetClashImportance(1)
Wiggle("wa", 1)
SaveBest()
end
function reFuze(scr) -- Restore recent buest if current score is not an improvement
local s = ScoreRB()
if s < scr then
recentbest.Restore()
else
scr = s
end
return scr
end
function Fuze() -- Complete Fuze
local scr = Score()
Fuze1(1, 0.6)
FuzeEnd()
scr = reFuze(scr)
Fuze2(1, 1)
SaveBest()
scr = reFuze(scr)
Fuze1(1, 0.9)
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() -- Determine which atom to add a band based on AA, First/Last segment
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
-- TODO: Figure out why it does not always restore best score properly.
function QuakeR()
-- Variable for storing the gain in each iteration.
local gain = 0
-- Seed the random number generator
math.randomseed(os.time())
math.random()
math.random()
math.random()
-- Determine proper banding for all segments
-- TODO: Recalculate after mutating
calcBandAtom()
-- Disable filters
behavior.SetFiltersDisabled(true)
selection.SelectAll()
StartingScore = Score()
bestScore = StartingScore
recentbest.Save() -- TODO: Likely does nothing and can thus be removed. Need to check tho
save.Quicksave(3)
print("Starting " .. recipeTitle .. tostring(qLoops) .. " passes. Start score: " .. floor3(StartingScore))
for x = 1, qLoops do
print("Pass " .. tostring(x) .. " of " .. tostring(qLoops))
-- Randomly select values for where to start bands, what the sent for band length and space between bands
local start = math.floor(math.random(segCnt / 10)) --first band somewhere in first 10% of protein
local len = math.floor(math.random(segCnt / 2 - 5)) + 10
local step = math.floor(math.random(segCnt / 2 - 5)) + 10
-- Set in the maximum loss when pulling
local loss = math.abs(math.floor(Score() * maxLoss / 100))
-- Delete existing bands
band.DeleteAll()
print(
"Bands from segment " ..
tostring(start) .. " of length " .. tostring(len) .. " every " .. tostring(step) .. " segments."
)
print("Pulling until loss of " .. tostring(loss) .. " points.")
-- Add bands starting at start at intervals step
for x = start, segCnt, step do
for y = start + len, segCnt, step do
band.AddBetweenSegments(x, y, bandAtom[x], bandAtom[y])
end
end
-- Set our CI and save the recentbest value
behavior.SetClashImportance(pullingCI)
recentbest.Save()
-- Re-initialize the gain measurement
gain = 0
-- Set the strength of the bands
for str = minBS, maxBS, 0.07 do --search enough band strength to move
bandstr(str)
-- Wiggle the entire protein for 1 iteration
-- Keep doing this until no more gain
repeat
structure.WiggleAll(1, true, false)
gain = SaveBest()
if gain > 0 then
recentbest.Restore()
end
until gain <= 0
-- also stop loop if gain is more than the target loss
if gain < -loss then
break
end
end
-- Remove all bands and reset clash importance
band.DeleteAll()
behavior.SetClashImportance(1)
recentbest.Save() --after pulling
-- Stabilize
print("Stabilizing...")
if qStab() > doFuze then
print("Fuzing....")
Fuze()
end
SaveBest()
save.Quickload(3) --load best state
print("Current score: " .. floor3(Score()) .. " Total gain: " .. floor3(Score() - StartingScore))
end
print("Total QuakeR gain: " .. floor3(Score() - StartingScore))
return true
end
-- TODO: Add additional settings
function GetParameters() -- Display a settings dialog for the user, return the values
local dlog = dialog.CreateDialog("QuakeR v5 with mutate")
dlog.iterations = dialog.AddSlider("iterations: ", qLoops, 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
return true
else
return false
end
end
function main()
if (GetParameters() == false) then
return -- graceful exit
end
QuakeR()
CleanUp()
end
function CleanUp(err)
if err:find("Cancelled") ~= nil then
print "QuakeR Cancelled"
else
print(err)
end
behavior.SetClashImportance(1)
-- band.DeleteAll()
SaveBest()
save.Quickload(3)
-- Re-enable filters
behavior.SetFiltersDisabled(false)
print("Total QuakeR gain: " .. floor3(bestScore - StartingScore))
end
-- Get the total number of segments, then remove any ligand elements from it
segCnt = structure.GetCount()
while structure.GetSecondaryStructure(segCnt) == "M" do
segCnt = segCnt - 1
end
-- TODO: Add these options to the UI
--- VVVVVVVVVV OPTIONS
qLoops = 50 -- <<<OVER THERE! do more! much more!
minBS = 0.3 --starting minimum bands strength
maxBS = 1.0 --maximum band strength
maxLoss = 1 --minimum percentage loss when pulling. ie 5% of 10000 is 500pts
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.
-- Call the main function
xpcall(main, CleanUp)