spacr 0.0.18__py3-none-any.whl → 0.0.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.
- spacr/alpha.py +291 -14
- spacr/annotate_app.py +2 -2
- spacr/core.py +1377 -296
- spacr/foldseek.py +793 -0
- spacr/get_alfafold_structures.py +72 -0
- spacr/graph_learning.py +259 -65
- spacr/graph_learning_lap.py +73 -71
- spacr/gui_classify_app.py +5 -21
- spacr/gui_mask_app.py +36 -30
- spacr/gui_measure_app.py +10 -24
- spacr/gui_utils.py +82 -54
- spacr/io.py +505 -205
- spacr/measure.py +160 -80
- spacr/old_code.py +155 -1
- spacr/plot.py +243 -99
- spacr/sim.py +666 -119
- spacr/timelapse.py +343 -52
- spacr/train.py +18 -10
- spacr/utils.py +252 -151
- {spacr-0.0.18.dist-info → spacr-0.0.21.dist-info}/METADATA +32 -27
- spacr-0.0.21.dist-info/RECORD +33 -0
- {spacr-0.0.18.dist-info → spacr-0.0.21.dist-info}/WHEEL +1 -1
- spacr/gui_temp.py +0 -212
- spacr/test_annotate_app.py +0 -58
- spacr/test_plot.py +0 -43
- spacr/test_train.py +0 -39
- spacr/test_utils.py +0 -33
- spacr-0.0.18.dist-info/RECORD +0 -36
- {spacr-0.0.18.dist-info → spacr-0.0.21.dist-info}/LICENSE +0 -0
- {spacr-0.0.18.dist-info → spacr-0.0.21.dist-info}/entry_points.txt +0 -0
- {spacr-0.0.18.dist-info → spacr-0.0.21.dist-info}/top_level.txt +0 -0
spacr/gui_mask_app.py
CHANGED
@@ -1,4 +1,4 @@
|
|
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
|
@@ -16,11 +16,19 @@ 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 mask_variables, check_mask_gui_settings,
|
19
|
+
from .gui_utils import ScrollableFrame, StdoutRedirector, clear_canvas, main_thread_update_function, create_dark_mode, 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#, toggle_advanced_settings
|
21
21
|
|
22
22
|
thread_control = {"run_thread": None, "stop_requested": False}
|
23
23
|
|
24
|
+
def toggle_advanced_settings():
|
25
|
+
advanced = advanced_var.get()
|
26
|
+
for widget in advanced_widgets:
|
27
|
+
if advanced:
|
28
|
+
widget.grid()
|
29
|
+
else:
|
30
|
+
widget.grid_remove()
|
31
|
+
|
24
32
|
@log_function_call
|
25
33
|
def initiate_abort():
|
26
34
|
global thread_control
|
@@ -39,7 +47,7 @@ def run_mask_gui(q, fig_queue, stop_requested):
|
|
39
47
|
process_stdout_stderr(q)
|
40
48
|
try:
|
41
49
|
settings = check_mask_gui_settings(vars_dict)
|
42
|
-
settings = add_mask_gui_defaults(settings)
|
50
|
+
#settings = add_mask_gui_defaults(settings)
|
43
51
|
#for key in settings:
|
44
52
|
# value = settings[key]
|
45
53
|
# print(key, value, type(value))
|
@@ -65,29 +73,15 @@ def import_settings(scrollable_frame):
|
|
65
73
|
global vars_dict
|
66
74
|
|
67
75
|
csv_file_path = filedialog.askopenfilename(filetypes=[("CSV files", "*.csv")])
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
with open(csv_file_path, newline='') as csvfile:
|
75
|
-
reader = csv.DictReader(csvfile)
|
76
|
-
for row in reader:
|
77
|
-
key = row['Key']
|
78
|
-
value = row['Value']
|
79
|
-
# Evaluate the value safely using safe_literal_eval
|
80
|
-
imported_variables[key] = safe_literal_eval(value)
|
81
|
-
|
82
|
-
# Track changed variables and apply the imported ones, printing changes as we go
|
83
|
-
for key, var in vars_dict.items():
|
84
|
-
if key in imported_variables and var.get() != imported_variables[key]:
|
85
|
-
print(f"Updating '{key}' from '{var.get()}' to '{imported_variables[key]}'")
|
86
|
-
var.set(imported_variables[key])
|
76
|
+
csv_settings = read_settings_from_csv(csv_file_path)
|
77
|
+
variables = mask_variables()
|
78
|
+
#variables = add_mask_gui_defaults(variables)
|
79
|
+
new_settings = update_settings_from_csv(variables, csv_settings)
|
80
|
+
vars_dict = generate_fields(new_settings, scrollable_frame)
|
87
81
|
|
88
82
|
@log_function_call
|
89
83
|
def initiate_mask_root(width, height):
|
90
|
-
global root, vars_dict, q, canvas, fig_queue, canvas_widget, thread_control
|
84
|
+
global root, vars_dict, q, canvas, fig_queue, canvas_widget, thread_control, advanced_widgets, advanced_var
|
91
85
|
|
92
86
|
theme = 'breeze'
|
93
87
|
|
@@ -101,7 +95,8 @@ def initiate_mask_root(width, height):
|
|
101
95
|
style = ttk.Style(root)
|
102
96
|
set_dark_style(style)
|
103
97
|
|
104
|
-
|
98
|
+
style_text_boxes(style)
|
99
|
+
set_default_font(root, font_name="Arial", size=8)
|
105
100
|
#root.state('zoomed') # For Windows to maximize the window
|
106
101
|
root.attributes('-fullscreen', True)
|
107
102
|
root.geometry(f"{width}x{height}")
|
@@ -153,6 +148,10 @@ def initiate_mask_root(width, height):
|
|
153
148
|
# Setup for user input fields (variables)
|
154
149
|
variables = mask_variables()
|
155
150
|
vars_dict = generate_fields(variables, scrollable_frame)
|
151
|
+
#del vars_dict['fps']
|
152
|
+
|
153
|
+
# Debugging: print vars_dict to ensure it is populated correctly
|
154
|
+
#print("vars_dict:", vars_dict)
|
156
155
|
|
157
156
|
# Horizontal container for Matplotlib figure and the vertical pane (for settings and console)
|
158
157
|
horizontal_container = tk.PanedWindow(vertical_container, orient=tk.VERTICAL) #HORIZONTAL
|
@@ -181,21 +180,27 @@ def initiate_mask_root(width, height):
|
|
181
180
|
q = Queue()
|
182
181
|
sys.stdout = StdoutRedirector(console_output)
|
183
182
|
sys.stderr = StdoutRedirector(console_output)
|
183
|
+
|
184
|
+
advanced_var = tk.BooleanVar()
|
185
|
+
advanced_checkbox = ttk.Checkbutton(scrollable_frame.scrollable_frame, text="Advanced Settings", variable=advanced_var, command=toggle_advanced_settings)
|
186
|
+
advanced_checkbox.grid(row=46, column=1, pady=10, padx=10)
|
184
187
|
|
185
188
|
# This is your GUI setup where you create the Run button
|
186
189
|
run_button = ttk.Button(scrollable_frame.scrollable_frame, text="Run",command=lambda: start_process(q, fig_queue))
|
187
|
-
run_button.grid(row=
|
190
|
+
run_button.grid(row=45, column=0, pady=10, padx=10)
|
188
191
|
|
189
192
|
abort_button = ttk.Button(scrollable_frame.scrollable_frame, text="Abort", command=initiate_abort)
|
190
|
-
abort_button.grid(row=
|
193
|
+
abort_button.grid(row=45, column=1, pady=10, padx=10)
|
191
194
|
|
192
195
|
progress_label = ttk.Label(scrollable_frame.scrollable_frame, text="Processing: 0%", background="#333333", foreground="white")
|
193
|
-
progress_label.grid(row=41, column=0, columnspan=2, sticky="ew", pady=(5, 0))
|
194
|
-
|
196
|
+
progress_label.grid(row=41, column=0, columnspan=2, sticky="ew", pady=(5, 0), padx=10)
|
197
|
+
|
195
198
|
# Create the Import Settings button
|
196
199
|
import_btn = tk.Button(root, text="Import Settings", command=lambda: import_settings(scrollable_frame))
|
197
|
-
import_btn.pack(pady=20)
|
200
|
+
import_btn.pack(pady=20, padx=10)
|
201
|
+
|
198
202
|
|
203
|
+
|
199
204
|
_process_console_queue()
|
200
205
|
_process_fig_queue()
|
201
206
|
create_dark_mode(root, style, console_output)
|
@@ -207,6 +212,7 @@ def initiate_mask_root(width, height):
|
|
207
212
|
def gui_mask():
|
208
213
|
global vars_dict, root
|
209
214
|
root, vars_dict = initiate_mask_root(1000, 1500)
|
215
|
+
|
210
216
|
root.mainloop()
|
211
217
|
|
212
218
|
if __name__ == "__main__":
|
spacr/gui_measure_app.py
CHANGED
@@ -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, StringVar, BooleanVar, IntVar, DoubleVar, Tk
|
11
11
|
|
12
12
|
try:
|
13
13
|
ctypes.windll.shcore.SetProcessDpiAwareness(True)
|
@@ -16,7 +16,7 @@ except AttributeError:
|
|
16
16
|
|
17
17
|
from .logger import log_function_call
|
18
18
|
from .gui_utils import ScrollableFrame, StdoutRedirector, process_stdout_stderr, set_dark_style, set_default_font, generate_fields, create_dark_mode, main_thread_update_function
|
19
|
-
from .gui_utils import measure_variables, measure_crop_wrapper, clear_canvas, safe_literal_eval, check_measure_gui_settings,
|
19
|
+
from .gui_utils import measure_variables, measure_crop_wrapper, clear_canvas, safe_literal_eval, check_measure_gui_settings, read_settings_from_csv, update_settings_from_csv
|
20
20
|
|
21
21
|
thread_control = {"run_thread": None, "stop_requested": False}
|
22
22
|
|
@@ -25,8 +25,8 @@ def run_measure_gui(q, fig_queue, stop_requested):
|
|
25
25
|
global vars_dict
|
26
26
|
process_stdout_stderr(q)
|
27
27
|
try:
|
28
|
+
print('hello')
|
28
29
|
settings = check_measure_gui_settings(vars_dict)
|
29
|
-
settings = add_measure_gui_defaults(settings)
|
30
30
|
#for key in settings:
|
31
31
|
# value = settings[key]
|
32
32
|
# print(key, value, type(value))
|
@@ -60,29 +60,15 @@ def initiate_abort():
|
|
60
60
|
thread_control["run_thread"].terminate()
|
61
61
|
thread_control["run_thread"] = None
|
62
62
|
|
63
|
+
@log_function_call
|
63
64
|
def import_settings(scrollable_frame):
|
64
|
-
global vars_dict
|
65
|
+
global vars_dict
|
65
66
|
|
66
67
|
csv_file_path = filedialog.askopenfilename(filetypes=[("CSV files", "*.csv")])
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
imported_variables = {}
|
72
|
-
|
73
|
-
with open(csv_file_path, newline='') as csvfile:
|
74
|
-
reader = csv.DictReader(csvfile)
|
75
|
-
for row in reader:
|
76
|
-
key = row['Key']
|
77
|
-
value = row['Value']
|
78
|
-
# Evaluate the value safely using safe_literal_eval
|
79
|
-
imported_variables[key] = safe_literal_eval(value)
|
80
|
-
|
81
|
-
# Track changed variables and apply the imported ones, printing changes as we go
|
82
|
-
for key, var in vars_dict.items():
|
83
|
-
if key in imported_variables and var.get() != imported_variables[key]:
|
84
|
-
print(f"Updating '{key}' from '{var.get()}' to '{imported_variables[key]}'")
|
85
|
-
var.set(imported_variables[key])
|
68
|
+
csv_settings = read_settings_from_csv(csv_file_path)
|
69
|
+
variables = measure_variables()
|
70
|
+
new_settings = update_settings_from_csv(variables, csv_settings)
|
71
|
+
vars_dict = generate_fields(new_settings, scrollable_frame)
|
86
72
|
|
87
73
|
@log_function_call
|
88
74
|
def initiate_measure_root(width, height):
|
@@ -201,7 +187,7 @@ def initiate_measure_root(width, height):
|
|
201
187
|
_process_fig_queue()
|
202
188
|
create_dark_mode(root, style, console_output)
|
203
189
|
|
204
|
-
root.after(100, lambda: main_thread_update_function(root, q, fig_queue, canvas_widget, progress_label))
|
190
|
+
#root.after(100, lambda: main_thread_update_function(root, q, fig_queue, canvas_widget, progress_label))
|
205
191
|
|
206
192
|
return root, vars_dict
|
207
193
|
|
spacr/gui_utils.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
import spacr, inspect, traceback, io, sys, ast, ctypes, matplotlib, re
|
2
|
-
matplotlib.use('Agg')
|
1
|
+
import spacr, inspect, traceback, io, sys, ast, ctypes, matplotlib, re, csv
|
3
2
|
import matplotlib.pyplot as plt
|
3
|
+
matplotlib.use('Agg')
|
4
4
|
import numpy as np
|
5
5
|
import tkinter as tk
|
6
6
|
from tkinter import ttk, messagebox
|
@@ -14,6 +14,41 @@ except AttributeError:
|
|
14
14
|
|
15
15
|
from .logger import log_function_call
|
16
16
|
|
17
|
+
def set_default_font(root, font_name="Helvetica", size=12):
|
18
|
+
default_font = (font_name, size)
|
19
|
+
root.option_add("*Font", default_font)
|
20
|
+
root.option_add("*TButton.Font", default_font)
|
21
|
+
root.option_add("*TLabel.Font", default_font)
|
22
|
+
root.option_add("*TEntry.Font", default_font)
|
23
|
+
|
24
|
+
def style_text_boxes(style):
|
25
|
+
style.configure('TEntry', padding='5 5 5 5', borderwidth=1, relief='solid', background='#333333', foreground='#ffffff')
|
26
|
+
style.configure('TButton', padding='10 10 10 10', borderwidth=1, relief='solid', background='#444444', foreground='#ffffff', font=('Helvetica', 12, 'bold'))
|
27
|
+
style.map('TButton',
|
28
|
+
background=[('active', '#555555'), ('disabled', '#222222')],
|
29
|
+
foreground=[('active', '#ffffff'), ('disabled', '#888888')])
|
30
|
+
style.configure('TLabel', padding='5 5 5 5', borderwidth=1, relief='flat', background='#2e2e2e', foreground='#ffffff')
|
31
|
+
|
32
|
+
def read_settings_from_csv(csv_file_path):
|
33
|
+
settings = {}
|
34
|
+
with open(csv_file_path, newline='') as csvfile:
|
35
|
+
reader = csv.DictReader(csvfile)
|
36
|
+
for row in reader:
|
37
|
+
key = row['Key']
|
38
|
+
value = row['Value']
|
39
|
+
settings[key] = value
|
40
|
+
return settings
|
41
|
+
|
42
|
+
def update_settings_from_csv(variables, csv_settings):
|
43
|
+
new_settings = variables.copy() # Start with a copy of the original settings
|
44
|
+
for key, value in csv_settings.items():
|
45
|
+
if key in new_settings:
|
46
|
+
# Get the variable type and options from the original settings
|
47
|
+
var_type, options, _ = new_settings[key]
|
48
|
+
# Update the default value with the CSV value, keeping the type and options unchanged
|
49
|
+
new_settings[key] = (var_type, options, value)
|
50
|
+
return new_settings
|
51
|
+
|
17
52
|
def safe_literal_eval(value):
|
18
53
|
try:
|
19
54
|
# First, try to evaluate as a literal
|
@@ -31,7 +66,7 @@ def disable_interactivity(fig):
|
|
31
66
|
for handler_id in list(handlers.keys()):
|
32
67
|
fig.canvas.mpl_disconnect(handler_id)
|
33
68
|
|
34
|
-
def
|
69
|
+
def set_default_font_v1(app, font_name="Arial Bold", size=10):
|
35
70
|
default_font = nametofont("TkDefaultFont")
|
36
71
|
text_font = nametofont("TkTextFont")
|
37
72
|
fixed_font = nametofont("TkFixedFont")
|
@@ -103,62 +138,52 @@ def check_mask_gui_settings(vars_dict):
|
|
103
138
|
def check_measure_gui_settings(vars_dict):
|
104
139
|
settings = {}
|
105
140
|
for key, var in vars_dict.items():
|
106
|
-
value = var.get() #
|
141
|
+
value = var.get() # Retrieves the string representation for entries or the actual value for checkboxes and combos.
|
107
142
|
|
108
143
|
try:
|
109
|
-
if key
|
110
|
-
# Converts string representation to a list of integers
|
144
|
+
if key in ['channels', 'png_dims']:
|
111
145
|
settings[key] = [int(chan) for chan in ast.literal_eval(value)] if value else []
|
112
146
|
|
113
147
|
elif key in ['cell_loc', 'pathogen_loc', 'treatment_loc']:
|
114
|
-
|
115
|
-
|
148
|
+
# Convert to a list of lists of strings, ensuring all structures are lists.
|
149
|
+
settings[key] = [list(map(str, sublist)) for sublist in ast.literal_eval(value)] if value else []
|
150
|
+
|
116
151
|
elif key == 'dialate_png_ratios':
|
117
|
-
settings[key] = [float(num) for num in
|
152
|
+
settings[key] = [float(num) for num in ast.literal_eval(value)] if value else []
|
118
153
|
|
119
154
|
elif key == 'normalize':
|
120
|
-
|
121
|
-
settings[key] = [int(num) for num in ast.literal_eval(value)] if value else None
|
155
|
+
settings[key] = [int(num) for num in ast.literal_eval(value)] if value else []
|
122
156
|
|
123
|
-
|
124
|
-
|
157
|
+
# Directly assign string values for these specific keys
|
158
|
+
elif key in ['normalize_by', 'experiment', 'measurement', 'input_folder']:
|
125
159
|
settings[key] = value
|
126
160
|
|
127
161
|
elif key == 'png_size':
|
128
|
-
|
129
|
-
temp_val = ast.literal_eval(value) if value else []
|
130
|
-
settings[key] = [list(map(int, dim)) for dim in temp_val] if temp_val else None
|
131
|
-
|
132
|
-
# Handling for other keys as in your original function...
|
162
|
+
settings[key] = [list(map(int, dim)) for dim in ast.literal_eval(value)] if value else []
|
133
163
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
elif key == 'timelapse_objects':
|
139
|
-
# Ensure it's a list of strings
|
140
|
-
settings[key] = eval(value) if value else []
|
141
|
-
|
142
|
-
# Handling for keys that should be treated as strings directly
|
143
|
-
elif key in ['normalize_by', 'experiment', 'measurement', 'input_folder']:
|
144
|
-
settings[key] = str(value) if value else None
|
164
|
+
# Ensure these are lists of strings, converting from tuples if necessary
|
165
|
+
elif key in ['timelapse_objects', 'crop_mode', 'cells', 'pathogens', 'treatments']:
|
166
|
+
eval_value = ast.literal_eval(value) if value else []
|
167
|
+
settings[key] = list(map(str, eval_value)) if isinstance(eval_value, (list, tuple)) else [str(eval_value)]
|
145
168
|
|
146
|
-
# Handling for single values
|
169
|
+
# Handling for single non-string values (int, float, bool)
|
147
170
|
elif key in ['cell_mask_dim', 'cell_min_size', 'nucleus_mask_dim', 'nucleus_min_size', 'pathogen_mask_dim', 'pathogen_min_size', 'cytoplasm_min_size', 'max_workers', 'channel_of_interest', 'nr_imgs']:
|
148
171
|
settings[key] = int(value) if value else None
|
149
172
|
|
150
173
|
elif key == 'um_per_pixel':
|
151
174
|
settings[key] = float(value) if value else None
|
152
175
|
|
153
|
-
#
|
176
|
+
# Handling boolean values based on checkboxes
|
154
177
|
elif key in ['save_png', 'use_bounding_box', 'save_measurements', 'plot', 'plot_filtration', 'include_uninfected', 'dialate_pngs', 'timelapse', 'representative_images']:
|
155
|
-
settings[key] =
|
178
|
+
settings[key] = var.get()
|
156
179
|
|
157
180
|
except SyntaxError as e:
|
158
|
-
|
181
|
+
print(f"Syntax error processing {key}: {str(e)}")
|
182
|
+
#messagebox.showerror("Error", f"Syntax error processing {key}: {str(e)}")
|
159
183
|
return None
|
160
184
|
except Exception as e:
|
161
|
-
|
185
|
+
print(f"Error processing {key}: {str(e)}")
|
186
|
+
#messagebox.showerror("Error", f"Error processing {key}: {str(e)}")
|
162
187
|
return None
|
163
188
|
|
164
189
|
return settings
|
@@ -268,6 +293,10 @@ def sim_variables():
|
|
268
293
|
}
|
269
294
|
return variables
|
270
295
|
|
296
|
+
def add_measure_gui_defaults(settings):
|
297
|
+
settings['compartments'] = ['pathogen', 'cytoplasm']
|
298
|
+
return settings
|
299
|
+
|
271
300
|
def measure_variables():
|
272
301
|
variables = {
|
273
302
|
'input_folder':('entry', None, '/mnt/data/CellVoyager/40x/einar/mitotrackerHeLaToxoDsRed_20240224_123156/test_gui/merged'),
|
@@ -304,6 +333,7 @@ def measure_variables():
|
|
304
333
|
'treatments': ('entry', None, '["cm","lovastatin_20uM"]'),
|
305
334
|
'treatment_loc': ('entry', None, '[["c1","c2"], ["c3","c4"]]'),
|
306
335
|
'channel_of_interest':('entry', None, 3),
|
336
|
+
'compartments':('entry', None, '["pathogen","cytoplasm"]'),
|
307
337
|
'measurement':('entry', None, 'mean_intensity'),
|
308
338
|
'nr_imgs':('entry', None, 32),
|
309
339
|
'um_per_pixel':('entry', None, 0.1)
|
@@ -352,7 +382,7 @@ def classify_variables():
|
|
352
382
|
return variables
|
353
383
|
|
354
384
|
|
355
|
-
|
385
|
+
#@log_function_call
|
356
386
|
def create_input_field(frame, label_text, row, var_type='entry', options=None, default_value=None):
|
357
387
|
label = ttk.Label(frame, text=label_text, style='TLabel') # Assuming you have a dark mode style for labels too
|
358
388
|
label.grid(column=0, row=row, sticky=tk.W, padx=5, pady=5)
|
@@ -376,10 +406,6 @@ def create_input_field(frame, label_text, row, var_type='entry', options=None, d
|
|
376
406
|
var = None # Placeholder in case of an undefined var_type
|
377
407
|
|
378
408
|
return var
|
379
|
-
|
380
|
-
def add_measure_gui_defaults(settings):
|
381
|
-
settings['compartments'] = ['pathogen', 'cytoplasm']
|
382
|
-
return settings
|
383
409
|
|
384
410
|
def mask_variables():
|
385
411
|
variables = {
|
@@ -401,10 +427,10 @@ def mask_variables():
|
|
401
427
|
'pathogen_background': ('entry', None, 100),
|
402
428
|
'pathogen_Signal_to_noise': ('entry', None, 3),
|
403
429
|
'pathogen_CP_prob': ('entry', None, 0),
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
430
|
+
'preprocess': ('check', None, True),
|
431
|
+
'masks': ('check', None, True),
|
432
|
+
'examples_to_plot': ('entry', None, 1),
|
433
|
+
'randomize': ('check', None, True),
|
408
434
|
'batch_size': ('entry', None, 50),
|
409
435
|
'timelapse': ('check', None, False),
|
410
436
|
'timelapse_displacement': ('entry', None, None),
|
@@ -413,14 +439,14 @@ def mask_variables():
|
|
413
439
|
'timelapse_remove_transient': ('check', None, True),
|
414
440
|
'timelapse_mode': ('combo', ['trackpy', 'btrack'], 'trackpy'),
|
415
441
|
'timelapse_objects': ('combo', ['cell','nucleus','pathogen','cytoplasm', None], None),
|
416
|
-
|
417
|
-
|
442
|
+
'fps': ('entry', None, 2),
|
443
|
+
'remove_background': ('check', None, True),
|
418
444
|
'lower_quantile': ('entry', None, 0.01),
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
445
|
+
'merge': ('check', None, False),
|
446
|
+
'normalize_plots': ('check', None, True),
|
447
|
+
'all_to_mip': ('check', None, False),
|
448
|
+
'pick_slice': ('check', None, False),
|
449
|
+
'skip_mode': ('entry', None, None),
|
424
450
|
'save': ('check', None, True),
|
425
451
|
'plot': ('check', None, True),
|
426
452
|
'workers': ('entry', None, 30),
|
@@ -488,7 +514,7 @@ def set_dark_style(style):
|
|
488
514
|
style.configure('TEntry', background='#333333', foreground='white')
|
489
515
|
style.configure('TCheckbutton', background='#333333', foreground='white')
|
490
516
|
|
491
|
-
|
517
|
+
#@log_function_call
|
492
518
|
def main_thread_update_function(root, q, fig_queue, canvas_widget, progress_label):
|
493
519
|
try:
|
494
520
|
ansi_escape_pattern = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
|
@@ -497,6 +523,8 @@ def main_thread_update_function(root, q, fig_queue, canvas_widget, progress_labe
|
|
497
523
|
clean_message = ansi_escape_pattern.sub('', message)
|
498
524
|
if clean_message.startswith("Progress"):
|
499
525
|
progress_label.config(text=clean_message)
|
526
|
+
if clean_message.startswith("\rProgress"):
|
527
|
+
progress_label.config(text=clean_message)
|
500
528
|
elif clean_message.startswith("Successfully"):
|
501
529
|
progress_label.config(text=clean_message)
|
502
530
|
elif clean_message.startswith("Processing"):
|
@@ -543,7 +571,6 @@ def clear_canvas(canvas):
|
|
543
571
|
# Redraw the now empty canvas without changing its size
|
544
572
|
canvas.draw_idle()
|
545
573
|
|
546
|
-
@log_function_call
|
547
574
|
def measure_crop_wrapper(settings, q, fig_queue):
|
548
575
|
"""
|
549
576
|
Wraps the measure_crop function to integrate with GUI processes.
|
@@ -567,7 +594,8 @@ def measure_crop_wrapper(settings, q, fig_queue):
|
|
567
594
|
plt.show = my_show
|
568
595
|
|
569
596
|
try:
|
570
|
-
|
597
|
+
print('start')
|
598
|
+
spacr.measure.measure_crop(settings=settings)
|
571
599
|
except Exception as e:
|
572
600
|
errorMessage = f"Error during processing: {e}"
|
573
601
|
q.put(errorMessage) # Send the error message to the GUI via the queue
|
@@ -599,7 +627,7 @@ def preprocess_generate_masks_wrapper(settings, q, fig_queue):
|
|
599
627
|
plt.show = my_show
|
600
628
|
|
601
629
|
try:
|
602
|
-
spacr.core.preprocess_generate_masks(settings['src'], settings=settings
|
630
|
+
spacr.core.preprocess_generate_masks(settings['src'], settings=settings)
|
603
631
|
except Exception as e:
|
604
632
|
errorMessage = f"Error during processing: {e}"
|
605
633
|
q.put(errorMessage) # Send the error message to the GUI via the queue
|