spacr 0.2.1__py3-none-any.whl → 0.2.21__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 (90) hide show
  1. spacr/gui.py +2 -1
  2. spacr/gui_elements.py +2 -7
  3. spacr/resources/icons/abort.png +0 -0
  4. spacr/resources/icons/classify.png +0 -0
  5. spacr/resources/icons/make_masks.png +0 -0
  6. spacr/resources/icons/mask.png +0 -0
  7. spacr/resources/icons/measure.png +0 -0
  8. spacr/resources/icons/recruitment.png +0 -0
  9. spacr/resources/icons/regression.png +0 -0
  10. spacr/resources/icons/run.png +0 -0
  11. spacr/resources/icons/umap.png +0 -0
  12. {spacr-0.2.1.dist-info → spacr-0.2.21.dist-info}/METADATA +1 -1
  13. spacr-0.2.21.dist-info/RECORD +56 -0
  14. spacr/alpha.py +0 -807
  15. spacr/annotate_app.py +0 -670
  16. spacr/annotate_app_v2.py +0 -670
  17. spacr/app_make_masks_v2.py +0 -686
  18. spacr/classify_app.py +0 -201
  19. spacr/cli.py +0 -41
  20. spacr/foldseek.py +0 -779
  21. spacr/get_alfafold_structures.py +0 -72
  22. spacr/gui_2.py +0 -157
  23. spacr/gui_annotate.py +0 -145
  24. spacr/gui_classify_app.py +0 -201
  25. spacr/gui_make_masks_app.py +0 -927
  26. spacr/gui_make_masks_app_v2.py +0 -688
  27. spacr/gui_mask_app.py +0 -249
  28. spacr/gui_measure_app.py +0 -246
  29. spacr/gui_run.py +0 -58
  30. spacr/gui_sim_app.py +0 -0
  31. spacr/gui_wrappers.py +0 -149
  32. spacr/icons/abort.png +0 -0
  33. spacr/icons/abort.svg +0 -1
  34. spacr/icons/download.png +0 -0
  35. spacr/icons/download.svg +0 -1
  36. spacr/icons/download_for_offline_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.png +0 -0
  37. spacr/icons/download_for_offline_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.svg +0 -1
  38. spacr/icons/logo_spacr.png +0 -0
  39. spacr/icons/make_masks.png +0 -0
  40. spacr/icons/make_masks.svg +0 -1
  41. spacr/icons/map_barcodes.png +0 -0
  42. spacr/icons/map_barcodes.svg +0 -1
  43. spacr/icons/mask.png +0 -0
  44. spacr/icons/mask.svg +0 -1
  45. spacr/icons/measure.png +0 -0
  46. spacr/icons/measure.svg +0 -1
  47. spacr/icons/play_circle_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.png +0 -0
  48. spacr/icons/play_circle_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.svg +0 -1
  49. spacr/icons/run.png +0 -0
  50. spacr/icons/run.svg +0 -1
  51. spacr/icons/sequencing.png +0 -0
  52. spacr/icons/sequencing.svg +0 -1
  53. spacr/icons/settings.png +0 -0
  54. spacr/icons/settings.svg +0 -1
  55. spacr/icons/settings_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.png +0 -0
  56. spacr/icons/settings_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.svg +0 -1
  57. spacr/icons/stop_circle_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.png +0 -0
  58. spacr/icons/stop_circle_100dp_E8EAED_FILL0_wght100_GRAD-25_opsz48.svg +0 -1
  59. spacr/icons/theater_comedy_100dp_E8EAED_FILL0_wght100_GRAD200_opsz48.png +0 -0
  60. spacr/icons/theater_comedy_100dp_E8EAED_FILL0_wght100_GRAD200_opsz48.svg +0 -1
  61. spacr/make_masks_app.py +0 -929
  62. spacr/make_masks_app_v2.py +0 -688
  63. spacr/mask_app.py +0 -249
  64. spacr/measure_app.py +0 -246
  65. spacr/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model +0 -0
  66. spacr/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model_settings.csv +0 -23
  67. spacr/models/cp/toxo_pv_lumen.CP_model +0 -0
  68. spacr/old_code.py +0 -358
  69. spacr/resources/icons/abort.svg +0 -1
  70. spacr/resources/icons/annotate.svg +0 -1
  71. spacr/resources/icons/classify.svg +0 -1
  72. spacr/resources/icons/download.svg +0 -1
  73. spacr/resources/icons/icon.psd +0 -0
  74. spacr/resources/icons/make_masks.svg +0 -1
  75. spacr/resources/icons/map_barcodes.svg +0 -1
  76. spacr/resources/icons/mask.svg +0 -1
  77. spacr/resources/icons/measure.svg +0 -1
  78. spacr/resources/icons/run.svg +0 -1
  79. spacr/resources/icons/run_2.png +0 -0
  80. spacr/resources/icons/run_2.svg +0 -1
  81. spacr/resources/icons/sequencing.svg +0 -1
  82. spacr/resources/icons/settings.svg +0 -1
  83. spacr/resources/icons/train_cellpose.svg +0 -1
  84. spacr/test_gui.py +0 -0
  85. spacr-0.2.1.dist-info/RECORD +0 -126
  86. /spacr/resources/icons/{cellpose.png → cellpose_all.png} +0 -0
  87. {spacr-0.2.1.dist-info → spacr-0.2.21.dist-info}/LICENSE +0 -0
  88. {spacr-0.2.1.dist-info → spacr-0.2.21.dist-info}/WHEEL +0 -0
  89. {spacr-0.2.1.dist-info → spacr-0.2.21.dist-info}/entry_points.txt +0 -0
  90. {spacr-0.2.1.dist-info → spacr-0.2.21.dist-info}/top_level.txt +0 -0
@@ -1,72 +0,0 @@
1
- import csv
2
- import os
3
- import requests
4
-
5
- def download_alphafold_structures(tsv_location, dst, version="4"):
6
- # Create the destination directory if it does not exist
7
- dst_pdb = os.path.join(dst,'pdb')
8
- dst_cif = os.path.join(dst,'cif')
9
- dst_pae = os.path.join(dst,'pae')
10
-
11
- if not os.path.exists(dst):
12
- os.makedirs(dst)
13
- if not os.path.exists(dst_pdb):
14
- os.makedirs(dst_pdb)
15
- if not os.path.exists(dst_cif):
16
- os.makedirs(dst_cif)
17
- if not os.path.exists(dst_pae):
18
- os.makedirs(dst_pae)
19
-
20
- failed_downloads = [] # List to keep track of failed downloads
21
-
22
- # Open the TSV file and read entries
23
- with open(tsv_location, 'r') as tsv_file:
24
- reader = csv.DictReader(tsv_file, delimiter='\t')
25
- for row in reader:
26
- entry = row['Entry']
27
- af_link = f"https://alphafold.ebi.ac.uk/files/AF-{entry}-F1-model_v{version}.pdb"
28
- cif_link = f"https://alphafold.ebi.ac.uk/files/AF-{entry}-F1-model_v{version}.cif"
29
- pae_link = f"https://alphafold.ebi.ac.uk/files/AF-{entry}-F1-predicted_aligned_error_v{version}.json"
30
-
31
- try:
32
- response_pdb = requests.get(af_link, stream=True)
33
- response_cif = requests.get(cif_link, stream=True)
34
- response_pae = requests.get(pae_link, stream=True)
35
- if response_pdb.status_code == 200:
36
-
37
- # Save the PDB file
38
- with open(os.path.join(dst_pdb, f"AF-{entry}-F1-model_v{version}.pdb"), 'wb') as pdb_file:
39
- pdb_file.write(response_pdb.content)
40
- print(f"Downloaded: AF-{entry}-F1-model_v{version}.pdb")
41
-
42
- # Save the CIF file
43
- with open(os.path.join(dst_cif, f"AF-{entry}-F1-model_v{version}.cif"), 'wb') as cif_file:
44
- cif_file.write(response_cif.content)
45
- print(f"Downloaded: AF-{entry}-F1-model_v{version}.cif")
46
-
47
- # Save the PAE file
48
- with open(os.path.join(dst_pae, f"AF-{entry}-F1-predicted_aligned_error_v{version}.json"), 'wb') as pdb_file:
49
- pdb_file.write(response_pae.content)
50
- print(f"Downloaded: AF-{entry}-F1-predicted_aligned_error_v{version}.json")
51
-
52
- else:
53
- # If the file could not be downloaded, record the entry
54
- failed_downloads.append(entry)
55
- print(f"Failed to download structure for: {entry}")
56
- except Exception as e:
57
- print(f"Error downloading structure for {entry}: {e}")
58
- failed_downloads.append(entry)
59
-
60
- # Save the list of failed downloads to a CSV file in the destination folder
61
- if failed_downloads:
62
- with open(os.path.join(dst, 'failed_downloads.csv'), 'w', newline='') as failed_file:
63
- writer = csv.writer(failed_file)
64
- writer.writerow(['Entry'])
65
- for entry in failed_downloads:
66
- writer.writerow([entry])
67
- print(f"Failed download entries saved to: {os.path.join(dst, 'failed_downloads.csv')}")
68
-
69
- # Example usage:
70
- #tsv_location = '/home/carruthers/Downloads/GT1_proteome/GT1_proteins_uniprot.tsv' # Replace with the path to your TSV file containing a list of UniProt entries
71
- #dst_folder = '/home/carruthers/Downloads/GT1_proteome' # Replace with your destination folder
72
- #download_alphafold_structures(tsv_location, dst_folder)
spacr/gui_2.py DELETED
@@ -1,157 +0,0 @@
1
- import tkinter as tk
2
- from tkinter import ttk
3
- from PIL import Image, ImageTk, ImageDraw
4
- import os
5
- from multiprocessing import set_start_method
6
- from .gui_elements import spacrButton, create_menu_bar, set_dark_style
7
- from .gui_core import initiate_root
8
-
9
- class MainApp(tk.Tk):
10
- def __init__(self, default_app=None):
11
- super().__init__()
12
- width = self.winfo_screenwidth()
13
- height = self.winfo_screenheight()
14
- self.geometry(f"{width}x{height}")
15
- self.title("SpaCr GUI Collection")
16
- self.configure(bg='#333333') # Set window background to dark gray
17
-
18
- # Initialize style and apply dark style to the main window
19
- style = ttk.Style()
20
- self.color_settings = set_dark_style(style, parent_frame=self)
21
- self.main_buttons = {} # Initialize main_buttons dictionary here
22
- self.additional_buttons = {} # Initialize additional_buttons dictionary here
23
-
24
- self.main_gui_apps = {
25
- "Mask": (lambda frame: initiate_root(frame, 'mask'), "Generate cellpose masks for cells, nuclei and pathogen images."),
26
- "Measure": (lambda frame: initiate_root(frame, 'measure'), "Measure single object intensity and morphological feature. Crop and save single object image"),
27
- "Annotate": (lambda frame: initiate_root(frame, 'annotate'), "Annotation single object images on a grid. Annotations are saved to database."),
28
- "Make Masks": (lambda frame: initiate_root(frame, 'make_masks'), "Adjust pre-existing Cellpose models to your specific dataset for improved performance"),
29
- "Classify": (lambda frame: initiate_root(frame, 'classify'), "Train Torch Convolutional Neural Networks (CNNs) or Transformers to classify single object images."),
30
- }
31
-
32
- self.additional_gui_apps = {
33
- "Sequencing": (lambda frame: initiate_root(frame, 'sequencing'), "Analyze sequencing data."),
34
- "Umap": (lambda frame: initiate_root(frame, 'umap'), "Generate UMAP embeddings with datapoints represented as images."),
35
- "Train Cellpose": (lambda frame: initiate_root(frame, 'train_cellpose'), "Train custom Cellpose models."),
36
- "ML Analyze": (lambda frame: initiate_root(frame, 'ml_analyze'), "Machine learning analysis of data."),
37
- "Cellpose Masks": (lambda frame: initiate_root(frame, 'cellpose_masks'), "Generate Cellpose masks."),
38
- "Cellpose All": (lambda frame: initiate_root(frame, 'cellpose_all'), "Run Cellpose on all images."),
39
- "Map Barcodes": (lambda frame: initiate_root(frame, 'map_barcodes'), "Map barcodes to data."),
40
- "Regression": (lambda frame: initiate_root(frame, 'regression'), "Perform regression analysis."),
41
- "Recruitment": (lambda frame: initiate_root(frame, 'recruitment'), "Analyze recruitment data.")
42
- }
43
-
44
- self.selected_app = tk.StringVar()
45
- self.create_widgets()
46
-
47
- if default_app in self.main_gui_apps:
48
- self.load_app(default_app, self.main_gui_apps[default_app][0])
49
- elif default_app in self.additional_gui_apps:
50
- self.load_app(default_app, self.additional_gui_apps[default_app][0])
51
-
52
- def create_widgets(self):
53
- # Create the menu bar
54
- create_menu_bar(self)
55
-
56
- # Create a canvas to hold the selected app and other elements
57
- self.canvas = tk.Canvas(self, highlightthickness=0)
58
- self.canvas.grid(row=0, column=0, sticky="nsew")
59
- self.grid_rowconfigure(0, weight=1)
60
- self.grid_columnconfigure(0, weight=1)
61
-
62
- # Create a frame inside the canvas to hold the main content
63
- self.content_frame = tk.Frame(self.canvas)
64
- self.content_frame.grid(row=0, column=0, sticky="nsew")
65
-
66
- # Center the content frame within the canvas
67
- self.canvas.create_window((self.winfo_screenwidth() // 2, self.winfo_screenheight() // 2), window=self.content_frame, anchor="center")
68
-
69
- # Apply dark style to canvas and content_frame
70
- set_dark_style(ttk.Style(), containers=[self.canvas, self.content_frame])
71
-
72
- # Create startup screen with buttons for each main GUI app and drop-down for additional apps
73
- self.create_startup_screen()
74
-
75
- def create_startup_screen(self):
76
- self.clear_frame(self.content_frame)
77
-
78
- # Create frames for the grids
79
- main_buttons_frame = tk.Frame(self.content_frame)
80
- main_buttons_frame.pack(pady=10)
81
- set_dark_style(ttk.Style(), containers=[main_buttons_frame])
82
-
83
- additional_buttons_frame = tk.Frame(self.content_frame)
84
- additional_buttons_frame.pack(pady=10)
85
- set_dark_style(ttk.Style(), containers=[additional_buttons_frame])
86
-
87
- # Create a frame for the description below the icon grids
88
- description_frame = tk.Frame(self.content_frame, height=50)
89
- description_frame.pack(fill=tk.X, pady=10)
90
- description_frame.pack_propagate(False) # Prevent the frame from resizing based on its content
91
- set_dark_style(ttk.Style(), containers=[description_frame])
92
-
93
- # Use a Label widget to display descriptions
94
- self.description_label = tk.Label(description_frame, text="", wraplength=800, justify="center", font=('Helvetica', 12), fg=self.color_settings['fg_color'], bg=self.color_settings['bg_color'])
95
- self.description_label.pack(fill=tk.BOTH, pady=10)
96
-
97
- # Load the logo image and place it in the main apps row
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
- 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."
101
-
102
- # Create icon buttons for the main apps
103
- for i, (app_name, app_data) in enumerate(self.main_gui_apps.items()):
104
- app_func, app_desc = app_data
105
- button = spacrButton(main_buttons_frame, text=app_name, command=lambda app_name=app_name, app_func=app_func: self.load_app(app_name, app_func), icon_name=app_name.lower(), size=100, show_text=False)
106
- button.grid(row=0, column=i + 1, padx=5, pady=5)
107
- self.main_buttons[button] = app_desc
108
-
109
- # Create icon buttons for the additional apps
110
- for i, (app_name, app_data) in enumerate(self.additional_gui_apps.items()):
111
- app_func, app_desc = app_data
112
- button = spacrButton(additional_buttons_frame, text=app_name, command=lambda app_name=app_name, app_func=app_func: self.load_app(app_name, app_func), icon_name=app_name.lower(), size=75, show_text=False)
113
- button.grid(row=0, column=i, padx=5, pady=5)
114
- self.additional_buttons[button] = app_desc
115
-
116
- # Update description initially
117
- self.update_description()
118
-
119
- def update_description(self):
120
- # Check all buttons and update description if any has the active color
121
- for button, desc in {**self.main_buttons, **self.additional_buttons}.items():
122
- if button.canvas.itemcget(button.button_bg, "fill") == self.color_settings['active_color']:
123
- self.show_description(desc)
124
- return
125
- self.clear_description()
126
-
127
- def show_description(self, description):
128
- if self.description_label.winfo_exists():
129
- self.description_label.config(text=description)
130
- self.description_label.update_idletasks() # Ensure the label updates immediately
131
-
132
- def clear_description(self):
133
- if self.description_label.winfo_exists():
134
- self.description_label.config(text="")
135
- self.description_label.update_idletasks() # Ensure the label updates immediately
136
-
137
- def load_app(self, app_name, app_func):
138
- # Clear the current content frame
139
- self.clear_frame(self.canvas)
140
-
141
- # Initialize the selected app
142
- app_frame = tk.Frame(self.canvas)
143
- app_frame.pack(fill=tk.BOTH, expand=True)
144
- set_dark_style(ttk.Style(), containers=[app_frame])
145
- app_func(app_frame)
146
-
147
- def clear_frame(self, frame):
148
- for widget in frame.winfo_children():
149
- widget.destroy()
150
-
151
- def gui_app():
152
- app = MainApp()
153
- app.mainloop()
154
-
155
- if __name__ == "__main__":
156
- set_start_method('spawn', force=True)
157
- gui_app()
spacr/gui_annotate.py DELETED
@@ -1,145 +0,0 @@
1
- import tkinter as tk
2
- from tkinter import ttk
3
- from tkinter import font as tkFont
4
- from PIL import Image, ImageTk
5
- import os
6
- import requests
7
-
8
- # Import your GUI apps
9
- from .gui_mask_app import initiate_mask_root
10
- from .gui_measure_app import initiate_measure_root
11
- from .annotate_app import initiate_annotation_app_root
12
- from .mask_app import initiate_mask_app_root
13
- from .gui_classify_app import initiate_classify_root
14
-
15
- from .gui_utils import CustomButton, style_text_boxes
16
-
17
- class MainApp(tk.Tk):
18
- def __init__(self):
19
- super().__init__()
20
- self.title("SpaCr GUI Collection")
21
- self.geometry("1100x1500")
22
- self.configure(bg="black")
23
- #self.attributes('-fullscreen', True)
24
-
25
- style = ttk.Style()
26
- style_text_boxes(style)
27
-
28
- self.gui_apps = {
29
- "Mask": (initiate_mask_root, "Generate cellpose masks for cells, nuclei and pathogen images."),
30
- "Measure": (initiate_measure_root, "Measure single object intensity and morphological feature. Crop and save single object image"),
31
- "Annotate": (initiate_annotation_app_root, "Annotation single object images on a grid. Annotations are saved to database."),
32
- "Make Masks": (initiate_mask_app_root, "Adjust pre-existing Cellpose models to your specific dataset for improved performance"),
33
- "Classify": (initiate_classify_root, "Train Torch Convolutional Neural Networks (CNNs) or Transformers to classify single object images.")
34
- }
35
-
36
- self.selected_app = tk.StringVar()
37
- self.create_widgets()
38
-
39
- def create_widgets(self):
40
- # Create the menu bar
41
- #create_menu_bar(self)
42
- # Create a canvas to hold the selected app and other elements
43
- self.canvas = tk.Canvas(self, bg="black", highlightthickness=0, width=4000, height=4000)
44
- self.canvas.grid(row=0, column=0, sticky="nsew")
45
- self.grid_rowconfigure(0, weight=1)
46
- self.grid_columnconfigure(0, weight=1)
47
- # Create a frame inside the canvas to hold the main content
48
- self.content_frame = tk.Frame(self.canvas, bg="black")
49
- self.content_frame.pack(fill=tk.BOTH, expand=True)
50
- # Create startup screen with buttons for each GUI app
51
- self.create_startup_screen()
52
-
53
- def create_startup_screen(self):
54
- self.clear_frame(self.content_frame)
55
-
56
- # Create a frame for the logo and description
57
- logo_frame = tk.Frame(self.content_frame, bg="black")
58
- logo_frame.pack(pady=20, expand=True)
59
-
60
- # Load the logo image
61
- if not self.load_logo(logo_frame):
62
- tk.Label(logo_frame, text="Logo not found", bg="black", fg="white", font=('Helvetica', 24, tkFont.NORMAL)).pack(padx=10, pady=10)
63
-
64
- # Add SpaCr text below the logo with padding for sharper text
65
- tk.Label(logo_frame, text="SpaCr", bg="black", fg="#008080", font=('Helvetica', 24, tkFont.NORMAL)).pack(padx=10, pady=10)
66
-
67
- # Create a frame for the buttons and descriptions
68
- buttons_frame = tk.Frame(self.content_frame, bg="black")
69
- buttons_frame.pack(pady=10, expand=True, padx=10)
70
-
71
- for i, (app_name, app_data) in enumerate(self.gui_apps.items()):
72
- app_func, app_desc = app_data
73
-
74
- # Create custom button with text
75
- button = CustomButton(buttons_frame, text=app_name, command=lambda app_name=app_name: self.load_app(app_name), font=('Helvetica', 12))
76
- button.grid(row=i, column=0, pady=10, padx=10, sticky="w")
77
-
78
- description_label = tk.Label(buttons_frame, text=app_desc, bg="black", fg="white", wraplength=800, justify="left", font=('Helvetica', 10, tkFont.NORMAL))
79
- description_label.grid(row=i, column=1, pady=10, padx=10, sticky="w")
80
-
81
- # Ensure buttons have a fixed width
82
- buttons_frame.grid_columnconfigure(0, minsize=150)
83
- # Ensure descriptions expand as needed
84
- buttons_frame.grid_columnconfigure(1, weight=1)
85
-
86
- def load_logo(self, frame):
87
- def download_image(url, save_path):
88
- try:
89
- response = requests.get(url, stream=True)
90
- response.raise_for_status() # Raise an HTTPError for bad responses
91
- with open(save_path, 'wb') as f:
92
- for chunk in response.iter_content(chunk_size=8192):
93
- f.write(chunk)
94
- return True
95
- except requests.exceptions.RequestException as e:
96
- print(f"Failed to download image from {url}: {e}")
97
- return False
98
-
99
- try:
100
- img_path = os.path.join(os.path.dirname(__file__), 'logo_spacr.png')
101
- print(f"Trying to load logo from {img_path}")
102
- logo_image = Image.open(img_path)
103
- except (FileNotFoundError, Image.UnidentifiedImageError):
104
- print(f"File {img_path} not found or is not a valid image. Attempting to download from GitHub.")
105
- if download_image('https://raw.githubusercontent.com/EinarOlafsson/spacr/main/spacr/logo_spacr.png', img_path):
106
- try:
107
- print(f"Downloaded file size: {os.path.getsize(img_path)} bytes")
108
- logo_image = Image.open(img_path)
109
- except Image.UnidentifiedImageError as e:
110
- print(f"Downloaded file is not a valid image: {e}")
111
- return False
112
- else:
113
- return False
114
- except Exception as e:
115
- print(f"An error occurred while loading the logo: {e}")
116
- return False
117
- try:
118
- logo_image = logo_image.resize((800, 800), Image.Resampling.LANCZOS)
119
- logo_photo = ImageTk.PhotoImage(logo_image)
120
- logo_label = tk.Label(frame, image=logo_photo, bg="black")
121
- logo_label.image = logo_photo # Keep a reference to avoid garbage collection
122
- logo_label.pack()
123
- return True
124
- except Exception as e:
125
- print(f"An error occurred while processing the logo image: {e}")
126
- return False
127
-
128
- def load_app(self, app_name):
129
- selected_app_func, _ = self.gui_apps[app_name]
130
- self.clear_frame(self.content_frame)
131
-
132
- app_frame = tk.Frame(self.content_frame, bg="black")
133
- app_frame.pack(fill=tk.BOTH, expand=True)
134
- selected_app_func(app_frame)#, self.winfo_width(), self.winfo_height())
135
-
136
- def clear_frame(self, frame):
137
- for widget in frame.winfo_children():
138
- widget.destroy()
139
-
140
- def gui_app():
141
- app = MainApp()
142
- app.mainloop()
143
-
144
- if __name__ == "__main__":
145
- gui_app()
spacr/gui_classify_app.py DELETED
@@ -1,201 +0,0 @@
1
- import sys, ctypes, matplotlib
2
- import tkinter as tk
3
- from tkinter import ttk, scrolledtext
4
- from matplotlib.figure import Figure
5
- from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
6
- from matplotlib.figure import Figure
7
- matplotlib.use('Agg')
8
- from tkinter import filedialog
9
- from multiprocessing import Process, Queue, Value
10
- import traceback
11
-
12
- try:
13
- ctypes.windll.shcore.SetProcessDpiAwareness(True)
14
- except AttributeError:
15
- pass
16
-
17
- from .logger import log_function_call
18
- from .gui_utils import ScrollableFrame, StdoutRedirector, CustomButton, set_dark_style, set_default_font, generate_fields, process_stdout_stderr, clear_canvas, main_thread_update_function
19
- from .gui_utils import classify_variables, check_classify_gui_settings, train_test_model_wrapper, read_settings_from_csv, update_settings_from_csv, style_text_boxes, create_menu_bar
20
-
21
- thread_control = {"run_thread": None, "stop_requested": False}
22
-
23
- #@log_function_call
24
- def initiate_abort():
25
- global thread_control
26
- if thread_control.get("stop_requested") is not None:
27
- thread_control["stop_requested"].value = 1
28
-
29
- if thread_control.get("run_thread") is not None:
30
- thread_control["run_thread"].join(timeout=5)
31
- if thread_control["run_thread"].is_alive():
32
- thread_control["run_thread"].terminate()
33
- thread_control["run_thread"] = None
34
-
35
- #@log_function_call
36
- def run_classify_gui(q, fig_queue, stop_requested):
37
- global vars_dict
38
- process_stdout_stderr(q)
39
- try:
40
- settings = check_classify_gui_settings(vars_dict)
41
- for key in settings:
42
- value = settings[key]
43
- print(key, value, type(value))
44
- train_test_model_wrapper(settings['src'], settings)
45
- except Exception as e:
46
- q.put(f"Error during processing: {e}")
47
- traceback.print_exc()
48
- finally:
49
- stop_requested.value = 1
50
-
51
- #@log_function_call
52
- def start_process(q, fig_queue):
53
- global thread_control
54
- if thread_control.get("run_thread") is not None:
55
- initiate_abort()
56
-
57
- stop_requested = Value('i', 0) # multiprocessing shared value for inter-process communication
58
- thread_control["stop_requested"] = stop_requested
59
- thread_control["run_thread"] = Process(target=run_classify_gui, args=(q, fig_queue, stop_requested))
60
- thread_control["run_thread"].start()
61
-
62
- def import_settings(scrollable_frame):
63
- global vars_dict
64
-
65
- csv_file_path = filedialog.askopenfilename(filetypes=[("CSV files", "*.csv")])
66
- csv_settings = read_settings_from_csv(csv_file_path)
67
- variables = classify_variables()
68
- new_settings = update_settings_from_csv(variables, csv_settings)
69
- vars_dict = generate_fields(new_settings, scrollable_frame)
70
-
71
- #@log_function_call
72
- def initiate_classify_root(parent_frame):
73
- global vars_dict, q, canvas, fig_queue, canvas_widget, thread_control
74
-
75
- style = ttk.Style(parent_frame)
76
- set_dark_style(style)
77
- style_text_boxes(style)
78
- set_default_font(parent_frame, font_name="Helvetica", size=8)
79
-
80
- parent_frame.configure(bg='#333333')
81
- parent_frame.grid_rowconfigure(0, weight=1)
82
- parent_frame.grid_columnconfigure(0, weight=1)
83
- fig_queue = Queue()
84
-
85
- def _process_fig_queue():
86
- global canvas
87
- try:
88
- while not fig_queue.empty():
89
- clear_canvas(canvas)
90
- fig = fig_queue.get_nowait()
91
- for ax in fig.get_axes():
92
- ax.set_xticks([]) # Remove x-axis ticks
93
- ax.set_yticks([]) # Remove y-axis ticks
94
- ax.xaxis.set_visible(False) # Hide the x-axis
95
- ax.yaxis.set_visible(False) # Hide the y-axis
96
- fig.tight_layout()
97
- fig.set_facecolor('#333333')
98
- canvas.figure = fig
99
- fig_width, fig_height = canvas_widget.winfo_width(), canvas_widget.winfo_height()
100
- fig.set_size_inches(fig_width / fig.dpi, fig_height / fig.dpi, forward=True)
101
- canvas.draw_idle()
102
- except Exception as e:
103
- traceback.print_exc()
104
- finally:
105
- canvas_widget.after(100, _process_fig_queue)
106
-
107
- def _process_console_queue():
108
- while not q.empty():
109
- message = q.get_nowait()
110
- console_output.insert(tk.END, message)
111
- console_output.see(tk.END)
112
- console_output.after(100, _process_console_queue)
113
-
114
- vertical_container = tk.PanedWindow(parent_frame, orient=tk.HORIZONTAL)
115
- vertical_container.grid(row=0, column=0, sticky=tk.NSEW)
116
- parent_frame.grid_rowconfigure(0, weight=1)
117
- parent_frame.grid_columnconfigure(0, weight=1)
118
-
119
- # Settings Section
120
- settings_frame = tk.Frame(vertical_container, bg='#333333')
121
- vertical_container.add(settings_frame, stretch="always")
122
- settings_label = ttk.Label(settings_frame, text="Settings", background="#333333", foreground="white")
123
- settings_label.grid(row=0, column=0, pady=10, padx=10)
124
- scrollable_frame = ScrollableFrame(settings_frame, width=500)
125
- scrollable_frame.grid(row=1, column=0, sticky="nsew")
126
- settings_frame.grid_rowconfigure(1, weight=1)
127
- settings_frame.grid_columnconfigure(0, weight=1)
128
-
129
- # Setup for user input fields (variables)
130
- variables = classify_variables()
131
- vars_dict = generate_fields(variables, scrollable_frame)
132
-
133
- # Button section
134
- import_btn = CustomButton(scrollable_frame.scrollable_frame, text="Import", command=lambda: import_settings(scrollable_frame), font=('Helvetica', 10))
135
- import_btn.grid(row=47, column=0, pady=20, padx=20)
136
- run_button = CustomButton(scrollable_frame.scrollable_frame, text="Run", command=lambda: start_process(q, fig_queue), font=('Helvetica', 10))
137
- run_button.grid(row=45, column=0, pady=20, padx=20)
138
- abort_button = CustomButton(scrollable_frame.scrollable_frame, text="Abort", command=initiate_abort, font=('Helvetica', 10))
139
- abort_button.grid(row=45, column=1, pady=20, padx=20)
140
- progress_label = ttk.Label(scrollable_frame.scrollable_frame, text="Processing: 0%", background="black", foreground="white") # Create progress field
141
- progress_label.grid(row=50, column=0, columnspan=2, sticky="ew", pady=(5, 0), padx=10)
142
-
143
- # Plot Canvas Section
144
- plot_frame = tk.PanedWindow(vertical_container, orient=tk.VERTICAL)
145
- vertical_container.add(plot_frame, stretch="always")
146
- figure = Figure(figsize=(30, 4), dpi=100, facecolor='#333333')
147
- plot = figure.add_subplot(111)
148
- plot.plot([], [])
149
- plot.axis('off')
150
- canvas = FigureCanvasTkAgg(figure, master=plot_frame)
151
- canvas.get_tk_widget().configure(cursor='arrow', background='#333333', highlightthickness=0)
152
- canvas_widget = canvas.get_tk_widget()
153
- plot_frame.add(canvas_widget, stretch="always")
154
- canvas.draw()
155
- canvas.figure = figure
156
-
157
- # Console Section
158
- console_frame = tk.Frame(vertical_container, bg='#333333')
159
- vertical_container.add(console_frame, stretch="always")
160
- console_label = ttk.Label(console_frame, text="Console", background="#333333", foreground="white")
161
- console_label.grid(row=0, column=0, pady=10, padx=10)
162
- console_output = scrolledtext.ScrolledText(console_frame, height=10, bg='#333333', fg='white', insertbackground='white')
163
- console_output.grid(row=1, column=0, sticky="nsew")
164
- console_frame.grid_rowconfigure(1, weight=1)
165
- console_frame.grid_columnconfigure(0, weight=1)
166
-
167
- q = Queue()
168
- sys.stdout = StdoutRedirector(console_output)
169
- sys.stderr = StdoutRedirector(console_output)
170
-
171
- _process_console_queue()
172
- _process_fig_queue()
173
-
174
- parent_frame.after(100, lambda: main_thread_update_function(parent_frame, q, fig_queue, canvas_widget, progress_label))
175
-
176
- return parent_frame, vars_dict
177
-
178
- def gui_classify():
179
- root = tk.Tk()
180
- width = root.winfo_screenwidth()
181
- height = root.winfo_screenheight()
182
- root.geometry(f"{width}x{height}")
183
- root.title("SpaCr: classify objects")
184
-
185
- # Clear previous content if any
186
- if hasattr(root, 'content_frame'):
187
- for widget in root.content_frame.winfo_children():
188
- widget.destroy()
189
- root.content_frame.grid_forget()
190
- else:
191
- root.content_frame = tk.Frame(root)
192
- root.content_frame.grid(row=1, column=0, sticky="nsew")
193
- root.grid_rowconfigure(1, weight=1)
194
- root.grid_columnconfigure(0, weight=1)
195
-
196
- initiate_classify_root(root.content_frame)
197
- create_menu_bar(root)
198
- root.mainloop()
199
-
200
- if __name__ == "__main__":
201
- gui_classify()