neo_tools.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. # -*- coding: utf-8 -*-
  2. """
  3. Tools to manipulate Neo objects.
  4. :copyright: Copyright 2014-2016 by the Elephant team, see AUTHORS.txt.
  5. :license: Modified BSD, see LICENSE.txt for details.
  6. """
  7. from __future__ import division, print_function
  8. from itertools import chain
  9. from neo.core.container import unique_objs
  10. def extract_neo_attrs(obj, parents=True, child_first=True,
  11. skip_array=False, skip_none=False):
  12. """Given a neo object, return a dictionary of attributes and annotations.
  13. Parameters
  14. ----------
  15. obj : neo object
  16. parents : bool, optional
  17. Also include attributes and annotations from parent neo
  18. objects (if any).
  19. child_first : bool, optional
  20. If True (default True), values of child attributes are used
  21. over parent attributes in the event of a name conflict.
  22. If False, parent attributes are used.
  23. This parameter does nothing if `parents` is False.
  24. skip_array : bool, optional
  25. If True (default False), skip attributes that store non-scalar
  26. array values.
  27. skip_none : bool, optional
  28. If True (default False), skip annotations and attributes that
  29. have a value of `None`.
  30. Returns
  31. -------
  32. dict
  33. A dictionary where the keys are annotations or attribute names and
  34. the values are the corresponding annotation or attribute value.
  35. """
  36. attrs = obj.annotations.copy()
  37. for attr in obj._necessary_attrs + obj._recommended_attrs:
  38. if skip_array and len(attr) >= 3 and attr[2]:
  39. continue
  40. attr = attr[0]
  41. if attr == getattr(obj, '_quantity_attr', None):
  42. continue
  43. attrs[attr] = getattr(obj, attr, None)
  44. if skip_none:
  45. for attr, value in attrs.copy().items():
  46. if value is None:
  47. del attrs[attr]
  48. if not parents:
  49. return attrs
  50. for parent in getattr(obj, 'parents', []):
  51. if parent is None:
  52. continue
  53. newattr = extract_neo_attrs(parent, parents=True,
  54. child_first=child_first,
  55. skip_array=skip_array,
  56. skip_none=skip_none)
  57. if child_first:
  58. newattr.update(attrs)
  59. attrs = newattr
  60. else:
  61. attrs.update(newattr)
  62. return attrs
  63. def _get_all_objs(container, classname):
  64. """Get all `neo` objects of a given type from a container.
  65. The objects can be any list, dict, or other iterable or mapping containing
  66. neo objects of a particular class, as well as any neo object that can hold
  67. the object.
  68. Objects are searched recursively, so the objects can be nested (such as a
  69. list of blocks).
  70. Parameters
  71. ----------
  72. container : list, tuple, iterable, dict, neo container
  73. The container for the neo objects.
  74. classname : str
  75. The name of the class, with proper capitalization
  76. (so `SpikeTrain`, not `Spiketrain` or `spiketrain`)
  77. Returns
  78. -------
  79. list
  80. A list of unique `neo` objects
  81. """
  82. if container.__class__.__name__ == classname:
  83. return [container]
  84. classholder = classname.lower() + 's'
  85. if hasattr(container, classholder):
  86. vals = getattr(container, classholder)
  87. elif hasattr(container, 'list_children_by_class'):
  88. vals = container.list_children_by_class(classname)
  89. elif hasattr(container, 'values') and not hasattr(container, 'ndim'):
  90. vals = container.values()
  91. elif hasattr(container, '__iter__') and not hasattr(container, 'ndim'):
  92. vals = container
  93. else:
  94. raise ValueError('Cannot handle object of type %s' % type(container))
  95. res = list(chain.from_iterable(_get_all_objs(obj, classname)
  96. for obj in vals))
  97. return unique_objs(res)
  98. def get_all_spiketrains(container):
  99. """Get all `neo.Spiketrain` objects from a container.
  100. The objects can be any list, dict, or other iterable or mapping containing
  101. spiketrains, as well as any neo object that can hold spiketrains:
  102. `neo.Block`, `neo.ChannelIndex`, `neo.Unit`, and `neo.Segment`.
  103. Containers are searched recursively, so the objects can be nested
  104. (such as a list of blocks).
  105. Parameters
  106. ----------
  107. container : list, tuple, iterable, dict,
  108. neo Block, neo Segment, neo Unit, neo ChannelIndex
  109. The container for the spiketrains.
  110. Returns
  111. -------
  112. list
  113. A list of the unique `neo.SpikeTrain` objects in `container`.
  114. """
  115. return _get_all_objs(container, 'SpikeTrain')
  116. def get_all_events(container):
  117. """Get all `neo.Event` objects from a container.
  118. The objects can be any list, dict, or other iterable or mapping containing
  119. events, as well as any neo object that can hold events:
  120. `neo.Block` and `neo.Segment`.
  121. Containers are searched recursively, so the objects can be nested
  122. (such as a list of blocks).
  123. Parameters
  124. ----------
  125. container : list, tuple, iterable, dict, neo Block, neo Segment
  126. The container for the events.
  127. Returns
  128. -------
  129. list
  130. A list of the unique `neo.Event` objects in `container`.
  131. """
  132. return _get_all_objs(container, 'Event')
  133. def get_all_epochs(container):
  134. """Get all `neo.Epoch` objects from a container.
  135. The objects can be any list, dict, or other iterable or mapping containing
  136. epochs, as well as any neo object that can hold epochs:
  137. `neo.Block` and `neo.Segment`.
  138. Containers are searched recursively, so the objects can be nested
  139. (such as a list of blocks).
  140. Parameters
  141. ----------
  142. container : list, tuple, iterable, dict, neo Block, neo Segment
  143. The container for the epochs.
  144. Returns
  145. -------
  146. list
  147. A list of the unique `neo.Epoch` objects in `container`.
  148. """
  149. return _get_all_objs(container, 'Epoch')