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,628 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
import time
|
|
3
|
+
import pandas as pd
|
|
4
|
+
import numpy as np
|
|
5
|
+
from multiprocessing import Pool
|
|
6
|
+
import shutil
|
|
7
|
+
|
|
8
|
+
from corems.mass_spectra.input.corems_hdf5 import ReadCoreMSHDFMassSpectraCollection
|
|
9
|
+
from corems.mass_spectra.output.export import LCMSMetabolomicsExport
|
|
10
|
+
from corems.mass_spectra.input.rawFileReader import ImportMassSpectraThermoMSFileReader
|
|
11
|
+
from corems.encapsulation.factory.parameters import LCMSParameters
|
|
12
|
+
from corems.molecular_id.search.database_interfaces import MSPInterface
|
|
13
|
+
from corems.encapsulation.factory.parameters import hush_output
|
|
14
|
+
from corems.mass_spectra.output.export import LCMSCollectionExport
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
Example showing the new pipeline-based sample processing approach.
|
|
18
|
+
|
|
19
|
+
The new approach combines multiple sample-level operations (gap-filling,
|
|
20
|
+
feature reloading, MS1/MS2 searches, etc.) into a single parallelized pass,
|
|
21
|
+
which is more efficient than processing samples multiple times.
|
|
22
|
+
|
|
23
|
+
Two usage patterns:
|
|
24
|
+
1. High-level convenience method: process_consensus_features()
|
|
25
|
+
2. Advanced pipeline builder: process_samples_pipeline() with custom operations
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def summarize_processing_results(lcms_collection):
|
|
29
|
+
"""
|
|
30
|
+
Summarize the processing state of the LCMS collection.
|
|
31
|
+
|
|
32
|
+
Reports on completed processing steps by inspecting the collection
|
|
33
|
+
and sample objects directly. Useful for verifying which operations
|
|
34
|
+
were performed during process_consensus_features().
|
|
35
|
+
|
|
36
|
+
Parameters
|
|
37
|
+
----------
|
|
38
|
+
lcms_collection : LCMSCollection
|
|
39
|
+
The LCMS collection to summarize
|
|
40
|
+
"""
|
|
41
|
+
print("\n" + "="*60)
|
|
42
|
+
print("LCMS Collection Processing Summary")
|
|
43
|
+
print("="*60)
|
|
44
|
+
|
|
45
|
+
# Basic collection info
|
|
46
|
+
n_samples = len(lcms_collection)
|
|
47
|
+
|
|
48
|
+
# Collection-level feature count (from dataframe - all features)
|
|
49
|
+
collection_mf_count = len(lcms_collection.mass_features_dataframe) if lcms_collection.mass_features_dataframe is not None else 0
|
|
50
|
+
|
|
51
|
+
# Sample-level loaded feature count (from mass_features dict - loaded for processing)
|
|
52
|
+
loaded_mf_count = sum(len(lcms_obj.mass_features) for lcms_obj in lcms_collection)
|
|
53
|
+
|
|
54
|
+
# Cluster count
|
|
55
|
+
if 'cluster' in lcms_collection.mass_features_dataframe.columns:
|
|
56
|
+
n_clusters = lcms_collection.mass_features_dataframe['cluster'].nunique()
|
|
57
|
+
else:
|
|
58
|
+
n_clusters = 0
|
|
59
|
+
|
|
60
|
+
print(f"\nSamples: {n_samples}")
|
|
61
|
+
print(f"Total features in collection: {collection_mf_count}")
|
|
62
|
+
print(f"Representative features loaded: {loaded_mf_count}")
|
|
63
|
+
if n_clusters > 0:
|
|
64
|
+
print(f"Consensus clusters: {n_clusters}")
|
|
65
|
+
|
|
66
|
+
# Gap filling - check for induced mass features
|
|
67
|
+
induced_counts = [len(lcms_obj.induced_mass_features) for lcms_obj in lcms_collection]
|
|
68
|
+
total_induced = sum(induced_counts)
|
|
69
|
+
samples_with_induced = sum(1 for c in induced_counts if c > 0)
|
|
70
|
+
if total_induced > 0:
|
|
71
|
+
print(f"\nGap Filling: ✓ Complete")
|
|
72
|
+
print(f" {samples_with_induced}/{n_samples} samples have induced features ({total_induced} total)")
|
|
73
|
+
|
|
74
|
+
# Feature loading - check if mass features have MS1/MS2 spectra
|
|
75
|
+
mf_with_ms1 = 0
|
|
76
|
+
mf_with_ms2 = 0
|
|
77
|
+
mf_with_ms2_scans = 0
|
|
78
|
+
total_ms2_spectra = 0
|
|
79
|
+
total_ms2_scan_numbers = 0
|
|
80
|
+
|
|
81
|
+
for lcms_obj in lcms_collection:
|
|
82
|
+
for mf in lcms_obj.mass_features.values():
|
|
83
|
+
if hasattr(mf, 'mass_spectrum') and mf.mass_spectrum is not None:
|
|
84
|
+
mf_with_ms1 += 1
|
|
85
|
+
if hasattr(mf, 'ms2_mass_spectra') and mf.ms2_mass_spectra:
|
|
86
|
+
mf_with_ms2 += 1
|
|
87
|
+
total_ms2_spectra += len(mf.ms2_mass_spectra)
|
|
88
|
+
if hasattr(mf, 'ms2_scan_numbers') and mf.ms2_scan_numbers is not None and len(mf.ms2_scan_numbers) > 0:
|
|
89
|
+
mf_with_ms2_scans += 1
|
|
90
|
+
total_ms2_scan_numbers += len(mf.ms2_scan_numbers)
|
|
91
|
+
|
|
92
|
+
if mf_with_ms1 > 0 or mf_with_ms2 > 0:
|
|
93
|
+
print(f"\nMS Data Association: ✓ Complete")
|
|
94
|
+
if mf_with_ms1 > 0:
|
|
95
|
+
print(f" MS1: {mf_with_ms1}/{loaded_mf_count} loaded features ({mf_with_ms1/loaded_mf_count*100:.1f}%)")
|
|
96
|
+
if mf_with_ms2 > 0:
|
|
97
|
+
print(f" MS2: {mf_with_ms2}/{loaded_mf_count} loaded features ({total_ms2_spectra} spectra)")
|
|
98
|
+
if mf_with_ms2_scans > 0:
|
|
99
|
+
print(f" MS2 scan numbers: {mf_with_ms2_scans}/{loaded_mf_count} loaded features ({total_ms2_scan_numbers} scans)")
|
|
100
|
+
|
|
101
|
+
# Molecular formula search
|
|
102
|
+
mf_with_formulas = 0
|
|
103
|
+
total_formulas = 0
|
|
104
|
+
|
|
105
|
+
for lcms_obj in lcms_collection:
|
|
106
|
+
for mf in lcms_obj.mass_features.values():
|
|
107
|
+
if hasattr(mf, 'mass_spectrum') and mf.mass_spectrum is not None:
|
|
108
|
+
try:
|
|
109
|
+
ms1_peak = mf.ms1_peak
|
|
110
|
+
if hasattr(ms1_peak, 'molecular_formulas') and ms1_peak.molecular_formulas:
|
|
111
|
+
mf_with_formulas += 1
|
|
112
|
+
total_formulas += len(ms1_peak.molecular_formulas)
|
|
113
|
+
except (AttributeError, IndexError):
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
if mf_with_formulas > 0:
|
|
117
|
+
print(f"\nMolecular Formula Search: ✓ Complete")
|
|
118
|
+
print(f" {mf_with_formulas}/{loaded_mf_count} loaded features assigned ({total_formulas} total formulas)")
|
|
119
|
+
print(f" Average {total_formulas/mf_with_formulas:.1f} formulas per feature")
|
|
120
|
+
|
|
121
|
+
# MS2 spectral search
|
|
122
|
+
mf_with_spectral_matches = 0
|
|
123
|
+
total_spectral_matches = 0
|
|
124
|
+
scans_searched = 0
|
|
125
|
+
|
|
126
|
+
for lcms_obj in lcms_collection:
|
|
127
|
+
if hasattr(lcms_obj, 'spectral_search_results') and lcms_obj.spectral_search_results:
|
|
128
|
+
scans_searched += len(lcms_obj.spectral_search_results)
|
|
129
|
+
|
|
130
|
+
for mf in lcms_obj.mass_features.values():
|
|
131
|
+
if hasattr(mf, 'ms2_similarity_results') and mf.ms2_similarity_results:
|
|
132
|
+
mf_with_spectral_matches += 1
|
|
133
|
+
total_spectral_matches += len(mf.ms2_similarity_results)
|
|
134
|
+
|
|
135
|
+
if mf_with_spectral_matches > 0:
|
|
136
|
+
print(f"\nMS2 Spectral Search: ✓ Complete")
|
|
137
|
+
print(f" {scans_searched} MS2 scans with library search results")
|
|
138
|
+
print(f" {mf_with_spectral_matches}/{loaded_mf_count} loaded features matched ({total_spectral_matches} total matches)")
|
|
139
|
+
if hasattr(lcms_collection, 'spectral_search_molecular_metadata'):
|
|
140
|
+
print(f" Library size: {len(lcms_collection.spectral_search_molecular_metadata)} entries")
|
|
141
|
+
|
|
142
|
+
# Check for loaded EICs
|
|
143
|
+
total_eics_loaded = 0
|
|
144
|
+
samples_with_eics = 0
|
|
145
|
+
|
|
146
|
+
for lcms_obj in lcms_collection:
|
|
147
|
+
if hasattr(lcms_obj, 'eics') and lcms_obj.eics:
|
|
148
|
+
samples_with_eics += 1
|
|
149
|
+
total_eics_loaded += len(lcms_obj.eics)
|
|
150
|
+
|
|
151
|
+
if total_eics_loaded > 0:
|
|
152
|
+
print(f"\nEIC Loading: ✓ Complete")
|
|
153
|
+
print(f" {total_eics_loaded} EICs loaded across {samples_with_eics}/{n_samples} samples")
|
|
154
|
+
print(f" Average {total_eics_loaded/samples_with_eics:.1f} EICs per sample")
|
|
155
|
+
|
|
156
|
+
# Memory management check
|
|
157
|
+
raw_data_present = any(1 in lcms_obj._ms_unprocessed and not lcms_obj._ms_unprocessed[1].empty
|
|
158
|
+
for lcms_obj in lcms_collection)
|
|
159
|
+
if not raw_data_present:
|
|
160
|
+
print(f"\nMemory: ✓ Raw MS1 data cleaned")
|
|
161
|
+
|
|
162
|
+
print("\n" + "="*60)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def validate_save_load(lcms_collection, collection_save_path, ncores=1):
|
|
166
|
+
"""
|
|
167
|
+
Validate that the LCMS collection can be saved and reloaded correctly.
|
|
168
|
+
|
|
169
|
+
This function tests the save/load functionality by reloading the collection
|
|
170
|
+
from HDF5 and comparing various attributes to ensure data integrity.
|
|
171
|
+
|
|
172
|
+
Parameters
|
|
173
|
+
----------
|
|
174
|
+
lcms_collection : LCMSCollection
|
|
175
|
+
The original LCMS collection to validate against
|
|
176
|
+
collection_save_path : Path
|
|
177
|
+
Path to the saved collection HDF5 file (without extension)
|
|
178
|
+
ncores : int, optional
|
|
179
|
+
Number of cores to use for loading. Default is 1.
|
|
180
|
+
|
|
181
|
+
Returns
|
|
182
|
+
-------
|
|
183
|
+
LCMSCollection
|
|
184
|
+
The reloaded LCMS collection for further testing
|
|
185
|
+
"""
|
|
186
|
+
print("\n" + "="*60)
|
|
187
|
+
print("SAVE/LOAD VALIDATION TEST")
|
|
188
|
+
print("="*60)
|
|
189
|
+
|
|
190
|
+
# Reload the collection from HDF5
|
|
191
|
+
from corems.mass_spectra.input.corems_hdf5 import ReadSavedLCMSCollection
|
|
192
|
+
reader = ReadSavedLCMSCollection(
|
|
193
|
+
collection_hdf5_path=str(collection_save_path.with_suffix('.hdf5')),
|
|
194
|
+
cores=ncores)
|
|
195
|
+
lcms_collection2 = reader.get_lcms_collection(
|
|
196
|
+
load_raw=False, load_light=True,
|
|
197
|
+
load_representatives=True, load_eics=True,
|
|
198
|
+
load_ms1=True, load_ms2=True)
|
|
199
|
+
|
|
200
|
+
# Check that len of mass features matches
|
|
201
|
+
mf_count_1 = len(lcms_collection.mass_features_dataframe)
|
|
202
|
+
mf_count_2 = len(lcms_collection2.mass_features_dataframe)
|
|
203
|
+
if mf_count_1 == mf_count_2:
|
|
204
|
+
print(f"✓ Mass feature count matches after reload: {mf_count_1}")
|
|
205
|
+
else:
|
|
206
|
+
print(f"✗ Mass feature count mismatch after reload! Original: {mf_count_1}, Reloaded: {mf_count_2}")
|
|
207
|
+
|
|
208
|
+
# Check that the len of induced mass features matches
|
|
209
|
+
induced_count_1 = len(lcms_collection.induced_mass_features_dataframe)
|
|
210
|
+
induced_count_2 = len(lcms_collection2.induced_mass_features_dataframe)
|
|
211
|
+
if induced_count_1 == induced_count_2:
|
|
212
|
+
print(f"✓ Induced mass feature count matches after reload: {induced_count_1}")
|
|
213
|
+
else:
|
|
214
|
+
print(f"✗ Induced mass feature count mismatch after reload! Original: {induced_count_1}, Reloaded: {induced_count_2}")
|
|
215
|
+
|
|
216
|
+
# Check that the len of loaded EICs matches
|
|
217
|
+
total_eics_1 = sum(len(lcms_obj.eics) for lcms_obj in lcms_collection)
|
|
218
|
+
total_eics_2 = sum(len(lcms_obj.eics) for lcms_obj in lcms_collection2)
|
|
219
|
+
if total_eics_1 == total_eics_2:
|
|
220
|
+
print(f"✓ Total loaded EIC count matches after reload: {total_eics_1}")
|
|
221
|
+
else:
|
|
222
|
+
print(f"✗ Total loaded EIC count mismatch after reload! Original: {total_eics_1}, Reloaded: {total_eics_2}")
|
|
223
|
+
|
|
224
|
+
# Check that the _ms dictionary matches (mass spectra loaded)
|
|
225
|
+
total_ms_1 = sum(len(lcms_obj._ms) for lcms_obj in lcms_collection)
|
|
226
|
+
total_ms_2 = sum(len(lcms_obj._ms) for lcms_obj in lcms_collection2)
|
|
227
|
+
if total_ms_1 == total_ms_2:
|
|
228
|
+
print(f"✓ Total loaded mass spectra (_ms) count matches after reload: {total_ms_1}")
|
|
229
|
+
else:
|
|
230
|
+
print(f"✗ Total loaded mass spectra (_ms) count mismatch after reload! Original: {total_ms_1}, Reloaded: {total_ms_2}")
|
|
231
|
+
|
|
232
|
+
# Check that we can replot the first cluster from the reloaded collection
|
|
233
|
+
if len(lcms_collection2.cluster_summary_dataframe) > 0:
|
|
234
|
+
first_cluster_id = lcms_collection2.cluster_summary_dataframe.index[0]
|
|
235
|
+
print(f"Re-plotting cluster {first_cluster_id} from reloaded collection")
|
|
236
|
+
lcms_collection2.plot_cluster(
|
|
237
|
+
cluster_id=first_cluster_id,
|
|
238
|
+
to_plot=["EIC", "MS1", "MS2"],
|
|
239
|
+
plot_smoothed_eic=False,
|
|
240
|
+
plot_eic_datapoints=False
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
# Check that scan numbers in _ms match for first sample
|
|
244
|
+
if len(lcms_collection) > 0 and len(lcms_collection2) > 0:
|
|
245
|
+
ms_scans_1 = set(lcms_collection[0]._ms.keys())
|
|
246
|
+
ms_scans_2 = set(lcms_collection2[0]._ms.keys())
|
|
247
|
+
if ms_scans_1 == ms_scans_2:
|
|
248
|
+
print(f"✓ Mass spectra scan numbers match for first sample: {len(ms_scans_1)} scans")
|
|
249
|
+
else:
|
|
250
|
+
print(f"✗ Mass spectra scan numbers mismatch for first sample!")
|
|
251
|
+
print(f" Original: {len(ms_scans_1)} scans, Reloaded: {len(ms_scans_2)} scans")
|
|
252
|
+
only_in_1 = ms_scans_1 - ms_scans_2
|
|
253
|
+
only_in_2 = ms_scans_2 - ms_scans_1
|
|
254
|
+
if only_in_1:
|
|
255
|
+
print(f" Only in original: {list(sorted(only_in_1))[:10]}...")
|
|
256
|
+
if only_in_2:
|
|
257
|
+
print(f" Only in reloaded: {list(sorted(only_in_2))[:10]}...")
|
|
258
|
+
|
|
259
|
+
print("\n" + "="*60)
|
|
260
|
+
|
|
261
|
+
return lcms_collection2
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def preprocess_raw_samples(raw_data_path, processed_folder, ncores=1, reprocess=False):
|
|
265
|
+
"""
|
|
266
|
+
Preprocess raw LCMS sample files into HDF5 format.
|
|
267
|
+
|
|
268
|
+
Parameters
|
|
269
|
+
----------
|
|
270
|
+
raw_data_path : Path
|
|
271
|
+
Path to folder containing raw data files
|
|
272
|
+
processed_folder : Path
|
|
273
|
+
Path to folder where processed HDF5 files will be saved
|
|
274
|
+
ncores : int, optional
|
|
275
|
+
Number of cores to use for parallel processing. Default is 1.
|
|
276
|
+
reprocess : bool, optional
|
|
277
|
+
If True, deletes existing processed folder and reprocesses all files.
|
|
278
|
+
If False, skips preprocessing. Default is False.
|
|
279
|
+
|
|
280
|
+
Returns
|
|
281
|
+
-------
|
|
282
|
+
list or None
|
|
283
|
+
List of processed HDF5 file paths if reprocess=True, None otherwise
|
|
284
|
+
"""
|
|
285
|
+
if not reprocess:
|
|
286
|
+
print("\n=== Skipping sample preprocessing (using existing processed data) ===")
|
|
287
|
+
return None
|
|
288
|
+
|
|
289
|
+
# Delete existing processed dir if reprocessing
|
|
290
|
+
if processed_folder.exists():
|
|
291
|
+
shutil.rmtree(processed_folder)
|
|
292
|
+
|
|
293
|
+
# Create processed folder
|
|
294
|
+
processed_folder.mkdir(parents=True, exist_ok=True)
|
|
295
|
+
|
|
296
|
+
# Find all raw files (adjust extension based on your data format)
|
|
297
|
+
raw_files = list(raw_data_path.glob("*.raw")) + list(raw_data_path.glob("*.mzML"))
|
|
298
|
+
|
|
299
|
+
if not raw_files:
|
|
300
|
+
raise ValueError(f"No raw files found in {raw_data_path}")
|
|
301
|
+
|
|
302
|
+
print(f"\n=== Preprocessing {len(raw_files)} samples in parallel using {ncores} cores ===")
|
|
303
|
+
start_time = time.time()
|
|
304
|
+
|
|
305
|
+
# Get configured parameters once (will be shared across all workers)
|
|
306
|
+
params = get_configured_lcms_parameters()
|
|
307
|
+
|
|
308
|
+
# Prepare arguments for parallel processing
|
|
309
|
+
process_args = [(raw_file, processed_folder, params) for raw_file in raw_files]
|
|
310
|
+
|
|
311
|
+
# Process samples in parallel
|
|
312
|
+
with Pool(processes=ncores) as pool:
|
|
313
|
+
processed_files = pool.map(process_single_sample, process_args)
|
|
314
|
+
|
|
315
|
+
print(f"Preprocessing complete: {time.time() - start_time:.1f} seconds using {ncores} cores")
|
|
316
|
+
print(f"Processed {len(processed_files)} samples\n")
|
|
317
|
+
|
|
318
|
+
return processed_files
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def get_configured_lcms_parameters():
|
|
322
|
+
"""
|
|
323
|
+
Create and configure LCMSParameters for sample processing.
|
|
324
|
+
|
|
325
|
+
Returns
|
|
326
|
+
-------
|
|
327
|
+
LCMSParameters
|
|
328
|
+
Configured parameters object with all processing settings
|
|
329
|
+
"""
|
|
330
|
+
# Suppress verbose output before creating parameters
|
|
331
|
+
hush_output()
|
|
332
|
+
|
|
333
|
+
# Create parameters (use_defaults=False respects hush_output)
|
|
334
|
+
params = LCMSParameters()
|
|
335
|
+
|
|
336
|
+
# Persistent homology parameters
|
|
337
|
+
params.lc_ms.peak_picking_method = "persistent homology"
|
|
338
|
+
params.lc_ms.ph_inten_min_rel = 0.0005
|
|
339
|
+
params.lc_ms.ph_persis_min_rel = 0.01
|
|
340
|
+
params.lc_ms.ph_smooth_it = 0
|
|
341
|
+
params.lc_ms.ms2_min_fe_score = 0.3
|
|
342
|
+
params.lc_ms.ms1_scans_to_average = 1
|
|
343
|
+
|
|
344
|
+
# MSParameters for ms1 mass spectra
|
|
345
|
+
ms1_params = params.mass_spectrum['ms1']
|
|
346
|
+
ms1_params.mass_spectrum.noise_threshold_method = "relative_abundance"
|
|
347
|
+
ms1_params.mass_spectrum.noise_threshold_min_relative_abundance = 0.1
|
|
348
|
+
ms1_params.mass_spectrum.noise_min_mz = 0
|
|
349
|
+
ms1_params.mass_spectrum.min_picking_mz = 0
|
|
350
|
+
ms1_params.mass_spectrum.noise_max_mz = np.inf
|
|
351
|
+
ms1_params.mass_spectrum.max_picking_mz = np.inf
|
|
352
|
+
ms1_params.ms_peak.legacy_resolving_power = False
|
|
353
|
+
ms1_params.molecular_search.url_database = ""
|
|
354
|
+
ms1_params.molecular_search.usedAtoms = {
|
|
355
|
+
'C': (5, 30),
|
|
356
|
+
'H': (18, 200),
|
|
357
|
+
'O': (1, 23),
|
|
358
|
+
'N': (0, 3),
|
|
359
|
+
'P': (0, 1),
|
|
360
|
+
'S': (0, 1),
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
# Settings for ms2 data (HCD scans)
|
|
364
|
+
ms2_params_hcd = ms1_params.copy()
|
|
365
|
+
params.mass_spectrum['ms2'] = ms2_params_hcd
|
|
366
|
+
|
|
367
|
+
# Reporting settings
|
|
368
|
+
params.lc_ms.export_eics = True
|
|
369
|
+
params.lc_ms.export_profile_spectra = False
|
|
370
|
+
|
|
371
|
+
# Peak metrics filtering settings
|
|
372
|
+
params.lc_ms.remove_mass_features_by_peak_metrics = True
|
|
373
|
+
params.lc_ms.mass_feature_attribute_filter_dict = {
|
|
374
|
+
'dispersity_index': {'value': 0.5, 'operator': '<'}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
return params
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def process_single_sample(args):
|
|
381
|
+
"""
|
|
382
|
+
Process a single LCMS sample file.
|
|
383
|
+
|
|
384
|
+
Parameters, params)
|
|
385
|
+
|
|
386
|
+
Returns
|
|
387
|
+
-------
|
|
388
|
+
str
|
|
389
|
+
Path to the processed HDF5 file
|
|
390
|
+
"""
|
|
391
|
+
raw_file_path, processed_folder, params = args
|
|
392
|
+
|
|
393
|
+
# Import the raw data
|
|
394
|
+
print(f"Processing {raw_file_path.name}...\n")
|
|
395
|
+
parser = ImportMassSpectraThermoMSFileReader(str(raw_file_path))
|
|
396
|
+
lcms_obj = parser.get_lcms_obj(spectra="ms1")
|
|
397
|
+
|
|
398
|
+
# Use the pre-configured parameters
|
|
399
|
+
lcms_obj.parameters = params
|
|
400
|
+
|
|
401
|
+
# Get configured parameters
|
|
402
|
+
lcms_obj.parameters = get_configured_lcms_parameters()
|
|
403
|
+
|
|
404
|
+
# Use persistent homology to find mass features in the lc-ms data and integrate
|
|
405
|
+
# Assign MS2 scan numbers during peak picking for choosing representatives with MS2
|
|
406
|
+
lcms_obj.find_mass_features(assign_ms2_scans=True, ms2_scan_filter=None)
|
|
407
|
+
lcms_obj.integrate_mass_features(drop_if_fail=True)
|
|
408
|
+
|
|
409
|
+
# Add peak metrics and filter mass features based on the new parameters
|
|
410
|
+
lcms_obj.add_peak_metrics(remove_by_metrics=True)
|
|
411
|
+
|
|
412
|
+
# Save to HDF5
|
|
413
|
+
output_name = raw_file_path.stem
|
|
414
|
+
exporter = LCMSMetabolomicsExport(str(processed_folder / output_name), lcms_obj)
|
|
415
|
+
exporter.to_hdf(overwrite=True)
|
|
416
|
+
|
|
417
|
+
print(f"✓ Completed {raw_file_path.name} - {len(lcms_obj.mass_features)} mass features")
|
|
418
|
+
return str(processed_folder / f"{output_name}.hdf5")
|
|
419
|
+
|
|
420
|
+
if __name__ == "__main__":
|
|
421
|
+
# =============================================================================
|
|
422
|
+
# Configuration
|
|
423
|
+
# =============================================================================
|
|
424
|
+
ncores = 1
|
|
425
|
+
reprocess_samples = False # Set to True to reprocess raw data
|
|
426
|
+
perform_ms2_search = True # Set to True to perform MS2 spectral library search
|
|
427
|
+
|
|
428
|
+
# Paths
|
|
429
|
+
base_path = Path("/Volumes/LaCie/nmdc_data/collection_testing/dev_test/")
|
|
430
|
+
collection_save_path = base_path / "collection"
|
|
431
|
+
raw_data_path = base_path / "raw"
|
|
432
|
+
processed_folder = base_path / "processed2"
|
|
433
|
+
msp_file_location = Path("/Users/heal742/LOCAL/05_NMDC/02_MetaMS/metams/test_data/test_lcms_metab_data/20250407_database.msp")
|
|
434
|
+
new_raw_data_path = raw_data_path # Update raw file paths in collection if moved after the first step
|
|
435
|
+
|
|
436
|
+
# =============================================================================
|
|
437
|
+
# Step 1: Preprocess Individual Samples (Optional)
|
|
438
|
+
# =============================================================================
|
|
439
|
+
if reprocess_samples:
|
|
440
|
+
print("\n=== Preprocessing Raw Samples and Doing Initial Peak Picking===")
|
|
441
|
+
preprocess_raw_samples(
|
|
442
|
+
raw_data_path=raw_data_path,
|
|
443
|
+
processed_folder=processed_folder,
|
|
444
|
+
ncores=ncores,
|
|
445
|
+
reprocess=reprocess_samples
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
# =============================================================================
|
|
449
|
+
# Step 2: Load LCMS Collection
|
|
450
|
+
# =============================================================================
|
|
451
|
+
print("\n=== Loading LCMS Collection ===")
|
|
452
|
+
parser = ReadCoreMSHDFMassSpectraCollection(
|
|
453
|
+
folder_location=processed_folder,
|
|
454
|
+
cores=ncores
|
|
455
|
+
)
|
|
456
|
+
print(f"Found {len(parser.manifest)} samples")
|
|
457
|
+
|
|
458
|
+
# Load collection (light loading for efficiency)
|
|
459
|
+
start_time = time.time()
|
|
460
|
+
lcms_collection = parser.get_lcms_collection(load_raw=False, load_light=True)
|
|
461
|
+
print(f"Loaded in {time.time() - start_time:.1f} seconds")
|
|
462
|
+
print(f"Total mass features: {len(lcms_collection.mass_features_dataframe)}")
|
|
463
|
+
|
|
464
|
+
# Update raw file locations
|
|
465
|
+
lcms_collection.update_raw_file_locations(new_raw_folder=str(new_raw_data_path))
|
|
466
|
+
|
|
467
|
+
# =============================================================================
|
|
468
|
+
# Step 3: Align Retention Times Across Samples
|
|
469
|
+
# =============================================================================
|
|
470
|
+
print("\n=== Aligning Retention Times ===")
|
|
471
|
+
start_time = time.time()
|
|
472
|
+
lcms_collection.align_lcms_objects()
|
|
473
|
+
print(f"Alignment complete: {time.time() - start_time:.1f} seconds")
|
|
474
|
+
|
|
475
|
+
# =============================================================================
|
|
476
|
+
# Step 4: Generate Consensus Mass Features
|
|
477
|
+
# =============================================================================
|
|
478
|
+
print("\n=== Generating Consensus Mass Features ===")
|
|
479
|
+
start_time = time.time()
|
|
480
|
+
lcms_collection.add_consensus_mass_features()
|
|
481
|
+
print(f"Generated {len(lcms_collection.cluster_summary_dataframe)} consensus clusters")
|
|
482
|
+
print(f"Consensus generation: {time.time() - start_time:.1f} seconds")
|
|
483
|
+
|
|
484
|
+
# =============================================================================
|
|
485
|
+
# Step 5: Prepare MS2 Spectral Library
|
|
486
|
+
# =============================================================================
|
|
487
|
+
if perform_ms2_search:
|
|
488
|
+
print("\n=== Preparing MS2 Spectral Library ===")
|
|
489
|
+
my_msp = MSPInterface(file_path=msp_file_location)
|
|
490
|
+
spectral_lib, molecular_metadata = my_msp.get_metabolomics_spectra_library(
|
|
491
|
+
polarity="positive",
|
|
492
|
+
format="flashentropy",
|
|
493
|
+
normalize=True,
|
|
494
|
+
fe_kwargs={
|
|
495
|
+
"normalize_intensity": True,
|
|
496
|
+
"min_ms2_difference_in_da": 0.02,
|
|
497
|
+
"max_ms2_tolerance_in_da": 0.01,
|
|
498
|
+
"max_indexed_mz": 3000,
|
|
499
|
+
"precursor_ions_removal_da": None,
|
|
500
|
+
"noise_threshold": 0,
|
|
501
|
+
},
|
|
502
|
+
)
|
|
503
|
+
print(f"Loaded spectral library: {len(molecular_metadata)} entries")
|
|
504
|
+
else:
|
|
505
|
+
spectral_lib = None
|
|
506
|
+
molecular_metadata = None
|
|
507
|
+
print("Skipping MS2 spectral library preparation")
|
|
508
|
+
|
|
509
|
+
# =============================================================================
|
|
510
|
+
# Step 6: Process Consensus Features with Integrated Pipeline
|
|
511
|
+
# =============================================================================
|
|
512
|
+
print("\n=== Processing Consensus Features ===")
|
|
513
|
+
start_time = time.time()
|
|
514
|
+
pipeline_results = lcms_collection.process_consensus_features(
|
|
515
|
+
load_representatives=True,
|
|
516
|
+
perform_gap_filling=True,
|
|
517
|
+
add_ms1=True,
|
|
518
|
+
add_ms2=True,
|
|
519
|
+
molecular_formula_search=True,
|
|
520
|
+
ms2_spectral_search=perform_ms2_search,
|
|
521
|
+
spectral_lib=spectral_lib,
|
|
522
|
+
molecular_metadata=molecular_metadata,
|
|
523
|
+
gather_eics=True,
|
|
524
|
+
keep_raw_data=False
|
|
525
|
+
)
|
|
526
|
+
print(f"Pipeline complete: {time.time() - start_time:.1f} seconds using {ncores} cores")
|
|
527
|
+
|
|
528
|
+
# =============================================================================
|
|
529
|
+
# Step 6.5: Test Consensus Cluster Plotting
|
|
530
|
+
# =============================================================================
|
|
531
|
+
print("\n=== Testing Consensus Cluster Plotting ===")
|
|
532
|
+
|
|
533
|
+
# Plot the first cluster as a test
|
|
534
|
+
if len(lcms_collection.cluster_summary_dataframe) > 0:
|
|
535
|
+
first_cluster_id = lcms_collection.cluster_summary_dataframe.index[0]
|
|
536
|
+
# 3116 is a good one to look at :)
|
|
537
|
+
print(f"Plotting cluster {first_cluster_id}")
|
|
538
|
+
lcms_collection.plot_cluster(
|
|
539
|
+
cluster_id=first_cluster_id,
|
|
540
|
+
to_plot=["EIC", "MS1", "MS2"],
|
|
541
|
+
plot_smoothed_eic=False,
|
|
542
|
+
plot_eic_datapoints=False
|
|
543
|
+
)
|
|
544
|
+
|
|
545
|
+
# =============================================================================
|
|
546
|
+
# Step 7: Summarize Processing Results
|
|
547
|
+
# =============================================================================
|
|
548
|
+
summarize_processing_results(lcms_collection)
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
# =============================================================================
|
|
552
|
+
# Step 8: Save and Export Results
|
|
553
|
+
# =============================================================================
|
|
554
|
+
print("\n=== Exporting LCMS Collection ===")
|
|
555
|
+
# Create pivot tables summarizing the collection across samples
|
|
556
|
+
pivot_table_intensity = lcms_collection.collection_pivot_table(attribute='intensity', verbose=False)
|
|
557
|
+
pivot_table_ids = lcms_collection.collection_pivot_table(verbose=False)
|
|
558
|
+
pivot_table_intensity.to_csv("example_collection_pivot_intensity.csv")
|
|
559
|
+
|
|
560
|
+
# Describe each cluster with its representative mass feature
|
|
561
|
+
cluster_reps = lcms_collection.cluster_representatives_table()
|
|
562
|
+
cluster_reps.to_csv("example_cluster_representatives.csv", index=False)
|
|
563
|
+
print(f"Cluster representatives table: {len(cluster_reps)} clusters")
|
|
564
|
+
|
|
565
|
+
# Summarize the annotations for each cluster
|
|
566
|
+
feature_annotations = lcms_collection.feature_annotations_table(
|
|
567
|
+
molecular_metadata=molecular_metadata,
|
|
568
|
+
drop_unannotated=True
|
|
569
|
+
)
|
|
570
|
+
print(f"Feature annotations table: {len(feature_annotations)} rows across {feature_annotations['cluster'].nunique()} clusters")
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
# Plot the first mass feature with an annotation with MS2_mirror
|
|
574
|
+
if not feature_annotations.empty:
|
|
575
|
+
# Find first annotated cluster with non-null value in ref_ms_id
|
|
576
|
+
first_annotated_cluster = feature_annotations.loc[
|
|
577
|
+
feature_annotations['ref_ms_id'].notnull(), 'cluster'
|
|
578
|
+
].iloc[0]
|
|
579
|
+
print(f"Plotting annotated feature for cluster {first_annotated_cluster}")
|
|
580
|
+
lcms_collection.plot_cluster(
|
|
581
|
+
cluster_id=first_annotated_cluster,
|
|
582
|
+
to_plot=["EIC", "MS1", "MS2_mirror"],
|
|
583
|
+
molecular_metadata=molecular_metadata,
|
|
584
|
+
spectral_library=spectral_lib
|
|
585
|
+
)
|
|
586
|
+
|
|
587
|
+
# Save the feature annotations table to CSV for inspection
|
|
588
|
+
feature_annotations.to_csv("example_feature_annotations.csv", index=False)
|
|
589
|
+
|
|
590
|
+
# Save the entire collection to HDF5
|
|
591
|
+
exporter = LCMSCollectionExport(
|
|
592
|
+
out_file_path=str(collection_save_path),
|
|
593
|
+
mass_spectra_collection=lcms_collection)
|
|
594
|
+
exporter.export_to_hdf5(overwrite=True, save_parameters=True, parameter_format="toml")
|
|
595
|
+
|
|
596
|
+
# =============================================================================
|
|
597
|
+
# Step 9: Validate Save/Load Functionality
|
|
598
|
+
# =============================================================================
|
|
599
|
+
lcms_collection2 = validate_save_load(lcms_collection, collection_save_path, ncores=ncores)
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
"""
|
|
603
|
+
# Make some more plots
|
|
604
|
+
lcms_collection.plot_mz_features_across_samples()
|
|
605
|
+
lcms_collection.plot_mz_features_per_cluster()
|
|
606
|
+
lcms_collection.plot_consensus_mz_features() ## zoomed out
|
|
607
|
+
lcms_collection.plot_consensus_mz_features(xb = 10, xt = 15, yb = 500, yt = 600) ## zoomed in
|
|
608
|
+
lcms_collection.cluster_inspection_plot(0)
|
|
609
|
+
|
|
610
|
+
dim_list = [
|
|
611
|
+
'mz',
|
|
612
|
+
'scan_time_aligned',
|
|
613
|
+
'half_height_width',
|
|
614
|
+
'tailing_factor',
|
|
615
|
+
'dispersity_index',
|
|
616
|
+
'intensity',
|
|
617
|
+
'persistence'
|
|
618
|
+
]
|
|
619
|
+
lcms_collection.plot_cluster_outlier_frequency(dim_list, clu_size_thresh = 0.25)
|
|
620
|
+
|
|
621
|
+
# Create pivot tables and reports
|
|
622
|
+
results = lcms_collection.collection_pivot_table()
|
|
623
|
+
results1 = lcms_collection.collection_pivot_table(attribute = 'intensity')
|
|
624
|
+
results2 = lcms_collection.collection_consensus_report(how = 'intensity')
|
|
625
|
+
results3 = lcms_collection.collection_consensus_report(how = 'median')
|
|
626
|
+
|
|
627
|
+
#TODO KRH: Add visualization of matched spectrum with consensus mass feature
|
|
628
|
+
"""
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import os
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
username = os.environ.get('DMS_USER_NAME') or 'XXXX'
|
|
8
|
+
password = os.environ.get('DMS_USER_PASSWORD') or 'XXXXX'
|
|
9
|
+
|
|
10
|
+
s = requests.Session()
|
|
11
|
+
s.auth = (username, password)
|
|
12
|
+
|
|
13
|
+
url_request = "https://dms2.pnl.gov/data/ax/json/list_report/dataset/{}".format("4-AA_L-AsparticAcid")
|
|
14
|
+
r = s.get(url_request)
|
|
15
|
+
|
|
16
|
+
data_list = r.json()
|
|
17
|
+
for data in data_list:
|
|
18
|
+
print(data)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
filein = Path("data/ftms_nom_data_products.json")
|
|
22
|
+
outfile = Path("data/ftms_nom_nmdc_data.csv")
|
|
23
|
+
|
|
24
|
+
with outfile.open("w") as csv_data:
|
|
25
|
+
|
|
26
|
+
csv_data.write('{},{} \n'.format('DMS Dataset ID', "Dataset"))
|
|
27
|
+
|
|
28
|
+
with filein.open() as json_data:
|
|
29
|
+
|
|
30
|
+
list_data = json.load(json_data)
|
|
31
|
+
for data in list_data:
|
|
32
|
+
filename = (data.get("name").replace(".csv", ""))
|
|
33
|
+
if filename[0:6] == 'Brodie':
|
|
34
|
+
|
|
35
|
+
url_request = "https://dms2.pnl.gov/data/ax/json/list_report/dataset/{}".format(filename)
|
|
36
|
+
r = s.get(url_request)
|
|
37
|
+
|
|
38
|
+
data_list = r.json()
|
|
39
|
+
for data in data_list:
|
|
40
|
+
(data.get('ID'))
|
|
41
|
+
|
|
42
|
+
csv_data.write('{},{}\n'.format(data.get('ID'), filename))
|