autogaita 1.5.2__py3-none-any.whl → 1.5.5__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.
@@ -0,0 +1,414 @@
1
+ # %%.......... LOCAL FUNCTION(S) #3 - BUILD RUN AND DONE WINDOWS .............
2
+
3
+ from autogaita.gui.first_level_gui_utils import (
4
+ update_config_file,
5
+ extract_results_from_json_file,
6
+ get_results_and_cfg,
7
+ runanalysis,
8
+ )
9
+ import autogaita.gui.gui_utils as gui_utils
10
+ import autogaita.gui.gaita_widgets as gaita_widgets
11
+ import customtkinter as ctk
12
+ import tkinter as tk
13
+
14
+
15
+ def build_run_and_done_windows(
16
+ tracking_software,
17
+ analysis,
18
+ root,
19
+ cfg,
20
+ widget_cfg,
21
+ gui_specific_vars,
22
+ root_dimensions,
23
+ ):
24
+ """The run window, get information, pass information & run."""
25
+ # unpack root window dimensions & widget cfg
26
+ widget_cfg = widget_cfg
27
+ FG_COLOR = widget_cfg["FG_COLOR"]
28
+ HOVER_COLOR = widget_cfg["HOVER_COLOR"]
29
+ HEADER_FONT_NAME = widget_cfg["HEADER_FONT_NAME"]
30
+ MAIN_HEADER_FONT_SIZE = widget_cfg["MAIN_HEADER_FONT_SIZE"]
31
+ TEXT_FONT_NAME = widget_cfg["TEXT_FONT_NAME"]
32
+ ADV_CFG_TEXT_FONT_SIZE = widget_cfg["ADV_CFG_TEXT_FONT_SIZE"]
33
+
34
+ w = root_dimensions[0]
35
+ h = root_dimensions[1]
36
+
37
+ # ............................. run window ..............................
38
+ runwindow = ctk.CTkToplevel(root)
39
+ user_ready = tk.IntVar(runwindow, 0) # used to know when user is ready 4 screen 3
40
+ if analysis == "single":
41
+ runwindow.title("Single GaitA")
42
+ else:
43
+ runwindow.title("Batch GaitA")
44
+ if tracking_software == "DLC":
45
+ runwindow.geometry(f"{int(w / 2)}x{h}+{int(w / 4)}+0")
46
+ elif tracking_software == "SLEAP":
47
+ runwindow.geometry(f"{int(w / 2)}x{int(h / 2)}+{int(w / 4)}+{int(h / 4)}")
48
+ gui_utils.fix_window_after_its_creation(runwindow)
49
+ # fill window with required info labels & entries - then get results
50
+ results = populate_run_window(
51
+ tracking_software,
52
+ analysis,
53
+ runwindow,
54
+ cfg,
55
+ widget_cfg,
56
+ gui_specific_vars,
57
+ user_ready,
58
+ )
59
+
60
+ # IMPORTANT NOTE
61
+ # --------------
62
+ # we have a wait_variable (user_ready) in populate_run_window waiting for user being
63
+ # ready before results are returned and everything below this line will be executed
64
+ # when calling populate_run_window
65
+ # => the scope of that IntVar has to be runwindow (see initialisation line above)
66
+ # otherwise things won't work when we call _dlc_gui from autogaita.py
67
+ runwindow.destroy()
68
+
69
+ # .........................................................................
70
+ # .............. IMPORTANT - GET VARS & CHECK USER-INPUT ..................
71
+ # .........................................................................
72
+ # ==> Extract "this" results & cfg info IMMEDIATELY BEFORE running analysis
73
+ # (i.e., before providing donewindow)
74
+ # ==> get_results_and_cfg checks whether the numerical vars (see
75
+ # FLOAT_/INT_VARS) were numbers - if not it returns an error_msg, which
76
+ # we use to inform users about their wrong input
77
+ # -- Catch this here and don't even show donewindow if input is wrong
78
+ # ==> NEVER, EVER change the global variable cfg!
79
+ try:
80
+ this_runs_results, this_runs_cfg = get_results_and_cfg(
81
+ results, cfg, analysis, gui_specific_vars
82
+ )
83
+ except:
84
+ error_msg = get_results_and_cfg(results, cfg, analysis, gui_specific_vars)
85
+ tk.messagebox.showerror(title="Try again", message=error_msg)
86
+ return
87
+
88
+ # ............................. done window .............................
89
+ donewindow = ctk.CTkToplevel(root)
90
+ donewindow.title("GaitA Ready :)")
91
+ donewindow_w = w * (3 / 5)
92
+ donewindow_h = h * (1 / 5)
93
+ donewindow_x = (w - donewindow_w) // 2
94
+ donewindow_y = h * (1 / 2.5)
95
+ donewindow.geometry(
96
+ "%dx%d+%d+%d" % (donewindow_w, donewindow_h, donewindow_x, donewindow_y)
97
+ )
98
+ gui_utils.fix_window_after_its_creation(donewindow)
99
+
100
+ # labels
101
+ done_label1_string = "Your results will be saved as your data is processed"
102
+ done_label1 = ctk.CTkLabel(
103
+ donewindow,
104
+ text=done_label1_string,
105
+ font=(TEXT_FONT_NAME, ADV_CFG_TEXT_FONT_SIZE),
106
+ )
107
+ done_label1.grid(row=0, column=0, sticky="nsew")
108
+ done_label2_string = (
109
+ "Please see the Python command window for progress "
110
+ + "and the figure panel for an overview of all plots."
111
+ )
112
+ done_label2 = ctk.CTkLabel(
113
+ donewindow,
114
+ text=done_label2_string,
115
+ font=(TEXT_FONT_NAME, ADV_CFG_TEXT_FONT_SIZE),
116
+ )
117
+ done_label2.grid(row=1, column=0, sticky="nsew")
118
+ done_label3_string = (
119
+ "You may start another analysis while we are "
120
+ + "processing - however your PC might slow down a bit. "
121
+ )
122
+ done_label3 = ctk.CTkLabel(
123
+ donewindow,
124
+ text=done_label3_string,
125
+ font=(TEXT_FONT_NAME, ADV_CFG_TEXT_FONT_SIZE),
126
+ )
127
+ done_label3.grid(row=2, column=0, sticky="nsew")
128
+ done_label4_string = (
129
+ "Thank you for using AutoGaitA! Feel free to "
130
+ + "contact me on Github or at autogaita@fz-juelich.de - MH."
131
+ )
132
+ done_label4 = ctk.CTkLabel(
133
+ donewindow,
134
+ text=done_label4_string,
135
+ font=(TEXT_FONT_NAME, ADV_CFG_TEXT_FONT_SIZE),
136
+ )
137
+ done_label4.grid(row=3, column=0, sticky="nsew")
138
+ # run button
139
+ done_button = ctk.CTkButton(
140
+ donewindow,
141
+ text="Run!",
142
+ fg_color=FG_COLOR,
143
+ hover_color=HOVER_COLOR,
144
+ font=(HEADER_FONT_NAME, MAIN_HEADER_FONT_SIZE),
145
+ command=lambda: (
146
+ runanalysis(tracking_software, analysis, this_runs_results, this_runs_cfg),
147
+ donewindow.destroy(),
148
+ ),
149
+ )
150
+ done_button.grid(row=4, column=0, sticky="nsew", pady=10, padx=200)
151
+
152
+ gui_utils.maximise_widgets(donewindow)
153
+
154
+
155
+ # %%.......... LOCAL FUNCTION(S) #4 - POPULATE RUN WINDOW ....................
156
+ def populate_run_window(
157
+ tracking_software,
158
+ analysis,
159
+ runwindow,
160
+ cfg,
161
+ widget_cfg,
162
+ gui_specific_vars,
163
+ user_ready,
164
+ ):
165
+ """Populate the information window before running analysis"""
166
+
167
+ # unpack widget cfg
168
+ FG_COLOR = widget_cfg["FG_COLOR"]
169
+ HOVER_COLOR = widget_cfg["HOVER_COLOR"]
170
+ TEXT_FONT_NAME = widget_cfg["TEXT_FONT_NAME"]
171
+ TEXT_FONT_SIZE = widget_cfg["TEXT_FONT_SIZE"]
172
+ ADV_CFG_TEXT_FONT_SIZE = widget_cfg["ADV_CFG_TEXT_FONT_SIZE"]
173
+ HEADER_FONT_NAME = widget_cfg["HEADER_FONT_NAME"]
174
+ HEADER_FONT_SIZE = widget_cfg["MAIN_HEADER_FONT_SIZE"]
175
+ AUTOGAITA_FOLDER_PATH = widget_cfg["AUTOGAITA_FOLDER_PATH"]
176
+ # unpack variable dict
177
+ CONFIG_FILE_NAME = gui_specific_vars["CONFIG_FILE_NAME"]
178
+ LIST_VARS = gui_specific_vars["LIST_VARS"]
179
+ DICT_VARS = gui_specific_vars["DICT_VARS"]
180
+ TK_STR_VARS = gui_specific_vars["TK_STR_VARS"]
181
+ TK_BOOL_VARS = gui_specific_vars["TK_BOOL_VARS"]
182
+
183
+ # ..................... load results dict from config.....................
184
+ # use the values in the config json file for the results dictionary
185
+ results = extract_results_from_json_file(
186
+ runwindow, AUTOGAITA_FOLDER_PATH, CONFIG_FILE_NAME, TK_STR_VARS, TK_BOOL_VARS
187
+ )
188
+
189
+ # ........................ build the frame ...............................
190
+ if analysis == "single":
191
+ if tracking_software == "DLC":
192
+ # mouse number
193
+ mousenum_label, mousenum_entry = gaita_widgets.label_and_entry_pair(
194
+ runwindow,
195
+ "What is the number of the animal/subject?",
196
+ results["mouse_num"],
197
+ widget_cfg,
198
+ adv_cfg_textsize=True,
199
+ )
200
+ mousenum_label.grid(row=0, column=0)
201
+ mousenum_entry.grid(row=1, column=0)
202
+ # run number
203
+ runnum_label, runnum_entry = gaita_widgets.label_and_entry_pair(
204
+ runwindow,
205
+ "What is the number of the trial?",
206
+ results["run_num"],
207
+ widget_cfg,
208
+ adv_cfg_textsize=True,
209
+ )
210
+ runnum_label.grid(row=2, column=0)
211
+ runnum_entry.grid(row=3, column=0)
212
+ # set row index accordingly
213
+ r = 4
214
+ elif tracking_software == "SLEAP":
215
+ # ID
216
+ ID_label, ID_entry = gaita_widgets.label_and_entry_pair(
217
+ runwindow,
218
+ "What is the ID of the animal/subject?",
219
+ results["name"],
220
+ widget_cfg,
221
+ adv_cfg_textsize=True,
222
+ )
223
+ ID_label.grid(row=0, column=0)
224
+ ID_entry.grid(row=1, column=0)
225
+ # set row index accordingly
226
+ r = 2
227
+ else:
228
+ r = 0
229
+ # if tracking_software == "SLEAP":
230
+ # # empty label 1 (for spacing)
231
+ # empty_label_sleap = ctk.CTkLabel(runwindow, text="")
232
+ # empty_label_sleap.grid(row=r, column=0)
233
+ # r += 1
234
+ # root directory
235
+ rootdir_label, rootdir_entry = gaita_widgets.label_and_entry_pair(
236
+ runwindow,
237
+ "Directory containing the files to be analysed",
238
+ results["root_dir"],
239
+ widget_cfg,
240
+ adv_cfg_textsize=True,
241
+ )
242
+ rootdir_label.grid(row=r + 0, column=0)
243
+ rootdir_entry.grid(row=r + 1, column=0)
244
+ # stepcycle latency XLS
245
+ SCXLS_label, SCXLS_entry = gaita_widgets.label_and_entry_pair(
246
+ runwindow,
247
+ "Filename of the Annotation Table Excel file",
248
+ results["sctable_filename"],
249
+ widget_cfg,
250
+ adv_cfg_textsize=True,
251
+ )
252
+ SCXLS_label.grid(row=r + 2, column=0)
253
+ SCXLS_entry.grid(row=r + 3, column=0)
254
+ # empty label 1 (for spacing)
255
+ empty_label_one = ctk.CTkLabel(runwindow, text="")
256
+ empty_label_one.grid(row=r + 4, column=0)
257
+ last_sleap_row = r + 4
258
+ # ......................... DLC-specific information .............................
259
+ if tracking_software == "DLC":
260
+ # file naming convention label one
261
+ name_convention_string_one = (
262
+ "According to the [A]_[B]_[C]_[D]-[E][G] filename convention "
263
+ )
264
+ name_convention_label_one = ctk.CTkLabel(
265
+ runwindow,
266
+ text=name_convention_string_one,
267
+ font=(TEXT_FONT_NAME, TEXT_FONT_SIZE),
268
+ )
269
+ name_convention_label_one.grid(row=r + 5, column=0)
270
+ # file naming convention label two
271
+ name_convention_string_two = (
272
+ "(e.g. C57B6_Mouse10_25mm_Run1-6DLC-JointTracking):"
273
+ )
274
+ name_convention_label_two = ctk.CTkLabel(
275
+ runwindow,
276
+ text=name_convention_string_two,
277
+ font=(TEXT_FONT_NAME, ADV_CFG_TEXT_FONT_SIZE),
278
+ )
279
+ name_convention_label_two.grid(row=r + 6, column=0)
280
+ # empty label 2 (for spacing)
281
+ empty_label_two = ctk.CTkLabel(runwindow, text="")
282
+ empty_label_two.grid(row=r + 7, column=0)
283
+ # data string
284
+ data_label, data_entry = gaita_widgets.label_and_entry_pair(
285
+ runwindow,
286
+ "[G] What is the identifier of the DLC-tracked coordinate file?",
287
+ results["data_string"],
288
+ widget_cfg,
289
+ adv_cfg_textsize=True,
290
+ )
291
+ data_label.grid(row=r + 8, column=0)
292
+ data_entry.grid(row=r + 9, column=0)
293
+ # beam string
294
+ beam_label, beam_entry = gaita_widgets.label_and_entry_pair(
295
+ runwindow,
296
+ "[G] What is the identifier of the DLC-tracked baseline file? (optional)",
297
+ results["beam_string"],
298
+ widget_cfg,
299
+ adv_cfg_textsize=True,
300
+ )
301
+ beam_label.grid(row=r + 10, column=0)
302
+ beam_entry.grid(row=r + 11, column=0)
303
+ # premouse_num string
304
+ premouse_label, premouse_entry = gaita_widgets.label_and_entry_pair(
305
+ runwindow,
306
+ "[B] Define the 'unique subject identifier' preceding the number",
307
+ results["premouse_string"],
308
+ widget_cfg,
309
+ adv_cfg_textsize=True,
310
+ )
311
+ premouse_label.grid(row=r + 12, column=0)
312
+ premouse_entry.grid(row=r + 13, column=0)
313
+ # postmouse_num string
314
+ postmouse_label, postmouse_entry = gaita_widgets.label_and_entry_pair(
315
+ runwindow,
316
+ "[C] Define the 'unique task identifier",
317
+ results["postmouse_string"],
318
+ widget_cfg,
319
+ adv_cfg_textsize=True,
320
+ )
321
+ postmouse_label.grid(row=r + 14, column=0)
322
+ postmouse_entry.grid(row=r + 15, column=0)
323
+ # prerun string
324
+ prerun_label, prerun_entry = gaita_widgets.label_and_entry_pair(
325
+ runwindow,
326
+ "[D] Define the 'unique trial identifier",
327
+ results["prerun_string"],
328
+ widget_cfg,
329
+ adv_cfg_textsize=True,
330
+ )
331
+ prerun_label.grid(row=r + 16, column=0)
332
+ prerun_entry.grid(row=r + 17, column=0)
333
+ # postrun string
334
+ postrun_label, postrun_entry = gaita_widgets.label_and_entry_pair(
335
+ runwindow,
336
+ "[E] Define the 'unique camera identifier",
337
+ results["postrun_string"],
338
+ widget_cfg,
339
+ adv_cfg_textsize=True,
340
+ )
341
+ postrun_label.grid(row=r + 18, column=0)
342
+ postrun_entry.grid(row=r + 19, column=0)
343
+ # ......................... SLEAP-specific information ...........................
344
+ elif tracking_software == "SLEAP":
345
+ # info labels
346
+ info_label_1 = ctk.CTkLabel(
347
+ runwindow,
348
+ text="Below two identifers are both required if height-correcting to a tracked baseline.",
349
+ font=(TEXT_FONT_NAME, ADV_CFG_TEXT_FONT_SIZE),
350
+ )
351
+ info_label_1.grid(row=last_sleap_row + 1, column=0)
352
+ info_label_2 = ctk.CTkLabel(
353
+ runwindow,
354
+ text="If not height-correcting, identifier 1 can still be used for differentiating SLEAP files from other files.",
355
+ font=(TEXT_FONT_NAME, ADV_CFG_TEXT_FONT_SIZE),
356
+ )
357
+ info_label_2.grid(row=last_sleap_row + 2, column=0)
358
+ # data string
359
+ data_label, data_entry = gaita_widgets.label_and_entry_pair(
360
+ runwindow,
361
+ "1. Identifier of SLEAP-tracked coordinate files",
362
+ results["data_string"],
363
+ widget_cfg,
364
+ adv_cfg_textsize=True,
365
+ )
366
+ data_label.grid(row=last_sleap_row + 3, column=0)
367
+ data_entry.grid(row=last_sleap_row + 4, column=0)
368
+ # beam string
369
+ beam_label, beam_entry = gaita_widgets.label_and_entry_pair(
370
+ runwindow,
371
+ "2. Identifier of SLEAP-tracked baseline files",
372
+ results["beam_string"],
373
+ widget_cfg,
374
+ adv_cfg_textsize=True,
375
+ )
376
+ beam_label.grid(row=last_sleap_row + 5, column=0)
377
+ beam_entry.grid(row=last_sleap_row + 6, column=0)
378
+ # empty label 3 (for spacing)
379
+ empty_label_three = ctk.CTkLabel(runwindow, text="")
380
+ empty_label_three.grid(row=last_sleap_row + 7, column=0)
381
+ # button confirming being done
382
+ # => change value of user_ready in this call
383
+ finishbutton = ctk.CTkButton(
384
+ runwindow,
385
+ text="I am done, pass the info!",
386
+ fg_color=FG_COLOR,
387
+ hover_color=HOVER_COLOR,
388
+ font=(HEADER_FONT_NAME, HEADER_FONT_SIZE),
389
+ command=lambda: (
390
+ update_config_file(
391
+ results,
392
+ cfg,
393
+ AUTOGAITA_FOLDER_PATH,
394
+ CONFIG_FILE_NAME,
395
+ LIST_VARS,
396
+ DICT_VARS,
397
+ TK_STR_VARS,
398
+ TK_BOOL_VARS,
399
+ ),
400
+ user_ready.set(1),
401
+ ),
402
+ )
403
+ if tracking_software == "DLC":
404
+ finishbutton_row = r + 20
405
+ elif tracking_software == "SLEAP":
406
+ finishbutton_row = last_sleap_row + 8
407
+ finishbutton.grid(
408
+ row=finishbutton_row, column=0, rowspan=2, sticky="nsew", pady=5, padx=70
409
+ )
410
+ # maximise widgets
411
+ gui_utils.maximise_widgets(runwindow)
412
+ # wait until user is ready before returning
413
+ runwindow.wait_variable(user_ready)
414
+ return results