spacr.qt.roi_tool¶
Draw an ROI on the layer canvas, and hand it to Measure.
The two halves of item B14. spacr.roi is the half that runs in a
measurement worker — the geometry, the keep/drop rule and the environment route
that gets both into a spawn pool. This is the half that needs a mouse: a
pen that turns clicks into a spacr.layers.Shape, and a panel that
turns the shapes layer into a spacr.roi.RoiSet and switches the
measurement filter on.
The pen draws into the model, not onto the widget¶
Every vertex is a world coordinate taken from
spacr.layers.Canvas.world_at(), and the polygon being drawn is a real
Shape in a real ShapesLayer. So
the half-finished ROI is rendered by the same compositor as everything else,
it survives a zoom, and the finished ROI is already in the form
spacr.roi.RoiSet.from_shapes_layer() reads. Nothing about the drawing is
in pixels, which is what lets an ROI drawn on a downsampled preview name the
same region on a full-resolution mask.
The panel says whether it will actually work¶
Switching the filter on is one call, and the thing worth putting on screen is
not that it succeeded but whether it will reach the processes that do the
measuring. A filter registered in the GUI process alone is a silent no-op in
every spawn worker: the run finishes, the numbers are for the whole field,
and nothing says so. spacr.roi.worker_delivery_status() answers that in
advance and the panel shows its answer, warning-coloured when it is “no”.
Classes¶
Draw an ROI, then measure only inside it. |
|
Turns clicks on a |
Module Contents¶
- class spacr.qt.roi_tool.RoiPanel(canvas: spacr.qt.layer_viewer.LayerCanvas, parent=None, *, roi_path: str | None = None)[source]¶
Bases:
PySide6.QtWidgets.QWidgetDraw an ROI, then measure only inside it.
- Parameters:
canvas – the
LayerCanvasto draw on. The panel adds its own shapes layer to that canvas’s stack the first time drawing starts.roi_path – where the ROI is written. A worker reads it from there, so it has to be a real file; defaults to
./roi/measure_roi.json.parent – parent widget; ownership only.
Build the ROI panel over a canvas.
- Parameters:
canvas – the canvas whose shapes layer the ROI is drawn into.
parent – parent widget, or
None.roi_path – where the ROI is saved; defaults to
roi/measure_roi.jsonunder the working directory. It is a file because a worker process can only reach the ROI through the file system.
- closeEvent(event) None[source]¶
Take the pen off the canvas so it does not outlive this panel.
- Parameters:
event – the close event; it is passed on to the base class unchanged.
- enable() bool[source]¶
Register the drawn ROI as a Measure region filter.
- Returns:
True when the filter was installed. A drawing mistake is reported in the status line rather than raised out of a click.
- roi_layer(create: bool = True) spacr.layers.ShapesLayer | None[source]¶
The ROI shapes layer, adding it to the stack the first time.
Given the spacing of whatever 2-D layer is already in the stack, so an ROI drawn over a µm-calibrated image is stored in µm and one drawn over a pixel-spaced field is stored in pixels — the units the measurement will be compared against.
- roi_set() spacr.roi.RoiSet[source]¶
Build a
spacr.roi.RoiSetfrom what has been drawn.- Raises:
spacr.roi.RoiError – if nothing closed has been drawn yet.
- set_roi_path(path: str) str[source]¶
Choose where the ROI file is written; returns the absolute path.
- Parameters:
path – where the ROI file should be written; it is made absolute.
- property stack: spacr.layers.LayerStack[source]¶
The stack the canvas is showing.
- class spacr.qt.roi_tool.RoiPen(layer: spacr.layers.ShapesLayer, *, kind: str = 'polygon', parent: PySide6.QtCore.QObject | None = None)[source]¶
Bases:
spacr.qt.layer_viewer.CanvasTool,PySide6.QtCore.QObjectTurns clicks on a
LayerCanvasinto a shape.Left click adds a vertex, double click (or Return) closes the polygon, Backspace takes the last vertex back and Escape abandons the whole thing. A rectangle and an ellipse take two clicks — opposite corners — and close themselves, because a third click on a two-corner shape has no meaning.
While it is being drawn the ROI is a
pathshape in the layer, so the user sees the outline they have so far; when it closes, the path is replaced by a real closed shape. Both are model objects: there is no parallel “rubber band” drawing that could disagree with what is stored.- Parameters:
layer – the
ShapesLayerto draw into.kind –
'polygon','rectangle'or'ellipse'.parent – parent object; ownership only.
Arm a pen that draws one closed shape into a shapes layer.
- Parameters:
layer – the layer the finished ROI is added to.
kind – shape to draw –
"polygon","rectangle"or"ellipse".parent – parent object, or
None.
- Raises:
LayerError – if
layeris not aShapesLayer, or ifkindis not one of the three closed shapes – an ROI has an inside, so an open path cannot be one.
- add_world(world: Dict[str, float]) int[source]¶
Add one vertex given as
{axis: world}; returns the vertex count.A rectangle or an ellipse closes itself on the second vertex.
- Parameters:
world – the vertex position as
{axis: world coordinate}, converted to data coordinates through the layer’s spacing.
- close_shape() int[source]¶
Finish the shape. Returns its index, or
-1if there was not one.Too few vertices is not an error: a stray double click on an empty canvas should do nothing, not raise out of a mouse handler.
- double_click(view: spacr.qt.layer_viewer.LayerCanvas, world: Dict[str, float], event: Any) bool[source]¶
Close the polygon. The second click of the pair is not a vertex.
- Parameters:
view – the canvas that received the double-click; unused.
world – the click position as
{axis: world coordinate}; unused, because the double-click only closes the shape.event – the mouse event; unused.
- key(view: spacr.qt.layer_viewer.LayerCanvas, event: Any) bool[source]¶
Escape abandons, Return closes, Backspace undoes.
- Parameters:
view – the canvas that received the key press; unused.
event – the key event; only its
key()is read.
- press(view: spacr.qt.layer_viewer.LayerCanvas, world: Dict[str, float], event: Any) bool[source]¶
Place a vertex (left button) or take the last one back (right).
- Parameters:
view – the canvas that received the press; unused.
world – the press position as
{axis: world coordinate}, added as a vertex on a left-button press.event – the mouse event; only its
button()is read, and an event without one counts as a left click.
- property layer: spacr.layers.ShapesLayer[source]¶
The layer this pen draws into.
- property pending: numpy.ndarray[source]¶
The vertices placed so far,
(M, ndim)in DATA coordinates.