spacr 0.1.12__py3-none-any.whl → 0.1.16__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/app_annotate.py +2 -3
- spacr/app_classify.py +16 -11
- spacr/app_make_masks.py +1 -2
- spacr/app_make_masks_v2.py +1 -3
- spacr/app_mask.py +25 -23
- spacr/app_measure.py +20 -15
- spacr/gui.py +6 -5
- spacr/gui_utils.py +101 -81
- {spacr-0.1.12.dist-info → spacr-0.1.16.dist-info}/METADATA +12 -26
- {spacr-0.1.12.dist-info → spacr-0.1.16.dist-info}/RECORD +14 -14
- spacr-0.1.16.dist-info/entry_points.txt +8 -0
- spacr-0.1.12.dist-info/entry_points.txt +0 -9
- {spacr-0.1.12.dist-info → spacr-0.1.16.dist-info}/LICENSE +0 -0
- {spacr-0.1.12.dist-info → spacr-0.1.16.dist-info}/WHEEL +0 -0
- {spacr-0.1.12.dist-info → spacr-0.1.16.dist-info}/top_level.txt +0 -0
spacr/app_annotate.py
CHANGED
@@ -13,7 +13,7 @@ from IPython.display import display, HTML
|
|
13
13
|
from tkinter import font as tkFont
|
14
14
|
from tkinter import TclError
|
15
15
|
|
16
|
-
from .gui_utils import ScrollableFrame, CustomButton, set_dark_style, set_default_font,
|
16
|
+
from .gui_utils import ScrollableFrame, CustomButton, set_dark_style, set_default_font, set_dark_style, create_menu_bar
|
17
17
|
|
18
18
|
class ImageApp:
|
19
19
|
def __init__(self, root, db_path, src, image_type=None, channels=None, grid_rows=None, grid_cols=None, image_size=(200, 200), annotation_column='annotate', normalize=False, percentiles=(1,99), measurement=None, threshold=None):
|
@@ -372,7 +372,6 @@ global_image_refs = []
|
|
372
372
|
def initiate_annotation_app_root(parent_frame):
|
373
373
|
style = ttk.Style(parent_frame)
|
374
374
|
set_dark_style(style)
|
375
|
-
style_text_boxes(style)
|
376
375
|
set_default_font(parent_frame, font_name="Arial", size=8)
|
377
376
|
|
378
377
|
parent_frame.configure(bg='black')
|
@@ -536,4 +535,4 @@ def gui_annotate():
|
|
536
535
|
root.mainloop()
|
537
536
|
|
538
537
|
if __name__ == "__main__":
|
539
|
-
gui_annotate()
|
538
|
+
gui_annotate()
|
spacr/app_classify.py
CHANGED
@@ -15,8 +15,9 @@ except AttributeError:
|
|
15
15
|
pass
|
16
16
|
|
17
17
|
from .logger import log_function_call
|
18
|
-
from .
|
19
|
-
from .gui_utils import
|
18
|
+
from .settings import set_default_train_test_model
|
19
|
+
from .gui_utils import ScrollableFrame, StdoutRedirector, CustomButton, set_dark_style, set_default_font, generate_fields, process_stdout_stderr, clear_canvas, main_thread_update_function, convert_settings_dict_for_gui
|
20
|
+
from .gui_utils import check_classify_gui_settings, train_test_model_wrapper, read_settings_from_csv, update_settings_from_csv, set_dark_style, create_menu_bar
|
20
21
|
|
21
22
|
thread_control = {"run_thread": None, "stop_requested": False}
|
22
23
|
|
@@ -64,7 +65,8 @@ def import_settings(scrollable_frame):
|
|
64
65
|
|
65
66
|
csv_file_path = filedialog.askopenfilename(filetypes=[("CSV files", "*.csv")])
|
66
67
|
csv_settings = read_settings_from_csv(csv_file_path)
|
67
|
-
|
68
|
+
settings = set_default_train_test_model({})
|
69
|
+
variables = convert_settings_dict_for_gui(settings)
|
68
70
|
new_settings = update_settings_from_csv(variables, csv_settings)
|
69
71
|
vars_dict = generate_fields(new_settings, scrollable_frame)
|
70
72
|
|
@@ -74,7 +76,6 @@ def initiate_classify_root(parent_frame):
|
|
74
76
|
|
75
77
|
style = ttk.Style(parent_frame)
|
76
78
|
set_dark_style(style)
|
77
|
-
style_text_boxes(style)
|
78
79
|
set_default_font(parent_frame, font_name="Helvetica", size=8)
|
79
80
|
|
80
81
|
parent_frame.configure(bg='black')
|
@@ -121,24 +122,28 @@ def initiate_classify_root(parent_frame):
|
|
121
122
|
vertical_container.add(settings_frame, stretch="always")
|
122
123
|
settings_label = ttk.Label(settings_frame, text="Settings", background="black", foreground="white")
|
123
124
|
settings_label.grid(row=0, column=0, pady=10, padx=10)
|
124
|
-
scrollable_frame = ScrollableFrame(settings_frame,
|
125
|
+
scrollable_frame = ScrollableFrame(settings_frame, bg='black')
|
125
126
|
scrollable_frame.grid(row=1, column=0, sticky="nsew")
|
126
127
|
settings_frame.grid_rowconfigure(1, weight=1)
|
127
128
|
settings_frame.grid_columnconfigure(0, weight=1)
|
128
129
|
|
129
130
|
# Setup for user input fields (variables)
|
130
|
-
|
131
|
+
settings = set_default_train_test_model({})
|
132
|
+
variables = convert_settings_dict_for_gui(settings)
|
131
133
|
vars_dict = generate_fields(variables, scrollable_frame)
|
132
134
|
|
133
135
|
# Button section
|
134
|
-
|
135
|
-
import_btn.grid(row=47, column=0, pady=20, padx=20)
|
136
|
+
btn_row = 1
|
136
137
|
run_button = CustomButton(scrollable_frame.scrollable_frame, text="Run", command=lambda: start_process(q, fig_queue), font=('Helvetica', 10))
|
137
|
-
run_button.grid(row=
|
138
|
+
run_button.grid(row=btn_row, column=0, pady=20, padx=20)
|
138
139
|
abort_button = CustomButton(scrollable_frame.scrollable_frame, text="Abort", command=initiate_abort, font=('Helvetica', 10))
|
139
|
-
abort_button.grid(row=
|
140
|
+
abort_button.grid(row=btn_row, column=1, pady=20, padx=20)
|
141
|
+
btn_row += 1
|
142
|
+
import_btn = CustomButton(scrollable_frame.scrollable_frame, text="Import", command=lambda: import_settings(scrollable_frame), font=('Helvetica', 10))
|
143
|
+
import_btn.grid(row=btn_row, column=0, pady=20, padx=20)
|
144
|
+
btn_row += 1
|
140
145
|
progress_label = ttk.Label(scrollable_frame.scrollable_frame, text="Processing: 0%", background="black", foreground="white") # Create progress field
|
141
|
-
progress_label.grid(row=
|
146
|
+
progress_label.grid(row=btn_row, column=0, columnspan=2, sticky="ew", pady=(5, 0), padx=10)
|
142
147
|
|
143
148
|
# Plot Canvas Section
|
144
149
|
plot_frame = tk.PanedWindow(vertical_container, orient=tk.VERTICAL)
|
spacr/app_make_masks.py
CHANGED
@@ -13,7 +13,7 @@ from ttkthemes import ThemedTk
|
|
13
13
|
|
14
14
|
from .logger import log_function_call
|
15
15
|
|
16
|
-
from .gui_utils import ScrollableFrame, CustomButton, set_dark_style, set_default_font,
|
16
|
+
from .gui_utils import ScrollableFrame, CustomButton, set_dark_style, set_default_font, set_dark_style, create_menu_bar
|
17
17
|
|
18
18
|
class modify_masks:
|
19
19
|
|
@@ -864,7 +864,6 @@ class modify_masks:
|
|
864
864
|
def initiate_mask_app_root(parent_frame):
|
865
865
|
style = ttk.Style(parent_frame)
|
866
866
|
set_dark_style(style)
|
867
|
-
style_text_boxes(style)
|
868
867
|
set_default_font(parent_frame, font_name="Arial", size=8)
|
869
868
|
|
870
869
|
container = tk.PanedWindow(parent_frame, orient=tk.HORIZONTAL)
|
spacr/app_make_masks_v2.py
CHANGED
@@ -13,7 +13,7 @@ from ttkthemes import ThemedTk
|
|
13
13
|
from pyqtgraph import GraphicsLayoutWidget, ViewBox, ImageItem, mkQApp
|
14
14
|
|
15
15
|
from .logger import log_function_call
|
16
|
-
from .gui_utils import ScrollableFrame, CustomButton, set_dark_style, set_default_font, create_dark_mode,
|
16
|
+
from .gui_utils import ScrollableFrame, CustomButton, set_dark_style, set_default_font, create_dark_mode, set_dark_style, create_menu_bar
|
17
17
|
|
18
18
|
class ModifyMasks:
|
19
19
|
def __init__(self, root, folder_path, scale_factor):
|
@@ -635,8 +635,6 @@ def initiate_mask_app_root(width, height):
|
|
635
635
|
root = ThemedTk(theme=theme)
|
636
636
|
style = ttk.Style(root)
|
637
637
|
set_dark_style(style)
|
638
|
-
|
639
|
-
style_text_boxes(style)
|
640
638
|
set_default_font(root, font_name="Arial", size=8)
|
641
639
|
root.geometry(f"{width}x{height}")
|
642
640
|
root.title("Mask App")
|
spacr/app_mask.py
CHANGED
@@ -16,9 +16,10 @@ except AttributeError:
|
|
16
16
|
pass
|
17
17
|
|
18
18
|
from .logger import log_function_call
|
19
|
+
from .settings import set_default_settings_preprocess_generate_masks
|
19
20
|
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,
|
21
|
-
from .gui_utils import
|
21
|
+
from .gui_utils import clear_canvas, main_thread_update_function, set_dark_style, generate_fields, process_stdout_stderr, set_default_font, set_dark_style, convert_settings_dict_for_gui
|
22
|
+
from .gui_utils import check_mask_gui_settings, preprocess_generate_masks_wrapper, read_settings_from_csv, update_settings_from_csv, create_menu_bar
|
22
23
|
|
23
24
|
thread_control = {"run_thread": None, "stop_requested": False}
|
24
25
|
|
@@ -37,10 +38,9 @@ def toggle_test_mode():
|
|
37
38
|
def toggle_advanced_settings():
|
38
39
|
global vars_dict
|
39
40
|
|
40
|
-
timelapse_settings = ['timelapse',
|
41
|
-
misc_settings = ['
|
42
|
-
opperational_settings = ['
|
43
|
-
|
41
|
+
timelapse_settings = ['timelapse','fps','timelapse_displacement','timelapse_memory','timelapse_frame_limits','timelapse_remove_transient','timelapse_mode','timelapse_objects']
|
42
|
+
misc_settings = ['all_to_mip','pick_slice','skip_mode','upscale','upscale_factor','adjust_cells','lower_percentile','filter','merge_pathogens','pathogen_model']
|
43
|
+
opperational_settings = ['examples_to_plot','normalize_plots','normalize','cmap','figuresize','plot','pathogen_FT','cell_FT','nucleus_FT','nucleus_CP_prob','nucleus_Signal_to_noise','nucleus_background','cell_CP_prob','cell_Signal_to_noise','cell_background','pathogen_CP_prob','pathogen_Signal_to_noise','pathogen_background','remove_background_pathogen','remove_background_nucleus','remove_background_cell','verbose','randomize','workers','metadata_type','custom_regex','test_images','batch_size','save','masks','preprocess']
|
44
44
|
advanced_settings = timelapse_settings+misc_settings+opperational_settings
|
45
45
|
|
46
46
|
# Toggle visibility of advanced settings
|
@@ -94,7 +94,8 @@ def import_settings(scrollable_frame):
|
|
94
94
|
|
95
95
|
csv_file_path = filedialog.askopenfilename(filetypes=[("CSV files", "*.csv")])
|
96
96
|
csv_settings = read_settings_from_csv(csv_file_path)
|
97
|
-
|
97
|
+
settings = set_default_settings_preprocess_generate_masks({})
|
98
|
+
variables = convert_settings_dict_for_gui(settings)
|
98
99
|
new_settings = update_settings_from_csv(variables, csv_settings)
|
99
100
|
vars_dict = generate_fields(new_settings, scrollable_frame)
|
100
101
|
|
@@ -104,7 +105,6 @@ def initiate_mask_root(parent_frame):
|
|
104
105
|
|
105
106
|
style = ttk.Style(parent_frame)
|
106
107
|
set_dark_style(style)
|
107
|
-
style_text_boxes(style)
|
108
108
|
set_default_font(parent_frame, font_name="Helvetica", size=8)
|
109
109
|
parent_frame.configure(bg='black')
|
110
110
|
parent_frame.grid_rowconfigure(0, weight=1)
|
@@ -151,7 +151,7 @@ def initiate_mask_root(parent_frame):
|
|
151
151
|
for widget in parent_frame.winfo_children():
|
152
152
|
widget.destroy()
|
153
153
|
|
154
|
-
vertical_container = tk.PanedWindow(parent_frame, orient=tk.HORIZONTAL)
|
154
|
+
vertical_container = tk.PanedWindow(parent_frame, orient=tk.HORIZONTAL, bg='black')
|
155
155
|
vertical_container.grid(row=0, column=0, sticky=tk.NSEW)
|
156
156
|
parent_frame.grid_rowconfigure(0, weight=1)
|
157
157
|
parent_frame.grid_columnconfigure(0, weight=1)
|
@@ -159,9 +159,9 @@ def initiate_mask_root(parent_frame):
|
|
159
159
|
# Settings Section
|
160
160
|
settings_frame = tk.Frame(vertical_container, bg='black')
|
161
161
|
vertical_container.add(settings_frame, stretch="always")
|
162
|
-
settings_label = ttk.Label(settings_frame, text="Settings", style="Custom.TLabel")
|
162
|
+
settings_label = ttk.Label(settings_frame, text="Settings", style="Custom.TLabel", background="black", foreground="white")
|
163
163
|
settings_label.grid(row=0, column=0, pady=10, padx=10)
|
164
|
-
scrollable_frame = ScrollableFrame(settings_frame,
|
164
|
+
scrollable_frame = ScrollableFrame(settings_frame, bg='black')
|
165
165
|
scrollable_frame.grid(row=1, column=0, sticky="nsew")
|
166
166
|
settings_frame.grid_rowconfigure(1, weight=1)
|
167
167
|
settings_frame.grid_columnconfigure(0, weight=1)
|
@@ -169,25 +169,27 @@ def initiate_mask_root(parent_frame):
|
|
169
169
|
# Create advanced settings checkbox
|
170
170
|
advanced_var = tk.BooleanVar(value=False)
|
171
171
|
advanced_Toggle = ToggleSwitch(scrollable_frame.scrollable_frame, text="Advanced Settings", variable=advanced_var, command=toggle_advanced_settings)
|
172
|
-
advanced_Toggle.grid(row=
|
173
|
-
|
172
|
+
advanced_Toggle.grid(row=4, column=0, pady=10, padx=10)
|
173
|
+
settings = set_default_settings_preprocess_generate_masks({})
|
174
|
+
variables = convert_settings_dict_for_gui(settings)
|
174
175
|
vars_dict = generate_fields(variables, scrollable_frame)
|
175
176
|
toggle_advanced_settings()
|
176
177
|
vars_dict['Test mode'] = (None, None, tk.BooleanVar(value=False))
|
177
|
-
|
178
|
-
# Button section
|
179
|
-
test_mode_button = CustomButton(scrollable_frame.scrollable_frame, text="Test Mode", command=toggle_test_mode, font=('Helvetica', 10))
|
180
|
-
#CustomButton(buttons_frame, text=app_name, command=lambda app_name=app_name: self.load_app(app_name, app_func), font=('Helvetica', 12))
|
181
178
|
|
182
|
-
|
183
|
-
|
184
|
-
import_btn.grid(row=47, column=0, pady=10, padx=10)
|
179
|
+
# Button section
|
180
|
+
btn_row = 1
|
185
181
|
run_button = CustomButton(scrollable_frame.scrollable_frame, text="Run", command=lambda: start_process(q, fig_queue))
|
186
|
-
run_button.grid(row=
|
182
|
+
run_button.grid(row=btn_row, column=0, pady=5, padx=5)
|
187
183
|
abort_button = CustomButton(scrollable_frame.scrollable_frame, text="Abort", command=initiate_abort, font=('Helvetica', 10))
|
188
|
-
abort_button.grid(row=
|
184
|
+
abort_button.grid(row=btn_row, column=1, pady=5, padx=5)
|
185
|
+
btn_row += 1
|
186
|
+
test_mode_button = CustomButton(scrollable_frame.scrollable_frame, text="Test", command=toggle_test_mode, font=('Helvetica', 10))
|
187
|
+
test_mode_button.grid(row=btn_row, column=0, pady=5, padx=5)
|
188
|
+
import_btn = CustomButton(scrollable_frame.scrollable_frame, text="Import", command=lambda: import_settings(scrollable_frame), font=('Helvetica', 10))
|
189
|
+
import_btn.grid(row=btn_row, column=1, pady=5, padx=5)
|
190
|
+
btn_row += 1
|
189
191
|
progress_label = ttk.Label(scrollable_frame.scrollable_frame, text="Processing: 0%", background="black", foreground="white")
|
190
|
-
progress_label.grid(row=
|
192
|
+
progress_label.grid(row=btn_row, column=0, columnspan=2, sticky="ew", pady=(5, 0), padx=10)
|
191
193
|
|
192
194
|
# Plot Canvas Section
|
193
195
|
plot_frame = tk.PanedWindow(vertical_container, orient=tk.VERTICAL)
|
spacr/app_measure.py
CHANGED
@@ -13,9 +13,10 @@ except AttributeError:
|
|
13
13
|
pass
|
14
14
|
|
15
15
|
from .logger import log_function_call
|
16
|
-
from .
|
17
|
-
from .gui_utils import
|
18
|
-
from .gui_utils import
|
16
|
+
from .settings import get_measure_crop_settings
|
17
|
+
from .gui_utils import ScrollableFrame, StdoutRedirector, CustomButton, ToggleSwitch
|
18
|
+
from .gui_utils import process_stdout_stderr, set_dark_style, set_default_font, generate_fields, main_thread_update_function, create_menu_bar, convert_settings_dict_for_gui
|
19
|
+
from .gui_utils import measure_crop_wrapper, clear_canvas, check_measure_gui_settings, read_settings_from_csv, update_settings_from_csv, set_dark_style
|
19
20
|
|
20
21
|
thread_control = {"run_thread": None, "stop_requested": False}
|
21
22
|
|
@@ -24,7 +25,8 @@ def import_settings(scrollable_frame):
|
|
24
25
|
|
25
26
|
csv_file_path = filedialog.askopenfilename(filetypes=[("CSV files", "*.csv")])
|
26
27
|
csv_settings = read_settings_from_csv(csv_file_path)
|
27
|
-
|
28
|
+
settings = get_measure_crop_settings({})
|
29
|
+
variables = convert_settings_dict_for_gui(settings)
|
28
30
|
new_settings = update_settings_from_csv(variables, csv_settings)
|
29
31
|
vars_dict = generate_fields(new_settings, scrollable_frame)
|
30
32
|
|
@@ -102,7 +104,6 @@ def initiate_measure_root(parent_frame):
|
|
102
104
|
|
103
105
|
style = ttk.Style(parent_frame)
|
104
106
|
set_dark_style(style)
|
105
|
-
style_text_boxes(style)
|
106
107
|
set_default_font(parent_frame, font_name="Helvetica", size=8)
|
107
108
|
|
108
109
|
parent_frame.configure(bg='black')
|
@@ -160,7 +161,7 @@ def initiate_measure_root(parent_frame):
|
|
160
161
|
vertical_container.add(settings_frame, stretch="always")
|
161
162
|
settings_label = ttk.Label(settings_frame, text="Settings", background="black", foreground="white")
|
162
163
|
settings_label.grid(row=0, column=0, pady=10, padx=10)
|
163
|
-
scrollable_frame = ScrollableFrame(settings_frame,
|
164
|
+
scrollable_frame = ScrollableFrame(settings_frame, bg='black')
|
164
165
|
scrollable_frame.grid(row=1, column=0, sticky="nsew")
|
165
166
|
settings_frame.grid_rowconfigure(1, weight=1)
|
166
167
|
settings_frame.grid_columnconfigure(0, weight=1)
|
@@ -168,23 +169,27 @@ def initiate_measure_root(parent_frame):
|
|
168
169
|
# Create advanced settings checkbox
|
169
170
|
advanced_var = tk.BooleanVar(value=False)
|
170
171
|
advanced_Toggle = ToggleSwitch(scrollable_frame.scrollable_frame, text="Advanced Settings", variable=advanced_var, command=toggle_advanced_settings)
|
171
|
-
advanced_Toggle.grid(row=
|
172
|
-
|
172
|
+
advanced_Toggle.grid(row=4, column=0, pady=10, padx=10)
|
173
|
+
settings = get_measure_crop_settings({})
|
174
|
+
variables = convert_settings_dict_for_gui(settings)
|
173
175
|
vars_dict = generate_fields(variables, scrollable_frame)
|
174
176
|
toggle_advanced_settings()
|
175
177
|
vars_dict['Test mode'] = (None, None, tk.BooleanVar(value=False))
|
176
178
|
|
177
179
|
# Button section
|
178
|
-
|
179
|
-
test_mode_button.grid(row=47, column=1, pady=10, padx=10)
|
180
|
-
import_btn = CustomButton(scrollable_frame.scrollable_frame, text="Import", command=lambda: import_settings(scrollable_frame), font=('Helvetica', 10))
|
181
|
-
import_btn.grid(row=47, column=0, pady=20, padx=20)
|
180
|
+
btn_row = 1
|
182
181
|
run_button = CustomButton(scrollable_frame.scrollable_frame, text="Run", command=lambda: start_process(q, fig_queue), font=('Helvetica', 10))
|
183
|
-
run_button.grid(row=
|
182
|
+
run_button.grid(row=btn_row, column=0, pady=5, padx=5)
|
184
183
|
abort_button = CustomButton(scrollable_frame.scrollable_frame, text="Abort", command=initiate_abort, font=('Helvetica', 10))
|
185
|
-
abort_button.grid(row=
|
184
|
+
abort_button.grid(row=btn_row, column=1, pady=5, padx=5)
|
185
|
+
btn_row += 1
|
186
|
+
test_mode_button = CustomButton(scrollable_frame.scrollable_frame, text="Test Mode", command=toggle_test_mode)
|
187
|
+
test_mode_button.grid(row=btn_row, column=0, pady=5, padx=5)
|
188
|
+
import_btn = CustomButton(scrollable_frame.scrollable_frame, text="Import", command=lambda: import_settings(scrollable_frame), font=('Helvetica', 10))
|
189
|
+
import_btn.grid(row=btn_row, column=1, pady=5, padx=5)
|
190
|
+
btn_row += 1
|
186
191
|
progress_label = ttk.Label(scrollable_frame.scrollable_frame, text="Processing: 0%", background="black", foreground="white") # Create progress field
|
187
|
-
progress_label.grid(row=
|
192
|
+
progress_label.grid(row=btn_row, column=0, columnspan=2, sticky="ew", pady=(5, 0), padx=10)
|
188
193
|
|
189
194
|
# Plot Canvas Section
|
190
195
|
plot_frame = tk.PanedWindow(vertical_container, orient=tk.VERTICAL)
|
spacr/gui.py
CHANGED
@@ -11,7 +11,7 @@ from .app_measure import initiate_measure_root
|
|
11
11
|
from .app_annotate import initiate_annotation_app_root
|
12
12
|
from .app_make_masks import initiate_mask_app_root
|
13
13
|
from .app_classify import initiate_classify_root
|
14
|
-
from .gui_utils import CustomButton,
|
14
|
+
from .gui_utils import CustomButton, set_dark_style, create_menu_bar
|
15
15
|
|
16
16
|
class MainApp(tk.Tk):
|
17
17
|
def __init__(self):
|
@@ -22,7 +22,7 @@ class MainApp(tk.Tk):
|
|
22
22
|
self.title("SpaCr GUI Collection")
|
23
23
|
self.configure(bg="black")
|
24
24
|
style = ttk.Style()
|
25
|
-
|
25
|
+
set_dark_style(style)
|
26
26
|
|
27
27
|
self.gui_apps = {
|
28
28
|
"Mask": (initiate_mask_root, "Generate cellpose masks for cells, nuclei and pathogen images."),
|
@@ -74,7 +74,7 @@ class MainApp(tk.Tk):
|
|
74
74
|
app_func, app_desc = app_data
|
75
75
|
|
76
76
|
# Create custom button with text
|
77
|
-
button = CustomButton(buttons_frame, text=app_name, command=lambda app_name=app_name: self.load_app(app_name, app_func), font=('Helvetica', 12))
|
77
|
+
button = CustomButton(buttons_frame, text=app_name, command=lambda app_name=app_name, app_func=app_func: self.load_app(app_name, app_func), font=('Helvetica', 12))
|
78
78
|
button.grid(row=i, column=0, pady=10, padx=10, sticky="w")
|
79
79
|
|
80
80
|
description_label = tk.Label(buttons_frame, text=app_desc, bg="black", fg="white", wraplength=800, justify="left", font=('Helvetica', 12))
|
@@ -100,7 +100,6 @@ class MainApp(tk.Tk):
|
|
100
100
|
|
101
101
|
try:
|
102
102
|
img_path = os.path.join(os.path.dirname(__file__), 'logo_spacr.png')
|
103
|
-
print(f"Trying to load logo from {img_path}")
|
104
103
|
logo_image = Image.open(img_path)
|
105
104
|
except (FileNotFoundError, Image.UnidentifiedImageError):
|
106
105
|
print(f"File {img_path} not found or is not a valid image. Attempting to download from GitHub.")
|
@@ -117,7 +116,9 @@ class MainApp(tk.Tk):
|
|
117
116
|
print(f"An error occurred while loading the logo: {e}")
|
118
117
|
return False
|
119
118
|
try:
|
120
|
-
|
119
|
+
screen_height = frame.winfo_screenheight()
|
120
|
+
new_height = int(screen_height // 4)
|
121
|
+
logo_image = logo_image.resize((new_height, new_height), Image.Resampling.LANCZOS)
|
121
122
|
logo_photo = ImageTk.PhotoImage(logo_image)
|
122
123
|
logo_label = tk.Label(frame, image=logo_photo, bg="black")
|
123
124
|
logo_label.image = logo_photo # Keep a reference to avoid garbage collection
|
spacr/gui_utils.py
CHANGED
@@ -10,7 +10,6 @@ from torchvision import models
|
|
10
10
|
|
11
11
|
from tkinter import font as tkFont
|
12
12
|
|
13
|
-
|
14
13
|
from .logger import log_function_call
|
15
14
|
|
16
15
|
try:
|
@@ -147,7 +146,6 @@ def load_app(root, app_name, app_func):
|
|
147
146
|
else:
|
148
147
|
proceed_with_app(root, app_name, app_func)
|
149
148
|
|
150
|
-
|
151
149
|
def create_menu_bar(root):
|
152
150
|
from .app_mask import initiate_mask_root
|
153
151
|
from .app_measure import initiate_measure_root
|
@@ -188,14 +186,19 @@ class CustomButton(tk.Frame):
|
|
188
186
|
self.text = text
|
189
187
|
self.command = command
|
190
188
|
|
191
|
-
|
189
|
+
# Detect screen height and calculate button dimensions
|
190
|
+
screen_height = self.winfo_screenheight()
|
191
|
+
button_height = screen_height // 50
|
192
|
+
button_width = button_height * 3
|
193
|
+
|
194
|
+
self.canvas = tk.Canvas(self, width=button_width, height=button_height, highlightthickness=0, bg="black")
|
192
195
|
self.canvas.grid(row=0, column=0)
|
193
196
|
|
194
|
-
self.button_bg = self.create_rounded_rectangle(0, 0,
|
197
|
+
self.button_bg = self.create_rounded_rectangle(0, 0, button_width, button_height, radius=20, fill="#800080")
|
195
198
|
|
196
199
|
# Use the passed font or default to Helvetica if not provided
|
197
200
|
self.font_style = font if font else tkFont.Font(family="Helvetica", size=12, weight=tkFont.NORMAL)
|
198
|
-
self.button_text = self.canvas.create_text(
|
201
|
+
self.button_text = self.canvas.create_text(button_width // 2, button_height // 2, text=self.text, fill="white", font=self.font_style)
|
199
202
|
|
200
203
|
self.bind("<Enter>", self.on_enter)
|
201
204
|
self.bind("<Leave>", self.on_leave)
|
@@ -333,38 +336,6 @@ def set_default_font(root, font_name="Helvetica", size=12):
|
|
333
336
|
root.option_add("*TLabel.Font", default_font)
|
334
337
|
root.option_add("*TEntry.Font", default_font)
|
335
338
|
|
336
|
-
def check_and_download_font_v1():
|
337
|
-
font_name = "Helvetica"
|
338
|
-
font_dir = "fonts"
|
339
|
-
font_path = os.path.join(font_dir, "OpenSans-Regular.ttf")
|
340
|
-
|
341
|
-
# Check if the font is already available
|
342
|
-
available_fonts = list(tkFont.families())
|
343
|
-
if font_name not in available_fonts:
|
344
|
-
print(f"Font '{font_name}' not found. Downloading...")
|
345
|
-
if not os.path.exists(font_dir):
|
346
|
-
os.makedirs(font_dir)
|
347
|
-
|
348
|
-
if not os.path.exists(font_path):
|
349
|
-
url = "https://github.com/google/fonts/blob/main/apache/opensans/OpenSans-Regular.ttf?raw=true"
|
350
|
-
response = requests.get(url)
|
351
|
-
with open(font_path, "wb") as f:
|
352
|
-
f.write(response.content)
|
353
|
-
|
354
|
-
# Load the font
|
355
|
-
try:
|
356
|
-
tkFont.nametofont("TkDefaultFont").configure(family=font_name, size=10)
|
357
|
-
tkFont.nametofont("TkTextFont").configure(family=font_name, size=10)
|
358
|
-
tkFont.nametofont("TkHeadingFont").configure(family=font_name, size=12)
|
359
|
-
except tk.TclError:
|
360
|
-
tkFont.nametofont("TkDefaultFont").configure(family="Helvetica", size=10)
|
361
|
-
tkFont.nametofont("TkTextFont").configure(family="Helvetica", size=10)
|
362
|
-
tkFont.nametofont("TkHeadingFont").configure(family="Helvetica", size=12)
|
363
|
-
else:
|
364
|
-
tkFont.nametofont("TkDefaultFont").configure(family=font_name, size=10)
|
365
|
-
tkFont.nametofont("TkTextFont").configure(family=font_name, size=10)
|
366
|
-
tkFont.nametofont("TkHeadingFont").configure(family=font_name, size=12)
|
367
|
-
|
368
339
|
def check_and_download_font():
|
369
340
|
font_name = "Helvetica"
|
370
341
|
font_dir = "fonts"
|
@@ -382,8 +353,6 @@ def check_and_download_font():
|
|
382
353
|
response = requests.get(url)
|
383
354
|
with open(font_path, "wb") as f:
|
384
355
|
f.write(response.content)
|
385
|
-
|
386
|
-
# Load the font
|
387
356
|
try:
|
388
357
|
tkFont.nametofont("TkDefaultFont").configure(family=font_name, size=10)
|
389
358
|
tkFont.nametofont("TkTextFont").configure(family=font_name, size=10)
|
@@ -397,32 +366,39 @@ def check_and_download_font():
|
|
397
366
|
tkFont.nametofont("TkTextFont").configure(family=font_name, size=10)
|
398
367
|
tkFont.nametofont("TkHeadingFont").configure(family=font_name, size=12)
|
399
368
|
|
400
|
-
def
|
401
|
-
|
402
|
-
|
403
|
-
style.configure('
|
404
|
-
style.configure('TCombobox', fieldbackground='#000000', background='#000000', foreground='#ffffff', font=font_style)
|
369
|
+
def set_dark_style_v1(style):
|
370
|
+
font_style = tkFont.Font(family="Helvetica", size=10)
|
371
|
+
style.configure('TEntry', padding='5 5 5 5', borderwidth=1, relief='solid', fieldbackground='black', foreground='#ffffff', font=font_style)
|
372
|
+
style.configure('TCombobox', fieldbackground='black', background='black', foreground='#ffffff', font=font_style)
|
405
373
|
style.configure('Custom.TButton', padding='10 10 10 10', borderwidth=1, relief='solid', background='#008080', foreground='#ffffff', font=font_style)
|
406
374
|
style.map('Custom.TButton',
|
407
375
|
background=[('active', '#66b2b2'), ('disabled', '#004d4d'), ('!disabled', '#008080')],
|
408
376
|
foreground=[('active', '#ffffff'), ('disabled', '#888888')])
|
409
|
-
style.configure('Custom.TLabel', padding='5 5 5 5', borderwidth=1, relief='flat', background='
|
377
|
+
style.configure('Custom.TLabel', padding='5 5 5 5', borderwidth=1, relief='flat', background='black', foreground='#ffffff', font=font_style)
|
410
378
|
style.configure('TCheckbutton', background='black', foreground='#ffffff', indicatoron=False, relief='flat', font=font_style)
|
411
379
|
style.map('TCheckbutton', background=[('selected', '#555555'), ('active', '#555555')])
|
412
380
|
|
413
|
-
def
|
381
|
+
def set_dark_style(style):
|
414
382
|
font_style = tkFont.Font(family="Helvetica", size=10)
|
415
|
-
style.configure('TEntry', padding='5 5 5 5', borderwidth=1, relief='solid', fieldbackground='black', foreground='#ffffff', font=font_style)
|
416
|
-
style.configure('TCombobox', fieldbackground='black', background='black', foreground='#ffffff', font=font_style)
|
417
|
-
style.configure('Custom.TButton', padding='10 10 10 10', borderwidth=1, relief='solid', background='#008080', foreground='#ffffff', font=font_style)
|
383
|
+
style.configure('TEntry', padding='5 5 5 5', borderwidth=1, relief='solid', fieldbackground='black', foreground='#ffffff', font=font_style) # Entry
|
384
|
+
style.configure('TCombobox', fieldbackground='black', background='black', foreground='#ffffff', font=font_style) # Combobox
|
385
|
+
style.configure('Custom.TButton', padding='10 10 10 10', borderwidth=1, relief='solid', background='#008080', foreground='#ffffff', font=font_style) # Custom Button
|
418
386
|
style.map('Custom.TButton',
|
419
387
|
background=[('active', '#66b2b2'), ('disabled', '#004d4d'), ('!disabled', '#008080')],
|
420
388
|
foreground=[('active', '#ffffff'), ('disabled', '#888888')])
|
421
|
-
style.configure('Custom.TLabel', padding='5 5 5 5', borderwidth=1, relief='flat', background='
|
422
|
-
style.configure('TCheckbutton', background='black', foreground='#ffffff', indicatoron=False, relief='flat', font=font_style)
|
389
|
+
style.configure('Custom.TLabel', padding='5 5 5 5', borderwidth=1, relief='flat', background='black', foreground='#ffffff', font=font_style) # Custom Label
|
390
|
+
style.configure('TCheckbutton', background='black', foreground='#ffffff', indicatoron=False, relief='flat', font=font_style) # Checkbutton
|
423
391
|
style.map('TCheckbutton', background=[('selected', '#555555'), ('active', '#555555')])
|
424
|
-
|
425
|
-
|
392
|
+
style.configure('TLabel', background='black', foreground='#ffffff', font=font_style) # Label
|
393
|
+
style.configure('TFrame', background='black') # Frame
|
394
|
+
style.configure('TPanedwindow', background='black') # PanedWindow
|
395
|
+
style.configure('TNotebook', background='black', tabmargins=[2, 5, 2, 0]) # Notebook
|
396
|
+
style.configure('TNotebook.Tab', background='black', foreground='#ffffff', padding=[5, 5], font=font_style)
|
397
|
+
style.map('TNotebook.Tab', background=[('selected', '#555555'), ('active', '#555555')])
|
398
|
+
style.configure('TButton', background='black', foreground='#ffffff', padding='5 5 5 5', font=font_style) # Button (regular)
|
399
|
+
style.map('TButton', background=[('active', '#555555'), ('disabled', '#333333')])
|
400
|
+
style.configure('Vertical.TScrollbar', background='black', troughcolor='black', bordercolor='black') # Scrollbar
|
401
|
+
style.configure('Horizontal.TScrollbar', background='black', troughcolor='black', bordercolor='black')
|
426
402
|
|
427
403
|
def read_settings_from_csv(csv_file_path):
|
428
404
|
settings = {}
|
@@ -461,36 +437,45 @@ def disable_interactivity(fig):
|
|
461
437
|
for handler_id in list(handlers.keys()):
|
462
438
|
fig.canvas.mpl_disconnect(handler_id)
|
463
439
|
|
464
|
-
class
|
440
|
+
class ScrollableFrame_v1(ttk.Frame):
|
465
441
|
def __init__(self, container, *args, bg='black', **kwargs):
|
466
442
|
super().__init__(container, *args, **kwargs)
|
467
|
-
self.configure(style='TFrame')
|
468
|
-
|
469
|
-
|
443
|
+
self.configure(style='TFrame')
|
444
|
+
screen_width = self.winfo_screenwidth()
|
445
|
+
frame_width = screen_width // 4 # Set the frame width to 1/4th of the screen width
|
446
|
+
canvas = tk.Canvas(self, bg=bg, width=frame_width) # Set canvas background to match dark mode
|
470
447
|
scrollbar = ttk.Scrollbar(self, orient="vertical", command=canvas.yview)
|
471
|
-
|
472
|
-
self.scrollable_frame = ttk.Frame(canvas, style='TFrame') # Ensure it uses the styled frame
|
448
|
+
self.scrollable_frame = ttk.Frame(canvas, style='TFrame', padding=5) # Ensure it uses the styled frame
|
473
449
|
self.scrollable_frame.bind(
|
474
450
|
"<Configure>",
|
475
451
|
lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
|
476
452
|
)
|
477
|
-
|
478
453
|
canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
|
479
454
|
canvas.configure(yscrollcommand=scrollbar.set)
|
480
|
-
|
481
455
|
canvas.pack(side="left", fill="both", expand=True)
|
482
456
|
scrollbar.pack(side="right", fill="y")
|
483
457
|
|
484
|
-
class
|
485
|
-
def __init__(self,
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
458
|
+
class ScrollableFrame(ttk.Frame):
|
459
|
+
def __init__(self, container, width=None, *args, bg='black', **kwargs):
|
460
|
+
super().__init__(container, *args, **kwargs)
|
461
|
+
self.configure(style='TFrame')
|
462
|
+
if width is None:
|
463
|
+
screen_width = self.winfo_screenwidth()
|
464
|
+
width = screen_width // 4
|
465
|
+
canvas = tk.Canvas(self, bg=bg, width=width)
|
466
|
+
scrollbar = ttk.Scrollbar(self, orient="vertical", command=canvas.yview)
|
467
|
+
|
468
|
+
self.scrollable_frame = ttk.Frame(canvas, style='TFrame')
|
469
|
+
self.scrollable_frame.bind(
|
470
|
+
"<Configure>",
|
471
|
+
lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
|
472
|
+
)
|
473
|
+
canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
|
474
|
+
canvas.configure(yscrollcommand=scrollbar.set)
|
475
|
+
canvas.pack(side="left", fill="both", expand=True)
|
476
|
+
scrollbar.pack(side="right", fill="y")
|
477
|
+
for child in self.scrollable_frame.winfo_children():
|
478
|
+
child.configure(bg='black')
|
494
479
|
|
495
480
|
class StdoutRedirector:
|
496
481
|
def __init__(self, text_widget):
|
@@ -793,7 +778,7 @@ def create_input_field(frame, label_text, row, var_type='entry', options=None, d
|
|
793
778
|
return (label, entry, var) # Return both the label and the entry, and the variable
|
794
779
|
elif var_type == 'check':
|
795
780
|
var = tk.BooleanVar(value=default_value) # Set default value (True/False)
|
796
|
-
check = ToggleSwitch(frame, text=
|
781
|
+
check = ToggleSwitch(frame, text="", variable=var) # Use ToggleSwitch class
|
797
782
|
check.grid(column=1, row=row, sticky=tk.W, padx=5)
|
798
783
|
return (label, check, var) # Return both the label and the checkbutton, and the variable
|
799
784
|
elif var_type == 'combo':
|
@@ -806,10 +791,43 @@ def create_input_field(frame, label_text, row, var_type='entry', options=None, d
|
|
806
791
|
else:
|
807
792
|
var = None # Placeholder in case of an undefined var_type
|
808
793
|
return (label, None, var)
|
794
|
+
|
795
|
+
def convert_settings_dict_for_gui(settings):
|
796
|
+
variables = {}
|
797
|
+
special_cases = {
|
798
|
+
'metadata_type': ('combo', ['cellvoyager', 'cq1', 'nikon', 'zeis', 'custom'], 'cellvoyager'),
|
799
|
+
'channels': ('combo', ['[0,1,2,3]', '[0,1,2]', '[0,1]', '[0]'], '[0,1,2,3]'),
|
800
|
+
'magnification': ('combo', [20, 40, 60], 20),
|
801
|
+
'nucleus_channel': ('combo', [0, 1, 2, 3, None], None),
|
802
|
+
'cell_channel': ('combo', [0, 1, 2, 3, None], None),
|
803
|
+
'pathogen_channel': ('combo', [0, 1, 2, 3, None], None),
|
804
|
+
'timelapse_mode': ('combo', ['trackpy', 'btrack'], 'trackpy'),
|
805
|
+
'timelapse_objects': ('combo', ['cell', 'nucleus', 'pathogen', 'cytoplasm', None], None),
|
806
|
+
'model_type': ('combo', ['resnet50', 'other_model'], 'resnet50'),
|
807
|
+
'optimizer_type': ('combo', ['adamw', 'adam'], 'adamw'),
|
808
|
+
'schedule': ('combo', ['reduce_lr_on_plateau', 'step_lr'], 'reduce_lr_on_plateau'),
|
809
|
+
'loss_type': ('combo', ['focal_loss', 'binary_cross_entropy_with_logits'], 'focal_loss'),
|
810
|
+
'normalize_by': ('combo', ['fov', 'png'], 'png'),
|
811
|
+
}
|
812
|
+
for key, value in settings.items():
|
813
|
+
if key in special_cases:
|
814
|
+
variables[key] = special_cases[key]
|
815
|
+
elif isinstance(value, bool):
|
816
|
+
variables[key] = ('check', None, value)
|
817
|
+
elif isinstance(value, int) or isinstance(value, float):
|
818
|
+
variables[key] = ('entry', None, value)
|
819
|
+
elif isinstance(value, str):
|
820
|
+
variables[key] = ('entry', None, value)
|
821
|
+
elif value is None:
|
822
|
+
variables[key] = ('entry', None, value)
|
823
|
+
elif isinstance(value, list):
|
824
|
+
variables[key] = ('entry', None, str(value))
|
825
|
+
return variables
|
809
826
|
|
810
827
|
def mask_variables():
|
811
828
|
variables = {
|
812
|
-
'src': ('entry', None, '/
|
829
|
+
'src': ('entry', None, 'path/to/images'),
|
830
|
+
'pathogen_model': ('entry', None, 'path/to/model'),
|
813
831
|
'metadata_type': ('combo', ['cellvoyager', 'cq1', 'nikon', 'zeis', 'custom'], 'cellvoyager'),
|
814
832
|
'custom_regex': ('entry', None, None),
|
815
833
|
'experiment': ('entry', None, 'exp'),
|
@@ -819,14 +837,17 @@ def mask_variables():
|
|
819
837
|
'nucleus_background': ('entry', None, 100),
|
820
838
|
'nucleus_Signal_to_noise': ('entry', None, 5),
|
821
839
|
'nucleus_CP_prob': ('entry', None, 0),
|
840
|
+
'remove_background_nucleus': ('check', None, False),
|
822
841
|
'cell_channel': ('combo', [0,1,2,3, None], 3),
|
823
842
|
'cell_background': ('entry', None, 100),
|
824
843
|
'cell_Signal_to_noise': ('entry', None, 5),
|
825
844
|
'cell_CP_prob': ('entry', None, 0),
|
845
|
+
'remove_background_cell': ('check', None, False),
|
826
846
|
'pathogen_channel': ('combo', [0,1,2,3, None], 2),
|
827
847
|
'pathogen_background': ('entry', None, 100),
|
828
848
|
'pathogen_Signal_to_noise': ('entry', None, 3),
|
829
849
|
'pathogen_CP_prob': ('entry', None, 0),
|
850
|
+
'remove_background_pathogen': ('check', None, False),
|
830
851
|
'preprocess': ('check', None, True),
|
831
852
|
'masks': ('check', None, True),
|
832
853
|
'examples_to_plot': ('entry', None, 1),
|
@@ -842,7 +863,7 @@ def mask_variables():
|
|
842
863
|
'fps': ('entry', None, 2),
|
843
864
|
'remove_background': ('check', None, True),
|
844
865
|
'lower_quantile': ('entry', None, 0.01),
|
845
|
-
'merge': ('check', None, False),
|
866
|
+
#'merge': ('check', None, False),
|
846
867
|
'normalize_plots': ('check', None, True),
|
847
868
|
'all_to_mip': ('check', None, False),
|
848
869
|
'pick_slice': ('check', None, False),
|
@@ -851,6 +872,11 @@ def mask_variables():
|
|
851
872
|
'plot': ('check', None, True),
|
852
873
|
'workers': ('entry', None, 30),
|
853
874
|
'verbose': ('check', None, True),
|
875
|
+
'filter': ('check', None, True),
|
876
|
+
'merge_pathogens': ('check', None, True),
|
877
|
+
'adjust_cells': ('check', None, True),
|
878
|
+
'test_images': ('entry', None, 10),
|
879
|
+
'random_test': ('check', None, True),
|
854
880
|
}
|
855
881
|
return variables
|
856
882
|
|
@@ -871,7 +897,7 @@ def add_mask_gui_defaults(settings):
|
|
871
897
|
|
872
898
|
def generate_fields(variables, scrollable_frame):
|
873
899
|
vars_dict = {}
|
874
|
-
row =
|
900
|
+
row = 5
|
875
901
|
tooltips = {
|
876
902
|
"src": "Path to the folder containing the images.",
|
877
903
|
"metadata_type": "Type of metadata to expect in the images. This will determine how the images are processed. If 'custom' is selected, you can provide a custom regex pattern to extract metadata from the image names",
|
@@ -993,12 +1019,6 @@ def create_dark_mode(root, style, console_output):
|
|
993
1019
|
if console_output != None:
|
994
1020
|
console_output.config(bg=dark_bg, fg=light_text, insertbackground=light_text) #, font=("Helvetica", 12)
|
995
1021
|
root.configure(bg=dark_bg)
|
996
|
-
|
997
|
-
def set_dark_style(style):
|
998
|
-
style.configure('TFrame', background='black')
|
999
|
-
style.configure('TLabel', background='black', foreground='white')
|
1000
|
-
style.configure('TEntry', background='black', foreground='white')
|
1001
|
-
style.configure('TCheckbutton', background='black', foreground='white')
|
1002
1022
|
|
1003
1023
|
##@log_function_call
|
1004
1024
|
def main_thread_update_function(root, q, fig_queue, canvas_widget, progress_label):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: spacr
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.16
|
4
4
|
Summary: Spatial phenotype analysis of crisp screens (SpaCr)
|
5
5
|
Home-page: https://github.com/EinarOlafsson/spacr
|
6
6
|
Author: Einar Birnir Olafsson
|
@@ -9,7 +9,6 @@ Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
10
10
|
Classifier: Operating System :: OS Independent
|
11
11
|
License-File: LICENSE
|
12
|
-
Requires-Dist: dgl ==0.9.1
|
13
12
|
Requires-Dist: torch <3.0,>=2.2.1
|
14
13
|
Requires-Dist: torchvision <1.0,>=0.17.1
|
15
14
|
Requires-Dist: torch-geometric <3.0,>=2.5.1
|
@@ -40,12 +39,8 @@ Requires-Dist: ttf-opensans >=2020.10.30
|
|
40
39
|
Requires-Dist: customtkinter <6.0,>=5.2.2
|
41
40
|
Requires-Dist: biopython <2.0,>=1.80
|
42
41
|
Requires-Dist: lxml <6.0,>=5.1.0
|
43
|
-
Requires-Dist: qtpy <2.5,>=2.4.1
|
44
|
-
Requires-Dist: superqt <0.7,>=0.6.7
|
45
|
-
Requires-Dist: pyqt6 <6.8,>=6.7.1
|
46
|
-
Requires-Dist: pyqtgraph <0.14,>=0.13.7
|
47
42
|
Provides-Extra: dev
|
48
|
-
Requires-Dist: pytest
|
43
|
+
Requires-Dist: pytest <3.11,>=3.9 ; extra == 'dev'
|
49
44
|
Provides-Extra: full
|
50
45
|
Requires-Dist: opencv-python ; extra == 'full'
|
51
46
|
Provides-Extra: headless
|
@@ -67,7 +62,7 @@ Requires-Dist: opencv-python-headless ; extra == 'headless'
|
|
67
62
|
SpaCr
|
68
63
|
=====
|
69
64
|
|
70
|
-
Spatial phenotype analysis of CRISPR-Cas9 screens (SpaCr). The spatial organization of organelles and proteins within cells constitutes a key level of functional regulation. In the context of infectious disease, the spatial relationships between host cell structures and intracellular pathogens are critical to
|
65
|
+
Spatial phenotype analysis of CRISPR-Cas9 screens (SpaCr). The spatial organization of organelles and proteins within cells constitutes a key level of functional regulation. In the context of infectious disease, the spatial relationships between host cell structures and intracellular pathogens are critical to understanding host clearance mechanisms and how pathogens evade them. SpaCr is a Python-based software package for generating single-cell image data for deep-learning sub-cellular/cellular phenotypic classification from pooled genetic CRISPR-Cas9 screens. SpaCr provides a flexible toolset to extract single-cell images and measurements from high-content cell painting experiments, train deep-learning models to classify cellular/subcellular phenotypes, simulate, and analyze pooled CRISPR-Cas9 imaging screens.
|
71
66
|
|
72
67
|
Features
|
73
68
|
--------
|
@@ -76,9 +71,9 @@ Features
|
|
76
71
|
|
77
72
|
- **Object Measurements:** Measurements for each object including scikit-image-regionprops, intensity percentiles, shannon-entropy, pearsons and manders correlations, homogeneity, and radial distribution. Measurements are saved to a SQL database in object-level tables.
|
78
73
|
|
79
|
-
- **Crop Images:**
|
74
|
+
- **Crop Images:** Save objects (cells, nuclei, pathogen, cytoplasm) as images. Object image paths are saved in a SQL database.
|
80
75
|
|
81
|
-
- **Train CNNs or Transformers:** Train Torch
|
76
|
+
- **Train CNNs or Transformers:** Train Torch models to classify single object images.
|
82
77
|
|
83
78
|
- **Manual Annotation:** Supports manual annotation of single-cell images and segmentation to refine training datasets for training CNNs/Transformers or cellpose, respectively.
|
84
79
|
|
@@ -95,29 +90,20 @@ Features
|
|
95
90
|
Installation
|
96
91
|
------------
|
97
92
|
|
98
|
-
|
93
|
+
If using Windows, switch to Linux—it's free, open-source, and better.
|
99
94
|
|
100
|
-
|
101
|
-
~~~~~~
|
95
|
+
Before installing SpaCr on OSX ensure OpenMP is installed::
|
102
96
|
|
103
|
-
|
97
|
+
brew install libomp
|
104
98
|
|
105
|
-
(Tkinter is included with the standard Python installation on macOS
|
106
|
-
|
107
|
-
On Linux:
|
108
|
-
|
109
|
-
::
|
99
|
+
SpaCr GUI requires Tkinter. On Linux, ensure Tkinter is installed. (Tkinter is included with the standard Python installation on macOS and Windows)::
|
110
100
|
|
111
101
|
sudo apt-get install python3-tk
|
112
102
|
|
113
|
-
Install
|
114
|
-
|
115
|
-
::
|
103
|
+
Install SpaCr with pip::
|
116
104
|
|
117
105
|
pip install spacr
|
118
106
|
|
119
|
-
Run
|
120
|
-
|
121
|
-
::
|
107
|
+
Run SpaCr GUI::
|
122
108
|
|
123
|
-
|
109
|
+
spacr
|
@@ -3,12 +3,12 @@ spacr/__main__.py,sha256=bkAJJD2kjIqOP-u1kLvct9jQQCeUXzlEjdgitwi1Lm8,75
|
|
3
3
|
spacr/alpha.py,sha256=Y95sLEfpK2OSYKRn3M8eUOU33JJeXfV8zhrC4KnwSTY,35244
|
4
4
|
spacr/annotate_app.py,sha256=imQ7ZEXDyM6ce1dxZ1xUS1-KequuF_NCI4xCaPLjvco,29275
|
5
5
|
spacr/annotate_app_v2.py,sha256=imQ7ZEXDyM6ce1dxZ1xUS1-KequuF_NCI4xCaPLjvco,29275
|
6
|
-
spacr/app_annotate.py,sha256=
|
7
|
-
spacr/app_classify.py,sha256=
|
8
|
-
spacr/app_make_masks.py,sha256=
|
9
|
-
spacr/app_make_masks_v2.py,sha256
|
10
|
-
spacr/app_mask.py,sha256=
|
11
|
-
spacr/app_measure.py,sha256=
|
6
|
+
spacr/app_annotate.py,sha256=27NzovmbcSa-zdqo9WrFfBcggybhVQmKbgSBDTFnSvU,23588
|
7
|
+
spacr/app_classify.py,sha256=7UKRGW245Chtxc_oCmyS-4omQpffvzzBvsHmC5ey4v8,8665
|
8
|
+
spacr/app_make_masks.py,sha256=ksggY0xBWt7Fgbd451JOabA064kcjiDm8MTslUq1FLo,45088
|
9
|
+
spacr/app_make_masks_v2.py,sha256=csZbUFhOfdHCQ1Wi21bgC1PG8ll5InMqUVmY3-90xlc,30543
|
10
|
+
spacr/app_mask.py,sha256=dDZyIlI71vSMqBT3tC9I3BN8J0kxRf9-h5gBiI7pWZk,11357
|
11
|
+
spacr/app_measure.py,sha256=jOhtqpO6BQSEpeUZA3taR9jThmo0J7BXMq1URzrdyjA,10841
|
12
12
|
spacr/chris.py,sha256=YlBjSgeZaY8HPy6jkrT_ISAnCMAKVfvCxF0I9eAZLFM,2418
|
13
13
|
spacr/classify_app.py,sha256=Zi15ryc1ocYitRF4kyxlC27XxGyzfSPdvj2d6ZrSh7E,8446
|
14
14
|
spacr/cli.py,sha256=507jfOOEV8BoL4eeUcblvH-iiDHdBrEVJLu1ghAAPSc,1800
|
@@ -17,7 +17,7 @@ spacr/deep_spacr.py,sha256=N0o7ILD2p1FTfU4DFxnpjs00xjLhwib-ev0XGqA6muU,37035
|
|
17
17
|
spacr/foldseek.py,sha256=YIP1d4Ci6CeA9jSyiv-HTDbNmAmcSM9Y_DaOs7wYzLY,33546
|
18
18
|
spacr/get_alfafold_structures.py,sha256=ehx_MQgb12k3hFecP6cYVlm5TLO8iWjgevy8ESyS3cw,3544
|
19
19
|
spacr/graph_learning.py,sha256=1tR-ZxvXE3dBz1Saw7BeVFcrsUFu9OlUZeZVifih9eo,13070
|
20
|
-
spacr/gui.py,sha256=
|
20
|
+
spacr/gui.py,sha256=xyf2bmAck8OrbYlvNLpY6rs4EuhuCOxff3f8ZcEZHBQ,6594
|
21
21
|
spacr/gui_2.py,sha256=ZAI5quQYbhQJ40vK0NCqU_UMSPLkpfeQpomBWUSM0fc,6946
|
22
22
|
spacr/gui_annotate.py,sha256=ugBksLGOHdtOLlEuRyyc59TrkYKu3rDf8JxEgiBSVao,6536
|
23
23
|
spacr/gui_classify_app.py,sha256=Zi15ryc1ocYitRF4kyxlC27XxGyzfSPdvj2d6ZrSh7E,8446
|
@@ -26,7 +26,7 @@ spacr/gui_make_masks_app_v2.py,sha256=X3izTBXdCZDlkVe-fbG-jmCQtcAbmK0OIivjyWaLhu
|
|
26
26
|
spacr/gui_mask_app.py,sha256=mhTl_XzXLFl8Tx3WYEMpdYB_qw9u5JJa0EdkvlcIzAE,10706
|
27
27
|
spacr/gui_measure_app.py,sha256=_C1-XFL5HSquUEEbM_NcxdvHx-socPFCx85MBG4d6xo,10598
|
28
28
|
spacr/gui_sim_app.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
29
|
-
spacr/gui_utils.py,sha256=
|
29
|
+
spacr/gui_utils.py,sha256=emUGYxxk9LOsYk2ozLc6mfglzeb4WqBwYhXwitLLJBA,58746
|
30
30
|
spacr/io.py,sha256=IoERqSwoxJrInYl-E0WfwFOEDZXFdJofk5DmpbyLGWM,112077
|
31
31
|
spacr/logger.py,sha256=7Zqr3TuuOQLWT32gYr2q1qvv7x0a2JhLANmZcnBXAW8,670
|
32
32
|
spacr/make_masks_app.py,sha256=iGaTwhowoe2JMOSOf8bJwQZTooRhLQx7KO0ewnAmqDY,45138
|
@@ -46,9 +46,9 @@ spacr/version.py,sha256=axH5tnGwtgSnJHb5IDhiu4Zjk5GhLyAEDRe-rnaoFOA,409
|
|
46
46
|
spacr/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model,sha256=z8BbHWZPRnE9D_BHO0fBREE85c1vkltDs-incs2ytXQ,26566572
|
47
47
|
spacr/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model_settings.csv,sha256=fBAGuL_B8ERVdVizO3BHozTDSbZUh1yFzsYK3wkQN68,420
|
48
48
|
spacr/models/cp/toxo_pv_lumen.CP_model,sha256=2y_CindYhmTvVwBH39SNILF3rI3x9SsRn6qrMxHy3l0,26562451
|
49
|
-
spacr-0.1.
|
50
|
-
spacr-0.1.
|
51
|
-
spacr-0.1.
|
52
|
-
spacr-0.1.
|
53
|
-
spacr-0.1.
|
54
|
-
spacr-0.1.
|
49
|
+
spacr-0.1.16.dist-info/LICENSE,sha256=SR-2MeGc6SCM1UORJYyarSWY_A-JaOMFDj7ReSs9tRM,1083
|
50
|
+
spacr-0.1.16.dist-info/METADATA,sha256=-VoJLJbzVVNvGhVmWA2uh5DydW0W4KjiCnz5WYwgLlQ,5004
|
51
|
+
spacr-0.1.16.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
52
|
+
spacr-0.1.16.dist-info/entry_points.txt,sha256=e6tBSk-bac5ypML_iWIROnQ-hDSLZT_sGpGviPNHG4g,277
|
53
|
+
spacr-0.1.16.dist-info/top_level.txt,sha256=GJPU8FgwRXGzKeut6JopsSRY2R8T3i9lDgya42tLInY,6
|
54
|
+
spacr-0.1.16.dist-info/RECORD,,
|
@@ -0,0 +1,8 @@
|
|
1
|
+
[console_scripts]
|
2
|
+
annotate = spacr.app_annotate:gui_annotate
|
3
|
+
classify = spacr.app_classify:gui_classify
|
4
|
+
make_masks = spacr.app_make_mask:gui_make_masks
|
5
|
+
mask = spacr.app_mask:gui_mask
|
6
|
+
measure = spacr.app_measure:gui_measure
|
7
|
+
sim = spacr.app_sim:gui_sim
|
8
|
+
spacr = spacr.gui:gui_app
|
@@ -1,9 +0,0 @@
|
|
1
|
-
[console_scripts]
|
2
|
-
annotate = spacr.annotate_app_v2:gui_annotate
|
3
|
-
classify = spacr.gui_classify_app:gui_classify
|
4
|
-
gui = spacr.gui:gui_app
|
5
|
-
make_masks = spacr.gui_make_mask_app:gui_make_masks
|
6
|
-
make_masks2 = spacr.gui_make_mask_app_v2:gui_make_masks
|
7
|
-
mask = spacr.gui_mask_app:gui_mask
|
8
|
-
measure = spacr.gui_measure_app:gui_measure
|
9
|
-
sim = spacr.gui_sim_app:gui_sim
|
File without changes
|
File without changes
|
File without changes
|