Icon representing a recipe

Recipe: QuakeR v5.1 with mutate and filter disabling

created by marsfan

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)

Comments