Derive a grid layout from the ch axis - #10
Merged
Merged
Conversation
The geometry counterpart to chmeta, which already does this for names: given a ch coordinate axis, work out where each channel's cell goes and how big it is. It comes from intent-tools, and deliberately did not move into phosphor with the grids it feeds. Reading x/y/size/headstage off a structured axis is decoding one acquisition system's convention, and a renderer that takes plain arrays should not have to know it. This is the layer that already owns that translation. Labels delegate to chmeta.channel_names rather than repeating its fallback, so a grid can name channels by bank and elec exactly as the sweep does -- the intent-tools version could only read a label field. Everything degrades to a square-ish tiling: no ch axis, no coordinate fields, or only one of the two. A plot that draws nothing is less useful than one that draws the right number of cells in the wrong places, and geometry is missing often enough that this is the common path, not the edge case. Exported lazily, like ShmemSweepWidget: it needs phosphor's geometry helpers, and importing ezmsg.tools.plot must not pull in a GPU stack. 12 tests.
A grid deriving its layout from every message pays for it on every message, while the answer changes about once a session. ChannelLayoutCache wraps channel_layout and recomputes only when the axis actually differs: 102 us down to 6 us at 128 channels. Fingerprinted on the axis' bytes rather than its identity. It arrives deserialized from another process, so it is a new object every message describing the same electrodes -- keying on identity would make the cache miss exactly where it is wanted. A cache rather than a shared instance, so two consumers watching one stream each keep their own and neither has to know the other exists. The derivation stays here, where any application can call it.
CI installs the test group, not the viewer or sigmon extras, so phosphor is absent -- which is the point of it being optional, and which these tests did not allow for. Nine jobs failed on ModuleNotFoundError. Guarded the way test_shmem_sweep already guards for the same reason, but keyed on phosphor itself rather than the module under test: layout.py imports it inside the function, so the module imports cleanly without it and only fails when called. Keying on the module would never have skipped. 19 pass where phosphor is installed, 1 skipped where it is not.
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.
The geometry counterpart to
chmeta, which already does this for names: given achcoordinate axis, work out where each channel's cell goes and how big it is.It comes from intent-tools, where it fed an evoked-potential grid, and it
deliberately did not move into phosphor along with the grids it serves.
Reading
x/y/size/headstageoff a structured axis is decoding oneacquisition system's convention, and a renderer that takes plain arrays should
not have to know it. This is the layer that already owns that translation —
phosphor 0.9.x gained
ChannelGridWidgetandTraceGridWidget, both of whichtake positions and sizes as arrays.
Labels delegate to
chmeta.channel_namesrather than repeating its fallback, soa grid can name channels by
bankandelecexactly as the sweep does. Theintent-tools version could only read a
labelfield.Everything degrades to a square-ish tiling: no
chaxis, no coordinate fields,or only one of the two. A plot that draws nothing is less useful than one that
draws the right number of cells in the wrong places, and geometry is missing
often enough that this is the common path, not the edge case.
ChannelLayoutCacheA grid deriving its layout from every message pays for it on every message,
while the answer changes about once a session. The cache recomputes only when
the axis actually differs — 102 us down to 6 us at 128 channels.
Fingerprinted on the axis' bytes rather than its identity: it arrives
deserialized from another process, so it is a new object every message
describing the same electrodes, and keying on identity would miss exactly where
the cache is wanted.
A cache rather than a shared instance, so two consumers watching one stream each
keep their own and neither has to know the other exists. The derivation stays
here, where any application can call it.
Notes
Exported lazily, like
ShmemSweepWidget: it needs phosphor's geometry helpers,and importing
ezmsg.tools.plotmust not pull in a GPU stack.phosphor>=0.9.1in theviewerandsigmonextras.19 new tests.
🤖 Generated with Claude Code