CoreMS 4.0.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.
Files changed (171) hide show
  1. corems/__init__.py +63 -0
  2. corems/chroma_peak/__init__.py +0 -0
  3. corems/chroma_peak/calc/ChromaPeakCalc.py +480 -0
  4. corems/chroma_peak/calc/__init__.py +0 -0
  5. corems/chroma_peak/calc/subset.py +196 -0
  6. corems/chroma_peak/factory/__init__.py +0 -0
  7. corems/chroma_peak/factory/chroma_peak_classes.py +1178 -0
  8. corems/encapsulation/__init__.py +0 -0
  9. corems/encapsulation/constant.py +1283 -0
  10. corems/encapsulation/factory/__init__.py +0 -0
  11. corems/encapsulation/factory/parameters.py +392 -0
  12. corems/encapsulation/factory/processingSetting.py +1244 -0
  13. corems/encapsulation/input/__init__.py +0 -0
  14. corems/encapsulation/input/parameter_from_json.py +579 -0
  15. corems/encapsulation/output/__init__.py +0 -0
  16. corems/encapsulation/output/parameter_to_dict.py +142 -0
  17. corems/encapsulation/output/parameter_to_json.py +332 -0
  18. corems/mass_spectra/__init__.py +0 -0
  19. corems/mass_spectra/calc/GC_Calc.py +84 -0
  20. corems/mass_spectra/calc/GC_Deconvolution.py +558 -0
  21. corems/mass_spectra/calc/GC_RI_Calibration.py +44 -0
  22. corems/mass_spectra/calc/MZSearch.py +249 -0
  23. corems/mass_spectra/calc/SignalProcessing.py +656 -0
  24. corems/mass_spectra/calc/__init__.py +0 -0
  25. corems/mass_spectra/calc/lc_calc.py +5790 -0
  26. corems/mass_spectra/calc/lc_calc_operations.py +1127 -0
  27. corems/mass_spectra/factory/GC_Class.py +791 -0
  28. corems/mass_spectra/factory/__init__.py +0 -0
  29. corems/mass_spectra/factory/chromat_data.py +51 -0
  30. corems/mass_spectra/factory/lc_class.py +2721 -0
  31. corems/mass_spectra/input/__init__.py +0 -0
  32. corems/mass_spectra/input/andiNetCDF.py +200 -0
  33. corems/mass_spectra/input/boosterHDF5.py +216 -0
  34. corems/mass_spectra/input/brukerSolarix.py +153 -0
  35. corems/mass_spectra/input/brukerSolarix_utils.py +73 -0
  36. corems/mass_spectra/input/corems_hdf5.py +1710 -0
  37. corems/mass_spectra/input/massList.py +133 -0
  38. corems/mass_spectra/input/mzml.py +668 -0
  39. corems/mass_spectra/input/parserbase.py +239 -0
  40. corems/mass_spectra/input/rawFileReader.py +1839 -0
  41. corems/mass_spectra/output/__init__.py +0 -0
  42. corems/mass_spectra/output/export.py +2800 -0
  43. corems/mass_spectrum/__init__.py +0 -0
  44. corems/mass_spectrum/calc/AutoRecalibration.py +237 -0
  45. corems/mass_spectrum/calc/Calibration.py +602 -0
  46. corems/mass_spectrum/calc/CalibrationCalc.py +253 -0
  47. corems/mass_spectrum/calc/KendrickGroup.py +239 -0
  48. corems/mass_spectrum/calc/MassErrorPrediction.py +436 -0
  49. corems/mass_spectrum/calc/MassSpectrumCalc.py +303 -0
  50. corems/mass_spectrum/calc/MeanResolvingPowerFilter.py +212 -0
  51. corems/mass_spectrum/calc/NoiseCalc.py +371 -0
  52. corems/mass_spectrum/calc/NoiseCalc_Bayes.py +93 -0
  53. corems/mass_spectrum/calc/PeakPicking.py +994 -0
  54. corems/mass_spectrum/calc/__init__.py +0 -0
  55. corems/mass_spectrum/factory/MassSpectrumClasses.py +1753 -0
  56. corems/mass_spectrum/factory/__init__.py +0 -0
  57. corems/mass_spectrum/input/__init__.py +0 -0
  58. corems/mass_spectrum/input/baseClass.py +531 -0
  59. corems/mass_spectrum/input/boosterHDF5.py +161 -0
  60. corems/mass_spectrum/input/coremsHDF5.py +475 -0
  61. corems/mass_spectrum/input/massList.py +402 -0
  62. corems/mass_spectrum/input/numpyArray.py +133 -0
  63. corems/mass_spectrum/output/__init__.py +0 -0
  64. corems/mass_spectrum/output/export.py +841 -0
  65. corems/molecular_formula/__init__.py +0 -0
  66. corems/molecular_formula/calc/MolecularFormulaCalc.py +885 -0
  67. corems/molecular_formula/calc/__init__.py +0 -0
  68. corems/molecular_formula/factory/MolecularFormulaFactory.py +895 -0
  69. corems/molecular_formula/factory/__init__.py +0 -0
  70. corems/molecular_formula/input/__init__.py +0 -0
  71. corems/molecular_formula/input/masslist_ref.py +355 -0
  72. corems/molecular_id/__init__.py +0 -0
  73. corems/molecular_id/calc/ClusterFilter.py +251 -0
  74. corems/molecular_id/calc/MolecularFilter.py +122 -0
  75. corems/molecular_id/calc/SpectralSimilarity.py +632 -0
  76. corems/molecular_id/calc/__init__.py +0 -0
  77. corems/molecular_id/calc/math_distance.py +1637 -0
  78. corems/molecular_id/data/FAMES_REF.msp +980 -0
  79. corems/molecular_id/data/PNNLMetV20191015.msp +157267 -0
  80. corems/molecular_id/factory/EI_SQL.py +650 -0
  81. corems/molecular_id/factory/MolecularLookupTable.py +914 -0
  82. corems/molecular_id/factory/__init__.py +0 -0
  83. corems/molecular_id/factory/classification.py +884 -0
  84. corems/molecular_id/factory/lipid_molecular_metadata.py +50 -0
  85. corems/molecular_id/factory/molecularSQL.py +827 -0
  86. corems/molecular_id/factory/spectrum_search_results.py +119 -0
  87. corems/molecular_id/input/__init__.py +0 -0
  88. corems/molecular_id/input/nistMSI.py +148 -0
  89. corems/molecular_id/search/__init__.py +0 -0
  90. corems/molecular_id/search/compoundSearch.py +214 -0
  91. corems/molecular_id/search/database_interfaces.py +1527 -0
  92. corems/molecular_id/search/findOxygenPeaks.py +330 -0
  93. corems/molecular_id/search/lcms_spectral_search.py +348 -0
  94. corems/molecular_id/search/molecularFormulaSearch.py +1117 -0
  95. corems/molecular_id/search/priorityAssignment.py +723 -0
  96. corems/ms_peak/__init__.py +0 -0
  97. corems/ms_peak/calc/MSPeakCalc.py +1010 -0
  98. corems/ms_peak/calc/__init__.py +0 -0
  99. corems/ms_peak/factory/MSPeakClasses.py +542 -0
  100. corems/ms_peak/factory/__init__.py +0 -0
  101. corems/transient/__init__.py +0 -0
  102. corems/transient/calc/TransientCalc.py +362 -0
  103. corems/transient/calc/__init__.py +0 -0
  104. corems/transient/factory/TransientClasses.py +457 -0
  105. corems/transient/factory/__init__.py +0 -0
  106. corems/transient/input/__init__.py +0 -0
  107. corems/transient/input/brukerSolarix.py +461 -0
  108. corems/transient/input/midasDatFile.py +172 -0
  109. corems-4.0.0.dist-info/METADATA +475 -0
  110. corems-4.0.0.dist-info/RECORD +171 -0
  111. corems-4.0.0.dist-info/WHEEL +5 -0
  112. corems-4.0.0.dist-info/licenses/LICENSE +22 -0
  113. corems-4.0.0.dist-info/top_level.txt +4 -0
  114. examples/archive/scripts/CoreMS_tutorial.py +94 -0
  115. examples/archive/scripts/DI HR-MS Halogens Bruker.py +196 -0
  116. examples/archive/scripts/DI HR-MS MassList.py +385 -0
  117. examples/archive/scripts/GC-MS MetabRef.py +213 -0
  118. examples/archive/scripts/GC-MS NetCDF.py +217 -0
  119. examples/archive/scripts/HR-MS Thermo Raw 21T.py +136 -0
  120. examples/archive/scripts/LC-ICPMS_metal_peaks.py +297 -0
  121. examples/archive/scripts/LCMS-Thermo.py +460 -0
  122. examples/archive/scripts/LCMS_isotopes.py +283 -0
  123. examples/archive/scripts/MSParams_example.py +21 -0
  124. examples/archive/scripts/Molecular Formula Data Aggreation.py +84 -0
  125. examples/archive/scripts/Single Mz Search.py +69 -0
  126. examples/test_notebooks.py +145 -0
  127. ext_lib/ChemstationMSFileReader.dll +0 -0
  128. ext_lib/ChemstationMSFileReader.xml +126 -0
  129. ext_lib/RawFileReaderLicense.doc +0 -0
  130. ext_lib/ThermoFisher.CommonCore.BackgroundSubtraction.dll +0 -0
  131. ext_lib/ThermoFisher.CommonCore.BackgroundSubtraction.xml +2307 -0
  132. ext_lib/ThermoFisher.CommonCore.Data.dll +0 -0
  133. ext_lib/ThermoFisher.CommonCore.Data.xml +28974 -0
  134. ext_lib/ThermoFisher.CommonCore.MassPrecisionEstimator.dll +0 -0
  135. ext_lib/ThermoFisher.CommonCore.MassPrecisionEstimator.xml +241 -0
  136. ext_lib/ThermoFisher.CommonCore.RawFileReader.dll +0 -0
  137. ext_lib/ThermoFisher.CommonCore.RawFileReader.xml +31174 -0
  138. ext_lib/__init__.py +0 -0
  139. ext_lib/dotnet/OpenMcdf.Extensions.dll +0 -0
  140. ext_lib/dotnet/OpenMcdf.dll +0 -0
  141. ext_lib/dotnet/OpenMcdf.xml +1154 -0
  142. ext_lib/dotnet/System.IO.FileSystem.AccessControl.dll +0 -0
  143. ext_lib/dotnet/System.IO.FileSystem.AccessControl.xml +506 -0
  144. ext_lib/dotnet/System.Security.AccessControl.dll +0 -0
  145. ext_lib/dotnet/System.Security.AccessControl.xml +2043 -0
  146. ext_lib/dotnet/System.Security.Principal.Windows.dll +0 -0
  147. ext_lib/dotnet/System.Security.Principal.Windows.xml +1011 -0
  148. ext_lib/dotnet/ThermoFisher.CommonCore.BackgroundSubtraction.dll +0 -0
  149. ext_lib/dotnet/ThermoFisher.CommonCore.BackgroundSubtraction.xml +2307 -0
  150. ext_lib/dotnet/ThermoFisher.CommonCore.Data.dll +0 -0
  151. ext_lib/dotnet/ThermoFisher.CommonCore.Data.xml +29148 -0
  152. ext_lib/dotnet/ThermoFisher.CommonCore.MassPrecisionEstimator.dll +0 -0
  153. ext_lib/dotnet/ThermoFisher.CommonCore.MassPrecisionEstimator.xml +241 -0
  154. ext_lib/dotnet/ThermoFisher.CommonCore.RawFileReader.dll +0 -0
  155. ext_lib/dotnet/ThermoFisher.CommonCore.RawFileReader.xml +31492 -0
  156. ext_lib/version +18 -0
  157. support_code/atom_parsers/AtomsDescription.py +359 -0
  158. support_code/atom_parsers/CreateAtomsDescription.py +56 -0
  159. support_code/nmdc/filefinder.py +90 -0
  160. support_code/nmdc/lipidomics/lipidomics_workflow.py +748 -0
  161. support_code/nmdc/lipidomics/manifest_examples.py +49 -0
  162. support_code/nmdc/metabolomics/gcms_workflow.py +158 -0
  163. support_code/nmdc/metabolomics/lcms_metabolomics_targeted_search.py +59 -0
  164. support_code/nmdc/metabolomics/lcms_metabolomics_workflow.py +248 -0
  165. support_code/nmdc/metabolomics/metabolomics_collection.py +628 -0
  166. support_code/nmdc/metadata/dms_api.py +42 -0
  167. support_code/nmdc/nom/archived_scripts/nmdc_metadata_gen.py +288 -0
  168. support_code/nmdc/nom/archived_scripts/nom_grow_workflow.py +209 -0
  169. support_code/nmdc/nom/nom_workflow.py +312 -0
  170. support_code/windows_only_importers/BrukerCompassXtract.py +180 -0
  171. support_code/windows_only_importers/ThermoMSFileReader.py +405 -0
@@ -0,0 +1,656 @@
1
+ import numpy as np
2
+
3
+ from scipy.signal import savgol_filter
4
+ from scipy.signal.windows import boxcar
5
+ from scipy import interpolate
6
+ from matplotlib import pyplot as plt
7
+ from numpy import abs
8
+ from numpy import array, polyfit, asarray
9
+
10
+
11
+ def peak_detector(tic, max_tic): # TODO remove max_tic argument?
12
+ """
13
+ Find peaks by detecting minima in the first derivative of the data
14
+ Used in LC/GC data processing
15
+
16
+ Parameters
17
+ ----------
18
+ tic : array
19
+ array of data points to find the peaks
20
+ max_tic : float
21
+ maximum value of the data points
22
+
23
+ Returns
24
+ -------
25
+ tuple
26
+ tuple of indexes of the start, apex and final points of the peak
27
+
28
+ """
29
+ dy = derivate(tic)
30
+
31
+ indexes = np.where((np.hstack((dy, 0)) < 0) & (np.hstack((0, dy)) > 0))[0]
32
+
33
+ for index in indexes:
34
+ start_index = find_minima(index, tic, right=False)
35
+ final_index = find_minima(index, tic)
36
+
37
+ yield (start_index, index, final_index)
38
+
39
+
40
+ def find_nearest_scan(data, nodes):
41
+ """
42
+ Find nearest data point in a list of nodes (derivated data)
43
+ in LC/GC this is 'scan', in MS this is 'm/z' data point
44
+
45
+ Parameters
46
+ ----------
47
+ data : float
48
+ data point to find the nearest node
49
+ nodes : array
50
+ array of nodes to search for the nearest node
51
+
52
+ Returns
53
+ -------
54
+ float
55
+ nearest node to the data point
56
+ """
57
+
58
+ array_data = asarray(nodes)
59
+
60
+ scan_index = (abs(array_data - data)).argmin()
61
+
62
+ return nodes[scan_index]
63
+
64
+
65
+ def check_corrected_abundance(
66
+ closest_left,
67
+ closest_right,
68
+ apex_index,
69
+ signal,
70
+ max_signal,
71
+ signal_threshold,
72
+ abun_norm,
73
+ ):
74
+ """
75
+ Check the corrected abundance of the peak
76
+
77
+ Parameters
78
+ ----------
79
+ closest_left : int
80
+ index of the closest left node
81
+ closest_right : int
82
+ index of the closest right node
83
+ apex_index : int
84
+ index of the apex node
85
+ signal : array
86
+ array of data points to find the peaks
87
+ max_signal : float
88
+ maximum value of the data points
89
+ signal_threshold : float
90
+ threshold for the signal
91
+ abun_norm : float
92
+ abundance normalization factor
93
+
94
+ Returns
95
+ -------
96
+ float
97
+ corrected abundance of the peak
98
+
99
+
100
+ """
101
+ x = [closest_left, closest_right]
102
+ y = [signal[closest_left], signal[closest_right]]
103
+
104
+ pol = polyfit(x, y, 1) # TODO replace with faster method in this file
105
+
106
+ corrected_peak_height = signal[apex_index] - pol(apex_index)
107
+
108
+ if (corrected_peak_height / max_signal) * abun_norm > signal_threshold:
109
+ return corrected_peak_height
110
+ else:
111
+ return False
112
+
113
+
114
+ def peak_picking_first_derivative(
115
+ domain,
116
+ signal,
117
+ max_height,
118
+ max_prominence,
119
+ max_signal,
120
+ min_peak_datapoints,
121
+ peak_derivative_threshold,
122
+ signal_threshold=0.1,
123
+ correct_baseline=True,
124
+ plot_res=False,
125
+ abun_norm=100,
126
+ check_abundance=False,
127
+ apex_indexes=[],
128
+ ):
129
+ """
130
+ Find peaks by detecting minima in the first derivative of the data
131
+ Used in LC/GC and MS data processing
132
+ Optional baseline correction, then peak apex detection via 1st derivative.
133
+ For each apex the peak datapoints surrounding the apex are determined.
134
+ Some basic thresholding is applied (signal, number of datapoints, etc).
135
+
136
+ Parameters
137
+ ----------
138
+ domain : array
139
+ array of data points to find the peaks
140
+ signal : array
141
+ array of data points to find the peaks
142
+ max_height : float
143
+ maximum height of the peak
144
+ max_prominence : float
145
+ maximum prominence of the peak
146
+ max_signal : float
147
+ maximum signal of the peak
148
+ min_peak_datapoints : int
149
+ minimum number of data points in the peak
150
+ peak_derivative_threshold : float
151
+ threshold for the peak derivative
152
+ signal_threshold : float
153
+ threshold for the signal
154
+ correct_baseline : bool
155
+ flag to correct the baseline
156
+ plot_res : bool
157
+ flag to plot the results
158
+ abun_norm : float
159
+ abundance normalization factor
160
+ check_abundance : bool
161
+ flag to check the abundance
162
+
163
+
164
+ Returns
165
+ -------
166
+ tuple
167
+ tuple of indexes of the start, apex and final points of the peak
168
+
169
+
170
+ """
171
+ if correct_baseline:
172
+ signal = signal - baseline_detector(signal, domain, max_height, max_prominence)
173
+
174
+ domain = np.array(domain)
175
+ signal = np.array(signal)
176
+
177
+ dy = derivate(signal)
178
+ if len(apex_indexes) == 0:
179
+ # Find apexes
180
+ apex_indexes = np.where((np.hstack((dy, 0)) < 0) & (np.hstack((0, dy)) > 0))[0]
181
+ else:
182
+ apex_indexes = np.array(apex_indexes)
183
+
184
+ if apex_indexes.size and apex_indexes is not None:
185
+ apex_indexes = apex_indexes[
186
+ signal[apex_indexes] / max_signal >= signal_threshold
187
+ ]
188
+
189
+ signal = signal / max(signal)
190
+ start_peak = []
191
+ end_peak = []
192
+
193
+ pos_dy_threshold = peak_derivative_threshold # max(dy) * peak_derivative_threshold
194
+ neg_dy_threshold = -peak_derivative_threshold # min(dy) * peak_derivative_threshold
195
+ len_dy = len(dy)
196
+ # take apex_index and move left to find start
197
+ for index in apex_indexes:
198
+ # catch for starting position
199
+
200
+ if index == 0:
201
+ index_start = index
202
+ else:
203
+ index_start = index - 1
204
+
205
+ # catch for ending position
206
+ if (index + 1) >= dy.shape[0]:
207
+ index_end = index - 1
208
+ else:
209
+ index_end = index + 1
210
+
211
+ # while dy[index_start-1] > 0 and index_start != 0:
212
+ while dy[index_start - 1] > pos_dy_threshold and index_start > 0:
213
+ index_start = index_start - 1
214
+ start_peak.append(index_start)
215
+
216
+ # while dy[index_end] < 0 and index_end != (len(dy) - 1):
217
+ while dy[index_end] < neg_dy_threshold and index_end != (len_dy - 1):
218
+ index_end = index_end + 1
219
+ end_peak.append(index_end)
220
+
221
+ start_peak = array(start_peak)
222
+ end_peak = array(end_peak)
223
+
224
+ for apex_index in apex_indexes:
225
+ # index_gt_apex = np.where(end_peak >= apex_index)[0]
226
+ # index_lt_apex = np.where(start_peak <= apex_index)[0]
227
+ index_gt_apex = np.arange(np.searchsorted(end_peak, apex_index), len(end_peak))
228
+ index_lt_apex = np.arange(
229
+ 0, np.searchsorted(start_peak, apex_index, side="right")
230
+ )
231
+
232
+ if not index_gt_apex.size == 0 and not index_lt_apex.size == 0:
233
+ closest_right = find_nearest_scan(apex_index, end_peak[index_gt_apex])
234
+ closest_left = find_nearest_scan(apex_index, start_peak[index_lt_apex])
235
+ if check_abundance:
236
+ corrected_peak_height = check_corrected_abundance(
237
+ closest_left,
238
+ closest_right,
239
+ apex_index,
240
+ signal,
241
+ max_signal,
242
+ signal_threshold,
243
+ abun_norm,
244
+ )
245
+ else:
246
+ corrected_peak_height = signal[apex_index]
247
+
248
+ if (closest_right - closest_left) >= min_peak_datapoints:
249
+ if plot_res:
250
+ plt.plot(
251
+ domain[closest_left : closest_right + 1],
252
+ dy[closest_left : closest_right + 1],
253
+ c="red",
254
+ )
255
+ plt.plot(
256
+ domain[closest_left : closest_right + 1],
257
+ signal[closest_left : closest_right + 1],
258
+ c="black",
259
+ )
260
+ plt.title(str((corrected_peak_height / max_signal) * 100))
261
+ plt.show()
262
+
263
+ yield (closest_left, apex_index, closest_right)
264
+
265
+
266
+ def find_minima(index, tic, right=True):
267
+ """
268
+ Find the index of the local minima in the given time-of-flight (TOF) intensity array.
269
+
270
+ Parameters:
271
+ -----------
272
+ index: int
273
+ The starting index to search for the minima.
274
+ tic: list
275
+ TIC data points
276
+ right : bool, optional
277
+ Determines the direction of the search. If True, search to the right of the index. If False, search to the left of the index. Default is True.
278
+
279
+ Returns:
280
+ --------
281
+ int
282
+ The index of the local minima in the TIC array.
283
+ """
284
+
285
+ j = index
286
+ # apex_abundance = tic[index]
287
+ tic_len = len(tic)
288
+
289
+ if right:
290
+ minima = tic[j] >= tic[j + 1]
291
+ else:
292
+ minima = tic[j] >= tic[j - 1]
293
+
294
+ while minima:
295
+ if j == 1 or j == tic_len - 2:
296
+ break
297
+
298
+ if right:
299
+ j += 1
300
+
301
+ minima = tic[j] >= tic[j + 1]
302
+
303
+ else:
304
+ j -= 1
305
+ minima = tic[j] >= tic[j - 1]
306
+
307
+ if right:
308
+ return j
309
+ else:
310
+ return j
311
+
312
+
313
+ def derivate(data_array):
314
+ """
315
+ Calculate derivative of the data points.
316
+ Replaces nan with infinity
317
+
318
+ Parameters
319
+ ----------
320
+ data_array : array
321
+ array of data points
322
+
323
+ Returns
324
+ -------
325
+ array
326
+ array of the derivative of the data points
327
+ """
328
+ data_array = np.array(data_array)
329
+
330
+ dy = data_array[1:] - data_array[:-1]
331
+
332
+ # replaces nan for infinity
333
+ indices_nan = np.where(np.isnan(data_array))[0]
334
+
335
+ if indices_nan.size:
336
+ data_array[indices_nan] = np.inf
337
+ dy[np.where(np.isnan(dy))[0]] = np.inf
338
+
339
+ return dy
340
+
341
+
342
+ def minima_detector(tic, max_tic, peak_height_max_percent, peak_max_prominence_percent):
343
+ """
344
+ Minima detector for the TIC data points.
345
+
346
+ Parameters
347
+ ----------
348
+ tic : array
349
+ array of data points to find the peaks
350
+ max_tic : float
351
+ maximum value of the data points
352
+ peak_height_max_percent : float
353
+ maximum height of the peak
354
+ peak_max_prominence_percent : float
355
+ maximum prominence of the peak
356
+
357
+ Returns
358
+ -------
359
+ generator
360
+ generator of the indexes of the minima in the TIC array
361
+
362
+ """
363
+ peak_height_diff = lambda hi, li: ((tic[hi] - tic[li]) / max_tic) * 100
364
+
365
+ for start_index, index, final_index in peak_detector(tic, max_tic):
366
+ # abundance max threshold
367
+ if (tic[index] / max_tic) * 100 < peak_height_max_percent:
368
+ # calculates prominence and filter
369
+ if (
370
+ peak_height_diff(index, start_index)
371
+ and peak_height_diff(index, final_index) < peak_max_prominence_percent
372
+ ):
373
+ yield from (start_index, final_index)
374
+
375
+
376
+ def baseline_detector(
377
+ tic, rt, peak_height_max_percent, peak_max_prominence_percent, do_interpolation=True
378
+ ):
379
+ """
380
+ Baseline detector for the TIC data points.
381
+ For LC/GC data processing
382
+
383
+ Parameters
384
+ ----------
385
+ tic : array
386
+ array of data points to find the peaks
387
+ rt : array
388
+ array of retention time data points
389
+ peak_height_max_percent : float
390
+ maximum height of the peak
391
+ peak_max_prominence_percent : float
392
+ maximum prominence of the peak
393
+ do_interpolation : bool, optional
394
+ flag to interpolate the data points. Default is True
395
+
396
+ Returns
397
+ -------
398
+ array
399
+ array of the baseline corrected data points
400
+
401
+ """
402
+ rt = np.array(rt)
403
+
404
+ max_tic = max(tic)
405
+
406
+ indexes = sorted(
407
+ list(
408
+ set(
409
+ i
410
+ for i in minima_detector(
411
+ tic, max_tic, peak_height_max_percent, peak_max_prominence_percent
412
+ )
413
+ )
414
+ )
415
+ )
416
+
417
+ y = -tic
418
+
419
+ x1 = rt[indexes]
420
+
421
+ y1 = y[indexes]
422
+
423
+ if len(x1) <= 5:
424
+ return tic
425
+
426
+ if not do_interpolation:
427
+ y0 = np.zeros(tic.shape)
428
+ y0[indexes] = y[indexes]
429
+
430
+ return y0
431
+
432
+ else:
433
+ f1 = interpolate.interp1d(x1, y1, kind="quadratic", fill_value="extrapolate")
434
+
435
+ ynew1 = f1(list(rt))
436
+
437
+ # from matplotlib import pyplot as plt
438
+ # if self.deconv_rt_list and self.deconv_mz == 51:
439
+
440
+ # plt.plot(rt, tic-(-1* ynew1), color='green')
441
+
442
+ # plt.plot(rt, -1* ynew1, c='black')
443
+
444
+ # s = self.smooth(s, 10, 'blackman')
445
+
446
+ # plt.plot(self.retention_time, -s)
447
+
448
+ # plt.show()
449
+
450
+ return -1 * ynew1
451
+
452
+
453
+ def peak_detector_generator(
454
+ tic, stds, method, rt, max_height, min_height, max_prominence, min_datapoints
455
+ ):
456
+ """
457
+ Peak detector generator for the TIC data points.
458
+
459
+ Parameters
460
+ ----------
461
+ tic : array
462
+ array of data points to find the peaks
463
+ stds : float
464
+ standard deviation
465
+ method : str
466
+ method to detect the peaks
467
+ Available methods: 'manual_relative_abundance', 'auto_relative_abundance', 'second_derivative'
468
+ rt : array
469
+ array of retention time data points
470
+ max_height : float
471
+ maximum height of the peak
472
+ min_height : float
473
+ minimum height of the peak
474
+ max_prominence : float
475
+ maximum prominence of the peak
476
+ min_datapoints : int
477
+ minimum number of data points in the peak
478
+
479
+ Returns
480
+ -------
481
+ generator
482
+ generator of the indexes of the peaks in the TIC array
483
+
484
+ """
485
+ max_tic = max(tic)
486
+
487
+ if method == "manual_relative_abundance":
488
+ tic = tic - baseline_detector(tic, rt, max_height, max_prominence)
489
+
490
+ norm_tic = (tic / max_tic) * 100
491
+
492
+ remove_indexes = np.where(norm_tic < min_height)[0]
493
+
494
+ # if self.deconv_rt_list and self.deconv_mz == 51:
495
+ # plt.plot(self.deconv_rt_list, tic, label=self.deconv_mz)
496
+
497
+ elif method == "auto_relative_abundance":
498
+ tic = tic - baseline_detector(tic, rt, max_height, max_prominence)
499
+
500
+ baseline = baseline_detector(tic, rt, max_height, max_prominence)
501
+
502
+ peak_detect_threshold = np.nanmean(baseline) + (stds * np.std(baseline))
503
+
504
+ remove_indexes = np.where(tic < peak_detect_threshold)[0]
505
+
506
+ elif method == "second_derivative":
507
+ remove_indexes = second_derivative_threshold(
508
+ tic, stds, rt, max_height, max_prominence
509
+ )
510
+
511
+ else:
512
+ NotImplemented(method)
513
+
514
+ peak_height_diff = lambda hi, li: ((tic[hi] - tic[li]) / max_tic) * 100
515
+
516
+ dy = derivate(tic)
517
+
518
+ include_indexes = np.where((np.hstack((dy, 0)) < 0) & (np.hstack((0, dy)) > 0))[0]
519
+
520
+ final_indexes = sorted(set(include_indexes) - set(remove_indexes))
521
+
522
+ # from matplotlib import pyplot as plt
523
+
524
+ # plt.plot(self.retention_time, tic, color='black')
525
+ # plt.scatter(self.retention_time[remove_indexes], tic[remove_indexes], color='red')
526
+ # plt.scatter(self.retention_time[include_indexes], tic[include_indexes], color='blue')
527
+ # plt.scatter(self.retention_time[final_indexes], tic[final_indexes], color='blue')
528
+
529
+ # plt.show()
530
+
531
+ for index in final_indexes:
532
+ start_index = find_minima(index, tic, right=False)
533
+ final_index = find_minima(index, tic)
534
+
535
+ if final_index - start_index > min_datapoints:
536
+ # if min( peak_height_diff(index,start_index), peak_height_diff(index,final_index) )> self.chromatogram_settings.peak_min_prominence_percent :
537
+
538
+ yield (start_index, index, final_index)
539
+
540
+
541
+ def smooth_signal(x, window_len, window, pol_order, implemented_smooth_method):
542
+ """
543
+ Smooth the data using a window with requested size.
544
+
545
+ This method is based on the convolution of a scaled window with the signal.
546
+ The signal is prepared by introducing reflected copies of the signal
547
+ (with the window size) in both ends so that transient parts are minimized
548
+ in the begining and end part of the output signal.
549
+
550
+ Parameters
551
+ ----------
552
+ x: array
553
+ the input signal
554
+ window_len: int
555
+ the dimension of the smoothing window; should be an odd integer
556
+ window: str
557
+ the type of window from 'flat', 'hanning', 'hamming', 'bartlett', 'blackman'
558
+ pol_order: int
559
+ the order of the polynomial to fit the data
560
+ implemented_smooth_method: list
561
+ list of implemented smoothing methods
562
+
563
+ Returns
564
+ -------
565
+ y: array
566
+ the smoothed signal
567
+
568
+ Notes:
569
+ -----
570
+ See also: numpy.hanning, numpy.hamming, numpy.bartlett, numpy.blackman, numpy.convolve
571
+ scipy.signal.savgol_filter
572
+
573
+ """
574
+ x = np.array(x)
575
+
576
+ if x.ndim != 1:
577
+ raise ValueError("smooth only accepts 1 dimension arrays.")
578
+
579
+ if x.size < window_len:
580
+ raise ValueError("Input array needs to be bigger than window size")
581
+
582
+ # if window_len < 3:
583
+ # return x
584
+
585
+ if not window in implemented_smooth_method:
586
+ raise ValueError(
587
+ "Window method should be 'flat', 'hanning', 'hamming', 'bartlett', 'blackman'"
588
+ )
589
+
590
+ s = np.r_[x[window_len - 1 : 0 : -1], x, x[-1:-window_len:-1]]
591
+
592
+ if window == "savgol":
593
+ return savgol_filter(x, window_len, pol_order)
594
+
595
+ elif window == "boxcar": # moving average
596
+ w = boxcar(window_len)
597
+
598
+ y = np.convolve(w, s, mode="valid")
599
+
600
+ elif window == "flat": # moving average
601
+ w = np.ones(window_len, "d")
602
+
603
+ y = np.convolve(w / w.sum(), s, mode="valid")
604
+
605
+ else:
606
+ w = eval(window + "(window_len)")
607
+
608
+ y = np.convolve(w / w.sum(), s, mode="valid")
609
+
610
+ return y[int(window_len / 2 - 1) : int(-window_len / 2)]
611
+
612
+
613
+ def second_derivative_threshold(
614
+ tic, stds, rt, peak_height_max_percent, peak_max_prominence_percent
615
+ ):
616
+ """
617
+ Second derivative threshold for the TIC data points.
618
+ For LC/GC data processing
619
+
620
+ Parameters
621
+ ----------
622
+ tic : array
623
+ array of data points to find the peaks
624
+ stds : float
625
+ standard deviation
626
+ rt : array
627
+ array of retention time data points
628
+ peak_height_max_percent : float
629
+ maximum height of the peak
630
+
631
+ Returns
632
+ -------
633
+ array
634
+ array of the indexes of the data points to remove
635
+
636
+ """
637
+
638
+ dy = derivate(tic)
639
+
640
+ dydy = derivate(dy)
641
+ dydy = np.hstack((dydy, 0))
642
+ dydy = np.hstack((0, dydy))
643
+
644
+ baseline = baseline_detector(
645
+ dydy,
646
+ rt,
647
+ peak_height_max_percent,
648
+ peak_max_prominence_percent,
649
+ do_interpolation=False,
650
+ )
651
+
652
+ threshold_median = np.median(baseline) - (stds * np.std(baseline))
653
+
654
+ remove_indexes = np.where(dydy > threshold_median)[0]
655
+
656
+ return remove_indexes
File without changes