spacr.qt.widgets.model_zoo_picker

Browse the model zoo, download a model, and hand back its path.

A model setting takes a filesystem path, which is exact and unhelpful: the user has to know a model exists, find where it lives, and type it correctly before anything happens. This dialog is the other way in – the list of models spaCR knows about, what each was trained on, whether it is already on this machine, and a button that downloads one and returns its path to the field that opened it.

WHY THE DOWNLOAD LOCATION IS A CONTROL RATHER THAN A CONSTANT. Checkpoints are large – the Toxoplasma models are 1.2 GB each – and on a shared workstation or a laptop with a small root volume the default is often the wrong disk. A lab that keeps models on a NAS wants them there once, not once per user. So the folder is on screen, remembered between openings, and shown before anything is fetched rather than discovered afterwards in a full-disk error.

NOTHING IS DOWNLOADED WITHOUT BEING ASKED FOR. Opening the dialog lists; the download happens on the button. That matters because the list is useful on its own – seeing that a model exists and what it was trained on is often the whole question – and because a dialog that starts a gigabyte transfer on open is one users learn not to open.

WHY THE LIST HAS FIVE HEADINGS RATHER THAN A BOOLEAN. It used to be one list with “show unvetted community uploads” beside it – a control that could fold away exactly one of the catalogue’s five origins. With ten models trained here, four stock Cellpose-SAM backbones, bioimage.io’s collection, the Cellpose 3 backend’s own four and a shared catalogue, a user who wanted the ten and not the rest had no way to say so. SourceStrip is the five origins as five clickable names, each one blue when its rows are on screen and muted when they are folded away, remembered between openings. The warning the boolean carried is unchanged and still arrives before the first unvetted row does – see ModelZooPicker._may_show_source().

Classes

BackendInstallDialog

Install, or uninstall, one segmentation backend, with progress and

ModelZooPicker

Pick a model from the zoo; returns a local path.

SourceStrip

The five source headings, their state, and where that state is kept.

Functions

choose_model(→ Optional[str])

Open the picker and return the chosen path, or None.

community_guard(owner)

A SourceStrip guard that warns once about community uploads.

confirm_community_uploads(→ bool)

Say what an unvetted upload is, and ask whether to show them anyway.

install_backend(→ bool)

Open the install dialog for one backend. True when it is ready after.

install_backend_package(→ bool)

Install the backend a zoo row needs. True when it is ready after.

remembered_model_dir(→ str)

The folder the user last downloaded into, or the default.

remembered_sources(→ tuple)

Which source headings this user last left on.

uninstall_backend(→ bool)

Open the uninstall dialog for one backend. True when it was removed.

Module Contents

class spacr.qt.widgets.model_zoo_picker.BackendInstallDialog(name: str, parent: PySide6.QtWidgets.QWidget | None = None, *, uninstall: bool = False, job=None, reinstall: bool = False, why: str = '')[source]

Bases: PySide6.QtWidgets.QDialog

Install, or uninstall, one segmentation backend, with progress and Cancel.

WHAT IT CHANGES, SAID BEFORE IT CHANGES IT. A backend installs into an environment of its own under ~/.spacr/backends; spaCR’s own environment is never touched, so nothing here can stop spaCR starting. The dialog says where it goes, what it downloads, how large it is and under what licence before Install is pressed.

THE WINDOW KEEPS RESPONDING. The install – a venv, then pip, often for minutes – runs on a worker thread; the dialog shows which step it is on and pip’s latest line, and Cancel stops pip and everything it started and removes the half-built environment. A failure shows the failing command’s own output, verbatim.

Parameters:
  • name – the backend, e.g. 'cellpose3'.

  • parent – the widget that opened it; the dialog’s parent is its window.

  • uninstall – remove the backend’s environment instead.

  • job – job(progress=..., cancel=...); the real install or uninstall when None. Tests pass their own.

  • reinstall – build an installed backend’s environment again (item 518), for a backend installed before a package it now needs was pinned; the dialog says so and its button says Reinstall.

  • why – a sentence saying why the install is offered, shown first in the description.

Variables:

error – the last failure’s message, verbatim; empty until one.

THE SCREEN BEHIND IT CAN FOLLOW IT. job_started, job_progressed, job_failed and job_cancelled tell the widget that opened the dialog what the install is doing, so a button can say “installing” while it runs and a console can say why it failed after the dialog has gone.

IT BELONGS TO THE WINDOW, NOT THE WIDGET THAT ASKED (item 521). A dialog inherits the style sheet of every widget above it, and Plaque Assay asks from its preview, whose own scale slider re-states the application sheet at that preview’s scale: at 150 % Install and Cancel were 59 px tall, not the 40 px of every other button. Parented to parent.window() it is themed like every other dialog and still centred on, and modal to, the window that opened it.

THE BAR SITS ON THE BUTTONS. The progress line is the last thing above the buttons and the status keeps four lines’ room while a job runs, so the bar does not move as the status line grows and shrinks.

Describe the backend and wait for the button.

closeEvent(event)[source]

Closing the window is Cancel; it never leaves a thread behind.

Parameters:

event – the close event; while a job is running it is ignored and reject() is called instead, otherwise it is passed on to the base class.

reject() → None[source]

Cancel a running install; close once it has stopped.

start() → None[source]

Start the job on a worker thread.

property running: bool[source]

Whether the install or uninstall is in progress.

class spacr.qt.widgets.model_zoo_picker.ModelZooPicker(kinds: tuple | None = None, parent: PySide6.QtWidgets.QWidget | None = None)[source]

Bases: PySide6.QtWidgets.QDialog

Pick a model from the zoo; returns a local path.

Parameters:
  • kinds – restrict the list to these spacr.model_zoo.KINDS. A pathogen-model field wants ("cellpose",) – offering a detector there would be offering something that cannot be loaded.

  • parent – the widget that opened this.

Build the model zoo dialog.

Parameters:
  • kinds – restrict the listing to these model kinds; None lists everything spaCR knows about.

  • parent – parent widget, or None.

chosen_path() → str | None[source]

The path the user accepted, or None if they cancelled.

closeEvent(event)[source]

Join the download before the dialog goes away.

Parameters:

event – the close event; passed on to the base class after any download is stopped.

done(result: int) → None[source]

Retire catalogue callbacks and probe polling on every dialog exit.

Parameters:

result – dialog result passed unchanged to Qt.

A network request may still be running. Its thread is retained by the shared drain mechanism until it finishes. Retiring catalogue work never waits for HTTP, and discarded results cannot refresh this dialog.

refresh() → None[source]

Reload the catalogue and redraw the table.

Answers from the shared catalogue’s cache rather than the network – see _warm_the_community_catalogue().

reject() → None[source]

Cancel closes the dialog; it must not leave a thread behind.

selected_entry()[source]

The catalogue entry on the highlighted row, or None.

class spacr.qt.widgets.model_zoo_picker.SourceStrip(parent: PySide6.QtWidgets.QWidget | None = None, guard=None)[source]

Bases: PySide6.QtWidgets.QWidget

The five source headings, their state, and where that state is kept.

Replaces the single “show unvetted community uploads” checkbox. The catalogue has five origins and the checkbox could fold away exactly one of them; a user who wants the ten models trained here, and not bioimage.io’s collection, had no way to say so.

The strip owns the preference and nothing else: which rows a table then shows is the table’s business, reached through changed. That is what lets the picker, the Model Zoo page and Make Masks agree about what is on without sharing a widget.

Parameters:
  • parent – the widget that owns it.

  • guard – guard(name) -> bool, consulted before a heading is turned ON. Returning False leaves it off – it is how the community warning refuses. None allows everything.

Build the five headings in the state this user left them.

enabled() → tuple[source]

The headings that are on, in ZOO_SOURCES order.

heading(name: str) → _SourceHeading[source]

The label for one source, for a test or a tooltip retarget.

Parameters:

name – a source name from spacr.model_zoo.ZOO_SOURCES; converted to str. An unknown name raises KeyError.

is_on(name: str) → bool[source]

Whether one heading is on.

Parameters:

name – a source name from spacr.model_zoo.ZOO_SOURCES; converted to str, and an unknown name gives False.

set_on(name: str, on: bool) → bool[source]

Turn one heading on or off, asking _guard first.

Parameters:
  • name – the heading.

  • on – the state wanted.

Returns:

the state it actually ended in.

spacr.qt.widgets.model_zoo_picker.choose_model(parent: PySide6.QtWidgets.QWidget | None = None, kinds: tuple | None = None) → str | None[source]

Open the picker and return the chosen path, or None.

The one-call form for a settings row’s trailing button:

path = choose_model(self, kinds=("cellpose",))
if path:
    field.setText(path)
Parameters:
  • parent – the widget opening the dialog.

  • kinds – restrict to these model kinds.

Returns:

a local filesystem path, or None when cancelled.

spacr.qt.widgets.model_zoo_picker.community_guard(owner)[source]

A SourceStrip guard that warns once about community uploads.

Shared by the picker and the Model Zoo page so the two say the same thing, once each, rather than one of them quietly listing unvetted rows. The “once” is per window, which is what the checkbox did.

Parameters:

owner – the widget the warning belongs to; it carries the flag.

spacr.qt.widgets.model_zoo_picker.confirm_community_uploads(parent) → bool[source]

Say what an unvetted upload is, and ask whether to show them anyway.

The words are the retired checkbox’s own, unchanged. The control that carried them was what was wrong; the sentence was not. It is said rather than merely labelled because the difference between a reviewed model and an unreviewed one is not visible in a table.

Parameters:

parent – the widget the dialog belongs to.

Returns:

True when the user said to show them.

spacr.qt.widgets.model_zoo_picker.install_backend(parent, name: str, *, watch=None, reinstall: bool = False, why: str = '') → bool[source]

Open the install dialog for one backend. True when it is ready after.

Shared by the Model Zoo screen, the Model Zoo button, the Make Masks Mode box and Plaque Assay’s Figure mode, so the places that can start an install say the same thing about it and run the same install.

Parameters:
  • parent – the widget asking.

  • name – the backend.

  • watch – watch(dialog), called before the dialog opens, so the caller can connect to its job_* signals and follow the install.

  • reinstall – build an installed backend again (item 518).

  • why – a sentence saying why it is offered, shown in the dialog.

spacr.qt.widgets.model_zoo_picker.install_backend_package(parent, entry) → bool[source]

Install the backend a zoo row needs. True when it is ready after.

Parameters:
  • parent – the widget asking.

  • entry – a backend row, or a cellpose3 model row.

spacr.qt.widgets.model_zoo_picker.remembered_model_dir() → str[source]

The folder the user last downloaded into, or the default.

Reading through QSettings rather than holding it on the dialog: the next model is usually wanted in the same place as the last one, and that is true across sessions, not only within one.

spacr.qt.widgets.model_zoo_picker.remembered_sources() → tuple[source]

Which source headings this user last left on.

Through QSettings for the same reason the download folder is – the headings a user folds away stay folded away tomorrow, not only for the rest of this dialog. Read here rather than held on the dialog so the Make Masks Mode box and the Model Zoo page answer from the same preference without owning a copy of it.

Returns:

names from spacr.model_zoo.ZOO_SOURCES, in that order.

spacr.qt.widgets.model_zoo_picker.uninstall_backend(parent, name: str) → bool[source]

Open the uninstall dialog for one backend. True when it was removed.

Parameters:
  • parent – the widget asking.

  • name – the backend.