spacr.qt.screens.map_barcodes¶
Barcode QC integration and shared support for folded modules.
The Barcode QC page assesses reads per well, low-depth wells, unmapped reads, barcode collisions, positional effects, library coverage and the resulting abundance threshold. It opens beside the Map Barcodes settings with its full settings form, run controls, console and figures.
This module also provides the common infrastructure used by host screens:
install_fold_strip(), FoldOpener,
build_settings_screen() and install_window_hooks(). These helpers
mount a complete module page, connect host signals and attach its masthead
button without duplicating analytical implementations.
Classes¶
The live search: reads in, measured settings out, nothing written yet. |
|
What one search is going to read, worked out from the settings form. |
|
One folded module, mounted on its host as extra settings categories. |
|
Manage category folds and pipeline gates for one host screen. |
|
Open a folded module and reuse its screen between activations. |
Functions¶
|
Build the live search and the card it sits in, unmounted. |
|
The screen NAVIGATION builds for |
|
Build a fully connected settings screen for module |
|
Connect |
|
Return the settings a proposal would change, old value beside new. |
|
Return the display name, description, and maturity stage for |
|
Return the window title for folded module |
|
Take |
|
Return the host's page strip, creating it when first requested. |
|
Attach the live barcode search to the Map Barcodes screen. |
|
Install buttons for |
|
Put Map Barcodes' fold strip, its live barcode search and its spatial |
|
Install the fold strip declared for |
|
Install fold strips as screens become current in |
|
Work out which reads and which reference tables a search should read. |
|
Apply the folded module's registered name, description, and stage. |
|
Add |
|
Show |
Module Contents¶
- class spacr.qt.screens.map_barcodes.BarcodeSearchPanel(screen=None, parent: PySide6.QtWidgets.QWidget | None = None, *, threaded: bool = True, max_reads: int | None = None, chunk_reads: int | None = None, read_sample: int = READ_SAMPLE_READS)[source]¶
Bases:
PySide6.QtWidgets.QWidgetThe live search: reads in, measured settings out, nothing written yet.
Press the search button and the panel samples the reads of one sample from the folder the form names, measures every reference table against them in both orientations and in both mates, and refines what it shows after each chunk of reads. It ends by proposing the settings those measurements imply and waiting, because applying them is the user’s decision.
What is on screen, and why each part is there. The findings table carries the observed rate and the rate expected by coincidence in adjacent columns, with the ratio between them beside both, because a rate alone cannot be told from an accident and this panel exists to stop somebody acting on one. The text window shows reads with their matches coloured by barcode type, because a barcode landing in the same columns on row after row is the evidence that settles an argument a percentage cannot. The proposal shows the value the form holds beside the value the search suggests, so what Apply is about to do is legible before it does it.
It follows the form. Once a search has been asked for, changing any setting the search reads – the sequencing folder, a reference table, the barcode set or the anchor – starts it again after the form has been still for a moment, the way the Mask live preview follows its settings. Settings the search does not read never start one. Apply is the exception to everything live about this panel: the form changes only when it is pressed, so a value somebody typed is never replaced by a measurement that arrived while they were typing.
What it costs. Every file is read inside a submitted job, one chunk at a time, so the interface stays live throughout and a search can be abandoned at any point. Cancelling proposes nothing: an interrupted measurement is an honest partial report and a dishonest recommendation.
- Parameters:
screen – the Map Barcodes screen whose settings form is read for the search and written by Apply. May be None, which leaves the panel usable as a display with nothing to read from and nothing to write to.
parent – parent widget; ownership only.
threaded – run the search on worker threads. False runs each step inline, in the same order and through the same handlers, so a test can drive a whole search synchronously.
max_reads – how many reads to sample from each file. The engine’s own default when omitted.
chunk_reads – how many reads each step of the search takes from each file. The engine’s own default when omitted.
read_sample – how many reads the text window shows.
- Variables:
search_button – starts a search.
cancel_button – abandons the search in flight.
apply_button – writes the proposed settings into the form; disabled until a finished search has proposed something that differs from what the form already holds.
status – one line saying what the search is doing or has found.
findings – the table of measurements, one row per reference table per mate per orientation.
proposal_label – what Apply would change, and what the search learned that no setting can hold.
reads – the text window showing sampled reads with matches coloured.
Build the panel and arm it against one settings screen.
- apply_proposal() Tuple[str, ...][source]¶
Write the proposed settings into the form, on purpose.
Nothing calls this on its own. A search that finishes enables the button and stops there, because a panel that quietly replaced values somebody typed would be a worse failure than the one it exists to prevent.
- Returns:
the keys that were written, in the order they were written.
- cancel_search() bool[source]¶
Abandon the search in flight and propose nothing from it.
The chunk already on a worker thread is not interrupted; it finishes and its result is dropped on arrival, which is what cancelling means for work that holds no lock and cannot be asked to stop in the middle.
- Returns:
True when there was a search to cancel.
- changeEvent(event) None[source]¶
Redraw the measurements when the theme underneath them changes.
The verdict colours are taken from the palette that was on screen when the row was drawn, so a row drawn before a theme change keeps the old theme’s ink until it is drawn again.
- Parameters:
event – the Qt change event being delivered.
- closeEvent(event) None[source]¶
Stop the search rather than let it outlive the panel.
- Parameters:
event – the Qt close event being delivered.
- current_settings()[source]¶
Return the settings as the form holds them at this moment.
- Returns:
the settings dictionary, empty when there is no form.
- is_searching() bool[source]¶
Return whether a search is running.
- Returns:
True while the panel is working through the reads.
- on_apply_clicked(_checked: bool = False) None[source]¶
Write the proposed settings into the form.
- Parameters:
_checked – Qt’s toggle state, unused.
- on_cancel_clicked(_checked: bool = False) None[source]¶
Abandon the search in flight.
- Parameters:
_checked – Qt’s toggle state, unused.
- on_search_clicked(_checked: bool = False) None[source]¶
Start a search, or restart one that is already running.
- Parameters:
_checked – Qt’s toggle state, unused.
- proposal()[source]¶
Return the proposal a finished search produced.
- Returns:
the proposal, or None when no search has finished.
- proposed_changes()[source]¶
Return the settings Apply would write, old value beside new.
- Returns:
a tuple of entries, each holding a setting’s key, the value the form holds and the value the search proposes.
- report()[source]¶
Return the most recent report, complete or not.
- Returns:
the report, or None when no search has produced one.
- class spacr.qt.screens.map_barcodes.BarcodeSearchPlan[source]¶
What one search is going to read, worked out from the settings form.
Planning is separated from searching because the two fail in different ways and the user needs to be told which one happened. A plan that cannot be made is a sentence about the form, such as a folder holding no sequencing files, and it is worth showing before any read is opened; a search that finds nothing is a measurement, and means something else entirely.
- Variables:
fastq_files – the sequencing files to read, as a mapping from the label each carries in the report to its path. The labels are the mate names, so a report can say which mate carried which barcode.
reference_tables – one entry per reference table, holding the name it is reported under, the path it is read from, and the barcode role it fills.
anchor – the fixed vector sequence the mapping run locates its window by, searched alongside the tables so that offsets can be expressed relative to it. Empty when the settings name none.
sample – the name of the sample whose reads are being searched.
other_samples – how many further samples sit beside it in the same folder. Barcode layout is a property of the library rather than of one sample, so one sample settles it for all of them, but the count is shown so nobody thinks the others were missed.
problem – a sentence saying why this plan cannot be searched, or an empty string when it can.
- class spacr.qt.screens.map_barcodes.CategoryFold(screen: PySide6.QtWidgets.QWidget, key: str, gates: Sequence[str] = ())[source]¶
One folded module, mounted on its host as extra settings categories.
The module’s settings form is built through the same path as its own screen. Categories containing settings absent from the host are then mounted on the host and remain hidden until the fold is enabled.
The fold switch exclusively controls the mounted categories’ visibility. They are omitted from
_settings_sectionsbecause the maturity filter and settings search also change the visibility of sections in that list. Consequently, settings search does not include an inactive folded category.Settings already provided by the host are not duplicated. Because
collect()indexes controls by setting name, duplicate controls would create ambiguous values and could replace values entered on the host. Existing keys are therefore removed from the folded form, and categories with no remaining controls are not mounted.- Parameters:
screen – the host module’s
AppScreen.key – the folded module’s registry key.
gates – setting names the host’s pipeline reads to decide whether to do what this module does. They are forced True while the fold is on and False while it is off, so the run matches what the form is showing.
Record one settings category that folds in and out of the host.
- Parameters:
screen – the host screen whose form the category joins.
key – the fold’s key.
gates – the settings whose values decide whether it applies.
- collect() Dict[str, object][source]¶
Return the settings contributed by this fold.
The host model collects both host and folded settings. This method selects only the keys mounted by the current fold.
- mount() bool[source]¶
Build the module’s categories and put them on the host, hidden.
- Returns:
True when at least one category was mounted. False means the host has no settings form, or the folded module has nothing this host does not already show – both of which leave the host exactly as it was.
- class spacr.qt.screens.map_barcodes.CategoryFoldSet(screen: PySide6.QtWidgets.QWidget, folds: Dict[str, Sequence[str]], implies: Dict[str, Sequence[str]] | None = None)[source]¶
Manage category folds and pipeline gates for one host screen.
A host declares its folded modules and their associated gates. This class mounts their settings, builds the masthead controls, and synchronizes gate values with the active folds.
- Parameters:
screen – the host module’s
AppScreen.folds –
key -> gate names, in the order the strip draws them.implies – dependencies as
key -> keys. Activating a dependent fold also activates its prerequisites. For example, the motility assay activates the timelapse branch required for tracking.
Build the set of category folds this screen offers.
- Parameters:
screen – the host screen.
folds – each fold’s key mapped to the settings that gate it; the mapping’s order is the order the strip shows them in.
implies – folds that turning one on also turns on.
- apply_gates() Dict[str, bool][source]¶
Derive and store gate values from all active folds.
Values are recomputed collectively because multiple folds may share a gate. Gates are stored in the settings model defaults rather than in duplicate form controls;
collect()includes defaults for keys without widgets.
- build_strip(parent: PySide6.QtWidgets.QWidget | None = None) spacr.qt.widgets.fold_strip.FoldStrip | None[source]¶
The masthead strip: one checkable button per mounted fold.
- is_active(key: str) bool[source]¶
Whether
key’s categories are showing and its gate is on.- Parameters:
key – application key of the folded module; an unknown key returns
False.
- mount() Tuple[str, ...][source]¶
Mount each fold’s categories on the host in a hidden state.
- Returns:
keys of folds that contributed at least one setting.
- set_active(key: str, on: bool) None[source]¶
Set a fold’s state and update its dependency relationships.
Enabling a dependent fold enables its prerequisites. Disabling a prerequisite disables active dependents. Available strip buttons are updated through their normal signal path to keep display and form state synchronized.
- Parameters:
key – application key of the folded module; an unknown key is ignored.
on –
Trueto enable the fold and its prerequisites,Falseto disable it and any active fold that depends on it.
- sync_from_settings(settings: Dict[str, object]) Tuple[str, ...][source]¶
Synchronize fold states with values in a loaded settings mapping.
Fold gates have no dedicated widgets, so bulk settings application cannot update them through the form. This method reads the gate values directly and activates the corresponding folds.
- Parameters:
settings – the dict that was applied.
- Returns:
the keys switched on by it.
- class spacr.qt.screens.map_barcodes.FoldOpener(screen: PySide6.QtWidgets.QWidget, key: str, build: Callable[[PySide6.QtWidgets.QWidget | None], PySide6.QtWidgets.QWidget])[source]¶
Open a folded module and reuse its screen between activations.
The opener is an object so the fold strip controls its lifetime through the button connection. The module appears as a page on its host when the host supports pages, or as a separate window otherwise. Its screen is constructed once and retained, preventing duplicate database handles or job runners and preserving loaded state when the user changes pages.
- Parameters:
screen – the host screen the button sits on.
key – the folded module’s registry key.
build – called with the main window (or None) and returning the folded module’s screen.
Record how to build one folded module’s page, without building it.
- Parameters:
screen – the host screen the page is opened on.
key – the folded module’s registry key.
build – called with a parent to build the page, on first open.
- spacr.qt.screens.map_barcodes.build_barcode_search_card(screen, **kwargs)[source]¶
Build the live search and the card it sits in, unmounted.
Returned unmounted, as the live preview’s card is, so that the caller decides where it goes and whether it starts visible.
- Parameters:
screen – the Map Barcodes screen the search reads and writes.
kwargs – passed through to
BarcodeSearchPanel.
- Returns:
the panel and the card holding it.
- spacr.qt.screens.map_barcodes.build_registered_screen(key: str, host_window: PySide6.QtWidgets.QWidget | None = None) PySide6.QtWidgets.QWidget[source]¶
The screen NAVIGATION builds for
key, for a fold button to open.Folded modules that still hold a registry row are reached two ways – the button on their host’s masthead and the command palette – and the two must land on the same screen. Asking the window to build it is what guarantees that:
_build_screenis the one place that knows which keys have a dedicated screen class, which are catalogue-drivenAppScreenscreens, and which come from a plugin.The alternative was a table here mapping ten keys to ten classes, which is the same knowledge written a second time and free to drift from the first.
Falls back to
build_settings_screen()when there is no window to ask – the headless and unit-test path, where a settings screen is what the catalogue-driven modules would have produced anyway.- Parameters:
key – the folded module’s registry key.
host_window – the main window, when there is one.
- Returns:
the screen.
- spacr.qt.screens.map_barcodes.build_settings_screen(key: str, host_window: PySide6.QtWidgets.QWidget | None = None) PySide6.QtWidgets.QWidget[source]¶
Build a fully connected settings screen for module
key.The returned screen has the same host connections and declared pipeline ports as the standalone screen, including error explanation and cluster execution actions. Modules without declared ports omit the chaining controls.
- Parameters:
key – the folded module’s registry key.
host_window – the main window, when there is one to connect to.
- Returns:
the screen.
- spacr.qt.screens.map_barcodes.connect_host(screen: PySide6.QtWidgets.QWidget, host_window: PySide6.QtWidgets.QWidget | None) None[source]¶
Connect
screen’s host signals tohost_window’s slots.Connections are derived from
spacr.qt.chaining.HOST_CONNECTIONS, the same mapping used byMainWindow._build_screen. Folded and standalone screens therefore expose the same host-level actions.- Parameters:
screen – the screen whose host signals, named in
HOST_CONNECTIONS, are connected.host_window – the window providing the matching slots;
Noneconnects nothing.
- spacr.qt.screens.map_barcodes.describe_proposed_changes(proposal, current_settings)[source]¶
Return the settings a proposal would change, old value beside new.
Showing what will change before it changes is the difference between a convenience and a trap. Somebody who typed a window length has to be able to see that pressing Apply replaces it, and with what, while there is still time to decide not to.
- Parameters:
proposal – the proposal a finished search produced.
current_settings – the settings as the form holds them now.
- Returns:
a tuple of entries, each holding the setting’s key, the value the form holds and the value the search proposes, for those settings whose value would actually change.
- spacr.qt.screens.map_barcodes.fold_description(key: str) Tuple[str, str, str][source]¶
Return the display name, description, and maturity stage for
key.Registry metadata is preferred while the module remains registered.
FOLD_FALLBACKsupplies the same presentation metadata after a folded module’s standalone registry entry is removed.- Parameters:
key – application key of the folded module, looked up in the app registry, then the declared catalogue, then the fold fallback records.
- spacr.qt.screens.map_barcodes.folded_module_title(key: str) str[source]¶
Return the window title for folded module
key.The application title table is preferred so renamed modules remain consistent throughout the interface. Fallback metadata is used after a module’s standalone registry entry is removed.
- Parameters:
key – application key of the folded module; when no title or name is recorded it is title-cased with underscores as spaces.
- spacr.qt.screens.map_barcodes.hide_as_page(screen: PySide6.QtWidgets.QWidget, host: PySide6.QtWidgets.QWidget | None) bool[source]¶
Take
screenoffhost’s page strip, keeping the screen.The counterpart to
show_as_page(), for a control that closes what it opened. It takes the same route the strip’s own close mark takes –_close_fold_page()– so a page closed by a switch and a page closed by its cross leave the module in the same state, loaded and off the strip rather than destroyed.- Parameters:
screen – the folded module’s widget.
host – the host module’s screen.
- Returns:
True when a page was taken off the strip, False when the host has no strip or the widget is not on it.
- spacr.qt.screens.map_barcodes.host_pages(screen: PySide6.QtWidgets.QWidget, title: str = '') PySide6.QtWidgets.QTabWidget | None[source]¶
Return the host’s page strip, creating it when first requested.
The host body becomes a non-closable first page and retains its layout stretch. Pages opened for folded modules can be closed without destroying their underlying screens.
- Parameters:
screen – the host module’s screen.
title – caption for the host page. If omitted, use
screen._fold_page_titleand then the registered application name.
- Returns:
the page strip, or
Nonewhen the host has no page body.
- spacr.qt.screens.map_barcodes.install_barcode_search(screen: PySide6.QtWidgets.QWidget, **kwargs)[source]¶
Attach the live barcode search to the Map Barcodes screen.
The search starts hidden, and a toggle on the screen shows it.
Installed rather than built into the screen for the reason every other panel on this screen is installed from outside: the screen is the generic settings screen, which knows nothing about sequencing and should not have to. Repeated calls return the panel that is already there, because the stack watcher reaches a screen again every time it becomes current.
- Parameters:
screen – the screen to install into. Anything that is not the Map Barcodes screen is left alone.
kwargs – passed through to
BarcodeSearchPanel, which is how a test asks for a smaller read sample or an unthreaded search.
- Returns:
the panel, or None when the screen is not the Map Barcodes screen or has no runtime panel to mount into.
- spacr.qt.screens.map_barcodes.install_fold_strip(screen: PySide6.QtWidgets.QWidget, host_key: str, folded: Sequence[str], builders: Dict[str, Callable[[PySide6.QtWidgets.QWidget | None], PySide6.QtWidgets.QWidget]]) spacr.qt.widgets.fold_strip.FoldStrip | None[source]¶
Install buttons for
foldedmodules onscreen’s masthead.Repeated calls return the existing strip. Construction failures are contained so the host screen remains usable without the optional strip.
- Parameters:
screen – the host module’s screen.
host_key – registry key required on
screen.folded – the folded modules’ keys, in strip order.
builders – mapping from module key to a screen factory.
- Returns:
the installed strip, or
Nonewhen the screen is not the requested host, has no masthead, contains no eligible modules, or strip construction fails.
- spacr.qt.screens.map_barcodes.install_folds(screen: PySide6.QtWidgets.QWidget) spacr.qt.widgets.fold_strip.FoldStrip | None[source]¶
Put Map Barcodes’ fold strip, its live barcode search and its spatial transcriptomics panel on
screen.The search is installed here rather than through a seam of its own because this is the call every route to the Map Barcodes screen already passes through. A panel installed anywhere else would be present when the screen is reached one way and missing when it is reached another.
- Parameters:
screen – the screen to install into.
- Returns:
the fold strip, or None when this screen hosts no folds.
- spacr.qt.screens.map_barcodes.install_folds_on(screen: PySide6.QtWidgets.QWidget) spacr.qt.widgets.fold_strip.FoldStrip | None[source]¶
Install the fold strip declared for
screen’s application key.The owning module is selected through
FOLD_HOST_MODULES. Screens without a fold declaration are left unchanged.- Parameters:
screen – the host screen; its
app_keyselects the owning module inFOLD_HOST_MODULES.
- spacr.qt.screens.map_barcodes.install_window_hooks(window) _StackWatcher | None[source]¶
Install fold strips as screens become current in
window.Repeated calls return the existing stack watcher rather than connecting an additional callback.
- Parameters:
window – the main window.
- Returns:
the watcher, or None when the window has no screen stack.
- spacr.qt.screens.map_barcodes.plan_barcode_search(settings)[source]¶
Work out which reads and which reference tables a search should read.
The sequencing folder of a real screen holds several samples, and one of them is enough. Which mate carries which barcode, which orientation the reference tables are stored in relative to the reads, and where in the read the barcodes sit are all properties of the library and the sequencing run rather than of a sample, so measuring them on the first sample settles them for every sample beside it. The others are counted rather than read, and the count is reported so that nobody has to wonder whether they were forgotten.
Nothing here opens a read. It lists a folder and checks that the reference files exist, so it is cheap enough to run whenever the search button is pressed and it can say what is missing before a single byte is decoded.
- Parameters:
settings – the Map Barcodes settings as the form holds them.
- Returns:
the plan. Its problem is a sentence when there is nothing to search and empty when the plan can be carried out.
- spacr.qt.screens.map_barcodes.restate_fold_button(button, key: str) None[source]¶
Apply the folded module’s registered name, description, and stage.
The operation has no visible effect while the registry still contains the module because the strip already uses the same metadata. After the registry row is removed, the fallback metadata preserves the module’s accessible label, tooltip, and maturity-stage styling.
- Parameters:
button – the fold-strip button to update (tooltip, accessible name and
stage);Nonedoes nothing.key – application key of the folded module whose metadata is applied.
- spacr.qt.screens.map_barcodes.show_as_page(screen: PySide6.QtWidgets.QWidget, host: PySide6.QtWidgets.QWidget | None, title: str) PySide6.QtWidgets.QWidget | None[source]¶
Add
screentohost’s page strip and select it.- Parameters:
screen – widget for the folded module.
host – the host module’s screen.
title – page caption, normally the folded module’s display name.
- Returns:
screen, orNonewhen the host cannot contain pages.
- spacr.qt.screens.map_barcodes.show_as_window(screen: PySide6.QtWidgets.QWidget, owner: PySide6.QtWidgets.QWidget | None, title: str) PySide6.QtWidgets.QWidget[source]¶
Show
screenas its own window, owned byowner’s window.This fallback is used when the host cannot display the screen as a page; see
show_as_page(). The main window owns the resulting window so that Qt retains it for the application’s lifetime and closes it with the application.- Parameters:
screen – the screen to show; it is reparented as a top-level window, titled, resized and raised.
owner – a widget whose top-level window becomes the new window’s parent;
Noneleaves it unparented.title – the window title.
Nested helpers¶
- _SpatialTranscriptomicsPanel.__init__.destroyed(*_args)¶
Stop the job runner when the panel object is destroyed.
Destruction may follow a reopen, after the initial token retired; this state stays usable without touching the destroyed widget.
spacr/qt/screens/map_barcodes.py:2671
- _SpatialTranscriptomicsPanel._path_row.browse(_checked=False)¶
Fill this row from its folder, input-file or output-file picker.
spacr/qt/screens/map_barcodes.py:2711
- _SpatialTranscriptomicsPanel._start_action.work()¶
Load, register and optionally assign in a worker thread.
spacr/qt/screens/map_barcodes.py:2982