Manually setting SpikeGLX recording sampling frequency
I'd like to manually set the sampling frequency of a Neuropixels recording loaded via read_spikeglx. The reason is that my analysis requires precise synchronization of traces, and environmental fluctuations (e.g. temperature) can create slight discrepancies from the calibrated sampling frequency on an experiment-by-experiment basis. Using the sync channel, I can compute an empirical sampling frequency for each experiment, and I would like to use these values. Is there a way to do this? If not, can the simple feature of manually setting recording properties be introduced? My current workaround is directly editing the .meta file. Thanks!
I wrote this subclass, which also seems to work for .get_times() because .time_vector is None for SpikeGLX imports. Feel free to close this issue if it's not a priority to override recording properties in general.
import spikeinterface.full as si
class OverriddenFrequencyRecording(si.BaseRecording):
"""
Class to override the sampling frequency of a recording.
Parameters
----------
parent_recording: BaseRecording
sampling_frequency: float
"""
def __init__(self, parent_recording, sampling_frequency):
si.BaseRecording.__init__(
self,
sampling_frequency=sampling_frequency,
channel_ids=parent_recording.get_channel_ids(),
dtype=parent_recording.get_dtype(),
)
# link recording segment
for parent_segment in parent_recording._recording_segments:
sub_segment = OverriddenFrequencyRecordingSegment(parent_segment, sampling_frequency)
self.add_recording_segment(sub_segment)
# copy annotation and properties
parent_recording.copy_metadata(self)
self._parent = parent_recording
# update dump dict
self._kwargs = {
"parent_recording": parent_recording,
"sampling_frequency": sampling_frequency,
}
class OverriddenFrequencyRecordingSegment(si.BaseRecordingSegment):
"""
Class to override the sampling frequency of a recording segment.
"""
def __init__(self, parent_recording_segment, sampling_frequency):
d = parent_recording_segment.get_times_kwargs()
d = d.copy()
d["sampling_frequency"] = sampling_frequency
si.BaseRecordingSegment.__init__(self, **d)
self._parent_recording_segment = parent_recording_segment
def get_num_samples(self) -> int:
return self._parent_recording_segment.get_num_samples()
def get_traces(
self,
start_frame: int | None = None,
end_frame: int | None = None,
channel_indices: list | None = None,
) -> np.ndarray:
return self._parent_recording_segment.get_traces(start_frame, end_frame, channel_indices)
Something to discuss, maybe we should allow override of any recording sampling_frequency with a special method?
Hi @louiskang
You can also set_times to a recording with the synchronized timestamps. Would that work? I think it would be more precise then setting a "global" fixed sampling rate, as indeed you might have fluctuations over the course of the experiment
That’s true, but in my case I downsample the data before LFP processing, and I believe that ResampleRecording just looks for sampling_frequency. Thanks!
On Wed, Dec 10, 2025 at 18:34 Alessio Buccino @.***> wrote:
alejoe91 left a comment (SpikeInterface/spikeinterface#4248) https://github.com/SpikeInterface/spikeinterface/issues/4248#issuecomment-3636174739
Hi @louiskang https://github.com/louiskang
You can also set_times to a recording with the synchronized timestamps. Would that work? I think it would be more precise then setting a "global" fixed sampling rate, as indeed you might have fluctuations over the course of the experiment
— Reply to this email directly, view it on GitHub https://github.com/SpikeInterface/spikeinterface/issues/4248#issuecomment-3636174739, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGN4FPZZ37CBP7RVGZWFU3L4A7SL7AVCNFSM6AAAAACOI73YISVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTMMZWGE3TINZTHE . You are receiving this because you were mentioned.Message ID: @.***>