Icon representing a recipe

Recipe: Cut And Wiggle v3.1

created by SemperRabbit

Profile


Name
Cut And Wiggle v3.1
ID
108503
Shared with
Public
Parent
Cut And Wiggle v3
Children
Created on
November 27, 2023 at 02:40 AM UTC
Updated on
November 27, 2023 at 02:44 AM UTC
Description

Cuts the protein at regular intervals and wiggles. See comments for more info.

Best for


Code


------------------------------------------------------------------------------- -- Cut And Wiggle v 3 -- -- Performs a fuse-wiggle with cuts inserted every "step size" segment -- Randomly chooses shifts to attempt but eventually tries them all. -- Decrements step size if all shifts have failed to produce gain. -- Restarts at original step size after all have been tried. -- -- Originally by Susume -- Gui and features added by KarenCH -- Enhanced by zeroblue -- Enhancements: -- Recent best saves and restores changed to improve scoring, -- especially when running at a high CI less than 1 or when using bands. -- Order of offsets is now less random: All possible offsets are tried, -- and no offset for a given step size is tried twice in a row. -- Random seed function fixed to produce different results with each run. -- Added to step size to allow limited ranges of step sizes -- After all step sizes and offsets have been tried, the lowCI is randomly changed. -- Added an option to disable filters for puzzles that have them. -- Reorganized functionality. -- Really will run forever now. -- SemperRabbit 20220608@2150 JST: added cleanup button to dialog to remove all cuts from a cancel. -- V3.1 -- Adds option to only work with selected AAs. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------------ -- HELPER FUNCTIONS AND INTERNAL-ONLY CONSTANTS ------------------------------------------------------------------------------------ OriginalCI = 1.0 startingStepSize=3 toStepSize=10 lowCI = 0.3 originalLowCI = 0.3 highCI=1.0 shortwiggle = 1 longwiggle = 25 StartSegment = 0 EndSegment = structure.GetCount() originalScore = 0 bestScore = 0 hasFilters = false toggleFilters = false selectedOnly = false -- v3.1 function setStartEnd() low = structure.GetCount() high = 1 if selectedOnly then for i=1 , structure.GetCount(), 1 do if selection.IsSelected(i) then if low >= i then low = i end if high <= i then high = i end end end else low = 1 high = structure.getCount() end StartSegment = low EndSegment = high end function SeedRandom() local seed = os.time()%1000 print("Seed is: "..seed) math.randomseed(seed) end function GetOffsetList(stepsize) local offsetOrderedList = {} for i=1, stepsize do table.insert( offsetOrderedList, i ) end return offsetOrderedList end function RandomizeList(offsetOrderedList) local offsetRandomList = {} for i=1, #offsetOrderedList do local offsetPos = math.random( #offsetOrderedList ) local thisOffset = table.remove ( offsetOrderedList, offsetPos ) table.insert( offsetRandomList, thisOffset ) end return offsetRandomList end function TableList(myTable) local myString="" for i=1,#myTable do myString = myString..myTable[i]..', ' end return(string.sub(myString,1,#myString-2)) end function SetupOffsetList( stepsize ) local offsetList = GetOffsetList( stepsize ) offsetList = RandomizeList( offsetList ) print("Offset list is: "..TableList(offsetList)) return offsetList end function Round(num, idp) local mult = 10^(idp or 0) if num >= 0 then return math.floor(num * mult + 0.5) / mult else return math.ceil(num * mult - 0.5) / mult end end function RandomizeLowCI( ) local newLowCI = lowCI while newLowCI == lowCI do newLowCI = Round(newLowCI + (math.random( 21 ) - 11) * 0.01, 2) if newLowCI < 0.04 or newLowCI > math.max(highCI * 0.5, originalLowCI * 1.1) then newLowCI = lowCI end end lowCI = newLowCI print( "New lowCI = "..lowCI ) end function PrintSettings( ) print("Starting step size = "..startingStepSize) print("To step size = "..toStepSize) print("lowCI = "..lowCI) print("highCI = "..highCI) print("shortwiggle = "..shortwiggle) print("longwiggle = "..longwiggle) end ------------------------------------------------------------------------------------ -- THE WIGGLER ------------------------------------------------------------------------------------ function DoWiggle( ) PrintSettings( ) originalLowCI = lowCI local stepsize = startingStepSize -- create initial offsetList local offsetList = SetupOffsetList( stepsize ) -- set the step size change value local stepSizeChange = 0 if toStepSize > startingStepSize then stepSizeChange = 1 elseif toStepSize < startingStepSize then stepSizeChange = -1 end --print( "Step size change is: "..stepSizeChange ) -- loop until user cancels while 1==1 do local offset = table.remove( offsetList, 1 ) print( "Starting at seg "..offset.." with stepsize="..stepsize ) Wiggler(offset, stepsize) -- scoring and shake local newScore = current.GetEnergyScore( ) if newScore > bestScore then recentbest.Save( ) structure.ShakeSidechainsAll( 1 ) recentbest.Restore( ) save.Quicksave( 3 ) newScore = current.GetEnergyScore( ) print( "Score improved by "..newScore-bestScore.." to "..newScore ) bestScore = newScore -- create new offsetList offsetList = GetOffsetList(stepsize) local currentOffset = table.remove ( offsetList, offset ) -- remove the current offset offsetList = RandomizeList( offsetList ) table.insert( offsetList, currentOffset ) -- add last offset to end print( "Offset list is: "..TableList( offsetList ) ) else print( "Failed with loss of "..newScore-bestScore ) if toggleFilters then behavior.SetSlowFiltersDisabled(true) end save.Quickload( 3 ) end -- If offsetList is empty, create a new one if #offsetList == 0 then if stepsize == toStepSize then print( "Finished end step size. Restarting with step size "..startingStepSize ) stepsize = startingStepSize RandomizeLowCI( ) else stepsize = stepsize + stepSizeChange print( "Step size changed to.. "..stepsize ) print( "Score increase so far of: "..bestScore-originalScore.." from "..originalScore) end -- create new offsetList offsetList = SetupOffsetList( stepsize ) end end end function Wiggler( offset, stepsize ) if toggleFilters then behavior.SetSlowFiltersDisabled(true) end if selectedOnly then -- v3.1 for i = StartSegment+offset, EndSegment-1, stepsize do structure.InsertCut( i ) end behavior.SetClashImportance( lowCI ) structure.WiggleSelected( shortwiggle ) recentbest.Save( ) behavior.SetClashImportance( highCI ) structure.WiggleSelected( longwiggle ) recentbest.Restore( ) for i = StartSegment+offset, EndSegment-1, stepsize do structure.DeleteCut( i ) end recentbest.Save( ) behavior.SetClashImportance( lowCI ) structure.WiggleSelected( shortwiggle ) behavior.SetClashImportance( highCI ) structure.WiggleSelected( longwiggle ) recentbest.Restore( ) else for i = StartSegment+offset, EndSegment-1, stepsize do structure.InsertCut( i ) end behavior.SetClashImportance( lowCI ) structure.WiggleAll( shortwiggle ) recentbest.Save( ) behavior.SetClashImportance( highCI ) structure.WiggleAll( longwiggle ) recentbest.Restore( ) for i = StartSegment+offset, EndSegment-1, stepsize do structure.DeleteCut( i ) end recentbest.Save( ) behavior.SetClashImportance( lowCI ) structure.WiggleAll( shortwiggle ) behavior.SetClashImportance( highCI ) structure.WiggleAll( longwiggle ) recentbest.Restore( ) end if toggleFilters then behavior.SetSlowFiltersDisabled(false) end end ------------------------------------------------------------------------------------ -- USER DIALOG BOX ------------------------------------------------------------------------------------ function GetParams( ) dlg = dialog.CreateDialog( "Cut And Wiggle" ) dlg.step = dialog.AddSlider( "Initial step size", startingStepSize, 1, 20, 0 ) dlg.toStep = dialog.AddSlider( "To step size", toStepSize, 1, 20, 0 ) dlg.lowCI = dialog.AddSlider( "LowCI", lowCI, 0, 1, 2 ) dlg.highCI = dialog.AddSlider( "HighCI", highCI, 0, 1, 2 ) dlg.shortwiggle = dialog.AddSlider( "ShortWiggleIters", shortwiggle, 1, 10, 0 ) dlg.longwiggle = dialog.AddSlider( "LongWiggleIters", longwiggle, 1, 50, 0 ) if hasFilters then dlg.disable = dialog.AddCheckbox("Wiggle with disabled slow filters",filterActive) end dlg.bSelectedOnly = dialog.AddCheckbox("Work on selected (contiguous) AAs only",selectedOnly) -- v3.1 dlg.ok = dialog.AddButton( "OK", 1 ) dlg.cancel = dialog.AddButton( "Cancel", 0 ) dlg.cleanup = dialog.AddButton ("Cleanup", 2) local dlgret = dialog.Show( dlg ) if dlgret == 1 then startingStepSize = dlg.step.value toStepSize = dlg.toStep.value lowCI = dlg.lowCI.value highCI = dlg.highCI.value shortwiggle = dlg.shortwiggle.value longwiggle = dlg.longwiggle.value if hasFilters then toggleFilters = dlg.disable.value end selectedOnly = dlg.bSelectedOnly.value -- v3.1 if selectedOnly then setStartEnd() end return true elseif dlgret == 2 then cleanup() return false else print( "dialog cancelled" ) return false end end ------------------------------------------------------------------------------------ -- CONTROLLERS: SETUP AND CLEANUP ------------------------------------------------------------------------------------ function cleanCuts( ) for i,j in ipairs(structure.GetCuts()) do structure.DeleteCut( j ) end end function cleanup( ) if toggleFilters then behavior.SetSlowFiltersDisabled(false) end if bestScore > current.GetEnergyScore( ) then save.Quickload( 3 ) else bestScore = current.GetEnergyScore( ) end behavior.SetClashImportance( OriginalCI ) PrintSettings( ) print( "Total score increase of: "..bestScore-originalScore.." from "..originalScore) cleanCuts( ) end function main( ) SeedRandom() print( "Original in slot 2, High score in slot 3" ) save.Quicksave( 2 ) --starting position save.Quicksave( 3 ) --high score bestScore = current.GetEnergyScore( ) -- Test for filters if not behavior.GetSlowFiltersDisabled() then behavior.SetSlowFiltersDisabled(true) if current.GetEnergyScore( ) ~= bestScore then hasFilters = true print( "Slow filters detected" ) end behavior.SetSlowFiltersDisabled(false) end print( "Starting score "..bestScore ) originalScore = bestScore OriginalCI = behavior.GetClashImportance( ) while GetParams( ) do DoWiggle( ) end cleanup( ) end xpcall( main,cleanup )

Comments


JuliaBCollet Lv 1

Thank you for this script! as I continue to learn LUA, I am really grateful to have the opportunity to use this with my proteins :-)