Profile
- Name
- tlaloc Select Multistart 4.00
- ID
- 37276
- Shared with
- Public
- Parent
- None
- Children
- Created on
- January 10, 2012 at 07:08 AM UTC
- Updated on
- January 10, 2012 at 07:08 AM UTC
- Description
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.
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 > 2.0 then
-- no amount of strength will get it to move
strength = 2.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()
local functionName, scoreStart = fsl.ScriptBegin('tlaloc Helixer')
local countSegments = structure.GetCount()
assert(band.GetCount() == 0, 'Must delete existing bands\nbefore running this code.')
local distanceHelix = 5.5
local bandIncrement = 1
local bandStrength = bandIncrement
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(), distanceHelix)
end
end
end
end
while true do
fsl.MakeStable(true, .1, 10)
local allFixed = true
bandStrength = bandStrength + bandIncrement
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(distanceHelix - 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
-------------------------------------------------
-- 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
-------------------------------------------------
-- 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(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
-------------------------------------------------
-- 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, 2.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
-------------------------------------------------
-- 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
-----------------------------------------
-- 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, 2.0, deltaChange do
assert(strength < 2.0, 'Strength out of bounds')
if strength < 0 then
strength = 0
end
if strength > 2.0 then
strength = 2.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 > 2.0 then
strength = 2.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
-------------------------------------------------
-- 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 = _RepeatBlueFuse,
Cataclysm = _CataclysmDialog,
Contract = _ContractDialog,
Helixer = _Helixer,
Hydrophobe = _Hydrophobe,
MutateAll = _MutateAll,
Push = _Push,
RandomTug = _RandomTug,
RepeatRandomTug = _RepeatRandomTug,
Rebuilder = _Rebuilder,
RepeatRebuilder = _RepeatRebuilder,
RebuilderDialog = _RebuilderDialog,
SelectMultiStart = _SelectMultiStartDialog,
Settle = _Settle,
RepeatSettle = _RepeatSettle,
Shakeout = _Shakeout,
Twitch = _TwitchDialog,
}
-------------------------------------------------
-- Main code
fsl.ScriptInitialize()
script.SelectMultiStart()
fsl.ScriptFinalize()