batteryrunners
¶
Battery runner classes and Report classes
These classes / objects are for generic checking / fixing batteries
The BatteryRunner
class will run a series of checks on a single
object.
A check is a callable, of signature func(obj, fix=False)
which
returns a tuple (obj, Report)
for func(obj, False)
or
func(obj, True)
, where the obj may be a modified object, or a
different object, if fix==True
.
To run checks only, and return problem report objects:
>>> from nibabel.batteryrunners import BatteryRunner, Report
>>> def chk(obj, fix=False): # minimal check
... return obj, Report()
>>> btrun = BatteryRunner((chk,))
>>> reports = btrun.check_only('a string')
To run checks and fixes, returning fixed object and problem report sequence, with possible fix messages:
>>> fixed_obj, report_seq = btrun.check_fix('a string')
Reports are iterable things, where the elements in the iterations are
Problems
, with attributes error
, problem_level
,
problem_msg
, and possibly empty fix_msg
. The problem_level
is an integer, giving the level of problem, from 0 (no problem) to 50
(very bad problem). The levels follow the log levels from the logging
module (e.g 40 equivalent to “error” level, 50 to “critical”). The
error
can be one of None
if no error to suggest, or an Exception
class that the user might consider raising for this situation. The
problem_msg
and fix_msg
are human readable strings that should
explain what happened.
More about checks
¶
Checks are callables returning objects and reports, like chk
below,
such that:
obj, report = chk(obj, fix=False)
obj, report = chk(obj, fix=True)
For example, for the Analyze header, we need to check the datatype:
def chk_datatype(hdr, fix=True):
rep = Report(hdr, HeaderDataError)
code = int(hdr['datatype'])
try:
dtype = AnalyzeHeader._data_type_codes.dtype[code]
except KeyError:
rep.problem_level = 40
rep.problem_msg = 'data code not recognized'
else:
if dtype.type is np.void:
rep.problem_level = 40
rep.problem_msg = 'data code not supported'
else:
return hdr, rep
if fix:
rep.fix_problem_msg = 'not attempting fix'
return hdr, rep
or the bitpix:
def chk_bitpix(hdr, fix=True):
rep = Report(HeaderDataError)
code = int(hdr['datatype'])
try:
dt = AnalyzeHeader._data_type_codes.dtype[code]
except KeyError:
rep.problem_level = 10
rep.problem_msg = 'no valid datatype to fix bitpix'
return hdr, rep
bitpix = dt.itemsize * 8
if bitpix == hdr['bitpix']:
return hdr, rep
rep.problem_level = 10
rep.problem_msg = 'bitpix does not match datatype')
if fix:
hdr['bitpix'] = bitpix # inplace modification
rep.fix_msg = 'setting bitpix to match datatype'
return hdr, ret
or the pixdims:
def chk_pixdims(hdr, fix=True):
rep = Report(hdr, HeaderDataError)
if not np.any(hdr['pixdim'][1:4] < 0):
return hdr, rep
rep.problem_level = 40
rep.problem_msg = 'pixdim[1,2,3] should be positive'
if fix:
hdr['pixdim'][1:4] = np.abs(hdr['pixdim'][1:4])
rep.fix_msg = 'setting to abs of pixdim values'
return hdr, rep
|
Class to run set of checks |
|
Initialize report with values |
BatteryRunner
¶
- class nibabel.batteryrunners.BatteryRunner(checks)¶
Bases:
object
Class to run set of checks
Initialize instance from sequence of checks
- Parameters:
- checkssequence
sequence of checks, where checks are callables matching signature
obj, rep = chk(obj, fix=False)
. Checks are run in the order they are passed.
Examples
>>> def chk(obj, fix=False): # minimal check ... return obj, Report() >>> btrun = BatteryRunner((chk,))
- __init__(checks)¶
Initialize instance from sequence of checks
- Parameters:
- checkssequence
sequence of checks, where checks are callables matching signature
obj, rep = chk(obj, fix=False)
. Checks are run in the order they are passed.
Examples
>>> def chk(obj, fix=False): # minimal check ... return obj, Report() >>> btrun = BatteryRunner((chk,))
- check_fix(obj)¶
Run checks, with fixes, on obj returning obj, reports
- Parameters:
- objanything
object on which to run checks, fixes
- Returns:
- objanything
possibly modified or replaced obj, after fixes
- reportssequence
sequence of reports on checks, fixes
- check_only(obj)¶
Run checks on obj returning reports
- Parameters:
- objanything
object on which to run checks
- Returns:
- reportssequence
sequence of report objects reporting on result of running checks (without fixes) on obj
Report
¶
- class nibabel.batteryrunners.Report(error=<class 'Exception'>, problem_level=0, problem_msg='', fix_msg='')¶
Bases:
object
Initialize report with values
- Parameters:
- errorNone or Exception
Error to raise if raising error for this check. If None, no error can be raised for this check (it was probably normal).
- problem_levelint
level of problem. From 0 (no problem) to 50 (severe problem). If the report originates from a fix, then this is the level of the problem remaining after the fix. Default is 0
- problem_msgstring
String describing problem detected. Default is ‘’
- fix_msgstring
String describing any fix applied. Default is ‘’.
Examples
>>> rep = Report() >>> rep.problem_level 0 >>> rep = Report(TypeError, 10) >>> rep.problem_level 10
- __init__(error=<class 'Exception'>, problem_level=0, problem_msg='', fix_msg='')¶
Initialize report with values
- Parameters:
- errorNone or Exception
Error to raise if raising error for this check. If None, no error can be raised for this check (it was probably normal).
- problem_levelint
level of problem. From 0 (no problem) to 50 (severe problem). If the report originates from a fix, then this is the level of the problem remaining after the fix. Default is 0
- problem_msgstring
String describing problem detected. Default is ‘’
- fix_msgstring
String describing any fix applied. Default is ‘’.
Examples
>>> rep = Report() >>> rep.problem_level 0 >>> rep = Report(TypeError, 10) >>> rep.problem_level 10
- log_raise(logger, error_level=40)¶
Log problem, raise error if problem >= error_level
- Parameters:
- loggerlog
log object, implementing
log
method- error_levelint, optional
If
self.problem_level
>= error_level, raise error
- property message¶
formatted message string, including fix message if present
- write_raise(stream, error_level=40, log_level=30)¶
Write report to stream
- Parameters:
- streamfile-like
implementing
write
method- error_levelint, optional
level at which to raise error for problem detected in
self
- log_levelint, optional
Such that if log_level is >=
self.problem_level
we write the report to stream, otherwise we write nothing.