Source code for mordred._base.descriptor

from abc import ABCMeta, abstractmethod
from inspect import isabstract
from contextlib import contextmanager

import six
import numpy as np


class MissingValueException(Exception):
    "internally used exception"

    __slots__ = ('error',)

    def __init__(self, error):
        self.error = error


[docs]class Descriptor(six.with_metaclass(ABCMeta, object)): r"""abstract base class of descriptors.""" __slots__ = '_context', explicit_hydrogens = True kekulize = False require_connected = False require_3D = False def __reduce_ex__(self, version): return self.__class__, self.parameters() @abstractmethod
[docs] def parameters(self): '''get __init__ arguments of this descriptor instance. (abstract method) ''' raise NotImplementedError('not implemented Descriptor.parameters method')
@property def as_argument(self): '''argument representation of descriptor''' return self @staticmethod def _pretty(v): v = getattr(v, 'as_argument', v) return repr(v) def __repr__(self): return '{}({})'.format( self.__class__, ', '.join(self._pretty(a) for a in self.parameters()) ) def __hash__(self): return hash((self.__class__, self.parameters())) def __compare_by_reduce(meth): def compare(self, other): l = self.__class__, self.parameters() r = other.__class__, other.parameters() return getattr(l, meth)(r) return compare __eq__ = __compare_by_reduce('__eq__') __ne__ = __compare_by_reduce('__ne__') __lt__ = __compare_by_reduce('__lt__') __gt__ = __compare_by_reduce('__gt__') __le__ = __compare_by_reduce('__le__') __ge__ = __compare_by_reduce('__ge__') rtype = None @classmethod
[docs] def preset(cls): r"""generate preset descriptor instances. :rtype: iterable """ return ()
[docs] def dependencies(self): r"""descriptor dependencies. :rtype: {:py:class:`str`: (:py:class:`Descriptor` or :py:class:`None`)} or :py:class:`None` """ pass
@abstractmethod
[docs] def calculate(self, mol): r"""calculate descriptor value. (abstract method) """ raise NotImplementedError('not implemented Descriptor.calculate method')
@classmethod
[docs] def is_descriptor_class(cls, desc): r"""check calculatable descriptor class or not. :rtype: :py:class:`bool` """ return ( isinstance(desc, type) and issubclass(desc, cls) and not isabstract(desc) )
@property def mol(self): '''get molecule''' return self._context.get_mol(self) @property def coord(self): '''get 3D coordinate''' if not self.require_3D: self.fail(AttributeError('use 3D coordinate in 2D descriptor')) return self._context.get_coord(self) @contextmanager
[docs] def rethrow_zerodiv(self): '''treat zero div as known exception''' with np.errstate(divide='raise', invalid='raise'): try: yield except (FloatingPointError, ZeroDivisionError) as e: self.fail(ZeroDivisionError(*e.args))
[docs] def fail(self, exception): '''raise known exception and return missing value''' raise MissingValueException(exception)
@contextmanager
[docs] def rethrow_na(self, exception): '''treat any exceptions as known exception''' try: yield except exception as e: self.fail(e)