masster 0.5.9__py3-none-any.whl → 0.5.11__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.
Potentially problematic release.
This version of masster might be problematic. Click here for more details.
- masster/_version.py +1 -1
- masster/sample/adducts.py +2 -2
- masster/sample/helpers.py +47 -15
- masster/sample/plot.py +1209 -912
- masster/sample/processing.py +1 -1
- masster/sample/sample.py +91 -48
- masster/study/export.py +4 -6
- masster/study/h5.py +66 -15
- masster/study/helpers.py +24 -5
- masster/study/load.py +1 -164
- masster/study/merge.py +16 -18
- masster/study/plot.py +105 -35
- masster/study/processing.py +17 -14
- masster/study/study5_schema.json +3 -0
- {masster-0.5.9.dist-info → masster-0.5.11.dist-info}/METADATA +3 -1
- {masster-0.5.9.dist-info → masster-0.5.11.dist-info}/RECORD +19 -19
- {masster-0.5.9.dist-info → masster-0.5.11.dist-info}/WHEEL +0 -0
- {masster-0.5.9.dist-info → masster-0.5.11.dist-info}/entry_points.txt +0 -0
- {masster-0.5.9.dist-info → masster-0.5.11.dist-info}/licenses/LICENSE +0 -0
masster/study/merge.py
CHANGED
|
@@ -340,8 +340,6 @@ def merge(study, **kwargs) -> None:
|
|
|
340
340
|
- MS2 spectra are automatically linked when link_ms2=True
|
|
341
341
|
- Adduct relationships are identified and stored after merging
|
|
342
342
|
"""
|
|
343
|
-
start_time = time.time()
|
|
344
|
-
|
|
345
343
|
# Initialize with defaults and override with kwargs
|
|
346
344
|
params = merge_defaults()
|
|
347
345
|
|
|
@@ -429,9 +427,13 @@ def merge(study, **kwargs) -> None:
|
|
|
429
427
|
# Feature maps will be generated on-demand within each merge method
|
|
430
428
|
|
|
431
429
|
study.logger.info(
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
430
|
+
f"Merging samples using {params.method}, min_samples={params.min_samples}, rt_tol={params.rt_tol}s, mz_tol={params.mz_tol}Da"
|
|
431
|
+
)
|
|
432
|
+
if "chunked" in params.method:
|
|
433
|
+
study.logger.info(
|
|
434
|
+
f"threads={params.threads}, chunk_size={params.chunk_size}, dechunking='{params.dechunking}'"
|
|
435
|
+
)
|
|
436
|
+
|
|
435
437
|
# Initialize
|
|
436
438
|
study.consensus_df = pl.DataFrame()
|
|
437
439
|
study.consensus_ms2 = pl.DataFrame()
|
|
@@ -486,10 +488,6 @@ def merge(study, **kwargs) -> None:
|
|
|
486
488
|
|
|
487
489
|
# Finalize merge: filter by min_samples and add isotope/MS2 data
|
|
488
490
|
__finalize_merge(study, params.link_ms2, params.extract_ms1, params.min_samples)
|
|
489
|
-
|
|
490
|
-
# Log completion without the misleading feature count
|
|
491
|
-
elapsed = time.time() - start_time
|
|
492
|
-
study.logger.debug(f"Merge process completed in {elapsed:.1f}s")
|
|
493
491
|
|
|
494
492
|
|
|
495
493
|
def _merge_kd(study, params: merge_defaults) -> oms.ConsensusMap:
|
|
@@ -757,7 +755,7 @@ def _merge_kd_chunked(study, params: merge_defaults, cached_adducts_df=None, cac
|
|
|
757
755
|
|
|
758
756
|
else:
|
|
759
757
|
# Parallel processing
|
|
760
|
-
study.logger.info(f"Processing chunks in parallel using {params.threads} processes")
|
|
758
|
+
#study.logger.info(f"Processing chunks in parallel using {params.threads} processes")
|
|
761
759
|
|
|
762
760
|
# Prepare chunk data for parallel processing using features_df slices
|
|
763
761
|
chunk_data_list = []
|
|
@@ -818,7 +816,7 @@ def _merge_kd_chunked(study, params: merge_defaults, cached_adducts_df=None, cac
|
|
|
818
816
|
serialized_chunk_results.append((chunk_start_idx, consensus_features))
|
|
819
817
|
completed_chunks += 1
|
|
820
818
|
n_samples_in_chunk = len(chunk_data_list[chunk_idx]['chunk_samples_data'])
|
|
821
|
-
study.logger.
|
|
819
|
+
study.logger.info(f"Completed chunk {completed_chunks}/{total_chunks} (samples {chunk_start_idx + 1}-{chunk_start_idx + n_samples_in_chunk})")
|
|
822
820
|
except Exception as exc:
|
|
823
821
|
# Check if this is a BrokenProcessPool exception from Windows multiprocessing issues
|
|
824
822
|
if isinstance(exc, BrokenProcessPool) or "process pool" in str(exc).lower():
|
|
@@ -852,7 +850,7 @@ def _merge_kd_chunked(study, params: merge_defaults, cached_adducts_df=None, cac
|
|
|
852
850
|
serialized_chunk_results.append((chunk_start_idx, consensus_features))
|
|
853
851
|
completed_chunks += 1
|
|
854
852
|
n_samples_in_chunk = len(chunk_data_list[chunk_idx]['chunk_samples_data'])
|
|
855
|
-
study.logger.
|
|
853
|
+
study.logger.info(f"Completed chunk {completed_chunks}/{total_chunks} (samples {chunk_start_idx + 1}-{chunk_start_idx + n_samples_in_chunk})")
|
|
856
854
|
except Exception as exc:
|
|
857
855
|
study.logger.error(f"Chunk {chunk_idx} generated an exception: {exc}")
|
|
858
856
|
raise exc
|
|
@@ -932,7 +930,7 @@ def _merge_qt_chunked(study, params: merge_defaults, cached_adducts_df=None, cac
|
|
|
932
930
|
|
|
933
931
|
else:
|
|
934
932
|
# Parallel processing
|
|
935
|
-
study.logger.info(f"Processing chunks in parallel using {params.threads} processes")
|
|
933
|
+
#study.logger.info(f"Processing chunks in parallel using {params.threads} processes")
|
|
936
934
|
|
|
937
935
|
# Prepare chunk data for parallel processing using features_df slices
|
|
938
936
|
chunk_data_list = []
|
|
@@ -993,7 +991,7 @@ def _merge_qt_chunked(study, params: merge_defaults, cached_adducts_df=None, cac
|
|
|
993
991
|
serialized_chunk_results.append((chunk_start_idx, consensus_features))
|
|
994
992
|
completed_chunks += 1
|
|
995
993
|
n_samples_in_chunk = len(chunk_data_list[chunk_idx]['chunk_samples_data'])
|
|
996
|
-
study.logger.
|
|
994
|
+
study.logger.info(f"Completed chunk {completed_chunks}/{total_chunks} (samples {chunk_start_idx + 1}-{chunk_start_idx + n_samples_in_chunk})")
|
|
997
995
|
except Exception as exc:
|
|
998
996
|
# Check if this is a BrokenProcessPool exception from Windows multiprocessing issues
|
|
999
997
|
if isinstance(exc, BrokenProcessPool) or "process pool" in str(exc).lower():
|
|
@@ -1027,7 +1025,7 @@ def _merge_qt_chunked(study, params: merge_defaults, cached_adducts_df=None, cac
|
|
|
1027
1025
|
serialized_chunk_results.append((chunk_start_idx, consensus_features))
|
|
1028
1026
|
completed_chunks += 1
|
|
1029
1027
|
n_samples_in_chunk = len(chunk_data_list[chunk_idx]['chunk_samples_data'])
|
|
1030
|
-
study.logger.
|
|
1028
|
+
study.logger.info(f"Completed chunk {completed_chunks}/{total_chunks} (samples {chunk_start_idx + 1}-{chunk_start_idx + n_samples_in_chunk})")
|
|
1031
1029
|
except Exception as exc:
|
|
1032
1030
|
study.logger.error(f"Chunk {chunk_idx} generated an exception: {exc}")
|
|
1033
1031
|
raise exc
|
|
@@ -2265,7 +2263,7 @@ def _perform_adduct_grouping(study, rt_tol, mz_tol):
|
|
|
2265
2263
|
)
|
|
2266
2264
|
|
|
2267
2265
|
# Use optimized adduct grouping
|
|
2268
|
-
study.logger.info(f"About to call adduct grouping for {len(consensus_data)} consensus features")
|
|
2266
|
+
#study.logger.info(f"About to call adduct grouping for {len(consensus_data)} consensus features")
|
|
2269
2267
|
adduct_group_list, adduct_of_list = __merge_adduct_grouping(
|
|
2270
2268
|
study, consensus_data, rt_tol/3, mz_tol
|
|
2271
2269
|
)
|
|
@@ -3082,9 +3080,9 @@ def __finalize_merge(study, link_ms2, extract_ms1, min_samples):
|
|
|
3082
3080
|
# Count tight clusters with specified thresholds
|
|
3083
3081
|
tight_clusters = _count_tight_clusters(study,mz_tol=0.04, rt_tol=0.3)
|
|
3084
3082
|
|
|
3085
|
-
study.logger.
|
|
3083
|
+
study.logger.success(
|
|
3086
3084
|
f"Merging completed. Consensus features: {len(study.consensus_df)}. "
|
|
3087
|
-
f"Completeness: {c:.2f}. Tight clusters
|
|
3085
|
+
f"Completeness: {c:.2f}. Tight clusters: {tight_clusters}.",
|
|
3088
3086
|
)
|
|
3089
3087
|
else:
|
|
3090
3088
|
study.logger.warning(
|
masster/study/plot.py
CHANGED
|
@@ -9,6 +9,8 @@ import panel
|
|
|
9
9
|
import polars as pl
|
|
10
10
|
from tqdm import tqdm
|
|
11
11
|
|
|
12
|
+
# Import cmap for colormap handling
|
|
13
|
+
from cmap import Colormap
|
|
12
14
|
hv.extension("bokeh")
|
|
13
15
|
|
|
14
16
|
|
|
@@ -17,6 +19,93 @@ hv.extension("bokeh")
|
|
|
17
19
|
from bokeh.layouts import row as bokeh_row
|
|
18
20
|
|
|
19
21
|
|
|
22
|
+
def _export_with_webdriver_manager(plot_obj, filename, format_type, logger=None):
|
|
23
|
+
"""
|
|
24
|
+
Export plot to PNG or SVG using webdriver-manager for automatic driver management.
|
|
25
|
+
|
|
26
|
+
Parameters:
|
|
27
|
+
plot_obj: Bokeh plot object or holoviews object to export
|
|
28
|
+
filename: Output filename
|
|
29
|
+
format_type: Either "png" or "svg"
|
|
30
|
+
logger: Logger for error reporting (optional)
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
bool: True if export successful, False otherwise
|
|
34
|
+
"""
|
|
35
|
+
try:
|
|
36
|
+
# Convert holoviews to bokeh if needed
|
|
37
|
+
if hasattr(plot_obj, 'opts'): # Likely a holoviews object
|
|
38
|
+
import holoviews as hv
|
|
39
|
+
bokeh_plot = hv.render(plot_obj)
|
|
40
|
+
else:
|
|
41
|
+
bokeh_plot = plot_obj
|
|
42
|
+
|
|
43
|
+
# Try webdriver-manager export first
|
|
44
|
+
try:
|
|
45
|
+
from webdriver_manager.chrome import ChromeDriverManager
|
|
46
|
+
from selenium import webdriver
|
|
47
|
+
from selenium.webdriver.chrome.service import Service
|
|
48
|
+
from selenium.webdriver.chrome.options import Options
|
|
49
|
+
|
|
50
|
+
# Set up Chrome options for headless operation
|
|
51
|
+
chrome_options = Options()
|
|
52
|
+
chrome_options.add_argument("--headless")
|
|
53
|
+
chrome_options.add_argument("--no-sandbox")
|
|
54
|
+
chrome_options.add_argument("--disable-dev-shm-usage")
|
|
55
|
+
chrome_options.add_argument("--disable-gpu")
|
|
56
|
+
|
|
57
|
+
# Use webdriver-manager to automatically get the correct ChromeDriver
|
|
58
|
+
service = Service(ChromeDriverManager().install())
|
|
59
|
+
driver = webdriver.Chrome(service=service, options=chrome_options)
|
|
60
|
+
|
|
61
|
+
# Export with managed webdriver
|
|
62
|
+
if format_type == "png":
|
|
63
|
+
from bokeh.io import export_png
|
|
64
|
+
export_png(bokeh_plot, filename=filename, webdriver=driver)
|
|
65
|
+
elif format_type == "svg":
|
|
66
|
+
from bokeh.io import export_svg
|
|
67
|
+
export_svg(bokeh_plot, filename=filename, webdriver=driver)
|
|
68
|
+
else:
|
|
69
|
+
raise ValueError(f"Unsupported format: {format_type}")
|
|
70
|
+
|
|
71
|
+
driver.quit()
|
|
72
|
+
return True
|
|
73
|
+
|
|
74
|
+
except ImportError:
|
|
75
|
+
if logger:
|
|
76
|
+
logger.debug(f"webdriver-manager not available, using default {format_type.upper()} export")
|
|
77
|
+
# Fall back to default export
|
|
78
|
+
if format_type == "png":
|
|
79
|
+
from bokeh.io import export_png
|
|
80
|
+
export_png(bokeh_plot, filename=filename)
|
|
81
|
+
elif format_type == "svg":
|
|
82
|
+
from bokeh.io import export_svg
|
|
83
|
+
export_svg(bokeh_plot, filename=filename)
|
|
84
|
+
return True
|
|
85
|
+
|
|
86
|
+
except Exception as e:
|
|
87
|
+
if logger:
|
|
88
|
+
logger.debug(f"{format_type.upper()} export with webdriver-manager failed: {e}, using default {format_type.upper()} export")
|
|
89
|
+
try:
|
|
90
|
+
# Final fallback to default export
|
|
91
|
+
if format_type == "png":
|
|
92
|
+
from bokeh.io import export_png
|
|
93
|
+
export_png(bokeh_plot, filename=filename)
|
|
94
|
+
elif format_type == "svg":
|
|
95
|
+
from bokeh.io import export_svg
|
|
96
|
+
export_svg(bokeh_plot, filename=filename)
|
|
97
|
+
return True
|
|
98
|
+
except Exception as e2:
|
|
99
|
+
if logger:
|
|
100
|
+
logger.error(f"{format_type.upper()} export failed: {e2}")
|
|
101
|
+
return False
|
|
102
|
+
|
|
103
|
+
except Exception as e:
|
|
104
|
+
if logger:
|
|
105
|
+
logger.error(f"Export preparation failed: {e}")
|
|
106
|
+
return False
|
|
107
|
+
|
|
108
|
+
|
|
20
109
|
def _isolated_save_plot(plot_object, filename, abs_filename, logger, plot_title="Plot"):
|
|
21
110
|
"""
|
|
22
111
|
Save a plot using isolated file saving that doesn't affect global Bokeh state.
|
|
@@ -38,11 +127,10 @@ def _isolated_save_plot(plot_object, filename, abs_filename, logger, plot_title=
|
|
|
38
127
|
logger.info(f"Plot saved to: {abs_filename}")
|
|
39
128
|
|
|
40
129
|
elif filename.endswith(".png"):
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
export_png(plot_object, filename=filename)
|
|
130
|
+
success = _export_with_webdriver_manager(plot_object, filename, "png", logger)
|
|
131
|
+
if success:
|
|
44
132
|
logger.info(f"Plot saved to: {abs_filename}")
|
|
45
|
-
|
|
133
|
+
else:
|
|
46
134
|
# Fall back to HTML if PNG export not available
|
|
47
135
|
html_filename = filename.replace('.png', '.html')
|
|
48
136
|
abs_html_filename = html_filename if abs_filename == filename else abs_filename.replace('.png', '.html')
|
|
@@ -55,16 +143,15 @@ def _isolated_save_plot(plot_object, filename, abs_filename, logger, plot_title=
|
|
|
55
143
|
with open(html_filename, 'w', encoding='utf-8') as f:
|
|
56
144
|
f.write(html)
|
|
57
145
|
|
|
58
|
-
logger.warning(f"PNG export not available
|
|
59
|
-
elif filename.endswith(".
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
from bokeh.io.export import export_pdf
|
|
63
|
-
export_pdf(plot_object, filename=filename)
|
|
146
|
+
logger.warning(f"PNG export not available. Saved as HTML instead: {abs_html_filename}")
|
|
147
|
+
elif filename.endswith(".svg"):
|
|
148
|
+
success = _export_with_webdriver_manager(plot_object, filename, "svg", logger)
|
|
149
|
+
if success:
|
|
64
150
|
logger.info(f"Plot saved to: {abs_filename}")
|
|
65
|
-
|
|
66
|
-
# Fall back to HTML if
|
|
67
|
-
html_filename = filename.replace('.
|
|
151
|
+
else:
|
|
152
|
+
# Fall back to HTML if SVG export not available
|
|
153
|
+
html_filename = filename.replace('.svg', '.html')
|
|
154
|
+
abs_html_filename = html_filename if abs_filename == filename else abs_filename.replace('.svg', '.html')
|
|
68
155
|
from bokeh.resources import Resources
|
|
69
156
|
from bokeh.embed import file_html
|
|
70
157
|
|
|
@@ -74,27 +161,13 @@ def _isolated_save_plot(plot_object, filename, abs_filename, logger, plot_title=
|
|
|
74
161
|
with open(html_filename, 'w', encoding='utf-8') as f:
|
|
75
162
|
f.write(html)
|
|
76
163
|
|
|
77
|
-
logger.warning(f"
|
|
78
|
-
elif filename.endswith(".svg"):
|
|
79
|
-
# Try to save as SVG, fall back to HTML if not available
|
|
80
|
-
try:
|
|
81
|
-
from bokeh.io.export import export_svg
|
|
82
|
-
export_svg(plot_object, filename=filename)
|
|
83
|
-
logger.info(f"Plot saved to: {abs_filename}")
|
|
84
|
-
except Exception as e:
|
|
85
|
-
# Fall back to HTML if SVG export not available
|
|
86
|
-
html_filename = filename.replace('.svg', '.html')
|
|
87
|
-
abs_html_filename = html_filename if abs_filename == filename else abs_filename.replace('.svg', '.html')
|
|
88
|
-
from bokeh.resources import Resources
|
|
89
|
-
from bokeh.embed import file_html
|
|
90
|
-
|
|
91
|
-
resources = Resources(mode='cdn')
|
|
164
|
+
logger.warning(f"SVG export not available. Saved as HTML instead: {abs_html_filename}")
|
|
92
165
|
html = file_html(plot_object, resources, title=plot_title)
|
|
93
166
|
|
|
94
167
|
with open(html_filename, 'w', encoding='utf-8') as f:
|
|
95
168
|
f.write(html)
|
|
96
169
|
|
|
97
|
-
logger.warning(f"SVG export not available
|
|
170
|
+
logger.warning(f"SVG export not available. Saved as HTML instead: {abs_html_filename}")
|
|
98
171
|
else:
|
|
99
172
|
# Default to HTML for unknown extensions using isolated approach
|
|
100
173
|
from bokeh.resources import Resources
|
|
@@ -548,11 +621,11 @@ def plot_consensus_2d(
|
|
|
548
621
|
self,
|
|
549
622
|
filename=None,
|
|
550
623
|
colorby="number_samples",
|
|
551
|
-
cmap=
|
|
624
|
+
cmap="viridis",
|
|
625
|
+
alpha=0.7,
|
|
552
626
|
markersize=8,
|
|
553
627
|
sizeby="inty_mean",
|
|
554
628
|
scaling="static",
|
|
555
|
-
alpha=0.7,
|
|
556
629
|
width=600,
|
|
557
630
|
height=450,
|
|
558
631
|
mz_range=None,
|
|
@@ -639,7 +712,7 @@ def plot_consensus_2d(
|
|
|
639
712
|
if cmap is None:
|
|
640
713
|
cmap = "viridis"
|
|
641
714
|
elif cmap == "grey":
|
|
642
|
-
cmap = "
|
|
715
|
+
cmap = "greys"
|
|
643
716
|
|
|
644
717
|
# plot with bokeh
|
|
645
718
|
import bokeh.plotting as bp
|
|
@@ -657,9 +730,6 @@ def plot_consensus_2d(
|
|
|
657
730
|
from bokeh.models.annotations import ColorBar
|
|
658
731
|
from bokeh.palettes import viridis, Category20
|
|
659
732
|
|
|
660
|
-
# Import cmap for colormap handling
|
|
661
|
-
from cmap import Colormap
|
|
662
|
-
|
|
663
733
|
# Convert Polars DataFrame to pandas for Bokeh compatibility
|
|
664
734
|
data_pd = data.to_pandas()
|
|
665
735
|
source = ColumnDataSource(data_pd)
|
masster/study/processing.py
CHANGED
|
@@ -86,8 +86,6 @@ def align(self, **kwargs):
|
|
|
86
86
|
self.logger.error(f"Unknown alignment algorithm '{algorithm}'")
|
|
87
87
|
return
|
|
88
88
|
|
|
89
|
-
self.logger.debug("Alignment completed successfully.")
|
|
90
|
-
|
|
91
89
|
# Reset consensus data structures after alignment since RT changes invalidate consensus
|
|
92
90
|
consensus_reset_count = 0
|
|
93
91
|
if not self.consensus_df.is_empty():
|
|
@@ -225,8 +223,8 @@ def find_ms2(self, **kwargs):
|
|
|
225
223
|
unique_consensus_features = self.consensus_ms2["consensus_uid"].n_unique()
|
|
226
224
|
else:
|
|
227
225
|
unique_consensus_features = 0
|
|
228
|
-
self.logger.
|
|
229
|
-
f"Linking completed. {len(self.consensus_ms2)} MS2 spectra associated to {unique_consensus_features} consensus features.",
|
|
226
|
+
self.logger.success(
|
|
227
|
+
f"Linking completed. Found {len(self.consensus_ms2)} MS2 spectra associated to {unique_consensus_features} consensus features.",
|
|
230
228
|
)
|
|
231
229
|
|
|
232
230
|
|
|
@@ -514,7 +512,7 @@ def _integrate_chrom_impl(self, **kwargs):
|
|
|
514
512
|
],
|
|
515
513
|
).drop("__row_idx") # Remove the temporary row index column
|
|
516
514
|
|
|
517
|
-
self.logger.
|
|
515
|
+
self.logger.success(
|
|
518
516
|
f"Integration completed. Updated {len(update_rows)} features with chromatogram data.",
|
|
519
517
|
)
|
|
520
518
|
except Exception as e:
|
|
@@ -681,16 +679,15 @@ def _align_pose_clustering(study_obj, params):
|
|
|
681
679
|
params_oms.setValue("pairfinder:distance_RT:exponent", 2.0)
|
|
682
680
|
|
|
683
681
|
aligner = oms.MapAlignmentAlgorithmPoseClustering()
|
|
684
|
-
study_obj.logger.info(
|
|
682
|
+
study_obj.logger.info(
|
|
683
|
+
f"Align RTs with Pose clustering: rt_tol={params.get('rt_tol')}",
|
|
684
|
+
)
|
|
685
685
|
|
|
686
686
|
# Set ref_index to feature map index with largest number of features
|
|
687
687
|
ref_index = [
|
|
688
688
|
i[0] for i in sorted(enumerate([fm.size() for fm in fmaps]), key=lambda x: x[1])
|
|
689
689
|
][-1]
|
|
690
|
-
|
|
691
|
-
f"Reference map is {study_obj.samples_df.row(ref_index, named=True)['sample_name']}",
|
|
692
|
-
)
|
|
693
|
-
|
|
690
|
+
|
|
694
691
|
aligner.setParameters(params_oms)
|
|
695
692
|
aligner.setReference(fmaps[ref_index])
|
|
696
693
|
study_obj.logger.debug(f"Parameters for alignment: {params}")
|
|
@@ -836,6 +833,12 @@ def _align_pose_clustering(study_obj, params):
|
|
|
836
833
|
# Clean up temporary feature maps to release memory
|
|
837
834
|
del fmaps
|
|
838
835
|
study_obj.logger.debug("Temporary feature maps deleted to release memory")
|
|
836
|
+
|
|
837
|
+
# Resolve reference sample UID from the reference index
|
|
838
|
+
ref_sample_uid = sample_uid_lookup.get(ref_index)
|
|
839
|
+
study_obj.logger.success(
|
|
840
|
+
f"Alignment completed. Reference sample UID {ref_sample_uid}.",
|
|
841
|
+
)
|
|
839
842
|
|
|
840
843
|
|
|
841
844
|
def _align_kd_algorithm(study_obj, params):
|
|
@@ -879,7 +882,7 @@ def _align_kd_algorithm(study_obj, params):
|
|
|
879
882
|
_raw_mp = None
|
|
880
883
|
max_points = int(_raw_mp) if _raw_mp is not None else 1000
|
|
881
884
|
study_obj.logger.info(
|
|
882
|
-
f"KD
|
|
885
|
+
f"Align RTs with KD-Tree: rt_tol={params.get('rt_tol')}, max_points={max_points}",
|
|
883
886
|
)
|
|
884
887
|
|
|
885
888
|
# Work directly with features_df instead of feature maps
|
|
@@ -1091,8 +1094,8 @@ def _align_kd_algorithm(study_obj, params):
|
|
|
1091
1094
|
).alias("rt")
|
|
1092
1095
|
)
|
|
1093
1096
|
|
|
1094
|
-
study_obj.logger.
|
|
1095
|
-
f"Alignment completed. Reference sample UID {ref_sample_uid}
|
|
1097
|
+
study_obj.logger.success(
|
|
1098
|
+
f"Alignment completed. Reference sample UID {ref_sample_uid}.",
|
|
1096
1099
|
)
|
|
1097
1100
|
|
|
1098
1101
|
|
|
@@ -1365,7 +1368,7 @@ def find_iso(self, rt_tol=0.1, mz_tol=0.01, uids=None):
|
|
|
1365
1368
|
# Count how many consensus features have isotope data
|
|
1366
1369
|
iso_count = sum(1 for data in consensus_iso_data.values() if data is not None and len(data) > 0)
|
|
1367
1370
|
|
|
1368
|
-
self.logger.success(f"
|
|
1371
|
+
self.logger.success(f"Isotope detection completed. Found isotope patterns for {iso_count}/{len(self.consensus_df)} consensus features.")
|
|
1369
1372
|
|
|
1370
1373
|
|
|
1371
1374
|
def reset_iso(self):
|
masster/study/study5_schema.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: masster
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.11
|
|
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
|
|
@@ -685,6 +685,7 @@ Requires-Dist: altair>=5.5.0
|
|
|
685
685
|
Requires-Dist: bokeh>=3.7.3
|
|
686
686
|
Requires-Dist: cmap>=0.6.2
|
|
687
687
|
Requires-Dist: datashader>=0.18.1
|
|
688
|
+
Requires-Dist: get-gecko-driver>=1.4
|
|
688
689
|
Requires-Dist: h5py>=3.14.0
|
|
689
690
|
Requires-Dist: hdbscan>=0.8.40
|
|
690
691
|
Requires-Dist: holoviews>=1.21.0
|
|
@@ -703,6 +704,7 @@ Requires-Dist: scikit-learn>=1.7.1
|
|
|
703
704
|
Requires-Dist: scipy>=1.12.0
|
|
704
705
|
Requires-Dist: tqdm>=4.65.0
|
|
705
706
|
Requires-Dist: umap-learn>=0.5.9.post2
|
|
707
|
+
Requires-Dist: webdriver-manager>=4.0.2
|
|
706
708
|
Provides-Extra: dev
|
|
707
709
|
Requires-Dist: bandit>=1.7.0; extra == 'dev'
|
|
708
710
|
Requires-Dist: black>=23.0.0; extra == 'dev'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
masster/__init__.py,sha256=ueZ224WPNRRjQEYTaQUol818nwQgJwB93HbEfmtPRmg,1041
|
|
2
|
-
masster/_version.py,sha256=
|
|
2
|
+
masster/_version.py,sha256=LIAWlWB39tjwTXYs1erXTAAMa3xwkL23VfkGq-MORxk,257
|
|
3
3
|
masster/chromatogram.py,sha256=iYpdv8C17zVnlWvOFgAn9ns2uFGiF-GgoYf5QVVAbHs,19319
|
|
4
4
|
masster/logger.py,sha256=XT2gUcUIct8LWzTp9n484g5MaB89toT76CGA41oBvfA,18375
|
|
5
5
|
masster/spectrum.py,sha256=TWIgDcl0lveG40cLVZTWGp8-FxMolu-P8EjZyRBtXL4,49850
|
|
@@ -19,16 +19,16 @@ masster/data/wiff/2025_01_14_VW_7600_LpMx_DBS_CID_2min_TOP15_030msecMS1_005msecR
|
|
|
19
19
|
masster/lib/__init__.py,sha256=TcePNx3SYZHz6763TL9Sg4gUNXaRWjlrOtyS6vsu-hg,178
|
|
20
20
|
masster/lib/lib.py,sha256=SSN06UtiM-hIdjS3eCiIHsJ_8S4YHRGOLGmdPIh-efo,27481
|
|
21
21
|
masster/sample/__init__.py,sha256=HL0m1ept0PMAYUCQtDDnkdOS12IFl6oLAq4TZQz83uY,170
|
|
22
|
-
masster/sample/adducts.py,sha256=
|
|
22
|
+
masster/sample/adducts.py,sha256=aBDoBKRjh6rMIF65yH6vx7KpQxeMUv796q3H46TySwY,32603
|
|
23
23
|
masster/sample/h5.py,sha256=X5VBHBpgJ2FJc9mtCggJ1HSQ3ujRmb1Wnpr9sJ8bGVA,115445
|
|
24
|
-
masster/sample/helpers.py,sha256=
|
|
24
|
+
masster/sample/helpers.py,sha256=Mt9LX-Dy1Xro1a_Sy6nxQzCkP_-q7nK4xVnNm44v7UA,43872
|
|
25
25
|
masster/sample/lib.py,sha256=E-j9c3Wd8f9a-H8xj7CAOwlA8KcyXPoFyYm3c8r7LtI,33755
|
|
26
26
|
masster/sample/load.py,sha256=swjRBCoFGni9iPztHIKPVB5ru_xDMVryB_inPXdujTw,51819
|
|
27
27
|
masster/sample/parameters.py,sha256=Gg2KcuNbV_wZ_Wwv93QlM5J19ji0oSIvZLPV1NoBmq0,4456
|
|
28
|
-
masster/sample/plot.py,sha256=
|
|
29
|
-
masster/sample/processing.py,sha256=
|
|
28
|
+
masster/sample/plot.py,sha256=5qn2Cpl363f3hW1ZeI4BZV9_36VLx39PKQMrebJhfp4,104864
|
|
29
|
+
masster/sample/processing.py,sha256=qk-6_v424nwfaoVmdbHj-_lJiW7OkWS7SuQzQWNAFGI,55919
|
|
30
30
|
masster/sample/quant.py,sha256=tHNjvUFTdehKR31BXBZnVsBxMD9XJHgaltITOjr71uE,7562
|
|
31
|
-
masster/sample/sample.py,sha256=
|
|
31
|
+
masster/sample/sample.py,sha256=pw4fIE5gecdupZOOWFUiRCs0x-3qa3Nv7V_UdJ-CAsc,22202
|
|
32
32
|
masster/sample/sample5_schema.json,sha256=H5e2T6rHIDzul2kp_yP-ILUUWUpW08wP2pEQjMR0nSk,3977
|
|
33
33
|
masster/sample/save.py,sha256=pbiRoWEA2DnhDKmMJncjveNlBqizJLOVRm5cug4ZwyM,38658
|
|
34
34
|
masster/sample/sciex.py,sha256=vnbxsq_qnAQVuzcpziP1o3IC4kM5amGBcPmC2TAuDLw,46319
|
|
@@ -40,18 +40,18 @@ masster/sample/defaults/get_spectrum_def.py,sha256=o62p31PhGd-LiIkTOzKQhwPtnO2At
|
|
|
40
40
|
masster/sample/defaults/sample_def.py,sha256=keoXyMyrm_iLgbYqfIbqCpJ3XHBVlNwCNmb5iMQL0iY,14579
|
|
41
41
|
masster/study/__init__.py,sha256=55axdFuqRX4aXtJ8ocnhcLB32fNtmmJpCi58moO0r4g,237
|
|
42
42
|
masster/study/analysis.py,sha256=L-wXBnGZCLB5UUDrjIdOiMG9zdej3Tw_SftcEmmTukM,84264
|
|
43
|
-
masster/study/export.py,sha256=
|
|
44
|
-
masster/study/h5.py,sha256=
|
|
45
|
-
masster/study/helpers.py,sha256=
|
|
43
|
+
masster/study/export.py,sha256=c1HJdLAM6Ply0n8f0DjMk4mXd9lOYePr60UJTBksUho,60092
|
|
44
|
+
masster/study/h5.py,sha256=w4fjNmYPjvTUj0EMVK-_6I2-ZbI_6xHHcM8lXxo1pSw,97676
|
|
45
|
+
masster/study/helpers.py,sha256=fBZ6hDa_C8muqS4XWkE6KXtNQ-yEX4bkxnu34y1SZ5c,191933
|
|
46
46
|
masster/study/id.py,sha256=heKU309cUsNeFxbWYvqxVIAJLrR1H0YqMgLanLx9Do4,80091
|
|
47
|
-
masster/study/load.py,sha256=
|
|
48
|
-
masster/study/merge.py,sha256=
|
|
47
|
+
masster/study/load.py,sha256=BMjoUDkXNI6iU2tRE2eBRzxMrvW0gRyLepqYOWaMPXU,101192
|
|
48
|
+
masster/study/merge.py,sha256=nGDJk5S65pgXz1IFytfjKBS_h2YWqI4sqEMWTAHzRjM,169504
|
|
49
49
|
masster/study/parameters.py,sha256=bTvmcwX9INxzcrEAmTiFH8qeWVhwkvMTZjuP394pz5o,3279
|
|
50
|
-
masster/study/plot.py,sha256=
|
|
51
|
-
masster/study/processing.py,sha256=
|
|
50
|
+
masster/study/plot.py,sha256=ftQAVgEYkZuKAVIlbTR5bUypF8DpMOxSXwOyYz_BsOQ,110610
|
|
51
|
+
masster/study/processing.py,sha256=5b8K4tP-Xu1-mhdf0om-m-g65Z9Uz3Dp4UBhuMLh0yU,58627
|
|
52
52
|
masster/study/save.py,sha256=47AP518epJJ9TjaGGyrLKsMsyjIk8_J4ka7bmsnRtFQ,9268
|
|
53
53
|
masster/study/study.py,sha256=gudugPJk3LOtZh-YsszSRCBDrBG78cexoG0CSM86EPs,38701
|
|
54
|
-
masster/study/study5_schema.json,sha256=
|
|
54
|
+
masster/study/study5_schema.json,sha256=lTFePwY8bQngyBnNCP60-UP9tnZLGhFo3YtJgwHTWdo,7797
|
|
55
55
|
masster/study/defaults/__init__.py,sha256=m3Z5KXGqsTdh7GjYzZoENERt39yRg0ceVRV1DeCt1P0,610
|
|
56
56
|
masster/study/defaults/align_def.py,sha256=Du0F592ej2einT8kOx8EUs610axSvur8_-6N19O-uJY,10209
|
|
57
57
|
masster/study/defaults/export_def.py,sha256=eXl3h4aoLX88XkHTpqahLd-QZ2gjUqrmjq8IJULXeWo,1203
|
|
@@ -67,8 +67,8 @@ masster/wizard/README.md,sha256=mL1A3YWJZOefpJ6D0-HqGLkVRmUlOpwyVFdvJBeeoZM,1414
|
|
|
67
67
|
masster/wizard/__init__.py,sha256=a2hcZnHASjfuw1lqZhZnvTR58rc33rRnoGAY_JfvGhI,683
|
|
68
68
|
masster/wizard/example.py,sha256=xEZFTH9UZ8HKOm6s3JL8Js0Uw5ChnISWBHSZCL32vsM,7983
|
|
69
69
|
masster/wizard/wizard.py,sha256=UobIGFZtp1s_9WJlpl6DQ2-pp7flPQ6dlYZJqYE92OM,38131
|
|
70
|
-
masster-0.5.
|
|
71
|
-
masster-0.5.
|
|
72
|
-
masster-0.5.
|
|
73
|
-
masster-0.5.
|
|
74
|
-
masster-0.5.
|
|
70
|
+
masster-0.5.11.dist-info/METADATA,sha256=54_-tSRkHbi38SbxeXkzYMljofCkWi3ShR6Zkm8984w,45191
|
|
71
|
+
masster-0.5.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
72
|
+
masster-0.5.11.dist-info/entry_points.txt,sha256=ZHguQ_vPmdbpqq2uGtmEOLJfgP-DQ1T0c07Lxh30wc8,58
|
|
73
|
+
masster-0.5.11.dist-info/licenses/LICENSE,sha256=bx5iLIKjgAdYQ7sISn7DsfHRKkoCUm1154sJJKhgqnU,35184
|
|
74
|
+
masster-0.5.11.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|