masster 0.4.3__py3-none-any.whl → 0.4.5__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/__init__.py +8 -8
- masster/_version.py +1 -1
- masster/chromatogram.py +1 -1
- masster/data/dda/20250530_VH_IQX_KW_RP_HSST3_100mm_12min_pos_v4_DDA_OT_C-MiLUT_QC_dil2_01_20250602151849.sample5 +0 -0
- masster/data/dda/20250530_VH_IQX_KW_RP_HSST3_100mm_12min_pos_v4_DDA_OT_C-MiLUT_QC_dil3_01_20250602150634.sample5 +0 -0
- masster/data/dda/20250530_VH_IQX_KW_RP_HSST3_100mm_12min_pos_v4_MS1_C-MiLUT_C008_v6_r38_01.sample5 +0 -0
- masster/data/dda/20250530_VH_IQX_KW_RP_HSST3_100mm_12min_pos_v4_MS1_C-MiLUT_C008_v7_r37_01.sample5 +0 -0
- masster/data/dda/20250530_VH_IQX_KW_RP_HSST3_100mm_12min_pos_v4_MS1_C-MiLUT_C017_v5_r99_01.sample5 +0 -0
- masster/data/libs/__pycache__/ccm.cpython-312.pyc +0 -0
- masster/data/libs/__pycache__/urine.cpython-312.pyc +0 -0
- masster/data/libs/ccm.csv +120 -0
- masster/data/libs/urine.csv +4693 -0
- masster/data/wiff/2025_01_14_VW_7600_LpMx_DBS_CID_2min_TOP15_030msecMS1_005msecReac_CE35_DBS-ON_3.timeseries.data +0 -0
- masster/data/wiff/2025_01_14_VW_7600_LpMx_DBS_CID_2min_TOP15_030msecMS1_005msecReac_CE35_DBS-ON_3.wiff +0 -0
- masster/data/wiff/2025_01_14_VW_7600_LpMx_DBS_CID_2min_TOP15_030msecMS1_005msecReac_CE35_DBS-ON_3.wiff.scan +0 -0
- masster/data/wiff/2025_01_14_VW_7600_LpMx_DBS_CID_2min_TOP15_030msecMS1_005msecReac_CE35_DBS-ON_3.wiff2 +0 -0
- masster/logger.py +11 -11
- masster/sample/__init__.py +1 -1
- masster/sample/adducts.py +338 -264
- masster/sample/defaults/find_adducts_def.py +21 -8
- masster/sample/h5.py +561 -282
- masster/sample/helpers.py +131 -75
- masster/sample/lib.py +4 -4
- masster/sample/load.py +31 -17
- masster/sample/parameters.py +1 -1
- masster/sample/plot.py +7 -7
- masster/sample/processing.py +117 -87
- masster/sample/sample.py +103 -90
- masster/sample/sample5_schema.json +196 -0
- masster/sample/save.py +35 -12
- masster/spectrum.py +1 -1
- masster/study/__init__.py +1 -1
- masster/study/defaults/align_def.py +5 -1
- masster/study/defaults/identify_def.py +3 -1
- masster/study/defaults/study_def.py +58 -25
- masster/study/export.py +360 -210
- masster/study/h5.py +560 -158
- masster/study/helpers.py +496 -203
- masster/study/helpers_optimized.py +1 -1
- masster/study/id.py +538 -349
- masster/study/load.py +233 -143
- masster/study/plot.py +71 -71
- masster/study/processing.py +456 -254
- masster/study/save.py +15 -5
- masster/study/study.py +213 -131
- masster/study/study5_schema.json +360 -0
- masster-0.4.5.dist-info/METADATA +131 -0
- masster-0.4.5.dist-info/RECORD +71 -0
- masster-0.4.3.dist-info/METADATA +0 -791
- masster-0.4.3.dist-info/RECORD +0 -56
- {masster-0.4.3.dist-info → masster-0.4.5.dist-info}/WHEEL +0 -0
- {masster-0.4.3.dist-info → masster-0.4.5.dist-info}/entry_points.txt +0 -0
- {masster-0.4.3.dist-info → masster-0.4.5.dist-info}/licenses/LICENSE +0 -0
- {masster-0.4.3.dist-info → masster-0.4.5.dist-info}/top_level.txt +0 -0
masster/study/plot.py
CHANGED
|
@@ -26,17 +26,17 @@ def _isolated_save_plot(plot_object, filename, abs_filename, logger, plot_title=
|
|
|
26
26
|
# Use isolated file saving that doesn't affect global output state
|
|
27
27
|
from bokeh.resources import Resources
|
|
28
28
|
from bokeh.embed import file_html
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
# Create HTML content without affecting global state
|
|
31
31
|
resources = Resources(mode='cdn')
|
|
32
32
|
html = file_html(plot_object, resources, title=plot_title)
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
# Write directly to file
|
|
35
35
|
with open(filename, 'w', encoding='utf-8') as f:
|
|
36
36
|
f.write(html)
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
logger.info(f"Plot saved to: {abs_filename}")
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
elif filename.endswith(".png"):
|
|
41
41
|
try:
|
|
42
42
|
from bokeh.io.export import export_png
|
|
@@ -47,13 +47,13 @@ def _isolated_save_plot(plot_object, filename, abs_filename, logger, plot_title=
|
|
|
47
47
|
html_filename = filename.replace('.png', '.html')
|
|
48
48
|
from bokeh.resources import Resources
|
|
49
49
|
from bokeh.embed import file_html
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
resources = Resources(mode='cdn')
|
|
52
52
|
html = file_html(plot_object, resources, title=plot_title)
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
with open(html_filename, 'w', encoding='utf-8') as f:
|
|
55
55
|
f.write(html)
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
logger.warning(f"PNG export not available, saved as HTML instead: {html_filename}")
|
|
58
58
|
elif filename.endswith(".pdf"):
|
|
59
59
|
# Try to save as PDF, fall back to HTML if not available
|
|
@@ -66,25 +66,25 @@ def _isolated_save_plot(plot_object, filename, abs_filename, logger, plot_title=
|
|
|
66
66
|
html_filename = filename.replace('.pdf', '.html')
|
|
67
67
|
from bokeh.resources import Resources
|
|
68
68
|
from bokeh.embed import file_html
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
resources = Resources(mode='cdn')
|
|
71
71
|
html = file_html(plot_object, resources, title=plot_title)
|
|
72
|
-
|
|
72
|
+
|
|
73
73
|
with open(html_filename, 'w', encoding='utf-8') as f:
|
|
74
74
|
f.write(html)
|
|
75
|
-
|
|
75
|
+
|
|
76
76
|
logger.warning(f"PDF export not available, saved as HTML instead: {html_filename}")
|
|
77
77
|
else:
|
|
78
78
|
# Default to HTML for unknown extensions using isolated approach
|
|
79
79
|
from bokeh.resources import Resources
|
|
80
80
|
from bokeh.embed import file_html
|
|
81
|
-
|
|
81
|
+
|
|
82
82
|
resources = Resources(mode='cdn')
|
|
83
83
|
html = file_html(plot_object, resources, title=plot_title)
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
with open(filename, 'w', encoding='utf-8') as f:
|
|
86
86
|
f.write(html)
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
logger.info(f"Plot saved to: {abs_filename}")
|
|
89
89
|
|
|
90
90
|
|
|
@@ -97,28 +97,28 @@ def _isolated_show_notebook(plot_object):
|
|
|
97
97
|
import holoviews as hv
|
|
98
98
|
import warnings
|
|
99
99
|
import logging
|
|
100
|
-
|
|
100
|
+
|
|
101
101
|
# Suppress both warnings and logging messages for the specific Bokeh callback warnings
|
|
102
102
|
# that occur when Panel components with Python callbacks are converted to standalone Bokeh
|
|
103
103
|
bokeh_logger = logging.getLogger('bokeh.embed.util')
|
|
104
104
|
original_level = bokeh_logger.level
|
|
105
105
|
bokeh_logger.setLevel(logging.ERROR) # Suppress WARNING level messages
|
|
106
|
-
|
|
106
|
+
|
|
107
107
|
with warnings.catch_warnings():
|
|
108
108
|
warnings.filterwarnings("ignore", message=".*standalone HTML/JS output.*", category=UserWarning)
|
|
109
109
|
warnings.filterwarnings("ignore", message=".*real Python callbacks.*", category=UserWarning)
|
|
110
|
-
|
|
110
|
+
|
|
111
111
|
try:
|
|
112
112
|
# First clear all output state
|
|
113
113
|
reset_output()
|
|
114
|
-
|
|
114
|
+
|
|
115
115
|
# Set notebook mode
|
|
116
116
|
output_notebook(hide_banner=True)
|
|
117
|
-
|
|
118
|
-
# Reset Holoviews to notebook mode
|
|
117
|
+
|
|
118
|
+
# Reset Holoviews to notebook mode
|
|
119
119
|
hv.extension('bokeh', logo=False)
|
|
120
120
|
hv.output(backend='bokeh', mode='jupyter')
|
|
121
|
-
|
|
121
|
+
|
|
122
122
|
# Show in notebook
|
|
123
123
|
show(plot_object)
|
|
124
124
|
finally:
|
|
@@ -129,16 +129,16 @@ def _isolated_show_notebook(plot_object):
|
|
|
129
129
|
def _isolated_save_panel_plot(panel_obj, filename, abs_filename, logger, plot_title):
|
|
130
130
|
"""
|
|
131
131
|
Save a Panel plot using isolated approach that doesn't affect global Bokeh state.
|
|
132
|
-
|
|
132
|
+
|
|
133
133
|
Args:
|
|
134
134
|
panel_obj: Panel object to save
|
|
135
|
-
filename: Target filename
|
|
135
|
+
filename: Target filename
|
|
136
136
|
abs_filename: Absolute path for logging
|
|
137
137
|
logger: Logger instance
|
|
138
138
|
plot_title: Title for logging
|
|
139
139
|
"""
|
|
140
140
|
import os # Import os for path operations
|
|
141
|
-
|
|
141
|
+
|
|
142
142
|
if filename.endswith(".html"):
|
|
143
143
|
# Panel save method should be isolated but let's be sure
|
|
144
144
|
try:
|
|
@@ -147,7 +147,7 @@ def _isolated_save_panel_plot(panel_obj, filename, abs_filename, logger, plot_ti
|
|
|
147
147
|
logger.info(f"{plot_title} saved to: {abs_filename}")
|
|
148
148
|
except Exception as e:
|
|
149
149
|
logger.error(f"Failed to save {plot_title}: {e}")
|
|
150
|
-
|
|
150
|
+
|
|
151
151
|
elif filename.endswith(".png"):
|
|
152
152
|
try:
|
|
153
153
|
from panel.io.save import save_png
|
|
@@ -164,7 +164,7 @@ def _isolated_save_panel_plot(panel_obj, filename, abs_filename, logger, plot_ti
|
|
|
164
164
|
logger.warning(f"PNG export not available, saved as HTML instead: {abs_html_filename}")
|
|
165
165
|
except Exception as e:
|
|
166
166
|
logger.error(f"Failed to save {plot_title} as HTML fallback: {e}")
|
|
167
|
-
|
|
167
|
+
|
|
168
168
|
elif filename.endswith(".pdf"):
|
|
169
169
|
# Try to save as PDF, fall back to HTML if not available
|
|
170
170
|
try:
|
|
@@ -193,29 +193,29 @@ def _isolated_save_panel_plot(panel_obj, filename, abs_filename, logger, plot_ti
|
|
|
193
193
|
def _isolated_show_panel_notebook(panel_obj):
|
|
194
194
|
"""
|
|
195
195
|
Show a Panel plot in notebook with state isolation to prevent browser opening.
|
|
196
|
-
|
|
196
|
+
|
|
197
197
|
Args:
|
|
198
198
|
panel_obj: Panel object to display
|
|
199
199
|
"""
|
|
200
200
|
# Reset Bokeh state completely to prevent browser opening if output_file was called before
|
|
201
201
|
from bokeh.io import reset_output, output_notebook
|
|
202
202
|
import holoviews as hv
|
|
203
|
-
|
|
203
|
+
|
|
204
204
|
# First clear all output state
|
|
205
205
|
reset_output()
|
|
206
|
-
|
|
206
|
+
|
|
207
207
|
# Set notebook mode
|
|
208
208
|
output_notebook(hide_banner=True)
|
|
209
|
-
|
|
210
|
-
# Reset Holoviews to notebook mode
|
|
209
|
+
|
|
210
|
+
# Reset Holoviews to notebook mode
|
|
211
211
|
hv.extension('bokeh', logo=False)
|
|
212
212
|
hv.output(backend='bokeh', mode='jupyter')
|
|
213
|
-
|
|
214
|
-
# For Panel objects in notebooks, use
|
|
215
|
-
import panel as
|
|
213
|
+
|
|
214
|
+
# For Panel objects in notebooks, use on.extension and display inline
|
|
215
|
+
import panel as on
|
|
216
216
|
try:
|
|
217
217
|
# Configure Panel for notebook display
|
|
218
|
-
|
|
218
|
+
on.extension('bokeh', inline=True, comms='vscode')
|
|
219
219
|
# Use IPython display to show inline instead of show()
|
|
220
220
|
from IPython.display import display
|
|
221
221
|
display(panel_obj)
|
|
@@ -278,25 +278,25 @@ def plot_alignment(
|
|
|
278
278
|
# Create mapping from sample_uid to map_id and filter accordingly
|
|
279
279
|
if hasattr(self, "samples_df") and self.samples_df is not None and not self.samples_df.is_empty():
|
|
280
280
|
samples_info = self.samples_df.to_pandas()
|
|
281
|
-
|
|
281
|
+
|
|
282
282
|
# Filter samples_info to only selected sample_uids and get their map_ids
|
|
283
283
|
selected_samples = samples_info[samples_info["sample_uid"].isin(sample_uids)]
|
|
284
284
|
if selected_samples.empty:
|
|
285
285
|
self.logger.error("No matching samples found for the provided sample_uids.")
|
|
286
286
|
return
|
|
287
|
-
|
|
287
|
+
|
|
288
288
|
# Get the map_ids for selected samples
|
|
289
289
|
selected_map_ids = selected_samples["map_id"].tolist()
|
|
290
|
-
|
|
290
|
+
|
|
291
291
|
# Filter feature maps based on map_ids
|
|
292
292
|
filtered_maps = []
|
|
293
293
|
for map_id in selected_map_ids:
|
|
294
294
|
if 0 <= map_id < len(fmaps):
|
|
295
295
|
filtered_maps.append(fmaps[map_id])
|
|
296
|
-
|
|
296
|
+
|
|
297
297
|
fmaps = filtered_maps
|
|
298
298
|
samples_info = selected_samples.reset_index(drop=True)
|
|
299
|
-
|
|
299
|
+
|
|
300
300
|
if not fmaps:
|
|
301
301
|
self.logger.error("No feature maps found for the selected samples.")
|
|
302
302
|
return
|
|
@@ -438,7 +438,7 @@ def plot_alignment(
|
|
|
438
438
|
|
|
439
439
|
# Use Polars instead of pandas
|
|
440
440
|
features_df = self.features_df
|
|
441
|
-
|
|
441
|
+
|
|
442
442
|
# Filter by selected samples if specified
|
|
443
443
|
if sample_uids is not None:
|
|
444
444
|
features_df = features_df.filter(pl.col("sample_uid").is_in(sample_uids))
|
|
@@ -633,10 +633,10 @@ def plot_alignment(
|
|
|
633
633
|
import os
|
|
634
634
|
if not os.path.isabs(filename):
|
|
635
635
|
filename = os.path.join(self.folder, filename)
|
|
636
|
-
|
|
636
|
+
|
|
637
637
|
# Convert to absolute path for logging
|
|
638
638
|
abs_filename = os.path.abspath(filename)
|
|
639
|
-
|
|
639
|
+
|
|
640
640
|
# Use isolated file saving
|
|
641
641
|
_isolated_save_plot(layout, filename, abs_filename, self.logger, "Alignment Plot")
|
|
642
642
|
else:
|
|
@@ -864,10 +864,10 @@ def plot_consensus_2d(
|
|
|
864
864
|
import os
|
|
865
865
|
if not os.path.isabs(filename):
|
|
866
866
|
filename = os.path.join(self.folder, filename)
|
|
867
|
-
|
|
867
|
+
|
|
868
868
|
# Convert to absolute path for logging
|
|
869
869
|
abs_filename = os.path.abspath(filename)
|
|
870
|
-
|
|
870
|
+
|
|
871
871
|
# Use isolated file saving
|
|
872
872
|
_isolated_save_plot(p, filename, abs_filename, self.logger, "Consensus 2D Plot")
|
|
873
873
|
else:
|
|
@@ -1091,17 +1091,17 @@ def plot_samples_2d(
|
|
|
1091
1091
|
# Only set legend properties if a legend was actually created to avoid Bokeh warnings
|
|
1092
1092
|
if getattr(p, "legend", None) and len(p.legend) > 0:
|
|
1093
1093
|
p.legend.visible = False
|
|
1094
|
-
|
|
1094
|
+
|
|
1095
1095
|
# Apply consistent save/display behavior
|
|
1096
1096
|
if filename is not None:
|
|
1097
1097
|
# Convert relative paths to absolute paths using study folder as base
|
|
1098
1098
|
import os
|
|
1099
1099
|
if not os.path.isabs(filename):
|
|
1100
1100
|
filename = os.path.join(self.folder, filename)
|
|
1101
|
-
|
|
1101
|
+
|
|
1102
1102
|
# Convert to absolute path for logging
|
|
1103
1103
|
abs_filename = os.path.abspath(filename)
|
|
1104
|
-
|
|
1104
|
+
|
|
1105
1105
|
# Use isolated file saving
|
|
1106
1106
|
_isolated_save_plot(p, filename, abs_filename, self.logger, "Samples 2D Plot")
|
|
1107
1107
|
else:
|
|
@@ -1132,7 +1132,7 @@ def plot_bpc(
|
|
|
1132
1132
|
from bokeh.plotting import figure, show, output_file
|
|
1133
1133
|
from bokeh.models import ColumnDataSource, HoverTool
|
|
1134
1134
|
from bokeh.io.export import export_png
|
|
1135
|
-
from
|
|
1135
|
+
from master.study.helpers import get_bpc
|
|
1136
1136
|
|
|
1137
1137
|
sample_uids = self._get_sample_uids(samples)
|
|
1138
1138
|
if not sample_uids:
|
|
@@ -1271,10 +1271,10 @@ def plot_bpc(
|
|
|
1271
1271
|
import os
|
|
1272
1272
|
if not os.path.isabs(filename):
|
|
1273
1273
|
filename = os.path.join(self.folder, filename)
|
|
1274
|
-
|
|
1274
|
+
|
|
1275
1275
|
# Convert to absolute path for logging
|
|
1276
1276
|
abs_filename = os.path.abspath(filename)
|
|
1277
|
-
|
|
1277
|
+
|
|
1278
1278
|
# Use isolated file saving
|
|
1279
1279
|
_isolated_save_plot(p, filename, abs_filename, self.logger, "BPC Plot")
|
|
1280
1280
|
else:
|
|
@@ -1309,7 +1309,7 @@ def plot_eic(
|
|
|
1309
1309
|
from bokeh.plotting import figure, show, output_file
|
|
1310
1310
|
from bokeh.models import ColumnDataSource, HoverTool
|
|
1311
1311
|
from bokeh.io.export import export_png
|
|
1312
|
-
from
|
|
1312
|
+
from master.study.helpers import get_eic
|
|
1313
1313
|
|
|
1314
1314
|
# Use study's eic_mz_tol parameter as default if not provided
|
|
1315
1315
|
if mz_tol is None:
|
|
@@ -1442,10 +1442,10 @@ def plot_eic(
|
|
|
1442
1442
|
import os
|
|
1443
1443
|
if not os.path.isabs(filename):
|
|
1444
1444
|
filename = os.path.join(self.folder, filename)
|
|
1445
|
-
|
|
1445
|
+
|
|
1446
1446
|
# Convert to absolute path for logging
|
|
1447
1447
|
abs_filename = os.path.abspath(filename)
|
|
1448
|
-
|
|
1448
|
+
|
|
1449
1449
|
# Use isolated file saving
|
|
1450
1450
|
_isolated_save_plot(p, filename, abs_filename, self.logger, "EIC Plot")
|
|
1451
1451
|
else:
|
|
@@ -1595,10 +1595,10 @@ def plot_rt_correction(
|
|
|
1595
1595
|
import os
|
|
1596
1596
|
if not os.path.isabs(filename):
|
|
1597
1597
|
filename = os.path.join(self.folder, filename)
|
|
1598
|
-
|
|
1598
|
+
|
|
1599
1599
|
# Convert to absolute path for logging
|
|
1600
1600
|
abs_filename = os.path.abspath(filename)
|
|
1601
|
-
|
|
1601
|
+
|
|
1602
1602
|
# Use isolated file saving
|
|
1603
1603
|
_isolated_save_plot(p, filename, abs_filename, self.logger, "RT Correction Plot")
|
|
1604
1604
|
else:
|
|
@@ -1692,19 +1692,19 @@ def plot_chrom(
|
|
|
1692
1692
|
sorted_indices = np.argsort(rt)
|
|
1693
1693
|
rt = rt[sorted_indices]
|
|
1694
1694
|
inty = inty[sorted_indices]
|
|
1695
|
-
|
|
1695
|
+
|
|
1696
1696
|
# Get sample uid for this sample name
|
|
1697
1697
|
sample_uid = sample_name_to_uid.get(sample, None)
|
|
1698
1698
|
sample_color = color_map.get(sample, "#1f77b4")
|
|
1699
|
-
|
|
1699
|
+
|
|
1700
1700
|
# Create arrays with sample information for hover tooltips
|
|
1701
1701
|
sample_names_array = [sample] * len(rt)
|
|
1702
1702
|
sample_uids_array = [sample_uid] * len(rt)
|
|
1703
1703
|
sample_colors_array = [sample_color] * len(rt)
|
|
1704
|
-
|
|
1704
|
+
|
|
1705
1705
|
curve = hv.Curve(
|
|
1706
|
-
(rt, inty, sample_names_array, sample_uids_array, sample_colors_array),
|
|
1707
|
-
kdims=["RT"],
|
|
1706
|
+
(rt, inty, sample_names_array, sample_uids_array, sample_colors_array),
|
|
1707
|
+
kdims=["RT"],
|
|
1708
1708
|
vdims=["inty", "sample_name", "sample_uid", "sample_color"]
|
|
1709
1709
|
).opts(
|
|
1710
1710
|
color=color_map[sample],
|
|
@@ -1775,17 +1775,17 @@ def plot_chrom(
|
|
|
1775
1775
|
# stack vertically.
|
|
1776
1776
|
# Stack all plots vertically in a Panel column
|
|
1777
1777
|
layout = panel.Column(*[panel.panel(plot) for plot in plots])
|
|
1778
|
-
|
|
1778
|
+
|
|
1779
1779
|
# Apply consistent save/display behavior
|
|
1780
1780
|
if filename is not None:
|
|
1781
1781
|
# Convert relative paths to absolute paths using study folder as base
|
|
1782
1782
|
import os
|
|
1783
1783
|
if not os.path.isabs(filename):
|
|
1784
1784
|
filename = os.path.join(self.folder, filename)
|
|
1785
|
-
|
|
1785
|
+
|
|
1786
1786
|
# Convert to absolute path for logging
|
|
1787
1787
|
abs_filename = os.path.abspath(filename)
|
|
1788
|
-
|
|
1788
|
+
|
|
1789
1789
|
# Use isolated Panel saving
|
|
1790
1790
|
_isolated_save_panel_plot(panel.panel(layout), filename, abs_filename, self.logger, "Chromatogram Plot")
|
|
1791
1791
|
else:
|
|
@@ -2031,10 +2031,10 @@ def plot_consensus_stats(
|
|
|
2031
2031
|
import os
|
|
2032
2032
|
if not os.path.isabs(filename):
|
|
2033
2033
|
filename = os.path.join(self.folder, filename)
|
|
2034
|
-
|
|
2034
|
+
|
|
2035
2035
|
# Convert to absolute path for logging
|
|
2036
2036
|
abs_filename = os.path.abspath(filename)
|
|
2037
|
-
|
|
2037
|
+
|
|
2038
2038
|
# Use isolated file saving
|
|
2039
2039
|
_isolated_save_plot(grid, filename, abs_filename, self.logger, "Consensus Stats Plot")
|
|
2040
2040
|
else:
|
|
@@ -2097,7 +2097,7 @@ def plot_pca(
|
|
|
2097
2097
|
|
|
2098
2098
|
# Extract only the sample columns (exclude consensus_uid column)
|
|
2099
2099
|
sample_cols = [col for col in consensus_matrix.columns if col != "consensus_uid"]
|
|
2100
|
-
|
|
2100
|
+
|
|
2101
2101
|
# Convert consensus matrix to numpy, excluding the consensus_uid column
|
|
2102
2102
|
if hasattr(consensus_matrix, "select"):
|
|
2103
2103
|
# Polars DataFrame
|
|
@@ -2295,10 +2295,10 @@ def plot_pca(
|
|
|
2295
2295
|
import os
|
|
2296
2296
|
if not os.path.isabs(filename):
|
|
2297
2297
|
filename = os.path.join(self.folder, filename)
|
|
2298
|
-
|
|
2298
|
+
|
|
2299
2299
|
# Convert to absolute path for logging
|
|
2300
2300
|
abs_filename = os.path.abspath(filename)
|
|
2301
|
-
|
|
2301
|
+
|
|
2302
2302
|
# Use isolated file saving
|
|
2303
2303
|
_isolated_save_plot(p, filename, abs_filename, self.logger, "PCA Plot")
|
|
2304
2304
|
else:
|
|
@@ -2325,7 +2325,7 @@ def plot_tic(
|
|
|
2325
2325
|
from bokeh.plotting import figure, show, output_file
|
|
2326
2326
|
from bokeh.models import ColumnDataSource, HoverTool
|
|
2327
2327
|
from bokeh.io.export import export_png
|
|
2328
|
-
from
|
|
2328
|
+
from master.study.helpers import get_tic
|
|
2329
2329
|
|
|
2330
2330
|
sample_uids = self._get_sample_uids(samples)
|
|
2331
2331
|
if not sample_uids:
|
|
@@ -2449,10 +2449,10 @@ def plot_tic(
|
|
|
2449
2449
|
import os
|
|
2450
2450
|
if not os.path.isabs(filename):
|
|
2451
2451
|
filename = os.path.join(self.folder, filename)
|
|
2452
|
-
|
|
2452
|
+
|
|
2453
2453
|
# Convert to absolute path for logging
|
|
2454
2454
|
abs_filename = os.path.abspath(filename)
|
|
2455
|
-
|
|
2455
|
+
|
|
2456
2456
|
# Use isolated file saving
|
|
2457
2457
|
_isolated_save_plot(p, filename, abs_filename, self.logger, "TIC Plot")
|
|
2458
2458
|
else:
|