Source code for neurom.utils

# Copyright (c) 2015, Ecole Polytechnique Federale de Lausanne, Blue Brain Project
# All rights reserved.
#
# This file is part of NeuroM <https://github.com/BlueBrain/NeuroM>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#     1. Redistributions of source code must retain the above copyright
#        notice, this list of conditions and the following disclaimer.
#     2. Redistributions in binary form must reproduce the above copyright
#        notice, this list of conditions and the following disclaimer in the
#        documentation and/or other materials provided with the distribution.
#     3. Neither the name of the copyright holder nor the names of
#        its contributors may be used to endorse or promote products
#        derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""NeuroM helper utilities."""
from enum import Enum
import json
import warnings
from functools import partial, update_wrapper, wraps

import numpy as np


[docs]class memoize(object): """cache the return value of a method. This class is meant to be used as a decorator of methods. The return value from a given method invocation will be cached on the instance whose method was invoked. All arguments passed to a method decorated with memoize must be hashable. If a memoized method is invoked directly on its class the result will not be cached. Instead the method will be invoked like a static method:: class Obj(object): @memoize def add_to(self, arg): return self + arg Obj.add_to(1) # not enough arguments Obj.add_to(1, 2) # returns 3, result is not cached """ def __init__(self, func): """Initialize a memoize object.""" self.func = func update_wrapper(self, func) def __get__(self, obj, objtype=None): """Get the attribute from the object.""" return partial(self, obj) def __call__(self, *args, **kw): """Callable for decorator.""" obj = args[0] try: cache = obj.__cache # pylint: disable=protected-access except AttributeError: cache = obj.__cache = {} key = (self.func, args[1:], frozenset(kw.items())) try: res = cache[key] except KeyError: res = cache[key] = self.func(*args, **kw) return res
def _warn_deprecated(msg): """Issue a deprecation warning.""" warnings.simplefilter('always', DeprecationWarning) warnings.warn(msg, category=DeprecationWarning, stacklevel=2) warnings.simplefilter('default', DeprecationWarning)
[docs]def deprecated(fun_name=None, msg=""): """Issue a deprecation warning for a function.""" def _deprecated(fun): """Issue a deprecation warning for a function.""" @wraps(fun) def _wrapper(*args, **kwargs): """Issue deprecation warning and forward arguments to fun.""" name = fun_name if fun_name is not None else fun.__name__ _warn_deprecated('Call to deprecated function %s. %s' % (name, msg)) return fun(*args, **kwargs) return _wrapper return _deprecated
def deprecated_module(mod_name, msg=""): """Issue a deprecation warning for a module.""" _warn_deprecated('Module %s is deprecated. %s' % (mod_name, msg)) class NeuromJSON(json.JSONEncoder): """JSON encoder that handles numpy types. In python3, numpy.dtypes don't serialize to correctly, so a custom converter is needed. """ def default(self, o): # pylint: disable=method-hidden """Override default method for numpy types.""" if isinstance(o, np.floating): return float(o) if isinstance(o, np.integer): return int(o) if isinstance(o, np.ndarray): return o.tolist() return json.JSONEncoder.default(self, o) # pylint: disable=comparison-with-callable
[docs]class OrderedEnum(Enum): """An ordered enum class. Implementation taken here https://docs.python.org/3/library/enum.html#orderedenum Fixes https://github.com/BlueBrain/NeuroM/issues/697 """ def __ge__(self, other): """Check greater than or equal to.""" if self.__class__ is other.__class__: return self.value >= other.value raise NotImplementedError def __gt__(self, other): """Check greater than.""" if self.__class__ is other.__class__: return self.value > other.value raise NotImplementedError def __le__(self, other): """Check less than or equal to.""" if self.__class__ is other.__class__: return self.value <= other.value raise NotImplementedError def __lt__(self, other): """Check less than.""" if self.__class__ is other.__class__: return self.value < other.value raise NotImplementedError