imspy-core 0.4.0__py3-none-any.whl
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.
- imspy_core/__init__.py +75 -0
- imspy_core/chemistry/__init__.py +37 -0
- imspy_core/chemistry/amino_acids.py +7 -0
- imspy_core/chemistry/constants.py +12 -0
- imspy_core/chemistry/elements.py +6 -0
- imspy_core/chemistry/mobility.py +82 -0
- imspy_core/chemistry/sum_formula.py +38 -0
- imspy_core/chemistry/unimod.py +5 -0
- imspy_core/chemistry/utility.py +43 -0
- imspy_core/core/__init__.py +9 -0
- imspy_core/core/base.py +38 -0
- imspy_core/data/__init__.py +17 -0
- imspy_core/data/peptide.py +528 -0
- imspy_core/data/spectrum.py +586 -0
- imspy_core/timstof/__init__.py +25 -0
- imspy_core/timstof/collision.py +31 -0
- imspy_core/timstof/data.py +429 -0
- imspy_core/timstof/dda.py +364 -0
- imspy_core/timstof/dia.py +131 -0
- imspy_core/timstof/frame.py +604 -0
- imspy_core/timstof/quadrupole.py +189 -0
- imspy_core/timstof/slice.py +506 -0
- imspy_core/utility/__init__.py +21 -0
- imspy_core/utility/sequence.py +38 -0
- imspy_core/utility/utilities.py +278 -0
- imspy_core-0.4.0.dist-info/METADATA +70 -0
- imspy_core-0.4.0.dist-info/RECORD +28 -0
- imspy_core-0.4.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,586 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import json
|
|
3
|
+
import numpy as np
|
|
4
|
+
from typing import List, Tuple, Callable
|
|
5
|
+
import pandas as pd
|
|
6
|
+
from numpy.typing import NDArray
|
|
7
|
+
from scipy.signal import find_peaks
|
|
8
|
+
import imspy_connector
|
|
9
|
+
|
|
10
|
+
from imspy_core.core.base import RustWrapperObject
|
|
11
|
+
|
|
12
|
+
ims = imspy_connector.py_spectrum
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_peak_integral(peaks: NDArray[np.int32], peak_info: dict) -> NDArray[np.float64]:
|
|
16
|
+
"""Calculates the integral of the peaks in a spectrum.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
peaks (NDArray[np.int32]): Peak indices.
|
|
20
|
+
peak_info (dict): Peak info.
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
NDArray[np.float64]: Peak integrals.
|
|
24
|
+
"""
|
|
25
|
+
integrals = np.zeros(len(peaks), dtype=np.float64)
|
|
26
|
+
FWHM = peak_info['widths']
|
|
27
|
+
h = peak_info['prominences']
|
|
28
|
+
integrals = np.sqrt(2*np.pi) * h * FWHM / (2*np.sqrt(2*np.log(2)))
|
|
29
|
+
return integrals
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class IndexedMzSpectrum(RustWrapperObject):
|
|
33
|
+
def __init__(self, index: NDArray[np.int32], mz: NDArray[np.float64], intensity: NDArray[np.float64]):
|
|
34
|
+
"""IndexedMzSpectrum class.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
index (NDArray[np.int32]): Index.
|
|
38
|
+
mz (NDArray[np.float64]): m/z.
|
|
39
|
+
intensity (NDArray[np.float64]): Intensity.
|
|
40
|
+
|
|
41
|
+
Raises:
|
|
42
|
+
AssertionError: If the length of the index, mz and intensity arrays are not equal.
|
|
43
|
+
"""
|
|
44
|
+
assert len(index) == len(mz) == len(intensity), ("The length of the index, mz and intensity arrays must be "
|
|
45
|
+
"equal.")
|
|
46
|
+
self.__spec_ptr = ims.PyIndexedMzSpectrum(index, mz, intensity)
|
|
47
|
+
|
|
48
|
+
@classmethod
|
|
49
|
+
def from_py_ptr(cls, spec: ims.PyIndexedMzSpectrum):
|
|
50
|
+
"""Create a IndexedMzSpectrum from a PyIndexedMzSpectrum.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
spec (pims.PyIndexedMzSpectrum): PyIndexedMzSpectrum to create the IndexedMzSpectrum from.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
IndexedMzSpectrum: IndexedMzSpectrum created from the PyIndexedMzSpectrum.
|
|
57
|
+
"""
|
|
58
|
+
instance = cls.__new__(cls)
|
|
59
|
+
instance.__spec_ptr = spec
|
|
60
|
+
return instance
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def index(self) -> NDArray[np.int32]:
|
|
64
|
+
"""Index.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
NDArray[np.int32]: Index.
|
|
68
|
+
"""
|
|
69
|
+
return self.__spec_ptr.index
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def mz(self) -> NDArray[np.float64]:
|
|
73
|
+
"""m/z.
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
NDArray[np.float64]: m/z.
|
|
77
|
+
"""
|
|
78
|
+
return self.__spec_ptr.mz
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def intensity(self) -> NDArray[np.float64]:
|
|
82
|
+
"""Intensity.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
NDArray[np.float64]: Intensity.
|
|
86
|
+
"""
|
|
87
|
+
return self.__spec_ptr.intensity
|
|
88
|
+
|
|
89
|
+
def filter(self, mz_min: float = 0.0, mz_max: float = 2000.0, intensity_min: float = 0.0,
|
|
90
|
+
intensity_max: float = 1e9) -> 'IndexedMzSpectrum':
|
|
91
|
+
"""Filter the spectrum for a given m/z range and intensity range.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
mz_min (float): Minimum m/z value.
|
|
95
|
+
mz_max (float): Maximum m/z value.
|
|
96
|
+
intensity_min (float, optional): Minimum intensity value. Defaults to 0.0.
|
|
97
|
+
intensity_max (float, optional): Maximum intensity value. Defaults to 1e9.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
IndexedMzSpectrum: Filtered spectrum.
|
|
101
|
+
"""
|
|
102
|
+
return IndexedMzSpectrum.from_py_ptr(
|
|
103
|
+
self.__spec_ptr.filter_ranged(mz_min, mz_max, intensity_min, intensity_max))
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def df(self) -> pd.DataFrame:
|
|
107
|
+
"""Data.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
pd.DataFrame: Data.
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
return pd.DataFrame({'index': self.index, 'mz': self.mz, 'intensity': self.intensity})
|
|
114
|
+
|
|
115
|
+
def get_py_ptr(self) -> ims.PyIndexedMzSpectrum:
|
|
116
|
+
"""Get the spec_ptr.
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
pims.PyIndexedMzSpectrum: spec_ptr.
|
|
120
|
+
"""
|
|
121
|
+
return self.__spec_ptr
|
|
122
|
+
|
|
123
|
+
def __repr__(self):
|
|
124
|
+
return f"IndexedMzSpectrum(num_peaks={len(self.index)})"
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class MzSpectrum(RustWrapperObject):
|
|
128
|
+
|
|
129
|
+
@classmethod
|
|
130
|
+
def from_jsons(cls, jsons: str) -> MzSpectrum:
|
|
131
|
+
json_dict:dict = json.loads(jsons)
|
|
132
|
+
mz = json_dict["mz"]
|
|
133
|
+
intensity = json_dict["intensity"]
|
|
134
|
+
return cls(np.array(mz, dtype=np.float64), np.array(intensity, dtype=np.float64))
|
|
135
|
+
|
|
136
|
+
@classmethod
|
|
137
|
+
def from_mz_spectra_list(cls, spectra_list:List[MzSpectrum], resolution: int) -> MzSpectrum:
|
|
138
|
+
"""Generates a convoluted mass spectrum by adding all spectra in the given list.
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
spectra_list (List[MzSpectrum]): List of mass spectra.
|
|
142
|
+
resolution (int): Desired resolution of returned spectrum.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
MzSpectrum: Convoluted spectrum.
|
|
146
|
+
"""
|
|
147
|
+
return cls.from_py_ptr(ims.PyMzSpectrum.from_mzspectra_list([spectrum.__spec_ptr for spectrum in spectra_list], resolution))
|
|
148
|
+
|
|
149
|
+
def __init__(self, mz: NDArray[np.float64], intensity: NDArray[np.float64]):
|
|
150
|
+
"""MzSpectrum class.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
mz (NDArray[np.float64]): m/z.
|
|
154
|
+
intensity (NDArray[np.float64]): Intensity.
|
|
155
|
+
|
|
156
|
+
Raises:
|
|
157
|
+
AssertionError: If the length of the mz and intensity arrays are not equal.
|
|
158
|
+
"""
|
|
159
|
+
assert len(mz) == len(intensity), "The length of the mz and intensity arrays must be equal."
|
|
160
|
+
self.__spec_ptr = ims.PyMzSpectrum(mz, intensity)
|
|
161
|
+
|
|
162
|
+
@property
|
|
163
|
+
def mz(self) -> NDArray[np.float64]:
|
|
164
|
+
"""m/z.
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
NDArray[np.float64]: m/z.
|
|
168
|
+
"""
|
|
169
|
+
return self.__spec_ptr.mz
|
|
170
|
+
|
|
171
|
+
@property
|
|
172
|
+
def intensity(self) -> NDArray[np.float64]:
|
|
173
|
+
"""Intensity.
|
|
174
|
+
|
|
175
|
+
Returns:
|
|
176
|
+
NDArray[np.float64]: Intensity.
|
|
177
|
+
"""
|
|
178
|
+
return self.__spec_ptr.intensity
|
|
179
|
+
|
|
180
|
+
@property
|
|
181
|
+
def df(self) -> pd.DataFrame:
|
|
182
|
+
"""Data.
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
pd.DataFrame: Data.
|
|
186
|
+
"""
|
|
187
|
+
|
|
188
|
+
return pd.DataFrame({'mz': self.mz, 'intensity': self.intensity})
|
|
189
|
+
|
|
190
|
+
@classmethod
|
|
191
|
+
def from_py_ptr(cls, spec: ims.PyMzSpectrum):
|
|
192
|
+
"""Create a MzSpectrum from a PyMzSpectrum.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
spec (pims.PyMzSpectrum): PyMzSpectrum to create the MzSpectrum from.
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
MzSpectrum: MzSpectrum created from the PyMzSpectrum.
|
|
199
|
+
"""
|
|
200
|
+
instance = cls.__new__(cls)
|
|
201
|
+
instance.__spec_ptr = spec
|
|
202
|
+
return instance
|
|
203
|
+
|
|
204
|
+
def __repr__(self):
|
|
205
|
+
return f"MzSpectrum(num_peaks={len(self.mz)})"
|
|
206
|
+
|
|
207
|
+
def __add__(self, other: MzSpectrum) -> MzSpectrum:
|
|
208
|
+
"""Overwrite + operator for adding of spectra
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
other (MzSpectrum): Other spectrum.
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
MzSpectrum: Sum of spectra
|
|
215
|
+
"""
|
|
216
|
+
return self.from_py_ptr(self.__spec_ptr + other.__spec_ptr)
|
|
217
|
+
|
|
218
|
+
def __mul__(self, scale) -> MzSpectrum:
|
|
219
|
+
"""Overwrite * operator for scaling of spectrum
|
|
220
|
+
|
|
221
|
+
Args:
|
|
222
|
+
scale (float): Scale.
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
MzSpectrum: Scaled spectrum
|
|
226
|
+
"""
|
|
227
|
+
return self.from_py_ptr(self.__spec_ptr * scale)
|
|
228
|
+
|
|
229
|
+
def to_windows(self, window_length: float = 10, overlapping: bool = True, min_num_peaks: int = 5,
|
|
230
|
+
min_intensity: float = 1) -> Tuple[NDArray, List[MzSpectrum]]:
|
|
231
|
+
"""Convert the spectrum to a list of windows.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
window_length (float, optional): Window length. Defaults to 10.
|
|
235
|
+
overlapping (bool, optional): Whether the windows should overlap. Defaults to True.
|
|
236
|
+
min_num_peaks (int, optional): Minimum number of peaks in a window. Defaults to 5.
|
|
237
|
+
min_intensity (float, optional): Minimum intensity of a peak in a window. Defaults to 1.
|
|
238
|
+
|
|
239
|
+
Returns:
|
|
240
|
+
Tuple[NDArray, List[MzSpectrum]]: List of windows.
|
|
241
|
+
"""
|
|
242
|
+
|
|
243
|
+
indices, windows = self.__spec_ptr.to_windows(window_length, overlapping, min_num_peaks, min_intensity)
|
|
244
|
+
return indices, [MzSpectrum.from_py_ptr(window) for window in windows]
|
|
245
|
+
|
|
246
|
+
def to_resolution(self, resolution: int) -> MzSpectrum:
|
|
247
|
+
"""Bins the spectrum's m/z values to a
|
|
248
|
+
given resolution and sums the intensities.
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
resolution (int): Negative decadic logarithm of bin size.
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
MzSpectrum: A new `MzSpectrum` where m/z values are binned according to the given resolution.
|
|
255
|
+
"""
|
|
256
|
+
return MzSpectrum.from_py_ptr(self.__spec_ptr.to_resolution(resolution))
|
|
257
|
+
|
|
258
|
+
def filter(self, mz_min: float = 0.0, mz_max: float = 2000.0, intensity_min: float = 0.0,
|
|
259
|
+
intensity_max: float = 1e9) -> MzSpectrum:
|
|
260
|
+
"""Filter the spectrum for a given m/z range and intensity range.
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
mz_min (float): Minimum m/z value.
|
|
264
|
+
mz_max (float): Maximum m/z value.
|
|
265
|
+
intensity_min (float, optional): Minimum intensity value. Defaults to 0.0.
|
|
266
|
+
intensity_max (float, optional): Maximum intensity value. Defaults to 1e9.
|
|
267
|
+
|
|
268
|
+
Returns:
|
|
269
|
+
MzSpectrum: Filtered spectrum.
|
|
270
|
+
"""
|
|
271
|
+
return MzSpectrum.from_py_ptr(
|
|
272
|
+
self.__spec_ptr.filter_ranged(mz_min, mz_max, intensity_min, intensity_max))
|
|
273
|
+
|
|
274
|
+
def vectorized(self, resolution: int = 2) -> MzSpectrumVectorized:
|
|
275
|
+
"""Convert the spectrum to a vectorized spectrum.
|
|
276
|
+
|
|
277
|
+
Args:
|
|
278
|
+
resolution (int, optional): Resolution. Defaults to 2.
|
|
279
|
+
|
|
280
|
+
Returns:
|
|
281
|
+
MzSpectrumVectorized: Vectorized spectrum.
|
|
282
|
+
"""
|
|
283
|
+
return MzSpectrumVectorized.from_py_ptr(self.__spec_ptr.vectorized(resolution))
|
|
284
|
+
|
|
285
|
+
def to_jsons(self) -> str:
|
|
286
|
+
"""
|
|
287
|
+
generates json string representation of MzSpectrum
|
|
288
|
+
"""
|
|
289
|
+
json_dict = {}
|
|
290
|
+
json_dict["mz"] = self.mz.tolist()
|
|
291
|
+
json_dict["intensity"] = self.intensity.tolist()
|
|
292
|
+
|
|
293
|
+
return json.dumps(json_dict)
|
|
294
|
+
|
|
295
|
+
def to_centroided(self, baseline_noise_level: int = 0.0, sigma: float = 0.1, normalize: bool = True):
|
|
296
|
+
"""Convert the spectrum to a centroided spectrum.
|
|
297
|
+
|
|
298
|
+
Returns:
|
|
299
|
+
MzSpectrum: Centroided spectrum.
|
|
300
|
+
"""
|
|
301
|
+
# first generate dense spectrum
|
|
302
|
+
return MzSpectrum.from_py_ptr(self.__spec_ptr.to_centroided(baseline_noise_level, sigma, normalize))
|
|
303
|
+
|
|
304
|
+
def add_mz_noise_uniform(self, noise_ppm: float, right_drag: bool = False) -> MzSpectrum:
|
|
305
|
+
"""Add uniform noise to the m/z values of the spectrum.
|
|
306
|
+
|
|
307
|
+
Args:
|
|
308
|
+
noise_ppm (float): Noise ppm, noise will be sampled from a uniform distribution with mean 0 and std noise_ppm.
|
|
309
|
+
right_drag (bool, optional): If true, the noise will be shifted to the right. Defaults to False.
|
|
310
|
+
|
|
311
|
+
Returns:
|
|
312
|
+
MzSpectrum: Spectrum with added noise.
|
|
313
|
+
"""
|
|
314
|
+
return MzSpectrum.from_py_ptr(self.__spec_ptr.add_mz_noise_uniform(noise_ppm, right_drag))
|
|
315
|
+
|
|
316
|
+
def add_mz_noise_normal(self, noise_ppm: float) -> MzSpectrum:
|
|
317
|
+
"""Add normal noise to the intensity values of the spectrum.
|
|
318
|
+
|
|
319
|
+
Args:
|
|
320
|
+
noise_ppm (float): Noise ppm, noise will be sampled from a normal distribution with mean 0 and std noise_ppm / 3.0.
|
|
321
|
+
|
|
322
|
+
Returns:
|
|
323
|
+
MzSpectrum: Spectrum with added noise.
|
|
324
|
+
"""
|
|
325
|
+
return MzSpectrum.from_py_ptr(self.__spec_ptr.add_mz_noise_normal(noise_ppm))
|
|
326
|
+
|
|
327
|
+
def get_py_ptr(self) -> ims.PyMzSpectrum:
|
|
328
|
+
"""Get the spec_ptr.
|
|
329
|
+
|
|
330
|
+
Returns:
|
|
331
|
+
pims.PyMzSpectrum: spec_ptr.
|
|
332
|
+
"""
|
|
333
|
+
return self.__spec_ptr
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
class MzSpectrumVectorized(RustWrapperObject):
|
|
337
|
+
def __init__(self, indices: NDArray[np.int32], values: NDArray[np.float64], resolution: int):
|
|
338
|
+
"""MzSpectrum class.
|
|
339
|
+
|
|
340
|
+
Args:
|
|
341
|
+
mz (NDArray[np.float64]): m/z.
|
|
342
|
+
values (NDArray[np.float64]): Intensity.
|
|
343
|
+
|
|
344
|
+
Raises:
|
|
345
|
+
AssertionError: If the length of the mz and intensity arrays are not equal.
|
|
346
|
+
"""
|
|
347
|
+
assert len(indices) == len(values), "The length of the mz and intensity arrays must be equal."
|
|
348
|
+
self.__spec_ptr = ims.PyMzSpectrumVectorized(indices, values, resolution)
|
|
349
|
+
|
|
350
|
+
@classmethod
|
|
351
|
+
def from_py_ptr(cls, spec: ims.PyMzSpectrumVectorized):
|
|
352
|
+
"""Create a MzSpectrum from a PyMzSpectrum.
|
|
353
|
+
|
|
354
|
+
Args:
|
|
355
|
+
spec (pims.PyMzSpectrum): PyMzSpectrum to create the MzSpectrum from.
|
|
356
|
+
|
|
357
|
+
Returns:
|
|
358
|
+
MzSpectrum: MzSpectrum created from the PyMzSpectrum.
|
|
359
|
+
"""
|
|
360
|
+
instance = cls.__new__(cls)
|
|
361
|
+
instance.__spec_ptr = spec
|
|
362
|
+
return instance
|
|
363
|
+
|
|
364
|
+
@property
|
|
365
|
+
def resolution(self) -> float:
|
|
366
|
+
"""Resolution.
|
|
367
|
+
|
|
368
|
+
Returns:
|
|
369
|
+
float: Resolution.
|
|
370
|
+
"""
|
|
371
|
+
return self.__spec_ptr.resolution
|
|
372
|
+
|
|
373
|
+
@property
|
|
374
|
+
def indices(self) -> NDArray[np.int32]:
|
|
375
|
+
"""m/z.
|
|
376
|
+
|
|
377
|
+
Returns:
|
|
378
|
+
NDArray[np.float64]: m/z.
|
|
379
|
+
"""
|
|
380
|
+
return self.__spec_ptr.indices
|
|
381
|
+
|
|
382
|
+
@property
|
|
383
|
+
def values(self) -> NDArray[np.float64]:
|
|
384
|
+
"""Intensity.
|
|
385
|
+
|
|
386
|
+
Returns:
|
|
387
|
+
NDArray[np.float64]: Intensity.
|
|
388
|
+
"""
|
|
389
|
+
return self.__spec_ptr.values
|
|
390
|
+
|
|
391
|
+
def to_centroided(self, integrate_method: Callable = get_peak_integral) -> MzSpectrum:
|
|
392
|
+
"""Convert the spectrum to a centroided spectrum.
|
|
393
|
+
|
|
394
|
+
Returns:
|
|
395
|
+
MzSpectrum: Centroided spectrum.
|
|
396
|
+
"""
|
|
397
|
+
# first generate dense spectrum
|
|
398
|
+
dense_spectrum = MzSpectrumVectorized.from_py_ptr(self.__spec_ptr.to_dense_spectrum(None))
|
|
399
|
+
# find peaks in the dense spectrum and widths with scipy
|
|
400
|
+
peaks, peak_info = find_peaks(dense_spectrum.values, height=0, width=(0, 0.5))
|
|
401
|
+
# then get the peak integrals
|
|
402
|
+
integrals = integrate_method(peaks, peak_info)
|
|
403
|
+
# then create a new spectrum with the peak indices and the integrals
|
|
404
|
+
return MzSpectrum.from_py_ptr(ims.PyMzSpectrum(dense_spectrum.indices[peaks] / np.power(10, dense_spectrum.resolution), integrals))
|
|
405
|
+
|
|
406
|
+
def __repr__(self):
|
|
407
|
+
return f"MzSpectrumVectorized(num_values={len(self.values)})"
|
|
408
|
+
|
|
409
|
+
def get_py_ptr(self) -> ims.PyMzSpectrumVectorized:
|
|
410
|
+
"""Get the spec_ptr.
|
|
411
|
+
|
|
412
|
+
Returns:
|
|
413
|
+
pims.PyMzSpectrumVectorized: spec_ptr.
|
|
414
|
+
"""
|
|
415
|
+
return self.__spec_ptr
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
class TimsSpectrum(RustWrapperObject):
|
|
419
|
+
def __init__(self, frame_id: int, scan: int, retention_time: float, mobility: float, ms_type: int,
|
|
420
|
+
index: NDArray[np.int32], mz: NDArray[np.float64], intensity: NDArray[np.float64]):
|
|
421
|
+
"""TimsSpectrum class.
|
|
422
|
+
|
|
423
|
+
Args:
|
|
424
|
+
index (NDArray[np.int32]): Index.
|
|
425
|
+
mz (NDArray[np.float64]): m/z.
|
|
426
|
+
intensity (NDArray[np.float64]): Intensity.
|
|
427
|
+
|
|
428
|
+
Raises:
|
|
429
|
+
AssertionError: If the length of the index, mz and intensity arrays are not equal.
|
|
430
|
+
"""
|
|
431
|
+
assert len(index) == len(mz) == len(intensity), ("The length of the index, mz and intensity arrays must be "
|
|
432
|
+
"equal.")
|
|
433
|
+
self.__spec_ptr = ims.PyTimsSpectrum(frame_id, scan, retention_time, mobility, ms_type, index, mz, intensity)
|
|
434
|
+
|
|
435
|
+
@classmethod
|
|
436
|
+
def from_py_ptr(cls, spec: ims.PyTimsSpectrum):
|
|
437
|
+
"""Create a TimsSpectrum from a PyTimsSpectrum.
|
|
438
|
+
|
|
439
|
+
Args:
|
|
440
|
+
spec (pims.PyTimsSpectrum): PyTimsSpectrum to create the TimsSpectrum from.
|
|
441
|
+
|
|
442
|
+
Returns:
|
|
443
|
+
TimsSpectrum: TimsSpectrum created from the PyTimsSpectrum.
|
|
444
|
+
"""
|
|
445
|
+
instance = cls.__new__(cls)
|
|
446
|
+
instance.__spec_ptr = spec
|
|
447
|
+
return instance
|
|
448
|
+
|
|
449
|
+
@property
|
|
450
|
+
def index(self) -> NDArray[np.int32]:
|
|
451
|
+
"""Index.
|
|
452
|
+
|
|
453
|
+
Returns:
|
|
454
|
+
NDArray[np.int32]: Index.
|
|
455
|
+
"""
|
|
456
|
+
return self.__spec_ptr.index
|
|
457
|
+
|
|
458
|
+
@property
|
|
459
|
+
def mz(self) -> NDArray[np.float64]:
|
|
460
|
+
"""m/z.
|
|
461
|
+
|
|
462
|
+
Returns:
|
|
463
|
+
NDArray[np.float64]: m/z.
|
|
464
|
+
"""
|
|
465
|
+
return self.__spec_ptr.mz
|
|
466
|
+
|
|
467
|
+
@property
|
|
468
|
+
def intensity(self) -> NDArray[np.float64]:
|
|
469
|
+
"""Intensity.
|
|
470
|
+
|
|
471
|
+
Returns:
|
|
472
|
+
NDArray[np.float64]: Intensity.
|
|
473
|
+
"""
|
|
474
|
+
return self.__spec_ptr.intensity
|
|
475
|
+
|
|
476
|
+
@property
|
|
477
|
+
def ms_type(self) -> str:
|
|
478
|
+
"""MS type.
|
|
479
|
+
|
|
480
|
+
Returns:
|
|
481
|
+
str: MS type.
|
|
482
|
+
"""
|
|
483
|
+
return self.__spec_ptr.ms_type
|
|
484
|
+
|
|
485
|
+
@property
|
|
486
|
+
def mobility(self) -> float:
|
|
487
|
+
"""Inverse mobility.
|
|
488
|
+
|
|
489
|
+
Returns:
|
|
490
|
+
float: Inverse mobility.
|
|
491
|
+
"""
|
|
492
|
+
return self.__spec_ptr.mobility
|
|
493
|
+
|
|
494
|
+
@property
|
|
495
|
+
def scan(self) -> int:
|
|
496
|
+
"""Scan.
|
|
497
|
+
|
|
498
|
+
Returns:
|
|
499
|
+
int: Scan.
|
|
500
|
+
"""
|
|
501
|
+
return self.__spec_ptr.scan
|
|
502
|
+
|
|
503
|
+
@property
|
|
504
|
+
def retention_time(self) -> float:
|
|
505
|
+
"""Retention time.
|
|
506
|
+
|
|
507
|
+
Returns:
|
|
508
|
+
float: Retention time.
|
|
509
|
+
"""
|
|
510
|
+
return self.__spec_ptr.retention_time
|
|
511
|
+
|
|
512
|
+
@property
|
|
513
|
+
def frame_id(self) -> int:
|
|
514
|
+
"""Frame ID.
|
|
515
|
+
|
|
516
|
+
Returns:
|
|
517
|
+
int: Frame ID.
|
|
518
|
+
"""
|
|
519
|
+
return self.__spec_ptr.frame_id
|
|
520
|
+
|
|
521
|
+
@property
|
|
522
|
+
def mz_spectrum(self) -> MzSpectrum:
|
|
523
|
+
"""Get the MzSpectrum.
|
|
524
|
+
|
|
525
|
+
Returns:
|
|
526
|
+
MzSpectrum: Spectrum.
|
|
527
|
+
"""
|
|
528
|
+
return MzSpectrum.from_py_ptr(self.__spec_ptr.mz_spectrum)
|
|
529
|
+
|
|
530
|
+
@property
|
|
531
|
+
def df(self) -> pd.DataFrame:
|
|
532
|
+
"""Data.
|
|
533
|
+
|
|
534
|
+
Returns:
|
|
535
|
+
pd.DataFrame: Data.
|
|
536
|
+
"""
|
|
537
|
+
|
|
538
|
+
return pd.DataFrame({
|
|
539
|
+
'frame': np.repeat(self.frame_id, len(self.index)),
|
|
540
|
+
'retention_time': np.repeat(self.retention_time, len(self.index)),
|
|
541
|
+
'scan': np.repeat(self.scan, len(self.index)),
|
|
542
|
+
'mobility': np.repeat(self.mobility, len(self.index)),
|
|
543
|
+
'tof': self.index,
|
|
544
|
+
'mz': self.mz,
|
|
545
|
+
'intensity': self.intensity
|
|
546
|
+
})
|
|
547
|
+
|
|
548
|
+
def __repr__(self):
|
|
549
|
+
return (f"TimsSpectrum(id={self.frame_id}, retention_time={np.round(self.retention_time, 2)}, "
|
|
550
|
+
f"scan={self.scan}, mobility={np.round(self.mobility, 2)}, ms_type={self.ms_type}, "
|
|
551
|
+
f"num_peaks={len(self.index)})")
|
|
552
|
+
|
|
553
|
+
def filter(self, mz_min: float = 0.0, mz_max: float = 2000.0, intensity_min: float = 0.0,
|
|
554
|
+
intensity_max: float = 1e9) -> 'TimsSpectrum':
|
|
555
|
+
"""Filter the spectrum for a given m/z range and intensity range.
|
|
556
|
+
|
|
557
|
+
Args:
|
|
558
|
+
mz_min (float): Minimum m/z value.
|
|
559
|
+
mz_max (float): Maximum m/z value.
|
|
560
|
+
intensity_min (float, optional): Minimum intensity value. Defaults to 0.0.
|
|
561
|
+
intensity_max (float, optional): Maximum intensity value. Defaults to 1e9.
|
|
562
|
+
|
|
563
|
+
Returns:
|
|
564
|
+
TimsSpectrum: Filtered spectrum.
|
|
565
|
+
"""
|
|
566
|
+
return TimsSpectrum.from_py_ptr(
|
|
567
|
+
self.__spec_ptr.filter_ranged(mz_min, mz_max, intensity_min, intensity_max))
|
|
568
|
+
|
|
569
|
+
def get_py_ptr(self) -> ims.PyTimsSpectrum:
|
|
570
|
+
"""Get the spec_ptr.
|
|
571
|
+
|
|
572
|
+
Returns:
|
|
573
|
+
pims.PyTimsSpectrum: spec_ptr.
|
|
574
|
+
"""
|
|
575
|
+
return self.__spec_ptr
|
|
576
|
+
|
|
577
|
+
def __add__(self, other):
|
|
578
|
+
"""Overwrite + operator for adding of spectra
|
|
579
|
+
|
|
580
|
+
Args:
|
|
581
|
+
other (TimsSpectrum): Other spectrum.
|
|
582
|
+
|
|
583
|
+
Returns:
|
|
584
|
+
TimsSpectrum: Sum of spectra
|
|
585
|
+
"""
|
|
586
|
+
return self.from_py_ptr(self.__spec_ptr + other.__spec_ptr)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TimsTOF module for imspy_core.
|
|
3
|
+
|
|
4
|
+
Contains classes for reading and processing timsTOF data.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .data import TimsDataset, AcquisitionMode
|
|
8
|
+
from .frame import TimsFrame, TimsFrameVectorized
|
|
9
|
+
from .slice import TimsSlice, TimsSliceVectorized, TimsPlane
|
|
10
|
+
from .dda import TimsDatasetDDA, PrecursorDDA, FragmentDDA
|
|
11
|
+
from .dia import TimsDatasetDIA
|
|
12
|
+
from .quadrupole import (
|
|
13
|
+
TimsTofQuadrupoleDDA, TimsTofQuadrupoleDIA, PasefMeta
|
|
14
|
+
)
|
|
15
|
+
from .collision import TimsTofCollisionEnergy, TimsTofCollisionEnergyDIA
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
'TimsDataset', 'AcquisitionMode',
|
|
19
|
+
'TimsFrame', 'TimsFrameVectorized',
|
|
20
|
+
'TimsSlice', 'TimsSliceVectorized', 'TimsPlane',
|
|
21
|
+
'TimsDatasetDDA', 'PrecursorDDA', 'FragmentDDA',
|
|
22
|
+
'TimsDatasetDIA',
|
|
23
|
+
'TimsTofQuadrupoleDDA', 'TimsTofQuadrupoleDIA', 'PasefMeta',
|
|
24
|
+
'TimsTofCollisionEnergy', 'TimsTofCollisionEnergyDIA',
|
|
25
|
+
]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
import imspy_connector
|
|
3
|
+
ims = imspy_connector.py_quadrupole
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TimsTofCollisionEnergy:
|
|
7
|
+
def __init__(self):
|
|
8
|
+
pass
|
|
9
|
+
|
|
10
|
+
@abstractmethod
|
|
11
|
+
def get_collision_energy(self) -> float:
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
@abstractmethod
|
|
15
|
+
def get_collision_energies(self) -> list[float]:
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TimsTofCollisionEnergyDIA(TimsTofCollisionEnergy):
|
|
20
|
+
def __init__(self, frame: list[int], frame_window_group: list[int], window_group: list[int], scan_start: list[int],
|
|
21
|
+
scan_end: list[int], collision_energy: list[float]):
|
|
22
|
+
|
|
23
|
+
super().__init__()
|
|
24
|
+
self.__ptr = ims.PyTimsTofCollisionEnergyDIA(frame, frame_window_group, window_group,
|
|
25
|
+
scan_start, scan_end, collision_energy)
|
|
26
|
+
|
|
27
|
+
def get_collision_energy(self, frame_id: int, scan_id: int) -> float:
|
|
28
|
+
return self.__ptr.get_collision_energy(frame_id, scan_id)
|
|
29
|
+
|
|
30
|
+
def get_collision_energies(self, frame_ids: list[int], scan_ids: list[int]) -> list[float]:
|
|
31
|
+
return self.__ptr.get_collision_energies(frame_ids, scan_ids)
|