block.py 4.9 KB

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