basesignal.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. # -*- coding: utf-8 -*-
  2. '''
  3. This module implements :class:`BaseSignal`, an array of signals.
  4. :class:`BaseSignal` inherits from :class:`quantites.Quantity`, which
  5. inherits from :class:`numpy.array`.
  6. Inheritance from :class:`numpy.array` is explained here:
  7. http://docs.scipy.org/doc/numpy/user/basics.subclassing.html
  8. In brief:
  9. * Initialization of a new object from constructor happens in :meth:`__new__`.
  10. This is where user-specified attributes are set.
  11. * :meth:`__array_finalize__` is called for all new objects, including those
  12. created by slicing. This is where attributes are copied over from
  13. the old object.
  14. '''
  15. # needed for python 3 compatibility
  16. from __future__ import absolute_import, division, print_function
  17. import logging
  18. import numpy as np
  19. import quantities as pq
  20. from neo.core.baseneo import BaseNeo, MergeError, merge_annotations
  21. from neo.core.channelindex import ChannelIndex
  22. logger = logging.getLogger("Neo")
  23. class BaseSignal(BaseNeo, pq.Quantity):
  24. def __ne__(self, other):
  25. '''
  26. Non-equality test (!=)
  27. '''
  28. return not self.__eq__(other)
  29. def _apply_operator(self, other, op, *args):
  30. '''
  31. Handle copying metadata to the new :class:`BaseSignal`
  32. after a mathematical operation.
  33. '''
  34. self._check_consistency(other)
  35. f = getattr(super(BaseSignal, self), op)
  36. new_signal = f(other, *args)
  37. new_signal._copy_data_complement(self)
  38. return new_signal
  39. def __add__(self, other, *args):
  40. '''
  41. Addition (+)
  42. '''
  43. return self._apply_operator(other, "__add__", *args)
  44. def __sub__(self, other, *args):
  45. '''
  46. Subtraction (-)
  47. '''
  48. return self._apply_operator(other, "__sub__", *args)
  49. def __mul__(self, other, *args):
  50. '''
  51. Multiplication (*)
  52. '''
  53. return self._apply_operator(other, "__mul__", *args)
  54. def __truediv__(self, other, *args):
  55. '''
  56. Float division (/)
  57. '''
  58. return self._apply_operator(other, "__truediv__", *args)
  59. def __div__(self, other, *args):
  60. '''
  61. Integer division (//)
  62. '''
  63. return self._apply_operator(other, "__div__", *args)
  64. __radd__ = __add__
  65. __rmul__ = __sub__
  66. def as_array(self, units=None):
  67. """
  68. Return the signal as a plain NumPy array.
  69. If `units` is specified, first rescale to those units.
  70. """
  71. if units:
  72. return self.rescale(units).magnitude
  73. else:
  74. return self.magnitude
  75. def as_quantity(self):
  76. """
  77. Return the signal as a quantities array.
  78. """
  79. return self.view(pq.Quantity)