spacr.qt.widgets.plaque_preview

Plaque Assay’s live preview, in its two modes, and the switch between them.

Plaque Assay reads two kinds of folder, and the Mask preview it used to borrow fitted neither:

  • Plaque mode – a folder of cropped plaque images. The run segments every image and writes one table of per-image values and one of per-plaque values. All there is to check before running is the mask, so the preview segments one image with the model and thresholds the run will use and draws the plaque outlines, with the count and mean area.

  • Figure mode – a folder of published figures. The run finds the plaque images inside each figure with a detector, reads the text printed around them, decides which condition each one shows, and segments each crop. The preview does every one of those steps on one figure and shows them: the boxes, the text that was read, the proposed condition per image, and the plaque outlines inside each box. The table under it is where a person corrects a condition and ticks it OK; saving writes figure_annotations.csv beside the figures, which the run reads.

A missing legend is asked for here rather than at the terminal: when a panel letter was read and no legend is known for the figure, a paste box appears, and a pasted legend is stored in legends.csv beside the figures so the run keys the same passages.

The detector and the text reader are the spacr[papers] extra. Without them Figure mode says so, with the command that installs them, instead of failing.

Everything that takes time runs on a JobRunner worker, and the pure pieces below the widgets take their heavy callables as parameters so they can be tested without a model.

Attributes

AUTOMATIC_BOX_THICKNESS

pick one from the figure's size.

IMAGE_TABS

The views of the plaque picture, the ones Mask generation's live preview

OVERLAY_STYLE_KEY

Where the style is remembered between sessions, in the preferences store

Classes

ContributeDialog

Annotate images for spaCR's community training data, then send them.

OverlayStyle

How the segmented plaques and the detected wells are drawn.

PaperDialog

Ask which paper to fetch, and where its folder goes.

PlaqueModeSwitch

A two-button Plaque | Figure switch.

PlaqueOverlayDialog

How the plaques are drawn: outlines or a filled overlay, and in what.

PlaquePreviewPanel

Plaque Assay's live preview, in Plaque mode or Figure mode.

PlaqueSettingsDialog

The Plaque Assay preview's settings: a Figure tab and a Plaque detection tab.

Functions

annotate_figure(→ List[Any])

Propose a condition per image, with any saved review applied.

ask_input_mode(→ Optional[str])

Ask input_mode_box()'s question and return the answer.

box_thickness_for(→ int)

The line weight the well boxes are drawn with, in image pixels.

boxed_picture(, selected, box_thickness)

rgb as a picture, with the numbered well boxes painted on it.

build_plaque_preview_card(host)

Build the Plaque Assay Live preview card and panel, unplaced.

check_the_src(→ Optional[str])

Ask about the mode for a new src when it holds the other mode's input.

choose_plaque_mode(→ None)

Put Plaque Assay in mode the way its switch does.

detect_figure(→ Dict[str, Any])

Figure mode's Run preview: find the plaque wells and read the text.

detector_choices(→ List[str])

What the detector box offers: the zoo's plaque-image detectors.

figure_pass(→ Dict[str, Any])

Figure mode on one figure: find, read and segment, as the run does.

follow_the_input(→ Optional[str])

Ask about the mode when the input is for the other one, and switch.

images_in(→ List[pathlib.Path])

The images directly inside src, as the run lists them.

input_mode_box(→ PySide6.QtWidgets.QMessageBox)

The dialog that asks input_mode_question()'s question.

input_mode_question(→ str)

Which question, if any, what was found asks about the mode.

install_plaque_mode(→ Optional[PlaqueModeSwitch])

Put the Plaque | Figure switch at the top of the settings and bind it.

keys_hidden_in(→ Tuple[str, ...])

The settings that do not apply in mode and come off the form.

load_display_image(→ numpy.ndarray)

One image as H x W x 3 uint8 RGB, whatever it was stored as.

load_overlay_style(→ OverlayStyle)

The style remembered from the last session.

missing_papers_packages(→ List[str])

The spacr[papers] packages this environment cannot import.

normalise_mode(→ str)

The mode a setting value names, 'plaque' for anything unknown.

object_palette(→ Tuple[numpy.ndarray, numpy.ndarray])

The object ids in a label image and one distinct colour for each.

outline_labels() → numpy.ndarray)

Draw the boundary of every labelled object onto an image.

overlay_colour(→ Any)

A colour setting as 'random' or an (r, g, b) triple.

paper_folder_name(→ str)

The sub-folder a paper's figures are fetched into.

papers_install_message(→ str)

What Figure mode says when its optional packages are missing.

parse_sizes(→ Tuple[int, ...])

Detector inference sizes from a setting value.

plaque_model_choices(→ List[str])

What the plaque model box offers: zoo plaque models, then bundled.

plaque_pass(→ Dict[str, Any])

Plaque mode on one image: segment it and count what was found.

plaque_rows(→ List[Dict[str, Any]])

One row per plaque, with the per-plaque values the run writes.

prepare_figure_review(result, settings, *[, caption, ...])

Read review sidecars and infer rulers on a worker, without Qt access.

region_at(→ Optional[int])

Which box a point on the figure falls in.

remember_the_input(→ None)

Note that source was settled for mode, so writing it into

render_objects(→ Optional[numpy.ndarray])

The label image alone, one colour per object on black.

render_overlay() → numpy.ndarray)

Draw the labelled objects onto an image as outlines or a filled overlay.

resolve_detector(→ Tuple[str, str, Any])

The detector checkpoint a key names, found without a download.

resolve_plaque_model(→ Tuple[str, str, Any])

The checkpoint the plaque run would segment with, found without a download.

seed_well_boxes(→ List[Any])

The wells spaCR's own detector finds on one page, to start the boxes from.

segment_well(→ Dict[str, Any])

Find the plaques in one detected well of a figure.

session_style(→ OverlayStyle)

The style a new panel starts from.

store_overlay_style(→ None)

Remember style for the next session.

write_legend(→ pathlib.Path)

Store one figure's legend in legends.csv, keeping the others.

Module Contents

class spacr.qt.widgets.plaque_preview.ContributeDialog(mode: str, paths: Sequence[Any], *, seeder: Callable[[pathlib.Path], Any] | None = None, known: Dict[str, Any] | None = None, paper: Dict[str, Any] | None = None, upload: Callable[[pathlib.Path, str], str] | None = None, threaded: bool = True, parent: PySide6.QtWidgets.QWidget | None = None, target: str | None = None)[source]

Bases: PySide6.QtWidgets.QDialog

Annotate images for spaCR’s community training data, then send them.

Figure mode draws a box around every well on each page (YOLO labels for the well detector); Plaque mode paints every plaque as a mask (for the next plaque model). Each image starts from what spaCR itself finds, so the contributor corrects rather than starts from nothing. Upload stays off until every image in the list carries at least one box or plaque.

Parameters:
  • mode – 'figure' or 'plaque'.

  • paths – the images to annotate.

  • seeder – fn(path) -> boxes (figure) or fn(path) -> labels (plaque): spaCR’s own proposal, run off the GUI thread.

  • known – proposals already on screen, by path, so they are not computed twice.

  • paper – the source paper’s doi, title, pmcid, when the folder records one.

  • upload – fn(folder, target) -> url; the contributor’s own Hugging Face login (upload_with_own_login()) when None.

  • threaded – run the proposal and the upload off the GUI thread.

  • parent – the owning widget.

  • target – the community collection (community_repo()): "figures" in Figure mode, "plaques" in Plaque mode when None. Any other name sends the masks to einarolafsson/community_<name>.

Build the list, the editor area, the conscience and Upload.

Parameters:
  • mode – see the class docstring.

  • paths – see the class docstring.

  • seeder – see the class docstring.

  • known – see the class docstring.

  • paper – see the class docstring.

  • upload – see the class docstring.

  • threaded – see the class docstring.

  • parent – see the class docstring.

  • target – see the class docstring.

add_image(path: Any) → None[source]

Put one image in the list and start spaCR’s proposal for it.

Parameters:

path – the image.

count(path: Any) → int[source]

How many boxes or plaques path carries now.

Parameters:

path – the image.

editor(path: Any = None) → PySide6.QtWidgets.QWidget | None[source]

The editor of path (the current image when None).

Parameters:

path – the image.

remove_current() → None[source]

Take the current image out of the contribution.

upload(*_args: Any) → bool[source]

Check, ask for consent once, write the contribution and send it.

Returns:

True when an upload was started.

class spacr.qt.widgets.plaque_preview.OverlayStyle[source]

How the segmented plaques and the detected wells are drawn.

Changing it redraws what is already segmented; nothing is run again. Every width is in IMAGE pixels: the outlines are grown on the image array and the boxes are painted into the pixmap before it is shown, so a line keeps its share of the picture as the view is zoomed and in a saved picture, the way the outlines always did.

Parameters:
  • display – 'outlines' or 'fill'.

  • outline_colour – an (r, g, b) triple, or 'random' for one colour per object.

  • outline_thickness – outline width in pixels.

  • fill_colour – an (r, g, b) triple, or 'random'.

  • fill_opacity – fill opacity in percent, 0 to 100.

  • box_thickness – the line weight of the detector’s well boxes in pixels, or AUTOMATIC_BOX_THICKNESS for the width the preview always chose from the figure’s size (box_thickness_for()).

as_dict() → Dict[str, Any][source]

The style as plain values that survive a JSON round trip.

Returns:

{field: value} with colours as 'random' or a list of three ints.

classmethod from_dict(values: Any) → OverlayStyle[source]

A style from as_dict()’s values.

Parameters:

values – the mapping; keys it does not know are ignored.

Returns:

the normalised style, or the default when values cannot be read.

normalised() → OverlayStyle[source]

The same style with every value clamped to what can be drawn.

Returns:

a new OverlayStyle.

class spacr.qt.widgets.plaque_preview.PaperDialog(parent: PySide6.QtWidgets.QWidget | None = None, folder: str = '')[source]

Bases: PySide6.QtWidgets.QDialog

Ask which paper to fetch, and where its folder goes.

Parameters:
  • parent – the owning widget.

  • folder – the folder the paper’s own folder is made in.

Build the two fields.

Parameters:
  • parent – the owning widget.

  • folder – the starting parent folder.

values() → Tuple[str, str][source]

The reference and the parent folder, stripped.

Returns:

(reference, folder).

class spacr.qt.widgets.plaque_preview.PlaqueModeSwitch(parent: PySide6.QtWidgets.QWidget | None = None)[source]

Bases: PySide6.QtWidgets.QWidget

A two-button Plaque | Figure switch.

Parameters:

parent – the owning widget.

Build the two buttons, Plaque selected.

Parameters:

parent – the owning widget.

button(mode: str) → PySide6.QtWidgets.QToolButton[source]

The button for mode.

Parameters:

mode – 'plaque' or 'figure'.

Returns:

the button.

mode() → str[source]

The mode selected now.

set_mode(mode: Any) → None[source]

Select mode without announcing it.

Parameters:

mode – 'plaque' or 'figure'.

class spacr.qt.widgets.plaque_preview.PlaqueOverlayDialog(style: OverlayStyle, parent: PySide6.QtWidgets.QWidget | None = None)[source]

Bases: PySide6.QtWidgets.QDialog

How the plaques are drawn: outlines or a filled overlay, and in what.

Opened from a right-click on the preview image. Every change is applied at once to what is already segmented, so the window stays open beside the picture it changes; nothing is segmented again. The line weight of the well boxes lives here too, because it is remembered with the rest of the style. A QDialog, so spacr.qt.widgets.glass gives it the rounded, translucent card of the other settings windows.

Parameters:
  • style – the OverlayStyle to start from.

  • parent – the preview panel.

Lay the controls out.

Parameters:
  • style – the starting style.

  • parent – the owning widget.

overlay_style() → OverlayStyle[source]

The style the controls describe.

set_overlay_style(style: OverlayStyle) → None[source]

Show style without announcing it.

Parameters:

style – the style to show.

class spacr.qt.widgets.plaque_preview.PlaquePreviewPanel(parent: PySide6.QtWidgets.QWidget | None = None, *, threaded: bool = True)[source]

Bases: PySide6.QtWidgets.QWidget, spacr.qt.widgets.preview_contract.LivePreviewContract

Plaque Assay’s live preview, in Plaque mode or Figure mode.

The screen drives it through the same four calls every live preview answers: load_source_async(), apply_settings(), set_propagate_callback() and settings_for_propagation().

Parameters:
  • parent – the owning widget.

  • threaded – run passes on worker threads; False runs them inline, which is what tests use.

Build the controls; nothing is loaded or resolved here.

Parameters:
  • parent – the owning widget.

  • threaded – see the class docstring.

apply_settings(settings: Dict[str, Any]) → None[source]

Seed every control from the module’s settings.

Parameters:

settings – the form’s values.

closeEvent(event)[source]

Stop the workers with the panel.

Parameters:

event – the close event.

contribute_training_data(*, paths: Sequence[Any] | None = None, detect: Callable | None = None, segment: Callable | None = None, upload: Callable | None = None) → ContributeDialog | None[source]

Open the annotate-then-upload window for this mode.

Figure mode boxes every well for the YOLO well detector; Plaque mode paints every plaque for the next plaque model. What the preview has already found for the current image is the starting point; other images are proposed by the same detector or model.

Parameters:
  • paths – the images to start with; the current image when None.

  • detect – replaces the well detector (tests).

  • segment – replaces the plaque model (tests).

  • upload – replaces the Hugging Face upload (tests).

Returns:

the dialog, or None when there is no image to annotate.

current_path() → pathlib.Path | None[source]

The image selected in the picker.

current_settings() → Dict[str, Any][source]

The module’s settings with this panel’s values over them.

fetch_paper(reference: str, parent: Any, *, fetch: Callable | None = None, offer_install: bool = True) → bool[source]

Fetch a paper’s figures into parent/<paper>, off the GUI thread.

The figure legends are gathered automatically: spacr.plaque_papers.fetch_paper_to_folder() writes the figures and legends.csv, which this panel already reads. When it is done the form’s src is pointed at the new folder, so the figures load the way any folder does.

Parameters:
  • reference – a DOI, PMID, PMC id or PDF path.

  • parent – the folder the paper’s folder is made in.

  • fetch – replaces fetch_paper_to_folder (tests).

  • offer_install – offer the reader’s install when it is needed; False for the fetch that follows an install, so one offer is made per PDF however the install ends.

Returns:

True when the fetch was started, or when a PDF that needs the figure reader was answered with its install.

A PDF on disk is read by the figure reader, so when the reader is not installed, or was installed before it read PDFs, the install is offered here first and the PDF read once it is ready. A reader that says so only while reading gets the same offer when the fetch comes back (_on_paper_fetched()).

fetch_papers(pdfs: Sequence[Any], parent: Any = None, *, fetch: Callable | None = None, offer_install: bool = True) → bool[source]

Read several PDFs, one after another, off the GUI thread.

Each paper’s figures go into a folder of its own, parent/<paper>, and when the last is read src is pointed at parent, which Figure mode’s preview and run read paper by paper. The status line says which paper of how many is being read; a PDF that cannot be read is reported by name and the others are read all the same.

Parameters:
  • pdfs – the PDF paths, in reading order.

  • parent – the folder the papers’ folders are made in; the first PDF’s folder when None.

  • fetch – replaces fetch_paper_to_folder (tests).

  • offer_install – offer the figure reader’s install first when it is needed.

Returns:

True when the reading was started, or answered with the reader’s install offer.

find_plaques_in_all_wells(*, segment: Callable | None = None) → bool[source]

Find the plaques in every detected well, one after another.

Parameters:

segment – replaces the plaque model (tests).

Returns:

True when a pass was started.

load_source_async(source: Any, **_ignored: Any) → bool[source]

List the images in source off the GUI thread and show the first.

Parameters:

source – the source folder, or one image.

Returns:

True when a listing was started.

mode() → str[source]

The mode the panel is in.

open_overlay_settings() → PlaqueOverlayDialog[source]

Open (or raise) the overlay settings, applied live.

Non-modal, because what it answers is how the picture beside it looks.

Returns:

the dialog, shown.

open_settings(tab: str | None = None) → PlaqueSettingsDialog[source]

Open (or raise) the one settings window, in the tab for this mode.

One settings button serves the whole live preview, with a tab for figure detection and one for plaque detection. A QDialog, so spacr.qt.widgets.glass gives it the same rounded, translucent card every other settings window has.

Parameters:

tab – 'figure' or 'plaque' to open on; the mode’s own first tab when None.

Returns:

the dialog.

overlay_menu() → PySide6.QtWidgets.QMenu[source]

The right-click menu of the preview images.

Returns:

a menu with Outlines / Filled overlay, a random-colour toggle for whichever is shown, and the full overlay settings, then Save picture. On the masks, flows and cell probability views, which carry no outline, only Save picture.

overlay_style() → OverlayStyle[source]

How the plaques are drawn now.

plaque_table_rows() → List[Dict[str, Any]][source]

Every plaque found so far, with the well it is in.

The ratio to the panel median is taken over every segmented well of the same panel, as the run’s area_vs_panel_median is.

Returns:

dicts, one per plaque, well by well.

preview_running() → bool[source]

Whether a pass still owns a worker, including after Cancel.

preview_selected_well(*, segment: Callable | None = None) → bool[source]

Find the plaques in the highlighted well, off the GUI thread.

Parameters:

segment – replaces the plaque model (tests).

Returns:

True when a pass was started.

propagate() → None[source]

Write the tuned values into the module’s settings.

ruler_active() → bool[source]

Whether the Ruler button is down.

ruler_microns_per_pixel() → float | None[source]

The pixel size the ruler measures microns with, or None.

In Figure mode it is the highlighted well’s resolved scale: the value typed into its Wells row, else the settings’ Pixels per µm, else a scale bar or whole well the run found. In Plaque mode it is the settings’ Pixels per µm. None means the ruler reports pixels only, and the note beside the Ruler button says so.

Returns:

microns per image pixel, or None when no size is known.

run_preview(*_args: Any, detect: Callable | None = None, read_text: Callable | None = None, segment: Callable | None = None) → bool[source]

Run the selected mode on the selected image, off the GUI thread.

Parameters:
  • detect – replaces the detector (tests).

  • read_text – replaces the text reader (tests).

  • segment – replaces the plaque model (tests); Plaque mode only, Figure mode segments per well.

Returns:

True when a pass was started.

save_annotations() → pathlib.Path | None[source]

Write the review to figure_annotations.csv, keeping other figures’.

Returns:

destination of the queued write, or None when not started. Completion or failure is reported in the preview status.

save_picture(path: str | None = None, view: _ImageView | None = None) → str | None[source]

Write a preview picture as it is drawn, at its native size.

The plaque outlines and the well boxes are part of the picture’s pixels, so the saved file carries the chosen line weights and colours; the ruler’s line is not saved.

Parameters:
  • path – where to write; None asks.

  • view – the picture to save; None means the one last right-clicked, else the view shown in the image pane.

Returns:

the path written, or None when nothing was written.

select_well(index: int, *, from_table: bool = False) → None[source]

Highlight one well: its box, its row, and its crop on the right.

Parameters:
  • index – the well, 0-based in reading order.

  • from_table – True when the Wells table asked, so its selection is left as the user made it.

selected_well() → int | None[source]

The index of the highlighted well, or None.

set_mode(mode: Any) → None[source]

Show the controls mode needs, without announcing the change.

The source is listed again when it was listed for the other mode: the two modes list a folder differently (Figure mode reads a folder of paper folders paper by paper), so a figure folder chosen in Plaque mode would otherwise stay “No images found” after the switch.

Parameters:

mode – 'plaque' or 'figure'.

set_overlay_style(style: OverlayStyle) → None[source]

Draw the plaques another way, from what is already segmented.

The style is kept for the rest of the session, so a panel built later starts from it, and remembered for the next session in the preferences store.

Parameters:

style – the new OverlayStyle.

set_preview_busy(busy: bool) → None[source]

Keep rerun controls disabled until cancelled inference has exited.

Parameters:

busy – requested busy state; active preview jobs also keep controls disabled until their workers retire.

Returns:

None.

set_propagate_callback(callback) → None[source]

Where propagate() sends the tuned values.

Parameters:

callback – fn(dict).

settings_for_propagation() → Dict[str, Any][source]

The values to write back into the form, in its own names.

A model the panel only seeded is not written back: the form already holds it, and writing a resolved path over a zoo key would change what a recorded run says it asked for.

Returns:

setting name -> value.

shutdown() → None[source]

Leave no worker thread behind.

table_rows() → List[Dict[str, Any]][source]

The review as spacr.plaque_papers.write_annotation_overrides() rows.

text_options()[source]

The spacr.plaque_papers.TextOptions the controls describe.

text_values() → Dict[str, Any][source]

The Text detection controls as text_* settings.

Returns:

setting name -> value, in the form’s own types.

views() → spacr.qt.widgets.segmentation_views.SegmentationViews[source]

The four views of the preview picture.

class spacr.qt.widgets.plaque_preview.PlaqueSettingsDialog(panel: PlaquePreviewPanel)[source]

Bases: PySide6.QtWidgets.QDialog

The Plaque Assay preview’s settings: a Figure tab and a Plaque detection tab.

The controls belong to the panel and are lent to this window while it is open, so a value set here is the value the next pass uses, and it survives the window being closed – give_back() returns them.

In Plaque mode the Figure tab is hidden: nothing there applies to a folder of cropped plaque images.

Parameters:

panel – the PlaquePreviewPanel whose controls it shows.

Lay the panel’s controls out in two tabs.

Parameters:

panel – the preview panel; also the window’s parent.

give_back() → None[source]

Return every lent control to the panel, hidden, values intact.

show_mode(mode: Any, tab: str | None = None) → None[source]

Show the tabs mode uses and open the right one.

Parameters:
  • mode – 'plaque' or 'figure'.

  • tab – 'figure', 'text' or 'plaque' to open on.

spacr.qt.widgets.plaque_preview.annotate_figure(result: Dict[str, Any], caption: str, src: Any, *, confirm: bool, options: Any = None) → List[Any][source]

Propose a condition per image, with any saved review applied.

Parameters:
  • result – a figure_pass() result.

  • caption – the figure’s legend, '' when unknown.

  • src – the figure folder, where figure_annotations.csv lives.

  • confirm – confirm_annotations. When on, an image nobody has approved starts unticked; when off it starts ticked, because the run measures it.

  • options – a spacr.plaque_papers.TextOptions – the Text detection settings; the defaults when None.

Returns:

spacr.plaque_papers.Annotation per region.

spacr.qt.widgets.plaque_preview.ask_input_mode(parent: Any, question: str, name: str, mode: Any, *, pdfs: int = 0, images: int = 0) → str | None[source]

Ask input_mode_box()’s question and return the answer.

Returns:

the mode to read the input in, or None to leave it unread. Closing a switch question keeps the mode it is in; closing the PDFs-or-images question reads neither.

spacr.qt.widgets.plaque_preview.box_thickness_for(width: int, height: int, weight: int = AUTOMATIC_BOX_THICKNESS) → int[source]

The line weight the well boxes are drawn with, in image pixels.

Parameters:
  • width – the figure’s width in pixels.

  • height – its height.

  • weight – the chosen weight; AUTOMATIC_BOX_THICKNESS picks one from the figure’s size, at least 2 px and one more for every 400 px of its longer side, which is what the preview always drew.

Returns:

a whole number of pixels, 1 or more.

spacr.qt.widgets.plaque_preview.boxed_picture(rgb: numpy.ndarray, boxes: Sequence[Tuple[Any, bool]] = (), selected: int | None = None, box_thickness: int = AUTOMATIC_BOX_THICKNESS) → PySide6.QtGui.QPixmap[source]

rgb as a picture, with the numbered well boxes painted on it.

Parameters:
  • rgb – H x W x 3 uint8.

  • boxes – (region, approved) pairs, numbered from 1.

  • selected – the index of the box to highlight.

  • box_thickness – the boxes’ line weight in image pixels, or AUTOMATIC_BOX_THICKNESS; see box_thickness_for(). The highlighted box is drawn twice as wide.

Returns:

the picture, at the image’s own size.

spacr.qt.widgets.plaque_preview.build_plaque_preview_card(host: Any)[source]

Build the Plaque Assay Live preview card and panel, unplaced.

Parameters:

host – the screen.

Returns:

(panel, card).

spacr.qt.widgets.plaque_preview.check_the_src(screen: Any, source: str) → str | None[source]

Ask about the mode for a new src when it holds the other mode’s input.

Asked once per source and mode, and only while the screen is on screen. A src that names a PDF, or a folder of PDFs, in Figure mode – already, or after the answer switched to it – has every PDF read the way dropped ones are, so the preview and the run get the paper’s figure folder rather than a PDF they cannot open.

Parameters:
  • screen – the Plaque Assay screen.

  • source – src as the form holds it.

Returns:

the question asked, or ''.

spacr.qt.widgets.plaque_preview.choose_plaque_mode(screen: Any, mode: Any) → None[source]

Put Plaque Assay in mode the way its switch does.

Parameters:
  • screen – the Plaque Assay screen.

  • mode – 'plaque' or 'figure'.

spacr.qt.widgets.plaque_preview.detect_figure(path: Any, settings: Dict[str, Any], *, detect: Callable | None = None, read_text: Callable | None = None) → Dict[str, Any][source]

Figure mode’s Run preview: find the plaque wells and read the text.

Nothing is segmented here: Run preview detects the plaque wells, and a separate Plaque preview button segments the plaques of the highlighted row and well box (segment_well()).

Parameters:
  • path – the figure.

  • settings – the module’s settings.

  • detect – passed to spacr.plaque_papers.find_plaque_regions(); the zoo detector when None.

  • read_text – fn(path) -> [Word]; RapidOCR, followed by the enlarged second reading, when None.

Returns:

{'path', 'image', 'regions', 'words', 'words_source'}, or {'error', 'entry'}. A PDF’s text layer saved beside the figure (text_layer.json) is read before any OCR.

spacr.qt.widgets.plaque_preview.detector_choices(entries: Iterable[Any] | None = None) → List[str][source]

What the detector box offers: the zoo’s plaque-image detectors.

Parameters:

entries – zoo entries; the zoo’s own listing when None.

Returns:

zoo keys, newest first.

spacr.qt.widgets.plaque_preview.figure_pass(path: Any, settings: Dict[str, Any], *, detect: Callable | None = None, read_text: Callable | None = None, segment: Callable[[numpy.ndarray], numpy.ndarray] | None = None) → Dict[str, Any][source]

Figure mode on one figure: find, read and segment, as the run does.

The annotation itself is left to annotate_figure(), which is cheap and is repeated whenever a legend is pasted.

Parameters:
  • path – the figure.

  • settings – the module’s settings.

  • detect – passed to spacr.plaque_papers.find_plaque_regions(); the zoo detector when None.

  • read_text – fn(path) -> [Word]; RapidOCR, followed by the enlarged second reading, when None.

  • segment – fn(crop) -> labels; the run’s plaque model when None.

Returns:

{'path', 'overlay', 'regions', 'words', 'counts', 'mean_areas', 'note'}, or {'error', 'entry'}.

spacr.qt.widgets.plaque_preview.follow_the_input(screen: Any, pdfs: Sequence[Any], images: Sequence[Any], figures: Sequence[Any], name: str) → str | None[source]

Ask about the mode when the input is for the other one, and switch.

Used for a drop (spacr.qt.dnd_handlers.PlaqueDropHandler) and for a new src (_follow_the_src()).

Parameters:
  • screen – the Plaque Assay screen.

  • pdfs – PDFs found.

  • images – plaque images found.

  • figures – paper folders found.

  • name – what was dropped or found, as the person knows it.

Returns:

the mode the input is to be read in, now current, or None to leave it unread.

spacr.qt.widgets.plaque_preview.images_in(src: Any, papers: bool = False) → List[pathlib.Path][source]

The images directly inside src, as the run lists them.

Parameters:
Returns:

image paths sorted by name, folder by folder; empty when there are none.

spacr.qt.widgets.plaque_preview.input_mode_box(parent: Any, question: str, name: str, mode: Any, *, pdfs: int = 0, images: int = 0) → PySide6.QtWidgets.QMessageBox[source]

The dialog that asks input_mode_question()’s question.

A QMessageBox, so it wears the same glass card as every other dialog spaCR opens. Each answer button carries the mode it chooses in its plaque_mode property; Cancel carries ''.

Parameters:
  • parent – the screen.

  • question – TO_FIGURE, TO_PLAQUE or MIXED.

  • name – what was dropped or found, as the person knows it.

  • mode – the mode Plaque Assay is in.

  • pdfs – how many PDFs or paper folders were found.

  • images – how many images were found.

Returns:

the dialog, not yet shown.

spacr.qt.widgets.plaque_preview.input_mode_question(pdfs: Sequence[Any], images: Sequence[Any], figures: Sequence[Any], mode: Any) → str[source]

Which question, if any, what was found asks about the mode.

PDFs are read in Figure mode and plaque images in Plaque mode, so input for the other mode asks to switch, and input for both asks which to read.

Parameters:
  • pdfs – PDFs found.

  • images – images found outside a figure folder.

  • figures – folders a paper was fetched into (they hold its paper.json, legends.csv or text_layer.json).

  • mode – the mode Plaque Assay is in.

Returns:

TO_FIGURE, TO_PLAQUE, MIXED, or '' when the input fits the mode.

spacr.qt.widgets.plaque_preview.install_plaque_mode(screen: Any) → PlaqueModeSwitch | None[source]

Put the Plaque | Figure switch at the top of the settings and bind it.

The form’s plaque_mode control is the one source of truth. Both switches – this one and the preview’s – write it, and follow it when something else changes it, such as a loaded settings file. Its row is hidden, because the switch speaks for it, and so are the settings the other mode does not read.

Parameters:

screen – the Plaque Assay screen.

Returns:

the switch, or None when the screen has no settings column.

spacr.qt.widgets.plaque_preview.keys_hidden_in(mode: Any) → Tuple[str, ...][source]

The settings that do not apply in mode and come off the form.

Parameters:

mode – the plaque mode.

Returns:

setting keys.

spacr.qt.widgets.plaque_preview.load_display_image(path: Any) → numpy.ndarray[source]

One image as H x W x 3 uint8 RGB, whatever it was stored as.

Parameters:

path – the image file.

Returns:

the pixels.

spacr.qt.widgets.plaque_preview.load_overlay_style() → OverlayStyle[source]

The style remembered from the last session.

Returns:

the stored OverlayStyle, or the default when nothing was stored or the stored value cannot be read.

spacr.qt.widgets.plaque_preview.missing_papers_packages(importable: Callable[[str], bool] | None = None) → List[str][source]

The spacr[papers] packages this environment cannot import.

Asked with importlib.util.find_spec(), which does not import anything – importing ultralytics rewrites its settings file.

Parameters:

importable – fn(module) -> bool, for tests.

Returns:

display names of the missing packages, empty when all are here.

spacr.qt.widgets.plaque_preview.normalise_mode(value: Any) → str[source]

The mode a setting value names, 'plaque' for anything unknown.

Parameters:

value – 'plaque', 'figure', any case, or anything else.

Returns:

'plaque' or 'figure'.

spacr.qt.widgets.plaque_preview.object_palette(labels: numpy.ndarray) → Tuple[numpy.ndarray, numpy.ndarray][source]

The object ids in a label image and one distinct colour for each.

The palette is the Mask preview’s color (random) one (spacr.qt.widgets.live_preview._random_outline_palette()), so an object keeps its colour across the Overlay and Objects tabs and across a change of thickness or opacity.

Parameters:

labels – a label image, 0 = background.

Returns:

(ids, colours): sorted positive ids and an N x 3 uint8 array.

spacr.qt.widgets.plaque_preview.outline_labels(rgb: numpy.ndarray, labels: numpy.ndarray, colour: Tuple[int, int, int] = OUTLINE_COLOUR, offset: Tuple[int, int] = (0, 0)) → numpy.ndarray[source]

Draw the boundary of every labelled object onto an image.

Parameters:
  • rgb – H x W x 3 image; changed in place.

  • labels – a label image, 0 = background.

  • colour – the outline colour.

  • offset – (y, x) where labels sits inside rgb.

Returns:

rgb.

spacr.qt.widgets.plaque_preview.overlay_colour(value: Any, default: Any = OUTLINE_COLOUR) → Any[source]

A colour setting as 'random' or an (r, g, b) triple.

Parameters:
  • value – 'random', a #rrggbb string, a QColor or a triple.

  • default – what an unreadable value means.

Returns:

'random' or a tuple of three ints in 0..255.

spacr.qt.widgets.plaque_preview.paper_folder_name(reference: Any) → str[source]

The sub-folder a paper’s figures are fetched into.

Parameters:

reference – a DOI, PMID, PMC id or PDF path.

Returns:

a name safe on every file system: a PDF’s stem, or the reference with every character that is not a letter, digit, dot or dash turned into _.

spacr.qt.widgets.plaque_preview.papers_install_message(missing: Sequence[str]) → str[source]

What Figure mode says when its optional packages are missing.

Parameters:

missing – names from missing_papers_packages().

Returns:

one paragraph with the install command.

spacr.qt.widgets.plaque_preview.parse_sizes(value: Any) → Tuple[int, ...][source]

Detector inference sizes from a setting value.

Parameters:

value – '640,1280', a list of numbers, or one number.

Returns:

the positive sizes, in order; the defaults when none parse.

spacr.qt.widgets.plaque_preview.plaque_model_choices(entries: Iterable[Any] | None = None) → List[str][source]

What the plaque model box offers: zoo plaque models, then bundled.

Parameters:

entries – zoo entries; the zoo’s own listing when None.

Returns:

setting values, newest zoo model first.

spacr.qt.widgets.plaque_preview.plaque_pass(path: Any, settings: Dict[str, Any], *, segment: Callable[[pathlib.Path], numpy.ndarray] | None = None) → Dict[str, Any][source]

Plaque mode on one image: segment it and count what was found.

Runs on a worker thread; touches no widget.

Parameters:
  • path – the image.

  • settings – the module’s settings.

  • segment – fn(path) -> labels or fn(path) -> (labels, flows) with flows as spacr.plaque.plaque_flow_outputs() gives it; the run’s model, with its flows, when None.

Returns:

{'path', 'image', 'labels', 'overlay', 'flow_rgb', 'cellprob', 'count', 'mean_area', 'areas', 'note'}, or {'error', 'entry'} when the model cannot be used. flow_rgb and cellprob are None when the segmenter gave no flows.

spacr.qt.widgets.plaque_preview.plaque_rows(labels: numpy.ndarray) → List[Dict[str, Any]][source]

One row per plaque, with the per-plaque values the run writes.

The columns of the run’s per_plaque table (spacr.submodules.analyze_plaques()), with the ratio taken to the median plaque in this well. The ratio to the panel median needs every well of the panel and is added by the caller.

Parameters:

labels – a label image, 0 = background.

Returns:

dicts with plaque_id, area_px, area_vs_well_median, perimeter_px, equivalent_diameter_px, eccentricity, solidity, centroid_y and centroid_x.

spacr.qt.widgets.plaque_preview.prepare_figure_review(result, settings, *, caption=None, previous=())[source]

Read review sidecars and infer rulers on a worker, without Qt access.

Parameters:
  • result – detected figure including image, regions, words and path.

  • settings – snapshot of preview settings.

  • caption – supplied legend; None reads legends.csv beside the image.

  • previous – optional snapshot of current annotations, preserving manual calibration, condition edits and approval during reannotation.

Returns:

result copy with review_caption, annotations and automatic_scales.

spacr.qt.widgets.plaque_preview.region_at(regions: Sequence[Any], x: float, y: float) → int | None[source]

Which box a point on the figure falls in.

Parameters:
  • regions – the detected wells.

  • x – figure column.

  • y – figure row.

Returns:

the index of the smallest box holding the point, or None.

spacr.qt.widgets.plaque_preview.remember_the_input(screen: Any, source: Any, mode: Any = None) → None[source]

Note that source was settled for mode, so writing it into src does not ask again.

Parameters:
  • screen – the Plaque Assay screen.

  • source – the folder or file.

  • mode – the mode it was settled for; the current one when None.

spacr.qt.widgets.plaque_preview.render_objects(labels: numpy.ndarray | None) → numpy.ndarray | None[source]

The label image alone, one colour per object on black.

Drawn by spacr.qt.widgets.segmentation_views.render_labels(), so a plaque mask has the colours a Mask generation mask has.

Parameters:

labels – a label image, 0 = background, or None.

Returns:

H x W x 3 uint8, or None when there is nothing to draw.

spacr.qt.widgets.plaque_preview.render_overlay(rgb: numpy.ndarray, labels: numpy.ndarray, style: OverlayStyle | None = None, offset: Tuple[int, int] = (0, 0)) → numpy.ndarray[source]

Draw the labelled objects onto an image as outlines or a filled overlay.

Parameters:
  • rgb – H x W x 3 uint8 image; changed in place.

  • labels – a label image, 0 = background.

  • style – the OverlayStyle; yellow one-pixel outlines when None, which is what the preview always drew.

  • offset – (y, x) where labels sits inside rgb.

Returns:

rgb.

spacr.qt.widgets.plaque_preview.resolve_detector(key: Any, src: Any = None) → Tuple[str, str, Any][source]

The detector checkpoint a key names, found without a download.

Looks where the run looks: the path itself, the zoo entry’s own path, ~/.spacr/models and the run’s model cache under <src>/plaque_figures/models.

Parameters:
  • key – a zoo key or a checkpoint path.

  • src – the figure folder.

Returns:

(path, note, entry); path is '' when it is not here, and entry is what a download would fetch.

spacr.qt.widgets.plaque_preview.resolve_plaque_model(settings: Dict[str, Any]) → Tuple[str, str, Any][source]

The checkpoint the plaque run would segment with, found without a download.

The run’s own resolver answers (spacr.submodules._resolve_plaque_model() with fetch=False), so the preview cannot drift from it.

Parameters:

settings – the module’s settings.

Returns:

(path, note, entry): the path, or '' when it is not on this machine; a sentence to show; and the zoo entry that a download would fetch, when there is one.

spacr.qt.widgets.plaque_preview.seed_well_boxes(path: Any, settings: Dict[str, Any], *, detect: Callable | None = None) → List[Any][source]

The wells spaCR’s own detector finds on one page, to start the boxes from.

Parameters:
  • path – the figure page.

  • settings – the module’s settings (detector, sizes, confidence).

  • detect – replaces the detector (tests).

Returns:

the regions, with x0, y0, x1, y1.

spacr.qt.widgets.plaque_preview.segment_well(image: numpy.ndarray, region: Any, settings: Dict[str, Any], *, segment: Callable[[numpy.ndarray], numpy.ndarray] | None = None) → Dict[str, Any][source]

Find the plaques in one detected well of a figure.

Runs on a worker thread; touches no widget. The model and its thresholds are the Plaque settings, through the same spacr.plaque.segment_plaque_image() Plaque mode uses, except the diameter: the crop is segmented at the model’s own scale (_at_figure_scale()).

Parameters:
  • image – the figure, H x W x 3.

  • region – the well’s box.

  • settings – the module’s settings.

  • segment – fn(crop) -> labels or fn(crop) -> (labels, flows) with flows as spacr.plaque.plaque_flow_outputs() gives it; the plaque model, with its flows, when None.

Returns:

{'labels', 'flow_rgb', 'cellprob', 'rows', 'count', 'mean_area', 'note'}, or {'error', 'entry'}. flow_rgb and cellprob are None when the segmenter gave no flows.

spacr.qt.widgets.plaque_preview.session_style() → OverlayStyle[source]

The style a new panel starts from.

Returns:

the style this session last chose, else the one remembered from the last session, else the default.

spacr.qt.widgets.plaque_preview.store_overlay_style(style: OverlayStyle) → None[source]

Remember style for the next session.

Parameters:

style – the style to keep.

spacr.qt.widgets.plaque_preview.write_legend(path: Any, stem: str, legend: str) → pathlib.Path[source]

Store one figure’s legend in legends.csv, keeping the others.

Parameters:
  • path – the CSV (file and legend columns).

  • stem – the figure’s file stem.

  • legend – the legend text.

Returns:

the path written.

spacr.qt.widgets.plaque_preview.AUTOMATIC_BOX_THICKNESS = 0[source]

pick one from the figure’s size.

Type:

The box weight that means

spacr.qt.widgets.plaque_preview.IMAGE_TABS[source]

The views of the plaque picture, the ones Mask generation’s live preview offers: spacr.qt.widgets.segmentation_views.VIEWS.

spacr.qt.widgets.plaque_preview.OVERLAY_STYLE_KEY = 'plaque_preview/overlay_style'[source]

Where the style is remembered between sessions, in the preferences store the rest of the GUI keeps its choices in (spacr.qt.preferences._settings()).

Nested helpers

ContributeDialog.add_image.work(p: Path = path) → Any

spaCR’s proposal for one image, or the reason there is none.

spacr/qt/widgets/plaque_preview.py:2951

PlaquePreviewPanel._follow_reader_install.cancelled() → None

Say that nothing was installed and nothing was left.

spacr/qt/widgets/plaque_preview.py:4724

PlaquePreviewPanel._follow_reader_install.failure(message: str) → None

Say why, in the installer’s own words.

spacr/qt/widgets/plaque_preview.py:4717

PlaquePreviewPanel._follow_reader_install.progressed(text: str) → None

One line, rewritten, saying which step the install is on.

spacr/qt/widgets/plaque_preview.py:4712

PlaquePreviewPanel._next_paper.job() → Dict[str, Any]

Read one PDF, turning its failure into an answer.

spacr/qt/widgets/plaque_preview.py:5742

PlaquePreviewPanel._save_review_file.finished(result)

Ignore stale export completions and report failure or invoke the current success callback.

spacr/qt/widgets/plaque_preview.py:5510

PlaquePreviewPanel._use_pasted_legend.saved()

Normalize the edited legend text, close its editor and rebuild the figure annotations.

spacr/qt/widgets/plaque_preview.py:5530

PlaquePreviewPanel.contribute_training_data.seeder(path: Path) → Any

spaCR’s well boxes on one page.

spaCR’s plaque mask of one image.

spacr/qt/widgets/plaque_preview.py:4959 spacr/qt/widgets/plaque_preview.py:4977

PlaquePreviewPanel.fetch_paper.job() → Dict[str, Any]

Fetch, turning a reader that must be installed into an answer.

spacr/qt/widgets/plaque_preview.py:5611

PlaquePreviewPanel.plaque_table_rows.annotation(index: int) → Any

The annotation of region index, or None if it has none.

spacr/qt/widgets/plaque_preview.py:5350

PlaquePreviewPanel.run_preview.work()

Detect figure wells and prepare a review result unless detection already returned an error.

spacr/qt/widgets/plaque_preview.py:4299

_serialized_inference.run(*args, **kwargs)

Serialize the wrapped inference call so cached model instances cannot overlap.

spacr/qt/widgets/plaque_preview.py:948

figure_pass.segment(crop: np.ndarray) → np.ndarray

The Cellpose label mask of one plaque-well crop.

spacr/qt/widgets/plaque_preview.py:1166

install_plaque_mode.choose(mode: str) → None

Store mode in the form, then show it.

spacr/qt/widgets/plaque_preview.py:5892

install_plaque_mode.show(mode: str) → None

Show mode on the switch and the preview, and hide the other mode’s rows.

spacr/qt/widgets/plaque_preview.py:5876

missing_papers_packages.found(module: str) → bool

Whether module can be found without importing it.

spacr/qt/widgets/plaque_preview.py:268

plaque_pass.segment(p: Path) → Tuple[np.ndarray, Dict[str, Any]]

The plaque label mask of the image at p, with its flows.

spacr/qt/widgets/plaque_preview.py:1032

segment_well.segment(c: np.ndarray) → Tuple[np.ndarray, Dict[str, Any]]

The plaque label mask of one well crop, with its flows.

spacr/qt/widgets/plaque_preview.py:1432