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.
- corems/__init__.py +63 -0
- corems/chroma_peak/__init__.py +0 -0
- corems/chroma_peak/calc/ChromaPeakCalc.py +480 -0
- corems/chroma_peak/calc/__init__.py +0 -0
- corems/chroma_peak/calc/subset.py +196 -0
- corems/chroma_peak/factory/__init__.py +0 -0
- corems/chroma_peak/factory/chroma_peak_classes.py +1178 -0
- corems/encapsulation/__init__.py +0 -0
- corems/encapsulation/constant.py +1283 -0
- corems/encapsulation/factory/__init__.py +0 -0
- corems/encapsulation/factory/parameters.py +392 -0
- corems/encapsulation/factory/processingSetting.py +1244 -0
- corems/encapsulation/input/__init__.py +0 -0
- corems/encapsulation/input/parameter_from_json.py +579 -0
- corems/encapsulation/output/__init__.py +0 -0
- corems/encapsulation/output/parameter_to_dict.py +142 -0
- corems/encapsulation/output/parameter_to_json.py +332 -0
- corems/mass_spectra/__init__.py +0 -0
- corems/mass_spectra/calc/GC_Calc.py +84 -0
- corems/mass_spectra/calc/GC_Deconvolution.py +558 -0
- corems/mass_spectra/calc/GC_RI_Calibration.py +44 -0
- corems/mass_spectra/calc/MZSearch.py +249 -0
- corems/mass_spectra/calc/SignalProcessing.py +656 -0
- corems/mass_spectra/calc/__init__.py +0 -0
- corems/mass_spectra/calc/lc_calc.py +5790 -0
- corems/mass_spectra/calc/lc_calc_operations.py +1127 -0
- corems/mass_spectra/factory/GC_Class.py +791 -0
- corems/mass_spectra/factory/__init__.py +0 -0
- corems/mass_spectra/factory/chromat_data.py +51 -0
- corems/mass_spectra/factory/lc_class.py +2721 -0
- corems/mass_spectra/input/__init__.py +0 -0
- corems/mass_spectra/input/andiNetCDF.py +200 -0
- corems/mass_spectra/input/boosterHDF5.py +216 -0
- corems/mass_spectra/input/brukerSolarix.py +153 -0
- corems/mass_spectra/input/brukerSolarix_utils.py +73 -0
- corems/mass_spectra/input/corems_hdf5.py +1710 -0
- corems/mass_spectra/input/massList.py +133 -0
- corems/mass_spectra/input/mzml.py +668 -0
- corems/mass_spectra/input/parserbase.py +239 -0
- corems/mass_spectra/input/rawFileReader.py +1839 -0
- corems/mass_spectra/output/__init__.py +0 -0
- corems/mass_spectra/output/export.py +2800 -0
- corems/mass_spectrum/__init__.py +0 -0
- corems/mass_spectrum/calc/AutoRecalibration.py +237 -0
- corems/mass_spectrum/calc/Calibration.py +602 -0
- corems/mass_spectrum/calc/CalibrationCalc.py +253 -0
- corems/mass_spectrum/calc/KendrickGroup.py +239 -0
- corems/mass_spectrum/calc/MassErrorPrediction.py +436 -0
- corems/mass_spectrum/calc/MassSpectrumCalc.py +303 -0
- corems/mass_spectrum/calc/MeanResolvingPowerFilter.py +212 -0
- corems/mass_spectrum/calc/NoiseCalc.py +371 -0
- corems/mass_spectrum/calc/NoiseCalc_Bayes.py +93 -0
- corems/mass_spectrum/calc/PeakPicking.py +994 -0
- corems/mass_spectrum/calc/__init__.py +0 -0
- corems/mass_spectrum/factory/MassSpectrumClasses.py +1753 -0
- corems/mass_spectrum/factory/__init__.py +0 -0
- corems/mass_spectrum/input/__init__.py +0 -0
- corems/mass_spectrum/input/baseClass.py +531 -0
- corems/mass_spectrum/input/boosterHDF5.py +161 -0
- corems/mass_spectrum/input/coremsHDF5.py +475 -0
- corems/mass_spectrum/input/massList.py +402 -0
- corems/mass_spectrum/input/numpyArray.py +133 -0
- corems/mass_spectrum/output/__init__.py +0 -0
- corems/mass_spectrum/output/export.py +841 -0
- corems/molecular_formula/__init__.py +0 -0
- corems/molecular_formula/calc/MolecularFormulaCalc.py +885 -0
- corems/molecular_formula/calc/__init__.py +0 -0
- corems/molecular_formula/factory/MolecularFormulaFactory.py +895 -0
- corems/molecular_formula/factory/__init__.py +0 -0
- corems/molecular_formula/input/__init__.py +0 -0
- corems/molecular_formula/input/masslist_ref.py +355 -0
- corems/molecular_id/__init__.py +0 -0
- corems/molecular_id/calc/ClusterFilter.py +251 -0
- corems/molecular_id/calc/MolecularFilter.py +122 -0
- corems/molecular_id/calc/SpectralSimilarity.py +632 -0
- corems/molecular_id/calc/__init__.py +0 -0
- corems/molecular_id/calc/math_distance.py +1637 -0
- corems/molecular_id/data/FAMES_REF.msp +980 -0
- corems/molecular_id/data/PNNLMetV20191015.msp +157267 -0
- corems/molecular_id/factory/EI_SQL.py +650 -0
- corems/molecular_id/factory/MolecularLookupTable.py +914 -0
- corems/molecular_id/factory/__init__.py +0 -0
- corems/molecular_id/factory/classification.py +884 -0
- corems/molecular_id/factory/lipid_molecular_metadata.py +50 -0
- corems/molecular_id/factory/molecularSQL.py +827 -0
- corems/molecular_id/factory/spectrum_search_results.py +119 -0
- corems/molecular_id/input/__init__.py +0 -0
- corems/molecular_id/input/nistMSI.py +148 -0
- corems/molecular_id/search/__init__.py +0 -0
- corems/molecular_id/search/compoundSearch.py +214 -0
- corems/molecular_id/search/database_interfaces.py +1527 -0
- corems/molecular_id/search/findOxygenPeaks.py +330 -0
- corems/molecular_id/search/lcms_spectral_search.py +348 -0
- corems/molecular_id/search/molecularFormulaSearch.py +1117 -0
- corems/molecular_id/search/priorityAssignment.py +723 -0
- corems/ms_peak/__init__.py +0 -0
- corems/ms_peak/calc/MSPeakCalc.py +1010 -0
- corems/ms_peak/calc/__init__.py +0 -0
- corems/ms_peak/factory/MSPeakClasses.py +542 -0
- corems/ms_peak/factory/__init__.py +0 -0
- corems/transient/__init__.py +0 -0
- corems/transient/calc/TransientCalc.py +362 -0
- corems/transient/calc/__init__.py +0 -0
- corems/transient/factory/TransientClasses.py +457 -0
- corems/transient/factory/__init__.py +0 -0
- corems/transient/input/__init__.py +0 -0
- corems/transient/input/brukerSolarix.py +461 -0
- corems/transient/input/midasDatFile.py +172 -0
- corems-4.0.0.dist-info/METADATA +475 -0
- corems-4.0.0.dist-info/RECORD +171 -0
- corems-4.0.0.dist-info/WHEEL +5 -0
- corems-4.0.0.dist-info/licenses/LICENSE +22 -0
- corems-4.0.0.dist-info/top_level.txt +4 -0
- examples/archive/scripts/CoreMS_tutorial.py +94 -0
- examples/archive/scripts/DI HR-MS Halogens Bruker.py +196 -0
- examples/archive/scripts/DI HR-MS MassList.py +385 -0
- examples/archive/scripts/GC-MS MetabRef.py +213 -0
- examples/archive/scripts/GC-MS NetCDF.py +217 -0
- examples/archive/scripts/HR-MS Thermo Raw 21T.py +136 -0
- examples/archive/scripts/LC-ICPMS_metal_peaks.py +297 -0
- examples/archive/scripts/LCMS-Thermo.py +460 -0
- examples/archive/scripts/LCMS_isotopes.py +283 -0
- examples/archive/scripts/MSParams_example.py +21 -0
- examples/archive/scripts/Molecular Formula Data Aggreation.py +84 -0
- examples/archive/scripts/Single Mz Search.py +69 -0
- examples/test_notebooks.py +145 -0
- ext_lib/ChemstationMSFileReader.dll +0 -0
- ext_lib/ChemstationMSFileReader.xml +126 -0
- ext_lib/RawFileReaderLicense.doc +0 -0
- ext_lib/ThermoFisher.CommonCore.BackgroundSubtraction.dll +0 -0
- ext_lib/ThermoFisher.CommonCore.BackgroundSubtraction.xml +2307 -0
- ext_lib/ThermoFisher.CommonCore.Data.dll +0 -0
- ext_lib/ThermoFisher.CommonCore.Data.xml +28974 -0
- ext_lib/ThermoFisher.CommonCore.MassPrecisionEstimator.dll +0 -0
- ext_lib/ThermoFisher.CommonCore.MassPrecisionEstimator.xml +241 -0
- ext_lib/ThermoFisher.CommonCore.RawFileReader.dll +0 -0
- ext_lib/ThermoFisher.CommonCore.RawFileReader.xml +31174 -0
- ext_lib/__init__.py +0 -0
- ext_lib/dotnet/OpenMcdf.Extensions.dll +0 -0
- ext_lib/dotnet/OpenMcdf.dll +0 -0
- ext_lib/dotnet/OpenMcdf.xml +1154 -0
- ext_lib/dotnet/System.IO.FileSystem.AccessControl.dll +0 -0
- ext_lib/dotnet/System.IO.FileSystem.AccessControl.xml +506 -0
- ext_lib/dotnet/System.Security.AccessControl.dll +0 -0
- ext_lib/dotnet/System.Security.AccessControl.xml +2043 -0
- ext_lib/dotnet/System.Security.Principal.Windows.dll +0 -0
- ext_lib/dotnet/System.Security.Principal.Windows.xml +1011 -0
- ext_lib/dotnet/ThermoFisher.CommonCore.BackgroundSubtraction.dll +0 -0
- ext_lib/dotnet/ThermoFisher.CommonCore.BackgroundSubtraction.xml +2307 -0
- ext_lib/dotnet/ThermoFisher.CommonCore.Data.dll +0 -0
- ext_lib/dotnet/ThermoFisher.CommonCore.Data.xml +29148 -0
- ext_lib/dotnet/ThermoFisher.CommonCore.MassPrecisionEstimator.dll +0 -0
- ext_lib/dotnet/ThermoFisher.CommonCore.MassPrecisionEstimator.xml +241 -0
- ext_lib/dotnet/ThermoFisher.CommonCore.RawFileReader.dll +0 -0
- ext_lib/dotnet/ThermoFisher.CommonCore.RawFileReader.xml +31492 -0
- ext_lib/version +18 -0
- support_code/atom_parsers/AtomsDescription.py +359 -0
- support_code/atom_parsers/CreateAtomsDescription.py +56 -0
- support_code/nmdc/filefinder.py +90 -0
- support_code/nmdc/lipidomics/lipidomics_workflow.py +748 -0
- support_code/nmdc/lipidomics/manifest_examples.py +49 -0
- support_code/nmdc/metabolomics/gcms_workflow.py +158 -0
- support_code/nmdc/metabolomics/lcms_metabolomics_targeted_search.py +59 -0
- support_code/nmdc/metabolomics/lcms_metabolomics_workflow.py +248 -0
- support_code/nmdc/metabolomics/metabolomics_collection.py +628 -0
- support_code/nmdc/metadata/dms_api.py +42 -0
- support_code/nmdc/nom/archived_scripts/nmdc_metadata_gen.py +288 -0
- support_code/nmdc/nom/archived_scripts/nom_grow_workflow.py +209 -0
- support_code/nmdc/nom/nom_workflow.py +312 -0
- support_code/windows_only_importers/BrukerCompassXtract.py +180 -0
- support_code/windows_only_importers/ThermoMSFileReader.py +405 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Simple examples demonstrating manifest creation utility usage.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from corems.mass_spectra.input.corems_hdf5 import create_manifest_from_folder
|
|
7
|
+
|
|
8
|
+
# Example 1: Basic usage - auto-select middle sample as center
|
|
9
|
+
print("Example 1: Basic usage (middle sample as center)")
|
|
10
|
+
print("-" * 60)
|
|
11
|
+
manifest_path = create_manifest_from_folder(
|
|
12
|
+
folder_path=Path("/Volumes/LaCie/nmdc_data/collection_testing/blanchard_lipid/mini_collection_test_out2"),
|
|
13
|
+
overwrite=True
|
|
14
|
+
)
|
|
15
|
+
print()
|
|
16
|
+
|
|
17
|
+
# Example 2: Custom batch threshold
|
|
18
|
+
print("Example 2: Custom batch threshold (24 hours)")
|
|
19
|
+
print("-" * 60)
|
|
20
|
+
manifest_path = create_manifest_from_folder(
|
|
21
|
+
folder_path=Path("/Volumes/LaCie/nmdc_data/collection_testing/blanchard_lipid/mini_collection_test_out2"),
|
|
22
|
+
output_path=Path("/Volumes/LaCie/nmdc_data/collection_testing/blanchard_lipid/mini_collection_test_out2/manifest_24hr.csv"),
|
|
23
|
+
batch_time_threshold_hours=24.0,
|
|
24
|
+
overwrite=True
|
|
25
|
+
)
|
|
26
|
+
print()
|
|
27
|
+
|
|
28
|
+
# Example 3: Specify a sample as center by name
|
|
29
|
+
print("Example 3: Specify center sample by name")
|
|
30
|
+
print("-" * 60)
|
|
31
|
+
manifest_path = create_manifest_from_folder(
|
|
32
|
+
folder_path=Path("/Volumes/LaCie/nmdc_data/collection_testing/blanchard_lipid/mini_collection_test_out2"),
|
|
33
|
+
output_path=Path("/Volumes/LaCie/nmdc_data/collection_testing/blanchard_lipid/mini_collection_test_out2/manifest_custom_center.csv"),
|
|
34
|
+
batch_time_threshold_hours=12.0,
|
|
35
|
+
center_name="Blanch_Nat_Lip_C_7_AB_M_07_POS_23Jan18_Brandi-WCSH5801",
|
|
36
|
+
overwrite=True
|
|
37
|
+
)
|
|
38
|
+
print()
|
|
39
|
+
|
|
40
|
+
# Example 4: Strict batch threshold
|
|
41
|
+
print("Example 4: Strict batch threshold (1 hour)")
|
|
42
|
+
print("-" * 60)
|
|
43
|
+
manifest_path = create_manifest_from_folder(
|
|
44
|
+
folder_path=Path("/Volumes/LaCie/nmdc_data/collection_testing/blanchard_lipid/mini_collection_test_out2"),
|
|
45
|
+
output_path=Path("/Volumes/LaCie/nmdc_data/collection_testing/blanchard_lipid/mini_collection_test_out2/manifest_1hr.csv"),
|
|
46
|
+
batch_time_threshold_hours=1.0,
|
|
47
|
+
overwrite=True
|
|
48
|
+
)
|
|
49
|
+
print()
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
warnings.filterwarnings("ignore")
|
|
3
|
+
|
|
4
|
+
import sys
|
|
5
|
+
sys.path.append("./")
|
|
6
|
+
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from multiprocessing import Pool
|
|
9
|
+
import cProfile
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
from corems.molecular_id.input.nistMSI import ReadNistMSI
|
|
13
|
+
from corems.mass_spectra.input.andiNetCDF import ReadAndiNetCDF
|
|
14
|
+
from corems.molecular_id.search.compoundSearch import LowResMassSpectralMatch
|
|
15
|
+
from corems.mass_spectra.calc.GC_RI_Calibration import get_rt_ri_pairs
|
|
16
|
+
from support_code.nmdc.filefinder import get_dirname, get_filename
|
|
17
|
+
|
|
18
|
+
import glob
|
|
19
|
+
from nmdc.metadata.nmdc_registration import NMDC_Metadata
|
|
20
|
+
|
|
21
|
+
def start_sql_from_file():
|
|
22
|
+
|
|
23
|
+
ref_lib_path = Path.cwd() / "tests/tests_data/gcms/" / "PNNLMetV20191015.MSL"
|
|
24
|
+
sql_obj = ReadNistMSI(ref_lib_path).get_sqlLite_obj()
|
|
25
|
+
return sql_obj
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_gcms(file_path):
|
|
29
|
+
|
|
30
|
+
reader_gcms = ReadAndiNetCDF(file_path)
|
|
31
|
+
|
|
32
|
+
reader_gcms.run()
|
|
33
|
+
|
|
34
|
+
gcms = reader_gcms.get_gcms_obj()
|
|
35
|
+
|
|
36
|
+
# gcms.process_chromatogram()
|
|
37
|
+
|
|
38
|
+
return gcms
|
|
39
|
+
|
|
40
|
+
def get_reference_dict(calibration_file_path=False):
|
|
41
|
+
|
|
42
|
+
from PySide2.QtWidgets import QFileDialog, QApplication
|
|
43
|
+
from PySide2.QtCore import Qt
|
|
44
|
+
|
|
45
|
+
if not calibration_file_path:
|
|
46
|
+
app = QApplication(sys.argv)
|
|
47
|
+
file_dialog = QFileDialog()
|
|
48
|
+
file_dialog.setWindowFlags(Qt.WindowStaysOnTopHint)
|
|
49
|
+
file_path = file_dialog.getOpenFileName(None, "FAMES REF FILE", filter="*.cdf")[0]
|
|
50
|
+
file_dialog.close()
|
|
51
|
+
app.exit()
|
|
52
|
+
else:
|
|
53
|
+
file_path = calibration_file_path
|
|
54
|
+
|
|
55
|
+
if not file_path:
|
|
56
|
+
return None
|
|
57
|
+
|
|
58
|
+
else:
|
|
59
|
+
|
|
60
|
+
gcms_ref_obj = get_gcms(file_path)
|
|
61
|
+
# sql_obj = start_sql_from_file()
|
|
62
|
+
rt_ri_pairs = get_rt_ri_pairs(gcms_ref_obj) # sql_obj=sql_obj)
|
|
63
|
+
# !!!!!! READ !!!!! use the previous two lines if db/pnnl_lowres_gcms_compounds.sqlite does not exist
|
|
64
|
+
# and comment the next line
|
|
65
|
+
# rt_ri_pairs = get_rt_ri_pairs(gcms_ref_obj)
|
|
66
|
+
|
|
67
|
+
return rt_ri_pairs, file_path
|
|
68
|
+
|
|
69
|
+
def run(args):
|
|
70
|
+
|
|
71
|
+
file_path, ref_dict, cal_file_path = args
|
|
72
|
+
|
|
73
|
+
gcms = get_gcms(file_path)
|
|
74
|
+
|
|
75
|
+
gcms.process_chromatogram()
|
|
76
|
+
|
|
77
|
+
gcms.calibrate_ri(ref_dict, cal_file_path)
|
|
78
|
+
|
|
79
|
+
# sql_obj = start_sql_from_file()
|
|
80
|
+
|
|
81
|
+
lowResSearch = LowResMassSpectralMatch(gcms) # sql_obj=sql_obj)
|
|
82
|
+
# !!!!!! READ !!!!! use the previous two lines if db/pnnl_lowres_gcms_compounds.sqlite does not exist
|
|
83
|
+
# and comment the next line
|
|
84
|
+
# lowResSearch = LowResMassSpectralMatch(gcms)
|
|
85
|
+
lowResSearch.run()
|
|
86
|
+
|
|
87
|
+
return gcms
|
|
88
|
+
|
|
89
|
+
def calibrate_and_search(out_put_file_name, jobs, dms_file_path):
|
|
90
|
+
|
|
91
|
+
from PySide2.QtWidgets import QFileDialog
|
|
92
|
+
from PySide2.QtCore import Qt
|
|
93
|
+
|
|
94
|
+
ref_dict, cal_file_path = get_reference_dict()
|
|
95
|
+
if ref_dict:
|
|
96
|
+
|
|
97
|
+
file_dialog = QFileDialog()
|
|
98
|
+
file_dialog.setWindowFlags(Qt.WindowStaysOnTopHint)
|
|
99
|
+
|
|
100
|
+
if file_dialog:
|
|
101
|
+
|
|
102
|
+
file_locations = file_dialog.getOpenFileNames(None, "Standard Compounds Files", filter="*.cdf")
|
|
103
|
+
file_dialog.close()
|
|
104
|
+
|
|
105
|
+
# run in multiprocessing mode
|
|
106
|
+
pool = Pool(jobs)
|
|
107
|
+
args = [(file_path, ref_dict, cal_file_path) for file_path in file_locations[0]]
|
|
108
|
+
gcmss = pool.map(run, args)
|
|
109
|
+
pool.close()
|
|
110
|
+
pool.join()
|
|
111
|
+
|
|
112
|
+
for file_index, gcms in enumerate(gcmss):
|
|
113
|
+
|
|
114
|
+
file_path = Path(file_locations[0][file_index])
|
|
115
|
+
# print(out_put_file_name)
|
|
116
|
+
|
|
117
|
+
gcms.to_csv(file_path, write_metadata=False, id_label="emsl:")
|
|
118
|
+
nmdc = NMDC_Metadata(file_path, cal_file_path, file_path.with_suffix(".cvs"), dms_file_path)
|
|
119
|
+
nmdc.create_nmdc_gcms_metadata(gcms)
|
|
120
|
+
|
|
121
|
+
# gcms.to_excel(out_put_file_name)
|
|
122
|
+
# gcms.to_pandas(out_put_file_name)
|
|
123
|
+
# gcms.to_hdf()
|
|
124
|
+
|
|
125
|
+
# df = gcms.get_dataframe()
|
|
126
|
+
# json_data = gcms.to_json()
|
|
127
|
+
|
|
128
|
+
# print(json_data)
|
|
129
|
+
|
|
130
|
+
# gcms.plot_processed_chromatogram()
|
|
131
|
+
|
|
132
|
+
# gcms.plot_gc_peaks()
|
|
133
|
+
|
|
134
|
+
# gcms.plot_chromatogram()
|
|
135
|
+
|
|
136
|
+
# gcms.plot_smoothed_chromatogram()
|
|
137
|
+
|
|
138
|
+
# gcms.plot_baseline_subtraction()
|
|
139
|
+
|
|
140
|
+
# gcms.plot_detected_baseline()
|
|
141
|
+
|
|
142
|
+
# matplotlib.pyplot.show()
|
|
143
|
+
|
|
144
|
+
def worker(args):
|
|
145
|
+
|
|
146
|
+
cProfile.runctx('run(args)', globals(), locals(), 'gc-ms.prof')
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
if __name__ == '__main__':
|
|
151
|
+
# import matplotlib
|
|
152
|
+
# matplotlib.use('TkAgg')
|
|
153
|
+
# %%
|
|
154
|
+
cores = 4
|
|
155
|
+
out_put_file_group_name = 'sql_test'
|
|
156
|
+
dms_file_path="db/GC-MS Metabolomics Experiments to Process Final.xlsx"
|
|
157
|
+
calibrate_and_search(out_put_file_group_name, cores, dms_file_path)
|
|
158
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from corems.mass_spectra.input.rawFileReader import ImportMassSpectraThermoMSFileReader
|
|
4
|
+
|
|
5
|
+
if __name__ == "__main__":
|
|
6
|
+
# =============================================================================
|
|
7
|
+
# Configuration
|
|
8
|
+
# =============================================================================
|
|
9
|
+
# Paths
|
|
10
|
+
base_path = Path("/Volumes/LaCie/nmdc_data/collection_testing/dev_test/")
|
|
11
|
+
raw_data_path = base_path / "raw"
|
|
12
|
+
|
|
13
|
+
# Instantiate LCMS object from the first raw data file
|
|
14
|
+
first_raw_file = next(raw_data_path.glob("*.raw"))
|
|
15
|
+
parser = ImportMassSpectraThermoMSFileReader(first_raw_file)
|
|
16
|
+
lcms_obj = parser.get_lcms_obj(spectra="ms1")
|
|
17
|
+
assert lcms_obj is not None, "Failed to instantiate LCMS object."
|
|
18
|
+
|
|
19
|
+
# Set parameters for the LCMS object, only ones we NEED to change from defaults to get things running
|
|
20
|
+
# Ideally, we'd load carefully chosen parameters from a file here for general processing
|
|
21
|
+
lcms_obj.parameters.mass_spectrum['ms2'].mass_spectrum.noise_threshold_method = "relative_abundance"
|
|
22
|
+
|
|
23
|
+
# Prepare a search dictionary for a targeted search
|
|
24
|
+
# Here are examples of target m/z and RT values
|
|
25
|
+
# Could derive this from an msp file.
|
|
26
|
+
target_mz_list = [254.2837, 521.325988, 503.3134460449219, 317.2839050292969]
|
|
27
|
+
target_rt_list = [5.83, 6.017, 7.977, 6.8658]
|
|
28
|
+
target_search_dict = {
|
|
29
|
+
"target_mz_list": target_mz_list,
|
|
30
|
+
"target_rt_list": target_rt_list,
|
|
31
|
+
"mz_tolerance_ppm": 5, #QUESTION: per target or bulk?
|
|
32
|
+
"rt_tolerance": 0.5, #QUESTION: per target or bulk?
|
|
33
|
+
"type": "internal standard"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
# Look for mass features in targeted search mode
|
|
37
|
+
lcms_obj.find_mass_features(
|
|
38
|
+
targeted_search = True,
|
|
39
|
+
target_search_dict=target_search_dict
|
|
40
|
+
)
|
|
41
|
+
# Alternatively, or additionally, we could do normal (untargeted) mass feature finding here
|
|
42
|
+
# lcms_obj.find_mass_features(targeted_search=False)
|
|
43
|
+
|
|
44
|
+
# Let's integrate, add ms1 and ms2
|
|
45
|
+
lcms_obj.integrate_mass_features()
|
|
46
|
+
lcms_obj.add_associated_ms1(use_parser=False, spectrum_mode="profile")
|
|
47
|
+
lcms_obj.add_associated_ms2_dda(use_parser=True, spectrum_mode="centroid")
|
|
48
|
+
|
|
49
|
+
# Here we could do formula searching and MS2 search against a MSP database with MS2s of the search targets (similar to test_lcms_metabolomics.py)
|
|
50
|
+
# BUT, we'd need a compatible msp file, and that's not ultra simple
|
|
51
|
+
|
|
52
|
+
# Check out the mass feature dataframe
|
|
53
|
+
mf_df = lcms_obj.mass_features_to_df(drop_na_cols=True)
|
|
54
|
+
|
|
55
|
+
# Can visualize as well
|
|
56
|
+
lcms_obj.mass_features[0].plot(return_fig = False)
|
|
57
|
+
|
|
58
|
+
# Here could do some post-processing to report the "best hit" per target and include confidence metrics
|
|
59
|
+
print("here")
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from multiprocessing import Pool
|
|
4
|
+
import warnings
|
|
5
|
+
|
|
6
|
+
from corems.molecular_id.search.database_interfaces import MSPInterface
|
|
7
|
+
from corems.mass_spectra.input.corems_hdf5 import ReadCoreMSHDFMassSpectra
|
|
8
|
+
from corems.mass_spectra.output.export import LCMSMetabolomicsExport
|
|
9
|
+
|
|
10
|
+
from support_code.nmdc.lipidomics.lipidomics_workflow import (
|
|
11
|
+
instantiate_lcms_obj,
|
|
12
|
+
set_params_on_lcms_obj,
|
|
13
|
+
check_scan_translator,
|
|
14
|
+
add_mass_features,
|
|
15
|
+
molecular_formula_search,
|
|
16
|
+
process_ms2,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def prepare_metadata(msp_file_path):
|
|
21
|
+
print("Parsing MSP file...")
|
|
22
|
+
my_msp = MSPInterface(file_path=msp_file_path)
|
|
23
|
+
print("Parsing MSP file complete.")
|
|
24
|
+
metadata = {
|
|
25
|
+
"fe": {"positive": None, "negative": None},
|
|
26
|
+
"molecular_metadata": {},
|
|
27
|
+
}
|
|
28
|
+
msp_positive, metabolite_metadata_positive = (
|
|
29
|
+
my_msp.get_metabolomics_spectra_library(
|
|
30
|
+
polarity="positive",
|
|
31
|
+
format="flashentropy",
|
|
32
|
+
normalize=True,
|
|
33
|
+
fe_kwargs={
|
|
34
|
+
"normalize_intensity": True,
|
|
35
|
+
"min_ms2_difference_in_da": 0.02, # for cleaning spectra
|
|
36
|
+
"max_ms2_tolerance_in_da": 0.01, # for setting search space
|
|
37
|
+
"max_indexed_mz": 3000,
|
|
38
|
+
"precursor_ions_removal_da": None,
|
|
39
|
+
"noise_threshold": 0,
|
|
40
|
+
},
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
metadata["fe"]["positive"] = msp_positive
|
|
44
|
+
metadata["molecular_metadata"] = metabolite_metadata_positive
|
|
45
|
+
|
|
46
|
+
msp_negative, metabolite_metadata_negative = (
|
|
47
|
+
my_msp.get_metabolomics_spectra_library(
|
|
48
|
+
polarity="negative",
|
|
49
|
+
format="flashentropy",
|
|
50
|
+
normalize=True,
|
|
51
|
+
fe_kwargs={
|
|
52
|
+
"normalize_intensity": True,
|
|
53
|
+
"min_ms2_difference_in_da": 0.02, # for cleaning spectra
|
|
54
|
+
"max_ms2_tolerance_in_da": 0.01, # for setting search space
|
|
55
|
+
"max_indexed_mz": 3000,
|
|
56
|
+
"precursor_ions_removal_da": None,
|
|
57
|
+
"noise_threshold": 0,
|
|
58
|
+
},
|
|
59
|
+
)
|
|
60
|
+
)
|
|
61
|
+
metadata["fe"]["negative"] = msp_negative
|
|
62
|
+
metadata["molecular_metadata"].update(metabolite_metadata_negative)
|
|
63
|
+
|
|
64
|
+
return metadata
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def export_results(myLCMSobj, out_path, molecular_metadata=None, final=False):
|
|
68
|
+
"""Export results to hdf5 and csv as a lipid report
|
|
69
|
+
|
|
70
|
+
Parameters
|
|
71
|
+
----------
|
|
72
|
+
myLCMSobj : corems LCMS object
|
|
73
|
+
LCMS object to process
|
|
74
|
+
out_path : str or Path
|
|
75
|
+
Path to output file
|
|
76
|
+
molecular_metadata : dict
|
|
77
|
+
Dict with molecular metadata
|
|
78
|
+
final : bool
|
|
79
|
+
Whether to export final results
|
|
80
|
+
|
|
81
|
+
Returns
|
|
82
|
+
-------
|
|
83
|
+
None, exports results to hdf5 and csv as a lipid report
|
|
84
|
+
"""
|
|
85
|
+
exporter = LCMSMetabolomicsExport(out_path, myLCMSobj)
|
|
86
|
+
exporter.to_hdf(overwrite=True)
|
|
87
|
+
if final:
|
|
88
|
+
# Do not show warnings, these are expected
|
|
89
|
+
exporter.report_to_csv(molecular_metadata=molecular_metadata)
|
|
90
|
+
else:
|
|
91
|
+
with warnings.catch_warnings():
|
|
92
|
+
warnings.simplefilter("ignore")
|
|
93
|
+
exporter.report_to_csv()
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def run_ms2_search(out_path, metadata, scan_translator=None):
|
|
97
|
+
"""Run ms2 spectral search and export final results
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
out_path : str or Path
|
|
102
|
+
Path to output file
|
|
103
|
+
metadata : dict
|
|
104
|
+
Dict with keys "mzs", "fe", and "molecular_metadata" with values of dicts of precursor mzs (negative and positive), flash entropy search databases (negative and positive), and molecular metadata, respectively
|
|
105
|
+
|
|
106
|
+
Returns
|
|
107
|
+
-------
|
|
108
|
+
None, runs ms2 spectral search and exports final results
|
|
109
|
+
"""
|
|
110
|
+
# Read in the intermediate results
|
|
111
|
+
out_path = Path(out_path)
|
|
112
|
+
out_path_hdf5 = str(out_path) + ".corems/" + out_path.stem + ".hdf5"
|
|
113
|
+
parser = ReadCoreMSHDFMassSpectra(out_path_hdf5)
|
|
114
|
+
myLCMSobj = parser.get_lcms_obj()
|
|
115
|
+
process_ms2(myLCMSobj, metadata, scan_translator=scan_translator)
|
|
116
|
+
export_results(
|
|
117
|
+
myLCMSobj,
|
|
118
|
+
out_path=str(out_path),
|
|
119
|
+
molecular_metadata=metadata["molecular_metadata"],
|
|
120
|
+
final=True,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def run_lcms_metabolomics_workflow(
|
|
125
|
+
file_in,
|
|
126
|
+
out_path,
|
|
127
|
+
params_toml,
|
|
128
|
+
scan_translator,
|
|
129
|
+
metadata,
|
|
130
|
+
):
|
|
131
|
+
myLCMSobj = instantiate_lcms_obj(file_in)
|
|
132
|
+
set_params_on_lcms_obj(myLCMSobj, params_toml, verbose)
|
|
133
|
+
|
|
134
|
+
# If the ms1 data are centroided, switch the peak picking method to centroided persistent homology
|
|
135
|
+
# and set the noise threshold method to relative abundance
|
|
136
|
+
ms1_scan_df = myLCMSobj.scan_df[myLCMSobj.scan_df.ms_level == 1]
|
|
137
|
+
if all(x == "centroid" for x in ms1_scan_df.ms_format.to_list()):
|
|
138
|
+
# Switch peak picking method to centroided persistent homology
|
|
139
|
+
myLCMSobj.parameters.lc_ms.peak_picking_method = "centroided_persistent_homology"
|
|
140
|
+
myLCMSobj.parameters.mass_spectrum[
|
|
141
|
+
"ms1"
|
|
142
|
+
].mass_spectrum.noise_threshold_method = "relative_abundance"
|
|
143
|
+
|
|
144
|
+
myLCMSobj.parameters.mass_spectrum[
|
|
145
|
+
"ms1"
|
|
146
|
+
].mass_spectrum.noise_threshold_min_relative_abundance = 0.1
|
|
147
|
+
|
|
148
|
+
check_scan_translator(myLCMSobj, scan_translator)
|
|
149
|
+
add_mass_features(myLCMSobj, scan_translator)
|
|
150
|
+
myLCMSobj.remove_unprocessed_data()
|
|
151
|
+
molecular_formula_search(myLCMSobj)
|
|
152
|
+
# Just for testing, not needed for workflow
|
|
153
|
+
export_results(
|
|
154
|
+
myLCMSobj,
|
|
155
|
+
out_path=str(out_path),
|
|
156
|
+
molecular_metadata=metadata["molecular_metadata"],
|
|
157
|
+
final=False,
|
|
158
|
+
)
|
|
159
|
+
process_ms2(myLCMSobj, metadata, scan_translator=scan_translator)
|
|
160
|
+
export_results(
|
|
161
|
+
myLCMSobj,
|
|
162
|
+
out_path=str(out_path),
|
|
163
|
+
molecular_metadata=metadata["molecular_metadata"],
|
|
164
|
+
final=True,
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def run_lcms_metabolomics_workflow_batch(
|
|
169
|
+
file_dir,
|
|
170
|
+
out_dir,
|
|
171
|
+
params_toml,
|
|
172
|
+
msp_file_path,
|
|
173
|
+
scan_translator=None,
|
|
174
|
+
cores=1,
|
|
175
|
+
):
|
|
176
|
+
"""Run the LCMS metabolomics workflow on a batch of files
|
|
177
|
+
|
|
178
|
+
Parameters
|
|
179
|
+
----------
|
|
180
|
+
file_dir : str or Path
|
|
181
|
+
Path to directory with raw files
|
|
182
|
+
out_dir : str or Path
|
|
183
|
+
Path to output directory
|
|
184
|
+
params_toml : str or Path
|
|
185
|
+
Path to toml file with parameters for all samples
|
|
186
|
+
msp_file_path : str or Path
|
|
187
|
+
Path to msp file with spectral library for MS2 search
|
|
188
|
+
scan_translator : str or Path
|
|
189
|
+
Path to toml file with scan translator for MS2 search
|
|
190
|
+
cores : int
|
|
191
|
+
Number of cores to use for processing
|
|
192
|
+
"""
|
|
193
|
+
# Make output dir and get list of files to process
|
|
194
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
195
|
+
files_list = [
|
|
196
|
+
f for f in file_dir.iterdir() if f.suffix.lower() in {".raw", ".mzml"}
|
|
197
|
+
]
|
|
198
|
+
out_paths_list = [out_dir / f.stem for f in files_list]
|
|
199
|
+
|
|
200
|
+
# Prepare search databases for ms2 search
|
|
201
|
+
my_msp_FE = prepare_metadata(msp_file_path)
|
|
202
|
+
|
|
203
|
+
# Run signal processing, get associated ms1, add associated ms2, do ms1 molecular search, and export temp results
|
|
204
|
+
# Note that this is exactly the same as the lipidomics workflow
|
|
205
|
+
if cores == 1 or len(files_list) == 1:
|
|
206
|
+
for file_in, file_out in list(zip(files_list, out_paths_list)):
|
|
207
|
+
print(f"Processing {file_in}")
|
|
208
|
+
run_lcms_metabolomics_workflow(
|
|
209
|
+
file_in=file_in,
|
|
210
|
+
out_path=file_out,
|
|
211
|
+
params_toml=params_toml,
|
|
212
|
+
scan_translator=scan_translator,
|
|
213
|
+
metadata=my_msp_FE,
|
|
214
|
+
)
|
|
215
|
+
elif cores > 1:
|
|
216
|
+
raise ValueError(
|
|
217
|
+
"Parallel processing is not yet supported for LCMS metabolomics workflow."
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
if __name__ == "__main__":
|
|
222
|
+
# Set input variables to run
|
|
223
|
+
msp_file_path = "/Users/heal742/LOCAL/05_NMDC/02_MetaMS/metams/test_data/test_lcms_metab_data/20250407_database.msp"
|
|
224
|
+
# msp_file_path = "/Users/heal742/LOCAL/corems_dev/corems/tests/tests_data/lcms/test_db.msp"
|
|
225
|
+
file_dir = Path(
|
|
226
|
+
"/Users/heal742/Library/CloudStorage/OneDrive-PNNL/Documents/_DMS_data/_NMDC/_massive/_bioscales_lcms/problem"
|
|
227
|
+
)
|
|
228
|
+
params_toml = Path(
|
|
229
|
+
"/Users/heal742/LOCAL/05_NMDC/02_MetaMS/data_processing/_bioscales_lcms_metabolomics/metadata/bioscales_hilic_corems.toml"
|
|
230
|
+
)
|
|
231
|
+
scan_translator = Path(
|
|
232
|
+
"/Users/heal742/LOCAL/05_NMDC/02_MetaMS/data_processing/_bioscales_lcms_metabolomics/metadata/bioscales_scan_translator.toml"
|
|
233
|
+
)
|
|
234
|
+
out_dir = Path("tmp_data/__lcms_metab_test_data_250509")
|
|
235
|
+
verbose = True
|
|
236
|
+
cores = 1
|
|
237
|
+
|
|
238
|
+
# Set up output directory
|
|
239
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
240
|
+
|
|
241
|
+
run_lcms_metabolomics_workflow_batch(
|
|
242
|
+
file_dir=file_dir,
|
|
243
|
+
out_dir=out_dir,
|
|
244
|
+
params_toml=params_toml,
|
|
245
|
+
msp_file_path=msp_file_path,
|
|
246
|
+
scan_translator=scan_translator,
|
|
247
|
+
cores=cores,
|
|
248
|
+
)
|