From 4f79e71480174fc7c7510f539c67cc8236657c7b Mon Sep 17 00:00:00 2001 From: Christian Tabedzki <35670232+tabedzki@users.noreply.github.com> Date: Tue, 11 Aug 2026 10:26:20 -0400 Subject: [PATCH] fix: resolve NP2004 probe model correctly from SpikeGLX metadata The imDatPrb_type SpikeGLX code (e.g. 2003) does not always map to one of the known probe model constants (1100/21/24). Previously the fallback stringified the raw type code (e.g. "2003"), which never matches a registered ProbeType, causing ingestion to fail with NotImplementedError or a foreign key violation on insert. Fall back to the probe part number (imDatPrb_pn, e.g. "NP2004") instead, matching the geometry already defined in probe_geometry.M. Also pull in upstream's imMaxInt-based IMAX lookup and the imDatPrb_type default fix (1 -> 0), and register NP2004 in create_neuropixels_probe_types() so it is created automatically on schema activation. Assisted-by: ClaudeCode:claude-sonnet-5 --- element_array_ephys/probe.py | 1 + element_array_ephys/readers/spikeglx.py | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/element_array_ephys/probe.py b/element_array_ephys/probe.py index 124646a9..d433ed53 100644 --- a/element_array_ephys/probe.py +++ b/element_array_ephys/probe.py @@ -137,6 +137,7 @@ def create_neuropixels_probe_types(): "neuropixels 2.0 - SS", "neuropixels 2.0 - MS", "2013", + "NP2004", ): if not (ProbeType & {"probe_type": probe_type}): create_neuropixels_probe(probe_type) diff --git a/element_array_ephys/readers/spikeglx.py b/element_array_ephys/readers/spikeglx.py index 0eb48999..b8e6d2a0 100644 --- a/element_array_ephys/readers/spikeglx.py +++ b/element_array_ephys/readers/spikeglx.py @@ -96,15 +96,15 @@ def get_channel_bit_volts(self, band="ap"): dataVolts = dataInt * Vmax / Imax / gain """ vmax = float(self.apmeta.meta["imAiRangeMax"]) + imax = self.apmeta.meta.get("imMaxInt") + imax = float(imax) if imax else IMAX[self.apmeta.probe_model] if band == "ap": - imax = IMAX[self.apmeta.probe_model] imroTbl_data = self.apmeta.imroTbl["data"] imroTbl_idx = 3 chn_ind = self.apmeta.get_recording_channels_indices(exclude_sync=True) elif band == "lf": - imax = IMAX[self.lfmeta.probe_model] imroTbl_data = self.lfmeta.imroTbl["data"] imroTbl_idx = 4 chn_ind = self.lfmeta.get_recording_channels_indices(exclude_sync=True) @@ -266,7 +266,7 @@ def __init__(self, meta_filepath): self.probe_PN = self.meta.get("imDatPrb_pn", "3A") # Infer npx probe model (e.g. 1.0 (3A, 3B) or 2.0) - probe_model = self.meta.get("imDatPrb_type", 1) + probe_model = self.meta.get("imDatPrb_type", 0) if probe_model < 1: if "typeEnabled" in self.meta and self.probe_PN == "3A": self.probe_model = "neuropixels 1.0 - 3A" @@ -283,7 +283,7 @@ def __init__(self, meta_filepath): elif probe_model == 24: self.probe_model = "neuropixels 2.0 - MS" else: - self.probe_model = str(probe_model) + self.probe_model = self.probe_PN # Get recording time self.recording_time = datetime.strptime(