mailRe: RelaxWarnings


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by Chris MacRaild on August 17, 2006 - 12:30:
On Thu, 2006-08-17 at 03:15 +1000, Edward d'Auvergne wrote:


A problem that needs to be solved is how do we implement specific
warnings?  For example if two distant areas of relax test for zero
length XH bond vectors, there should be one function which takes the
residue number and formats a standard message for that warning.
However the 'warn()' function expects a message?  What if we have a
class object called RelaxZeroLengthWarning which has a __call__()
method which returns the formatted string?  You could then, from
within different parts of relax, generate an error by having the code:

if len(xh) == 0.0:
    warn(RelaxZeroLengthWarning(res))

where warn was placed into __builtin__ by relax (see the
'nan_catch_test' branch) and 'res' is the residue number.  There
might, however, be a much better way to implement specific warnings.
The rest of the system could be setup as in the 'nan_catch_test'
branch.


This is a good point. After some head-scratching, I think the 'correct'
way to do it is to treat each warning category specifically in the
formatwarning function. So we would have something more like:

def format(message, category, filename, lineno):
    if issubclass(category, RelaxZeroLengthWarning):
        message = "Zero length vector at residue %s" % message

    # ...lots more specific warning cases...

    if issubclass(category, BaseWarning):
        message = "RelaxWarning: %s\n" % message

    return message

warnings.formatwarning = format


Then the 'message' for RelaxZeroLengthWarning when we do warn() is just
the residue, and format() does the rest.

A number of RelaxErrors take a number of arguments and from my reading
of the docs I would guess that the warning system would assert that
the 'message' argument to 'warn()' must be a string.  

Another good point. That proposal wont work.

How about using
the '__call__()' function to pass in the relevant data to the class
using keywords and then store it within the object.

The problem here is that __call__() works when you call an instance of a
class. RelaxZeroLengthWarning is a class, so RelaxZeroLengthWarning(res)
instanciates the class, effectively calling __init__(res). 

After some more head-scratching and some help from Gary, I realise that
this is a actually what we want. warn() can be called with a single
argument which is an instance of a Warning class, then message is str()
called on that instance, and category is class() called on that
instance. So if we code the message formatting in __str__() for each of
the warning classes, we can do:

warn(RelaxZeroLengthWarning(res))

as you propose, and this will allow for an arbitrary number and type of
arguments. It might even be possible to subclass the warning classes
from the equivalent error class, making for even more streamlining of
the code.

I'll have a shot at making this work, based on the start you have made
in the nan_catch_test branch.

Chris

  Then the
subsequently called format function can use the else-if chain to pull
out and format the stored data?

Edward





Related Messages


Powered by MHonArc, Updated Thu Aug 17 14:20:57 2006