masster 0.4.11__tar.gz → 0.4.13__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.

Potentially problematic release.


This version of masster might be problematic. Click here for more details.

Files changed (88) hide show
  1. {masster-0.4.11 → masster-0.4.13}/PKG-INFO +1 -1
  2. {masster-0.4.11 → masster-0.4.13}/pyproject.toml +1 -1
  3. {masster-0.4.11 → masster-0.4.13}/src/masster/_version.py +1 -1
  4. {masster-0.4.11 → masster-0.4.13}/src/masster/lib/lib.py +45 -3
  5. {masster-0.4.11 → masster-0.4.13}/src/masster/study/helpers.py +262 -310
  6. {masster-0.4.11 → masster-0.4.13}/src/masster/study/id.py +564 -324
  7. {masster-0.4.11 → masster-0.4.13}/src/masster/study/plot.py +38 -23
  8. {masster-0.4.11 → masster-0.4.13}/src/masster/study/processing.py +268 -178
  9. {masster-0.4.11 → masster-0.4.13}/src/masster/study/study.py +95 -60
  10. {masster-0.4.11 → masster-0.4.13}/src/masster/study/study5_schema.json +12 -0
  11. {masster-0.4.11 → masster-0.4.13}/uv.lock +1 -1
  12. {masster-0.4.11 → masster-0.4.13}/.github/workflows/publish.yml +0 -0
  13. {masster-0.4.11 → masster-0.4.13}/.github/workflows/security.yml +0 -0
  14. {masster-0.4.11 → masster-0.4.13}/.github/workflows/test.yml +0 -0
  15. {masster-0.4.11 → masster-0.4.13}/.gitignore +0 -0
  16. {masster-0.4.11 → masster-0.4.13}/.pre-commit-config.yaml +0 -0
  17. {masster-0.4.11 → masster-0.4.13}/LICENSE +0 -0
  18. {masster-0.4.11 → masster-0.4.13}/Makefile +0 -0
  19. {masster-0.4.11 → masster-0.4.13}/README.md +0 -0
  20. {masster-0.4.11 → masster-0.4.13}/TESTING.md +0 -0
  21. {masster-0.4.11 → masster-0.4.13}/demo/example_batch_process.py +0 -0
  22. {masster-0.4.11 → masster-0.4.13}/demo/example_sample_process.py +0 -0
  23. {masster-0.4.11 → masster-0.4.13}/src/masster/__init__.py +0 -0
  24. {masster-0.4.11 → masster-0.4.13}/src/masster/chromatogram.py +0 -0
  25. {masster-0.4.11 → masster-0.4.13}/src/masster/data/dda/20250530_VH_IQX_KW_RP_HSST3_100mm_12min_pos_v4_DDA_OT_C-MiLUT_QC_dil2_01_20250602151849.sample5 +0 -0
  26. {masster-0.4.11 → masster-0.4.13}/src/masster/data/dda/20250530_VH_IQX_KW_RP_HSST3_100mm_12min_pos_v4_DDA_OT_C-MiLUT_QC_dil3_01_20250602150634.sample5 +0 -0
  27. {masster-0.4.11 → masster-0.4.13}/src/masster/data/dda/20250530_VH_IQX_KW_RP_HSST3_100mm_12min_pos_v4_MS1_C-MiLUT_C008_v6_r38_01.sample5 +0 -0
  28. {masster-0.4.11 → masster-0.4.13}/src/masster/data/dda/20250530_VH_IQX_KW_RP_HSST3_100mm_12min_pos_v4_MS1_C-MiLUT_C008_v7_r37_01.sample5 +0 -0
  29. {masster-0.4.11 → masster-0.4.13}/src/masster/data/dda/20250530_VH_IQX_KW_RP_HSST3_100mm_12min_pos_v4_MS1_C-MiLUT_C017_v5_r99_01.sample5 +0 -0
  30. {masster-0.4.11 → masster-0.4.13}/src/masster/data/libs/ccm.csv +0 -0
  31. {masster-0.4.11 → masster-0.4.13}/src/masster/data/libs/urine.csv +0 -0
  32. {masster-0.4.11 → masster-0.4.13}/src/masster/data/wiff/2025_01_14_VW_7600_LpMx_DBS_CID_2min_TOP15_030msecMS1_005msecReac_CE35_DBS-ON_3.timeseries.data +0 -0
  33. {masster-0.4.11 → masster-0.4.13}/src/masster/data/wiff/2025_01_14_VW_7600_LpMx_DBS_CID_2min_TOP15_030msecMS1_005msecReac_CE35_DBS-ON_3.wiff +0 -0
  34. {masster-0.4.11 → masster-0.4.13}/src/masster/data/wiff/2025_01_14_VW_7600_LpMx_DBS_CID_2min_TOP15_030msecMS1_005msecReac_CE35_DBS-ON_3.wiff.scan +0 -0
  35. {masster-0.4.11 → masster-0.4.13}/src/masster/data/wiff/2025_01_14_VW_7600_LpMx_DBS_CID_2min_TOP15_030msecMS1_005msecReac_CE35_DBS-ON_3.wiff2 +0 -0
  36. {masster-0.4.11 → masster-0.4.13}/src/masster/lib/__init__.py +0 -0
  37. {masster-0.4.11 → masster-0.4.13}/src/masster/logger.py +0 -0
  38. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/__init__.py +0 -0
  39. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/adducts.py +0 -0
  40. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/defaults/__init__.py +0 -0
  41. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/defaults/find_adducts_def.py +0 -0
  42. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/defaults/find_features_def.py +0 -0
  43. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/defaults/find_ms2_def.py +0 -0
  44. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/defaults/get_spectrum_def.py +0 -0
  45. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/defaults/sample_def.py +0 -0
  46. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/h5.py +0 -0
  47. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/helpers.py +0 -0
  48. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/lib.py +0 -0
  49. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/load.py +0 -0
  50. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/parameters.py +0 -0
  51. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/plot.py +0 -0
  52. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/processing.py +0 -0
  53. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/quant.py +0 -0
  54. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/sample.py +0 -0
  55. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/sample5_schema.json +0 -0
  56. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/save.py +0 -0
  57. {masster-0.4.11 → masster-0.4.13}/src/masster/sample/sciex.py +0 -0
  58. {masster-0.4.11 → masster-0.4.13}/src/masster/spectrum.py +0 -0
  59. {masster-0.4.11 → masster-0.4.13}/src/masster/study/__init__.py +0 -0
  60. {masster-0.4.11 → masster-0.4.13}/src/masster/study/defaults/__init__.py +0 -0
  61. {masster-0.4.11 → masster-0.4.13}/src/masster/study/defaults/align_def.py +0 -0
  62. {masster-0.4.11 → masster-0.4.13}/src/masster/study/defaults/export_def.py +0 -0
  63. {masster-0.4.11 → masster-0.4.13}/src/masster/study/defaults/fill_chrom_def.py +0 -0
  64. {masster-0.4.11 → masster-0.4.13}/src/masster/study/defaults/fill_def.py +0 -0
  65. {masster-0.4.11 → masster-0.4.13}/src/masster/study/defaults/find_consensus_def.py +0 -0
  66. {masster-0.4.11 → masster-0.4.13}/src/masster/study/defaults/find_ms2_def.py +0 -0
  67. {masster-0.4.11 → masster-0.4.13}/src/masster/study/defaults/identify_def.py +0 -0
  68. {masster-0.4.11 → masster-0.4.13}/src/masster/study/defaults/integrate_chrom_def.py +0 -0
  69. {masster-0.4.11 → masster-0.4.13}/src/masster/study/defaults/integrate_def.py +0 -0
  70. {masster-0.4.11 → masster-0.4.13}/src/masster/study/defaults/merge_def.py +0 -0
  71. {masster-0.4.11 → masster-0.4.13}/src/masster/study/defaults/study_def.py +0 -0
  72. {masster-0.4.11 → masster-0.4.13}/src/masster/study/export.py +0 -0
  73. {masster-0.4.11 → masster-0.4.13}/src/masster/study/h5.py +0 -0
  74. {masster-0.4.11 → masster-0.4.13}/src/masster/study/load.py +0 -0
  75. {masster-0.4.11 → masster-0.4.13}/src/masster/study/parameters.py +0 -0
  76. {masster-0.4.11 → masster-0.4.13}/src/masster/study/save.py +0 -0
  77. {masster-0.4.11 → masster-0.4.13}/tests/conftest.py +0 -0
  78. {masster-0.4.11 → masster-0.4.13}/tests/test_chromatogram.py +0 -0
  79. {masster-0.4.11 → masster-0.4.13}/tests/test_defaults.py +0 -0
  80. {masster-0.4.11 → masster-0.4.13}/tests/test_imports.py +0 -0
  81. {masster-0.4.11 → masster-0.4.13}/tests/test_integration.py +0 -0
  82. {masster-0.4.11 → masster-0.4.13}/tests/test_logger.py +0 -0
  83. {masster-0.4.11 → masster-0.4.13}/tests/test_parameters.py +0 -0
  84. {masster-0.4.11 → masster-0.4.13}/tests/test_sample.py +0 -0
  85. {masster-0.4.11 → masster-0.4.13}/tests/test_spectrum.py +0 -0
  86. {masster-0.4.11 → masster-0.4.13}/tests/test_study.py +0 -0
  87. {masster-0.4.11 → masster-0.4.13}/tests/test_version.py +0 -0
  88. {masster-0.4.11 → masster-0.4.13}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: masster
3
- Version: 0.4.11
3
+ Version: 0.4.13
4
4
  Summary: Mass spectrometry data analysis package
5
5
  Project-URL: homepage, https://github.com/zamboni-lab/masster
6
6
  Project-URL: repository, https://github.com/zamboni-lab/masster
@@ -1,7 +1,7 @@
1
1
 
2
2
  [project]
3
3
  name = "masster"
4
- version = "0.4.11"
4
+ version = "0.4.13"
5
5
  description = "Mass spectrometry data analysis package"
6
6
  authors = [
7
7
  { name = "Zamboni Lab" }
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
 
4
- __version__ = "0.4.11"
4
+ __version__ = "0.4.13"
5
5
 
6
6
 
7
7
  def get_version():
@@ -142,11 +142,41 @@ class Lib:
142
142
  Returns:
143
143
  Accurate mass as float, or None if calculation fails
144
144
  """
145
+ # Skip obviously invalid formulas
146
+ if not formula or not isinstance(formula, str):
147
+ return None
148
+
149
+ # Clean up whitespace
150
+ formula = formula.strip()
151
+
152
+ # Skip formulas that are obviously invalid
153
+ invalid_patterns = [
154
+ # Contains parentheses with multipliers like (C12H19NO19S3)nH2O
155
+ lambda f: '(' in f and ')' in f and any(c.isalpha() and not c.isupper() for c in f.split(')')[1:]),
156
+ # Contains words instead of chemical symbols
157
+ lambda f: any(word in f.lower() for word in ['and', 'or', 'not', 'with', 'without']),
158
+ # Contains lowercase letters at the start (element symbols should be uppercase)
159
+ lambda f: f and f[0].islower(),
160
+ # Contains unusual characters that shouldn't be in formulas
161
+ lambda f: any(char in f for char in ['@', '#', '$', '%', '^', '&', '*', '=', '+', '?', '/', '\\', '|']),
162
+ # Empty or very short non-standard formulas
163
+ lambda f: len(f) < 2 and not f.isupper(),
164
+ ]
165
+
166
+ for pattern_check in invalid_patterns:
167
+ try:
168
+ if pattern_check(formula):
169
+ warnings.warn(f"Skipping obviously invalid formula: '{formula}'")
170
+ return None
171
+ except Exception:
172
+ # If pattern checking fails, continue to PyOpenMS parsing
173
+ pass
174
+
145
175
  try:
146
176
  empirical_formula = oms.EmpiricalFormula(formula)
147
177
  return empirical_formula.getMonoWeight()
148
178
  except Exception as e:
149
- warnings.warn(f"Error calculating accurate mass for formula {formula}: {e}")
179
+ warnings.warn(f"Error calculating accurate mass for formula '{formula}': {e}")
150
180
  return None
151
181
 
152
182
  def _generate_adduct_variants(self,
@@ -272,8 +302,12 @@ class Lib:
272
302
  all_variants = []
273
303
  cmpd_id_counter = 1
274
304
  lib_id_counter = 1
305
+ total_compounds = 0
306
+ skipped_compounds = 0
275
307
 
276
308
  for row in df.iter_rows(named=True):
309
+ total_compounds += 1
310
+
277
311
  # Extract compound data
278
312
  # assign a compound-level uid so all adducts share the same cmpd_uid
279
313
  compound_level_uid = cmpd_id_counter
@@ -297,8 +331,12 @@ class Lib:
297
331
  )
298
332
  all_variants.extend(variants)
299
333
 
334
+ # Track if compound was skipped due to invalid formula
335
+ if len(variants) == 0:
336
+ skipped_compounds += 1
337
+
300
338
  # Handle RT2 column if present
301
- if "rt2" in column_mapping:
339
+ if "rt2" in column_mapping and len(variants) > 0: # Only if main variants were created
302
340
  rt2_value = self._safe_float_conversion(row.get(column_mapping["rt2"], None))
303
341
  if rt2_value is not None:
304
342
  # Create additional variants with RT2
@@ -321,9 +359,13 @@ class Lib:
321
359
  else:
322
360
  self.lib_df = new_lib_df
323
361
 
324
- print(f"Successfully imported {len(all_variants)} library entries from {csvfile}")
362
+ #successful_compounds = total_compounds - skipped_compounds
363
+ print(f"Imported {len(all_variants)} library entries from {csvfile}")
364
+ #print(f"Processed {total_compounds} compounds: {successful_compounds} successful, {skipped_compounds} skipped due to invalid formulas")
325
365
  else:
326
366
  print(f"No valid compounds found in {csvfile}")
367
+ if skipped_compounds > 0:
368
+ print(f"All {total_compounds} compounds were skipped due to invalid formulas")
327
369
 
328
370
  def _map_csv_columns(self, columns: List[str]) -> Dict[str, str]:
329
371
  """