Commit a16bc50a authored by Paul McCarthy's avatar Paul McCarthy
Browse files

Re-worked memoize function so it can be

instanceified. Image.isNeurological is now memoized.
parent 5636fd1b
......@@ -242,7 +242,7 @@ class Nifti1(object):
# a 4x4 array (via memoizeMD5), or the call
# to aff2axcodes. I'm guessing the latter,
# but am not 100% sure.
@memoize.memoizeMD5
@memoize.Instanceify(memoize.memoizeMD5)
def axisMapping(self, xform):
"""Returns the (approximate) correspondence of each axis in the source
coordinate system to the axes in the destination coordinate system,
......@@ -257,10 +257,11 @@ class Nifti1(object):
return nib.orientations.aff2axcodes(xform, inaxes)
@memoize.Instanceify(memoize.memoize)
def isNeurological(self):
"""Returns ``True`` if it looks like this ``Nifti1`` object is in
neurological orientation, ``False`` otherwise. This test is purely
based on the determinent of the voxel-to-mm transformation matrix -
based on the determinant of the voxel-to-mm transformation matrix -
if it has a positive determinant, the image is assumed to be in
neurological orientation, otherwise it is assumed to be in
radiological orientation.
......
......@@ -27,7 +27,7 @@ log = logging.getLogger(__name__)
# TODO Make this a class, and add
# a "clearCache" method to it.
def memoize(args=None, kwargs=None):
def memoize(func):
"""Memoize the given function by the value of the input arguments, allowing
the caller to specify which positional arguments (by index) and keyword
arguments (by name) are used for the comparison.
......@@ -36,55 +36,41 @@ def memoize(args=None, kwargs=None):
memoized on all arguments. Note that the arguments used for memoization
must be hashable, as they are used as keys in a dictionary.
This decorator must always be called with brackets, e.g. ::
memoize()
def myfunc():
# do stuff to be memoized
:arg args: A list of positional argument indices.
:arg kwargs: A list of keyword argument names.
"""
def decorator(func):
cache = {}
def wrapper(*a, **kwa):
key = []
cache = {}
defaultKey = '_memoize_noargs_'
if args is not None: key += [a[ i] for i in args]
if kwargs is not None: key += [kwa[k] for k in kwargs]
def wrapper(*a, **kwa):
# This decorator was created without
# any arguments specified - use all
# the arguments as the cache key.
if len(key) == 0:
key = []
# Keyword arguments are unordered,
# so we'll try and overcome this
# by sorting the kwarg dict keys.
key = list(a) + list([kwa[k] for k in sorted(kwa.keys)])
if a is not None: key += list(a)
if kwa is not None: key += [kwa[k] for k in sorted(kwa.keys())]
key = tuple(key)
# This decorator was created without
# any arguments specified - use the
# default cache key.
if len(key) == 0:
key = [defaultKey]
try:
result = cache[key]
key = tuple(key)
try:
result = cache[key]
except KeyError:
except KeyError:
result = func(*a, **kwa)
cache[key] = result
result = func(*a, **kwa)
cache[key] = result
log.debug('Adding to cache[{}]: {}'.format(
key, result))
log.debug('Adding to cache[{}]: {}'.format(key, result))
return result
return wrapper
return decorator
return result
return wrapper
def memoizeMD5(func):
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment