Skip to content

Commit a1cc513

Browse files
committed
remove old function
1 parent 84e7caa commit a1cc513

3 files changed

Lines changed: 80 additions & 167 deletions

File tree

src/probeinterface/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
parse_spikeglx_snsGeomMap,
2929
get_saved_channel_indices_from_spikeglx_meta,
3030
read_openephys,
31-
read_openephys_binary,
3231
get_saved_channel_indices_from_openephys_settings,
3332
)
3433
from .utils import combine_probes

src/probeinterface/neuropixels_tools.py

Lines changed: 56 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,55 +1599,72 @@ def read_openephys(
15991599
raise_error: bool = True,
16001600
) -> Probe:
16011601
"""
1602-
Read probe positions from Open Ephys folder when using the Neuropix-PXI plugin.
1603-
The reader assumes that the NP_PROBE fields are available in the settings file.
1604-
Open Ephys versions 0.5.x and 0.6.x are supported:
1605-
* For version 0.6.x, the probe names are inferred from the STREAM field. Probe
1606-
information is then populated sequentially with the NP_PROBE fields.
1607-
* For version 0.5.x, STREAMs are not available. In this case, if multiple probes
1608-
are available, they are named sequentially based on the nodeId. E.g. "100.0",
1609-
"100.1". These substrings are used for selection.
1610-
1611-
When ``oebin_file`` is provided, the function also reads the structure.oebin to
1612-
compute ``device_channel_indices`` that map each probe contact to its column in
1613-
the binary data file. This is required for correct channel ordering when reading
1614-
binary recordings.
1602+
Read a Neuropixels probe geometry from an Open Ephys settings.xml file.
1603+
1604+
A single settings.xml can describe multiple probes (one ``<NP_PROBE>`` element
1605+
per probe). When the file contains more than one probe, use one of the three
1606+
mutually exclusive selectors (``stream_name``, ``probe_name``, or
1607+
``serial_number``) to choose which probe to return.
1608+
1609+
By default the function returns a probe with identity wiring
1610+
(``device_channel_indices = [0, 1, 2, ...]``). When ``oebin_file`` is also
1611+
provided, the function reads the structure.oebin to compute
1612+
``device_channel_indices`` that map each probe contact to its column in
1613+
the binary data file.
1614+
1615+
Open Ephys versions 0.5.x, 0.6.x, and 1.0 are supported. For version
1616+
0.6.x+, probe names are inferred from ``<STREAM>`` elements. For version
1617+
0.5.x (no ``<STREAM>`` elements), probes are named sequentially based on
1618+
the processor's ``nodeId`` (e.g. ``"100.0"``, ``"100.1"``).
16151619
16161620
Parameters
16171621
----------
1618-
settings_file : Path, str, or None
1619-
If more than one settings.xml file is in the folder structure, this argument
1620-
is required to indicate which settings file to use
1622+
settings_file : Path or str
1623+
Path to the Open Ephys settings.xml file. Each experiment under a
1624+
Record Node has its own settings file (``settings.xml`` for experiment 1,
1625+
``settings_2.xml`` for experiment 2, etc.). The caller is responsible
1626+
for passing the correct one.
16211627
stream_name : str or None
1622-
If more than one probe is used, the 'stream_name' indicates which probe to load base on the
1623-
stream. For example, if there are 3 probes ('ProbeA', 'ProbeB', ProbeC) and the stream_name is
1624-
contains the substring 'ProbeC' (e.g. 'my-stream-ProbeC'), then the probe associated with
1625-
ProbeC is returned. If this argument is used, the 'probe_name' and 'serial_number' must be None.
1628+
Select a probe by substring match against probe names derived from
1629+
``<STREAM>`` elements. For example, if the settings file has probes
1630+
``"ProbeA"``, ``"ProbeB"``, ``"ProbeC"``, passing
1631+
``stream_name="Record Node 104#Neuropix-PXI-100.ProbeC-AP"`` selects
1632+
ProbeC because ``"ProbeC"`` is a substring of the stream name. This is
1633+
what SpikeInterface passes (the neo stream name). Mutually exclusive
1634+
with ``probe_name`` and ``serial_number``.
16261635
probe_name : str or None
1627-
If more than one probe is used, the 'probe_name' indicates which probe to load base on the
1628-
probe name (e.g. "ProbeB"). If this argument is used, the 'stream_name' and 'serial_number'
1629-
must be None.
1636+
Select a probe by exact match against its name (e.g. ``"ProbeB"``).
1637+
Useful for interactive use. Mutually exclusive with ``stream_name``
1638+
and ``serial_number``.
16301639
serial_number : str or None
1631-
If more than one probe is used, the 'serial_number' indicates which probe to load base on the
1632-
serial number. If this argument is used, the 'stream_name' and 'probe_name'
1633-
must be None.
1640+
Select a probe by exact match against its serial number. Useful for
1641+
automated pipelines that track probes by hardware serial. Mutually
1642+
exclusive with ``stream_name`` and ``probe_name``.
16341643
oebin_file : Path, str, or None
1635-
Path to the structure.oebin JSON file. When provided, ``stream_name`` is
1636-
required and ``device_channel_indices`` are computed from the oebin's
1637-
``electrode_index`` metadata. When None, identity wiring is used.
1638-
fix_x_position_for_oe_5: bool
1639-
The neuropixels PXI plugin in the open-ephys < 0.6.0 contains a bug in the y position. This option allow to fix it.
1640-
raise_error: bool
1641-
If True, any error would raise an exception. If False, None is returned. Default True
1642-
1643-
Note
1644-
----
1645-
The electrode positions are only available when recording using the Neuropix-PXI plugin version >= 0.3.3
1644+
Path to the structure.oebin JSON file for a specific recording. When
1645+
provided, ``stream_name`` is required. The oebin's ``electrode_index``
1646+
metadata is used to compute ``device_channel_indices`` mapping each
1647+
probe contact to its binary file column. When None, identity wiring
1648+
is used.
1649+
fix_x_position_for_oe_5 : bool
1650+
Correct a y-position bug in the Neuropix-PXI plugin for Open Ephys
1651+
< 0.6.0, where multi-shank probe y-coordinates included an erroneous
1652+
shank pitch offset. Despite the parameter name, this corrects the y
1653+
(not x) position. Default True.
1654+
raise_error : bool
1655+
If True, any error raises an exception. If False, None is returned.
1656+
Default True.
16461657
16471658
Returns
16481659
-------
1649-
probe : Probe object
1650-
1660+
probe : Probe or None
1661+
The probe with ``device_channel_indices`` set. Returns None if
1662+
``raise_error`` is False and an error occurs.
1663+
1664+
Notes
1665+
-----
1666+
Electrode positions are only available when recording with the
1667+
Neuropix-PXI plugin version >= 0.3.3.
16511668
"""
16521669
if oebin_file is not None and stream_name is None:
16531670
raise ValueError("stream_name is required when oebin_file is provided.")
@@ -1678,46 +1695,6 @@ def read_openephys(
16781695
return probe
16791696

16801697

1681-
def read_openephys_binary(
1682-
settings_file: str | Path,
1683-
oebin_file: str | Path,
1684-
stream_name: str,
1685-
fix_x_position_for_oe_5: bool = True,
1686-
) -> Probe:
1687-
"""
1688-
Read probe positions from an Open Ephys binary format recording.
1689-
1690-
.. deprecated::
1691-
Use ``read_openephys(..., oebin_file=...)`` instead.
1692-
1693-
Parameters
1694-
----------
1695-
settings_file : Path or str
1696-
Path to the Open Ephys settings.xml file.
1697-
oebin_file : Path or str
1698-
Path to the structure.oebin JSON file.
1699-
stream_name : str
1700-
Stream name to select which probe and oebin stream to use.
1701-
fix_x_position_for_oe_5 : bool
1702-
Fix a y-position bug in Open Ephys < 0.6.0. Default True.
1703-
1704-
Returns
1705-
-------
1706-
probe : Probe
1707-
"""
1708-
warnings.warn(
1709-
"read_openephys_binary is deprecated. Use read_openephys(..., oebin_file=...) instead.",
1710-
DeprecationWarning,
1711-
stacklevel=2,
1712-
)
1713-
return read_openephys(
1714-
settings_file,
1715-
stream_name=stream_name,
1716-
oebin_file=oebin_file,
1717-
fix_x_position_for_oe_5=fix_x_position_for_oe_5,
1718-
)
1719-
1720-
17211698
def get_saved_channel_indices_from_openephys_settings(
17221699
settings_file: str | Path, stream_name: str
17231700
) -> Optional[np.array]:

tests/test_io/test_openephys.py

Lines changed: 24 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from probeinterface import read_openephys
1111
from probeinterface.neuropixels_tools import _parse_openephys_settings, _select_openephys_probe_info
12-
from probeinterface.neuropixels_tools import _slice_catalogue_probe, build_neuropixels_probe, read_openephys_binary
12+
from probeinterface.neuropixels_tools import _slice_catalogue_probe, build_neuropixels_probe
1313
from probeinterface.testing import validate_probe_dict
1414

1515
data_path = Path(__file__).absolute().parent.parent / "data" / "openephys"
@@ -469,7 +469,7 @@ def _read_oebin_electrode_indices(oebin_file, stream_name):
469469
return []
470470

471471

472-
def test_read_openephys_binary_wiring():
472+
def test_read_openephys_with_oebin_wiring():
473473
"""Verify wiring invariant: for each contact, the oebin's electrode_index at the
474474
assigned binary column matches the contact's electrode index."""
475475
settings = data_path / "OE_Neuropix-PXI-NP1-binary" / "Record_Node_101" / "settings.xml"
@@ -478,7 +478,7 @@ def test_read_openephys_binary_wiring():
478478
)
479479
stream_name = "Neuropix-PXI-100.ProbeA"
480480

481-
probe = read_openephys_binary(settings, oebin, stream_name)
481+
probe = read_openephys(settings, stream_name=stream_name, oebin_file=oebin)
482482

483483
assert probe.get_contact_count() == 384
484484
assert probe.device_channel_indices is not None
@@ -494,31 +494,36 @@ def test_read_openephys_binary_wiring():
494494
)
495495

496496

497-
def test_read_openephys_binary_contact_ids_match_canonical_pattern():
498-
"""Verify that read_openephys_binary contact_ids are consistent with SpikeGLX (issue #394)."""
497+
def test_read_openephys_with_oebin_contact_ids_match_canonical_pattern():
498+
"""Verify that contact_ids with oebin are consistent with SpikeGLX (issue #394)."""
499499
# NP2014 single-shank
500-
probe = read_openephys_binary(
500+
probe = read_openephys(
501501
data_path / "OE_Neuropix-PXI-NP1-binary" / "Record_Node_101" / "settings.xml",
502-
data_path / "OE_Neuropix-PXI-NP1-binary" / "Record_Node_101" / "experiment1" / "recording1" / "structure.oebin",
503-
"Neuropix-PXI-100.ProbeA",
502+
stream_name="Neuropix-PXI-100.ProbeA",
503+
oebin_file=data_path
504+
/ "OE_Neuropix-PXI-NP1-binary"
505+
/ "Record_Node_101"
506+
/ "experiment1"
507+
/ "recording1"
508+
/ "structure.oebin",
504509
)
505510
_assert_contact_ids_match_canonical_pattern(probe, "NP2014 binary")
506511

507512
# NP1032 4-shank
508-
probe = read_openephys_binary(
513+
probe = read_openephys(
509514
data_path / "OE_Neuropix-PXI-NP2-4shank-binary" / "Record_Node_101" / "settings.xml",
510-
data_path
515+
stream_name="Neuropix-PXI-100.ProbeA-AP",
516+
oebin_file=data_path
511517
/ "OE_Neuropix-PXI-NP2-4shank-binary"
512518
/ "Record_Node_101"
513519
/ "experiment4"
514520
/ "recording2"
515521
/ "structure.oebin",
516-
"Neuropix-PXI-100.ProbeA-AP",
517522
)
518523
_assert_contact_ids_match_canonical_pattern(probe, "NP1032 binary")
519524

520525

521-
def test_read_openephys_binary_sync_channel_filtered():
526+
def test_read_openephys_with_oebin_sync_channel_filtered():
522527
"""Verify that the oebin sync channel (385 channels) is filtered, producing 384 contacts."""
523528
settings = data_path / "OE_Neuropix-PXI-NP2-4shank-binary" / "Record_Node_101" / "settings.xml"
524529
oebin = (
@@ -530,90 +535,34 @@ def test_read_openephys_binary_sync_channel_filtered():
530535
/ "structure.oebin"
531536
)
532537

533-
probe = read_openephys_binary(settings, oebin, "Neuropix-PXI-100.ProbeA-AP")
538+
probe = read_openephys(settings, stream_name="Neuropix-PXI-100.ProbeA-AP", oebin_file=oebin)
534539
assert probe.get_contact_count() == 384
535540

536541

537-
def test_read_openephys_binary_plugin_channel_key():
538-
"""Verify that plugin_channel_key annotation is set."""
542+
def test_read_openephys_with_oebin_plugin_channel_key():
543+
"""Verify that plugin_channel_key annotation is set when using oebin_file."""
539544
settings = data_path / "OE_Neuropix-PXI-NP1-binary" / "Record_Node_101" / "settings.xml"
540545
oebin = (
541546
data_path / "OE_Neuropix-PXI-NP1-binary" / "Record_Node_101" / "experiment1" / "recording1" / "structure.oebin"
542547
)
543548
stream_name = "Neuropix-PXI-100.ProbeA"
544549

545-
probe = read_openephys_binary(settings, oebin, stream_name)
550+
probe = read_openephys(settings, stream_name=stream_name, oebin_file=oebin)
546551
keys = probe.contact_annotations.get("plugin_channel_key", None)
547552
assert keys is not None, "plugin_channel_key annotation not set"
548553
assert len(keys) == probe.get_contact_count()
549-
# Keys should be like "CH0", "CH1", etc.
550554
assert all(k.startswith("CH") for k in keys)
551555

552556

553-
def test_read_openephys_binary_no_matching_stream():
554-
"""Verify error when stream_name doesn't match any oebin stream."""
557+
def test_read_openephys_with_oebin_no_matching_stream():
558+
"""Verify error when stream_name doesn't match any probe in settings."""
555559
settings = data_path / "OE_Neuropix-PXI-NP1-binary" / "Record_Node_101" / "settings.xml"
556560
oebin = (
557561
data_path / "OE_Neuropix-PXI-NP1-binary" / "Record_Node_101" / "experiment1" / "recording1" / "structure.oebin"
558562
)
559563

560564
with pytest.raises(Exception, match="Inconsistency between provided stream"):
561-
read_openephys_binary(settings, oebin, "NonExistentStream")
562-
563-
564-
def test_read_openephys_with_oebin_file():
565-
"""Verify read_openephys(..., oebin_file=...) matches read_openephys_binary results."""
566-
settings = data_path / "OE_Neuropix-PXI-NP1-binary" / "Record_Node_101" / "settings.xml"
567-
oebin = (
568-
data_path / "OE_Neuropix-PXI-NP1-binary" / "Record_Node_101" / "experiment1" / "recording1" / "structure.oebin"
569-
)
570-
stream_name = "Neuropix-PXI-100.ProbeA"
571-
572-
probe = read_openephys(settings, stream_name=stream_name, oebin_file=oebin)
573-
574-
assert probe.get_contact_count() == 384
575-
assert probe.device_channel_indices is not None
576-
577-
# Wiring invariant
578-
oebin_electrode_indices = _read_oebin_electrode_indices(oebin, stream_name)
579-
for i, contact_id in enumerate(probe.contact_ids):
580-
electrode_index = int(contact_id.split("e")[-1])
581-
column = probe.device_channel_indices[i]
582-
assert oebin_electrode_indices[column] == electrode_index
583-
584-
585-
def test_read_openephys_with_oebin_file_4shank():
586-
"""Verify read_openephys(..., oebin_file=...) works for 4-shank probes."""
587-
settings = data_path / "OE_Neuropix-PXI-NP2-4shank-binary" / "Record_Node_101" / "settings.xml"
588-
oebin = (
589-
data_path
590-
/ "OE_Neuropix-PXI-NP2-4shank-binary"
591-
/ "Record_Node_101"
592-
/ "experiment4"
593-
/ "recording2"
594-
/ "structure.oebin"
595-
)
596-
stream_name = "Neuropix-PXI-100.ProbeA-AP"
597-
598-
probe = read_openephys(settings, stream_name=stream_name, oebin_file=oebin)
599-
600-
assert probe.get_contact_count() == 384
601-
_assert_contact_ids_match_canonical_pattern(probe, "NP1032 oebin_file")
602-
603-
604-
def test_read_openephys_with_oebin_file_plugin_channel_key():
605-
"""Verify that plugin_channel_key annotation is set when using oebin_file."""
606-
settings = data_path / "OE_Neuropix-PXI-NP1-binary" / "Record_Node_101" / "settings.xml"
607-
oebin = (
608-
data_path / "OE_Neuropix-PXI-NP1-binary" / "Record_Node_101" / "experiment1" / "recording1" / "structure.oebin"
609-
)
610-
stream_name = "Neuropix-PXI-100.ProbeA"
611-
612-
probe = read_openephys(settings, stream_name=stream_name, oebin_file=oebin)
613-
keys = probe.contact_annotations.get("plugin_channel_key", None)
614-
assert keys is not None, "plugin_channel_key annotation not set"
615-
assert len(keys) == probe.get_contact_count()
616-
assert all(k.startswith("CH") for k in keys)
565+
read_openephys(settings, stream_name="NonExistentStream", oebin_file=oebin)
617566

618567

619568
def test_read_openephys_oebin_file_requires_stream_name():
@@ -668,18 +617,6 @@ def test_read_openephys_multishank_wiring():
668617
)
669618

670619

671-
def test_read_openephys_binary_deprecation_warning():
672-
"""Verify that read_openephys_binary emits a DeprecationWarning."""
673-
settings = data_path / "OE_Neuropix-PXI-NP1-binary" / "Record_Node_101" / "settings.xml"
674-
oebin = (
675-
data_path / "OE_Neuropix-PXI-NP1-binary" / "Record_Node_101" / "experiment1" / "recording1" / "structure.oebin"
676-
)
677-
stream_name = "Neuropix-PXI-100.ProbeA"
678-
679-
with pytest.warns(DeprecationWarning, match="read_openephys_binary is deprecated"):
680-
read_openephys_binary(settings, oebin, stream_name)
681-
682-
683620
if __name__ == "__main__":
684621
# test_multiple_probes()
685622
# test_NP_Ultra()

0 commit comments

Comments
 (0)