Back to Recipes Homepage
recipe picture
Recipe: HBuster2
Created by Enzyme 62 3
4.31818
Your rating: None Average: 4.3 (22 votes)

Profile

Name: HBuster2
ID: 101089
Created on: Sun, 06/07/2015 - 05:43
Updated on: Sun, 06/07/2015 - 14:50
Description:

HBuster2



Best For


Comments

Enzyme's picture
User offline. Last seen 48 years 17 weeks ago. Offline
Joined: 07/10/2008
Groups: None
lysine

resolved issue where lysine mutations where using leucine

Joined: 09/24/2012
Groups: Go Science
bug report

line 95 bad argument 2, rotamer out of range

LociOiling's picture
User offline. Last seen 2 hours 34 min ago. Offline
Joined: 12/27/2012
Groups: Beta Folders
rotamer counts can change unexpectedly, code to handle

I've hit the same error Bruno mentions several times on puzzle 1100. It's been really hard to reproduce, however. It seems likely that the error is occurring in the recipe-defined function rotamer.Optimize(), but I don't see a specific problem there. The function works correctly even when the rotamer count changes during the process of snapping to all the sidechain positions.

The same issue has impacted Acid Tweeker in the past, but I believe Bruno has fixed it there.

This is a case where it would be nice if rotamer.SetRotamer returned an error code instead of crashing the recipe. Fortunately, the Lua pcall() function provides a way to implement this wish list item.

The basic idea is to call rotamer.SetRotamer using pcall, then check for an error:

--
-- SafeSnap uses the Lua protected call function, pcall,
-- to call rotamer.SetRotamer
--
-- SafeSnap returns a numeric return code and an error message.
--
-- The return codes are:
--
-- 0 - successful, error message is nil
-- -1 - bad rotamer index
--
-- Errors other than a bad rotamer index are rethrown using
-- the Lua function error().
--
function SafeSnap ( segIdx, rotIdx )
--
-- error message when attempting to snap to an invalid rotamer
--
local BADSNAP = "(snap index out of bounds)"
--
-- don't allow a bad rotamer to stop us
--
local good, errmsg = pcall ( rotamer.SetRotamer, segIdx, rotIdx )
if good then
return 0, nil
else
local err2 = ParseError ( errmsg )
local errp = err2:find ( BADSNAP )
if errp ~= nil then
return -1, err2
end
error ( errmsg, 0 )
end
end

Note that errors other than "snap index out of bounds" are simply reissued
using the Lua error() function.

The helper function ParseError() is adapted from the cleanup logic developed by Bruno and Jean-Bob:

function ParseError ( errmsg )
local reason
local start, stop, line, msg
start, stop, line, msg = errmsg:find ( ":(%d+):%s()" )
if msg ~= nil then
errmsg = errmsg:sub ( msg, #errmsg )
end
return errmsg
end

The recipe then uses SafeSnap instead of rotamer.SetRotamer:

--
-- attempt to snap the sidechain in a safe, non-crashy manner
--
local rc, errmsg = SafeSnap ( segIdx, rotIdx )
if rc ~= 0 then
print ( "optimize: BAD SNAP, segment = "
.. segIdx ..
", rotamer = "
.. rotIdx ..
", current rotamer count = "
.. rotamer.GetCount ( segIdx ) )
end

When the bad rotamer index problem hits, I don't see a reason to stop the recipe. To me, it makes more sense to log the error and continue processing.

So far this logic seems to be working. I'm running a test recipe using this logic now. I'll release the test recipe once it's had a little more time to find a problem.

LociOiling's picture
User offline. Last seen 2 hours 34 min ago. Offline
Joined: 12/27/2012
Groups: Beta Folders
forgot to add preformatted tags

Here's the code from the previous post with added tags:

--
--  SafeSnap uses the Lua protected call function, pcall,
--  to call rotamer.SetRotamer
--
--  SafeSnap returns a numeric return code and an error message.
--
--  The return codes are:
--
--   0 - successful, error message is nil
--  -1 - bad rotamer index
--
--  Errors other than a bad rotamer index are rethrown using 
--  the Lua function error().
--  
    function SafeSnap ( segIdx, rotIdx )
    --
    --  error message when attempting to snap to an invalid rotamer
    --
        local BADSNAP = "(snap index out of bounds)" 
    --
    --  don't allow a bad rotamer to stop us
    --
        local good, errmsg = pcall ( rotamer.SetRotamer, segIdx, rotIdx )
        if good then
            return 0, nil
        else
            local err2 = ParseError ( errmsg )
            local errp = err2:find ( BADSNAP )
            if errp ~= nil then
                return -1, err2
            end
            error ( errmsg, 0 )
        end
    end
    function ParseError ( errmsg )
        local reason
        local start, stop, line, msg
        start, stop, line, msg = errmsg:find ( ":(%d+):%s()" )
        if msg ~= nil then
            errmsg = errmsg:sub ( msg, #errmsg )
        end
        return errmsg    
    end
    --
    --  attempt to snap the sidechain in a safe, non-crashy manner
    --
        local rc, errmsg = SafeSnap ( segIdx, rotIdx )
        if rc ~= 0 then
            print ( "optimize: BAD SNAP, segment = "
                        .. segIdx ..
                    ", rotamer = "
                        .. rotIdx .. 
                    ", current rotamer count = "
                        .. rotamer.GetCount ( segIdx ) )
        end
LociOiling's picture
User offline. Last seen 2 hours 34 min ago. Offline
Joined: 12/27/2012
Groups: Beta Folders
see also

I've added this code to the wiki:

http://foldit.wikia.com/wiki/Using_pcall_to_trap_Lua_errors

I then found an existing page:

http://foldit.wikia.com/wiki/Lua_Error_Handling

which shows an example of trapping an error in band.Add. My version goes it one better by detecting a specific error condition and converting it into a return code.

LociOiling's picture
User offline. Last seen 2 hours 34 min ago. Offline
Joined: 12/27/2012
Groups: Beta Folders
not sure about the I18N aspects

I'm not sure whether error messages are thrown in the local language. If they are, you'll need to change "(snap index out of bounds)" to suit your locale. I'll test this at some point.

Joined: 07/21/2013
Groups: Beta Folders
problems with rotamers

https://fold.it/portal/node/996019

when you call get_rotamer_count initially, you are in initial state

when you call set_rotamer( 1 ), you are in rot_1 state

when you call set_rotamer( 2 ), this would not be the correct thing to do

you have to save the initial state

then set_rotamer( 1 )

then do stuff to check things

then recover initial state

then call set_rotamer( 2 )

then do stuff to check things

then recover initial state

then call set_rotamer( 3 )

this should fix your rotamer out of range problem

Want to try?
Add to Cookbook!
To download recipes to your cookbook, you need to have the game client running.
Parent

none

Children

none

Authors
Sitemap

Developed by: UW Center for Game Science, UW Institute for Protein Design, Northeastern University, Vanderbilt University Meiler Lab, UC Davis
Supported by: DARPA, NSF, NIH, HHMI, Microsoft, Adobe, RosettaCommons