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,723 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from copy import deepcopy
|
|
5
|
+
from threading import Thread
|
|
6
|
+
from itertools import product
|
|
7
|
+
|
|
8
|
+
import tqdm
|
|
9
|
+
|
|
10
|
+
from corems.encapsulation.constant import Labels, Atoms
|
|
11
|
+
from corems.molecular_id.calc.MolecularFilter import MolecularFormulaSearchFilters
|
|
12
|
+
from corems.molecular_id.search.findOxygenPeaks import FindOxygenPeaks
|
|
13
|
+
from corems.molecular_id.search.molecularFormulaSearch import (
|
|
14
|
+
SearchMolecularFormulaWorker,
|
|
15
|
+
)
|
|
16
|
+
from corems.molecular_id.factory.molecularSQL import MolForm_SQL
|
|
17
|
+
from corems.molecular_id.calc.ClusterFilter import ClusteringFilter
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class OxygenPriorityAssignment(Thread):
|
|
21
|
+
"""A class for assigning priority to oxygen classes in a molecular search.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
mass_spectrum_obj : MassSpectrum
|
|
26
|
+
The mass spectrum object.
|
|
27
|
+
sql_db : bool, optional
|
|
28
|
+
Whether to use an SQL database. The default is False.
|
|
29
|
+
|
|
30
|
+
Attributes
|
|
31
|
+
----------
|
|
32
|
+
mass_spectrum_obj : MassSpectrum
|
|
33
|
+
The mass spectrum object.
|
|
34
|
+
sql_db : MolForm_SQL
|
|
35
|
+
The SQL database object.
|
|
36
|
+
|
|
37
|
+
Methods
|
|
38
|
+
-------
|
|
39
|
+
* run().
|
|
40
|
+
Run the priority assignment process.
|
|
41
|
+
* create_data_base().
|
|
42
|
+
Create the molecular database for the specified heteroatomic classes.
|
|
43
|
+
* run_worker_mass_spectrum(assign_classes_order_tuples).
|
|
44
|
+
Run the molecular formula search for each class in the specified order.
|
|
45
|
+
* get_dict_molecular_database(classe_str_list).
|
|
46
|
+
Get the molecular database as a dictionary.
|
|
47
|
+
* ox_classes_and_peaks_in_order_().
|
|
48
|
+
Get the oxygen classes and associated peaks in order.
|
|
49
|
+
* get_classes_in_order(dict_ox_class_and_ms_peak)
|
|
50
|
+
Get the classes in order.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
def __init__(self, mass_spectrum_obj, sql_db=False):
|
|
54
|
+
# TODO:- add support for other atoms and adducts: Done
|
|
55
|
+
# - add dbe range on search runtime : Done
|
|
56
|
+
# - add docs
|
|
57
|
+
# - improve performace : Done
|
|
58
|
+
|
|
59
|
+
Thread.__init__(self)
|
|
60
|
+
self.mass_spectrum_obj = mass_spectrum_obj
|
|
61
|
+
# initiated at create_molecular_database()
|
|
62
|
+
# self.dict_molecular_lookup_table = None
|
|
63
|
+
|
|
64
|
+
if not sql_db:
|
|
65
|
+
self.sql_db = MolForm_SQL(
|
|
66
|
+
url=mass_spectrum_obj.molecular_search_settings.url_database
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
else:
|
|
70
|
+
self.sql_db = sql_db
|
|
71
|
+
|
|
72
|
+
def run(self):
|
|
73
|
+
"""Run the priority assignment process."""
|
|
74
|
+
# get Oxygen classes dict and the associate mspeak class
|
|
75
|
+
# list_of_classes_min_max_dbe = self.class_and_dbes_in_order()
|
|
76
|
+
# create database separated to give the user the chance to use mass spec filters
|
|
77
|
+
|
|
78
|
+
assign_classes_order_str_dict_tuple_list = self.create_data_base()
|
|
79
|
+
|
|
80
|
+
if assign_classes_order_str_dict_tuple_list:
|
|
81
|
+
self.run_worker_mass_spectrum(assign_classes_order_str_dict_tuple_list)
|
|
82
|
+
|
|
83
|
+
else:
|
|
84
|
+
raise RuntimeError("call create_data_base() first")
|
|
85
|
+
|
|
86
|
+
self.sql_db.close()
|
|
87
|
+
|
|
88
|
+
def create_data_base(self):
|
|
89
|
+
"""Create the molecular database for the specified heteroatomic classes.
|
|
90
|
+
|
|
91
|
+
Returns
|
|
92
|
+
-------
|
|
93
|
+
assign_classes_order_str_dict_tuple_ : list
|
|
94
|
+
A list of tuples containing the class names and dictionaries of class attributes.
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
def create_molecular_database():
|
|
98
|
+
"""Checks and creates the database entries for the specified heteroatomic classes."""
|
|
99
|
+
min_o = min(self.mass_spectrum_obj, key=lambda msp: msp[0]["O"])[0]["O"] - 2
|
|
100
|
+
|
|
101
|
+
if min_o <= 0:
|
|
102
|
+
min_o = 1
|
|
103
|
+
|
|
104
|
+
max_o = max(self.mass_spectrum_obj, key=lambda msp: msp[0]["O"])[0]["O"] + 2
|
|
105
|
+
|
|
106
|
+
# min_dbe = min(self.mass_spectrum_obj, key=lambda msp: msp[0].dbe)[0].dbe
|
|
107
|
+
|
|
108
|
+
# max_dbe = max(self.mass_spectrum_obj, key=lambda msp: msp[0].dbe)[0].dbe
|
|
109
|
+
|
|
110
|
+
# self.lookupTableSettings.use_pah_line_rule = False
|
|
111
|
+
|
|
112
|
+
# self.lookupTableSettings.min_dbe = min_dbe/2#min_dbe - 7 if (min_dbe - 7) > 0 else 0
|
|
113
|
+
|
|
114
|
+
# self.lookupTableSettings.max_dbe = max_dbe * 2 #max_dbe + 7
|
|
115
|
+
|
|
116
|
+
self.mass_spectrum_obj.reset_indexes()
|
|
117
|
+
|
|
118
|
+
self.mass_spectrum_obj.filter_by_noise_threshold()
|
|
119
|
+
|
|
120
|
+
# initial_ox = deepcopy(self.mass_spectrum_obj.molecular_search_settings.usedAtoms)
|
|
121
|
+
|
|
122
|
+
self.mass_spectrum_obj.molecular_search_settings.usedAtoms["O"] = (
|
|
123
|
+
min_o,
|
|
124
|
+
max_o,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
self.nominal_mzs = self.mass_spectrum_obj.nominal_mz
|
|
128
|
+
|
|
129
|
+
# get the most abundant peak and them every 14Da, only allow Ox and its derivatives
|
|
130
|
+
if self.mass_spectrum_obj.parameters.mass_spectrum.verbose_processing:
|
|
131
|
+
print("Getting Oxygen Series")
|
|
132
|
+
find_formula_thread = FindOxygenPeaks(self.mass_spectrum_obj, self.sql_db)
|
|
133
|
+
find_formula_thread.run()
|
|
134
|
+
|
|
135
|
+
# mass spec obj indexes are set to interate over only the peaks with a molecular formula candidate
|
|
136
|
+
if self.mass_spectrum_obj.parameters.mass_spectrum.verbose_processing:
|
|
137
|
+
print("Getting Oxygen Series")
|
|
138
|
+
find_formula_thread.set_mass_spec_indexes_by_found_peaks()
|
|
139
|
+
|
|
140
|
+
# get the Ox class and the DBE for the lowest error molecular formula candidate
|
|
141
|
+
dict_ox_class_and_ms_peak = self.ox_classes_and_peaks_in_order_()
|
|
142
|
+
|
|
143
|
+
# sort the classes by abundance
|
|
144
|
+
if self.mass_spectrum_obj.parameters.mass_spectrum.verbose_processing:
|
|
145
|
+
print("Getting Oxygen Series Order")
|
|
146
|
+
assign_classes_order_str_dict_tuple_list = self.get_classes_in_order(
|
|
147
|
+
dict_ox_class_and_ms_peak
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
create_molecular_database()
|
|
151
|
+
|
|
152
|
+
return assign_classes_order_str_dict_tuple_list
|
|
153
|
+
|
|
154
|
+
def run_worker_mass_spectrum(self, assign_classes_order_tuples):
|
|
155
|
+
"""Run the molecular formula search for each class in the specified order.
|
|
156
|
+
|
|
157
|
+
Parameters
|
|
158
|
+
----------
|
|
159
|
+
assign_classes_order_tuples : list
|
|
160
|
+
A list of tuples containing the class names and dictionaries of class attributes.
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
def check_adduct_class(classe_dict):
|
|
164
|
+
"""Check if the class contains any adduct atoms.
|
|
165
|
+
|
|
166
|
+
Parameters
|
|
167
|
+
----------
|
|
168
|
+
classe_dict : dict
|
|
169
|
+
The dictionary of class attributes.
|
|
170
|
+
|
|
171
|
+
Returns
|
|
172
|
+
-------
|
|
173
|
+
bool
|
|
174
|
+
True if the class contains adduct atoms, False otherwise.
|
|
175
|
+
"""
|
|
176
|
+
return any(
|
|
177
|
+
[
|
|
178
|
+
key in classe_dict.keys()
|
|
179
|
+
for key in self.mass_spectrum_obj.molecular_search_settings.adduct_atoms_neg
|
|
180
|
+
]
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
def set_min_max_dbe_by_oxygen(classe_dict):
|
|
184
|
+
"""Calculate the minimum and maximum DBE based on the number of oxygen atoms.
|
|
185
|
+
|
|
186
|
+
Parameters
|
|
187
|
+
----------
|
|
188
|
+
classe_dict : dict
|
|
189
|
+
The dictionary of class attributes.
|
|
190
|
+
"""
|
|
191
|
+
# calculates min and max DBE based on the Oxygen number
|
|
192
|
+
# ref :https://pubs.acs.org/doi/full/10.1021/ac200464q
|
|
193
|
+
# if class does not has O it use the pha rule
|
|
194
|
+
# ref : Vlad Lobodin manuscript to be include here
|
|
195
|
+
|
|
196
|
+
# atoms_exchanges = ['N']
|
|
197
|
+
# if 'O' in classe_dict.keys():
|
|
198
|
+
#
|
|
199
|
+
# Oxygen_number = classe_dict.get("O")
|
|
200
|
+
# for atom in atoms_exchanges:
|
|
201
|
+
# if atom in classe_dict.keys():
|
|
202
|
+
# Oxygen_number += classe_dict.get(atom)
|
|
203
|
+
#
|
|
204
|
+
# self.mass_spectrum_obj.molecular_search_settings.min_dbe = (Oxygen_number/3) - 0.5
|
|
205
|
+
# self.mass_spectrum_obj.molecular_search_settings.max_dbe = Oxygen_number*3 + 0.5 + 2
|
|
206
|
+
#
|
|
207
|
+
# else:
|
|
208
|
+
|
|
209
|
+
self.mass_spectrum_obj.molecular_search_settings.use_pah_line_rule = True
|
|
210
|
+
|
|
211
|
+
def run_search(possible_formulas_dict, mass_spectrum_obj, min_abundance):
|
|
212
|
+
"""Run the molecular formula search for each mass spectrum peak.
|
|
213
|
+
|
|
214
|
+
Parameters
|
|
215
|
+
----------
|
|
216
|
+
possible_formulas_dict : dict
|
|
217
|
+
A dictionary of possible molecular formulas.
|
|
218
|
+
mass_spectrum_obj : MassSpectrum
|
|
219
|
+
The mass spectrum object.
|
|
220
|
+
min_abundance : float
|
|
221
|
+
The minimum abundance threshold.
|
|
222
|
+
|
|
223
|
+
Returns
|
|
224
|
+
-------
|
|
225
|
+
list
|
|
226
|
+
A list of assigned peak indexes.
|
|
227
|
+
"""
|
|
228
|
+
all_assigned_indexes = list()
|
|
229
|
+
|
|
230
|
+
for ms_peak in mass_spectrum_obj.sort_by_abundance():
|
|
231
|
+
if ms_peak:
|
|
232
|
+
continue
|
|
233
|
+
# already assigned a molecular formula
|
|
234
|
+
|
|
235
|
+
nominal_mz = ms_peak.nominal_mz_exp
|
|
236
|
+
|
|
237
|
+
# get mono isotopic peaks that was added a molecular formula obj
|
|
238
|
+
# TODO update error variables
|
|
239
|
+
|
|
240
|
+
possible_formulas_nominal = possible_formulas_dict.get(nominal_mz)
|
|
241
|
+
|
|
242
|
+
if possible_formulas_nominal:
|
|
243
|
+
ms_peak_indexes = SearchMolecularFormulaWorker().find_formulas(
|
|
244
|
+
possible_formulas_nominal,
|
|
245
|
+
min_abundance,
|
|
246
|
+
mass_spectrum_obj,
|
|
247
|
+
ms_peak,
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
all_assigned_indexes.extend(ms_peak_indexes)
|
|
251
|
+
|
|
252
|
+
# filter peaks by percentile threshold of found isotopologues
|
|
253
|
+
all_assigned_indexes = MolecularFormulaSearchFilters().filter_isotopologue(
|
|
254
|
+
all_assigned_indexes, mass_spectrum_obj
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
# filter noise by kendrick density
|
|
258
|
+
all_assigned_indexes = MolecularFormulaSearchFilters().filter_kendrick(
|
|
259
|
+
all_assigned_indexes, mass_spectrum_obj
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
# filter per min peaks per mono isotopic class
|
|
263
|
+
# this function should always be the last filter,
|
|
264
|
+
# thefore no need to return remaining indexes
|
|
265
|
+
MolecularFormulaSearchFilters().check_min_peaks(
|
|
266
|
+
all_assigned_indexes, mass_spectrum_obj
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
# error_average = self.mass_spectrum_obj.molecular_search_settings.mz_error_average
|
|
270
|
+
|
|
271
|
+
kmd_base = self.mass_spectrum_obj.mspeaks_settings.kendrick_base
|
|
272
|
+
|
|
273
|
+
self.mass_spectrum_obj.change_kendrick_base_all_mspeaks(kmd_base)
|
|
274
|
+
|
|
275
|
+
ClusteringFilter().filter_kendrick(self.mass_spectrum_obj)
|
|
276
|
+
|
|
277
|
+
min_abundance = self.mass_spectrum_obj.min_abundance
|
|
278
|
+
|
|
279
|
+
list_classes_str = [i[0] for i in assign_classes_order_tuples]
|
|
280
|
+
verbose = self.mass_spectrum_obj.parameters.mass_spectrum.verbose_processing
|
|
281
|
+
pbar = tqdm.tqdm(assign_classes_order_tuples, disable= not verbose)
|
|
282
|
+
dict_molecular_lookup_table = self.get_dict_molecular_database(list_classes_str)
|
|
283
|
+
|
|
284
|
+
for classe_tuple in pbar:
|
|
285
|
+
classe_str = classe_tuple[0]
|
|
286
|
+
classe_dict = classe_tuple[1]
|
|
287
|
+
|
|
288
|
+
set_min_max_dbe_by_oxygen(classe_dict)
|
|
289
|
+
|
|
290
|
+
# if len(classe_dict.keys()) == 2:
|
|
291
|
+
# if classe_dict.get('S') == 1:
|
|
292
|
+
# continue
|
|
293
|
+
# limits the dbe by the Ox class most abundant,
|
|
294
|
+
# need to add other atoms contribution to be more accurate
|
|
295
|
+
# but +-7 should be sufficient to cover the range
|
|
296
|
+
|
|
297
|
+
if self.mass_spectrum_obj.molecular_search_settings.isProtonated:
|
|
298
|
+
# tqdm.set_description_str(desc=None, refresh=True)
|
|
299
|
+
if verbose:
|
|
300
|
+
pbar.set_description_str(
|
|
301
|
+
desc="Started molecular formula search for class %s, (de)protonated "
|
|
302
|
+
% classe_str,
|
|
303
|
+
refresh=True,
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
ion_type = Labels.protonated_de_ion
|
|
307
|
+
|
|
308
|
+
possible_formulas_dict = dict_molecular_lookup_table.get(ion_type).get(
|
|
309
|
+
classe_str
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
if possible_formulas_dict:
|
|
313
|
+
run_search(
|
|
314
|
+
possible_formulas_dict, self.mass_spectrum_obj, min_abundance
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
if self.mass_spectrum_obj.molecular_search_settings.isRadical:
|
|
318
|
+
# print("Started molecular formula search for class %s, radical" % classe_str)
|
|
319
|
+
if verbose:
|
|
320
|
+
pbar.set_description_str(
|
|
321
|
+
desc="Started molecular formula search for class %s, radical"
|
|
322
|
+
% classe_str,
|
|
323
|
+
refresh=True,
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
ion_type = Labels.radical_ion
|
|
327
|
+
|
|
328
|
+
possible_formulas_dict = dict_molecular_lookup_table.get(ion_type).get(
|
|
329
|
+
classe_str
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
if possible_formulas_dict:
|
|
333
|
+
run_search(
|
|
334
|
+
possible_formulas_dict, self.mass_spectrum_obj, min_abundance
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
# looks for adduct, used_atom_valences should be 0
|
|
338
|
+
# this code does not support H exchance by halogen atoms
|
|
339
|
+
if self.mass_spectrum_obj.molecular_search_settings.isAdduct:
|
|
340
|
+
if verbose:
|
|
341
|
+
pbar.set_description_str(
|
|
342
|
+
desc="Started molecular formula search for class %s, adduct"
|
|
343
|
+
% classe_str,
|
|
344
|
+
refresh=True,
|
|
345
|
+
)
|
|
346
|
+
# print("Started molecular formula search for class %s, adduct" % classe_str)
|
|
347
|
+
|
|
348
|
+
ion_type = Labels.radical_ion
|
|
349
|
+
|
|
350
|
+
possible_formulas_dict = dict_molecular_lookup_table.get(ion_type).get(
|
|
351
|
+
classe_str
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
""" commenting unfinished code for release 2.0, see end of file for details"""
|
|
355
|
+
# possible_formulas_adduct =self.add_adducts(possible_formulas_dict)
|
|
356
|
+
|
|
357
|
+
# if possible_formulas_adduct:
|
|
358
|
+
|
|
359
|
+
run_search(
|
|
360
|
+
possible_formulas_dict, self.mass_spectrum_obj, min_abundance
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
def get_dict_molecular_database(self, classe_str_list):
|
|
364
|
+
"""Get the molecular database as a dictionary.
|
|
365
|
+
|
|
366
|
+
Parameters
|
|
367
|
+
----------
|
|
368
|
+
classe_str_list : list
|
|
369
|
+
A list of class names.
|
|
370
|
+
|
|
371
|
+
Returns
|
|
372
|
+
-------
|
|
373
|
+
dict
|
|
374
|
+
A dictionary containing the molecular database.
|
|
375
|
+
"""
|
|
376
|
+
nominal_mzs = self.nominal_mzs
|
|
377
|
+
mf_search_settings = self.mass_spectrum_obj.molecular_search_settings
|
|
378
|
+
ion_charge = self.mass_spectrum_obj.polarity
|
|
379
|
+
|
|
380
|
+
sql_db = MolForm_SQL(url=mf_search_settings.url_database)
|
|
381
|
+
|
|
382
|
+
dict_res = {}
|
|
383
|
+
|
|
384
|
+
if mf_search_settings.isProtonated:
|
|
385
|
+
dict_res[Labels.protonated_de_ion] = sql_db.get_dict_by_classes(
|
|
386
|
+
classe_str_list,
|
|
387
|
+
Labels.protonated_de_ion,
|
|
388
|
+
nominal_mzs,
|
|
389
|
+
ion_charge,
|
|
390
|
+
mf_search_settings,
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
if mf_search_settings.isRadical:
|
|
394
|
+
dict_res[Labels.radical_ion] = sql_db.get_dict_by_classes(
|
|
395
|
+
classe_str_list,
|
|
396
|
+
Labels.radical_ion,
|
|
397
|
+
nominal_mzs,
|
|
398
|
+
ion_charge,
|
|
399
|
+
mf_search_settings,
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
if mf_search_settings.isAdduct:
|
|
403
|
+
adduct_list = (
|
|
404
|
+
mf_search_settings.adduct_atoms_neg
|
|
405
|
+
if ion_charge < 0
|
|
406
|
+
else mf_search_settings.adduct_atoms_pos
|
|
407
|
+
)
|
|
408
|
+
dict_res[Labels.adduct_ion] = sql_db.get_dict_by_classes(
|
|
409
|
+
classe_str_list,
|
|
410
|
+
Labels.adduct_ion,
|
|
411
|
+
nominal_mzs,
|
|
412
|
+
ion_charge,
|
|
413
|
+
mf_search_settings,
|
|
414
|
+
adducts=adduct_list,
|
|
415
|
+
)
|
|
416
|
+
|
|
417
|
+
return dict_res
|
|
418
|
+
|
|
419
|
+
def ox_classes_and_peaks_in_order_(self) -> dict:
|
|
420
|
+
"""Get the oxygen classes and associated peaks in order.
|
|
421
|
+
|
|
422
|
+
Returns
|
|
423
|
+
-------
|
|
424
|
+
dict
|
|
425
|
+
A dictionary containing the oxygen classes and associated peaks.
|
|
426
|
+
"""
|
|
427
|
+
# order is only valid in python 3.4 and above
|
|
428
|
+
# change to OrderedDict if your version is lower
|
|
429
|
+
dict_ox_class_and_ms_peak = dict()
|
|
430
|
+
|
|
431
|
+
for mspeak in self.mass_spectrum_obj.sort_by_abundance(reverse=True):
|
|
432
|
+
# change this filter to cia filter, give more option here, confidence, number of isotopologue found etc
|
|
433
|
+
|
|
434
|
+
ox_classe = mspeak.best_molecular_formula_candidate.class_label
|
|
435
|
+
|
|
436
|
+
if ox_classe in dict_ox_class_and_ms_peak.keys():
|
|
437
|
+
# get the most abundant of the same ox class
|
|
438
|
+
if mspeak.abundance > dict_ox_class_and_ms_peak[ox_classe].abundance:
|
|
439
|
+
dict_ox_class_and_ms_peak[ox_classe] = mspeak
|
|
440
|
+
else:
|
|
441
|
+
dict_ox_class_and_ms_peak[ox_classe] = mspeak
|
|
442
|
+
|
|
443
|
+
return dict_ox_class_and_ms_peak
|
|
444
|
+
|
|
445
|
+
def get_classes_in_order(self, dict_ox_class_and_ms_peak) -> [(str, dict)]:
|
|
446
|
+
"""Get the classes in order.
|
|
447
|
+
|
|
448
|
+
Parameters
|
|
449
|
+
----------
|
|
450
|
+
dict_ox_class_and_ms_peak : dict
|
|
451
|
+
A dictionary containing the oxygen classes and associated peaks.
|
|
452
|
+
|
|
453
|
+
Returns
|
|
454
|
+
-------
|
|
455
|
+
list
|
|
456
|
+
A list of tuples containing the class names and dictionaries of class attributes.
|
|
457
|
+
|
|
458
|
+
Notes
|
|
459
|
+
-----
|
|
460
|
+
structure is
|
|
461
|
+
('HC', {'HC': 1})
|
|
462
|
+
"""
|
|
463
|
+
|
|
464
|
+
usedAtoms = deepcopy(self.mass_spectrum_obj.molecular_search_settings.usedAtoms)
|
|
465
|
+
|
|
466
|
+
usedAtoms.pop("C")
|
|
467
|
+
usedAtoms.pop("H")
|
|
468
|
+
usedAtoms.pop("O")
|
|
469
|
+
|
|
470
|
+
min_n, max_n = usedAtoms.get("N") if usedAtoms.get("N") else (0, 0)
|
|
471
|
+
min_s, max_s = usedAtoms.get("S") if usedAtoms.get("S") else (0, 0)
|
|
472
|
+
min_p, max_p = usedAtoms.get("P") if usedAtoms.get("P") else (0, 0)
|
|
473
|
+
|
|
474
|
+
possible_n = [n for n in range(min_n, max_n + 1)]
|
|
475
|
+
possible_s = [s for s in range(min_s, max_s + 1)]
|
|
476
|
+
possible_p = [p for p in range(min_p, max_p + 1)]
|
|
477
|
+
|
|
478
|
+
# used to enforce order for commum atoms
|
|
479
|
+
# and track the atom index in on the tuple in all_atoms_tuples
|
|
480
|
+
atoms_in_order = ["N", "S", "P"]
|
|
481
|
+
|
|
482
|
+
# do number atoms prodcut and remove then from the usedAtoms dict
|
|
483
|
+
all_atoms_tuples = product(possible_n, possible_s, possible_p)
|
|
484
|
+
for atom in atoms_in_order:
|
|
485
|
+
usedAtoms.pop(atom, None)
|
|
486
|
+
|
|
487
|
+
# iterate over other atoms besides C,H, N, O, S and P
|
|
488
|
+
|
|
489
|
+
for selected_atom_label, min_max_tuple in usedAtoms.items():
|
|
490
|
+
min_x = min_max_tuple[0]
|
|
491
|
+
max_x = min_max_tuple[1]
|
|
492
|
+
|
|
493
|
+
possible_x = [x for x in range(min_x, max_x + 1)]
|
|
494
|
+
all_atoms_tuples = product(all_atoms_tuples, possible_x)
|
|
495
|
+
|
|
496
|
+
# merge tuples
|
|
497
|
+
all_atoms_tuples = [
|
|
498
|
+
all_atoms_combined[0] + (all_atoms_combined[1],)
|
|
499
|
+
for all_atoms_combined in all_atoms_tuples
|
|
500
|
+
]
|
|
501
|
+
|
|
502
|
+
# add atom label to the atoms_in_order list
|
|
503
|
+
|
|
504
|
+
# important to index where the atom position is in on the tuple in all_atoms_tuples
|
|
505
|
+
atoms_in_order.append(selected_atom_label)
|
|
506
|
+
|
|
507
|
+
classes_strings_dict_tuples, hc_class = self.get_class_strings_dict(
|
|
508
|
+
all_atoms_tuples, atoms_in_order
|
|
509
|
+
)
|
|
510
|
+
|
|
511
|
+
combined_classes = self.combine_ox_class_with_other(
|
|
512
|
+
atoms_in_order, classes_strings_dict_tuples, dict_ox_class_and_ms_peak
|
|
513
|
+
)
|
|
514
|
+
|
|
515
|
+
combination_classes_ordered = self.sort_classes(
|
|
516
|
+
atoms_in_order, combined_classes
|
|
517
|
+
)
|
|
518
|
+
|
|
519
|
+
oxygen_class_str_dict_tuple = [
|
|
520
|
+
(ox_class, mspeak[0].class_dict)
|
|
521
|
+
for ox_class, mspeak in dict_ox_class_and_ms_peak.items()
|
|
522
|
+
]
|
|
523
|
+
|
|
524
|
+
## add classes together and ignores classes selected from the main series
|
|
525
|
+
for class_tuple in combination_classes_ordered:
|
|
526
|
+
if class_tuple not in oxygen_class_str_dict_tuple:
|
|
527
|
+
oxygen_class_str_dict_tuple.append(class_tuple)
|
|
528
|
+
|
|
529
|
+
return oxygen_class_str_dict_tuple
|
|
530
|
+
|
|
531
|
+
@staticmethod
|
|
532
|
+
def get_class_strings_dict(all_atoms_tuples, atoms_in_order) -> [(str, dict)]:
|
|
533
|
+
"""Get the class strings and dictionaries.
|
|
534
|
+
|
|
535
|
+
Parameters
|
|
536
|
+
----------
|
|
537
|
+
all_atoms_tuples : tuple
|
|
538
|
+
A tuple containing the atoms.
|
|
539
|
+
atoms_in_order : list
|
|
540
|
+
A list of atoms in order.
|
|
541
|
+
|
|
542
|
+
Returns
|
|
543
|
+
--------
|
|
544
|
+
list
|
|
545
|
+
A list of tuples containing the class strings and dictionaries.
|
|
546
|
+
|
|
547
|
+
"""
|
|
548
|
+
classe_list = []
|
|
549
|
+
hc_class = []
|
|
550
|
+
|
|
551
|
+
for all_atoms_tuple in all_atoms_tuples:
|
|
552
|
+
classe_str = ""
|
|
553
|
+
classe_dict = dict()
|
|
554
|
+
|
|
555
|
+
for each_atoms_index, atoms_number in enumerate(all_atoms_tuple):
|
|
556
|
+
if atoms_number != 0:
|
|
557
|
+
classe_str = (
|
|
558
|
+
classe_str
|
|
559
|
+
+ atoms_in_order[each_atoms_index]
|
|
560
|
+
+ str(atoms_number)
|
|
561
|
+
+ " "
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
classe_dict[atoms_in_order[each_atoms_index]] = atoms_number
|
|
565
|
+
|
|
566
|
+
classe_str = classe_str.strip()
|
|
567
|
+
|
|
568
|
+
if len(classe_str) > 0:
|
|
569
|
+
classe_list.append((classe_str, classe_dict))
|
|
570
|
+
|
|
571
|
+
elif len(classe_str) == 0:
|
|
572
|
+
hc_class.append(("HC", {"HC": 1}))
|
|
573
|
+
|
|
574
|
+
return classe_list, hc_class
|
|
575
|
+
|
|
576
|
+
@staticmethod
|
|
577
|
+
def combine_ox_class_with_other(
|
|
578
|
+
atoms_in_order, classes_strings_dict_tuples, dict_ox_class_and_ms_peak
|
|
579
|
+
) -> [dict]:
|
|
580
|
+
"""Combine the oxygen classes with other classes.
|
|
581
|
+
|
|
582
|
+
Parameters
|
|
583
|
+
----------
|
|
584
|
+
atoms_in_order : list
|
|
585
|
+
A list of atoms in order.
|
|
586
|
+
classes_strings_dict_tuples : list
|
|
587
|
+
|
|
588
|
+
dict_ox_class_and_ms_peak : dict
|
|
589
|
+
A dictionary containing the oxygen classes and associated peaks.
|
|
590
|
+
|
|
591
|
+
Returns
|
|
592
|
+
-------
|
|
593
|
+
list
|
|
594
|
+
A list of dictionaries.
|
|
595
|
+
"""
|
|
596
|
+
# sort methods that uses the key of classes dictionary and the atoms_in_order as reference
|
|
597
|
+
# c_tuple[1] = class_dict, because is one key:value map we loop through keys and get the first item only
|
|
598
|
+
# sort by len first then sort based on the atoms_in_order list
|
|
599
|
+
atoms_in_order = Atoms.atoms_order
|
|
600
|
+
|
|
601
|
+
Oxygen_mfs = dict_ox_class_and_ms_peak.values()
|
|
602
|
+
|
|
603
|
+
# sort_method = lambda word: (len(word[0]), [atoms_in_order.index(atom) for atom in list( word[1].keys())])
|
|
604
|
+
|
|
605
|
+
# print(classes_strings_dict_tuples)
|
|
606
|
+
# classe_in_order = sorted(classes_strings_dict_tuples, key = sort_method)
|
|
607
|
+
# print(classe_in_order)
|
|
608
|
+
|
|
609
|
+
combination = []
|
|
610
|
+
|
|
611
|
+
# _ ignoring the class_str
|
|
612
|
+
for _, other_classe_dict in classes_strings_dict_tuples:
|
|
613
|
+
# combination.extend([[other_classe_str + ' ' + Oxygen_mf[0].class_label , {**other_classe_dict, **Oxygen_mf[0].class_dict}] for Oxygen_mf in Oxygen_mfs])
|
|
614
|
+
combination.extend(
|
|
615
|
+
[
|
|
616
|
+
{**other_classe_dict, **Oxygen_mf[0].class_dict}
|
|
617
|
+
for Oxygen_mf in Oxygen_mfs
|
|
618
|
+
]
|
|
619
|
+
)
|
|
620
|
+
|
|
621
|
+
return combination
|
|
622
|
+
|
|
623
|
+
@staticmethod
|
|
624
|
+
def sort_classes(atoms_in_order, combination_tuples) -> [(str, dict)]:
|
|
625
|
+
"""Sort the classes.
|
|
626
|
+
|
|
627
|
+
Parameters
|
|
628
|
+
----------
|
|
629
|
+
atoms_in_order : list
|
|
630
|
+
A list of atoms in order.
|
|
631
|
+
combination_tuples : list
|
|
632
|
+
|
|
633
|
+
Returns
|
|
634
|
+
-------
|
|
635
|
+
list
|
|
636
|
+
A list of tuples containing the class strings and dictionaries.
|
|
637
|
+
"""
|
|
638
|
+
join_list_of_list_classes = list()
|
|
639
|
+
atoms_in_order = ["N", "S", "P", "O"] + atoms_in_order[3:]
|
|
640
|
+
|
|
641
|
+
sort_method = (
|
|
642
|
+
lambda atoms_keys: [atoms_in_order.index(atoms_keys)]
|
|
643
|
+
) # (len(word[0]), print(word[1]))#[atoms_in_order.index(atom) for atom in list( word[1].keys())])
|
|
644
|
+
for class_dict in combination_tuples:
|
|
645
|
+
sorted_dict_keys = sorted(class_dict, key=sort_method)
|
|
646
|
+
class_str = " ".join(
|
|
647
|
+
[atom + str(class_dict[atom]) for atom in sorted_dict_keys]
|
|
648
|
+
)
|
|
649
|
+
new_class_dict = {atom: class_dict[atom] for atom in sorted_dict_keys}
|
|
650
|
+
join_list_of_list_classes.append((class_str, new_class_dict))
|
|
651
|
+
|
|
652
|
+
return join_list_of_list_classes
|
|
653
|
+
|
|
654
|
+
'''
|
|
655
|
+
The code bellow is unfinished, might be added to next release, 2.1
|
|
656
|
+
def add_adducts(self, possible_formulas):
|
|
657
|
+
""" Add adducts to the molecular formula candidates.
|
|
658
|
+
|
|
659
|
+
Parameters
|
|
660
|
+
----------
|
|
661
|
+
possible_formulas : dict
|
|
662
|
+
A dictionary of possible molecular formulas.
|
|
663
|
+
|
|
664
|
+
Returns
|
|
665
|
+
-------
|
|
666
|
+
dict
|
|
667
|
+
A dictionary of possible molecular formulas with adducts.
|
|
668
|
+
|
|
669
|
+
"""
|
|
670
|
+
ion_type = Labels.adduct_ion
|
|
671
|
+
|
|
672
|
+
if self.mass_spectrum_obj.polarity < 0:
|
|
673
|
+
adduct_atoms = self.mass_spectrum_obj.molecular_search_settings.adduct_atoms_neg
|
|
674
|
+
molform_model = MolecularFormulaDict
|
|
675
|
+
else:
|
|
676
|
+
adduct_atoms = self.mass_spectrum_obj.molecular_search_settings.adduct_atoms_pos
|
|
677
|
+
molform_model = MolecularFormulaTablePos
|
|
678
|
+
|
|
679
|
+
new_dict = {}
|
|
680
|
+
|
|
681
|
+
for nominal_mz, list_formulas in possible_formulas.items():
|
|
682
|
+
|
|
683
|
+
for adduct_atom in adduct_atoms:
|
|
684
|
+
|
|
685
|
+
adduct_atom_mass= Atoms.atomic_masses.get(adduct_atom)
|
|
686
|
+
|
|
687
|
+
for molecularFormulaTable in list_formulas:
|
|
688
|
+
|
|
689
|
+
formula_dict = json.loads(molecularFormulaTable.mol_formula)
|
|
690
|
+
|
|
691
|
+
if adduct_atom in formula_dict.keys():
|
|
692
|
+
formula_dict[adduct_atom] += 1
|
|
693
|
+
else:
|
|
694
|
+
formula_dict[adduct_atom] = 1
|
|
695
|
+
|
|
696
|
+
mz = adduct_atom_mass + molecularFormulaTable.mz
|
|
697
|
+
nm = int(mz)
|
|
698
|
+
|
|
699
|
+
new_formul_obj = molform_model( **{"mol_formula" : json.dumps(formula_dict),
|
|
700
|
+
"mz" : mz,
|
|
701
|
+
"ion_type" : ion_type,
|
|
702
|
+
"nominal_mz" : nm,
|
|
703
|
+
"ion_charge" : molecularFormulaTable.ion_charge,
|
|
704
|
+
"classe" : molecularFormulaTable.classe,
|
|
705
|
+
"C" : molecularFormulaTable.C,
|
|
706
|
+
"H" : molecularFormulaTable.H,
|
|
707
|
+
"N" : molecularFormulaTable.N,
|
|
708
|
+
"O" : molecularFormulaTable.O,
|
|
709
|
+
"S" : molecularFormulaTable.S,
|
|
710
|
+
"P" : molecularFormulaTable.P,
|
|
711
|
+
"H_C" : molecularFormulaTable.H_C,
|
|
712
|
+
"O_C" : molecularFormulaTable.O_C,
|
|
713
|
+
"DBE" : molecularFormulaTable.DBE,
|
|
714
|
+
})
|
|
715
|
+
if nm in new_dict:
|
|
716
|
+
new_dict[nm].append(new_formul_obj)
|
|
717
|
+
|
|
718
|
+
else:
|
|
719
|
+
new_dict[nm]= [new_formul_obj]
|
|
720
|
+
|
|
721
|
+
return new_dict
|
|
722
|
+
|
|
723
|
+
'''
|