Skip to content

Commit 5d004d2

Browse files
committed
docs(flashlfq): add quant-aggregation rule (don't silently sum) + discoverability cross-links
New governing-principle doc: quant may NOT be summed across scan files, sub-groups, searches, or experiment conditions unless the units were co-measured in one run and are known-valid to combine (PSM count may sum; quant may not) -- covers the fraction-vs-replicate metadata gap and cross-run non-comparability. Discoverability so a memory-less session is routed to it: - CLAUDE.md: 'before you sum quant across anything, read this' pointer. - grains doc: caveat at the 'sum the search's scan files' roll-up table. - the four 2026-07-29 review docs: added to each See-also block. (A matching pointer comment at the multi-scan-file guard lives with the held quant controller code and is intentionally not committed here.)
1 parent 3f17d81 commit 5d004d2

7 files changed

Lines changed: 150 additions & 0 deletions

CLAUDE.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,16 @@ A few cross-cutting concepts that aren't obvious from the schema:
8585
show only on single-search views. For the full stack (schema → import → searchers → REST → UI) and why
8686
this matters for MS1 quant, see `limelight_features_docs/limelight_search_sub_groups_deep_dive.md`.
8787

88+
**MS1 quant aggregation — before you sum quant across anything, read this.** Whenever you write code that
89+
combines, sums, or shows a single quant/abundance number for a group of units — multiple **scan files** of
90+
one search, multiple **sub-groups**, multiple **searches**, or an experiment **condition** — read
91+
`limelight_features_docs/flashlfq_quant__do_not_silently_sum_across_scan_files_searches_conditions.md`
92+
first. Short version: **PSM count may sum across those; quant may NOT.** A quant value is a physical MS1
93+
measurement tied to one scan file and one run, so it may only be aggregated over units that were
94+
co-measured in one run and are known-valid to combine (Limelight has no fraction-vs-replicate metadata and
95+
won't). Where that doesn't hold (a multi-scan-file search, a condition spanning searches), **decline the
96+
quant — never silently sum it the way PSM count does.**
97+
8898
## Building
8999

90100
### Full project

limelight_features_docs/flashlfq_open_mod_quant_correctness_boundary_2026-07-29.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ chromatographic feature). *form / display form* = a peptidoform at the display g
2424
- `flashlfq_usage_critical_review_2026-07-29.md` — end-to-end, code-observed usage audit.
2525
- `flashlfq_open_mod_quant_deferred_mass_doublecount.md` — the deferred open-mod defects + in-code `throw`
2626
tripwires (the concrete bugs in the held prototype that this doc's "what can be correct" presupposes fixed).
27+
- `flashlfq_quant__do_not_silently_sum_across_scan_files_searches_conditions.md` — the governing rule for
28+
when quant may/may not be summed across scan files, sub-groups, searches, or conditions (PSM count may
29+
sum; quant may not).
2730

2831
---
2932

limelight_features_docs/flashlfq_open_mod_quant_deferred_mass_doublecount.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ and `flashlfq_quant_data_model_and_display_grains.md` (the deferral scope note).
2828
- `flashlfq_usage_critical_review_2026-07-29.md` — end-to-end, code-observed usage audit (non-open-mod path).
2929
- `flashlfq_open_mod_quant_correctness_boundary_2026-07-29.md` — what open-mod quant can vs. can never be
3030
correct (the ceiling a fixed implementation could claim).
31+
- `flashlfq_quant__do_not_silently_sum_across_scan_files_searches_conditions.md` — the governing rule for
32+
when quant may/may not be summed across scan files, sub-groups, searches, or conditions (PSM count may
33+
sum; quant may not).
3134

3235
---
3336

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# Quant: when MS1 intensities can (and cannot) be summed — scan files, sub-groups, searches, conditions
2+
3+
**Date:** 2026-07-29
4+
**Status:** governing principle for FlashLFQ / MS1 quant aggregation. Read this **before writing any code
5+
that combines, sums, rolls up, or shows a single quant number for a group of things** — multiple scan
6+
files, multiple sub-groups, multiple searches, or an experiment *condition*. (Filed under a deliberately
7+
blunt name because this is the exact trap you hit when you think "I'll just sum the scan-file quant like we
8+
sum PSM count.")
9+
10+
> ## THE ONE RULE
11+
> **PSM count aggregates freely. Quant does NOT.**
12+
> A PSM count is an additive count of identifications, so summing it across anything is always fine. An MS1
13+
> quant value is a *physical measurement* of one peptidoform in one raw file from one run — you may **only**
14+
> aggregate it across units that were **(a) co-measured in one run** and **(b) known-valid to combine**.
15+
> Everywhere the UI collapses several units into one column/row, PSM count may sum but **quant must either
16+
> stay at the measured grain or be DECLINED — it may never silently follow PSM count's sum.**
17+
18+
---
19+
20+
## Why: the measured grain, and the two directions you cannot move freely
21+
22+
The atom of MS1 label-free quant is **(peptidoform, scan file, one FlashLFQ run) → intensity**. From that
23+
atom there are two directions the UI is tempted to move, and **both are constrained**:
24+
25+
- **You cannot subdivide *below* the grain.** An integrated/apex precursor feature is not decomposable into
26+
per-charge, per-PSM, or per-(sub-group-sharing-a-file) pieces — that information isn't in the data. (The
27+
~54% charge-filter over-count and the "can't split a shared peak" results are covered in
28+
`flashlfq_quant_run_on_final_filtered_psms.md` and `flashlfq_open_mod_quant_correctness_boundary_2026-07-29.md`.
29+
Not this doc's focus.)
30+
- **You cannot aggregate *above* the grain freely.** Summing intensities across scan files / searches /
31+
conditions is valid only under specific conditions. **This doc is about that direction.**
32+
33+
## The two obstacles to aggregating upward (sometimes stacked)
34+
35+
Aggregating quant across a set of units runs into one or both of these. Either one alone forbids a silent sum.
36+
37+
### Obstacle 1 — the fraction-vs-replicate metadata gap
38+
Multiple units (e.g. a search's several scan files) can be two opposite things:
39+
- **Fractions of ONE sample** (SCX / high-pH / gas-phase split) → the fractions together are one sample →
40+
**summing is correct** (it reconstructs the sample total).
41+
- **Replicates / conditions** → each unit is its own sample → **summing is meaningless** (it adds
42+
independent samples and destroys the comparison the experiment was for).
43+
44+
The *same sum* is right or wrong depending on which it is — and **Limelight has no metadata to distinguish
45+
them, and will not add any.** The fraction/replicate intent lives only with whoever built the search; there
46+
is no Limelight field for it, and FlashLFQ's own `Condition`/`Fraction` experimental-design slots have
47+
nothing true to populate. So **a silent sum silently assumes "fractions"** and is unfixable by better
48+
engineering — the fact simply does not exist in the system.
49+
50+
### Obstacle 2 — cross-run non-comparability
51+
Quant is per-search: **each search is its own FlashLFQ run** (Model A). Separate runs have **no shared
52+
match-between-runs, RT alignment, or normalization**, so their intensities are not on a common scale. You
53+
cannot validly combine values from different runs even if you *knew* they belonged to one sample — this is
54+
exactly why the boss rejected **Model B** (cross-search joint runs): "LFQ intensities are only comparable
55+
when co-quantified in one run." This obstacle applies whenever the units being combined came from
56+
**different searches**.
57+
58+
---
59+
60+
## The concrete cases (each maps to the rule)
61+
62+
| Combining… | PSM count | Quant — ruling | Obstacle(s) |
63+
|---|---|---|---|
64+
| **Single search, single scan file** ||**valid** — the base case | none |
65+
| **Multiple searches shown SIDE BY SIDE** (one column each) | per-search columns |**valid** — each search is its own run, shown separately; **not** combined into one number | none (they're not summed) |
66+
| **Scan files → one search** (a search with >1 scan file — including when it's viewed with other searches and collapsed to one column) | sums across files |**DECLINE** — do **not** sum quant across the scan files (temp guard today) | Obstacle 1 |
67+
| **Sub-groups that PARTITION scan files** | per-sub-group | ✅ valid — each sub-group = union of whole, exclusively-owned scan files (a legitimate aggregate) | none |
68+
| **Sub-groups that CROSS-CUT scan files** | per-sub-group |**DECLINE** — can't attribute a shared file's peak to a sub-group (see `flashlfq_quant_subgroup_scanfile_eligibility.md`) | (subdivision, not summing) |
69+
| **Searches → one CONDITION** (experiment pages) | combines across searches |**DECLINE** — do **not** sum quant across a condition's searches | Obstacle 1 **and** 2 (stacked) — the hardest case |
70+
71+
**The load-bearing point, stated loudly:** in the multi-scan-file and the experiment-condition cases the
72+
display collapses several units into **one column/cell** and **PSM count fills it by summing**. Quant
73+
**cannot follow** — its cell must be **declined**, not summed. This is the single most likely place to
74+
introduce a silent, invisible error, because "PSM count already sums here, so quant should too" feels right
75+
and is wrong.
76+
77+
## What "decline" means
78+
79+
Don't silently hide and don't substitute a summed number. Show the cell as unavailable with a plain-language
80+
reason, e.g.:
81+
- multi-file search: *"Quant isn't available for a search with multiple scan files — MS1 intensities can't
82+
be summed across raw files without knowing whether they are fractions of one sample or separate
83+
replicates, and Limelight doesn't track that."*
84+
- condition: *"Quant isn't available at the condition level — it would combine separate per-search FlashLFQ
85+
runs, which aren't comparable, across searches Limelight can't confirm are one sample."*
86+
87+
Decline is **per-unit**, not per-view: in a mixed view, still show quant for the valid searches; decline only
88+
the offending column/cell.
89+
90+
## The only honest escape hatch (future, not a default)
91+
If a number for a multi-file search or a condition is ever genuinely wanted, the missing fact must be
92+
supplied **explicitly by the user** ("these files/searches are fractions of one sample → sum" vs
93+
"replicates → don't"), surfaced as a deliberate choice. That re-introduces the metadata *from the user*,
94+
where it actually lives. **Never make it a default, and never infer it.** (And note Obstacle 2 still limits
95+
cross-*search* combination even then.)
96+
97+
## Not to be confused with: apex-vs-area
98+
This doc is about **which grains may be combined**. A *separate* concern is the physical additivity of a
99+
sum you are allowed to make — summing a peptidoform's own features/charges (co-measured, one run) is a
100+
legitimate aggregate, but with FlashLFQ's default `--int` off it sums **apex heights**, an approximate
101+
(not additive) quantity. That is covered in `flashlfq_quant_mapping_critical_review_2026-07-29.md`
102+
("Open decision — apex vs area") and `flashlfq_output_to_limelight_mapping.md`. Keep the two ideas
103+
distinct: *may I combine these units at all?* (this doc) vs *is the value I'm summing an additive
104+
quantity?* (apex-vs-area).
105+
106+
---
107+
108+
## Related docs
109+
- `flashlfq_quant_data_model_and_display_grains.md` — the display roll-up grains; **this rule governs which
110+
of those roll-ups are valid.**
111+
- `flashlfq_quant_subgroup_scanfile_eligibility.md` — the sub-group instance of this rule (partition vs
112+
cross-cut).
113+
- `flashlfq_per_scan_file_separate_run_rationale.md` — why runs see one scan file; the multi-file summing
114+
discussion.
115+
- `flashlfq_quant_mapping_critical_review_2026-07-29.md` — H1/H2 (the composed design's matrix→scalar
116+
problem, of which this is the underlying rule) and the apex-vs-area open decision.
117+
- `quant_maxquant_design_discussion.md` — Model A vs Model B (Obstacle 2's origin).

limelight_features_docs/flashlfq_quant_data_model_and_display_grains.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,17 @@ case; sub-groups collapse to search level when multiple searches are shown). The
6464
**"Quant (<search label>)"** (multi-search), replacing the current "Quant (form) (Primary)"; the
6565
"Quant (peptide) for validation" column is dropped.
6666

67+
> **⚠ "sum the search's scan files" DOES NOT carry over to quant the way it does to PSM Count — read the
68+
> aggregation rule before implementing these roll-ups.** The "sum the search's scan files" cells above are
69+
> valid for quant **only when the search has one scan file** (or genuine fractions). For a search with
70+
> **multiple** scan files, summing quant is the fraction-vs-replicate trap — it is **declined for now** (a
71+
> temporary guard), NOT summed the way PSM Count is; and a **condition** spanning searches is worse
72+
> (cross-run non-comparability too). PSM Count may sum across all of these; quant may not. The governing
73+
> rule — which of these roll-ups are valid, and why a multi-scan-file search is declined rather than summed
74+
> — is `flashlfq_quant__do_not_silently_sum_across_scan_files_searches_conditions.md`. (Mode 3 sub-group
75+
> summing is valid only when sub-groups **partition** scan files — see
76+
> `flashlfq_quant_subgroup_scanfile_eligibility.md`.)
77+
6778
## 3. A search can have multiple scan files and no sub-groups
6879

6980
Important constraint that rules out shortcuts: **scan files and sub-groups are independent.** A search may

limelight_features_docs/flashlfq_quant_mapping_critical_review_2026-07-29.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ code before acting.
2929
correct (MS1 precursor-physics ceiling).
3030
- `flashlfq_open_mod_quant_deferred_mass_doublecount.md` — the deferred open-mod defects + in-code `throw`
3131
tripwires.
32+
- `flashlfq_quant__do_not_silently_sum_across_scan_files_searches_conditions.md` — the governing rule for
33+
when quant may/may not be summed across scan files, sub-groups, searches, or conditions (PSM count may
34+
sum; quant may not) — the underlying rule behind H1/H2.
3235

3336
---
3437

limelight_features_docs/flashlfq_usage_critical_review_2026-07-29.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ by executing a run.
1919
correct (MS1 precursor-physics ceiling).
2020
- `flashlfq_open_mod_quant_deferred_mass_doublecount.md` — the deferred open-mod defects + in-code `throw`
2121
tripwires.
22+
- `flashlfq_quant__do_not_silently_sum_across_scan_files_searches_conditions.md` — the governing rule for
23+
when quant may/may not be summed across scan files, sub-groups, searches, or conditions (PSM count may
24+
sum; quant may not).
2225

2326
---
2427

0 commit comments

Comments
 (0)