Spaces:
Sleeping
Prompt β Add HPV (head & neck) as a second dataset, with a top-level cancer selector
Add the TCGA HNSC (head & neck) cohort and an HPV-detection objective, behind a new top-level "Cancer / problem" selector. The DSL, engine, airgap, parameters, live view, population, program graph, and result/verdict are SHARED and unchanged β only the dataset-specific config swaps (objectives, biology panel, reference sets, diagnostics, post-hoc targets). Read the named code first; don't assume. Do this in two stages.
GUIDING PRINCIPLE: the engine is single. Everything that changes per cancer is config around it.
================================================================= ## STAGE 1 β Backend: the HNSC dataset + HPV objective
1a. Data pipeline (the main lift)
- FIRST verify the data source: confirm the cBioPortal TCGA HNSC study id and that its clinical data carries HPV status (HPV+/HPVβ). Mirror the COADREAD provenance approach documented in CLAUDE.md (LFS-resolved media URL). State the study id + HPV field you used.
- Build a second processed cohort alongside the colorectal one: HNSC
expression.parquet+clinical/labels including anhpv_statuslabel (HPV+ / HPVβ), restricted to samples with a called HPV status and complete expression. Put schema constants (anHNSC_PROCESSED_DIR, HNSC filenames, the HPV-status column + how +/β is derived) indata_pipeline/schema.pyβ do not hardcode in build. Ensure the build writeshpv_statusinto the labels socohort.labels["hpv_status"]exists after Load. - LOADING β IMPORTANT:
dsl.Load(operators.py ~line 62) only schema-resolves the exact string"processed"; ANY other string is treated as a literal directory path. So do NOT writeLoad("processed_hnsc"). Instead, EITHER (a) extendLoadto map named sources ("processed"βCOADREAD dir,"processed_hnsc"βschema.HNSC_PROCESSED_DIR), OR (b) pass the HNSC directory Path straight toLoad(hnsc_dir)β Load's existingelsebranch already loads any directory containing clinical.parquet + expression.parquet, so option (b) needs no change to Load.
1b. Objective
- Add a binary objective for HPV: spec
{ target: "hpv", metric: "auroc" }, reusing the SAME orientation-agnostic binary-AUROC machinery as MSI. Concretely: extendV2Objective.target(currentlyLiteral["msi","tmb","none"]) to include"hpv"withbinary=True; route itsscore_vectorthrough the AUROC path andworst_scoreβ0.5 (identical to MSI); add anHPV_OBJECTIVEand dispatchhpv+aurocinengine_v2.fitness.objective_from_spec. No new operators.
1c. Data loading per (dataset, target)
_prepare_lab_data(api/app.py ~line 177) is currently keyed by target and always usesLoad("processed")(colorectal). Generalise it to key by (dataset, target): add adatasetargument; fordataset="hnsc", target="hpv", load the HNSC cohort, anonymise its expression, and sety= (hpv_status == HPV+). Keep colorectal (dataset="coadread", msi/tmb/none) exactly as-is.
1d. API
RunRequestgains adataset: strfield (default "coadread")._workerpasses it through to_prepare_lab_data. Validate dataset+objective combinations (e.g. hpv only valid for hnsc; msi/tmb only for coadread).REFERENCE_SETS(api/app.py ~line 106) becomes per-dataset: colorectal keeps MMR/immune; HNSC gets HPV reference sets β e.g."HPV_markers"= {CDKN2A, β¦} and a"cell_cycle"/ E2F-target set (define from a small curated list in one place, like MMR_GENES)./evaluateand any diagnostics select the reference sets for the active dataset.- Diagnostics: the MSI/TMB-rank diagnostics are colorectal-specific β gate them to that dataset; HNSC can have its own (or none) for now.
- Airgap unchanged: anonymise HNSC expression; HPV status is a label (target), never a gene name. Extend the airgap tests to the HNSC path (no gene-symbol leak).
================================================================= ## STAGE 2 β Frontend: cancer selector + per-dataset config + full "?" coverage
2a. Top-level Cancer / problem selector
- Add a segmented control (same style as the Objective control) ABOVE the Objective row: Colorectal (TCGA COADREAD) | Head & Neck (TCGA HNSC). (No side "what swaps" panel β that was mockup annotation only.)
- Drive everything from a dataset registry: each entry =
{ label, dataset_id, objectives, biologyPanel, referenceSets, diagnostics, postHocTargets, axisLabels }. The page renders the selected entry's config around the unchanged engine. Selecting a cancer setsdataseton the run request and swaps the objective options, biology panel, reference sets, and diagnostics.
2b. HPV biology panel β include the schematic
- Add a "What is HPV? (the biology)" collapsed-by-default disclosure, mirroring the existing "What is MMR?" panel EXACTLY (same collapsible pattern). Embed the HPV reference SVG from repo root
hpv_reference.svg(already created) verbatim, responsive (width 100%, height auto). Show it for the Head & Neck dataset; show the MMR panel for Colorectal.
2c. HPV objective + rich "?" explainer
- Add the "HPV detection" objective card for the HNSC dataset (objective spec
{target:"hpv", metric:"auroc"}), plus "Unsupervised" (same engine). - Give it the SAME rich click-to-open ParamHelp modal as the other objectives, in plain English (no assumed knowledge). Content: what it optimises ("a score that separates HPV+ from HPVβ tumours"); how it's scored (AUROC: 0.5 = coin-flip, 1.0 = perfect; minority ~15β25% HPV+, so AUROC not accuracy); represented as
{target: hpv, metric: AUROC}; and the honest note that this is detection/recovery of a known viral signature (p16/CDKN2A, cell-cycle), not new causation. Use the same intro/footer pattern as the other objective modals.
2d. Full "?" coverage β every objective, parameter, result metric, and chart axis
This is a hard requirement, including for HPV:
- Objectives: all have rich "?" explainers (above).
- Parameters: shared engine β the existing ParamHelp "?" already cover them; no change.
- Result metrics (Held-out, Permutation p, Nodes, Genes) and the verdict / post-hoc "?" and inline text must be objective-aware and read correctly for HPV (held-out = AUROC separation of HPV+/β; the post-hoc/verdict framing is the supervised one β "real and useful" vs "not reliable" β NOT the unsupervised two-questions framing).
- Charts: the fitness-curve y-axis label + its "?" for the HPV objective = "separation (AUROC)" with the AUROC explanation (same as MSI). Ensure the objective-aware label/tooltip records include the
hpvcase. - All "?" text in plain English explaining the concept, consistent with the rest of the Lab.
2e. Reveal & evaluate
- For HNSC, the reference-set toggle shows the HPV sets (HPV_markers / cell_cycle) instead of MMR/immune; overlap + reveal work the same way. Expected win: revealing the winner shows it recovered CDKN2A/p16 + cell-cycle genes.
CONSTRAINTS
- Colorectal behaviour, airgap tests, and existing runs unchanged.
- The engine / DSL / parameters / live view / population / program graph are identical across datasets β only config swaps.
Checkpoint
After Stage 1: a CLI/API HPV run on HNSC completes and separates HPV+/β (held-out AUROC should be high). After Stage 2: the cancer selector swaps to Head & Neck, the "What is HPV?" schematic shows, an HPV run gives a strong held-out AUROC with a plain verdict, and reveal recovers p16/CDKN2A + cell-cycle genes. Airgap tests green; colorectal unchanged.