Skip to content

OncoPrint and plots at scale: positional assembly, concurrent and batched fetches - #81

Closed
alisman wants to merge 1 commit into
masterfrom
session/performance
Closed

alisman wants to merge 1 commit into
masterfrom
session/performance

Conversation

@alisman

@alisman alisman commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

OncoPrint and plots measured at large scale (the 52k-sample study, the 5 largest, GENIE + 5 largest at 409k patients, 50 and 312 studies) and made faster where the time actually went. The browser was never the cost: at 409k patients the binary contract decodes in <1 ms and draws in 45–107 ms.

OncoPrint, first request (engine, alternating runs against master)

case before after
msk_impact_50k_2026, 48k patients 1.4–1.9 s 1.3–1.5 s
5 largest studies, 166k patients 3.8–5.0 s 2.5–2.7 s
GENIE + 5 largest, 409k patients 10.8–13.9 s 7.5–8.2 s
50 studies 5.6–6.0 s 3.4–3.8 s
312 studies 14.7–17.4 s 4.5–5.6 s
  • Positional assembly. Every row used to be found by its column-id string (and multi-study ids were rebuilt per row). buildContract now looks each id up once and hands assembleIndexed rows by position; assembleContract keeps its interface as an adapter (CLI, local tables, Python conformance). Hot loops split into their own functions, so V8 optimises them.
  • Fetches start together (clinical, heatmaps, overlays, derived rows, annotation); the annotation reuses the cached OncoKB pin and reads only driver rows.
  • Whole-study fetches batched (batchStudies): small studies share a statement up to 25,000 samples; a big study keeps its own (one statement over six huge studies measured slower).
  • Panel coverage computes per-panel masks first (195 → 86 ms at 48k).

Plots and the analysis

  • Pooled box plots skip the point fetch that the cap would discard, and check every study's axes up front — a refusal at 312 studies: 3.2–6.2 s → 0.7–1.2 s.
  • Coverage runs beside the second round of queries; a single-study scatter asks for its coefficients beside its extent.
  • Profiles loaded for all studies at once; import dates in one statement per connection (312 queries / 3.1 s after the views, gone).
  • Not shipped: a UNION ALL request per statement kind — measured as slow as serial, as PERFORMANCE.md §3c found for the other views. A 312-study plot is still its own 1,248 queries (11–25 s). Two levers, both decisions rather than code: CLICKHOUSE_MAX_INFLIGHT=16 (view 19.4 → 12.2 s; 32 gains nothing more), or compiling an axis for many studies in one statement (against invariant 3). Recorded in PERFORMANCE.md §3e.

Verified

  • OncoPrint contracts identical to master (sha256 without timings) for 13 specs: heatmaps, VAF, generic assay, clustering, overlays, derived rows, merged and sample-level tracks, cohort groups, 409k patients, five refusals; both analysis-route oncoprint views identical.
  • Plot results equal to master in canonical form (master's own point order and float sums vary run to run — checked against itself) for 11 documents, plus 50 and 312 studies.
  • View snapshots re-recorded (queries changed); only diffexpr moved, in the 15th–17th significant digit of warehouse-computed sums.
  • Full gate: unit, lint, Python, check:portal 619/619, check:pooled 68/68, cohort logic, examples/method scripts, e2e.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Hptav8P2gBZUQtEUT6389d

…ched fetches

OncoPrint (lib/oncoprint.ts, lib/oncoprint-assemble.ts):
- buildContract meets each column id once, in a per-study map, and hands the new
  assembleIndexed rows by column position. assembleContract keeps the id-keyed interface
  (CLI, local tables, Python conformance) as an adapter onto it. Assembly at 166k patients
  2.1-2.6s -> 0.6-0.7s; at 409k 5.4-7.0s -> 1.7-2.2s. The hottest loops are their own
  functions, so V8 optimises them whole.
- Every study's fetches start together: clinical tracks, heatmaps, overlays, derived rows
  and the driver annotation no longer wait for the alterations. The annotation reuses the
  cached OncoKB pin and reads only driver rows.
- Whole-study fetches (alterations, coverage, profiled-for, clinical, every column) take a
  list of studies and run one statement per batch (batchStudies: small studies share one up
  to 25,000 samples, a large one keeps its own). 312 studies 14.7-17.4s -> 4.5-5.6s.
- Panel coverage computes each panel's mask before joining samples.

Plots and the analysis:
- A pooled box skips the point fetch when its own count is past the cap (exact), and checks
  every study's axes up front instead of as a side effect of that fetch: a refusal at 312
  studies 3.2-6.2s -> 0.7-1.2s. Coverage runs beside the second round; a single-study
  scatter asks for its coefficients beside its extent.
- The analysis loads every study's profiles at once (studyProfilesMany) and lists import
  dates in one statement per connection (studiesImported): 312 queries after the views, 3.1s,
  gone.
- A UNION ALL request per statement kind was built for plots and measured as slow as serial
  (as PERFORMANCE.md 3c found for the other views); not shipped. What is left is recorded in
  PERFORMANCE.md 3e.

Verified: contracts identical to master (sha256 without timings) for 13 specs incl. heatmaps,
VAF, generic assay, clustering, overlays, derived rows, merged/sample tracks, cohort groups,
409k patients and five refusals, plus both analysis-route oncoprint views; plot results equal
in canonical form (master's own point order and float sums vary run to run) for 11 documents
up to 50 studies and at 312. View snapshots re-recorded (queries changed); only diffexpr moved,
in the 15th-17th digit of warehouse-computed sums. Full gate passes (check:portal 619/619,
check:pooled 68/68, e2e).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hptav8P2gBZUQtEUT6389d
@vercel

vercel Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
cbiolab-genie Ready Ready Preview Oct 27, 2026 8:35am UTC
cohort-lab Ready Ready Preview Oct 27, 2026 8:35am UTC

Request Review

This branch was successfully deployed

1 active deployment
Preview – cohort-lab — 8ffbc82d Deployed Oct 27, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant