spacr.qt.screens.regression

Regression, and the three modules that are the rest of the visit.

A regression run is not finished when the coefficients appear. Three screens carry on from there, and none of them duplicates anything the results panel does:

  • Volcano Explorer is the only publication-figure path in spaCR. Its volcano is a matplotlib render behind a 56-field style that can be saved and reloaded as JSON, every called point labelled, colour or shape driven by an annotation file merged on an inferred key, arbitrary x/y columns, and a vector re-render at journal size. The panel’s own volcano is pyqtgraph and can honour none of it, so the explorer is offered from that plot’s own menu as “Publication figure…”, seeded with the frame already on screen.

  • Hit List displays one ranked row per gene for the loaded regression run. Backends that report p-values receive Benjamini–Hochberg q-values computed across the genes tested; penalised backends instead rank by bootstrap selection frequency and do not report q-values. Each row includes the effect estimate, a 95% interval when a standard error is available, and gRNA sign agreement when guide-level coefficients are available. Annotation CSVs are collapsed to one row per gene before validated many-to-one joins. The complete HitListScreen is installed as the Hits tab after Guide support, follows the run loaded by the results panel, and exports the displayed filtered list as CSV, Markdown, or self-contained HTML.

  • Methods & Results builds the run digest – package versions, timings, seed and error policy, per-module parameters parsed out of the emitted macro, the segmentation verdict, artifact counts, held-out metrics – drafts the two sections from it and then mechanically checks every number in the draft back against the digest. It opens seeded with the project the regression screen is already pointed at, so the path it otherwise asks the user to type is filled in.

Each of the three is also a button on the Regression masthead: the module’s own icon with no text, its one-line description as the tooltip, lit on hover in the maturity colour its tile used – see spacr.qt.widgets.fold_strip.FoldStrip. The button and the place the capability lives are the same door: the Hit List button raises the Hits tab rather than opening a second hit list, and the Volcano Explorer button opens exactly what “Publication figure…” opens.

ONE CORRECTION FAMILY ON ONE VOLCANO. A guide permutation writes every minimum-support family stacked into one long table, and fits one family per response when several outcomes were fitted. Each of those is its own Benjamini-Hochberg family, so drawing the table unfiltered puts a guide on the plot two to four times at different heights and pools two corrections into one picture. single_correction_family() is the cut, and install_correction_families() puts it in front of the panel’s own set_frame so every route into the panel – a finished run, a folder opened by hand, a dropped bundle – draws one family.

The shared half of a fold – opening a module in a window, wiring the host signals a sidebar row used to wire, and hanging the strip off the masthead – lives in spacr.qt.screens.map_barcodes and is imported rather than repeated.

Classes

DiagnosticsOpener

The Diagnostics button: show the panels the last run wrote.

HitsOpener

The Hits button: raise the tab, or open the module when there is none.

Functions

build_methods_export(→ PySide6.QtWidgets.QWidget)

Methods & Results' own screen, seeded with the run it will describe.

build_publication_figure(→ PySide6.QtWidgets.QWidget)

Volcano Explorer's own screen, seeded with what is on screen.

install_correction_families(→ bool)

Put single_correction_family() in front of panel.set_frame.

install_extras(→ bool)

Give screen's results panel the three folded capabilities.

install_folds(...)

Put Regression's fold strip on screen's masthead.

install_hits_tab(panel)

Add the Hit List to panel as a tab, beside Guide support.

install_publication_figure(→ bool)

Offer opener as "Publication figure…" on the panel's volcano.

open_publication_figure(...)

Build the Volcano Explorer seeded from screen's results panel.

project_path(→ str)

Resolve the project directory associated with a regression screen.

publication_opener(...)

Return the shared Volcano Explorer opener for screen.

raise_hits_tab(→ bool)

Bring the Hits tab to the front. False when there is none.

results_panel(screen)

screen's results panel, or None on a screen that has none.

single_correction_family(frame)

frame reduced to ONE multiple-testing family, ready to plot.

Module Contents

class spacr.qt.screens.regression.DiagnosticsOpener(screen: PySide6.QtWidgets.QWidget)[source]

The Diagnostics button: show the panels the last run wrote.

NOT A MODULE. spacr.ml writes these panels into the run’s results folder as it finishes – see _write_regression_diagnostics – so there is nothing to compute here and nothing to configure. The button opens what is already on disk.

Which is also why it can be pressed when there is nothing to show. A run that has not happened, or one whose backend has no residuals, has no folder or a partial one, and saying so is more useful than a button that appears to do nothing.

Parameters:

screen – the host screen the button sits on.

Record the screen the diagnostics page is opened on.

Parameters:

screen – the host screen.

open() None[source]

Open the folder, or say why there is nothing to open.

verdict() tuple[source]

(level, detail) for the badge, from what is on disk.

The button is badged with the worst of score_design / score_residuals / score_inference. That worst is already computed and written – diagnostic_summary.csv carries a suite/verdict_level row – so this is a READ, and it has to stay one. Recomputing it here would let the button and the panels disagree about the same run.

("", "") when there is nothing to read, which is not the same as a pass: a run that has not happened has no verdict, and a green dot would claim it did and was fine.

class spacr.qt.screens.regression.HitsOpener(screen: PySide6.QtWidgets.QWidget)[source]

The Hits button: raise the tab, or open the module when there is none.

ONE HIT LIST, not two. Where the results panel exists the list is already a tab on it, loaded with the run on screen, so the button goes there – and it brings the Results page forward first, because a button that silently changed a tab behind the settings form would read as a button that does nothing.

A bare settings screen has no panel and so no tab; then the module opens in a window of its own, like every other fold, with the run folder seeded.

Parameters:

screen – the host screen the button sits on.

Record the screen the hit list is opened on, and how to build it.

Parameters:

screen – the host screen; the page itself is built lazily, on first open.

open(_checked: bool = False) PySide6.QtWidgets.QWidget | None[source]

Show the hit list, wherever this screen keeps it.

spacr.qt.screens.regression.build_methods_export(host_window: PySide6.QtWidgets.QWidget | None = None, screen: PySide6.QtWidgets.QWidget | None = None) PySide6.QtWidgets.QWidget[source]

Methods & Results’ own screen, seeded with the run it will describe.

Both sources the regression screen knows are filled in: the project, which supplies the provenance summary and the segmentation verdict, and the results folder, which supplies the hit statistics. The other two – the run journal and the classifier checkpoint – are the user’s to name, and every one of them is optional on that screen.

spacr.qt.screens.regression.build_publication_figure(panel, host_window=None) PySide6.QtWidgets.QWidget[source]

Volcano Explorer’s own screen, seeded with what is on screen.

The frame is preferred over the folder: the panel may be showing a table nobody can find again – a live run, a bare CSV, a frame handed in – and re-reading the folder would draw a different table from the one the user asked to publish. The folder is the fallback, and the explorer’s own “Open results…” is there when there is neither.

Every capability the explorer has arrives with it, because what is built is the module itself: the 56-field style with its JSON save and load, the annotation merge, arbitrary x/y columns and the vector re-render at page size.

Parameters:
  • panel – the results panel to seed from, or None.

  • host_window – the main window, for navigation. Unused by the explorer today; taken so the builder matches every other fold’s.

Returns:

the Volcano Explorer screen.

spacr.qt.screens.regression.install_correction_families(panel) bool[source]

Put single_correction_family() in front of panel.set_frame.

Every route into the results panel ends in set_frame – a finished run, a folder opened through “Load results…”, a dropped bundle, a frame handed straight in – so one wrapper there is what makes the volcano show one correction family whichever way the table arrived.

Idempotent, so installing twice does not stack two cuts.

Parameters:

panel – the RegressionResultsPanel, or None.

Returns:

True when this call installed the cut.

spacr.qt.screens.regression.install_extras(screen: PySide6.QtWidgets.QWidget) bool[source]

Give screen’s results panel the three folded capabilities.

Separate from the strip because the strip is only the way IN: the Hits tab, the publication-figure entry and the one-family cut are on the panel whether or not a masthead could be found to hang buttons on.

Returns:

True when a panel was found and prepared.

spacr.qt.screens.regression.install_folds(screen: PySide6.QtWidgets.QWidget) spacr.qt.widgets.fold_strip.FoldStrip | None[source]

Put Regression’s fold strip on screen’s masthead.

Built here rather than through spacr.qt.screens.map_barcodes.install_fold_strip() because one of the three buttons does not open a window: the Hits button raises a tab on the screen the user is already looking at.

Idempotent, and defensive by design: a screen that opens without its fold buttons is a smaller screen, while an exception raised here would be no regression screen at all.

Returns:

the strip, or None when this screen cannot carry one – it is not the host, it has no masthead, or one is already installed.

spacr.qt.screens.regression.install_hits_tab(panel)[source]

Add the Hit List to panel as a tab, beside Guide support.

The whole screen goes in, not a copy of its table: the filter bar, the metadata picker and the three export buttons ARE the capability the panel has none of, and a tab that reimplemented the list would keep whichever parts the person doing the folding thought of.

The tab follows the panel: whenever a run is loaded the hit list is pointed at the same folder, so it is never showing one run’s hits beside another run’s coefficients.

Idempotent.

Parameters:

panel – the results panel.

Returns:

the HitListScreen, or None when the tab could not be built.

spacr.qt.screens.regression.install_publication_figure(panel, opener: Callable[[], object]) bool[source]

Offer opener as “Publication figure…” on the panel’s volcano.

The entry goes on the pyqtgraph volcano’s own right-click menu, under a section of its own, because that is where a user who wants the figure is already looking – and it is deliberately NOT offer_style on that plot, which would hang 56 style fields off a renderer that can honour none of them.

The menu is built fresh on every right-click, so the entry is added by wrapping the builder rather than by holding a menu: a plot that rebuilt its menu would otherwise drop the entry the first time the user changed anything.

Idempotent. Returns False when there is no volcano to offer it on.

spacr.qt.screens.regression.open_publication_figure(host_window: PySide6.QtWidgets.QWidget | None = None, screen: PySide6.QtWidgets.QWidget | None = None) PySide6.QtWidgets.QWidget | None[source]

Build the Volcano Explorer seeded from screen’s results panel.

spacr.qt.screens.regression.project_path(screen) str[source]

Resolve the project directory associated with a regression screen.

The function first examines the run loaded in the results panel and returns the parent of its nearest results directory. If no project can be resolved from that run, it reads src from the screen’s settings model. A sequence-valued src contributes its first entry.

Parameters:

screen – Regression screen or compatible host.

Returns:

Project path, or "" when it cannot be determined.

spacr.qt.screens.regression.publication_opener(screen) spacr.qt.screens.map_barcodes.FoldOpener[source]

Return the shared Volcano Explorer opener for screen.

The opener is created on first use and retained on the screen. Both the Publication figure… command and the masthead action use this instance, so reopening the explorer raises the existing window rather than creating a duplicate with independent state.

Parameters:

screen – Regression screen that owns the publication workflow.

Returns:

Persistent FoldOpener.

spacr.qt.screens.regression.raise_hits_tab(panel) bool[source]

Bring the Hits tab to the front. False when there is none.

spacr.qt.screens.regression.results_panel(screen)[source]

screen’s results panel, or None on a screen that has none.

spacr.qt.screens.regression.single_correction_family(frame)[source]

frame reduced to ONE multiple-testing family, ready to plot.

A guide permutation fits the same guides once per minimum-support threshold and once per response, stacks the lot into one long table, and corrects each stack separately. Two things follow, and both are wrong on a plot: the same guide is drawn two to four times at different heights, and two Benjamini-Hochberg corrections share one axis – so a q-value read off the picture belongs to whichever family the point came from, which nothing on the picture says.

The primary family is the smallest minimum_wells_threshold, which is what perform_regression writes results.csv from when guide_primary_min_wells is left blank; where several responses were fitted the first is kept, because each response is its own correction family and the explorer’s column controls can switch.

A frame with neither column is returned unchanged, which is every parametric run – so this costs an ordinary table nothing.

Parameters:

frame – a coefficient table, or None.

Returns:

the same object when there was nothing to cut, otherwise a new frame holding one family.