CoreMS 3.1.0__tar.gz → 3.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. {CoreMS-3.1.0 → CoreMS-3.2.0}/CoreMS.egg-info/PKG-INFO +4 -4
  2. {CoreMS-3.1.0 → CoreMS-3.2.0}/CoreMS.egg-info/requires.txt +1 -0
  3. {CoreMS-3.1.0 → CoreMS-3.2.0}/PKG-INFO +4 -4
  4. {CoreMS-3.1.0 → CoreMS-3.2.0}/README.md +3 -3
  5. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/__init__.py +17 -14
  6. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/encapsulation/factory/parameters.py +6 -0
  7. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/encapsulation/factory/processingSetting.py +3 -0
  8. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/factory/GC_Class.py +16 -4
  9. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/calc/Calibration.py +2 -6
  10. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/calc/MassErrorPrediction.py +2 -2
  11. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/calc/MassSpectrumCalc.py +6 -3
  12. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/input/massList.py +28 -23
  13. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/factory/MolecularLookupTable.py +9 -5
  14. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/factory/molecularSQL.py +2 -4
  15. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/search/compoundSearch.py +2 -3
  16. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/search/database_interfaces.py +68 -14
  17. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/search/lcms_spectral_search.py +1 -1
  18. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/search/molecularFormulaSearch.py +272 -133
  19. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/search/priorityAssignment.py +20 -18
  20. {CoreMS-3.1.0 → CoreMS-3.2.0}/requirements.txt +1 -0
  21. {CoreMS-3.1.0 → CoreMS-3.2.0}/setup.py +1 -1
  22. CoreMS-3.2.0/tests/test_gcms.py +92 -0
  23. {CoreMS-3.1.0 → CoreMS-3.2.0}/tests/test_setting_settings.py +26 -0
  24. {CoreMS-3.1.0 → CoreMS-3.2.0}/tests/test_wf_lipidomics.py +6 -22
  25. CoreMS-3.1.0/tests/test_gcms.py +0 -131
  26. {CoreMS-3.1.0 → CoreMS-3.2.0}/CoreMS.egg-info/SOURCES.txt +0 -0
  27. {CoreMS-3.1.0 → CoreMS-3.2.0}/CoreMS.egg-info/dependency_links.txt +0 -0
  28. {CoreMS-3.1.0 → CoreMS-3.2.0}/CoreMS.egg-info/top_level.txt +0 -0
  29. {CoreMS-3.1.0 → CoreMS-3.2.0}/Dockerfile +0 -0
  30. {CoreMS-3.1.0 → CoreMS-3.2.0}/LICENSE +0 -0
  31. {CoreMS-3.1.0 → CoreMS-3.2.0}/MANIFEST.in +0 -0
  32. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/chroma_peak/__init__.py +0 -0
  33. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/chroma_peak/calc/ChromaPeakCalc.py +0 -0
  34. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/chroma_peak/calc/__init__.py +0 -0
  35. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/chroma_peak/factory/__init__.py +0 -0
  36. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/chroma_peak/factory/chroma_peak_classes.py +0 -0
  37. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/encapsulation/__init__.py +0 -0
  38. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/encapsulation/constant.py +0 -0
  39. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/encapsulation/factory/__init__.py +0 -0
  40. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/encapsulation/input/__init__.py +0 -0
  41. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/encapsulation/input/parameter_from_json.py +0 -0
  42. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/encapsulation/output/__init__.py +0 -0
  43. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/encapsulation/output/parameter_to_dict.py +0 -0
  44. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/encapsulation/output/parameter_to_json.py +0 -0
  45. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/__init__.py +0 -0
  46. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/calc/GC_Calc.py +0 -0
  47. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/calc/GC_Deconvolution.py +0 -0
  48. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/calc/GC_RI_Calibration.py +0 -0
  49. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/calc/MZSearch.py +0 -0
  50. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/calc/SignalProcessing.py +0 -0
  51. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/calc/__init__.py +0 -0
  52. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/calc/lc_calc.py +0 -0
  53. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/factory/__init__.py +0 -0
  54. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/factory/chromat_data.py +0 -0
  55. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/factory/lc_class.py +0 -0
  56. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/input/__init__.py +0 -0
  57. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/input/andiNetCDF.py +0 -0
  58. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/input/boosterHDF5.py +0 -0
  59. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/input/brukerSolarix.py +0 -0
  60. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/input/corems_hdf5.py +0 -0
  61. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/input/massList.py +0 -0
  62. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/input/mzml.py +0 -0
  63. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/input/parserbase.py +0 -0
  64. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/input/rawFileReader.py +0 -0
  65. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/output/__init__.py +0 -0
  66. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectra/output/export.py +0 -0
  67. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/__init__.py +0 -0
  68. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/calc/AutoRecalibration.py +0 -0
  69. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/calc/CalibrationCalc.py +0 -0
  70. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/calc/KendrickGroup.py +0 -0
  71. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/calc/MeanResolvingPowerFilter.py +0 -0
  72. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/calc/NoiseCalc.py +0 -0
  73. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/calc/NoiseCalc_Bayes.py +0 -0
  74. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/calc/PeakPicking.py +0 -0
  75. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/calc/__init__.py +0 -0
  76. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/factory/MassSpectrumClasses.py +0 -0
  77. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/factory/__init__.py +0 -0
  78. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/input/__init__.py +0 -0
  79. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/input/baseClass.py +0 -0
  80. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/input/boosterHDF5.py +0 -0
  81. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/input/coremsHDF5.py +0 -0
  82. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/input/numpyArray.py +0 -0
  83. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/output/__init__.py +0 -0
  84. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/mass_spectrum/output/export.py +0 -0
  85. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_formula/__init__.py +0 -0
  86. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_formula/calc/MolecularFormulaCalc.py +0 -0
  87. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_formula/calc/__init__.py +0 -0
  88. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_formula/factory/MolecularFormulaFactory.py +0 -0
  89. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_formula/factory/__init__.py +0 -0
  90. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_formula/input/__init__.py +0 -0
  91. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_formula/input/masslist_ref.py +0 -0
  92. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/__init__.py +0 -0
  93. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/calc/ClusterFilter.py +0 -0
  94. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/calc/MolecularFilter.py +0 -0
  95. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/calc/SpectralSimilarity.py +0 -0
  96. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/calc/__init__.py +0 -0
  97. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/calc/math_distance.py +0 -0
  98. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/factory/EI_SQL.py +0 -0
  99. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/factory/__init__.py +0 -0
  100. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/factory/classification.py +0 -0
  101. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/factory/lipid_molecular_metadata.py +0 -0
  102. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/factory/spectrum_search_results.py +0 -0
  103. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/input/__init__.py +0 -0
  104. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/input/nistMSI.py +0 -0
  105. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/search/__init__.py +0 -0
  106. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/molecular_id/search/findOxygenPeaks.py +0 -0
  107. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/ms_peak/__init__.py +0 -0
  108. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/ms_peak/calc/MSPeakCalc.py +0 -0
  109. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/ms_peak/calc/__init__.py +0 -0
  110. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/ms_peak/factory/MSPeakClasses.py +0 -0
  111. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/ms_peak/factory/__init__.py +0 -0
  112. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/transient/__init__.py +0 -0
  113. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/transient/calc/TransientCalc.py +0 -0
  114. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/transient/calc/__init__.py +0 -0
  115. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/transient/factory/TransientClasses.py +0 -0
  116. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/transient/factory/__init__.py +0 -0
  117. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/transient/input/__init__.py +0 -0
  118. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/transient/input/brukerSolarix.py +0 -0
  119. {CoreMS-3.1.0 → CoreMS-3.2.0}/corems/transient/input/midasDatFile.py +0 -0
  120. {CoreMS-3.1.0 → CoreMS-3.2.0}/disclaimer.txt +0 -0
  121. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/ChemstationMSFileReader.dll +0 -0
  122. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/ChemstationMSFileReader.xml +0 -0
  123. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/RawFileReaderLicense.doc +0 -0
  124. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/ThermoFisher.CommonCore.BackgroundSubtraction.dll +0 -0
  125. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/ThermoFisher.CommonCore.BackgroundSubtraction.xml +0 -0
  126. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/ThermoFisher.CommonCore.Data.dll +0 -0
  127. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/ThermoFisher.CommonCore.Data.xml +0 -0
  128. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/ThermoFisher.CommonCore.MassPrecisionEstimator.dll +0 -0
  129. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/ThermoFisher.CommonCore.MassPrecisionEstimator.xml +0 -0
  130. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/ThermoFisher.CommonCore.RawFileReader.dll +0 -0
  131. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/ThermoFisher.CommonCore.RawFileReader.xml +0 -0
  132. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/__init__.py +0 -0
  133. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/OpenMcdf.Extensions.dll +0 -0
  134. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/OpenMcdf.dll +0 -0
  135. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/OpenMcdf.xml +0 -0
  136. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/System.IO.FileSystem.AccessControl.dll +0 -0
  137. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/System.IO.FileSystem.AccessControl.xml +0 -0
  138. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/System.Security.AccessControl.dll +0 -0
  139. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/System.Security.AccessControl.xml +0 -0
  140. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/System.Security.Principal.Windows.dll +0 -0
  141. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/System.Security.Principal.Windows.xml +0 -0
  142. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/ThermoFisher.CommonCore.BackgroundSubtraction.dll +0 -0
  143. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/ThermoFisher.CommonCore.BackgroundSubtraction.xml +0 -0
  144. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/ThermoFisher.CommonCore.Data.dll +0 -0
  145. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/ThermoFisher.CommonCore.Data.xml +0 -0
  146. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/ThermoFisher.CommonCore.MassPrecisionEstimator.dll +0 -0
  147. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/ThermoFisher.CommonCore.MassPrecisionEstimator.xml +0 -0
  148. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/ThermoFisher.CommonCore.RawFileReader.dll +0 -0
  149. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/dotnet/ThermoFisher.CommonCore.RawFileReader.xml +0 -0
  150. {CoreMS-3.1.0 → CoreMS-3.2.0}/ext_lib/version +0 -0
  151. {CoreMS-3.1.0 → CoreMS-3.2.0}/setup.cfg +0 -0
  152. {CoreMS-3.1.0 → CoreMS-3.2.0}/tests/test_calibration.py +0 -0
  153. {CoreMS-3.1.0 → CoreMS-3.2.0}/tests/test_classification.py +0 -0
  154. {CoreMS-3.1.0 → CoreMS-3.2.0}/tests/test_input.py +0 -0
  155. {CoreMS-3.1.0 → CoreMS-3.2.0}/tests/test_mass_spectrum.py +0 -0
  156. {CoreMS-3.1.0 → CoreMS-3.2.0}/tests/test_mass_spectrum_export_import.py +0 -0
  157. {CoreMS-3.1.0 → CoreMS-3.2.0}/tests/test_molecular_formula.py +0 -0
  158. {CoreMS-3.1.0 → CoreMS-3.2.0}/tests/test_molecular_formula_db_factory.py +0 -0
  159. {CoreMS-3.1.0 → CoreMS-3.2.0}/tests/test_molecular_formula_search.py +0 -0
  160. {CoreMS-3.1.0 → CoreMS-3.2.0}/tests/test_mspeak.py +0 -0
  161. {CoreMS-3.1.0 → CoreMS-3.2.0}/tests/test_output.py +0 -0
  162. {CoreMS-3.1.0 → CoreMS-3.2.0}/tests/test_search_mass_list.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: CoreMS
3
- Version: 3.1.0
3
+ Version: 3.2.0
4
4
  Summary: Mass Spectrometry Framework for Small Molecules Analysis
5
5
  Home-page: https://github.com/EMSL-Computing/CoreMS
6
6
  Author: Corilo, Yuri
@@ -65,7 +65,7 @@ CoreMS aims to provide
65
65
 
66
66
  ## Current Version
67
67
 
68
- `3.1.0`
68
+ `3.2.0`
69
69
 
70
70
  ***
71
71
 
@@ -351,11 +351,11 @@ UML (unified modeling language) diagrams for Direct Infusion FT-MS and GC-MS cla
351
351
 
352
352
  If you use CoreMS in your work, please use the following citation:
353
353
 
354
- Version [3.1.0 Release on GitHub](https://github.com/EMSL-Computing/CoreMS/releases/tag/v3.1.0), archived on Zenodo:
354
+ Version [3.2.0 Release on GitHub](https://github.com/EMSL-Computing/CoreMS/releases/tag/v3.2.0), archived on Zenodo:
355
355
 
356
356
  [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.14009575.svg)](https://doi.org/10.5281/zenodo.14009575)
357
357
 
358
- Yuri E. Corilo, William R. Kew, Lee Ann McCue, Katherine R . Heal, James C. Carr (2024, October 29). EMSL-Computing/CoreMS: CoreMS 3.1.0 (Version v3.1.0), as developed on Github. Zenodo. http://doi.org/10.5281/zenodo.14009575
358
+ Yuri E. Corilo, William R. Kew, Lee Ann McCue, Katherine R . Heal, James C. Carr (2024, October 29). EMSL-Computing/CoreMS: CoreMS 3.2.0 (Version v3.2.0), as developed on Github. Zenodo. http://doi.org/10.5281/zenodo.14009575
359
359
 
360
360
  ```
361
361
 
@@ -10,6 +10,7 @@ netCDF4~=1.6.3
10
10
  numpy~=1.24.2
11
11
  openpyxl~=3.1.1
12
12
  pandas~=1.5.3
13
+ psycopg2~=2.9.10
13
14
  pyswarm~=0.6
14
15
  pythonnet~=3.0.1
15
16
  pymzml~=2.5.2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: CoreMS
3
- Version: 3.1.0
3
+ Version: 3.2.0
4
4
  Summary: Mass Spectrometry Framework for Small Molecules Analysis
5
5
  Home-page: https://github.com/EMSL-Computing/CoreMS
6
6
  Author: Corilo, Yuri
@@ -65,7 +65,7 @@ CoreMS aims to provide
65
65
 
66
66
  ## Current Version
67
67
 
68
- `3.1.0`
68
+ `3.2.0`
69
69
 
70
70
  ***
71
71
 
@@ -351,11 +351,11 @@ UML (unified modeling language) diagrams for Direct Infusion FT-MS and GC-MS cla
351
351
 
352
352
  If you use CoreMS in your work, please use the following citation:
353
353
 
354
- Version [3.1.0 Release on GitHub](https://github.com/EMSL-Computing/CoreMS/releases/tag/v3.1.0), archived on Zenodo:
354
+ Version [3.2.0 Release on GitHub](https://github.com/EMSL-Computing/CoreMS/releases/tag/v3.2.0), archived on Zenodo:
355
355
 
356
356
  [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.14009575.svg)](https://doi.org/10.5281/zenodo.14009575)
357
357
 
358
- Yuri E. Corilo, William R. Kew, Lee Ann McCue, Katherine R . Heal, James C. Carr (2024, October 29). EMSL-Computing/CoreMS: CoreMS 3.1.0 (Version v3.1.0), as developed on Github. Zenodo. http://doi.org/10.5281/zenodo.14009575
358
+ Yuri E. Corilo, William R. Kew, Lee Ann McCue, Katherine R . Heal, James C. Carr (2024, October 29). EMSL-Computing/CoreMS: CoreMS 3.2.0 (Version v3.2.0), as developed on Github. Zenodo. http://doi.org/10.5281/zenodo.14009575
359
359
 
360
360
  ```
361
361
 
@@ -49,7 +49,7 @@ CoreMS aims to provide
49
49
 
50
50
  ## Current Version
51
51
 
52
- `3.1.0`
52
+ `3.2.0`
53
53
 
54
54
  ***
55
55
 
@@ -335,11 +335,11 @@ UML (unified modeling language) diagrams for Direct Infusion FT-MS and GC-MS cla
335
335
 
336
336
  If you use CoreMS in your work, please use the following citation:
337
337
 
338
- Version [3.1.0 Release on GitHub](https://github.com/EMSL-Computing/CoreMS/releases/tag/v3.1.0), archived on Zenodo:
338
+ Version [3.2.0 Release on GitHub](https://github.com/EMSL-Computing/CoreMS/releases/tag/v3.2.0), archived on Zenodo:
339
339
 
340
340
  [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.14009575.svg)](https://doi.org/10.5281/zenodo.14009575)
341
341
 
342
- Yuri E. Corilo, William R. Kew, Lee Ann McCue, Katherine R . Heal, James C. Carr (2024, October 29). EMSL-Computing/CoreMS: CoreMS 3.1.0 (Version v3.1.0), as developed on Github. Zenodo. http://doi.org/10.5281/zenodo.14009575
342
+ Yuri E. Corilo, William R. Kew, Lee Ann McCue, Katherine R . Heal, James C. Carr (2024, October 29). EMSL-Computing/CoreMS: CoreMS 3.2.0 (Version v3.2.0), as developed on Github. Zenodo. http://doi.org/10.5281/zenodo.14009575
343
343
 
344
344
  ```
345
345
 
@@ -1,5 +1,5 @@
1
1
  __author__ = "Yuri E. Corilo"
2
- __version__ = "3.1.0"
2
+ __version__ = "3.2.0"
3
3
  import time
4
4
  import os
5
5
  import sys
@@ -21,19 +21,22 @@ else:
21
21
 
22
22
 
23
23
 
24
- def timeit(method):
25
- def timed(*args, **kw):
26
- ts = time.time()
27
- result = method(*args, **kw)
28
- te = time.time()
29
- if "log_time" in kw:
30
- name = kw.get("log_name", method.__name__.upper())
31
- kw["log_time"][name] = int((te - ts) * 1000)
32
- else:
33
- print("%r %2.2f ms" % (method.__name__, (te - ts) * 1000))
34
- return result
35
-
36
- return timed
24
+ def timeit(print_time=True):
25
+ def decorator(method):
26
+ def timed(*args, **kw):
27
+ # Extract print_time from kwargs if provided
28
+ local_print_time = kw.pop('print_time', print_time)
29
+ ts = time.time()
30
+ result = method(*args, **kw)
31
+ te = time.time()
32
+ if "log_time" in kw:
33
+ name = kw.get("log_name", method.__name__.upper())
34
+ kw["log_time"][name] = int((te - ts) * 1000)
35
+ elif local_print_time:
36
+ print("%r %2.2f ms" % (method.__name__, (te - ts) * 1000))
37
+ return result
38
+ return timed
39
+ return decorator
37
40
 
38
41
 
39
42
  class SuppressPrints:
@@ -13,6 +13,12 @@ from corems.encapsulation.factory.processingSetting import (
13
13
  )
14
14
  from corems.encapsulation.factory.processingSetting import DataInputSetting
15
15
 
16
+ def hush_output():
17
+ """Toggle all the verbose_processing flags to False on the MSParameters, GCMSParameters and LCMSParameters classes"""
18
+ MSParameters.molecular_search.verbose_processing = False
19
+ MSParameters.mass_spectrum.verbose_processing = False
20
+ GCMSParameters.gc_ms.verbose_processing = False
21
+ LCMSParameters.lc_ms.verbose_processing = False
16
22
 
17
23
  def reset_ms_parameters():
18
24
  """Reset the MSParameter class to the default values"""
@@ -816,7 +816,10 @@ class MolecularFormulaSearchSettings:
816
816
  m/z error average. Default is 0.0.
817
817
  used_atom_valences : dict, optional
818
818
  Dictionary of atoms and valences. Default is {'C': 4, '13C': 4, 'H': 1, 'O': 2, '18O': 2, 'N': 3, 'S': 2, '34S': 2, 'P': 3, 'Cl': 1, '37Cl': 1, 'Br': 1, 'Na': 1, 'F': 1, 'K': 0}.
819
+ verbose_processing: bool, optional
820
+ If True, print verbose processing information. Default is True.
819
821
  """
822
+ verbose_processing: bool = True
820
823
 
821
824
  use_isotopologue_filter: bool = False
822
825
 
@@ -201,6 +201,18 @@ class GCMSBase(GC_Calculations, MassDeconvolution):
201
201
 
202
202
  self.scans_number = sorted(self._ms.keys())
203
203
 
204
+ @property
205
+ def parameters(self):
206
+ """GCMS Parameters"""
207
+ return self._parameters
208
+
209
+ @parameters.setter
210
+ def parameters(self, gcms_parameters_instance):
211
+ self._parameters = gcms_parameters_instance
212
+
213
+ # Note: maintaining `parameter` for backwards compatibility,
214
+ # but proper usage would reference `parameters` to conform
215
+ # to other classes.
204
216
  @property
205
217
  def parameter(self):
206
218
  """GCMS Parameters"""
@@ -213,20 +225,20 @@ class GCMSBase(GC_Calculations, MassDeconvolution):
213
225
  @property
214
226
  def molecular_search_settings(self):
215
227
  """Molecular Search Settings"""
216
- return self.parameter.molecular_search
228
+ return self.parameters.molecular_search
217
229
 
218
230
  @molecular_search_settings.setter
219
231
  def molecular_search_settings(self, settings_class_instance):
220
- self.parameter.molecular_search = settings_class_instance
232
+ self.parameters.molecular_search = settings_class_instance
221
233
 
222
234
  @property
223
235
  def chromatogram_settings(self):
224
236
  """Chromatogram Settings"""
225
- return self.parameter.gc_ms
237
+ return self.parameters.gc_ms
226
238
 
227
239
  @chromatogram_settings.setter
228
240
  def chromatogram_settings(self, settings_class_instance):
229
- self.parameter.gc_ms = settings_class_instance
241
+ self.parameters.gc_ms = settings_class_instance
230
242
 
231
243
  @property
232
244
  def scans_number(self):
@@ -65,7 +65,7 @@ class MzDomainCalibration:
65
65
 
66
66
  # define reference mass list - bruker .ref format
67
67
  self.ref_mass_list_path = ref_masslist
68
- if self.mass_spectrum.percentile_assigned()[0] != 0:
68
+ if self.mass_spectrum.percentile_assigned(mute_output=True)[0] != 0:
69
69
  warnings.warn(
70
70
  "Warning: calibrating spectra which have already been assigned may yield erroneous results"
71
71
  )
@@ -77,10 +77,6 @@ class MzDomainCalibration:
77
77
  "MS Obj loaded - " + str(len(mass_spectrum.mspeaks)) + " peaks found."
78
78
  )
79
79
 
80
- print(
81
- "MS Obj loaded - " + str(len(mass_spectrum.mspeaks)) + " peaks found."
82
- )
83
-
84
80
  def load_ref_mass_list(self):
85
81
  """Load reference mass list (Bruker format)
86
82
 
@@ -228,7 +224,7 @@ class MzDomainCalibration:
228
224
  cal_peaks_mz = list(tmpdf.values)
229
225
  cal_refs_mz = list(tmpdf.index)
230
226
  elif calibration_ref_match_method == "merged":
231
- warnings.warn("Using experimental new reference mass list merging")
227
+ #warnings.warn("Using experimental new reference mass list merging")
232
228
  # This is a new approach (August 2024) which uses Pandas 'merged_asof' to find the peaks closest in m/z between
233
229
  # reference and measured masses. This is a quicker way to match, and seems to get more matches.
234
230
  # It may not work as well when the data are far from correc initial mass
@@ -90,12 +90,12 @@ class MassErrorPrediction(Thread):
90
90
 
91
91
  def calc_error_dist(self):
92
92
  """Calculate the error distribution."""
93
+ verbose = self.mass_spectrum_obj.parameters.mass_spectrum.verbose_processing
93
94
  results_list = []
94
95
 
95
96
  indexes_without_results = list(range(len(self.mass_spectrum_obj)))
96
97
  # loop trough mass spectrum
97
-
98
- for peak_obj_idx, peak_obj in enumerate(tqdm(self.mass_spectrum_obj)):
98
+ for peak_obj_idx, peak_obj in enumerate(tqdm(self.mass_spectrum_obj), disable=not verbose):
99
99
  # access ms peaks triplets ( peak_obj_idx -1, peak_obj_idx, and peak_obj_idx + 1)
100
100
  # check lower and upper boundaries to not excesses mass spectrum range
101
101
 
@@ -38,13 +38,16 @@ class MassSpecCalc(PeakPicking, NoiseThresholdCalc):
38
38
  Calculate the weight average molecular weight
39
39
  """
40
40
 
41
- def percentile_assigned(self, report_error: bool = False):
41
+ def percentile_assigned(self, report_error: bool = False, mute_output: bool = False):
42
42
  """Percentage of peaks which are assigned
43
43
 
44
44
  Parameters
45
45
  -----------
46
46
  report_error: bool, optional
47
47
  Report the error of the assigned peaks. Default is False.
48
+ mute_output: bool, optional
49
+ Override the verbose setting. Default is False.
50
+ If True, the function will silence results
48
51
  """
49
52
  verbose = self.parameters.mass_spectrum.verbose_processing
50
53
  assign_abun = 0
@@ -68,7 +71,7 @@ class MassSpecCalc(PeakPicking, NoiseThresholdCalc):
68
71
  total_relative_abundance = (assign_abun / (not_assign_abun + assign_abun)) * 100
69
72
  if report_error:
70
73
  rms_error = sqrt(mean(array(error) ** 2))
71
- if verbose:
74
+ if verbose and not mute_output:
72
75
  print(
73
76
  "%i assigned peaks and %i unassigned peaks, total = %.2f %%, relative abundance = %.2f %%, RMS error (best candidate) (ppm) = %.3f"
74
77
  % (i, j, total_percent, total_relative_abundance, rms_error)
@@ -76,7 +79,7 @@ class MassSpecCalc(PeakPicking, NoiseThresholdCalc):
76
79
  return i, j, total_percent, total_relative_abundance, rms_error
77
80
 
78
81
  else:
79
- if verbose:
82
+ if verbose and not mute_output:
80
83
  print(
81
84
  "%i assigned peaks and %i unassigned peaks , total = %.2f %%, relative abundance = %.2f %%"
82
85
  % (
@@ -106,6 +106,7 @@ class ReadCoremsMasslist(MassListBaseClass):
106
106
  mass_spec_mz_exp_list = mass_spec_obj.mz_exp
107
107
 
108
108
  for df_index, mz_exp in enumerate(mz_exp_df):
109
+ bad_mf = False
109
110
  counts = 0
110
111
 
111
112
  ms_peak_index = list(mass_spec_mz_exp_list).index(float(mz_exp))
@@ -175,7 +176,7 @@ class ReadCoremsMasslist(MassListBaseClass):
175
176
  # Next, generate isotopologues from the parent
176
177
  isos = list(
177
178
  mono_mfobj.isotopologues(
178
- min_abundance=mass_spec_obj[df_index].abundance * 0.001,
179
+ min_abundance=mass_spec_obj.abundance.min()*0.01,
179
180
  current_mono_abundance=mass_spec_obj[mono_index].abundance,
180
181
  dynamic_range=mass_spec_obj.dynamic_range,
181
182
  )
@@ -200,28 +201,32 @@ class ReadCoremsMasslist(MassListBaseClass):
200
201
  matched_isos.append(iso)
201
202
 
202
203
  if len(matched_isos) == 0:
203
- raise ValueError("No isotopologue matched the formula_dict")
204
- mfobj = matched_isos[0]
205
-
206
- # Add the mono isotopic index, confidence score and isotopologue similarity
207
- mfobj.mspeak_index_mono_isotopic = int(
208
- dataframe.iloc[df_index]["Mono Isotopic Index"]
209
- )
210
-
211
- # Add the confidence score and isotopologue similarity and average MZ error score
212
- if "m/z Error Score" in dataframe:
213
- mfobj._mass_error_average_score = float(
214
- dataframe.iloc[df_index]["m/z Error Score"]
215
- )
216
- if "Confidence Score" in dataframe:
217
- mfobj._confidence_score = float(
218
- dataframe.iloc[df_index]["Confidence Score"]
219
- )
220
- if "Isotopologue Similarity" in dataframe:
221
- mfobj._isotopologue_similarity = float(
222
- dataframe.iloc[df_index]["Isotopologue Similarity"]
223
- )
224
- mass_spec_obj[ms_peak_index].add_molecular_formula(mfobj)
204
+ #FIXME: This should not occur see https://code.emsl.pnl.gov/mass-spectrometry/corems/-/issues/190
205
+ warnings.warn(f"No isotopologue matched the formula_dict: {formula_dict}")
206
+ bad_mf = True
207
+ else:
208
+ bad_mf = False
209
+ mfobj = matched_isos[0]
210
+
211
+ # Add the mono isotopic index, confidence score and isotopologue similarity
212
+ mfobj.mspeak_index_mono_isotopic = int(
213
+ dataframe.iloc[df_index]["Mono Isotopic Index"]
214
+ )
215
+ if not bad_mf:
216
+ # Add the confidence score and isotopologue similarity and average MZ error score
217
+ if "m/z Error Score" in dataframe:
218
+ mfobj._mass_error_average_score = float(
219
+ dataframe.iloc[df_index]["m/z Error Score"]
220
+ )
221
+ if "Confidence Score" in dataframe:
222
+ mfobj._confidence_score = float(
223
+ dataframe.iloc[df_index]["Confidence Score"]
224
+ )
225
+ if "Isotopologue Similarity" in dataframe:
226
+ mfobj._isotopologue_similarity = float(
227
+ dataframe.iloc[df_index]["Isotopologue Similarity"]
228
+ )
229
+ mass_spec_obj[ms_peak_index].add_molecular_formula(mfobj)
225
230
 
226
231
 
227
232
  class ReadMassList(MassListBaseClass):
@@ -364,14 +364,17 @@ class MolecularCombinations:
364
364
  self.sql_db.session.execute(insert_query)
365
365
  self.sql_db.session.commit()
366
366
 
367
- @timeit
368
- def runworker(self, molecular_search_settings):
367
+ @timeit(print_time=True)
368
+ def runworker(self, molecular_search_settings, **kwargs):
369
369
  """Run the molecular formula lookup table worker.
370
370
 
371
371
  Parameters
372
372
  ----------
373
373
  molecular_search_settings : object
374
374
  An object containing user-defined settings.
375
+ kwargs : dict
376
+ A dictionary of keyword arguments.
377
+ Most notably, the print_time argument which is passed to the timeit decorator.
375
378
 
376
379
  Returns
377
380
  -------
@@ -380,6 +383,7 @@ class MolecularCombinations:
380
383
 
381
384
 
382
385
  """
386
+ verbose = molecular_search_settings.verbose_processing
383
387
 
384
388
  classes_list, class_to_create, existing_classes_objs = (
385
389
  self.check_database_get_class_list(molecular_search_settings)
@@ -412,7 +416,7 @@ class MolecularCombinations:
412
416
  self.even_ch_dbe = [obj.dbe for obj in even_ch_obj]
413
417
 
414
418
  all_results = list()
415
- for class_tuple in tqdm(class_to_create):
419
+ for class_tuple in tqdm(class_to_create, disable = not verbose):
416
420
  results = self.populate_combinations(class_tuple, settings)
417
421
  all_results.extend(results)
418
422
  if settings.db_jobs == 1:
@@ -438,8 +442,8 @@ class MolecularCombinations:
438
442
  ]
439
443
  p = multiprocessing.Pool(settings.db_jobs)
440
444
  for class_list in tqdm(
441
- p.imap_unordered(insert_database_worker, worker_args)
442
- ):
445
+ p.imap_unordered(insert_database_worker, worker_args), disable= not verbose
446
+ ):
443
447
  pass
444
448
  p.close()
445
449
  p.join()
@@ -473,6 +473,7 @@ class MolForm_SQL:
473
473
  if the number of classes and nominal_m/zs are higher than 999 the query will fail
474
474
  Solution: use postgres or split query
475
475
  """
476
+ verbose = molecular_search_settings.verbose_processing
476
477
 
477
478
  def query_normal(class_list, len_adduct):
478
479
  """query for normal database
@@ -565,10 +566,7 @@ class MolForm_SQL:
565
566
 
566
567
  elif ion_type == Labels.adduct_ion and adduct_atom:
567
568
  return int(formula_obj._adduct_mz(ion_charge, adduct_atom))
568
-
569
- for formula_obj, ch_obj, classe_obj in tqdm.tqdm(
570
- formulas, desc="Loading molecular formula database"
571
- ):
569
+ for formula_obj, ch_obj, classe_obj in tqdm.tqdm(formulas, desc="Loading molecular formula database", disable = not verbose):
572
570
  nominal_mz = nominal_mass_by_ion_type(formula_obj)
573
571
 
574
572
  if self.type != "normal":
@@ -127,7 +127,6 @@ class LowResMassSpectralMatch(Thread):
127
127
 
128
128
  return spectral_similarity_scores, ri_score, similarity_score
129
129
 
130
- # @timeit
131
130
  def run(self):
132
131
  """Runs the low-resolution mass spectral match."""
133
132
  # TODO select the best gcms peak
@@ -148,8 +147,8 @@ class LowResMassSpectralMatch(Thread):
148
147
  self.gcms_obj.chromatogram_settings.use_deconvolution = (
149
148
  original_use_deconvolution
150
149
  )
151
-
152
- for gc_peak in tqdm.tqdm(self.gcms_obj):
150
+ verbose = self.gcms_obj.chromatogram_settings.verbose_processing
151
+ for gc_peak in tqdm.tqdm(self.gcms_obj, disable = not verbose):
153
152
  if not self.calibration:
154
153
  window = self.gcms_obj.molecular_search_settings.ri_search_range
155
154
 
@@ -646,12 +646,14 @@ class MetabRefLCInterface(MetabRefInterface):
646
646
  super().__init__()
647
647
 
648
648
  # API endpoint for precursor m/z search
649
+ # inputs = mz, tolerance (in Da), polarity, page_no, per_page
649
650
  self.PRECURSOR_MZ_URL = (
650
- "https://metabref.emsl.pnnl.gov/api/precursors/m/{}/t/{}/{}"
651
+ "https://metabref.emsl.pnnl.gov/api/precursors/m/{}/t/{}/{}?page={}&per_page={}"
651
652
  )
652
653
 
653
654
  # API endpoint for returning full list of precursor m/z values in database
654
- self.PRECURSOR_MZ_ALL_URL = "https://metabref.emsl.pnnl.gov/api/precursors/{}"
655
+ # inputs = polarity, page_no, per_page
656
+ self.PRECURSOR_MZ_ALL_URL = "https://metabref.emsl.pnnl.gov/api/precursors/{}?page={}&per_page={}"
655
657
 
656
658
  self.__init_format_map__()
657
659
 
@@ -674,7 +676,7 @@ class MetabRefLCInterface(MetabRefInterface):
674
676
  self.format_map["fe"] = self.format_map["flashentropy"]
675
677
  self.format_map["flash-entropy"] = self.format_map["flashentropy"]
676
678
 
677
- def query_by_precursor(self, mz_list, polarity, mz_tol_ppm, mz_tol_da_api=0.2):
679
+ def query_by_precursor(self, mz_list, polarity, mz_tol_ppm, mz_tol_da_api=0.2, max_per_page=50):
678
680
  """
679
681
  Query MetabRef by precursor m/z values.
680
682
 
@@ -690,6 +692,8 @@ class MetabRefLCInterface(MetabRefInterface):
690
692
  mz_tol_da_api : float, optional
691
693
  Maximum tolerance between precursor m/z values for API search, in daltons.
692
694
  Used to group similar mzs into a single API query for speed. Default is 0.2.
695
+ max_per_page : int, optional
696
+ Maximum records to return from MetabRef API query at a time. Default is 50.
693
697
 
694
698
  Returns
695
699
  -------
@@ -705,7 +709,7 @@ class MetabRefLCInterface(MetabRefInterface):
705
709
  mz_list.sort()
706
710
  mz_groups = [[mz_list[0]]]
707
711
  for x in mz_list[1:]:
708
- if abs(x - mz_groups[-1][-1]) <= mz_tol_da_api:
712
+ if abs(x - mz_groups[-1][0]) <= mz_tol_da_api:
709
713
  mz_groups[-1].append(x)
710
714
  else:
711
715
  mz_groups.append([x])
@@ -722,32 +726,59 @@ class MetabRefLCInterface(MetabRefInterface):
722
726
  tol = (max(mz_group) - min(mz_group)) / 2 + mz_tol_ppm**-6 * max(
723
727
  mz_group
724
728
  )
725
- lib = lib + self.get_query(
726
- self.PRECURSOR_MZ_URL.format(str(mz), str(tol), polarity)
729
+
730
+ # Get first page of results
731
+ response = self.get_query(
732
+ self.PRECURSOR_MZ_URL.format(str(mz), str(tol), polarity, 1, max_per_page)
727
733
  )
734
+ lib = lib + response['results']
735
+
736
+ # If there are more pages of results, get them
737
+ if response['total_pages'] > 1:
738
+ for i in np.arange(2, response['total_pages']+1):
739
+ lib = lib + self.get_query(
740
+ self.PRECURSOR_MZ_URL.format(str(mz), str(tol), polarity, i, max_per_page)
741
+ )['results']
728
742
 
729
743
  return lib
730
744
 
731
- def request_all_precursors(self, polarity):
745
+ def request_all_precursors(self, polarity, per_page = 50000):
732
746
  """
733
- Request all precursor m/z values from MetabRef.
747
+ Request all precursor m/z values for MS2 spectra from MetabRef.
734
748
 
735
749
  Parameters
736
750
  ----------
737
751
  polarity : str
738
752
  Ionization polarity, either "positive" or "negative".
753
+ per_page : int, optional
754
+ Number of records to fetch per call. Default is 50000
739
755
 
740
756
  Returns
741
757
  -------
742
758
  list
743
- List of all precursor m/z values.
759
+ List of all precursor m/z values, sorted.
744
760
  """
745
761
  # If polarity is anything other than positive or negative, raise error
746
762
  if polarity not in ["positive", "negative"]:
747
763
  raise ValueError("Polarity must be 'positive' or 'negative'")
748
764
 
749
- # Query MetabRef for all precursor m/z values
750
- return self.get_query(self.PRECURSOR_MZ_ALL_URL.format(polarity))
765
+ precursors = []
766
+
767
+ # Get first page of results and total number of pages of results
768
+ response = self.get_query(self.PRECURSOR_MZ_ALL_URL.format(polarity, str(1), str(per_page)))
769
+ total_pages = response['total_pages']
770
+ precursors.extend([x['precursor_ion'] for x in response['results']])
771
+
772
+ # Go through remaining pages of results
773
+ for i in np.arange(2, total_pages + 1):
774
+ response = self.get_query(self.PRECURSOR_MZ_ALL_URL.format(polarity, str(i), str(per_page)))
775
+ precursors.extend([x['precursor_ion'] for x in response['results']])
776
+
777
+ # Sort precursors from smallest to largest and remove duplicates
778
+ precursors = list(set(precursors))
779
+ precursors.sort()
780
+
781
+ return precursors
751
782
 
752
783
  def get_lipid_library(
753
784
  self,
@@ -789,14 +820,25 @@ class MetabRefLCInterface(MetabRefInterface):
789
820
 
790
821
  """
791
822
  mz_list.sort()
823
+ mz_list = np.array(mz_list)
792
824
 
793
825
  # Get all precursors in the library matching the polarity
794
826
  precusors_in_lib = self.request_all_precursors(polarity=polarity)
795
- precusors_in_lib.sort()
796
827
  precusors_in_lib = np.array(precusors_in_lib)
797
828
 
798
829
  # Compare the mz_list with the precursors in the library, keep any mzs that are within mz_tol of any precursor in the library
799
- mz_list = np.array(mz_list)
830
+ lib_mz_df = pd.DataFrame(precusors_in_lib, columns=["lib_mz"])
831
+ lib_mz_df["closest_obs_mz"] = mz_list[
832
+ find_closest(mz_list, lib_mz_df.lib_mz.values)
833
+ ]
834
+ lib_mz_df["mz_diff_ppm"] = np.abs(
835
+ (lib_mz_df["lib_mz"] - lib_mz_df["closest_obs_mz"])
836
+ / lib_mz_df["lib_mz"]
837
+ * 1e6
838
+ )
839
+ lib_mz_sub = lib_mz_df[lib_mz_df["mz_diff_ppm"] <= mz_tol_ppm]
840
+
841
+ # Do the same in the opposite direction
800
842
  mz_df = pd.DataFrame(mz_list, columns=["mass_feature_mz"])
801
843
  mz_df["closest_lib_pre_mz"] = precusors_in_lib[
802
844
  find_closest(precusors_in_lib, mz_df.mass_feature_mz.values)
@@ -808,9 +850,15 @@ class MetabRefLCInterface(MetabRefInterface):
808
850
  )
809
851
  mz_df_sub = mz_df[mz_df["mz_diff_ppm"] <= mz_tol_ppm]
810
852
 
853
+ # Evaluate which is fewer mzs - lib_mz_sub or mz_df_sub and use that as the input for next step
854
+ if len(lib_mz_sub) < len(mz_df_sub):
855
+ mzs_to_query = lib_mz_sub.lib_mz.values
856
+ else:
857
+ mzs_to_query = mz_df_sub.mass_feature_mz.values
858
+
811
859
  # Query the library for the precursors in the mz_list that are in the library to retrieve the spectra and metadata
812
860
  lib = self.query_by_precursor(
813
- mz_list=mz_df_sub.mass_feature_mz.values,
861
+ mz_list=mzs_to_query,
814
862
  polarity=polarity,
815
863
  mz_tol_ppm=mz_tol_ppm,
816
864
  mz_tol_da_api=mz_tol_da_api,
@@ -830,6 +878,12 @@ class MetabRefLCInterface(MetabRefInterface):
830
878
  {k: v for k, v in x.items() if k not in ["Molecular Data", "Lipid Tree"]}
831
879
  for x in lib
832
880
  ]
881
+ # Unpack the 'Lipid Fragments' key and the 'MSO Data" key from each entry
882
+ for x in lib:
883
+ if "Lipid Fragments" in x.keys():
884
+ x.update(x.pop("Lipid Fragments"))
885
+ if "MSO Data" in x.keys():
886
+ x.update(x.pop("MSO Data"))
833
887
 
834
888
  # Format the spectral library
835
889
  format_func = self._get_format_func(format)
@@ -88,7 +88,7 @@ class LCMSSpectralSearch:
88
88
  )
89
89
 
90
90
  # Get types of fragments in the lib entry
91
- lib_frags = lib_entry["fragment_types"].split(", ")
91
+ lib_frags = lib_entry["fragment_types"]
92
92
  # make list of the fragment types that are present in the query spectrum
93
93
  lib_in_query_ids = list(
94
94
  set(