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
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
__author__ = "Yuri E. Corilo"
|
|
2
|
+
__date__ = "Oct 24, 2019"
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
import re
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Dict, List
|
|
9
|
+
|
|
10
|
+
import pandas as pd
|
|
11
|
+
|
|
12
|
+
from corems.encapsulation.constant import Atoms, Labels
|
|
13
|
+
from corems.molecular_formula.factory.MolecularFormulaFactory import (
|
|
14
|
+
LCMSLibRefMolecularFormula,
|
|
15
|
+
MolecularFormula,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class MolecularFormulaLinkProxy:
|
|
20
|
+
"""Proxy class for MolecularFormulaLink to be used in the molecular formula ref file import
|
|
21
|
+
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
molecular_formula : MolecularFormula | LCMSLibRefMolecularFormula
|
|
25
|
+
corems MolecularFormula or LCMSLibRefMolecularFormula object
|
|
26
|
+
mz : float
|
|
27
|
+
target m/z
|
|
28
|
+
|
|
29
|
+
Attributes
|
|
30
|
+
----------
|
|
31
|
+
C : int
|
|
32
|
+
number of carbon atoms
|
|
33
|
+
H : int
|
|
34
|
+
number of hydrogen atoms
|
|
35
|
+
H_C : float
|
|
36
|
+
ratio of hydrogen to carbon atoms
|
|
37
|
+
class_label : str
|
|
38
|
+
molecular formula class label
|
|
39
|
+
mz_calc : float
|
|
40
|
+
calculated m/z
|
|
41
|
+
dbe : int
|
|
42
|
+
double bond equivalent
|
|
43
|
+
formula_dict : dict
|
|
44
|
+
molecular formula dictionary
|
|
45
|
+
|
|
46
|
+
Methods
|
|
47
|
+
-------
|
|
48
|
+
* to_dict().
|
|
49
|
+
return molecular formula dictionary
|
|
50
|
+
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
def __init__(self, molecular_formula, mz):
|
|
54
|
+
self.C = molecular_formula.get("C")
|
|
55
|
+
self.H = molecular_formula.get("H")
|
|
56
|
+
self.H_C = molecular_formula.get("H") / molecular_formula.get("C")
|
|
57
|
+
self.class_label = json.dumps(molecular_formula.class_dict)
|
|
58
|
+
self.mz_calc = float(mz)
|
|
59
|
+
self.dbe = molecular_formula.dbe
|
|
60
|
+
self.formula_dict = molecular_formula.to_dict()
|
|
61
|
+
|
|
62
|
+
def to_dict(self):
|
|
63
|
+
return self.formula_dict
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class ImportMassListRef: # Thread
|
|
67
|
+
"""Import Mass List from Reference File
|
|
68
|
+
|
|
69
|
+
Parameters
|
|
70
|
+
----------
|
|
71
|
+
ref_file_location : str
|
|
72
|
+
path to the reference file
|
|
73
|
+
|
|
74
|
+
Attributes
|
|
75
|
+
----------
|
|
76
|
+
ref_file_location : str
|
|
77
|
+
path to the reference file
|
|
78
|
+
|
|
79
|
+
Methods
|
|
80
|
+
-------
|
|
81
|
+
* molecular_formula_ref(mz, molecular_formula).
|
|
82
|
+
Return MolecularFormulaLinkProxy object
|
|
83
|
+
* from_lcms_lib_file(ion_charge, ion_types).
|
|
84
|
+
Return Dict[standard_name, Dict[m/z, List[MolecularFormula]]] from LCMS library reference file
|
|
85
|
+
* from_bruker_ref_file().
|
|
86
|
+
Return List[MolecularFormula] from Bruker reference file
|
|
87
|
+
* from_corems_ref_file(delimiter).
|
|
88
|
+
Return List[MolecularFormula] from CoreMS reference file
|
|
89
|
+
* split(delimiters, string, maxsplit).
|
|
90
|
+
Splits a string using a list of delimiters.
|
|
91
|
+
* mformula_s_to_dict(s_mformulatring, iontype).
|
|
92
|
+
Converts a molecular formula string to a dict
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
def __init__(self, ref_file_location):
|
|
96
|
+
# Thread.__init__(self)
|
|
97
|
+
|
|
98
|
+
self.ref_file_location = Path(ref_file_location)
|
|
99
|
+
|
|
100
|
+
if not self.ref_file_location.exists():
|
|
101
|
+
tb = sys.exc_info()[2]
|
|
102
|
+
raise FileNotFoundError(ref_file_location).with_traceback(tb)
|
|
103
|
+
|
|
104
|
+
def molecular_formula_ref(self, mz, molecular_formula):
|
|
105
|
+
"""Instantiate a MolecularFormulaLinkProxy object
|
|
106
|
+
|
|
107
|
+
Parameters
|
|
108
|
+
----------
|
|
109
|
+
mz : float
|
|
110
|
+
target m/z
|
|
111
|
+
molecular_formula : MolecularFormula | LCMSLibRefMolecularFormula
|
|
112
|
+
corems MolecularFormula or LCMSLibRefMolecularFormula object
|
|
113
|
+
|
|
114
|
+
Returns
|
|
115
|
+
-------
|
|
116
|
+
MolecularFormulaLinkProxy
|
|
117
|
+
MolecularFormulaLinkProxy object
|
|
118
|
+
"""
|
|
119
|
+
return MolecularFormulaLinkProxy(molecular_formula, mz)
|
|
120
|
+
|
|
121
|
+
def from_lcms_lib_file(
|
|
122
|
+
self, ion_charge: float, ion_types: List[str]
|
|
123
|
+
) -> Dict[str, Dict[float, List[LCMSLibRefMolecularFormula]]]:
|
|
124
|
+
"""Create a dictionary of LCMSLibRefMolecularFormula objects from LCMS library reference file
|
|
125
|
+
|
|
126
|
+
Parameters
|
|
127
|
+
----------
|
|
128
|
+
ion_charge : float
|
|
129
|
+
ion charge
|
|
130
|
+
ion_types : List[str]
|
|
131
|
+
list of ion types
|
|
132
|
+
|
|
133
|
+
Returns
|
|
134
|
+
-------
|
|
135
|
+
Dict
|
|
136
|
+
Dict[standard_name, Dict[m/z, List[MolecularFormula]]] from LCMS library reference file. m/z is the target m/z; standard_name is the name of the molecular standard mix; MolecularFormula is the corems molecular formula class
|
|
137
|
+
"""
|
|
138
|
+
|
|
139
|
+
data = {}
|
|
140
|
+
|
|
141
|
+
with open(self.ref_file_location) as ref_f:
|
|
142
|
+
df = pd.read_csv(ref_f, header=0, encoding="unicode_escape")
|
|
143
|
+
|
|
144
|
+
for index, row in df.iterrows():
|
|
145
|
+
formula_s = row["Neutral Formula"]
|
|
146
|
+
formula_dict = self.mformula_s_to_dict(formula_s, Labels.neutral)
|
|
147
|
+
name = row["Compound Name"]
|
|
148
|
+
kegg_id = row["KEGG ID"]
|
|
149
|
+
standard_name = row["NEW MIX"]
|
|
150
|
+
cas = row["KEGG ID"]
|
|
151
|
+
# print(row["Neutral Formula"], formula_dict)
|
|
152
|
+
molf_formula = LCMSLibRefMolecularFormula(
|
|
153
|
+
formula_dict,
|
|
154
|
+
ion_charge,
|
|
155
|
+
Labels.neutral,
|
|
156
|
+
name=name,
|
|
157
|
+
kegg_id=kegg_id,
|
|
158
|
+
cas=cas,
|
|
159
|
+
)
|
|
160
|
+
# if round(molf_formula.mz_calc, 4) != round(row['Mass Adduct -H'],4):
|
|
161
|
+
# print(formula_s)
|
|
162
|
+
# print(round(molf_formula.mz_calc, 4) , round(row['Mass Adduct -H'],4))
|
|
163
|
+
|
|
164
|
+
if standard_name in data.keys():
|
|
165
|
+
# TODO change it to target ion types and add ion type in the data structure
|
|
166
|
+
mz_calc = molf_formula.protonated_mz
|
|
167
|
+
|
|
168
|
+
if mz_calc in data.get(standard_name).keys():
|
|
169
|
+
data.get(standard_name).get(mz_calc).append(molf_formula)
|
|
170
|
+
|
|
171
|
+
else:
|
|
172
|
+
data[standard_name][mz_calc] = [molf_formula]
|
|
173
|
+
else:
|
|
174
|
+
data[standard_name] = {molf_formula.mz_calc: [molf_formula]}
|
|
175
|
+
# print(formula_s, formula_dict)
|
|
176
|
+
# if molf_formula.ion_type != 'de-protonated':
|
|
177
|
+
# print( 'ha', molf_formula.ion_type )
|
|
178
|
+
# print(formula_dict)
|
|
179
|
+
# print(row['c1'], row['c2'])
|
|
180
|
+
|
|
181
|
+
return data
|
|
182
|
+
|
|
183
|
+
def from_bruker_ref_file(self) -> List[MolecularFormula]:
|
|
184
|
+
"""Create a list of MolecularFormula objects from Bruker reference file
|
|
185
|
+
|
|
186
|
+
Returns
|
|
187
|
+
-------
|
|
188
|
+
List[MolecularFormula]
|
|
189
|
+
List of MolecularFormula objects from Bruker reference file
|
|
190
|
+
"""
|
|
191
|
+
|
|
192
|
+
import csv
|
|
193
|
+
|
|
194
|
+
list_mf_obj = []
|
|
195
|
+
|
|
196
|
+
with open(self.ref_file_location) as ref_f:
|
|
197
|
+
labels = ref_f.readline().strip("\n").split(";")
|
|
198
|
+
|
|
199
|
+
for line in ref_f.readlines():
|
|
200
|
+
if line != "\n":
|
|
201
|
+
list_ref = line.strip("\n").split(" ")
|
|
202
|
+
|
|
203
|
+
if list_ref[2][-1] == "+":
|
|
204
|
+
ion_charge = int(list_ref[2][:-1])
|
|
205
|
+
|
|
206
|
+
else:
|
|
207
|
+
ion_charge = -1 * int(list_ref[2][:-1])
|
|
208
|
+
|
|
209
|
+
ion_mol_formula = list_ref[0]
|
|
210
|
+
mz = float(list_ref[1])
|
|
211
|
+
formula_dict = self.mformula_s_to_dict(ion_mol_formula)
|
|
212
|
+
|
|
213
|
+
list_mf_obj.append(
|
|
214
|
+
MolecularFormula(formula_dict, ion_charge, external_mz=mz)
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
return list_mf_obj
|
|
218
|
+
|
|
219
|
+
def from_corems_ref_file(self, delimiter="\t"): # pragma: no cover
|
|
220
|
+
"""Create a list of MolecularFormula objects from CoreMS reference file
|
|
221
|
+
|
|
222
|
+
Not being used
|
|
223
|
+
|
|
224
|
+
Parameters
|
|
225
|
+
----------
|
|
226
|
+
delimiter : str
|
|
227
|
+
delimiter used in the reference file
|
|
228
|
+
|
|
229
|
+
Returns
|
|
230
|
+
-------
|
|
231
|
+
List[MolecularFormula]
|
|
232
|
+
List of MolecularFormula objects from CoreMS reference file
|
|
233
|
+
"""
|
|
234
|
+
# not being used
|
|
235
|
+
import csv
|
|
236
|
+
|
|
237
|
+
list_mf_obj = []
|
|
238
|
+
|
|
239
|
+
with open("res/RefMassLists/Crude-Pos-ESI.ref") as ref_f:
|
|
240
|
+
labels = ref_f.readline().strip("\n").split(delimiter)
|
|
241
|
+
|
|
242
|
+
for line in ref_f.readlines():
|
|
243
|
+
if line != "\n":
|
|
244
|
+
list_ref = line.strip("\n").split(delimiter)
|
|
245
|
+
|
|
246
|
+
formula_string = list_ref[0]
|
|
247
|
+
ion_charge = int(list_ref[1])
|
|
248
|
+
ion_type = list_ref[2]
|
|
249
|
+
|
|
250
|
+
molform = MolecularFormula(
|
|
251
|
+
formula_string, ion_charge, ion_type=ion_type
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
list_mf_obj.append(self.molecular_formula_ref(molform))
|
|
255
|
+
|
|
256
|
+
return list_mf_obj
|
|
257
|
+
|
|
258
|
+
def split(self, delimiters, string, maxsplit=0): # pragma: no cover
|
|
259
|
+
"""Splits a string using a list of delimiters.
|
|
260
|
+
|
|
261
|
+
Does not work when formula has atoms with same characters, i.e - C10H21NNa
|
|
262
|
+
|
|
263
|
+
Parameters
|
|
264
|
+
----------
|
|
265
|
+
delimiters : list
|
|
266
|
+
list of delimiters
|
|
267
|
+
string : str
|
|
268
|
+
string to be split
|
|
269
|
+
maxsplit : int, optional
|
|
270
|
+
maximum number of splits. Default is 0
|
|
271
|
+
|
|
272
|
+
Returns
|
|
273
|
+
-------
|
|
274
|
+
list
|
|
275
|
+
list of strings obtained after splitting the string
|
|
276
|
+
list
|
|
277
|
+
list of counts obtained after splitting the string
|
|
278
|
+
"""
|
|
279
|
+
regexPattern = "|".join(map(re.escape, delimiters)) # pragma: no cover
|
|
280
|
+
isotopes = re.findall(regexPattern, string) # pragma: no cover
|
|
281
|
+
counts = re.split(regexPattern, string, maxsplit) # pragma: no cover
|
|
282
|
+
return isotopes, counts
|
|
283
|
+
|
|
284
|
+
def mformula_s_to_dict(self, s_mformulatring, iontype="unknown"):
|
|
285
|
+
"""Converts a molecular formula string to a dict
|
|
286
|
+
|
|
287
|
+
Parameters
|
|
288
|
+
----------
|
|
289
|
+
s_mformulatring : str
|
|
290
|
+
molecular formula string, i.e. 'C10H21NNa'
|
|
291
|
+
iontype : str, optional
|
|
292
|
+
ion type. Default is 'unknown'
|
|
293
|
+
|
|
294
|
+
Returns
|
|
295
|
+
-------
|
|
296
|
+
dict
|
|
297
|
+
molecular formula dictionary
|
|
298
|
+
|
|
299
|
+
Notes
|
|
300
|
+
-----
|
|
301
|
+
Does not work if the atomic mass number is passed i.e. 37Cl, 81Br, convention follow the light isotope labeling 35Cl is Cl, 12C is C, etc.
|
|
302
|
+
If you need to use heavy isotopes please use another reference file format that separate the formula string by a blank space and parse it using the function corems_ref_file
|
|
303
|
+
|
|
304
|
+
Raises
|
|
305
|
+
------
|
|
306
|
+
TypeError
|
|
307
|
+
Atom does not exist in Atoms.atoms_order list
|
|
308
|
+
Exception
|
|
309
|
+
Empty molecular formula
|
|
310
|
+
"""
|
|
311
|
+
if s_mformulatring:
|
|
312
|
+
# find the case C122
|
|
313
|
+
all_atoms = re.findall(r"[A-Z]{1}[0-9]{1,10000}", s_mformulatring)
|
|
314
|
+
|
|
315
|
+
# find the case Br2
|
|
316
|
+
all_atoms2 = re.findall(r"[A-Z]{1}[a-z]{1}[0-9]{1,10000}", s_mformulatring)
|
|
317
|
+
# find the case N
|
|
318
|
+
single_digit_atoms_one = re.findall(
|
|
319
|
+
r"[A-Z]{1}(?![0-9])(?![a-z])", s_mformulatring
|
|
320
|
+
)
|
|
321
|
+
# print(single_digit_atoms_one)
|
|
322
|
+
# find the case Na
|
|
323
|
+
due_digit_atoms_one = re.findall(
|
|
324
|
+
r"[A-Z]{1}[a-z]{1}(?![0-9])", s_mformulatring
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
all_atoms = (
|
|
328
|
+
all_atoms + all_atoms2 + due_digit_atoms_one + single_digit_atoms_one
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
dict_res = {}
|
|
332
|
+
|
|
333
|
+
for each_atom_count in all_atoms:
|
|
334
|
+
count = re.findall(r"[0-9]{1,10000}", each_atom_count)
|
|
335
|
+
atom = "".join(re.findall(r"[A-z]", each_atom_count))
|
|
336
|
+
|
|
337
|
+
if atom in Atoms.atoms_order:
|
|
338
|
+
if count:
|
|
339
|
+
dict_res[atom] = int(count[0])
|
|
340
|
+
else:
|
|
341
|
+
dict_res[atom] = 1
|
|
342
|
+
|
|
343
|
+
else:
|
|
344
|
+
tb = sys.exc_info()[2]
|
|
345
|
+
raise TypeError(
|
|
346
|
+
"Atom %s does not exist in Atoms.atoms_order list" % atom
|
|
347
|
+
).with_traceback(tb)
|
|
348
|
+
|
|
349
|
+
dict_res[Labels.ion_type] = iontype
|
|
350
|
+
|
|
351
|
+
return dict_res
|
|
352
|
+
|
|
353
|
+
else:
|
|
354
|
+
tb = sys.exc_info()[2]
|
|
355
|
+
raise Exception("Empty molecular formula").with_traceback(tb)
|
|
File without changes
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from sklearn.cluster import DBSCAN
|
|
3
|
+
from sklearn.preprocessing import StandardScaler
|
|
4
|
+
|
|
5
|
+
# import matplotlib.pyplot as plt
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ClusteringFilter:
|
|
9
|
+
"""Class for filtering and clustering mass spectra data using various algorithms.
|
|
10
|
+
|
|
11
|
+
Attributes
|
|
12
|
+
-------
|
|
13
|
+
mass_spectrum : MassSpectrum
|
|
14
|
+
Mass spectrum object.
|
|
15
|
+
ms_peaks : list
|
|
16
|
+
List of mass peaks.
|
|
17
|
+
ms_peak_indexes : list
|
|
18
|
+
List of peak indexes.
|
|
19
|
+
min_samples : int
|
|
20
|
+
Minimum number of samples in a cluster.
|
|
21
|
+
eps : float
|
|
22
|
+
The maximum distance between two samples for one to be considered as in the neighborhood of the other.
|
|
23
|
+
bandwidth : float
|
|
24
|
+
Bandwidth used in MeanShift algorithm.
|
|
25
|
+
quantile : float
|
|
26
|
+
Quantile used in estimate_bandwidth function.
|
|
27
|
+
n_samples : int
|
|
28
|
+
Number of samples used in estimate_bandwidth function.
|
|
29
|
+
bin_seeding : bool
|
|
30
|
+
If true, initial kernel locations are not locations of all points, but rather the location of the discretized version of points, where points are binned onto a grid whose coarseness corresponds to the bandwidth. Setting this option to True will speed up the algorithm because fewer seeds will be initialized.
|
|
31
|
+
min_peaks_per_class : int
|
|
32
|
+
Minimum number of peaks per class.
|
|
33
|
+
|
|
34
|
+
Methods
|
|
35
|
+
-------
|
|
36
|
+
* get_mass_error_matrix_data(ms_peaks).
|
|
37
|
+
Get the mass error matrix data from a list of mass peaks.
|
|
38
|
+
* get_kendrick_matrix_data(mass_spectrum).
|
|
39
|
+
Get the Kendrick matrix data from a mass spectrum.
|
|
40
|
+
* filter_kendrick(mass_spectrum).
|
|
41
|
+
Filter the mass spectrum data using the Kendrick algorithm.
|
|
42
|
+
* filter_kendrick_by_index(ms_peak_indexes, mass_spectrum_obj).
|
|
43
|
+
Filter the mass spectrum data using the Kendrick algorithm based on a list of peak indexes.
|
|
44
|
+
* remove_assignment_by_mass_error(mass_spectrum).
|
|
45
|
+
Remove assignments from the mass spectrum based on mass error.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
def get_mass_error_matrix_data(self, ms_peaks):
|
|
51
|
+
"""Get the mass error matrix data from a list of mass peaks.
|
|
52
|
+
|
|
53
|
+
Parameters
|
|
54
|
+
----------
|
|
55
|
+
ms_peaks : list
|
|
56
|
+
List of mass peaks.
|
|
57
|
+
|
|
58
|
+
Returns
|
|
59
|
+
-------
|
|
60
|
+
matrix_data : ndarray
|
|
61
|
+
Matrix data containing mass and error values.
|
|
62
|
+
list_indexes_mass_spec : list
|
|
63
|
+
List of indexes of mass peaks in the original mass spectrum.
|
|
64
|
+
"""
|
|
65
|
+
mass_list = list()
|
|
66
|
+
error_list = list()
|
|
67
|
+
list_indexes_mass_spec = []
|
|
68
|
+
|
|
69
|
+
for index, mspeak in enumerate(ms_peaks):
|
|
70
|
+
if mspeak.is_assigned:
|
|
71
|
+
# print(mspeak.mz_exp, len(mspeak))
|
|
72
|
+
for mformula in mspeak:
|
|
73
|
+
mass_list.append(mspeak.mz_exp)
|
|
74
|
+
error_list.append(mformula.mz_error)
|
|
75
|
+
list_indexes_mass_spec.append(index)
|
|
76
|
+
|
|
77
|
+
kendrick_dict = {"mass": mass_list, "error": error_list}
|
|
78
|
+
df = pd.DataFrame(kendrick_dict)
|
|
79
|
+
matrix_data = df.values.astype("float32", copy=False)
|
|
80
|
+
return matrix_data, list_indexes_mass_spec
|
|
81
|
+
|
|
82
|
+
def get_kendrick_matrix_data(self, mass_spectrum):
|
|
83
|
+
"""Get the Kendrick matrix data from a mass spectrum.
|
|
84
|
+
|
|
85
|
+
Parameters
|
|
86
|
+
----------
|
|
87
|
+
mass_spectrum : MassSpectrum
|
|
88
|
+
Mass spectrum object.
|
|
89
|
+
|
|
90
|
+
Returns
|
|
91
|
+
-------
|
|
92
|
+
matrix_data : ndarray
|
|
93
|
+
Matrix data containing Kendrick mass and Kendrick mass defect values.
|
|
94
|
+
"""
|
|
95
|
+
km = mass_spectrum.kendrick_mass
|
|
96
|
+
kmd = mass_spectrum.kmd
|
|
97
|
+
kendrick_dict = {"km": km, "kmd": kmd}
|
|
98
|
+
df = pd.DataFrame(kendrick_dict)
|
|
99
|
+
matrix_data = df.values.astype("float32", copy=False)
|
|
100
|
+
return matrix_data
|
|
101
|
+
|
|
102
|
+
def filter_kendrick(self, mass_spectrum):
|
|
103
|
+
"""Filter the mass spectrum data using the Kendrick algorithm.
|
|
104
|
+
|
|
105
|
+
Parameters
|
|
106
|
+
----------
|
|
107
|
+
mass_spectrum : MassSpectrum
|
|
108
|
+
Mass spectrum object.
|
|
109
|
+
|
|
110
|
+
"""
|
|
111
|
+
matrix_data = self.get_kendrick_matrix_data(mass_spectrum)
|
|
112
|
+
|
|
113
|
+
stdscaler = StandardScaler().fit(matrix_data)
|
|
114
|
+
|
|
115
|
+
matrix_data_scaled = stdscaler.transform(matrix_data)
|
|
116
|
+
|
|
117
|
+
clusters = DBSCAN(eps=0.75, min_samples=50).fit_predict(matrix_data_scaled)
|
|
118
|
+
|
|
119
|
+
# Number of clusters in labels, ignoring noise if present.
|
|
120
|
+
n_clusters_ = len(set(clusters)) - (1 if -1 in clusters else 0)
|
|
121
|
+
n_noise_ = list(clusters).count(-1)
|
|
122
|
+
|
|
123
|
+
indexes = []
|
|
124
|
+
for i in range(len(clusters)):
|
|
125
|
+
if clusters[i] == -1:
|
|
126
|
+
indexes.append(i)
|
|
127
|
+
|
|
128
|
+
if mass_spectrum.parameters.mass_spectrum.verbose_processing:
|
|
129
|
+
print("Estimated number of clusters: %d" % n_clusters_)
|
|
130
|
+
print("Estimated number of noise points: %d" % n_noise_)
|
|
131
|
+
mass_spectrum.filter_by_index(indexes)
|
|
132
|
+
# from matplotlib import pyplot as plt
|
|
133
|
+
# plt.scatter(matrix_data[:, 0], matrix_data[:, 1], c=clusters, cmap="jet")
|
|
134
|
+
# plt.xlabel("km")
|
|
135
|
+
# plt.ylabel("kmd")
|
|
136
|
+
# plt.show()
|
|
137
|
+
# plt.close()
|
|
138
|
+
|
|
139
|
+
def filter_kendrick_by_index(self, ms_peak_indexes, mass_spectrum_obj):
|
|
140
|
+
"""Filter the mass spectrum data using the Kendrick algorithm based on a list of peak indexes.
|
|
141
|
+
|
|
142
|
+
Parameters
|
|
143
|
+
----------
|
|
144
|
+
ms_peak_indexes : list
|
|
145
|
+
List of peak indexes.
|
|
146
|
+
mass_spectrum_obj : MassSpectrum
|
|
147
|
+
Mass spectrum object.
|
|
148
|
+
|
|
149
|
+
Returns
|
|
150
|
+
-------
|
|
151
|
+
noise_idx : list
|
|
152
|
+
List of indexes of noise points in the mass spectrum.
|
|
153
|
+
"""
|
|
154
|
+
min_samples = mass_spectrum_obj.molecular_search_settings.min_peaks_per_class
|
|
155
|
+
|
|
156
|
+
kendrick_dict = {"km": list(), "kmd": list()}
|
|
157
|
+
|
|
158
|
+
if len(ms_peak_indexes) <= 1:
|
|
159
|
+
return []
|
|
160
|
+
|
|
161
|
+
for index, _ in ms_peak_indexes:
|
|
162
|
+
kendrick_dict["km"].append(mass_spectrum_obj[index].kendrick_mass)
|
|
163
|
+
kendrick_dict["kmd"].append(mass_spectrum_obj[index].kmd)
|
|
164
|
+
|
|
165
|
+
# check min data points otherwise StandardScaler().fit(0 will fail
|
|
166
|
+
|
|
167
|
+
df = pd.DataFrame(kendrick_dict)
|
|
168
|
+
matrix_data = df.values.astype("float32", copy=False)
|
|
169
|
+
|
|
170
|
+
stdscaler = StandardScaler().fit(matrix_data)
|
|
171
|
+
matrix_data_scaled = stdscaler.transform(matrix_data)
|
|
172
|
+
|
|
173
|
+
clusters = DBSCAN(eps=0.8, min_samples=min_samples).fit_predict(
|
|
174
|
+
matrix_data_scaled
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
# Number of clusters in labels, ignoring noise if present.
|
|
178
|
+
n_clusters_ = len(set(clusters)) - (1 if -1 in clusters else 0)
|
|
179
|
+
n_noise_ = list(clusters).count(-1)
|
|
180
|
+
|
|
181
|
+
if mass_spectrum_obj.parameters.mass_spectrum.verbose_processing:
|
|
182
|
+
print("Estimated number of clusters: %d" % n_clusters_)
|
|
183
|
+
print("Estimated number of noise points: %d" % n_noise_)
|
|
184
|
+
|
|
185
|
+
noise_idx = []
|
|
186
|
+
|
|
187
|
+
other_peaks_idx = []
|
|
188
|
+
|
|
189
|
+
for i in range(len(clusters)):
|
|
190
|
+
if clusters[i] == -1:
|
|
191
|
+
noise_idx.append(ms_peak_indexes[i])
|
|
192
|
+
|
|
193
|
+
else:
|
|
194
|
+
other_peaks_idx.append(ms_peak_indexes[i])
|
|
195
|
+
|
|
196
|
+
# mfs = [mass_spectrum_obj[index].best_molecular_formula_candidate.string for index in other_peaks_idx]
|
|
197
|
+
|
|
198
|
+
# mfs_noise = [mass_spectrum_obj[index].best_molecular_formula_candidate.string for index in noise_idx]
|
|
199
|
+
|
|
200
|
+
# print(mfs)
|
|
201
|
+
# print(mfs_noise)
|
|
202
|
+
|
|
203
|
+
# from matplotlib import pyplot as plt
|
|
204
|
+
# plt.scatter(matrix_data[:, 0], matrix_data[:, 1], c=clusters, cmap="jet")
|
|
205
|
+
# plt.xlabel("km")
|
|
206
|
+
# plt.ylabel("kmd")
|
|
207
|
+
# plt.show()
|
|
208
|
+
# plt.close()
|
|
209
|
+
|
|
210
|
+
return noise_idx
|
|
211
|
+
|
|
212
|
+
def remove_assignment_by_mass_error(self, mass_spectrum):
|
|
213
|
+
"""Remove assignments from the mass spectrum based on mass error.
|
|
214
|
+
|
|
215
|
+
Parameters
|
|
216
|
+
----------
|
|
217
|
+
mass_spectrum : MassSpectrum
|
|
218
|
+
Mass spectrum object.
|
|
219
|
+
|
|
220
|
+
"""
|
|
221
|
+
# data need to be binned by mz unit or more to be able to use clustering
|
|
222
|
+
|
|
223
|
+
matrix_data, list_indexes_mass_spec = self.get_mass_error_matrix_data(
|
|
224
|
+
mass_spectrum
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
stdscaler = StandardScaler().fit(matrix_data)
|
|
228
|
+
|
|
229
|
+
matrix_data_scaled = stdscaler.transform(matrix_data)
|
|
230
|
+
|
|
231
|
+
# bandwidth = estimate_bandwidth(matrix_data_scaled, quantile=0.3, n_samples=int(len(ms_peaks)/3))
|
|
232
|
+
|
|
233
|
+
# clusters = MeanShift(bandwidth=bandwidth, bin_seeding=True).fit_predict(matrix_data_scaled)
|
|
234
|
+
|
|
235
|
+
# eps and min_samp need to be optimized by precision and number of mspeaks
|
|
236
|
+
clusters = DBSCAN(eps=0.15).fit_predict(matrix_data_scaled)
|
|
237
|
+
|
|
238
|
+
indexes = []
|
|
239
|
+
|
|
240
|
+
# from matplotlib import pyplot as plt
|
|
241
|
+
# plt.scatter(matrix_data[:, 0], matrix_data[:, 1], c=clusters, cmap="plasma")
|
|
242
|
+
# plt.xlabel("km")
|
|
243
|
+
# plt.ylabel("kmd")
|
|
244
|
+
# plt.show()
|
|
245
|
+
# plt.close()
|
|
246
|
+
|
|
247
|
+
for i in range(len(clusters)):
|
|
248
|
+
if clusters[i] == -1:
|
|
249
|
+
indexes.append(list_indexes_mass_spec[i])
|
|
250
|
+
|
|
251
|
+
mass_spectrum.remove_assignment_by_index(indexes)
|