예제 #1
0
 def test_getStatic_required_markers(self, key):
     """
     This function tests that an exception is raised when removing given keys from the vsk_data dictionary. All
     of the tested markers are required to exist in the vsk_data dictionary to run pycgmStatic.getStatic(), so
     deleting those keys should raise an exception.
     """
     del self.vsk_data[key]
     with pytest.raises(Exception):
         pycgmStatic.getStatic(self.motion_data, self.vsk_data)
예제 #2
0
    def setup_class(cls):
        """
        Called once for all tests for pycgmIO.
        Sets rounding_precision, loads filenames to
        be used for testing load functions, and sets
        the python version being used.

        We also run the pyCGM code to get a frame of
        output data to test pycgmIO.writeResult().
        """
        cls.rounding_precision = 8
        cwd = os.getcwd()
        if (cwd.split(os.sep)[-1] == "pyCGM_Single"):
            parent = os.path.dirname(cwd)
            os.chdir(parent)
        cls.cwd = os.getcwd()
        cls.pyver = sys.version_info.major

        cls.filename_59993_Frame = os.path.join(
            cls.cwd,
            pyCGM_Helpers.getfilenames(1)[1])
        cls.filename_Sample_Static = os.path.join(
            cls.cwd, 'SampleData/ROM/Sample_Static.csv')
        cls.filename_RoboSM_vsk = os.path.join(
            cls.cwd,
            pyCGM_Helpers.getfilenames(3)[2])

        dynamic_trial, static_trial, vsk_file, _, _ = pyCGM_Helpers.getfilenames(
            x=2)
        motion_data = pycgmIO.loadData(os.path.join(cls.cwd, dynamic_trial))
        static_data = pycgmIO.loadData(os.path.join(cls.cwd, static_trial))
        vsk_data = pycgmIO.loadVSK(os.path.join(cls.cwd, vsk_file), dict=False)
        cal_SM = pycgmStatic.getStatic(static_data, vsk_data, flat_foot=False)
        cls.kinematics = pycgmCalc.calcAngles(motion_data,start=0,end=1,\
                         vsk=cal_SM,splitAnglesAxis=False,formatData=False)
예제 #3
0
    def test_getKinetics(self):
        """
        This test provides coverage of the getKinetics function in pycgmKinetics.py,
        defined as getKinetics(data, Bodymass), where data is an array of joint centers 
        and Bodymass is a float or int.

        This test uses helper functions to obtain the data variable (aka joint_centers).

        Each index in accuracyTests is used as parameters for the function getKinetics 
        and the result is then checked to be equal with the same index in 
        accuracyResults using 8 decimal point precision comparison.
        """
        # Testing is done by using 5 different bodymasses and the same joint_center obtained from the helper functions.
        from pyCGM_Single.pyCGM_Helpers import getfilenames
        from pyCGM_Single.pycgmIO import loadData, loadVSK
        from pyCGM_Single.pycgmStatic import getStatic
        from pyCGM_Single.pycgmCalc import calcAngles

        cwd = os.getcwd() + os.sep
        # Data is obtained from the sample files.
        dynamic_trial, static_trial, vsk_file, _, _ = getfilenames(2)
        motionData = loadData(cwd + dynamic_trial)
        staticData = loadData(cwd + static_trial)
        vsk = loadVSK(cwd + vsk_file, dict=False)

        calSM = getStatic(staticData, vsk, flat_foot=False)
        _, joint_centers = calcAngles(motionData,
                                      start=None,
                                      end=None,
                                      vsk=calSM,
                                      splitAnglesAxis=False,
                                      formatData=False,
                                      returnjoints=True)

        accuracyTests = []
        calSM['Bodymass'] = 5.0
        # This creates five individual assertions to check, all with the same joint_centers but different bodymasses.
        for i in range(5):
            accuracyTests.append((joint_centers, calSM['Bodymass']))
            calSM[
                'Bodymass'] += 35.75  #Increment the bodymass by a substantial amount each time.

        accuracyResults = [
            ([246.57466721, 313.55662383, 1026.56323492]),
            ([246.59137623, 313.6216639, 1026.56440096]),
            ([246.60850798, 313.6856272, 1026.56531282]),
            ([246.6260863, 313.74845693, 1026.56594554]),
            ([246.64410308, 313.81017167, 1026.5663452]),
        ]
        for i in range(len(accuracyResults)):
            # Call getKinetics(joint_centers,bodymass) and round each variable in the 3-element returned list to the 8th decimal precision.
            result = [
                np.around(arr, rounding_precision)
                for arr in pycgmKinetics.getKinetics(accuracyTests[i][0],
                                                     accuracyTests[i][1])
            ]

            # Compare the result with the values in the expected results, within a rounding precision of 8.
            np.testing.assert_almost_equal(result[i], accuracyResults[i],
                                           rounding_precision)
예제 #4
0
 def test_getStatic_InterAsisDistance(self):
     """
     This function tests that when pycgmStatic.getStatic() is called with vsk_data['InterAsisDistance'] is 0, that
     the value for calSM['InterAsisDistance'] is calculated from motionData
     """
     self.vsk_data['InterAsisDistance'] = 0
     result = pycgmStatic.getStatic(self.motion_data, self.vsk_data)
     np.testing.assert_almost_equal(result['InterAsisDistance'], 215.9094195515741, rounding_precision)
예제 #5
0
 def test_getStatic_marker_assignment(self, key, keyVal):
     """
     This function tests that when assigning a value to the given keys from the vsk_data dictionary, the value in
     the resulting calSM corresponds. All of the tested markers are assigned to calSM in pycgmStatic.getStatic()
     """
     self.vsk_data[key] = keyVal
     result = pycgmStatic.getStatic(self.motion_data, self.vsk_data)
     np.testing.assert_almost_equal(result[key], keyVal, rounding_precision)
예제 #6
0
 def test_getStatic_MeanLegLength(self, LeftLegLength, RightLegLength, MeanLegLengthExpected):
     """
     This function tests that pycgmStatic.getStatic() properly calculates calSM['MeanLegLength'] by averaging the
     values in vsk_data['LeftLegLength'] and vsk_data['RightLegLength']
     """
     self.vsk_data['LeftLegLength'] = LeftLegLength
     self.vsk_data['RightLegLength'] = RightLegLength
     result = pycgmStatic.getStatic(self.motion_data, self.vsk_data)
     np.testing.assert_almost_equal(result['MeanLegLength'], MeanLegLengthExpected, rounding_precision)
예제 #7
0
 def test_getStatic_zero_markers(self, key):
     """
     This function tests that when deleting given keys from the vsk_data dictionary, the value in the resulting
     calSM is 0. All of the tested markers are set to 0 if they don't exist in pycgmStatic.getStatic(), so
     deleting these keys should not raise an exception.
     """
     del self.vsk_data[key]
     result = pycgmStatic.getStatic(self.motion_data, self.vsk_data)
     np.testing.assert_almost_equal(result[key], 0, rounding_precision)
예제 #8
0
 def test_getStatic_AsisToTrocanterMeasure(self, leftVal, rightVal, leftExpected, rightExpected):
     """
     Tests that if LeftAsisTrocanterDistance or RightAsisTrocanterDistance are 0 in the input vsk dictionary, their
     corresponding values in calSM will be calculated from LeftLegLength and RightLegLength, but if they both have
     values than they will be assigned from the vsk dictionary
     """
     self.vsk_data['LeftAsisTrocanterDistance'] = leftVal
     self.vsk_data['RightAsisTrocanterDistance'] = rightVal
     result = pycgmStatic.getStatic(self.motion_data, self.vsk_data)
     np.testing.assert_almost_equal(result['L_AsisToTrocanterMeasure'], leftExpected, rounding_precision)
     np.testing.assert_almost_equal(result['R_AsisToTrocanterMeasure'], rightExpected, rounding_precision)
예제 #9
0
 def test_gen(self):
     """
     This function tests that the correct values are returned in calSM['RightStaticRotOff'],
     calSM['RightStaticPlantFlex'], calSM['LeftStaticRotOff'], calSM['LeftStaticPlantFlex'], and calSM['HeadOffset'].
     All of these values are calculated from calls to staticCalculation and staticCalculationHead for every frame
     in motionData
     """
     result = pycgmStatic.getStatic(self.motion_data, self.vsk_data)
     np.testing.assert_almost_equal(result['RightStaticRotOff'], 0.015683497632642041, rounding_precision)
     np.testing.assert_almost_equal(result['RightStaticPlantFlex'], 0.27024179070027576, rounding_precision)
     np.testing.assert_almost_equal(result['LeftStaticRotOff'], 0.0094029102924030206, rounding_precision)
     np.testing.assert_almost_equal(result['LeftStaticPlantFlex'], 0.20251085737834015, rounding_precision)
     np.testing.assert_almost_equal(result['HeadOffset'], 0.25719904693106527, rounding_precision)
예제 #10
0
def main():
    #Load the filenames
    #pyCGM_Helpers.py contains some sample directory data based on github directories
    args = pyCGM_Helpers.parse_args()
    dynamic_trial, static_trial, vsk_file = args.dynamic_trial, args.static_trial, args.vsk_file
    outputfile = args.outputDir + "/result_" + str(dynamic_trial[-11:-4])
    CoM_output = args.outputDir + "/result_COM_" + str(dynamic_trial[-11:-4])
    output_jc = args.outputDir + "/result_JC_" + str(
        dynamic_trial[-11:-4]) + ".csv"
    #Load a dynamic trial, static trial, and vsk (subject measurements)
    motionData, vskData, staticData = loadData(dynamic_trial, static_trial,
                                               vsk_file, args.player)
    motionData = editData(motionData, args.player)
    staticData = editData(staticData, args.player)
    #     print(motionData)
    #Calibrate the static offsets and subject measurements
    calSM = pycgmStatic.getStatic(staticData, vskData, flat_foot=False)

    # #Load data as a dictionary instead of a frame-by-frame array of dictionary
    # staticDataDict = pycgmIO.dataAsDict(staticData,npArray=True)
    # motionDataDict = pycgmIO.dataAsDict(motionData,npArray=True)

    # ####  Start Pipeline oeprations
    # movementFilled = rigid_fill(motionDataDict,staticDataDict)
    # movementFiltered = filtering(motionDataDict)
    # movementFinal = prep(movementFiltered)
    # motionData = movementFinal
    # ### End pipeline operations

    #hack for changing the global coordinates until finding a proper way
    # this impacts the global angles, such as pelvis, but not the anatomical angles (e.g., hip)
    #calSM['GCS'] = pycgmStatic.rotmat(x=0,y=0,z=180)
    #calSM['HeadOffset'] = 0  #example of manually modifying a subject measurement

    kinematics, joint_centers = pycgmCalc.calcAngles(motionData,
                                                     start=None,
                                                     end=None,
                                                     vsk=calSM,
                                                     splitAnglesAxis=False,
                                                     formatData=False,
                                                     returnjoints=True)
    kinetics = pycgmCalc.calcKinetics(joint_centers, calSM['Bodymass'])
    df = pd.DataFrame(joint_centers)
    df.to_csv(output_jc)

    #Write the results to a csv file, if wanted,
    # otherwise could just return the angles/axis to some other function
    pycgmIO.writeResult(kinematics, outputfile, angles=True, axis=False)
    pycgmIO.writeKinetics(CoM_output, kinetics)  #quick save of CoM

    return
예제 #11
0
 def test_Test_Files_center_of_mass(self):
     """
     Test center of mass output values using sample files in SampleData/Test_Files/.
     """
     motion_data, static_data, vsk_data = load_files(
         self.filename_test_dynamic, self.filename_test_static,
         self.filename_test_vsk)
     cal_SM = getStatic(static_data, vsk_data, flat_foot=False)
     kinematics, joint_centers = calcAngles(motion_data,
                                            vsk=cal_SM,
                                            splitAnglesAxis=False,
                                            formatData=False,
                                            returnjoints=True)
     kinetics = calcKinetics(joint_centers, cal_SM['Bodymass'])
     expected = load_center_of_mass(
         os.path.join(self.directory_test, 'Movement_trial.csv'), 5, 2)
     compare_center_of_mass(kinetics, expected, 30)
예제 #12
0
    def run_static(self):
        self.current_model_kind = 'Static cgm pipeline'  # used to update status of run
        if not self.mainwindow.vsk:
            self.mainwindow.ui.messageBrowser.setText('Load VSK in files')
            return 0

        if not self.set_current_array():
            self.mainwindow.ui.messageBrowser.setText(
                'Ensure PiG marker setup is used and all markers are labelled '
                'correctly')
            return 0

        try:
            # get static offsets to be used for calculating angles in static and dynamic trials
            self.calibrated_measurements = pycgmStatic.getStatic(
                self.current_array, self.mainwindow.vsk, flat_foot=False)
        except Exception as err:
            self.mainwindow.ui.messageBrowser.setText(
                'Could not calculate static offsets. Error : ' + str(err))
            return 0

        else:
            return self.gen_model_worker()  # we will start thread
예제 #13
0
    def setup_class(cls):
        """
        Called once for all tests for pycgmCalc.
        Sets rounding_precision, and loads from SampleData/ROM/
        to be used for testing the calculation functions.
        """
        cls.rounding_precision = 8
        cwd = os.getcwd()
        if (cwd.split(os.sep)[-1] == "pyCGM_Single"):
            parent = os.path.dirname(cwd)
            os.chdir(parent)
        cls.cwd = os.getcwd()

        #Load data from SampleData/ROM/ for testing
        dynamic_trial, static_trial, vsk_file, _, _ = pyCGM_Helpers.getfilenames(
            x=2)
        cls.motion_data = pycgmIO.loadData(os.path.join(
            cls.cwd, dynamic_trial))
        cls.static_data = pycgmIO.loadData(os.path.join(cls.cwd, static_trial))
        cls.vsk_data = pycgmIO.loadVSK(os.path.join(cls.cwd, vsk_file),
                                       dict=False)
        cls.cal_SM = pycgmStatic.getStatic(cls.static_data,
                                           cls.vsk_data,
                                           flat_foot=False)
예제 #14
0
    def setup_class(self):
        """
        Called once for all tests in TestCSVOutput.
        Sets rounding precision, and sets the current working
        directory to the pyCGM folder. Sets the current python version
        and loads filenames used for testing.

        We also use the pycgm functions to generate and load output CSV data
        and load them into the class.
        """
        self.rounding_precision = 8
        cwd = os.getcwd()
        if (cwd.split(os.sep)[-1] == "pyCGM_Single"):
            parent = os.path.dirname(cwd)
            os.chdir(parent)
        self.cwd = os.getcwd()
        self.pyver = sys.version_info.major

        #Create a temporary directory used for writing CSVs to
        if (self.pyver == 2):
            self.tmp_dir_name = tempfile.mkdtemp()
        else:
            self.tmp_dir = tempfile.TemporaryDirectory()
            self.tmp_dir_name = self.tmp_dir.name

        #Create file path names for the files being tested
        self.sample_data_directory = os.path.join(self.cwd, "SampleData")
        self.directory_59993_Frame = os.path.join(self.sample_data_directory,
                                                  '59993_Frame')
        self.directory_ROM = os.path.join(self.sample_data_directory, 'ROM')
        self.directory_test = os.path.join(self.sample_data_directory,
                                           'Test_Files')

        #Load outputs to be tested for SampleData/59993_Frame/

        self.filename_59993_Frame_dynamic = os.path.join(
            self.directory_59993_Frame, '59993_Frame_Dynamic.c3d')
        self.filename_59993_Frame_static = os.path.join(
            self.directory_59993_Frame, '59993_Frame_Static.c3d')
        self.filename_59993_Frame_vsk = os.path.join(
            self.directory_59993_Frame, '59993_Frame_SM.vsk')

        motion_data, static_data, vsk_data = load_files(
            self.filename_59993_Frame_dynamic,
            self.filename_59993_Frame_static, self.filename_59993_Frame_vsk)
        cal_SM = getStatic(static_data, vsk_data, flat_foot=False)
        kinematics, joint_centers = calcAngles(motion_data,
                                               start=0,
                                               end=500,
                                               vsk=cal_SM,
                                               splitAnglesAxis=False,
                                               formatData=False,
                                               returnjoints=True)

        outfile = os.path.join(self.tmp_dir_name, 'output_59993_Frame')
        writeResult(kinematics, outfile, angles=True, axis=False)
        expected_file = os.path.join(self.directory_59993_Frame,
                                     'pycgm_results.csv.csv')

        self.result_59993_Frame = load_output_csv(outfile + '.csv')
        self.expected_59993_Frame = load_output_csv(expected_file)

        #Load outputs to be tested for SampleData/ROM/

        self.filename_ROM_dynamic = os.path.join(self.directory_ROM,
                                                 'Sample_Dynamic.c3d')
        self.filename_ROM_static = os.path.join(self.directory_ROM,
                                                'Sample_Static.c3d')
        self.filename_ROM_vsk = os.path.join(self.directory_ROM,
                                             'Sample_SM.vsk')

        motion_data, static_data, vsk_data = load_files(
            self.filename_ROM_dynamic, self.filename_ROM_static,
            self.filename_ROM_vsk)
        cal_SM = getStatic(static_data, vsk_data, flat_foot=False)
        kinematics, joint_centers = calcAngles(motion_data,
                                               vsk=cal_SM,
                                               splitAnglesAxis=False,
                                               formatData=False,
                                               returnjoints=True)

        outfile = os.path.join(self.tmp_dir_name, 'output_ROM')
        writeResult(kinematics, outfile, angles=True, axis=False)
        expected_file = os.path.join(self.directory_ROM,
                                     'pycgm_results.csv.csv')

        self.result_ROM = load_output_csv(outfile + '.csv')
        self.expected_ROM = load_output_csv(expected_file)

        #Load outputs to be tested for SampleData/Test_Files/

        self.filename_test_dynamic = os.path.join(self.directory_test,
                                                  'Movement_trial.c3d')
        self.filename_test_static = os.path.join(self.directory_test,
                                                 'Static_trial.c3d')
        self.filename_test_vsk = os.path.join(self.directory_test, 'Test.vsk')

        motion_data, static_data, vsk_data = load_files(
            self.filename_test_dynamic, self.filename_test_static,
            self.filename_test_vsk)
        cal_SM = getStatic(static_data, vsk_data, flat_foot=False)
        kinematics, joint_centers = calcAngles(motion_data,
                                               vsk=cal_SM,
                                               splitAnglesAxis=False,
                                               formatData=False,
                                               returnjoints=True)

        outfile = os.path.join(self.tmp_dir_name, 'output_Test_Files')
        writeResult(kinematics, outfile, angles=True, axis=False)
        expected_file = os.path.join(self.directory_test, 'Movement_trial.csv')

        self.result_Test_Files = load_output_csv(outfile + '.csv')
        self.expected_Test_Files = load_output_csv(expected_file,
                                                   header_line_number=2,
                                                   first_output_row=5,
                                                   first_output_col=2,
                                                   label_prefix_len=5)