MaldiAMRKit 0.18.0__tar.gz → 0.20.0__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.
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0/MaldiAMRKit.egg-info}/PKG-INFO +25 -4
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/MaldiAMRKit.egg-info/SOURCES.txt +3 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/MaldiAMRKit.egg-info/requires.txt +8 -1
- {maldiamrkit-0.18.0/MaldiAMRKit.egg-info → maldiamrkit-0.20.0}/PKG-INFO +25 -4
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/README.md +19 -2
- maldiamrkit-0.20.0/maldiamrkit/__init__.py +38 -0
- maldiamrkit-0.20.0/maldiamrkit/_registry.py +124 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/alignment/raw_warping.py +5 -5
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/__init__.py +5 -5
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/example.yaml +1 -1
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/dataset_layouts.py +29 -22
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/input_layouts.py +23 -10
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/dataset.py +15 -4
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/drift/plots.py +0 -3
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/evaluation/mic_regression.py +1 -1
- maldiamrkit-0.20.0/maldiamrkit/io/readers.py +600 -0
- maldiamrkit-0.20.0/maldiamrkit/io/writers.py +139 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/preprocessing/__init__.py +10 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/preprocessing/binning.py +68 -37
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/preprocessing/preprocessing_pipeline.py +106 -19
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/preprocessing/transformers.py +178 -1
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/similarity/__init__.py +12 -1
- maldiamrkit-0.20.0/maldiamrkit/similarity/metrics.py +389 -0
- maldiamrkit-0.20.0/maldiamrkit/similarity/pairwise.py +159 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/spectrum.py +8 -3
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/susceptibility/breakpoint.py +5 -5
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/pyproject.toml +1 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/requirements-docs.txt +0 -1
- maldiamrkit-0.20.0/requirements-formats.txt +5 -0
- maldiamrkit-0.18.0/maldiamrkit/__init__.py +0 -38
- maldiamrkit-0.18.0/maldiamrkit/io/readers.py +0 -343
- maldiamrkit-0.18.0/maldiamrkit/similarity/metrics.py +0 -222
- maldiamrkit-0.18.0/maldiamrkit/similarity/pairwise.py +0 -97
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/LICENSE +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/MaldiAMRKit.egg-info/dependency_links.txt +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/MaldiAMRKit.egg-info/entry_points.txt +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/MaldiAMRKit.egg-info/top_level.txt +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/_compat.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/alignment/__init__.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/alignment/peak_align.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/alignment/strategies.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/alignment/warping.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/cli.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/README.md +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v1.0.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v1.1.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v1.2.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v1.3.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v10.0.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v11.0.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v12.0.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v13.1.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v14.0.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v15.0.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v16.0.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v2.0.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v4.0.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v5.0.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v6.0.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v7.1.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v8.0.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v8.1.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/breakpoints/eucast/eucast_v9.0.yaml +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/builder.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/duplicates.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/loader.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/data/site_info.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/detection/__init__.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/detection/peak_detector.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/detection/peaklist.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/differential/__init__.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/differential/analysis.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/differential/plots.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/differential/stats.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/drift/__init__.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/drift/monitor.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/drift/pca_drift.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/drift/peak_drift.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/drift/reference.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/evaluation/__init__.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/evaluation/metrics.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/evaluation/splitting.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/filters.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/io/__init__.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/io/mic.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/preprocessing/merging.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/preprocessing/pipeline.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/preprocessing/quality.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/py.typed +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/similarity/clustering.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/similarity/plots.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/susceptibility/__init__.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/susceptibility/label_encoder.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/susceptibility/mic_encoder.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/visualization/__init__.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/visualization/_common.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/visualization/alignment_plots.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/visualization/exploratory_plots.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/visualization/peak_plots.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/maldiamrkit/visualization/spectrum_plots.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/requirements-batch.txt +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/requirements-dev.txt +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/requirements.txt +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/setup.cfg +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/tests/test_compat.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/tests/test_numerical_edge_cases.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/tests/test_peak_detector.py +0 -0
- {maldiamrkit-0.18.0 → maldiamrkit-0.20.0}/tests/test_peaklist.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MaldiAMRKit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.20.0
|
|
4
4
|
Summary: A comprehensive toolkit for MALDI-TOF mass spectrometry data preprocessing for antimicrobial resistance (AMR) prediction purposes
|
|
5
5
|
Author-email: Ettore Rocchi <ettore.rocchi3@unibo.it>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -39,7 +39,6 @@ Requires-Dist: tqdm>=4.60.0
|
|
|
39
39
|
Provides-Extra: docs
|
|
40
40
|
Requires-Dist: sphinx>=7.0.0; extra == "docs"
|
|
41
41
|
Requires-Dist: pydata-sphinx-theme>=0.15.0; extra == "docs"
|
|
42
|
-
Requires-Dist: sphinx-autodoc-typehints>=2.0.0; extra == "docs"
|
|
43
42
|
Requires-Dist: sphinx-design>=0.6.0; extra == "docs"
|
|
44
43
|
Requires-Dist: sphinxcontrib-typer>=0.5.0; extra == "docs"
|
|
45
44
|
Requires-Dist: nbsphinx>=0.9.0; extra == "docs"
|
|
@@ -53,6 +52,11 @@ Requires-Dist: hypothesis>=6.0.0; extra == "dev"
|
|
|
53
52
|
Provides-Extra: batch
|
|
54
53
|
Requires-Dist: umap-learn>=0.5; extra == "batch"
|
|
55
54
|
Requires-Dist: combatlearn>=1.3; extra == "batch"
|
|
55
|
+
Provides-Extra: formats
|
|
56
|
+
Requires-Dist: pyteomics>=4.0; extra == "formats"
|
|
57
|
+
Requires-Dist: lxml>=4.0; extra == "formats"
|
|
58
|
+
Requires-Dist: psims>=1.0; extra == "formats"
|
|
59
|
+
Requires-Dist: pynumpress>=0.1.5; python_version >= "3.11" and extra == "formats"
|
|
56
60
|
Dynamic: license-file
|
|
57
61
|
|
|
58
62
|
# MaldiAMRKit
|
|
@@ -109,6 +113,14 @@ pip install maldiamrkit[batch]
|
|
|
109
113
|
|
|
110
114
|
Installs [`combatlearn`](https://github.com/EttoreRocchi/combatlearn) for ComBat-based batch effect correction and `umap-learn` for UMAP exploratory plots.
|
|
111
115
|
|
|
116
|
+
### Optional: extended mzML/mzXML support
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
pip install maldiamrkit[formats]
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`.mzML` and `.mzXML` files are read out of the box (zlib-compressed or uncompressed arrays). This extra installs [`pyteomics`](https://pyteomics.readthedocs.io/) with `lxml`, `psims`, and `pynumpress`, which additionally handle numpress-compressed arrays. `pynumpress` ships no wheels for Python 3.10, so numpress arrays need Python 3.11 or newer.
|
|
123
|
+
|
|
112
124
|
### Development Installation
|
|
113
125
|
|
|
114
126
|
```bash
|
|
@@ -130,6 +142,12 @@ pip install -e .[dev]
|
|
|
130
142
|
### Alignment & Detection
|
|
131
143
|
- **Spectral Alignment**: Shift, linear, piecewise, DTW, quadratic, cubic, and LOWESS warping for both binned and raw full-resolution spectra
|
|
132
144
|
- **Peak Detection**: Local maxima and persistent homology methods
|
|
145
|
+
- **Peak Sets**: `PeakSet` / `PeakList` represent each spectrum as a variable-length `(m/z, intensity)` set for peak-set models, via `MaldiPeakDetector.transform_peaklist()` on binned spectra or `create_peakset_input()` at full m/z resolution; extraction is stateless per spectrum, so results are cacheable without leakage
|
|
146
|
+
- **Fit-Free Peak Alignment**: `align_peaks()` warps a peak set onto caller-supplied reference peaks, so the reference stays fitted on the training split
|
|
147
|
+
|
|
148
|
+
### Extensibility
|
|
149
|
+
- **Component Registries**: Plug your own components into the name-dispatched machinery - `register_spectral_metric()` for distance metrics (usable in `spectral_distance`, `pairwise_distances`, and `DriftMonitor`), `register_transformer()` to make `PreprocessingPipeline` configs holding custom transformers round-trip through JSON/YAML, and `register_binning_method()` for custom bin edges
|
|
150
|
+
- **Discovery & Safety**: `list_spectral_metrics()`, `list_transformers()`, `list_binning_methods()` report what is registered; built-ins are replaced only with an explicit `override=True`, and unregistering an overridden built-in restores the default
|
|
133
151
|
|
|
134
152
|
### Evaluation
|
|
135
153
|
- **AMR Metrics**: VME, ME, sensitivity, specificity, categorical agreement, and `amr_classification_report` following EUCAST conventions
|
|
@@ -155,9 +173,10 @@ pip install -e .[dev]
|
|
|
155
173
|
- **Dataset Building & Loading**: `DatasetBuilder` and `DatasetLoader` with pluggable layout adapters (`FlatLayout`, `BrukerTreeLayout`, `DRIAMSLayout`, `MARISMaLayout`)
|
|
156
174
|
- **Replicate Collapsing**: `DRIAMSLayout(collapse_replicates=True)` merges technical replicates (`_MALDI<N>`) to one row per isolate at load time via the active `duplicate_strategy`
|
|
157
175
|
- **Bruker Format Support**: Read Bruker flexAnalysis binary data (fid/1r + acqus) natively via `read_spectrum()` on directories
|
|
176
|
+
- **Open Formats**: Read `.mzML` and `.mzXML` files (optionally gzipped) via `read_spectrum()`, `MaldiSpectrum`, and `FlatLayout(spectrum_ext=".mzML")`; `pip install maldiamrkit[formats]` adds `pyteomics` for numpress-compressed arrays
|
|
158
177
|
- **MIC Parsing**: `parse_mic_column()` for parsing MIC strings with qualifiers and European decimals
|
|
159
178
|
- **Composable Filters**: `SpeciesFilter`, `DrugFilter`, `QualityFilter`, `MetadataFilter` combinable with `&`/`|`/`~` operators
|
|
160
|
-
- **Spectrum Export**: Save spectra to CSV or
|
|
179
|
+
- **Spectrum Export**: Save spectra to CSV, TXT, or mzML via `MaldiSpectrum.save()` and `MaldiSet.save_spectra()`
|
|
161
180
|
|
|
162
181
|
### Visualization & Tools
|
|
163
182
|
- **Exploratory Plots**: PCA, t-SNE, and UMAP scatter plots colored by species, resistance phenotype, or any metadata column
|
|
@@ -248,8 +267,10 @@ For more detailed examples, see the notebooks:
|
|
|
248
267
|
- [Differential Analysis](notebooks/06_differential_analysis.ipynb) - R vs. S peak testing, volcano/Manhattan plots, and multi-drug comparison
|
|
249
268
|
- [Drift Monitoring](notebooks/07_drift_monitoring.ipynb) - Baseline-anchored drift detection: reference similarity, PCA trajectory, peak stability, and effect-size drift
|
|
250
269
|
- [Susceptibility](notebooks/08_susceptibility.ipynb) - `MICEncoder` + `BreakpointTable` for log2(MIC) regression targets, S/I/R categorisation with ATU, and `mic_regression_report` evaluation
|
|
270
|
+
- [Peak Sets](notebooks/09_peak_sets.ipynb) - `PeakSet` / `PeakList` extraction, ranking and padding, caching, and fit-free peak alignment
|
|
271
|
+
- [Custom Components](notebooks/10_custom_components.ipynb) - registering a custom distance metric and a custom transformer end-to-end
|
|
251
272
|
|
|
252
|
-
Notebooks `01`-`03` and `08` run on the small example dataset bundled under [`data/`](data/) or are fully self-contained. Notebooks `04`-`07` need more samples and pull the real **MALDI-Kleb-AI** archive (Rocchi *et al.*, 2026; [Zenodo DOI 10.5281/zenodo.17405072](https://zenodo.org/records/17405072)) via the [`demo`](notebooks/_demo.py) helper. By default the helper restricts the dataset to the **Rome sub-cohort** (~470 spectra, single acquisition centre, no batch correction required); the 370 MB tarball is cached under `~/.cache/maldiamrkit/` on first use.
|
|
273
|
+
Notebooks `01`-`03` and `08`-`10` run on the small example dataset bundled under [`data/`](data/) or are fully self-contained. Notebooks `04`-`07` need more samples and pull the real **MALDI-Kleb-AI** archive (Rocchi *et al.*, 2026; [Zenodo DOI 10.5281/zenodo.17405072](https://zenodo.org/records/17405072)) via the [`demo`](notebooks/_demo.py) helper. By default the helper restricts the dataset to the **Rome sub-cohort** (~470 spectra, single acquisition centre, no batch correction required); the 370 MB tarball is cached under `~/.cache/maldiamrkit/` on first use.
|
|
253
274
|
|
|
254
275
|
## MaldiSuite Ecosystem
|
|
255
276
|
|
|
@@ -4,6 +4,7 @@ pyproject.toml
|
|
|
4
4
|
requirements-batch.txt
|
|
5
5
|
requirements-dev.txt
|
|
6
6
|
requirements-docs.txt
|
|
7
|
+
requirements-formats.txt
|
|
7
8
|
requirements.txt
|
|
8
9
|
MaldiAMRKit.egg-info/PKG-INFO
|
|
9
10
|
MaldiAMRKit.egg-info/SOURCES.txt
|
|
@@ -13,6 +14,7 @@ MaldiAMRKit.egg-info/requires.txt
|
|
|
13
14
|
MaldiAMRKit.egg-info/top_level.txt
|
|
14
15
|
maldiamrkit/__init__.py
|
|
15
16
|
maldiamrkit/_compat.py
|
|
17
|
+
maldiamrkit/_registry.py
|
|
16
18
|
maldiamrkit/cli.py
|
|
17
19
|
maldiamrkit/dataset.py
|
|
18
20
|
maldiamrkit/filters.py
|
|
@@ -71,6 +73,7 @@ maldiamrkit/evaluation/splitting.py
|
|
|
71
73
|
maldiamrkit/io/__init__.py
|
|
72
74
|
maldiamrkit/io/mic.py
|
|
73
75
|
maldiamrkit/io/readers.py
|
|
76
|
+
maldiamrkit/io/writers.py
|
|
74
77
|
maldiamrkit/preprocessing/__init__.py
|
|
75
78
|
maldiamrkit/preprocessing/binning.py
|
|
76
79
|
maldiamrkit/preprocessing/merging.py
|
|
@@ -27,8 +27,15 @@ hypothesis>=6.0.0
|
|
|
27
27
|
[docs]
|
|
28
28
|
sphinx>=7.0.0
|
|
29
29
|
pydata-sphinx-theme>=0.15.0
|
|
30
|
-
sphinx-autodoc-typehints>=2.0.0
|
|
31
30
|
sphinx-design>=0.6.0
|
|
32
31
|
sphinxcontrib-typer>=0.5.0
|
|
33
32
|
nbsphinx>=0.9.0
|
|
34
33
|
ipykernel>=6.0.0
|
|
34
|
+
|
|
35
|
+
[formats]
|
|
36
|
+
pyteomics>=4.0
|
|
37
|
+
lxml>=4.0
|
|
38
|
+
psims>=1.0
|
|
39
|
+
|
|
40
|
+
[formats:python_version >= "3.11"]
|
|
41
|
+
pynumpress>=0.1.5
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MaldiAMRKit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.20.0
|
|
4
4
|
Summary: A comprehensive toolkit for MALDI-TOF mass spectrometry data preprocessing for antimicrobial resistance (AMR) prediction purposes
|
|
5
5
|
Author-email: Ettore Rocchi <ettore.rocchi3@unibo.it>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -39,7 +39,6 @@ Requires-Dist: tqdm>=4.60.0
|
|
|
39
39
|
Provides-Extra: docs
|
|
40
40
|
Requires-Dist: sphinx>=7.0.0; extra == "docs"
|
|
41
41
|
Requires-Dist: pydata-sphinx-theme>=0.15.0; extra == "docs"
|
|
42
|
-
Requires-Dist: sphinx-autodoc-typehints>=2.0.0; extra == "docs"
|
|
43
42
|
Requires-Dist: sphinx-design>=0.6.0; extra == "docs"
|
|
44
43
|
Requires-Dist: sphinxcontrib-typer>=0.5.0; extra == "docs"
|
|
45
44
|
Requires-Dist: nbsphinx>=0.9.0; extra == "docs"
|
|
@@ -53,6 +52,11 @@ Requires-Dist: hypothesis>=6.0.0; extra == "dev"
|
|
|
53
52
|
Provides-Extra: batch
|
|
54
53
|
Requires-Dist: umap-learn>=0.5; extra == "batch"
|
|
55
54
|
Requires-Dist: combatlearn>=1.3; extra == "batch"
|
|
55
|
+
Provides-Extra: formats
|
|
56
|
+
Requires-Dist: pyteomics>=4.0; extra == "formats"
|
|
57
|
+
Requires-Dist: lxml>=4.0; extra == "formats"
|
|
58
|
+
Requires-Dist: psims>=1.0; extra == "formats"
|
|
59
|
+
Requires-Dist: pynumpress>=0.1.5; python_version >= "3.11" and extra == "formats"
|
|
56
60
|
Dynamic: license-file
|
|
57
61
|
|
|
58
62
|
# MaldiAMRKit
|
|
@@ -109,6 +113,14 @@ pip install maldiamrkit[batch]
|
|
|
109
113
|
|
|
110
114
|
Installs [`combatlearn`](https://github.com/EttoreRocchi/combatlearn) for ComBat-based batch effect correction and `umap-learn` for UMAP exploratory plots.
|
|
111
115
|
|
|
116
|
+
### Optional: extended mzML/mzXML support
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
pip install maldiamrkit[formats]
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`.mzML` and `.mzXML` files are read out of the box (zlib-compressed or uncompressed arrays). This extra installs [`pyteomics`](https://pyteomics.readthedocs.io/) with `lxml`, `psims`, and `pynumpress`, which additionally handle numpress-compressed arrays. `pynumpress` ships no wheels for Python 3.10, so numpress arrays need Python 3.11 or newer.
|
|
123
|
+
|
|
112
124
|
### Development Installation
|
|
113
125
|
|
|
114
126
|
```bash
|
|
@@ -130,6 +142,12 @@ pip install -e .[dev]
|
|
|
130
142
|
### Alignment & Detection
|
|
131
143
|
- **Spectral Alignment**: Shift, linear, piecewise, DTW, quadratic, cubic, and LOWESS warping for both binned and raw full-resolution spectra
|
|
132
144
|
- **Peak Detection**: Local maxima and persistent homology methods
|
|
145
|
+
- **Peak Sets**: `PeakSet` / `PeakList` represent each spectrum as a variable-length `(m/z, intensity)` set for peak-set models, via `MaldiPeakDetector.transform_peaklist()` on binned spectra or `create_peakset_input()` at full m/z resolution; extraction is stateless per spectrum, so results are cacheable without leakage
|
|
146
|
+
- **Fit-Free Peak Alignment**: `align_peaks()` warps a peak set onto caller-supplied reference peaks, so the reference stays fitted on the training split
|
|
147
|
+
|
|
148
|
+
### Extensibility
|
|
149
|
+
- **Component Registries**: Plug your own components into the name-dispatched machinery - `register_spectral_metric()` for distance metrics (usable in `spectral_distance`, `pairwise_distances`, and `DriftMonitor`), `register_transformer()` to make `PreprocessingPipeline` configs holding custom transformers round-trip through JSON/YAML, and `register_binning_method()` for custom bin edges
|
|
150
|
+
- **Discovery & Safety**: `list_spectral_metrics()`, `list_transformers()`, `list_binning_methods()` report what is registered; built-ins are replaced only with an explicit `override=True`, and unregistering an overridden built-in restores the default
|
|
133
151
|
|
|
134
152
|
### Evaluation
|
|
135
153
|
- **AMR Metrics**: VME, ME, sensitivity, specificity, categorical agreement, and `amr_classification_report` following EUCAST conventions
|
|
@@ -155,9 +173,10 @@ pip install -e .[dev]
|
|
|
155
173
|
- **Dataset Building & Loading**: `DatasetBuilder` and `DatasetLoader` with pluggable layout adapters (`FlatLayout`, `BrukerTreeLayout`, `DRIAMSLayout`, `MARISMaLayout`)
|
|
156
174
|
- **Replicate Collapsing**: `DRIAMSLayout(collapse_replicates=True)` merges technical replicates (`_MALDI<N>`) to one row per isolate at load time via the active `duplicate_strategy`
|
|
157
175
|
- **Bruker Format Support**: Read Bruker flexAnalysis binary data (fid/1r + acqus) natively via `read_spectrum()` on directories
|
|
176
|
+
- **Open Formats**: Read `.mzML` and `.mzXML` files (optionally gzipped) via `read_spectrum()`, `MaldiSpectrum`, and `FlatLayout(spectrum_ext=".mzML")`; `pip install maldiamrkit[formats]` adds `pyteomics` for numpress-compressed arrays
|
|
158
177
|
- **MIC Parsing**: `parse_mic_column()` for parsing MIC strings with qualifiers and European decimals
|
|
159
178
|
- **Composable Filters**: `SpeciesFilter`, `DrugFilter`, `QualityFilter`, `MetadataFilter` combinable with `&`/`|`/`~` operators
|
|
160
|
-
- **Spectrum Export**: Save spectra to CSV or
|
|
179
|
+
- **Spectrum Export**: Save spectra to CSV, TXT, or mzML via `MaldiSpectrum.save()` and `MaldiSet.save_spectra()`
|
|
161
180
|
|
|
162
181
|
### Visualization & Tools
|
|
163
182
|
- **Exploratory Plots**: PCA, t-SNE, and UMAP scatter plots colored by species, resistance phenotype, or any metadata column
|
|
@@ -248,8 +267,10 @@ For more detailed examples, see the notebooks:
|
|
|
248
267
|
- [Differential Analysis](notebooks/06_differential_analysis.ipynb) - R vs. S peak testing, volcano/Manhattan plots, and multi-drug comparison
|
|
249
268
|
- [Drift Monitoring](notebooks/07_drift_monitoring.ipynb) - Baseline-anchored drift detection: reference similarity, PCA trajectory, peak stability, and effect-size drift
|
|
250
269
|
- [Susceptibility](notebooks/08_susceptibility.ipynb) - `MICEncoder` + `BreakpointTable` for log2(MIC) regression targets, S/I/R categorisation with ATU, and `mic_regression_report` evaluation
|
|
270
|
+
- [Peak Sets](notebooks/09_peak_sets.ipynb) - `PeakSet` / `PeakList` extraction, ranking and padding, caching, and fit-free peak alignment
|
|
271
|
+
- [Custom Components](notebooks/10_custom_components.ipynb) - registering a custom distance metric and a custom transformer end-to-end
|
|
251
272
|
|
|
252
|
-
Notebooks `01`-`03` and `08` run on the small example dataset bundled under [`data/`](data/) or are fully self-contained. Notebooks `04`-`07` need more samples and pull the real **MALDI-Kleb-AI** archive (Rocchi *et al.*, 2026; [Zenodo DOI 10.5281/zenodo.17405072](https://zenodo.org/records/17405072)) via the [`demo`](notebooks/_demo.py) helper. By default the helper restricts the dataset to the **Rome sub-cohort** (~470 spectra, single acquisition centre, no batch correction required); the 370 MB tarball is cached under `~/.cache/maldiamrkit/` on first use.
|
|
273
|
+
Notebooks `01`-`03` and `08`-`10` run on the small example dataset bundled under [`data/`](data/) or are fully self-contained. Notebooks `04`-`07` need more samples and pull the real **MALDI-Kleb-AI** archive (Rocchi *et al.*, 2026; [Zenodo DOI 10.5281/zenodo.17405072](https://zenodo.org/records/17405072)) via the [`demo`](notebooks/_demo.py) helper. By default the helper restricts the dataset to the **Rome sub-cohort** (~470 spectra, single acquisition centre, no batch correction required); the 370 MB tarball is cached under `~/.cache/maldiamrkit/` on first use.
|
|
253
274
|
|
|
254
275
|
## MaldiSuite Ecosystem
|
|
255
276
|
|
|
@@ -52,6 +52,14 @@ pip install maldiamrkit[batch]
|
|
|
52
52
|
|
|
53
53
|
Installs [`combatlearn`](https://github.com/EttoreRocchi/combatlearn) for ComBat-based batch effect correction and `umap-learn` for UMAP exploratory plots.
|
|
54
54
|
|
|
55
|
+
### Optional: extended mzML/mzXML support
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pip install maldiamrkit[formats]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`.mzML` and `.mzXML` files are read out of the box (zlib-compressed or uncompressed arrays). This extra installs [`pyteomics`](https://pyteomics.readthedocs.io/) with `lxml`, `psims`, and `pynumpress`, which additionally handle numpress-compressed arrays. `pynumpress` ships no wheels for Python 3.10, so numpress arrays need Python 3.11 or newer.
|
|
62
|
+
|
|
55
63
|
### Development Installation
|
|
56
64
|
|
|
57
65
|
```bash
|
|
@@ -73,6 +81,12 @@ pip install -e .[dev]
|
|
|
73
81
|
### Alignment & Detection
|
|
74
82
|
- **Spectral Alignment**: Shift, linear, piecewise, DTW, quadratic, cubic, and LOWESS warping for both binned and raw full-resolution spectra
|
|
75
83
|
- **Peak Detection**: Local maxima and persistent homology methods
|
|
84
|
+
- **Peak Sets**: `PeakSet` / `PeakList` represent each spectrum as a variable-length `(m/z, intensity)` set for peak-set models, via `MaldiPeakDetector.transform_peaklist()` on binned spectra or `create_peakset_input()` at full m/z resolution; extraction is stateless per spectrum, so results are cacheable without leakage
|
|
85
|
+
- **Fit-Free Peak Alignment**: `align_peaks()` warps a peak set onto caller-supplied reference peaks, so the reference stays fitted on the training split
|
|
86
|
+
|
|
87
|
+
### Extensibility
|
|
88
|
+
- **Component Registries**: Plug your own components into the name-dispatched machinery - `register_spectral_metric()` for distance metrics (usable in `spectral_distance`, `pairwise_distances`, and `DriftMonitor`), `register_transformer()` to make `PreprocessingPipeline` configs holding custom transformers round-trip through JSON/YAML, and `register_binning_method()` for custom bin edges
|
|
89
|
+
- **Discovery & Safety**: `list_spectral_metrics()`, `list_transformers()`, `list_binning_methods()` report what is registered; built-ins are replaced only with an explicit `override=True`, and unregistering an overridden built-in restores the default
|
|
76
90
|
|
|
77
91
|
### Evaluation
|
|
78
92
|
- **AMR Metrics**: VME, ME, sensitivity, specificity, categorical agreement, and `amr_classification_report` following EUCAST conventions
|
|
@@ -98,9 +112,10 @@ pip install -e .[dev]
|
|
|
98
112
|
- **Dataset Building & Loading**: `DatasetBuilder` and `DatasetLoader` with pluggable layout adapters (`FlatLayout`, `BrukerTreeLayout`, `DRIAMSLayout`, `MARISMaLayout`)
|
|
99
113
|
- **Replicate Collapsing**: `DRIAMSLayout(collapse_replicates=True)` merges technical replicates (`_MALDI<N>`) to one row per isolate at load time via the active `duplicate_strategy`
|
|
100
114
|
- **Bruker Format Support**: Read Bruker flexAnalysis binary data (fid/1r + acqus) natively via `read_spectrum()` on directories
|
|
115
|
+
- **Open Formats**: Read `.mzML` and `.mzXML` files (optionally gzipped) via `read_spectrum()`, `MaldiSpectrum`, and `FlatLayout(spectrum_ext=".mzML")`; `pip install maldiamrkit[formats]` adds `pyteomics` for numpress-compressed arrays
|
|
101
116
|
- **MIC Parsing**: `parse_mic_column()` for parsing MIC strings with qualifiers and European decimals
|
|
102
117
|
- **Composable Filters**: `SpeciesFilter`, `DrugFilter`, `QualityFilter`, `MetadataFilter` combinable with `&`/`|`/`~` operators
|
|
103
|
-
- **Spectrum Export**: Save spectra to CSV or
|
|
118
|
+
- **Spectrum Export**: Save spectra to CSV, TXT, or mzML via `MaldiSpectrum.save()` and `MaldiSet.save_spectra()`
|
|
104
119
|
|
|
105
120
|
### Visualization & Tools
|
|
106
121
|
- **Exploratory Plots**: PCA, t-SNE, and UMAP scatter plots colored by species, resistance phenotype, or any metadata column
|
|
@@ -191,8 +206,10 @@ For more detailed examples, see the notebooks:
|
|
|
191
206
|
- [Differential Analysis](notebooks/06_differential_analysis.ipynb) - R vs. S peak testing, volcano/Manhattan plots, and multi-drug comparison
|
|
192
207
|
- [Drift Monitoring](notebooks/07_drift_monitoring.ipynb) - Baseline-anchored drift detection: reference similarity, PCA trajectory, peak stability, and effect-size drift
|
|
193
208
|
- [Susceptibility](notebooks/08_susceptibility.ipynb) - `MICEncoder` + `BreakpointTable` for log2(MIC) regression targets, S/I/R categorisation with ATU, and `mic_regression_report` evaluation
|
|
209
|
+
- [Peak Sets](notebooks/09_peak_sets.ipynb) - `PeakSet` / `PeakList` extraction, ranking and padding, caching, and fit-free peak alignment
|
|
210
|
+
- [Custom Components](notebooks/10_custom_components.ipynb) - registering a custom distance metric and a custom transformer end-to-end
|
|
194
211
|
|
|
195
|
-
Notebooks `01`-`03` and `08` run on the small example dataset bundled under [`data/`](data/) or are fully self-contained. Notebooks `04`-`07` need more samples and pull the real **MALDI-Kleb-AI** archive (Rocchi *et al.*, 2026; [Zenodo DOI 10.5281/zenodo.17405072](https://zenodo.org/records/17405072)) via the [`demo`](notebooks/_demo.py) helper. By default the helper restricts the dataset to the **Rome sub-cohort** (~470 spectra, single acquisition centre, no batch correction required); the 370 MB tarball is cached under `~/.cache/maldiamrkit/` on first use.
|
|
212
|
+
Notebooks `01`-`03` and `08`-`10` run on the small example dataset bundled under [`data/`](data/) or are fully self-contained. Notebooks `04`-`07` need more samples and pull the real **MALDI-Kleb-AI** archive (Rocchi *et al.*, 2026; [Zenodo DOI 10.5281/zenodo.17405072](https://zenodo.org/records/17405072)) via the [`demo`](notebooks/_demo.py) helper. By default the helper restricts the dataset to the **Rome sub-cohort** (~470 spectra, single acquisition centre, no batch correction required); the 370 MB tarball is cached under `~/.cache/maldiamrkit/` on first use.
|
|
196
213
|
|
|
197
214
|
## MaldiSuite Ecosystem
|
|
198
215
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""MaldiAMRKit: MALDI-TOF preprocessing toolkit for AMR prediction.
|
|
2
|
+
|
|
3
|
+
Subpackage guide
|
|
4
|
+
----------------
|
|
5
|
+
- ``maldiamrkit.data``: DatasetBuilder, DatasetLoader, InputLayout, DatasetLayout
|
|
6
|
+
- ``maldiamrkit.filters``: SpeciesFilter, DrugFilter, QualityFilter, MetadataFilter
|
|
7
|
+
- ``maldiamrkit.preprocessing``: PreprocessingPipeline, transformers, binning, quality, merging
|
|
8
|
+
- ``maldiamrkit.alignment``: Warping, RawWarping, create_raw_input, align_peaks, AlignmentStrategy, AlignmentMethod
|
|
9
|
+
- ``maldiamrkit.detection``: MaldiPeakDetector, PeakSet, PeakList, create_peakset_input
|
|
10
|
+
- ``maldiamrkit.evaluation``: AMR metrics (binary + mic_regression_report), splitting (LabelEncoder moved to susceptibility)
|
|
11
|
+
- ``maldiamrkit.susceptibility``: MICEncoder, BreakpointTable, BreakpointResult, LabelEncoder
|
|
12
|
+
- ``maldiamrkit.similarity``: spectral_distance, pairwise_distances, clustering, plots
|
|
13
|
+
- ``maldiamrkit.differential``: DifferentialAnalysis, plot_volcano, plot_manhattan, plot_drug_comparison
|
|
14
|
+
- ``maldiamrkit.drift``: DriftMonitor, plot_reference_drift, plot_pca_drift, plot_peak_stability, plot_effect_size_drift
|
|
15
|
+
- ``maldiamrkit.visualization``: plot_spectrum, plot_pseudogel, plot_peaks, plot_alignment, plot_pca, plot_tsne, plot_umap
|
|
16
|
+
- ``maldiamrkit.io``: read_spectrum, parse_mic_column
|
|
17
|
+
|
|
18
|
+
Examples
|
|
19
|
+
--------
|
|
20
|
+
>>> from maldiamrkit import MaldiSpectrum, MaldiSet
|
|
21
|
+
>>> from maldiamrkit.preprocessing import PreprocessingPipeline
|
|
22
|
+
>>> from maldiamrkit.alignment import Warping
|
|
23
|
+
>>> from maldiamrkit.data import DatasetBuilder, DatasetLoader, FlatLayout, DRIAMSLayout
|
|
24
|
+
>>> from maldiamrkit.susceptibility import MICEncoder, BreakpointTable
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from .dataset import MaldiSet
|
|
28
|
+
from .spectrum import MaldiSpectrum
|
|
29
|
+
|
|
30
|
+
__version__ = "0.20.0"
|
|
31
|
+
__author__ = "Ettore Rocchi"
|
|
32
|
+
|
|
33
|
+
__all__ = [
|
|
34
|
+
"MaldiSet",
|
|
35
|
+
"MaldiSpectrum",
|
|
36
|
+
"__version__",
|
|
37
|
+
"__author__",
|
|
38
|
+
]
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""Shared machinery for the package's name-dispatched component registries.
|
|
2
|
+
|
|
3
|
+
The public registration APIs (``register_spectral_metric``,
|
|
4
|
+
``register_transformer``, ``register_binning_method`` and their
|
|
5
|
+
``unregister_*`` / ``list_*`` companions) are thin wrappers around one
|
|
6
|
+
:class:`_ComponentRegistry` instance per component kind, so the three
|
|
7
|
+
registries share a single implementation of the built-in protection,
|
|
8
|
+
override, restore, and name-resolution semantics.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from enum import Enum
|
|
14
|
+
from typing import Any, Callable
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class _ComponentRegistry(dict):
|
|
18
|
+
"""A ``name -> component`` mapping whose built-in entries are protected.
|
|
19
|
+
|
|
20
|
+
Behaves as a plain dict for lookups, while the mutation methods enforce
|
|
21
|
+
the registry contract:
|
|
22
|
+
|
|
23
|
+
- registering a new name is always allowed (re-registering a custom name
|
|
24
|
+
replaces it silently);
|
|
25
|
+
- replacing a built-in requires ``override=True``;
|
|
26
|
+
- unregistering an overridden built-in restores the default component;
|
|
27
|
+
- unregistering a pristine built-in is refused.
|
|
28
|
+
|
|
29
|
+
Parameters
|
|
30
|
+
----------
|
|
31
|
+
kind : str
|
|
32
|
+
Full component noun used in error messages, e.g. ``"spectral
|
|
33
|
+
metric"``.
|
|
34
|
+
short : str
|
|
35
|
+
Short noun used where the messages already say the kind, e.g.
|
|
36
|
+
``"metric"``.
|
|
37
|
+
register_fn : str
|
|
38
|
+
Name of the public registration function to point users at.
|
|
39
|
+
entries : dict
|
|
40
|
+
The built-in components. A copy is kept as the immutable set of
|
|
41
|
+
defaults that :meth:`unregister` can restore.
|
|
42
|
+
validate : callable, optional
|
|
43
|
+
Called with the candidate component before registration; should
|
|
44
|
+
raise ``TypeError`` for unacceptable components.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
def __init__(
|
|
48
|
+
self,
|
|
49
|
+
kind: str,
|
|
50
|
+
short: str,
|
|
51
|
+
register_fn: str,
|
|
52
|
+
entries: dict[str, Any],
|
|
53
|
+
validate: Callable[[Any], None] | None = None,
|
|
54
|
+
) -> None:
|
|
55
|
+
super().__init__(entries)
|
|
56
|
+
self._kind = kind
|
|
57
|
+
self._short = short
|
|
58
|
+
self._register_fn = register_fn
|
|
59
|
+
self._validate = validate
|
|
60
|
+
self._defaults: dict[str, Any] = dict(entries)
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def defaults(self) -> dict[str, Any]:
|
|
64
|
+
"""The built-in components (``name -> component``), never mutated."""
|
|
65
|
+
return self._defaults
|
|
66
|
+
|
|
67
|
+
def register(self, name: str, component: Any, *, override: bool = False) -> None:
|
|
68
|
+
if self._validate is not None:
|
|
69
|
+
self._validate(component)
|
|
70
|
+
if name in self._defaults and not override:
|
|
71
|
+
raise ValueError(
|
|
72
|
+
f"{name!r} is a built-in {self._kind}. "
|
|
73
|
+
"Pass override=True to replace it."
|
|
74
|
+
)
|
|
75
|
+
self[name] = component
|
|
76
|
+
|
|
77
|
+
def unregister(self, name: str) -> None:
|
|
78
|
+
if name in self._defaults:
|
|
79
|
+
default = self._defaults[name]
|
|
80
|
+
if self.get(name) is default:
|
|
81
|
+
raise ValueError(
|
|
82
|
+
f"Cannot unregister built-in {self._kind} {name!r}. "
|
|
83
|
+
f"Built-in {self._short}s are {sorted(self._defaults)}."
|
|
84
|
+
)
|
|
85
|
+
self[name] = default
|
|
86
|
+
return
|
|
87
|
+
try:
|
|
88
|
+
del self[name]
|
|
89
|
+
except KeyError:
|
|
90
|
+
raise KeyError(f"No {self._kind} named {name!r} is registered.") from None
|
|
91
|
+
|
|
92
|
+
def names(self) -> list[str]:
|
|
93
|
+
return sorted(self)
|
|
94
|
+
|
|
95
|
+
def resolve_key(
|
|
96
|
+
self,
|
|
97
|
+
value: Any,
|
|
98
|
+
enum_cls: type[Enum] | None = None,
|
|
99
|
+
*,
|
|
100
|
+
not_a: str = "valid",
|
|
101
|
+
) -> str:
|
|
102
|
+
"""Return the registry key for *value*, an enum member or a name.
|
|
103
|
+
|
|
104
|
+
Raises
|
|
105
|
+
------
|
|
106
|
+
ValueError
|
|
107
|
+
If *value* names no registered component. The message lists the
|
|
108
|
+
registered names and points at the registration function.
|
|
109
|
+
"""
|
|
110
|
+
if enum_cls is not None and isinstance(value, enum_cls):
|
|
111
|
+
key = value.value
|
|
112
|
+
else:
|
|
113
|
+
key = value
|
|
114
|
+
try:
|
|
115
|
+
known = key in self
|
|
116
|
+
except TypeError:
|
|
117
|
+
known = False
|
|
118
|
+
if not known:
|
|
119
|
+
raise ValueError(
|
|
120
|
+
f"{value!r} is not a {not_a} {self._kind}. Use one of "
|
|
121
|
+
f"{self.names()} or register a custom {self._short} with "
|
|
122
|
+
f"{self._register_fn}()."
|
|
123
|
+
)
|
|
124
|
+
return key
|
|
@@ -45,11 +45,11 @@ def create_raw_input(
|
|
|
45
45
|
How to handle duplicate sample IDs (e.g. the same sample
|
|
46
46
|
appearing in multiple year subdirectories):
|
|
47
47
|
|
|
48
|
-
* ``"first"
|
|
49
|
-
* ``"last"
|
|
50
|
-
* ``"drop"
|
|
51
|
-
* ``"keep_all"
|
|
52
|
-
* ``"average"
|
|
48
|
+
* ``"first"``: keep the first occurrence (default).
|
|
49
|
+
* ``"last"``: keep the last occurrence.
|
|
50
|
+
* ``"drop"``: remove all duplicates.
|
|
51
|
+
* ``"keep_all"``: keep every replicate with ``_repN`` suffixes.
|
|
52
|
+
* ``"average"``: keep all replicates and add an
|
|
53
53
|
``_original_id`` column so that
|
|
54
54
|
:meth:`RawWarping.transform` can group and average them.
|
|
55
55
|
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Submodules
|
|
4
4
|
----------
|
|
5
|
-
- ``input_layouts
|
|
6
|
-
- ``dataset_layouts
|
|
7
|
-
- ``builder
|
|
8
|
-
- ``loader
|
|
9
|
-
- ``site_info
|
|
5
|
+
- ``input_layouts``: :class:`InputLayout` adapters for :class:`DatasetBuilder`
|
|
6
|
+
- ``dataset_layouts``: :class:`DatasetLayout` adapters for :class:`DatasetLoader`
|
|
7
|
+
- ``builder``: :class:`DatasetBuilder`, :class:`ProcessingHandler`, :class:`BuildReport`
|
|
8
|
+
- ``loader``: :class:`DatasetLoader`
|
|
9
|
+
- ``site_info``: :class:`SiteInfo`, :class:`BuildInfo`, ``read_site_info``,
|
|
10
10
|
``write_site_info`` (self-describing dataset manifest written at build time
|
|
11
11
|
and consulted by :class:`DRIAMSLayout` at load time)
|
|
12
12
|
"""
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Synthetic example breakpoint table
|
|
1
|
+
# Synthetic example breakpoint table: NOT FOR CLINICAL USE.
|
|
2
2
|
#
|
|
3
3
|
# Used by tests, docs, and notebooks for shape demonstration only. The
|
|
4
4
|
# values below are illustrative and have been deliberately simplified;
|
|
@@ -169,25 +169,28 @@ class DRIAMSLayout(DatasetLayout):
|
|
|
169
169
|
The column is renamed to ``'Species'`` for downstream use.
|
|
170
170
|
year : str, int, or None
|
|
171
171
|
Restrict to a single year.
|
|
172
|
-
metadata_dir : str,
|
|
173
|
-
Subdirectory name containing metadata CSV files.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
172
|
+
metadata_dir : str, optional
|
|
173
|
+
Subdirectory name containing metadata CSV files. Taken from
|
|
174
|
+
``site_info.json`` when the dataset has one, else ``"id"``.
|
|
175
|
+
metadata_suffix : str, optional
|
|
176
|
+
Filename suffix for metadata CSV files. Taken from
|
|
177
|
+
``site_info.json`` when the dataset has one, else ``"_clean.csv"``.
|
|
178
|
+
spectrum_ext : str, optional
|
|
179
|
+
File extension for spectrum files (including the dot). Taken from
|
|
180
|
+
``site_info.json`` when the dataset has one, else ``".txt"``.
|
|
178
181
|
duplicate_strategy : str or DuplicateStrategy, default ``"first"``
|
|
179
182
|
How to handle duplicate spectrum IDs (e.g. the same sample
|
|
180
183
|
appearing in multiple year subdirectories):
|
|
181
184
|
|
|
182
|
-
* ``"first"
|
|
183
|
-
* ``"last"
|
|
184
|
-
* ``"drop"
|
|
185
|
-
* ``"keep_all"
|
|
186
|
-
* ``"average"
|
|
185
|
+
* ``"first"``: keep the first occurrence (default).
|
|
186
|
+
* ``"last"``: keep the last occurrence.
|
|
187
|
+
* ``"drop"``: remove all duplicates.
|
|
188
|
+
* ``"keep_all"``: keep every replicate with ``_repN`` suffixes.
|
|
189
|
+
* ``"average"``: tag replicates for downstream averaging.
|
|
187
190
|
id_transform : callable, optional
|
|
188
191
|
Function mapping raw ``ID`` strings to a canonical *sample*
|
|
189
192
|
identifier. When set, duplicates are detected on the
|
|
190
|
-
transformed identifier rather than the raw one
|
|
193
|
+
transformed identifier rather than the raw one, so
|
|
191
194
|
technical-replicate files that share an underlying sample
|
|
192
195
|
(e.g. DRIAMS ``UUID_MALDI1`` / ``UUID_MALDI2``) are
|
|
193
196
|
recognized as duplicates by ``duplicate_strategy``. The raw
|
|
@@ -212,11 +215,15 @@ class DRIAMSLayout(DatasetLayout):
|
|
|
212
215
|
collapse DRIAMS technical replicates (``_MALDI<N>``) to one row per
|
|
213
216
|
underlying isolate via the active ``duplicate_strategy``. Ignored when
|
|
214
217
|
an explicit ``id_transform`` is given (that always takes precedence).
|
|
215
|
-
mz_min : float,
|
|
218
|
+
mz_min : float, optional
|
|
216
219
|
Lower m/z edge to assign to bin index 0 when a ``binned_N/`` stage
|
|
217
|
-
is loaded. Only consulted by :meth:`postprocess_spectrum`.
|
|
218
|
-
|
|
219
|
-
|
|
220
|
+
is loaded. Only consulted by :meth:`postprocess_spectrum`. Taken
|
|
221
|
+
from the ``mz_range`` in ``site_info.json`` when the dataset has one,
|
|
222
|
+
else ``2000.0``.
|
|
223
|
+
mz_max : float, optional
|
|
224
|
+
Upper m/z edge assigned to bin index ``N-1``. Taken from the
|
|
225
|
+
``mz_range`` in ``site_info.json`` when the dataset has one, else
|
|
226
|
+
``19997.0``.
|
|
220
227
|
normalize_tic : bool, default=False
|
|
221
228
|
When ``True``, re-apply a TIC normalization
|
|
222
229
|
(``intensity <- intensity / sum(intensity)``) to every loaded
|
|
@@ -224,7 +231,7 @@ class DRIAMSLayout(DatasetLayout):
|
|
|
224
231
|
published DRIAMS / MS-UMG ``binned_6000/`` files do not sum
|
|
225
232
|
to 1.0 on disk (empirically ~1.29 and ~1.36 respectively),
|
|
226
233
|
despite the DRIAMS preprocessing script calling
|
|
227
|
-
``calibrateIntensity(method="TIC")`` before trimming
|
|
234
|
+
``calibrateIntensity(method="TIC")`` before trimming; the
|
|
228
235
|
cause is somewhere in the upstream pipeline (MALDIquant version
|
|
229
236
|
or an implicit scaling step) and has not been reproduced here.
|
|
230
237
|
Enabling this kwarg gives sum=1.0 per spectrum, aligning DRIAMS
|
|
@@ -531,13 +538,13 @@ class MARISMaLayout(DatasetLayout):
|
|
|
531
538
|
How to handle duplicate specimen identifiers (e.g. the same
|
|
532
539
|
sample measured at multiple MALDI target positions):
|
|
533
540
|
|
|
534
|
-
* ``"first"
|
|
535
|
-
* ``"last"
|
|
536
|
-
* ``"drop"
|
|
537
|
-
* ``"keep_all"
|
|
541
|
+
* ``"first"``: keep the first occurrence (default).
|
|
542
|
+
* ``"last"``: keep the last occurrence.
|
|
543
|
+
* ``"drop"``: remove all duplicates.
|
|
544
|
+
* ``"keep_all"``: keep every replicate, appending the
|
|
538
545
|
target-position value to the ID
|
|
539
546
|
(``{identifier}_{target_position}``).
|
|
540
|
-
* ``"average"
|
|
547
|
+
* ``"average"``: tag replicates for downstream averaging
|
|
541
548
|
(adds ``_original_id`` column).
|
|
542
549
|
id_transform : callable, optional
|
|
543
550
|
Function mapping raw ``ID`` strings to a canonical *sample*
|
|
@@ -80,6 +80,10 @@ class FlatLayout(InputLayout):
|
|
|
80
80
|
``spectra_dir`` is itself flat but the years are known from another
|
|
81
81
|
source. Takes precedence over the inferred subfolder year,
|
|
82
82
|
but not over ``year_column``.
|
|
83
|
+
spectrum_ext : str, default=".txt"
|
|
84
|
+
File extension of the spectrum files. Any format understood by
|
|
85
|
+
:func:`~maldiamrkit.io.read_spectrum` works, e.g. ``".mzML"`` or
|
|
86
|
+
``".mzXML"`` for open-format exports.
|
|
83
87
|
"""
|
|
84
88
|
|
|
85
89
|
def __init__(
|
|
@@ -90,30 +94,39 @@ class FlatLayout(InputLayout):
|
|
|
90
94
|
id_column: str = "ID",
|
|
91
95
|
year_column: str | None = None,
|
|
92
96
|
year_overrides: dict[str, str] | None = None,
|
|
97
|
+
spectrum_ext: str = ".txt",
|
|
93
98
|
) -> None:
|
|
94
99
|
self.spectra_dir = Path(spectra_dir)
|
|
95
100
|
self.metadata_csv = Path(metadata_csv)
|
|
96
101
|
self.id_column = id_column
|
|
97
102
|
self.year_column = year_column
|
|
98
103
|
self.year_overrides = year_overrides
|
|
104
|
+
self.spectrum_ext = (
|
|
105
|
+
spectrum_ext if spectrum_ext.startswith(".") else f".{spectrum_ext}"
|
|
106
|
+
)
|
|
99
107
|
self._year_map: dict[str, str] | None = None
|
|
100
108
|
self._folder_year_map: dict[str, str] = {}
|
|
101
109
|
|
|
102
110
|
def discover_spectra(self) -> list[Path]:
|
|
103
|
-
"""Find
|
|
111
|
+
"""Find spectrum files, whether flat or in (possibly nested) subfolders.
|
|
112
|
+
|
|
113
|
+
The extension is ``spectrum_ext`` (``.txt`` by default).
|
|
104
114
|
|
|
105
115
|
Files are searched flat first, then one level down, then
|
|
106
116
|
recursively. Whenever a spectrum sits under a four-digit-year
|
|
107
117
|
folder, that year is recorded so it can serve as a fallback when
|
|
108
118
|
no ``year_column`` is supplied (see :meth:`get_year`).
|
|
109
119
|
"""
|
|
110
|
-
|
|
120
|
+
pattern = f"*{self.spectrum_ext}"
|
|
121
|
+
files = sorted(self.spectra_dir.glob(pattern))
|
|
111
122
|
if not files:
|
|
112
|
-
files = sorted(self.spectra_dir.glob("
|
|
123
|
+
files = sorted(self.spectra_dir.glob(f"*/{pattern}"))
|
|
113
124
|
if not files:
|
|
114
|
-
files = sorted(self.spectra_dir.rglob(
|
|
125
|
+
files = sorted(self.spectra_dir.rglob(pattern))
|
|
115
126
|
if not files:
|
|
116
|
-
raise ValueError(
|
|
127
|
+
raise ValueError(
|
|
128
|
+
f"No {self.spectrum_ext} spectrum files found in {self.spectra_dir}"
|
|
129
|
+
)
|
|
117
130
|
|
|
118
131
|
self._folder_year_map = {}
|
|
119
132
|
for f in files:
|
|
@@ -214,13 +227,13 @@ class BrukerTreeLayout(InputLayout):
|
|
|
214
227
|
How to handle duplicate specimen identifiers (e.g. the same
|
|
215
228
|
sample measured at multiple MALDI target positions):
|
|
216
229
|
|
|
217
|
-
* ``"first"
|
|
218
|
-
* ``"last"
|
|
219
|
-
* ``"drop"
|
|
220
|
-
* ``"keep_all"
|
|
230
|
+
* ``"first"``: keep the first occurrence (default).
|
|
231
|
+
* ``"last"``: keep the last occurrence.
|
|
232
|
+
* ``"drop"``: remove all duplicates.
|
|
233
|
+
* ``"keep_all"``: keep every replicate, appending the
|
|
221
234
|
target-position value to the ID
|
|
222
235
|
(``{identifier}_{target_position}``).
|
|
223
|
-
* ``"average"
|
|
236
|
+
* ``"average"``: tag replicates for downstream averaging
|
|
224
237
|
(adds ``_original_id`` column).
|
|
225
238
|
validate : bool, default=True
|
|
226
239
|
If ``True``, skip empty spectra (all-zero ``fid``) and warn
|