config can be dict, dir, None (from current dir)
This commit is contained in:
parent
f23f82c6eb
commit
9dff5d73be
@ -68,18 +68,6 @@ def setup_logging(session_dir):
|
||||
handlers = [logging.handlers.TimedRotatingFileHandler(os.path.join(session_dir, 'logs.txt'), when='D', interval=7), logging.StreamHandler()])
|
||||
|
||||
|
||||
def determine_level():
|
||||
'''
|
||||
Determine the level at which the function is called.
|
||||
Level = 1: called from a Trial folder
|
||||
Level = 2: called from a Participant folder
|
||||
Level = 3: called from a Session folder
|
||||
'''
|
||||
|
||||
level = max([len(root.split(os.sep)) for root,dirs,files in os.walk('.') if 'Config.toml' in files])
|
||||
return level
|
||||
|
||||
|
||||
def recursive_update(dict_to_update, dict_with_new_values):
|
||||
'''
|
||||
Update nested dictionaries without overwriting existing keys in any level of nesting
|
||||
@ -102,62 +90,86 @@ def recursive_update(dict_to_update, dict_with_new_values):
|
||||
return dict_to_update
|
||||
|
||||
|
||||
def read_config_files(level):
|
||||
def determine_level(config_dir):
|
||||
'''
|
||||
Determine the level at which the function is called.
|
||||
Level = 1: Trial folder
|
||||
Level = 2: Participant folder
|
||||
Level = 3: Session folder
|
||||
'''
|
||||
|
||||
len_paths = [len(root.split(os.sep)) for root,dirs,files in os.walk(config_dir) if 'Config.toml' in files]
|
||||
level = max(len_paths) - min(len_paths) + 1
|
||||
return level
|
||||
|
||||
|
||||
def read_config_files(config):
|
||||
'''
|
||||
Read Session, Participant, and Trial configuration files,
|
||||
and output a dictionary with all the parameters.
|
||||
'''
|
||||
|
||||
# Trial level
|
||||
if level == 1:
|
||||
session_config_dict = toml.load(os.path.join('..','..','Config.toml'))
|
||||
participant_config_dict = toml.load(os.path.join('..','Config.toml'))
|
||||
trial_config_dict = toml.load('Config.toml')
|
||||
if type(config)==dict:
|
||||
level = 3 # log_dir = os.getcwd()
|
||||
config_dicts = [config]
|
||||
if config_dicts[0].get('project').get('project_dir') == None:
|
||||
raise ValueError('Please specify the project directory in config_dict:\n \
|
||||
config_dict.get("project").update({"project_dir":"<YOUR_PROJECT_DIRECTORY>"})')
|
||||
else:
|
||||
# if launched without an argument, config == None, else it is the path to the config directory
|
||||
config_dir = ['.' if config == None else config][0]
|
||||
level = determine_level(config_dir)
|
||||
|
||||
session_config_dict = recursive_update(session_config_dict,participant_config_dict)
|
||||
session_config_dict = recursive_update(session_config_dict,trial_config_dict)
|
||||
session_config_dict.get("project").update({"project_dir":os.getcwd()})
|
||||
config_dicts = [session_config_dict]
|
||||
# Trial level
|
||||
if level == 1:
|
||||
session_config_dict = toml.load(os.path.join(config_dir, '..','..','Config.toml'))
|
||||
participant_config_dict = toml.load(os.path.join(config_dir, '..','Config.toml'))
|
||||
trial_config_dict = toml.load(os.path.join(config_dir, 'Config.toml'))
|
||||
|
||||
# Participant level
|
||||
if level == 2:
|
||||
session_config_dict = toml.load(os.path.join('..','Config.toml'))
|
||||
participant_config_dict = toml.load('Config.toml')
|
||||
config_dicts = []
|
||||
# Create config dictionaries for all trials of the participant
|
||||
for (root,dirs,files) in os.walk('.'):
|
||||
if 'Config.toml' in files and root != '.':
|
||||
trial_config_dict = toml.load(os.path.join(root, files[0]))
|
||||
# deep copy, otherwise session_config_dict is modified at each iteration within the config_dicts list
|
||||
temp_dict = deepcopy(session_config_dict)
|
||||
temp_dict = recursive_update(temp_dict,participant_config_dict)
|
||||
temp_dict = recursive_update(temp_dict,trial_config_dict)
|
||||
temp_dict.get("project").update({"project_dir":os.path.join(os.getcwd(), os.path.relpath(root))})
|
||||
if not os.path.basename(root) in temp_dict.get("project").get('exclude_from_batch'):
|
||||
config_dicts.append(temp_dict)
|
||||
session_config_dict = recursive_update(session_config_dict,participant_config_dict)
|
||||
session_config_dict = recursive_update(session_config_dict,trial_config_dict)
|
||||
session_config_dict.get("project").update({"project_dir":config_dir})
|
||||
config_dicts = [session_config_dict]
|
||||
|
||||
# Session level
|
||||
if level == 3:
|
||||
session_config_dict = toml.load('Config.toml')
|
||||
config_dicts = []
|
||||
# Create config dictionaries for all trials of all participants of the session
|
||||
for (root,dirs,files) in os.walk('.'):
|
||||
if 'Config.toml' in files and root != '.':
|
||||
# participant
|
||||
if len(root.split(os.sep)) == 2:
|
||||
participant_config_dict = toml.load(os.path.join(root, files[0]))
|
||||
# trial
|
||||
elif len(root.split(os.sep)) == 3:
|
||||
# Participant level
|
||||
if level == 2:
|
||||
session_config_dict = toml.load(os.path.join(config_dir, '..','Config.toml'))
|
||||
participant_config_dict = toml.load(os.path.join(config_dir, 'Config.toml'))
|
||||
config_dicts = []
|
||||
# Create config dictionaries for all trials of the participant
|
||||
for (root,dirs,files) in os.walk(config_dir):
|
||||
if 'Config.toml' in files and root != config_dir:
|
||||
trial_config_dict = toml.load(os.path.join(root, files[0]))
|
||||
# deep copy, otherwise session_config_dict is modified at each iteration within the config_dicts list
|
||||
temp_dict = deepcopy(session_config_dict)
|
||||
temp_dict = recursive_update(temp_dict,participant_config_dict)
|
||||
temp_dict = recursive_update(temp_dict,trial_config_dict)
|
||||
temp_dict.get("project").update({"project_dir":os.path.join(os.getcwd(), os.path.relpath(root))})
|
||||
if not os.path.relpath(root) in [os.path.relpath(p) for p in temp_dict.get("project").get('exclude_from_batch')]:
|
||||
temp_dict.get("project").update({"project_dir":os.path.join(config_dir, os.path.relpath(root))})
|
||||
if not os.path.basename(root) in temp_dict.get("project").get('exclude_from_batch'):
|
||||
config_dicts.append(temp_dict)
|
||||
|
||||
return config_dicts
|
||||
# Session level
|
||||
if level == 3:
|
||||
session_config_dict = toml.load(os.path.join(config_dir, 'Config.toml'))
|
||||
config_dicts = []
|
||||
# Create config dictionaries for all trials of all participants of the session
|
||||
for (root,dirs,files) in os.walk(config_dir):
|
||||
if 'Config.toml' in files and root != config_dir:
|
||||
# participant
|
||||
if determine_level(root) == 2:
|
||||
participant_config_dict = toml.load(os.path.join(root, files[0]))
|
||||
# trial
|
||||
elif determine_level(root) == 1:
|
||||
trial_config_dict = toml.load(os.path.join(root, files[0]))
|
||||
# deep copy, otherwise session_config_dict is modified at each iteration within the config_dicts list
|
||||
temp_dict = deepcopy(session_config_dict)
|
||||
temp_dict = recursive_update(temp_dict,participant_config_dict)
|
||||
temp_dict = recursive_update(temp_dict,trial_config_dict)
|
||||
temp_dict.get("project").update({"project_dir":os.path.join(config_dir, os.path.relpath(root))})
|
||||
if not os.path.relpath(root) in [os.path.relpath(p) for p in temp_dict.get("project").get('exclude_from_batch')]:
|
||||
config_dicts.append(temp_dict)
|
||||
|
||||
return level, config_dicts
|
||||
|
||||
|
||||
def base_params(config_dict, level):
|
||||
@ -182,23 +194,15 @@ def calibration(config=None):
|
||||
'''
|
||||
Cameras calibration from checkerboards or from qualisys files.
|
||||
|
||||
config is usually deduced from the path the function is called from
|
||||
(see read_config_files(level) function) but it can also be a dictionary
|
||||
config can be a dictionary,
|
||||
or a trial, participant, or session directory path,
|
||||
or the function can be called without an argument, in which case it is the current directory.
|
||||
'''
|
||||
|
||||
from Pose2Sim.calibration import calibrate_cams_all
|
||||
|
||||
if type(config)==dict:
|
||||
level = 3 # log_dir = os.getcwd()
|
||||
config_dict = config
|
||||
if config_dict.get('project').get('project_dir') == None:
|
||||
raise ValueError('Please specify the project directory in config_dict:\n \
|
||||
config_dict.get("project").update({"project_dir":"<YOUR_PROJECT_DIRECTORY>"})')
|
||||
else:
|
||||
# Determine the level at which the function is called (session:3, participant:2, trial:1)
|
||||
level = determine_level()
|
||||
config_dict = read_config_files(level)[0]
|
||||
|
||||
level, config_dicts = read_config_files(config)
|
||||
config_dict = config_dicts[0]
|
||||
session_dir = os.path.realpath([os.getcwd() if level==3 else os.path.join(os.getcwd(), '..') if level==2 else os.path.join(os.getcwd(), '..', '..')][0])
|
||||
config_dict.get("project").update({"project_dir":session_dir})
|
||||
|
||||
|
@ -1,107 +0,0 @@
|
||||
[2023-12-08 12:52:35.337] [info] Loaded model model from file D:\softs\github_david\Openpose-to-Opensim\Pose_from_simu_draft\Model_Pose2Sim_Body25b_scaled.osim
|
||||
[2023-12-08 12:52:35.338] [warning] Couldn't find file 'r_pelvis.vtp'.
|
||||
[2023-12-08 12:52:35.338] [warning] Couldn't find file 'l_pelvis.vtp'.
|
||||
[2023-12-08 12:52:35.339] [warning] Couldn't find file 'sacrum.vtp'.
|
||||
[2023-12-08 12:52:35.339] [warning] Couldn't find file 'femur_r.vtp'.
|
||||
[2023-12-08 12:52:35.339] [warning] Couldn't find file 'r_patella.vtp'.
|
||||
[2023-12-08 12:52:35.339] [warning] Couldn't find file 'tibia_r.vtp'.
|
||||
[2023-12-08 12:52:35.339] [warning] Couldn't find file 'fibula_r.vtp'.
|
||||
[2023-12-08 12:52:35.340] [warning] Couldn't find file 'talus_rv.vtp'.
|
||||
[2023-12-08 12:52:35.341] [warning] Couldn't find file 'foot.vtp'.
|
||||
[2023-12-08 12:52:35.341] [warning] Couldn't find file 'bofoot.vtp'.
|
||||
[2023-12-08 12:52:35.341] [warning] Couldn't find file 'femur_l.vtp'.
|
||||
[2023-12-08 12:52:35.341] [warning] Couldn't find file 'l_patella.vtp'.
|
||||
[2023-12-08 12:52:35.342] [warning] Couldn't find file 'tibia_l.vtp'.
|
||||
[2023-12-08 12:52:35.342] [warning] Couldn't find file 'fibula_l.vtp'.
|
||||
[2023-12-08 12:52:35.342] [warning] Couldn't find file 'talus_lv.vtp'.
|
||||
[2023-12-08 12:52:35.342] [warning] Couldn't find file 'l_foot.vtp'.
|
||||
[2023-12-08 12:52:35.343] [warning] Couldn't find file 'l_bofoot.vtp'.
|
||||
[2023-12-08 12:52:35.343] [warning] Couldn't find file 'lumbar5.vtp'.
|
||||
[2023-12-08 12:52:35.343] [warning] Couldn't find file 'lumbar4.vtp'.
|
||||
[2023-12-08 12:52:35.343] [warning] Couldn't find file 'lumbar3.vtp'.
|
||||
[2023-12-08 12:52:35.343] [warning] Couldn't find file 'lumbar2.vtp'.
|
||||
[2023-12-08 12:52:35.344] [warning] Couldn't find file 'lumbar1.vtp'.
|
||||
[2023-12-08 12:52:35.344] [warning] Couldn't find file 'cerv1sm.vtp'.
|
||||
[2023-12-08 12:52:35.344] [warning] Couldn't find file 'cerv2sm.vtp'.
|
||||
[2023-12-08 12:52:35.344] [warning] Couldn't find file 'cerv3sm.vtp'.
|
||||
[2023-12-08 12:52:35.344] [warning] Couldn't find file 'cerv4sm.vtp'.
|
||||
[2023-12-08 12:52:35.345] [warning] Couldn't find file 'cerv5sm.vtp'.
|
||||
[2023-12-08 12:52:35.345] [warning] Couldn't find file 'cerv6sm.vtp'.
|
||||
[2023-12-08 12:52:35.345] [warning] Couldn't find file 'cerv7.vtp'.
|
||||
[2023-12-08 12:52:35.345] [warning] Couldn't find file 'thoracic12_s.vtp'.
|
||||
[2023-12-08 12:52:35.345] [warning] Couldn't find file 'thoracic11_s.vtp'.
|
||||
[2023-12-08 12:52:35.345] [warning] Couldn't find file 'thoracic10_s.vtp'.
|
||||
[2023-12-08 12:52:35.346] [warning] Couldn't find file 'thoracic9_s.vtp'.
|
||||
[2023-12-08 12:52:35.346] [warning] Couldn't find file 'thoracic8_s.vtp'.
|
||||
[2023-12-08 12:52:35.346] [warning] Couldn't find file 'thoracic7_s.vtp'.
|
||||
[2023-12-08 12:52:35.346] [warning] Couldn't find file 'thoracic6_s.vtp'.
|
||||
[2023-12-08 12:52:35.346] [warning] Couldn't find file 'thoracic5_s.vtp'.
|
||||
[2023-12-08 12:52:35.346] [warning] Couldn't find file 'thoracic4_s.vtp'.
|
||||
[2023-12-08 12:52:35.346] [warning] Couldn't find file 'thoracic3_s.vtp'.
|
||||
[2023-12-08 12:52:35.347] [warning] Couldn't find file 'thoracic2_s.vtp'.
|
||||
[2023-12-08 12:52:35.347] [warning] Couldn't find file 'thoracic1_s.vtp'.
|
||||
[2023-12-08 12:52:35.347] [warning] Couldn't find file 'hat_ribs_scap.vtp'.
|
||||
[2023-12-08 12:52:35.347] [warning] Couldn't find file 'hat_jaw.vtp'.
|
||||
[2023-12-08 12:52:35.347] [warning] Couldn't find file 'hat_skull.vtp'.
|
||||
[2023-12-08 12:52:35.347] [warning] Couldn't find file 'humerus_rv.vtp'.
|
||||
[2023-12-08 12:52:35.348] [warning] Couldn't find file 'ulna_rv.vtp'.
|
||||
[2023-12-08 12:52:35.348] [warning] Couldn't find file 'radius_rv.vtp'.
|
||||
[2023-12-08 12:52:35.348] [warning] Couldn't find file 'pisiform_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.348] [warning] Couldn't find file 'lunate_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.348] [warning] Couldn't find file 'scaphoid_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.348] [warning] Couldn't find file 'triquetrum_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.348] [warning] Couldn't find file 'hamate_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.348] [warning] Couldn't find file 'capitate_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.348] [warning] Couldn't find file 'trapezoid_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.349] [warning] Couldn't find file 'trapezium_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.349] [warning] Couldn't find file 'metacarpal2_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.349] [warning] Couldn't find file 'index_proximal_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.349] [warning] Couldn't find file 'index_medial_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.349] [warning] Couldn't find file 'index_distal_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.349] [warning] Couldn't find file 'metacarpal3_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.349] [warning] Couldn't find file 'middle_proximal_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.349] [warning] Couldn't find file 'middle_medial_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.349] [warning] Couldn't find file 'middle_distal_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.350] [warning] Couldn't find file 'metacarpal4_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.350] [warning] Couldn't find file 'ring_proximal_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.350] [warning] Couldn't find file 'ring_medial_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.350] [warning] Couldn't find file 'ring_distal_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.350] [warning] Couldn't find file 'metacarpal5_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.350] [warning] Couldn't find file 'little_proximal_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.350] [warning] Couldn't find file 'little_medial_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.351] [warning] Couldn't find file 'little_distal_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.351] [warning] Couldn't find file 'metacarpal1_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.351] [warning] Couldn't find file 'thumb_proximal_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.351] [warning] Couldn't find file 'thumb_distal_rvs.vtp'.
|
||||
[2023-12-08 12:52:35.351] [warning] Couldn't find file 'humerus_lv.vtp'.
|
||||
[2023-12-08 12:52:35.352] [warning] Couldn't find file 'ulna_lv.vtp'.
|
||||
[2023-12-08 12:52:35.352] [warning] Couldn't find file 'radius_lv.vtp'.
|
||||
[2023-12-08 12:52:35.352] [warning] Couldn't find file 'pisiform_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.352] [warning] Couldn't find file 'lunate_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.352] [warning] Couldn't find file 'scaphoid_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.352] [warning] Couldn't find file 'triquetrum_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.353] [warning] Couldn't find file 'hamate_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.353] [warning] Couldn't find file 'capitate_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.353] [warning] Couldn't find file 'trapezoid_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.353] [warning] Couldn't find file 'trapezium_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.353] [warning] Couldn't find file 'metacarpal2_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.353] [warning] Couldn't find file 'index_proximal_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.353] [warning] Couldn't find file 'index_medial_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.353] [warning] Couldn't find file 'index_distal_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.353] [warning] Couldn't find file 'metacarpal3_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.354] [warning] Couldn't find file 'middle_proximal_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.354] [warning] Couldn't find file 'middle_medial_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.354] [warning] Couldn't find file 'middle_distal_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.354] [warning] Couldn't find file 'metacarpal4_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.354] [warning] Couldn't find file 'ring_proximal_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.354] [warning] Couldn't find file 'ring_medial_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.354] [warning] Couldn't find file 'ring_distal_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.355] [warning] Couldn't find file 'metacarpal5_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.355] [warning] Couldn't find file 'little_proximal_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.355] [warning] Couldn't find file 'little_medial_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.355] [warning] Couldn't find file 'little_distal_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.355] [warning] Couldn't find file 'metacarpal1_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.355] [warning] Couldn't find file 'thumb_proximal_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.355] [warning] Couldn't find file 'thumb_distal_lvs.vtp'.
|
||||
[2023-12-08 12:52:35.680] [warning] Coordinate.setValue: coordinate pro_sup_r is locked. Unable to change its value.
|
||||
[2023-12-08 12:52:35.758] [warning] Coordinate.setValue: coordinate pro_sup_l is locked. Unable to change its value.
|
156
Pose2Sim/Utilities/reproj_from_trc_calib.py
Normal file
156
Pose2Sim/Utilities/reproj_from_trc_calib.py
Normal file
@ -0,0 +1,156 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
'''
|
||||
##################################################
|
||||
## Reproject 3D points on camera planes ##
|
||||
##################################################
|
||||
|
||||
Build a trc file which stores all real and virtual markers
|
||||
calculated from a .mot motion file and a .osim model file.
|
||||
|
||||
Default: DeepLabCut
|
||||
|
||||
Usage:
|
||||
from Pose2Sim.Utilities import reproj_from_trc_calib; reproj_from_trc_calib.reproj_from_trc_calib_func(r'<input_trc_file>', r'<input_calib_file>', r'<openpose_or_deeplabcut_format>')
|
||||
python -m reproj_from_trc_calib -t input_trc_file -c input_calib_file
|
||||
python -m reproj_from_trc_calib -t input_trc_file -c input_calib_file -o 'openpose'
|
||||
'''
|
||||
|
||||
|
||||
## INIT
|
||||
import os
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import opensim as osim
|
||||
import argparse
|
||||
|
||||
|
||||
## AUTHORSHIP INFORMATION
|
||||
__author__ = "David Pagnon"
|
||||
__copyright__ = "Copyright 2021, Pose2Sim"
|
||||
__credits__ = ["David Pagnon"]
|
||||
__license__ = "BSD 3-Clause License"
|
||||
__version__ = "0.5"
|
||||
__maintainer__ = "David Pagnon"
|
||||
__email__ = "contact@david-pagnon.com"
|
||||
__status__ = "Development"
|
||||
|
||||
|
||||
## FUNCTIONS
|
||||
def get_marker_positions(motion_data, model):
|
||||
'''
|
||||
Get dataframe of marker positions
|
||||
|
||||
INPUTS:
|
||||
- motion_data: .mot file opened with osim.TimeSeriesTable
|
||||
- model: .osim file opened with osim.Model
|
||||
|
||||
OUTPUT:
|
||||
- marker_positions_pd: DataFrame of marker positions
|
||||
'''
|
||||
|
||||
# Markerset
|
||||
marker_set = model.getMarkerSet()
|
||||
marker_set_names = [mk.getName() for mk in list(marker_set)]
|
||||
marker_set_names_xyz = np.array([[m+'_x', m+'_y', m+'_z'] for m in marker_set_names]).flatten()
|
||||
|
||||
# Data
|
||||
times = motion_data.getIndependentColumn()
|
||||
joint_angle_set_names = motion_data.getColumnLabels() # or [c.getName() for c in model.getCoordinateSet()]
|
||||
joint_angle_set_names = [j for j in joint_angle_set_names if not j.endswith('activation')]
|
||||
motion_data_pd = pd.DataFrame(motion_data.getMatrix().to_numpy()[:,:len(joint_angle_set_names)], columns=joint_angle_set_names)
|
||||
|
||||
# Get marker positions at each state
|
||||
state = model.initSystem()
|
||||
marker_positions = []
|
||||
for n,t in enumerate(times):
|
||||
# put the model in the right position
|
||||
for coord in joint_angle_set_names:
|
||||
if not coord.endswith('_tx') and not coord.endswith('_ty') and not coord.endswith('_tz'):
|
||||
value = motion_data_pd.loc[n,coord]*np.pi/180
|
||||
else:
|
||||
value = motion_data_pd.loc[n,coord]
|
||||
model.getCoordinateSet().get(coord).setValue(state,value)
|
||||
# get marker positions
|
||||
marker_positions += [np.array([marker_set.get(mk_name).findLocationInFrame(state, model.getGround()).to_numpy() for mk_name in marker_set_names]).flatten()]
|
||||
marker_positions_pd = pd.DataFrame(marker_positions, columns=marker_set_names_xyz)
|
||||
marker_positions_pd.insert(0, 'time', times)
|
||||
marker_positions_pd.insert(0, 'frame', np.arange(len(times)))
|
||||
|
||||
return marker_positions_pd
|
||||
|
||||
|
||||
def trc_from_mot_osim_func(*args):
|
||||
'''
|
||||
Build a trc file which stores all real and virtual markers
|
||||
calculated from a .mot motion file and a .osim model file.
|
||||
|
||||
Usage:
|
||||
from Pose2Sim.Utilities import trc_from_mot_osim; trc_from_mot_osim.trc_from_mot_osim_func(r'<input_mot_file>', r'<output_osim_file>', r'<trc_output_file>')
|
||||
python -m trc_from_mot_osim -m input_mot_file -o input_osim_file
|
||||
python -m trc_from_mot_osim -m input_mot_file -o input_osim_file -t trc_output_file
|
||||
'''
|
||||
|
||||
try:
|
||||
motion_path = args[0]['input_mot_file'] # invoked with argparse
|
||||
osim_path = args[0]['input_osim_file']
|
||||
if args[0]['trc_output_file'] == None:
|
||||
trc_path = motion_path.replace('.mot', '.trc')
|
||||
else:
|
||||
trc_path = args[0]['trc_output_file']
|
||||
except:
|
||||
motion_path = args[0] # invoked as a function
|
||||
osim_path = args[1]
|
||||
try:
|
||||
trc_path = args[2]
|
||||
except:
|
||||
trc_path = motion_path.replace('.mot', '.trc')
|
||||
|
||||
# Create dataframe with marker positions
|
||||
model = osim.Model(osim_path)
|
||||
motion_data = osim.TimeSeriesTable(motion_path)
|
||||
marker_positions_pd = get_marker_positions(motion_data, model)
|
||||
|
||||
# Trc header
|
||||
times = motion_data.getIndependentColumn()
|
||||
marker_set = model.getMarkerSet()
|
||||
marker_set_names = [mk.getName() for mk in list(marker_set)]
|
||||
|
||||
fps = str(int( 1/ (times[1]-times[0]) / (len(times)-1) ))
|
||||
nb_frames = str(len(times))
|
||||
nb_markers = str(len(marker_set_names))
|
||||
header0_str = 'PathFileType\t4\t(X/Y/Z)\t' + os.path.basename(trc_path)
|
||||
|
||||
header1 = {}
|
||||
header1['DataRate'] = fps
|
||||
header1['CameraRate'] = fps
|
||||
header1['NumFrames'] = nb_frames
|
||||
header1['NumMarkers'] = nb_markers
|
||||
header1['Units'] = 'm'
|
||||
header1['OrigDataRate'] = fps
|
||||
header1['OrigDataStartFrame'] = '0'
|
||||
header1['OrigNumFrames'] = nb_frames
|
||||
header1_str1 = '\t'.join(header1.keys())
|
||||
header1_str2 = '\t'.join(header1.values())
|
||||
|
||||
header2_str1 = 'Frame#\tTime\t' + '\t\t\t'.join([mk.strip() for mk in marker_set_names]) + '\t\t'
|
||||
header2_str2 = '\t\t'+'\t'.join(['X{i}\tY{i}\tZ{i}'.format(i=i+1) for i in range(int(header1['NumMarkers']))])
|
||||
|
||||
header_trc = '\n'.join([header0_str, header1_str1, header1_str2, header2_str1, header2_str2])
|
||||
|
||||
# write data
|
||||
with open(trc_path, 'w') as trc_o:
|
||||
trc_o.write(header_trc+'\n')
|
||||
marker_positions_pd.to_csv(trc_path, header=False, sep = '\t', mode='a', index=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-m', '--input_mot_file', required = True, help='input mot file')
|
||||
parser.add_argument('-o', '--input_osim_file', required = True, help='input osim file')
|
||||
parser.add_argument('-t', '--trc_output_file', required=False, help='trc output file')
|
||||
args = vars(parser.parse_args())
|
||||
|
||||
trc_from_mot_osim_func(args)
|
Loading…
Reference in New Issue
Block a user