Add ROI readback plotters#632
Conversation
Add RectanglesReadbackPlotter and PolygonsReadbackPlotter for displaying ROI shapes from workflow outputs in the new composable layer system. Each shape is colored by its ROI index for stable visual identity. Extend DataRequirements with: - deny_coords: reject data containing specified coordinates - required_dim_names: require specific dimension names This enables the wizard to correctly filter plotters based on data structure. LinePlotter now denies roi_index to avoid showing for ROI data. Prompt: We are in the process of converting the bespoke ROI plot setup to the new approach of using composable layers in PlotOrchestrator/ PlotGridTabs. The next step would be to add a plotter that can plot the "readback" rectangles or polygons. The end goal is that we want to be able, in the PlotConfigModal, select a detector workflow, select the "rectangles" output, get a Rectangles plotter on the wizard step, and then plot this with different colors per rectangle based on index. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Decouple ROI type identification from the DataArray name attribute. Previously, ROI.from_data_array() dispatched based on da.name, but job_manager.py overwrites this with the field title, breaking parsing. Now dispatch based on dimension name which is preserved through Kafka: - 'bounds' -> RectangleROI - 'vertex' -> PolygonROI - 'ellipse' -> EllipseROI This allows DetectorViewOutputs field titles to be user-friendly strings like "Rectangle ROI (readback)" without breaking ROI deserialization. Changes: - ROI.from_data_array() dispatches on da.dims[0] instead of da.name - EllipseROI uses 'ellipse' dimension instead of generic 'dim' - Removed name-setting in to_data_array/to_concatenated_data_array - Removed _get_plural_name/_get_singular_name helpers - Updated tests to reflect dimension-based dispatch Prompt: I need to change the title field in DetectorViewOutputs as shown in the diff. But as the comment in the code emphasizes, this breaks ROI.from_data_array. Can you think of a better solution? The title is what the user sees, so it must not be relied upon. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
8fa326b to
f554135
Compare
| The ROI type is encoded in the DataArray's name attribute, which maps to the | ||
| 'label' field in da00 Variable for the signal. | ||
| The ROI type is encoded in the DataArray's dimension name: 'bounds' for | ||
| rectangles, 'vertex' for polygons, 'ellipse' for ellipses. |
There was a problem hiding this comment.
I find this mechanism difficult to follow/error prone.
Can we think of a different approach? Like make NewTypes for each case, where they would all be data arrays?
There was a problem hiding this comment.
The thing is that this gets serialized into da00 and the "other side" has to be able to tell what it is. We could add extra dummy coords or similar (minor message size/cost increase), but it is not really simpler I think?
| """Plotters for ROI readback data from workflows. | ||
|
|
||
| These plotters display ROI shapes (rectangles, polygons) that come from | ||
| workflow outputs, with per-shape colors based on ROI index. |
There was a problem hiding this comment.
Not sure I get what is meant by "that come from workflow outputs".
I thought the shapes were drawn by the user?
There was a problem hiding this comment.
See first line in what you quote: This is the "readback" - the detector view workflow that produces and output spectrum also returns the actual ROI that was used to make that spectrum.
| sc.array(dims=['x'], values=[1.0, 2.0, 3.0]), | ||
| ) | ||
| compatible = plotter_registry.get_compatible_plotters({'key': data}) | ||
| assert 'lines' in compatible |
There was a problem hiding this comment.
I didn't really understand how the position or size of a rectangle or polygon gets updated from user interaction.
For my own understanding, can you describe quickly how that works?
There was a problem hiding this comment.
The backend detector view publishes the readback coords. This plotter plots this. There is no user interaction here.
The user interaction comes into play in the follow-up PR: Users draws/moves -> message to backend -> backend publishes readback (and updated ROI spectrum).
This is another (small) step towards replacing the complex and bespoke ROI plotter setup. In this change we add the ability the plot the "readback" ROI rectangles and polygons as their own layers.
We can thus now:
What is missing for a fully modular setup is now just the "ROI request", based on a Holoviews stream. This is the most complex one.
As a secondary change in this PR we avoid depending on a particular name for detector the ROI type. As the
titleis now used for user display (output selection on plot creation, layer header) we needed something more informative instead of an internal identifier.