Beispiel #1
0
    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
Beispiel #2
0
    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))
Beispiel #3
0
    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))
Beispiel #5
0
#        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)
Beispiel #6
0
    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')