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