Skip to content

Commit 28cb527

Browse files
authored
Merge pull request #3849 from SpikeInterface/white_matter
WhiteMatterRecordingExtractor
2 parents e068774 + e7ed9ab commit 28cb527

File tree

4 files changed

+126
-0
lines changed

4 files changed

+126
-0
lines changed

doc/api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ Non-NEO-based
153153
.. autofunction:: toy_example
154154
.. autofunction:: read_tridesclous
155155
.. autofunction:: read_waveclus
156+
.. autofunction:: read_whitematter
156157
.. autofunction:: read_yass
157158

158159

src/spikeinterface/extractors/extractorlist.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
from .cbin_ibl import CompressedBinaryIblExtractor, read_cbin_ibl
4040
from .iblextractors import IblRecordingExtractor, IblSortingExtractor, read_ibl_recording, read_ibl_sorting
4141
from .mcsh5extractors import MCSH5RecordingExtractor, read_mcsh5
42+
from .whitematterrecordingextractor import WhiteMatterRecordingExtractor
4243

4344
# sorting extractors in relation with a sorter
4445
from .cellexplorersortingextractor import CellExplorerSortingExtractor, read_cellexplorer
@@ -92,6 +93,7 @@
9293
IblRecordingExtractor,
9394
MCSH5RecordingExtractor,
9495
SinapsResearchPlatformRecordingExtractor,
96+
WhiteMatterRecordingExtractor,
9597
]
9698
recording_extractor_full_list += neo_recording_extractors_list
9799

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import pytest
2+
import numpy as np
3+
from pathlib import Path
4+
5+
from spikeinterface.extractors import WhiteMatterRecordingExtractor, BinaryRecordingExtractor
6+
from spikeinterface.core.numpyextractors import NumpyRecording
7+
from spikeinterface import get_global_dataset_folder, download_dataset
8+
9+
10+
def test_round_trip(tmp_path):
11+
num_channels = 10
12+
num_samples = 500
13+
traces_list = [np.ones(shape=(num_samples, num_channels), dtype="int16")]
14+
sampling_frequency = 30_000.0
15+
recording = NumpyRecording(traces_list=traces_list, sampling_frequency=sampling_frequency)
16+
17+
file_path = tmp_path / "test_WhiteMatterRecordingExtractor.raw"
18+
BinaryRecordingExtractor.write_recording(recording=recording, file_paths=file_path, dtype="int16", byte_offset=8)
19+
20+
sampling_frequency = recording.get_sampling_frequency()
21+
num_channels = recording.get_num_channels()
22+
binary_recorder = WhiteMatterRecordingExtractor(
23+
file_path=file_path,
24+
sampling_frequency=sampling_frequency,
25+
num_channels=num_channels,
26+
)
27+
28+
# Test for full traces
29+
assert np.allclose(recording.get_traces(), binary_recorder.get_traces())
30+
31+
# Test for a sub-set of the traces
32+
start_frame = 20
33+
end_frame = 40
34+
smaller_traces = recording.get_traces(start_frame=start_frame, end_frame=end_frame)
35+
binary_smaller_traces = binary_recorder.get_traces(start_frame=start_frame, end_frame=end_frame)
36+
37+
np.allclose(smaller_traces, binary_smaller_traces)
38+
39+
40+
gin_repo = "https://gin.g-node.org/NeuralEnsemble/ephy_testing_data"
41+
local_folder = get_global_dataset_folder() / "ephy_testing_data"
42+
remote_path = Path("whitematter") / "HSW_2024_12_12__10_28_23__70min_17sec__hsamp_64ch_25000sps_stub.bin"
43+
44+
45+
def test_on_data():
46+
file_path = download_dataset(
47+
repo=gin_repo, remote_path=remote_path, local_folder=local_folder, update_if_exists=True
48+
)
49+
50+
sampling_frequency = 25_000.0
51+
num_channels = 64
52+
recording = WhiteMatterRecordingExtractor(
53+
file_path=file_path,
54+
sampling_frequency=sampling_frequency,
55+
num_channels=num_channels,
56+
)
57+
assert recording.get_sampling_frequency() == sampling_frequency
58+
assert recording.get_num_channels() == num_channels
59+
assert recording.get_duration() == 1.0
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from pathlib import Path
2+
from typing import List, Union, Optional
3+
4+
from spikeinterface.core import BinaryRecordingExtractor
5+
from spikeinterface.core.core_tools import define_function_from_class
6+
7+
8+
class WhiteMatterRecordingExtractor(BinaryRecordingExtractor):
9+
"""
10+
RecordingExtractor for the WhiteMatter binary format.
11+
12+
The recording format is a raw binary file containing int16 data,
13+
with an 8-byte header offset.
14+
15+
Parameters
16+
----------
17+
file_path : Path
18+
Path to the binary file.
19+
sampling_frequency : float
20+
The sampling frequency.
21+
num_channels : int
22+
Number of channels in the recording.
23+
channel_ids : list or None, default: None
24+
A list of channel ids. If None, channel_ids = list(range(num_channels)).
25+
is_filtered : bool or None, default: None
26+
If True, the recording is assumed to be filtered. If None, `is_filtered` is not set.
27+
"""
28+
29+
mode = "file"
30+
31+
# Specific parameters for WhiteMatter format
32+
DTYPE = "int16"
33+
GAIN_TO_UV = 6.25e3 / 32768
34+
OFFSET_TO_UV = 0.0
35+
FILE_OFFSET = 8
36+
TIME_AXIS = 0
37+
# This extractor is based on a single example file without a formal specification from WhiteMatter.
38+
# The parameters above are currently assumed to be constant for all WhiteMatter files.
39+
# If you encounter issues with this extractor, these assumptions may need to be revisited.
40+
41+
def __init__(
42+
self,
43+
file_path: Union[str, Path],
44+
sampling_frequency: float,
45+
num_channels: int,
46+
channel_ids: Optional[List] = None,
47+
is_filtered: Optional[bool] = None,
48+
):
49+
super().__init__(
50+
file_paths=[file_path],
51+
sampling_frequency=sampling_frequency,
52+
num_channels=num_channels,
53+
dtype=self.DTYPE,
54+
time_axis=self.TIME_AXIS,
55+
file_offset=self.FILE_OFFSET,
56+
gain_to_uV=self.GAIN_TO_UV,
57+
offset_to_uV=self.OFFSET_TO_UV,
58+
is_filtered=is_filtered,
59+
channel_ids=channel_ids,
60+
)
61+
62+
63+
# Define function equivalent for convenience
64+
read_whitematter = define_function_from_class(source_class=WhiteMatterRecordingExtractor, name="read_whitematter")

0 commit comments

Comments
 (0)