How a spectrum becomes a molecule

The plan

How do we actually run this in ninety days with the compute we have?

Kaggle notebook constraints, Explorer and Modal, a validation set that does not lie, lessons from sibling projects, milestones and kill criteria.

The queen's digest

5/5 workers reported · Tue Oct 06 2026 20:00:00 GMT-0400 (Eastern Daylight Time)

Queen digest — compute, pipelines, validation design, submission mechanics, timeline

TL;DR (5 bullets a chief of staff would read)

  1. The data is now on disk and the competition is machine-readable. A worker downloaded train.parquet (3,033,286,496 B) to C:\Temp\casmi26\data\. The installed Kaggle CLI 2.2.4 answers authoritatively where the JS-rendered site cannot: is_kernels_submissions_only=True, max_daily_submissions=5, merge deadline 2026-12-07, final 2026-12-14 23:59, 2,672 teams. We went from 403-Forbidden to userHasEntered=True during this tick.
  2. Every timsTOF spectrum in training is Enveda's own. 1,154,969 timsTOF rows = 1,153,785 enveda-180 (synthetic Enamine chemistry, ~0.03 % in COCONUT) + 1,184 enveda-np-examples (250 NP structures, zero of them exclusive — all also appear in GNPS/MassBank/RIKEN). So "timsTOF and natural product and structure-disjoint" has exactly 250 candidate members. There is no clean instrument-matched NP hold-out; we must substitute QTOF.
  3. The public leaderboard cannot discriminate in the medal zone. Full LB pulled today: 2,673 teams, max 0.480 (not the brief's 0.471), median 0.328. 263 teams score ≥0.42 but only 35 ≥0.43 — a 228-team pile-up inside one 0.01-wide band. Treat any public-LB delta below ~0.01 as noise. But it is not scored on the decoy test.parquet: library search would saturate it, and nobody is near 1.0.
  4. Compute is not the bottleneck; candidate coverage is. A 25 M-param peak-token transformer is ~2 min/epoch on one H200, ~$10 for 50 epochs on Modal. Meanwhile a random ranker's MRR@25 is exactly H₂₅/n = 3.816/n, so pool size is a first-order multiplier on the score. Spend the quarter on the pool, not on the GPU.
  5. Our own confidence will not rank our own candidates, and the cascade is a trap. Both sibling challenges found within-item confidence ρ ≈ −0.03. Independently, the eyewitness ROC literature overturned "sequential superiority". Both point the same way: fuse simultaneously, gate only for cost, and route with a calibrated absence detector rather than ranker self-confidence.

New concrete facts

  1. Peak statistics, measured on the real file (explorer_modal...md, pyarrow 25.0.1): 401,806,233 peaks; mean 158 / median 42 per spectrum; p99 1,347; max 73,318. 85.5 % of peaks are <1 % of base peak; 95.2 % lie in m/z 50–1000. In-RAM 6.45 GB as pyarrow, 25.7 GB as Python float lists (the notebook-OOM case), 0.80 GB as a flattened float16 offset array clipped to top-100. Dense 0.01 Da bins would be 482.5 GB — sparse only. Confidence: high (measured).
  2. Corrupt rows exist: precursor_mz max = 2,430,333. Any pipeline that trusts the precursor blindly will ingest garbage. 1 file. High.
  3. RDKit chain of custody is a smaller risk than feared, and I can say why. (kaggle_code...md + my own measurements.) Canonicalize() calls pickCanonical() on whatever partial set exists when the maxTransforms=1000 cap is hit — no status check, no warning — with a lexicographic canonical-SMILES tie-break. The cap IS hit on polyphenols (quercetin 363 tautomers/179 ms, rutin 357 ms, tetracycline 287 ms) versus 0.2–6 ms for caffeine/morphine/erythromycin. But: raising the cap 1000→20000 changed zero of 8 polyphenol InChIKey14s; the bundled InChI has been 1.07.3 since 2024.09.6; no listed change between 2026.03.3 and .6 touches the transform table or scoring; and canonicalisation is a no-op for database-derived SMILES (my 8-molecule canary reproduces the standard keys exactly, and is input-order stable over 12 randomized SMILES each). Residual exposure is concentrated in de-novo-generated SMILES in odd tautomeric forms. 2 files, ~6 sources. High on the measurements, medium on the cross-version claim.
  4. Kaggle environment: image is Colab-based, Python 3.13, numpy 2.1.3, no RDKit — it must be vendored. rdkit==2026.03.3 cp313 manylinux_2_28_x86_64 wheel = 37,187,145 B, uploaded 2026-06-05, Requires-Dist: numpy, Pillow with no pins (worker downloaded it). Re-run limit "≤9 h, internet off, external public data and pretrained weights allowed" is from a GitHub mirror of the rules page — medium, not verified on Kaggle itself.
  5. Explorer reality check (my own sinfo/scontrol/squeue): gyorilab = one node d4079, 4×H200, 773 GB RAM, MaxTime 30 days vs 8 h on the public gpu partition — but AllocTRES shows all 4 GPUs allocated, three to jobs running 26 d / 11 d / 11 d against 30-day limits. Public gpu has 4×(8×H200) and a 104-pending vs 52-running backlog. /scratch is 91 % full. High.
  6. Pool-size evidence is real but non-monotonic. CSI:FingerID top-1 68.5 % → 34.4 % (biodatabase → PubChem, PMC4611636); MetFrag fragmentation-only 22 % → 6 % (PMC4732001). Counter-evidence: CASMI 2016 (PMC5368104), the only study binning by actual candidate count, found performance worst at 200–1,000 candidates and better both above and below — formula size confounds pool size. Also: metadata use moved 34 % → 70 %, beating every model improvement in that contest. Medium-high.
  7. Fusion: quality-weighted RRF, k=60 (flat over k=10–100: MAP .2134→.2147, Cormack SIGIR 2009, read in full) — but CombMNZ beat RRF in Cormack's own LETOR 3 table (.6107 vs .6051), so a bake-off is mandatory. Borda's PXR failure is mechanistically explained: linear-in-rank weighting lets one engine veto a candidate at rank 400 of 1,000 when only the top 25 are ever scored. High.
  8. Submission effort profile (my LB pull): median submissions used is 54 for teams ≥0.44 (n=12), 22 for the 0.42–0.43 band (n=228), 3 for teams <0.30. Leaders average ~2.3/day, not the permitted 5. 2,541 of 2,673 teams are solo. High.

Forced analogies — what the eyewitness-line-up lens produced

Paid off.

  • Filler fairness → a pool-first discipline. "A line-up is biased when the fillers don't match the witness's description" became a measurable profile (candidates/query, Tanimoto(true, nearest decoy), mass-window width) and the rule fix the pool before fixing the ranker.
  • Target-absent line-ups. ~45 % of hidden molecules never reach top-25, i.e. the culprit is not in the line-up. This reframes the biggest single loss as a detection problem and yields a calibrated absence detector that reallocates slots to a second generator.
  • CAC curves / "pristine conditions" (Wixted & Wells 2017) → a concrete acceptance gate: monotone CAC, ECE ≤ 0.05, AUROC(absence) ≥ 0.8 before confidence is allowed to drive any decision.
  • The mock-witness test — the single cheapest new experiment the lens produced: train on precursor m/z + formula + adduct only, no MS2. If that beats H₂₅/n on our pools, we are harvesting line-up bias, not spectral evidence.
  • Chain of custody → the version-canary protocol in fact 3.

Duds, kept honestly.

  • Sequential line-ups. I expected this to argue for a cascaded ranker. It argues the opposite: the sequential-superiority effect was overturned once Gronlund/Wixted/Mickes replaced diagnosticity ratios with ROC analysis. Cascade ranking (SIGIR 2011/2017) agrees — gating buys compute, not accuracy. Use the cascade for cost only.
  • Double-blind administration. Breaks: we are one human plus agents, and unlike a witness we can resubmit. Only the pre-registration half survived, as prereg_template.md.
  • MRR@25 charges nothing for a false pick, whereas a wrong line-up identification is catastrophic. The cost asymmetry that drives the whole eyewitness literature simply does not exist here.

Contradictions within my subdomain

  1. "Bigger pools hurt" is supported but incomplete. CSI:FingerID/MetFrag say monotone decay; CASMI 2016 says non-monotonic, worst at 200–1,000, confounded by formula. Any pool-size experiment we run must control for molecular formula or it will measure chemistry instead.
  2. Consensus strength is unstable. The sibling digest's "+0.038" is, at source, +0.0380 at reference depth 7 with ρ = −0.258. Adding a weaker engine halved it (+0.0380 → +0.0178). And consensus is a catastrophe detector, not a fine-ranker: ρ = −0.763 where 19.2 % of poses were catastrophic vs −0.258 where 0.2 % were. Orthogonality alone must not earn a seat in our fusion — engines need an admission gate.
  3. enveda-180: drop it or keep it? The filler-selection lens says it is biased chemistry (0.03 % COCONUT). The data says it supplies 99.9 % of all timsTOF spectra — drop it and we lose the instrument entirely. Resolution: re-weight, do not drop; separate the instrument signal from the chemistry signal (runs R0–R6).
  4. Public LB meaning. My pile-up statistic says it cannot discriminate; the 90-day worker argues it is an unbiased but noisy sample of the private set (SE ≈ 0.02–0.04). Both can be true and both imply the same rule.

Gotchas for the modeler

  • to_pandas() on the list columns costs 25.7 GB in a 29–32 GB Kaggle session. Use pyarrow or a flattened layout.
  • A corrupt precursor_mz of 2,430,333 exists. Filter before trusting mass windows.
  • Canonicalize() silently truncates at the cap and reports nothing. Log enum_status per candidate.
  • Tautomer-canonicalising a million-candidate pool is infeasible at 180–360 ms/molecule for flavonoids. Canonicalise unique structures only (train 275,810; COCONUT ≈480 k), cache, and never do PubChem wholesale.
  • Holding out the 250 NP timsTOF structures requires deleting their rows from every library, not just one.
  • 39 % of "independent" opinions in the sibling project were duplicates. Dedupe before counting consensus.
  • gyorilab's 30-day queue is fully occupied by 11–26-day jobs; do not plan around it being free.
  • CRLF line endings break sbatch; rsync is broken on Explorer (use scp via xfer.discovery.neu.edu).
  • Modal is $2.10/GPU-h for A100-40GB as fetched today, not the brief's $1.40.

Questions for other queens

  • q4_challenge_intelligence (posted to rules_x_execution): what fraction of the hidden set is the public LB computed on? Every kill criterion's threshold depends on that standard error. Also confirm the 9 h re-run limit from a second source — ours is one GitHub mirror.
  • q6_candidate_space_retrieval: our pool-size experiment must control for molecular formula (CASMI 2016 found the damage non-monotonic and formula-confounded). Does your coverage math do that? And what is the measured recall@25 of a COCONUT-only pool — that is our ceiling, and my workers could only bound it.
  • q2_data_forensics: please confirm independently that all 1,154,969 timsTOF rows are enveda-180 + enveda-np-examples, and reverse-engineer the multi-CE merge function from single-vs-merged enveda-180 rows. Our whole hold-out design depends on reproducing that merge exactly.
  • q5_methods_lineage: we need ≥4 genuinely orthogonal engines with an admission gate. Which four, and how correlated are their errors? Sibling evidence says shared training data pushes ρ to ≈ +0.45.

Layman sentences

  1. We are trying to name an unknown molecule from the pattern of fragments it breaks into, and the hardest part is not the guessing — it is making sure the right answer is even on our list of suspects.
  2. Almost half the hidden molecules will never make our shortlist at all, so the biggest win is widening the shortlist, not polishing the ranking.
  3. Our practice exam is far easier than the real one, and 228 teams are currently tied within a hair of each other on a scoreboard that cannot tell them apart.

Gaps I could not fill

  • Kaggle's official docs are JS shells; GPU types (L4×4, TPU v5e), max submission size, and the 9 h re-run limit rest on third-party mirrors. Medium confidence, flagged in two worker files.
  • No public ablation of enveda-180 exists. One datapoint only: a model trained on enveda-180 alone scores 0.138 vs 0.107 random on NPs. The R0–R6 grid is designed but unrun.
  • True MFU on H200 is derived, not benchmarked — a 200-step run would settle it.
  • Whether gyorilab membership (AllowGroups=rc,gyorilab) actually admits our account is unconfirmed; we hold b.gyori and m.minkara associations but have not queued a job.
  • Fox & Shaw 1994 (CombSUM/CombMNZ original) was not opened — the fusion recommendation leans on Cormack 2009.