spacr.qt.screens.align

Align & Stitch: plan a tile layout, flag unregistered tiles, then write.

A failed registration is not visible in the stitched output. A tile that did not register is placed at its nominal stage position; the result still looks like a mosaic and has the right dimensions, but is offset by however far the stage was off.

This screen therefore shows the plan before the write:

  • pick a folder of tiles, press Plan — nothing is written, no canvas is allocated, and only tile headers plus overlap strips are read;

  • the layout is drawn tile by tile, coloured by registration confidence, with anything that fell back to the stage position drawn in the warning colour and hatched. Those tiles are countable at a glance;

  • the estimated canvas size and the RAM the write would use are stated before the write button is enabled;

  • Write stack then composites incrementally, and optionally records the coordinates into measurements.db.

Every long operation runs on a worker thread and reports back through a bound method, never a closure — see AlignScreen._run_job(). Errors land in the inline status label; a QMessageBox here would hang a headless run, so there are none.

Classes

AlignScreen

The Align & Stitch tool.

TileLayoutWidget

The stitch layout: one rectangle per tile, coloured by confidence.

Functions

confidence_colour(→ PySide6.QtGui.QColor)

Colour for one tile in the layout view.

Module Contents

class spacr.qt.screens.align.AlignScreen(parent=None, threaded: bool = True)[source]

Bases: PySide6.QtWidgets.QWidget

The Align & Stitch tool.

Parameters:
  • parent – parent widget.

  • threaded – run the scan/plan/write on a worker thread (the default). Tests pass False for deterministic, synchronous behaviour — both paths emit the same signals.

Variables:

last_error – text of the most recent failure, "" when the last operation succeeded. Errors are only reported here and in the inline status label, never in a modal dialog.

Build the Align screen with nothing planned or written yet.

active_jobs() → int[source]

How many worker threads are still winding down.

apply_settings(settings: Dict[str, Any]) → None[source]

Load a settings dict back into the controls.

Parameters:

settings – partial or full Align settings; missing keys are filled from spacr.align.default_settings() before the controls are set.

build_plan() → bool[source]

Scan the source and solve the layout. Writes nothing.

Returns:

True when the job was started (or, unthreaded, when it succeeded).

is_busy() → bool[source]

True while a job is in flight.

plan()[source]

The current spacr.align.AlignPlan, or None.

report_text() → str[source]

The rendered plan (test/introspection helper).

result()[source]

The last spacr.align.AlignResult, or None.

settings() → Dict[str, Any][source]

Return the controls as a spacr.align.default_settings() dict.

Kept public so the Batch Runner and the Queue can snapshot this screen the way they snapshot every other one.

status_text() → str[source]

Current inline status message (test/introspection helper).

tile_info_text() → str[source]

The per-tile readout line (test/introspection helper).

write_stack() → bool[source]

Composite the current plan to disk, and optionally to the database.

class spacr.qt.screens.align.TileLayoutWidget(parent=None)[source]

Bases: PySide6.QtWidgets.QWidget

The stitch layout: one rectangle per tile, coloured by confidence.

Draws the plan, not the pixels — it never opens an image, so showing the layout reads no image data. Hovering is not wired; the per-tile detail lives in the report pane beside it, where it can be read and copied.

Parameters:

parent – parent widget.

Build an empty layout view, sized to expand with its pane.

mousePressEvent(event) → None[source]

Emit tile_clicked for whatever was under the cursor.

Parameters:

event – the mouse press event; only its position is read. A press outside every tile emits -1.

paintEvent(event) → None[source]

Draw the tile rectangles, or the empty-state hint.

Parameters:

event – the paint event; not read, the whole widget is redrawn.

plan()[source]

The plan currently drawn.

set_plan(plan) → None[source]

Show plan (an spacr.align.AlignPlan), or None.

Parameters:

plan – the plan whose placements are drawn; None shows the empty-state hint.

tile_rects() → List[Tuple[int, QRectF]][source]

Return (tile_index, rect) in widget coordinates.

Public so a test can assert the layout without screen-scraping pixels.

spacr.qt.screens.align.confidence_colour(confidence: float, method: str) → PySide6.QtGui.QColor[source]

Colour for one tile in the layout view.

A tile placed by stage position alone is drawn in the warning colour whatever its (zero) confidence, because a stage-position placement is a different category from a weak registration. Registered tiles ramp from the muted surface at confidence 0.3 to full accent at 1.0, so a weak match reads as pale rather than as a different category.

Parameters:
  • confidence – registration confidence from 0 to 1; values outside 0.3-1.0 are clamped to the ends of the ramp.

  • method – placement method, one of the spacr.align.METHOD_* values; "nominal" gives the warning colour and "unreadable" the error colour regardless of confidence.

Nested helpers

AlignScreen._run_job._job(payload: Dict[str, Any]) → None

Call the wrapped function, stashing its result in the payload.

The payload is how a value crosses back from the worker: a return would be swallowed by the runner.

spacr/qt/screens/align.py:751

AlignScreen.build_plan._work()

Scan the tiles and build the stitch plan. Off the GUI thread.

spacr/qt/screens/align.py:614

AlignScreen.write_stack._work()

Write the stitched stack. Off the GUI thread.

spacr/qt/screens/align.py:690