Skip to content

Commit 852fc67

Browse files
committed
title
1 parent c94e60b commit 852fc67

1 file changed

Lines changed: 18 additions & 46 deletions

File tree

doc/neuropixels_readers.rst

Lines changed: 18 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
Neuropixels format readers: catalogue construction and recording-specific wiring
2-
=================================================================================
1+
The Neuropixels catalogue pattern
2+
=================================
33

44
.. currentmodule:: probeinterface
55

@@ -63,30 +63,31 @@ and produce a probe ready to use with SpikeInterface:
6363
Neuropixels 1.0, ``NP2000`` for Neuropixels 2.0 single-shank, ``NP2014``
6464
for Neuropixels 2.0 4-shank
6565

66-
The first three readers identify the actual probe stock-keeping unit (SKU)
67-
from the recording metadata. SpikeGadgets is the exception: its ``.rec`` XML
68-
does not carry a part number field, so the reader cannot identify the SKU.
69-
It picks one representative per geometry-equivalent family (all Neuropixels
70-
1.0 staggered variants share contact positions; all Neuropixels 2.0
71-
single-shank variants share contact positions; all Neuropixels 2.0 4-shank
72-
variants share contact positions) and clears the ``model_name``,
73-
``description``, and ``part_number`` annotations on the returned probe so
74-
downstream code does not read the stand-in as an attribution.
66+
The first three readers read the part number directly from the recording
67+
metadata. SpikeGadgets is the exception: its ``.rec`` XML does not carry a
68+
part number field, so the reader cannot know which specific variant produced
69+
the recording. It picks one representative per geometry-equivalent family
70+
(all Neuropixels 1.0 staggered variants share contact positions; all
71+
Neuropixels 2.0 single-shank variants share contact positions; all
72+
Neuropixels 2.0 4-shank variants share contact positions) and clears the
73+
``model_name``, ``description``, and ``part_number`` annotations on the
74+
returned probe so downstream code does not read the stand-in as an
75+
attribution.
7576

7677

7778
From catalogue probe to probe in a recording setup
7879
--------------------------------------------------
7980

80-
The catalogue probe is pure geometry, divorced from any session. A real
81+
The catalogue probe is pure geometry, divorced from any recording session. A real
8182
recording uses only a subset of those contacts: the Neuropixels headstage
8283
acquires 384 channels at a time, and the recording configuration selects
8384
which catalogue contacts those 384 are drawn from (384 of 960 on Neuropixels
8485
1.0, 384 of 1280 per shank on Neuropixels 2.0 single-shank, 384 of 5120 on
8586
Neuropixels 2.0 4-shank). The selection mechanism differs by recording
8687
format (an IMRO table for SpikeGLX, a channel map in ``settings.xml`` for
87-
Open Ephys, the ``SpikeNTrode`` list in SpikeGadgets's ``.rec`` XML); the
88-
"Matching catalogue contacts to recorded data" section below covers each
89-
case. On top of the selection, the recording adds session-specific state:
88+
Open Ephys, the ``SpikeNTrode`` list in SpikeGadgets's ``.rec`` XML); each
89+
reader's docstring covers the specifics for that format. On top of the
90+
selection, the recording adds session-specific state:
9091
per-contact analog band (AP) and local field potential (LFP) gains, ADC
9192
sample order, reference configuration, and the channel-to-file mapping that
9293
says where each contact's data lives in the saved binary. Probeinterface
@@ -98,7 +99,7 @@ Each reader produces the recording-setup probe in the same three steps:
9899
1. Build the catalogue probe by calling
99100
:py:func:`build_neuropixels_probe(part_number) <build_neuropixels_probe>`
100101
with the part number obtained from the recording metadata.
101-
2. Slice the catalogue probe to the active electrodes for this session via
102+
2. Slice the catalogue probe to the active electrodes for this recording session via
102103
:py:meth:`probe.get_slice(active_indices) <Probe.get_slice>`. The slice
103104
drops the unrecorded contacts but preserves the probe-level annotations
104105
and the per-contact catalogue annotations (ADC group, sample order) on the
@@ -109,35 +110,6 @@ Each reader produces the recording-setup probe in the same three steps:
109110
to record where each surviving contact's data lives in the saved file.
110111

111112

112-
Matching catalogue contacts to recorded data
113-
--------------------------------------------
114-
115-
The catalogue-build step is the same across readers; the matching step is
116-
where the formats differ. ``active_indices`` and ``device_channel_indices``
117-
come from a different field in each metadata source:
118-
119-
* **SpikeGLX:** ``active_indices`` is the electrode list parsed from the IMRO
120-
table embedded in the ``.ap.meta`` file. ``device_channel_indices`` is
121-
identity (``np.arange(n)``) because SpikeGLX writes one column per active
122-
electrode in IMRO selection order.
123-
* **Open Ephys:** ``active_indices`` is the electrode list parsed from the
124-
``CHANNELS`` block in ``settings.xml``. ``device_channel_indices`` follows
125-
the order the binary stream uses, which the same XML file describes.
126-
* **IMRO (standalone):** ``active_indices`` is parsed directly from the IMRO
127-
entries. There is no recording to wire to, so :py:func:`read_imro` returns
128-
the sliced probe without setting ``device_channel_indices``; callers that
129-
have a corresponding ``.ap.bin`` use :py:func:`read_spikeglx` instead.
130-
* **SpikeGadgets:** ``active_indices`` is the list of ``SpikeNTrode``
131-
electrodes from the ``.rec`` XML, remapped from Trodes' ``channelsOn`` bit
132-
order to the catalogue's contact order (an identity remap for Neuropixels
133-
1.0; a row-major-to-shank-major remap for Neuropixels 2.0 4-shank; a
134-
per-row column swap for Neuropixels 2.0 single-shank).
135-
``device_channel_indices`` is the ``hwChan`` attribute on each
136-
``SpikeNTrode``, which happens to coincide with the column index in the
137-
SpikeGadgets datalogger's binary stream because the firmware writes samples
138-
in ``hwChan`` ascending order.
139-
140-
141113
What the pattern solves
142114
-----------------------
143115

@@ -161,7 +133,7 @@ before the catalogue pattern) had three problems:
161133
probe directly hid the fact that 576 catalogue contacts were silently
162134
dropped. The explicit ``probe.get_slice(active_indices)`` step makes the
163135
selection visible and inspectable: callers can ask "which catalogue
164-
contacts did this session record?" and get a direct answer.
136+
contacts did this recording session record?" and get a direct answer.
165137

166138
The pattern also pays out on the upgrade path. When IMEC ships a new probe
167139
variant, the integration work is "add the part number to ProbeTable, re-run

0 commit comments

Comments
 (0)