Skip to content

Commit 77f199b

Browse files
Merge pull request #21 from OpenMS/copilot/add-ion-mobility-support
Add ion mobility support via float data arrays and mobilogram wrapper
2 parents 3a8f885 + da88471 commit 77f199b

File tree

6 files changed

+940
-87
lines changed

6 files changed

+940
-87
lines changed

README.md

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,79 @@ peaks_df = spec.to_dataframe()
299299
print(peaks_df.head())
300300
```
301301

302+
### Ion Mobility Support
303+
304+
`openms-python` provides comprehensive support for ion mobility data through float data arrays and mobilograms.
305+
306+
#### Float Data Arrays
307+
308+
Spectra can have additional data arrays (e.g., ion mobility values) associated with each peak:
309+
310+
```python
311+
from openms_python import Py_MSSpectrum
312+
import pandas as pd
313+
import numpy as np
314+
315+
# Create a spectrum with ion mobility data
316+
df = pd.DataFrame({
317+
'mz': [100.0, 200.0, 300.0],
318+
'intensity': [50.0, 100.0, 75.0],
319+
'ion_mobility': [1.5, 2.3, 3.1]
320+
})
321+
322+
spec = Py_MSSpectrum.from_dataframe(df, retention_time=60.5, ms_level=1)
323+
324+
# Access ion mobility values
325+
print(spec.ion_mobility) # array([1.5, 2.3, 3.1])
326+
327+
# Set ion mobility values
328+
spec.ion_mobility = np.array([1.6, 2.4, 3.2])
329+
330+
# Convert to DataFrame with float arrays
331+
df = spec.to_dataframe(include_float_arrays=True)
332+
print(df)
333+
# mz intensity ion_mobility
334+
# 0 100.0 50.0 1.6
335+
# 1 200.0 100.0 2.4
336+
# 2 300.0 75.0 3.2
337+
```
338+
339+
#### Mobilograms
340+
341+
Mobilograms represent the ion mobility dimension, showing intensity vs. drift time for a specific m/z.
342+
343+
**Note:** OpenMS C++ has a native `Mobilogram` class that may not yet be wrapped in pyopenms. This wrapper uses `MSChromatogram` as the underlying representation for mobilogram data.
344+
345+
```python
346+
from openms_python import Py_Mobilogram
347+
import numpy as np
348+
349+
# Create a mobilogram from arrays
350+
drift_times = np.array([1.0, 1.5, 2.0, 2.5, 3.0])
351+
intensities = np.array([100.0, 150.0, 200.0, 180.0, 120.0])
352+
353+
mob = Py_Mobilogram.from_arrays(drift_times, intensities, mz=500.0)
354+
355+
print(f"m/z: {mob.mz}")
356+
print(f"Points: {len(mob)}")
357+
print(f"Base peak drift time: {mob.base_peak_drift_time}")
358+
359+
# Convert to DataFrame
360+
df = mob.to_dataframe()
361+
print(df.head())
362+
# drift_time intensity mz
363+
# 0 1.0 100.0 500.0
364+
# 1 1.5 150.0 500.0
365+
# 2 2.0 200.0 500.0
366+
367+
# Create from DataFrame
368+
df = pd.DataFrame({
369+
'drift_time': [1.0, 2.0, 3.0],
370+
'intensity': [50.0, 100.0, 75.0]
371+
})
372+
mob = Py_Mobilogram.from_dataframe(df, mz=600.0)
373+
```
374+
302375
## Workflow helpers
303376

304377
`openms_python` now exposes opinionated utilities that combine the primitive
@@ -696,16 +769,34 @@ plt.show()
696769
- `base_peak_mz`: m/z of most intense peak
697770
- `base_peak_intensity`: Intensity of base peak
698771
- `peaks`: Tuple of (mz_array, intensity_array)
772+
- `float_data_arrays`: List of FloatDataArray objects
773+
- `ion_mobility`: Ion mobility values as NumPy array
774+
- `drift_time`: Spectrum-level drift time value
699775

700776
**Methods:**
701777
- `from_dataframe(df, **metadata)`: Create from DataFrame (class method)
702-
- `to_dataframe()`: Convert to DataFrame
778+
- `to_dataframe(include_float_arrays=True)`: Convert to DataFrame
703779
- `filter_by_mz(min_mz, max_mz)`: Filter peaks by m/z
704780
- `filter_by_intensity(min_intensity)`: Filter peaks by intensity
705781
- `top_n_peaks(n)`: Keep top N peaks
706782
- `normalize_intensity(max_value)`: Normalize intensities
707783

708-
- `normalize_intensity(max_value)`: Normalize intensities
784+
### Py_Mobilogram
785+
786+
**Properties:**
787+
- `name`: Name of the mobilogram
788+
- `mz`: m/z value this mobilogram represents
789+
- `drift_time`: Drift time values as NumPy array
790+
- `intensity`: Intensity values as NumPy array
791+
- `peaks`: Tuple of (drift_time_array, intensity_array)
792+
- `total_ion_current`: Sum of intensities
793+
- `base_peak_drift_time`: Drift time of most intense point
794+
- `base_peak_intensity`: Intensity of base peak
795+
796+
**Methods:**
797+
- `from_arrays(drift_time, intensity, mz=None, name=None)`: Create from arrays (class method)
798+
- `from_dataframe(df, **metadata)`: Create from DataFrame (class method)
799+
- `to_dataframe()`: Convert to DataFrame
709800

710801
### Identifications, ProteinIdentifications & PeptideIdentifications
711802

openms_python/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
from .py_msexperiment import Py_MSExperiment
2525
from .py_msspectrum import Py_MSSpectrum
26+
from .py_mobilogram import Py_Mobilogram
2627
from .py_feature import Py_Feature
2728
from .py_featuremap import Py_FeatureMap
2829
from .py_consensusmap import Py_ConsensusMap
@@ -99,6 +100,7 @@ def get_example(name: str, *, load: bool = False, target_dir: Union[str, Path, N
99100
__all__ = [
100101
"Py_MSExperiment",
101102
"Py_MSSpectrum",
103+
"Py_Mobilogram",
102104
"Py_Feature",
103105
"Py_FeatureMap",
104106
"Py_ConsensusMap",

0 commit comments

Comments
 (0)