spacr 0.2.1__py3-none-any.whl → 0.2.3__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.
Files changed (95) hide show
  1. spacr/gui.py +2 -1
  2. spacr/gui_core.py +75 -34
  3. spacr/gui_elements.py +323 -59
  4. spacr/gui_utils.py +26 -32
  5. spacr/resources/icons/abort.png +0 -0
  6. spacr/resources/icons/classify.png +0 -0
  7. spacr/resources/icons/make_masks.png +0 -0
  8. spacr/resources/icons/mask.png +0 -0
  9. spacr/resources/icons/measure.png +0 -0
  10. spacr/resources/icons/ml_analyze.png +0 -0
  11. spacr/resources/icons/recruitment.png +0 -0
  12. spacr/resources/icons/regression.png +0 -0
  13. spacr/resources/icons/run.png +0 -0
  14. spacr/resources/icons/spacr_logo_rotation.gif +0 -0
  15. spacr/resources/icons/train_cellpose.png +0 -0
  16. spacr/resources/icons/umap.png +0 -0
  17. {spacr-0.2.1.dist-info → spacr-0.2.3.dist-info}/METADATA +1 -1
  18. spacr-0.2.3.dist-info/RECORD +58 -0
  19. spacr/alpha.py +0 -807
  20. spacr/annotate_app.py +0 -670
  21. spacr/annotate_app_v2.py +0 -670
  22. spacr/app_make_masks_v2.py +0 -686
  23. spacr/classify_app.py +0 -201
  24. spacr/cli.py +0 -41
  25. spacr/foldseek.py +0 -779
  26. spacr/get_alfafold_structures.py +0 -72
  27. spacr/gui_2.py +0 -157
  28. spacr/gui_annotate.py +0 -145
  29. spacr/gui_classify_app.py +0 -201
  30. spacr/gui_make_masks_app.py +0 -927
  31. spacr/gui_make_masks_app_v2.py +0 -688
  32. spacr/gui_mask_app.py +0 -249
  33. spacr/gui_measure_app.py +0 -246
  34. spacr/gui_run.py +0 -58
  35. spacr/gui_sim_app.py +0 -0
  36. spacr/gui_wrappers.py +0 -149
  37. spacr/icons/abort.png +0 -0
  38. spacr/icons/abort.svg +0 -1
  39. spacr/icons/download.png +0 -0
  40. spacr/icons/download.svg +0 -1
  41. spacr/icons/download_for_offline_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.png +0 -0
  42. spacr/icons/download_for_offline_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.svg +0 -1
  43. spacr/icons/logo_spacr.png +0 -0
  44. spacr/icons/make_masks.png +0 -0
  45. spacr/icons/make_masks.svg +0 -1
  46. spacr/icons/map_barcodes.png +0 -0
  47. spacr/icons/map_barcodes.svg +0 -1
  48. spacr/icons/mask.png +0 -0
  49. spacr/icons/mask.svg +0 -1
  50. spacr/icons/measure.png +0 -0
  51. spacr/icons/measure.svg +0 -1
  52. spacr/icons/play_circle_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.png +0 -0
  53. spacr/icons/play_circle_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.svg +0 -1
  54. spacr/icons/run.png +0 -0
  55. spacr/icons/run.svg +0 -1
  56. spacr/icons/sequencing.png +0 -0
  57. spacr/icons/sequencing.svg +0 -1
  58. spacr/icons/settings.png +0 -0
  59. spacr/icons/settings.svg +0 -1
  60. spacr/icons/settings_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.png +0 -0
  61. spacr/icons/settings_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.svg +0 -1
  62. spacr/icons/stop_circle_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.png +0 -0
  63. spacr/icons/stop_circle_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.svg +0 -1
  64. spacr/icons/theater_comedy_100dp_E8EAED_FILL0_wght100_GRAD200_opsz48.png +0 -0
  65. spacr/icons/theater_comedy_100dp_E8EAED_FILL0_wght100_GRAD200_opsz48.svg +0 -1
  66. spacr/make_masks_app.py +0 -929
  67. spacr/make_masks_app_v2.py +0 -688
  68. spacr/mask_app.py +0 -249
  69. spacr/measure_app.py +0 -246
  70. spacr/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model +0 -0
  71. spacr/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model_settings.csv +0 -23
  72. spacr/models/cp/toxo_pv_lumen.CP_model +0 -0
  73. spacr/old_code.py +0 -358
  74. spacr/resources/icons/abort.svg +0 -1
  75. spacr/resources/icons/annotate.svg +0 -1
  76. spacr/resources/icons/classify.svg +0 -1
  77. spacr/resources/icons/download.svg +0 -1
  78. spacr/resources/icons/icon.psd +0 -0
  79. spacr/resources/icons/make_masks.svg +0 -1
  80. spacr/resources/icons/map_barcodes.svg +0 -1
  81. spacr/resources/icons/mask.svg +0 -1
  82. spacr/resources/icons/measure.svg +0 -1
  83. spacr/resources/icons/run.svg +0 -1
  84. spacr/resources/icons/run_2.png +0 -0
  85. spacr/resources/icons/run_2.svg +0 -1
  86. spacr/resources/icons/sequencing.svg +0 -1
  87. spacr/resources/icons/settings.svg +0 -1
  88. spacr/resources/icons/train_cellpose.svg +0 -1
  89. spacr/test_gui.py +0 -0
  90. spacr-0.2.1.dist-info/RECORD +0 -126
  91. /spacr/resources/icons/{cellpose.png → cellpose_all.png} +0 -0
  92. {spacr-0.2.1.dist-info → spacr-0.2.3.dist-info}/LICENSE +0 -0
  93. {spacr-0.2.1.dist-info → spacr-0.2.3.dist-info}/WHEEL +0 -0
  94. {spacr-0.2.1.dist-info → spacr-0.2.3.dist-info}/entry_points.txt +0 -0
  95. {spacr-0.2.1.dist-info → spacr-0.2.3.dist-info}/top_level.txt +0 -0
spacr/gui.py CHANGED
@@ -97,7 +97,7 @@ class MainApp(tk.Tk):
97
97
  # Load the logo image and place it in the main apps row
98
98
  logo_button = spacrButton(main_buttons_frame, text="SpaCr", command=lambda: self.load_app("logo_spacr", initiate_root), icon_name="logo_spacr", size=100, show_text=False)
99
99
  logo_button.grid(row=0, column=0, padx=5, pady=5)
100
- self.main_buttons[logo_button] = "SpaCr: An advanced application suite for cellpose masks, measurements, annotations, and more."
100
+ self.main_buttons[logo_button] = "SpaCr provides a flexible toolset to extract single-cell images and measurements from high-content cell painting experiments, train deep-learning models to classify cellular/subcellular phenotypes, simulate, and analyze pooled CRISPR-Cas9 imaging screens.."
101
101
 
102
102
  # Create icon buttons for the main apps
103
103
  for i, (app_name, app_data) in enumerate(self.main_gui_apps.items()):
@@ -115,6 +115,7 @@ class MainApp(tk.Tk):
115
115
 
116
116
  # Update description initially
117
117
  self.update_description()
118
+ #
118
119
 
119
120
  def update_description(self):
120
121
  # Check all buttons and update description if any has the active color
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
@@ -507,6 +494,7 @@ def setup_button_section(horizontal_container, settings_type='mask', window_dime
507
494
  btn_row = 1
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,11 @@ 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
+ progress_bar = spacrProgressBar(button_scrollable_frame.scrollable_frame, orient='horizontal', mode='determinate')
522
+ progress_bar.grid(row=0, column=0, columnspan=2, pady=5, padx=5, sticky='ew')
523
+ widgets.append(progress_bar)
531
524
 
532
525
  if vars_dict is not None:
533
526
  toggle_settings(button_scrollable_frame)
@@ -535,7 +528,7 @@ def setup_button_section(horizontal_container, settings_type='mask', window_dime
535
528
  description_frame = tk.Frame(horizontal_container)
536
529
  horizontal_container.add(description_frame, stretch="always", sticky="nsew")
537
530
  description_frame.grid_columnconfigure(0, weight=1)
538
- description_frame.grid_rowconfigure(0, weight=1) # Add this line to make the row expandable
531
+ description_frame.grid_rowconfigure(0, weight=1)
539
532
 
540
533
  description_label = tk.Label(description_frame, text="Module Description", anchor='nw', justify='left', wraplength=width - 50)
541
534
  description_label.grid(row=0, column=0, pady=50, padx=20, sticky='nsew')
@@ -554,7 +547,8 @@ def setup_button_section(horizontal_container, settings_type='mask', window_dime
554
547
  style = ttk.Style(horizontal_container)
555
548
  _ = set_dark_style(style, containers=containers, widgets=widgets)
556
549
 
557
- return button_frame, button_scrollable_frame, description_frame, description_label
550
+ return button_scrollable_frame
551
+
558
552
 
559
553
  def hide_all_settings(vars_dict, categories):
560
554
  """
@@ -647,17 +641,68 @@ def process_fig_queue():
647
641
  after_id = canvas_widget.after(100, process_fig_queue)
648
642
  parent_frame.after_tasks.append(after_id)
649
643
 
650
- def process_console_queue():
644
+ def process_console_queue_v1():
651
645
  global q, console_output, parent_frame
652
646
  while not q.empty():
653
647
  message = q.get_nowait()
654
648
  console_output.insert(tk.END, message)
655
649
  console_output.see(tk.END)
650
+ after_id = console_output.after(100, process_console_queue_v1)
651
+ parent_frame.after_tasks.append(after_id)
652
+
653
+ def process_console_queue():
654
+ global q, console_output, parent_frame, progress_bar, progress_label
655
+
656
+ # Initialize function attribute if it doesn't exist
657
+ if not hasattr(process_console_queue, "completed_tasks"):
658
+ process_console_queue.completed_tasks = []
659
+
660
+ ansi_escape_pattern = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
661
+
662
+ while not q.empty():
663
+ message = q.get_nowait()
664
+ clean_message = ansi_escape_pattern.sub('', message)
665
+ console_output.insert(tk.END, clean_message + "\n")
666
+ console_output.see(tk.END)
667
+
668
+ # Check if the message contains progress information
669
+ if clean_message.startswith("Progress"):
670
+ try:
671
+ # Extract the progress information
672
+ match = re.search(r'(\d+)/(\d+)', clean_message)
673
+ if match:
674
+ current_progress = int(match.group(1))
675
+ total_progress = int(match.group(2))
676
+
677
+ # Add the task to the completed set
678
+ process_console_queue.completed_tasks.append(current_progress)
679
+ #print('completed_tasks', process_console_queue.completed_tasks)
680
+
681
+ # Calculate the unique progress count
682
+ unique_progress_count = len(np.unique(process_console_queue.completed_tasks))
683
+
684
+ # Update the progress bar
685
+ if progress_bar:
686
+ progress_bar['maximum'] = total_progress
687
+ progress_bar['value'] = unique_progress_count
688
+
689
+ # Update the progress label
690
+ if progress_label:
691
+ progress_label_text = f"Processing: {unique_progress_count}/{total_progress}"
692
+ progress_label.config(text=progress_label_text)
693
+
694
+ # Clear completed tasks when progress is complete
695
+ if unique_progress_count > total_progress:
696
+ process_console_queue.completed_tasks.clear()
697
+ except Exception as e:
698
+ print(f"Error parsing progress message: {e}")
699
+
656
700
  after_id = console_output.after(100, process_console_queue)
657
701
  parent_frame.after_tasks.append(after_id)
658
702
 
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
703
+
704
+ 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):
705
+ global q, console_output, parent_frame, vars_dict, canvas, canvas_widget, scrollable_frame, progress_label, fig_queue, progress_bar
661
706
  q = q_var
662
707
  console_output = console_output_var
663
708
  parent_frame = parent_frame_var
@@ -665,8 +710,8 @@ def set_globals(q_var, console_output_var, parent_frame_var, vars_dict_var, canv
665
710
  canvas = canvas_var
666
711
  canvas_widget = canvas_widget_var
667
712
  scrollable_frame = scrollable_frame_var
668
- progress_label = progress_label_var
669
713
  fig_queue = fig_queue_var
714
+ progress_bar = progress_bar_var
670
715
 
671
716
  def create_containers(parent_frame):
672
717
  vertical_container = tk.PanedWindow(parent_frame, orient=tk.VERTICAL)
@@ -694,7 +739,7 @@ def setup_frame(parent_frame):
694
739
  return parent_frame, vertical_container, horizontal_container
695
740
 
696
741
  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
742
+ global q, fig_queue, parent_frame, scrollable_frame, button_frame, vars_dict, canvas, canvas_widget, button_scrollable_frame, progress_bar
698
743
  from .gui_utils import main_thread_update_function
699
744
  from .gui import gui_app
700
745
  set_start_method('spawn', force=True)
@@ -733,16 +778,12 @@ def initiate_root(parent, settings_type='mask'):
733
778
  canvas, canvas_widget = setup_plot_section(vertical_container)
734
779
  console_output = setup_console(vertical_container)
735
780
 
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)
781
+ set_globals(q, console_output, parent_frame, vars_dict, canvas, canvas_widget, scrollable_frame, fig_queue, progress_bar)
742
782
  process_console_queue()
743
783
  process_fig_queue()
744
- after_id = parent_frame.after(100, lambda: main_thread_update_function(parent_frame, q, fig_queue, canvas_widget, progress_label))
784
+ after_id = parent_frame.after(100, lambda: main_thread_update_function(parent_frame, q, fig_queue, canvas_widget))
745
785
  parent_frame.after_tasks.append(after_id)
746
786
 
747
787
  print("Root initialization complete")
748
788
  return parent_frame, vars_dict
789
+