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