ezmsg.nwb.electrodes#

Build a structured ch axis from an NWB electrodes table.

A live acquisition source hands downstream stages a structured ch CoordinateAxis – per-channel geometry, labels, and array identity – rather than a bare list of names. Rereferencing per array, plotting by position, and selecting by headstage all read those fields. Replaying the same recording through the same graph gave a plain string array instead, so every one of those stages had to special-case its source.

This builds the live layout from what an NWB writer put in the electrodes table, so an offline graph sees the same axis as an online one. CHANNEL_DTYPE deliberately matches ezmsg.blackrock.channel_map.CHANNEL_DTYPE field for field; the point is that weights fitted offline and applied live cluster channels identically.

Off by default. The columns this reads beyond label are conventions of one acquisition stack, not part of the NWB schema – most files have none of them, and inventing geometry for a file that never recorded any would be worse than saying so.

Coordinates are taken verbatim. rel_x/rel_y are stored here in micrometers, matching the device’s own channel-map units and the int32 micrometers the live source emits. NWB’s schema nominally describes electrode positions in meters, so a file that followed that reading would land three orders of magnitude away. Converting on a guess is how a scale factor becomes silently wrong (see scaling for the same lesson learned on sample values), so nothing here rescales; a file in meters needs its writer fixed or its axis rebuilt downstream.

Module Attributes

CHANNEL_DTYPE

Per-channel record, field-for-field identical to the live source's.

COLUMN_SOURCES

Which electrodes-table columns feed each field, in order of preference.

Functions

array_identity(label, headstage, bank='')[source]#

Electrode-array identity for a channel.

A transcription of ezmsg.blackrock.channel_map._array_identity – two channels belong to the same array iff they share a connector (the label prefix before the first -) on the same headstage:

("elec1-m1-63", 1) -> "hs1-elec1"
("elec1-m1-63", 2) -> "hs2-elec1"

Labels with no connector structure fall back to the bank, so grouping degrades to bank-level rather than collapsing every such channel into one cluster. Returns "" when neither is available.

Copied rather than imported: ezmsg-blackrock is not a dependency of this package and should not become one just to read a file. The duplication is the price of that, and array_identity() is small and pinned by a test that spells out the mapping it must produce.

Return type:

str

Parameters:
build_channel_axis(table, region_idx, *, stream_key='')[source]#

A CHANNEL_DTYPE record per channel of one series.

region_idx is the series’ electrodes region – the positional indices into the full table – so a series referencing a subset of the electrodes gets that subset’s rows, in its own order.

Columns absent from the table leave their field at its zero value rather than failing: a writer that recorded positions but no headstage still produces a usable geometry. A table with no recognized column at all raises, because the caller asked for this explicitly and a record of all zeros would answer that request with fabricated data.

Return type:

ndarray

Parameters:
has_channel_metadata(table)[source]#

Whether this table carries anything beyond labels to build an axis from.

Return type:

bool

Parameters:

table (Any)