Icon representing a recipe

Recipe: tlaloc Random Tug 4.00

created by Tlaloc

Profile


Name
tlaloc Random Tug 4.00
ID
38626
Shared with
Public
Parent
None
Children
Created on
February 14, 2012 at 06:07 AM UTC
Updated on
February 14, 2012 at 06:07 AM UTC
Description

Creates a band between two random segments and shakes out. Keeps trying different segments. Sometimes finds points that tlaloc cataclysm does not. Good script when you are at a local minimum and cannot find points anywhere else.

Best for


Code


-- tlaloc scripts 4.00 --=================================================================================================| -- You must keep the following attribution and notice in any republication of this script. Please -- remove the word 'tlaloc' from the script name on the fold.it web site recipe page if you -- publicly release a modification of the script. --======================================= -- Author: tlaloc (aka Greg Reddick) -- Copyright 2010-2012 by Greg Reddick -- Except for parts that are specifically excluded in the comments, which came from other sources, -- this script is licensed as follows: -- Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License -- http://creativecommons.org/licenses/by-nc-sa/3.0/ --======================================= -- Conventions used in this file can be found at: -- http://foldit.wikia.com/wiki/Tlaloc_Script_Standards --======================================= -- tlaloc standard library fsl = {} script = {} group = {} banding = {} ----------------------------------------- -- fsl (Foldit Standard Library) local _scoreRecentBest = -999999.9 local _initialized = false local _scoreStart = -999999.9 local _saveSlots = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} local _printStatus = true local _bandsAtStart = 0 local amino = {'a', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'y' } local function _BandAddBetweenSegments(segmentIndex1, segmentIndex2) fsl.Print('Adding band between segment '..segmentIndex1..' and '..segmentIndex2) band.AddBetweenSegments(segmentIndex1, segmentIndex2) end local function _BandAddRandom() local segmentCount = structure.GetCount() local x = math.random(1, segmentCount) local y repeat y = math.random(1, segmentCount) until math.abs(x - y) >= 2 fsl.BandAddBetweenSegments(x, y) return x, y end local function _BandDeleteScriptStart() fsl.Print('Deleting created bands') if fsl.BandsAtStart() == 0 then band.DeleteAll() else for i=band.GetCount(), fsl.BandsAtStart() + 1, -1 do band.Delete(i) end end end local function _BandDisable() fsl.Print('Disabling bands') band.DisableAll() end local function _BandDisableScriptStart() fsl.Print('Disabling created bands') if fsl.BandsAtStart() == 0 then band.DisableAll() else for i=fsl.BandsAtStart() + 1, band.GetCount() do band.Disable(i) end end end local function _BandEnable() fsl.Print('Enabling bands') band.EnableAll() end local function _BandEnableScriptStart() fsl.Print('Enabling created bands') if fsl.BandsAtStart() == 0 then band.EnableAll() else for i=fsl.BandsAtStart() + 1, band.GetCount() do band.Enable(i) end end end local function _BandStrength(strength) -- Just modifies all bands strengths. The UI only lets the strength go from 0.5 to 1.5, and -- it's tedious to modify a lot of bands. Great when you really, really want the backbone to -- move and it's being stubborn. fsl.Print('Setting band strength to '..strength) for i=1, band.GetCount() do band.SetStrength(i, strength) end end local function _BandsAtStart() return _bandsAtStart end local function _BlueFuse(iterations, sigma, ...) -- Based on vertex's BlueFuse -- This function is not covered by the Creative Commons license given at the start of the -- script since it a port of Vertex's BlueFuse algorithm, with some enhancements. local arg = {...} local saveSlot = fsl.RequestSaveSlot() local scoreStart = current.GetScore() local scoreBest = scoreStart save.Quicksave(saveSlot) fsl.SetBehaviorClashImportance(1.0) for i=1, #arg do fsl.SetBehaviorClashImportance(arg[i]) local printStatus = fsl.PrintStatus(false) fsl.Shake(1) fsl.SetBehaviorClashImportance(1.0) fsl.WiggleAll(iterations) fsl.MakeStable(false, sigma, iterations) fsl.PrintStatus(printStatus) local score = current.GetScore() if score > scoreBest then scoreBest = score save.Quicksave(saveSlot) fsl.ReportAndLockScoreIncrease() end end save.Quickload(saveSlot) fsl.ReleaseSaveSlot(saveSlot) local delta = current.GetScore() - scoreStart fsl.Print('Bluefuse complete. Score change='..delta) return delta end local function _ConvertToLoops() -- Converts the entire protein into loops, if it wasn't already all loops. It saves the -- original structure so that it can be retrieved pressing Ctrl+9. fsl.Print('Converting structure to loops') local countSegments = structure.GetCount() -- Only overwrite the saved structure if the current structure isn't all loops local nonLoops = false for i=1, countSegments do if structure.GetSecondaryStructure(i) ~= 'L' then nonLoops = true break end end if not nonLoops then save.SaveSecondaryStructure() end local structure = {} for i=1, countSegments do structure[i] = structure.GetSecondaryStructure(i) end selection.SelectAll() structure.SetSecondaryStructure('L') return structure end local function _FindBestStart() -- Performs a Select MultiStart, then shakes out each start to find the best one. assert(band.GetCount() == 0, 'Must delete existing bands\nbefore running this code.') local saveSlot = fsl.RequestSaveSlot() local scoreBest = -999999.9 local indexBest = 0 local scores = fsl.SelectMultiStart(500, false) local countTries = #scores for i=1, countTries do fsl.PrintTries('Find Best Start', i, countTries) fsl.Print('Current best is start #'..indexBest..' with score '..scoreBest) -- find start that has the score score while true do fsl.ResetPuzzle() if current.GetScore() == scores[i] then break end end fsl.ResetRecentBest() fsl.MakeStable(nil, .01, 1) fsl.BlueFuse(1, .01, .05, .07, .03) script.Settle(.1, 1, 1, 2, 1, 2, 2, 2) local score = current.GetScore() if score > scoreBest then scoreBest = score indexBest = i save.Quicksave(saveSlot) end end save.Quickload(saveSlot) fsl.ResetRecentBest() fsl.Print('Best start was #'..indexBest) fsl.ReleaseSaveSlot(saveSlot) end local function _FindCenterSegment() -- Finds the segment that is the least distance to all other segments -- returns index of the center segment fsl.Print('Finding the center segment') local segmentCount = structure.GetCount() local minDistance = 100000.0 local distance local indexCenter for i=1,segmentCount do distance = 0 for j=1,segmentCount do distance = distance + structure.GetDistance(i, j) end if(distance < minDistance) then minDistance = distance indexCenter = i end end return indexCenter end local function _FindMutatableSegments() local changeableSegments = {} for i=1, structure.GetCount() do if structure.IsMutable(i) then changeableSegments[#changeableSegments + 1] = i end end return changeableSegments end local function _FreezeAll() fsl.Print('Freezing all segments') selection.SelectAll() freeze.FreezeSelected(true, true) end local function _FreezeSegments(interval, start) fsl.Print('Freezing every '..interval..' segments') fsl.Print(' starting at segment '..start) selection.DeselectAll() for i=start, structure.GetCount(), interval do selection.Select(i) end freeze.FreezeSelected(true, true) end local function _GetScoreStart() return _scoreStart end local function _GetSegmentScores(segmentFirst, segmentLast) local score = 0 for i=segmentFirst, segmentLast do score = score + current.GetSegmentEnergyScore(i) end return score end local function _LocalRebuild(iterations) structure.RebuildSelected(iterations) fsl.ReportAndLockScoreIncrease() end local function _LocalWiggleInterval(interval, start, iterations) local saveSlot = fsl.RequestSaveSlot() fsl.Print('LocalWiggle every '..interval..' segments') fsl.Print(' starting at segment '..start) local first local segmentCount = structure.GetCount() for i=start, segmentCount, interval do selection.DeselectAll() local first = i if first < 1 then first = 1 end local last = i + interval if last > segmentCount then last = segmentCount end selection.SelectRange(first, last) local score = current.GetScore() save.Quicksave(saveSlot) structure.LocalWiggleAll(iterations) if current.GetScore() <= score then save.Quickload(saveSlot) end fsl.ReportAndLockScoreIncrease() end fsl.ReleaseSaveSlot(saveSlot) end local function _MakeDeNovo() assert(band.GetCount() == 0, 'Must delete existing bands\nbefore running this code.') save.Quicksave(1) fsl.SetPristine() fsl.SetBehaviorClashImportance(0) fsl.BandAddBetweenSegments(1, structure.GetCount()) band.SetGoalLength(i, 3000.0) band.SetStrength(i, 10.0) for i=1, 10 do fsl.Shake(1) fsl.WiggleAll(1) end fsl.BandDeleteScriptStart() fsl.SetBehaviorClashImportance(1.0) end local _shakesWin = 0 local _wigglesWin = 0 local _tiesWin = 0 local function _MakeStable(shakeFirst, sigmaStableScore, iterations) -- shakeFirst -- if true shakes before wiggling -- if false wiggles before shaking -- if nil, tries it both ways and takes the best score local saveSlotOriginal = fsl.RequestSaveSlot() local saveSlotShake = fsl.RequestSaveSlot() local prevScore = 0 local delta local score if shakeFirst == nil then save.Quicksave(saveSlotOriginal) fsl.Print('Trying shake first') local scoreShakeFirst = fsl.MakeStable(true, sigmaStableScore, iterations) save.Quicksave(saveSlotShake) save.Quickload(saveSlotOriginal) fsl.Print('Trying wiggle first') local scoreWiggleFirst = fsl.MakeStable(false, sigmaStableScore, iterations) fsl.Print('Shake='..scoreShakeFirst..' Wiggle='..scoreWiggleFirst) if scoreShakeFirst > scoreWiggleFirst then _shakesWin = _shakesWin + 1 fsl.Print('Restoring shake result') save.Quickload(saveSlotShake) else if scoreShakeFirst == scoreWiggleFirst then _tiesWin = _tiesWin + 1 else _wigglesWin = _wigglesWin + 1 end fsl.Print('Keeping wiggle result') end fsl.Print('Shakes win='.._shakesWin..' Wiggles win='.._wigglesWin..' ties='.._tiesWin) else repeat local printStatus = fsl.PrintStatus(false) if shakeFirst then fsl.Shake(1) fsl.WiggleBackbone(iterations) else fsl.WiggleBackbone(iterations) fsl.Shake(1) end fsl.PrintStatus(printStatus) score = current.GetScore() delta = math.abs(score - prevScore) if prevScore ~= 0 then fsl.Print('delta='..delta..' goal='..sigmaStableScore) end prevScore = score until delta <= sigmaStableScore fsl.WiggleSidechains(iterations) end fsl.ReleaseSaveSlot(saveSlotShake) fsl.ReleaseSaveSlot(saveSlotOriginal) return current.GetScore() end local function _Mutate(iterations) fsl.Print('Mutating for '..iterations..' iterations') structure.MutateSidechainsAll(iterations) fsl.ReportAndLockScoreIncrease() end local function _Print(...) if _printStatus then print(...) end end local function _PrintStatus(status) local prevStatus = _printStatus _printStatus = status return prevStatus end local function _PrintLine() fsl.Print('--------------------------------------------------') end local function _PrintTries(functionName, try, tries, keyword) if keyword == nil then keyword = 'try' end if tries == nil then fsl.Print('**** '..functionName..' '..keyword..' '..try..' ****') else fsl.Print('**** '..functionName..' '..keyword..' '..try..' of '..tries..' ****') end end local function _ReleaseSaveSlot(slot) _saveSlots[#_saveSlots + 1] = slot end local function _ReportAndLockScoreIncrease() local score = recentbest.GetScore() if score > _scoreRecentBest then recipe.ReportStatus() _scoreRecentBest = score end end local function _ReportScoreImprovement(scoreRecentBest) if scoreRecentBest == nil then scoreRecentBest = recentbest.GetScore() end recipe.ReportStatus() local improvement = scoreRecentBest - fsl.GetScoreStart() return improvement end local function _RequestSaveSlot() assert(#_saveSlots > 0, 'Out of save slots') local saveSlot = _saveSlots[#_saveSlots] _saveSlots[#_saveSlots] = nil return saveSlot end local function _ResetPuzzle() fsl.Print('Resetting puzzle') puzzle.StartOver() end local function _ResetRecentBest() fsl.Print('Saving recent best') recentbest.Save() _scoreRecentBest = current.GetScore() end local function _RestoreOriginalStructure() -- Resets to the structure available at the time the puzzle is reset. Since alignment tool -- applies structure after that time, this will not recover that structure. Furthermore, this -- works randomly on puzzles that are multistart, where it always takes the reset structure, -- which is random. If the original structure is all loops, then it refuses to do anything, -- and will keep the current structure. fsl.Print('Restoring original structure') local saveSlot = fsl.RequestSaveSlot() save.Quicksave(saveSlot) fsl.ResetPuzzle() local allLoops = true for i=1, structure.GetCount() do if structure.GetSecondaryStructure(i) ~= "L" then allLoops = false break end end if allLoops then save.Quickload(saveSlot) else save.SaveSecondaryStructure() save.Quickload(saveSlot) save.LoadSecondaryStructure() end fsl.ReleaseSaveSlot(saveSlot) end local function _RestoreRecentBest() fsl.Print('Restoring recent best') recentbest.Restore() end local function _RestoreStructure(structure) fsl.Print('Restoring structure') for i=1, structure.GetCount() do selection.DeselectAll() selection.Select(i) structure.SetSecondaryStructure(structure[i]) end end local function _Round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end local function _ScriptBegin(functionName) recipe.SectionStart(functionName) fsl.ReportAndLockScoreIncrease() return functionName, current.GetScore() end local function _ScriptEnd(functionName, scoreStart, noRestore, functionExecute, ...) if not noRestore then fsl.RestoreRecentBest() end local delta = current.GetScore() - scoreStart recipe.ReportStatus() fsl.Print(functionName..' complete. Score change='..delta) if functionExecute ~= nil then functionExecute(...) fsl.ResetRecentBest() end recipe.SectionEnd() return delta end local function _ScriptFinalize() recipe.SectionEnd() assert(#_saveSlots == 10, 'One or more save slots not released') end local function _ScriptInitialize() assert(not _initialized, 'Initialized more than once') _initialized = true math.randomseed(recipe.GetRandomSeed()) _scoreStart = current.GetScore() _bandsAtStart = band.GetCount() fsl.ResetRecentBest() recipe.SectionStart("Script Start") return _scoreStart end local function _SelectMultiStart(tries, saveStart, start) -- This script figures out how many different starts there are, and saves them into the -- quickload save spots. You can use ctrl+1, ctrl+2, or ctrl+3 to load the first 3 after -- running this script. You can also change the parameter to SelectMultiStart to select ones -- that appear beyond the first 3. assert(band.GetCount() == 0, 'Must delete existing bands\nbefore running this code.') local puzzle = {} local scores = {} local count = 0 fsl.SetPristine() fsl.ResetRecentBest() -- Find the unique starting scores for i=1, tries do fsl.ResetPuzzle() local score = current.GetScore() if puzzle[score] == nil then count = count + 1 puzzle[score] = count scores[count] = score end end -- Bubble sort to sort by score. Inefficient, but -- I don't care because the number will always be -- small. for i=1,count - 1 do for j = count, i + 1, -1 do if scores[i] < scores[j] then scores[j], scores[i] = scores[i], scores[j] puzzle[scores[j]] = i puzzle[scores[i]] = j end end end if saveStart then for i=1, count do fsl.Print('puzzle #'..i..' has score '..scores[i]) if i < 10 then while true do fsl.ResetPuzzle() if current.GetScore() == scores[i] then save.Quicksave(i) break end end end end if start ~= nil then if start > count then start = count fsl.Print('There are only '..count..' number of starts.') end fsl.Print('Loading start #'..start) save.Quickload(start) else fsl.RestoreRecentBest() end else fsl.RestoreRecentBest() end fsl.Print('There are '..count..' starts') return scores end local function _SetBehaviorClashImportance(importance) fsl.Print('Setting clash importance to '..importance) behavior.SetClashImportance(importance) end local function _SetPristine(noClash, noUnfreeze, noDeleteBands, noSelectAll) -- Clean up the environment local printStatus = fsl.PrintStatus(false) if not noClash then fsl.SetBehaviorClashImportance(1.0) end if not noUnfreeze then fsl.UnfreezeAll() end if not noDeleteBands then band.DeleteAll() _bandsAtStart = 0 end if not noSelectAll then selection.DeselectAll() selection.SelectAll() end fsl.PrintStatus(printStatus) end local function _Shake(iterations) fsl.Print('Shaking sidechains for '..iterations..' iterations') structure.ShakeSidechainsAll(iterations) fsl.ReportAndLockScoreIncrease() end local function _UnfreezeAll() fsl.Print('Unfreezing all segments') freeze.UnfreezeAll() end local function _WiggleAll(iterations) fsl.Print('Wiggle all for '..iterations..' iterations') structure.WiggleAll(iterations) fsl.ReportAndLockScoreIncrease() end local function _WiggleBackbone(iterations) fsl.Print('Wiggle backbone for '..iterations..' iterations') structure.WiggleAll(iterations, true, false) fsl.ReportAndLockScoreIncrease() end local function _WiggleSidechains(iterations) fsl.Print('Wiggle sidechains for '..iterations..' iterations') structure.WiggleAll(iterations, false, true) fsl.ReportAndLockScoreIncrease() end fsl = { BandAddBetweenSegments = _BandAddBetweenSegments, BandAddRandom = _BandAddRandom, BandDeleteScriptStart = _BandDeleteScriptStart, BandDisable = _BandDisable, BandDisableScriptStart = _BandDisableScriptStart, BandEnable = _BandEnable, BandEnableScriptStart = _BandEnableScriptStart, BandStrength = _BandStrength, BandsAtStart = _BandsAtStart, BlueFuse = _BlueFuse, ConvertToLoops = _ConvertToLoops, FindBestStart = _FindBestStart, FindCenterSegment = _FindCenterSegment, FindMutatableSegments = _FindMutatableSegments, FreezeAll = _FreezeAll, FreezeSegments = _FreezeSegments, GetScoreStart = _GetScoreStart, GetSegmentScores = _GetSegmentScores, LocalRebuild = _LocalRebuild, LocalWiggleInterval = _LocalWiggleInterval, MakeDeNovo = _MakeDeNovo, MakeStable = _MakeStable, Mutate = _Mutate, Print = _Print, PrintLine = _PrintLine, PrintStatus = _PrintStatus, PrintTries = _PrintTries, ReleaseSaveSlot = _ReleaseSaveSlot, RequestSaveSlot = _RequestSaveSlot, ReportAndLockScoreIncrease = _ReportAndLockScoreIncrease, ReportScoreImprovement = _ReportScoreImprovement, ResetPuzzle = _ResetPuzzle, ResetRecentBest = _ResetRecentBest, RestoreOriginalStructure = _RestoreOriginalStructure, RestoreRecentBest = _RestoreRecentBest, RestoreStructure = _RestoreStructure, Round = _Round, ScriptBegin = _ScriptBegin, ScriptEnd = _ScriptEnd, ScriptFinalize = _ScriptFinalize, ScriptInitialize = _ScriptInitialize, SelectMultiStart = _SelectMultiStart, SetBehaviorClashImportance = _SetBehaviorClashImportance, SetPristine = _SetPristine, Shake = _Shake, UnfreezeAll = _UnfreezeAll, WiggleAll = _WiggleAll, WiggleBackbone = _WiggleBackbone, WiggleSidechains = _WiggleSidechains, } -- End fsl (Foldit Standard Library) ------------------------------------------------- -- Banding library local function _CreateBandsToCenter() -- Partly based on some ideas in 'Bands from center' by srssmith92 fsl.Print('Creating bands to center') local indexCenter = fsl.FindCenterSegment() fsl.BandDisable() for i=1, structure.GetCount() do if(i ~= indexCenter) then -- If hydrophobic if structure.IsHydrophobic(i) then fsl.BandAddBetweenSegments(i,indexCenter) end end end end local function _CreateRandomBands() fsl.Print('Creating random bands') fsl.BandDisable() for i=1, math.floor(structure.GetCount()/4) do fsl.BandAddRandom() end end local function _CreateHydrophobeBands() fsl.Print('Creating hydrophobe bands') local countSegments = structure.GetCount() fsl.BandDisable() for x=1, countSegments do if structure.IsHydrophobic(x) then for y=x+2, countSegments do if structure.IsHydrophobic(y) then fsl.BandAddBetweenSegments(x, y) end end end end end local banding = { CreateBandsToCenter = _CreateBandsToCenter, CreateRandomBands = _CreateRandomBands, CreateHydrophobeBands = _CreateHydrophobeBands, } -- End banding library ------------------------------------------------- -- End tlaloc standard library --=============================================== ------------------------------------------------- -- tlaloc BandStrength --[[ Allows you to set the band strength of all current bands. --]] local function _BandStrengthDialog() if band.GetCount() > 0 then local ask = dialog.CreateDialog("tlaloc BandStrength") ask.Comment = dialog.AddLabel("Set all current bands to this strength") ask.Strength = dialog.AddSlider("Strength", 1, .1, 10, 1) ask.OK = dialog.AddButton("Change", 1) ask.Cancel = dialog.AddButton("Cancel", 0) if (dialog.Show(ask) > 0) then fsl.BandStrength(ask.Strength.value) end else local tell = dialog.CreateDialog("tlaloc BandStrength") tell.Message = dialog.AddLabel("There are no bands to change.") tell.OK = dialog.AddButton("Close", 0) dialog.Show(tell) end end ------------------------------------------------- -- tlaloc Cataclysm --[[ Works the same as tlaloc contract, but uses random bands instead of bands to center. --]] local function _Cataclysm(tries) local functionName, scoreStart = fsl.ScriptBegin('tlaloc Cataclysm') for i=1,tries do fsl.PrintTries(functionName, i, tries) script.RepeatContract(7, .03, 10, .03, 1, 1, banding.CreateRandomBands) script.RepeatBlueFuse(1, .01, .05, .07, .03) end return fsl.ScriptEnd(functionName, scoreStart, false) end local function _CataclysmDialog() local ask = dialog.CreateDialog("tlaloc Cataclysm") ask.Label1 = dialog.AddLabel("Make this many different contractions") ask.Tries = dialog.AddSlider("Tries", 4, 1, 10, 0) ask.OK = dialog.AddButton("Start", 1) ask.Cancel = dialog.AddButton("Cancel", 0) if dialog.Show(ask) > 0 then _Cataclysm(ask.Tries.value) end end ------------------------------------------------- -- tlaloc Contract --[[ Contracts bands and releases finding points. Works iteratively until no points are to be found. --]] local function _SetEnableBands(startStrength, changeScore, deltaStrength) local strength = startStrength local score = nil local delta = nil local startScore = current.GetScore() repeat fsl.Print('Bands strength='..strength) for i=fsl.BandsAtStart() + 1, band.GetCount() do band.SetStrength(i, strength) end fsl.WiggleBackbone(1) score = current.GetScore() delta = math.abs(score - startScore) strength = strength + deltaStrength if strength > 10.0 then -- no amount of strength will get it to move strength = 10.0 break end until delta >= changeScore strength = strength - deltaStrength return strength end local contractprocs = { SetEnableBands = _SetEnableBands, } local strengthContract local function _Contract(sigmaStableScore, changeScore, deltaStrength, strengthBackoffMultiplier, iterations, shakeFirst, repeating, bandingMethod) -- sigmaStableScore is the maximum amount of score change for the structure to be consider stable. -- changeScore is the minimum amount of score change for there to be a significant change in the structure of the protein. -- deltaStrength is the amount of strength of bands added on each iteration. Smaller values take longer, larger values may cause too much change. -- strengthBackoffMultiplier is the amount that it reduces the strength that it moved on the last pass for the next pass. -- iterations is the parameter to the wiggle and shakes -- shakeFirst is whether it should shake before wiggling -- repeating is set to true when this function will be called multiple times without resetting in between -- bandingMethod is a reference to the function that establishes the bands local functionName, scoreStart = fsl.ScriptBegin('tlaloc Contract') if not repeating then if bandingMethod ~= nil then bandingMethod() end strengthContract = 0 end fsl.BandEnableScriptStart() strengthContract = strengthContract - (strengthBackoffMultiplier * deltaStrength) if strengthContract < 0 then strengthContract = 0 end strengthContract = contractprocs.SetEnableBands(strengthContract, changeScore, deltaStrength) fsl.BandDisableScriptStart() fsl.MakeStable(shakeFirst, sigmaStableScore, iterations) return fsl.ScriptEnd(functionName, scoreStart, repeating) end local function _RepeatContract(tries, sigmaStableScore, changeScore, deltaStrength, strengthBackoffMultiplier, iterations, bandingMethod) -- tries is the number of contractions without finding points before it gives up -- sigmaStableScore is the maximum amount of score change for the structure to be consider stable. -- changeScore is the minimum amount of score change for there to be a significant change in the structure of the protein. -- deltaStrength is the amount of strength of bands added on each iteration. Smaller values take longer, larger values may cause too much change. -- strengthBackoffMultiplier is the amount that it reduces the strength that it moved on the last pass for the next pass. -- iterations is the parameter to the wiggle and shakes -- bandingMethod is a reference to the function that establishes the bands local functionName, scoreStart = fsl.ScriptBegin('tlaloc Repeat Contract') if bandingMethod ~= nil then bandingMethod() end strengthContract = 0 local foundpoints local scoreBefore = scoreStart repeat foundpoints = false for try=1, tries do fsl.PrintLine() fsl.PrintTries(functionName, try, tries) _Contract(sigmaStableScore, changeScore, deltaStrength, strengthBackoffMultiplier, iterations, tries % 2 == 0, true, 0) local score = current.GetScore() local delta = score - scoreBefore if delta > 0 then foundpoints = true scoreBefore = score fsl.Print('Found '..delta..' points, starting over') break end end until not foundpoints fsl.WiggleSidechains(20) return fsl.ScriptEnd(functionName, scoreStart, false, fsl.BandDeleteScriptStart) end local function _ContractDialog() --script.RepeatContract(7, .03, 10, .03, 1, 1, banding.CreateBandsToCenter) -- tries is the number of contractions without finding points before it gives up -- sigmaStableScore is the maximum amount of score change for the structure to be consider stable. -- changeScore is the minimum amount of score change for there to be a significant change in the structure of the protein. -- deltaStrength is the amount of strength of bands added on each iteration. Smaller values take longer, larger values may cause too much change. -- strengthBackoffMultiplier is the amount that it reduces the strength that it moved on the last pass for the next pass. -- iterations is the parameter to the wiggle and shakes -- bandingMethod is a reference to the function that establishes the bands local ask = dialog.CreateDialog("tlaloc Contract") ask.TriesLabel = dialog.AddLabel("# of contractions with no points found before giving up") ask.Tries = dialog.AddSlider("Tries", 7, 1, 100, 0) ask.SigmaStableScoreLabel = dialog.AddLabel("Max score change for the structure to be stable") ask.SigmaStableScore = dialog.AddSlider("Stable Score", .03, .01, 1.00, 2) ask.ChangeScoreLabel1 = dialog.AddLabel("Min score change for there to be significant") ask.ChangeScoreLabel2 = dialog.AddLabel("change in the structure of the protein") ask.ChangeScore = dialog.AddSlider("Change Score", 10, 1, 100, 0) ask.DeltaStrengthLabel = dialog.AddLabel("Strength of bands to add on each iteration") ask.DeltaStrength = dialog.AddSlider("Delta", .03, .01, .25, 2) ask.BackoffMultiplierLabel = dialog.AddLabel("Multiple of Delta to reduce band strength each pass") ask.BackoffMultiplier = dialog.AddSlider("Back off", 1, 1, 10, 0) ask.IterationsLabel = dialog.AddLabel("# of iterations to perform on wiggles and shakes") ask.Iterations = dialog.AddSlider("Iterations", 1, 1, 25, 0) ask.OK = dialog.AddButton("Start", 1) ask.Cancel = dialog.AddButton("Cancel", 0) if dialog.Show(ask) > 0 then _RepeatContract(ask.Tries.value, ask.SigmaStableScore.value, ask.ChangeScore.value, ask.DeltaStrength.value, ask.BackoffMultiplier.value, ask.Iterations.value, banding.CreateBandsToCenter) end end ------------------------------------------------- -- tlaloc Helixer --[[ Tries to create regularly spaced helixes using bands. --]] local function _Helixer(spacing, strengthStart, strengthIncrement, iterations) local functionName, scoreStart = fsl.ScriptBegin('tlaloc Helixer') local countSegments = structure.GetCount() assert(band.GetCount() == 0, 'Must delete existing bands\nbefore running this code.') local bandStrength = strengthStart local bands = {} for i = 1, countSegments do if structure.GetSecondaryStructure(i) == 'H' then if i + 3 <= countSegments then local helix = true for dest = i+1, i+3 do if structure.GetSecondaryStructure(dest) ~= 'H' then helix = false break end end if helix then fsl.BandAddBetweenSegments(i, i+3) bands[#bands + 1] = {First = i, Last = i+3} band.SetStrength(band.GetCount(), bandStrength) band.SetGoalLength(band.GetCount(), spacing) end end end end while true do fsl.MakeStable(true, .1, iterations) local allFixed = true bandStrength = bandStrength + strengthIncrement if bandStrength > 10 then break end for i = 1, #bands do local distance = structure.GetDistance(bands[i].First, bands[i].Last) fsl.Print('Band '..i..' distance='..distance) if math.abs(spacing - distance) > .1 then fsl.Print('Changing band '..i..' '..bands[i].First..'-'..bands[i].Last..' to '..bandStrength) band.SetStrength(i, bandStrength) allFixed = false end end if allFixed then break end end return fsl.ScriptEnd(functionName, scoreStart, true) end local function _HelixerDialog() if band.GetCount() > 0 then local tell = dialog.CreateDialog("tlaloc Helixer") tell.Error = dialog.AddLabel("Must delete all existing bands before running.") tell.OK = dialog.AddButton("Cancel", 0) dialog.Show(tell) else local ask = dialog.CreateDialog("tlaloc Helixer") ask.Label = dialog.AddLabel("Tries to create regularly spaced helixes using bands.") ask.SpacingLabel = dialog.AddLabel("Maintain this spacing between bands") ask.Spacing = dialog.AddSlider("Spacing", 5.5, .01, 10, 1) ask.StrengthStartLabel = dialog.AddLabel("Start at this band strength") ask.StrengthStart = dialog.AddSlider("Strength", 1.0, 0.1, 10.0, 1) ask.StrengthIncrementLabel = dialog.AddLabel("Increment strength by this much") ask.StrengthIncrement = dialog.AddSlider("Increment", 1.0, 0.1, 10.0, 1) ask.IterationsLabel = dialog.AddLabel("Wiggle and shake for this many iterations") ask.Iterations = dialog.AddSlider("Iterations", 10, 1, 25, 0) ask.OK = dialog.AddButton("Start", 1) ask.Cancel = dialog.AddButton("Cancel", 0) if dialog.Show(ask) > 0 then _Helixer(ask.Spacing.value, ask.StrengthStart.value, ask.StrengthIncrement.value, ask.Iterations.value) end end end ------------------------------------------------- -- tlaloc Hydrophobe --[[ Pushes out hydrophyllic segments, pulls in hydrophobic segments. Good after threading to stabilize. Also good when stuck. --]] local function _Hydrophobe(expand, percentBands) local functionName, scoreStart = fsl.ScriptBegin('tlaloc Hydrophobe') fsl.BandDisable() local countSegments = structure.GetCount() for x=1, countSegments - 2 do for y = x + 2, countSegments do local isHydrophobicX = structure.IsHydrophobic(x) local isHydrophobicY = structure.IsHydrophobic(y) if (isHydrophobicX == isHydrophobicY) and (math.random() <= percentBands) then fsl.BandAddBetweenSegments(x, y) local bandLast = band.GetCount() local distance = structure.GetDistance(x, y) if isHydrophobicX then band.SetGoalLength(bandLast, distance - expand) else band.SetGoalLength(bandLast, distance + expand) end end end end fsl.WiggleBackbone(1) fsl.BandDeleteScriptStart() fsl.MakeStable(false, .01, 1) fsl.BlueFuse(1, .01, .05, .07, .03) return fsl.ScriptEnd(functionName, scoreStart, true, fsl.BandDeleteScriptStart) end local function _HydrophobeDialog() local ask = dialog.CreateDialog("tlaloc Hydrophobe") ask.Label1 = dialog.AddLabel("Pushes hydrophilic segments out") ask.Label2 = dialog.AddLabel("and hydrophobic segments in") ask.ExpandLabel = dialog.AddLabel("Push or pull segments by this amount") ask.Expand = dialog.AddSlider("Expand", 1, .1, 10, 1) ask.PercentLabel = dialog.AddLabel("Percentage of bands") ask.Percent = dialog.AddSlider("Percent", 10, 1, 100, 0) ask.OK = dialog.AddButton("Start", 1) ask.Cancel = dialog.AddButton("Cancel", 0) if dialog.Show(ask) > 0 then _Hydrophobe(ask.Expand.value, ask.Percent.value / 100) end end ------------------------------------------------- -- tlaloc MutateAll --[[ Only useful on design puzzles. Mutates every mutatable segment to every possibility, then shakes out. Do not stop the script during the first part of the run (see output) as it will leave the segments in a bad state. Time to run is proportional to the number of mutatable segments. --]] local function _MutateAll(iterations) local functionName, scoreStart = fsl.ScriptBegin('tlaloc MutateAll') local saveSlot = fsl.RequestSaveSlot() local countSegments = structure.GetCount() - 1 --BUG in foldit requires the -1 local changeableSegments = fsl.FindMutatableSegments() local originalSegments = {} for i=1, countSegments do originalSegments[i] = {AA=structure.GetAminoAcid(i), Score=0} end -- Shake out the protein before starting, otherwise it will be inaccurate fsl.MakeStable(true, 1, 5) --[[ for i=1, #changeableSegments do selection.DeselectAll() selection.Select(changeableSegments[i]) structure.SetAminoAcid('g') end --]] local randomSegments = {} while #randomSegments < #changeableSegments do local i = math.random(1, #changeableSegments) if changeableSegments[i] ~= 0 then randomSegments[#randomSegments + 1] = changeableSegments[i] changeableSegments[i] = 0 end end fsl.ResetRecentBest() local scorePrevious = current.GetScore() for i=1, #randomSegments do local segment = randomSegments[i] fsl.PrintTries('Mutating', i, #randomSegments, 'segment') local aa = structure.GetAminoAcid(segment) fsl.Print('Segment #'..segment..' is '..aa) for iAmino=1, #amino do if aa ~= amino[iAmino] then selection.DeselectAll() selection.Select(segment) fsl.Print(i..' Trying amino acid '..iAmino..' '..amino[iAmino]) structure.SetAminoAcid(segment, amino[iAmino]) fsl.MakeStable(true, .1, 1) -- Loop until it iterates over all sidechains without finding any points local tryagain repeat tryagain = false local scoreBeforeSidechains = current.GetScore() local scoreRecentBestBeforeSidechains = recentbest.GetScore() local positions= rotamer.GetCount(segment) for iSidechains=1, positions do fsl.PrintTries('Sidechain', iSidechains, positions, 'position') rotamer.SetRotamer(segment, iSidechains) save.Quicksave(saveSlot) local printStatus = fsl.PrintStatus(false) fsl.WiggleAll(iterations) fsl.PrintStatus(printStatus) local scoreCur = current.GetScore() local delta = scoreCur - scoreBeforeSidechains local scoreRecentBest = recentbest.GetScore() local deltaRecentBest = scoreRecentBest - scoreRecentBestBeforeSidechains --[[ fsl.Print('scoreCur='..scoreCur) fsl.Print('scoreBeforeSidechains='..scoreBeforeSidechains) fsl.Print('delta='..delta) --]] if delta <= 0.1 and deltaRecentBest <= 0 then save.Quickload(saveSlot) else fsl.Print('Score improved by '..delta..', trying sidechains again') fsl.Print('Score='..scoreCur..' Best='..scoreRecentBest) tryagain = true break end end until not tryagain fsl.ReportAndLockScoreIncrease() fsl.RestoreRecentBest() local score = current.GetScore() if score > scorePrevious then originalSegments[segment].Score = originalSegments[segment].Score + (score - scorePrevious) scorePrevious = score end fsl.ReportScoreImprovement() end end for i=1, countSegments do local aa = structure.GetAminoAcid(i) if aa ~= originalSegments[i].AA or originalSegments[i].Score ~= 0 then fsl.Print('Segment #'..i..' '..originalSegments[i].AA..'->'..aa..' improved '..originalSegments[i].Score) end end end fsl.ReleaseSaveSlot(saveSlot) return fsl.ScriptEnd(functionName, scoreStart, true) end local function _MutateAllDialog() local ask = dialog.CreateDialog("tlaloc Mutate All") ask.Label = dialog.AddLabel("Mutate all mutable segments") ask.IterationsLabel = dialog.AddLabel("Number of iterations for WiggleAll") ask.Iterations = dialog.AddSlider("Iterations", 1, 1, 25, 0) ask.OK = dialog.AddButton("Start", 1) ask.Cancel = dialog.AddButton("Cancel", 0) if dialog.Show(ask) > 0 then _MutateAll(ask.Iterations.value) end end ------------------------------------------------- -- tlaloc Push --[[ Uses bands to "inflate" the protein, moving everything away from everything else, then shaking out. Similar to tlaloc hydrophobe, but does not try to manipulate the hydrophobic segments. Good in the mid-game when stuck at a local minimum. Unlike most of my scripts, this one does not restore to the starting score if it does not exceed it, letting you try other manipulation from where the script finishes. Manually Undo Restore Rcnt Best to get to the best score since it started. --]] local function _Push(expand, percentBands) local functionName, scoreStart = fsl.ScriptBegin('tlaloc Push') fsl.BandDisable() local countSegments = structure.GetCount() for x=1, countSegments - 2 do if not structure.IsHydrophobic(x) then for y = x + 2, countSegments do if (not structure.IsHydrophobic(y)) and (math.random() <= percentBands) then local distance = structure.GetDistance(x, y) fsl.BandAddBetweenSegments(x, y) local bandLast = band.GetCount() band.SetStrength(bandLast, 10.0) band.SetGoalLength(bandLast, distance + expand) end end end end fsl.WiggleBackbone(1) fsl.BandDeleteScriptStart() fsl.MakeStable(false, .01, 1) fsl.BlueFuse(1, .01, .05, .07, .03) return fsl.ScriptEnd(functionName, scoreStart, true, fsl.BandDeleteScriptStart) end local function _PushDialog() local ask = dialog.CreateDialog("tlaloc Push") ask.Label = dialog.AddLabel("Uses bands to 'inflate' the protein") ask.ExpandLabel = dialog.AddLabel("Push or pull segments by this amount") ask.Expand = dialog.AddSlider("Expand", 1, .1, 10, 1) ask.PercentLabel = dialog.AddLabel("Percentage of bands") ask.Percent = dialog.AddSlider("Percent", 10, 1, 100, 0) ask.OK = dialog.AddButton("Start", 1) ask.Cancel = dialog.AddButton("Cancel", 0) if dialog.Show(ask) > 0 then _Push(ask.Expand.value, ask.Percent.value / 100) end end ------------------------------------------------- -- Repeat BlueFuse --[[ Repeats vertex's Blue Fuse algorithm until no point are found. BlueFuse alters the clashing importance to different values, wiggles, then sets the clashing importance to 1 and shakes out. --]] local function _RepeatBlueFuse(iterations, sigma, ...) local functionName, scoreStart = fsl.ScriptBegin('tlaloc Repeat BlueFuse') local try = 0 repeat try = try + 1 fsl.PrintLine() fsl.PrintTries(functionName, try) until math.abs(fsl.BlueFuse(iterations, sigma, ...)) <= sigma return fsl.ScriptEnd(functionName, scoreStart, false) end local function _RepeatBlueFuseDialog() local ask = dialog.CreateDialog("tlaloc Repeat Blue Fuse") ask.IterationsLabel = dialog.AddLabel("Number of iterations to wiggle and shake") ask.Iterations = dialog.AddSlider("Iterations", 1, 1, 25, 0) ask.SigmaLabel = dialog.AddLabel("Stop when point gain less than this") ask.Sigma = dialog.AddSlider("Score", .01, .001, .1, 3) ask.ClashImportanceLabel = dialog.AddLabel("Set the clashing importance these values:") ask.ClashImportance1 = dialog.AddSlider("Clash1", .05, .01, 1.00, 2) ask.ClashImportance2 = dialog.AddSlider("Clash2", .07, .01, 1.00, 2) ask.ClashImportance3 = dialog.AddSlider("Clash3", .03, .01, 1.00, 2) ask.OK = dialog.AddButton("Start", 1) ask.Cancel = dialog.AddButton("Cancel", 0) if dialog.Show(ask) > 0 then _RepeatBlueFuse(ask.Iterations.value, ask.Sigma.value, ask.ClashImportance1.value, ask.ClashImportance2.value, ask.ClashImportance3.value) end end ----------------------------------------- -- tlaloc Random Tug --[[ Creates a band between two random segments and shakes out. Keeps trying different segments. Sometimes finds points that tlaloc cataclysm does not. Good script when you are at a local minimum and cannot find points anywhere else. --]] local function _Tug(sigmaStableScore, sigmaMovement, deltaChange, x, y, pull) local score = current.GetScore() -- either pull or push if pull then fsl.Print('Pulling') for strength=deltaChange, 10.0, deltaChange do assert(strength <= 10.0, 'Strength out of bounds') if strength < 0 then strength = 0 end if strength > 10.0 then strength = 10.0 end band.SetStrength(1, strength) fsl.WiggleBackbone(1) if math.abs(current.GetScore() - score) >= sigmaMovement then fsl.Print('Band strength='..strength) break end end else fsl.Print('Pushing') local lengthStart = structure.GetDistance(x, y) strength = 1.0 for length=lengthStart, lengthStart + 20, 0.1 do band.SetGoalLength(1, length) fsl.WiggleBackbone(1) if math.abs(current.GetScore() - score) >= sigmaMovement then fsl.Print('length='..length) break end band.SetStrength(1, strength) strength = strength + deltaChange if strength > 10.0 then strength = 10.0 end end end fsl.BandDeleteScriptStart() fsl.MakeStable(nil, sigmaStableScore, 1) end local randomtugprocs = { Tug = _Tug, } local function _RandomTug(sigmaStableScore, sigmaMovement, deltaChange, noRestore) local functionName, scoreStart = fsl.ScriptBegin('tlaloc Random Tug') local x,y = fsl.BandAddRandom() randomtugprocs.Tug(sigmaStableScore, sigmaMovement, deltaChange, x, y, math.random(0, 1) == 0) return fsl.ScriptEnd(functionName, scoreStart, noRestore, fsl.BandDeleteScriptStart) end local function _RepeatRandomTug(tries, sigmaStableScore, sigmaMovement, deltaChange) local functionName, scoreStart = fsl.ScriptBegin('tlaloc Repeat Random Tug') for try=1, tries do fsl.PrintLine() fsl.PrintTries(functionName, try, tries) if script.RandomTug(sigmaStableScore, sigmaMovement, deltaChange) > 0 then fsl.BlueFuse(1, .01, .05, .07, .03) end end return fsl.ScriptEnd(functionName, scoreStart, false) end local function _RepeatRandomTugDialog() local ask = dialog.CreateDialog("tlaloc Repeat Random Tug") ask.Label = dialog.AddLabel("Tugs or pushes between random segments") ask.TriesLabel = dialog.AddLabel("Perform this many tugs") ask.Tries = dialog.AddSlider("Tries", 100, 1, 1000, 0) ask.StableScoreLabel = dialog.AddLabel("Shake and wiggle until this stable") ask.StableScore = dialog.AddSlider("Stable Score", .5, .01, 1.00, 2) ask.MovementLabel = dialog.AddLabel("This score change required before shaking out") ask.Movement = dialog.AddSlider("Movement", 10, 1, 100, 0) ask.DeltaLabel = dialog.AddLabel("Band strengths are incremented by this much") ask.Delta = dialog.AddSlider("Delta", .10, .01, 1.00, 2) ask.OK = dialog.AddButton("Start", 1) ask.Cancel = dialog.AddButton("Cancel", 0) if dialog.Show(ask) > 0 then _RepeatRandomTug(ask.Tries.value, ask.StableScore.value, ask.Movement.value, ask.Delta.value) end end ------------------------------------------------- -- tlaloc Rebuilder --[[ Vigorously rebuilds the protein. --]] local rebuilderprocs = {} local function _PrintImprovements(improvements) fsl.PrintLine() fsl.Print('Improvements:') for i=1, #improvements do fsl.Print(' range='..improvements[i].range..' index='..improvements[i].index..' rebuild='..improvements[i].rebuild..' segment='..improvements[i].segment..' ++'..improvements[i].improvement) end fsl.PrintLine() end local function _Rebuilder(segmentTarget, threshhold, sigma, range, maxRange, triesRebuild, triesFind, indexTarget, segments, improvements) -- segmentTarget is the segment to work on -- threshold is the amount a segment must improve before it moves on to the next segment -- sigma is the minimum amount score must improve before it records an improvement and saves -- range is how many segments to work with on either side of the worst segment -- maxRange is the maximum number of segments it will work on (for reporting purposes) -- triesRebuild is how many rebuilds it will perform on a given segment -- triesFind is how many tries it makes at finding a rebuild before giving up -- segments is the maximum number of segments it will rebuild -- improvements is a table of the improvements it has found local functionName, scoreStart = fsl.ScriptBegin('tlaloc Rebuilder') fsl.Print('Working on segment '..segmentTarget) local saveSlot = fsl.RequestSaveSlot() save.Quicksave(saveSlot) local countSegments = structure.GetCount() -- If the target is at the ends of the protein, shift the target so that the entire range -- so that the target +/- the range is all on the protein if segmentTarget - range < 1 then segmentTarget = segmentTarget + (1 - (segmentTarget - range)) end if segmentTarget + range > countSegments then segmentTarget = segmentTarget - ((segmentTarget + range) - countSegments) end local segmentFirst = segmentTarget - range local segmentLast = segmentTarget + range local scores = {} for tryRebuild=1, triesRebuild do local scoreBeforeRebuild = current.GetScore() rebuilderprocs.PrintImprovements(improvements) local scoreNew = false -- try to find a rebuild we haven't done before for tryNewScore=1, triesFind do fsl.PrintTries('Range', range, maxRange, 'segments') fsl.PrintTries('Working on worst index', indexTarget, segments, 'segment') fsl.PrintTries('Rebuild', tryRebuild, triesRebuild) fsl.PrintTries('Finding rebuild', tryNewScore, triesFind) selection.DeselectAll() selection.SelectRange(segmentFirst, segmentLast) fsl.Print('Rebuilding segments '..segmentFirst..'-'..segmentLast) fsl.Print('Segment score before rebuild='..fsl.GetSegmentScores(segmentFirst, segmentLast)) fsl.LocalRebuild(1) local scoreSegmentsRebuild = fsl.Round(fsl.GetSegmentScores(segmentFirst, segmentLast), 9) if not scores[scoreSegmentsRebuild] then fsl.Print('Segment score after rebuild='..scoreSegmentsRebuild) scoreNew = true scores[scoreSegmentsRebuild] = true break end end -- When we get to here, either we found a new rebuild, or we did all the triesFind if not scoreNew then -- made all the triesFind and didn't find valid rebuild, so quit break else fsl.Print('Working from rebuild score='..current.GetScore()) -- Actions to shake out rebuild improvement fsl.MakeStable(true, .1, 3) script.RepeatBlueFuse(3, .1, .05, .07, .03) local scoreCurrent = current.GetScore() fsl.Print('Stabilized at score='..scoreCurrent) if scoreCurrent - sigma > scoreBeforeRebuild then fsl.Print('Score improved...saving as current') save.Quicksave(saveSlot) improvements[#improvements + 1] = {index=indexTarget, range=range, rebuild=tryRebuild, segment=segmentTarget, improvement=scoreCurrent-scoreBeforeRebuild} if scoreCurrent - threshhold > scoreBeforeRebuild then break end else save.Quickload(saveSlot) end end end fsl.ReleaseSaveSlot(saveSlot) return fsl.ScriptEnd(functionName, scoreStart, false) end local function _RepeatRebuilder(maxRange, triesRebuild, maxScore, triesFind, threshhold, sigma, start, reverse) -- Rebuilds all segments starting with the worst -- maxRange is the # of segments adjacent to the segment to rebuild -- triesRebuild is the number of rebuilds to attempt on each segment -- maxScore is the segment score below which to rebuild -- triesFind is how many attempts to find a good rebuild -- threshhold is the minimum score improvement necessary to move on to another segment -- sigma is how much of a score improvement is necessary to keep the rebuild -- start is the segment to start the rebuild from (usually 1, but can be changed if you resume) -- reverse true changes it to go from maxRange to 1 instead of 1 to maxRange local functionName, scoreStart = fsl.ScriptBegin('tlaloc Repeat Rebuilder') local countSegments = structure.GetCount() assert(maxRange <= 10, 'range must be less than or equal to 10') local scores = {} for i=1, countSegments do scores[i]={segment=i, score=current.GetSegmentEnergyScore(i)} end for i=1,countSegments do for j = countSegments, i+1, -1 do if scores[i].score > scores[j].score then scores[j], scores[i] = scores[i], scores[j] end end end for i=1,countSegments do fsl.Print(i..' segment='..scores[i].segment..' score='..scores[i].score) end local segments = countSegments fsl.Print('Segments to be worked on') for i=1, countSegments do if scores[i].score >= maxScore then segments = i - 1 break end fsl.Print(i..' segment='..scores[i].segment..' score='..scores[i].score) end fsl.Print() local improvements={} local first = start local last = maxRange local increment = 1 if reverse then first,last = last,first increment = -1 end for range=first, last, increment do for indexTarget=start, segments do fsl.PrintTries('Working on worst index', indexTarget, segments, 'segment') fsl.Print('segment='..scores[indexTarget].segment..' score='..scores[indexTarget].score) fsl.PrintTries('Range', range, maxRange, 'segments') rebuilderprocs.Rebuilder(scores[indexTarget].segment, threshhold, sigma, range, maxRange, triesRebuild, triesFind, indexTarget, segments, improvements) end end rebuilderprocs.PrintImprovements(improvements) return fsl.ScriptEnd(functionName, scoreStart, false) end rebuilderprocs = { PrintImprovements = _PrintImprovements, Rebuilder = _Rebuilder, } local function _RebuilderDialog() local ask = dialog.CreateDialog("Tlaloc Rebuilder") ask.Label1 = dialog.AddLabel("# of segments adjacent to the segment to rebuild") ask.MaxRange = dialog.AddSlider("Range", 3, 1, 5, 0) ask.Label2 = dialog.AddLabel("# of rebuilds to attempt on each segment") ask.TriesRebuild = dialog.AddSlider("Rebuilds", 2, 1, 10, 0) ask.Label3 = dialog.AddLabel("Segment score below which to rebuild") ask.MaxScore = dialog.AddSlider("Score", 0, -50, 50, 1) ask.Label4 = dialog.AddLabel("How many attempts to find a good rebuild") ask.TriesFind = dialog.AddSlider("Tries", 50, 10, 100, 0) ask.Label5 = dialog.AddLabel("Score improvement to move on to another segment") ask.Threshhold = dialog.AddSlider("Improvement", 10, .1, 100, 1) ask.Label6 = dialog.AddLabel("Range to 1 (vs 1 to Range)") ask.Reverse = dialog.AddCheckbox("Reverse", true) ask.Start = dialog.AddButton("Start", 1) ask.Cancel = dialog.AddButton("Cancel", 0) if (dialog.Show(ask) > 0) then _RepeatRebuilder(ask.MaxRange.value, ask.TriesRebuild.value, ask.MaxScore.value, ask.TriesFind.value, ask.Threshhold.value, .1, 1, ask.Reverse.value) end end ------------------------------------------------- -- tlaloc SelectMultiStart --[[ This script figures out how many different starts there are, and saves them into the quickload save spots. You can use ctrl+1, ctrl+2, or ctrl+3 to load the first 3 after running this script. --]] local function _SelectMultiStartDialog() local functionName, scoreStart = fsl.ScriptBegin('tlaloc SelectMultiStart') local ask = dialog.CreateDialog("tlaloc SelectMultiStart") ask.Description = dialog.AddLabel("Finds all the starts and lets you select one.") ask.AttemptsLabel = dialog.AddLabel("How many attempts to find the start") ask.Attempts = dialog.AddSlider("Attempts", 150, 50, 500, 0) ask.SelectLabel = dialog.AddLabel("Select this start when done") ask.Select = dialog.AddSlider("Start #", 1, 1, 10, 0) ask.CommentLabel1 = dialog.AddLabel("A start number higher than the number of starts") ask.CommentLabel2 = dialog.AddLabel("will select the last start.") ask.OK = dialog.AddButton("Start", 1) ask.Cancel = dialog.AddButton("Cancel", 0) if dialog.Show(ask) > 0 then fsl.SelectMultiStart(ask.Attempts.value, true, ask.Select.value) end return fsl.ScriptEnd(functionName, scoreStart, false) end ------------------------------------------------- -- tlaloc Settle -- Based on CoLapses Settle --[[ Repeats the settle algorithm until no points are found. Settle does local wiggles in different patterns across the entire protein. --]] -- This function is not covered by the Creative Commons license given at the start of the script -- since it a port of CoLapse's algorithm, with some enhancements. local function _Settle(sigmaStable, iterations, finalStart, finalInterval, ...) local functionName, scoreStart = fsl.ScriptBegin('tlaloc Settle') local arg = {...} local start local interval assert(#arg % 2 == 0) for i=1, #arg, 2 do start = arg[i] interval = arg[i+1] fsl.UnfreezeAll() fsl.FreezeSegments(interval, start) fsl.LocalWiggleInterval(interval, start - interval + 1, iterations) end fsl.UnfreezeAll() fsl.FreezeSegments(finalInterval, finalStart) fsl.LocalWiggleInterval(finalInterval, finalStart - finalInterval + 1, iterations) fsl.WiggleBackbone(iterations) fsl.UnfreezeAll() fsl.MakeStable(nil, sigmaStable, iterations) return fsl.ScriptEnd(functionName, scoreStart, false) end local function _RepeatSettle(sigmaImprovement, sigmaStable, iterations, finalStart, finalInterval, ...) local functionName, scoreStart = fsl.ScriptBegin('tlaloc Repeat Settle') local i = 0 repeat fsl.PrintLine() i = i + 1 fsl.PrintTries(functionName, i) until _Settle(sigmaStable, iterations, finalStart, finalInterval, ...) <= sigmaImprovement return fsl.ScriptEnd(functionName, scoreStart, false) end ------------------------------------------------- -- tlaloc Shakeout --[[ Finds the best score between doing a shake/wiggle or a wiggle/shake. Then does a repeat Bluefuse until no points are found. Very good to run any time you find points elsewhere. --]] local function _Shakeout(iterations, sigma, ...) local functionName, scoreStart = fsl.ScriptBegin('tlaloc Shakeout') fsl.MakeStable(nil, sigma, iterations) script.RepeatBlueFuse(iterations, sigma, ...) return fsl.ScriptEnd(functionName, scoreStart, false) end ----------------------------------------- -- tlaloc Twitch --[[ Freezes all segments except the ones around where it is working, uses a band to move the segment. --]] local function _Twitch(range, distance, strength, sigma, iterations) local functionName, scoreStart = fsl.ScriptBegin('tlaloc Twitch') local countSegments = structure.GetCount() for segmentCur = 1, countSegments do local segmentStart = segmentCur - range local segmentEnd = segmentCur + range if segmentStart < 1 then segmentStart = 1 end if segmentEnd > countSegments then segmentEnd = countSegments end freeze.FreezeAll() for i = segmentStart, segmentEnd do freeze.Unfreeze(i, true, true) end local bandLength = distance + 1 local segment1 = 1 local segment2 = countSegments if segmentCur == 1 then segment1 = 2 end if segmentCur == segment2 then segment2 = segment2 - 1 end local bandNumber = band.Add(segmentCur, segment1, segment2, bandLength, 0, 0) local segmentLock = segmentStart - 1 if segmentLock == 0 then segmentLock = segmentEnd + 1 end local bandLock = band.Add(segmentLock, segmentCur, segment2, 1, 0, 0) band.SetGoalLength(bandLock, 1) band.SetStrength(bandLock, 10) band.SetGoalLength(bandNumber, distance) fsl.MakeStable(true, sigma, iterations) fsl.ReportAndLockScoreIncrease() fsl.RestoreRecentBest() fsl.BandDeleteScriptStart() freeze.UnfreezeAll() end return fsl.ScriptEnd(functionName, scoreStart, false) end local function _TwitchDialog() local ask = dialog.CreateDialog("tlaloc Twitch") ask.Range = dialog.AddSlider("Range", 1, 1, 5, 0) ask.Distance = dialog.AddSlider("Distance", .5, .1, 1, 1) ask.Strength = dialog.AddSlider("Strength", 1, .1, 10, 1) ask.Sigma = dialog.AddSlider("Sigma", .03, .01, 1, 2) ask.Iterations = dialog.AddSlider("Iterations", 1, 1, 25, 0) ask.OK = dialog.AddButton("Start", 1) ask.Cancel = dialog.AddButton("Cancel", 0) if dialog.Show(ask) > 0 then _Twitch(ask.Range.value, ask.Distance.value, ask.Strength.value, ask.Sigma.value, ask.Iterations.value) end end script = { BandStrength = _BandStrengthDialog, RepeatBlueFuse = _RepeatBlueFuseDialog, Cataclysm = _CataclysmDialog, Contract = _ContractDialog, Helixer = _HelixerDialog, Hydrophobe = _HydrophobeDialog, MutateAll = _MutateAllDialog, Push = _PushDialog, RandomTug = _RandomTug, RepeatRandomTug = _RepeatRandomTugDialog, Rebuilder = _RebuilderDialog, SelectMultiStart = _SelectMultiStartDialog, Settle = _Settle, RepeatSettle = _RepeatSettle, Shakeout = _Shakeout, Twitch = _TwitchDialog, } ------------------------------------------------- -- Main code fsl.ScriptInitialize() script.RepeatRandomTug() fsl.ScriptFinalize()

Comments