spacr.qt.screens.classifier_evaluation

Classifier Evaluation workbench for out-of-fold result bundles.

Discovery and CSV/JSON parsing run away from the GUI thread. The screen only renders already-loaded data, so a large OOF prediction table cannot freeze the application while it is being read.

C8 — the confusion matrix is a query, not a picture

Every cell of the matrix is clickable, and clicking one asks spacr.qt.linked_selection.open_objects() for exactly the crops that cell counted — so “43 uninfected called infected” stops being a number and becomes 43 images you can look at. The analysis behind it is in spacr.confusion, which has no Qt in it; this file is the table, the two lists and the buttons.

Two lists, not one, per cell. The model being sure and wrong is evidence against the annotation; the model being unsure and wrong is evidence about the boundary. They are different diagnoses with different fixes, so they are opened separately and never blended into one confidence-sorted list where the distinction disappears somewhere in the middle of a scroll.

And before either: where did the errors come from. A cell broken down per well and per plate answers the question that makes re-labelling worth doing at all — 43 errors from 20 wells is the model’s problem, 43 errors from one well is the bench’s.

Classes

ClassifierEvaluationScreen

Browse and inspect classifier evaluation bundles.

Functions

find_evaluation_bundles(→ List[pathlib.Path])

Discover evaluation manifests while keeping sklearn off GUI startup.

load_evaluation_bundle(→ Dict[str, Any])

Load one evaluation bundle without importing sklearn at GUI startup.

Module Contents

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

Bases: PySide6.QtWidgets.QWidget

Browse and inspect classifier evaluation bundles.

Parameters:
  • parent – Qt parent.

  • threaded – discover and parse bundles in a worker thread. Tests may pass False to make refresh deterministic.

Variables:
  • last_error – latest non-fatal source or parsing error.

  • bundles – manifests found by the most recent scan.

Build the screen and arm its drop zone.

The confusion cell under inspection is held, so moving the confidence threshold re-splits that cell rather than making the user click it again.

Parameters:
  • parent – parent widget, or None.

  • threaded – scan on a worker thread. Set False in tests so scan finishes before it returns.

closeEvent(event) → None[source]

Drain scan/load workers before Qt destroys this screen.

A job left running here outlives its owner but stays in the process-wide run registry, which MainWindow.closeEvent reads to decide whether the application may quit.

Parameters:

event – the close event; it is not inspected, only passed on to the base class once the workers are drained.

open_cell(which: str) → Any[source]

Route one half of the open cell to whatever shows crops.

Nothing here imports Annotate: the request travels through spacr.qt.linked_selection.open_objects(), so a second destination added later needs no change in this file.

The per-key confidences ride along in context so the receiver can show why this order, and the threshold so it can say where the split was made.

Parameters:

which – "high" for the confident (sure and wrong) half of the open cell or "low" for the unconfident half; a value the cell rejects is reported in the status line.

Returns:

whatever the opener returned, or None when there was nothing to open or nowhere to open it.

scan() → None[source]

Discover evaluation bundles without blocking the GUI thread.

show_cell(true_class: str, predicted_class: str) → None[source]

Inspect one confusion cell. The seam a test (or a link) goes through.

Parameters:
  • true_class – annotated class naming the confusion-matrix row.

  • predicted_class – model-predicted class naming the confusion-matrix column.

Returns:

nothing; the two lists, the breakdown and the buttons are the result.

spacr.qt.screens.classifier_evaluation.find_evaluation_bundles(root: Any) → List[pathlib.Path][source]

Discover evaluation manifests while keeping sklearn off GUI startup.

The implementation is imported only when a scan worker calls this seam. Keeping the seam at module scope also lets tests and downstream wrappers replace discovery without importing the scientific stack eagerly.

spacr.qt.screens.classifier_evaluation.load_evaluation_bundle(path: Any) → Dict[str, Any][source]

Load one evaluation bundle without importing sklearn at GUI startup.

Nested helpers

ClassifierEvaluationScreen._load_selected_bundle._work(_settings)

Load one evaluation bundle. Off the GUI thread.

spacr/qt/screens/classifier_evaluation.py:529

ClassifierEvaluationScreen.scan._work(_settings)

Find the evaluation bundles under a folder. Off the GUI thread.

spacr/qt/screens/classifier_evaluation.py:463