mailRe: RelaxWarnings


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

Header


Content

Posted by Edward d'Auvergne on August 17, 2006 - 14:16:
On 8/17/06, Chris MacRaild wrote:
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.


I didn't think of using the __str__() function, you don't have to ignore the message argument. Also the else-if block isn't necessary as you just need to pull out matches to BaseWarning.

Chris, would you be able to revert the changes I made to the 1.2 line
(the RelaxErrorSystem stuff).  This experiment is a dead end so it
would be good to revert the changes to clean it up.  Then you could
either use the nan_catch_test branch or a new branch off 1.2 to try
out the warning system.

I have to run off to the airport now,

Edward



Related Messages


Powered by MHonArc, Updated Wed Aug 30 07:01:15 2006