MaldiBatchKit 0.2.1__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.
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2/MaldiBatchKit.egg-info}/PKG-INFO +20 -17
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/MaldiBatchKit.egg-info/requires.txt +1 -1
- {maldibatchkit-0.2.1/MaldiBatchKit.egg-info → maldibatchkit-0.2.2}/PKG-INFO +20 -17
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/README.md +18 -15
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/__init__.py +1 -1
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/cli.py +9 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/corrections/baselines.py +3 -3
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/corrections/maldi.py +1 -1
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/metrics.py +15 -5
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/requirements-docs.txt +1 -1
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/tests/test_cli.py +23 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/tests/test_metrics.py +22 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/LICENSE +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/MaldiBatchKit.egg-info/SOURCES.txt +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/MaldiBatchKit.egg-info/dependency_links.txt +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/MaldiBatchKit.egg-info/entry_points.txt +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/MaldiBatchKit.egg-info/top_level.txt +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/_base.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/_cli_io.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/_utils.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/corrections/__init__.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/corrections/auto.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/corrections/combat.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/corrections/harmony.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/corrections/limma.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/corrections/noop.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/corrections/quality_weighted.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/diagnostics/__init__.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/diagnostics/benchmark.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/diagnostics/generic.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/diagnostics/maldi.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/diagnostics/report.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/integrations/__init__.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/integrations/maldiset.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/py.typed +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/viz/__init__.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/viz/peaks.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/viz/summary.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/maldibatchkit/viz/umap.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/pyproject.toml +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/requirements-dev.txt +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/requirements-viz.txt +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/requirements.txt +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/setup.cfg +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/tests/test_cli_io.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/tests/test_mz_axis_resolution.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/tests/test_no_data_leakage.py +0 -0
- {maldibatchkit-0.2.1 → maldibatchkit-0.2.2}/tests/test_package.py +0 -0
- {maldibatchkit-0.2.1 → 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.
|
|
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
|
|
@@ -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:
|
|
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,7 +62,10 @@ Dynamic: license-file
|
|
|
62
62
|
[](https://github.com/EttoreRocchi/MaldiBatchKit/blob/main/LICENSE)
|
|
63
63
|
|
|
64
64
|
<p align="center">
|
|
65
|
-
<
|
|
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">
|
|
@@ -70,7 +73,7 @@ Dynamic: license-file
|
|
|
70
73
|
</p>
|
|
71
74
|
|
|
72
75
|
<p align="center">
|
|
73
|
-
<img src="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"/>
|
|
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"/>
|
|
74
77
|
</p>
|
|
75
78
|
|
|
76
79
|
<p align="center">
|
|
@@ -83,7 +86,7 @@ Dynamic: license-file
|
|
|
83
86
|
<a href="#citation">Citation</a>
|
|
84
87
|
</p>
|
|
85
88
|
|
|
86
|
-
MaldiBatchKit is part of the **MaldiSuite** ecosystem
|
|
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).
|
|
87
90
|
|
|
88
91
|
## Installation
|
|
89
92
|
|
|
@@ -124,8 +127,8 @@ Visit the **MaldiSuite** landing page at <https://ettorerocchi.github.io/MaldiSu
|
|
|
124
127
|
- `SpeciesAwareComBat` - convenience preset for ComBat-Fortin with `species` as the protected biological covariate.
|
|
125
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.
|
|
126
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.
|
|
127
|
-
- **Diagnostic benchmark**: `BatchCorrectionBenchmark` runs a fixed set of metrics across multiple correctors with stratified
|
|
128
|
-
- **
|
|
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.
|
|
129
132
|
- **Integration adapter**: `MaldiSetAdapter` turns a `maldiamrkit.MaldiSet` into a corrected `MaldiSet` in one call.
|
|
130
133
|
- **CLI**: `maldibatchkit correct ...` and `maldibatchkit diagnose ...`.
|
|
131
134
|
|
|
@@ -176,6 +179,8 @@ corrected_ds.X # harmonised feature matrix
|
|
|
176
179
|
corrected_ds.y # AMR labels, unchanged
|
|
177
180
|
```
|
|
178
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
|
+
|
|
179
184
|
### CLI
|
|
180
185
|
|
|
181
186
|
The CLI is organised as `maldibatchkit correct <method>` + `maldibatchkit diagnose`. Every method has its own subcommand with only the flags it actually uses:
|
|
@@ -250,7 +255,7 @@ from sklearn.pipeline import Pipeline
|
|
|
250
255
|
from maldibatchkit import AutoCorrector
|
|
251
256
|
|
|
252
257
|
pipe = Pipeline([
|
|
253
|
-
("correct", AutoCorrector(batch=batch, discrete_covariates=species)),
|
|
258
|
+
("correct", AutoCorrector(batch=batch, discrete_covariates=species, quality=snr)),
|
|
254
259
|
("clf", LogisticRegression(max_iter=1000)),
|
|
255
260
|
])
|
|
256
261
|
grid = GridSearchCV(
|
|
@@ -347,26 +352,24 @@ from maldibatchkit.diagnostics import (
|
|
|
347
352
|
)
|
|
348
353
|
```
|
|
349
354
|
|
|
350
|
-
|
|
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`.
|
|
351
356
|
|
|
352
|
-
## MaldiSuite
|
|
357
|
+
## MaldiSuite ecosystem
|
|
353
358
|
|
|
354
|
-
MaldiBatchKit is the
|
|
359
|
+
MaldiBatchKit is one of the three packages of the **MaldiSuite** ecosystem:
|
|
355
360
|
|
|
356
361
|
- **[MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit)** - data model (`MaldiSpectrum`, `MaldiSet`), preprocessing, alignment, peak detection, differential analysis, and AMR-aware evaluation.
|
|
357
362
|
- **MaldiBatchKit** (this package) - batch-effect correction and harmonisation for multi-centre / multi-instrument MALDI-TOF spectra.
|
|
358
363
|
- **[MaldiDeepKit](https://github.com/EttoreRocchi/MaldiDeepKit)** - sklearn-compatible deep learning classifiers (MLP, CNN, ResNet, Transformer).
|
|
359
364
|
|
|
360
|
-
The three packages share the `MaldiSet`
|
|
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/>).
|
|
361
366
|
|
|
362
367
|
## Citation
|
|
363
368
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
> _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.
|
|
367
370
|
|
|
368
|
-
|
|
371
|
+
Please also cite the upstream references for whichever methods you apply (Johnson 2007, Fortin 2018, Chen 2022, Ritchie 2015, Korsunsky 2019).
|
|
369
372
|
|
|
370
373
|
## License
|
|
371
374
|
|
|
372
|
-
MIT. See [LICENSE](LICENSE).
|
|
375
|
+
MIT. See [LICENSE](https://github.com/EttoreRocchi/MaldiBatchKit/blob/main/LICENSE).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MaldiBatchKit
|
|
3
|
-
Version: 0.2.
|
|
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
|
|
@@ -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:
|
|
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,7 +62,10 @@ Dynamic: license-file
|
|
|
62
62
|
[](https://github.com/EttoreRocchi/MaldiBatchKit/blob/main/LICENSE)
|
|
63
63
|
|
|
64
64
|
<p align="center">
|
|
65
|
-
<
|
|
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">
|
|
@@ -70,7 +73,7 @@ Dynamic: license-file
|
|
|
70
73
|
</p>
|
|
71
74
|
|
|
72
75
|
<p align="center">
|
|
73
|
-
<img src="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"/>
|
|
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"/>
|
|
74
77
|
</p>
|
|
75
78
|
|
|
76
79
|
<p align="center">
|
|
@@ -83,7 +86,7 @@ Dynamic: license-file
|
|
|
83
86
|
<a href="#citation">Citation</a>
|
|
84
87
|
</p>
|
|
85
88
|
|
|
86
|
-
MaldiBatchKit is part of the **MaldiSuite** ecosystem
|
|
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).
|
|
87
90
|
|
|
88
91
|
## Installation
|
|
89
92
|
|
|
@@ -124,8 +127,8 @@ Visit the **MaldiSuite** landing page at <https://ettorerocchi.github.io/MaldiSu
|
|
|
124
127
|
- `SpeciesAwareComBat` - convenience preset for ComBat-Fortin with `species` as the protected biological covariate.
|
|
125
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.
|
|
126
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.
|
|
127
|
-
- **Diagnostic benchmark**: `BatchCorrectionBenchmark` runs a fixed set of metrics across multiple correctors with stratified
|
|
128
|
-
- **
|
|
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.
|
|
129
132
|
- **Integration adapter**: `MaldiSetAdapter` turns a `maldiamrkit.MaldiSet` into a corrected `MaldiSet` in one call.
|
|
130
133
|
- **CLI**: `maldibatchkit correct ...` and `maldibatchkit diagnose ...`.
|
|
131
134
|
|
|
@@ -176,6 +179,8 @@ corrected_ds.X # harmonised feature matrix
|
|
|
176
179
|
corrected_ds.y # AMR labels, unchanged
|
|
177
180
|
```
|
|
178
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
|
+
|
|
179
184
|
### CLI
|
|
180
185
|
|
|
181
186
|
The CLI is organised as `maldibatchkit correct <method>` + `maldibatchkit diagnose`. Every method has its own subcommand with only the flags it actually uses:
|
|
@@ -250,7 +255,7 @@ from sklearn.pipeline import Pipeline
|
|
|
250
255
|
from maldibatchkit import AutoCorrector
|
|
251
256
|
|
|
252
257
|
pipe = Pipeline([
|
|
253
|
-
("correct", AutoCorrector(batch=batch, discrete_covariates=species)),
|
|
258
|
+
("correct", AutoCorrector(batch=batch, discrete_covariates=species, quality=snr)),
|
|
254
259
|
("clf", LogisticRegression(max_iter=1000)),
|
|
255
260
|
])
|
|
256
261
|
grid = GridSearchCV(
|
|
@@ -347,26 +352,24 @@ from maldibatchkit.diagnostics import (
|
|
|
347
352
|
)
|
|
348
353
|
```
|
|
349
354
|
|
|
350
|
-
|
|
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`.
|
|
351
356
|
|
|
352
|
-
## MaldiSuite
|
|
357
|
+
## MaldiSuite ecosystem
|
|
353
358
|
|
|
354
|
-
MaldiBatchKit is the
|
|
359
|
+
MaldiBatchKit is one of the three packages of the **MaldiSuite** ecosystem:
|
|
355
360
|
|
|
356
361
|
- **[MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit)** - data model (`MaldiSpectrum`, `MaldiSet`), preprocessing, alignment, peak detection, differential analysis, and AMR-aware evaluation.
|
|
357
362
|
- **MaldiBatchKit** (this package) - batch-effect correction and harmonisation for multi-centre / multi-instrument MALDI-TOF spectra.
|
|
358
363
|
- **[MaldiDeepKit](https://github.com/EttoreRocchi/MaldiDeepKit)** - sklearn-compatible deep learning classifiers (MLP, CNN, ResNet, Transformer).
|
|
359
364
|
|
|
360
|
-
The three packages share the `MaldiSet`
|
|
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/>).
|
|
361
366
|
|
|
362
367
|
## Citation
|
|
363
368
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
> _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.
|
|
367
370
|
|
|
368
|
-
|
|
371
|
+
Please also cite the upstream references for whichever methods you apply (Johnson 2007, Fortin 2018, Chen 2022, Ritchie 2015, Korsunsky 2019).
|
|
369
372
|
|
|
370
373
|
## License
|
|
371
374
|
|
|
372
|
-
MIT. See [LICENSE](LICENSE).
|
|
375
|
+
MIT. See [LICENSE](https://github.com/EttoreRocchi/MaldiBatchKit/blob/main/LICENSE).
|
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
[](https://github.com/EttoreRocchi/MaldiBatchKit/blob/main/LICENSE)
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
|
-
<
|
|
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">
|
|
@@ -17,7 +20,7 @@
|
|
|
17
20
|
</p>
|
|
18
21
|
|
|
19
22
|
<p align="center">
|
|
20
|
-
<img src="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"/>
|
|
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"/>
|
|
21
24
|
</p>
|
|
22
25
|
|
|
23
26
|
<p align="center">
|
|
@@ -30,7 +33,7 @@
|
|
|
30
33
|
<a href="#citation">Citation</a>
|
|
31
34
|
</p>
|
|
32
35
|
|
|
33
|
-
MaldiBatchKit is part of the **MaldiSuite** ecosystem
|
|
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).
|
|
34
37
|
|
|
35
38
|
## Installation
|
|
36
39
|
|
|
@@ -71,8 +74,8 @@ Visit the **MaldiSuite** landing page at <https://ettorerocchi.github.io/MaldiSu
|
|
|
71
74
|
- `SpeciesAwareComBat` - convenience preset for ComBat-Fortin with `species` as the protected biological covariate.
|
|
72
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.
|
|
73
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.
|
|
74
|
-
- **Diagnostic benchmark**: `BatchCorrectionBenchmark` runs a fixed set of metrics across multiple correctors with stratified
|
|
75
|
-
- **
|
|
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.
|
|
76
79
|
- **Integration adapter**: `MaldiSetAdapter` turns a `maldiamrkit.MaldiSet` into a corrected `MaldiSet` in one call.
|
|
77
80
|
- **CLI**: `maldibatchkit correct ...` and `maldibatchkit diagnose ...`.
|
|
78
81
|
|
|
@@ -123,6 +126,8 @@ corrected_ds.X # harmonised feature matrix
|
|
|
123
126
|
corrected_ds.y # AMR labels, unchanged
|
|
124
127
|
```
|
|
125
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
|
+
|
|
126
131
|
### CLI
|
|
127
132
|
|
|
128
133
|
The CLI is organised as `maldibatchkit correct <method>` + `maldibatchkit diagnose`. Every method has its own subcommand with only the flags it actually uses:
|
|
@@ -197,7 +202,7 @@ from sklearn.pipeline import Pipeline
|
|
|
197
202
|
from maldibatchkit import AutoCorrector
|
|
198
203
|
|
|
199
204
|
pipe = Pipeline([
|
|
200
|
-
("correct", AutoCorrector(batch=batch, discrete_covariates=species)),
|
|
205
|
+
("correct", AutoCorrector(batch=batch, discrete_covariates=species, quality=snr)),
|
|
201
206
|
("clf", LogisticRegression(max_iter=1000)),
|
|
202
207
|
])
|
|
203
208
|
grid = GridSearchCV(
|
|
@@ -294,26 +299,24 @@ from maldibatchkit.diagnostics import (
|
|
|
294
299
|
)
|
|
295
300
|
```
|
|
296
301
|
|
|
297
|
-
|
|
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`.
|
|
298
303
|
|
|
299
|
-
## MaldiSuite
|
|
304
|
+
## MaldiSuite ecosystem
|
|
300
305
|
|
|
301
|
-
MaldiBatchKit is the
|
|
306
|
+
MaldiBatchKit is one of the three packages of the **MaldiSuite** ecosystem:
|
|
302
307
|
|
|
303
308
|
- **[MaldiAMRKit](https://github.com/EttoreRocchi/MaldiAMRKit)** - data model (`MaldiSpectrum`, `MaldiSet`), preprocessing, alignment, peak detection, differential analysis, and AMR-aware evaluation.
|
|
304
309
|
- **MaldiBatchKit** (this package) - batch-effect correction and harmonisation for multi-centre / multi-instrument MALDI-TOF spectra.
|
|
305
310
|
- **[MaldiDeepKit](https://github.com/EttoreRocchi/MaldiDeepKit)** - sklearn-compatible deep learning classifiers (MLP, CNN, ResNet, Transformer).
|
|
306
311
|
|
|
307
|
-
The three packages share the `MaldiSet`
|
|
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/>).
|
|
308
313
|
|
|
309
314
|
## Citation
|
|
310
315
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
> _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.
|
|
314
317
|
|
|
315
|
-
|
|
318
|
+
Please also cite the upstream references for whichever methods you apply (Johnson 2007, Fortin 2018, Chen 2022, Ritchie 2015, Korsunsky 2019).
|
|
316
319
|
|
|
317
320
|
## License
|
|
318
321
|
|
|
319
|
-
MIT. See [LICENSE](LICENSE).
|
|
322
|
+
MIT. See [LICENSE](https://github.com/EttoreRocchi/MaldiBatchKit/blob/main/LICENSE).
|
|
@@ -357,6 +357,15 @@ def correct_limma(
|
|
|
357
357
|
"""limma::removeBatchEffect (Ritchie 2015)."""
|
|
358
358
|
X, batch, extras = load_matrix(input, batch_csv)
|
|
359
359
|
design = load_dataframe_csv(design_csv, X.index) if design_csv else None
|
|
360
|
+
if design is not None:
|
|
361
|
+
text = [
|
|
362
|
+
c for c in design.columns if not pd.api.types.is_numeric_dtype(design[c])
|
|
363
|
+
]
|
|
364
|
+
if text:
|
|
365
|
+
raise typer.BadParameter(
|
|
366
|
+
f"--design-csv columns must be numeric; {text} are not. "
|
|
367
|
+
"Encode categorical covariates as dummy columns first."
|
|
368
|
+
)
|
|
360
369
|
transformer = Limma(batch=batch, design=design, eps=eps)
|
|
361
370
|
_run_and_save(transformer, X, output, batch, extras)
|
|
362
371
|
|
|
@@ -43,9 +43,9 @@ class MedianCentering(BaseBatchCorrector):
|
|
|
43
43
|
The fitted parameter is a ``(n_batches, n_features)`` table of
|
|
44
44
|
medians. At ``transform`` time, the median for the batch each sample
|
|
45
45
|
belongs to is subtracted. Batches that were absent at ``fit`` time
|
|
46
|
-
fall back to the grand median learned from training data
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
fall back to the grand median learned from training data; this keeps
|
|
47
|
+
the transformer defined on unseen folds without leaking information
|
|
48
|
+
from the test set.
|
|
49
49
|
|
|
50
50
|
Parameters
|
|
51
51
|
----------
|
|
@@ -22,7 +22,7 @@ def _try_import_maldiamrkit():
|
|
|
22
22
|
"This transformer requires 'maldiamrkit' (normally installed "
|
|
23
23
|
"alongside MaldiBatchKit). Reinstall with "
|
|
24
24
|
"`pip install -U maldibatchkit` or "
|
|
25
|
-
"`pip install maldiamrkit>=0.
|
|
25
|
+
"`pip install maldiamrkit>=0.15.0`."
|
|
26
26
|
) from exc
|
|
27
27
|
return maldiamrkit
|
|
28
28
|
|
|
@@ -54,11 +54,12 @@ and untouched. ``weights=`` only controls the *across-batch* reducer.
|
|
|
54
54
|
|
|
55
55
|
Degenerate folds
|
|
56
56
|
----------------
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
A batch with fewer than two samples, or, for every metric except MCC,
|
|
58
|
+
with only one class in the held-out fold, leaves the metric undefined.
|
|
59
|
+
These batches are **dropped from the aggregate with a warning** and the
|
|
60
|
+
remaining weights are renormalised (an array of weights keeps the
|
|
61
|
+
entries of the remaining batches). Use ``weights=`` plus a careful split
|
|
62
|
+
design if you need a different policy.
|
|
62
63
|
|
|
63
64
|
``make_batch_scorer`` factory
|
|
64
65
|
-----------------------------
|
|
@@ -232,6 +233,15 @@ def _per_batch_metric(
|
|
|
232
233
|
stacklevel=2,
|
|
233
234
|
)
|
|
234
235
|
|
|
236
|
+
if not isinstance(weights, str | Mapping):
|
|
237
|
+
# An array is aligned with every batch level: keep the kept batches.
|
|
238
|
+
full = np.asarray(weights, dtype=float)
|
|
239
|
+
if full.shape != levels.shape:
|
|
240
|
+
raise ValueError(
|
|
241
|
+
f"weights array length {full.shape[0]} does not match the number "
|
|
242
|
+
f"of batch levels {levels.shape[0]}."
|
|
243
|
+
)
|
|
244
|
+
weights = full[valid]
|
|
235
245
|
w = _resolve_weights(levels[valid], sizes[valid], weights)
|
|
236
246
|
return float(np.sum(w * scores[valid]))
|
|
237
247
|
|
|
@@ -256,6 +256,29 @@ def test_correct_limma(csv_inputs):
|
|
|
256
256
|
assert result.exit_code == 0, result.output
|
|
257
257
|
|
|
258
258
|
|
|
259
|
+
def test_correct_limma_text_design_refused(csv_inputs, tiny_dataset, tmp_path):
|
|
260
|
+
"""A non-numeric design CSV gives a usage error, not a traceback."""
|
|
261
|
+
design = tmp_path / "text_design.csv"
|
|
262
|
+
_write_dataframe_csv(design, tiny_dataset["species"].rename("species").to_frame())
|
|
263
|
+
result = runner.invoke(
|
|
264
|
+
app,
|
|
265
|
+
[
|
|
266
|
+
"correct",
|
|
267
|
+
"limma",
|
|
268
|
+
"-i",
|
|
269
|
+
str(csv_inputs["X"]),
|
|
270
|
+
"-o",
|
|
271
|
+
str(csv_inputs["out"]),
|
|
272
|
+
"--batch-csv",
|
|
273
|
+
str(csv_inputs["batch"]),
|
|
274
|
+
"--design-csv",
|
|
275
|
+
str(design),
|
|
276
|
+
],
|
|
277
|
+
)
|
|
278
|
+
assert result.exit_code == 2
|
|
279
|
+
assert "numeric" in " ".join(result.output.split())
|
|
280
|
+
|
|
281
|
+
|
|
259
282
|
def test_correct_harmony(csv_inputs):
|
|
260
283
|
result = runner.invoke(
|
|
261
284
|
app,
|
|
@@ -376,3 +376,25 @@ def test_single_class_batch_dropped_for_f1_precision_recall(fn):
|
|
|
376
376
|
with pytest.warns(UserWarning, match="dropped"):
|
|
377
377
|
v = fn(y, y.copy(), batch=batch)
|
|
378
378
|
assert v == pytest.approx(1.0)
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
def test_array_weights_follow_dropped_batches():
|
|
382
|
+
"""An array of weights stays aligned when a single-class batch is dropped."""
|
|
383
|
+
batch = np.array(["a"] * 10 + ["b"] * 10 + ["c"] * 10)
|
|
384
|
+
y = np.array([0] * 10 + [0, 1] * 5 + [0, 1] * 5)
|
|
385
|
+
score = np.linspace(0.0, 1.0, 30)
|
|
386
|
+
with pytest.warns(UserWarning, match="dropped"):
|
|
387
|
+
got = batch_roc_auc_score(y, score, batch=batch, weights=[5.0, 1.0, 3.0])
|
|
388
|
+
with pytest.warns(UserWarning, match="dropped"):
|
|
389
|
+
ref = batch_roc_auc_score(
|
|
390
|
+
y, score, batch=batch, weights={"a": 5.0, "b": 1.0, "c": 3.0}
|
|
391
|
+
)
|
|
392
|
+
assert got == pytest.approx(ref)
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
def test_array_weights_wrong_length_raises():
|
|
396
|
+
batch = np.array(["a"] * 4 + ["b"] * 4 + ["c"] * 4)
|
|
397
|
+
y = np.array([0, 1] * 6)
|
|
398
|
+
score = np.linspace(0.0, 1.0, 12)
|
|
399
|
+
with pytest.raises(ValueError, match="does not match"):
|
|
400
|
+
batch_roc_auc_score(y, score, batch=batch, weights=[1.0, 1.0])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|