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,475 @@
1
+ import json
2
+
3
+ from pandas import DataFrame
4
+ import h5py
5
+ from io import BytesIO
6
+ from s3path import S3Path
7
+
8
+ from corems.encapsulation.input.parameter_from_json import _set_dict_data_ms
9
+ from corems.mass_spectrum.input.massList import ReadCoremsMasslist
10
+ from corems.mass_spectrum.factory.MassSpectrumClasses import MassSpecCentroid
11
+ from corems.encapsulation.factory.parameters import default_parameters
12
+
13
+
14
+ class ReadCoreMSHDF_MassSpectrum(ReadCoremsMasslist):
15
+ """Class for reading mass spectrum data from a CoreMS HDF5 file.
16
+
17
+ Attributes
18
+ ----------
19
+ h5pydata : h5py.File
20
+ The HDF5 file object.
21
+ scans : list
22
+ List of scan labels in the HDF5 file.
23
+
24
+ Parameters
25
+ ----------
26
+ file_location : str or S3Path
27
+ The path to the CoreMS HDF5 file.
28
+
29
+ Methods
30
+ -------
31
+ * load_raw_data(mass_spectrum, scan_index=0) Load raw data into the mass spectrum object.
32
+ * get_mass_spectrum(scan_number=0, time_index=-1, auto_process=True, load_settings=True, load_raw=True).Get a mass spectrum object.
33
+ * load_settings(mass_spectrum, scan_index=0, time_index=-1). Load settings into the mass spectrum object.
34
+ * get_dataframe(scan_index=0, time_index=-1). Get a pandas DataFrame representing the mass spectrum.
35
+ * get_time_index_to_pull(scan_label, time_index). Get the time index to pull from the HDF5 file.
36
+ * get_high_level_attr_data(attr_str). Get high-level attribute data from the HDF5 file.
37
+ * get_scan_group_attr_data(scan_index, time_index, attr_group, attr_srt=None). Get scan group attribute data from the HDF5 file.
38
+ * get_raw_data_attr_data(scan_index, attr_group, attr_str). Get raw data attribute data from the HDF5 file.
39
+ * get_output_parameters(polarity, scan_index=0). Get the output parameters for the mass spectrum.
40
+ """
41
+
42
+ def __init__(self, file_location):
43
+ super().__init__(file_location)
44
+
45
+ if isinstance(self.file_location, S3Path):
46
+ data = BytesIO(self.file_location.open("rb").read())
47
+ else:
48
+ data = self.file_location
49
+
50
+ self.h5pydata = h5py.File(data, "r")
51
+
52
+ self.scans = list(self.h5pydata.keys())
53
+
54
+ def close(self):
55
+ """Close the underlying HDF5 file handle."""
56
+ if self.h5pydata and self.h5pydata.id.valid:
57
+ self.h5pydata.close()
58
+
59
+ def __enter__(self):
60
+ return self
61
+
62
+ def __exit__(self, *args):
63
+ self.close()
64
+
65
+ def load_raw_data(self, mass_spectrum, scan_index=0):
66
+ """
67
+ Load raw data into the mass spectrum object.
68
+
69
+ Parameters
70
+ ----------
71
+ mass_spectrum : MassSpecCentroid
72
+ The mass spectrum object to load the raw data into.
73
+ scan_index : int, optional
74
+ The index of the scan to load the raw data from. Default is 0.
75
+ """
76
+
77
+ scan_label = self.scans[scan_index]
78
+
79
+ # Check if the "raw_ms" dataset exists and has data
80
+ if "raw_ms" in self.h5pydata[scan_label] and self.h5pydata[scan_label]["raw_ms"].shape is not None:
81
+ mz_profile = self.h5pydata[scan_label]["raw_ms"][0]
82
+
83
+ abundance_profile = self.h5pydata[scan_label]["raw_ms"][1]
84
+
85
+ mass_spectrum.mz_exp_profile = mz_profile
86
+
87
+ mass_spectrum.abundance_profile = abundance_profile
88
+
89
+ def get_mass_spectrum(
90
+ self,
91
+ scan_number=0,
92
+ time_index=-1,
93
+ auto_process=True,
94
+ load_settings=True,
95
+ load_raw=True,
96
+ load_molecular_formula=True,
97
+ ):
98
+ """
99
+ Instantiate a mass spectrum object from the CoreMS HDF5 file.
100
+ Note that this always returns a centroid mass spectrum object; functionality for profile and
101
+ frequency mass spectra is not yet implemented.
102
+
103
+ Parameters
104
+ ----------
105
+ scan_number : int, optional
106
+ The index of the scan to retrieve the mass spectrum from. Default is 0.
107
+ time_index : int, optional
108
+ The index of the time point to retrieve the mass spectrum from. Default is -1.
109
+ auto_process : bool, optional
110
+ Whether to automatically process the mass spectrum. Default is True.
111
+ load_settings : bool, optional
112
+ Whether to load the settings into the mass spectrum object. Default is True.
113
+ load_raw : bool, optional
114
+ Whether to load the raw data into the mass spectrum object. Default is True.
115
+ load_molecular_formula : bool, optional
116
+ Whether to load the molecular formula into the mass spectrum object.
117
+ Default is True.
118
+
119
+ Returns
120
+ -------
121
+ MassSpecCentroid
122
+ The mass spectrum object.
123
+
124
+ Raises
125
+ ------
126
+ ValueError
127
+ If the CoreMS file is not valid.
128
+ If the mass spectrum has not been processed and load_molecular_formula is True.
129
+ """
130
+ if "mass_spectra" in self.scans[0]:
131
+ scan_index = self.scans.index("mass_spectra/" + str(scan_number))
132
+ else:
133
+ scan_index = self.scans.index(str(scan_number))
134
+ dataframe = self.get_dataframe(scan_index, time_index=time_index)
135
+ if dataframe["Molecular Formula"].any() and not dataframe["C"].any():
136
+ cols = dataframe.columns.tolist()
137
+ cols = cols[cols.index("Molecular Formula") + 1 :]
138
+ for index, row in dataframe.iterrows():
139
+ if row["Molecular Formula"] is not None:
140
+ og_formula = row["Molecular Formula"]
141
+ for col in cols:
142
+ if "col" in og_formula:
143
+ # get the digit after the element ("col") in the molecular formula and set it to the dataframe
144
+ row[col] = int(og_formula.split(col)[1].split(" ")[0])
145
+
146
+ if not set(
147
+ ["H/C", "O/C", "Heteroatom Class", "Ion Type", "Is Isotopologue"]
148
+ ).issubset(dataframe.columns):
149
+ raise ValueError(
150
+ "%s it is not a valid CoreMS file" % str(self.file_location)
151
+ )
152
+
153
+ dataframe.rename(columns=self.parameters.header_translate, inplace=True)
154
+
155
+ # Cast m/z, and 'Peak Height' to float
156
+ dataframe["m/z"] = dataframe["m/z"].astype(float)
157
+ dataframe["Peak Height"] = dataframe["Peak Height"].astype(float)
158
+
159
+ polarity = dataframe["Ion Charge"].values[0]
160
+
161
+ output_parameters = self.get_output_parameters(polarity, scan_index=scan_index)
162
+
163
+ mass_spec_obj = MassSpecCentroid(
164
+ dataframe.to_dict(orient="list"), output_parameters, auto_process=False
165
+ )
166
+
167
+ if auto_process:
168
+ # Set the settings on the mass spectrum object to relative abuncance of 0 so all peaks get added
169
+ mass_spec_obj.settings.noise_threshold_method = "absolute_abundance"
170
+ mass_spec_obj.settings.noise_threshold_absolute_abundance = 0
171
+ mass_spec_obj.process_mass_spec()
172
+
173
+ if load_settings:
174
+ # Load settings into the mass spectrum object
175
+ self.load_settings(
176
+ mass_spec_obj, scan_index=scan_index, time_index=time_index
177
+ )
178
+
179
+ if load_raw:
180
+ self.load_raw_data(mass_spec_obj, scan_index=scan_index)
181
+
182
+ if load_molecular_formula:
183
+ if not auto_process:
184
+ raise ValueError(
185
+ "Can only add molecular formula if the mass spectrum has been processed"
186
+ )
187
+ else:
188
+ self.add_molecular_formula(mass_spec_obj, dataframe)
189
+
190
+ return mass_spec_obj
191
+
192
+ def load_settings(self, mass_spectrum, scan_index=0, time_index=-1):
193
+ """
194
+ Load settings into the mass spectrum object.
195
+
196
+ Parameters
197
+ ----------
198
+ mass_spectrum : MassSpecCentroid
199
+ The mass spectrum object to load the settings into.
200
+ scan_index : int, optional
201
+ The index of the scan to load the settings from. Default is 0.
202
+ time_index : int, optional
203
+ The index of the time point to load the settings from. Default is -1.
204
+ """
205
+
206
+ loaded_settings = {}
207
+ loaded_settings["MoleculaSearch"] = self.get_scan_group_attr_data(
208
+ scan_index, time_index, "MoleculaSearchSetting"
209
+ )
210
+ loaded_settings["MassSpecPeak"] = self.get_scan_group_attr_data(
211
+ scan_index, time_index, "MassSpecPeakSetting"
212
+ )
213
+ loaded_settings["MassSpectrum"] = self.get_scan_group_attr_data(
214
+ scan_index, time_index, "MassSpectrumSetting"
215
+ )
216
+ loaded_settings["Transient"] = self.get_scan_group_attr_data(
217
+ scan_index, time_index, "TransientSetting"
218
+ )
219
+
220
+ _set_dict_data_ms(loaded_settings, mass_spectrum)
221
+
222
+ def get_dataframe(self, scan_index=0, time_index=-1):
223
+ """
224
+ Get a pandas DataFrame representing the mass spectrum.
225
+
226
+ Parameters
227
+ ----------
228
+ scan_index : int, optional
229
+ The index of the scan to retrieve the DataFrame from. Default is 0.
230
+ time_index : int, optional
231
+ The index of the time point to retrieve the DataFrame from. Default is -1.
232
+
233
+ Returns
234
+ -------
235
+ DataFrame
236
+ The pandas DataFrame representing the mass spectrum.
237
+ """
238
+
239
+ columnsLabels = self.get_scan_group_attr_data(
240
+ scan_index, time_index, "ColumnsLabels"
241
+ )
242
+
243
+ scan_label = self.scans[scan_index]
244
+
245
+ index_to_pull = self.get_time_index_to_pull(scan_label, time_index)
246
+
247
+ corems_table_data = self.h5pydata[scan_label][index_to_pull]
248
+
249
+ list_dict = []
250
+ for row in corems_table_data:
251
+ data_dict = {}
252
+ for data_index, data in enumerate(row):
253
+ label = columnsLabels[data_index]
254
+ # if data starts with a b' it is a byte string, so decode it
255
+ if isinstance(data, bytes):
256
+ data = data.decode("utf-8")
257
+ if data == "nan":
258
+ data = None
259
+ data_dict[label] = data
260
+
261
+ list_dict.append(data_dict)
262
+
263
+ # Reorder the columns from low to high "Index" to match the order of the dataframe
264
+ df = DataFrame(list_dict)
265
+ # set the "Index" column to int so it sorts correctly
266
+ df["Index"] = df["Index"].astype(int)
267
+ df = df.sort_values(by="Index")
268
+ # Reset index to match the "Index" column
269
+ df = df.set_index("Index", drop=False)
270
+
271
+ return df
272
+
273
+ def get_time_index_to_pull(self, scan_label, time_index):
274
+ """
275
+ Get the time index to pull from the HDF5 file.
276
+
277
+ Parameters
278
+ ----------
279
+ scan_label : str
280
+ The label of the scan.
281
+ time_index : int
282
+ The index of the time point.
283
+
284
+ Returns
285
+ -------
286
+ str
287
+ The time index to pull.
288
+ """
289
+
290
+ time_data = sorted(
291
+ [(i, int(i)) for i in self.h5pydata[scan_label].keys() if i != "raw_ms"],
292
+ key=lambda m: m[1],
293
+ )
294
+
295
+ index_to_pull = time_data[time_index][0]
296
+
297
+ return index_to_pull
298
+
299
+ def get_high_level_attr_data(self, attr_str):
300
+ """
301
+ Get high-level attribute data from the HDF5 file.
302
+
303
+ Parameters
304
+ ----------
305
+ attr_str : str
306
+ The attribute string.
307
+
308
+ Returns
309
+ -------
310
+ dict
311
+ The attribute data.
312
+
313
+ Raises
314
+ ------
315
+ KeyError
316
+ If the attribute string is not found in the HDF5 file.
317
+ """
318
+
319
+ return self.h5pydata.attrs[attr_str]
320
+
321
+ def get_scan_group_attr_data(
322
+ self, scan_index, time_index, attr_group, attr_srt=None
323
+ ):
324
+ """
325
+ Get scan group attribute data from the HDF5 file.
326
+
327
+ Parameters
328
+ ----------
329
+ scan_index : int
330
+ The index of the scan.
331
+ time_index : int
332
+ The index of the time point.
333
+ attr_group : str
334
+ The attribute group.
335
+ attr_srt : str, optional
336
+ The attribute string. Default is None.
337
+
338
+ Returns
339
+ -------
340
+ dict
341
+ The attribute data.
342
+
343
+ Notes
344
+ -----
345
+ This method retrieves attribute data from the HDF5 file for a specific scan and time point.
346
+ The attribute data is stored in the specified attribute group.
347
+ If an attribute string is provided, only the corresponding attribute value is returned.
348
+ If no attribute string is provided, all attribute data in the group is returned as a dictionary.
349
+ """
350
+ # Get index of self.scans where scan_index_str is found
351
+ scan_label = self.scans[scan_index]
352
+
353
+ index_to_pull = self.get_time_index_to_pull(scan_label, time_index)
354
+
355
+ if attr_srt:
356
+ return json.loads(
357
+ self.h5pydata[scan_label][index_to_pull].attrs[attr_group]
358
+ )[attr_srt]
359
+
360
+ else:
361
+ data = self.h5pydata[scan_label][index_to_pull].attrs.get(attr_group)
362
+ if data:
363
+ return json.loads(data)
364
+ else:
365
+ return {}
366
+
367
+ def get_raw_data_attr_data(self, scan_index, attr_group, attr_str):
368
+ """
369
+ Get raw data attribute data from the HDF5 file.
370
+
371
+ Parameters
372
+ ----------
373
+ scan_index : int
374
+ The index of the scan.
375
+ attr_group : str
376
+ The attribute group.
377
+ attr_str : str
378
+ The attribute string.
379
+
380
+ Returns
381
+ -------
382
+ dict
383
+ The attribute data.
384
+
385
+ Raises
386
+ ------
387
+ KeyError
388
+ If the attribute string is not found in the attribute group.
389
+
390
+ Notes
391
+ -----
392
+ This method retrieves the attribute data associated with a specific scan, attribute group, and attribute string
393
+ from the HDF5 file. It returns the attribute data as a dictionary.
394
+
395
+ Example usage:
396
+ >>> data = get_raw_data_attr_data(0, "group1", "attribute1")
397
+ >>> print(data)
398
+ {'key1': 'value1', 'key2': 'value2'}
399
+ """
400
+ scan_label = self.scans[scan_index]
401
+
402
+ # First try to get from raw_ms dataset attributes (backward compatibility)
403
+ if "raw_ms" in self.h5pydata[scan_label] and attr_group in self.h5pydata[scan_label]["raw_ms"].attrs:
404
+ try:
405
+ return json.loads(self.h5pydata[scan_label]["raw_ms"].attrs[attr_group])[attr_str]
406
+ except KeyError:
407
+ attr_str = attr_str.replace("baseline", "baselise")
408
+ return json.loads(self.h5pydata[scan_label]["raw_ms"].attrs[attr_group])[attr_str]
409
+
410
+ # If not found in raw_ms, try to get from scan group attributes (new format)
411
+ elif attr_group in self.h5pydata[scan_label].attrs:
412
+ try:
413
+ return json.loads(self.h5pydata[scan_label].attrs[attr_group])[attr_str]
414
+ except KeyError:
415
+ attr_str = attr_str.replace("baseline", "baselise")
416
+ return json.loads(self.h5pydata[scan_label].attrs[attr_group])[attr_str]
417
+
418
+ else:
419
+ raise KeyError(f"Attribute group '{attr_group}' not found in either raw_ms dataset or scan group for scan {scan_label}")
420
+
421
+ def get_output_parameters(self, polarity, scan_index=0):
422
+ """
423
+ Get the output parameters for the mass spectrum.
424
+
425
+ Parameters
426
+ ----------
427
+ polarity : str
428
+ The polarity of the mass spectrum.
429
+ scan_index : int, optional
430
+ The index of the scan. Default is 0.
431
+
432
+ Returns
433
+ -------
434
+ dict
435
+ The output parameters.
436
+ """
437
+
438
+ d_params = default_parameters(self.file_location)
439
+ d_params["filename_path"] = self.file_location
440
+ d_params["polarity"] = self.get_raw_data_attr_data(
441
+ scan_index, "MassSpecAttrs", "polarity"
442
+ )
443
+ d_params["rt"] = self.get_raw_data_attr_data(scan_index, "MassSpecAttrs", "rt")
444
+
445
+ d_params["tic"] = self.get_raw_data_attr_data(
446
+ scan_index, "MassSpecAttrs", "tic"
447
+ )
448
+
449
+ d_params["mobility_scan"] = self.get_raw_data_attr_data(
450
+ scan_index, "MassSpecAttrs", "mobility_scan"
451
+ )
452
+ d_params["mobility_rt"] = self.get_raw_data_attr_data(
453
+ scan_index, "MassSpecAttrs", "mobility_rt"
454
+ )
455
+ d_params["Aterm"] = self.get_raw_data_attr_data(
456
+ scan_index, "MassSpecAttrs", "Aterm"
457
+ )
458
+ d_params["Bterm"] = self.get_raw_data_attr_data(
459
+ scan_index, "MassSpecAttrs", "Bterm"
460
+ )
461
+ d_params["Cterm"] = self.get_raw_data_attr_data(
462
+ scan_index, "MassSpecAttrs", "Cterm"
463
+ )
464
+ d_params["baseline_noise"] = self.get_raw_data_attr_data(
465
+ scan_index, "MassSpecAttrs", "baseline_noise"
466
+ )
467
+ d_params["baseline_noise_std"] = self.get_raw_data_attr_data(
468
+ scan_index, "MassSpecAttrs", "baseline_noise_std"
469
+ )
470
+
471
+ d_params["analyzer"] = self.get_high_level_attr_data("analyzer")
472
+ d_params["instrument_label"] = self.get_high_level_attr_data("instrument_label")
473
+ d_params["sample_name"] = self.get_high_level_attr_data("sample_name")
474
+
475
+ return d_params