def test_STOFileAdapter(self): adapter = osim.STOFileAdapter() table = adapter.read(os.path.join(test_dir, 'subject02_grf_HiFreq.mot')) assert table.getNumRows() == 439 assert table.getNumColumns() == 18 table = adapter.read( os.path.join(test_dir, 'std_subject01_walk1_ik.mot')) assert table.getNumRows() == 73 assert table.getNumColumns() == 23
def to_sto(self, filename, metadata=None): """ Write a sto file from a Analogs3dOsim Parameters ---------- filename : string path of the file to write metadata : dict, optional dict with optional metadata to add in the output file """ filename = Path(filename) # Make sure the directory exists, otherwise create it if not filename.parents[0].is_dir(): filename.parents[0].mkdir() table = osim.TimeSeriesTable() # set metadata table.setColumnLabels(self.get_labels) if metadata: for key, value in metadata.items(): table.addTableMetaDataString(key, str(value)) if 'nColumns' not in metadata: table.addTableMetaDataString('nColumns', str(self.shape[1])) else: table.addTableMetaDataString('nColumns', str(self.shape[1])) table.addTableMetaDataString('nRows', str(self.shape[-1])) time_vector = np.arange(start=0, stop=1 / self.get_rate * self.shape[2], step=1 / self.get_rate) for iframe in range(self.shape[-1]): a = self.get_frame(iframe) row = osim.RowVector(a.ravel().tolist()) table.appendRow(time_vector[iframe], row) adapter = osim.STOFileAdapter() adapter.write(table, str(filename))
def test_C3DFileAdapter(self): try: adapter = osim.C3DFileAdapter() except AttributeError: # C3D support not available. OpenSim was not compiled with BTK. return tables = adapter.read(os.path.join(test_dir, 'walking2.c3d')) markers = tables['markers'] forces = tables['forces'] assert markers.getNumRows() == 1249 assert markers.getNumColumns() == 44 assert forces.getNumRows() == 9992 assert forces.getNumColumns() == 6 tables = adapter.read(os.path.join(test_dir, 'walking5.c3d')) # Marker data read from C3D. markers = tables['markers'] assert markers.getNumRows() == 1103 assert markers.getNumColumns() == 40 assert markers.getTableMetaDataString('DataRate') == '250.000000' assert markers.getTableMetaDataString('Units') == 'mm' # Flatten marker data. markersFlat = markers.flatten() assert markersFlat.getNumRows() == 1103 assert markersFlat.getNumColumns() == 40 * 3 # Make sure flattenned marker data is writable/readable to/from file. markersFilename = 'markers.sto' stoAdapter = osim.STOFileAdapter() stoAdapter.write(markersFlat, markersFilename) markersDouble = stoAdapter.read(markersFilename) assert markersDouble.getNumRows() == 1103 assert markersDouble.getNumColumns() == 40 * 3 # Forces data read from C3d. forces = tables['forces'] assert forces.getNumRows() == 8824 assert forces.getNumColumns() == 6 assert forces.getTableMetaDataString('DataRate') == '2000.000000' assert forces.getTableMetaDataVectorUnsigned('Types') == (2, 2) fpCalMats = forces.getTableMetaDataVectorMatrix("CalibrationMatrices") assert len(fpCalMats) == 2 assert fpCalMats[0].nrow() == 6 assert fpCalMats[0].ncol() == 6 assert fpCalMats[1].nrow() == 6 assert fpCalMats[1].ncol() == 6 fpCorners = forces.getTableMetaDataVectorMatrix("Corners") assert len(fpCorners) == 2 assert fpCorners[0].nrow() == 3 assert fpCorners[0].ncol() == 4 assert fpCorners[1].nrow() == 3 assert fpCorners[1].ncol() == 4 fpOrigins = forces.getTableMetaDataVectorMatrix("Origins") assert len(fpOrigins) == 2 assert fpOrigins[0].nrow() == 3 assert fpOrigins[0].ncol() == 1 assert fpOrigins[1].nrow() == 3 assert fpOrigins[1].ncol() == 1 assert forces.getDependentsMetaDataString('units') == ('N', 'mm', 'Nmm', 'N', 'mm', 'Nmm') # Flatten forces data. forcesFlat = forces.flatten() assert forcesFlat.getNumRows() == 8824 assert forcesFlat.getNumColumns() == 6 * 3 # Make sure flattenned forces data is writable/readable to/from file. forcesFilename = 'forces.sto' stoAdapter.write(forcesFlat, forcesFilename) forcesDouble = stoAdapter.read(forcesFilename) assert forcesDouble.getNumRows() == 8824 assert forcesDouble.getNumColumns() == 6 * 3 # Clean up. os.remove(markersFilename) os.remove(forcesFilename)
inverse.set_kinematics_allow_extra_columns(True) inverse.set_minimize_sum_squared_activations(True) # Append additional outputs path for quantities that are calculated # post-hoc using the inverse problem solution. inverse.append_output_paths('.*normalized_fiber_length') inverse.append_output_paths('.*passive_force_multiplier') # Part 4d: Solve! Write the MocoSolution to file. inverseSolution = inverse.solve() solution = inverseSolution.getMocoSolution() solution.write('inverseSolution.sto') # Part 4e: Get the outputs we calculated from the inverse solution. inverseOutputs = inverseSolution.getOutputs() sto = osim.STOFileAdapter() sto.write(inverseOutputs, 'muscleOutputs.sto') ## Part 5: Muscle-driven Inverse Problem with Passive Assistance # Part 5a: Create a new muscle-driven model, now adding a SpringGeneralizedForce # about the knee coordinate. device = osim.SpringGeneralizedForce('knee_angle_r') device.setStiffness(50) device.setRestLength(0) device.setViscosity(0) muscleDrivenModel.addForce(device) # Part 5b: Create a ModelProcessor similar to the previous one, using the same # reserve actuator strength so we can compare muscle activity accurately. modelProcessor = osim.ModelProcessor(muscleDrivenModel) modelProcessor.append(osim.ModOpAddReserves(2))
# COP = 1, /// the center of pressure # PWA = 2 /// the point of wrench application (Shimba 1984) https://www.ncbi.nlm.nih.gov/pubmed/6715389 markers = tables['markers'] forces = tables['forces'] # Marker data read from C3D. markers = tables['markers'] # Flatten marker data. markersFlat = markers.flatten() # Make sure flattenned marker data is writable/readable to/from file. markersFilename = 'markers.sto' stoAdapter = osim.STOFileAdapter() stoAdapter.write(markersFlat, markersFilename) markersDouble = stoAdapter.read(markersFilename) # Forces data read from C3d. forces = tables['forces'] fpCalMats = forces.getTableMetaDataVectorMatrix("CalibrationMatrices") fpCorners = forces.getTableMetaDataVectorMatrix("Corners") fpOrigins = forces.getTableMetaDataVectorMatrix("Origins") # Flatten forces data. forcesFlat = forces.flatten() # Make sure flattenned forces data is writable/readable to/from file. forcesFilename = 'forces.sto' stoAdapter.write(forcesFlat, forcesFilename)
def __init__( self, model, trajectory_filepath, bilateral=True, ref_files=None, colormap=None, output=None, ): self.model = model self.model.initSystem() self.trajectory_filepath = trajectory_filepath self.trajectory = osim.MocoTrajectory(self.trajectory_filepath) self.bilateral = bilateral self.ref_files = ref_files self.colormap = colormap trajectory_fname = ntpath.basename(self.trajectory_filepath) trajectory_fname = trajectory_fname.replace('.sto', '') trajectory_fname = trajectory_fname.replace('.mot', '') self.trajectory_fname = trajectory_fname if output: self.output = output else: self.output = trajectory_fname + '_report.pdf' # Get any reference files provided by the user and create a list of NumPy # arrays to use in plotting. self.refs = list() if ref_files != None: for ref_file in ref_files: filename, file_ext = os.path.splitext(ref_file) # If the reference is a file with metadata indicating that # rotational data is in degrees, convert to radians and write to # a new file to be used for plotting. # TODO: don't write the extra file permanently if file_ext == '.sto' or file_ext == '.mot': ref = osim.TimeSeriesTable(ref_file) if (ref.hasTableMetaDataKey('inDegrees') and ref.getTableMetaDataAsString('inDegrees') == 'yes'): simbodyEngine = self.model.getSimbodyEngine() simbodyEngine.convertDegreesToRadians(ref) ref_file = ref_file.replace(file_ext, '_radians' + file_ext) sto_adapter = osim.STOFileAdapter() sto_adapter.write(ref, ref_file) num_header_rows = 1 with open(ref_file) as f: for line in f: if not line.startswith('endheader'): num_header_rows += 1 else: break this_ref = np.genfromtxt(ref_file, names=True, delimiter='\t', skip_header=num_header_rows) self.refs.append(this_ref) # Load the colormap provided by the user. Use a default colormap ('jet') # if not provided. Uniformly sample the colormap based on the number of # reference data sets, plus one for the MocoTrajectory. import matplotlib.cm as cm if colormap is None: colormap = 'jet' self.cmap_samples = np.linspace(0.1, 0.9, len(self.refs) + 1) self.cmap = cm.get_cmap(colormap) ## Legend handles and labels. # =========================== # Create legend handles and labels that can be used to create a figure # legend that is applicable all figures. self.legend_handles = list() self.legend_labels = list() all_files = list() if ref_files != None: all_files += ref_files all_files.append(trajectory_filepath) lw = 8 / len(self.cmap_samples) if lw < 0.5: lw = 0.5 if lw > 2: lw = 2 for sample, file in zip(self.cmap_samples, all_files): color = self.cmap(sample) import matplotlib.lines as mlines if bilateral: r = mlines.Line2D([], [], ls='-', color=color, linewidth=lw) self.legend_handles.append(r) self.legend_labels.append(file + ' (right leg)') l = mlines.Line2D([], [], ls='--', color=color, linewidth=lw) self.legend_handles.append(l) self.legend_labels.append(file + ' (left leg)') else: h = mlines.Line2D([], [], ls='-', color=color, linewidth=lw) self.legend_handles.append(h) self.legend_labels.append(file) # Time # ----- # Convert trajectory time vector to a plotting-friendly NumPy array. self.time = convert(self.trajectory.getTime()) # Create a conservative set of x-tick values based on the time vector. nexttime = math.ceil(self.time[0] * 10) / 10 nexttolast = math.floor(self.time[-1] * 10) / 10 if (nexttolast - nexttime) < 1.5: self.timeticks = np.arange(nexttime, nexttolast, 0.2) else: self.timeticks = None self.plots_per_page = 15.0 self.num_cols = 3 # Add an extra row to hold the legend and other infromation. self.num_rows = (self.plots_per_page / 3) + 1
def read_STO(dirname, filename): adapter = osim.STOFileAdapter() return adapter.read(dirname + os.sep + filename + '.sto')