autogaita 1.0.3__tar.gz → 1.0.5__tar.gz

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.
Files changed (88) hide show
  1. {autogaita-1.0.3 → autogaita-1.0.5}/PKG-INFO +1 -1
  2. autogaita-1.0.5/autogaita/batchrun_scripts/group_dlcrun.py +112 -0
  3. autogaita-1.0.3/autogaita/batchrun_scripts/group_dlcrun.py → autogaita-1.0.5/autogaita/batchrun_scripts/group_dlcrun_forpaper.py +36 -91
  4. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/batchrun_scripts/group_universal3Drun.py +1 -0
  5. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/group/group_1_preparation.py +50 -34
  6. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/group/group_2_data_processing.py +72 -3
  7. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/group/group_4_stats.py +17 -4
  8. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/group/group_main.py +37 -30
  9. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/group/group_utils.py +4 -0
  10. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/gui/group_gui.py +100 -59
  11. autogaita-1.0.5/autogaita/gui/group_gui_config.json +42 -0
  12. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/sleap/sleap_1_preparation.py +3 -8
  13. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita.egg-info/PKG-INFO +1 -1
  14. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita.egg-info/SOURCES.txt +1 -0
  15. {autogaita-1.0.3 → autogaita-1.0.5}/setup.py +1 -1
  16. {autogaita-1.0.3 → autogaita-1.0.5}/tests/test_group_approval.py +39 -8
  17. autogaita-1.0.5/tests/test_group_unit.py +278 -0
  18. autogaita-1.0.3/autogaita/gui/group_gui_config.json +0 -114
  19. autogaita-1.0.3/tests/test_group_unit.py +0 -133
  20. {autogaita-1.0.3 → autogaita-1.0.5}/LICENSE +0 -0
  21. {autogaita-1.0.3 → autogaita-1.0.5}/README.md +0 -0
  22. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/__init__.py +0 -0
  23. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/__main__.py +0 -0
  24. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/batchrun_scripts/__init__.py +0 -0
  25. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/batchrun_scripts/dlc_multirun.py +0 -0
  26. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/batchrun_scripts/dlc_singlerun.py +0 -0
  27. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/batchrun_scripts/sleap_singlerun.py +0 -0
  28. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/batchrun_scripts/universal3D_multirun.py +0 -0
  29. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/batchrun_scripts/universal3D_singlerun.py +0 -0
  30. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/common2D/__init__.py +0 -0
  31. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/common2D/common2D_3_analysis.py +0 -0
  32. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/common2D/common2D_4_plots.py +0 -0
  33. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/common2D/common2D_constants.py +0 -0
  34. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/common2D/common2D_utils.py +0 -0
  35. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/dlc/__init__.py +0 -0
  36. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/dlc/dlc_1_preparation.py +0 -0
  37. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/dlc/dlc_2_sc_extraction.py +0 -0
  38. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/dlc/dlc_main.py +0 -0
  39. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/dlc/dlc_utils.py +0 -0
  40. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/group/__init__.py +0 -0
  41. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/group/group_3_PCA.py +0 -0
  42. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/group/group_5_plots.py +0 -0
  43. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/group/group_constants.py +0 -0
  44. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/gui/__init__.py +0 -0
  45. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/gui/dlc_gui.py +0 -0
  46. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/gui/dlc_gui_config.json +0 -0
  47. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/gui/first_level_gui_utils.py +0 -0
  48. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/gui/gaita_widgets.py +0 -0
  49. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/gui/gui_constants.py +0 -0
  50. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/gui/gui_utils.py +0 -0
  51. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/gui/main_gui.py +0 -0
  52. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/gui/sleap_gui.py +0 -0
  53. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/gui/sleap_gui_config.json +0 -0
  54. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/gui/universal3D_gui.py +0 -0
  55. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/gui/universal3D_gui_config.json +0 -0
  56. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/gui/window_2D_advanced_config.py +0 -0
  57. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/gui/window_2D_columninfo.py +0 -0
  58. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/gui/window_2D_run_and_done.py +0 -0
  59. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/resources/__init__.py +0 -0
  60. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/resources/constants.py +0 -0
  61. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/resources/icon.icns +0 -0
  62. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/resources/icon.ico +0 -0
  63. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/resources/logo.png +0 -0
  64. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/resources/pic_to_demo_for_repo.png +0 -0
  65. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/resources/utils.py +0 -0
  66. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/sleap/__init__.py +0 -0
  67. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/sleap/sleap_2_sc_extraction.py +0 -0
  68. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/sleap/sleap_main.py +0 -0
  69. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/universal3D/__init__.py +0 -0
  70. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/universal3D/universal3D_1_preparation.py +0 -0
  71. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/universal3D/universal3D_2_sc_extraction.py +0 -0
  72. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/universal3D/universal3D_3_analysis.py +0 -0
  73. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/universal3D/universal3D_4_plots.py +0 -0
  74. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/universal3D/universal3D_constants.py +0 -0
  75. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/universal3D/universal3D_datafile_preparation.py +0 -0
  76. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/universal3D/universal3D_main.py +0 -0
  77. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita/universal3D/universal3D_utils.py +0 -0
  78. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita.egg-info/dependency_links.txt +0 -0
  79. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita.egg-info/requires.txt +0 -0
  80. {autogaita-1.0.3 → autogaita-1.0.5}/autogaita.egg-info/top_level.txt +0 -0
  81. {autogaita-1.0.3 → autogaita-1.0.5}/setup.cfg +0 -0
  82. {autogaita-1.0.3 → autogaita-1.0.5}/tests/__init__.py +0 -0
  83. {autogaita-1.0.3 → autogaita-1.0.5}/tests/test_common2D_unit_3_main_analysis.py +0 -0
  84. {autogaita-1.0.3 → autogaita-1.0.5}/tests/test_dlc_approval.py +0 -0
  85. {autogaita-1.0.3 → autogaita-1.0.5}/tests/test_dlc_unit_1_preparation.py +0 -0
  86. {autogaita-1.0.3 → autogaita-1.0.5}/tests/test_dlc_unit_2_sc_extraction.py +0 -0
  87. {autogaita-1.0.3 → autogaita-1.0.5}/tests/test_universal3D_approval.py +0 -0
  88. {autogaita-1.0.3 → autogaita-1.0.5}/tests/test_universal3D_unit.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: autogaita
3
- Version: 1.0.3
3
+ Version: 1.0.5
4
4
  Summary: Automatic Gait Analysis in Python. A toolbox to streamline and standardise the analysis of kinematics across species after ML-based body posture tracking. Despite being optimised for gait analyses, AutoGaitA has the potential to be used for any kind of kinematic analysis.
5
5
  Home-page: https://github.com/mahan-hosseini/AutoGaitA/
6
6
  Author: Mahan Hosseini
@@ -0,0 +1,112 @@
1
+ import autogaita
2
+
3
+
4
+ def group_dlcrun():
5
+ """
6
+ Batchrun script to run AutoGaitA Group for Results obtained with AutoGaitA DLC.
7
+ folderinfo & cfg dictionaries must be configured as explained in our documentation. See the "AutoGaitA without the GUI" section of our documentation for references to in-depth explanations to all dictionary keys (note that each key of dicts corresponds to some object in the AutoGaitA Group GUI)
8
+ """
9
+ # folderinfo
10
+ # => Note that length of folderinfo's group_names & group_dirs lists determines how # many groups are compared.
11
+ # => Also note that indices must correspond (i.e., idx # 1's name will be used # for dataset stored in group_dir's idx 1)
12
+ folderinfo = {}
13
+ folderinfo["group_names"] = [
14
+ # RM Dataset
15
+ "5mm",
16
+ "12mm",
17
+ "25mm",
18
+ # Interaction Issue Dataset
19
+ # "Control",
20
+ # "Silenced",
21
+ # Testing Dataset
22
+ # "one",
23
+ # "two",
24
+ ]
25
+ folderinfo["group_dirs"] = [
26
+ # --------------------------
27
+ # Full Dataset (39 subjects)
28
+ # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Sanity Test Interaction Graziana/Result 10 joints/Control Full",
29
+ # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Sanity Test Interaction Graziana/Result 10 joints/Silenced Full/",
30
+ # --------------------------
31
+ # Reduced Dataset (5 subjects)
32
+ # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Sanity Test Interaction Graziana/Result 10 joints/Control",
33
+ # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Sanity Test Interaction Graziana/Result 10 joints/Silenced/",
34
+ # --------------------------
35
+ # Testing Dataset
36
+ # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Testing/Group 1/",
37
+ # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Testing/Group 2/",
38
+ # --------------------------
39
+ # RM Dataset (example data in repo)
40
+ "/Users/mahan/sciebo/PythonCode/gaita_repo/example data/5mm/Results/",
41
+ "/Users/mahan/sciebo/PythonCode/gaita_repo/example data/12mm/Results/",
42
+ "/Users/mahan/sciebo/PythonCode/gaita_repo/example data/25mm/Results/",
43
+ ]
44
+ folderinfo["results_dir"] = (
45
+ "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/example_data_results5/"
46
+ # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Sanity Test Interaction Graziana/Result 10 joints/Mahan Results/"
47
+ # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Testing/GroupResults/"
48
+ )
49
+ folderinfo["load_dir"] = (
50
+ "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/example_data_results/"
51
+ # ""
52
+ )
53
+ # cfg
54
+ cfg = {}
55
+ cfg["do_permtest"] = True
56
+ cfg["do_anova"] = True
57
+ cfg["permutation_number"] = 100
58
+ cfg["PCA_n_components"] = 3
59
+ # cfg["PCA_n_components"] = 0.33
60
+ # cfg["PCA_custom_scatter_PCs"] = "4,5,6;4,5;2,4,6"
61
+ cfg["PCA_custom_scatter_PCs"] = ""
62
+ cfg["PCA_save_3D_video"] = False # True
63
+ cfg["PCA_bins"] = "" # "0-10,24,50-75"
64
+ cfg["stats_threshold"] = 0.05
65
+ cfg["plot_SE"] = False
66
+ cfg["color_palette"] = "viridis"
67
+ cfg["dont_show_plots"] = True
68
+ cfg["legend_outside"] = True
69
+ cfg["which_leg"] = "left"
70
+ cfg["anova_design"] = "RM ANOVA"
71
+ # cfg["anova_design"] = "Mixed ANOVA"
72
+ cfg["permutation_number"] = 100
73
+ cfg["PCA_variables"] = [
74
+ "Hind paw tao y",
75
+ "Ankle y",
76
+ "Knee y",
77
+ "Ankle Angle",
78
+ "Knee Angle",
79
+ "Nose x",
80
+ "Knee y",
81
+ "Knee x",
82
+ "Knee Velocity",
83
+ "Knee Acceleration",
84
+ "Knee Angle",
85
+ "Knee Angle Velocity",
86
+ "Knee Angle Acceleration",
87
+ "Hip Angle",
88
+ ]
89
+ cfg["stats_variables"] = [
90
+ "Hind paw tao y",
91
+ # "Ankle y",
92
+ # "Knee y",
93
+ # "Ankle Angle",
94
+ # "Knee Angle",
95
+ # "Nose x",
96
+ # "Knee y",
97
+ # "Knee x",
98
+ # "Knee Velocity",
99
+ # "Knee Acceleration",
100
+ # "Knee Angle",
101
+ # "Knee Angle Velocity",
102
+ # "Knee Angle Acceleration",
103
+ # "Hip Angle",
104
+ # "Elbow Angle"
105
+ ]
106
+ # run
107
+ autogaita.group(folderinfo, cfg)
108
+
109
+
110
+ # %% what happens if we just hit run
111
+ if __name__ == "__main__":
112
+ group_dlcrun()
@@ -6,26 +6,27 @@ def group_dlcrun():
6
6
  Batchrun script to run AutoGaitA Group for Results obtained with AutoGaitA DLC.
7
7
  folderinfo & cfg dictionaries must be configured as explained in our documentation. See the "AutoGaitA without the GUI" section of our documentation for references to in-depth explanations to all dictionary keys (note that each key of dicts corresponds to some object in the AutoGaitA Group GUI)
8
8
  """
9
- # folderinfo
10
- # => Note that length of folderinfo's group_names & group_dirs lists determines how # many groups are compared.
11
- # => Also note that indices must correspond (i.e., idx # 1's name will be used # for dataset stored in group_dir's idx 1)
9
+
10
+ # ----------------------------- 3 Months 3 Beams --------------------------------
11
+ # folderinfo = {}
12
+ # folderinfo["group_names"] = [
13
+ # # RM Dataset
14
+ # "3m_5mm",
15
+ # "3m_12mm",
16
+ # "3m_25mm",
17
+ # ]
18
+ # folderinfo["group_dirs"] = [
19
+ # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/5mm/9w/",
20
+ # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/12mm/9w/",
21
+ # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/25mm/9w/",
22
+ # ]
23
+ # folderinfo["results_dir"] = (
24
+ # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/3Months3BeamsForPaper"
25
+
26
+ # ----------------------------- Old Young 3 Beams --------------------------------
12
27
  folderinfo = {}
13
28
  folderinfo["group_names"] = [
14
- # ----------
15
29
  # RM Dataset
16
- # "5mm",
17
- # "12mm",
18
- # "25mm",
19
- # -------
20
- # Interaction Issue Dataset
21
- # "Control",
22
- # "Silenced",
23
- # --------
24
- # Testing Dataset
25
- # "one",
26
- # "two",
27
- # --------
28
- # Beam x Age for Manuscript
29
30
  "3m_5mm",
30
31
  "3m_12mm",
31
32
  "3m_25mm",
@@ -34,57 +35,37 @@ def group_dlcrun():
34
35
  "24m_25mm",
35
36
  ]
36
37
  folderinfo["group_dirs"] = [
37
- # --------------------------
38
- # Full Dataset (39 subjects)
39
- # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Sanity Test Interaction Graziana/Result 10 joints/Control Full",
40
- # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Sanity Test Interaction Graziana/Result 10 joints/Silenced Full/",
41
- # --------------------------
42
- # Reduced Dataset (5 subjects)
43
- # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Sanity Test Interaction Graziana/Result 10 joints/Control",
44
- # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Sanity Test Interaction Graziana/Result 10 joints/Silenced/",
45
- # --------------------------
46
- # Testing Dataset
47
- # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Testing/Group 1/",
48
- # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Testing/Group 2/",
49
- # --------------------------
50
- # RM Dataset (example data in repo)
51
- # "/Users/mahan/sciebo/PythonCode/gaita_repo/example data/5mm/Results/",
52
- # "/Users/mahan/sciebo/PythonCode/gaita_repo/example data/12mm/Results/",
53
- # "/Users/mahan/sciebo/PythonCode/gaita_repo/example data/25mm/Results/",
54
- # --------------------------
55
- # Beam x Age for Manuscript
56
- "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/5mm/9w",
57
- "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/12mm/9w",
58
- "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/25mm/9w",
59
- "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/5mm/104w",
60
- "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/12mm/104w",
61
- "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/25mm/104w"
38
+ "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/5mm/9w/",
39
+ "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/12mm/9w/",
40
+ "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/25mm/9w/",
41
+ "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/5mm/104w/",
42
+ "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/12mm/104w/",
43
+ "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/255mm/104w/",
62
44
  ]
63
45
  folderinfo["results_dir"] = (
64
- # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/example_data_results/"
65
- # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Sanity Test Interaction Graziana/Result 10 joints/Mahan Results/"
66
- # "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Testing/GroupResults/"
67
- "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/YoungOld3BeamsForPaper"
46
+ "/Users/mahan/sciebo/Research/AutoGaitA/Mouse/Full Dataset and Results Nov 2024/YoungOld3BeamsForPaper_v2"
68
47
  )
48
+ folderinfo["load_dir"] = ""
49
+
69
50
  # cfg
70
51
  cfg = {}
71
- cfg["do_permtest"] = False # True
52
+ cfg["do_permtest"] = False
72
53
  cfg["do_anova"] = True
73
- cfg["permutation_number"] = 100
74
- cfg["PCA_n_components"] = 0.9
75
- cfg["PCA_custom_scatter_PCs"] = "1,3;2,3;2,3,4;;;;"
76
- cfg["PCA_save_3D_video"] = False
54
+ cfg["permutation_number"] = 10000
55
+ cfg["PCA_n_components"] = 3
56
+ # cfg["PCA_n_components"] = 0.33
57
+ # cfg["PCA_custom_scatter_PCs"] = "4,5,6;4,5;2,4,6"
58
+ cfg["PCA_custom_scatter_PCs"] = ""
59
+ cfg["PCA_save_3D_video"] = False # True
77
60
  cfg["PCA_bins"] = "" # "0-10,24,50-75"
78
61
  cfg["stats_threshold"] = 0.05
79
62
  cfg["plot_SE"] = True
80
- cfg["color_palette"] = "inferno"
63
+ cfg["color_palette"] = "Set2"
81
64
  cfg["dont_show_plots"] = True
82
65
  cfg["legend_outside"] = True
83
66
  cfg["which_leg"] = "left"
84
67
  cfg["anova_design"] = "RM ANOVA"
85
- # cfg["anova_design"] = "Mixed ANOVA"
86
68
  cfg["PCA_variables"] = [
87
- # Beam x Age
88
69
  "Nose x",
89
70
  "Nose y",
90
71
  "Ear base x",
@@ -144,44 +125,8 @@ def group_dlcrun():
144
125
  "Lower Shoulder Angle Acceleration",
145
126
  "Iliac Crest Angle Velocity",
146
127
  "Iliac Crest Angle Acceleration",
147
-
148
-
149
- # PREVIOUS TESTING FEATURES
150
- # -----------------
151
- # "Hind paw tao y",
152
- # "Ankle y",
153
- # "Knee y",
154
- # "Ankle Angle",
155
- # "Knee Angle",
156
- # "Nose x",
157
- # "Knee y",
158
- # "Knee x",
159
- # "Knee Velocity",
160
- # "Knee Acceleration",
161
- # "Knee Angle",
162
- # "Knee Angle Velocity",
163
- # "Knee Angle Acceleration",
164
- # "Hip Angle",
165
128
  ]
166
129
  cfg["stats_variables"] = [
167
- # "Hind paw tao y",
168
- # "Ankle y",
169
- # "Knee y",
170
- # "Ankle Angle",
171
- # "Knee Angle",
172
- # "Nose x",
173
- # "Knee y",
174
- # "Knee x",
175
- # "Knee Velocity",
176
- # "Knee Acceleration",
177
- # "Knee Angle",
178
- # "Knee Angle Velocity",
179
- # "Knee Angle Acceleration",
180
- # "Hip Angle",
181
- # "Elbow Angle"
182
-
183
-
184
- # Beam x Age
185
130
  "Hip x",
186
131
  "Hip y",
187
132
  "Knee x",
@@ -195,7 +140,7 @@ def group_dlcrun():
195
140
  "Knee Velocity",
196
141
  "Ankle Angle",
197
142
  "Knee Angle",
198
- "Hip Angle"
143
+ "Hip Angle",
199
144
  ]
200
145
  # run
201
146
  autogaita.group(folderinfo, cfg)
@@ -23,6 +23,7 @@ def group_universal3Drun():
23
23
  + cfg["which_leg"]
24
24
  + " leg/"
25
25
  )
26
+ folderinfo["load_dir"] = ""
26
27
  # cfg
27
28
  cfg["do_permtest"] = True
28
29
  cfg["do_anova"] = True
@@ -49,43 +49,59 @@ def some_prep(folderinfo, cfg):
49
49
  if os.path.exists(info_file_path):
50
50
  os.remove(info_file_path)
51
51
 
52
- # extracted_cfg_vars: save_to_xls, PCA stuff & dont show plots
53
- cfg = extract_cfg_vars(folderinfo, cfg)
54
-
55
- # see if there's a config json file and add to cfg dict
56
- for g_idx, group_dir in enumerate(group_dirs):
52
+ # *********** IMPORTANT ***********
53
+ # if load_dir, we have already saved a group config.json (see below before return)
54
+ # => use this and just return the cfg
55
+ # => make sure to write folderinfo["contrast"] manually above as is and then return
56
+ # that folderinfo plus the cfg you load from the file
57
+ if folderinfo["load_dir"]:
57
58
  with open(
58
- os.path.join(group_dir, CONFIG_JSON_FILENAME), "r"
59
+ os.path.join(folderinfo["load_dir"], CONFIG_JSON_FILENAME), "r"
59
60
  ) as config_json_file:
60
- config_vars_from_json = json.load(config_json_file)
61
- for key in config_vars_from_json.keys():
62
- # assigning like this ensure all keys are in all jsons across groups
63
- if g_idx == 0:
64
- cfg[key] = config_vars_from_json[key]
65
- else:
66
- # sanity check for group-differences in cfg variables!
67
- if (key not in cfg.keys()) | (
68
- cfg[key] != config_vars_from_json[key]
69
- ):
70
- error_message = (
71
- "config.json variables differ between groups!"
72
- + "\nPlease make sure that all cfg variables between "
73
- + "groups match & try again!"
74
- )
75
- raise ValueError(error_message)
76
- else:
61
+ cfg = json.load(config_json_file)
62
+ cfg["loaded"] = True # used in a unit test in test_group_unit.py
63
+
64
+ else: # if not, do the below things based on group dirs' configs
65
+ # 1. extracted_cfg_vars: save_to_xls, PCA stuff & dont show plots
66
+ cfg = extract_cfg_vars(folderinfo, cfg)
67
+
68
+ # 2. ennsure each key's across-group-equivalence and then add to cfg dict
69
+ for g_idx, group_dir in enumerate(group_dirs):
70
+ with open(
71
+ os.path.join(group_dir, CONFIG_JSON_FILENAME), "r"
72
+ ) as config_json_file:
73
+ config_vars_from_json = json.load(config_json_file)
74
+ for key in config_vars_from_json.keys():
75
+ # assigning like this ensure all keys are in all jsons across groups
76
+ if g_idx == 0:
77
77
  cfg[key] = config_vars_from_json[key]
78
+ else:
79
+ # sanity check for group-differences in cfg variables!
80
+ if (key not in cfg.keys()) | (
81
+ cfg[key] != config_vars_from_json[key]
82
+ ):
83
+ error_message = (
84
+ "config.json variables differ between groups!"
85
+ + "\nPlease make sure that all cfg variables between "
86
+ + "groups match & try again!"
87
+ )
88
+ raise ValueError(error_message)
89
+ else:
90
+ cfg[key] = config_vars_from_json[key]
78
91
 
79
- # after having checked cfg keys for equivalence, we have to make sure that
80
- # hind_joints is renamed to joints if DLC
81
- # => note that cfg will not be updated (and overwritten from input if Universal 3D so it's)
82
- # okay that we do this
83
- if cfg["tracking_software"] == "DLC":
84
- cfg["joints"] = cfg["hind_joints"]
85
- joints = cfg["joints"]
86
- angles = cfg["angles"]
92
+ # 3. rename hind_joints is to joints if DLC or SLEAP
93
+ if "hind_joints" in cfg.keys():
94
+ cfg["joints"] = cfg["hind_joints"]
87
95
 
88
- # prepare some plotting color stuff
96
+ # ******** IMPORTANT *******
97
+ # => Do the following two things regardless of load_dir:
98
+ # 1. save cfg to json file in results_dir for load_dir capability
99
+ config_json_path = os.path.join(results_dir, CONFIG_JSON_FILENAME)
100
+ if os.path.exists(config_json_path): # overwrite if exists
101
+ os.remove(config_json_path)
102
+ with open(config_json_path, "w") as config_json_file:
103
+ json.dump(cfg, config_json_file)
104
+ # 2. create this plot stuff manually (cycler objects cannot be written to json)
89
105
  cfg["group_color_cycler"] = plt.cycler(
90
106
  "color", sns.color_palette(cfg["color_palette"], len(group_names))
91
107
  )
@@ -93,10 +109,10 @@ def some_prep(folderinfo, cfg):
93
109
  zip(group_names, cfg["group_color_cycler"].by_key()["color"])
94
110
  )
95
111
  cfg["joint_color_cycler"] = plt.cycler(
96
- "color", sns.color_palette(cfg["color_palette"], len(joints))
112
+ "color", sns.color_palette(cfg["color_palette"], len(cfg["joints"]))
97
113
  )
98
114
  cfg["angle_color_cycler"] = plt.cycler(
99
- "color", sns.color_palette(cfg["color_palette"], len(angles["name"]))
115
+ "color", sns.color_palette(cfg["color_palette"], len(cfg["angles"]["name"]))
100
116
  )
101
117
 
102
118
  return folderinfo, cfg
@@ -190,7 +190,7 @@ def bin_num_error_helper_function(folderinfo, dfs, g, group_names, sc_breaks, b)
190
190
  raise ValueError(message)
191
191
 
192
192
 
193
- def test_PCA_and_stats_variables(df, group_name, name, folderinfo, cfg):
193
+ def check_PCA_and_stats_variables(df, group_name, name, folderinfo, cfg):
194
194
  """Tests if PCA & stats variables are present in all groups' datasets"""
195
195
  PCA_variables = cfg["PCA_variables"]
196
196
  stats_variables = cfg["stats_variables"]
@@ -275,7 +275,7 @@ def import_and_combine_dfs(
275
275
  else:
276
276
  df_copy = df.copy()
277
277
  # test: are our PCA & stats variables present in this ID's dataset?
278
- test_PCA_and_stats_variables(df_copy, group_name, name, folderinfo, cfg)
278
+ check_PCA_and_stats_variables(df_copy, group_name, name, folderinfo, cfg)
279
279
  # add some final info & append to group_df
280
280
  if tracking_software == "DLC":
281
281
  # add this run's info to df (& prepare Stepcycle column)
@@ -542,7 +542,6 @@ def idxs_list_to_list_of_SC_lists(idxs):
542
542
 
543
543
  def grand_avg_and_std(avg_dfs, folderinfo, cfg):
544
544
  """Compute the grand averages & standard deviations for all columns of df"""
545
-
546
545
  # unpack
547
546
  group_names = folderinfo["group_names"]
548
547
  results_dir = folderinfo["results_dir"]
@@ -592,3 +591,73 @@ def grand_avg_and_std(avg_dfs, folderinfo, cfg):
592
591
  )
593
592
  save_results_sheet(g_std_dfs[g], save_to_xls, g_std_filepath)
594
593
  return g_avg_dfs, g_std_dfs
594
+
595
+
596
+ # %% ................. local functions #4 - load previous dataframes .................
597
+ def load_previous_runs_dataframes(folderinfo, cfg):
598
+ """If user asked for it load previous runs dataframes instead of generating them (i.e., avg_dfs, g_avg_dfs, g_std_dfs)"""
599
+ avg_dfs = [[]] * len(folderinfo["group_names"])
600
+ g_avg_dfs = [[]] * len(folderinfo["group_names"])
601
+ g_std_dfs = [[]] * len(folderinfo["group_names"])
602
+ for g, group_name in enumerate((folderinfo["group_names"])):
603
+ try:
604
+ avg_dfs[g] = pd.read_excel(
605
+ os.path.join(
606
+ folderinfo["load_dir"],
607
+ group_name + " - " + AVG_GROUP_SHEET_NAME + ".xlsx",
608
+ )
609
+ )
610
+ g_avg_dfs[g] = pd.read_excel(
611
+ os.path.join(
612
+ folderinfo["load_dir"],
613
+ group_name + " - " + G_AVG_GROUP_SHEET_NAME + ".xlsx",
614
+ )
615
+ )
616
+ g_std_dfs[g] = pd.read_excel(
617
+ os.path.join(
618
+ folderinfo["load_dir"],
619
+ group_name + " - " + G_STD_GROUP_SHEET_NAME + ".xlsx",
620
+ )
621
+ )
622
+ except FileNotFoundError:
623
+ error_msg = (
624
+ "\n******************\n! CRITICAL ERROR !\n******************\n"
625
+ + f"Unable to load the data of group '{group_name}' from \n"
626
+ + f"{folderinfo['load_dir']}"
627
+ + "\n\nTry again!"
628
+ )
629
+ print(error_msg)
630
+ write_issues_to_textfile(error_msg, folderinfo)
631
+ raise FileNotFoundError
632
+ # re-index avg_dfs based on unique SC Percentages
633
+ array_of_idxs = np.arange(len(avg_dfs[0][SC_PERCENTAGE_COL].unique()))
634
+ for g in range(len(avg_dfs)):
635
+ repeat_index_this_often = len(avg_dfs[g]) // len(array_of_idxs)
636
+ new_idx = np.tile(array_of_idxs, repeat_index_this_often)
637
+ avg_dfs[g] = avg_dfs[g].set_index(new_idx)
638
+ # check if PCA & stats variables are present in all dataframes
639
+ for g, group_name in enumerate(folderinfo["group_names"]):
640
+ check_PCA_and_stats_variables(
641
+ avg_dfs[g], group_name, "Average", folderinfo, cfg
642
+ )
643
+ check_PCA_and_stats_variables(
644
+ g_avg_dfs[g], group_name, "Grand Average", folderinfo, cfg
645
+ )
646
+ check_PCA_and_stats_variables(
647
+ g_std_dfs[g], group_name, "Grand Standard Deviation", folderinfo, cfg
648
+ )
649
+ # since import_data writes bin_num (running a sanity check before) we have to do
650
+ # it here too. No need to run the sanity check again since that was done previously
651
+ cfg["bin_num"] = len(np.unique(avg_dfs[0][SC_PERCENTAGE_COL]))
652
+ if cfg["bin_num"] * len(np.unique(avg_dfs[0][ID_COL])) != len(avg_dfs[0]):
653
+ error_msg = (
654
+ "\n******************\n! CRITICAL ERROR !\n******************\n"
655
+ + "Something is wrong with your IDs and SC Percentage columns."
656
+ + "\nThere seem to be duplicates. Make sure that this is not the case."
657
+ + "\nOtherwise, run it again without loading your previous run's results."
658
+ )
659
+ print(error_msg)
660
+ write_issues_to_textfile(error_msg, folderinfo)
661
+ raise ValueError(error_msg)
662
+ else:
663
+ return avg_dfs, g_avg_dfs, g_std_dfs, cfg
@@ -446,7 +446,7 @@ def plot_permutation_test_results(
446
446
  if tracking_software in ["DLC", "SLEAP"]:
447
447
  unit = "x in pixels"
448
448
  elif tracking_software == "Universal 3D":
449
- unit = "Y in (your units)"
449
+ unit = "Y"
450
450
  f.supylabel(
451
451
  ylabel_velocity_and_acceleration(feature, unit, sampling_rate),
452
452
  fontsize=STATS_PLOTS_SUPLABEL_SIZE,
@@ -586,6 +586,8 @@ def ANOVA_main(
586
586
  # => note pingouin checks both or sphericity by default
587
587
  if just_do_tukeys is False:
588
588
  ANOVA_result = run_ANOVA(stats_df, stats_var, cfg)
589
+ else:
590
+ ANOVA_result = None
589
591
 
590
592
  # run Tukeys for pairwise comparisons
591
593
  # => always running multiple comparison tests as well. see Prism's doc for why
@@ -894,7 +896,7 @@ def plot_multcomp_results(
894
896
  if tracking_software in ["DLC", "SLEAP"]:
895
897
  unit = "x in pixels"
896
898
  elif tracking_software == "Universal 3D":
897
- unit = "Y in (your units)"
899
+ unit = "Y"
898
900
  f.supylabel(
899
901
  ylabel_velocity_and_acceleration(feature, unit, sampling_rate),
900
902
  fontsize=STATS_PLOTS_SUPLABEL_SIZE,
@@ -995,14 +997,25 @@ def save_stats_summary_to_text(
995
997
  message = ""
996
998
 
997
999
  # only for ANOVA - add the table above contrast loop
998
- if "ANOVA" in which_test:
1000
+ if "ANOVA" in which_test and ANOVA_result is not None:
999
1001
  message = (
1000
1002
  message
1001
1003
  + "\n\n--------------------\nA N O V A T A B L E"
1002
1004
  + "\n--------------------"
1003
1005
  + "\n"
1004
- + str(ANOVA_result)
1005
1006
  )
1007
+ message += "\n" # col header row
1008
+ for col in ANOVA_result.columns:
1009
+ message += f"| {col} | "
1010
+ n_rows, n_cols = np.shape(ANOVA_result)
1011
+ for row_idx in range(n_rows):
1012
+ message += "\n" # new row
1013
+ for col_idx in range(n_cols):
1014
+ val = ANOVA_result.iloc[row_idx, col_idx]
1015
+ if isinstance(val, str):
1016
+ message += f"| {val} | "
1017
+ else:
1018
+ message += f"| {str(round(val, 4))} | "
1006
1019
 
1007
1020
  # contrast specific info
1008
1021
  for contrast in contrasts: