--- a +++ b/Python_tool/MuscleParOptTool/Public_functions.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Thu Mar 25 15:54:35 2021 + +@author: emi +""" +#------ import packages --------- +from lxml import etree +import re + +# adding OpenSim to python script +import sys +sys.path.append('/opt/opensim-core/lib/python3.6/site-packages/') +import opensim +#-------------------------------- + + +def getModelJointDefinitions(osimModel): + + # functon to retun a strcuture for a specifc model, returning a list of the + # joints present in the model and their associated frames and subsequently + # the bodies which make up these joints - operating under the assumption + # that frames are written using the bodyName_offset as naming convention + + # Written by Emiliano Ravera emiliano.ravera@uner.edu.ar as part of the + # Python version of work by Luca Modenese in the parameterisation of muscle + # tendon properties. + + # load model XML file + osimModel_filepath = osimModel.getInputFileName() + osimModel_file = etree.parse(osimModel_filepath) + model = osimModel_file.getroot() + # create an empty dictionary to hold the data + jointStructure = {} + + # Weld Joint type + for joint in model.findall('.//WeldJoint'): + # add the name to the dictionary + jointStructure[joint.get('name')] = {} + # add the parent frame name + jointStructure[joint.get('name')]['parentFrame'] = joint.find('socket_parent_frame').text + # add the child frame name + jointStructure[joint.get('name')]['childFrame'] = joint.find('socket_child_frame').text + # add the parent body + jointStructure[joint.get('name')]['parentBody'] = re.sub('_offset', '', joint.find('socket_parent_frame').text) + # add the child body + jointStructure[joint.get('name')]['childBody'] = re.sub('_offset', '', joint.find('socket_child_frame').text) + # Pin Joint type + for joint in model.findall('.//PinJoint'): + # add the name to the dictionary + jointStructure[joint.get('name')] = {} + # add the parent frame name + jointStructure[joint.get('name')]['parentFrame'] = joint.find('socket_parent_frame').text + # add the child frame name + jointStructure[joint.get('name')]['childFrame'] = joint.find('socket_child_frame').text + # add the parent body + jointStructure[joint.get('name')]['parentBody'] = re.sub('_offset', '', joint.find('socket_parent_frame').text) + # add the child body + jointStructure[joint.get('name')]['childBody'] = re.sub('_offset', '', joint.find('socket_child_frame').text) + # Slider Joint type + for joint in model.findall('.//SliderJoint'): + # add the name to the dictionary + jointStructure[joint.get('name')] = {} + # add the parent frame name + jointStructure[joint.get('name')]['parentFrame'] = joint.find('socket_parent_frame').text + # add the child frame name + jointStructure[joint.get('name')]['childFrame'] = joint.find('socket_child_frame').text + # add the parent body + jointStructure[joint.get('name')]['parentBody'] = re.sub('_offset', '', joint.find('socket_parent_frame').text) + # add the child body + jointStructure[joint.get('name')]['childBody'] = re.sub('_offset', '', joint.find('socket_child_frame').text) + # Ball Joint type + for joint in model.findall('.//BallJoint'): + # add the name to the dictionary + jointStructure[joint.get('name')] = {} + # add the parent frame name + jointStructure[joint.get('name')]['parentFrame'] = joint.find('socket_parent_frame').text + # add the child frame name + jointStructure[joint.get('name')]['childFrame'] = joint.find('socket_child_frame').text + # add the parent body + jointStructure[joint.get('name')]['parentBody'] = re.sub('_offset', '', joint.find('socket_parent_frame').text) + # add the child body + jointStructure[joint.get('name')]['childBody'] = re.sub('_offset', '', joint.find('socket_child_frame').text) + # Ellipsoid Joint type + for joint in model.findall('.//EllipsoidJoint'): + # add the name to the dictionary + jointStructure[joint.get('name')] = {} + # add the parent frame name + jointStructure[joint.get('name')]['parentFrame'] = joint.find('socket_parent_frame').text + # add the child frame name + jointStructure[joint.get('name')]['childFrame'] = joint.find('socket_child_frame').text + # add the parent body + jointStructure[joint.get('name')]['parentBody'] = re.sub('_offset', '', joint.find('socket_parent_frame').text) + # add the child body + jointStructure[joint.get('name')]['childBody'] = re.sub('_offset', '', joint.find('socket_child_frame').text) + # Free Joint type + for joint in model.findall('.//FreeJoint'): + # add the name to the dictionary + jointStructure[joint.get('name')] = {} + # add the parent frame name + jointStructure[joint.get('name')]['parentFrame'] = joint.find('socket_parent_frame').text + # add the child frame name + jointStructure[joint.get('name')]['childFrame'] = joint.find('socket_child_frame').text + # add the parent body + jointStructure[joint.get('name')]['parentBody'] = re.sub('_offset', '', joint.find('socket_parent_frame').text) + # add the child body + jointStructure[joint.get('name')]['childBody'] = re.sub('_offset', '', joint.find('socket_child_frame').text) + # Custom Joint type + for joint in model.findall('.//CustomJoint'): + # add the name to the dictionary + jointStructure[joint.get('name')] = {} + # add the parent frame name + jointStructure[joint.get('name')]['parentFrame'] = joint.find('socket_parent_frame').text + # add the child frame name + jointStructure[joint.get('name')]['childFrame'] = joint.find('socket_child_frame').text + # add the parent body + jointStructure[joint.get('name')]['parentBody'] = re.sub('_offset', '', joint.find('socket_parent_frame').text) + # add the child body + jointStructure[joint.get('name')]['childBody'] = re.sub('_offset', '', joint.find('socket_child_frame').text) + + + return jointStructure + + +# ---------------------------------------------------------------------------- +def getChildBodyJoint(jointStructure, bodyName): + # Functon to return the name of the joint from a specified model and joint + # structure ( generatate using getModelJointDefinitions.m ) , where the + # specified body is the child body + + # Written by Emiliano Ravera emiliano.ravera@uner.edu.ar as part of the + # Python version of work by Luca Modenese in the parameterisation of muscle + # tendon properties. + + # Input: OpenSim model objects + # Output: jointName - the joint where the specified body is the child + + jointName = [] + + for joint in jointStructure: + jointName.append([joint for (key, value) in jointStructure[joint].items() if value == bodyName and key == 'childBody']) + + jointName = list(filter(None, jointName)) + + jointName = jointName[0] + + return jointName + + +# ---------------------------------------------------------------------------- +def getParentBodyJoint(jointStructure, bodyName): + # Functon to return the name of the joint from a specified model and joint + # structure ( generatate using getModelJointDefinitions.m ) , where the + # specified body is the parent body + + # Written by Emiliano Ravera emiliano.ravera@uner.edu.ar as part of the + # Python version of work by Luca Modenese in the parameterisation of muscle + # tendon properties. + + # Input: OpenSim model objects + # Output: jointName - the joint where the specified body is the parent + + jointName = [] + + for joint in jointStructure: + jointName.append([joint for (key, value) in jointStructure[joint].items() if value == bodyName and key == 'parentBody']) + + jointName = list(filter(None, jointName)) + jointName = jointName[0] + + return jointName + +# ---------------------------------------------------------------------------- +def getMuscleAttachBody(osimModel, musclePathPointName): + # Functon to return the name of the muscel path point from a specified model + # and muscle, where the specified body is the parent body + + # Written by Emiliano Ravera emiliano.ravera@uner.edu.ar as part of the + # Python version of work by Luca Modenese in the parameterisation of muscle + # tendon properties. + + # Input: OpenSim model objects + # Output: bodyName - the body for the specified musclepath + + bodyName = [] + # load model XML file + osimModel_filepath = osimModel.getInputFileName() + osimModel_file = etree.parse(osimModel_filepath) + model = osimModel_file.getroot() + + musclePath = model.findall('./' + musclePathPointName) + + for musclePath in model.findall('.//PathPoint'): + if musclePath.get('name') == musclePathPointName: + bodyName = re.sub('/bodyset/', '', musclePath.find('socket_parent_frame').text) + + for musclePath in model.findall('.//ConditionalPathPoint'): + if musclePath.get('name') == musclePathPointName: + bodyName = re.sub('/bodyset/', '', musclePath.find('socket_parent_frame').text) + + for musclePath in model.findall('.//MovingPathPoint'): + if musclePath.get('name') == musclePathPointName: + bodyName = re.sub('/bodyset/', '', musclePath.find('socket_parent_frame').text) + + return bodyName +