masster 0.5.14__tar.gz → 0.5.16__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 (96) hide show
  1. {masster-0.5.14 → masster-0.5.16}/PKG-INFO +1 -1
  2. {masster-0.5.14 → masster-0.5.16}/pyproject.toml +1 -1
  3. {masster-0.5.14 → masster-0.5.16}/src/masster/__init__.py +1 -1
  4. {masster-0.5.14 → masster-0.5.16}/src/masster/_version.py +1 -1
  5. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/adducts.py +8 -5
  6. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/processing.py +6 -0
  7. {masster-0.5.14 → masster-0.5.16}/src/masster/study/id.py +4 -3
  8. {masster-0.5.14 → masster-0.5.16}/src/masster/study/plot.py +3 -0
  9. {masster-0.5.14 → masster-0.5.16}/src/masster/wizard/__init__.py +2 -2
  10. {masster-0.5.14 → masster-0.5.16}/src/masster/wizard/wizard.py +544 -437
  11. {masster-0.5.14 → masster-0.5.16}/uv.lock +1 -1
  12. {masster-0.5.14 → masster-0.5.16}/.github/workflows/publish.yml +0 -0
  13. {masster-0.5.14 → masster-0.5.16}/.github/workflows/security.yml +0 -0
  14. {masster-0.5.14 → masster-0.5.16}/.github/workflows/test.yml +0 -0
  15. {masster-0.5.14 → masster-0.5.16}/.gitignore +0 -0
  16. {masster-0.5.14 → masster-0.5.16}/.pre-commit-config.yaml +0 -0
  17. {masster-0.5.14 → masster-0.5.16}/LICENSE +0 -0
  18. {masster-0.5.14 → masster-0.5.16}/Makefile +0 -0
  19. {masster-0.5.14 → masster-0.5.16}/README.md +0 -0
  20. {masster-0.5.14 → masster-0.5.16}/TESTING.md +0 -0
  21. {masster-0.5.14 → masster-0.5.16}/demo/example_batch_process.py +0 -0
  22. {masster-0.5.14 → masster-0.5.16}/demo/example_sample_process.py +0 -0
  23. {masster-0.5.14 → masster-0.5.16}/src/masster/chromatogram.py +0 -0
  24. {masster-0.5.14 → masster-0.5.16}/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
  25. {masster-0.5.14 → masster-0.5.16}/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
  26. {masster-0.5.14 → masster-0.5.16}/src/masster/data/dda/20250530_VH_IQX_KW_RP_HSST3_100mm_12min_pos_v4_MS1_C-MiLUT_C008_v6_r38_01.sample5 +0 -0
  27. {masster-0.5.14 → masster-0.5.16}/src/masster/data/dda/20250530_VH_IQX_KW_RP_HSST3_100mm_12min_pos_v4_MS1_C-MiLUT_C008_v7_r37_01.sample5 +0 -0
  28. {masster-0.5.14 → masster-0.5.16}/src/masster/data/dda/20250530_VH_IQX_KW_RP_HSST3_100mm_12min_pos_v4_MS1_C-MiLUT_C017_v5_r99_01.sample5 +0 -0
  29. {masster-0.5.14 → masster-0.5.16}/src/masster/data/libs/aa.csv +0 -0
  30. {masster-0.5.14 → masster-0.5.16}/src/masster/data/libs/ccm.csv +0 -0
  31. {masster-0.5.14 → masster-0.5.16}/src/masster/data/libs/hilic.csv +0 -0
  32. {masster-0.5.14 → masster-0.5.16}/src/masster/data/libs/urine.csv +0 -0
  33. {masster-0.5.14 → masster-0.5.16}/src/masster/data/wiff/2025_01_14_VW_7600_LpMx_DBS_CID_2min_TOP15_030msecMS1_005msecReac_CE35_DBS-ON_3.timeseries.data +0 -0
  34. {masster-0.5.14 → masster-0.5.16}/src/masster/data/wiff/2025_01_14_VW_7600_LpMx_DBS_CID_2min_TOP15_030msecMS1_005msecReac_CE35_DBS-ON_3.wiff +0 -0
  35. {masster-0.5.14 → masster-0.5.16}/src/masster/data/wiff/2025_01_14_VW_7600_LpMx_DBS_CID_2min_TOP15_030msecMS1_005msecReac_CE35_DBS-ON_3.wiff.scan +0 -0
  36. {masster-0.5.14 → masster-0.5.16}/src/masster/data/wiff/2025_01_14_VW_7600_LpMx_DBS_CID_2min_TOP15_030msecMS1_005msecReac_CE35_DBS-ON_3.wiff2 +0 -0
  37. {masster-0.5.14 → masster-0.5.16}/src/masster/lib/__init__.py +0 -0
  38. {masster-0.5.14 → masster-0.5.16}/src/masster/lib/lib.py +0 -0
  39. {masster-0.5.14 → masster-0.5.16}/src/masster/logger.py +0 -0
  40. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/__init__.py +0 -0
  41. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/defaults/__init__.py +0 -0
  42. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/defaults/find_adducts_def.py +0 -0
  43. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/defaults/find_features_def.py +0 -0
  44. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/defaults/find_ms2_def.py +0 -0
  45. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/defaults/get_spectrum_def.py +0 -0
  46. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/defaults/sample_def.py +0 -0
  47. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/h5.py +0 -0
  48. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/helpers.py +0 -0
  49. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/lib.py +0 -0
  50. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/load.py +0 -0
  51. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/parameters.py +0 -0
  52. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/plot.py +0 -0
  53. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/quant.py +0 -0
  54. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/sample.py +0 -0
  55. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/sample5_schema.json +0 -0
  56. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/save.py +0 -0
  57. {masster-0.5.14 → masster-0.5.16}/src/masster/sample/sciex.py +0 -0
  58. {masster-0.5.14 → masster-0.5.16}/src/masster/spectrum.py +0 -0
  59. {masster-0.5.14 → masster-0.5.16}/src/masster/study/__init__.py +0 -0
  60. {masster-0.5.14 → masster-0.5.16}/src/masster/study/analysis.py +0 -0
  61. {masster-0.5.14 → masster-0.5.16}/src/masster/study/defaults/__init__.py +0 -0
  62. {masster-0.5.14 → masster-0.5.16}/src/masster/study/defaults/align_def.py +0 -0
  63. {masster-0.5.14 → masster-0.5.16}/src/masster/study/defaults/export_def.py +0 -0
  64. {masster-0.5.14 → masster-0.5.16}/src/masster/study/defaults/fill_def.py +0 -0
  65. {masster-0.5.14 → masster-0.5.16}/src/masster/study/defaults/find_consensus_def.py +0 -0
  66. {masster-0.5.14 → masster-0.5.16}/src/masster/study/defaults/find_ms2_def.py +0 -0
  67. {masster-0.5.14 → masster-0.5.16}/src/masster/study/defaults/identify_def.py +0 -0
  68. {masster-0.5.14 → masster-0.5.16}/src/masster/study/defaults/integrate_chrom_def.py +0 -0
  69. {masster-0.5.14 → masster-0.5.16}/src/masster/study/defaults/integrate_def.py +0 -0
  70. {masster-0.5.14 → masster-0.5.16}/src/masster/study/defaults/merge_def.py +0 -0
  71. {masster-0.5.14 → masster-0.5.16}/src/masster/study/defaults/study_def.py +0 -0
  72. {masster-0.5.14 → masster-0.5.16}/src/masster/study/export.py +0 -0
  73. {masster-0.5.14 → masster-0.5.16}/src/masster/study/h5.py +0 -0
  74. {masster-0.5.14 → masster-0.5.16}/src/masster/study/helpers.py +0 -0
  75. {masster-0.5.14 → masster-0.5.16}/src/masster/study/importers.py +0 -0
  76. {masster-0.5.14 → masster-0.5.16}/src/masster/study/load.py +0 -0
  77. {masster-0.5.14 → masster-0.5.16}/src/masster/study/merge.py +0 -0
  78. {masster-0.5.14 → masster-0.5.16}/src/masster/study/parameters.py +0 -0
  79. {masster-0.5.14 → masster-0.5.16}/src/masster/study/processing.py +0 -0
  80. {masster-0.5.14 → masster-0.5.16}/src/masster/study/save.py +0 -0
  81. {masster-0.5.14 → masster-0.5.16}/src/masster/study/study.py +0 -0
  82. {masster-0.5.14 → masster-0.5.16}/src/masster/study/study5_schema.json +0 -0
  83. {masster-0.5.14 → masster-0.5.16}/src/masster/wizard/README.md +0 -0
  84. {masster-0.5.14 → masster-0.5.16}/src/masster/wizard/example.py +0 -0
  85. {masster-0.5.14 → masster-0.5.16}/tests/conftest.py +0 -0
  86. {masster-0.5.14 → masster-0.5.16}/tests/test_chromatogram.py +0 -0
  87. {masster-0.5.14 → masster-0.5.16}/tests/test_defaults.py +0 -0
  88. {masster-0.5.14 → masster-0.5.16}/tests/test_imports.py +0 -0
  89. {masster-0.5.14 → masster-0.5.16}/tests/test_integration.py +0 -0
  90. {masster-0.5.14 → masster-0.5.16}/tests/test_logger.py +0 -0
  91. {masster-0.5.14 → masster-0.5.16}/tests/test_parameters.py +0 -0
  92. {masster-0.5.14 → masster-0.5.16}/tests/test_sample.py +0 -0
  93. {masster-0.5.14 → masster-0.5.16}/tests/test_spectrum.py +0 -0
  94. {masster-0.5.14 → masster-0.5.16}/tests/test_study.py +0 -0
  95. {masster-0.5.14 → masster-0.5.16}/tests/test_version.py +0 -0
  96. {masster-0.5.14 → masster-0.5.16}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: masster
3
- Version: 0.5.14
3
+ Version: 0.5.16
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.5.14"
4
+ version = "0.5.16"
5
5
  description = "Mass spectrometry data analysis package"
6
6
  authors = [
7
7
  { name = "Zamboni Lab" }
@@ -22,7 +22,7 @@ from masster.lib import Lib
22
22
  from masster.sample.sample import Sample
23
23
  from masster.spectrum import Spectrum
24
24
  from masster.study.study import Study
25
- from masster.wizard import Wizard, wizard_def
25
+ from masster.wizard import Wizard
26
26
 
27
27
 
28
28
  __all__ = [
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
 
4
- __version__ = "0.5.14"
4
+ __version__ = "0.5.16"
5
5
 
6
6
 
7
7
  def get_version():
@@ -107,7 +107,9 @@ def _get_adducts(self, adducts_list: list = None, **kwargs):
107
107
 
108
108
  # 1. Single adducts
109
109
  for spec in base_specs:
110
- if charge_min <= spec["charge"] <= charge_max:
110
+ # For neutral adducts (charge=0), always allow them
111
+ # For charged adducts, check if absolute value is within range
112
+ if spec["charge"] == 0 or (charge_min <= abs(spec["charge"]) <= charge_max):
111
113
  formatted_name = _format_adduct_name([spec])
112
114
  combinations_list.append(
113
115
  {
@@ -125,7 +127,7 @@ def _get_adducts(self, adducts_list: list = None, **kwargs):
125
127
  base_charge = spec["charge"]
126
128
  for multiplier in range(2, min(max_combinations + 1, 5)):
127
129
  total_charge = base_charge * multiplier
128
- if charge_min <= total_charge <= charge_max:
130
+ if charge_min <= abs(total_charge) <= charge_max:
129
131
  components = [spec] * multiplier
130
132
  formatted_name = _format_adduct_name(components)
131
133
 
@@ -146,7 +148,8 @@ def _get_adducts(self, adducts_list: list = None, **kwargs):
146
148
  for pos_spec in positive_specs:
147
149
  for neut_spec in neutral_specs:
148
150
  total_charge = pos_spec["charge"] + neut_spec["charge"]
149
- if charge_min <= total_charge <= charge_max:
151
+ # For combinations with neutrals, the total charge should follow abs() rule only if non-zero
152
+ if total_charge == 0 or (charge_min <= abs(total_charge) <= charge_max):
150
153
  components = [pos_spec, neut_spec]
151
154
  formatted_name = _format_adduct_name(components)
152
155
  combinations_list.append(
@@ -166,7 +169,7 @@ def _get_adducts(self, adducts_list: list = None, **kwargs):
166
169
  for combo in combinations(positive_specs, 2):
167
170
  if combo[0]["formula"] != combo[1]["formula"]:
168
171
  total_charge = combo[0]["charge"] + combo[1]["charge"]
169
- if charge_min <= total_charge <= charge_max:
172
+ if total_charge == 0 or (charge_min <= abs(total_charge) <= charge_max):
170
173
  components = list(combo)
171
174
  formatted_name = _format_adduct_name(components)
172
175
  combinations_list.append(
@@ -189,7 +192,7 @@ def _get_adducts(self, adducts_list: list = None, **kwargs):
189
192
  components = [pos_spec] + list(neut_combo)
190
193
  total_charge = sum(spec["charge"] for spec in components)
191
194
 
192
- if charge_min <= total_charge <= charge_max:
195
+ if total_charge == 0 or (charge_min <= abs(total_charge) <= charge_max):
193
196
  formatted_name = _format_adduct_name(components)
194
197
  total_mass_shift = sum(spec["mass_shift"] for spec in components)
195
198
  combined_prob = np.prod(
@@ -586,6 +586,12 @@ def find_features(self, **kwargs):
586
586
  self.logger.debug(
587
587
  f"Parameters: chrom_fwhm={params.get('chrom_fwhm')}, noise={params.get('noise')}, tol_ppm={params.get('tol_ppm')}, isotope_filtering_model={params.get('isotope_filtering_model')}",
588
588
  )
589
+ # check that noise is not lower than 1% quantile of ms1_df inty
590
+ noise_threshold = self.ms1_df.select(pl.col("inty")).quantile(0.01)[0, 0]
591
+ if params.get("noise") < noise_threshold / 10:
592
+ self.logger.warning(
593
+ f"Warning: noise threshold {params.get('noise')} is lower than 1% quantile of MS1 intensities ({noise_threshold:.1f}). This may lead to many false positives.",
594
+ )
589
595
 
590
596
  exp = oms.MSExperiment()
591
597
  # find max number of cycles in self.ms1_df
@@ -1503,7 +1503,8 @@ def _get_adducts(study, adducts_list: list | None = None, **kwargs):
1503
1503
 
1504
1504
  # 1. Single adducts (filter out neutral adducts with charge == 0)
1505
1505
  for spec in base_specs:
1506
- if charge_min <= spec["charge"] <= charge_max and spec["charge"] != 0:
1506
+ # Study-level filtering: exclude neutral adducts (charge=0) but use abs() for charged adducts
1507
+ if spec["charge"] != 0 and charge_min <= abs(spec["charge"]) <= charge_max:
1507
1508
  formatted_name = _format_adduct_name([spec])
1508
1509
  combinations_list.append(
1509
1510
  {
@@ -1521,7 +1522,7 @@ def _get_adducts(study, adducts_list: list | None = None, **kwargs):
1521
1522
  base_charge = spec["charge"]
1522
1523
  for multiplier in range(2, min(max_combinations + 1, 4)): # Up to 3x multiplier
1523
1524
  total_charge = base_charge * multiplier
1524
- if charge_min <= total_charge <= charge_max and total_charge != 0:
1525
+ if charge_min <= abs(total_charge) <= charge_max and total_charge != 0:
1525
1526
  components = [spec] * multiplier
1526
1527
  formatted_name = _format_adduct_name(components)
1527
1528
  probability_multiplied = float(spec["probability"]) ** multiplier
@@ -1543,7 +1544,7 @@ def _get_adducts(study, adducts_list: list | None = None, **kwargs):
1543
1544
  for pos_spec in positive_specs[:2]: # Limit to first 2 positive specs
1544
1545
  for neut_spec in neutral_specs[:1]: # Only 1 neutral loss
1545
1546
  total_charge = pos_spec["charge"] + neut_spec["charge"]
1546
- if charge_min <= total_charge <= charge_max and total_charge != 0:
1547
+ if charge_min <= abs(total_charge) <= charge_max and total_charge != 0:
1547
1548
  components = [pos_spec, neut_spec]
1548
1549
  formatted_name = _format_adduct_name(components)
1549
1550
  combinations_list.append(
@@ -449,6 +449,9 @@ def plot_alignment(
449
449
  rt_current = row_dict["rt"]
450
450
  mz = row_dict["mz"]
451
451
  inty = row_dict["inty"]
452
+ # Skip if inty is None
453
+ if inty is None:
454
+ continue
452
455
  alpha = inty / max_inty
453
456
  size = markersize + 2 if sample_idx == 0 else markersize
454
457
 
@@ -12,6 +12,6 @@ The analyze() function combines create_analysis() with immediate execution of th
12
12
  generated script for fully automated processing.
13
13
  """
14
14
 
15
- from .wizard import Wizard, wizard_def, create_analysis, create_notebook, analyze
15
+ from .wizard import Wizard, wizard_def, create_scripts
16
16
 
17
- __all__ = ["Wizard", "wizard_def", "create_analysis", "create_notebook", "analyze"]
17
+ __all__ = ["Wizard", "wizard_def", "create_scripts"]