def __init__(self, model_input, model_output, xml_input, xml_output, static_path, mass=-1, height=-1, age=-1, remove_unused=True): self.model = osim.Model(model_input) self.model_output = model_output self.model__with_markers_output = model_output.replace( '.osim', '_markers.osim') self.static_path = static_path self.xml_output = xml_output self.time_range = self.time_range_from_static() # initialize scale tool from setup file self.scale_tool = osim.ScaleTool(xml_input) self.set_anthropometry(mass, height, age) # Tell scale tool to use the loaded model self.scale_tool.getGenericModelMaker().setModelFileName(model_input) self.run_model_scaler() self.run_marker_placer() if not remove_unused: self.add_unused_markers()
def check_tasks(self): """Lists tasks that are <apply>'d for markers that either don't exist in the model or are not in the TRC file. Also lists tasks for which there is data, but that are either not in the model or do not have an IK task. """ scale = osm.ScaleTool(self.setup_fpath) tasks = scale.getMarkerPlacer().getIKTaskSet() trc = util.TRCFile(self.marker_trajectories_fpath) trc_names = trc.marker_names model = osm.Model(self.generic_model_fpath) markerset = osm.MarkerSet(self.prescale_markerset_fpath) # Markers with IK tasks but without data. # --------------------------------------- markers_without_data = [] for i in range(tasks.getSize()): task = tasks.get(i) name = task.getName() applied = task.getApply() if applied: if (not name in trc_names) or (not markerset.contains(name)): if task.getConcreteClassName() != 'IKCoordinateTask': markers_without_data.append(name) if markers_without_data != [] and not self.ignore_nonexistant_data: raise Exception('There are IK tasks for the following markers, ' 'yet data does not exist for them: {}'.format( markers_without_data)) del name # Markers for which there is data but they're not specified elsewhere. # -------------------------------------------------------------------- unused_markers = [] for name in trc.marker_names: if (not markerset.contains(name)) or (not tasks.contains(name)): unused_markers.append(name) if unused_markers != []: raise Exception("You have data for the following markers, but " "you are not using them in Scale's IK: {}".format( unused_markers)) # No data for these markers in the model or prescale markerset. # ------------------------------------------------------------- excess_model_markers = [] for im in range(markerset.getSize()): name = markerset.get(im).getName() if not tasks.contains(name): excess_model_markers.append(name) if excess_model_markers != []: raise Exception("The following model markers do not have tasks or " "experimental data: {}".format(excess_model_markers))
def setup_scale_xml(scale_filename: str, trial: str, model: str, output_directory: str, input_directory: str): ''' Rewrites the scale setup xml file for a new trial Inputs: scale_filename: full filename for the template inverse kinematics setup xml file trial: trial name, e.g., "_12Mar_ss_12ms_01" model: model name, e.g., "AB08" directory: output directory name References: Megan Schroeder, 11/01/2014 ''' # Static trc filename static_trc = input_directory + "\\" + model + trial + "_Static.trc" # Create marker_data object to read starting and ending times from trc file marker_data = osim.MarkerData(static_trc) time_range = osim.ArrayDouble() time_range.setitem(0, marker_data.getStartFrameTime()) time_range.setitem(1, marker_data.getLastFrameTime()) # Create scale_tool object scale_tool = osim.ScaleTool(scale_filename) scale_tool.setName(model) # Modify top-level properties # TODO, get height (optional), age (optional) and mass (required) of subject scale_tool.setPathToSubject(model) #scale_tool.setSubjectMass() #scale_tool.setSubjectHeight() #scale_tool.setSubjectAge # Update generic_model_maker generic_model_marker = scale_tool.getGenericModelMaker() generic_model_marker.setModelFileName(model + ".osim") generic_model_marker.setMarkerSetFileName(model + '_Scale_MarkerSet.xml') # Update model_scaler model_scaler = scale_tool.getModelScaler() model_scaler.setApply(True) scale_order = osim.ArrayStr() scale_order.setitem(0, 'Measurements') model_scaler.setScalingOrder(scale_order) measurements_set = model_scaler.getMeasurementSet() measurements_set.assign( osim.MeasurementSet().makeObjectFromFile(model + '_Scale_MarkerSet.xml')) model_scaler.setMarkerFileName(static_trc) model_scaler.setTimeRange(time_range) model_scaler.setPreserveMassDist(True) output_filename = trial + 'TempScaled.osim' model_scaler.setOutputModelFileName(output_filename) ouput_scale_filename = trial + '_ScaleSet.xml' model_scaler.setOutputScaleFileName(ouput_scale_filename)
def scale(): import os import opensim as osim import shutil import directories # Global Directories allDir = list(directories.main(directories)) parentDir = allDir[0] paramsDir = allDir[1] genericDir = allDir[2] subID = allDir[4] subResultsDir = allDir[5] # Get generic Model genericModel = "gait2354_LockedJoints.osim" genericModelFile = genericDir + "/" + genericModel if not os.path.exists(subResultsDir): os.mkdir(subResultsDir) # generic input XML files scaleSetupFull = paramsDir + "/setupScale.xml" markerSetFull = paramsDir + "/markerSet.xml" # Make scale directory if non-existent scaleResultsDir = subResultsDir + "/scale" if os.path.exists(scaleResultsDir): shutil.rmtree(scaleResultsDir, ignore_errors=True) if not os.path.exists(scaleResultsDir): os.mkdir(scaleResultsDir) # Output XML Files outputScaleFile = subID + "_scaleFactors.xml" adjustedMarkerSet = subID + "_movedMarkers.xml" # Output Model Files outputModelFile = subID + ".osim" # Input Data Files dataFiles = parentDir + "/data/osDemo" staticMarkerFile = "subject01_static.trc" staticMarkerFull = dataFiles + "/" + staticMarkerFile shutil.copy(staticMarkerFull, scaleResultsDir + "/" + staticMarkerFile) # Output Data Files staticCoordinates = subID + "_staticCoordinates.mot" # Subject Measurements subjectMass = 72.60000000 # Load Model aModel = osim.Model(genericModelFile) aModel.setName(subID) # Initialize System aModel.initSystem() aState = aModel.initSystem() # Add Marker Set newMarkers = osim.MarkerSet(markerSetFull) aModel.replaceMarkerSet(aState, newMarkers) # Re-initialize State aState = aModel.initSystem() # Get Time Array for .trc file markerData = osim.MarkerData(staticMarkerFull) # Get Initial and Final Time initial_time = markerData.getStartFrameTime() final_time = markerData.getLastFrameTime() # Create an array double and apply the time range TimeArray = osim.ArrayDouble() TimeArray.set(0, initial_time) TimeArray.set(1, final_time) # Scale Tool scaleTool = osim.ScaleTool(scaleSetupFull) scaleTool.setSubjectMass(subjectMass) # GenericModelMaker- # Tell scale tool to use the loaded model scaleTool.getGenericModelMaker().setModelFileName(genericDir + "/" + genericModel) # # Set the Marker Set file (incase a markerset isnt attached to the model) scaleTool.getGenericModelMaker().setMarkerSetFileName(markerSetFull) # ModelScaler- # Whether or not to use the model scaler during scale scaleTool.getModelScaler().setApply(1) # Set the marker file (.trc) to be used for scaling scaleTool.getModelScaler().setMarkerFileName("/" + staticMarkerFile) # set a time range scaleTool.getModelScaler().setTimeRange(TimeArray) # Indicating whether or not to preserve relative mass between segments scaleTool.getModelScaler().setPreserveMassDist(1) # Name of OpenSim model file (.osim) to write when done scaling. scaleTool.getModelScaler().setOutputModelFileName("") # Filename to write scale factors that were applied to the unscaled model (optional) scaleTool.getModelScaler().setOutputScaleFileName(outputScaleFile) # Run model scaler Tool scaleTool.getModelScaler().processModel(aState, aModel, scaleResultsDir, subjectMass) # initialize aState = aModel.initSystem() # # Marker Placer # # Whether or not to use the model scaler during scale scaleTool.getMarkerPlacer().setApply(1) # # Set the marker placer time range scaleTool.getMarkerPlacer().setTimeRange(TimeArray) # # Set the marker file (.trc) to be used for scaling scaleTool.getMarkerPlacer().setStaticPoseFileName("/" + staticMarkerFile) # # Return name to a variable for future use in functions scaledAdjustedModel = scaleTool.getMarkerPlacer().setOutputModelFileName( "/" + outputModelFile) # # Set the output motion filename scaleTool.getMarkerPlacer().setOutputMotionFileName("/" + staticCoordinates) # # Set the output xml of the marker adjustments scaleTool.getMarkerPlacer().setOutputMarkerFileName("/" + adjustedMarkerSet) # # Maximum amount of movement allowed in marker data when averaging scaleTool.getMarkerPlacer().setMaxMarkerMovement(-1) # # Run Marker Placer scaleTool.getMarkerPlacer().processModel(aState, aModel, scaleResultsDir) scaleTool.printToXML(scaleResultsDir + "/" + subID + "_setupScale.xml") # Clear Terminal os.system('cls' if os.name == 'nt' else 'clear') shutil.copy(scaleResultsDir + "/" + outputModelFile, subResultsDir) return ()
def create_scale_setup(self, file_dep, target): # EDIT THESE FIELDS IN PARTICULAR. # -------------------------------- time_range = osm.ArrayDouble() time_range.append(self.init_time) time_range.append(self.final_time) tool = osm.ScaleTool() tool.setName('%s_%s' % (self.study.name, self.subject.name)) tool.setSubjectMass(self.subject.mass) # GenericModelMaker # ================= gmm = tool.getGenericModelMaker() gmm.setModelFileName(os.path.relpath(file_dep['generic_model'], self.results_scale_path)) gmm.setMarkerSetFileName(os.path.relpath(self.prescale_markerset_fname)) # ModelScaler # =========== scaler = tool.getModelScaler() scaler.setPreserveMassDist(True) marker_traj_rel_fpath = os.path.relpath(file_dep['marker_traj'], self.results_scale_path) scaler.setMarkerFileName(marker_traj_rel_fpath) scale_order_str = osm.ArrayStr() scale_order_str.append('manualScale') scale_order_str.append('measurements') scaler.setScalingOrder(scale_order_str) scaler.setTimeRange(time_range) mset = scaler.getMeasurementSet() # Manual scalings # --------------- sset = scaler.getScaleSet() # MarkerPlacer # ============ placer = tool.getMarkerPlacer() placer.setStaticPoseFileName(marker_traj_rel_fpath) placer.setTimeRange(time_range) placer.setOutputModelFileName(os.path.relpath( self.output_model_fpath, self.results_scale_path)) placer.setOutputMotionFileName(os.path.relpath( self.output_motion_fpath, self.results_scale_path)) placer.setOutputMarkerFileName(os.path.relpath( self.output_markerset_fpath, self.results_scale_path)) ikts = util.IKTaskSet(placer.getIKTaskSet()) self.edit_setup_function(util, mset, sset, ikts) # Validate Scales # =============== model = osm.Model(file_dep['generic_model']) bset = model.getBodySet() for iscale in range(sset.getSize()): segment_name = sset.get(iscale).getSegmentName() if not bset.contains(segment_name): raise Exception("You specified a Scale for " "body %s but it's not in the model." % segment_name) if not os.path.exists(self.results_scale_path): os.makedirs(self.results_scale_path) tool.printToXML(target['setup'])
static = c3d.read(staticFile[0]) markersStatic = c3d.getMarkersTable(static) #Write static data to file trc.write(markersStatic, staticFile[0].split('.')[0]+'.trc') #Set variable for static trial trc staticTrial_trc = staticFile[0].split('.')[0]+'.trc' #Set scale time range scaleTimeRange = osim.ArrayDouble() scaleTimeRange.set(0,osim.Storage(staticTrial_trc).getFirstTime()) scaleTimeRange.set(1,osim.Storage(staticTrial_trc).getFirstTime()+0.5) #Set-up scale tool scaleTool.append(osim.ScaleTool()) #Set mass in scale tool scaleTool[ii-startInd].setSubjectMass(mass) #Set generic model file scaleTool[ii-startInd].getGenericModelMaker().setModelFileName(genModelFileName) #Set the measurement set scaleTool[ii-startInd].getModelScaler().setMeasurementSet(measurementSet) #Set scale tasks for k in range(0,scaleTaskSet.getSize()-1): scaleTool[ii-startInd].getMarkerPlacer().getIKTaskSet().adoptAndAppend(scaleTaskSet.get(k)) #Set marker file
# Add a marker set to the model markerSet = osim.MarkerSet(XML_markers_path) osimModel.replaceMarkerSet(state, markerSet) state = osimModel.initSystem() # Get the marker data from a .trc file markerData = osim.MarkerData(TRC_file) initial_time = markerData.getStartFrameTime() final_time = markerData.getLastFrameTime() TimeArray = osim.ArrayDouble() # Time range TimeArray.set(0,initial_time) TimeArray.set(1,final_time) # Scale Tool scaleTool = osim.ScaleTool(XML_generic_ST_path) scaleTool.setName('Subject') # Name of the subject scaleTool.setSubjectMass(70) # Mass of the subject scaleTool.setSubjectHeight(-1) # Only for information (not used by scaling) scaleTool.setSubjectAge(-1) # Only for information (not used by scaling) # Generic Model Maker scaleTool.getGenericModelMaker().setModelFileName('Rajagopal2015.osim') scaleTool.getGenericModelMaker().setMarkerSetFileName(XML_markers_path) # Model Scaler scaleTool.getModelScaler().setApply(1) scaleTool.getModelScaler().setScalingOrder(osim.ArrayStr('measurements', 1)) scaleTool.getModelScaler().setMarkerFileName(TRC_file) scaleTool.getModelScaler().setTimeRange(TimeArray) scaleTool.getModelScaler().setPreserveMassDist(1)
# navigation is what is causing issues. # # See the README.MD file next to this for more info. import os import opensim as osim import osimHelper import numpy as np import pandas as pd import matplotlib.pyplot as plt import xml.etree.ElementTree as et # %% Model scaling #Set up the scale tool scaleTool = osim.ScaleTool() #Set participant mass (64.3kg) scaleTool.setSubjectMass(64.3) #Set generic model file genModelFileName = os.getcwd()+'\\pfjLoading_GenericOsimModel_LaiArnold.osim' scaleTool.getGenericModelMaker().setModelFileName(genModelFileName) #Set the measurement set measurementSetObject = osim.OpenSimObject.makeObjectFromFile('scaleMeasurementSet.xml') measurementSet = osim.MeasurementSet.safeDownCast(measurementSetObject) scaleTool.getModelScaler().setMeasurementSet(measurementSet) #Set scale tasks taskSet = osim.IKTaskSet('scaleTasks.xml')
import numpy import opensim import matplotlib.pyplot as plt import os model = opensim.Model(location_models + model_name) model.updateMarkerSet(markerset) model.initSystem() state = model.initSystem() #Scale Tool scale_tool = opensim.ScaleTool(os.path.join(location_XMLs, scale_file)) scale_tool.setSubjectMass(subject_mass) scale_tool.setPathToSubject('') scale_tool.getGenericModelMaker().setModelFileName( os.path.join(location_models, model_name)) scale_tool.getGenericModelMaker().setMarkerSetFileName( os.path.join(location_markersets, markerset_name)) scale_tool.getGenericModelMaker().processModel() scale_tool.getModelScaler().setMarkerFileName(marker_file) # scale_tool.getModelScaler().setOutputModelFileName(os.path.join(data_folder,scaled_model_filename)) scale_tool.getModelScaler().processModel(model, '', subject_mass) scale_tool.getMarkerPlacer().setMarkerFileName(marker_file) scale_tool.getMarkerPlacer().processModel(model) scale_tool.run() #Save Model