spacr.qt.screens.model_zoo¶
Model Zoo — every model this machine can segment or classify with, in one list.
The question “which models do I have, where did they come from, and does this
one work on my images” is currently answered with find, memory and a full
plate run. This screen answers it in a list, a provenance card and three
fields.
Layout:
┌──────────────────────────────────────────────────────────────────────┐
│ /data/screen1 [Choose folder…] [Scan] │
├──────────────────────────────────────────────────────────────────────┤
│ model kind source v size checksum trained on │
│ toxo_plaque… cellpose bundled 1 25 MB none /nas_mnt/… │
│ maxvit_t_epoch… classifier local 1 310 MB none /data/… │
│ hela_60x.CP… cellpose remote 1 26 MB published unknown │
├──────────────────────────────────────────────────────────────────────┤
│ hela_60x_confluent.CP_model [cellpose · remote · v1] │
│ uri https://… │
│ sha256 9f86d0… (published) │
│ trained on unknown │
│ ! this model does not say what it was trained on… │
├──────────────────────────────────────────────────────────────────────┤
│ Download to [~/.spacr/models ] [Choose…] [Download] [Cancel] │
│ [==================== ] 12.4 MB / 26.5 MB │
├──────────────────────────────────────────────────────────────────────┤
│ Test on [3] fields from [/data/screen1/plate1/1] [Choose…] [Test] │
│ field objects seg_qc flags ┌───────────────┐ │
│ A01_f01 212 ok - │ [ masks ] │ │
│ A01_f02 198 warn high_border_fraction └───────────────┘ │
└──────────────────────────────────────────────────────────────────────┘
Design notes:
Provenance is a column, not a tooltip. “What was this trained on” is what decides whether a model applies to your images at all, so it is in the table and spelled
unknownwhere it is unknown — a blank cell reads as “no constraints”, which is the opposite of what it means.Downloads are off the GUI thread, atomic, and cancellable. The bytes go to a temp file inside the destination and are renamed only after the checksum passes (
spacr.model_zoo.fetch()), so Cancel leaves the destination exactly as it was — no half-written file at a name that looks like a model.worker.finishedis relayed through a signal into a bound method. PySide6 delivers a plain closure connected to a worker’s signal as a direct call on the worker thread, and the completion handler here fills a QPlainTextEdit and a QTableWidget. Building QTextDocument children off the GUI thread is undefined behaviour, sofinishedchains throughModelZooScreen._job_settled— a widget-affine bound method — exactly asPlateViewScreendoes.No modal dialogs on any error path. A folder with no models, a checksum mismatch, a corrupt checkpoint, a cancelled download: all inline. A QMessageBox hangs a headless run.
Two selected models hand off to Model Compare. Benchmarking each one separately and reading the two tables is not a comparison — the A/B harness in
spacr.model_compareis, and it is the one that says out loud that neither model is ground truth. This screen builds a configuredModelCompareScreenand emits it rather than growing a second, weaker comparison of its own.Benchmarks are never sorted across field sets. The results table belongs to one model on one set of fields, and the summary line names the field set, because a score on your three fields says nothing about a score on anybody else’s.
Classes¶
Browse, verify, download and benchmark models supported by spaCR. |
Functions¶
|
Blend one model's mask over its field, in one colour. |
|
Collapse a listing to one row per model family, newest version first. |
Module Contents¶
- class spacr.qt.screens.model_zoo.ModelZooScreen(parent=None, threaded: bool = True)[source]¶
Bases:
PySide6.QtWidgets.QWidgetBrowse, verify, download and benchmark models supported by spaCR.
- Parameters:
parent – Qt parent.
threaded – run scans, downloads and benchmarks on worker threads (the default). Tests pass
Falseto run them inline; both paths emit the same signals in the same order.
- Variables:
last_error – text of the most recent failure,
''after a success. Errors go here and to the inline status label — never to a dialog.
Build the zoo: the scan list, the downloads and the benchmark.
- Parameters:
parent – parent widget.
threaded – whether scans and downloads run on workers.
- build_comparison_screen(threaded: bool = True)[source]¶
A
ModelCompareScreen, configured.The host can show this directly instead of wiring
compare_requesteditself.- Parameters:
threaded – passed through to the comparison screen.
- Returns:
the configured screen, or None when two models with local files are not selected.
- cancel_download() bool[source]¶
Ask the running download to stop. Nothing is left behind.
The flag is a plain dict read by the worker between chunks; the fetch deletes its temporary file and raises, so the destination folder never sees a partial model.
- Returns:
True when there was something to cancel.
- chosen_entry(row: int)[source]¶
The entry a row currently stands for, honouring its version pick.
- Parameters:
row – index into the grouped listing, i.e. the model family in the order
set_entries()laid the rows out.
- closeEvent(event)[source]¶
Let every in-flight job finish before the widget dies.
A QThread collected while still running aborts the process, so the widget waits rather than dropping its references and hoping.
- Parameters:
event – the close event, passed on to the base class after running jobs are cancelled and waited on (up to five seconds each).
- compare_selected() bool[source]¶
Hand two selected models to the A/B comparison.
Two separate benchmarks are not a comparison: they have no shared object matching, no split/merge attribution and no statement about which differences are real.
spacr.model_comparehas all three, so this emitscompare_requestedfor the host to open that screen rather than growing a weaker comparison here.- Returns:
True when the request was emitted.
- download_selected() bool[source]¶
Download the selected model into the destination folder.
Off the GUI thread, atomic, checksummed and versioned — see
spacr.model_zoo.fetch(). A cancel leaves the destination exactly as it was.- Returns:
for the synchronous path, whether a file was installed; for the threaded path, True once the job started.
- entries() List[spacr.model_zoo.ModelEntry][source]¶
Everything currently listed, in table order.
- preview_size()[source]¶
(w, h)the preview OCCUPIES,(0, 0)when there is none.Widget coordinates, not the pixel count behind them: the picture is rendered at the screen’s density, so on a HiDPI panel those two numbers differ by the device pixel ratio.
- result() spacr.model_zoo.BenchmarkResult | None[source]¶
The most recent
spacr.model_zoo.BenchmarkResult.
- run_benchmark() bool[source]¶
Segment the loaded fields with the selected model and score them.
- Returns:
for the synchronous path, whether a result was produced; for the threaded path, True once the job started.
- scan(folder: str | None = None, include_catalogue: bool = True) bool[source]¶
List the catalogue plus every checkpoint under
folder.Never raises and never opens a dialog: a mistyped path, a folder with no models, an unreadable tree all land in the status label.
- Parameters:
folder – folder to scan; None uses whatever is in the box.
include_catalogue – also list the bundled and declared entries.
- Returns:
for the synchronous path, whether anything was listed; for the threaded path, True once the job started.
- select(*rows: int) None[source]¶
Select these rows (test/programmatic helper).
Goes through the selection model rather than
selectRowbecause the latter clears the selection first in ExtendedSelection mode, soselect(0, 1)would leave exactly one row selected — and “two selected models” is the whole input to the compare hand-off.
- select_field(row: int) bool[source]¶
Draw field
row’s mask over its image.- Parameters:
row – index into the benchmark table.
- Returns:
True when something was drawn.
- selected_entries() List[spacr.model_zoo.ModelEntry][source]¶
The selected models, in table order.
Through the identity stamped on each row, not the row number: the table sorts, and a row number stops naming a model the moment a header is clicked.
- set_entries(entries) None[source]¶
Replace the listing (used by the scan, and directly by tests).
One row per model family. The version column is a combo box, so a model with several versions is one row the user opens rather than several rows they have to tell apart by suffix.
- Parameters:
entries – iterable of
spacr.model_zoo.ModelEntry; grouped into families by key, newest version first.
- set_fields_source(folder: str) bool[source]¶
Load benchmark fields without blocking the GUI thread.
- Parameters:
folder – a folder of
.tif/.png/.npy/.npz.- Returns:
with
threaded=False, True when at least one field loaded; otherwise True once the load starts. On failure the reason is in the status label.
- set_opener(opener: Callable | None) None[source]¶
Override how bytes are fetched.
fn(uri) -> chunksorfn(uri) -> (chunks, total); None restoresspacr.model_zoo.open_uri(). This is the seam the tests use, and it is why no test in this suite touches the network.- Parameters:
opener – callable of that form, or
None.
- set_segment_fn(fn: Callable | None) None[source]¶
Override the segmentation backend.
fn(images, config) -> masks; None restoresspacr.model_compare.segment_with_cellpose(). Every test injects one, which is why nothing here loads Cellpose.- Parameters:
fn – callable of that form, or
None.
- spacr.qt.screens.model_zoo.compose_labels(image: numpy.ndarray | None, mask: Any, alpha: float = 0.45) numpy.ndarray | None[source]¶
Blend one model’s mask over its field, in one colour.
The greyscale backdrop comes from
spacr.qt.screens.model_compare.to_display_gray()— the same 1-99.9 percentile stretch the comparison screen uses, so the same field looks the same in both places.One colour rather than a palette: a single segmentation has no correspondence to encode, and colouring by label id across two screens invites reading label 3 here as label 3 there.
- Parameters:
image – the field, or None for a black backdrop.
mask – a 2-D label image.
alpha – overlay strength.
- Returns:
a uint8
(H, W, 3)array, or None when the mask is not a 2-D label image.
- spacr.qt.screens.model_zoo.group_entries(entries) list[source]¶
Collapse a listing to one row per model family, newest version first.
The zoo used to show one row per checkpoint, so a model with three versions pushed two unrelated models off the screen. Grouping makes the row a MODEL and the version a choice within it.
Nested helpers¶
- ModelZooScreen._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 thread: a return would be swallowed by the runner.
spacr/qt/screens/model_zoo.py:1432
- ModelZooScreen.download_selected._job() zoo.ModelEntry¶
Install the chosen model. Off the GUI thread.
spacr/qt/screens/model_zoo.py:1050
- ModelZooScreen.rows.text(r, c)¶
The text shown in cell
(r, c), from its item or its combo box.spacr/qt/screens/model_zoo.py:861
- ModelZooScreen.run_benchmark._job() zoo.BenchmarkResult¶
Benchmark one model against the loaded fields. Off the GUI thread.
spacr/qt/screens/model_zoo.py:1241
- ModelZooScreen.scan._job() List[zoo.ModelEntry]¶
Find every model, catalogue plus local. Off the GUI thread.
spacr/qt/screens/model_zoo.py:897
- ModelZooScreen.set_fields_source._job()¶
Load the benchmark fields. Off the GUI thread.
spacr/qt/screens/model_zoo.py:1159