autogaita 1.5.2__py3-none-any.whl → 1.5.4__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,173 @@
1
+ Metadata-Version: 2.4
2
+ Name: autogaita
3
+ Version: 1.5.4
4
+ Summary: Automated Gait (and more!) Analysis in Python
5
+ Author-email: Mahan Hosseini <autogaita@fz-juelich.de>
6
+ License: GPLv3
7
+ Project-URL: Homepage, https://github.com/mahan-hosseini/AutoGaitA/
8
+ Project-URL: Documentation, https://docs.google.com/document/d/1iQxSwqBW3VdIXHm-AtV4TGlgpJPDldogVx6qzscsGxA/edit?tab=t.0
9
+ Project-URL: YouTube, https://youtube.com/playlist?list=PLCn5T7K_H8K56NIcEsfDK664OP7cN_Bad&si=JBEYuzDDRe7qz5Qd
10
+ Requires-Python: >=3.10
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: customtkinter>=5.2
14
+ Requires-Dist: pandas<3.0,>=2.0
15
+ Requires-Dist: numpy>=1.24
16
+ Requires-Dist: seaborn>=0.13
17
+ Requires-Dist: matplotlib>=3.7
18
+ Requires-Dist: scikit-learn>=1.2
19
+ Requires-Dist: pingouin>=0.5
20
+ Requires-Dist: scipy>=1.11
21
+ Requires-Dist: scikit-bio>=0.7.1
22
+ Requires-Dist: statsmodels>=0.14
23
+ Requires-Dist: ffmpeg-python>=0.2
24
+ Requires-Dist: openpyxl>=3.1
25
+ Requires-Dist: pillow>=10.3
26
+ Requires-Dist: h5py>=3.11
27
+ Requires-Dist: pyobjc; sys_platform == "darwin"
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest; extra == "dev"
30
+ Requires-Dist: hypothesis; extra == "dev"
31
+ Dynamic: license-file
32
+
33
+ ![AutoGaitA](https://github.com/mahan-hosseini/AutoGaitA/blob/main/autogaita/resources/logo.png?raw=true)
34
+ ![Repository Active](https://www.repostatus.org/badges/latest/active.svg)
35
+ [![Test AutoGaitA](https://github.com/mahan-hosseini/AutoGaitA/actions/workflows/autogaita_test_and_black.yml/badge.svg)](https://github.com/mahan-hosseini/AutoGaitA/actions/workflows/autogaita_test_and_black.yml)
36
+ ![Python](https://img.shields.io/badge/python-v3.10+-blue.svg)
37
+ [![PyPI - Version](https://img.shields.io/pypi/v/autogaita)](https://pypi.org/project/autogaita/)
38
+ ![license: GPL v3](https://img.shields.io/badge/license-GPLv3-blue.svg)
39
+ [![paper: biorxiv](https://img.shields.io/badge/paper-biorxiv-blue)](https://doi.org/10.1101/2024.04.14.589409)
40
+
41
+ ![Black](https://img.shields.io/badge/code%20style-black-000000.svg)
42
+ [![Tutorials](https://img.shields.io/badge/YouTube-red?style=for-the-badge&logo=youtube&logoColor=white)](https://youtube.com/playlist?list=PLCn5T7K_H8K56NIcEsfDK664OP7cN_Bad&feature=shared)
43
+ [![X URL](https://img.shields.io/twitter/url?url=https%3A%2F%2Fx.com%2Fautogaita&style=social&label=updates)](https://x.com/autogaita)
44
+
45
+ # Automated Gait Analysis in Python 🐸
46
+
47
+ - AutoGaitA simplifies, accelerates, and standardises gait analyses (as well as the analysis of other rhythmic behaviours) after body posture tracking in 2D with [DeepLabCut](https://github.com/DeepLabCut/DeepLabCut) and [SLEAP](https://github.com/talmolab/sleap) or marker-based as well as marker-less methods for obtaining 3D coordinates.
48
+ - AutoGaitA's first-level tools provide a wide range of automated kinematic analyses for each input video and AutoGaitA Group allows the comparison of up to six groups.
49
+ - AutoGaitA enables comparisons to be made across experimental conditions, species, disease states or genotypes.
50
+ - Despite being developed with gait data, AutoGaitA can be utilised for the analysis of any motor behaviour.
51
+
52
+ # 🚀 Quick Start (Recommended - no Python needed!)
53
+ This approach uses [uv](https://github.com/astral-sh/uv) for installation. It is really simple to set up:
54
+
55
+ ## 1. Install `uv`
56
+ * **macOS / Linux - Open your terminal & enter:**
57
+ ```bash
58
+ curl -LsSf https://astral.sh/uv/install.sh | sh
59
+ ```
60
+ * **Windows - Open Powershell and enter:**
61
+ ```powershell
62
+ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
63
+ ```
64
+
65
+ ## 2. Install & Run AutoGaitA
66
+ Open your terminal (Mac/Linux) or (restart) PowerShell/CMD (Windows) and run:
67
+
68
+ ```bash
69
+ uv tool install autogaita
70
+ autogaita
71
+ ```
72
+
73
+ **🥳 That's it - AutoGaitA is now installed!**
74
+ You can launch it anytime by opening a terminal and entering `autogaita`.
75
+
76
+ **To update** to the latest release (see the *Releases* panel on the right for the latest versions) open a terminal and enter: `uv tool upgrade autogaita`.
77
+
78
+ # 🐍 Legacy Installation (pip)
79
+ If you prefer to manage your own Python environments, use standard `pip`, or have a version before v1.4.2, you can still install AutoGaitA the traditional way.
80
+
81
+ Please refer to **[Our documentation](https://docs.google.com/document/d/1iQxSwqBW3VdIXHm-AtV4TGlgpJPDldogVx6qzscsGxA/edit?usp=sharing)** for step-by-step instructions on setting up a virtual environment, activating it, and installing via `pip`.
82
+
83
+ For upgrading a pip-installed version activate your virtual environment and enter: `pip install autogaita -U`
84
+
85
+ # Demo Video
86
+ *Check out the video below for a demonstration of AutoGaitA's main workflow!*
87
+ <p><a href="https://youtu.be/_HIZVuUzpzk?feature=shared">
88
+ <img src="https://github.com/mahan-hosseini/AutoGaitA/blob/main/autogaita/resources/pic_to_demo_for_repo.png" width="550">
89
+
90
+ # Tutorials & Examples
91
+
92
+ ## Walkthrough Tutorial Videos
93
+
94
+ **[The AutoGaitA YouTube Channel](https://youtube.com/playlist?list=PLCn5T7K_H8K56NIcEsfDK664OP7cN_Bad&si=mV5p2--nYvbofkPh) provides tutorials for file preparation and instructions on how to use AutoGaitA. This includes in-depth explanations of all details, (main & advanced) configurations, possibilities, and outputs.**
95
+
96
+ *Please note that tutorial videos might not always reflect the most up-to-date version of our toolbox, especially in the beginning when things are regularly changing. We will make sure to record new videos whenever there are major changes though. If updates are just minor we refer to them in the notes below each video. Last tutorial-update was with v1.4.0. (September 2025).*
97
+
98
+ ## Example Data
99
+ We provide an example dataset in the **example data** folder of this repository, with a set of mice walking over differently wide beams and both the beam as well as body coordinates being tracked with DLC. Note that this dataset was used in our tutorial videos introducing *AutoGaitA DLC*, *AutoGaitA Group* and in our video explaining file preparation for *AutoGaitA DLC*. We further provide a **group** folder there that can be used alongside the *AutoGaitA Group* tutorial to confirm that users generate the same set of results following our instructions.
100
+
101
+ ## Annotation Table Examples and Templates
102
+ Annotation Table example and template files for *AutoGaitA DLC* and *AutoGaitA Universal 3D* can be found in the [**annotation tables**](https://github.com/mahan-hosseini/AutoGaitA/tree/main/annotation%20tables) folder of this repository.
103
+
104
+ Users are advised to read the **General Recommendations** section of that folder, use the template to enter their data's timestamp information and to then compare the resulting table with our example to check formatting. Users working with ImageJ/FIJI are encouraged to check out the [AnnotationTable-Plugin](https://github.com/luca-flemming/AnnotationTable-Plugin) developed by our contributor Luca Flemming.
105
+
106
+ # Documentation
107
+
108
+ **[The AutoGaitA Documentation](https://docs.google.com/document/d/1iQxSwqBW3VdIXHm-AtV4TGlgpJPDldogVx6qzscsGxA/edit?usp=sharing) provides complete guidelines on installation, file preparation, AutoGaitA GUIs, using AutoGaitA via the command line, installing FFmpeg for rotating 3D PCA videos, lists known issues and FAQ.**
109
+
110
+ # Two important options
111
+
112
+ ## Custom joints & angles
113
+ **We strongly advise** users to pay attention to the *custom joints and angles* windows of AutoGaitA's first level toolboxes. Please see the relevant links below. These windows allow users to customise which columns of their data should be analysed and how angles should be computed.
114
+
115
+ By default, *AutoGaitA DLC* and *AutoGaitA Universal 3D* implement standard values for mouse and human locomotion, respectively. If your analysis deviates from these standards (e.g. by focussing on another behaviour or a different species) **you must change these values!**
116
+
117
+ **Find out more about *AutoGaitA's custom joints and angles:***
118
+ - [YouTube - AutoGaitA DLC/SLEAP Advanced Configuration](https://youtu.be/MP9g9kXRE_Q?feature=shared)
119
+ - [YouTube - AutoGaitA Universal 3D](https://youtu.be/vZyWmPcI6ao)
120
+ - [Documentation - AutoGaitA DLC/SLEAP](https://docs.google.com/document/d/1iQxSwqBW3VdIXHm-AtV4TGlgpJPDldogVx6qzscsGxA/edit?tab=t.0#heading=h.20bg7b7ymt0b)
121
+ - [Documentation - AutoGaitA Universal 3D](https://docs.google.com/document/d/1iQxSwqBW3VdIXHm-AtV4TGlgpJPDldogVx6qzscsGxA/edit?tab=t.0#heading=h.uz61bpmua7qz)
122
+
123
+ ## Bin number of step cycle normalisation
124
+ An important step in AutoGaitA is normalising step cycles (or instances of other behaviours) to a uniform length before calculating the video-level average. This uniform length is called *bin number*, must be set by users and defaults to a value of 25.
125
+
126
+ Step cycles are normalised via averaging temporally adjacent data points if their original length was larger than the bin number and repeating values if they were shorter originally. Examples are provided here:
127
+ - [Documentation/AutoGaitA DLC/Main Configuration/Option #6](https://docs.google.com/document/d/1iQxSwqBW3VdIXHm-AtV4TGlgpJPDldogVx6qzscsGxA/edit?tab=t.0#heading=h.bboivsfqr2lz).
128
+
129
+ **We strongly advise** users to think carefully about an appropriate bin number for their datasets. The correct value varies and depends strongly on the studied species, behaviour and the frame rate of cameras.
130
+
131
+ # 2D Kinematics in AutoGaitA Universal 3D
132
+ **We strongly advise** AutoGaitA Universal 3D users to carefully consider how our toolbox computes kinematics in 2D, i.e., angles along the y/z-plane and velocities along the y-dimensions. For more information, please see the corresponding **[important note on 2D kinematics in our documentation](https://docs.google.com/document/d/1iQxSwqBW3VdIXHm-AtV4TGlgpJPDldogVx6qzscsGxA/edit?tab=t.0#heading=h.xc5ome7hzfid)**.
133
+
134
+ # Analysing other behaviours - AutoCyclA 🚴
135
+ Even though AutoGaitA's main focus is to automate and standardise gait analyses, our toolbox can be used to automate the analyses of any rhythmic behaviour of interest. For a proof-of-principle demonstration and an introduction of the general workflow of such analyses, see **[AutoCyclA - Automated Cycling Analysis with AutoGaitA.](https://github.com/mahan-hosseini/AutoGaitA/tree/main/autocycla)**
136
+
137
+ # Updating AutoGaitA
138
+ It is strongly recommended that AutoGaitA is kept up to date since new features and important bugfixes are provided regularly.
139
+
140
+ AutoGaitA's cfg files and dictionaries sometimes change as a result, which means that previously generated first-level *Results* folders cannot always be analysed with AutoGaitA Group after an update. In such cases, it is recommended to re-run first-level analyses.
141
+
142
+ We document each version's cfg-changes in [AutoGaitA Releases](https://github.com/mahan-hosseini/AutoGaitA/releases), which is particularly relevant for users wrapping custom scripts around AutoGaitA's functions.
143
+
144
+ # Reference
145
+ If you use this code or data please [cite our preprint](https://doi.org/10.1101/2024.04.14.589409).
146
+
147
+ # License
148
+ AutoGaitA is licensed under [GPL v3.0](https://github.com/mahan-hosseini/AutoGaitA/blob/main/LICENSE) and Forschungszentrum Jülich GmbH holds all copyrights.
149
+
150
+ The AutoGaitA software is provided without warranty of any kind, express or implied, including, but not limited to, the implied warranty of fitness for a particular purpose.
151
+
152
+ # Authors
153
+ [Mahan Hosseini](https://github.com/mahan-hosseini)
154
+
155
+ # Contributors
156
+ [Kishan Thambu](https://github.com/thambukishan) - Undergraduate Student
157
+
158
+ [Sarah Sabbagh](https://github.com/sarahhsabbagh) - Undergraduate Student
159
+
160
+ [Luca Flemming](https://github.com/luca-flemming) - Undergraduate Student
161
+
162
+ [Nicholas del Grosso](https://github.com/nickdelgrosso) - RSE Advisor
163
+
164
+ # Contributing
165
+ If you would like to contribute to the AutoGaitA toolbox, feel free to open a pull request or contact us at autogaita@fz-juelich.de!
166
+
167
+ We are looking forward to your input and ideas 😊
168
+
169
+ # Archive
170
+ We have archived the resources of outdated AutoGaitA versions here:
171
+
172
+ - v0.4.1 - [Documentation](https://docs.google.com/document/d/1Y4wrrsjs0ybLDKPzE2LAatqPDq9jtwjIuk4M0jRZ3wE/edit?usp=sharing)
173
+ - v0.3.1 - [YouTube Tutorials](https://youtube.com/playlist?list=PLCn5T7K_H8K776DLuXKoPsUpI6Yb0NU33&si=7ZAAvcrPxR7WsB8a) & [Documentation](https://docs.google.com/document/d/11mJd7jUHk7joQ0BdZT98CJRrIANdyosMQMJGFtp6yR4/edit?usp=sharing)
@@ -65,23 +65,16 @@ autogaita/universal3D/universal3D_constants.py,sha256=r_bum9iHOoooVATZYXWPuv8a-V
65
65
  autogaita/universal3D/universal3D_datafile_preparation.py,sha256=rb1aaTVjM0fBH7cZb1zj_GZCtaizkCmIAk5UbBjNmCY,8409
66
66
  autogaita/universal3D/universal3D_main.py,sha256=V1SStyH3o8fOyYvFz-5tgHnnWg6AFkxVv_RW720K6M8,4613
67
67
  autogaita/universal3D/universal3D_utils.py,sha256=7HdqNrtWrSXRPnr7e3nUVH1OHC2SyZXqL1iphb-Q8ho,692
68
- autogaita-1.5.2.dist-info/licenses/LICENSE,sha256=YF6QR6Vjxcg5b_sYIyqkME7FZYau5TfEUGTG-0JeRK0,35129
69
- tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
- tests/test_common2D_unit_1_preparation.py,sha256=1YTbjZ4TDmn3KOht5O5_5reWztfKLZcgkuevcCektAY,13682
71
- tests/test_common2D_unit_2_sc_extraction.py,sha256=m5rtQZt3WQiserAW5LYDf-vLW13c7gAbGFcK7RjtMIg,13016
72
- tests/test_common2D_unit_3_analysis.py,sha256=YV6Ikog6XjFHG7Q4l8fgU6t36rTLSStID6LqqLGUY24,8432
73
- tests/test_common2D_unit_utils.py,sha256=TSpL0MoWTMmHadCy2FCv3i0izDMCujwDQYbdjRNLeiA,4759
74
- tests/test_dlc_approval.py,sha256=2_sZ4Unqb-2D-LZvfV4glfvDkOOisUTDXkTJnUWoyMM,3785
75
- tests/test_dlc_unit_1_preparation.py,sha256=zazG2JedU7wjnSdoVprTzrmao-SANDkotq_kn_FKRCE,4126
76
- tests/test_group_approval.py,sha256=istem-MPce_6KYZguLfi4oWCelaPM9l16kqQIE8_hN0,5931
77
- tests/test_group_unit.py,sha256=KbrlQbTnQ5kAQBhxHYUVdoV4qayIpJ1EcIsOavvyjP8,17555
78
- tests/test_universal3D_approval.py,sha256=CW3Wv223kotVG6zXPC0NppjjJsFYsgqUS08Ra8JAyX0,2847
79
- tests/test_universal3D_unit_1_preparation.py,sha256=DkZUanrWZP62jCexcXRaneTfQu12QWI8ERImaPOnMSw,2645
80
- tests/test_universal3D_unit_2_sc_extraction.py,sha256=S7bsK_fH2t6BQDqyF8j_0WwzVkQcrmhFXBBxUBjneQU,3759
81
- tests/test_universal3D_unit_3_analysis.py,sha256=T9qDctQmWZckyXk1ZnB29oyEMUHZbyiMS73UdRnQNGs,9650
82
- tests/test_utils.py,sha256=HZXcLqwU0vmtMjcm1yKd3AxRwSlPmP_CJoTpegBuHVk,16025
83
- autogaita-1.5.2.dist-info/METADATA,sha256=zxSJgsG5dCZA86wSDSDhrIB-RioRyTijZ7MJ2xZKPgU,1304
84
- autogaita-1.5.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
85
- autogaita-1.5.2.dist-info/entry_points.txt,sha256=IKvf_HCQ2RYkvfkSGFMT4ZFNcgRxw_EXkvXTuzCSyhU,61
86
- autogaita-1.5.2.dist-info/top_level.txt,sha256=y3YIdOoEdvhqc_IIerW_M2MAQaLOuZysJEyivyebxQw,16
87
- autogaita-1.5.2.dist-info/RECORD,,
68
+ autogaita-1.5.4.dist-info/licenses/LICENSE,sha256=YF6QR6Vjxcg5b_sYIyqkME7FZYau5TfEUGTG-0JeRK0,35129
69
+ autogaita_backup/common2D_run_and_done_gui.py,sha256=Uyd2aVUbEkER1W5UroEx5_8-BzcYQxDDi6jeXKaj0i8,15813
70
+ autogaita_backup/dlc_1_preparation.py,sha256=_jkyeGqrl0CpK1cF-P7HUQfpHAyqJ33a66wIWZwrDVo,18845
71
+ autogaita_backup/dlc_2_sc_extraction.py,sha256=6rQrAT8Nv7ko2xkEJ17sB-bPpQiHHUSFuJa-o70i79Y,9791
72
+ autogaita_backup/dlc_gui.py,sha256=aV86NuyzaQcR2Q13vO8Ab3ybAAqDGUROSyHaeL91uX4,12443
73
+ autogaita_backup/sleap_1_preparation.py,sha256=5UHSMC-cG7C9pUW2W6oaJbGVnSCOAo6Isy1aeA5qDzo,12616
74
+ autogaita_backup/sleap_2_sc_extraction.py,sha256=9Csf0UNDof3wNyeYOBsQRmBGvhhLohQqz-JK0N1LGY4,7394
75
+ autogaita_backup/sleap_gui.py,sha256=bxi7_qC4jiRnwi-Cop-GkLwfyiU4q7up_cFRSxR_hyk,12592
76
+ autogaita-1.5.4.dist-info/METADATA,sha256=gjDgfC9XIhOaCv7rkzxnev6JkPgspGoHDZPK_eFhRI4,12263
77
+ autogaita-1.5.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
78
+ autogaita-1.5.4.dist-info/entry_points.txt,sha256=IKvf_HCQ2RYkvfkSGFMT4ZFNcgRxw_EXkvXTuzCSyhU,61
79
+ autogaita-1.5.4.dist-info/top_level.txt,sha256=WxScRyWN9Rg5YuMUN8oVTmzarKCzHoPPIDiaQYf9gEQ,27
80
+ autogaita-1.5.4.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ autogaita
2
+ autogaita_backup
@@ -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