spacr 0.0.20__py3-none-any.whl → 0.0.35__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/alpha.py +291 -14
- spacr/annotate_app.py +7 -5
- spacr/chris.py +50 -0
- spacr/core.py +1301 -426
- spacr/foldseek.py +793 -0
- spacr/get_alfafold_structures.py +72 -0
- spacr/gui.py +144 -0
- spacr/gui_classify_app.py +65 -74
- spacr/gui_mask_app.py +110 -87
- spacr/gui_measure_app.py +104 -81
- spacr/gui_utils.py +276 -31
- spacr/io.py +261 -102
- spacr/mask_app.py +6 -3
- spacr/measure.py +150 -64
- spacr/plot.py +151 -12
- spacr/sim.py +666 -119
- spacr/timelapse.py +139 -9
- spacr/train.py +18 -10
- spacr/utils.py +43 -49
- {spacr-0.0.20.dist-info → spacr-0.0.35.dist-info}/METADATA +5 -2
- spacr-0.0.35.dist-info/RECORD +35 -0
- spacr-0.0.35.dist-info/entry_points.txt +8 -0
- spacr-0.0.20.dist-info/RECORD +0 -31
- spacr-0.0.20.dist-info/entry_points.txt +0 -7
- {spacr-0.0.20.dist-info → spacr-0.0.35.dist-info}/LICENSE +0 -0
- {spacr-0.0.20.dist-info → spacr-0.0.35.dist-info}/WHEEL +0 -0
- {spacr-0.0.20.dist-info → spacr-0.0.35.dist-info}/top_level.txt +0 -0
spacr/gui_mask_app.py
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
import
|
1
|
+
import sys, ctypes, matplotlib
|
2
2
|
import tkinter as tk
|
3
3
|
from tkinter import ttk, scrolledtext
|
4
4
|
from ttkthemes import ThemedTk
|
5
5
|
from matplotlib.figure import Figure
|
6
6
|
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
7
|
-
from matplotlib.figure import Figure
|
8
7
|
matplotlib.use('Agg')
|
9
8
|
from tkinter import filedialog
|
10
9
|
from multiprocessing import Process, Queue, Value
|
@@ -16,11 +15,41 @@ except AttributeError:
|
|
16
15
|
pass
|
17
16
|
|
18
17
|
from .logger import log_function_call
|
19
|
-
from .gui_utils import ScrollableFrame, StdoutRedirector,
|
20
|
-
from .gui_utils import
|
18
|
+
from .gui_utils import ScrollableFrame, StdoutRedirector, ToggleSwitch, CustomButton
|
19
|
+
from .gui_utils import clear_canvas, main_thread_update_function, set_dark_style, generate_fields, process_stdout_stderr, set_default_font, style_text_boxes
|
20
|
+
from .gui_utils import mask_variables, check_mask_gui_settings, preprocess_generate_masks_wrapper, read_settings_from_csv, update_settings_from_csv, create_menu_bar
|
21
21
|
|
22
22
|
thread_control = {"run_thread": None, "stop_requested": False}
|
23
23
|
|
24
|
+
def toggle_test_mode():
|
25
|
+
global vars_dict
|
26
|
+
current_state = vars_dict['test_mode'][2].get()
|
27
|
+
new_state = not current_state
|
28
|
+
vars_dict['test_mode'][2].set(new_state)
|
29
|
+
if new_state:
|
30
|
+
test_mode_button.config(bg="blue")
|
31
|
+
else:
|
32
|
+
test_mode_button.config(bg="gray")
|
33
|
+
|
34
|
+
def toggle_advanced_settings():
|
35
|
+
global vars_dict
|
36
|
+
|
37
|
+
timelapse_settings = ['timelapse', 'timelapse_memory', 'timelapse_remove_transient', 'timelapse_mode', 'timelapse_objects', 'timelapse_displacement', 'timelapse_frame_limits', 'fps']
|
38
|
+
misc_settings = ['examples_to_plot', 'all_to_mip', 'pick_slice', 'skip_mode']
|
39
|
+
opperational_settings = ['preprocess', 'masks', 'randomize', 'batch_size', 'custom_regex', 'merge', 'normalize_plots', 'workers', 'plot', 'remove_background', 'lower_quantile']
|
40
|
+
|
41
|
+
advanced_settings = timelapse_settings+misc_settings+opperational_settings
|
42
|
+
|
43
|
+
# Toggle visibility of advanced settings
|
44
|
+
for setting in advanced_settings:
|
45
|
+
label, widget, var = vars_dict[setting]
|
46
|
+
if advanced_var.get() is False:
|
47
|
+
label.grid_remove() # Hide the label
|
48
|
+
widget.grid_remove() # Hide the widget
|
49
|
+
else:
|
50
|
+
label.grid() # Show the label
|
51
|
+
widget.grid() # Show the widget
|
52
|
+
|
24
53
|
@log_function_call
|
25
54
|
def initiate_abort():
|
26
55
|
global thread_control
|
@@ -32,24 +61,20 @@ def initiate_abort():
|
|
32
61
|
if thread_control["run_thread"].is_alive():
|
33
62
|
thread_control["run_thread"].terminate()
|
34
63
|
thread_control["run_thread"] = None
|
35
|
-
|
64
|
+
|
36
65
|
@log_function_call
|
37
66
|
def run_mask_gui(q, fig_queue, stop_requested):
|
38
67
|
global vars_dict
|
39
68
|
process_stdout_stderr(q)
|
40
69
|
try:
|
41
70
|
settings = check_mask_gui_settings(vars_dict)
|
42
|
-
#settings = add_mask_gui_defaults(settings)
|
43
|
-
#for key in settings:
|
44
|
-
# value = settings[key]
|
45
|
-
# print(key, value, type(value))
|
46
71
|
preprocess_generate_masks_wrapper(settings, q, fig_queue)
|
47
72
|
except Exception as e:
|
48
73
|
q.put(f"Error during processing: {e}")
|
49
74
|
traceback.print_exc()
|
50
75
|
finally:
|
51
76
|
stop_requested.value = 1
|
52
|
-
|
77
|
+
|
53
78
|
@log_function_call
|
54
79
|
def start_process(q, fig_queue):
|
55
80
|
global thread_control
|
@@ -60,140 +85,138 @@ def start_process(q, fig_queue):
|
|
60
85
|
thread_control["stop_requested"] = stop_requested
|
61
86
|
thread_control["run_thread"] = Process(target=run_mask_gui, args=(q, fig_queue, stop_requested))
|
62
87
|
thread_control["run_thread"].start()
|
63
|
-
|
88
|
+
|
64
89
|
def import_settings(scrollable_frame):
|
65
90
|
global vars_dict
|
66
91
|
|
67
92
|
csv_file_path = filedialog.askopenfilename(filetypes=[("CSV files", "*.csv")])
|
68
93
|
csv_settings = read_settings_from_csv(csv_file_path)
|
69
94
|
variables = mask_variables()
|
70
|
-
#variables = add_mask_gui_defaults(variables)
|
71
95
|
new_settings = update_settings_from_csv(variables, csv_settings)
|
72
96
|
vars_dict = generate_fields(new_settings, scrollable_frame)
|
73
|
-
|
97
|
+
|
74
98
|
@log_function_call
|
75
|
-
def initiate_mask_root(width, height):
|
76
|
-
global
|
77
|
-
|
78
|
-
|
99
|
+
def initiate_mask_root(parent_frame, width, height):
|
100
|
+
global vars_dict, q, canvas, fig_queue, canvas_widget, thread_control, advanced_var, scrollable_frame
|
101
|
+
|
102
|
+
style = ttk.Style(parent_frame)
|
103
|
+
set_dark_style(style)
|
104
|
+
style_text_boxes(style)
|
105
|
+
set_default_font(parent_frame, font_name="Open Sans", size=8)
|
106
|
+
parent_frame.configure(bg='black')
|
107
|
+
parent_frame.grid_rowconfigure(0, weight=1)
|
108
|
+
parent_frame.grid_columnconfigure(0, weight=1)
|
79
109
|
|
80
|
-
if theme in ['clam']:
|
81
|
-
root = tk.Tk()
|
82
|
-
style = ttk.Style(root)
|
83
|
-
style.theme_use(theme) #plastik, clearlooks, elegance, default was clam #alt, breeze, arc
|
84
|
-
set_dark_style(style)
|
85
|
-
elif theme in ['breeze']:
|
86
|
-
root = ThemedTk(theme="breeze")
|
87
|
-
style = ttk.Style(root)
|
88
|
-
set_dark_style(style)
|
89
|
-
|
90
|
-
set_default_font(root, font_name="Arial", size=10)
|
91
|
-
#root.state('zoomed') # For Windows to maximize the window
|
92
|
-
root.attributes('-fullscreen', True)
|
93
|
-
root.geometry(f"{width}x{height}")
|
94
|
-
root.title("SpaCer: generate masks")
|
95
110
|
fig_queue = Queue()
|
96
|
-
|
111
|
+
|
97
112
|
def _process_fig_queue():
|
98
113
|
global canvas
|
99
114
|
try:
|
100
115
|
while not fig_queue.empty():
|
101
116
|
clear_canvas(canvas)
|
102
117
|
fig = fig_queue.get_nowait()
|
103
|
-
#set_fig_text_properties(fig, font_size=8)
|
104
118
|
for ax in fig.get_axes():
|
105
119
|
ax.set_xticks([]) # Remove x-axis ticks
|
106
120
|
ax.set_yticks([]) # Remove y-axis ticks
|
107
121
|
ax.xaxis.set_visible(False) # Hide the x-axis
|
108
122
|
ax.yaxis.set_visible(False) # Hide the y-axis
|
109
|
-
#ax.title.set_fontsize(14)
|
110
|
-
#disable_interactivity(fig)
|
111
123
|
fig.tight_layout()
|
112
|
-
fig.set_facecolor('
|
124
|
+
fig.set_facecolor('black')
|
113
125
|
canvas.figure = fig
|
114
126
|
fig_width, fig_height = canvas_widget.winfo_width(), canvas_widget.winfo_height()
|
115
127
|
fig.set_size_inches(fig_width / fig.dpi, fig_height / fig.dpi, forward=True)
|
116
|
-
canvas.draw_idle()
|
128
|
+
canvas.draw_idle()
|
117
129
|
except Exception as e:
|
118
130
|
traceback.print_exc()
|
119
|
-
#pass
|
120
131
|
finally:
|
121
132
|
canvas_widget.after(100, _process_fig_queue)
|
122
|
-
|
123
|
-
# Process queue for console output
|
133
|
+
|
124
134
|
def _process_console_queue():
|
125
135
|
while not q.empty():
|
126
136
|
message = q.get_nowait()
|
127
137
|
console_output.insert(tk.END, message)
|
128
138
|
console_output.see(tk.END)
|
129
139
|
console_output.after(100, _process_console_queue)
|
130
|
-
|
131
|
-
# Vertical container for settings and console
|
132
|
-
vertical_container = tk.PanedWindow(root, orient=tk.HORIZONTAL) #VERTICAL
|
133
|
-
vertical_container.pack(fill=tk.BOTH, expand=True)
|
134
140
|
|
135
|
-
|
136
|
-
|
137
|
-
|
141
|
+
vertical_container = tk.PanedWindow(parent_frame, orient=tk.HORIZONTAL)
|
142
|
+
vertical_container.grid(row=0, column=0, sticky=tk.NSEW)
|
143
|
+
parent_frame.grid_rowconfigure(0, weight=1)
|
144
|
+
parent_frame.grid_columnconfigure(0, weight=1)
|
138
145
|
|
139
|
-
#
|
146
|
+
# Settings Section
|
147
|
+
settings_frame = tk.Frame(vertical_container, bg='black')
|
148
|
+
vertical_container.add(settings_frame, stretch="always")
|
149
|
+
settings_label = ttk.Label(settings_frame, text="Settings", style="Custom.TLabel")
|
150
|
+
settings_label.grid(row=0, column=0, pady=10, padx=10)
|
151
|
+
scrollable_frame = ScrollableFrame(settings_frame, width=600)
|
152
|
+
scrollable_frame.grid(row=1, column=0, sticky="nsew")
|
153
|
+
settings_frame.grid_rowconfigure(1, weight=1)
|
154
|
+
settings_frame.grid_columnconfigure(0, weight=1)
|
155
|
+
|
156
|
+
# Create advanced settings checkbox
|
157
|
+
advanced_var = tk.BooleanVar(value=False)
|
158
|
+
advanced_Toggle = ToggleSwitch(scrollable_frame.scrollable_frame, text="Advanced Settings", variable=advanced_var, command=toggle_advanced_settings)
|
159
|
+
advanced_Toggle.grid(row=48, column=0, pady=10, padx=10)
|
140
160
|
variables = mask_variables()
|
141
161
|
vars_dict = generate_fields(variables, scrollable_frame)
|
162
|
+
toggle_advanced_settings()
|
163
|
+
vars_dict['Test mode'] = (None, None, tk.BooleanVar(value=False))
|
142
164
|
|
143
|
-
#
|
144
|
-
|
145
|
-
|
165
|
+
# Button section
|
166
|
+
test_mode_button = CustomButton(scrollable_frame.scrollable_frame, text="Test Mode", command=toggle_test_mode)
|
167
|
+
test_mode_button.grid(row=47, column=1, pady=10, padx=10)
|
168
|
+
import_btn = CustomButton(scrollable_frame.scrollable_frame, text="Import Settings", command=lambda: import_settings(scrollable_frame))
|
169
|
+
import_btn.grid(row=47, column=0, pady=20, padx=20)
|
170
|
+
run_button = CustomButton(scrollable_frame.scrollable_frame, text="Run", command=lambda: start_process(q, fig_queue))
|
171
|
+
run_button.grid(row=45, column=0, pady=20, padx=20)
|
172
|
+
abort_button = CustomButton(scrollable_frame.scrollable_frame, text="Abort", command=initiate_abort)
|
173
|
+
abort_button.grid(row=45, column=1, pady=20, padx=20)
|
174
|
+
progress_label = ttk.Label(scrollable_frame.scrollable_frame, text="Processing: 0%", background="black", foreground="white") # Create progress field
|
175
|
+
progress_label.grid(row=50, column=0, columnspan=2, sticky="ew", pady=(5, 0), padx=10)
|
146
176
|
|
147
|
-
#
|
148
|
-
|
177
|
+
# Plot Canvas Section
|
178
|
+
plot_frame = tk.PanedWindow(vertical_container, orient=tk.VERTICAL) # Horizontal container for Matplotlib figure and the vertical pane (for settings and console)
|
179
|
+
vertical_container.add(plot_frame, stretch="always")
|
180
|
+
figure = Figure(figsize=(30, 4), dpi=100, facecolor='black') # Matplotlib figure setup
|
149
181
|
plot = figure.add_subplot(111)
|
150
182
|
plot.plot([], []) # This creates an empty plot.
|
151
183
|
plot.axis('off')
|
152
|
-
|
153
|
-
|
154
|
-
canvas = FigureCanvasTkAgg(figure, master=horizontal_container)
|
155
|
-
canvas.get_tk_widget().configure(cursor='arrow', background='#333333', highlightthickness=0)
|
156
|
-
#canvas.get_tk_widget().configure(cursor='arrow')
|
184
|
+
canvas = FigureCanvasTkAgg(figure, master=plot_frame) # Embedd Matplotlib figure in Tkinter window
|
185
|
+
canvas.get_tk_widget().configure(cursor='arrow', background='black', highlightthickness=0)
|
157
186
|
canvas_widget = canvas.get_tk_widget()
|
158
|
-
|
187
|
+
plot_frame.add(canvas_widget, stretch="always")
|
159
188
|
canvas.draw()
|
160
189
|
canvas.figure = figure
|
161
190
|
|
162
|
-
# Console
|
163
|
-
|
164
|
-
vertical_container.add(
|
191
|
+
# Console Section
|
192
|
+
console_frame = tk.Frame(vertical_container, bg='black')
|
193
|
+
vertical_container.add(console_frame, stretch="always")
|
194
|
+
console_label = ttk.Label(console_frame, text="Console", background="black", foreground="white")
|
195
|
+
console_label.grid(row=0, column=0, pady=10, padx=10)
|
196
|
+
console_output = scrolledtext.ScrolledText(console_frame, height=10, bg='black', fg='white', insertbackground='white')
|
197
|
+
console_output.grid(row=1, column=0, sticky="nsew")
|
198
|
+
console_frame.grid_rowconfigure(1, weight=1)
|
199
|
+
console_frame.grid_columnconfigure(0, weight=1)
|
165
200
|
|
166
|
-
# Queue and redirection setup for updating console output safely
|
167
201
|
q = Queue()
|
168
202
|
sys.stdout = StdoutRedirector(console_output)
|
169
203
|
sys.stderr = StdoutRedirector(console_output)
|
170
|
-
|
171
|
-
# This is your GUI setup where you create the Run button
|
172
|
-
run_button = ttk.Button(scrollable_frame.scrollable_frame, text="Run",command=lambda: start_process(q, fig_queue))
|
173
|
-
run_button.grid(row=45, column=0, pady=10)
|
174
|
-
|
175
|
-
abort_button = ttk.Button(scrollable_frame.scrollable_frame, text="Abort", command=initiate_abort)
|
176
|
-
abort_button.grid(row=45, column=1, pady=10)
|
177
|
-
|
178
|
-
progress_label = ttk.Label(scrollable_frame.scrollable_frame, text="Processing: 0%", background="#333333", foreground="white")
|
179
|
-
progress_label.grid(row=41, column=0, columnspan=2, sticky="ew", pady=(5, 0))
|
180
|
-
|
181
|
-
# Create the Import Settings button
|
182
|
-
import_btn = tk.Button(root, text="Import Settings", command=lambda: import_settings(scrollable_frame))
|
183
|
-
import_btn.pack(pady=20)
|
184
|
-
|
204
|
+
|
185
205
|
_process_console_queue()
|
186
206
|
_process_fig_queue()
|
187
|
-
create_dark_mode(root, style, console_output)
|
188
207
|
|
189
|
-
|
190
|
-
|
191
|
-
return
|
208
|
+
parent_frame.after(100, lambda: main_thread_update_function(parent_frame, q, fig_queue, canvas_widget, progress_label))
|
209
|
+
|
210
|
+
return parent_frame, vars_dict
|
192
211
|
|
193
212
|
def gui_mask():
|
194
|
-
|
195
|
-
root
|
213
|
+
root = tk.Tk()
|
214
|
+
root.geometry("1000x800")
|
215
|
+
root.title("SpaCer: generate masks")
|
216
|
+
initiate_mask_root(root, 1000, 800)
|
217
|
+
create_menu_bar(root)
|
196
218
|
root.mainloop()
|
197
|
-
|
219
|
+
|
198
220
|
if __name__ == "__main__":
|
199
|
-
gui_mask()
|
221
|
+
gui_mask()
|
222
|
+
|
spacr/gui_measure_app.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import sys, traceback, matplotlib, ctypes
|
1
|
+
import sys, traceback, matplotlib, ctypes
|
2
2
|
import tkinter as tk
|
3
3
|
from tkinter import ttk, scrolledtext
|
4
4
|
from matplotlib.figure import Figure
|
@@ -7,7 +7,7 @@ import matplotlib.pyplot as plt
|
|
7
7
|
matplotlib.use('Agg') # Use the non-GUI Agg backend
|
8
8
|
from multiprocessing import Process, Queue, Value
|
9
9
|
from ttkthemes import ThemedTk
|
10
|
-
from tkinter import filedialog
|
10
|
+
from tkinter import filedialog
|
11
11
|
|
12
12
|
try:
|
13
13
|
ctypes.windll.shcore.SetProcessDpiAwareness(True)
|
@@ -15,11 +15,41 @@ except AttributeError:
|
|
15
15
|
pass
|
16
16
|
|
17
17
|
from .logger import log_function_call
|
18
|
-
from .gui_utils import ScrollableFrame, StdoutRedirector,
|
19
|
-
from .gui_utils import
|
18
|
+
from .gui_utils import ScrollableFrame, StdoutRedirector, CustomButton, ToggleSwitch
|
19
|
+
from .gui_utils import process_stdout_stderr, set_dark_style, set_default_font, generate_fields, main_thread_update_function, create_menu_bar
|
20
|
+
from .gui_utils import measure_variables, measure_crop_wrapper, clear_canvas, check_measure_gui_settings, read_settings_from_csv, update_settings_from_csv, style_text_boxes
|
20
21
|
|
21
22
|
thread_control = {"run_thread": None, "stop_requested": False}
|
22
23
|
|
24
|
+
def toggle_test_mode():
|
25
|
+
global vars_dict
|
26
|
+
current_state = vars_dict['test_mode'][2].get()
|
27
|
+
new_state = not current_state
|
28
|
+
vars_dict['test_mode'][2].set(new_state)
|
29
|
+
if new_state:
|
30
|
+
test_mode_button.config(bg="blue")
|
31
|
+
else:
|
32
|
+
test_mode_button.config(bg="gray")
|
33
|
+
|
34
|
+
def toggle_advanced_settings():
|
35
|
+
global vars_dict
|
36
|
+
|
37
|
+
timelapse_settings = ['timelapse', 'timelapse_objects']
|
38
|
+
misc_settings = ['representative_images', 'plot', 'plot_filtration', 'include_uninfected', 'dialate_pngs', 'dialate_png_ratios']
|
39
|
+
opperational_settings = ['max_workers','experiment','cells','cell_loc','pathogens','pathogen_loc','treatments','treatment_loc','channel_of_interest','compartments','measurement','nr_imgs', 'um_per_pixel']
|
40
|
+
|
41
|
+
advanced_settings = timelapse_settings+misc_settings+opperational_settings
|
42
|
+
|
43
|
+
# Toggle visibility of advanced settings
|
44
|
+
for setting in advanced_settings:
|
45
|
+
label, widget, var = vars_dict[setting]
|
46
|
+
if advanced_var.get() is False:
|
47
|
+
label.grid_remove() # Hide the label
|
48
|
+
widget.grid_remove() # Hide the widget
|
49
|
+
else:
|
50
|
+
label.grid() # Show the label
|
51
|
+
widget.grid() # Show the widget
|
52
|
+
|
23
53
|
@log_function_call
|
24
54
|
def run_measure_gui(q, fig_queue, stop_requested):
|
25
55
|
global vars_dict
|
@@ -27,9 +57,6 @@ def run_measure_gui(q, fig_queue, stop_requested):
|
|
27
57
|
try:
|
28
58
|
print('hello')
|
29
59
|
settings = check_measure_gui_settings(vars_dict)
|
30
|
-
#for key in settings:
|
31
|
-
# value = settings[key]
|
32
|
-
# print(key, value, type(value))
|
33
60
|
measure_crop_wrapper(settings=settings, q=q, fig_queue=fig_queue)
|
34
61
|
except Exception as e:
|
35
62
|
q.put(f"Error during processing: {e}")
|
@@ -71,28 +98,17 @@ def import_settings(scrollable_frame):
|
|
71
98
|
vars_dict = generate_fields(new_settings, scrollable_frame)
|
72
99
|
|
73
100
|
@log_function_call
|
74
|
-
def initiate_measure_root(width, height):
|
75
|
-
global
|
101
|
+
def initiate_measure_root(parent_frame, width, height):
|
102
|
+
global vars_dict, q, canvas, fig_queue, canvas_widget, thread_control, variables, advanced_var, scrollable_frame
|
76
103
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
elif theme in ['breeze']:
|
86
|
-
root = ThemedTk(theme="breeze")
|
87
|
-
style = ttk.Style(root)
|
88
|
-
set_dark_style(style)
|
89
|
-
|
90
|
-
set_default_font(root, font_name="Arial", size=10)
|
91
|
-
#root.state('zoomed') # For Windows to maximize the window
|
92
|
-
root.attributes('-fullscreen', True)
|
93
|
-
root.geometry(f"{width}x{height}")
|
94
|
-
root.configure(bg='#333333')
|
95
|
-
root.title("SpaCer: generate masks")
|
104
|
+
style = ttk.Style(parent_frame)
|
105
|
+
set_dark_style(style)
|
106
|
+
style_text_boxes(style)
|
107
|
+
set_default_font(parent_frame, font_name="Open Sans", size=8)
|
108
|
+
|
109
|
+
parent_frame.configure(bg='black')
|
110
|
+
parent_frame.grid_rowconfigure(0, weight=1)
|
111
|
+
parent_frame.grid_columnconfigure(0, weight=1)
|
96
112
|
fig_queue = Queue()
|
97
113
|
|
98
114
|
def _process_fig_queue():
|
@@ -101,27 +117,22 @@ def initiate_measure_root(width, height):
|
|
101
117
|
while not fig_queue.empty():
|
102
118
|
clear_canvas(canvas)
|
103
119
|
fig = fig_queue.get_nowait()
|
104
|
-
#set_fig_text_properties(fig, font_size=8)
|
105
120
|
for ax in fig.get_axes():
|
106
121
|
ax.set_xticks([]) # Remove x-axis ticks
|
107
122
|
ax.set_yticks([]) # Remove y-axis ticks
|
108
123
|
ax.xaxis.set_visible(False) # Hide the x-axis
|
109
124
|
ax.yaxis.set_visible(False) # Hide the y-axis
|
110
|
-
#ax.title.set_fontsize(14)
|
111
|
-
#disable_interactivity(fig)
|
112
125
|
fig.tight_layout()
|
113
|
-
fig.set_facecolor('
|
126
|
+
fig.set_facecolor('black')
|
114
127
|
canvas.figure = fig
|
115
128
|
fig_width, fig_height = canvas_widget.winfo_width(), canvas_widget.winfo_height()
|
116
129
|
fig.set_size_inches(fig_width / fig.dpi, fig_height / fig.dpi, forward=True)
|
117
|
-
canvas.draw_idle()
|
130
|
+
canvas.draw_idle()
|
118
131
|
except Exception as e:
|
119
132
|
traceback.print_exc()
|
120
|
-
#pass
|
121
133
|
finally:
|
122
134
|
canvas_widget.after(100, _process_fig_queue)
|
123
|
-
|
124
|
-
# Process queue for console output
|
135
|
+
|
125
136
|
def _process_console_queue():
|
126
137
|
while not q.empty():
|
127
138
|
message = q.get_nowait()
|
@@ -129,71 +140,83 @@ def initiate_measure_root(width, height):
|
|
129
140
|
console_output.see(tk.END)
|
130
141
|
console_output.after(100, _process_console_queue)
|
131
142
|
|
132
|
-
|
133
|
-
vertical_container
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
143
|
+
vertical_container = tk.PanedWindow(parent_frame, orient=tk.HORIZONTAL)
|
144
|
+
vertical_container.grid(row=0, column=0, sticky=tk.NSEW)
|
145
|
+
parent_frame.grid_rowconfigure(0, weight=1)
|
146
|
+
parent_frame.grid_columnconfigure(0, weight=1)
|
147
|
+
|
148
|
+
# Settings Section
|
149
|
+
settings_frame = tk.Frame(vertical_container, bg='black')
|
150
|
+
vertical_container.add(settings_frame, stretch="always")
|
151
|
+
settings_label = ttk.Label(settings_frame, text="Settings", background="black", foreground="white")
|
152
|
+
settings_label.grid(row=0, column=0, pady=10, padx=10)
|
153
|
+
scrollable_frame = ScrollableFrame(settings_frame, width=500)
|
154
|
+
scrollable_frame.grid(row=1, column=0, sticky="nsew")
|
155
|
+
settings_frame.grid_rowconfigure(1, weight=1)
|
156
|
+
settings_frame.grid_columnconfigure(0, weight=1)
|
157
|
+
|
158
|
+
# Create advanced settings checkbox
|
159
|
+
advanced_var = tk.BooleanVar(value=False)
|
160
|
+
advanced_Toggle = ToggleSwitch(scrollable_frame.scrollable_frame, text="Advanced Settings", variable=advanced_var, command=toggle_advanced_settings)
|
161
|
+
advanced_Toggle.grid(row=48, column=0, pady=10, padx=10)
|
141
162
|
variables = measure_variables()
|
142
163
|
vars_dict = generate_fields(variables, scrollable_frame)
|
164
|
+
toggle_advanced_settings()
|
165
|
+
vars_dict['Test mode'] = (None, None, tk.BooleanVar(value=False))
|
143
166
|
|
144
|
-
#
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
167
|
+
# Button section
|
168
|
+
test_mode_button = CustomButton(scrollable_frame.scrollable_frame, text="Test Mode", command=toggle_test_mode)
|
169
|
+
test_mode_button.grid(row=47, column=1, pady=10, padx=10)
|
170
|
+
import_btn = CustomButton(scrollable_frame.scrollable_frame, text="Import Settings", command=lambda: import_settings(scrollable_frame))
|
171
|
+
import_btn.grid(row=47, column=0, pady=20, padx=20)
|
172
|
+
run_button = CustomButton(scrollable_frame.scrollable_frame, text="Run", command=lambda: start_process(q, fig_queue))
|
173
|
+
run_button.grid(row=45, column=0, pady=20, padx=20)
|
174
|
+
abort_button = CustomButton(scrollable_frame.scrollable_frame, text="Abort", command=initiate_abort)
|
175
|
+
abort_button.grid(row=45, column=1, pady=20, padx=20)
|
176
|
+
progress_label = ttk.Label(scrollable_frame.scrollable_frame, text="Processing: 0%", background="black", foreground="white") # Create progress field
|
177
|
+
progress_label.grid(row=50, column=0, columnspan=2, sticky="ew", pady=(5, 0), padx=10)
|
178
|
+
|
179
|
+
# Plot Canvas Section
|
180
|
+
plot_frame = tk.PanedWindow(vertical_container, orient=tk.VERTICAL)
|
181
|
+
vertical_container.add(plot_frame, stretch="always")
|
182
|
+
figure = Figure(figsize=(30, 4), dpi=100, facecolor='black')
|
150
183
|
plot = figure.add_subplot(111)
|
151
|
-
plot.plot([], [])
|
184
|
+
plot.plot([], [])
|
152
185
|
plot.axis('off')
|
153
|
-
|
154
|
-
|
155
|
-
canvas = FigureCanvasTkAgg(figure, master=horizontal_container)
|
156
|
-
canvas.get_tk_widget().configure(cursor='arrow', background='#333333', highlightthickness=0)
|
157
|
-
#canvas.get_tk_widget().configure(cursor='arrow')
|
186
|
+
canvas = FigureCanvasTkAgg(figure, master=plot_frame)
|
187
|
+
canvas.get_tk_widget().configure(cursor='arrow', background='black', highlightthickness=0)
|
158
188
|
canvas_widget = canvas.get_tk_widget()
|
159
|
-
|
189
|
+
plot_frame.add(canvas_widget, stretch="always")
|
160
190
|
canvas.draw()
|
161
191
|
canvas.figure = figure
|
162
192
|
|
163
|
-
# Console
|
164
|
-
|
165
|
-
vertical_container.add(
|
193
|
+
# Console Section
|
194
|
+
console_frame = tk.Frame(vertical_container, bg='black')
|
195
|
+
vertical_container.add(console_frame, stretch="always")
|
196
|
+
console_label = ttk.Label(console_frame, text="Console", background="black", foreground="white")
|
197
|
+
console_label.grid(row=0, column=0, pady=10, padx=10)
|
198
|
+
console_output = scrolledtext.ScrolledText(console_frame, height=10, bg='black', fg='white', insertbackground='white')
|
199
|
+
console_output.grid(row=1, column=0, sticky="nsew")
|
200
|
+
console_frame.grid_rowconfigure(1, weight=1)
|
201
|
+
console_frame.grid_columnconfigure(0, weight=1)
|
166
202
|
|
167
|
-
# Queue and redirection setup for updating console output safely
|
168
203
|
q = Queue()
|
169
204
|
sys.stdout = StdoutRedirector(console_output)
|
170
205
|
sys.stderr = StdoutRedirector(console_output)
|
171
206
|
|
172
|
-
# This is your GUI setup where you create the Run button
|
173
|
-
run_button = ttk.Button(scrollable_frame.scrollable_frame, text="Run",command=lambda: start_process(q, fig_queue))
|
174
|
-
run_button.grid(row=40, column=0, pady=10)
|
175
|
-
|
176
|
-
abort_button = ttk.Button(scrollable_frame.scrollable_frame, text="Abort", command=initiate_abort)
|
177
|
-
abort_button.grid(row=40, column=1, pady=10)
|
178
|
-
|
179
|
-
progress_label = ttk.Label(scrollable_frame.scrollable_frame, text="Progress: ", background="#333333", foreground="white")
|
180
|
-
progress_label.grid(row=41, column=0, columnspan=2, sticky="ew", pady=(5, 0))
|
181
|
-
|
182
|
-
# Create the Import Settings button
|
183
|
-
import_btn = tk.Button(root, text="Import Settings", command=lambda: import_settings(scrollable_frame))
|
184
|
-
import_btn.pack(pady=20)
|
185
|
-
|
186
207
|
_process_console_queue()
|
187
208
|
_process_fig_queue()
|
188
|
-
create_dark_mode(root, style, console_output)
|
189
209
|
|
190
|
-
|
210
|
+
parent_frame.after(100, lambda: main_thread_update_function(parent_frame, q, fig_queue, canvas_widget, progress_label))
|
191
211
|
|
192
|
-
return
|
212
|
+
return parent_frame, vars_dict
|
193
213
|
|
194
214
|
def gui_measure():
|
195
|
-
|
196
|
-
root
|
215
|
+
root = tk.Tk()
|
216
|
+
root.geometry("1000x800")
|
217
|
+
root.title("SpaCer: generate masks")
|
218
|
+
initiate_measure_root(root, 1000, 800)
|
219
|
+
create_menu_bar(root)
|
197
220
|
root.mainloop()
|
198
221
|
|
199
222
|
if __name__ == "__main__":
|