spacr.qt.roi_tool¶
Draw an ROI on the layer canvas, and hand it to Measure.
The ROI feature is split across two modules. 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. The panel shows whether the filter will
reach the worker processes that do the measuring: a filter registered only in
the GUI process has no effect in a spawn worker, and the run then measures
whole fields without a warning. spacr.roi.worker_delivery_status()
reports this in advance, and the panel shows the result in the warning colour
when the filter will not reach the workers.
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.