MaldiAMRKit 0.22.1__tar.gz → 0.22.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 (107) hide show
  1. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2/MaldiAMRKit.egg-info}/PKG-INFO +47 -36
  2. {maldiamrkit-0.22.1/MaldiAMRKit.egg-info → maldiamrkit-0.22.2}/PKG-INFO +47 -36
  3. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/README.md +46 -35
  4. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/__init__.py +1 -1
  5. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/duplicates.py +1 -1
  6. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/input_layouts.py +9 -0
  7. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/io/readers.py +7 -2
  8. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/susceptibility/mic_encoder.py +12 -5
  9. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/LICENSE +0 -0
  10. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/MaldiAMRKit.egg-info/SOURCES.txt +0 -0
  11. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/MaldiAMRKit.egg-info/dependency_links.txt +0 -0
  12. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/MaldiAMRKit.egg-info/entry_points.txt +0 -0
  13. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/MaldiAMRKit.egg-info/requires.txt +0 -0
  14. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/MaldiAMRKit.egg-info/top_level.txt +0 -0
  15. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/_compat.py +0 -0
  16. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/_registry.py +0 -0
  17. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/alignment/__init__.py +0 -0
  18. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/alignment/_dtw.py +0 -0
  19. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/alignment/_versioning.py +0 -0
  20. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/alignment/peak_align.py +0 -0
  21. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/alignment/raw_warping.py +0 -0
  22. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/alignment/strategies.py +0 -0
  23. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/alignment/warping.py +0 -0
  24. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/cli.py +0 -0
  25. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/__init__.py +0 -0
  26. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/_metadata.py +0 -0
  27. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/README.md +0 -0
  28. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v1.0.yaml +0 -0
  29. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v1.1.yaml +0 -0
  30. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v1.2.yaml +0 -0
  31. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v1.3.yaml +0 -0
  32. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v10.0.yaml +0 -0
  33. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v11.0.yaml +0 -0
  34. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v12.0.yaml +0 -0
  35. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v13.1.yaml +0 -0
  36. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v14.0.yaml +0 -0
  37. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v15.0.yaml +0 -0
  38. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v16.0.yaml +0 -0
  39. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v2.0.yaml +0 -0
  40. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v4.0.yaml +0 -0
  41. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v5.0.yaml +0 -0
  42. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v6.0.yaml +0 -0
  43. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v7.1.yaml +0 -0
  44. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v8.0.yaml +0 -0
  45. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v8.1.yaml +0 -0
  46. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/eucast/eucast_v9.0.yaml +0 -0
  47. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/breakpoints/example.yaml +0 -0
  48. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/builder.py +0 -0
  49. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/dataset_layouts.py +0 -0
  50. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/loader.py +0 -0
  51. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/data/site_info.py +0 -0
  52. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/dataset.py +0 -0
  53. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/detection/__init__.py +0 -0
  54. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/detection/peak_detector.py +0 -0
  55. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/detection/peaklist.py +0 -0
  56. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/differential/__init__.py +0 -0
  57. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/differential/analysis.py +0 -0
  58. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/differential/plots.py +0 -0
  59. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/differential/stats.py +0 -0
  60. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/drift/__init__.py +0 -0
  61. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/drift/monitor.py +0 -0
  62. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/drift/pca_drift.py +0 -0
  63. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/drift/peak_drift.py +0 -0
  64. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/drift/plots.py +0 -0
  65. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/drift/reference.py +0 -0
  66. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/evaluation/__init__.py +0 -0
  67. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/evaluation/metrics.py +0 -0
  68. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/evaluation/mic_regression.py +0 -0
  69. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/evaluation/splitting.py +0 -0
  70. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/filters.py +0 -0
  71. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/io/__init__.py +0 -0
  72. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/io/mic.py +0 -0
  73. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/io/writers.py +0 -0
  74. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/preprocessing/__init__.py +0 -0
  75. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/preprocessing/binning.py +0 -0
  76. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/preprocessing/merging.py +0 -0
  77. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/preprocessing/pipeline.py +0 -0
  78. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/preprocessing/preprocessing_pipeline.py +0 -0
  79. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/preprocessing/quality.py +0 -0
  80. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/preprocessing/transformers.py +0 -0
  81. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/py.typed +0 -0
  82. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/similarity/__init__.py +0 -0
  83. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/similarity/clustering.py +0 -0
  84. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/similarity/metrics.py +0 -0
  85. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/similarity/pairwise.py +0 -0
  86. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/similarity/plots.py +0 -0
  87. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/spectrum.py +0 -0
  88. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/susceptibility/__init__.py +0 -0
  89. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/susceptibility/breakpoint.py +0 -0
  90. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/susceptibility/label_encoder.py +0 -0
  91. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/visualization/__init__.py +0 -0
  92. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/visualization/_common.py +0 -0
  93. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/visualization/alignment_plots.py +0 -0
  94. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/visualization/exploratory_plots.py +0 -0
  95. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/visualization/peak_plots.py +0 -0
  96. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/maldiamrkit/visualization/spectrum_plots.py +0 -0
  97. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/pyproject.toml +0 -0
  98. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/requirements-batch.txt +0 -0
  99. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/requirements-dev.txt +0 -0
  100. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/requirements-docs.txt +0 -0
  101. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/requirements-formats.txt +0 -0
  102. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/requirements.txt +0 -0
  103. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/setup.cfg +0 -0
  104. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/tests/test_compat.py +0 -0
  105. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/tests/test_numerical_edge_cases.py +0 -0
  106. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/tests/test_peak_detector.py +0 -0
  107. {maldiamrkit-0.22.1 → maldiamrkit-0.22.2}/tests/test_peaklist.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MaldiAMRKit
3
- Version: 0.22.1
3
+ Version: 0.22.2
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
@@ -71,13 +71,20 @@ Dynamic: license-file
71
71
  [![License](https://img.shields.io/github/license/EttoreRocchi/MaldiAMRKit)](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/LICENSE)
72
72
 
73
73
  <p align="center">
74
- <img src="docs/maldiamrkit.png" alt="MaldiAMRKit" width="320"/>
74
+ <picture>
75
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/EttoreRocchi/MaldiAMRKit/main/docs/maldiamrkit_dark.png">
76
+ <img src="https://raw.githubusercontent.com/EttoreRocchi/MaldiAMRKit/main/docs/maldiamrkit.png" alt="MaldiAMRKit" width="320"/>
77
+ </picture>
75
78
  </p>
76
79
 
77
80
  <p align="center">
78
81
  <strong>A comprehensive toolkit for MALDI-TOF mass spectrometry data preprocessing for antimicrobial resistance (AMR) prediction purposes</strong>
79
82
  </p>
80
83
 
84
+ <p align="center">
85
+ <img src="https://raw.githubusercontent.com/EttoreRocchi/MaldiAMRKit/main/docs/preprocessing_pipeline.svg" alt="Animated MaldiAMRKit pipeline: a raw MALDI-TOF spectrum is smoothed, baseline-corrected, peak-detected and binned into a feature vector that predicts antimicrobial resistance (R/S)" width="720"/>
86
+ </p>
87
+
81
88
  <p align="center">
82
89
  <a href="#installation">Installation</a> •
83
90
  <a href="#features">Features</a> •
@@ -106,13 +113,13 @@ pip install maldisuite
106
113
 
107
114
  Visit the **MaldiSuite** landing page at <https://ettorerocchi.github.io/MaldiSuite/>.
108
115
 
109
- ### Optional: Batch Correction & UMAP
116
+ ### Optional: UMAP & combatlearn
110
117
 
111
118
  ```bash
112
119
  pip install maldiamrkit[batch]
113
120
  ```
114
121
 
115
- Installs [`combatlearn`](https://github.com/EttoreRocchi/combatlearn) for ComBat-based batch effect correction and `umap-learn` for UMAP exploratory plots.
122
+ MaldiAMRKit has no batch corrector of its own. This extra adds `umap-learn` for UMAP exploratory plots, and [`combatlearn`](https://github.com/EttoreRocchi/combatlearn) to use ComBat directly on a feature matrix. For batch correction built for MALDI-TOF spectra, see [MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit).
116
123
 
117
124
  ### Optional: extended mzML/mzXML support
118
125
 
@@ -122,7 +129,7 @@ pip install maldiamrkit[formats]
122
129
 
123
130
  `.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.
124
131
 
125
- ### Development Installation
132
+ ### Development installation
126
133
 
127
134
  ```bash
128
135
  git clone https://github.com/EttoreRocchi/MaldiAMRKit.git
@@ -133,15 +140,15 @@ pip install -e .[dev]
133
140
  ## Features
134
141
 
135
142
  ### Preprocessing
136
- - **Composable Pipeline**: Build custom `PreprocessingPipeline` from individual transformers (smoothing, baseline correction, normalization, trimming), serializable to JSON/YAML
143
+ - **Composable Pipeline**: Build custom `PreprocessingPipeline` from individual transformers (smoothing, baseline correction, normalisation, trimming), serialisable to JSON/YAML
137
144
  - **Smoothing**: Savitzky-Golay and moving-average filters
138
145
  - **Baseline Correction**: SNIP, morphological top-hat, lower-convex-hull, and iterative rolling-median baselines
139
146
  - **Multiple Binning Strategies**: Uniform, proportional, adaptive, and custom bin edges
140
147
  - **Quality Metrics**: SNR estimation, MAD-based noise estimation, comprehensive quality reports, and alignment assessment
141
148
  - **Replicate Merging**: Mean/median/weighted merging with correlation-based outlier detection
142
149
 
143
- ### Alignment & Detection
144
- - **Spectral Alignment**: Shift, linear, piecewise, DTW, quadratic, cubic, and LOWESS warping for both binned and raw full-resolution spectra. Spectra are first shifted and then aligned to the reference of the shifted spectra, a non-rigid warp is kept only when the matched peaks support it, and resampling preserves the total intensity; spectra of several species are best aligned one species at a time
150
+ ### Alignment & detection
151
+ - **Spectral Alignment**: Shift, linear, piecewise, DTW, quadratic, cubic, and LOWESS warping for both binned and raw full-resolution spectra. Spectra are first shifted and then aligned to the reference of the shifted spectra, a non-rigid warp is kept only when the matched peaks support it, and resampling preserves the total intensity (neither applies to DTW); spectra of several species are best aligned one species at a time
145
152
  - **Peak Detection**: Local maxima and persistent homology methods
146
153
  - **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
147
154
  - **Fit-Free Peak Alignment**: `align_peaks()` warps a peak set onto caller-supplied reference peaks, which the caller estimates on the training split (for example `RawWarping(...).fit(X_train).ref_peaks_mz_`; a reference built with test spectra leaks)
@@ -158,19 +165,23 @@ pip install -e .[dev]
158
165
 
159
166
  ### Susceptibility (MIC encoding & breakpoints)
160
167
  - **`MICEncoder`**: Convert raw MIC strings into `log2(MIC)` regression targets plus S/I/R categories and ATU flags in a single pass
161
- - **`BreakpointTable`**: Clinical breakpoint tables (EUCAST v1.0-v16.0 bundled) loaded by version, year, latest, or custom YAML
168
+ - **`BreakpointTable`**: Clinical breakpoint tables (19 EUCAST versions between v1.0 and v16.0 bundled) loaded by version, year, latest, or custom YAML
162
169
  - **`LabelEncoder`**: Map R/I/S to binary with configurable intermediate handling (moved from `maldiamrkit.evaluation` in v0.15)
163
170
 
164
- ### Differential Analysis
171
+ ### Differential analysis
165
172
  - **`DifferentialAnalysis`**: Per-bin statistical testing (Mann-Whitney U, Welch's t-test) between resistant and susceptible groups, with multiple-testing correction, log2 fold change, and Cohen's d effect size
166
173
  - **Peak Ranking**: `top_peaks()` by adjusted p-value, `significant_peaks()` with fold-change and p-value thresholds, `compare_drugs()` for multi-drug boolean significance matrices (to select features for a classifier, rank peaks inside each training fold)
167
174
  - **AMR-Aware Plots**: `plot_volcano()`, `plot_manhattan()` along the m/z axis, and `plot_drug_comparison()` with binary heatmap or UpSet-style intersection view
168
175
 
169
- ### Drift Monitoring
176
+ ### Drift monitoring
170
177
  - **`DriftMonitor`**: Anchor a baseline on early timestamps (default: first 20%) and track temporal drift via three complementary views - reference similarity of per-window median spectra, PCA centroid trajectory in a baseline-fitted PCA space, and Jaccard stability of top-k differential peaks over time
171
178
  - **Trajectory Plots**: `plot_reference_drift`, `plot_pca_drift`, `plot_peak_stability`, `plot_effect_size_drift`
172
179
 
173
- ### Data Management
180
+ ### Spectral similarity
181
+ - **Distances & Clustering**: `spectral_distance` and `pairwise_distances` with built-in or registered metrics, `cluster_spectra` with hierarchical, HDBSCAN, and k-medoids methods, silhouette scores, and metadata concordance
182
+ - **Plots**: `plot_distance_heatmap` and `plot_dendrogram`
183
+
184
+ ### Data management
174
185
  - **Dataset Building & Loading**: `DatasetBuilder` and `DatasetLoader` with pluggable layout adapters (`FlatLayout`, `BrukerTreeLayout`, `DRIAMSLayout`, `MARISMaLayout`)
175
186
  - **Replicate Collapsing**: `DRIAMSLayout(collapse_replicates=True)` merges technical replicates (`_MALDI<N>`) to one row per isolate at load time via the active `duplicate_strategy`
176
187
  - **Bruker Format Support**: Read Bruker flexAnalysis binary data (fid/1r + acqus) natively via `read_spectrum()` on directories
@@ -179,9 +190,9 @@ pip install -e .[dev]
179
190
  - **Composable Filters**: `SpeciesFilter`, `DrugFilter`, `QualityFilter`, `MetadataFilter` combinable with `&`/`|`/`~` operators
180
191
  - **Spectrum Export**: Save spectra to CSV, TXT, or mzML via `MaldiSpectrum.save()` and `MaldiSet.save_spectra()`
181
192
 
182
- ### Visualization & Tools
183
- - **Exploratory Plots**: PCA, t-SNE, and UMAP scatter plots colored by species, resistance phenotype, or any metadata column
184
- - **Batch Effect Correction**: Multi-site/multi-instrument correction via [`combatlearn`](https://github.com/EttoreRocchi/combatlearn) (`pip install maldiamrkit[batch]`)
193
+ ### Visualisation & tools
194
+ - **Exploratory Plots**: PCA, t-SNE, and UMAP scatter plots coloured by species, resistance phenotype, or any metadata column
195
+ - **Batch Effect Correction**: Not part of this package. Use [`combatlearn`](https://github.com/EttoreRocchi/combatlearn) directly (`pip install maldiamrkit[batch]`) or [MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit)
185
196
  - **CLI**: `maldiamrkit preprocess`, `maldiamrkit quality`, and `maldiamrkit build` for batch processing
186
197
  - **Parallel Processing**: Multi-core support via `n_jobs` parameter
187
198
  - **ML-Ready**: Direct integration with scikit-learn pipelines
@@ -190,9 +201,9 @@ pip install -e .[dev]
190
201
 
191
202
  Full documentation is available at [maldiamrkit.readthedocs.io](https://maldiamrkit.readthedocs.io/).
192
203
 
193
- ## Quick Start
204
+ ## Quick start
194
205
 
195
- ### Load and Preprocess a Single Spectrum
206
+ ### Load and preprocess a single spectrum
196
207
 
197
208
  ```python
198
209
  from maldiamrkit import MaldiSpectrum
@@ -211,7 +222,7 @@ from maldiamrkit.visualization import plot_spectrum
211
222
  plot_spectrum(spec, stage="binned")
212
223
  ```
213
224
 
214
- ### Build a Dataset from Multiple Spectra
225
+ ### Build a dataset from multiple spectra
215
226
 
216
227
  ```python
217
228
  from maldiamrkit import MaldiSet
@@ -229,7 +240,7 @@ X = data.X # Feature matrix
229
240
  y = data.get_y_single("Drug") # Target labels
230
241
  ```
231
242
 
232
- ### Machine Learning Pipeline
243
+ ### Machine learning pipeline
233
244
 
234
245
  ```python
235
246
  from sklearn.pipeline import Pipeline
@@ -241,7 +252,7 @@ from maldiamrkit.detection import MaldiPeakDetector
241
252
 
242
253
  # Create ML pipeline
243
254
  pipe = Pipeline([
244
- ("peaks", MaldiPeakDetector(binary=False, prominence=0.05)),
255
+ ("peaks", MaldiPeakDetector(binary=False, prominence=1e-4)),
245
256
  ("warp", Warping(method="shift")),
246
257
  ("scaler", StandardScaler()),
247
258
  ("clf", RandomForestClassifier(n_estimators=100, random_state=42))
@@ -260,32 +271,32 @@ For more examples covering alignment, filtering, evaluation, CLI usage, and more
260
271
 
261
272
  For more detailed examples, see the notebooks:
262
273
 
263
- - [Quick Start](notebooks/01_quick_start.ipynb) - Loading, preprocessing, binning, and quality assessment
264
- - [Peak Detection](notebooks/02_peak_detection.ipynb) - Local maxima and persistent homology methods
265
- - [Alignment](notebooks/03_alignment.ipynb) - Warping methods and alignment quality
266
- - [Evaluation](notebooks/04_evaluation.ipynb) - AMR metrics, label encoding, and stratified splitting
267
- - [Exploration](notebooks/05_exploration.ipynb) - PCA, t-SNE, UMAP visualizations and batch correction
268
- - [Differential Analysis](notebooks/06_differential_analysis.ipynb) - R vs. S peak testing, volcano/Manhattan plots, and multi-drug comparison
269
- - [Drift Monitoring](notebooks/07_drift_monitoring.ipynb) - Baseline-anchored drift detection: reference similarity, PCA trajectory, peak stability, and effect-size drift
270
- - [Susceptibility](notebooks/08_susceptibility.ipynb) - `MICEncoder` + `BreakpointTable` for log2(MIC) regression targets, S/I/R categorisation with ATU, and `mic_regression_report` evaluation
271
- - [Peak Sets](notebooks/09_peak_sets.ipynb) - `PeakSet` / `PeakList` extraction, ranking and padding, caching, and fit-free peak alignment
272
- - [Custom Components](notebooks/10_custom_components.ipynb) - registering a custom distance metric and a custom transformer end-to-end
274
+ - [Quick Start](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/01_quick_start.ipynb) - Loading, preprocessing, binning, and quality assessment
275
+ - [Peak Detection](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/02_peak_detection.ipynb) - Local maxima and persistent homology methods
276
+ - [Alignment](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/03_alignment.ipynb) - Warping methods and alignment quality
277
+ - [Evaluation](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/04_evaluation.ipynb) - AMR metrics, label encoding, and stratified splitting
278
+ - [Exploration](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/05_exploration.ipynb) - PCA, t-SNE, and UMAP visualisations, spectral similarity, and clustering
279
+ - [Differential Analysis](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/06_differential_analysis.ipynb) - R vs. S peak testing, volcano/Manhattan plots, and multi-drug comparison
280
+ - [Drift Monitoring](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/07_drift_monitoring.ipynb) - Baseline-anchored drift detection: reference similarity, PCA trajectory, peak stability, and effect-size drift
281
+ - [Susceptibility](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/08_susceptibility.ipynb) - `MICEncoder` + `BreakpointTable` for log2(MIC) regression targets, S/I/R categorisation with ATU, and `mic_regression_report` evaluation
282
+ - [Peak Sets](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/09_peak_sets.ipynb) - `PeakSet` / `PeakList` extraction, ranking and padding, caching, and fit-free peak alignment
283
+ - [Custom Components](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/10_custom_components.ipynb) - registering a custom distance metric and a custom transformer end-to-end
273
284
 
274
- 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.
285
+ Notebooks `01`-`03` and `08`-`10` run on the small example dataset bundled under [`data/`](https://github.com/EttoreRocchi/MaldiAMRKit/tree/main/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`](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/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.
275
286
 
276
- ## MaldiSuite Ecosystem
287
+ ## MaldiSuite ecosystem
277
288
 
278
- MaldiAMRKit is the data-model and preprocessing package of the **MaldiSuite** ecosystem:
289
+ MaldiAMRKit is one of the three packages of the **MaldiSuite** ecosystem:
279
290
 
280
291
  - **MaldiAMRKit** (this package) - data model (`MaldiSpectrum`, `MaldiSet`), preprocessing, alignment, peak detection, differential analysis, and AMR-aware evaluation.
281
292
  - **[MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit)** - batch-effect correction and harmonisation for multi-centre / multi-instrument MALDI-TOF spectra.
282
293
  - **[MaldiDeepKit](https://github.com/EttoreRocchi/MaldiDeepKit)** - sklearn-compatible deep learning classifiers (MLP, CNN, ResNet, Transformer).
283
294
 
284
- 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/>).
295
+ 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/>).
285
296
 
286
297
  ## Contributing
287
298
 
288
- Pull requests, bug reports, and feature ideas are welcome. See the [Contributing Guide](CONTRIBUTING.md) for how to get started.
299
+ Pull requests, bug reports, and feature ideas are welcome. See the [Contributing Guide](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/CONTRIBUTING.md) for how to get started.
289
300
 
290
301
  ## Citing
291
302
 
@@ -297,7 +308,7 @@ See the [full publications list](https://maldiamrkit.readthedocs.io/en/latest/pa
297
308
 
298
309
  ## License
299
310
 
300
- This project is licensed under the **MIT License**. See the [LICENSE](LICENSE) file for details.
311
+ This project is licensed under the **MIT License**. See the [LICENSE](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/LICENSE) file for details.
301
312
 
302
313
  ## Acknowledgements
303
314
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MaldiAMRKit
3
- Version: 0.22.1
3
+ Version: 0.22.2
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
@@ -71,13 +71,20 @@ Dynamic: license-file
71
71
  [![License](https://img.shields.io/github/license/EttoreRocchi/MaldiAMRKit)](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/LICENSE)
72
72
 
73
73
  <p align="center">
74
- <img src="docs/maldiamrkit.png" alt="MaldiAMRKit" width="320"/>
74
+ <picture>
75
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/EttoreRocchi/MaldiAMRKit/main/docs/maldiamrkit_dark.png">
76
+ <img src="https://raw.githubusercontent.com/EttoreRocchi/MaldiAMRKit/main/docs/maldiamrkit.png" alt="MaldiAMRKit" width="320"/>
77
+ </picture>
75
78
  </p>
76
79
 
77
80
  <p align="center">
78
81
  <strong>A comprehensive toolkit for MALDI-TOF mass spectrometry data preprocessing for antimicrobial resistance (AMR) prediction purposes</strong>
79
82
  </p>
80
83
 
84
+ <p align="center">
85
+ <img src="https://raw.githubusercontent.com/EttoreRocchi/MaldiAMRKit/main/docs/preprocessing_pipeline.svg" alt="Animated MaldiAMRKit pipeline: a raw MALDI-TOF spectrum is smoothed, baseline-corrected, peak-detected and binned into a feature vector that predicts antimicrobial resistance (R/S)" width="720"/>
86
+ </p>
87
+
81
88
  <p align="center">
82
89
  <a href="#installation">Installation</a> •
83
90
  <a href="#features">Features</a> •
@@ -106,13 +113,13 @@ pip install maldisuite
106
113
 
107
114
  Visit the **MaldiSuite** landing page at <https://ettorerocchi.github.io/MaldiSuite/>.
108
115
 
109
- ### Optional: Batch Correction & UMAP
116
+ ### Optional: UMAP & combatlearn
110
117
 
111
118
  ```bash
112
119
  pip install maldiamrkit[batch]
113
120
  ```
114
121
 
115
- Installs [`combatlearn`](https://github.com/EttoreRocchi/combatlearn) for ComBat-based batch effect correction and `umap-learn` for UMAP exploratory plots.
122
+ MaldiAMRKit has no batch corrector of its own. This extra adds `umap-learn` for UMAP exploratory plots, and [`combatlearn`](https://github.com/EttoreRocchi/combatlearn) to use ComBat directly on a feature matrix. For batch correction built for MALDI-TOF spectra, see [MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit).
116
123
 
117
124
  ### Optional: extended mzML/mzXML support
118
125
 
@@ -122,7 +129,7 @@ pip install maldiamrkit[formats]
122
129
 
123
130
  `.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.
124
131
 
125
- ### Development Installation
132
+ ### Development installation
126
133
 
127
134
  ```bash
128
135
  git clone https://github.com/EttoreRocchi/MaldiAMRKit.git
@@ -133,15 +140,15 @@ pip install -e .[dev]
133
140
  ## Features
134
141
 
135
142
  ### Preprocessing
136
- - **Composable Pipeline**: Build custom `PreprocessingPipeline` from individual transformers (smoothing, baseline correction, normalization, trimming), serializable to JSON/YAML
143
+ - **Composable Pipeline**: Build custom `PreprocessingPipeline` from individual transformers (smoothing, baseline correction, normalisation, trimming), serialisable to JSON/YAML
137
144
  - **Smoothing**: Savitzky-Golay and moving-average filters
138
145
  - **Baseline Correction**: SNIP, morphological top-hat, lower-convex-hull, and iterative rolling-median baselines
139
146
  - **Multiple Binning Strategies**: Uniform, proportional, adaptive, and custom bin edges
140
147
  - **Quality Metrics**: SNR estimation, MAD-based noise estimation, comprehensive quality reports, and alignment assessment
141
148
  - **Replicate Merging**: Mean/median/weighted merging with correlation-based outlier detection
142
149
 
143
- ### Alignment & Detection
144
- - **Spectral Alignment**: Shift, linear, piecewise, DTW, quadratic, cubic, and LOWESS warping for both binned and raw full-resolution spectra. Spectra are first shifted and then aligned to the reference of the shifted spectra, a non-rigid warp is kept only when the matched peaks support it, and resampling preserves the total intensity; spectra of several species are best aligned one species at a time
150
+ ### Alignment & detection
151
+ - **Spectral Alignment**: Shift, linear, piecewise, DTW, quadratic, cubic, and LOWESS warping for both binned and raw full-resolution spectra. Spectra are first shifted and then aligned to the reference of the shifted spectra, a non-rigid warp is kept only when the matched peaks support it, and resampling preserves the total intensity (neither applies to DTW); spectra of several species are best aligned one species at a time
145
152
  - **Peak Detection**: Local maxima and persistent homology methods
146
153
  - **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
147
154
  - **Fit-Free Peak Alignment**: `align_peaks()` warps a peak set onto caller-supplied reference peaks, which the caller estimates on the training split (for example `RawWarping(...).fit(X_train).ref_peaks_mz_`; a reference built with test spectra leaks)
@@ -158,19 +165,23 @@ pip install -e .[dev]
158
165
 
159
166
  ### Susceptibility (MIC encoding & breakpoints)
160
167
  - **`MICEncoder`**: Convert raw MIC strings into `log2(MIC)` regression targets plus S/I/R categories and ATU flags in a single pass
161
- - **`BreakpointTable`**: Clinical breakpoint tables (EUCAST v1.0-v16.0 bundled) loaded by version, year, latest, or custom YAML
168
+ - **`BreakpointTable`**: Clinical breakpoint tables (19 EUCAST versions between v1.0 and v16.0 bundled) loaded by version, year, latest, or custom YAML
162
169
  - **`LabelEncoder`**: Map R/I/S to binary with configurable intermediate handling (moved from `maldiamrkit.evaluation` in v0.15)
163
170
 
164
- ### Differential Analysis
171
+ ### Differential analysis
165
172
  - **`DifferentialAnalysis`**: Per-bin statistical testing (Mann-Whitney U, Welch's t-test) between resistant and susceptible groups, with multiple-testing correction, log2 fold change, and Cohen's d effect size
166
173
  - **Peak Ranking**: `top_peaks()` by adjusted p-value, `significant_peaks()` with fold-change and p-value thresholds, `compare_drugs()` for multi-drug boolean significance matrices (to select features for a classifier, rank peaks inside each training fold)
167
174
  - **AMR-Aware Plots**: `plot_volcano()`, `plot_manhattan()` along the m/z axis, and `plot_drug_comparison()` with binary heatmap or UpSet-style intersection view
168
175
 
169
- ### Drift Monitoring
176
+ ### Drift monitoring
170
177
  - **`DriftMonitor`**: Anchor a baseline on early timestamps (default: first 20%) and track temporal drift via three complementary views - reference similarity of per-window median spectra, PCA centroid trajectory in a baseline-fitted PCA space, and Jaccard stability of top-k differential peaks over time
171
178
  - **Trajectory Plots**: `plot_reference_drift`, `plot_pca_drift`, `plot_peak_stability`, `plot_effect_size_drift`
172
179
 
173
- ### Data Management
180
+ ### Spectral similarity
181
+ - **Distances & Clustering**: `spectral_distance` and `pairwise_distances` with built-in or registered metrics, `cluster_spectra` with hierarchical, HDBSCAN, and k-medoids methods, silhouette scores, and metadata concordance
182
+ - **Plots**: `plot_distance_heatmap` and `plot_dendrogram`
183
+
184
+ ### Data management
174
185
  - **Dataset Building & Loading**: `DatasetBuilder` and `DatasetLoader` with pluggable layout adapters (`FlatLayout`, `BrukerTreeLayout`, `DRIAMSLayout`, `MARISMaLayout`)
175
186
  - **Replicate Collapsing**: `DRIAMSLayout(collapse_replicates=True)` merges technical replicates (`_MALDI<N>`) to one row per isolate at load time via the active `duplicate_strategy`
176
187
  - **Bruker Format Support**: Read Bruker flexAnalysis binary data (fid/1r + acqus) natively via `read_spectrum()` on directories
@@ -179,9 +190,9 @@ pip install -e .[dev]
179
190
  - **Composable Filters**: `SpeciesFilter`, `DrugFilter`, `QualityFilter`, `MetadataFilter` combinable with `&`/`|`/`~` operators
180
191
  - **Spectrum Export**: Save spectra to CSV, TXT, or mzML via `MaldiSpectrum.save()` and `MaldiSet.save_spectra()`
181
192
 
182
- ### Visualization & Tools
183
- - **Exploratory Plots**: PCA, t-SNE, and UMAP scatter plots colored by species, resistance phenotype, or any metadata column
184
- - **Batch Effect Correction**: Multi-site/multi-instrument correction via [`combatlearn`](https://github.com/EttoreRocchi/combatlearn) (`pip install maldiamrkit[batch]`)
193
+ ### Visualisation & tools
194
+ - **Exploratory Plots**: PCA, t-SNE, and UMAP scatter plots coloured by species, resistance phenotype, or any metadata column
195
+ - **Batch Effect Correction**: Not part of this package. Use [`combatlearn`](https://github.com/EttoreRocchi/combatlearn) directly (`pip install maldiamrkit[batch]`) or [MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit)
185
196
  - **CLI**: `maldiamrkit preprocess`, `maldiamrkit quality`, and `maldiamrkit build` for batch processing
186
197
  - **Parallel Processing**: Multi-core support via `n_jobs` parameter
187
198
  - **ML-Ready**: Direct integration with scikit-learn pipelines
@@ -190,9 +201,9 @@ pip install -e .[dev]
190
201
 
191
202
  Full documentation is available at [maldiamrkit.readthedocs.io](https://maldiamrkit.readthedocs.io/).
192
203
 
193
- ## Quick Start
204
+ ## Quick start
194
205
 
195
- ### Load and Preprocess a Single Spectrum
206
+ ### Load and preprocess a single spectrum
196
207
 
197
208
  ```python
198
209
  from maldiamrkit import MaldiSpectrum
@@ -211,7 +222,7 @@ from maldiamrkit.visualization import plot_spectrum
211
222
  plot_spectrum(spec, stage="binned")
212
223
  ```
213
224
 
214
- ### Build a Dataset from Multiple Spectra
225
+ ### Build a dataset from multiple spectra
215
226
 
216
227
  ```python
217
228
  from maldiamrkit import MaldiSet
@@ -229,7 +240,7 @@ X = data.X # Feature matrix
229
240
  y = data.get_y_single("Drug") # Target labels
230
241
  ```
231
242
 
232
- ### Machine Learning Pipeline
243
+ ### Machine learning pipeline
233
244
 
234
245
  ```python
235
246
  from sklearn.pipeline import Pipeline
@@ -241,7 +252,7 @@ from maldiamrkit.detection import MaldiPeakDetector
241
252
 
242
253
  # Create ML pipeline
243
254
  pipe = Pipeline([
244
- ("peaks", MaldiPeakDetector(binary=False, prominence=0.05)),
255
+ ("peaks", MaldiPeakDetector(binary=False, prominence=1e-4)),
245
256
  ("warp", Warping(method="shift")),
246
257
  ("scaler", StandardScaler()),
247
258
  ("clf", RandomForestClassifier(n_estimators=100, random_state=42))
@@ -260,32 +271,32 @@ For more examples covering alignment, filtering, evaluation, CLI usage, and more
260
271
 
261
272
  For more detailed examples, see the notebooks:
262
273
 
263
- - [Quick Start](notebooks/01_quick_start.ipynb) - Loading, preprocessing, binning, and quality assessment
264
- - [Peak Detection](notebooks/02_peak_detection.ipynb) - Local maxima and persistent homology methods
265
- - [Alignment](notebooks/03_alignment.ipynb) - Warping methods and alignment quality
266
- - [Evaluation](notebooks/04_evaluation.ipynb) - AMR metrics, label encoding, and stratified splitting
267
- - [Exploration](notebooks/05_exploration.ipynb) - PCA, t-SNE, UMAP visualizations and batch correction
268
- - [Differential Analysis](notebooks/06_differential_analysis.ipynb) - R vs. S peak testing, volcano/Manhattan plots, and multi-drug comparison
269
- - [Drift Monitoring](notebooks/07_drift_monitoring.ipynb) - Baseline-anchored drift detection: reference similarity, PCA trajectory, peak stability, and effect-size drift
270
- - [Susceptibility](notebooks/08_susceptibility.ipynb) - `MICEncoder` + `BreakpointTable` for log2(MIC) regression targets, S/I/R categorisation with ATU, and `mic_regression_report` evaluation
271
- - [Peak Sets](notebooks/09_peak_sets.ipynb) - `PeakSet` / `PeakList` extraction, ranking and padding, caching, and fit-free peak alignment
272
- - [Custom Components](notebooks/10_custom_components.ipynb) - registering a custom distance metric and a custom transformer end-to-end
274
+ - [Quick Start](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/01_quick_start.ipynb) - Loading, preprocessing, binning, and quality assessment
275
+ - [Peak Detection](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/02_peak_detection.ipynb) - Local maxima and persistent homology methods
276
+ - [Alignment](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/03_alignment.ipynb) - Warping methods and alignment quality
277
+ - [Evaluation](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/04_evaluation.ipynb) - AMR metrics, label encoding, and stratified splitting
278
+ - [Exploration](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/05_exploration.ipynb) - PCA, t-SNE, and UMAP visualisations, spectral similarity, and clustering
279
+ - [Differential Analysis](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/06_differential_analysis.ipynb) - R vs. S peak testing, volcano/Manhattan plots, and multi-drug comparison
280
+ - [Drift Monitoring](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/07_drift_monitoring.ipynb) - Baseline-anchored drift detection: reference similarity, PCA trajectory, peak stability, and effect-size drift
281
+ - [Susceptibility](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/08_susceptibility.ipynb) - `MICEncoder` + `BreakpointTable` for log2(MIC) regression targets, S/I/R categorisation with ATU, and `mic_regression_report` evaluation
282
+ - [Peak Sets](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/09_peak_sets.ipynb) - `PeakSet` / `PeakList` extraction, ranking and padding, caching, and fit-free peak alignment
283
+ - [Custom Components](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/10_custom_components.ipynb) - registering a custom distance metric and a custom transformer end-to-end
273
284
 
274
- 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.
285
+ Notebooks `01`-`03` and `08`-`10` run on the small example dataset bundled under [`data/`](https://github.com/EttoreRocchi/MaldiAMRKit/tree/main/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`](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/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.
275
286
 
276
- ## MaldiSuite Ecosystem
287
+ ## MaldiSuite ecosystem
277
288
 
278
- MaldiAMRKit is the data-model and preprocessing package of the **MaldiSuite** ecosystem:
289
+ MaldiAMRKit is one of the three packages of the **MaldiSuite** ecosystem:
279
290
 
280
291
  - **MaldiAMRKit** (this package) - data model (`MaldiSpectrum`, `MaldiSet`), preprocessing, alignment, peak detection, differential analysis, and AMR-aware evaluation.
281
292
  - **[MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit)** - batch-effect correction and harmonisation for multi-centre / multi-instrument MALDI-TOF spectra.
282
293
  - **[MaldiDeepKit](https://github.com/EttoreRocchi/MaldiDeepKit)** - sklearn-compatible deep learning classifiers (MLP, CNN, ResNet, Transformer).
283
294
 
284
- 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/>).
295
+ 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/>).
285
296
 
286
297
  ## Contributing
287
298
 
288
- Pull requests, bug reports, and feature ideas are welcome. See the [Contributing Guide](CONTRIBUTING.md) for how to get started.
299
+ Pull requests, bug reports, and feature ideas are welcome. See the [Contributing Guide](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/CONTRIBUTING.md) for how to get started.
289
300
 
290
301
  ## Citing
291
302
 
@@ -297,7 +308,7 @@ See the [full publications list](https://maldiamrkit.readthedocs.io/en/latest/pa
297
308
 
298
309
  ## License
299
310
 
300
- This project is licensed under the **MIT License**. See the [LICENSE](LICENSE) file for details.
311
+ This project is licensed under the **MIT License**. See the [LICENSE](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/LICENSE) file for details.
301
312
 
302
313
  ## Acknowledgements
303
314
 
@@ -9,13 +9,20 @@
9
9
  [![License](https://img.shields.io/github/license/EttoreRocchi/MaldiAMRKit)](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/LICENSE)
10
10
 
11
11
  <p align="center">
12
- <img src="docs/maldiamrkit.png" alt="MaldiAMRKit" width="320"/>
12
+ <picture>
13
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/EttoreRocchi/MaldiAMRKit/main/docs/maldiamrkit_dark.png">
14
+ <img src="https://raw.githubusercontent.com/EttoreRocchi/MaldiAMRKit/main/docs/maldiamrkit.png" alt="MaldiAMRKit" width="320"/>
15
+ </picture>
13
16
  </p>
14
17
 
15
18
  <p align="center">
16
19
  <strong>A comprehensive toolkit for MALDI-TOF mass spectrometry data preprocessing for antimicrobial resistance (AMR) prediction purposes</strong>
17
20
  </p>
18
21
 
22
+ <p align="center">
23
+ <img src="https://raw.githubusercontent.com/EttoreRocchi/MaldiAMRKit/main/docs/preprocessing_pipeline.svg" alt="Animated MaldiAMRKit pipeline: a raw MALDI-TOF spectrum is smoothed, baseline-corrected, peak-detected and binned into a feature vector that predicts antimicrobial resistance (R/S)" width="720"/>
24
+ </p>
25
+
19
26
  <p align="center">
20
27
  <a href="#installation">Installation</a> •
21
28
  <a href="#features">Features</a> •
@@ -44,13 +51,13 @@ pip install maldisuite
44
51
 
45
52
  Visit the **MaldiSuite** landing page at <https://ettorerocchi.github.io/MaldiSuite/>.
46
53
 
47
- ### Optional: Batch Correction & UMAP
54
+ ### Optional: UMAP & combatlearn
48
55
 
49
56
  ```bash
50
57
  pip install maldiamrkit[batch]
51
58
  ```
52
59
 
53
- Installs [`combatlearn`](https://github.com/EttoreRocchi/combatlearn) for ComBat-based batch effect correction and `umap-learn` for UMAP exploratory plots.
60
+ MaldiAMRKit has no batch corrector of its own. This extra adds `umap-learn` for UMAP exploratory plots, and [`combatlearn`](https://github.com/EttoreRocchi/combatlearn) to use ComBat directly on a feature matrix. For batch correction built for MALDI-TOF spectra, see [MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit).
54
61
 
55
62
  ### Optional: extended mzML/mzXML support
56
63
 
@@ -60,7 +67,7 @@ pip install maldiamrkit[formats]
60
67
 
61
68
  `.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
69
 
63
- ### Development Installation
70
+ ### Development installation
64
71
 
65
72
  ```bash
66
73
  git clone https://github.com/EttoreRocchi/MaldiAMRKit.git
@@ -71,15 +78,15 @@ pip install -e .[dev]
71
78
  ## Features
72
79
 
73
80
  ### Preprocessing
74
- - **Composable Pipeline**: Build custom `PreprocessingPipeline` from individual transformers (smoothing, baseline correction, normalization, trimming), serializable to JSON/YAML
81
+ - **Composable Pipeline**: Build custom `PreprocessingPipeline` from individual transformers (smoothing, baseline correction, normalisation, trimming), serialisable to JSON/YAML
75
82
  - **Smoothing**: Savitzky-Golay and moving-average filters
76
83
  - **Baseline Correction**: SNIP, morphological top-hat, lower-convex-hull, and iterative rolling-median baselines
77
84
  - **Multiple Binning Strategies**: Uniform, proportional, adaptive, and custom bin edges
78
85
  - **Quality Metrics**: SNR estimation, MAD-based noise estimation, comprehensive quality reports, and alignment assessment
79
86
  - **Replicate Merging**: Mean/median/weighted merging with correlation-based outlier detection
80
87
 
81
- ### Alignment & Detection
82
- - **Spectral Alignment**: Shift, linear, piecewise, DTW, quadratic, cubic, and LOWESS warping for both binned and raw full-resolution spectra. Spectra are first shifted and then aligned to the reference of the shifted spectra, a non-rigid warp is kept only when the matched peaks support it, and resampling preserves the total intensity; spectra of several species are best aligned one species at a time
88
+ ### Alignment & detection
89
+ - **Spectral Alignment**: Shift, linear, piecewise, DTW, quadratic, cubic, and LOWESS warping for both binned and raw full-resolution spectra. Spectra are first shifted and then aligned to the reference of the shifted spectra, a non-rigid warp is kept only when the matched peaks support it, and resampling preserves the total intensity (neither applies to DTW); spectra of several species are best aligned one species at a time
83
90
  - **Peak Detection**: Local maxima and persistent homology methods
84
91
  - **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
92
  - **Fit-Free Peak Alignment**: `align_peaks()` warps a peak set onto caller-supplied reference peaks, which the caller estimates on the training split (for example `RawWarping(...).fit(X_train).ref_peaks_mz_`; a reference built with test spectra leaks)
@@ -96,19 +103,23 @@ pip install -e .[dev]
96
103
 
97
104
  ### Susceptibility (MIC encoding & breakpoints)
98
105
  - **`MICEncoder`**: Convert raw MIC strings into `log2(MIC)` regression targets plus S/I/R categories and ATU flags in a single pass
99
- - **`BreakpointTable`**: Clinical breakpoint tables (EUCAST v1.0-v16.0 bundled) loaded by version, year, latest, or custom YAML
106
+ - **`BreakpointTable`**: Clinical breakpoint tables (19 EUCAST versions between v1.0 and v16.0 bundled) loaded by version, year, latest, or custom YAML
100
107
  - **`LabelEncoder`**: Map R/I/S to binary with configurable intermediate handling (moved from `maldiamrkit.evaluation` in v0.15)
101
108
 
102
- ### Differential Analysis
109
+ ### Differential analysis
103
110
  - **`DifferentialAnalysis`**: Per-bin statistical testing (Mann-Whitney U, Welch's t-test) between resistant and susceptible groups, with multiple-testing correction, log2 fold change, and Cohen's d effect size
104
111
  - **Peak Ranking**: `top_peaks()` by adjusted p-value, `significant_peaks()` with fold-change and p-value thresholds, `compare_drugs()` for multi-drug boolean significance matrices (to select features for a classifier, rank peaks inside each training fold)
105
112
  - **AMR-Aware Plots**: `plot_volcano()`, `plot_manhattan()` along the m/z axis, and `plot_drug_comparison()` with binary heatmap or UpSet-style intersection view
106
113
 
107
- ### Drift Monitoring
114
+ ### Drift monitoring
108
115
  - **`DriftMonitor`**: Anchor a baseline on early timestamps (default: first 20%) and track temporal drift via three complementary views - reference similarity of per-window median spectra, PCA centroid trajectory in a baseline-fitted PCA space, and Jaccard stability of top-k differential peaks over time
109
116
  - **Trajectory Plots**: `plot_reference_drift`, `plot_pca_drift`, `plot_peak_stability`, `plot_effect_size_drift`
110
117
 
111
- ### Data Management
118
+ ### Spectral similarity
119
+ - **Distances & Clustering**: `spectral_distance` and `pairwise_distances` with built-in or registered metrics, `cluster_spectra` with hierarchical, HDBSCAN, and k-medoids methods, silhouette scores, and metadata concordance
120
+ - **Plots**: `plot_distance_heatmap` and `plot_dendrogram`
121
+
122
+ ### Data management
112
123
  - **Dataset Building & Loading**: `DatasetBuilder` and `DatasetLoader` with pluggable layout adapters (`FlatLayout`, `BrukerTreeLayout`, `DRIAMSLayout`, `MARISMaLayout`)
113
124
  - **Replicate Collapsing**: `DRIAMSLayout(collapse_replicates=True)` merges technical replicates (`_MALDI<N>`) to one row per isolate at load time via the active `duplicate_strategy`
114
125
  - **Bruker Format Support**: Read Bruker flexAnalysis binary data (fid/1r + acqus) natively via `read_spectrum()` on directories
@@ -117,9 +128,9 @@ pip install -e .[dev]
117
128
  - **Composable Filters**: `SpeciesFilter`, `DrugFilter`, `QualityFilter`, `MetadataFilter` combinable with `&`/`|`/`~` operators
118
129
  - **Spectrum Export**: Save spectra to CSV, TXT, or mzML via `MaldiSpectrum.save()` and `MaldiSet.save_spectra()`
119
130
 
120
- ### Visualization & Tools
121
- - **Exploratory Plots**: PCA, t-SNE, and UMAP scatter plots colored by species, resistance phenotype, or any metadata column
122
- - **Batch Effect Correction**: Multi-site/multi-instrument correction via [`combatlearn`](https://github.com/EttoreRocchi/combatlearn) (`pip install maldiamrkit[batch]`)
131
+ ### Visualisation & tools
132
+ - **Exploratory Plots**: PCA, t-SNE, and UMAP scatter plots coloured by species, resistance phenotype, or any metadata column
133
+ - **Batch Effect Correction**: Not part of this package. Use [`combatlearn`](https://github.com/EttoreRocchi/combatlearn) directly (`pip install maldiamrkit[batch]`) or [MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit)
123
134
  - **CLI**: `maldiamrkit preprocess`, `maldiamrkit quality`, and `maldiamrkit build` for batch processing
124
135
  - **Parallel Processing**: Multi-core support via `n_jobs` parameter
125
136
  - **ML-Ready**: Direct integration with scikit-learn pipelines
@@ -128,9 +139,9 @@ pip install -e .[dev]
128
139
 
129
140
  Full documentation is available at [maldiamrkit.readthedocs.io](https://maldiamrkit.readthedocs.io/).
130
141
 
131
- ## Quick Start
142
+ ## Quick start
132
143
 
133
- ### Load and Preprocess a Single Spectrum
144
+ ### Load and preprocess a single spectrum
134
145
 
135
146
  ```python
136
147
  from maldiamrkit import MaldiSpectrum
@@ -149,7 +160,7 @@ from maldiamrkit.visualization import plot_spectrum
149
160
  plot_spectrum(spec, stage="binned")
150
161
  ```
151
162
 
152
- ### Build a Dataset from Multiple Spectra
163
+ ### Build a dataset from multiple spectra
153
164
 
154
165
  ```python
155
166
  from maldiamrkit import MaldiSet
@@ -167,7 +178,7 @@ X = data.X # Feature matrix
167
178
  y = data.get_y_single("Drug") # Target labels
168
179
  ```
169
180
 
170
- ### Machine Learning Pipeline
181
+ ### Machine learning pipeline
171
182
 
172
183
  ```python
173
184
  from sklearn.pipeline import Pipeline
@@ -179,7 +190,7 @@ from maldiamrkit.detection import MaldiPeakDetector
179
190
 
180
191
  # Create ML pipeline
181
192
  pipe = Pipeline([
182
- ("peaks", MaldiPeakDetector(binary=False, prominence=0.05)),
193
+ ("peaks", MaldiPeakDetector(binary=False, prominence=1e-4)),
183
194
  ("warp", Warping(method="shift")),
184
195
  ("scaler", StandardScaler()),
185
196
  ("clf", RandomForestClassifier(n_estimators=100, random_state=42))
@@ -198,32 +209,32 @@ For more examples covering alignment, filtering, evaluation, CLI usage, and more
198
209
 
199
210
  For more detailed examples, see the notebooks:
200
211
 
201
- - [Quick Start](notebooks/01_quick_start.ipynb) - Loading, preprocessing, binning, and quality assessment
202
- - [Peak Detection](notebooks/02_peak_detection.ipynb) - Local maxima and persistent homology methods
203
- - [Alignment](notebooks/03_alignment.ipynb) - Warping methods and alignment quality
204
- - [Evaluation](notebooks/04_evaluation.ipynb) - AMR metrics, label encoding, and stratified splitting
205
- - [Exploration](notebooks/05_exploration.ipynb) - PCA, t-SNE, UMAP visualizations and batch correction
206
- - [Differential Analysis](notebooks/06_differential_analysis.ipynb) - R vs. S peak testing, volcano/Manhattan plots, and multi-drug comparison
207
- - [Drift Monitoring](notebooks/07_drift_monitoring.ipynb) - Baseline-anchored drift detection: reference similarity, PCA trajectory, peak stability, and effect-size drift
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
212
+ - [Quick Start](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/01_quick_start.ipynb) - Loading, preprocessing, binning, and quality assessment
213
+ - [Peak Detection](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/02_peak_detection.ipynb) - Local maxima and persistent homology methods
214
+ - [Alignment](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/03_alignment.ipynb) - Warping methods and alignment quality
215
+ - [Evaluation](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/04_evaluation.ipynb) - AMR metrics, label encoding, and stratified splitting
216
+ - [Exploration](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/05_exploration.ipynb) - PCA, t-SNE, and UMAP visualisations, spectral similarity, and clustering
217
+ - [Differential Analysis](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/06_differential_analysis.ipynb) - R vs. S peak testing, volcano/Manhattan plots, and multi-drug comparison
218
+ - [Drift Monitoring](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/07_drift_monitoring.ipynb) - Baseline-anchored drift detection: reference similarity, PCA trajectory, peak stability, and effect-size drift
219
+ - [Susceptibility](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/08_susceptibility.ipynb) - `MICEncoder` + `BreakpointTable` for log2(MIC) regression targets, S/I/R categorisation with ATU, and `mic_regression_report` evaluation
220
+ - [Peak Sets](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/09_peak_sets.ipynb) - `PeakSet` / `PeakList` extraction, ranking and padding, caching, and fit-free peak alignment
221
+ - [Custom Components](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/notebooks/10_custom_components.ipynb) - registering a custom distance metric and a custom transformer end-to-end
211
222
 
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.
223
+ Notebooks `01`-`03` and `08`-`10` run on the small example dataset bundled under [`data/`](https://github.com/EttoreRocchi/MaldiAMRKit/tree/main/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`](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/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.
213
224
 
214
- ## MaldiSuite Ecosystem
225
+ ## MaldiSuite ecosystem
215
226
 
216
- MaldiAMRKit is the data-model and preprocessing package of the **MaldiSuite** ecosystem:
227
+ MaldiAMRKit is one of the three packages of the **MaldiSuite** ecosystem:
217
228
 
218
229
  - **MaldiAMRKit** (this package) - data model (`MaldiSpectrum`, `MaldiSet`), preprocessing, alignment, peak detection, differential analysis, and AMR-aware evaluation.
219
230
  - **[MaldiBatchKit](https://github.com/EttoreRocchi/MaldiBatchKit)** - batch-effect correction and harmonisation for multi-centre / multi-instrument MALDI-TOF spectra.
220
231
  - **[MaldiDeepKit](https://github.com/EttoreRocchi/MaldiDeepKit)** - sklearn-compatible deep learning classifiers (MLP, CNN, ResNet, Transformer).
221
232
 
222
- 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/>).
233
+ 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/>).
223
234
 
224
235
  ## Contributing
225
236
 
226
- Pull requests, bug reports, and feature ideas are welcome. See the [Contributing Guide](CONTRIBUTING.md) for how to get started.
237
+ Pull requests, bug reports, and feature ideas are welcome. See the [Contributing Guide](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/CONTRIBUTING.md) for how to get started.
227
238
 
228
239
  ## Citing
229
240
 
@@ -235,7 +246,7 @@ See the [full publications list](https://maldiamrkit.readthedocs.io/en/latest/pa
235
246
 
236
247
  ## License
237
248
 
238
- This project is licensed under the **MIT License**. See the [LICENSE](LICENSE) file for details.
249
+ This project is licensed under the **MIT License**. See the [LICENSE](https://github.com/EttoreRocchi/MaldiAMRKit/blob/main/LICENSE) file for details.
239
250
 
240
251
  ## Acknowledgements
241
252
 
@@ -27,7 +27,7 @@ Examples
27
27
  from .dataset import MaldiSet
28
28
  from .spectrum import MaldiSpectrum
29
29
 
30
- __version__ = "0.22.1"
30
+ __version__ = "0.22.2"
31
31
  __author__ = "Ettore Rocchi"
32
32
 
33
33
  __all__ = [
@@ -95,7 +95,7 @@ def apply_metadata_strategy(
95
95
  return df.drop_duplicates(subset=id_col, keep=False)
96
96
 
97
97
  if strategy is DuplicateStrategy.keep_all:
98
- isolates = df.get("_isolate", pd.Series(np.nan, index=df.index))
98
+ isolates = df.get("_isolate", pd.Series(np.nan, index=df.index, dtype=object))
99
99
  df = df.assign(_isolate=isolates.fillna(df[id_col]))
100
100
  return _suffix_duplicates(df, id_col, suffix_col)
101
101
 
@@ -316,6 +316,15 @@ class BrukerTreeLayout(InputLayout):
316
316
  for empty and duplicate spectra.
317
317
  """
318
318
  meta = self._read_raw_metadata()
319
+ missing = [
320
+ column
321
+ for column in (self.path_column, self.year_column)
322
+ if column not in meta.columns
323
+ ]
324
+ if missing:
325
+ raise ValueError(
326
+ f"Metadata columns {missing} not found. Available: {list(meta.columns)}"
327
+ )
319
328
  meta = apply_metadata_strategy(
320
329
  meta,
321
330
  self.duplicate_strategy,
@@ -14,6 +14,11 @@ import pandas as pd
14
14
 
15
15
  logger = logging.getLogger(__name__)
16
16
 
17
+ # Before pandas 3.1, float_precision="round_trip" is needed to parse floats
18
+ # exactly; pandas 3.1 parses them exactly by default and deprecates the argument.
19
+ _PANDAS_VERSION = tuple(int(part) for part in pd.__version__.split(".")[:2])
20
+ _EXACT_FLOATS = {"float_precision": "round_trip"} if _PANDAS_VERSION < (3, 1) else {}
21
+
17
22
 
18
23
  def sniff_delimiter(path: str | Path, sample_lines: int = 10) -> str:
19
24
  """
@@ -579,7 +584,7 @@ def read_spectrum(
579
584
  comment="#",
580
585
  header=None,
581
586
  names=["mass", "intensity"],
582
- float_precision="round_trip",
587
+ **_EXACT_FLOATS,
583
588
  )
584
589
 
585
590
  df = _coerce_numeric(df)
@@ -592,7 +597,7 @@ def read_spectrum(
592
597
  comment="#",
593
598
  header=None,
594
599
  names=["mass", "intensity"],
595
- float_precision="round_trip",
600
+ **_EXACT_FLOATS,
596
601
  )
597
602
  df = _coerce_numeric(df)
598
603
 
@@ -166,16 +166,23 @@ class MICEncoder(BaseEstimator, TransformerMixin):
166
166
  values = values.astype(float)
167
167
  bound = np.where(qualifiers == ">", np.nextafter(values, np.inf), values)
168
168
  batch = self.breakpoints.apply_batch(species_arr, drug_arr, bound)
169
- category = batch["category"].to_numpy(dtype=object)
169
+ # A copy: with pandas 3 copy-on-write, to_numpy returns a read-only view.
170
+ category = np.array(batch["category"].to_numpy(dtype=object), copy=True)
170
171
  undecided = (upper & (category != "S")) | (lower & (category != "R"))
171
172
  category[undecided] = pd.NA
172
173
  atu = batch["atu"].to_numpy(dtype=bool) & ~(upper | lower)
173
- out["category"] = pd.array(
174
- [pd.NA if pd.isna(c) else c for c in category], dtype="object"
174
+ # Object Series keep pd.NA for missing values; pandas 3 would store the
175
+ # strings of a plain array with its "str" dtype and NaN instead.
176
+ out["category"] = pd.Series(
177
+ [pd.NA if pd.isna(c) else c for c in category],
178
+ index=out.index,
179
+ dtype="object",
175
180
  )
176
181
  out["atu"] = pd.array(atu.tolist(), dtype="boolean")
177
- out["source"] = pd.array(
178
- [pd.NA if pd.isna(s) else s for s in batch["source"]], dtype="object"
182
+ out["source"] = pd.Series(
183
+ [pd.NA if pd.isna(s) else s for s in batch["source"]],
184
+ index=out.index,
185
+ dtype="object",
179
186
  )
180
187
  return out
181
188
 
File without changes
File without changes