spacr 0.2.21__py3-none-any.whl → 0.2.32__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.
- spacr/app_annotate.py +3 -4
- spacr/core.py +58 -229
- spacr/gui_core.py +83 -36
- spacr/gui_elements.py +414 -63
- spacr/gui_utils.py +58 -32
- spacr/io.py +121 -37
- spacr/measure.py +6 -8
- spacr/resources/icons/measure.png +0 -0
- spacr/resources/icons/ml_analyze.png +0 -0
- spacr/resources/icons/recruitment.png +0 -0
- spacr/resources/icons/spacr_logo_rotation.gif +0 -0
- spacr/resources/icons/train_cellpose.png +0 -0
- spacr/settings.py +1 -4
- spacr/utils.py +55 -0
- {spacr-0.2.21.dist-info → spacr-0.2.32.dist-info}/METADATA +1 -1
- {spacr-0.2.21.dist-info → spacr-0.2.32.dist-info}/RECORD +20 -18
- {spacr-0.2.21.dist-info → spacr-0.2.32.dist-info}/LICENSE +0 -0
- {spacr-0.2.21.dist-info → spacr-0.2.32.dist-info}/WHEEL +0 -0
- {spacr-0.2.21.dist-info → spacr-0.2.32.dist-info}/entry_points.txt +0 -0
- {spacr-0.2.21.dist-info → spacr-0.2.32.dist-info}/top_level.txt +0 -0
spacr/gui_core.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import os, traceback, ctypes, matplotlib, requests, csv, matplotlib, time, requests
|
1
|
+
import os, traceback, ctypes, matplotlib, requests, csv, matplotlib, time, requests, re
|
2
2
|
import matplotlib.pyplot as plt
|
3
3
|
matplotlib.use('Agg')
|
4
4
|
import tkinter as tk
|
@@ -10,14 +10,14 @@ from tkinter import ttk, scrolledtext
|
|
10
10
|
from matplotlib.figure import Figure
|
11
11
|
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
12
12
|
from huggingface_hub import list_repo_files
|
13
|
-
|
13
|
+
import numpy as np
|
14
14
|
try:
|
15
15
|
ctypes.windll.shcore.SetProcessDpiAwareness(True)
|
16
16
|
except AttributeError:
|
17
17
|
pass
|
18
18
|
|
19
19
|
from .settings import set_default_train_test_model, get_measure_crop_settings, set_default_settings_preprocess_generate_masks, get_analyze_reads_default_settings, set_default_umap_image_settings
|
20
|
-
from .gui_elements import spacrButton, spacrLabel, spacrFrame, spacrDropdownMenu ,set_dark_style, set_default_font
|
20
|
+
from .gui_elements import spacrProgressBar, spacrButton, spacrLabel, spacrFrame, spacrDropdownMenu ,set_dark_style, set_default_font
|
21
21
|
|
22
22
|
# Define global variables
|
23
23
|
q = None
|
@@ -89,7 +89,9 @@ def run_function_gui(settings_type, settings, q, fig_queue, stop_requested):
|
|
89
89
|
from .sim import run_multiple_simulations
|
90
90
|
from .deep_spacr import train_test_model
|
91
91
|
from .sequencing import analyze_reads, map_barcodes_folder, perform_regression
|
92
|
-
process_stdout_stderr(q)
|
92
|
+
process_stdout_stderr(q)
|
93
|
+
|
94
|
+
print(f'run_function_gui settings_type: {settings_type}')
|
93
95
|
|
94
96
|
if settings_type == 'mask':
|
95
97
|
function = preprocess_generate_masks
|
@@ -127,21 +129,6 @@ def run_function_gui(settings_type, settings, q, fig_queue, stop_requested):
|
|
127
129
|
elif settings_type == 'recruitment':
|
128
130
|
function = analyze_recruitment
|
129
131
|
imports = 2
|
130
|
-
#elif settings_type == 'cellpose_dataset':
|
131
|
-
# function = generate_cellpose_train_test
|
132
|
-
# imports = 1
|
133
|
-
#elif settings_type == 'plaques':
|
134
|
-
# function = analyze_plaques
|
135
|
-
# imports = 1
|
136
|
-
#elif settings_type == 'cellpose_compare':
|
137
|
-
# function = compare_cellpose_masks
|
138
|
-
# imports = 1
|
139
|
-
#elif settings_type == 'vision_scores':
|
140
|
-
# function = apply_model_to_tar
|
141
|
-
# imports = 1
|
142
|
-
#elif settings_type == 'vision_dataset':
|
143
|
-
# function = generate_dataset
|
144
|
-
# imports = 1
|
145
132
|
else:
|
146
133
|
raise ValueError(f"Invalid settings type: {settings_type}")
|
147
134
|
try:
|
@@ -484,7 +471,7 @@ def download_dataset(repo_id, subfolder, local_dir=None, retries=5, delay=5):
|
|
484
471
|
raise Exception("Failed to download files after multiple attempts.")
|
485
472
|
|
486
473
|
def setup_button_section(horizontal_container, settings_type='mask', window_dimensions=[500, 1000], run=True, abort=True, download=True, import_btn=True):
|
487
|
-
global button_frame, button_scrollable_frame, run_button, abort_button, download_dataset_button, import_button, q, fig_queue, vars_dict
|
474
|
+
global button_frame, button_scrollable_frame, run_button, abort_button, download_dataset_button, import_button, q, fig_queue, vars_dict, progress_bar
|
488
475
|
from .settings import descriptions
|
489
476
|
|
490
477
|
width = (window_dimensions[0]) // 8
|
@@ -504,9 +491,10 @@ def setup_button_section(horizontal_container, settings_type='mask', window_dime
|
|
504
491
|
widgets = [categories_label, button_scrollable_frame.scrollable_frame]
|
505
492
|
|
506
493
|
btn_col = 0
|
507
|
-
btn_row =
|
494
|
+
btn_row = 3
|
508
495
|
|
509
496
|
if run:
|
497
|
+
print(f'settings_type: {settings_type}')
|
510
498
|
run_button = spacrButton(button_scrollable_frame.scrollable_frame, text="run", command=lambda: start_process(q, fig_queue, settings_type))
|
511
499
|
run_button.grid(row=btn_row, column=btn_col, pady=5, padx=5, sticky='ew')
|
512
500
|
widgets.append(run_button)
|
@@ -528,6 +516,12 @@ def setup_button_section(horizontal_container, settings_type='mask', window_dime
|
|
528
516
|
import_button = spacrButton(button_scrollable_frame.scrollable_frame, text="settings", command=lambda: import_settings(settings_type))
|
529
517
|
import_button.grid(row=btn_row, column=btn_col, pady=5, padx=5, sticky='ew')
|
530
518
|
widgets.append(import_button)
|
519
|
+
btn_row += 1
|
520
|
+
|
521
|
+
# Add the progress bar under the settings category menu
|
522
|
+
progress_bar = spacrProgressBar(button_scrollable_frame.scrollable_frame, orient='horizontal', mode='determinate')
|
523
|
+
progress_bar.grid(row=0, column=0, columnspan=2, pady=5, padx=5, sticky='ew')
|
524
|
+
widgets.append(progress_bar)
|
531
525
|
|
532
526
|
if vars_dict is not None:
|
533
527
|
toggle_settings(button_scrollable_frame)
|
@@ -554,7 +548,8 @@ def setup_button_section(horizontal_container, settings_type='mask', window_dime
|
|
554
548
|
style = ttk.Style(horizontal_container)
|
555
549
|
_ = set_dark_style(style, containers=containers, widgets=widgets)
|
556
550
|
|
557
|
-
return
|
551
|
+
return button_scrollable_frame
|
552
|
+
|
558
553
|
|
559
554
|
def hide_all_settings(vars_dict, categories):
|
560
555
|
"""
|
@@ -615,7 +610,7 @@ def toggle_settings(button_scrollable_frame):
|
|
615
610
|
category_var = tk.StringVar()
|
616
611
|
non_empty_categories = [category for category, settings in categories.items() if any(setting in vars_dict for setting in settings)]
|
617
612
|
category_dropdown = spacrDropdownMenu(button_scrollable_frame.scrollable_frame, category_var, non_empty_categories, command=on_category_select)
|
618
|
-
category_dropdown.grid(row=
|
613
|
+
category_dropdown.grid(row=7, column=0, sticky="ew", pady=2, padx=2)
|
619
614
|
vars_dict = hide_all_settings(vars_dict, categories)
|
620
615
|
|
621
616
|
def process_fig_queue():
|
@@ -648,16 +643,72 @@ def process_fig_queue():
|
|
648
643
|
parent_frame.after_tasks.append(after_id)
|
649
644
|
|
650
645
|
def process_console_queue():
|
651
|
-
global q, console_output, parent_frame
|
646
|
+
global q, console_output, parent_frame, progress_bar
|
647
|
+
|
648
|
+
# Initialize function attribute if it doesn't exist
|
649
|
+
if not hasattr(process_console_queue, "completed_tasks"):
|
650
|
+
process_console_queue.completed_tasks = []
|
651
|
+
|
652
|
+
ansi_escape_pattern = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
|
653
|
+
|
652
654
|
while not q.empty():
|
653
655
|
message = q.get_nowait()
|
654
|
-
|
656
|
+
clean_message = ansi_escape_pattern.sub('', message)
|
657
|
+
console_output.insert(tk.END, clean_message + "\n")
|
655
658
|
console_output.see(tk.END)
|
659
|
+
|
660
|
+
# Check if the message contains progress information
|
661
|
+
if clean_message.startswith("Progress"):
|
662
|
+
try:
|
663
|
+
# Extract the progress information
|
664
|
+
match = re.search(r'(\d+)/(\d+)', clean_message)
|
665
|
+
if match:
|
666
|
+
current_progress = int(match.group(1))
|
667
|
+
total_progress = int(match.group(2))
|
668
|
+
|
669
|
+
# Add the task to the completed set
|
670
|
+
process_console_queue.completed_tasks.append(current_progress)
|
671
|
+
|
672
|
+
# Calculate the unique progress count
|
673
|
+
unique_progress_count = len(np.unique(process_console_queue.completed_tasks))
|
674
|
+
|
675
|
+
# Update the progress bar
|
676
|
+
if progress_bar:
|
677
|
+
progress_bar['maximum'] = total_progress
|
678
|
+
progress_bar['value'] = unique_progress_count
|
679
|
+
|
680
|
+
# Extract and update additional information
|
681
|
+
operation_match = re.search(r'operation_type: ([\w\s]+)', clean_message)
|
682
|
+
if operation_match:
|
683
|
+
progress_bar.operation_type = operation_match.group(1)
|
684
|
+
|
685
|
+
time_image_match = re.search(r'Time/image: ([\d.]+) sec', clean_message)
|
686
|
+
if time_image_match:
|
687
|
+
progress_bar.time_image = float(time_image_match.group(1))
|
688
|
+
|
689
|
+
time_batch_match = re.search(r'Time/batch: ([\d.]+) sec', clean_message)
|
690
|
+
if time_batch_match:
|
691
|
+
progress_bar.time_batch = float(time_batch_match.group(1))
|
692
|
+
|
693
|
+
time_left_match = re.search(r'Time_left: ([\d.]+) min', clean_message)
|
694
|
+
if time_left_match:
|
695
|
+
progress_bar.time_left = float(time_left_match.group(1))
|
696
|
+
|
697
|
+
# Update the progress label
|
698
|
+
if progress_bar.progress_label:
|
699
|
+
progress_bar.update_label()
|
700
|
+
|
701
|
+
# Clear completed tasks when progress is complete
|
702
|
+
if unique_progress_count >= total_progress:
|
703
|
+
process_console_queue.completed_tasks.clear()
|
704
|
+
except Exception as e:
|
705
|
+
print(f"Error parsing progress message: {e}")
|
706
|
+
|
656
707
|
after_id = console_output.after(100, process_console_queue)
|
657
708
|
parent_frame.after_tasks.append(after_id)
|
658
709
|
|
659
|
-
def set_globals(q_var, console_output_var, parent_frame_var, vars_dict_var, canvas_var, canvas_widget_var, scrollable_frame_var,
|
660
|
-
global q, console_output, parent_frame, vars_dict, canvas, canvas_widget, scrollable_frame,
|
710
|
+
def set_globals(q_var, console_output_var, parent_frame_var, vars_dict_var, canvas_var, canvas_widget_var, scrollable_frame_var, fig_queue_var, progress_bar_var):
|
711
|
+
global q, console_output, parent_frame, vars_dict, canvas, canvas_widget, scrollable_frame, fig_queue, progress_bar
|
661
712
|
q = q_var
|
662
713
|
console_output = console_output_var
|
663
714
|
parent_frame = parent_frame_var
|
@@ -665,8 +716,8 @@ def set_globals(q_var, console_output_var, parent_frame_var, vars_dict_var, canv
|
|
665
716
|
canvas = canvas_var
|
666
717
|
canvas_widget = canvas_widget_var
|
667
718
|
scrollable_frame = scrollable_frame_var
|
668
|
-
progress_label = progress_label_var
|
669
719
|
fig_queue = fig_queue_var
|
720
|
+
progress_bar = progress_bar_var
|
670
721
|
|
671
722
|
def create_containers(parent_frame):
|
672
723
|
vertical_container = tk.PanedWindow(parent_frame, orient=tk.VERTICAL)
|
@@ -694,7 +745,7 @@ def setup_frame(parent_frame):
|
|
694
745
|
return parent_frame, vertical_container, horizontal_container
|
695
746
|
|
696
747
|
def initiate_root(parent, settings_type='mask'):
|
697
|
-
global q, fig_queue, parent_frame, scrollable_frame, button_frame, vars_dict, canvas, canvas_widget,
|
748
|
+
global q, fig_queue, parent_frame, scrollable_frame, button_frame, vars_dict, canvas, canvas_widget, button_scrollable_frame, progress_bar
|
698
749
|
from .gui_utils import main_thread_update_function
|
699
750
|
from .gui import gui_app
|
700
751
|
set_start_method('spawn', force=True)
|
@@ -733,16 +784,12 @@ def initiate_root(parent, settings_type='mask'):
|
|
733
784
|
canvas, canvas_widget = setup_plot_section(vertical_container)
|
734
785
|
console_output = setup_console(vertical_container)
|
735
786
|
|
736
|
-
|
737
|
-
progress_output = setup_progress_frame(vertical_container)
|
738
|
-
else:
|
739
|
-
progress_output = None
|
740
|
-
|
741
|
-
set_globals(q, console_output, parent_frame, vars_dict, canvas, canvas_widget, scrollable_frame, progress_label, fig_queue)
|
787
|
+
set_globals(q, console_output, parent_frame, vars_dict, canvas, canvas_widget, scrollable_frame, fig_queue, progress_bar)
|
742
788
|
process_console_queue()
|
743
789
|
process_fig_queue()
|
744
|
-
after_id = parent_frame.after(100, lambda: main_thread_update_function(parent_frame, q, fig_queue, canvas_widget
|
790
|
+
after_id = parent_frame.after(100, lambda: main_thread_update_function(parent_frame, q, fig_queue, canvas_widget))
|
745
791
|
parent_frame.after_tasks.append(after_id)
|
746
792
|
|
747
793
|
print("Root initialization complete")
|
748
794
|
return parent_frame, vars_dict
|
795
|
+
|