block.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. '''
  2. This module defines :class:`Block`, the main container gathering all the data,
  3. whether discrete or continous, for a given recording session. base class
  4. used by all :module:`neo.core` classes.
  5. :class:`Block` derives from :class:`Container`,
  6. from :module:`neo.core.container`.
  7. '''
  8. from datetime import datetime
  9. from neo.core.container import Container, unique_objs
  10. class Block(Container):
  11. '''
  12. Main container gathering all the data, whether discrete or continous, for a
  13. given recording session.
  14. A block is not necessarily temporally homogeneous, in contrast to :class:`Segment`.
  15. *Usage*::
  16. >>> from neo.core import Block, Segment, Group, AnalogSignal
  17. >>> from quantities import nA, kHz
  18. >>> import numpy as np
  19. >>>
  20. >>> # create a Block with 3 Segment and 2 Group objects
  21. ,,, blk = Block()
  22. >>> for ind in range(3):
  23. ... seg = Segment(name='segment %d' % ind, index=ind)
  24. ... blk.segments.append(seg)
  25. ...
  26. >>> for ind in range(2):
  27. ... group = Group(name='Array probe %d' % ind)
  28. ... blk.groups.append(group)
  29. ...
  30. >>> # Populate the Block with AnalogSignal objects
  31. ... for seg in blk.segments:
  32. ... for group in blk.groups:
  33. ... a = AnalogSignal(np.random.randn(10000, 64)*nA,
  34. ... sampling_rate=10*kHz)
  35. ... group.analogsignals.append(a)
  36. ... seg.analogsignals.append(a)
  37. *Required attributes/properties*:
  38. None
  39. *Recommended attributes/properties*:
  40. :name: (str) A label for the dataset.
  41. :description: (str) Text description.
  42. :file_origin: (str) Filesystem path or URL of the original data file.
  43. :file_datetime: (datetime) The creation date and time of the original
  44. data file.
  45. :rec_datetime: (datetime) The date and time of the original recording.
  46. *Properties available on this object*:
  47. :list_units: (deprecated) descends through hierarchy and returns a list of
  48. :class:`Unit` objects existing in the block. This shortcut exists
  49. because a common analysis case is analyzing all neurons that
  50. you recorded in a session.
  51. Note: Any other additional arguments are assumed to be user-specific
  52. metadata and stored in :attr:`annotations`.
  53. *Container of*:
  54. :class:`Segment`
  55. :class:`Group`
  56. :class:`ChannelIndex` (deprecated)
  57. '''
  58. _container_child_objects = ('Segment', 'ChannelIndex', 'Group')
  59. _child_properties = ('Unit',)
  60. _recommended_attrs = ((('file_datetime', datetime),
  61. ('rec_datetime', datetime),
  62. ('index', int)) +
  63. Container._recommended_attrs)
  64. _repr_pretty_attrs_keys_ = (Container._repr_pretty_attrs_keys_ +
  65. ('file_origin', 'file_datetime',
  66. 'rec_datetime', 'index'))
  67. _repr_pretty_containers = ('segments',)
  68. def __init__(self, name=None, description=None, file_origin=None,
  69. file_datetime=None, rec_datetime=None, index=None,
  70. **annotations):
  71. '''
  72. Initalize a new :class:`Block` instance.
  73. '''
  74. super().__init__(name=name, description=description,
  75. file_origin=file_origin, **annotations)
  76. self.file_datetime = file_datetime
  77. self.rec_datetime = rec_datetime
  78. self.index = index
  79. self.regionsofinterest = [] # temporary workaround.
  80. # the goal is to store all sub-classes of RegionOfInterest in a single list
  81. # but this will need substantial changes to container handling
  82. @property
  83. def data_children_recur(self):
  84. '''
  85. All data child objects stored in the current object,
  86. obtained recursively.
  87. '''
  88. # subclassing this to remove duplicate objects such as SpikeTrain
  89. # objects in both Segment and Unit
  90. # Only Block can have duplicate items right now, so implement
  91. # this here for performance reasons.
  92. return tuple(unique_objs(super().data_children_recur))
  93. def list_children_by_class(self, cls):
  94. '''
  95. List all children of a particular class recursively.
  96. You can either provide a class object, a class name,
  97. or the name of the container storing the class.
  98. '''
  99. # subclassing this to remove duplicate objects such as SpikeTrain
  100. # objects in both Segment and Unit
  101. # Only Block can have duplicate items right now, so implement
  102. # this here for performance reasons.
  103. return unique_objs(super().list_children_by_class(cls))
  104. @property
  105. def list_units(self):
  106. '''
  107. Return a list of all :class:`Unit` objects in the :class:`Block`.
  108. '''
  109. return self.list_children_by_class('unit')