How a molecule becomes a spectrum

The data

What exactly is in train.parquet and test.parquet, and what is the hidden test really like?

Eleven source libraries, enveda-180, the decoy test set, the metric's fine print, leakage and domain shift.

Anatomy of train.parquet

Computed from the official Kaggle download on 2026-10-07. 2,539,608 spectra of 275,810 distinct structures (51,291 formulas) from eleven libraries. Blue marks what was acquired on the hidden test's instrument.

1213 / 1213
visible test rows that are verbatim enveda-180 training rows — the visible test is a decoy
1,154,969
timsTOF spectra in train, all from Enveda's two libraries (183,191 structures)
250
natural-product structures measured on timsTOF (enveda-np-examples) — the only honest proxy for the hidden test, and every one also exists in a public library
65 %
of training precursors fall inside the test's 245–460 m/z window
1.5 ppm
median precursor mass error; 90 % within 5 ppm, 93 % within 10 ppm — the rest are mislabeled adducts or formulas
6
median spectra per structure (max 1,468); 25 % of structures have ≤ 4
Spectra per source library
enveda-180
1,153,785
pluskal_ms2
527,581
riken
347,171
gnps
220,849
massbank
101,727
mona
92,416
spectraverse
50,933
msdial
40,765
drug_plus
2,545
enveda-np-examples
1,184
masaryk
652
Distinct structures per source library
enveda-180
182,941
pluskal_ms2
46,821
riken
15,892
gnps
45,750
massbank
9,180
mona
11,681
spectraverse
9,631
msdial
9,127
drug_plus
2,539
enveda-np-examples
250
masaryk
416
Structures found in no other library
enveda-180
180,653
pluskal_ms2
28,738
gnps
24,823
spectraverse
9,537
massbank
1,705
riken
1,319
msdial
566
mona
185
drug_plus
159
masaryk
12
Instrument label (top 10 of 82)
timsTOF
1,154,969
Orbitrap
745,562
QTOF
125,936
LC-ESI-QTOF
104,482
ESI-QFT
77,342
LC-ESI-QFT
55,024
LC-ESI-ITFT
45,109
qTof
33,777
ToF
26,535
qtof
26,111
Adduct (top 12 of 121). Note the dimers [2M+Na]+ and [2M+H]+: 280 k spectra whose precursor is twice the molecule
[M+H]+
1,324,585
[M-H]-
465,688
[2M+Na]+
190,033
[M+Na]+
178,092
[2M+H]+
92,041
[M+CH2O2-H]-
83,188
[2M-H]-
56,172
[M+NH4]+
53,452
[M+Cl]-
27,511
[M-H2O+H]+
21,682
[M+K]+
18,955
[M]+
8,818
Collision-energy pattern (top 10)
40
377,509
not recorded
337,443
60
322,682
merged 20/40/60
304,863
20
276,708
10
60,815
80
19,314
30
15,581
6
13,344
50
9,707
How collision energy was recorded (eV vs normalised NCE vs unknown)
eV
1,368,908
NCE
789,066
unknown
325,078
V
56,556
Precursor m/z, 25 Da bins; test window highlighted
100–125
10,706
125–150
23,315
150–175
36,568
175–200
45,973
200–225
47,892
225–250
54,758
250–275
120,307
275–300
186,604
300–325
328,354
325–350
409,792
350–375
215,226
375–400
161,390
400–425
93,953
425–450
85,289
450–475
54,539
475–500
43,301
500–525
33,003
525–550
32,103
550–575
33,090
575–600
41,178
600–625
43,744
625–650
53,594
650–675
56,699
675–700
71,318
700–725
56,100
725–750
38,101
750–775
31,268
775–800
29,206
800–825
21,295
825–850
14,445
850–875
10,895
875–900
8,742
900–925
6,270
925–950
6,036
950–975
5,860
975–1000
3,708
1000–1025
1,672
1025–1050
1,800
1050–1075
2,089
1075–1100
2,777
Median |precursor mass error| by library, ppm
spectraverse
0.65 ppm
enveda-180
0.98 ppm
msdial
1.47 ppm
masaryk
1.48 ppm
enveda-np-examples
1.65 ppm
pluskal_ms2
1.66 ppm
gnps
1.67 ppm
drug_plus
1.73 ppm
mona
1.8 ppm
massbank
1.95 ppm
riken
3.75 ppm
Structures containing each element (top 10)
H
275,806
C
275,801
O
268,565
N
255,569
S
70,611
F
51,421
Cl
29,848
Br
8,522
P
5,330
I
369

train.parquet from Kaggle (official download 2026-10-07), metadata columns only. Full tables: research/_meta/train_eda.md.

The queen's digest

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

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

  • The visible test is a random 400-structure draw of enveda-180 plus two row rules: no dimer adducts; monomer rows thinned to 66.7 % (0.71 positive / 0.53 negative). The cited "245–460 m/z window" is the Enamine HLL-200 mass band (99.67 % of enveda-180 monomers already lie in it), not an organiser filter — never prune pools or folds to it.
  • Decoy chemistry says nothing about the hidden set: 0/400 decoys in COCONUT, NP_Score −1.47, 36 % halogenated. The only NP-on-timsTOF proxy is enveda-np-examples (250 structures, 249 in COCONUT, all also present in other libraries on other instruments — a leak unless removed by InChIKey14 across every library).
  • The shipped precursor_error_ppm is an artefact: absolute, electron mass omitted, computed before a formate relabel (52,460 rows show ~2,400 ppm). Seven of 11 libraries ship a computed, not measured, precursor m/z. Recomputed timsTOF error is truncated at 5.13 ppm in enveda-180 and reaches 21 ppm in np-examples.
  • The metric is reproducible and a near no-op for database SMILES, but canonicalisation changes 12–17 % of NP keys, is stereo-dependent for 0.45 % and non-idempotent for 0.3 %; pre-canonicalise and dedupe the 25 slots with pinned RDKit 2026.03.3.
  • A validation recipe with real fold sizes exists: heldout_A = 1,977 structures / 13,556 timsTOF spectra (250 np-examples + 1,727 NP-like enveda-180); heldout_B = 293 strict database NPs; always report a spectrum-blind baseline (PubChem default order = 49.98 % hit@1 on MassSpecGym).

New concrete facts (file; source count; confidence)

  1. 1,213/1,213 test rows join uniquely to enveda-180 on (precursor_mz, num_peaks, base_peak, adduct); 400 ids → 400 InChIKey14; 395 exist only in enveda-180. [test_set_decoy…; computed; high]
  2. Structure selection is random (all stats within the 95 % band of 2,000 random 400-draws); row selection is not: 0/664 dimers kept, 1,213/1,818 monomers kept, keep-rate 0.59→0.71 across base-peak quintiles. [same; computed; high]
  3. 99.67 % of enveda-180 monomer rows lie in 245–460 m/z; 42 % of np-examples structures lie outside it. [same; computed; high]
  4. Hidden-set size: press release ~2,500 spectra vs Kaggle mirrors ~1,500 (1–16/molecule, median 3). 2,500/400 = 6.25 = enveda-180 all-adduct mean; 1,500/400 = 3.75 matches a monomer-only thinned set. "157–1,159 Da" not found verbatim. [same; 2 sources; medium / low]
  5. Train ∩ COCONUT = 26,111 of 275,810 IK14 (9.47 %); enveda-180 51/182,941; np-examples 249/250; the 9 public libraries hold 95,157 IK14 of which 26,068 are COCONUT — the whole "NP with a train spectrum" universe, none on timsTOF. COCONUT Oct-2026: 738,794 rows → 479,690 IK14. [_coconut_overlap…json; computed on standard keys; high]
  6. adduct_orig is already a Hill-formula rewrite (123 strings); mapping to adduct injective except [M+CH2O2-H]- ← {[M+CH2O2]- 52,460; [M+CHO2]- 30,728} and [M]+ ← [Cat]+. Polarity contradicts adduct sign in 6,087 rows (riken ion trap 4,870; gnps 441, of which 275 are truly [M−H]− by mass). [adducts…; computed; high]
  7. Shipped ppm = |error| without electron mass (reproduced to 0.2 ppm for 88–100 % of rows per library; r = −0.02 with true signed error); only np-examples is signed and correct. precursor_mz equals theory in pluskal 99.3 %, msdial 96.5 %, drug_plus 93 %, massbank 76 %, mona 69 %, spectraverse 60 %. [adducts…; computed; high]
  8. Recomputed timsTOF ppm: enveda-180 |ppm| ≤ 5.13 (99.98 % within ±5, 98.1 % within ±4), +1.9 ppm positive-mode bias; np-examples [M+H]+ p90 3.38, max 8.7; [M−H]− max 21.1. Per-adduct table in .json. [adducts…; computed; high; bias cause unverified]
  9. CE: eV = NCE·m/z/500·f(z), f = 1/0.9/0.85 (99.8 % reproducible); eV lists sorted ascending, orig in acquisition order (misaligned for 69 % of pluskal multi-CE rows); MassBank ramps collapsed to first value; GNPS/drug_plus/masaryk 100 % null CE; enveda-180 negative-mode CEs negative in orig. [adducts…; computed; high]
  10. Merged 20/40/60 rows are per-m/z sums (merged base peak / sum of singles' median 1.00), 258 vs 116 median peaks, floor 3.5× lower; 26.6 % of enveda-180 and 24.6 % of test rows merged, 68.5 % of test molecules have one; np-examples use ";" lists and 35/50/80 eV. [adducts… + test_set…; computed; high]
  11. Intensity floors are library barcodes (MassBank 1/999, MS-DIAL 0.01, RIKEN 0.01/0.005, pluskal ~7e-5, timsTOF none); base_peak_intensity null in exactly the 7 public libraries; 46 % of enveda-180 spectra have peaks above precursor + 0.5 Da. [adducts…; computed; high]
  12. Metric = MolFromSmiles → TautomerEnumerator().Canonicalize → MolToInchiKey[:14], no salt strip; 2026.03.3 ≡ 2026.03.6 on all tests; 12–17 % NP keys change; one third of NPs > 40 heavy atoms hit the 1,000-transform cap. [metric…; 3 write-ups + 1,056 local cases; medium — official notebook unopened]
  13. enveda-180 = Enamine HLL-200 on timsTOF Pro 2, PASEF, 20/40/60 eV, 77 % ESI+, Zenodo 10.5281/zenodo.20436851 (29 May 2026), 1,158,293 spectra / 184,330 compounds; train has 4,508 fewer. [enveda180…; high]
  14. Community-library audits: ~1–2 % wrong 2D structure, ~6–7 % precursor/adduct inconsistency; train ships 62,834 rows beyond 20 ppm uncleaned while the hidden test had precursor-inconsistent spectra dropped. [train_libraries…; medium]
  15. Domain shift: MassSpecGym MIST 14.64 % hit@1 (random 0.37 %); audit arXiv 2606.19624: spectrum-blind 49.98 % hit@1, formula leak 30×, no cross-library evaluation; King 2022 85 % cross-instrument vs 88–95 % same; CASMI-26 write-ups 0.867 local → 0.017 MRR on novel molecules; library search 0.098 on LB. [test_set…; 5 sources; medium]

Forced analogies — what the chain-of-custody lens produced

  • "The planted exemplar betrays the workshop" (test-set) — paid off twice. Separated real organiser rules (no dimers; positive-biased thinning) from folklore (the 245–460 window is the paper stock, not the forger's choice). Broke on chemistry: the decoy was cut from a different population, so its composition is zero evidence about the hidden set. Over-reading risk: if the hidden set has 2,500 rows, the no-dimer inference fails.
  • "Custody log of a number" (adducts) — paid off strongly. "Who computed this and when" exposed the ppm artefact and the 7 computed-m/z libraries. Breaks where a custody break is mass-neutral (string cosmetics) vs mass-changing (one proton in the formate relabel); only the latter changes the candidate pool.
  • "Exemplar collection vetting" (provenance) — partial. Gave a per-source custody score and a two-witness disagreement test; but libraries fail by honest one-hop mislabeling, not tampering, and custody says nothing about instrument shift.
  • "ACE-V fingerprint protocol" (metric) — paid off. Led to measuring the protocol's instability and a cheap hedge (submit stereo and flat forms when they disagree).
  • "Same protocol vs same population" (enveda-180) — paid off: instrument-proxy passes, chemistry-proxy fails.
  • Dud: reading the decoys' 36 % halogen fraction as a hint about hidden-set elements; the random-draw test killed it — the halogens are Enamine's.

Contradictions within my subdomain

  • Hidden-set size 1,500 vs 2,500 — decides whether dimers and the thinning operator matter.
  • np-examples COCONUT overlap "8 of 250" (one write-up) vs 249/250 (computed); the 8 is a keying error, but nothing has yet been recomputed with the competition canonicalisation.
  • Provenance worker's "drop |ppm| > 20" rule would delete 96 % of pluskal negative-mode formate rows because the shipped column is wrong, not the data. Superseded: recompute ppm, then filter.
  • Full 157–1,159 Da range recommended by one worker, unverifiable by another; keep wide (np-examples 42 % outside 245–460), label bounds low-confidence.
  • np-examples 1,184 spectra (file) vs 1,151 (Kaggle page).

Gotchas for the modeler

  1. A fold shaped like the decoy learns Enamine amides; empirical transfer 0.456 local → 0.112 LB.
  2. np-examples leak through other instruments — remove by InChIKey14 across all libraries.
  3. Library barcodes (intensity floor, base-peak null pattern, CE null pattern, computed m/z) let a model learn library instead of molecule.
  4. Shipped ppm is absolute, electron-free, 1 Da wrong on 52k rows; naive filters delete good spectra.
  5. Merged spectra are sums; 60 eV-only peaks are down-weighted; parsers must accept "," and ";" and signed CEs; 1,942 two-CE merges are junk.
  6. 46 % of timsTOF spectra carry peaks above the precursor; trim identically in train and test.
  7. The 7-adduct list is a sample ([M−H2O+H]+ occurs in np-examples).
  8. Metric: unparsable-guess behaviour unknown; stereo-dependent keys; transform cap on large polyphenols; submit single-fragment SMILES.
  9. enveda-180 row-level near-duplicates leak through random row splits.
  10. If the thinning was applied to the hidden set, negative mode is ~1.3× under-represented.

Questions for other queens

  • q6: with −4/+5 ppm instead of ±10, COCONUT window sizes in 250–460 and 460–1,160 Da? Cost of a low-prior [M−H2O+H]+ hypothesis?
  • q1_instrument_physics: cause of a +1.9 ppm positive-only offset on timsTOF Pro 2? Do PASEF merges sum or average microscans?
  • q5_methods_lineage: which pre-trained encoders were trained on summed multi-CE spectra vs single-CE?
  • q7_compute_execution: can the Kaggle discussion settle 1,500 vs 2,500 spectra and dimer presence?
  • q4_challenge_intelligence: did CASMI-22 rules define "precursor-inconsistent spectra dropped"? The same filter likely shaped this hidden set.

Layman sentences

  1. The practice test is a copy of training data from a drug-screening library: it shows the file format but nothing about what the real test molecules look like.
  2. Several numbers in the training file, including "how far off is the measured mass", were produced by a script that made mistakes we must undo before trusting them.
  3. The real test is natural products on one Bruker instrument; training has only 250 such molecules, so we must build our own fair exam and always compare against a baseline that never looks at the spectrum.

Gaps I could not fill

  • Official metric notebook and Kaggle data page not opened directly; protocol reconstructed from three write-ups.
  • Cause of the +1.9 ppm offset and 5.13 ppm truncation (Enveda ms_prepper not run locally).
  • Krettler et al. 2026 ChemRxiv preprint unresolvable (403).
  • No overlap recomputed with RDKit 2026.03.3 canonicalisation (~50 CPU-h; queued).
  • MIST CASMI-2022 drop magnitude (full text 403).
  • Whether normalized_smiles carries stereo (one-line check pending).