def gaitTrialProgressionY_backward_lateralX_static(cls): """ """ MAIN_PATH = pyCGM2.TEST_DATA_PATH + "operations\\progression\\" gaitFilename="static_Y_backward.c3d" acq = btkTools.smartReader(str(MAIN_PATH + gaitFilename)) valSACR=(acq.GetPoint("LPSI").GetValues() + acq.GetPoint("RPSI").GetValues()) / 2.0 btkTools.smartAppendPoint(acq,"SACR",valSACR,desc="") valMidAsis=(acq.GetPoint("LASI").GetValues() + acq.GetPoint("RASI").GetValues()) / 2.0 btkTools.smartAppendPoint(acq,"midASIS",valMidAsis,desc="") longitudinalAxis,forwardProgression,globalFrame = btkTools.findProgressionAxisFromPelvicMarkers(acq,["LASI","LPSI","RASI","RPSI"]) np.testing.assert_equal( longitudinalAxis,"Y") np.testing.assert_equal( forwardProgression,False) np.testing.assert_equal( globalFrame,"YXZ") longitudinalAxis2,forwardProgression2,globalFrame2 = btkTools.findProgressionAxisFromLongAxis(acq,"LPSI","LASI") np.testing.assert_equal( longitudinalAxis2,"Y") np.testing.assert_equal( forwardProgression2,False) np.testing.assert_equal( globalFrame2,"YXZ")
def gaitTrialGarches(cls): """ """ MAIN_PATH = pyCGM2.TEST_DATA_PATH + "operations\\progression\\" translators = { "LASI":"L.ASIS", "RASI":"R.ASIS", "LPSI":"L.PSIS", "RPSI":"R.PSIS", "RTHI":"R.Thigh", "RKNE":"R.Knee", "RTHAP":"R.THAP", "RTHAD":"R.THAD", "RTIB":"R.Shank", "RANK":"R.Ankle", "RTIAP":"R.TIAP", "RTIAD":"R.TIAD", "RHEE":"R.Heel", "RSMH":"R.SMH", "RTOE":"R.Toe", "RFMH":"R.FMH", "RVMH":"R.VMH", "LTHI":"L.Thigh", "LKNE":"L.Knee", "LTHAP":"L.THAP", "LTHAD":"L.THAD", "LTIB":"L.Shank", "LANK":"L.Ankle", "LTIAP":"L.TIAP", "LTIAD":"L.TIAD", "LHEE":"L.Heel", "LSMH":"L.SMH", "LTOE":"L.Toe", "LFMH":"L.FMH", "LVMH":"L.VMH", "RKNM":"R.Knee.Medial", "LKNM":"L.Knee.Medial", "RMED":"R.Ankle.Medial", "LMED":"L.Ankle.Medial" } gaitFilename="gait_garches_issue.c3d" acq = btkTools.smartReader(str(MAIN_PATH + gaitFilename),translators =translators ) valSACR=(acq.GetPoint("RPSI").GetValues() + acq.GetPoint("LPSI").GetValues()) / 2.0 btkTools.smartAppendPoint(acq,"SACR",valSACR,desc="") valMidAsis=(acq.GetPoint("RASI").GetValues() + acq.GetPoint("LASI").GetValues()) / 2.0 btkTools.smartAppendPoint(acq,"midASIS",valMidAsis,desc="") longitudinalAxis,forwardProgression,globalFrame = btkTools.findProgression(acq,"LASI") longitudinalAxis2,forwardProgression2,globalFrame2 = btkTools.findProgressionAxisFromPelvicMarkers(acq,["LASI","LPSI","RASI","RPSI"]) np.testing.assert_equal( longitudinalAxis,"Y") np.testing.assert_equal( longitudinalAxis2,"Y")
def basicCGM1_bodyBuilderFoot(cls): """ goal : know effet on Foot kinematics of a foot referential built according ta sequence metionned in some bodybuilder code: LFoot = [LTOE,LAJC-LTOE,LAJC-LKJC,zyx] """ MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\\basic\\" staticFilename = "MRI-US-01, 2008-08-08, 3DGA 02.c3d" acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model=cgm.CGM1LowerLimbs() model.configure() mp={ 'Bodymass' : 71.0, 'LeftLegLength' : 860.0, 'RightLegLength' : 865.0 , 'LeftKneeWidth' : 102.0, 'RightKneeWidth' : 103.4, 'LeftAnkleWidth' : 75.3, 'RightAnkleWidth' : 72.9, 'LeftSoleDelta' : 0, 'RightSoleDelta' : 0, } model.addAnthropoInputParameters(mp) scp=modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp,acqStatic,model, useBodyBuilderFoot=True).compute() # ------ Test 1 Motion Axe X ------- gaitFilename="MRI-US-01, 2008-08-08, 3DGA 14.c3d" acqGait = btkTools.smartReader(str(MAIN_PATH + gaitFilename)) # Motion FILTER # optimisation segmentaire et calibration fonctionnel modMotion=modelFilters.ModelMotionFilter(scp,acqGait,model,pyCGM2Enums.motionMethod.Determinist) modMotion.compute() # relative angles modelFilters.ModelJCSFilter(model,acqGait).compute(description="vectoriel", pointLabelSuffix="cgm1_6dof") # absolute angles longitudinalAxis,forwardProgression,globalFrame = btkTools.findProgressionAxisFromPelvicMarkers(acqGait,["LASI","LPSI","RASI","RPSI"]) modelFilters.ModelAbsoluteAnglesFilter(model,acqGait, segmentLabels=["Left Foot","Right Foot","Pelvis"], angleLabels=["LFootProgress", "RFootProgress","Pelvis"], eulerSequences=["TOR","TOR", "TOR"], globalFrameOrientation = globalFrame, forwardProgression = forwardProgression).compute(pointLabelSuffix="cgm1_6dof") btkTools.smartWriter(acqGait, "testuseBodyBuilderFoot.c3d")
def advancedCGM11_KadMed_TrueEquinus(cls): """ """ MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\\kad-med-TrueEquinus\\" staticFilename = "static.c3d" acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model=cgm.CGM1LowerLimbs() model.configure() markerDiameter=14 mp={ 'Bodymass' : 36.9, 'LeftLegLength' : 665.0, 'RightLegLength' : 655.0 , 'LeftKneeWidth' : 102.7, 'RightKneeWidth' : 100.2, 'LeftAnkleWidth' : 64.5, 'RightAnkleWidth' : 63.0, 'LeftSoleDelta' : 0, 'RightSoleDelta' : 0, } optional_mp={ 'InterAsisDistance' : 0, 'LeftAsisTrocanterDistance' : 0, 'LeftThighRotation' : 0, 'LeftShankRotation' : 0 , 'LeftTibialTorsion' : 0, 'RightAsisTrocanterDistance' : 0, 'RightThighRotation' : 0, 'RightShankRotation' : 0, 'RightTibialTorsion' : 0 } model.addAnthropoInputParameters(mp,optional=optional_mp) # -----------CGM STATIC CALIBRATION-------------------- scp=modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp,acqStatic,model).compute() # cgm decorator modelDecorator.Kad(model,acqStatic).compute() modelDecorator.AnkleCalibrationDecorator(model).midMaleolus(acqStatic, side="both") modelFilters.ModelCalibrationFilter(scp,acqStatic,model).compute() # tibial torsion ltt_vicon = np.rad2deg(acqStatic.GetMetaData().FindChild("PROCESSING").value().FindChild("LTibialTorsion").value().GetInfo().ToDouble()[0]) rtt_vicon =np.rad2deg(acqStatic.GetMetaData().FindChild("PROCESSING").value().FindChild("RTibialTorsion").value().GetInfo().ToDouble()[0]) logging.info(" LTibialTorsion : Vicon (%.6f) Vs pyCGM2 (%.6f)" %(ltt_vicon,model.mp_computed["LeftTibialTorsionOffset"])) logging.info(" RTibialTorsion : Vicon (%.6f) Vs pyCGM2 (%.6f)" %(rtt_vicon,model.mp_computed["RightTibialTorsionOffset"])) # thigh and shank Offsets lto = model.getViconThighOffset("Left") lso = model.getViconShankOffset("Left") rto = model.getViconThighOffset("Right") rso = model.getViconShankOffset("Right") lto_vicon = np.rad2deg(acqStatic.GetMetaData().FindChild("PROCESSING").value().FindChild("LThighRotation").value().GetInfo().ToDouble()[0]) lso_vicon = np.rad2deg(acqStatic.GetMetaData().FindChild("PROCESSING").value().FindChild("LShankRotation").value().GetInfo().ToDouble()[0]) rto_vicon = np.rad2deg(acqStatic.GetMetaData().FindChild("PROCESSING").value().FindChild("RThighRotation").value().GetInfo().ToDouble()[0]) rso_vicon = np.rad2deg(acqStatic.GetMetaData().FindChild("PROCESSING").value().FindChild("RShankRotation").value().GetInfo().ToDouble()[0]) logging.info(" LThighRotation : Vicon (%.6f) Vs pyCGM2 (%.6f)" %(lto_vicon,lto)) logging.info(" LShankRotation : Vicon (%.6f) Vs pyCGM2 (%.6f)" %(lso_vicon,lso)) logging.info(" RThighRotation : Vicon (%.6f) Vs pyCGM2 (%.6f)" %(rto_vicon,rto)) logging.info(" RShankRotation : Vicon (%.6f) Vs pyCGM2 (%.6f)" %(rso_vicon,rso)) btkTools.smartWriter(acqStatic,"Kad-med-TrueEquinus.c3d") gaitFilename="gait trial 01.c3d" acqGait = btkTools.smartReader(str(MAIN_PATH + gaitFilename)) # Motion FILTER # optimisation segmentaire et calibration fonctionnel modMotion=modelFilters.ModelMotionFilter(scp,acqGait,model,pyCGM2Enums.motionMethod.Determinist) modMotion.compute() # relative angles modelFilters.ModelJCSFilter(model,acqGait).compute(description="vectoriel", pointLabelSuffix="cgm1_6dof") # absolute angles longitudinalAxis,forwardProgression,globalFrame = btkTools.findProgressionAxisFromPelvicMarkers(acqGait,["LASI","LPSI","RASI","RPSI"]) modelFilters.ModelAbsoluteAnglesFilter(model,acqGait, segmentLabels=["Left Foot","Right Foot","Pelvis"], angleLabels=["LFootProgress", "RFootProgress","Pelvis"], eulerSequences=["TOR","TOR", "TOR"], globalFrameOrientation = globalFrame, forwardProgression = forwardProgression).compute(pointLabelSuffix="cgm1_6dof") btkTools.smartWriter(acqGait, "Kad-med-TrueEquinus-angles.c3d")
def kad_midMaleolus(cls): """ """ MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\\KAD-Med\\" staticFilename = "MRI-US-01, 2008-08-08, 3DGA 02.c3d" acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model=cgm.CGM1LowerLimbs() model.configure() mp={ 'Bodymass' : 71.0, 'LeftLegLength' : 860.0, 'RightLegLength' : 865.0 , 'LeftKneeWidth' : 102.0, 'RightKneeWidth' : 103.4, 'LeftAnkleWidth' : 75.3, 'RightAnkleWidth' : 72.9, 'LeftSoleDelta' : 0, 'RightSoleDelta' : 0, } model.addAnthropoInputParameters(mp) scp=modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp,acqStatic,model).compute() # cgm decorator modelDecorator.Kad(model,acqStatic).compute() modelDecorator.AnkleCalibrationDecorator(model).midMaleolus(acqStatic, side="both") modelFilters.ModelCalibrationFilter(scp,acqStatic,model).compute() # tibial torsion ltt_vicon = np.rad2deg(acqStatic.GetMetaData().FindChild("PROCESSING").value().FindChild("LTibialTorsion").value().GetInfo().ToDouble()[0]) rtt_vicon =np.rad2deg(acqStatic.GetMetaData().FindChild("PROCESSING").value().FindChild("RTibialTorsion").value().GetInfo().ToDouble()[0]) logging.info(" LTibialTorsion : Vicon (%.6f) Vs pyCGM2 (%.6f)" %(ltt_vicon,model.mp_computed["LeftTibialTorsionOffset"])) logging.info(" RTibialTorsion : Vicon (%.6f) Vs pyCGM2 (%.6f)" %(rtt_vicon,model.mp_computed["RightTibialTorsionOffset"])) # foot offsets spf_l,sro_l = model.getViconFootOffset("Left") spf_r,sro_r = model.getViconFootOffset("Right") vicon_spf_l = np.rad2deg(acqStatic.GetMetaData().FindChild("PROCESSING").value().FindChild("LStaticPlantFlex").value().GetInfo().ToDouble()[0]) vicon_spf_r = np.rad2deg(acqStatic.GetMetaData().FindChild("PROCESSING").value().FindChild("RStaticPlantFlex").value().GetInfo().ToDouble()[0]) vicon_sro_l = np.rad2deg(acqStatic.GetMetaData().FindChild("PROCESSING").value().FindChild("LStaticRotOff").value().GetInfo().ToDouble()[0]) vicon_sro_r = np.rad2deg(acqStatic.GetMetaData().FindChild("PROCESSING").value().FindChild("RStaticRotOff").value().GetInfo().ToDouble()[0]) logging.info(" LStaticPlantFlex : Vicon (%.6f) Vs bodyBuilderFoot (%.6f)" %(spf_l,vicon_spf_l)) logging.info(" RStaticPlantFlex : Vicon (%.6f) Vs bodyBuilderFoot (%.6f)" %(spf_r,vicon_spf_r)) logging.info(" LStaticRotOff : Vicon (%.6f) Vs bodyBuilderFoot (%.6f)" %(sro_l,vicon_sro_l)) logging.info(" RStaticRotOff : Vicon (%.6f) Vs bodyBuilderFoot (%.6f)" %(sro_r,vicon_sro_r)) # thigh and shank Offsets lto = model.getViconThighOffset("Left") lso = model.getViconShankOffset("Left") rto = model.getViconThighOffset("Right") rso = model.getViconShankOffset("Right") lto_vicon = np.rad2deg(acqStatic.GetMetaData().FindChild("PROCESSING").value().FindChild("LThighRotation").value().GetInfo().ToDouble()[0]) lso_vicon = np.rad2deg(acqStatic.GetMetaData().FindChild("PROCESSING").value().FindChild("LShankRotation").value().GetInfo().ToDouble()[0]) rto_vicon = np.rad2deg(acqStatic.GetMetaData().FindChild("PROCESSING").value().FindChild("RThighRotation").value().GetInfo().ToDouble()[0]) rso_vicon = np.rad2deg(acqStatic.GetMetaData().FindChild("PROCESSING").value().FindChild("RShankRotation").value().GetInfo().ToDouble()[0]) logging.info(" LThighRotation : Vicon (%.6f) Vs pyCGM2 (%.6f)" %(lto_vicon,lto)) logging.info(" LShankRotation : Vicon (%.6f) Vs pyCGM2 (%.6f)" %(lso_vicon,lso)) logging.info(" RThighRotation : Vicon (%.6f) Vs pyCGM2 (%.6f)" %(rto_vicon,rto)) logging.info(" RShankRotation : Vicon (%.6f) Vs pyCGM2 (%.6f)" %(rso_vicon,rso)) # ------ Test 1 Motion Axe X ------- gaitFilename="MRI-US-01, 2008-08-08, 3DGA 14.c3d" acqGait = btkTools.smartReader(str(MAIN_PATH + gaitFilename)) # Motion FILTER # optimisation segmentaire et calibration fonctionnel modMotion=modelFilters.ModelMotionFilter(scp,acqGait,model,pyCGM2Enums.motionMethod.Determinist) modMotion.compute() # relative angles modelFilters.ModelJCSFilter(model,acqGait).compute(description="vectoriel", pointLabelSuffix="cgm1_6dof") # absolute angles longitudinalAxis,forwardProgression,globalFrame = btkTools.findProgressionAxisFromPelvicMarkers(acqGait,["LASI","LPSI","RASI","RPSI"]) modelFilters.ModelAbsoluteAnglesFilter(model,acqGait, segmentLabels=["Left Foot","Right Foot","Pelvis"], angleLabels=["LFootProgress", "RFootProgress","Pelvis"], eulerSequences=["TOR","TOR", "TOR"], globalFrameOrientation = globalFrame, forwardProgression = forwardProgression).compute(pointLabelSuffix="cgm1_6dof") btkTools.smartWriter(acqGait, "advancedCGM1_kad_midMaleolus-14.c3d") # tests on joint angles np.testing.assert_almost_equal( acqGait.GetPoint("RHipAngles").GetValues(), acqGait.GetPoint("RHipAngles_cgm1_6dof").GetValues(), decimal =3) np.testing.assert_almost_equal( acqGait.GetPoint("LHipAngles").GetValues(), acqGait.GetPoint("LHipAngles_cgm1_6dof").GetValues(), decimal =3) np.testing.assert_almost_equal( acqGait.GetPoint("RKneeAngles").GetValues(), acqGait.GetPoint("RKneeAngles_cgm1_6dof").GetValues(), decimal =2) np.testing.assert_almost_equal( acqGait.GetPoint("LKneeAngles").GetValues(), acqGait.GetPoint("LKneeAngles_cgm1_6dof").GetValues(), decimal =2) np.testing.assert_almost_equal( acqGait.GetPoint("RPelvisAngles").GetValues(), acqGait.GetPoint("RPelvisAngles_cgm1_6dof").GetValues(), decimal =3) np.testing.assert_almost_equal( acqGait.GetPoint("LPelvisAngles").GetValues(), acqGait.GetPoint("LPelvisAngles_cgm1_6dof").GetValues(), decimal =3) # # tests on angles influence by Vicon error # np.testing.assert_almost_equal( acqGait.GetPoint("RAnkleAngles").GetValues(), # acqGait.GetPoint("RAnkleAngles_cgm1_6dof").GetValues(), decimal =3) # np.testing.assert_almost_equal( acqGait.GetPoint("LAnkleAngles").GetValues(), # acqGait.GetPoint("LAnkleAngles_cgm1_6dof").GetValues(), decimal =3) # # np.testing.assert_almost_equal( acqGait.GetPoint("LFootProgressAngles").GetValues(), # acqGait.GetPoint("LFootProgressAngles_cgm1_6dof").GetValues(), decimal =3) # np.testing.assert_almost_equal( acqGait.GetPoint("RFootProgressAngles").GetValues(), # acqGait.GetPoint("RFootProgressAngles_cgm1_6dof").GetValues(), decimal =3) # ------ Test 2 Motion Axe -X ------- gaitFilename="MRI-US-01, 2008-08-08, 3DGA 12.c3d" acqGait = btkTools.smartReader(str(MAIN_PATH + gaitFilename)) # Motion FILTER # optimisation segmentaire et calibration fonctionnel modMotion=modelFilters.ModelMotionFilter(scp,acqGait,model,pyCGM2Enums.motionMethod.Determinist) modMotion.compute() # relative angles modelFilters.ModelJCSFilter(model,acqGait).compute(description="vectoriel", pointLabelSuffix="cgm1_6dof") # absolute angles longitudinalAxis,forwardProgression,globalFrame = btkTools.findProgressionAxisFromPelvicMarkers(acqGait,["LASI","LPSI","RASI","RPSI"]) modelFilters.ModelAbsoluteAnglesFilter(model,acqGait, segmentLabels=["Left Foot","Right Foot","Pelvis"], angleLabels=["LFootProgress", "RFootProgress","Pelvis"], globalFrameOrientation = globalFrame, eulerSequences=["TOR","TOR", "TOR"], forwardProgression = forwardProgression).compute(pointLabelSuffix="cgm1_6dof") #btkTools.smartWriter(acqGait, "test.c3d") # tests on joint angles np.testing.assert_almost_equal( acqGait.GetPoint("RHipAngles").GetValues(), acqGait.GetPoint("RHipAngles_cgm1_6dof").GetValues(), decimal =3) np.testing.assert_almost_equal( acqGait.GetPoint("LHipAngles").GetValues(), acqGait.GetPoint("LHipAngles_cgm1_6dof").GetValues(), decimal =3) np.testing.assert_almost_equal( acqGait.GetPoint("RKneeAngles").GetValues(), acqGait.GetPoint("RKneeAngles_cgm1_6dof").GetValues(), decimal =2) np.testing.assert_almost_equal( acqGait.GetPoint("LKneeAngles").GetValues(), acqGait.GetPoint("LKneeAngles_cgm1_6dof").GetValues(), decimal =2) np.testing.assert_almost_equal( acqGait.GetPoint("RPelvisAngles").GetValues(), acqGait.GetPoint("RPelvisAngles_cgm1_6dof").GetValues(), decimal =3) np.testing.assert_almost_equal( acqGait.GetPoint("LPelvisAngles").GetValues(), acqGait.GetPoint("LPelvisAngles_cgm1_6dof").GetValues(), decimal =3)
def CGM2_4_SARA_test(cls): MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM2\\cgm2.4\\Knee Calibration\\" staticFilename = "static.c3d" funcFilename = "functional.c3d" gaitFilename = "gait trial 01.c3d" markerDiameter = 14 mp = { 'Bodymass': 69.0, 'LeftLegLength': 930.0, 'RightLegLength': 930.0, 'LeftKneeWidth': 94.0, 'RightKneeWidth': 64.0, 'LeftAnkleWidth': 67.0, 'RightAnkleWidth': 62.0, 'LeftSoleDelta': 0, 'RightSoleDelta': 0, "LeftToeOffset": 0, "RightToeOffset": 0, } acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model = cgm2.CGM2_4LowerLimbs() model.configure() model.addAnthropoInputParameters(mp) # --- INITIAL CALIBRATION --- scp = modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp, acqStatic, model).compute() # cgm decorator modelDecorator.HipJointCenterDecorator(model).hara() modelDecorator.KneeCalibrationDecorator(model).midCondyles( acqStatic, markerDiameter=markerDiameter, side="both", cgm1Behaviour=True) modelDecorator.AnkleCalibrationDecorator(model).midMaleolus( acqStatic, markerDiameter=markerDiameter, side="both") # final modelFilters.ModelCalibrationFilter( scp, acqStatic, model, seLeftHJCnode="LHJC_Hara", useRightHJCnode="RHJC_Hara", useLeftKJCnode="LKJC_mid", useLeftAJCnode="LAJC_mid", useRightKJCnode="RKJC_mid", useRightAJCnode="RAJC_mid", markerDiameter=markerDiameter).compute() # ------ LEFT KNEE CALIBRATION ------- acqFunc = btkTools.smartReader(str(MAIN_PATH + funcFilename)) # Motion of only left modMotionLeftKnee = modelFilters.ModelMotionFilter( scp, acqFunc, model, pyCGM2Enums.motionMethod.Sodervisk) modMotionLeftKnee.segmentalCompute(["Left Thigh", "Left Shank"]) # decorator modelDecorator.KneeCalibrationDecorator(model).sara( "Left", indexFirstFrame=831, indexLastFrame=1280) # ----add Point into the c3d---- Or_inThigh = model.getSegment("Left Thigh").getReferential( "TF").getNodeTrajectory("KneeFlexionOri") axis_inThigh = model.getSegment("Left Thigh").getReferential( "TF").getNodeTrajectory("KneeFlexionAxis") btkTools.smartAppendPoint(acqFunc, "Left" + "_KneeFlexionOri", Or_inThigh) btkTools.smartAppendPoint(acqFunc, "Left" + "_KneeFlexionAxis", axis_inThigh) # ------ RIGHT KNEE CALIBRATION ------- # Motion of only left modMotionRightKnee = modelFilters.ModelMotionFilter( scp, acqFunc, model, pyCGM2Enums.motionMethod.Sodervisk) modMotionRightKnee.segmentalCompute(["Right Thigh", "Right Shank"]) # decorator modelDecorator.KneeCalibrationDecorator(model).sara("Right", indexFirstFrame=61, indexLastFrame=551) # ----add Point into the c3d---- Or_inThigh = model.getSegment("Right Thigh").getReferential( "TF").getNodeTrajectory("KneeFlexionOri") axis_inThigh = model.getSegment("Right Thigh").getReferential( "TF").getNodeTrajectory("KneeFlexionAxis") btkTools.smartAppendPoint(acqFunc, "Right" + "_KneeFlexionOri", Or_inThigh) btkTools.smartAppendPoint(acqFunc, "Right" + "_KneeFlexionAxis", axis_inThigh) btkTools.smartWriter(acqFunc, "acqFunc-Sara.c3d") #--- FINAL CALIBRATION --- modelFilters.ModelCalibrationFilter( scp, acqStatic, model, useLeftHJCnode="LHJC_Hara", useRightHJCnode="RHJC_Hara", useLeftKJCnode="KJC_Sara", useLeftAJCnode="LAJC_mid", useRightKJCnode="KJC_Sara", useRightAJCnode="RAJC_mid", markerDiameter=markerDiameter, RotateLeftThighFlag=True, RotateRightThighFlag=True).compute() # save static c3d with update KJC btkTools.smartWriter(acqStatic, "Static-SARA.c3d") # ------ Fitting ------- acqGait = btkTools.smartReader(str(MAIN_PATH + gaitFilename)) # Motion FILTER modMotion = modelFilters.ModelMotionFilter( scp, acqGait, model, pyCGM2Enums.motionMethod.Determinist) modMotion.compute() # relative angles modelFilters.ModelJCSFilter(model, acqGait).compute( description="vectoriel", pointLabelSuffix="cgm1_6dof") # absolute angles longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromPelvicMarkers( acqGait, ["LASI", "RASI", "RPSI", "LPSI"]) modelFilters.ModelAbsoluteAnglesFilter( model, acqGait, segmentLabels=["Left HindFoot", "Right HindFoot", "Pelvis"], angleLabels=["LFootProgress", "RFootProgress", "Pelvis"], eulerSequences=["TOR", "TOR", "ROT"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix="cgm1_6dof") # ------- OPENSIM IK -------------------------------------- # --- osim builder --- cgmCalibrationprocedure = opensimFilters.CgmOpensimCalibrationProcedures( model) markersetFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_4\\cgm2_4-markerset.xml" osimfile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\osim\\lowerLimb_ballsJoints.osim" oscf = opensimFilters.opensimCalibrationFilter( osimfile, model, cgmCalibrationprocedure) oscf.addMarkerSet(markersetFile) scalingOsim = oscf.build(exportOsim=False) # --- fitting --- #procedure cgmFittingProcedure = opensimFilters.CgmOpensimFittingProcedure(model) iksetupFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_4\\cgm2_4-ikSetUp_template.xml" osrf = opensimFilters.opensimFittingFilter(iksetupFile, scalingOsim, cgmFittingProcedure, MAIN_PATH) acqIK = osrf.run(acqGait, str(MAIN_PATH + gaitFilename), exportSetUp=False) # -------- NEW MOTION FILTER ON IK MARKERS ------------------ modMotion_ik = modelFilters.ModelMotionFilter( scp, acqIK, model, pyCGM2Enums.motionMethod.Sodervisk, useForMotionTest=True) modMotion_ik.compute() finalJcs = modelFilters.ModelJCSFilter(model, acqIK) finalJcs.setFilterBool(False) finalJcs.compute(description="ik", pointLabelSuffix="2_ik") # btkTools.smartWriter(acqIK, "gait trial 01 - Fitting.c3d")
def calibrate(DATA_PATH,calibrateFilenameLabelled,translators,settings, required_mp,optional_mp, ik_flag,leftFlatFoot,rightFlatFoot,markerDiameter,hjcMethod, pointSuffix): # ---btk acquisition--- acqStatic = btkTools.smartReader(str(DATA_PATH+calibrateFilenameLabelled)) btkTools.checkMultipleSubject(acqStatic) acqStatic = btkTools.applyTranslators(acqStatic,translators) validFrames,vff,vlf = btkTools.findValidFrames(acqStatic,cgm2.CGM2_4LowerLimbs.TRACKING_MARKERS) # --------------------------MODEL-------------------------------------- # ---definition--- model=cgm2.CGM2_4LowerLimbs() model.configure() model.addAnthropoInputParameters(required_mp,optional=optional_mp) # --store calibration parameters-- model.setStaticFilename(calibrateFilenameLabelled) model.setCalibrationProperty("leftFlatFoot",leftFlatFoot) model.setCalibrationProperty("rightFlatFoot",rightFlatFoot) model.setCalibrationProperty("markerDiameter",markerDiameter) # ---check marker set used---- smc = cgm.CGM.checkCGM1_StaticMarkerConfig(acqStatic) # --------------------------STATIC CALBRATION-------------------------- scp=modelFilters.StaticCalibrationProcedure(model) # load calibration procedure # ---initial calibration filter---- # use if all optional mp are zero modelFilters.ModelCalibrationFilter(scp,acqStatic,model, leftFlatFoot = leftFlatFoot, rightFlatFoot = rightFlatFoot, markerDiameter=markerDiameter, ).compute() # ---- Decorators ----- decorators.applyDecorators_CGM(smc, model,acqStatic,optional_mp,markerDiameter) decorators.applyHJCDecorators(model,hjcMethod) # ----Final Calibration filter if model previously decorated ----- if model.decoratedModel: # initial static filter modelFilters.ModelCalibrationFilter(scp,acqStatic,model, leftFlatFoot = leftFlatFoot, rightFlatFoot = rightFlatFoot, markerDiameter=markerDiameter).compute() # ----------------------CGM MODELLING---------------------------------- # ----motion filter---- modMotion=modelFilters.ModelMotionFilter(scp,acqStatic,model,enums.motionMethod.Sodervisk, markerDiameter=markerDiameter) modMotion.compute() if ik_flag: # ---OPENSIM IK--- # --- opensim calibration Filter --- osimfile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\osim\\lowerLimb_ballsJoints.osim" # osimfile markersetFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_4\\cgm2_4-markerset.xml" # markerset cgmCalibrationprocedure = opensimFilters.CgmOpensimCalibrationProcedures(model) # procedure oscf = opensimFilters.opensimCalibrationFilter(osimfile, model, cgmCalibrationprocedure, str(DATA_PATH)) oscf.addMarkerSet(markersetFile) scalingOsim = oscf.build() # --- opensim Fitting Filter --- iksetupFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_4\\cgm2_4-ikSetUp_template.xml" # ik tool file cgmFittingProcedure = opensimFilters.CgmOpensimFittingProcedure(model) # procedure cgmFittingProcedure.updateMarkerWeight("LASI",settings["Fitting"]["Weight"]["LASI"]) cgmFittingProcedure.updateMarkerWeight("RASI",settings["Fitting"]["Weight"]["RASI"]) cgmFittingProcedure.updateMarkerWeight("LPSI",settings["Fitting"]["Weight"]["LPSI"]) cgmFittingProcedure.updateMarkerWeight("RPSI",settings["Fitting"]["Weight"]["RPSI"]) cgmFittingProcedure.updateMarkerWeight("RTHI",settings["Fitting"]["Weight"]["RTHI"]) cgmFittingProcedure.updateMarkerWeight("RKNE",settings["Fitting"]["Weight"]["RKNE"]) cgmFittingProcedure.updateMarkerWeight("RTIB",settings["Fitting"]["Weight"]["RTIB"]) cgmFittingProcedure.updateMarkerWeight("RANK",settings["Fitting"]["Weight"]["RANK"]) cgmFittingProcedure.updateMarkerWeight("RHEE",settings["Fitting"]["Weight"]["RHEE"]) cgmFittingProcedure.updateMarkerWeight("RTOE",settings["Fitting"]["Weight"]["RTOE"]) cgmFittingProcedure.updateMarkerWeight("LTHI",settings["Fitting"]["Weight"]["LTHI"]) cgmFittingProcedure.updateMarkerWeight("LKNE",settings["Fitting"]["Weight"]["LKNE"]) cgmFittingProcedure.updateMarkerWeight("LTIB",settings["Fitting"]["Weight"]["LTIB"]) cgmFittingProcedure.updateMarkerWeight("LANK",settings["Fitting"]["Weight"]["LANK"]) cgmFittingProcedure.updateMarkerWeight("LHEE",settings["Fitting"]["Weight"]["LHEE"]) cgmFittingProcedure.updateMarkerWeight("LTOE",settings["Fitting"]["Weight"]["LTOE"]) cgmFittingProcedure.updateMarkerWeight("LTHAP",settings["Fitting"]["Weight"]["LTHAP"]) cgmFittingProcedure.updateMarkerWeight("LTHAD",settings["Fitting"]["Weight"]["LTHAD"]) cgmFittingProcedure.updateMarkerWeight("LTIAP",settings["Fitting"]["Weight"]["LTIAP"]) cgmFittingProcedure.updateMarkerWeight("LTIAD",settings["Fitting"]["Weight"]["LTIAD"]) cgmFittingProcedure.updateMarkerWeight("RTHAP",settings["Fitting"]["Weight"]["RTHAP"]) cgmFittingProcedure.updateMarkerWeight("RTHAD",settings["Fitting"]["Weight"]["RTHAD"]) cgmFittingProcedure.updateMarkerWeight("RTIAP",settings["Fitting"]["Weight"]["RTIAP"]) cgmFittingProcedure.updateMarkerWeight("RTIAD",settings["Fitting"]["Weight"]["RTIAD"]) cgmFittingProcedure.updateMarkerWeight("LSMH",settings["Fitting"]["Weight"]["LSMH"]) cgmFittingProcedure.updateMarkerWeight("LFMH",settings["Fitting"]["Weight"]["LFMH"]) cgmFittingProcedure.updateMarkerWeight("LVMH",settings["Fitting"]["Weight"]["LVMH"]) cgmFittingProcedure.updateMarkerWeight("RSMH",settings["Fitting"]["Weight"]["RSMH"]) cgmFittingProcedure.updateMarkerWeight("RFMH",settings["Fitting"]["Weight"]["RFMH"]) cgmFittingProcedure.updateMarkerWeight("RVMH",settings["Fitting"]["Weight"]["RVMH"]) # cgmFittingProcedure.updateMarkerWeight("LTHL",settings["Fitting"]["Weight"]["LTHL"]) # cgmFittingProcedure.updateMarkerWeight("LTHLD",settings["Fitting"]["Weight"]["LTHLD"]) # cgmFittingProcedure.updateMarkerWeight("LPAT",settings["Fitting"]["Weight"]["LPAT"]) # cgmFittingProcedure.updateMarkerWeight("LTIBL",settings["Fitting"]["Weight"]["LTIBL"]) # cgmFittingProcedure.updateMarkerWeight("RTHL",settings["Fitting"]["Weight"]["RTHL"]) # cgmFittingProcedure.updateMarkerWeight("RTHLD",settings["Fitting"]["Weight"]["RTHLD"]) # cgmFittingProcedure.updateMarkerWeight("RPAT",settings["Fitting"]["Weight"]["RPAT"]) # cgmFittingProcedure.updateMarkerWeight("RTIBL",settings["Fitting"]["Weight"]["RTIBL"]) osrf = opensimFilters.opensimFittingFilter(iksetupFile, scalingOsim, cgmFittingProcedure, str(DATA_PATH) ) acqStaticIK = osrf.run(acqStatic,str(DATA_PATH + calibrateFilenameLabelled )) # eventual static acquisition to consider for joint kinematics finalAcqStatic = acqStaticIK if ik_flag else acqStatic # --- final pyCGM2 model motion Filter --- # use fitted markers modMotionFitted=modelFilters.ModelMotionFilter(scp,finalAcqStatic,model,enums.motionMethod.Sodervisk) modMotionFitted.compute() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model,finalAcqStatic).compute(description="vectoriel", pointLabelSuffix=pointSuffix) # detection of traveling axis longitudinalAxis,forwardProgression,globalFrame = btkTools.findProgressionAxisFromPelvicMarkers(finalAcqStatic,["LASI","RASI","RPSI","LPSI"]) # absolute angles modelFilters.ModelAbsoluteAnglesFilter(model,finalAcqStatic, segmentLabels=["Left Foot","Right Foot","Pelvis"], angleLabels=["LFootProgress", "RFootProgress","Pelvis"], eulerSequences=["TOR","TOR", "ROT"], globalFrameOrientation = globalFrame, forwardProgression = forwardProgression).compute(pointLabelSuffix=pointSuffix) return model, finalAcqStatic
def fitting(model,DATA_PATH, reconstructFilenameLabelled, translators,settings, ik_flag,markerDiameter, pointSuffix, mfpa, momentProjection): # --- btk acquisition ---- acqGait = btkTools.smartReader(str(DATA_PATH + reconstructFilenameLabelled)) btkTools.checkMultipleSubject(acqGait) acqGait = btkTools.applyTranslators(acqGait,translators) validFrames,vff,vlf = btkTools.findValidFrames(acqGait,cgm2.CGM2_4LowerLimbs.TRACKING_MARKERS) # --- initial motion Filter --- scp=modelFilters.StaticCalibrationProcedure(model) modMotion=modelFilters.ModelMotionFilter(scp,acqGait,model,enums.motionMethod.Sodervisk) modMotion.compute() if ik_flag: # ---OPENSIM IK--- # --- opensim calibration Filter --- osimfile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\osim\\lowerLimb_ballsJoints.osim" # osimfile markersetFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_4\\cgm2_4-markerset.xml" # markerset cgmCalibrationprocedure = opensimFilters.CgmOpensimCalibrationProcedures(model) # procedure oscf = opensimFilters.opensimCalibrationFilter(osimfile, model, cgmCalibrationprocedure, str(DATA_PATH)) oscf.addMarkerSet(markersetFile) scalingOsim = oscf.build() # --- opensim Fitting Filter --- iksetupFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_4\\cgm2_4-ikSetUp_template.xml" # ik tl file cgmFittingProcedure = opensimFilters.CgmOpensimFittingProcedure(model) # procedure cgmFittingProcedure.updateMarkerWeight("LASI",settings["Fitting"]["Weight"]["LASI"]) cgmFittingProcedure.updateMarkerWeight("RASI",settings["Fitting"]["Weight"]["RASI"]) cgmFittingProcedure.updateMarkerWeight("LPSI",settings["Fitting"]["Weight"]["LPSI"]) cgmFittingProcedure.updateMarkerWeight("RPSI",settings["Fitting"]["Weight"]["RPSI"]) cgmFittingProcedure.updateMarkerWeight("RTHI",settings["Fitting"]["Weight"]["RTHI"]) cgmFittingProcedure.updateMarkerWeight("RKNE",settings["Fitting"]["Weight"]["RKNE"]) cgmFittingProcedure.updateMarkerWeight("RTIB",settings["Fitting"]["Weight"]["RTIB"]) cgmFittingProcedure.updateMarkerWeight("RANK",settings["Fitting"]["Weight"]["RANK"]) cgmFittingProcedure.updateMarkerWeight("RHEE",settings["Fitting"]["Weight"]["RHEE"]) cgmFittingProcedure.updateMarkerWeight("RTOE",settings["Fitting"]["Weight"]["RTOE"]) cgmFittingProcedure.updateMarkerWeight("LTHI",settings["Fitting"]["Weight"]["LTHI"]) cgmFittingProcedure.updateMarkerWeight("LKNE",settings["Fitting"]["Weight"]["LKNE"]) cgmFittingProcedure.updateMarkerWeight("LTIB",settings["Fitting"]["Weight"]["LTIB"]) cgmFittingProcedure.updateMarkerWeight("LANK",settings["Fitting"]["Weight"]["LANK"]) cgmFittingProcedure.updateMarkerWeight("LHEE",settings["Fitting"]["Weight"]["LHEE"]) cgmFittingProcedure.updateMarkerWeight("LTOE",settings["Fitting"]["Weight"]["LTOE"]) cgmFittingProcedure.updateMarkerWeight("LTHAP",settings["Fitting"]["Weight"]["LTHAP"]) cgmFittingProcedure.updateMarkerWeight("LTHAD",settings["Fitting"]["Weight"]["LTHAD"]) cgmFittingProcedure.updateMarkerWeight("LTIAP",settings["Fitting"]["Weight"]["LTIAP"]) cgmFittingProcedure.updateMarkerWeight("LTIAD",settings["Fitting"]["Weight"]["LTIAD"]) cgmFittingProcedure.updateMarkerWeight("RTHAP",settings["Fitting"]["Weight"]["RTHAP"]) cgmFittingProcedure.updateMarkerWeight("RTHAD",settings["Fitting"]["Weight"]["RTHAD"]) cgmFittingProcedure.updateMarkerWeight("RTIAP",settings["Fitting"]["Weight"]["RTIAP"]) cgmFittingProcedure.updateMarkerWeight("RTIAD",settings["Fitting"]["Weight"]["RTIAD"]) cgmFittingProcedure.updateMarkerWeight("LSMH",settings["Fitting"]["Weight"]["LSMH"]) cgmFittingProcedure.updateMarkerWeight("LFMH",settings["Fitting"]["Weight"]["LFMH"]) cgmFittingProcedure.updateMarkerWeight("LVMH",settings["Fitting"]["Weight"]["LVMH"]) cgmFittingProcedure.updateMarkerWeight("RSMH",settings["Fitting"]["Weight"]["RSMH"]) cgmFittingProcedure.updateMarkerWeight("RFMH",settings["Fitting"]["Weight"]["RFMH"]) cgmFittingProcedure.updateMarkerWeight("RVMH",settings["Fitting"]["Weight"]["RVMH"]) # cgmFittingProcedure.updateMarkerWeight("LTHL",settings["Fitting"]["Weight"]["LTHL"]) # cgmFittingProcedure.updateMarkerWeight("LTHLD",settings["Fitting"]["Weight"]["LTHLD"]) # cgmFittingProcedure.updateMarkerWeight("LPAT",settings["Fitting"]["Weight"]["LPAT"]) # cgmFittingProcedure.updateMarkerWeight("LTIBL",settings["Fitting"]["Weight"]["LTIBL"]) # cgmFittingProcedure.updateMarkerWeight("RTHL",settings["Fitting"]["Weight"]["RTHL"]) # cgmFittingProcedure.updateMarkerWeight("RTHLD",settings["Fitting"]["Weight"]["RTHLD"]) # cgmFittingProcedure.updateMarkerWeight("RPAT",settings["Fitting"]["Weight"]["RPAT"]) # cgmFittingProcedure.updateMarkerWeight("RTIBL",settings["Fitting"]["Weight"]["RTIBL"]) osrf = opensimFilters.opensimFittingFilter(iksetupFile, scalingOsim, cgmFittingProcedure, str(DATA_PATH) ) logging.info("-------INVERSE KINEMATICS IN PROGRESS----------") acqIK = osrf.run(acqGait,str(DATA_PATH + reconstructFilenameLabelled )) logging.info("-------INVERSE KINEMATICS DONE-----------------") # eventual gait acquisition to consider for joint kinematics finalAcqGait = acqIK if ik_flag else acqGait # --- final pyCGM2 model motion Filter --- # use fitted markers modMotionFitted=modelFilters.ModelMotionFilter(scp,finalAcqGait,model,enums.motionMethod.Sodervisk , markerDiameter=markerDiameter) modMotionFitted.compute() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model,finalAcqGait).compute(description="vectoriel", pointLabelSuffix=pointSuffix) # detection of traveling axis longitudinalAxis,forwardProgression,globalFrame = btkTools.findProgressionAxisFromPelvicMarkers(finalAcqGait,["LASI","LPSI","RASI","RPSI"]) # absolute angles modelFilters.ModelAbsoluteAnglesFilter(model,finalAcqGait, segmentLabels=["Left Foot","Right Foot","Pelvis"], angleLabels=["LFootProgress", "RFootProgress","Pelvis"], eulerSequences=["TOR","TOR", "ROT"], globalFrameOrientation = globalFrame, forwardProgression = forwardProgression).compute(pointLabelSuffix=pointSuffix) #---- Body segment parameters---- bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() # --- force plate handling---- # find foot in contact mappedForcePlate = forceplates.matchingFootSideOnForceplate(finalAcqGait) forceplates.addForcePlateGeneralEvents(finalAcqGait,mappedForcePlate) logging.info("Force plate assignment : %s" %mappedForcePlate) if mfpa is not None: if len(mfpa) != len(mappedForcePlate): raise Exception("[pyCGM2] manual force plate assignment badly sets. Wrong force plate number. %s force plate require" %(str(len(mappedForcePlate)))) else: mappedForcePlate = mfpa forceplates.addForcePlateGeneralEvents(finalAcqGait,mappedForcePlate) logging.warning("Manual Force plate assignment : %s" %mappedForcePlate) # assembly foot and force plate modelFilters.ForcePlateAssemblyFilter(model,finalAcqGait,mappedForcePlate, leftSegmentLabel="Left Foot", rightSegmentLabel="Right Foot").compute() #---- Joint kinetics---- idp = modelFilters.CGMLowerlimbInverseDynamicProcedure() modelFilters.InverseDynamicFilter(model, finalAcqGait, procedure = idp, projection = momentProjection ).compute(pointLabelSuffix=pointSuffix) #---- Joint energetics---- modelFilters.JointPowerFilter(model,finalAcqGait).compute(pointLabelSuffix=pointSuffix) #---- zero unvalid frames --- btkTools.applyValidFramesOnOutput(finalAcqGait,validFrames) return finalAcqGait
def full_IK(cls): MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM2\\cgm2.4\\medial\\" staticFilename = "static.c3d" gaitFilename = "gait Trial 01.c3d" markerDiameter = 14 mp = { 'Bodymass': 69.0, 'LeftLegLength': 930.0, 'RightLegLength': 930.0, 'LeftKneeWidth': 94.0, 'RightKneeWidth': 64.0, 'LeftAnkleWidth': 67.0, 'RightAnkleWidth': 62.0, 'LeftSoleDelta': 0, 'RightSoleDelta': 0, "LeftToeOffset": 0, "RightToeOffset": 0, } # --- Calibration --- acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model = cgm2.CGM2_4LowerLimbs() model.configure() model.addAnthropoInputParameters(mp) # ---- Calibration ---- scp = modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp, acqStatic, model).compute() # cgm decorator modelDecorator.HipJointCenterDecorator(model).hara() modelDecorator.KneeCalibrationDecorator(model).midCondyles( acqStatic, markerDiameter=markerDiameter, side="both") modelDecorator.AnkleCalibrationDecorator(model).midMaleolus( acqStatic, markerDiameter=markerDiameter, side="both") # final modelFilters.ModelCalibrationFilter( scp, acqStatic, model, markerDiameter=markerDiameter).compute() # ------ Fitting ------- acqGait = btkTools.smartReader(str(MAIN_PATH + gaitFilename)) # Motion FILTER modMotion = modelFilters.ModelMotionFilter( scp, acqGait, model, pyCGM2Enums.motionMethod.Sodervisk) modMotion.compute() # relative angles modelFilters.ModelJCSFilter(model, acqGait).compute( description="vectoriel", pointLabelSuffix="cgm1_6dof") # absolute angles longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromPelvicMarkers( acqGait, ["LASI", "RASI", "RPSI", "LPSI"]) modelFilters.ModelAbsoluteAnglesFilter( model, acqGait, segmentLabels=["Left Foot", "Right Foot", "Pelvis"], angleLabels=["LFootProgress", "RFootProgress", "Pelvis"], eulerSequences=["TOR", "TOR", "ROT"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix="cgm1_6dof") # ---Marker decomp filter---- mtf = modelFilters.TrackingMarkerDecompositionFilter(model, acqGait) mtf.decompose() # ------- OPENSIM IK -------------------------------------- # --- osim builder --- cgmCalibrationprocedure = opensimFilters.CgmOpensimCalibrationProcedures( model) markersetFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_4\\cgm2_4-markerset - expert.xml" osimfile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\osim\\lowerLimb_ballsJoints.osim" oscf = opensimFilters.opensimCalibrationFilter( osimfile, model, cgmCalibrationprocedure, MAIN_PATH) oscf.addMarkerSet(markersetFile) scalingOsim = oscf.build(exportOsim=False) # --- fitting --- #procedure cgmFittingProcedure = opensimFilters.CgmOpensimFittingProcedure( model, expertMode=True) iksetupFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_4\\cgm2_4-expert-ikSetUp_template.xml" osrf = opensimFilters.opensimFittingFilter(iksetupFile, scalingOsim, cgmFittingProcedure, MAIN_PATH) acqIK = osrf.run(acqGait, str(MAIN_PATH + gaitFilename), exportSetUp=False) # -------- NEW MOTION FILTER ON IK MARKERS ------------------ modMotion_ik = modelFilters.ModelMotionFilter( scp, acqIK, model, pyCGM2Enums.motionMethod.Sodervisk, useForMotionTest=True) modMotion_ik.compute() finalJcs = modelFilters.ModelJCSFilter(model, acqIK) finalJcs.setFilterBool(False) finalJcs.compute(description="ik", pointLabelSuffix="2_ik") # btkTools.smartWriter(acqIK, "cgm24e_fullIK.c3d")
def calibrate(DATA_PATH, calibrateFilenameLabelled, translators, settings, required_mp, optional_mp, ik_flag, leftFlatFoot, rightFlatFoot, headFlat, markerDiameter, hjcMethod, pointSuffix, **kwargs): """ Calibration of the CGM2.5 :param DATA_PATH [str]: path to your data :param calibrateFilenameLabelled [str]: c3d file :param translators [dict]: translators to apply :param required_mp [dict]: required anthropometric data :param optional_mp [dict]: optional anthropometric data (ex: LThighOffset,...) :param ik_flag [bool]: enable the inverse kinematic solver :param leftFlatFoot [bool]: enable of the flat foot option for the left foot :param rightFlatFoot [bool]: enable of the flat foot option for the right foot :param headFlat [bool]: enable of the head flat option :param markerDiameter [double]: marker diameter (mm) :param hjcMethod [str or list of 3 float]: method for locating the hip joint centre :param pointSuffix [str]: suffix to add to model outputs """ # ---btk acquisition--- if "forceBtkAcq" in kwargs.keys(): acqStatic = kwargs["forceBtkAcq"] else: acqStatic = btkTools.smartReader( str(DATA_PATH + calibrateFilenameLabelled)) btkTools.checkMultipleSubject(acqStatic) acqStatic = btkTools.applyTranslators(acqStatic, translators) # ---check marker set used---- dcm = cgm.CGM.detectCalibrationMethods(acqStatic) # --------------------------MODEL-------------------------------------- # ---definition--- model = cgm2.CGM2_5() model.configure(acq=acqStatic, detectedCalibrationMethods=dcm) model.addAnthropoInputParameters(required_mp, optional=optional_mp) # --store calibration parameters-- model.setStaticFilename(calibrateFilenameLabelled) model.setCalibrationProperty("leftFlatFoot", leftFlatFoot) model.setCalibrationProperty("rightFlatFoot", rightFlatFoot) model.setCalibrationProperty("headFlat", headFlat) model.setCalibrationProperty("markerDiameter", markerDiameter) # --------------------------STATIC CALBRATION-------------------------- scp = modelFilters.StaticCalibrationProcedure( model) # load calibration procedure # ---initial calibration filter---- # use if all optional mp are zero modelFilters.ModelCalibrationFilter( scp, acqStatic, model, leftFlatFoot=leftFlatFoot, rightFlatFoot=rightFlatFoot, headFlat=headFlat, markerDiameter=markerDiameter, ).compute() # ---- Decorators ----- decorators.applyBasicDecorators(dcm, model, acqStatic, optional_mp, markerDiameter) decorators.applyHJCDecorators(model, hjcMethod) # ----Final Calibration filter if model previously decorated ----- if model.decoratedModel: # initial static filter modelFilters.ModelCalibrationFilter( scp, acqStatic, model, leftFlatFoot=leftFlatFoot, rightFlatFoot=rightFlatFoot, headFlat=headFlat, markerDiameter=markerDiameter).compute() # ----------------------CGM MODELLING---------------------------------- # ----motion filter---- modMotion = modelFilters.ModelMotionFilter(scp, acqStatic, model, enums.motionMethod.Sodervisk, markerDiameter=markerDiameter) modMotion.compute() if ik_flag: # ---OPENSIM IK--- # --- opensim calibration Filter --- osimfile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\osim\\lowerLimb_ballsJoints.osim" # osimfile markersetFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_4\\cgm2_4-markerset.xml" # markerset cgmCalibrationprocedure = opensimFilters.CgmOpensimCalibrationProcedures( model) # procedure oscf = opensimFilters.opensimCalibrationFilter( osimfile, model, cgmCalibrationprocedure, str(DATA_PATH)) oscf.addMarkerSet(markersetFile) scalingOsim = oscf.build() # --- opensim Fitting Filter --- iksetupFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_4\\cgm2_4-ikSetUp_template.xml" # ik tool file cgmFittingProcedure = opensimFilters.CgmOpensimFittingProcedure( model) # procedure cgmFittingProcedure.updateMarkerWeight( "LASI", settings["Fitting"]["Weight"]["LASI"]) cgmFittingProcedure.updateMarkerWeight( "RASI", settings["Fitting"]["Weight"]["RASI"]) cgmFittingProcedure.updateMarkerWeight( "LPSI", settings["Fitting"]["Weight"]["LPSI"]) cgmFittingProcedure.updateMarkerWeight( "RPSI", settings["Fitting"]["Weight"]["RPSI"]) cgmFittingProcedure.updateMarkerWeight( "RTHI", settings["Fitting"]["Weight"]["RTHI"]) cgmFittingProcedure.updateMarkerWeight( "RKNE", settings["Fitting"]["Weight"]["RKNE"]) cgmFittingProcedure.updateMarkerWeight( "RTIB", settings["Fitting"]["Weight"]["RTIB"]) cgmFittingProcedure.updateMarkerWeight( "RANK", settings["Fitting"]["Weight"]["RANK"]) cgmFittingProcedure.updateMarkerWeight( "RHEE", settings["Fitting"]["Weight"]["RHEE"]) cgmFittingProcedure.updateMarkerWeight( "RTOE", settings["Fitting"]["Weight"]["RTOE"]) cgmFittingProcedure.updateMarkerWeight( "LTHI", settings["Fitting"]["Weight"]["LTHI"]) cgmFittingProcedure.updateMarkerWeight( "LKNE", settings["Fitting"]["Weight"]["LKNE"]) cgmFittingProcedure.updateMarkerWeight( "LTIB", settings["Fitting"]["Weight"]["LTIB"]) cgmFittingProcedure.updateMarkerWeight( "LANK", settings["Fitting"]["Weight"]["LANK"]) cgmFittingProcedure.updateMarkerWeight( "LHEE", settings["Fitting"]["Weight"]["LHEE"]) cgmFittingProcedure.updateMarkerWeight( "LTOE", settings["Fitting"]["Weight"]["LTOE"]) cgmFittingProcedure.updateMarkerWeight( "LTHAP", settings["Fitting"]["Weight"]["LTHAP"]) cgmFittingProcedure.updateMarkerWeight( "LTHAD", settings["Fitting"]["Weight"]["LTHAD"]) cgmFittingProcedure.updateMarkerWeight( "LTIAP", settings["Fitting"]["Weight"]["LTIAP"]) cgmFittingProcedure.updateMarkerWeight( "LTIAD", settings["Fitting"]["Weight"]["LTIAD"]) cgmFittingProcedure.updateMarkerWeight( "RTHAP", settings["Fitting"]["Weight"]["RTHAP"]) cgmFittingProcedure.updateMarkerWeight( "RTHAD", settings["Fitting"]["Weight"]["RTHAD"]) cgmFittingProcedure.updateMarkerWeight( "RTIAP", settings["Fitting"]["Weight"]["RTIAP"]) cgmFittingProcedure.updateMarkerWeight( "RTIAD", settings["Fitting"]["Weight"]["RTIAD"]) cgmFittingProcedure.updateMarkerWeight( "LSMH", settings["Fitting"]["Weight"]["LSMH"]) cgmFittingProcedure.updateMarkerWeight( "LFMH", settings["Fitting"]["Weight"]["LFMH"]) cgmFittingProcedure.updateMarkerWeight( "LVMH", settings["Fitting"]["Weight"]["LVMH"]) cgmFittingProcedure.updateMarkerWeight( "RSMH", settings["Fitting"]["Weight"]["RSMH"]) cgmFittingProcedure.updateMarkerWeight( "RFMH", settings["Fitting"]["Weight"]["RFMH"]) cgmFittingProcedure.updateMarkerWeight( "RVMH", settings["Fitting"]["Weight"]["RVMH"]) # cgmFittingProcedure.updateMarkerWeight("LTHL",settings["Fitting"]["Weight"]["LTHL"]) # cgmFittingProcedure.updateMarkerWeight("LTHLD",settings["Fitting"]["Weight"]["LTHLD"]) # cgmFittingProcedure.updateMarkerWeight("LPAT",settings["Fitting"]["Weight"]["LPAT"]) # cgmFittingProcedure.updateMarkerWeight("LTIBL",settings["Fitting"]["Weight"]["LTIBL"]) # cgmFittingProcedure.updateMarkerWeight("RTHL",settings["Fitting"]["Weight"]["RTHL"]) # cgmFittingProcedure.updateMarkerWeight("RTHLD",settings["Fitting"]["Weight"]["RTHLD"]) # cgmFittingProcedure.updateMarkerWeight("RPAT",settings["Fitting"]["Weight"]["RPAT"]) # cgmFittingProcedure.updateMarkerWeight("RTIBL",settings["Fitting"]["Weight"]["RTIBL"]) osrf = opensimFilters.opensimFittingFilter(iksetupFile, scalingOsim, cgmFittingProcedure, str(DATA_PATH)) acqStaticIK = osrf.run(acqStatic, str(DATA_PATH + calibrateFilenameLabelled)) # eventual static acquisition to consider for joint kinematics finalAcqStatic = acqStaticIK if ik_flag else acqStatic # --- final pyCGM2 model motion Filter --- # use fitted markers modMotionFitted = modelFilters.ModelMotionFilter( scp, finalAcqStatic, model, enums.motionMethod.Sodervisk) modMotionFitted.compute() if "displayCoordinateSystem" in kwargs.keys( ) and kwargs["displayCoordinateSystem"]: csp = modelFilters.ModelCoordinateSystemProcedure(model) csdf = modelFilters.CoordinateSystemDisplayFilter( csp, model, finalAcqStatic) csdf.setStatic(False) csdf.display() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model, finalAcqStatic).compute( description="vectoriel", pointLabelSuffix=pointSuffix) # detection of traveling axis + absolute angle if model.m_bodypart != enums.BodyPart.UpperLimb: longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromPelvicMarkers( finalAcqStatic, ["LASI", "LPSI", "RASI", "RPSI"]) else: longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromLongAxis( finalAcqStatic, "C7", "CLAV") if model.m_bodypart != enums.BodyPart.UpperLimb: modelFilters.ModelAbsoluteAnglesFilter( model, finalAcqStatic, segmentLabels=["Left Foot", "Right Foot", "Pelvis"], angleLabels=["LFootProgress", "RFootProgress", "Pelvis"], eulerSequences=["TOR", "TOR", "ROT"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.LowerLimbTrunk: modelFilters.ModelAbsoluteAnglesFilter( model, finalAcqStatic, segmentLabels=["Thorax"], angleLabels=["Thorax"], eulerSequences=["YXZ"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.UpperLimb or model.m_bodypart == enums.BodyPart.FullBody: modelFilters.ModelAbsoluteAnglesFilter( model, finalAcqStatic, segmentLabels=["Thorax", "Head"], angleLabels=["Thorax", "Head"], eulerSequences=["YXZ", "TOR"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) # BSP model bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() if model.m_bodypart == enums.BodyPart.FullBody: modelFilters.CentreOfMassFilter( model, finalAcqStatic).compute(pointLabelSuffix=pointSuffix) return model, finalAcqStatic
def calibrate(DATA_PATH, calibrateFilenameLabelled, translators, required_mp, optional_mp, leftFlatFoot, rightFlatFoot, markerDiameter, hjcMethod, pointSuffix): # --------------------------ACQUISITION ------------------------------------ # ---btk acquisition--- acqStatic = btkTools.smartReader(str(DATA_PATH + calibrateFilenameLabelled)) btkTools.checkMultipleSubject(acqStatic) acqStatic = btkTools.applyTranslators(acqStatic, translators) # ---definition--- model = cgm2.CGM2_1LowerLimbs() model.configure() model.addAnthropoInputParameters(required_mp, optional=optional_mp) # --store calibration parameters-- model.setStaticFilename(calibrateFilenameLabelled) model.setCalibrationProperty("leftFlatFoot", leftFlatFoot) model.setCalibrationProperty("rightFlatFoot", rightFlatFoot) model.setCalibrationProperty("markerDiameter", markerDiameter) # ---check marker set used---- smc = cgm.CGM.checkCGM1_StaticMarkerConfig(acqStatic) # --------------------------STATIC CALBRATION-------------------------- scp = modelFilters.StaticCalibrationProcedure( model) # load calibration procedure # ---initial calibration filter---- # use if all optional mp are zero modelFilters.ModelCalibrationFilter( scp, acqStatic, model, leftFlatFoot=leftFlatFoot, rightFlatFoot=rightFlatFoot, markerDiameter=markerDiameter, ).compute() # ---- Decorators ----- decorators.applyDecorators_CGM(smc, model, acqStatic, optional_mp, markerDiameter) decorators.applyHJCDecorators(model, hjcMethod) # ----Final Calibration filter if model previously decorated ----- if model.decoratedModel: # initial static filter modelFilters.ModelCalibrationFilter( scp, acqStatic, model, leftFlatFoot=leftFlatFoot, rightFlatFoot=rightFlatFoot, markerDiameter=markerDiameter, ).compute() # ----------------------CGM MODELLING---------------------------------- # ----motion filter---- # notice : viconCGM1compatible option duplicate error on Construction of the foot coordinate system modMotion = modelFilters.ModelMotionFilter(scp, acqStatic, model, enums.motionMethod.Determinist, markerDiameter=markerDiameter) modMotion.compute() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model, acqStatic).compute( description="vectoriel", pointLabelSuffix=pointSuffix) # detection of traveling axis longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromPelvicMarkers( acqStatic, ["LASI", "RASI", "RPSI", "LPSI"]) # absolute angles modelFilters.ModelAbsoluteAnglesFilter( model, acqStatic, segmentLabels=["Left Foot", "Right Foot", "Pelvis"], angleLabels=["LFootProgress", "RFootProgress", "Pelvis"], eulerSequences=["TOR", "TOR", "ROT"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) return model, acqStatic
def fitting(model, DATA_PATH, reconstructFilenameLabelled, translators, markerDiameter, pointSuffix, mfpa, momentProjection): # --------------------------ACQUISITION ------------------------------------ # --- btk acquisition ---- acqGait = btkTools.smartReader(str(DATA_PATH + reconstructFilenameLabelled)) btkTools.checkMultipleSubject(acqGait) acqGait = btkTools.applyTranslators(acqGait, translators) validFrames, vff, vlf = btkTools.findValidFrames( acqGait, cgm.CGM1LowerLimbs.TRACKING_MARKERS) scp = modelFilters.StaticCalibrationProcedure(model) # ---Motion filter---- modMotion = modelFilters.ModelMotionFilter(scp, acqGait, model, enums.motionMethod.Determinist, markerDiameter=markerDiameter) modMotion.compute() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model, acqGait).compute(description="vectoriel", pointLabelSuffix=pointSuffix) # detection of traveling axis longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromPelvicMarkers( acqGait, ["LASI", "LPSI", "RASI", "RPSI"]) # absolute angles modelFilters.ModelAbsoluteAnglesFilter( model, acqGait, segmentLabels=["Left Foot", "Right Foot", "Pelvis"], angleLabels=["LFootProgress", "RFootProgress", "Pelvis"], eulerSequences=["TOR", "TOR", "ROT"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) #---- Body segment parameters---- bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() # --- force plate handling---- # find foot in contact mappedForcePlate = forceplates.matchingFootSideOnForceplate(acqGait) forceplates.addForcePlateGeneralEvents(acqGait, mappedForcePlate) logging.info("Automatic Force plate assignment : %s" % mappedForcePlate) if mfpa is not None: if len(mfpa) != len(mappedForcePlate): raise Exception( "[pyCGM2] manual force plate assignment badly sets. Wrong force plate number. %s force plate require" % (str(len(mappedForcePlate)))) else: mappedForcePlate = mfpa forceplates.addForcePlateGeneralEvents(acqGait, mappedForcePlate) logging.warning("Manual Force plate assignment : %s" % mappedForcePlate) # assembly foot and force plate modelFilters.ForcePlateAssemblyFilter( model, acqGait, mappedForcePlate, leftSegmentLabel="Left Foot", rightSegmentLabel="Right Foot").compute() #---- Joint kinetics---- idp = modelFilters.CGMLowerlimbInverseDynamicProcedure() modelFilters.InverseDynamicFilter( model, acqGait, procedure=idp, projection=momentProjection).compute(pointLabelSuffix=pointSuffix) #---- Joint energetics---- modelFilters.JointPowerFilter( model, acqGait).compute(pointLabelSuffix=pointSuffix) #---- zero unvalid frames --- btkTools.applyValidFramesOnOutput(acqGait, validFrames) return acqGait
def calibrate(DATA_PATH, calibrateFilenameLabelled, translators, required_mp, optional_mp, leftFlatFoot, rightFlatFoot, headFlat, markerDiameter, pointSuffix, **kwargs): """ Calibration of the CGM1 :param DATA_PATH [str]: path to your data :param calibrateFilenameLabelled [str]: c3d file :param translators [dict]: translators to apply :param required_mp [dict]: required anthropometric data :param optional_mp [dict]: optional anthropometric data (ex: LThighOffset,...) :param leftFlatFoot [bool]: enable of the flat foot option for the left foot :param rightFlatFoot [bool]: enable of the flat foot option for the right foot :param headFlat [bool]: enable of the head flat option :param markerDiameter [double]: marker diameter (mm) :param pointSuffix [str]: suffix to add to model outputs """ # --------------------------ACQUISITION ------------------------------------ if "forceBtkAcq" in kwargs.keys(): acqStatic = kwargs["forceBtkAcq"] else: # ---btk acquisition--- acqStatic = btkTools.smartReader( str(DATA_PATH + calibrateFilenameLabelled)) btkTools.checkMultipleSubject(acqStatic) acqStatic = btkTools.applyTranslators(acqStatic, translators) # ---check marker set used---- dcm = cgm.CGM.detectCalibrationMethods(acqStatic) # ---definition--- model = cgm.CGM1() model.configure(acq=acqStatic, detectedCalibrationMethods=dcm) model.addAnthropoInputParameters(required_mp, optional=optional_mp) # --store calibration parameters-- model.setStaticFilename(calibrateFilenameLabelled) model.setCalibrationProperty("leftFlatFoot", leftFlatFoot) model.setCalibrationProperty("rightFlatFoot", rightFlatFoot) model.setCalibrationProperty("headFlat", headFlat) model.setCalibrationProperty("markerDiameter", markerDiameter) # --------------------------STATIC CALBRATION-------------------------- scp = modelFilters.StaticCalibrationProcedure( model) # load calibration procedure # ---initial calibration filter---- modelFilters.ModelCalibrationFilter(scp, acqStatic, model, leftFlatFoot=leftFlatFoot, rightFlatFoot=rightFlatFoot, markerDiameter=markerDiameter, headFlat=headFlat, viconCGM1compatible=True).compute() # ---- Decorators ----- decorators.applyBasicDecorators(dcm, model, acqStatic, optional_mp, markerDiameter, cgm1only=True) pigStaticMarkers = cgm.CGM.get_markerLabelForPiGStatic(dcm) # ----Final Calibration filter if model previously decorated ----- if model.decoratedModel: # initial static filter modelFilters.ModelCalibrationFilter( scp, acqStatic, model, leftFlatFoot=leftFlatFoot, rightFlatFoot=rightFlatFoot, headFlat=headFlat, markerDiameter=markerDiameter, viconCGM1compatible=True).compute() # ----------------------CGM MODELLING---------------------------------- # ----motion filter---- # notice : viconCGM1compatible option duplicate error on Construction of the foot coordinate system modMotion = modelFilters.ModelMotionFilter( scp, acqStatic, model, enums.motionMethod.Determinist, markerDiameter=markerDiameter, viconCGM1compatible=False, pigStatic=True, useLeftKJCmarker=pigStaticMarkers[0], useLeftAJCmarker=pigStaticMarkers[1], useRightKJCmarker=pigStaticMarkers[2], useRightAJCmarker=pigStaticMarkers[3]) modMotion.compute() if "displayCoordinateSystem" in kwargs.keys( ) and kwargs["displayCoordinateSystem"]: csp = modelFilters.ModelCoordinateSystemProcedure(model) csdf = modelFilters.CoordinateSystemDisplayFilter( csp, model, acqStatic) csdf.setStatic(False) csdf.display() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model, acqStatic).compute( description="vectoriel", pointLabelSuffix=pointSuffix) # detection of traveling axis + absolute angle if model.m_bodypart != enums.BodyPart.UpperLimb: longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromPelvicMarkers( acqStatic, ["LASI", "LPSI", "RASI", "RPSI"]) else: longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromLongAxis( acqStatic, "C7", "CLAV") if model.m_bodypart != enums.BodyPart.UpperLimb: modelFilters.ModelAbsoluteAnglesFilter( model, acqStatic, segmentLabels=["Left Foot", "Right Foot", "Pelvis"], angleLabels=["LFootProgress", "RFootProgress", "Pelvis"], eulerSequences=["TOR", "TOR", "TOR"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.LowerLimbTrunk: modelFilters.ModelAbsoluteAnglesFilter( model, acqStatic, segmentLabels=["Thorax"], angleLabels=["Thorax"], eulerSequences=["YXZ"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.UpperLimb or model.m_bodypart == enums.BodyPart.FullBody: modelFilters.ModelAbsoluteAnglesFilter( model, acqStatic, segmentLabels=["Thorax", "Head"], angleLabels=["Thorax", "Head"], eulerSequences=["YXZ", "TOR"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) # BSP model bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() if model.m_bodypart == enums.BodyPart.FullBody: modelFilters.CentreOfMassFilter( model, acqStatic).compute(pointLabelSuffix=pointSuffix) return model, acqStatic
def fitting(model, DATA_PATH, reconstructFilenameLabelled, translators, markerDiameter, pointSuffix, mfpa, momentProjection, **kwargs): """ Fitting of the CGM1 :param model [str]: pyCGM2 model previously calibrated :param DATA_PATH [str]: path to your data :param reconstructFilenameLabelled [string list]: c3d files :param translators [dict]: translators to apply :param mfpa [str]: manual force plate assignement :param markerDiameter [double]: marker diameter (mm) :param pointSuffix [str]: suffix to add to model outputs :param momentProjection [str]: Coordinate system in which joint moment is expressed """ # --------------------------ACQUISITION ------------------------------------ if "forceBtkAcq" in kwargs.keys(): acqGait = kwargs["forceBtkAcq"] else: # --- btk acquisition ---- acqGait = btkTools.smartReader( str(DATA_PATH + reconstructFilenameLabelled)) btkTools.checkMultipleSubject(acqGait) acqGait = btkTools.applyTranslators(acqGait, translators) trackingMarkers = model.getTrackingMarkers() validFrames, vff, vlf = btkTools.findValidFrames(acqGait, trackingMarkers) scp = modelFilters.StaticCalibrationProcedure(model) # procedure # ---Motion filter---- modMotion = modelFilters.ModelMotionFilter(scp, acqGait, model, enums.motionMethod.Determinist, markerDiameter=markerDiameter, viconCGM1compatible=True) modMotion.compute() if "displayCoordinateSystem" in kwargs.keys( ) and kwargs["displayCoordinateSystem"]: csp = modelFilters.ModelCoordinateSystemProcedure(model) csdf = modelFilters.CoordinateSystemDisplayFilter(csp, model, acqGait) csdf.setStatic(False) csdf.display() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model, acqGait).compute(description="vectoriel", pointLabelSuffix=pointSuffix) # detection of traveling axis + absolute angle if model.m_bodypart != enums.BodyPart.UpperLimb: longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromPelvicMarkers( acqGait, ["LASI", "LPSI", "RASI", "RPSI"]) else: longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromLongAxis( acqGait, "C7", "CLAV") if model.m_bodypart != enums.BodyPart.UpperLimb: modelFilters.ModelAbsoluteAnglesFilter( model, acqGait, segmentLabels=["Left Foot", "Right Foot", "Pelvis"], angleLabels=["LFootProgress", "RFootProgress", "Pelvis"], eulerSequences=["TOR", "TOR", "TOR"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.LowerLimbTrunk: modelFilters.ModelAbsoluteAnglesFilter( model, acqGait, segmentLabels=["Thorax"], angleLabels=["Thorax"], eulerSequences=["YXZ"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.UpperLimb or model.m_bodypart == enums.BodyPart.FullBody: modelFilters.ModelAbsoluteAnglesFilter( model, acqGait, segmentLabels=["Thorax", "Head"], angleLabels=["Thorax", "Head"], eulerSequences=["YXZ", "TOR"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) #---- Body segment parameters---- bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() #---- CentreOfMass---- if model.m_bodypart == enums.BodyPart.FullBody: modelFilters.CentreOfMassFilter( model, acqGait).compute(pointLabelSuffix=pointSuffix) # Inverse dynamics if model.m_bodypart != enums.BodyPart.UpperLimb: # --- force plate handling---- # find foot in contact mappedForcePlate = forceplates.matchingFootSideOnForceplate(acqGait, mfpa=mfpa) forceplates.addForcePlateGeneralEvents(acqGait, mappedForcePlate) logging.warning("Manual Force plate assignment : %s" % mappedForcePlate) # assembly foot and force plate modelFilters.ForcePlateAssemblyFilter( model, acqGait, mappedForcePlate, leftSegmentLabel="Left Foot", rightSegmentLabel="Right Foot").compute() #---- Joint kinetics---- idp = modelFilters.CGMLowerlimbInverseDynamicProcedure() modelFilters.InverseDynamicFilter( model, acqGait, procedure=idp, projection=momentProjection, viconCGM1compatible=True).compute(pointLabelSuffix=pointSuffix) #---- Joint energetics---- modelFilters.JointPowerFilter( model, acqGait).compute(pointLabelSuffix=pointSuffix) #---- zero unvalid frames --- btkTools.applyValidFramesOnOutput(acqGait, validFrames) return acqGait
def basicCGM1_absoluteAngles_pelikin(cls): """ """ MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\Pelikin\\" staticFilename = "MRI-US-01, 2008-08-08, 3DGA 02.c3d" acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model=cgm.CGM1LowerLimbs() model.configure() markerDiameter=14 mp={ 'Bodymass' : 71.0, 'LeftLegLength' : 860.0, 'RightLegLength' : 865.0 , 'LeftKneeWidth' : 102.0, 'RightKneeWidth' : 103.4, 'LeftAnkleWidth' : 75.3, 'RightAnkleWidth' : 72.9, 'LeftSoleDelta' : 0, 'RightSoleDelta' : 0, } model.addAnthropoInputParameters(mp) scp=modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp,acqStatic,model).compute() # ------ Test 1 Motion Axe X ------- gaitFilename="MRI-US-01, 2008-08-08, 3DGA 14.c3d" acqGait = btkTools.smartReader(str(MAIN_PATH + gaitFilename)) # Motion FILTER # optimisation segmentaire et calibration fonctionnel modMotion=modelFilters.ModelMotionFilter(scp,acqGait,model,pyCGM2Enums.motionMethod.Determinist) modMotion.compute() longitudinalAxis,forwardProgression,globalFrame = btkTools.findProgressionAxisFromPelvicMarkers(acqGait,["LASI","LPSI","RASI","RPSI"]) modelFilters.ModelAbsoluteAnglesFilter(model,acqGait, segmentLabels=["Left Foot","Right Foot","Pelvis"], angleLabels=["LFootProgress", "RFootProgress","Pelvis"], eulerSequences=["TOR","TOR", "ROT"], globalFrameOrientation = globalFrame, forwardProgression = forwardProgression).compute(pointLabelSuffix="cgm1_6dof") #btkTools.smartWriter(acqGait, "verifX.c3d") # --- tests on angles np.testing.assert_almost_equal( acqGait.GetPoint("RNewPelAngles").GetValues(), acqGait.GetPoint("RPelvisAngles_cgm1_6dof").GetValues(), decimal =3) np.testing.assert_almost_equal( acqGait.GetPoint("LNewPelAngles").GetValues(), acqGait.GetPoint("LPelvisAngles_cgm1_6dof").GetValues(), decimal =3) # ------ Test 2 Motion Axe -X ------- gaitFilename="MRI-US-01, 2008-08-08, 3DGA 12.c3d" acqGait = btkTools.smartReader(str(MAIN_PATH + gaitFilename)) # Motion FILTER # optimisation segmentaire et calibration fonctionnel modMotion=modelFilters.ModelMotionFilter(scp,acqGait,model,pyCGM2Enums.motionMethod.Determinist) modMotion.compute() longitudinalAxis,forwardProgression,globalFrame = btkTools.findProgressionAxisFromPelvicMarkers(acqGait,["LASI","LPSI","RASI","RPSI"]) modelFilters.ModelAbsoluteAnglesFilter(model,acqGait, segmentLabels=["Left Foot","Right Foot","Pelvis"], angleLabels=["LFootProgress", "RFootProgress","Pelvis"], eulerSequences=["TOR","TOR", "ROT"], globalFrameOrientation = globalFrame, forwardProgression = forwardProgression).compute(pointLabelSuffix="cgm1_6dof") # --- tests on angles np.testing.assert_almost_equal( acqGait.GetPoint("RNewPelAngles").GetValues(), acqGait.GetPoint("RPelvisAngles_cgm1_6dof").GetValues(), decimal =3) np.testing.assert_almost_equal( acqGait.GetPoint("LNewPelAngles").GetValues(), acqGait.GetPoint("LPelvisAngles_cgm1_6dof").GetValues(), decimal =3)
def fitting(model, DATA_PATH, reconstructFilenameLabelled, translators, settings, ik_flag, markerDiameter, pointSuffix, mfpa, momentProjection, **kwargs): """ Fitting of the CGM2.5 :param model [str]: pyCGM2 model previously calibrated :param DATA_PATH [str]: path to your data :param reconstructFilenameLabelled [string list]: c3d files :param translators [dict]: translators to apply :param ik_flag [bool]: enable the inverse kinematic solver :param mfpa [str]: manual force plate assignement :param markerDiameter [double]: marker diameter (mm) :param pointSuffix [str]: suffix to add to model outputs :param momentProjection [str]: Coordinate system in which joint moment is expressed """ # --- btk acquisition ---- if "forceBtkAcq" in kwargs.keys(): acqGait = kwargs["forceBtkAcq"] else: acqGait = btkTools.smartReader( str(DATA_PATH + reconstructFilenameLabelled)) btkTools.checkMultipleSubject(acqGait) acqGait = btkTools.applyTranslators(acqGait, translators) trackingMarkers = model.getTrackingMarkers() validFrames, vff, vlf = btkTools.findValidFrames(acqGait, trackingMarkers) # --- initial motion Filter --- scp = modelFilters.StaticCalibrationProcedure(model) modMotion = modelFilters.ModelMotionFilter(scp, acqGait, model, enums.motionMethod.Sodervisk) modMotion.compute() if ik_flag: # ---OPENSIM IK--- # --- opensim calibration Filter --- osimfile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\osim\\lowerLimb_ballsJoints.osim" # osimfile markersetFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_4\\cgm2_4-markerset.xml" # markerset cgmCalibrationprocedure = opensimFilters.CgmOpensimCalibrationProcedures( model) # procedure oscf = opensimFilters.opensimCalibrationFilter( osimfile, model, cgmCalibrationprocedure, str(DATA_PATH)) oscf.addMarkerSet(markersetFile) scalingOsim = oscf.build() # --- opensim Fitting Filter --- iksetupFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_4\\cgm2_4-ikSetUp_template.xml" # ik tl file cgmFittingProcedure = opensimFilters.CgmOpensimFittingProcedure( model) # procedure cgmFittingProcedure.updateMarkerWeight( "LASI", settings["Fitting"]["Weight"]["LASI"]) cgmFittingProcedure.updateMarkerWeight( "RASI", settings["Fitting"]["Weight"]["RASI"]) cgmFittingProcedure.updateMarkerWeight( "LPSI", settings["Fitting"]["Weight"]["LPSI"]) cgmFittingProcedure.updateMarkerWeight( "RPSI", settings["Fitting"]["Weight"]["RPSI"]) cgmFittingProcedure.updateMarkerWeight( "RTHI", settings["Fitting"]["Weight"]["RTHI"]) cgmFittingProcedure.updateMarkerWeight( "RKNE", settings["Fitting"]["Weight"]["RKNE"]) cgmFittingProcedure.updateMarkerWeight( "RTIB", settings["Fitting"]["Weight"]["RTIB"]) cgmFittingProcedure.updateMarkerWeight( "RANK", settings["Fitting"]["Weight"]["RANK"]) cgmFittingProcedure.updateMarkerWeight( "RHEE", settings["Fitting"]["Weight"]["RHEE"]) cgmFittingProcedure.updateMarkerWeight( "RTOE", settings["Fitting"]["Weight"]["RTOE"]) cgmFittingProcedure.updateMarkerWeight( "LTHI", settings["Fitting"]["Weight"]["LTHI"]) cgmFittingProcedure.updateMarkerWeight( "LKNE", settings["Fitting"]["Weight"]["LKNE"]) cgmFittingProcedure.updateMarkerWeight( "LTIB", settings["Fitting"]["Weight"]["LTIB"]) cgmFittingProcedure.updateMarkerWeight( "LANK", settings["Fitting"]["Weight"]["LANK"]) cgmFittingProcedure.updateMarkerWeight( "LHEE", settings["Fitting"]["Weight"]["LHEE"]) cgmFittingProcedure.updateMarkerWeight( "LTOE", settings["Fitting"]["Weight"]["LTOE"]) cgmFittingProcedure.updateMarkerWeight( "LTHAP", settings["Fitting"]["Weight"]["LTHAP"]) cgmFittingProcedure.updateMarkerWeight( "LTHAD", settings["Fitting"]["Weight"]["LTHAD"]) cgmFittingProcedure.updateMarkerWeight( "LTIAP", settings["Fitting"]["Weight"]["LTIAP"]) cgmFittingProcedure.updateMarkerWeight( "LTIAD", settings["Fitting"]["Weight"]["LTIAD"]) cgmFittingProcedure.updateMarkerWeight( "RTHAP", settings["Fitting"]["Weight"]["RTHAP"]) cgmFittingProcedure.updateMarkerWeight( "RTHAD", settings["Fitting"]["Weight"]["RTHAD"]) cgmFittingProcedure.updateMarkerWeight( "RTIAP", settings["Fitting"]["Weight"]["RTIAP"]) cgmFittingProcedure.updateMarkerWeight( "RTIAD", settings["Fitting"]["Weight"]["RTIAD"]) cgmFittingProcedure.updateMarkerWeight( "LSMH", settings["Fitting"]["Weight"]["LSMH"]) cgmFittingProcedure.updateMarkerWeight( "LFMH", settings["Fitting"]["Weight"]["LFMH"]) cgmFittingProcedure.updateMarkerWeight( "LVMH", settings["Fitting"]["Weight"]["LVMH"]) cgmFittingProcedure.updateMarkerWeight( "RSMH", settings["Fitting"]["Weight"]["RSMH"]) cgmFittingProcedure.updateMarkerWeight( "RFMH", settings["Fitting"]["Weight"]["RFMH"]) cgmFittingProcedure.updateMarkerWeight( "RVMH", settings["Fitting"]["Weight"]["RVMH"]) # cgmFittingProcedure.updateMarkerWeight("LTHL",settings["Fitting"]["Weight"]["LTHL"]) # cgmFittingProcedure.updateMarkerWeight("LTHLD",settings["Fitting"]["Weight"]["LTHLD"]) # cgmFittingProcedure.updateMarkerWeight("LPAT",settings["Fitting"]["Weight"]["LPAT"]) # cgmFittingProcedure.updateMarkerWeight("LTIBL",settings["Fitting"]["Weight"]["LTIBL"]) # cgmFittingProcedure.updateMarkerWeight("RTHL",settings["Fitting"]["Weight"]["RTHL"]) # cgmFittingProcedure.updateMarkerWeight("RTHLD",settings["Fitting"]["Weight"]["RTHLD"]) # cgmFittingProcedure.updateMarkerWeight("RPAT",settings["Fitting"]["Weight"]["RPAT"]) # cgmFittingProcedure.updateMarkerWeight("RTIBL",settings["Fitting"]["Weight"]["RTIBL"]) osrf = opensimFilters.opensimFittingFilter(iksetupFile, scalingOsim, cgmFittingProcedure, str(DATA_PATH)) logging.info("-------INVERSE KINEMATICS IN PROGRESS----------") acqIK = osrf.run(acqGait, str(DATA_PATH + reconstructFilenameLabelled)) logging.info("-------INVERSE KINEMATICS DONE-----------------") # eventual gait acquisition to consider for joint kinematics finalAcqGait = acqIK if ik_flag else acqGait if "displayCoordinateSystem" in kwargs.keys( ) and kwargs["displayCoordinateSystem"]: csp = modelFilters.ModelCoordinateSystemProcedure(model) csdf = modelFilters.CoordinateSystemDisplayFilter( csp, model, finalAcqGait) csdf.setStatic(False) csdf.display() # --- final pyCGM2 model motion Filter --- # use fitted markers modMotionFitted = modelFilters.ModelMotionFilter( scp, finalAcqGait, model, enums.motionMethod.Sodervisk, markerDiameter=markerDiameter) modMotionFitted.compute() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model, finalAcqGait).compute( description="vectoriel", pointLabelSuffix=pointSuffix) # detection of traveling axis + absolute angle if model.m_bodypart != enums.BodyPart.UpperLimb: longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromPelvicMarkers( finalAcqGait, ["LASI", "LPSI", "RASI", "RPSI"]) else: longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromLongAxis( finalAcqGait, "C7", "CLAV") if model.m_bodypart != enums.BodyPart.UpperLimb: modelFilters.ModelAbsoluteAnglesFilter( model, finalAcqGait, segmentLabels=["Left Foot", "Right Foot", "Pelvis"], angleLabels=["LFootProgress", "RFootProgress", "Pelvis"], eulerSequences=["TOR", "TOR", "ROT"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.LowerLimbTrunk: modelFilters.ModelAbsoluteAnglesFilter( model, finalAcqGait, segmentLabels=["Thorax"], angleLabels=["Thorax"], eulerSequences=["YXZ"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.UpperLimb or model.m_bodypart == enums.BodyPart.FullBody: modelFilters.ModelAbsoluteAnglesFilter( model, finalAcqGait, segmentLabels=["Thorax", "Head"], angleLabels=["Thorax", "Head"], eulerSequences=["YXZ", "TOR"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) #---- Body segment parameters---- bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() if model.m_bodypart == enums.BodyPart.FullBody: modelFilters.CentreOfMassFilter( model, finalAcqGait).compute(pointLabelSuffix=pointSuffix) # Inverse dynamics if model.m_bodypart != enums.BodyPart.UpperLimb: # --- force plate handling---- # find foot in contact mappedForcePlate = forceplates.matchingFootSideOnForceplate( finalAcqGait, mfpa=mfpa) forceplates.addForcePlateGeneralEvents(finalAcqGait, mappedForcePlate) logging.warning("Manual Force plate assignment : %s" % mappedForcePlate) # assembly foot and force plate modelFilters.ForcePlateAssemblyFilter( model, finalAcqGait, mappedForcePlate, leftSegmentLabel="Left Foot", rightSegmentLabel="Right Foot").compute() #---- Joint kinetics---- idp = modelFilters.CGMLowerlimbInverseDynamicProcedure() modelFilters.InverseDynamicFilter( model, finalAcqGait, procedure=idp, projection=momentProjection, ).compute(pointLabelSuffix=pointSuffix) #---- Joint energetics---- modelFilters.JointPowerFilter( model, finalAcqGait).compute(pointLabelSuffix=pointSuffix) #---- zero unvalid frames --- btkTools.applyValidFramesOnOutput(finalAcqGait, validFrames) return finalAcqGait
def run(self, acqMotion, acqMotionFilename, exportSetUp=True): """ Run kinematic fitting :Parameters: - `acqMotion` (btk.Acquisition) - acquisition of a motion trial - `acqMotionFilename` (filename) - filename of the motion trial """ acqMotion_forIK = btk.btkAcquisition.Clone(acqMotion) progressionAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromPelvicMarkers( acqMotion, ["LASI", "RASI", "RPSI", "LPSI"]) # --- ikTasks # UPDATE method - ik tags ( need task in the initial iktools) for markerIt in self.m_procedure.ikTags.keys(): self._osimIK.updateIKTask(markerIt, self.m_procedure.ikTags[markerIt]) # --- configuration and run IK if os.path.isfile(self.opensimOutputDir + "ik_model_marker_locations.sto"): os.remove(self.opensimOutputDir + "ik_model_marker_locations.sto") R_LAB_OSIM = osimProcessing.setGlobalTransormation_lab_osim( progressionAxis, forwardProgression) self._osimIK.config(R_LAB_OSIM, acqMotion_forIK, acqMotionFilename) if exportSetUp: if os.path.isfile(self.opensimOutputDir + "scaledModel-ikSetUp.xml"): os.remove(self.opensimOutputDir + "scaledModel-ikSetUp.xml") self.exportXml("scaledModel-ikSetUp.xml", path=self.opensimOutputDir) self._osimIK.run() # --- gernerate acq with rigid markers acqMotionFinal = btk.btkAcquisition.Clone(acqMotion) for marker in self.m_procedure.ikTags.keys(): if self.m_procedure.ikTags[marker] != 0: values = osimProcessing.sto2pointValues( self.opensimOutputDir + "ik_model_marker_locations.sto", marker, R_LAB_OSIM) lenOsim = len(values) lenc3d = acqMotion.GetPoint(marker).GetFrameNumber() if lenOsim < lenc3d: logging.warning(" size osim (%i) inferior to c3d (%i)" % (lenOsim, lenc3d)) values2 = np.zeros((lenc3d, 3)) values2[0:lenOsim, :] = values values2[lenOsim:lenc3d, :] = acqMotion.GetPoint( marker).GetValues()[lenOsim:lenc3d, :] btkTools.smartAppendPoint( acqMotionFinal, marker + "_m", acqMotionFinal.GetPoint(marker).GetValues(), desc="measured") # new acq with marker overwrited btkTools.smartAppendPoint( acqMotionFinal, marker, values2, desc="kinematic fitting" ) # new acq with marker overwrited else: btkTools.smartAppendPoint( acqMotionFinal, marker + "_m", acqMotionFinal.GetPoint(marker).GetValues(), desc="measured") # measured marker suffix with _m btkTools.smartAppendPoint( acqMotionFinal, marker, values, desc="kinematic fitting" ) # new acq with marker overwrited return acqMotionFinal
bioMechModel.setClinicalDescriptor("LAnkle", enums.DataType.Angle, [0, 2, 1], [-1.0, -1.0, -1.0], [np.radians(90), 0.0, 0.0]) bioMechModel.setClinicalDescriptor("RHip", enums.DataType.Angle, [0, 1, 2], [-1.0, +1.0, +1.0], [0.0, 0.0, 0.0]) bioMechModel.setClinicalDescriptor("RKnee", enums.DataType.Angle, [0, 1, 2], [+1.0, +1.0, +1.0], [0.0, 0.0, 0.0]) bioMechModel.setClinicalDescriptor("RAnkle", enums.DataType.Angle, [0, 2, 1], [-1.0, +1.0, +1.0], [np.radians(90), 0.0, 0.0]) jcsf = modelFilters.ModelJCSFilter(bioMechModel, acqDynamic) jcsf.compute(description="vectoriel", pointLabelSuffix="rcm") longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromPelvicMarkers( acqDynamic, ["LASI", "LPSI", "RASI", "RPSI"]) bioMechModel.setClinicalDescriptor("Pelvis", enums.DataType.Angle, [0, 1, 2], [1.0, 1.0, -1.0], [0.0, 0.0, 0.0]) bioMechModel.setClinicalDescriptor("Left Foot", enums.DataType.Angle, [0, 2, 1], [1.0, 1.0, -1.0], [0.0, 0.0, 0.0]) bioMechModel.setClinicalDescriptor("Right Foot", enums.DataType.Angle, [0, 2, 1], [1.0, -1.0, 1.0], [0.0, 0.0, 0.0]) aaf = modelFilters.ModelAbsoluteAnglesFilter( bioMechModel, acqDynamic, segmentLabels=["Left Foot", "Right Foot", "Pelvis"],