ezmsg.blackrock.channel_map#
Attach Blackrock .cmp channel-map metadata to an AxisArray’s ch axis.
The output ch axis is a structured CoordinateAxis with fields
x, y, size, label, bank, elec, headstage for every
input channel. x/y/size are in micrometers; headstage is the
1-based headstage id (0 = none/auto).
ChannelMapUnit takes the complete set of per-headstage overlays in
one settings object (ChannelMapUnitSettings, a tuple of
ChannelMapSettings) and rebuilds the ch axis from scratch on each
reset. One settings push = the whole map, applied deterministically — there is
no cross-push accumulation that could coalesce if pushes aren’t separated by a
data message. An empty tuple clears the map (pure auto-grid).
Each reset proceeds in three phases:
Base layer — labels are pulled from the incoming
chaxis. When the incoming axis already carries structured geometry (e.g. a CereLink source that read it from device chaninfo), itsx/y/size/bank/elec/headstageare copied through verbatim, so a map already present upstream needs no.cmpfile at all. A channel counts as positioned (and so is skipped by the auto-grid) when it has a non-origin coordinate, or it is the first channel sitting at the(0, 0)origin — a lone origin electrode is a legitimate corner, but the device parks every unmapped channel at the origin, so origin pile-ups beyond the first fall through to the auto-grid. A companionsrc_maskrecords the positioned indices.CMP overlays — for each
ChannelMapSettingsincmp_configs, entries frompycbsdk.cmp.parse_cmp()are written at their channel index, overriding any source geometry there.parse_cmp(CerebusOSS/CereLink#184) returns entries keyed by device(bank, term)with flatx/y/size/headstagefields (x/yin micrometers) and verbatim labels; the channel index is(bank - 1) * 32 + (term - 1)—start_chanis already folded intobankvia its// 32offset. A companioncmp_maskrecords which indices were set so the auto-grid pass can avoid them.Auto-grid fill — positions/bank/elec for indices covered by neither a CMP overlay nor a source position, laid out below and to the right of the placed geometry so they don’t collide with it. The grid step matches the placed electrode pitch (inferred from its coordinates), so auto-laid channels share the same micrometer scale.
The same ChannelMapSettings record is also used as a per-headstage
entry in CereLinkSignalSettings.cmp_configs.
Classes
- class ChannelMapProcessor(*args, **kwargs)[source]#
Bases:
BaseStatefulTransformer[ChannelMapUnitSettings,AxisArray,AxisArray,ChannelMapState]Stateful transformer that attaches CMP-derived channel metadata.
Each reset rebuilds the axis in full from
settings.cmp_configs: a base layer from incoming labels, every CMP overlay applied in order, then the auto-grid fills indices no CMP claimed. Reset fires on a channel-count change or anycmp_configschange (the latter viaBaseProcessor.update_settings→_request_reset), so there is no cross-push state to coalesce. An emptycmp_configsyields a pure auto-grid.
- class ChannelMapSettings(filepath: str | None = None, start_chan: int = 1, hs_id: int = 0)[source]#
Bases:
Settings- filepath: str | None = None#
Path to the
.cmpfile.None(or an empty path) means no CMP — the auto-grid fallback generates coordinates for every channel.
- start_chan: int = 1#
1-based channel ID assigned to the first sorted CMP row. Mirrors
pycbsdk.Session.load_channel_map().
- class ChannelMapUnit(*args, settings=None, **kwargs)[source]#
Bases:
BaseTransformerUnit[ChannelMapUnitSettings,AxisArray,AxisArray,ChannelMapProcessor]- Parameters:
settings (Settings | None)
- SETTINGS#
alias of
ChannelMapUnitSettings
- class ChannelMapUnitSettings(cmp_configs: tuple[ChannelMapSettings, ...] = ())[source]#
Bases:
Settings- Parameters:
cmp_configs (tuple[ChannelMapSettings, ...])
- cmp_configs: tuple[ChannelMapSettings, ...] = ()#
Per-headstage overlays, applied in order on each reset. Empty (the default) means no CMP — the auto-grid lays out every channel.
- __init__(cmp_configs=())#
- Parameters:
cmp_configs (tuple[ChannelMapSettings, ...])
- Return type:
None
- class ChannelMapSettings(filepath: str | None = None, start_chan: int = 1, hs_id: int = 0)[source]#
Bases:
Settings- filepath: str | None = None#
Path to the
.cmpfile.None(or an empty path) means no CMP — the auto-grid fallback generates coordinates for every channel.
- start_chan: int = 1#
1-based channel ID assigned to the first sorted CMP row. Mirrors
pycbsdk.Session.load_channel_map().
- class ChannelMapUnitSettings(cmp_configs: tuple[ChannelMapSettings, ...] = ())[source]#
Bases:
Settings- Parameters:
cmp_configs (tuple[ChannelMapSettings, ...])
- cmp_configs: tuple[ChannelMapSettings, ...] = ()#
Per-headstage overlays, applied in order on each reset. Empty (the default) means no CMP — the auto-grid lays out every channel.
- __init__(cmp_configs=())#
- Parameters:
cmp_configs (tuple[ChannelMapSettings, ...])
- Return type:
None
- class ChannelMapProcessor(*args, **kwargs)[source]#
Bases:
BaseStatefulTransformer[ChannelMapUnitSettings,AxisArray,AxisArray,ChannelMapState]Stateful transformer that attaches CMP-derived channel metadata.
Each reset rebuilds the axis in full from
settings.cmp_configs: a base layer from incoming labels, every CMP overlay applied in order, then the auto-grid fills indices no CMP claimed. Reset fires on a channel-count change or anycmp_configschange (the latter viaBaseProcessor.update_settings→_request_reset), so there is no cross-push state to coalesce. An emptycmp_configsyields a pure auto-grid.
- class ChannelMapUnit(*args, settings=None, **kwargs)[source]#
Bases:
BaseTransformerUnit[ChannelMapUnitSettings,AxisArray,AxisArray,ChannelMapProcessor]- Parameters:
settings (Settings | None)
- SETTINGS#
alias of
ChannelMapUnitSettings