autogaita 1.3.0__tar.gz → 1.3.1__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.
- {autogaita-1.3.0 → autogaita-1.3.1}/PKG-INFO +1 -1
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/common2D/common2D_1_preparation.py +17 -2
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/common2D/common2D_utils.py +16 -3
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/group/group_1_preparation.py +12 -5
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/group_gui.py +1 -2
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/universal3D/universal3D_1_preparation.py +2 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita.egg-info/PKG-INFO +1 -1
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita.egg-info/SOURCES.txt +1 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/setup.py +1 -1
- autogaita-1.3.1/tests/test_common2D_unit_1_preparation.py +334 -0
- autogaita-1.3.1/tests/test_common2D_unit_utils.py +134 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/tests/test_dlc_unit_1_preparation.py +0 -14
- {autogaita-1.3.0 → autogaita-1.3.1}/tests/test_group_unit.py +44 -3
- autogaita-1.3.0/tests/test_common2D_unit_1_preparation.py +0 -240
- {autogaita-1.3.0 → autogaita-1.3.1}/LICENSE +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/README.md +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/__init__.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/__main__.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/batchrun_scripts/__init__.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/batchrun_scripts/dlc_multirun.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/batchrun_scripts/dlc_singlerun.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/batchrun_scripts/group_dlcrun.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/batchrun_scripts/group_dlcrun_forpaper.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/batchrun_scripts/group_universal3Drun.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/batchrun_scripts/sleap_singlerun.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/batchrun_scripts/universal3D_multirun.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/batchrun_scripts/universal3D_singlerun.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/common2D/__init__.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/common2D/common2D_2_sc_extraction.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/common2D/common2D_3_analysis.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/common2D/common2D_4_plots.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/common2D/common2D_constants.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/dlc/__init__.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/dlc/dlc_main.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/group/__init__.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/group/group_2_data_processing.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/group/group_3_PCA.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/group/group_4_stats.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/group/group_5_plots.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/group/group_constants.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/group/group_main.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/group/group_utils.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/__init__.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/common2D_advanced_config_gui.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/common2D_columninfo_gui.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/common2D_gui_constants.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/common2D_gui_utils.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/common2D_main_gui.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/common2D_run_and_done_gui.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/dlc_gui.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/dlc_gui_config.json +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/first_level_gui_utils.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/gaita_widgets.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/group_gui_config.json +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/gui_constants.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/gui_utils.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/main_gui.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/sleap_gui.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/sleap_gui_config.json +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/universal3D_gui.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/gui/universal3D_gui_config.json +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/resources/__init__.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/resources/constants.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/resources/icon.icns +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/resources/icon.ico +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/resources/logo.png +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/resources/pic_to_demo_for_repo.png +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/resources/utils.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/sleap/__init__.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/sleap/sleap_main.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/universal3D/__init__.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/universal3D/universal3D_2_sc_extraction.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/universal3D/universal3D_3_analysis.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/universal3D/universal3D_4_plots.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/universal3D/universal3D_constants.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/universal3D/universal3D_datafile_preparation.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/universal3D/universal3D_main.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita/universal3D/universal3D_utils.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita.egg-info/dependency_links.txt +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita.egg-info/requires.txt +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/autogaita.egg-info/top_level.txt +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/setup.cfg +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/tests/__init__.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/tests/test_common2D_unit_2_sc_extraction.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/tests/test_common2D_unit_3_analysis.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/tests/test_dlc_approval.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/tests/test_group_approval.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/tests/test_universal3D_approval.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/tests/test_universal3D_unit_1_preparation.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/tests/test_universal3D_unit_2_sc_extraction.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/tests/test_universal3D_unit_3_analysis.py +0 -0
- {autogaita-1.3.0 → autogaita-1.3.1}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: autogaita
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.1
|
|
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
|
|
@@ -45,6 +45,8 @@ def some_prep(tracking_software, info, folderinfo, cfg):
|
|
|
45
45
|
subtract_beam = cfg["subtract_beam"]
|
|
46
46
|
convert_to_mm = cfg["convert_to_mm"]
|
|
47
47
|
pixel_to_mm_ratio = cfg["pixel_to_mm_ratio"]
|
|
48
|
+
x_sc_broken_threshold = cfg["x_sc_broken_threshold"]
|
|
49
|
+
y_sc_broken_threshold = cfg["y_sc_broken_threshold"]
|
|
48
50
|
standardise_y_at_SC_level = cfg["standardise_y_at_SC_level"]
|
|
49
51
|
invert_y_axis = cfg["invert_y_axis"]
|
|
50
52
|
flip_gait_direction = cfg["flip_gait_direction"]
|
|
@@ -196,7 +198,11 @@ def some_prep(tracking_software, info, folderinfo, cfg):
|
|
|
196
198
|
config_vars_to_json = {
|
|
197
199
|
"sampling_rate": sampling_rate,
|
|
198
200
|
"convert_to_mm": convert_to_mm,
|
|
201
|
+
"pixel_to_mm_ratio": pixel_to_mm_ratio,
|
|
202
|
+
"x_sc_broken_threshold": x_sc_broken_threshold,
|
|
203
|
+
"y_sc_broken_threshold": y_sc_broken_threshold,
|
|
199
204
|
"standardise_y_at_SC_level": standardise_y_at_SC_level,
|
|
205
|
+
"flip_gait_direction": flip_gait_direction,
|
|
200
206
|
"analyse_average_x": analyse_average_x,
|
|
201
207
|
"standardise_x_coordinates": standardise_x_coordinates,
|
|
202
208
|
"x_standardisation_joint": x_standardisation_joint,
|
|
@@ -402,11 +408,20 @@ def check_this_filename_configuration(
|
|
|
402
408
|
prerun_string = folderinfo["prerun_string"]
|
|
403
409
|
whichvideo = "" # initialise
|
|
404
410
|
found_it = False
|
|
411
|
+
# handle leading zeros that we identified previously - if none convert nums to str
|
|
412
|
+
if "leading_mouse_num_zeros" in info.keys():
|
|
413
|
+
mouse_num = info["leading_mouse_num_zeros"] + str(mouse_num)
|
|
414
|
+
else:
|
|
415
|
+
mouse_num = str(mouse_num)
|
|
416
|
+
if "leading_run_num_zeros" in info.keys():
|
|
417
|
+
run_num = info["leading_run_num_zeros"] + str(run_num)
|
|
418
|
+
else:
|
|
419
|
+
run_num = str(run_num)
|
|
405
420
|
for filename in os.listdir(root_dir):
|
|
406
421
|
# the following condition is True for data & beam csv
|
|
407
422
|
if (
|
|
408
|
-
(premouse_string +
|
|
409
|
-
and (prerun_string +
|
|
423
|
+
(premouse_string + mouse_num + postmouse_string in filename)
|
|
424
|
+
and (prerun_string + run_num + postrun_string in filename)
|
|
410
425
|
and (filename.endswith(file_type_string))
|
|
411
426
|
):
|
|
412
427
|
found_it = True
|
|
@@ -64,7 +64,7 @@ def extract_info(tracking_software, folderinfo, in_GUI=False):
|
|
|
64
64
|
for string_addition in FILE_ID_STRING_ADDITIONS:
|
|
65
65
|
try:
|
|
66
66
|
candidate_postmouse_string = string_addition + postmouse_string
|
|
67
|
-
this_mouse_num = find_number(
|
|
67
|
+
this_mouse_num, leading_mouse_num_zeros = find_number(
|
|
68
68
|
filename,
|
|
69
69
|
premouse_string,
|
|
70
70
|
candidate_postmouse_string,
|
|
@@ -87,7 +87,7 @@ def extract_info(tracking_software, folderinfo, in_GUI=False):
|
|
|
87
87
|
for string_addition in FILE_ID_STRING_ADDITIONS:
|
|
88
88
|
try:
|
|
89
89
|
candidate_postrun_string = string_addition + postrun_string
|
|
90
|
-
this_run_num = find_number(
|
|
90
|
+
this_run_num, leading_run_num_zeros = find_number(
|
|
91
91
|
filename, prerun_string, candidate_postrun_string
|
|
92
92
|
)
|
|
93
93
|
except:
|
|
@@ -109,6 +109,14 @@ def extract_info(tracking_software, folderinfo, in_GUI=False):
|
|
|
109
109
|
info["name"].append(this_name)
|
|
110
110
|
info["mouse_num"].append(this_mouse_num)
|
|
111
111
|
info["run_num"].append(this_run_num)
|
|
112
|
+
# if we had to fix leading zeros, make sure to save them so we can use them in
|
|
113
|
+
# move_data_to_folders function later
|
|
114
|
+
# => make sure it's lists of strings because this is needed by the
|
|
115
|
+
# run_singlerun_in_multiruns function later
|
|
116
|
+
if leading_mouse_num_zeros:
|
|
117
|
+
info["leading_mouse_num_zeros"] = [leading_mouse_num_zeros]
|
|
118
|
+
if leading_run_num_zeros:
|
|
119
|
+
info["leading_run_num_zeros"] = [leading_run_num_zeros]
|
|
112
120
|
# this might happen if user entered wrong identifiers or folder
|
|
113
121
|
if len(info["name"]) < 1:
|
|
114
122
|
no_files_message = (
|
|
@@ -146,7 +154,12 @@ def find_number(fullstring, prestring, poststring):
|
|
|
146
154
|
"""Find (mouse/run) number based on user-defined strings in filenames"""
|
|
147
155
|
start_idx = fullstring.find(prestring) + len(prestring)
|
|
148
156
|
end_idx = fullstring.find(poststring)
|
|
149
|
-
|
|
157
|
+
# handle leading zeros
|
|
158
|
+
leading_zeros = ""
|
|
159
|
+
while fullstring[start_idx] == "0" and start_idx < end_idx - 1:
|
|
160
|
+
start_idx += 1
|
|
161
|
+
leading_zeros += "0"
|
|
162
|
+
return int(fullstring[start_idx:end_idx]), leading_zeros
|
|
150
163
|
|
|
151
164
|
|
|
152
165
|
# ........................... SC extraction helpers ..................................
|
|
@@ -28,10 +28,11 @@ def some_prep(folderinfo, cfg):
|
|
|
28
28
|
# Alright so the group pipeline's cfg (and thus, of course, config.json) is a bit
|
|
29
29
|
# special because it includes:
|
|
30
30
|
# 1) first-level config-keys, such as "joints" or "angles", that reflect what has
|
|
31
|
-
# been analysed at the first level.
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
31
|
+
# been analysed at the first level. Some of these are used in group workflow
|
|
32
|
+
# (e.g. tracking_software when plotting or sampling_rate for PCA) and all of
|
|
33
|
+
# these are checked for equivalence across groups when running this without
|
|
34
|
+
# load_dir (see the for g_idx loop below) to ensure we are not comparing
|
|
35
|
+
# different sampling rates or so with a group analysis
|
|
35
36
|
# 2) group-level config-keys, such as "do_permtest" or "PCA_variables" that define
|
|
36
37
|
# how group analysis should be done
|
|
37
38
|
# Now:
|
|
@@ -145,14 +146,20 @@ def some_prep(folderinfo, cfg):
|
|
|
145
146
|
|
|
146
147
|
|
|
147
148
|
def load_previous_runs_first_level_cfg_vars(folderinfo, cfg):
|
|
148
|
-
"""There are
|
|
149
|
+
"""There are a couple "first-level" cfg vars (like "joints") we require for group gaita's workflow - load them here"""
|
|
149
150
|
with open(
|
|
150
151
|
os.path.join(folderinfo["load_dir"], CONFIG_JSON_FILENAME), "r"
|
|
151
152
|
) as config_json_file:
|
|
152
153
|
old_cfg = json.load(config_json_file)
|
|
154
|
+
cfg["sampling_rate"] = old_cfg["sampling_rate"]
|
|
153
155
|
cfg["save_to_xls"] = old_cfg["save_to_xls"]
|
|
154
156
|
cfg["joints"] = old_cfg["joints"]
|
|
155
157
|
cfg["angles"] = old_cfg["angles"]
|
|
158
|
+
cfg["tracking_software"] = old_cfg["tracking_software"]
|
|
159
|
+
if "analyse_average_x" in old_cfg.keys():
|
|
160
|
+
cfg["analyse_average_x"] = old_cfg["analyse_average_x"]
|
|
161
|
+
if "analyse_average_y" in old_cfg.keys():
|
|
162
|
+
cfg["analyse_average_y"] = old_cfg["analyse_average_y"]
|
|
156
163
|
return cfg
|
|
157
164
|
|
|
158
165
|
|
|
@@ -12,7 +12,6 @@ import platform
|
|
|
12
12
|
import json
|
|
13
13
|
import copy
|
|
14
14
|
|
|
15
|
-
|
|
16
15
|
# %% global constants
|
|
17
16
|
from autogaita.gui.gui_constants import (
|
|
18
17
|
GROUP_FG_COLOR,
|
|
@@ -917,7 +916,7 @@ def check_folderinfo_and_cfg(folderinfo, cfg):
|
|
|
917
916
|
for key in inner_dict.keys():
|
|
918
917
|
# check string vars: group dirs & names and results dir
|
|
919
918
|
if key in STRING_VARS:
|
|
920
|
-
if key == "group_dirs" and len(folderinfo["load_dir"])
|
|
919
|
+
if key == "group_dirs" and len(folderinfo["load_dir"]) == 0:
|
|
921
920
|
for g_idx, group_dir in enumerate(inner_dict[key]):
|
|
922
921
|
if not os.path.exists(group_dir):
|
|
923
922
|
this_msg = (
|
|
@@ -30,6 +30,7 @@ def some_prep(info, folderinfo, cfg):
|
|
|
30
30
|
results_dir = info["results_dir"]
|
|
31
31
|
postname_string = folderinfo["postname_string"]
|
|
32
32
|
sampling_rate = cfg["sampling_rate"]
|
|
33
|
+
flip_gait_direction = cfg["flip_gait_direction"]
|
|
33
34
|
standardise_z_at_SC_level = cfg["standardise_z_at_SC_level"]
|
|
34
35
|
analyse_average_y = cfg["analyse_average_y"]
|
|
35
36
|
standardise_y_coordinates = cfg["standardise_y_coordinates"]
|
|
@@ -122,6 +123,7 @@ def some_prep(info, folderinfo, cfg):
|
|
|
122
123
|
config_json_path = os.path.join(group_path, CONFIG_JSON_FILENAME)
|
|
123
124
|
config_vars_to_json = {
|
|
124
125
|
"sampling_rate": sampling_rate,
|
|
126
|
+
"flip_gait_direction": flip_gait_direction,
|
|
125
127
|
"standardise_z_at_SC_level": standardise_z_at_SC_level,
|
|
126
128
|
"analyse_average_y": analyse_average_y,
|
|
127
129
|
"standardise_y_coordinates": standardise_y_coordinates,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: autogaita
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.1
|
|
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
|
|
@@ -77,6 +77,7 @@ tests/__init__.py
|
|
|
77
77
|
tests/test_common2D_unit_1_preparation.py
|
|
78
78
|
tests/test_common2D_unit_2_sc_extraction.py
|
|
79
79
|
tests/test_common2D_unit_3_analysis.py
|
|
80
|
+
tests/test_common2D_unit_utils.py
|
|
80
81
|
tests/test_dlc_approval.py
|
|
81
82
|
tests/test_dlc_unit_1_preparation.py
|
|
82
83
|
tests/test_group_approval.py
|
|
@@ -26,7 +26,7 @@ if platform.system() == "Darwin":
|
|
|
26
26
|
setup(
|
|
27
27
|
name="autogaita",
|
|
28
28
|
python_requires=">=3.10",
|
|
29
|
-
version="1.3.
|
|
29
|
+
version="1.3.1", # rc == release candidate (before release is finished)
|
|
30
30
|
author="Mahan Hosseini",
|
|
31
31
|
description="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.",
|
|
32
32
|
packages=find_packages(),
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
from autogaita.common2D.common2D_1_preparation import (
|
|
2
|
+
move_data_to_folders,
|
|
3
|
+
check_and_expand_cfg,
|
|
4
|
+
check_and_fix_cfg_strings,
|
|
5
|
+
flip_mouse_body,
|
|
6
|
+
some_prep, # note that first input of some_prep is set to "DLC" when not mattering!
|
|
7
|
+
)
|
|
8
|
+
from autogaita.common2D.common2D_utils import extract_info
|
|
9
|
+
import os
|
|
10
|
+
import copy
|
|
11
|
+
import math
|
|
12
|
+
import numpy as np
|
|
13
|
+
import pandas.testing as pdt
|
|
14
|
+
from hypothesis import given, strategies as st, settings, HealthCheck
|
|
15
|
+
import pytest
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# %%.............................. fixtures ..........................................
|
|
19
|
+
# NOTE
|
|
20
|
+
# ----
|
|
21
|
+
# Calling them FIXTURE_extract_... since we have a function called extract_info!
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@pytest.fixture
|
|
25
|
+
def extract_data_using_some_prep(
|
|
26
|
+
fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
27
|
+
):
|
|
28
|
+
data = some_prep(
|
|
29
|
+
"DLC", fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
30
|
+
)
|
|
31
|
+
return data
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@pytest.fixture
|
|
35
|
+
def fixture_extract_info(tmp_path):
|
|
36
|
+
info = {}
|
|
37
|
+
info["mouse_num"] = 15
|
|
38
|
+
info["run_num"] = 3
|
|
39
|
+
info["name"] = "ID " + str(info["mouse_num"]) + " - Run " + str(info["run_num"])
|
|
40
|
+
info["results_dir"] = os.path.join(tmp_path, info["name"])
|
|
41
|
+
return info
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@pytest.fixture
|
|
45
|
+
def fixture_extract_folderinfo():
|
|
46
|
+
folderinfo = {}
|
|
47
|
+
folderinfo["root_dir"] = "tests/test_data/dlc_data"
|
|
48
|
+
folderinfo["sctable_filename"] = (
|
|
49
|
+
"correct_annotation_table.xlsx" # has to be an excel file
|
|
50
|
+
)
|
|
51
|
+
folderinfo["data_string"] = "SIMINewOct"
|
|
52
|
+
folderinfo["beam_string"] = "BeamTraining"
|
|
53
|
+
folderinfo["premouse_string"] = "Mouse"
|
|
54
|
+
folderinfo["postmouse_string"] = "25mm"
|
|
55
|
+
folderinfo["prerun_string"] = "run"
|
|
56
|
+
folderinfo["postrun_string"] = "6DLC"
|
|
57
|
+
return folderinfo
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@pytest.fixture
|
|
61
|
+
def fixture_extract_cfg():
|
|
62
|
+
cfg = {}
|
|
63
|
+
cfg["sampling_rate"] = 100
|
|
64
|
+
cfg["subtract_beam"] = True
|
|
65
|
+
cfg["dont_show_plots"] = True
|
|
66
|
+
cfg["convert_to_mm"] = True
|
|
67
|
+
cfg["pixel_to_mm_ratio"] = 3.76
|
|
68
|
+
cfg["x_sc_broken_threshold"] = 200
|
|
69
|
+
cfg["y_sc_broken_threshold"] = 50
|
|
70
|
+
cfg["x_acceleration"] = True
|
|
71
|
+
cfg["angular_acceleration"] = True
|
|
72
|
+
cfg["save_to_xls"] = True
|
|
73
|
+
cfg["bin_num"] = 25
|
|
74
|
+
cfg["plot_SE"] = True
|
|
75
|
+
cfg["standardise_y_at_SC_level"] = False
|
|
76
|
+
cfg["standardise_y_to_a_joint"] = True
|
|
77
|
+
cfg["y_standardisation_joint"] = ["Knee"]
|
|
78
|
+
cfg["plot_joint_number"] = 3
|
|
79
|
+
cfg["color_palette"] = "viridis"
|
|
80
|
+
cfg["legend_outside"] = True
|
|
81
|
+
cfg["invert_y_axis"] = True
|
|
82
|
+
cfg["flip_gait_direction"] = True
|
|
83
|
+
cfg["analyse_average_x"] = True
|
|
84
|
+
cfg["standardise_x_coordinates"] = True
|
|
85
|
+
cfg["x_standardisation_joint"] = ["Hind paw tao"]
|
|
86
|
+
cfg["coordinate_standardisation_xls"] = ""
|
|
87
|
+
cfg["hind_joints"] = ["Hind paw tao", "Ankle", "Knee", "Hip", "Iliac Crest"]
|
|
88
|
+
cfg["fore_joints"] = [
|
|
89
|
+
"Front paw tao ",
|
|
90
|
+
"Wrist ",
|
|
91
|
+
"Elbow ",
|
|
92
|
+
"Lower Shoulder ",
|
|
93
|
+
"Upper Shoulder ",
|
|
94
|
+
]
|
|
95
|
+
cfg["beam_col_left"] = ["BeamLeft"] # BEAM_COL_LEFT & _RIGHT must be lists of len=1
|
|
96
|
+
cfg["beam_col_right"] = ["BeamRight"]
|
|
97
|
+
cfg["beam_hind_jointadd"] = ["Tail base ", "Tail center ", "Tail tip "]
|
|
98
|
+
cfg["beam_fore_jointadd"] = ["Nose ", "Ear base "]
|
|
99
|
+
cfg["angles"] = {
|
|
100
|
+
"name": ["Ankle ", "Knee ", "Hip "],
|
|
101
|
+
"lower_joint": ["Hind paw tao ", "Ankle ", "Knee "],
|
|
102
|
+
"upper_joint": ["Knee ", "Hip ", "Iliac Crest "],
|
|
103
|
+
}
|
|
104
|
+
return cfg
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
# %%.............................. preparation .......................................
|
|
108
|
+
# AN IMPORTANT NOTE ON THESE UNIT TESTS!
|
|
109
|
+
# Calling check_and_expand cfg outside of some_prep with the
|
|
110
|
+
# export_data_using_some_prep fixture leads to the cfg that is returned by
|
|
111
|
+
# check_and_expand to be None since the data var DOES NOT INCLUDE the beam!
|
|
112
|
+
# => We thus set cfg["subtract_beam"] to False prior to calling it (see e.g.the
|
|
113
|
+
# plot_joint test)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def test_move_data_to_folders_smoke_normal(
|
|
117
|
+
fixture_extract_info, fixture_extract_folderinfo
|
|
118
|
+
):
|
|
119
|
+
move_data_to_folders(
|
|
120
|
+
"DLC", ".csv", fixture_extract_info, fixture_extract_folderinfo
|
|
121
|
+
)
|
|
122
|
+
assert len(os.listdir(fixture_extract_info["results_dir"])) == 3
|
|
123
|
+
for file in os.listdir(fixture_extract_info["results_dir"]):
|
|
124
|
+
if file.endswith(".csv"):
|
|
125
|
+
assert (
|
|
126
|
+
(fixture_extract_folderinfo["premouse_string"] in file)
|
|
127
|
+
& (fixture_extract_folderinfo["postmouse_string"] in file)
|
|
128
|
+
& (fixture_extract_folderinfo["prerun_string"] in file)
|
|
129
|
+
& (fixture_extract_folderinfo["postrun_string"] in file)
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def test_move_data_to_folders_leading_zeros_handled(
|
|
134
|
+
tmp_path, fixture_extract_folderinfo
|
|
135
|
+
):
|
|
136
|
+
# ensure files with leading zeros are moved too
|
|
137
|
+
# => this needs some preparation because I want to test extract_info, too, which is
|
|
138
|
+
# required to output lists in each of its keys because I use it in multiruns to
|
|
139
|
+
# iterate over each idxs which consistute separate runs
|
|
140
|
+
fixture_extract_folderinfo["root_dir"] = (
|
|
141
|
+
"tests/test_data/dlc_data/test_data/leading_zeros/"
|
|
142
|
+
)
|
|
143
|
+
# CARE! function: extract_info for info where we handle leading zeros
|
|
144
|
+
info = extract_info("DLC", fixture_extract_folderinfo)
|
|
145
|
+
info["results_dir"] = tmp_path
|
|
146
|
+
# move_data... creates it, make sure it's not there
|
|
147
|
+
if os.path.exists(info["results_dir"]):
|
|
148
|
+
for file in os.listdir(info["results_dir"]):
|
|
149
|
+
os.remove(os.path.join(info["results_dir"], file))
|
|
150
|
+
os.rmdir(info["results_dir"])
|
|
151
|
+
# now make sure info is not a list
|
|
152
|
+
for key in info:
|
|
153
|
+
if isinstance(info[key], list):
|
|
154
|
+
info[key] = info[key][0]
|
|
155
|
+
move_data_to_folders("DLC", ".csv", info, fixture_extract_folderinfo)
|
|
156
|
+
assert len(os.listdir(info["results_dir"])) == 2
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# %%.......................... cfg & string stuff ....................................
|
|
160
|
+
def test_plot_joint_error(
|
|
161
|
+
extract_data_using_some_prep, fixture_extract_cfg, fixture_extract_info
|
|
162
|
+
):
|
|
163
|
+
fixture_extract_cfg["plot_joint_number"] = 2000
|
|
164
|
+
fixture_extract_cfg["subtract_beam"] = False
|
|
165
|
+
check_and_expand_cfg(
|
|
166
|
+
extract_data_using_some_prep, fixture_extract_cfg, fixture_extract_info
|
|
167
|
+
)
|
|
168
|
+
with open(os.path.join(fixture_extract_info["results_dir"], "Issues.txt")) as f:
|
|
169
|
+
content = f.read()
|
|
170
|
+
assert "we can :)" in content
|
|
171
|
+
fixture_extract_cfg = check_and_expand_cfg(
|
|
172
|
+
extract_data_using_some_prep, fixture_extract_cfg, fixture_extract_info
|
|
173
|
+
)
|
|
174
|
+
assert fixture_extract_cfg["plot_joints"] == fixture_extract_cfg["hind_joints"]
|
|
175
|
+
fixture_extract_cfg["plot_joint_number"] = 2
|
|
176
|
+
fixture_extract_cfg = check_and_expand_cfg(
|
|
177
|
+
extract_data_using_some_prep, fixture_extract_cfg, fixture_extract_info
|
|
178
|
+
)
|
|
179
|
+
assert fixture_extract_cfg["plot_joints"] == fixture_extract_cfg["hind_joints"][:2]
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def test_error_if_no_cfgkey_joints(
|
|
183
|
+
fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
184
|
+
):
|
|
185
|
+
full_cfg = copy.deepcopy(
|
|
186
|
+
fixture_extract_cfg
|
|
187
|
+
) # no referencing here - we need copies!
|
|
188
|
+
for cfg_key in [
|
|
189
|
+
"hind_joints",
|
|
190
|
+
"x_standardisation_joint",
|
|
191
|
+
"y_standardisation_joint",
|
|
192
|
+
]:
|
|
193
|
+
fixture_extract_cfg = copy.deepcopy(full_cfg) # here too!
|
|
194
|
+
fixture_extract_cfg[cfg_key] = ["not_in_data"]
|
|
195
|
+
data = some_prep(
|
|
196
|
+
"DLC", fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
197
|
+
)
|
|
198
|
+
with open(os.path.join(fixture_extract_info["results_dir"], "Issues.txt")) as f:
|
|
199
|
+
content = f.read()
|
|
200
|
+
if cfg_key == "hind_joints":
|
|
201
|
+
assert "hind limb joint names" in content
|
|
202
|
+
elif cfg_key == "x_standardisation_joint":
|
|
203
|
+
assert "x-coordinate standardisation joint" in content
|
|
204
|
+
elif cfg_key == "y_standardisation_joint":
|
|
205
|
+
assert "y-coordinate standardisation joint" in content
|
|
206
|
+
assert data is None
|
|
207
|
+
# cannot loop case of x & y joints being broken
|
|
208
|
+
fixture_extract_cfg = copy.deepcopy(full_cfg)
|
|
209
|
+
fixture_extract_cfg["x_standardisation_joint"] = ["not_in_data"]
|
|
210
|
+
fixture_extract_cfg["y_standardisation_joint"] = ["not_in_data"]
|
|
211
|
+
data = some_prep(
|
|
212
|
+
"DLC", fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
213
|
+
)
|
|
214
|
+
with open(os.path.join(fixture_extract_info["results_dir"], "Issues.txt")) as f:
|
|
215
|
+
content = f.read()
|
|
216
|
+
assert "x & y-coordinate standardisation joint" in content
|
|
217
|
+
assert data is None
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
@given(test_list=st.lists(st.text(), min_size=1))
|
|
221
|
+
@settings(suppress_health_check=[HealthCheck.function_scoped_fixture])
|
|
222
|
+
def test_removal_of_wrong_strings_from_cfg_key(
|
|
223
|
+
test_list, extract_data_using_some_prep, fixture_extract_cfg, fixture_extract_info
|
|
224
|
+
):
|
|
225
|
+
# the following loop is to account for hypothesis randomly generating strings that
|
|
226
|
+
# actually are data columns (happend for "Knee ")
|
|
227
|
+
for i in range(len(test_list)):
|
|
228
|
+
if test_list[i] + "x" in extract_data_using_some_prep.columns:
|
|
229
|
+
test_list.pop(i)
|
|
230
|
+
cfg_key = "hind_joints" # irrelevant since property testing
|
|
231
|
+
fixture_extract_cfg[cfg_key] = test_list
|
|
232
|
+
test_result = check_and_fix_cfg_strings(
|
|
233
|
+
extract_data_using_some_prep, fixture_extract_cfg, cfg_key, fixture_extract_info
|
|
234
|
+
)
|
|
235
|
+
assert not test_result # empty list is falsey
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def test_wrong_data_and_beam_strings(
|
|
239
|
+
fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
240
|
+
):
|
|
241
|
+
fixture_extract_folderinfo["beam_string"] = fixture_extract_folderinfo[
|
|
242
|
+
"data_string"
|
|
243
|
+
]
|
|
244
|
+
some_prep(
|
|
245
|
+
"DLC", fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
246
|
+
)
|
|
247
|
+
with open(os.path.join(fixture_extract_info["results_dir"], "Issues.txt")) as f:
|
|
248
|
+
content = f.read()
|
|
249
|
+
assert "Your data & baseline (beam) identifiers ([G] in our" in content
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def test_wrong_postmouse_string(
|
|
253
|
+
fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
254
|
+
):
|
|
255
|
+
fixture_extract_folderinfo["postmouse_string"] = "this_is_a_test"
|
|
256
|
+
some_prep(
|
|
257
|
+
"DLC", fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
258
|
+
)
|
|
259
|
+
with open(os.path.join(fixture_extract_info["results_dir"], "Issues.txt")) as f:
|
|
260
|
+
content = f.read()
|
|
261
|
+
assert "Unable to identify ANY RELEVANT FILES for" in content
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
# %%........................... dataframe stuff ......................................
|
|
265
|
+
def test_cols_we_added_to_data(
|
|
266
|
+
fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
267
|
+
):
|
|
268
|
+
data = some_prep(
|
|
269
|
+
"DLC", fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
270
|
+
)
|
|
271
|
+
assert (data.columns[0] == "Time") & (data.columns[1] == "Flipped")
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def test_datas_indexing_and_time_column(
|
|
275
|
+
fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
276
|
+
):
|
|
277
|
+
for fixture_extract_cfg["sampling_rate"] in [50, 500, 5000]:
|
|
278
|
+
data = some_prep(
|
|
279
|
+
"DLC", fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
280
|
+
)
|
|
281
|
+
# use isclose here because there are some floating point things going on (eg. 1.
|
|
282
|
+
# 66 and 1.660 for sampling rate of 500)
|
|
283
|
+
assert math.isclose(
|
|
284
|
+
data["Time"].max(),
|
|
285
|
+
(len(data) - 1) / (1 * fixture_extract_cfg["sampling_rate"]),
|
|
286
|
+
rel_tol=1e-9,
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
# %%........................... data manipulation ....................................
|
|
291
|
+
def test_global_min_standardisation(
|
|
292
|
+
fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
293
|
+
):
|
|
294
|
+
fixture_extract_cfg["subtract_beam"] = False
|
|
295
|
+
fixture_extract_cfg["standardise_y_to_a_joint"] = False
|
|
296
|
+
data = some_prep(
|
|
297
|
+
"DLC", fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
298
|
+
)
|
|
299
|
+
y_cols = [c for c in data.columns if c.endswith(" y")]
|
|
300
|
+
assert data[y_cols].min().min() == 0
|
|
301
|
+
# approach here is find difference between global & standardisation joint minma and
|
|
302
|
+
# see if all y cols' difference is equal to that
|
|
303
|
+
# => this implies that joint-based y-standardisation worked
|
|
304
|
+
global_and_standardisation_joints_y_min_diff = data[
|
|
305
|
+
fixture_extract_cfg["y_standardisation_joint"][0] + " y"
|
|
306
|
+
].min()
|
|
307
|
+
global_min_data = data.copy()
|
|
308
|
+
fixture_extract_cfg["standardise_y_to_a_joint"] = True
|
|
309
|
+
data = some_prep(
|
|
310
|
+
"DLC", fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
311
|
+
)
|
|
312
|
+
assert np.allclose( # use np.allclose here because we are comparing arrays
|
|
313
|
+
global_min_data[y_cols],
|
|
314
|
+
data[y_cols] + global_and_standardisation_joints_y_min_diff,
|
|
315
|
+
atol=1e-9,
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def test_flip_mouse_body(
|
|
320
|
+
fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
321
|
+
):
|
|
322
|
+
fixture_extract_cfg["flip_gait_direction"] = False
|
|
323
|
+
test_data = some_prep(
|
|
324
|
+
"DLC", fixture_extract_info, fixture_extract_folderinfo, fixture_extract_cfg
|
|
325
|
+
)
|
|
326
|
+
function_flipped_data = test_data.copy()
|
|
327
|
+
function_flipped_data = flip_mouse_body(test_data, fixture_extract_info)
|
|
328
|
+
x_cols = [col for col in function_flipped_data.columns if col.endswith(" x")]
|
|
329
|
+
global_x_max = max(test_data[x_cols].max())
|
|
330
|
+
for col in x_cols:
|
|
331
|
+
function_flipped_series = function_flipped_data[col]
|
|
332
|
+
function_flipped_series = function_flipped_series.astype(float)
|
|
333
|
+
manually_flipped_series = global_x_max - test_data[col]
|
|
334
|
+
pdt.assert_series_equal(function_flipped_series, manually_flipped_series)
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from autogaita.common2D.common2D_utils import extract_info, find_number
|
|
3
|
+
import os
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# %%.............................. fixtures ..........................................
|
|
8
|
+
# => CALL FIXTURES _fixture SINCE WE HAVE A FUNCTION CALLED extract_info!
|
|
9
|
+
@pytest.fixture
|
|
10
|
+
def fixture_extract_info(tmp_path):
|
|
11
|
+
info = {}
|
|
12
|
+
info["mouse_num"] = 15
|
|
13
|
+
info["run_num"] = 3
|
|
14
|
+
info["name"] = "ID " + str(info["mouse_num"]) + " - Run " + str(info["run_num"])
|
|
15
|
+
info["results_dir"] = os.path.join(tmp_path, info["name"])
|
|
16
|
+
return info
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@pytest.fixture
|
|
20
|
+
def fixture_extract_folderinfo():
|
|
21
|
+
folderinfo = {}
|
|
22
|
+
folderinfo["root_dir"] = "tests/test_data/dlc_data"
|
|
23
|
+
folderinfo["sctable_filename"] = (
|
|
24
|
+
"correct_annotation_table.xlsx" # has to be an excel file
|
|
25
|
+
)
|
|
26
|
+
folderinfo["data_string"] = "SIMINewOct"
|
|
27
|
+
folderinfo["beam_string"] = "BeamTraining"
|
|
28
|
+
folderinfo["premouse_string"] = "Mouse"
|
|
29
|
+
folderinfo["postmouse_string"] = "_25mm"
|
|
30
|
+
folderinfo["prerun_string"] = "run"
|
|
31
|
+
folderinfo["postrun_string"] = "-6DLC"
|
|
32
|
+
return folderinfo
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@pytest.fixture
|
|
36
|
+
def fixture_extract_cfg():
|
|
37
|
+
cfg = {}
|
|
38
|
+
cfg["sampling_rate"] = 100
|
|
39
|
+
cfg["subtract_beam"] = True
|
|
40
|
+
cfg["dont_show_plots"] = True
|
|
41
|
+
cfg["convert_to_mm"] = True
|
|
42
|
+
cfg["pixel_to_mm_ratio"] = 3.76
|
|
43
|
+
cfg["x_sc_broken_threshold"] = 200
|
|
44
|
+
cfg["y_sc_broken_threshold"] = 50
|
|
45
|
+
cfg["x_acceleration"] = True
|
|
46
|
+
cfg["angular_acceleration"] = True
|
|
47
|
+
cfg["save_to_xls"] = True
|
|
48
|
+
cfg["bin_num"] = 25
|
|
49
|
+
cfg["plot_SE"] = True
|
|
50
|
+
cfg["standardise_y_at_SC_level"] = False
|
|
51
|
+
cfg["standardise_y_to_a_joint"] = True
|
|
52
|
+
cfg["y_standardisation_joint"] = ["Knee"]
|
|
53
|
+
cfg["plot_joint_number"] = 3
|
|
54
|
+
cfg["color_palette"] = "viridis"
|
|
55
|
+
cfg["legend_outside"] = True
|
|
56
|
+
cfg["invert_y_axis"] = True
|
|
57
|
+
cfg["flip_gait_direction"] = True
|
|
58
|
+
cfg["analyse_average_x"] = True
|
|
59
|
+
cfg["standardise_x_coordinates"] = True
|
|
60
|
+
cfg["x_standardisation_joint"] = ["Hind paw tao"]
|
|
61
|
+
cfg["coordinate_standardisation_xls"] = ""
|
|
62
|
+
cfg["hind_joints"] = ["Hind paw tao", "Ankle", "Knee", "Hip", "Iliac Crest"]
|
|
63
|
+
cfg["fore_joints"] = [
|
|
64
|
+
"Front paw tao ",
|
|
65
|
+
"Wrist ",
|
|
66
|
+
"Elbow ",
|
|
67
|
+
"Lower Shoulder ",
|
|
68
|
+
"Upper Shoulder ",
|
|
69
|
+
]
|
|
70
|
+
cfg["beam_col_left"] = ["BeamLeft"] # BEAM_COL_LEFT & _RIGHT must be lists of len=1
|
|
71
|
+
cfg["beam_col_right"] = ["BeamRight"]
|
|
72
|
+
cfg["beam_hind_jointadd"] = ["Tail base ", "Tail center ", "Tail tip "]
|
|
73
|
+
cfg["beam_fore_jointadd"] = ["Nose ", "Ear base "]
|
|
74
|
+
cfg["angles"] = {
|
|
75
|
+
"name": ["Ankle ", "Knee ", "Hip "],
|
|
76
|
+
"lower_joint": ["Hind paw tao ", "Ankle ", "Knee "],
|
|
77
|
+
"upper_joint": ["Knee ", "Hip ", "Iliac Crest "],
|
|
78
|
+
}
|
|
79
|
+
return cfg
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# %%.............................. tests ..........................................
|
|
83
|
+
# 1) Test extract_info function
|
|
84
|
+
def test_extract_info_function(fixture_extract_folderinfo):
|
|
85
|
+
# => IT IS CORRECT THAT EXTRACT_INFO RETURNS lists of integers!
|
|
86
|
+
# a. smoke test standard case
|
|
87
|
+
info = extract_info("DLC", fixture_extract_folderinfo)
|
|
88
|
+
assert info["mouse_num"] == [15]
|
|
89
|
+
assert info["run_num"] == [3]
|
|
90
|
+
# b. test that underscores/hyphens are added
|
|
91
|
+
folderinfo = fixture_extract_folderinfo
|
|
92
|
+
folderinfo["postmouse_string"] = "25mm"
|
|
93
|
+
folderinfo["postrun_string"] = "6DLC"
|
|
94
|
+
info = extract_info("DLC", folderinfo)
|
|
95
|
+
assert info["mouse_num"] == [15]
|
|
96
|
+
assert info["run_num"] == [3]
|
|
97
|
+
# c. test that leading zeros are removed
|
|
98
|
+
folderinfo["root_dir"] = "tests/test_data/dlc_data/test_data/leading_zeros/"
|
|
99
|
+
info = extract_info("DLC", folderinfo)
|
|
100
|
+
assert info["mouse_num"] == [12]
|
|
101
|
+
assert info["run_num"] == [3]
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# 2) Test find number function - also for leading zeros
|
|
105
|
+
def test_find_number_valid_case():
|
|
106
|
+
fullstring = "Mouse1_Run002"
|
|
107
|
+
prestring = "Mouse"
|
|
108
|
+
poststring = "_Run"
|
|
109
|
+
result = find_number(fullstring, prestring, poststring)
|
|
110
|
+
assert result == (1, "")
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def test_find_number_prestring_not_found():
|
|
114
|
+
fullstring = "Mouse001_Run002"
|
|
115
|
+
prestring = "Cat"
|
|
116
|
+
poststring = "_Run"
|
|
117
|
+
with pytest.raises(ValueError):
|
|
118
|
+
find_number(fullstring, prestring, poststring)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def test_find_number_poststring_not_found():
|
|
122
|
+
fullstring = "Mouse001_Run002"
|
|
123
|
+
prestring = "Mouse"
|
|
124
|
+
poststring = "_Walk"
|
|
125
|
+
with pytest.raises(ValueError):
|
|
126
|
+
find_number(fullstring, prestring, poststring)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def test_find_number_leading_zeros():
|
|
130
|
+
fullstring = "Mouse001Run002"
|
|
131
|
+
prestring = "Mouse"
|
|
132
|
+
poststring = "Run"
|
|
133
|
+
result = find_number(fullstring, prestring, poststring)
|
|
134
|
+
assert result == (1, "00")
|