spacr 0.2.21__py3-none-any.whl → 0.2.31__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/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 = 1
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 button_frame, button_scrollable_frame, description_frame, description_label
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=5, column=0, sticky="ew", pady=2, padx=2)
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
- console_output.insert(tk.END, message)
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, progress_label_var, fig_queue_var):
660
- global q, console_output, parent_frame, vars_dict, canvas, canvas_widget, scrollable_frame, progress_label, fig_queue
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, progress_label, progress_output, button_scrollable_frame
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
- if settings_type in ['mask', 'measure', 'classify', 'sequencing']:
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, progress_label))
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
+