MaldiBatchKit 0.2.0__tar.gz → 0.2.2__tar.gz

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.
Files changed (49) hide show
  1. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2/MaldiBatchKit.egg-info}/PKG-INFO +26 -19
  2. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/MaldiBatchKit.egg-info/requires.txt +2 -2
  3. {maldibatchkit-0.2.0/MaldiBatchKit.egg-info → maldibatchkit-0.2.2}/PKG-INFO +26 -19
  4. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/README.md +23 -16
  5. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/__init__.py +1 -1
  6. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/_base.py +40 -6
  7. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/_cli_io.py +93 -60
  8. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/_utils.py +79 -5
  9. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/cli.py +78 -11
  10. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/corrections/auto.py +56 -30
  11. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/corrections/baselines.py +25 -16
  12. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/corrections/combat.py +55 -12
  13. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/corrections/harmony.py +58 -74
  14. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/corrections/limma.py +4 -2
  15. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/corrections/maldi.py +2 -2
  16. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/corrections/quality_weighted.py +58 -19
  17. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/diagnostics/benchmark.py +107 -34
  18. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/diagnostics/generic.py +5 -4
  19. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/diagnostics/maldi.py +9 -5
  20. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/diagnostics/report.py +41 -20
  21. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/integrations/maldiset.py +76 -28
  22. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/metrics.py +42 -27
  23. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/viz/peaks.py +2 -2
  24. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/viz/summary.py +0 -3
  25. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/viz/umap.py +4 -2
  26. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/requirements-docs.txt +1 -1
  27. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/requirements.txt +1 -1
  28. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/tests/test_cli.py +201 -2
  29. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/tests/test_cli_io.py +46 -9
  30. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/tests/test_metrics.py +77 -4
  31. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/tests/test_mz_axis_resolution.py +16 -5
  32. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/tests/test_no_data_leakage.py +1 -20
  33. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/LICENSE +0 -0
  34. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/MaldiBatchKit.egg-info/SOURCES.txt +0 -0
  35. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/MaldiBatchKit.egg-info/dependency_links.txt +0 -0
  36. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/MaldiBatchKit.egg-info/entry_points.txt +0 -0
  37. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/MaldiBatchKit.egg-info/top_level.txt +0 -0
  38. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/corrections/__init__.py +0 -0
  39. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/corrections/noop.py +0 -0
  40. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/diagnostics/__init__.py +0 -0
  41. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/integrations/__init__.py +0 -0
  42. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/py.typed +0 -0
  43. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/maldibatchkit/viz/__init__.py +0 -0
  44. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/pyproject.toml +0 -0
  45. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/requirements-dev.txt +0 -0
  46. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/requirements-viz.txt +0 -0
  47. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/setup.cfg +0 -0
  48. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/tests/test_package.py +0 -0
  49. {maldibatchkit-0.2.0 → maldibatchkit-0.2.2}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MaldiBatchKit
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Batch-effect correction methods for MALDI-TOF spectra in clinical AMR prediction workflows
5
5
  Author-email: Ettore Rocchi <ettore.rocchi3@unibo.it>
6
6
  License-Expression: MIT
@@ -27,7 +27,7 @@ Requires-Dist: pandas>=1.3.0
27
27
  Requires-Dist: scipy>=1.13.0
28
28
  Requires-Dist: scikit-learn>=1.6.0
29
29
  Requires-Dist: matplotlib>=3.4.0
30
- Requires-Dist: combatlearn>=2.0.0
30
+ Requires-Dist: combatlearn>=2.4.0
31
31
  Requires-Dist: harmonypy<2,>=0.2.0
32
32
  Requires-Dist: maldiamrkit>=0.15.0
33
33
  Requires-Dist: typer>=0.9.0
@@ -42,7 +42,7 @@ Requires-Dist: sphinx>=7.0.0; extra == "docs"
42
42
  Requires-Dist: pydata-sphinx-theme>=0.15.0; extra == "docs"
43
43
  Requires-Dist: sphinx-autodoc-typehints>=2.0.0; extra == "docs"
44
44
  Requires-Dist: sphinx-design>=0.6.0; extra == "docs"
45
- Requires-Dist: sphinx-click>=5.0.0; extra == "docs"
45
+ Requires-Dist: sphinxcontrib-typer>=0.5.0; extra == "docs"
46
46
  Requires-Dist: nbsphinx>=0.9.0; extra == "docs"
47
47
  Requires-Dist: ipykernel>=6.0.0; extra == "docs"
48
48
  Requires-Dist: ipywidgets>=8.0.0; extra == "docs"
@@ -62,13 +62,20 @@ Dynamic: license-file
62
62
  [![License](https://img.shields.io/github/license/EttoreRocchi/MaldiBatchKit)](https://github.com/EttoreRocchi/MaldiBatchKit/blob/main/LICENSE)
63
63
 
64
64
  <p align="center">
65
- <img src="docs/maldibatchkit_logo.png" alt="MaldiBatchKit" width="320"/>
65
+ <picture>
66
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/EttoreRocchi/MaldiBatchKit/main/docs/maldibatchkit_logo_dark.png">
67
+ <img src="https://raw.githubusercontent.com/EttoreRocchi/MaldiBatchKit/main/docs/maldibatchkit_logo.png" alt="MaldiBatchKit" width="320"/>
68
+ </picture>
66
69
  </p>
67
70
 
68
71
  <p align="center">
69
72
  <strong>Batch-effect correction methods for MALDI-TOF spectra in clinical AMR prediction workflows</strong>
70
73
  </p>
71
74
 
75
+ <p align="center">
76
+ <img src="https://raw.githubusercontent.com/EttoreRocchi/MaldiBatchKit/main/docs/batch_correction.svg" alt="Animated scatter plot: before correction MALDI-TOF samples cluster by acquisition site; after MaldiBatchKit the site effect is removed and samples cluster by species" width="720"/>
77
+ </p>
78
+
72
79
  <p align="center">
73
80
  <a href="#installation">Installation</a> •
74
81
  <a href="#features">Features</a> •
@@ -79,7 +86,7 @@ Dynamic: license-file
79
86
  <a href="#citation">Citation</a>
80
87
  </p>
81
88
 
82
- MaldiBatchKit is part of the **MaldiSuite** ecosystem and complements [MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit): where MaldiAMRKit handles preprocessing, alignment and AMR-aware evaluation, MaldiBatchKit focuses on the *harmonization* step, removing the inter-batch / inter-site shifts that plague multi-centre MALDI-TOF studies.
89
+ MaldiBatchKit corrects the inter-batch and inter-site shifts of multi-centre MALDI-TOF studies. It is part of the **MaldiSuite** ecosystem: it can be used on its own, or together with [MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit) and [MaldiDeepKit](https://github.com/EttoreRocchi/MaldiDeepKit).
83
90
 
84
91
  ## Installation
85
92
 
@@ -120,8 +127,8 @@ Visit the **MaldiSuite** landing page at <https://ettorerocchi.github.io/MaldiSu
120
127
  - `SpeciesAwareComBat` - convenience preset for ComBat-Fortin with `species` as the protected biological covariate.
121
128
  - **Diagnostics**: kBET, LISI, silhouette-by-batch, per-batch peak drift, per-batch TIC coefficient of variation, per-batch spectrum count, plus a combined `diagnostic_report` DataFrame summary.
122
129
  - **Method selection**: `AutoCorrector` exposes `method` as a settable hyperparameter so `GridSearchCV` can sweep across corrector families and let the downstream classifier metric (AUROC) decide. Ships with a `NoOpCorrector` so "do nothing" can sit on the candidate list as an honest baseline.
123
- - **Diagnostic benchmark**: `BatchCorrectionBenchmark` runs a fixed set of metrics across multiple correctors with stratified bootstrap CIs and a tidy `(method, metric, value, ci_lo, ci_hi)` summary, ready for paper-figure comparisons.
124
- - **Visualization**: UMAP before/after, per-batch peak-shape overlays, before/after bar charts.
130
+ - **Diagnostic benchmark**: `BatchCorrectionBenchmark` runs a fixed set of metrics across multiple correctors with intervals from stratified subsamples and a tidy `(method, metric, value, ci_lo, ci_hi)` summary, ready for paper-figure comparisons.
131
+ - **Visualisation**: UMAP before/after, per-batch peak-shape overlays, before/after bar charts.
125
132
  - **Integration adapter**: `MaldiSetAdapter` turns a `maldiamrkit.MaldiSet` into a corrected `MaldiSet` in one call.
126
133
  - **CLI**: `maldibatchkit correct ...` and `maldibatchkit diagnose ...`.
127
134
 
@@ -172,6 +179,8 @@ corrected_ds.X # harmonised feature matrix
172
179
  corrected_ds.y # AMR labels, unchanged
173
180
  ```
174
181
 
182
+ The `*_column` arguments name columns of the metadata behind `ds.meta`; a missing column raises `KeyError`. A corrector uses only what it accepts: `quality_column` has no effect with `SpeciesAwareComBat`.
183
+
175
184
  ### CLI
176
185
 
177
186
  The CLI is organised as `maldibatchkit correct <method>` + `maldibatchkit diagnose`. Every method has its own subcommand with only the flags it actually uses:
@@ -212,7 +221,7 @@ maldibatchkit correct combat-fortin \
212
221
  -o corrected.npz
213
222
  ```
214
223
 
215
- Run `maldibatchkit correct <method> --help` for the full flag list of any corrector. `combat-fortin` / `combat-chen` refuse to run without covariates (they would silently reduce to Johnson ComBat); `species-combat` / `quality-combat` require their dedicated `--species-csv` / `--quality-csv` inputs.
224
+ Run `maldibatchkit correct <method> --help` for the full flag list of any corrector. `combat-fortin` refuses to run without covariates (it would silently reduce to Johnson ComBat); `combat-chen` without covariates is plain CovBat (Johnson ComBat plus the covariance correction); `species-combat` / `quality-combat` require their dedicated `--species-csv` / `--quality-csv` inputs.
216
225
 
217
226
  ## Algorithms
218
227
 
@@ -220,7 +229,7 @@ Run `maldibatchkit correct <method> --help` for the full flag list of any correc
220
229
  |--------------------------------|---------------------------|----------------------|------------------|
221
230
  | ComBat (Johnson, Fortin, Chen) | `ComBat` | Fortin / Chen | yes |
222
231
  | Limma | `Limma` | via `design=` | yes |
223
- | Harmony | `Harmony` | via `covariates=` | yes |
232
+ | Harmony | `Harmony` | no (removes them) | yes |
224
233
  | Median centering | `MedianCentering` | no | yes |
225
234
  | Z-score per batch | `ZScorePerBatch` | no | yes |
226
235
  | Reference scaling | `ReferenceScaling` | no | yes |
@@ -246,7 +255,7 @@ from sklearn.pipeline import Pipeline
246
255
  from maldibatchkit import AutoCorrector
247
256
 
248
257
  pipe = Pipeline([
249
- ("correct", AutoCorrector(batch=batch, discrete_covariates=species)),
258
+ ("correct", AutoCorrector(batch=batch, discrete_covariates=species, quality=snr)),
250
259
  ("clf", LogisticRegression(max_iter=1000)),
251
260
  ])
252
261
  grid = GridSearchCV(
@@ -343,26 +352,24 @@ from maldibatchkit.diagnostics import (
343
352
  )
344
353
  ```
345
354
 
346
- All metrics take the same `(X, batch)` signature. `diagnostic_report` composes them into a tidy DataFrame suitable for `plot_diagnostic_summary`.
355
+ Most metrics take `(X, batch)`; `per_batch_spectrum_count` takes only `batch`. `diagnostic_report(before, after, batch)` composes them into a tidy DataFrame suitable for `plot_diagnostic_summary`.
347
356
 
348
- ## MaldiSuite Ecosystem
357
+ ## MaldiSuite ecosystem
349
358
 
350
- MaldiBatchKit is the harmonisation package of the **MaldiSuite** ecosystem:
359
+ MaldiBatchKit is one of the three packages of the **MaldiSuite** ecosystem:
351
360
 
352
361
  - **[MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit)** - data model (`MaldiSpectrum`, `MaldiSet`), preprocessing, alignment, peak detection, differential analysis, and AMR-aware evaluation.
353
362
  - **MaldiBatchKit** (this package) - batch-effect correction and harmonisation for multi-centre / multi-instrument MALDI-TOF spectra.
354
363
  - **[MaldiDeepKit](https://github.com/EttoreRocchi/MaldiDeepKit)** - sklearn-compatible deep learning classifiers (MLP, CNN, ResNet, Transformer).
355
364
 
356
- The three packages share the `MaldiSet` / `MaldiSpectrum` data model and are designed to compose in a single end-to-end pipeline. Install the full suite with `pip install maldisuite`. Landing page: [MaldiSuite](<https://ettorerocchi.github.io/MaldiSuite/>).
365
+ The three packages share the `MaldiSet` data model. Each can be used on its own, or combined with the others. Install the full suite with `pip install maldisuite`. Landing page: [MaldiSuite](<https://ettorerocchi.github.io/MaldiSuite/>).
357
366
 
358
367
  ## Citation
359
368
 
360
- If you use MaldiBatchKit in academic work please cite:
361
-
362
- > _Citation will be available soon._
369
+ MaldiBatchKit is part of MaldiSuite, which is described in an Application Note currently under review at *Bioinformatics*. The full citation will be added here once the article is published.
363
370
 
364
- along with the upstream references for whichever methods you apply (Johnson 2007, Fortin 2018, Chen 2022, Ritchie 2015, Korsunsky 2019).
371
+ Please also cite the upstream references for whichever methods you apply (Johnson 2007, Fortin 2018, Chen 2022, Ritchie 2015, Korsunsky 2019).
365
372
 
366
373
  ## License
367
374
 
368
- MIT. See [LICENSE](LICENSE).
375
+ MIT. See [LICENSE](https://github.com/EttoreRocchi/MaldiBatchKit/blob/main/LICENSE).
@@ -3,7 +3,7 @@ pandas>=1.3.0
3
3
  scipy>=1.13.0
4
4
  scikit-learn>=1.6.0
5
5
  matplotlib>=3.4.0
6
- combatlearn>=2.0.0
6
+ combatlearn>=2.4.0
7
7
  harmonypy<2,>=0.2.0
8
8
  maldiamrkit>=0.15.0
9
9
  typer>=0.9.0
@@ -20,7 +20,7 @@ sphinx>=7.0.0
20
20
  pydata-sphinx-theme>=0.15.0
21
21
  sphinx-autodoc-typehints>=2.0.0
22
22
  sphinx-design>=0.6.0
23
- sphinx-click>=5.0.0
23
+ sphinxcontrib-typer>=0.5.0
24
24
  nbsphinx>=0.9.0
25
25
  ipykernel>=6.0.0
26
26
  ipywidgets>=8.0.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MaldiBatchKit
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Batch-effect correction methods for MALDI-TOF spectra in clinical AMR prediction workflows
5
5
  Author-email: Ettore Rocchi <ettore.rocchi3@unibo.it>
6
6
  License-Expression: MIT
@@ -27,7 +27,7 @@ Requires-Dist: pandas>=1.3.0
27
27
  Requires-Dist: scipy>=1.13.0
28
28
  Requires-Dist: scikit-learn>=1.6.0
29
29
  Requires-Dist: matplotlib>=3.4.0
30
- Requires-Dist: combatlearn>=2.0.0
30
+ Requires-Dist: combatlearn>=2.4.0
31
31
  Requires-Dist: harmonypy<2,>=0.2.0
32
32
  Requires-Dist: maldiamrkit>=0.15.0
33
33
  Requires-Dist: typer>=0.9.0
@@ -42,7 +42,7 @@ Requires-Dist: sphinx>=7.0.0; extra == "docs"
42
42
  Requires-Dist: pydata-sphinx-theme>=0.15.0; extra == "docs"
43
43
  Requires-Dist: sphinx-autodoc-typehints>=2.0.0; extra == "docs"
44
44
  Requires-Dist: sphinx-design>=0.6.0; extra == "docs"
45
- Requires-Dist: sphinx-click>=5.0.0; extra == "docs"
45
+ Requires-Dist: sphinxcontrib-typer>=0.5.0; extra == "docs"
46
46
  Requires-Dist: nbsphinx>=0.9.0; extra == "docs"
47
47
  Requires-Dist: ipykernel>=6.0.0; extra == "docs"
48
48
  Requires-Dist: ipywidgets>=8.0.0; extra == "docs"
@@ -62,13 +62,20 @@ Dynamic: license-file
62
62
  [![License](https://img.shields.io/github/license/EttoreRocchi/MaldiBatchKit)](https://github.com/EttoreRocchi/MaldiBatchKit/blob/main/LICENSE)
63
63
 
64
64
  <p align="center">
65
- <img src="docs/maldibatchkit_logo.png" alt="MaldiBatchKit" width="320"/>
65
+ <picture>
66
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/EttoreRocchi/MaldiBatchKit/main/docs/maldibatchkit_logo_dark.png">
67
+ <img src="https://raw.githubusercontent.com/EttoreRocchi/MaldiBatchKit/main/docs/maldibatchkit_logo.png" alt="MaldiBatchKit" width="320"/>
68
+ </picture>
66
69
  </p>
67
70
 
68
71
  <p align="center">
69
72
  <strong>Batch-effect correction methods for MALDI-TOF spectra in clinical AMR prediction workflows</strong>
70
73
  </p>
71
74
 
75
+ <p align="center">
76
+ <img src="https://raw.githubusercontent.com/EttoreRocchi/MaldiBatchKit/main/docs/batch_correction.svg" alt="Animated scatter plot: before correction MALDI-TOF samples cluster by acquisition site; after MaldiBatchKit the site effect is removed and samples cluster by species" width="720"/>
77
+ </p>
78
+
72
79
  <p align="center">
73
80
  <a href="#installation">Installation</a> •
74
81
  <a href="#features">Features</a> •
@@ -79,7 +86,7 @@ Dynamic: license-file
79
86
  <a href="#citation">Citation</a>
80
87
  </p>
81
88
 
82
- MaldiBatchKit is part of the **MaldiSuite** ecosystem and complements [MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit): where MaldiAMRKit handles preprocessing, alignment and AMR-aware evaluation, MaldiBatchKit focuses on the *harmonization* step, removing the inter-batch / inter-site shifts that plague multi-centre MALDI-TOF studies.
89
+ MaldiBatchKit corrects the inter-batch and inter-site shifts of multi-centre MALDI-TOF studies. It is part of the **MaldiSuite** ecosystem: it can be used on its own, or together with [MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit) and [MaldiDeepKit](https://github.com/EttoreRocchi/MaldiDeepKit).
83
90
 
84
91
  ## Installation
85
92
 
@@ -120,8 +127,8 @@ Visit the **MaldiSuite** landing page at <https://ettorerocchi.github.io/MaldiSu
120
127
  - `SpeciesAwareComBat` - convenience preset for ComBat-Fortin with `species` as the protected biological covariate.
121
128
  - **Diagnostics**: kBET, LISI, silhouette-by-batch, per-batch peak drift, per-batch TIC coefficient of variation, per-batch spectrum count, plus a combined `diagnostic_report` DataFrame summary.
122
129
  - **Method selection**: `AutoCorrector` exposes `method` as a settable hyperparameter so `GridSearchCV` can sweep across corrector families and let the downstream classifier metric (AUROC) decide. Ships with a `NoOpCorrector` so "do nothing" can sit on the candidate list as an honest baseline.
123
- - **Diagnostic benchmark**: `BatchCorrectionBenchmark` runs a fixed set of metrics across multiple correctors with stratified bootstrap CIs and a tidy `(method, metric, value, ci_lo, ci_hi)` summary, ready for paper-figure comparisons.
124
- - **Visualization**: UMAP before/after, per-batch peak-shape overlays, before/after bar charts.
130
+ - **Diagnostic benchmark**: `BatchCorrectionBenchmark` runs a fixed set of metrics across multiple correctors with intervals from stratified subsamples and a tidy `(method, metric, value, ci_lo, ci_hi)` summary, ready for paper-figure comparisons.
131
+ - **Visualisation**: UMAP before/after, per-batch peak-shape overlays, before/after bar charts.
125
132
  - **Integration adapter**: `MaldiSetAdapter` turns a `maldiamrkit.MaldiSet` into a corrected `MaldiSet` in one call.
126
133
  - **CLI**: `maldibatchkit correct ...` and `maldibatchkit diagnose ...`.
127
134
 
@@ -172,6 +179,8 @@ corrected_ds.X # harmonised feature matrix
172
179
  corrected_ds.y # AMR labels, unchanged
173
180
  ```
174
181
 
182
+ The `*_column` arguments name columns of the metadata behind `ds.meta`; a missing column raises `KeyError`. A corrector uses only what it accepts: `quality_column` has no effect with `SpeciesAwareComBat`.
183
+
175
184
  ### CLI
176
185
 
177
186
  The CLI is organised as `maldibatchkit correct <method>` + `maldibatchkit diagnose`. Every method has its own subcommand with only the flags it actually uses:
@@ -212,7 +221,7 @@ maldibatchkit correct combat-fortin \
212
221
  -o corrected.npz
213
222
  ```
214
223
 
215
- Run `maldibatchkit correct <method> --help` for the full flag list of any corrector. `combat-fortin` / `combat-chen` refuse to run without covariates (they would silently reduce to Johnson ComBat); `species-combat` / `quality-combat` require their dedicated `--species-csv` / `--quality-csv` inputs.
224
+ Run `maldibatchkit correct <method> --help` for the full flag list of any corrector. `combat-fortin` refuses to run without covariates (it would silently reduce to Johnson ComBat); `combat-chen` without covariates is plain CovBat (Johnson ComBat plus the covariance correction); `species-combat` / `quality-combat` require their dedicated `--species-csv` / `--quality-csv` inputs.
216
225
 
217
226
  ## Algorithms
218
227
 
@@ -220,7 +229,7 @@ Run `maldibatchkit correct <method> --help` for the full flag list of any correc
220
229
  |--------------------------------|---------------------------|----------------------|------------------|
221
230
  | ComBat (Johnson, Fortin, Chen) | `ComBat` | Fortin / Chen | yes |
222
231
  | Limma | `Limma` | via `design=` | yes |
223
- | Harmony | `Harmony` | via `covariates=` | yes |
232
+ | Harmony | `Harmony` | no (removes them) | yes |
224
233
  | Median centering | `MedianCentering` | no | yes |
225
234
  | Z-score per batch | `ZScorePerBatch` | no | yes |
226
235
  | Reference scaling | `ReferenceScaling` | no | yes |
@@ -246,7 +255,7 @@ from sklearn.pipeline import Pipeline
246
255
  from maldibatchkit import AutoCorrector
247
256
 
248
257
  pipe = Pipeline([
249
- ("correct", AutoCorrector(batch=batch, discrete_covariates=species)),
258
+ ("correct", AutoCorrector(batch=batch, discrete_covariates=species, quality=snr)),
250
259
  ("clf", LogisticRegression(max_iter=1000)),
251
260
  ])
252
261
  grid = GridSearchCV(
@@ -343,26 +352,24 @@ from maldibatchkit.diagnostics import (
343
352
  )
344
353
  ```
345
354
 
346
- All metrics take the same `(X, batch)` signature. `diagnostic_report` composes them into a tidy DataFrame suitable for `plot_diagnostic_summary`.
355
+ Most metrics take `(X, batch)`; `per_batch_spectrum_count` takes only `batch`. `diagnostic_report(before, after, batch)` composes them into a tidy DataFrame suitable for `plot_diagnostic_summary`.
347
356
 
348
- ## MaldiSuite Ecosystem
357
+ ## MaldiSuite ecosystem
349
358
 
350
- MaldiBatchKit is the harmonisation package of the **MaldiSuite** ecosystem:
359
+ MaldiBatchKit is one of the three packages of the **MaldiSuite** ecosystem:
351
360
 
352
361
  - **[MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit)** - data model (`MaldiSpectrum`, `MaldiSet`), preprocessing, alignment, peak detection, differential analysis, and AMR-aware evaluation.
353
362
  - **MaldiBatchKit** (this package) - batch-effect correction and harmonisation for multi-centre / multi-instrument MALDI-TOF spectra.
354
363
  - **[MaldiDeepKit](https://github.com/EttoreRocchi/MaldiDeepKit)** - sklearn-compatible deep learning classifiers (MLP, CNN, ResNet, Transformer).
355
364
 
356
- The three packages share the `MaldiSet` / `MaldiSpectrum` data model and are designed to compose in a single end-to-end pipeline. Install the full suite with `pip install maldisuite`. Landing page: [MaldiSuite](<https://ettorerocchi.github.io/MaldiSuite/>).
365
+ The three packages share the `MaldiSet` data model. Each can be used on its own, or combined with the others. Install the full suite with `pip install maldisuite`. Landing page: [MaldiSuite](<https://ettorerocchi.github.io/MaldiSuite/>).
357
366
 
358
367
  ## Citation
359
368
 
360
- If you use MaldiBatchKit in academic work please cite:
361
-
362
- > _Citation will be available soon._
369
+ MaldiBatchKit is part of MaldiSuite, which is described in an Application Note currently under review at *Bioinformatics*. The full citation will be added here once the article is published.
363
370
 
364
- along with the upstream references for whichever methods you apply (Johnson 2007, Fortin 2018, Chen 2022, Ritchie 2015, Korsunsky 2019).
371
+ Please also cite the upstream references for whichever methods you apply (Johnson 2007, Fortin 2018, Chen 2022, Ritchie 2015, Korsunsky 2019).
365
372
 
366
373
  ## License
367
374
 
368
- MIT. See [LICENSE](LICENSE).
375
+ MIT. See [LICENSE](https://github.com/EttoreRocchi/MaldiBatchKit/blob/main/LICENSE).
@@ -9,13 +9,20 @@
9
9
  [![License](https://img.shields.io/github/license/EttoreRocchi/MaldiBatchKit)](https://github.com/EttoreRocchi/MaldiBatchKit/blob/main/LICENSE)
10
10
 
11
11
  <p align="center">
12
- <img src="docs/maldibatchkit_logo.png" alt="MaldiBatchKit" width="320"/>
12
+ <picture>
13
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/EttoreRocchi/MaldiBatchKit/main/docs/maldibatchkit_logo_dark.png">
14
+ <img src="https://raw.githubusercontent.com/EttoreRocchi/MaldiBatchKit/main/docs/maldibatchkit_logo.png" alt="MaldiBatchKit" width="320"/>
15
+ </picture>
13
16
  </p>
14
17
 
15
18
  <p align="center">
16
19
  <strong>Batch-effect correction methods for MALDI-TOF spectra in clinical AMR prediction workflows</strong>
17
20
  </p>
18
21
 
22
+ <p align="center">
23
+ <img src="https://raw.githubusercontent.com/EttoreRocchi/MaldiBatchKit/main/docs/batch_correction.svg" alt="Animated scatter plot: before correction MALDI-TOF samples cluster by acquisition site; after MaldiBatchKit the site effect is removed and samples cluster by species" width="720"/>
24
+ </p>
25
+
19
26
  <p align="center">
20
27
  <a href="#installation">Installation</a> •
21
28
  <a href="#features">Features</a> •
@@ -26,7 +33,7 @@
26
33
  <a href="#citation">Citation</a>
27
34
  </p>
28
35
 
29
- MaldiBatchKit is part of the **MaldiSuite** ecosystem and complements [MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit): where MaldiAMRKit handles preprocessing, alignment and AMR-aware evaluation, MaldiBatchKit focuses on the *harmonization* step, removing the inter-batch / inter-site shifts that plague multi-centre MALDI-TOF studies.
36
+ MaldiBatchKit corrects the inter-batch and inter-site shifts of multi-centre MALDI-TOF studies. It is part of the **MaldiSuite** ecosystem: it can be used on its own, or together with [MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit) and [MaldiDeepKit](https://github.com/EttoreRocchi/MaldiDeepKit).
30
37
 
31
38
  ## Installation
32
39
 
@@ -67,8 +74,8 @@ Visit the **MaldiSuite** landing page at <https://ettorerocchi.github.io/MaldiSu
67
74
  - `SpeciesAwareComBat` - convenience preset for ComBat-Fortin with `species` as the protected biological covariate.
68
75
  - **Diagnostics**: kBET, LISI, silhouette-by-batch, per-batch peak drift, per-batch TIC coefficient of variation, per-batch spectrum count, plus a combined `diagnostic_report` DataFrame summary.
69
76
  - **Method selection**: `AutoCorrector` exposes `method` as a settable hyperparameter so `GridSearchCV` can sweep across corrector families and let the downstream classifier metric (AUROC) decide. Ships with a `NoOpCorrector` so "do nothing" can sit on the candidate list as an honest baseline.
70
- - **Diagnostic benchmark**: `BatchCorrectionBenchmark` runs a fixed set of metrics across multiple correctors with stratified bootstrap CIs and a tidy `(method, metric, value, ci_lo, ci_hi)` summary, ready for paper-figure comparisons.
71
- - **Visualization**: UMAP before/after, per-batch peak-shape overlays, before/after bar charts.
77
+ - **Diagnostic benchmark**: `BatchCorrectionBenchmark` runs a fixed set of metrics across multiple correctors with intervals from stratified subsamples and a tidy `(method, metric, value, ci_lo, ci_hi)` summary, ready for paper-figure comparisons.
78
+ - **Visualisation**: UMAP before/after, per-batch peak-shape overlays, before/after bar charts.
72
79
  - **Integration adapter**: `MaldiSetAdapter` turns a `maldiamrkit.MaldiSet` into a corrected `MaldiSet` in one call.
73
80
  - **CLI**: `maldibatchkit correct ...` and `maldibatchkit diagnose ...`.
74
81
 
@@ -119,6 +126,8 @@ corrected_ds.X # harmonised feature matrix
119
126
  corrected_ds.y # AMR labels, unchanged
120
127
  ```
121
128
 
129
+ The `*_column` arguments name columns of the metadata behind `ds.meta`; a missing column raises `KeyError`. A corrector uses only what it accepts: `quality_column` has no effect with `SpeciesAwareComBat`.
130
+
122
131
  ### CLI
123
132
 
124
133
  The CLI is organised as `maldibatchkit correct <method>` + `maldibatchkit diagnose`. Every method has its own subcommand with only the flags it actually uses:
@@ -159,7 +168,7 @@ maldibatchkit correct combat-fortin \
159
168
  -o corrected.npz
160
169
  ```
161
170
 
162
- Run `maldibatchkit correct <method> --help` for the full flag list of any corrector. `combat-fortin` / `combat-chen` refuse to run without covariates (they would silently reduce to Johnson ComBat); `species-combat` / `quality-combat` require their dedicated `--species-csv` / `--quality-csv` inputs.
171
+ Run `maldibatchkit correct <method> --help` for the full flag list of any corrector. `combat-fortin` refuses to run without covariates (it would silently reduce to Johnson ComBat); `combat-chen` without covariates is plain CovBat (Johnson ComBat plus the covariance correction); `species-combat` / `quality-combat` require their dedicated `--species-csv` / `--quality-csv` inputs.
163
172
 
164
173
  ## Algorithms
165
174
 
@@ -167,7 +176,7 @@ Run `maldibatchkit correct <method> --help` for the full flag list of any correc
167
176
  |--------------------------------|---------------------------|----------------------|------------------|
168
177
  | ComBat (Johnson, Fortin, Chen) | `ComBat` | Fortin / Chen | yes |
169
178
  | Limma | `Limma` | via `design=` | yes |
170
- | Harmony | `Harmony` | via `covariates=` | yes |
179
+ | Harmony | `Harmony` | no (removes them) | yes |
171
180
  | Median centering | `MedianCentering` | no | yes |
172
181
  | Z-score per batch | `ZScorePerBatch` | no | yes |
173
182
  | Reference scaling | `ReferenceScaling` | no | yes |
@@ -193,7 +202,7 @@ from sklearn.pipeline import Pipeline
193
202
  from maldibatchkit import AutoCorrector
194
203
 
195
204
  pipe = Pipeline([
196
- ("correct", AutoCorrector(batch=batch, discrete_covariates=species)),
205
+ ("correct", AutoCorrector(batch=batch, discrete_covariates=species, quality=snr)),
197
206
  ("clf", LogisticRegression(max_iter=1000)),
198
207
  ])
199
208
  grid = GridSearchCV(
@@ -290,26 +299,24 @@ from maldibatchkit.diagnostics import (
290
299
  )
291
300
  ```
292
301
 
293
- All metrics take the same `(X, batch)` signature. `diagnostic_report` composes them into a tidy DataFrame suitable for `plot_diagnostic_summary`.
302
+ Most metrics take `(X, batch)`; `per_batch_spectrum_count` takes only `batch`. `diagnostic_report(before, after, batch)` composes them into a tidy DataFrame suitable for `plot_diagnostic_summary`.
294
303
 
295
- ## MaldiSuite Ecosystem
304
+ ## MaldiSuite ecosystem
296
305
 
297
- MaldiBatchKit is the harmonisation package of the **MaldiSuite** ecosystem:
306
+ MaldiBatchKit is one of the three packages of the **MaldiSuite** ecosystem:
298
307
 
299
308
  - **[MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit)** - data model (`MaldiSpectrum`, `MaldiSet`), preprocessing, alignment, peak detection, differential analysis, and AMR-aware evaluation.
300
309
  - **MaldiBatchKit** (this package) - batch-effect correction and harmonisation for multi-centre / multi-instrument MALDI-TOF spectra.
301
310
  - **[MaldiDeepKit](https://github.com/EttoreRocchi/MaldiDeepKit)** - sklearn-compatible deep learning classifiers (MLP, CNN, ResNet, Transformer).
302
311
 
303
- The three packages share the `MaldiSet` / `MaldiSpectrum` data model and are designed to compose in a single end-to-end pipeline. Install the full suite with `pip install maldisuite`. Landing page: [MaldiSuite](<https://ettorerocchi.github.io/MaldiSuite/>).
312
+ The three packages share the `MaldiSet` data model. Each can be used on its own, or combined with the others. Install the full suite with `pip install maldisuite`. Landing page: [MaldiSuite](<https://ettorerocchi.github.io/MaldiSuite/>).
304
313
 
305
314
  ## Citation
306
315
 
307
- If you use MaldiBatchKit in academic work please cite:
308
-
309
- > _Citation will be available soon._
316
+ MaldiBatchKit is part of MaldiSuite, which is described in an Application Note currently under review at *Bioinformatics*. The full citation will be added here once the article is published.
310
317
 
311
- along with the upstream references for whichever methods you apply (Johnson 2007, Fortin 2018, Chen 2022, Ritchie 2015, Korsunsky 2019).
318
+ Please also cite the upstream references for whichever methods you apply (Johnson 2007, Fortin 2018, Chen 2022, Ritchie 2015, Korsunsky 2019).
312
319
 
313
320
  ## License
314
321
 
315
- MIT. See [LICENSE](LICENSE).
322
+ MIT. See [LICENSE](https://github.com/EttoreRocchi/MaldiBatchKit/blob/main/LICENSE).
@@ -58,7 +58,7 @@ from .metrics import (
58
58
  make_batch_scorer,
59
59
  )
60
60
 
61
- __version__ = "0.2.0"
61
+ __version__ = "0.2.2"
62
62
  __author__ = "Ettore Rocchi"
63
63
 
64
64
  __all__ = [
@@ -27,7 +27,14 @@ import pandas as pd
27
27
  from sklearn.base import BaseEstimator, TransformerMixin
28
28
  from sklearn.utils.validation import check_array, check_is_fitted
29
29
 
30
- from ._utils import ArrayLike, _ensure_index, _subset
30
+ from ._utils import (
31
+ ArrayLike,
32
+ _check_label_values,
33
+ _check_positional_alignment,
34
+ _check_unique_ids,
35
+ _ensure_index,
36
+ _subset,
37
+ )
31
38
 
32
39
 
33
40
  def _check_array_finite(X: Any) -> None:
@@ -65,6 +72,8 @@ class BaseBatchCorrector(BaseEstimator, TransformerMixin): # type: ignore[misc]
65
72
  :meth:`get_params` / :meth:`set_params` work.
66
73
  """
67
74
 
75
+ _sample_aligned_params: tuple[str, ...] = ("batch",)
76
+
68
77
  def __init__(self, batch: ArrayLike) -> None:
69
78
  self.batch = batch
70
79
 
@@ -72,6 +81,13 @@ class BaseBatchCorrector(BaseEstimator, TransformerMixin): # type: ignore[misc]
72
81
  """Validate the feature matrix."""
73
82
  _check_array_finite(X)
74
83
 
84
+ def _check_sample_alignment(self, X: ArrayLike) -> None:
85
+ """Reject pandas per-sample inputs that an ndarray ``X`` cannot match."""
86
+ if isinstance(X, pd.DataFrame | pd.Series):
87
+ return
88
+ for name in self._sample_aligned_params:
89
+ _check_positional_alignment(getattr(self, name, None), len(X), name)
90
+
75
91
  def _prepare_fit(
76
92
  self, X: ArrayLike
77
93
  ) -> tuple[pd.DataFrame, npt.NDArray[Any], pd.Index]:
@@ -87,7 +103,10 @@ class BaseBatchCorrector(BaseEstimator, TransformerMixin): # type: ignore[misc]
87
103
  The shared index used by ``X`` and ``batch``.
88
104
  """
89
105
  self._validate_X(X)
106
+ self._check_sample_alignment(X)
90
107
  idx = _ensure_index(X)
108
+ _check_unique_ids(idx, "X")
109
+ self._fitted_on_frame_ = isinstance(X, pd.DataFrame)
91
110
  if isinstance(X, pd.DataFrame):
92
111
  self.feature_names_in_ = np.asarray(X.columns, dtype=object)
93
112
  X_df = X
@@ -104,11 +123,7 @@ class BaseBatchCorrector(BaseEstimator, TransformerMixin): # type: ignore[misc]
104
123
  raise ValueError(f"`batch` must be 1-D; got shape {batch_vec.shape}.")
105
124
  batch_vec = batch_vec.iloc[:, 0]
106
125
  batch_ser = pd.Series(batch_vec, index=idx)
107
- if batch_ser.isna().any():
108
- raise ValueError(
109
- f"batch contains {int(batch_ser.isna().sum())} NaN value(s); "
110
- f"all batch labels must be non-null."
111
- )
126
+ _check_label_values(batch_ser, "batch")
112
127
  return X_df, batch_ser.to_numpy(), idx
113
128
 
114
129
  def _prepare_transform(
@@ -117,13 +132,32 @@ class BaseBatchCorrector(BaseEstimator, TransformerMixin): # type: ignore[misc]
117
132
  """Run common ``transform``-time bookkeeping."""
118
133
  check_is_fitted(self)
119
134
  self._validate_X(X)
135
+ self._check_sample_alignment(X)
120
136
  idx = _ensure_index(X)
137
+ _check_unique_ids(idx, "X")
121
138
  was_df = isinstance(X, pd.DataFrame)
122
139
  X_df = X if was_df else pd.DataFrame(np.asarray(X), index=idx)
140
+ if X_df.shape[1] != self.n_features_in_:
141
+ raise ValueError(
142
+ f"X has {X_df.shape[1]} features, but {type(self).__name__} "
143
+ f"is expecting {self.n_features_in_} features as input."
144
+ )
145
+ if (
146
+ was_df
147
+ and getattr(self, "_fitted_on_frame_", False)
148
+ and not np.array_equal(
149
+ np.asarray(X.columns, dtype=object), self.feature_names_in_
150
+ )
151
+ ):
152
+ raise ValueError(
153
+ "The feature names should match those that were passed during "
154
+ "fit, in the same order."
155
+ )
123
156
  batch_vec = _subset(self.batch, idx)
124
157
  if isinstance(batch_vec, pd.DataFrame):
125
158
  batch_vec = batch_vec.iloc[:, 0]
126
159
  batch_ser = pd.Series(batch_vec, index=idx)
160
+ _check_label_values(batch_ser, "batch")
127
161
  return X_df, batch_ser.to_numpy(), idx, was_df
128
162
 
129
163
  def _fit_impl(