converter.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. from neo import Group, Unit, ChannelView, SpikeTrain
  2. from neo.core.basesignal import BaseSignal
  3. def _convert_unit(unit):
  4. group_unit = Group(unit.spiketrains,
  5. name=unit.name,
  6. file_origin=unit.file_origin,
  7. description=unit.description,
  8. allowed_types=[SpikeTrain],
  9. **unit.annotations)
  10. # clean up references
  11. for st in unit.spiketrains:
  12. delattr(st, 'unit')
  13. return group_unit
  14. def _convert_channel_index(channel_index):
  15. # convert child objects
  16. new_child_objects = []
  17. for child_obj in channel_index.children:
  18. if isinstance(child_obj, Unit):
  19. new_unit = _convert_unit(child_obj)
  20. new_child_objects.append(new_unit)
  21. elif isinstance(child_obj, BaseSignal):
  22. # always generate view, as this might provide specific info regarding the object
  23. new_view = ChannelView(child_obj, channel_index.index,
  24. name=channel_index.name,
  25. description=channel_index.description,
  26. file_origin=channel_index.file_origin,
  27. **channel_index.annotations)
  28. new_view.array_annotate(channel_ids=channel_index.channel_ids,
  29. channel_names=channel_index.channel_names)
  30. # separate dimenions of coordinates into different 1D array_annotations
  31. if channel_index.coordinates.shape:
  32. if len(channel_index.coordinates.shape) == 1:
  33. new_view.array_annotate(coordinates=channel_index.coordinates)
  34. elif len(channel_index.coordinates.shape) == 2:
  35. for dim in range(channel_index.coordinates.shape[1]):
  36. new_view.array_annotate(
  37. **{f'coordinates_dim{dim}': channel_index.coordinates[:, dim]})
  38. else:
  39. raise ValueError(f'Incompatible channel index coordinates with wrong '
  40. f'dimensions: Provided coordinates have shape '
  41. f'{channel_index.coordinates.shape}.')
  42. # clean up references
  43. delattr(child_obj, 'channel_index')
  44. new_child_objects.append(new_view)
  45. new_channel_group = Group(new_child_objects,
  46. name=channel_index.name,
  47. file_origin=channel_index.file_origin,
  48. description=channel_index.description,
  49. **channel_index.annotations)
  50. return new_channel_group
  51. def convert_channelindex_to_view_group(block):
  52. """
  53. Convert deprecated ChannelIndex and Unit objects to ChannelView and Group objects
  54. This conversion is preserving all information stored as attributes and (array) annotations.
  55. The conversion is done in-place.
  56. Each ChannelIndex is represented as a Group. Linked Unit objects are represented as child Group
  57. (subgroup) objects. Linked data objects (neo.AnalogSignal, neo.IrregularlySampledSignal) are
  58. represented by a View object linking to the original data object.
  59. Attributes are as far as possible conserved by the conversion of objects. `channel_ids`,
  60. `channel_names` and `coordinates` are converted to array_annotations.
  61. :param block: neo.Block structure to be converted
  62. :return: block: updated neo.Block structure
  63. """
  64. for channel_index in block.channel_indexes:
  65. new_channel_group = _convert_channel_index(channel_index)
  66. block.groups.append(new_channel_group)
  67. # clean up references
  68. delattr(block, 'channel_indexes')
  69. # this is a hack to clean up ImageSequence objects that are not properly linked to
  70. # ChannelIndex objects, see also Issue #878
  71. for seg in block.segments:
  72. for imgseq in seg.imagesequences:
  73. delattr(imgseq, 'channel_index')
  74. return block