@datagrok/proteomics 1.0.1 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -3
- package/CLAUDE.md +178 -0
- package/README.md +195 -3
- package/detectors.js +152 -9
- package/dist/package-test.js +1 -1744
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +1 -146
- package/dist/package.js.map +1 -1
- package/docs/personas-and-capabilities.md +165 -0
- package/files/demo/README.md +264 -0
- package/files/demo/cptac-spike-in.txt +1571 -0
- package/files/demo/enrichment-demo.csv +120 -0
- package/files/demo/fragpipe-smoke-test.tsv +11 -0
- package/files/demo/proteinGroups.txt +28 -0
- package/files/demo/spectronaut-hye-candidates.tsv +94 -0
- package/files/demo/spectronaut-hye-demo.tsv +8761 -0
- package/files/demo/spectronaut-hye-mix.tsv +8761 -0
- package/files/demo/spectronaut-hye-precursor-golden.json +938 -0
- package/files/demo/spectronaut-hye-precursor-golden.tsv +235 -0
- package/files/demo/spectronaut-hye-precursor.tsv +493 -0
- package/images/enrichment-crosslink.png +0 -0
- package/images/enrichment-term-selected.png +0 -0
- package/images/hero.png +0 -0
- package/images/pipeline.svg +80 -0
- package/package.json +88 -63
- package/scripts/deqms_de.R +60 -0
- package/scripts/limma_de.R +42 -0
- package/scripts/vsn_normalize.R +19 -0
- package/src/analysis/differential-expression.ts +450 -0
- package/src/analysis/enrichment-export.ts +101 -0
- package/src/analysis/enrichment.ts +602 -0
- package/src/analysis/experiment-setup.ts +199 -0
- package/src/analysis/imputation.ts +407 -0
- package/src/analysis/log2-scale.ts +139 -0
- package/src/analysis/normalization.ts +255 -0
- package/src/analysis/pca.ts +254 -0
- package/src/analysis/spc-storage.ts +515 -0
- package/src/analysis/spc.ts +544 -0
- package/src/analysis/subcellular-location.ts +431 -0
- package/src/demo/enrichment-demo.ts +94 -0
- package/src/demo/proteomics-demo.ts +123 -0
- package/src/global.d.ts +15 -0
- package/src/menu.ts +133 -0
- package/src/package-api.ts +136 -14
- package/src/package-test.ts +45 -20
- package/src/package.g.ts +161 -0
- package/src/package.ts +1029 -17
- package/src/panels/protein-focus.ts +63 -0
- package/src/panels/published-analysis-panel.ts +151 -0
- package/src/panels/uniprot-panel.ts +349 -0
- package/src/parsers/fragpipe-parser.ts +200 -0
- package/src/parsers/generic-parser.ts +197 -0
- package/src/parsers/maxquant-parser.ts +162 -0
- package/src/parsers/shared-utils.ts +163 -0
- package/src/parsers/spectronaut-candidates-parser.ts +307 -0
- package/src/parsers/spectronaut-parser.ts +604 -0
- package/src/publishing/assert-published-shape.ts +260 -0
- package/src/publishing/post-open-recovery.ts +104 -0
- package/src/publishing/publish-project.ts +515 -0
- package/src/publishing/publish-settings.ts +59 -0
- package/src/publishing/publish-state.ts +316 -0
- package/src/publishing/share-dialog.ts +171 -0
- package/src/publishing/trim-dataframe.ts +247 -0
- package/src/tests/analysis.ts +658 -0
- package/src/tests/enrichment-export.ts +61 -0
- package/src/tests/enrichment-visualization.ts +340 -0
- package/src/tests/enrichment.ts +224 -0
- package/src/tests/fragpipe-e2e.ts +74 -0
- package/src/tests/fragpipe-parser.ts +147 -0
- package/src/tests/gene-label-resolver.ts +387 -0
- package/src/tests/generic-parser.ts +152 -0
- package/src/tests/group-mean-correlation.ts +139 -0
- package/src/tests/log2-scale.ts +93 -0
- package/src/tests/organisms.ts +56 -0
- package/src/tests/parsers.ts +182 -0
- package/src/tests/publish-roundtrip.ts +584 -0
- package/src/tests/publish-spike.ts +377 -0
- package/src/tests/qc-dashboard.ts +210 -0
- package/src/tests/smart-pathway-filter.ts +193 -0
- package/src/tests/spc-formula-lines-spike.ts +129 -0
- package/src/tests/spc.ts +640 -0
- package/src/tests/spectronaut-candidates-e2e.ts +140 -0
- package/src/tests/spectronaut-candidates-parser.ts +398 -0
- package/src/tests/spectronaut-parser.ts +668 -0
- package/src/tests/subcellular-location.ts +361 -0
- package/src/tests/uniprot-panel.ts +202 -0
- package/src/tests/volcano.ts +603 -0
- package/src/utils/column-detection.ts +28 -0
- package/src/utils/gene-label-resolver.ts +443 -0
- package/src/utils/organisms.ts +82 -0
- package/src/utils/proteomics-types.ts +30 -0
- package/src/viewers/enrichment-viewers.ts +274 -0
- package/src/viewers/group-mean-correlation.ts +218 -0
- package/src/viewers/heatmap.ts +168 -0
- package/src/viewers/pca-plot.ts +169 -0
- package/src/viewers/qc-computations.ts +266 -0
- package/src/viewers/qc-dashboard.ts +176 -0
- package/src/viewers/spc-dashboard.ts +755 -0
- package/src/viewers/volcano.ts +690 -0
- package/test-console-output-1.log +2073 -0
- package/test-record-1.mp4 +0 -0
- package/tools/derive-precursor-golden-sidecar.mjs +81 -0
- package/tools/generate-enrichment-fixture.sh +160 -0
- package/tools/generate-spectronaut-candidates-fixture.mjs +212 -0
- package/tools/generate-spectronaut-precursor-fixture.mjs +128 -0
- package/tools/spectronaut-aggregate.sh +46 -0
- package/tools/spectronaut-aggregate.sql +80 -0
- package/tsconfig.json +18 -71
- package/webpack.config.js +86 -45
- package/.eslintignore +0 -1
- package/.eslintrc.json +0 -56
- package/LICENSE +0 -674
- package/package.png +0 -0
- package/scripts/number_antibody.py +0 -190
- package/scripts/number_antibody_abnumber.py +0 -177
- package/scripts/number_antibody_anarci.py +0 -200
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Personas & capabilities
|
|
2
|
+
|
|
3
|
+
Who does what with a Proteomics dataset, what each persona is *allowed* to do, and
|
|
4
|
+
**how that boundary is enforced** — today and where we are taking it.
|
|
5
|
+
|
|
6
|
+
This doc is the reference behind the README's ["What you can achieve"](../README.md#what-you-can-achieve)
|
|
7
|
+
section. The README leads with outcomes; this leads with the capability boundary and its
|
|
8
|
+
enforcement, because a client requirement (see [Target state](#target-state)) needs that
|
|
9
|
+
boundary to be real, not conventional.
|
|
10
|
+
|
|
11
|
+
## The two personas
|
|
12
|
+
|
|
13
|
+
| Persona | Role | Outcome they want |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| **Proteomics analyst** (data generator) | Builds the analysis: import → annotate → normalize → impute → differential expression | A defensible, reproducible, FDR-controlled result they can stand behind and hand off |
|
|
16
|
+
| **Biology scientist** (data consumer / reviewer) | Interprets a finished analysis: volcano, enrichment, per-protein annotation | To understand *what changed and what it means* — without touching (or being able to change) the analysis itself |
|
|
17
|
+
|
|
18
|
+
The dividing line is **"the interpretation"** — the set of decisions that determine what the
|
|
19
|
+
result *says*: group assignment, normalization, imputation, the DE method, and the
|
|
20
|
+
significance thresholds. The analyst owns these. The biologist reads the consequences and
|
|
21
|
+
explores them, but must not alter them.
|
|
22
|
+
|
|
23
|
+
## Capability matrix
|
|
24
|
+
|
|
25
|
+
Legend: ✅ allowed · 🚫 must not · 👁 read-only interaction (view/filter/select, no state change)
|
|
26
|
+
|
|
27
|
+
| Capability | Analyst | Biologist | Changes the interpretation? |
|
|
28
|
+
|---|---|---|---|
|
|
29
|
+
| Import a search-engine file | ✅ | — (receives a shared snapshot instead) | Produces it |
|
|
30
|
+
| Annotate Experiment (assign groups) | ✅ | 🚫 | **Yes** |
|
|
31
|
+
| Set Log2 Scale | ✅ | 🚫 | **Yes** |
|
|
32
|
+
| Normalize | ✅ | 🚫 | **Yes** |
|
|
33
|
+
| Impute Missing Values | ✅ | 🚫 | **Yes** |
|
|
34
|
+
| Differential Expression | ✅ | 🚫 | **Yes** |
|
|
35
|
+
| Compute SPC Status | ✅ | 🚫 | **Yes** |
|
|
36
|
+
| Volcano Plot | ✅ | 👁 | No (view) |
|
|
37
|
+
| Heatmap / PCA / Group-Mean Correlation / QC Dashboard | ✅ | 👁 | No (view) |
|
|
38
|
+
| Enrichment Analysis & Charts | ✅ | ✅ (derives biology; non-destructive) | No |
|
|
39
|
+
| UniProt protein panel | ✅ | ✅ | No |
|
|
40
|
+
| Filter / select / cross-link in any viewer | ✅ | ✅ | No |
|
|
41
|
+
| Share Analysis for Review | ✅ | 🚫 | N/A (publishes) |
|
|
42
|
+
| Save changes to a shared snapshot | ✅ (own copy) | 🚫 | **Yes** |
|
|
43
|
+
|
|
44
|
+
The 🚫 rows are the ones CK cares about: a biologist must not be able to re-run the pipeline
|
|
45
|
+
or re-thresholds and thereby produce a *different* interpretation of the same data.
|
|
46
|
+
|
|
47
|
+
## How the boundary is enforced today
|
|
48
|
+
|
|
49
|
+
The package differentiates on **three axes** — none of which is the user's identity.
|
|
50
|
+
|
|
51
|
+
### 1. By data shape — the only code-enforced line (`sampleOnly` grey-out)
|
|
52
|
+
|
|
53
|
+
`src/menu.ts` gates every analysis-mutating action behind
|
|
54
|
+
`sampleLevelDisabledReason(df)`. On a Spectronaut **Candidates** file (pre-computed DE, no
|
|
55
|
+
per-sample intensities) these items grey out with an explanatory tooltip:
|
|
56
|
+
|
|
57
|
+
> *Not applicable to a Spectronaut Candidates file — it already carries computed
|
|
58
|
+
> differential expression and has no per-sample intensities. Use Volcano Plot, Enrichment
|
|
59
|
+
> Analysis or the UniProt panel, or import the matching Spectronaut Report for sample-level
|
|
60
|
+
> analyses.*
|
|
61
|
+
|
|
62
|
+
Gated (sample-level): Annotate Experiment, Set Log2 Scale, Normalize, Impute, Differential
|
|
63
|
+
Expression, Compute SPC Status, Heatmap, PCA, Group-Mean Correlation, QC Dashboard, Show All
|
|
64
|
+
Visualizations.
|
|
65
|
+
|
|
66
|
+
Always available: Import, Volcano Plot, Enrichment Analysis + Charts, Export Enrichment
|
|
67
|
+
Inputs, SPC Dashboard, Share for Review, UniProt panel.
|
|
68
|
+
|
|
69
|
+
**This gates on the *data*, not the *person*.** It happens to keep a biologist who only ever
|
|
70
|
+
receives Candidates files in the interpretation lane — but it does nothing to stop a
|
|
71
|
+
biologist who opens a **Report** file from running the whole pipeline.
|
|
72
|
+
|
|
73
|
+
### 2. By workflow stage — the menu grouping mirrors the roles
|
|
74
|
+
|
|
75
|
+
`Import → Annotate → Analyze` is the analyst building the result; `Visualize → Share` is the
|
|
76
|
+
consumer interpreting it. The volcano auto-opening on both DE-completion and Candidates
|
|
77
|
+
import lands the interpreter on the deliverable without making them run the pipeline. This
|
|
78
|
+
is a *convention*, not a restriction.
|
|
79
|
+
|
|
80
|
+
### 3. By access — view-only sharing (the one real identity boundary)
|
|
81
|
+
|
|
82
|
+
`Share Analysis for Review` publishes a frozen, versioned snapshot and grants the reviewer
|
|
83
|
+
group **View only**. The publish flow's verify-and-rollback gate aborts if the reviewer
|
|
84
|
+
group has any Edit / Share / Delete right at the project, child-space, or umbrella-space
|
|
85
|
+
level. So through the **shared snapshot**, a biologist genuinely cannot change the
|
|
86
|
+
interpretation — they get a read-only copy.
|
|
87
|
+
|
|
88
|
+
## The gap
|
|
89
|
+
|
|
90
|
+
Enforcement today is **data-shape + access**, not **identity**. Concretely:
|
|
91
|
+
|
|
92
|
+
- A biology user who opens a **Report** file (not a Candidates file, not a shared snapshot)
|
|
93
|
+
sees the full analyst menu enabled and can run/redo DE, re-normalize, re-threshold, and
|
|
94
|
+
re-share. Nothing checks who they are.
|
|
95
|
+
- The view-only guarantee exists **only** for analyses that arrived via Share for Review. A
|
|
96
|
+
biologist working on a live table is unconstrained.
|
|
97
|
+
|
|
98
|
+
CK does not want their biologists to be able to change the interpretation *at all* — which
|
|
99
|
+
data-shape gating cannot guarantee, because it depends on which file they happened to open.
|
|
100
|
+
|
|
101
|
+
## Target state
|
|
102
|
+
|
|
103
|
+
Add an **identity/role** axis on top of the existing data-shape and access gating, so the
|
|
104
|
+
🚫 capabilities are unavailable to a biologist regardless of file type.
|
|
105
|
+
|
|
106
|
+
### What the platform can and cannot enforce
|
|
107
|
+
|
|
108
|
+
This constrains the design, so it comes first. Datagrok's permission model
|
|
109
|
+
(`grok.dapi.permissions`) grants **View / Edit / Share / Delete** on *entities* — projects,
|
|
110
|
+
connections, scripts, queries, packages. There is **no per-function "Execute" permission for
|
|
111
|
+
client-side TypeScript package functions** (a `Func` extends `Entity` but carries no ACL). So
|
|
112
|
+
you **cannot** express "grant the Proteomics group execute on `Normalize`, deny Biologics"
|
|
113
|
+
as a native grant.
|
|
114
|
+
|
|
115
|
+
That leaves two enforcement tiers, with very different strength:
|
|
116
|
+
|
|
117
|
+
- **Application-level group gating (a deterrent, not a wall).** A package function can check
|
|
118
|
+
`grok.dapi.groups.currentUserGroups()` at runtime and refuse to run for non-analysts. This
|
|
119
|
+
is real and has precedent (PowerPack, Grokky), but it runs in the browser and the
|
|
120
|
+
DataFrame mutation is client-side — a determined user could invoke the function from the
|
|
121
|
+
console. It hides analyst actions from biologists; it does **not** guarantee they can't
|
|
122
|
+
change data locally.
|
|
123
|
+
- **Server-enforced boundaries (the real walls).** Three exist: (a) the **view-only shared
|
|
124
|
+
snapshot** — already built (Share for Review); the reviewer group has only View on the
|
|
125
|
+
project, so the server blocks any *save*, and a locally re-run analysis can't be persisted;
|
|
126
|
+
(b) **package-level sharing** — deny the package to a group entirely, but that is
|
|
127
|
+
all-or-nothing and would also remove the volcano/enrichment/UniProt biologists legitimately
|
|
128
|
+
need; (c) **server-side Script/Query Execute permission** — real per-step gating, but only
|
|
129
|
+
for the R scripts, and the package's client-side fallbacks (`limma`/`vsn` → client t-test /
|
|
130
|
+
quantile) are a loophole that would have to be disabled for non-analysts.
|
|
131
|
+
|
|
132
|
+
**The strongest guarantee that already exists is the view-only shared snapshot.** If
|
|
133
|
+
biologists only ever receive analyses via Share for Review, the interpretation of record is
|
|
134
|
+
server-protected today. Everything below is about the *live-table* case.
|
|
135
|
+
|
|
136
|
+
### Direction (to be specified in an implementation phase)
|
|
137
|
+
|
|
138
|
+
1. **A "Proteomics Analysts" Datagrok group.** Analyst-only actions key off membership.
|
|
139
|
+
2. **Menu gating (UX layer).** Extend the `sampleOnly` predicate in `src/menu.ts` to an
|
|
140
|
+
`analystOnly` predicate that also greys out (with a clear reason) when the current user is
|
|
141
|
+
not in the analysts group — so interpretation-changing items disappear for biologists on
|
|
142
|
+
*any* table, not just Candidates. This is a deterrent, not a security boundary.
|
|
143
|
+
3. **Handler gating (defense in depth, still client-side).** Guard the mutating handlers in
|
|
144
|
+
`src/package.ts` (where `requireSampleLevelData` already lives) so a directly-invoked
|
|
145
|
+
function also refuses for non-analysts. This closes the menu-bypass path but, being
|
|
146
|
+
client-side, is still not a hard wall — the console can reach the same code.
|
|
147
|
+
4. **The hard wall stays server-side.** For a genuine guarantee, rely on the view-only shared
|
|
148
|
+
snapshot as the default biologist entry point; a true block on *live* tables would require
|
|
149
|
+
moving the mutating steps to server-side Scripts with Execute permission **and** disabling
|
|
150
|
+
the client fallbacks for non-analysts (a larger architectural change — scope only if
|
|
151
|
+
biologists must edit live tables and still be hard-blocked).
|
|
152
|
+
|
|
153
|
+
Open questions for the implementation phase: whether Enrichment re-runs count as "changing
|
|
154
|
+
the interpretation" (currently treated as non-destructive exploration); where CK's biologists
|
|
155
|
+
actually work (shared snapshots only vs. live files — this decides whether steps 2–4 are even
|
|
156
|
+
needed); how the analysts group is provisioned per client/deployment; and whether to expose
|
|
157
|
+
an explicit read-only "Reviewer mode" toggle vs. inferring it from group membership.
|
|
158
|
+
|
|
159
|
+
## See also
|
|
160
|
+
|
|
161
|
+
- [`README.md` → What you can achieve](../README.md#what-you-can-achieve) — the outcome-led persona intro
|
|
162
|
+
- [`CLAUDE.md` → Menu architecture](../CLAUDE.md) — how the ribbon menu and `isEnabled` grey-out are built
|
|
163
|
+
- `src/menu.ts` — `sampleLevelDisabledReason`, the `sampleOnly` gate
|
|
164
|
+
- `src/package.ts` — `requireSampleLevelData`, the handler-level guards
|
|
165
|
+
- `src/publishing/` — the Share for Review view-only publish flow
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Demo Datasets
|
|
2
|
+
|
|
3
|
+
Sample search-engine outputs that exercise every import path and the full analysis
|
|
4
|
+
pipeline (annotate → normalize → impute → differential expression → enrichment →
|
|
5
|
+
visualize), plus the fixtures the package's tests pin against. They are browsable in the
|
|
6
|
+
platform under **Files | App Data | Proteomics | demo**.
|
|
7
|
+
|
|
8
|
+
Most carry an engineered or known-ground-truth signal — spike-in standards or species
|
|
9
|
+
mixed at fixed ratios between conditions — so the differential-expression and volcano
|
|
10
|
+
results are checkable against the truth, not just plausible.
|
|
11
|
+
|
|
12
|
+
## Which dataset should I use?
|
|
13
|
+
|
|
14
|
+
| Dataset | Vendor / format | Acquisition | Best for |
|
|
15
|
+
|---------|-----------------|-------------|----------|
|
|
16
|
+
| `cptac-spike-in.txt` | MaxQuant `proteinGroups.txt` | DDA | The full pipeline on a real benchmark with known UPS spike-in truth |
|
|
17
|
+
| `proteinGroups.txt` | MaxQuant `proteinGroups.txt` | DDA | A fast, tiny MaxQuant import / UI smoke test |
|
|
18
|
+
| `fragpipe-smoke-test.tsv` | FragPipe `combined_protein.tsv` | DDA | The FragPipe path + UniProt panel (real accessions) with an engineered volcano |
|
|
19
|
+
| `spectronaut-hye-mix.tsv` | Spectronaut report (long) | DIA | Long-format DIA import and the three-species (HYE) ground-truth story |
|
|
20
|
+
| `spectronaut-hye-demo.tsv` | Spectronaut report (long, slim) | DIA | **The registered `Proteomics Demo`** — the full pipeline's richest endpoint, run end to end |
|
|
21
|
+
| `enrichment-demo.csv` | Engineered human DE result | — | **The registered `Proteomics Enrichment Demo`** — a single-organism pathway-enrichment story |
|
|
22
|
+
| `spectronaut-hye-candidates.tsv` | Spectronaut Candidates | DIA | The pre-computed-DE shortcut (straight to volcano/enrichment) |
|
|
23
|
+
| `spectronaut-hye-precursor*.{tsv,json}` | Spectronaut precursor / aggregated | DIA | Streaming-aggregation import and its golden-file equivalence tests |
|
|
24
|
+
|
|
25
|
+
The two HYE files (`spectronaut-hye-mix.tsv` and `spectronaut-hye-candidates.tsv`) tell the
|
|
26
|
+
same biological story from two angles — per-sample quantities vs. pre-computed
|
|
27
|
+
fold-change — so they pair well for comparing the package's own DE against a vendor-shaped
|
|
28
|
+
result.
|
|
29
|
+
|
|
30
|
+
## proteinGroups.txt
|
|
31
|
+
|
|
32
|
+
| Property | Value |
|
|
33
|
+
|----------|-------|
|
|
34
|
+
| **Format** | MaxQuant `proteinGroups.txt` (wide, tab-separated) |
|
|
35
|
+
| **Source** | Synthetic — generated for development and testing |
|
|
36
|
+
| **Organism** | Human |
|
|
37
|
+
| **Proteins** | 27 |
|
|
38
|
+
| **Samples** | 6 (Sample1–Sample6) |
|
|
39
|
+
| **Quantification** | LFQ intensity |
|
|
40
|
+
| **Columns** | 17 (Protein IDs, Gene names, Protein names, filter flags, LFQ intensities, coverage, peptide counts) |
|
|
41
|
+
| **Size** | 3.7 KB |
|
|
42
|
+
|
|
43
|
+
Minimal MaxQuant output suitable for quick import testing and UI development. Includes
|
|
44
|
+
`Potential contaminant`, `Reverse`, and `Only identified by site` filter columns.
|
|
45
|
+
|
|
46
|
+
## cptac-spike-in.txt
|
|
47
|
+
|
|
48
|
+
| Property | Value |
|
|
49
|
+
|----------|-------|
|
|
50
|
+
| **Format** | MaxQuant `proteinGroups.txt` (wide, tab-separated) |
|
|
51
|
+
| **Source** | CPTAC spike-in study — processed through MaxQuant |
|
|
52
|
+
| **Organism** | Human (with UPS spike-in standards) |
|
|
53
|
+
| **Proteins** | 1,569 |
|
|
54
|
+
| **Samples** | 6 (two conditions: 6A and 6B, 3 replicates each) |
|
|
55
|
+
| **Quantification** | LFQ intensity and raw Intensity |
|
|
56
|
+
| **Columns** | 80 (full MaxQuant output including peptide counts, sequence coverage, identification types, MS/MS counts) |
|
|
57
|
+
| **Size** | 4.6 MB |
|
|
58
|
+
|
|
59
|
+
Full-scale MaxQuant output from the CPTAC spike-in benchmark. Two conditions (6A vs 6B) with
|
|
60
|
+
known differentially abundant UPS proteins spiked into a constant yeast background. Ideal for
|
|
61
|
+
testing the complete pipeline: import, normalization, imputation, and differential expression.
|
|
62
|
+
|
|
63
|
+
## fragpipe-smoke-test.tsv
|
|
64
|
+
|
|
65
|
+
| Property | Value |
|
|
66
|
+
|----------|-------|
|
|
67
|
+
| **Format** | FragPipe `combined_protein.tsv` (wide, tab-separated) |
|
|
68
|
+
| **Source** | Synthetic — generated to exercise the FragPipe parser |
|
|
69
|
+
| **Organism** | Human (plus one bovine contaminant) |
|
|
70
|
+
| **Proteins** | 10 (8 targets + 1 `contam_` + 1 `rev_` decoy) |
|
|
71
|
+
| **Samples** | 4 (Ctrl_1, Ctrl_2, Treat_1, Treat_2 — two conditions × two replicates) |
|
|
72
|
+
| **Quantification** | MaxLFQ Intensity, Intensity, Razor Intensity (all three per sample) |
|
|
73
|
+
| **Columns** | 19 (Protein, Protein ID, Entry Name, Gene, Length, Organism, Description + 3 × 4 sample intensity columns) |
|
|
74
|
+
| **Size** | 2.1 KB |
|
|
75
|
+
|
|
76
|
+
Minimal FragPipe output for smoke-testing import and the full analysis pipeline. Real UniProt
|
|
77
|
+
accessions (TP53, BRCA1, EGFR, AKT1, MTOR, F2, PRKCD, HRAS) so the UniProt context panel
|
|
78
|
+
resolves. Includes a `contam_BOVIN_CASEIN` row and a `rev_sp|P12345|...` decoy row to exercise
|
|
79
|
+
the parser's contaminant/decoy filter. Differential abundance is engineered: TP53/AKT1/F2 up
|
|
80
|
+
in Treat, BRCA1/PRKCD down, EGFR/MTOR/HRAS unchanged — gives a predictable volcano-plot pattern.
|
|
81
|
+
|
|
82
|
+
## spectronaut-hye-mix.tsv
|
|
83
|
+
|
|
84
|
+
| Property | Value |
|
|
85
|
+
|----------|-------|
|
|
86
|
+
| **Format** | Spectronaut report (long, tab-separated) |
|
|
87
|
+
| **Source** | [SpectroPipeR](https://github.com/stemicha/SpectroPipeR) — HYE species mix benchmark (`inst/extdata/SN_test_HYE_mix_file.tsv`) |
|
|
88
|
+
| **Organism** | Human / Yeast / *E. coli* three-species mix |
|
|
89
|
+
| **Proteins** | 93 protein groups |
|
|
90
|
+
| **Samples** | 8 runs (two conditions: HYE mix A and HYE mix B, 4 replicates each) |
|
|
91
|
+
| **Quantification** | PG.Quantity (protein group), FG.MS2Quantity (fragment), PG.IBAQ |
|
|
92
|
+
| **Columns** | 35 (R.FileName, R.Condition, R.Replicate, PG.ProteinGroups, PG.Organisms, EG.Qvalue, EG.ModifiedPeptide, FG.Charge, and more) |
|
|
93
|
+
| **Instrument** | timsTOF Pro2 |
|
|
94
|
+
| **Size** | 5.0 MB |
|
|
95
|
+
|
|
96
|
+
Native Spectronaut DIA-MS long-format report from a three-species spike-in experiment. Each row
|
|
97
|
+
is a peptide precursor measurement across runs. Human, yeast, and *E. coli* proteins are mixed at
|
|
98
|
+
known ratios between conditions A and B, providing ground-truth differential abundance. Useful for
|
|
99
|
+
testing long-format import and DIA-specific workflows.
|
|
100
|
+
|
|
101
|
+
## spectronaut-hye-demo.tsv
|
|
102
|
+
|
|
103
|
+
| Property | Value |
|
|
104
|
+
|----------|-------|
|
|
105
|
+
| **Format** | Spectronaut report (long, tab-separated) — slimmed to the 7 columns the parser reads |
|
|
106
|
+
| **Source** | **Derived** from `spectronaut-hye-mix.tsv`: kept `R.FileName, R.Condition, R.Replicate, PG.ProteinGroups, PG.Organisms, PG.IBAQ, EG.Qvalue`, and scaled `PG.IBAQ` ×1000 into realistic intensity magnitudes. |
|
|
107
|
+
| **Organism** | Human / Yeast / *E. coli* three-species mix |
|
|
108
|
+
| **Proteins** | 93 protein groups |
|
|
109
|
+
| **Samples** | 8 runs (HYE mix A and HYE mix B, 4 replicates each) |
|
|
110
|
+
| **Quantification** | PG.IBAQ (scaled to realistic magnitude) |
|
|
111
|
+
| **Columns** | 7 |
|
|
112
|
+
| **Signal** | client-side Welch t-test + BH FDR yields ~45 significant (E. coli 27 + yeast 17 + human 1), log2FC up to ≈ 2.5 |
|
|
113
|
+
| **Size** | 1.1 MB |
|
|
114
|
+
|
|
115
|
+
Backs the package's single registered **`Proteomics Demo`** (`meta.demoPath: Bioinformatics |
|
|
116
|
+
Proteomics Differential Expression`). The demo imports this file and runs the whole pipeline —
|
|
117
|
+
import → impute → differential expression → volcano + heatmap — landing on the richest analysis
|
|
118
|
+
endpoint with no R environment and no manual steps. It also opens a **QC dashboard** on a second
|
|
119
|
+
tab and pre-selects the top-significant protein so its **UniProt** entry is already showing in the
|
|
120
|
+
context panel. Enrichment is intentionally excluded: g:Profiler enrichment assumes one organism,
|
|
121
|
+
and this is a three-species mix, so it would only map the human subset and mislead.
|
|
122
|
+
|
|
123
|
+
Why a separate file rather than reusing `spectronaut-hye-mix.tsv`: that fixture's `PG.IBAQ`
|
|
124
|
+
values were scaled *down* for size (max ≈ 34 k), which lands them in the ambiguous band where the
|
|
125
|
+
parser's log2-vs-raw heuristic (`detectLog2Status`) wrongly concludes the data is already
|
|
126
|
+
log2-transformed and skips the transform — producing meaningless linear "fold changes" (± thousands).
|
|
127
|
+
Scaling every intensity by a constant leaves fold-changes and significance **unchanged** (log2FC is
|
|
128
|
+
a difference of logs) but restores realistic magnitudes so the parser log2-transforms correctly.
|
|
129
|
+
The result is the textbook HYE outcome: the two spiked species (E. coli, yeast) separate on the
|
|
130
|
+
volcano while the constant human background stays flat. Regenerate with:
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
awk -F'\t' 'BEGIN{OFS="\t"; split("R.FileName,R.Condition,R.Replicate,PG.ProteinGroups,PG.Organisms,PG.IBAQ,EG.Qvalue", w, ",")}
|
|
134
|
+
NR==1{for(i=1;i<=NF;i++)h[$i]=i; s=""; for(k=1;k<=length(w);k++)s=s (k>1?OFS:"") w[k]; print s; next}
|
|
135
|
+
{o=""; for(k=1;k<=length(w);k++){c=w[k]; v=(c in h)?$(h[c]):""; if(c=="PG.IBAQ"&&v!=""&&v!="NA"&&v!="NaN")v=v*1000; o=o (k>1?OFS:"") v} print o}' \
|
|
136
|
+
spectronaut-hye-mix.tsv > spectronaut-hye-demo.tsv
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## enrichment-demo.csv
|
|
140
|
+
|
|
141
|
+
| Property | Value |
|
|
142
|
+
|----------|-------|
|
|
143
|
+
| **Format** | Pre-computed DE result (CSV): `Protein ID, Gene, log2FC, p-value, adj.p-value, significant` |
|
|
144
|
+
| **Source** | **Engineered for demonstration.** Real HGNC gene symbols + UniProt accessions; fold-changes and p-values are synthetic. |
|
|
145
|
+
| **Organism** | Human (single organism — enrichment requires one) |
|
|
146
|
+
| **Proteins** | 119 (30 up, 25 down, 64 non-significant background) |
|
|
147
|
+
| **Signal** | UP = cell cycle / mitosis; DOWN = oxidative phosphorylation; background = a diverse, unrelated set |
|
|
148
|
+
| **Size** | 4.5 KB |
|
|
149
|
+
|
|
150
|
+
Backs the registered **`Proteomics Enrichment Demo`** (`meta.demoPath: Proteomics | Enrichment
|
|
151
|
+
Analysis`). The demo loads this as a pre-computed DE result, opens the volcano, runs g:Profiler
|
|
152
|
+
over-representation analysis (GO / KEGG / Reactome / WikiPathways), and docks the enrichment
|
|
153
|
+
charts cross-linked to the volcano — selecting a term highlights its proteins.
|
|
154
|
+
|
|
155
|
+
Why engineered rather than a real dataset: enrichment assumes a **single organism**, which rules
|
|
156
|
+
out the three-species HYE files, and it needs a **coherent** regulated set so the returned terms
|
|
157
|
+
are recognizable. The two regulated sets are drawn from textbook, strongly-annotated pathways
|
|
158
|
+
(cell cycle up, oxidative phosphorylation down), so g:Profiler returns crisp terms — e.g. KEGG
|
|
159
|
+
"Cell cycle" and "Oxidative phosphorylation" at FDR < 1e-15. Gene symbols are real (g:Profiler
|
|
160
|
+
maps them); accessions are real (the UniProt panel resolves); only the statistics are synthetic.
|
|
161
|
+
Regenerate with `bash tools/generate-enrichment-fixture.sh` (the gene lists live in that script).
|
|
162
|
+
|
|
163
|
+
## spectronaut-hye-candidates.tsv
|
|
164
|
+
|
|
165
|
+
| Property | Value |
|
|
166
|
+
|----------|-------|
|
|
167
|
+
| **Format** | Spectronaut Candidates report (wide, tab-separated, pre-computed DE) |
|
|
168
|
+
| **Source** | **Derived** from `spectronaut-hye-mix.tsv` via this package's own Welch's t-test + BH FDR. Regenerate with `node tools/generate-spectronaut-candidates-fixture.mjs`. |
|
|
169
|
+
| **Comparison** | HYE mix B / HYE mix A (single comparison) |
|
|
170
|
+
| **Proteins** | 93 protein groups (30 Human + 30 Yeast + 30 *E. coli* + 3 other) |
|
|
171
|
+
| **Columns** | 18 (Valid, Comparison, Condition Numerator/Denominator, # of Ratios, Group, AVG Group Quantity Num/Den, AVG Log2 Ratio, Absolute AVG Log2 Ratio, % Change, Ratio, Pvalue, Qvalue, ProteinGroups, Genes, UniProtIds, Organisms) |
|
|
172
|
+
| **Signal** | log2FC range ≈ [−2.46, +3.66]; 43 significant at \|log2FC\| ≥ 1 ∧ q ≤ 0.05 (26 up, 17 down) |
|
|
173
|
+
| **Size** | 20 KB |
|
|
174
|
+
|
|
175
|
+
Exercises the `Proteomics | Import | Spectronaut Candidates...` path with values that line up
|
|
176
|
+
with the source PG file, so the two HYE fixtures tell the same biological story from different
|
|
177
|
+
angles. **Not a verbatim Spectronaut export** — we don't have Spectronaut here, so the script
|
|
178
|
+
does its own DE math and lays it out in Spectronaut's Candidates column shape. Schema matches
|
|
179
|
+
real Spectronaut Candidates output closely enough to round-trip through the importer; numerical
|
|
180
|
+
values are ours, not Biognosys's.
|
|
181
|
+
|
|
182
|
+
## spectronaut-hye-precursor.tsv
|
|
183
|
+
|
|
184
|
+
| Property | Value |
|
|
185
|
+
|----------|-------|
|
|
186
|
+
| **Format** | Spectronaut report (long, tab-separated, precursor/fragment-level) |
|
|
187
|
+
| **Source** | Synthetic — generated to exercise the streaming Spectronaut import path. Regenerate with `node tools/generate-spectronaut-precursor-fixture.mjs`. |
|
|
188
|
+
| **Organism** | Human / Yeast / *E. coli* three-species mix (synthetic) |
|
|
189
|
+
| **Proteins** | 41 protein groups (39 passing + 1 `CON__` + 1 `REV__`) |
|
|
190
|
+
| **Samples** | 6 runs (two conditions: CondA / CondB, 3 replicates each) |
|
|
191
|
+
| **Quantification** | PG.Quantity (constant per protein × condition × replicate) |
|
|
192
|
+
| **Columns** | 11 (R.FileName, R.Condition, R.Replicate, PG.ProteinGroups, PG.Organisms, PG.Quantity, EG.Qvalue, PEP.StrippedSequence, EG.ModifiedPeptide, FG.Charge, FG.Id) |
|
|
193
|
+
| **Size** | ~44 KB |
|
|
194
|
+
|
|
195
|
+
Small synthetic precursor-level Spectronaut report: ≥2 distinct precursor/fragment
|
|
196
|
+
rows per protein × sample. Carries the D-01 precursor signature columns
|
|
197
|
+
(`EG.ModifiedPeptide` / `FG.Charge` / `PEP.StrippedSequence`) so the header-sniff
|
|
198
|
+
routes it to the streaming aggregator, uses `CondA`/`CondB`, and carries **no**
|
|
199
|
+
`PG.Genes`/`PG.ProteinAccessions` columns (the real `spectronaut-hye-mix.tsv`
|
|
200
|
+
lacks them too). Deliberately includes one `CON__` row, one `REV__` row, one
|
|
201
|
+
protein mixing a passing precursor with a >0.01 sub-threshold one, one
|
|
202
|
+
non-numeric (`Profiled`) q-value protein, and one empty-string q-value protein so
|
|
203
|
+
every Spectronaut filter branch is exercised by a single fixture.
|
|
204
|
+
|
|
205
|
+
## spectronaut-hye-precursor-golden.tsv
|
|
206
|
+
|
|
207
|
+
| Property | Value |
|
|
208
|
+
|----------|-------|
|
|
209
|
+
| **Format** | Aggregated Spectronaut report (one row per protein × condition × replicate, tab-separated) |
|
|
210
|
+
| **Source** | **Derived** — verbatim duckdb output of `tools/spectronaut-aggregate.sh` over `spectronaut-hye-precursor.tsv`. Regenerate with `tools/spectronaut-aggregate.sh files/demo/spectronaut-hye-precursor.tsv files/demo/spectronaut-hye-precursor-golden.tsv`. |
|
|
211
|
+
| **Proteins** | 39 (the `CON__`/`REV__` decoys are dropped by the WHERE filter) |
|
|
212
|
+
| **Samples** | 6 (CondA / CondB × 3 replicates) |
|
|
213
|
+
| **Rows** | 234 data rows + header |
|
|
214
|
+
| **Columns** | 6 (PG.ProteinGroups, R.Condition, R.Replicate, R.FileName, PG.Quantity, EG.Qvalue) |
|
|
215
|
+
| **Size** | ~12 KB |
|
|
216
|
+
|
|
217
|
+
The D-04 equivalence oracle: the real duckdb aggregation of the fixture, not a
|
|
218
|
+
hand-derived approximation. The Plan-03 golden test compares the streaming
|
|
219
|
+
TypeScript aggregator's output against this file.
|
|
220
|
+
|
|
221
|
+
## spectronaut-hye-precursor-golden.json
|
|
222
|
+
|
|
223
|
+
| Property | Value |
|
|
224
|
+
|----------|-------|
|
|
225
|
+
| **Format** | JSON map `{ "<protein><condition>_<replicate>": { "quantity": number, "qvalue": number } }` |
|
|
226
|
+
| **Source** | **Transcribed verbatim** from `spectronaut-hye-precursor-golden.tsv` — no re-aggregation. Regenerate with `node tools/derive-precursor-golden-sidecar.mjs`. |
|
|
227
|
+
| **Entries** | 234 (one per surviving protein × condition × replicate) |
|
|
228
|
+
| **Size** | ~9 KB |
|
|
229
|
+
|
|
230
|
+
Read by `grok test` as the in-test oracle when committed-file reads are
|
|
231
|
+
unavailable in the test runner. It is **derived FROM** the golden `.tsv` and
|
|
232
|
+
never re-aggregated, so the equivalence test stays pinned to real duckdb output;
|
|
233
|
+
re-running the deriver against an unchanged golden produces a byte-identical JSON.
|
|
234
|
+
|
|
235
|
+
### Flip caveat & regeneration order
|
|
236
|
+
|
|
237
|
+
The committed `tools/spectronaut-aggregate.sql` carries a **reference-file-only**
|
|
238
|
+
DMD↔WT `R.Condition` correction (a one-off fix for the mislabeled
|
|
239
|
+
`2026-05-13 BP DMD WT.tsv` reference file). It is a structural **no-op** on this
|
|
240
|
+
`CondA`/`CondB` fixture, which is exactly why the same script doubles as both the
|
|
241
|
+
documented manual fallback **and** the test oracle without perturbing the golden.
|
|
242
|
+
The committed SQL also **drops** the two unused `any_value` carry-along SELECT
|
|
243
|
+
terms for the gene-symbol and protein-accession columns present in the `/tmp`
|
|
244
|
+
original — a documented divergence, because the package's Spectronaut data does
|
|
245
|
+
not carry those columns and keeping them would Binder-Error duckdb over this
|
|
246
|
+
fixture.
|
|
247
|
+
|
|
248
|
+
The fixture → golden `.tsv` → golden `.json` chain **must be regenerated in
|
|
249
|
+
order**, or the artifacts silently drift:
|
|
250
|
+
|
|
251
|
+
1. `node tools/generate-spectronaut-precursor-fixture.mjs`
|
|
252
|
+
2. `tools/spectronaut-aggregate.sh files/demo/spectronaut-hye-precursor.tsv files/demo/spectronaut-hye-precursor-golden.tsv`
|
|
253
|
+
3. `node tools/derive-precursor-golden-sidecar.mjs`
|
|
254
|
+
|
|
255
|
+
## License
|
|
256
|
+
|
|
257
|
+
- **proteinGroups.txt** — Synthetic data, no restrictions.
|
|
258
|
+
- **cptac-spike-in.txt** — Public benchmark data from the Clinical Proteomic Tumor Analysis Consortium.
|
|
259
|
+
- **fragpipe-smoke-test.tsv** — Synthetic data, no restrictions.
|
|
260
|
+
- **spectronaut-hye-mix.tsv** — From SpectroPipeR, licensed under MIT.
|
|
261
|
+
- **spectronaut-hye-candidates.tsv** — Derived from `spectronaut-hye-mix.tsv` (MIT). DE values computed by this package; no restrictions.
|
|
262
|
+
- **spectronaut-hye-precursor.tsv** — Synthetic data, no restrictions.
|
|
263
|
+
- **spectronaut-hye-precursor-golden.tsv** — Derived (duckdb aggregation) from `spectronaut-hye-precursor.tsv` (synthetic); no restrictions.
|
|
264
|
+
- **spectronaut-hye-precursor-golden.json** — Transcribed from `spectronaut-hye-precursor-golden.tsv` (synthetic); no restrictions.
|