NiBabel

Access a cacophony of neuro-imaging file formats

Table Of Contents

Previous topic

nibabel.arrayproxy.ArrayProxy

Next topic

nibabel.batteryrunners.BatteryRunner

This Page

Reggie -- the one

nibabel.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:

>>> 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 sitation. 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

digraph inheritancec4c6a24b03 { rankdir=LR; ratio=compress; fontsize=14; size="6.0, 8.0"; "BatteryRunner" [shape=ellipse,URL="nibabel.batteryrunners.BatteryRunner.html#nibabel.batteryrunners.BatteryRunner",fontname=Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans,fontsize=14,color=dodgerblue1,style=filled,height=0.75]; "Report" [shape=ellipse,URL="nibabel.batteryrunners.Report.html#nibabel.batteryrunners.Report",fontname=Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans,fontsize=14,color=dodgerblue1,style=filled,height=0.75]; }

Classes

BatteryRunner(checks) Class to run set of checks ..
Report([error, problem_level, problem_msg, ...]) Initialize report with values