spacr.qt.screens.run_compare

Workflow inputs and outputs

Run Compare

Compare compatible saved settings, counts and hit lists without treating changed input data as a controlled model comparison.

Open: Home → Run Compare.

Inputs and outputs below include conditional alternatives. The guidance and handoff notes say which route applies.

Inputs

  • Run history and artifacts — Project run records, settings, output paths, artifact provenance, status and logs.

  • Regression results and hits — Selected run results folder: coefficient/result CSVs, hit tables, settings and diagnostic figures.

Outputs

  • Run/model comparison — Comparison tables and figures from compatible saved runs or masks; agreement is not ground-truth accuracy.

Before this module

  • Regression: Compare compatible saved result sets and their settings.

API reference.

Module tutorial.

Run Compare — two runs of the same project, side by side.

Pick a project, pick two of its runs, and the screen answers the three questions that follow a re-run:

  1. What did I change? The settings diff, grouped under the same headings the settings panel groups them by, showing only what moved. Two hundred keys are not a diff; two keys under Cellpose are.

  2. What came out? Objects, wells and fields per plate and overall. A run that produced 12% fewer cells has a problem, and this is where it is visible first.

  3. Which hits moved? Appeared, vanished, and — just as importantly — changed rank. A hit list whose membership is stable but whose top ten reshuffles every run is not a stable result.

All three come from spacr.run_compare, which is headless: this file picks the runs and draws the tables and knows nothing else. The run lists come from the artifact registry (spacr.artifacts), never from a filesystem scan — a run whose outputs were deleted still has its settings recorded, and dropping it from the dropdown would lose the only copy of what produced the numbers somebody is asking about.

Incomparable runs are not diffed. Two runs of different plates subtract perfectly well and produce a table that looks exactly like a regression report. When spacr.run_compare.comparability() raises a blocker the tables stay empty and the banner says why, with a Compare anyway button for the user who knows better. Warnings — a different spaCR version above all — are shown with the tables rather than instead of them, because a version change explains a count change on its own.

Classes

RunCompareScreen

Put two runs of one project side by side.

Functions

make_run_compare_screen(→ RunCompareScreen)

Construct the Run Compare screen for lazy registry loading.

register(→ bool)

Add Run Compare to the app registry. Idempotent.

Module Contents

class spacr.qt.screens.run_compare.RunCompareScreen(parent=None, project: str = '')[source]

Bases: PySide6.QtWidgets.QWidget

Put two runs of one project side by side.

Parameters:
  • parent – Qt parent.

  • project – open straight onto this project root, skipping the folder picker. Tests and the “compare with the run that just finished” path both use it.

Variables:

last_error – text of the most recent failure, "" when the last operation worked. Failures land here and in the banner — never in a modal dialog, which hangs a headless run.

Build the run-comparison screen.

Parameters:
  • parent – parent widget, or None.

  • project – a project folder to list runs from immediately; empty leaves the screen asking for one.

compare(*, force: bool | None = None) → spacr.run_compare.RunComparison | None[source]

Compare the two selected runs and redraw the three tables.

Parameters:

force – diff even when the runs are not comparable. None keeps whatever the Compare anyway button last set — which is reset every time the selection changes, so forcing one pair never silently forces the next.

Returns:

the RunComparison, or None when two runs are not selected.

comparison() → spacr.run_compare.RunComparison | None[source]

The most recent comparison, or None.

load_project(project: str) → List[spacr.run_compare.RunRef][source]

Fill both dropdowns with the runs project has registered.

Parameters:

project – the project root.

Returns:

the runs found, newest first. Empty when the project has no registry yet — which is what a project that predates the artifact registry looks like, and the banner says so rather than the screen looking broken.

runs() → List[spacr.run_compare.RunRef][source]

The runs currently listed, newest first.

select(a: str, b: str) → None[source]

Select two runs by run id and compare them.

Parameters:
  • a – the baseline run’s id.

  • b – the compared run’s id.

selected_runs() → Tuple[spacr.run_compare.RunRef | None, spacr.run_compare.RunRef | None][source]

(A, B) as the dropdowns currently stand.

verdict_text() → str[source]

What the banner currently says.

spacr.qt.screens.run_compare.make_run_compare_screen() → RunCompareScreen[source]

Construct the Run Compare screen for lazy registry loading.

spacr.qt.screens.run_compare.register() → bool[source]

Add Run Compare to the app registry. Idempotent.

Called at import time so that importing this module is all it takes for the app to exist — the registration seam from 1a5ac2ab. It returns rather than raises on a duplicate key so a re-import (a reloaded module, a test that cleared the registry) is a no-op instead of taking the import down.

It is also named in spacr.qt.app._SELF_REGISTERING_APPS and in spacr.qt.SELF_REGISTERING_MODULES, which is belt and braces rather than a mistake: the first is what makes the row exist under a bare import spacr.qt.app — an inventory that depended on whether something else had imported this module is an inventory that fails on whichever file pytest collected first — and the second is the launch path, which must still work if the first ever fails. All three calls land on this function and it registers once.

GUI-only. cli_note and no entry: the answer this screen gives is three tables you read against each other, and spacr.run_compare is already the headless half — the note names the two functions rather than wrapping them in a settings file that would have to invent a spelling for “these two runs”.

Returns:

True when this call is what registered it.