Icon representing a recipe

Recipe: Banded Worm CrashPruf

created by LociOiling

Profile


Name
Banded Worm CrashPruf
ID
101958
Shared with
Public
Parent
None
Children
None
Created on
March 22, 2016 at 18:05 PM UTC
Updated on
March 22, 2016 at 18:05 PM UTC
Description

Banded Worm modified to provide extra information to be used in debugging current cysteine bridge (?) crashes

Best for


Code


------------------------------------------------------------------------------ -- Banded Worm ------------------------------------------------------------------------------ -- Modifies Worm LWS v2 (and is thus a pure AD script) -- -- by KarenCH -- -- -- This "CrashPruf" version loops forever and attempts -- to save the last operation in the segment notes. ------------------------------------------------------------------------------ USENORMALSCORE = true -- exploration puzzles would set false DEBUGRUN = true -- mostly goes with DebugPrint, but could get more use later BAND_STRENGTH_DEFAULT = 1.0 PROB_PUTBAND = 1.0 -- how often do we put bands in our wiggle steps? PROB_BIS_NOT_BETWEEN = 0.00 -- do we prefer BIS or bands between segs PROB_BETWEEN_USES_TIP = 1.00 -- between: should wiggled seg have band from aa tip BIS_LENGTH = 5.0 -- max length of a BIS SCALE_MAXCI = 1.0 QS_Start = 1 QS_Best = 3 EndCalled = false InitialScore = 0.0 StartTime = 0 CurrentBestScore = 0.0 InitialClashImportance = behavior.GetClashImportance() segCt = structure.GetCount() function BandedWorm( pattern ) recentbest.Save( ) SetCI( 1.0 ) SaveBest( ) local ss = getScore() for w = 1, #pattern do len = pattern[ w ] local sw = getScore() local swCurr = sw print( "Starting Banded Worm of len " .. len .. ", score: ".. TrimNum( getScore() ) ) local worm = "Banded Worm length = " .. len structure.SetNote ( 1, worm ) for s=1, segCt - len + 1 do selection.DeselectAll() selection.SelectRange( s, s + len - 1 ) local strng = "selection.SelectRange ( " .. s .. ", " .. s + len - 1 .. " )" structure.SetNote ( 2, strng ) local idx = random( s, s + len - 1 ) if random( ) < PROB_PUTBAND then PutSingleBand( idx ) structure.SetNote ( 4, "structure.LocalWiggleSelected( 2 ) -- banded" ) structure.LocalWiggleSelected( 2 ) DelBands( ) structure.SetNote ( 4, "structure.WiggleAll( 2 ) -- after banding" ) structure.WiggleAll( 2 ) end structure.SetNote ( 4, "structure.LocalWiggleSelected( 2 ) -- unbanded" ) structure.LocalWiggleSelected( 2 ) local swNew = getScore( ) if swNew > swCurr then structure.SetNote ( 4, "structure.LocalWiggleSelected( 20 ) -- long local wiggle" ) structure.LocalWiggleSelected( 20 ) recentbest.Restore( ) DelBands( ) print( ">>>> At " .. s .. ": Gained ".. swNew - swCurr ) SaveBest( ) swCurr = swNew end recentbest.Restore( ) DelBands( ) end print( "Pattern gain: ".. getScore( ) - sw ) SaveBest( ) end selection.DeselectAll() print( "Total Worm gain: " .. TrimNum( getScore( ) - ss ) ) end function PutSingleBand( idx ) changeSucceeded = false local strength = random( 0.5 * BAND_STRENGTH_DEFAULT, 1.5 * BAND_STRENGTH_DEFAULT, true ) local doBIS = random( ) < PROB_BIS_NOT_BETWEEN local doTip1 = random( ) < PROB_BETWEEN_USES_TIP if doBIS then changeSucceeded = PutBandInSpace( idx, BIS_LENGTH, strength ) else changeSucceeded = PutBandToRandomSeg( idx, strength, doTip1 ) end return changeSucceeded end ---------------------------------------------------------------- -- ---------------- BOILERPLATE --------------------- -- ---------------------------------------------------------------- ---------------------------------------------------------------- -- BASIC FUNCTIONALITY ---------------------------------------------------------------- function DebugPrint( str ) if DEBUGRUN then print( str ) end end function TrimNum( val ) return val - val % 0.001 end -- Not for "external" use - call getScore. This could change if customers want -- something besides current or recentbest. function internalGetScore( wantRB ) if wantRB == nil then wantRB = false end local s=0.0 if not USENORMALSCORE then if wantRB then s = recentbest.GetEnergyScore( ) else s=current.GetEnergyScore( ) end else if wantRB then s = recentbest.GetScore( ) else s=current.GetScore( ) end end return s end function getScore( ) return internalGetScore( false ) end function getRBScore( ) return internalGetScore( true ) end function SaveBest( ) local score = getScore( ) if score > CurrentBestScore then save.Quicksave( QS_Best ) CurrentBestScore = score end end function SetCI( ci ) behavior.SetClashImportance( SCALE_MAXCI * ci ) end ----------------------- MATHY STUFF ----------------------- function seedRandom() seed=os.time( )/math.abs( getScore( ) ) seed=seed%0.001 seed=1/seed while seed<10000000 do seed=seed*1000 end seed=seed-seed%1 seed = 4392698804 DebugPrint( "Seed is: "..seed ) math.randomseed( seed ) -- throw away a couple of randoms math.random( ) math.random( ) end function random( n1,n2, forceFloat ) --random function returns int or float depends on input vars if forceFloat == nil then forceFloat = false end if n1==nil then return math.random() else if n2==nil then if n1 == 0 then return 0 end -- a random number between 0 and 0 is 0 if n1%1==0 then -- can't test for "forceFloat", so caller must beware return math.random( n1) --integer else return math.random( ) * n1 --float end else if n1%1==0 and n2%1==0 and not forceFloat then return math.random( n1, n2 ) --integer between else return math.random( ) * (n2 - n1) + n1 --float between end end end end function randomThetaPhi() return math.acos( random( -1.0, 1.0, true ) ), random( 2 * math.pi ) end -- for branched aas, simply picks one (longer, one with donor/acceptor tip, or if no difference then either) function GetAtomOfTip( aa ) if aa == "a" then return 10 elseif aa == "c" then return 10 -- was 11, got error... elseif aa == "d" then return 8 elseif aa == "e" then return 9 elseif aa == "f" then return 20 elseif aa == "g" then return 0 -- glycine has no tip. just use a backbone atom elseif aa == "h" then return 17 elseif aa == "i" then return 18 elseif aa == "k" then return 9 elseif aa == "l" then return 16 elseif aa == "m" then return 17 elseif aa == "n" then return 14 elseif aa == "p" then return 13 elseif aa == "q" then return 9 elseif aa == "r" then return 22 elseif aa == "s" then return 11 elseif aa == "t" then return 6 elseif aa == "v" then return 13 elseif aa == "w" then return 24 elseif aa == "y" then return 12 else return 0 end end function GetTipAtomOfSeg( idx ) return GetAtomOfTip( structure.GetAminoAcid( idx )) end function DelBands() band.DeleteAll() end function BandBetweenSegsWithParameters( seg1, seg2, strength, goalLength, fromTip1, fromTip2 ) structure.SetNote ( 3, "" ) -- caller can set goalLength without setting strength by providing strength = 0.0 --if not ( IsMovableSeg( seg1) or IsMovableSeg( seg2) ) then return false end if fromTip1 == nil then fromTip1 = false end if fromTip2 == nil then fromTip2 = false end if fromTip1 then tip1 = GetTipAtomOfSeg(seg1) else tip1 = 0 end if fromTip2 then tip2 = GetTipAtomOfSeg(seg2) else tip2 = 0 end print ( "banding " .. seg1 .. " (" .. tip1 .. ") , " .. seg2 .. " (" .. tip2 .. ")" ) local bIdx = band.AddBetweenSegments( seg1, seg2, tip1, tip2 ) if bIdx ~= band.GetCount( ) then DebugPrint( "failed to add band from "..seg1.." to "..seg2) return false end local bandx = "band.AddBetweenSegments ( " .. seg1 .. ", " .. seg2 .. ", " .. tip1 .. ", " .. tip2 .. " ) " structure.SetNote ( 3, bandx ) if goalLength ~= nil then band.SetGoalLength( bIdx, goalLength ) end if strength ~= nil and strength > 0.0 then band.SetStrength( bIdx, strength ) end return true end function BandInSpaceWithParameters( seg, segFini, segInit, rho, theta, phi, strength, goalLength ) -- caller can set goalLength without setting strength by providing strength = 0.0 --if not ( IsMovableSeg( seg) ) then return false end structure.SetNote ( 3, "" ) local bIdx = band.Add( seg, segFini, segInit, rho, theta, phi ) if bIdx ~= band.GetCount( ) then return false end local bandx = "band.Add ( " .. seg .. ", " .. segFini .. ", " .. segInit .. ", " .. rho .. ", " .. theta .. ", " .. phi .. " ) " structure.SetNote ( 3, bandx ) if goalLength ~= nil then band.SetGoalLength( bIdx, goalLength ) end if strength ~= nil and strength ~= 0.0 then band.SetStrength( bIdx, strength ) end return true end function PutBandInSpace( idx, maxRho, strength ) -- trying to do tips is too weird, so we omit the capability local idx2, idx3 if idx < segCt then idx2 = idx + 1 else idx2 = idx - 2 end if idx > 1 then idx3 = idx - 1 else idx3 = idx + 2 end -- random point in sphere of radius maxRho local theta, phi = randomThetaPhi( ) local rho = (maxRho * random()^(1/3)) + 0.001 return BandInSpaceWithParameters( idx, idx2, idx3, rho, theta, phi, strength ) end function PutBandToRandomSeg( idx, strength, doTip ) needNew = true local failedTries = 0 while ( needNew and failedTries < 20 ) do idx2 = random( segCt ) -- ok if this one isn't movable (we assume idx is movable) if idx2 > idx + 1 or idx2 < idx - 1 then needNew = false break else failedTries = failedTries + 1 end end if not needNew then return BandBetweenSegsWithParameters( idx, idx2, strength, nil, doTip, doTip ) end return false end -------------------------------------------------------------------------- -- SETUP, CLEANUP, and MAIN -------------------------------------------------------------------------- function CleanPuzzleState( ) SetCI( 1.0 ) selection.DeselectAll() DelBands() end function PrintState( ) local gain = getScore() - InitialScore if gain < 0.001 then print( " No change" ) else print( " Startscore: "..TrimNum( InitialScore )) print( " Score: "..TrimNum( getScore() ) ) print( " Total gain: "..TrimNum( gain )) end print( " Run time: "..os.time() - StartTime) end function End( errstr ) if EndCalled then return end -- no infinite recursion please!!! EndCalled = true print( "" ) if errstr ~= nil then if string.find( errstr, "Cancelled" ) then print( "User cancel" ) else print( errstr ) end end save.Quickload( QS_Best ) PrintState( ) CleanPuzzleState( ) end function main( ) seedRandom( ) structure.SetNote ( 1, "" ) structure.SetNote ( 2, "" ) structure.SetNote ( 3, "" ) structure.SetNote ( 4, "" ) InitialScore = getScore( ) CurrentBestScore = InitialScore StartTime = os.time() save.Quicksave( QS_Start ) save.Quicksave( QS_Best ) InitialClashImportance = behavior.GetClashImportance() SCALE_MAXCI = InitialClashImportance pattern = { 2,5,11,3,13,4,7,1,6 } local run = 1 repeat print ( "Banded Worm run " .. run ) BandedWorm ( pattern ) run = run + 1 until false End( ) end xpcall( main, End )

Comments


LociOiling Lv 1

This modified version of Banded Worm attempts to preserve "black box" information in segment notes, in an attempt to diagnose the current crashes, which seem to be related to the presence of a disulfide bridge. Unfortunately, there is still a random element.

This recipe has reliably crashed for me somewhere in the first "pattern", which does LWS on length of 2 segments.