Skip to content

Commit d722b0b

Browse files
authored
Merge pull request #1609 from h-mayorquin/fix_time_metadata
Add timing metadata for `SpikeGLXRawIO`
2 parents 6f571f0 + a6fa96d commit d722b0b

File tree

2 files changed

+75
-4
lines changed

2 files changed

+75
-4
lines changed

neo/rawio/spikeglxrawio.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,14 +224,25 @@ def _parse_header(self):
224224
spike_channels = np.array(spike_channels, dtype=_spike_channel_dtype)
225225

226226
# deal with nb_segment and t_start/t_stop per segment
227-
self._t_starts = {seg_index: 0.0 for seg_index in range(nb_segment)}
227+
228+
self._t_starts = {stream_name: {} for stream_name in stream_names}
228229
self._t_stops = {seg_index: 0.0 for seg_index in range(nb_segment)}
229-
for seg_index in range(nb_segment):
230-
for stream_name in stream_names:
230+
231+
for stream_name in stream_names:
232+
for seg_index in range(nb_segment):
231233
info = self.signals_info_dict[seg_index, stream_name]
234+
235+
frame_start = float(info["meta"]["firstSample"])
236+
sampling_frequency = info["sampling_rate"]
237+
t_start = frame_start / sampling_frequency
238+
239+
self._t_starts[stream_name][seg_index] = t_start
232240
t_stop = info["sample_length"] / info["sampling_rate"]
233241
self._t_stops[seg_index] = max(self._t_stops[seg_index], t_stop)
234242

243+
244+
245+
235246
# fille into header dict
236247
self.header = {}
237248
self.header["nb_block"] = 1
@@ -276,7 +287,8 @@ def _segment_t_stop(self, block_index, seg_index):
276287
return self._t_stops[seg_index]
277288

278289
def _get_signal_t_start(self, block_index, seg_index, stream_index):
279-
return 0.0
290+
stream_name = self.header["signal_streams"][stream_index]["name"]
291+
return self._t_starts[stream_name][seg_index]
280292

281293
def _event_count(self, event_channel_idx, block_index=None, seg_index=None):
282294
timestamps, _, _ = self._get_event_timestamps(block_index, seg_index, event_channel_idx, None, None)

neo/test/rawiotest/test_spikeglxrawio.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,65 @@ def test_nidq_digital_channel(self):
112112
atol = 0.001
113113
assert np.allclose(on_diff, 1, atol=atol)
114114

115+
def test_t_start_reading(self):
116+
"""Test that t_start values are correctly read for all streams and segments."""
117+
118+
# Expected t_start values for each stream and segment
119+
expected_t_starts = {
120+
'imec0.ap': {
121+
0: 15.319535472007237,
122+
1: 15.339535431281986,
123+
2: 21.284723325294053,
124+
3: 21.3047232845688
125+
},
126+
'imec1.ap': {
127+
0: 15.319554693264516,
128+
1: 15.339521518106308,
129+
2: 21.284735282142822,
130+
3: 21.304702106984614
131+
},
132+
'imec0.lf': {
133+
0: 15.3191688060872,
134+
1: 15.339168765361949,
135+
2: 21.284356659374016,
136+
3: 21.304356618648765
137+
},
138+
'imec1.lf': {
139+
0: 15.319321358082725,
140+
1: 15.339321516521915,
141+
2: 21.284568614155827,
142+
3: 21.30456877259502
143+
}
144+
}
145+
146+
# Initialize the RawIO
147+
rawio = SpikeGLXRawIO(self.get_local_path("spikeglx/multi_trigger_multi_gate/SpikeGLX/5-19-2022-CI4"))
148+
rawio.parse_header()
149+
150+
# Get list of stream names
151+
stream_names = rawio.header["signal_streams"]["name"]
152+
153+
# Test t_start for each stream and segment
154+
for stream_name, expected_values in expected_t_starts.items():
155+
# Get stream index
156+
stream_index = list(stream_names).index(stream_name)
157+
158+
# Check each segment
159+
for seg_index, expected_t_start in expected_values.items():
160+
actual_t_start = rawio.get_signal_t_start(
161+
block_index=0,
162+
seg_index=seg_index,
163+
stream_index=stream_index
164+
)
165+
166+
# Use numpy.testing for proper float comparison
167+
np.testing.assert_allclose(
168+
actual_t_start,
169+
expected_t_start,
170+
rtol=1e-9,
171+
atol=1e-9,
172+
err_msg=f"Mismatch in t_start for stream '{stream_name}', segment {seg_index}"
173+
)
115174

116175
if __name__ == "__main__":
117176
unittest.main()

0 commit comments

Comments
 (0)