Icon representing a recipe

Recipe: BandFuze Orange Guard v0.2

created by Susume

Profile


Name
BandFuze Orange Guard v0.2
ID
103399
Shared with
Public
Parent
BandFuze Orange Guard v0.2
Children
None
Created on
April 12, 2020 at 17:16 PM UTC
Updated on
April 12, 2020 at 17:16 PM UTC
Description

Before running script, freeze the sidechains you want to keep orange. An adaptation of MurloW's awesome script BandFuze.

Best for


Code


--[[ ------------------------------------------------ BandFuze Orange Guard v0.1 Adapted from MurloW's wonderful script BandFuze. Orange Guard refers to protecting sidechains chosen by the player before the script starts, and only allowing them to change to a prescribed list of Orange sidechains. Player should FREEZE all sidechains they want to be guarded during the mutates, BEFORE starting the script. v0.1: Edit bandfuze code for readability, update wiggle function, remove call to "qStab", which in this script is not a Rav3n-style quick stabilize but actually an extra fuze. Establish lists of allowed (orange) AAs for each frozen sidechain. Deselect the player's frozen sidechains prior to each mutate, to prevent them from mutating. After mutate, try each allowed AA on the protected sidechains; keep only gains. At script end, re-freeze the sidechains the player had frozen before. v0.2: add printout at beginning of how many sidechains Orange Guard is protecting reduce reporting of Orange Guard actions during script add reporting of high score and filter score after each iteration Future version - might add dialog for editing the lists of allowed AAs. ------------------------------------------------]] ------------------------------------------------ -- INITIALIZATION ------------------------------------------------ IterationMultiplier = 1.2 -- 2.4 --not used anywhere else ItMu = IterationMultiplier -- used only in wig() function if ItMu<=0 then ItMu=1 end nSegs=structure.GetCount() p=print p("") behavior.SetSlowFiltersDisabled(false) oldbands = band.GetCount() Qbands = 0 function score() return current.GetScore() end function cut(x) return x-x%0.000000001 end startscore = score() bestscore = startscore --only gets changed by Check() function, gets read several places p(" Startscore: "..cut(startscore)) p(" Best score in quicksave slot 1, starting pose in slot 2 ") --save.Quicksave(1) -- moved to main --save.Quicksave(2) -- moved to main maxCI=behavior.GetClashImportance() if maxCI<0.1 then maxCI = 1 end p(" maxCI = "..maxCI) --if AllAla then --made AllAla a function that returns a boolean, rather than a global variable -- p(" No shaking, still mutating if checked.") --end function Seed() -- Rav3n_pl seed=os.time()/math.abs(current.GetEnergyScore()) seed=seed%0.001 seed=1/seed while seed<10000000 do seed=seed*10 end seed=seed-seed%1 --p("Seed is: "..seed) math.randomseed(seed) end Seed() ------------------------------------------------ -- END INITIALIZATION ------------------------------------------------ ------------------------------------------------ -- ORANGE GUARD ------------------------------------------------ OG = { Slot=77, --Quicksave slot used by this module --define substitution lists Protected={}, --Sparse table, keyed by residue number, returns true if that residue is protected. AllowedList={}, --Sparse table, keyed by residue number, returns list of allowed AAs. RulesList={ --[[Used only during Initialization - after that use AllowedList instead. Sparse table keyed by AA, containing sparse tables keyed by secondary structure, containing integer-keyed list of all allowed AAs for that position. Each AA is allowed to be changed back to its original value regardless of SS. 'a' and 'p' allowed only in loops. 'm' allowed only in loops and helices. 'f' allowed anywhere there was already f, w, or y. 'w' and 'y' allowed only where there was already w or y. ]] a={E={'a','i','l','v'}, H={'a','i','l','m','v'}, L={'a','i','l','m','p','v'}}, --allowed substitutions for alanine, by SS c={E={'c','i','l','v'}, H={'c','i','l','m','v'}, L={'a','c','i','l','m','p','v'}}, --for cysteine, etc. d={E={'d','i','l','v'}, H={'d','i','l','m','v'}, L={'a','d','i','l','m','p','v'}}, e={E={'e','i','l','v'}, H={'e','i','l','m','v'}, L={'a','e','i','l','m','p','v'}}, f={E={'f','i','l','v'}, H={'f','i','l','m','v'}, L={'a','f','i','l','m','p','v'}}, g={E={'g','i','l','v'}, H={'g','i','l','m','v'}, L={'a','g','i','l','m','p','v'}}, h={E={'h','i','l','v'}, H={'h','i','l','m','v'}, L={'a','h','i','l','m','p','v'}}, i={E={'i','l','v'}, H={'i','l','m','v'}, L={'a','i','l','m','p','v'}}, k={E={'i','k','l','v'}, H={'i','k','l','m','v'}, L={'a','i','k','l','m','p','v'}}, l={E={'i','l','v'}, H={'i','l','m','v'}, L={'a','i','l','m','p','v'}}, m={E={'i','l','m','v'}, H={'i','l','m','v'}, L={'a','i','l','m','p','v'}}, n={E={'i','l','n','v'}, H={'i','l','m','n','v'}, L={'a','i','l','m','n','p','v'}}, p={E={'i','l','p','v'}, H={'i','l','m','p','v'}, L={'a','i','l','m','p','v'}}, q={E={'i','l','q','v'}, H={'i','l','m','q','v'}, L={'a','i','l','m','p','q','v'}}, r={E={'i','l','r','v'}, H={'i','l','m','r','v'}, L={'a','i','l','m','p','r','v'}}, s={E={'i','l','s','v'}, H={'i','l','m','s','v'}, L={'a','i','l','m','p','s','v'}}, t={E={'i','l','t','v'}, H={'i','l','m','t','v'}, L={'a','i','l','m','p','t','v'}}, v={E={'i','l','v'}, H={'i','l','m','v'}, L={'a','i','l','m','p','v'}}, w={E={'f','i','l','v','w','y'}, H={'f','i','l','m','v','w','y'}, L={'a','f','i','l','m','p','v','w','y'}}, y={E={'f','i','l','v','w','y'}, H={'f','i','l','m','v','w','y'}, L={'a','f','i','l','m','p','v','w','y'}}, } } function OG.Init() --build lists of frozen sidechains and AAs allowed for each one local OGCount = 0 for ii = 1, structure.GetCount() do local BBFrozen, SCFrozen = freeze.IsFrozen(ii) local AA = structure.GetAminoAcid(ii) local SS = structure.GetSecondaryStructure(ii) if (SCFrozen or (AA=='g' and BBFrozen)) then OG.Protected[ii] = true OG.AllowedList[ii] = OG.RulesList[AA][SS] freeze.Unfreeze(ii, true, true) --frozen backbones are not preserved OGCount = OGCount + 1 end end print("Orange Guard is protecting "..OGCount.." amino acids.") end function OG.Cleanup() for segnum, value in pairs(OG.Protected) do --this is how you loop over a sparse table local AA = structure.GetAminoAcid(segnum) if AA=='g' then freeze.Freeze(segnum, true, false) else freeze.Freeze(segnum, false, true) end end end function OG.MutateSelected(iters) print(" OG.MutateSelected") local ProtectList={} for segnum, value in pairs(OG.Protected) do if selection.IsSelected(segnum) then ProtectList[segnum] = true selection.Deselect(segnum) end end structure.MutateSidechainsSelected(iters) local FiltersOff = behavior.GetFiltersDisabled() if FiltersOff then behavior.SetFiltersDisabled(false) end local SavedScore = current.GetScore() local NewScore = SavedScore save.Quicksave(OG.Slot) --print(" score after general mutate: "..SavedScore) --individually try substitutions on protected ones and save if better for segnum, value in pairs(ProtectList) do --print(" trying segment "..segnum) for jj, AA in pairs(OG.AllowedList[segnum]) do if structure.CanMutate(segnum, AA) then structure.SetAminoAcid(segnum, AA) NewScore = current.GetScore() if NewScore > SavedScore then save.Quicksave(OG.Slot) SavedScore = NewScore --print(" changed to "..AA..", new score "..SavedScore) end end end save.Quickload(OG.Slot) end behavior.SetFiltersDisabled(FiltersOff) for segnum, value in pairs(ProtectList) do selection.Select(segnum) end --print(" exit OG.MutateSelected") --if any changes, re-run mutate?? not at this point, because mutate is slow end ------------------------------------------------ -- END ORANGE GUARD ------------------------------------------------ function setCI(ci) return behavior.SetClashImportance(ci) end function wig(how, it, iters, minppi) behavior.SetSlowFiltersDisabled(true) if how==nil then how="wa" end --if minppi==nil then minppi=2 end --if iters==nil then iters=2 end if it==nil then it=10*ItMu end it=math.ceil(it) --if iters>0 then --iters=iters-1 --local sp=score() if how == "s" then if not AllAla() then structure.ShakeSidechainsAll(1) end elseif how == "wb" then structure.WiggleAll(it,true,false) elseif how == "ws" then structure.WiggleAll(it,false,true) elseif how == "wa" then structure.WiggleAll(it) end --if score()-sp > minppi and how ~= "s" then return wig(how, it, iters, minppi) end -- remove recursive wiggle, not needed since NewChapter --end behavior.SetSlowFiltersDisabled(false) end function Test() --p(" Test") save.Quicksave(93) recentbest.Save() sci=(math.random(maxCI*100)/100) setCI(sci) if (MutateOnce or MutateMany) then --p(" Mutate CI:", sci) selectMutables() --structure.MutateSidechainsSelected(1) OG.MutateSelected(1) Check() selection.DeselectAll() else --p(" Shake CI:", sci) wig('s') Check() end setCI(maxCI) wig() Check() setCI(maxCI/2) wig("wa",5) Check() setCI(maxCI) wig() Check() --qStab() --Susume - per tokens, comment this out for better speed when all you want is the mutates save.Quickload(93) setCI(maxCI) wig() Check() setCI(maxCI/2) wig("wa",5) Check() setCI(maxCI) wig() Check() recentbest.Restore() Check() if fuzt>=0 then if score()>(bestscore-fuzt) then Fuzit() end else if score()>=(bestscore+FF) then Fuzit() end end local FiltersOff = behavior.GetFiltersDisabled() behavior.SetFiltersDisabled(true) local UnfilteredScore = score() behavior.SetFiltersDisabled(false) local FilteredScore = score() local FilterBonus = FilteredScore - UnfilteredScore p("Current filter bonus/penalty = "..FilterBonus) p("Current score = "..FilteredScore) p("Best score = "..bestscore) behavior.SetFiltersDisabled(FiltersOff) --p(" exit Test") end function qStab() -- this is actually another type of fuze, not a quick stabilize setCI(maxCI/2) wig("wa",5) Check() setCI(maxCI) wig("s") Check() wig() Check() setCI(maxCI/2) wig("wa",5) Check() setCI(maxCI) wig() Check() wig('s') Check() wig() Check() end function Fuze(Shortfuze) --called only from the wrapper Fuzit() p(" Fuze, short = "..Shortfuze) Check() setCI(.05) wig("s") Check() setCI(maxCI) wig() Check() setCI(maxCI/3) wig("wa",5) Check() if not Shortfuze then setCI(.07) wig("s") Check() setCI(maxCI) wig() Check() setCI(maxCI/3) wig("wa",5) Check() end setCI(maxCI) wig("s") Check() wig() Check() p(" exit Fuze") end function mutaFuze(Shortfuze) --called only from the wrapper Fuzit() p(" mutaFuze, short = "..Shortfuze) setCI(0.15) selectMutables() structure.MutateSidechainsSelected(1) Check() selection.DeselectAll() setCI(maxCI) wig() Check() setCI(maxCI/3) wig("wa",4) Check() setCI(maxCI) wig() Check() if not Shortfuze then --setCI(0.2) --wig("s") --Check() --setCI(maxCI) --wig() --Check() setCI(maxCI/2) wig() Check() setCI(0.87*maxCI) selectMutables() structure.MutateSidechainsSelected(1) Check() selection.DeselectAll() end wig("wa",9) Check() p(" exit mutaFuze") end function Fuzit() --calls Fuze or mutaFuze with 50% chance of a relatively shorter fuze if (math.random(-100,100)>=0) then local Shortfuze=false else local Shortfuze=true end if MutateMany then mutaFuze(Shortfuze) else Fuze(Shortfuze) end end function Check() --p(" Check") if (bestscore < score()) then local gain = score() - bestscore bestscore = score() save.Quicksave(1) p(" ",cut(gain),"pts. New score ",bestscore) end end function AllAla() --returns true if the whole protein is alanine and/or glycine, --and therefore need not be shaken for i=1, structure.GetCount() do local Taa=structure.GetAminoAcid(i) if (Taa ~= 'a' and Taa ~= 'g') then return false --found a shakeable sidechain, no need to keep looking end end return true end function selectMutables() for i=1,nSegs do if structure.IsMutable(i) == true then selection.Select(i) end end end function End(errmsg) if done then return end done=true if string.find(errmsg,"Cancelled") then p("") p(" User cancel.") Result() p("") else Result() p("") p(errmsg) end OG.Cleanup() return errmsg end function Result() behavior.SetSlowFiltersDisabled(false) recentbest.Restore() Check() save.Quickload(1) Delbands() Tgain = (bestscore-startscore) if Tgain<0.008 then p(" No change.. :/ ") else p(" Startscore: "..cut(startscore)) p(" Score: "..cut(score())) p(" Total gain: "..cut(Tgain).." pts.") end setCI(maxCI) end function bandpull(minBS,maxBS) --p(" bandpull") if KeepBands then band.EnableAll() end local StartScore=score() local perc=math.random(80,200)/100 local loss=((perc*StartScore)/100) --p(" Min. loss: "..perc.."%, "..cut(loss),"points.") local lastBS=minBS for str=lastBS,maxBS, 0.1 do if KeepBandStrength then startband = oldbands+1 else startband = 1 end for i=startband, band.GetCount() do band.SetStrength(i, str) end wig('wb',5,1,500) -- wig extra params used: 1 means do not recurse the wiggle, -- 500 indicates how many points minimum change to recurse the wiggle, -- but the 1 overrides it so it doesn't recurse in any case if (StartScore-score()>=loss) or (score()>bestscore+1) then if band.GetCount()>(nSegs/10)*2 then lastBS=str-0.1 if lastBS<minBS then lastBS=minBS end else lastBS=minBS end break end end --p(" exit bandpull") end function bandage() --p(" bandage") if KeepBandStrength then startband = oldbands+1 else startband = 1 end if bloat==true then for i=startband, band.GetCount() do band.SetGoalLength(i,band.GetLength(i)+4) end else for i=startband, band.GetCount() do local leng=band.GetLength(i) local perc=math.random(20,50) local loss=((perc*leng)/100) band.SetGoalLength(i,band.GetLength(i)-loss) end end --p(" exit bandage") end function spacebands(amnt) --p(" spacebands") local zeBands=math.random(amnt)+Qbands if zeBands<1 then zeBands = 1 end while band.GetCount()<zeBands do segO = math.random(nSegs) OsegC=1 while structure.IsLocked(segO)==true do segO=math.random(nSegs) OsegC=OsegC+1 if OsegC>25 then break end end if ZL==true then rho=0.2 else rho=math.random(10) end theta = math.random(100,314.159)/100 phi = math.random(100,314.159)/100 if phi<1 then phi=phi+1 end if theta<1 then theta=theta+1 end if segO<=nSegs and segO>=1 then if segO==nSegs then segX = segO-1 segY = segO-2 elseif segO==1 then segX = segO+1 segY = segO+2 else segX = segO-1 segY = segO+1 end if segX>nSegs then segX=nSegs-1 end if segY>nSegs then segY=nSegs-1 end if segY<1 then segY=1 end if segX<1 then segX=1 end --[[ p(segX,"X") p(segY,"Y") p(segO,"O") p(theta,"theta") p(phi,"phi") ]] lb=band.Add(segO, segX, segY, rho, theta, phi) --local lb=band.GetCount() if ZL==true then band.SetGoalLength(lb,math.random(1)) band.SetStrength(lb,math.random(10)) else band.SetGoalLength(lb,math.random(band.GetLength(lb)*2)) end end end --p(" exit spacebands") end function Delbands() for db = band.GetCount(), oldbands+1, -1 do band.Delete(db) end end function Dia() if band.GetCount()~=0 then Bands=true end local HasMutables = false for i=1, nSegs do if structure.IsMutable(i) then HasMutables = true break end end opt = dialog.CreateDialog("Options.") opt.maxci=dialog.AddSlider("MaxCI:",maxCI,0.1,1,2) opt.Qq=dialog.AddCheckbox(" Quake.",true) opt.Bs=dialog.AddCheckbox(" BiS.",true) opt.Cmb=dialog.AddCheckbox(" Combine Quake and BiS.",false) opt.Sk=dialog.AddCheckbox(" Shock.",true) opt.Tg=dialog.AddCheckbox(" Tailgrab.",true) opt.fu = dialog.AddLabel("Fuzing threshold (negative value is gain)") opt.fuz = dialog.AddSlider("", -50, -100, 100, 1) if Bands then opt.KB=dialog.AddCheckbox("Keep original bands", true) opt.KBE=dialog.AddCheckbox("Keep enabled always",false) opt.KBSTR=dialog.AddCheckbox("Keep original strength and goal length", true) end if HasMutables then opt.mut=dialog.AddCheckbox("Mutate once, after bands",true) opt.muta=dialog.AddCheckbox("Mutate after bands and in fuze",false) -- once or twice randomly chosen every run end opt.ok = dialog.AddButton("Go go!",1) dialog.Show(opt) QQ=opt.Qq.value BiS=opt.Bs.value Shock=opt.Sk.value TG=opt.Tg.value Combo=opt.Cmb.value fuzt=opt.fuz.value maxCI=opt.maxci.value if Bands then KeepBands=opt.KB.value KeepBandsEnabled=opt.KBE.value KeepBandStrength=opt.KBSTR.value end if HasMutables then MutateOnce=opt.mut.value MutateMany=opt.muta.value end if fuzt<=0 then FF = (-1*fuzt) end return MutateOnce, MutateMany, maxCI, fuzt, FF, BiS, QQ, TG, Shock, Combo end function ZLb() if Combo==false then if BiS then p(" BiS ") for i=1, 2 do spacebands(nSegs/2) pci=(math.random(maxCI*100)/100) setCI(pci) --p(" Wiggle CI:", pci) bandpull(0.2,1) Delbands() if not KeepBandsEnabled then band.DisableAll() end Test() end --p(" exit BiS") end--bis end--combo false ZL=true if Shock then p(" Shock ") for u=1, 2 do spacebands(nSegs/2) pci=(math.random(maxCI*100)/100) setCI(pci) --p(" Wiggle CI:", pci) if KeepBands then band.EnableAll() end wig('wb',5,1) --wig extra param used to indicate not to recurse the wiggle Delbands() if not KeepBandsEnabled then band.DisableAll() end Test() end --p(" exit Shock") end ZL=false end function BandAcross() p(" TailGrab ") for i=1, nSegs do if structure.IsLocked(i)==false then first=i break end end for u=nSegs, 1, -1 do if structure.IsLocked(u)==false then last=u break end end band.AddBetweenSegments(first,last) bandage() pci=(math.random(maxCI*100)/100) setCI(pci) --p(" Wiggle CI:", pci) bandpull(0.2,1.4) Delbands() if not KeepBandsEnabled then band.DisableAll() end Test() RM=math.random(-100,100) if RM>=0 then bloat=false else bloat=true end band.AddBetweenSegments(nSegs/2,first) band.AddBetweenSegments(nSegs/2,last) bandage() pci=(math.random(maxCI*100)/100) setCI(pci) --p(" Wiggle CI:", pci) bandpull(0.2,1.4) Delbands() if not KeepBandsEnabled then band.DisableAll() end Test() --p(" end TailGrab") end function Quake() if Combo then p(" Combo ") for i=1, 4 do RM=math.random(-100,100) if RM>=0 then bloat=false else bloat=true end nrR=math.random(1, 19) for u=1, nrR do seg1=math.random(1,nSegs) seg2=math.random(1,nSegs) while structure.IsLocked(seg1) do seg1=math.random(1,nSegs) end while structure.IsLocked(seg2) do seg2=math.random(1,nSegs) end while seg1==seg2 do seg1=math.random(1,nSegs) end band.AddBetweenSegments(seg1,seg2) end bandage() Qbands=band.GetCount() spacebands(10) pci=(math.random(maxCI*100)/100) setCI(pci) --p(" Wiggle CI:", pci) bandpull(0.2,2) Delbands() if not KeepBandsEnabled then band.DisableAll() end end -- Combo for loop --p(" end Combo") else --not Combo p(" Quake ") for i=1, 2 do RM=math.random(-100,100) if RM>=0 then bloat=false else bloat=true end nrR=math.random(1, 19) for u=1, nrR do seg1=math.random(1,nSegs) seg2=math.random(1,nSegs) while structure.IsLocked(seg1) do seg1=math.random(1,nSegs) end while structure.IsLocked(seg2) do seg2=math.random(1,nSegs) end while seg1==seg2 do seg1=math.random(1,nSegs) end band.AddBetweenSegments(seg1,seg2) end -- u loop bandage() pci=(math.random(maxCI*100)/100) setCI(pci) --p(" Wiggle CI:", pci) bandpull(0.2,2) Delbands() if not KeepBandsEnabled then band.DisableAll() end end --quake loop --p(" end Quake") end --combo T/F Test() end function main() OG.Init() save.Quicksave(1) save.Quicksave(2) Dia() if not KeepBands then band.DeleteAll() oldbands=0 end while true do if QQ or Combo then Quake() end ZLb() if TG then BandAcross() end save.Quickload(1) end end err=xpcall(main,End)

Comments


RockOn Lv 1

Is this where one would click the 'show' checkbox when needing to see the 'core' issues?

And, again - why keep orange.

Thanks, for any help or clues.

Susume Lv 1

Orange Guard lets you protect orange sidechains that foldit wants to turn blue, by freezing those sidechains before you start the script. It will try to mutate those sidechains, but only to other orange ones.

Orange Guard will not score better than regular bandfuze, since it limits the mutations that foldit is allowed to try. The more sidechains you protect by freezing them, the more the score is limited. So why run it? It prevents foldit from producing a protein with a long stretch of only blue sidechains (say, an entire edge sheet, or more than one turn of a helix). The scientists generally don't pick a protein for testing in Rosetta if it has an entire blue sheet or a long stretch of blue helix, because they know the protein will not fold up as designed.

Use Orange Guard if getting your protein tested is more important to you than getting the top score. Better still, run Orange Guard in one track and the regular script in another track (you can use the same script, just don't freeze any sidechains first). Then you can have the best of both worlds.