@@ -531,6 +531,57 @@ def _demultiplex_digital_data(self, raw_digital_data, channel_ids, i_start, i_st
531531
532532 return output
533533
534+ def get_intan_timestamps (self , i_start = None , i_stop = None ):
535+ """
536+ Retrieves the sample indices from the Intan raw data within a specified range.
537+
538+ Note that sample indices are called timestamps in the Intan format but they are
539+ in fact just sample indices. This function extracts the sample index timestamps
540+ from Intan files, which represent relative time points in sample units (not absolute time).
541+ These indices can be particularly useful when working with recordings that have discontinuities.
542+
543+ Parameters
544+ ----------
545+ i_start : int, optional
546+ The starting index from which to retrieve sample indices. If None, starts from 0.
547+ i_stop : int, optional
548+ The stopping index up to which to retrieve sample indices (exclusive).
549+ If None, retrieves all available indices from i_start onward.
550+
551+ Returns
552+ -------
553+ timestamps : ndarray
554+ The flattened array of sample indices within the specified range.
555+
556+ Notes
557+ -----
558+ - Sample indices can be converted to seconds by dividing by the sampling rate of the amplifier stream.
559+ - The function automatically handles different file formats:
560+ * header-attached: Timestamps are extracted directly from the timestamp field
561+ * one-file-per-signal: Timestamps are read from the timestamp stream
562+ * one-file-per-channel: Timestamps are read from the first channel in the timestamp stream
563+ - When recordings have discontinuities (indicated by the `discontinuous_timestamps`
564+ attribute being True), these indices allow for proper temporal alignment of the data.
565+ """
566+ if i_start is None :
567+ i_start = 0
568+
569+ # Get the timestamps based on file format
570+ if self .file_format == "header-attached" :
571+ timestamps = self ._raw_data ["timestamp" ]
572+ elif self .file_format == "one-file-per-signal" :
573+ timestamps = self ._raw_data ["timestamp" ]
574+ elif self .file_format == "one-file-per-channel" :
575+ timestamps = self ._raw_data ["timestamp" ][0 ]
576+
577+ # TODO if possible ensure that timestamps memmaps are always of correct shape to avoid memory copy here.
578+ timestamps = timestamps .flatten () if timestamps .ndim > 1 else timestamps
579+
580+ if i_stop is None :
581+ return timestamps [i_start :]
582+ else :
583+ return timestamps [i_start :i_stop ]
584+
534585 def _assert_timestamp_continuity (self ):
535586 """
536587 Asserts the continuity of timestamps in the data.
@@ -545,26 +596,11 @@ def _assert_timestamp_continuity(self):
545596 NeoReadWriteError
546597 If timestamps are not continuous and `ignore_integrity_checks` is False.
547598 The error message includes a table detailing the discontinuities found.
548-
549- Notes
550- -----
551- The method extracts timestamps from the raw data based on the file format:
552-
553- * **header-attached:** Timestamps are extracted from a 'timestamp' field in the raw data.
554- * **one-file-per-signal:** Timestamps are taken from the last stream.
555- * **one-file-per-channel:** Timestamps are retrieved from the first channel of the last stream.
556599 """
557600 # check timestamp continuity
558- if self .file_format == "header-attached" :
559- timestamp = self ._raw_data ["timestamp" ].flatten ()
560-
561- # timestamps are always last stream for headerless binary files
562- elif self .file_format == "one-file-per-signal" :
563- timestamp = self ._raw_data ["timestamp" ]
564- elif self .file_format == "one-file-per-channel" :
565- timestamp = self ._raw_data ["timestamp" ][0 ]
601+ timestamps = self .get_intan_timestamps ()
566602
567- discontinuous_timestamps = np .diff (timestamp ) != 1
603+ discontinuous_timestamps = np .diff (timestamps ) != 1
568604 timestamps_are_not_contiguous = np .any (discontinuous_timestamps )
569605 if timestamps_are_not_contiguous :
570606 # Mark a flag that can be checked after parsing the header to see if the timestamps are continuous or not
@@ -582,8 +618,8 @@ def _assert_timestamp_continuity(self):
582618
583619 amplifier_sampling_rate = self ._global_info ["sampling_rate" ]
584620 for discontinuity_index in np .where (discontinuous_timestamps )[0 ]:
585- prev_ts = timestamp [discontinuity_index ]
586- next_ts = timestamp [discontinuity_index + 1 ]
621+ prev_ts = timestamps [discontinuity_index ]
622+ next_ts = timestamps [discontinuity_index + 1 ]
587623 time_diff = (next_ts - prev_ts ) / amplifier_sampling_rate
588624
589625 error_msg += (
0 commit comments