Skip to content

Commit 12b3f1b

Browse files
committed
wip
1 parent 48f94bf commit 12b3f1b

File tree

1 file changed

+102
-45
lines changed

1 file changed

+102
-45
lines changed

neo/rawio/spikegadgetsrawio.py

Lines changed: 102 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -46,68 +46,122 @@ def _parse_header(self):
4646

4747
f.seek(0)
4848
header_txt = f.read(header_size).decode('utf8')
49-
print(header_txt[-10:])
50-
f.seek(header_size)
51-
print(f.read(10))
49+
50+
#~ print(header_txt[-10:])
51+
#~ f.seek(header_size)
52+
#~ print(f.read(10))
5253

5354
#~ exit()
5455
# explore xml header
5556
root = ElementTree.fromstring(header_txt)
56-
5757
gconf = sr = root.find('GlobalConfiguration')
5858
hconf = root.find('HardwareConfiguration')
59+
sconf = root.find('SpikeConfiguration')
60+
5961
self._sampling_rate = float(hconf.attrib['samplingRate'])
6062

61-
# explore sub stream
62-
# the raw part is a complex vector of struct that depend on channel maps.
63-
# the "main_dtype" represent it
64-
main_dtype = []
63+
# explore sub stream and count packet size
64+
# first bytes is 0x55
65+
packet_size = 1
66+
67+
#~ main_dtype = []
68+
stream_bytes = {}
6569
for device in hconf:
66-
bytes = int(device.attrib['numBytes'])
67-
name = device.attrib['name']
68-
sub_dtype = (name, 'u1', (bytes, ))
69-
main_dtype.append(sub_dtype)
70-
self._main_dtype = np.dtype(main_dtype)
71-
#~ print(self._main_dtype)
70+
stream_id = device.attrib['name']
71+
num_bytes = int(device.attrib['numBytes'])
72+
stream_bytes[stream_id] = packet_size
73+
packet_size += num_bytes
74+
print('packet_size', packet_size)
75+
#~ print(stream_bytes)
76+
#~ exit()
7277

73-
#~ print(self._main_dtype.itemsize)
78+
# timesteamps 4 uint32
79+
self._timestamp_byte = packet_size
80+
packet_size += 4
7481

75-
self._raw_memmap = np.memmap(self.filename, mode='r', offset=header_size, dtype=self._main_dtype)
82+
num_ephy_channels = len(sconf)
83+
packet_size += 2 * num_ephy_channels
7684

77-
# wlak channels and keep only "analog" one
85+
raw_memmap = np.memmap(self.filename, mode='r', offset=header_size, dtype='<u1')
86+
87+
num_packet = raw_memmap.size // packet_size
88+
raw_memmap = raw_memmap[:num_packet*packet_size]
89+
self._raw_memmap = raw_memmap.reshape(-1, packet_size)
90+
91+
7892
stream_ids = []
7993
signal_streams = []
8094
signal_channels = []
81-
self._bytes_in_streams = {}
95+
96+
# walk deveice and keep only "analog" one
97+
self._mask_channels_bytes = {}
8298
for device in hconf:
8399
stream_id = device.attrib['name']
84100
for channel in device:
85101
#~ print(channel, channel.attrib)
86102

103+
if 'interleavedDataIDByte' in channel.attrib:
104+
# TODO deal with "headstageSensor" wich have interleaved
105+
continue
106+
87107
if channel.attrib['dataType'] == 'analog':
88108

89109
if stream_id not in stream_ids:
90110
stream_ids.append(stream_id)
91111
stream_name = stream_id
92112
signal_streams.append((stream_name, stream_id))
93-
self._bytes_in_streams[stream_id] = []
113+
self._mask_channels_bytes[stream_id] = []
94114

95115
name = channel.attrib['id']
96116
chan_id = channel.attrib['id']
97-
dtype = 'uint16' # TODO check this
117+
dtype = 'int16' # TODO check this
98118
units = 'uV' # TODO check where is the info
99119
gain = 1. # TODO check where is the info
100120
offset = 0. # TODO check where is the info
101121
signal_channels.append((name, chan_id, self._sampling_rate, 'int16',
102122
units, gain, offset, stream_id))
103123

104-
self._bytes_in_streams[stream_id].append(int(channel.attrib['startByte']))
124+
#~ self._bytes_in_streams[stream_id].append()
125+
num_bytes = stream_bytes[stream_id] + int(channel.attrib['startByte'])
126+
chan_mask = np.zeros(packet_size, dtype='bool')
127+
# int6: 2 bytes
128+
chan_mask[num_bytes] = True
129+
chan_mask[num_bytes+1] = True
130+
self._mask_channels_bytes[stream_id].append(chan_mask)
131+
132+
if num_ephy_channels > 0:
133+
stream_id = 'trodes'
134+
stream_name = stream_id
135+
signal_streams.append((stream_name, stream_id))
136+
self._mask_channels_bytes[stream_id] = []
137+
for chan_ind, trode in enumerate(sconf):
138+
name = trode.attrib['id']
139+
chan_id = trode.attrib['id']
140+
units = 'uV' # TODO check where is the info
141+
gain = 1. # TODO check where is the info
142+
offset = 0. # TODO check where is the info
143+
signal_channels.append((name, chan_id, self._sampling_rate, 'int16',
144+
units, gain, offset, stream_id))
145+
146+
chan_mask = np.zeros(packet_size, dtype='bool')
147+
148+
num_bytes = packet_size - 2 * num_ephy_channels + 2 * chan_ind
149+
chan_mask[num_bytes] = True
150+
chan_mask[num_bytes+1] = True
151+
self._mask_channels_bytes[stream_id].append(chan_mask)
152+
153+
# make mask as array
154+
self._mask_channels_bytes[stream_id]
155+
self._mask_streams = {}
156+
for stream_id, l in self._mask_channels_bytes.items():
157+
mask = np.array(l)
158+
self._mask_channels_bytes[stream_id] = mask
159+
self._mask_streams[stream_id] = np.any(mask, axis=0)
160+
161+
105162

106163
signal_streams = np.array(signal_streams, dtype=_signal_stream_dtype)
107164
signal_channels = np.array(signal_channels, dtype=_signal_channel_dtype)
108-
#~ print(signal_channels)
109-
#~ print(signal_streams)
110-
print(self._bytes_in_streams)
111165

112166

113167
# No events
@@ -151,34 +205,37 @@ def _get_signal_t_start(self, block_index, seg_index, stream_index):
151205

152206
def _get_analogsignal_chunk(self, block_index, seg_index, i_start, i_stop, stream_index, channel_indexes):
153207
stream_id = self.header['signal_streams'][stream_index]['id']
154-
print(stream_id)
155-
156-
raw_unit8 = self._raw_memmap[stream_id][i_start:i_stop]
157-
print('raw_unit8', raw_unit8.shape, raw_unit8.dtype)
208+
209+
raw_unit8 = self._raw_memmap[i_start:i_stop]
210+
#~ print('raw_unit8', raw_unit8.shape, raw_unit8.dtype)
158211

212+
num_chan = len(self._mask_channels_bytes[stream_id])
159213
if channel_indexes is None:
160-
channel_indexes = slice(channel_indexes)
161-
162-
nb = len(self._bytes_in_streams[stream_id])
163-
chan_inds = np.arange(nb)[channel_indexes]
164-
print('chan_inds', chan_inds)
165-
166-
byte_mask = np.zeros(raw_unit8.shape[1], dtype='bool')
167-
for chan_ind in chan_inds:
168-
bytes = self._bytes_in_streams[stream_id][chan_ind]
169-
# int16
170-
byte_mask[bytes] = True
171-
byte_mask[bytes+1] = True
214+
# no loop
215+
stream_mask = self._mask_streams[stream_id]
216+
else:
217+
#~ print('channel_indexes', channel_indexes)
218+
#~ print('chan_inds', chan_inds)
219+
220+
if instance(channel_indexes, slice):
221+
chan_inds = np.arange(num_chan)[channel_indexes]
222+
else:
223+
chan_inds = channel_indexes
224+
stream_mask = np.zeros(raw_unit8.shape[1], dtype='bool')
225+
for chan_ind in chan_inds:
226+
chan_mask = self._mask_channels_bytes[stream_id][chan_ind]
227+
stream_mask |= chan_mask
228+
172229

173-
print(byte_mask)
174230

175-
raw_unit8_mask = raw_unit8[:, byte_mask]
176-
print('raw_unit8_mask', raw_unit8_mask.shape, raw_unit8_mask.strides)
231+
#~ print(stream_mask)
177232

233+
# thisi fo a copy
234+
raw_unit8_mask = raw_unit8[:, stream_mask]
178235
shape = raw_unit8_mask.shape
179236
shape = (shape[0], shape[1] // 2)
180-
raw_unit16 = raw_unit8_mask.flatten().view('uint16').reshape(shape)
181-
print(raw_unit16.shape,raw_unit16.strides)
237+
raw_unit16 = raw_unit8_mask.flatten().view('int16').reshape(shape)
238+
#~ print(raw_unit16.shape,raw_unit16.strides)
182239

183240
return raw_unit16
184241

0 commit comments

Comments
 (0)