Edit on GitHub

starplast.strategy_panel

The Strategies tab: thirty-nine ways to infer something, each explained, runnable and self-testing.

Docked to the right of Evidence and Analysis. The top half lists the strategies by family, with the verdict each one earned when its self-test was run on the shipped data. The bottom half shows the selected one as a CARD first (strategy_card.StrategyCard): what it answers, the same four bars for every strategy (better than chance, reach, and two plain task metrics, each against chance), Run / Test / Details, four collapsed lines about its test, and one real failure beside one real success. Details ▸ opens the three tabs that hold everything else:

Guide     what it infers, why that works, how it fails, a step-by-step walkthrough, and how
          it is tested -- the text a person needs before believing its output
Settings  its parameters, each with a tooltip saying why it exists, and Run / Test / Stop
Results   the summary, the tables it produced, and the verdict of the last self-test

A strategy runs on the window's job runner, so it appears in the Jobs panel and can be stopped there like anything else. Results tables are registered through AnalysisPanel.results_table when the analysis panel is present, so they carry the same row action and right-click save as every other results table in the application.

Nothing here computes anything: strategies and strategy_catalog do, and this is their face.

DATA = '/home/runner/work/starplast/starplast/starplast/data'
MEASURED = '/home/runner/work/starplast/starplast/starplast/data/strategy_selftests.json'
TABLES = 6
VERDICT_COLORS = {'PASS': '#2e8b57', 'FAIL': '#c0392b', 'INCONCLUSIVE': '#888888'}
GRADE_COLORS = {'reliable': '#2e8b57', 'works when tuned': '#b8860b', 'weak': '#cc7a00', 'no skill': '#c0392b', 'untestable': '#888888'}
BUTTON_TIPS = {'run': 'Run the selected strategy with these settings on the whole table, in the background. Its tables appear under Results; a strategy that builds a map can then be shown on it.', 'test': "Run the strategy's self-test: hide information that is already known, ask the strategy for it back, and compare the answer with the same procedure on shuffled data. PASS means it beat that null by the stated margin on these settings.", 'stop': 'Ask the running strategy to stop. It stops at its next checkpoint, usually within a few seconds; nothing is written anywhere by a stopped run.', 'map': 'Put the map this result was computed on into the central view, colored by its clusters or modules, so the result can be looked at rather than only read.', 'genes_file': 'Read gene identifiers from a text or CSV file: every token in the first column, or the whole file if it is a plain list. Anything not found is reported.', 'genes_example': 'Fill the list with the members of one known category of the default label, so a gene-list strategy can be tried before you have a list of your own.', 'genes_gate': 'Use the genes currently gated on the map, so a structure you drew around can be handed straight to a gene-list strategy.', 'genes_test': 'Would the data have found these genes? Their labels are hidden all at once and five fast strategies are asked for them back; the answer opens in the evidence panel, gene by gene. Genes with no label are left out.', 'tuned': 'Fill the settings with the combination calibration found best for this strategy (chosen on some held-out seeds and confirmed on others). The held-out label or gene list stays yours to choose.', 'filter': "Type to show only strategies whose name, method, question or family contains the text -- for example 'list', 'network', 'HDBSCAN', 'logistic' or 'Plasmodium'.", 'details': 'Open everything the card leaves out: the Guide (method, techniques, walkthrough, every scorecard metric), the Settings (each parameter, the tuned setting, Stop) and the Results tables of the last run or test.', 'back': "Back to the strategy's card: the four bars, the test explained, and the worked examples."}
def load_measured(organism: str) -> dict:

The shipped self-test verdicts for one organism, or nothing if they were never measured.

def shipped_card(key: str, organism: str, measured: dict | None = None) -> dict:

metric -> (value, low, high) measured on the shipped data: the calibration's defaults with their 95% interval where the sweep recorded scorecards, else the single self-test.

A module function, not only a method, because the Start-here tab shows the same four bars for the strategies it recommends and must not compute them a second way.

def headline(key: str, organism: str, measured: dict | None = None) -> tuple:

(card, verdict, grade, basis) for one strategy's four bars, as StrategyCard takes them.

The calibration sweep's defaults with their 95% intervals where it measured the strategy on this space, else the single shipped self-test, else nothing and a line saying so.

class StrategyPanel(PyQt6.QtWidgets.QWidget):

The strategy list, a guide to the selected strategy, its settings, and its results.

StrategyPanel( nodes: pandas.DataFrame, runner=None, analysis=None, organism: str | None = None, graph=None, other=None, gated=None, parent=None)

Build the panel over one organism's table. Nothing is computed until something is run.

def embedding_ready(unknown):

pyqtSignal(*types, name: str = ..., revision: int = ..., arguments: Sequence = ...) -> PYQT_SIGNAL

types is normally a sequence of individual types. Each type is either a type object or a string that is the name of a C++ type. Alternatively each type could itself be a sequence of types each describing a different overloaded signal. name is the optional C++ name of the signal. If it is not specified then the name of the class attribute that is bound to the signal is used. revision is the optional revision of the signal that is exported to QML. If it is not specified then 0 is used. arguments is the optional sequence of the names of the signal's arguments.

def clusters_ready(unknown):

pyqtSignal(*types, name: str = ..., revision: int = ..., arguments: Sequence = ...) -> PYQT_SIGNAL

types is normally a sequence of individual types. Each type is either a type object or a string that is the name of a C++ type. Alternatively each type could itself be a sequence of types each describing a different overloaded signal. name is the optional C++ name of the signal. If it is not specified then the name of the class attribute that is bound to the signal is used. revision is the optional revision of the signal that is exported to QML. If it is not specified then 0 is used. arguments is the optional sequence of the names of the signal's arguments.

def gene_selected(unknown):

pyqtSignal(*types, name: str = ..., revision: int = ..., arguments: Sequence = ...) -> PYQT_SIGNAL

types is normally a sequence of individual types. Each type is either a type object or a string that is the name of a C++ type. Alternatively each type could itself be a sequence of types each describing a different overloaded signal. name is the optional C++ name of the signal. If it is not specified then the name of the class attribute that is bound to the signal is used. revision is the optional revision of the signal that is exported to QML. If it is not specified then 0 is used. arguments is the optional sequence of the names of the signal's arguments.

def test_genes(unknown):

pyqtSignal(*types, name: str = ..., revision: int = ..., arguments: Sequence = ...) -> PYQT_SIGNAL

types is normally a sequence of individual types. Each type is either a type object or a string that is the name of a C++ type. Alternatively each type could itself be a sequence of types each describing a different overloaded signal. name is the optional C++ name of the signal. If it is not specified then the name of the class attribute that is bound to the signal is used. revision is the optional revision of the signal that is exported to QML. If it is not specified then 0 is used. arguments is the optional sequence of the names of the signal's arguments.

def status(unknown):

pyqtSignal(*types, name: str = ..., revision: int = ..., arguments: Sequence = ...) -> PYQT_SIGNAL

types is normally a sequence of individual types. Each type is either a type object or a string that is the name of a C++ type. Alternatively each type could itself be a sequence of types each describing a different overloaded signal. name is the optional C++ name of the signal. If it is not specified then the name of the class attribute that is bound to the signal is used. revision is the optional revision of the signal that is exported to QML. If it is not specified then 0 is used. arguments is the optional sequence of the names of the signal's arguments.

def result_ready(unknown):

pyqtSignal(*types, name: str = ..., revision: int = ..., arguments: Sequence = ...) -> PYQT_SIGNAL

types is normally a sequence of individual types. Each type is either a type object or a string that is the name of a C++ type. Alternatively each type could itself be a sequence of types each describing a different overloaded signal. name is the optional C++ name of the signal. If it is not specified then the name of the class attribute that is bound to the signal is used. revision is the optional revision of the signal that is exported to QML. If it is not specified then 0 is used. arguments is the optional sequence of the names of the signal's arguments.

def test_ready(unknown):

pyqtSignal(*types, name: str = ..., revision: int = ..., arguments: Sequence = ...) -> PYQT_SIGNAL

types is normally a sequence of individual types. Each type is either a type object or a string that is the name of a C++ type. Alternatively each type could itself be a sequence of types each describing a different overloaded signal. name is the optional C++ name of the signal. If it is not specified then the name of the class attribute that is bound to the signal is used. revision is the optional revision of the signal that is exported to QML. If it is not specified then 0 is used. arguments is the optional sequence of the names of the signal's arguments.

ctx
measured
inputs: dict
filter
tree
guide
form_host
form
run_btn
test_btn
stop_btn
map_btn
tuned_btn
summary
verdict
result_tabs
tables
tabs
card
card_scroll
back_btn
stack
def select(self, key: str):

Make key the current strategy: its guide, and a fresh form of its parameters.

def headline(self, key: str) -> tuple:

(card, verdict, grade, basis) for the card's four bars, for this panel's organism.

def show_card(self):

Show the selected strategy's card: the default view.

def show_details(self, tab: int | None = None):

Open the Guide, Settings and Results behind the card, optionally at one tab.

def guide_html(self, s: starplast.strategies.Strategy) -> str:

The Guide tab for one strategy, as HTML.

def techniques_html(self, s: starplast.strategies.Strategy) -> str:

What the method is made of: each technique, what it does and why it is used here.

def shipped_card(self, key: str) -> dict:

metric -> (value, low, high) measured on the shipped data, for this panel's organism.

def scorecard_html(self, s: starplast.strategies.Strategy) -> str:

The strategy's scorecard: its task's standard metrics, each explained, with the values measured on the shipped data where they exist.

def test_list(self, box) -> int:

Ask for the box's genes to be hidden together and tested. Returns how many resolved.

def load_genes_file(self, box, path: str = '') -> int:

Fill a gene box from a file. Returns how many identifiers were read.

def fill_example(self, box) -> int:

Fill a gene box with a known category's members, so a list strategy can be tried.

def fill_from_gate(self, box) -> int:

Fill a gene box with the genes gated on the map.

def settings(self) -> dict:

The current form as the keyword arguments the strategy takes.

def set_setting(self, name: str, value):

Set one parameter's control -- for scripting the panel and for tests.

def use_tuned_settings(self) -> dict:

Fill the form with the calibrated best setting; returns what was applied.

A value the form cannot hold (an option this table lacks) is skipped and said, rather than failing the rest -- calibration ran on the shipped table and a user's may differ.

def run_current(self):

Run the selected strategy with the current settings.

def test_current(self):

Run the selected strategy's self-test with the current settings.

def stop_running(self) -> int:

Ask every job this panel started to stop. Returns how many were asked.

def frame(self, index: int) -> pandas.DataFrame:

The whole frame behind result table index, not only the rows on screen.

def show_result(self, result: starplast.strategies.StrategyResult):

Put a finished run on screen: its summary, its tables, and a way to see its map.

def show_test(self, test: starplast.strategies.TestResult):

Put a finished self-test on screen, leading with its verdict.

def show_on_map(self) -> bool:

Send the last result's map and clusters to the central view.