Module audit¶
This page records the repository-wide module audit completed on
2026-07-30. It is intentionally tied to the application registry in
spacr.qt.app.APPS: every visible module is listed once, with the backend
that actually runs it and the boundary that keeps long work off Qt’s main
thread.
Cross-cutting guarantees¶
Pipeline modules execute through
spacr.qt.bridge.make_thread. Worker exceptions, non-zeroSystemExitvalues, stderr, and partial progress are surfaced to the module console and diagnostic log.Interactive data tools use retained
QThreadworkers for database scans, model discovery, report scans, page loads, and large image decoding.Make Maskskeeps small image changes immediate but moves an estimated eight MiB or larger decode to a worker.Package-wide debug tracing is opt-in. Enabling verbose logging records calls and returns for spaCR functions, while pipeline exceptions retain their traceback.
Sphinx AutoAPI scans the whole
spacrpackage. Every public top-level function and class has a docstring, and a structural test prevents new undocumented public symbols.Every typed setting has explanatory tooltip text. The Qt label owns the hover tooltip and teal API dot; the per-app API map is tested against the module that the app actually runs.
Registry tests require GUI, headless CLI, pre-flight validation, defaults, and pipeline dispatch to agree. Module tests cover normal paths, invalid inputs, empty inputs, mismatched shapes/counts, worker failures, and repeat runs where applicable.
Static analysis has no unused imports or dead local assignments in the audited package code. Four remaining warnings belong to independently user-edited tutorial engine/script files that this audit deliberately preserves.
Module-by-module execution map¶
Module |
Primary backend |
Responsiveness and failure boundary |
Acceleration |
|---|---|---|---|
Mask |
|
Pipeline worker; streamed batches and explicit QC ledger |
Cellpose CUDA with CPU fallback |
Timelapse |
|
Pipeline worker; frame batches and tracking errors surfaced |
Cellpose/Trackastra where available |
Motility Assay |
|
Pipeline worker; bounded CPU workers |
CPU |
Measure |
|
Pipeline worker; batched fields and database writes |
CPU; candidate for selective GPU kernels |
Annotate |
|
Page-load thread plus asynchronous database save worker |
I/O bound |
Classify (CV) |
|
Pipeline worker and PyTorch data-loader workers |
PyTorch CUDA with CPU fallback |
Classify (ML) |
|
Pipeline worker |
CPU today; XGBoost CUDA is a candidate |
Map Barcodes |
|
Pipeline worker plus validated process workers/writer |
CPU and I/O bound |
Regression |
|
Pipeline worker |
CPU |
Align & Stitch |
|
Dedicated job thread; incremental mosaic writes |
CPU/OpenCV; GPU registration is a candidate |
Format Converter |
|
Preview and conversion jobs run outside the GUI thread |
I/O bound |
Import Project |
|
Mapping validation and import job report failures explicitly |
I/O bound |
External Masks |
|
Pipeline worker; read-only plan before writes |
CPU and I/O bound |
Plate Queue |
|
Retained queue runner; per-item status and stop handling |
Delegates to each module |
Batch Runner |
|
Sequential worker jobs with atomic persisted state |
Delegates to each module |
Database Browser |
|
Paged background queries and exports |
I/O bound |
Make Masks |
|
Large image/mask decode on |
CPU interactive editing |
Train Cellpose |
|
Pipeline worker; CUDA probe safely falls back to CPU |
Cellpose CUDA |
Cellpose Masks |
|
Pipeline worker |
Cellpose CUDA with CPU fallback |
Model Compare |
|
Model/field loading and inference in retained workers |
Cellpose CUDA with CPU fallback |
Model Zoo |
|
Discovery, validation, download, and benchmark workers |
Benchmark backend dependent |
Plate Viewer |
|
Database load and heatmap preparation in worker |
CPU |
Annotator Agreement |
|
Database read and agreement computation in worker |
CPU |
Image UMAP |
|
Pipeline/search workers; repeated runs have isolated lifecycle state |
CPU UMAP today; RAPIDS is a candidate |
Activation |
|
Pipeline worker |
PyTorch CUDA with CPU fallback |
Training Runs |
|
Scan and curve preparation in worker |
CPU and I/O bound |
Report |
|
Scan/render job in worker; output-open errors surfaced |
CPU and I/O bound |
Plaque Assay |
|
Pipeline worker |
CPU |
Recruitment |
|
Pipeline worker |
CPU |
Invasion Assay |
|
Pipeline worker; schema and threshold validation |
CPU |
Replication Assay |
|
Pipeline worker; parasite-to-vacuole assignment validation |
CPU |
Notable corrections from the audit¶
FASTQ parsing now validates four-line records, paired chunk counts, sequence/quality lengths, regex groups, duplicate barcodes, writer exit status, and reverse-complements R2 quality with its sequence.
Format Converter GUI/CLI dispatch now uses the same current conversion backend.
Replication runs the parasite-count assay promised by its UI; the legacy area proxy remains explicitly headless.
Plot significance thresholds no longer lose the
p <= 0.001marker to a misspelled variable.Make Masks finds TIFF masks saved for PNG/JPEG sources, preserves label IDs above 255, rejects mismatched shapes, and threads large decodes.
Classification image preloading now closes PIL files deterministically, uses bounded I/O threads instead of forking a live Qt/PyTorch process, and cannot strand a full prefetch queue during shutdown.
Training-dataset rules now reject unknown columns/operators, empty class or annotation definitions, invalid modes, and zero-crop selections with actionable exceptions instead of returning a silent
(None, None).Cellpose training/test/apply no longer force
gpu=Trueon machines where CUDA is unavailable.The legacy GUI keep-alive callback no longer consumes and discards worker errors before the console can display them.
Seven quarantined legacy-GUI defects are now covered as passing regressions: nested panel disabling, annotation databases without
cell_area, figure titles, fresh erase mode, zero-width zooms, fallback card spacing, and progress-label placement.Batch Runner worker progress, failure, and completion signals now cross an explicit queued Qt boundary. Queue settlement therefore always happens on the GUI thread, including after a worker exception.
Settings controls embedded in composite widgets now resolve their outer form label correctly. The informative tooltip and teal API link remain on that label instead of becoming attached to an inner field.
Every experimental Home layout now categorizes External Masks, and its staged-module count agrees with the canonical registry.
Reusable action buttons consistently expose positive and negative roles: blue/red outline at rest, translucent hover feedback, and a readable solid busy/pressed state.
Verification boundary¶
The root test suite was executed in bounded segments, including the complete remaining suffix after every first-failure correction. Qt tests were likewise run in fresh 20-file-or-smaller processes because the locally available Python-3.13 pytest/Qt shim develops native allocator corruption only after roughly 200 accumulated GUI tests. One hundred of 103 Qt files were exercised; the three omitted files are an independent, user-edited tutorial group, one of which currently contains a known unmatched parenthesis. Tutorial CLI and engine tests still pass.
All 624 other Python sources and tests parse successfully, git diff
--check is clean, and the API documentation, settings-category, app-registry,
declared-dependency, and debug-logging contracts pass. A rendered Sphinx build
was not attempted because Sphinx is not installed in the spaCR environment;
the structural AutoAPI contract was run instead.
High-value additions¶
Add a universal dry-run/resource estimate card: input count, projected output size, RAM/VRAM estimate, and settings/schema problems before Run.
Extend the existing run journal into checkpoint/resume for Mask, Measure, UMAP search, conversion, and report generation at field/batch boundaries.
Add data provenance hashes for input manifests, model artifacts, and settings so reports can prove exactly which source state produced them.
Add optional QC gates between modules (for example, stop Measure when segmentation failure rate exceeds a chosen threshold).
Add a small benchmark command that records throughput and peak RAM/VRAM for representative fields, making worker-count defaults specific to the current machine.
GPU opportunities¶
The best next GPU addition is optional RAPIDS cuML for Image UMAP and its
clustering, with the current implementation retained as the deterministic CPU
fallback. A second useful target is device='cuda' for supported XGBoost
Classify (ML) runs. Selected convolution, texture, and phase-correlation
kernels in Measure and Align could use CuPy/OpenCV CUDA, but only after
profiling: transfer overhead often exceeds the gain for small fields.
Barcode mapping, format conversion, SQLite browsing, report assembly, and most grouped statistics are dominated by decompression, filesystem, database, or small-table work and should remain on CPU.