Scheduled service maintenance on November 22


On Friday, November 22, 2024, between 06:00 CET and 18:00 CET, GIN services will undergo planned maintenance. Extended service interruptions should be expected. We will try to keep downtimes to a minimum, but recommend that users avoid critical tasks, large data uploads, or DOI requests during this time.

We apologize for any inconvenience.

neuroscoperawio.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. # -*- coding: utf-8 -*-
  2. """
  3. Reading from neuroscope format files.
  4. Ref: http://neuroscope.sourceforge.net/
  5. It is an old format from Buzsaki's lab
  6. Some old open datasets from spike sorting
  7. are still using this format.
  8. This only the signals.
  9. This should be done (but maybe never will):
  10. * SpikeTrain file '.clu' '.res'
  11. * Event '.ext.evt' or '.evt.ext'
  12. Author: Samuel Garcia
  13. """
  14. from __future__ import unicode_literals, print_function, division, absolute_import
  15. from .baserawio import (BaseRawIO, _signal_channel_dtype, _unit_channel_dtype,
  16. _event_channel_dtype)
  17. import numpy as np
  18. from xml.etree import ElementTree
  19. class NeuroScopeRawIO(BaseRawIO):
  20. extensions = ['xml', 'dat']
  21. rawmode = 'one-file'
  22. def __init__(self, filename=''):
  23. BaseRawIO.__init__(self)
  24. self.filename = filename
  25. def _source_name(self):
  26. return self.filename.replace('.xml', '').replace('.dat', '')
  27. def _parse_header(self):
  28. filename = self.filename.replace('.xml', '').replace('.dat', '')
  29. tree = ElementTree.parse(filename + '.xml')
  30. root = tree.getroot()
  31. acq = root.find('acquisitionSystem')
  32. nbits = int(acq.find('nBits').text)
  33. nb_channel = int(acq.find('nChannels').text)
  34. self._sampling_rate = float(acq.find('samplingRate').text)
  35. voltage_range = float(acq.find('voltageRange').text)
  36. # offset = int(acq.find('offset').text)
  37. amplification = float(acq.find('amplification').text)
  38. # find groups for channels
  39. channel_group = {}
  40. for grp_index, xml_chx in enumerate(
  41. root.find('anatomicalDescription').find('channelGroups').findall('group')):
  42. for xml_rc in xml_chx:
  43. channel_group[int(xml_rc.text)] = grp_index
  44. if nbits == 16:
  45. sig_dtype = 'int16'
  46. gain = voltage_range / (2 ** 16) / amplification / 1000.
  47. # ~ elif nbits==32:
  48. # Not sure if it is int or float
  49. # ~ dt = 'int32'
  50. # ~ gain = voltage_range/2**32/amplification
  51. else:
  52. raise (NotImplementedError)
  53. self._raw_signals = np.memmap(filename + '.dat', dtype=sig_dtype,
  54. mode='r', offset=0).reshape(-1, nb_channel)
  55. # signals
  56. sig_channels = []
  57. for c in range(nb_channel):
  58. name = 'ch{}grp{}'.format(c, channel_group[c])
  59. chan_id = c
  60. units = 'mV'
  61. offset = 0.
  62. group_id = 0
  63. sig_channels.append((name, chan_id, self._sampling_rate,
  64. sig_dtype, units, gain, offset, group_id))
  65. sig_channels = np.array(sig_channels, dtype=_signal_channel_dtype)
  66. # No events
  67. event_channels = []
  68. event_channels = np.array(event_channels, dtype=_event_channel_dtype)
  69. # No spikes
  70. unit_channels = []
  71. unit_channels = np.array(unit_channels, dtype=_unit_channel_dtype)
  72. # fille into header dict
  73. self.header = {}
  74. self.header['nb_block'] = 1
  75. self.header['nb_segment'] = [1]
  76. self.header['signal_channels'] = sig_channels
  77. self.header['unit_channels'] = unit_channels
  78. self.header['event_channels'] = event_channels
  79. self._generate_minimal_annotations()
  80. def _segment_t_start(self, block_index, seg_index):
  81. return 0.
  82. def _segment_t_stop(self, block_index, seg_index):
  83. t_stop = self._raw_signals.shape[0] / self._sampling_rate
  84. return t_stop
  85. def _get_signal_size(self, block_index, seg_index, channel_indexes):
  86. return self._raw_signals.shape[0]
  87. def _get_signal_t_start(self, block_index, seg_index, channel_indexes):
  88. return 0.
  89. def _get_analogsignal_chunk(self, block_index, seg_index, i_start, i_stop, channel_indexes):
  90. if channel_indexes is None:
  91. channel_indexes = slice(None)
  92. raw_signals = self._raw_signals[slice(i_start, i_stop), channel_indexes]
  93. return raw_signals