Skip to content

Commit da1af2e

Browse files
committed
drafty implementation
1 parent 4c53e44 commit da1af2e

File tree

1 file changed

+49
-5
lines changed

1 file changed

+49
-5
lines changed

neo/rawio/spikegadgetsrawio.py

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@
44
55
https://spikegadgets.com/spike-products/
66
7+
8+
The file ".rec" have :
9+
* a fist part in text with xml informations
10+
* a second part for the binary buffer
11+
712
Author: Samuel Garcia
813
"""
914
from .baserawio import (BaseRawIO, _signal_channel_dtype, _unit_channel_dtype,
1015
_event_channel_dtype)
1116

1217
import numpy as np
1318

19+
from xml.etree import ElementTree
1420

1521
class SpikeGadgetsRawIO(BaseRawIO):
1622
extensions = ['rec']
@@ -25,8 +31,42 @@ def _source_name(self):
2531

2632
def _parse_header(self):
2733

34+
# parse file until "</Configuration>"
35+
header_size = None
36+
with open(self.filename, mode='rb') as f:
37+
while True:
38+
line = f.readline()
39+
if b"</Configuration>" in line:
40+
header_size = f.tell()
41+
break
42+
if header_size is None:
43+
ValueError("SpikeGadgets : the xml header do not contain </Configuration>")
44+
print(header_size)
45+
f.seek(0)
46+
header_txt = f.read(header_size).decode('utf8')
47+
48+
# explore xml header
49+
root = ElementTree.fromstring(header_txt)
50+
51+
gconf = sr = root.find('GlobalConfiguration')
52+
hconf = root.find('HardwareConfiguration')
53+
self._sampling_rate = float(hconf.attrib['samplingRate'])
54+
2855
signal_channels = []
29-
signal_channels = np.array(sig_channels, dtype=_signal_channel_dtype)
56+
for chan_ind, child in enumerate(hconf.find('Device')):
57+
name = child.attrib['id']
58+
chan_id = chan_ind #TODO change this to str with new rawio refactoring
59+
dtype = 'int16' # TODO check this
60+
units = 'uV' # TODO check where is the info
61+
gain = 1. # TODO check where is the info
62+
offset = 0. # TODO check where is the info
63+
group_id = 0
64+
signal_channels.append((name, chan_id, self._sampling_rate, 'int16',
65+
units, gain, offset, group_id))
66+
signal_channels = np.array(signal_channels, dtype=_signal_channel_dtype)
67+
68+
self._raw_memmap = np.memmap(self.filename, mode='r', offset=header_size, dtype='int16')
69+
self._raw_memmap = self._raw_memmap.reshape(-1, signal_channels.size)
3070

3171
# No events
3272
event_channels = []
@@ -39,8 +79,8 @@ def _parse_header(self):
3979
# fille into header dict
4080
self.header = {}
4181
self.header['nb_block'] = 1
42-
self.header['nb_segment'] = [nb_segment]
43-
self.header['signal_channels'] = sig_channels
82+
self.header['nb_segment'] = [1]
83+
self.header['signal_channels'] = signal_channels
4484
self.header['unit_channels'] = unit_channels
4585
self.header['event_channels'] = event_channels
4686

@@ -50,16 +90,20 @@ def _segment_t_start(self, block_index, seg_index):
5090
return 0.
5191

5292
def _segment_t_stop(self, block_index, seg_index):
93+
size = self._raw_memmap.shape[0]
94+
t_stop = size / self._sampling_rate
5395
return t_stop
5496

5597
def _get_signal_size(self, block_index, seg_index, channel_indexes):
56-
sie = 0
98+
size = self._raw_memmap.shape[0]
5799
return size
58100

59101
def _get_signal_t_start(self, block_index, seg_index, channel_indexes):
60102
return 0.
61103

62104
def _get_analogsignal_chunk(self, block_index, seg_index, i_start, i_stop, channel_indexes):
63-
raw_signals = None
105+
if channel_indexes is None:
106+
channel_indexes = slice(None)
107+
raw_signals = self._raw_memmap[slice(i_start, i_stop), :][:, channel_indexes]
64108
return raw_signals
65109

0 commit comments

Comments
 (0)