spikeinterface icon indicating copy to clipboard operation
spikeinterface copied to clipboard

Manually setting SpikeGLX recording sampling frequency

Open louiskang opened this issue 1 month ago • 4 comments

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!

louiskang avatar Dec 07 '25 08:12 louiskang

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)

louiskang avatar Dec 07 '25 09:12 louiskang

Something to discuss, maybe we should allow override of any recording sampling_frequency with a special method?

h-mayorquin avatar Dec 09 '25 06:12 h-mayorquin

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

alejoe91 avatar Dec 10 '25 09:12 alejoe91

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: @.***>

louiskang avatar Dec 10 '25 10:12 louiskang