Add dense-array-base representation handle to ProbeGroup#425
Draft
h-mayorquin wants to merge 5 commits intoSpikeInterface:mainfrom
Draft
Add dense-array-base representation handle to ProbeGroup#425h-mayorquin wants to merge 5 commits intoSpikeInterface:mainfrom
h-mayorquin wants to merge 5 commits intoSpikeInterface:mainfrom
Conversation
This was referenced Apr 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Coming here from #420
This PR adds a new private
_contact_vectorproperty onProbeGroup. The property is a dense channel-ordered read-only array derived from the currentdevice_channel_indices:It contains only the subset of state SpikeInterface actually needs in channel order:
probe_index,x,y,z,shank_ids, andcontact_sides. Fields that are not available on theProbeGroupare not included in the representation. The property is private by convention: it is intended for integration with downstream libraries (notably SpikeInterface), and its fields and dtype may evolve with consumer requirements, so user code should not depend on it directly.This PR enables a middle way between the old
contact_vectorworkflow we are currently using in SpikeInterface and the full array-backed rewrite ofProbeGroupproposed in #420. #420 changes the identity ofProbeGroupitself to become an array-backed backend; this PR keeps the scope smaller and adds a cached attribute with only what SpikeInterface needs. The coupling between probeinterface and SpikeInterface now lives in one small surface (_contact_vectorand_build_contact_vector()) instead of being spread through the wholeProbeGroupclass, so the two libraries can evolve together without requiring larger changes on either side. This provides the probeinterface-side handle needed for the SpikeInterface #4465 direction, where the recording holds aProbeGroupobject directly and recovers the channel-facing behavior through this handle on demand.Three technical points:
SpikeInterface integration. The cache is invalidated on probegroup mutations (
add_probe,set_global_device_channel_indices,auto_generate_*) and rebuilt lazily on first access, so consumers just readprobegroup._contact_vectorand do not have to track when to rebuild. Probe-level mutations (e.g.probe.move) do not invalidate the cache; this keepsProbeGroupunaware ofProbeinternals and avoids the container/contained coupling that Refactor probegroup to be array-based #420 introduces via a_probe_groupback-reference and partial mutation guards onProbe. The only case where a consumer must call_build_contact_vector()explicitly is after mutating a probe post-attachment which is a a rare, well-defined exception that should be handled at the consumer side.Private to make it flexible. The property is private because its fields and dtype are tailored to SpikeInterface's current needs and will evolve with them. As a private attribute, the handle can grow, shrink, or change shape without becoming a public-API break. Keeping it private also avoids a footgun: someone mutating a probe after attaching the probegroup and expecting the changes to propagate to the cache (see the previous bullet). This mechanism is for SpikeInterface and for power users who know the contract, so let's keep it private and safe.
No serialization format change. The cache lives in memory only; it is rebuilt at access time from each probe's own
device_channel_indices, which already round-trip through probe serialization. So this PR needs no format version bump and no new way to encode channel order in the JSON/dict representation. The existing per-probe serialization is sufficient. Because the handle derives fromdevice_channel_indicesrather than replacing it, a consumer could also preserve the user-provided wiring as provenance and still obtain a channel-ordered view.The companion SpikeInterface PR illustrates the implementation of this.