spacr.qt.screens.agreement¶
Annotator Agreement — agreement between the annotation columns of one database.
The Annotate app writes one INTEGER column per pass into png_list. Two
people labelling the same crops therefore leave two columns side by side, and
this screen reports whether they agree, and on which rows they differ, before
either set is used as ground truth.
Layout:
┌───────────────────────────────────────────────────────────────────┐
│ /data/plate1/measurements/measurements.db [DB…] [Run folder…] │
│ Read-only (mode=ro) — nothing here can modify your annotations. │
├──────────────┬────────────────────────────────────────────────────┤
│ Annotators │ a b n abstain raw κ band │
│ ☑ alice │ alice bob 410 92 88.0% +0.61 substantial │
│ ☑ bob ├────────────────────────────────────────────────────┤
│ ☐ carol │ Confusion [alice vs bob ▾] 1 2 │
│ │ 1 310 22 │
│ [Compute] │ 2 27 51 │
├──────────────┴────────────────────────────────────────────────────┤
│ Overall Cohen's κ +0.61 (substantial) · raw 88.0% · 49 to review │
├───────────────────────────────────┬───────────────────────────────┤
│ Disagreements png_path alice bob│ [crop preview] │
│ …/A01_1_cell_3.png 1 2 │ │
└───────────────────────────────────┴───────────────────────────────┘
Design notes:
Read-only, structurally. Every connection goes through
spacr.agreement. It opens the file withfile:…?mode=roandPRAGMA query_only = ON, the same approach the Database Browser takes. Disagreements are resolved in the Annotate app; this screen does not write.Off the GUI thread. The report reads the whole
png_listannotation block, so it runs throughspacr.qt.bridge.make_thread()like every other spaCR job. Tests passthreaded=False.No modal dialogs on any error path. “You only picked one column”, “that file isn’t a database”, “this table has no annotation columns” — all of it lands in an inline status label. A QMessageBox would hang a headless run.
κ is never quoted alone. Raw percent agreement, the number of compared rows, the number of abstentions and the reason κ is undefined (when it is) are all on screen next to it. See
spacr.agreementfor why that matters on a screen where 98 % of cells are negative.
Classes¶
Inter-annotator agreement over the annotation columns of a database. |
Functions¶
|
Render a κ for display, or |
Module Contents¶
- class spacr.qt.screens.agreement.AgreementScreen(parent=None, threaded: bool = True)[source]¶
Bases:
PySide6.QtWidgets.QWidgetInter-annotator agreement over the annotation columns of a database.
- Parameters:
threaded – compute the report on a worker thread (the default). Tests pass
Falsefor deterministic, synchronous behaviour.parent – parent widget; ownership only.
- Variables:
last_error – text of the most recent failure,
""when the last operation succeeded. Errors are only ever reported here and in the inline status label — never in a modal dialog.
Build the screen and arm its drop zone.
- Parameters:
parent – parent widget, or
None.threaded – run the agreement computation on a worker thread. Set
Falsein tests socomputefinishes before it returns.
- closeEvent(event)[source]¶
Let every in-flight compute thread finish before the widget dies.
- Parameters:
event – the close event, passed on to the base class once each running job thread has been asked to quit and waited on (up to five seconds each).
- compute() bool[source]¶
Build the agreement report for the ticked columns.
Everything that can go wrong here is a normal state — no database, one column ticked, a column that turns out to be empty — so every failure is inline text and a
Falsereturn.- Returns:
for the synchronous path, whether the report was built; for the threaded path,
Trueonce the job has started.
- disagreement_rows() List[List[str]][source]¶
The review list as plain strings — key first, then each label.
- is_busy() bool[source]¶
Whether anything is still running.
What the window asks before closing.
- Returns:
True while work is outstanding.
- report() spacr.agreement.AgreementReport | None[source]¶
The most recent
AgreementReport, or None.
- select_columns(names) bool[source]¶
Tick exactly
names; report inline for anything unknown.- Parameters:
names – annotation column names to check; every other listed column is unchecked. Names not in the list are reported in the status line.
- Returns:
True when every requested column was found.
- select_disagreement(row: int) bool[source]¶
Show the crop for review row
row.A missing PNG is a fact about the dataset (crops get moved, or the database was copied without them), not an error worth a dialog — the preview says so and the row stays selected.
- Parameters:
row – zero-based row of the disagreement table; out of range clears the preview.
- Returns:
True when an image was actually rendered.
- set_database(path: str) bool[source]¶
Open
pathread-only and list its annotation columns.Accepts the database file or a run
srcfolder. Any problem (missing file, not a database, nopng_list) is reported in the status label and returnsFalse— this never raises.- Parameters:
path –
measurements.dbfile, runsrcfolder ormeasurementsfolder; resolved withspacr.qt.screens.db_browser.resolve_db_path().- Returns:
True when a database with at least one annotation column was opened.