def noIK_6dof(cls): MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM2\\cgm2.4\\fullBody\\" staticFilename = "PN01OP01S01STAT.c3d" gaitFilename = "PN01OP01S01STAT.c3d" markerDiameter = 14 mp = { 'Bodymass': 83.0, 'LeftLegLength': 874.0, 'RightLegLength': 876.0, 'LeftKneeWidth': 106.0, 'RightKneeWidth': 103.0, 'LeftAnkleWidth': 74.0, 'RightAnkleWidth': 72.0, 'LeftSoleDelta': 0, 'RightSoleDelta': 0, } # --- Calibration --- acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) translators = files.getTranslators(MAIN_PATH, "CGM2_4.translators") acqStatic = btkTools.applyTranslators(acqStatic, translators) model = cgm2.CGM2_4() model.configure() model.addAnthropoInputParameters(mp) # ---- Calibration ---- scp = modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp, acqStatic, model).compute() print "----" print model.getSegment("Left Shank").getReferential( "TF").relativeMatrixAnatomic print "----" # # 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)) acqGait = btkTools.applyTranslators(acqGait, translators) # Motion FILTER modMotion = modelFilters.ModelMotionFilter( scp, acqGait, model, enums.motionMethod.Sodervisk) modMotion.compute() btkTools.smartWriter(acqGait, "cgm24_noIK6dof_staticMotion.c3d")
def cgm24(cls): """ """ MAIN_PATH = pyCGM2.TEST_DATA_PATH + "operations\\markerDecomposition\\CGM24decomposeTracking\\" # staticFilename = "PN01OP01S01STAT.c3d" acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model=cgm2.CGM2_4LowerLimbs() model.setVersion("CGM2.4e") model.configure() markerDiameter=14 mp={ 'Bodymass' : 83.0, 'LeftLegLength' : 874.0, 'RightLegLength' : 876.0 , 'LeftKneeWidth' : 106.0, 'RightKneeWidth' : 103.0, 'LeftAnkleWidth' : 74.0, 'RightAnkleWidth' : 72.0, 'LeftSoleDelta' : 0, 'RightSoleDelta' : 0, } model.addAnthropoInputParameters(mp) # CALIBRATION scp=modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp,acqStatic,model, leftFlatFoot = 1, rightFlatFoot = 1, markerDiameter=markerDiameter, ).compute() modelDecorator.KneeCalibrationDecorator(model).midCondyles(acqStatic, markerDiameter=markerDiameter, side="left") modelDecorator.AnkleCalibrationDecorator(model).midMaleolus(acqStatic, markerDiameter=markerDiameter, side="left") modelDecorator.KneeCalibrationDecorator(model).midCondyles(acqStatic, markerDiameter=markerDiameter, side="right") modelDecorator.AnkleCalibrationDecorator(model).midMaleolus(acqStatic, markerDiameter=markerDiameter, side="right") modelDecorator.HipJointCenterDecorator(model).hara(side = "Both") scp=modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp,acqStatic,model, leftFlatFoot = 1, rightFlatFoot = 1, markerDiameter=markerDiameter, ).compute() # --- Test 1 Motion Axe X ------- gaitFilename="PN01OP01S01SS01.c3d" acqGait = btkTools.smartReader(str(MAIN_PATH + gaitFilename)) modMotion=modelFilters.ModelMotionFilter(scp,acqGait,model,pyCGM2Enums.motionMethod.Sodervisk ) modMotion.compute() mtf = modelFilters.TrackingMarkerDecompositionFilter(model,acqGait) mtf.decompose() btkTools.smartWriter(acqGait, "cgm24-decompose.c3d")
def basicCGM1_manualOffset_thighRotationOFF_shankRotationON_tibialTorsionON(cls): """ CGM1 manual offset behaviour : => - Manual Thigh Rotation must modify ShankRotation. - If zero TibialTorsion inputs -> flag RightTibialTorsion must be off and TibialTorsion keep zero value """ MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\\basic-manualOffsets-thiOFF_shaON_torsionON\\" staticFilename = "MRI-US-01, 2008-08-08, 3DGA 02.c3d" acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model=cgm.CGM1 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, } optional_mp={ 'InterAsisDistance' : 0, 'LeftAsisTrocanterDistance' : 0, 'LeftThighRotation' : 0, 'LeftShankRotation' : -10, 'LeftTibialTorsion' : -30, 'RightAsisTrocanterDistance' : 0, 'RightThighRotation' : 0, 'RightShankRotation' : -10, 'RightTibialTorsion' : -30 } model.addAnthropoInputParameters(mp,optional=optional_mp) # -----------CGM STATIC CALIBRATION-------------------- scp=modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp,acqStatic,model).compute() # decorators modelDecorator.Cgm1ManualOffsets(model).compute(acqStatic,"left",model.mp["LeftThighRotation"],markerDiameter,model.mp["LeftTibialTorsion"],model.mp["LeftShankRotation"]) modelDecorator.Cgm1ManualOffsets(model).compute(acqStatic,"right",model.mp["RightThighRotation"],markerDiameter,model.mp["RightTibialTorsion"],model.mp["RightShankRotation"]) # finql calibration modelFilters.ModelCalibrationFilter(scp,acqStatic,model ).compute() # TESTS np.testing.assert_equal(model.m_useRightTibialTorsion,True ) np.testing.assert_equal(model.m_useLeftTibialTorsion,True ) np.testing.assert_almost_equal(model.mp_computed["LeftShankRotationOffset"] ,0, decimal = 3) np.testing.assert_almost_equal(model.mp_computed["RightShankRotationOffset"] ,0, decimal = 3)
def noIK_6dof_Garches(cls): MAIN_PATH = pyCGM2.TEST_DATA_PATH + "Datasets Tests\\didier\\08_02_18_Vincent Pere\\" staticFilename = "08_02_18_Vincent_Pere_Statique_000_MOKKA.c3d" gaitFilename = "08_02_18_Vincent_Pere_Statique_000_MOKKA.c3d" markerDiameter = 14 mp = { 'Bodymass': 70.0, 'LeftLegLength': 890.0, 'RightLegLength': 890.0, 'LeftKneeWidth': 150.0, 'RightKneeWidth': 150.0, 'LeftAnkleWidth': 88.0, 'RightAnkleWidth': 99.0, 'LeftSoleDelta': 0, 'RightSoleDelta': 0, } # --- Calibration --- acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model = cgm2.CGM2_4() model.configure() model.addAnthropoInputParameters(mp) # ---- Calibration ---- scp = modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp, acqStatic, model).compute() print "----" print model.getSegment("Left Shank").getReferential( "TF").relativeMatrixAnatomic print "----" # # 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, enums.motionMethod.Sodervisk) modMotion.compute() btkTools.smartWriter(acqGait, "cgm24_noIK6dof_staticMotion_Garches.c3d")
def calibration_GarchesFlatFoot(cls): MAIN_PATH = pyCGM2.TEST_DATA_PATH + "Datasets Tests\\didier\\08_02_18_Vincent Pere\\" staticFilename = "08_02_18_Vincent_Pere_Statique_000_MOKKA.c3d" markerDiameter = 14 mp = { 'Bodymass': 70.0, 'LeftLegLength': 890.0, 'RightLegLength': 890.0, 'LeftKneeWidth': 150.0, 'RightKneeWidth': 150.0, 'LeftAnkleWidth': 88.0, 'RightAnkleWidth': 99.0, 'LeftSoleDelta': 0, 'RightSoleDelta': 0, "LeftToeOffset": 0, "RightToeOffset": 0, } # --- Calibration --- acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model = cgm2.CGM2_4() 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, leftFlatFoot=True, rightFlatFoot=True).compute() # display CS csp = modelFilters.ModelCoordinateSystemProcedure(model) csf = modelFilters.CoordinateSystemDisplayFilter(csp, model, acqStatic) csf.setStatic(True) csf.display() btkTools.smartWriter(acqStatic, "cgm2.4_GarchesFlatFoot.c3d")
def customLocalPosition(cls): """ GOAL : compare Joint centres and foot Offset """ MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM2\\cgm2.1\\native\\" staticFilename = "static.c3d" acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model=cgm2.CGM2_1LowerLimbs() 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) # -----------CGM STATIC CALIBRATION-------------------- # initial scp=modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp,acqStatic,model).compute() pos0_L = model.getSegment("Pelvis").getReferential("TF").static.getNode_byLabel("LHJC").getLocal() pos0_R = model.getSegment("Pelvis").getReferential("TF").static.getNode_byLabel("RHJC").getLocal() # cgm decorator modelDecorator.HipJointCenterDecorator(model).custom(position_Left = np.array([1,2,3]), position_Right = np.array([1,2,3]), methodDesc = "us") # add node to pelvis # final modelFilters.ModelCalibrationFilter(scp,acqStatic,model).compute() pos_L = model.getSegment("Pelvis").getReferential("TF").static.getNode_byLabel("LHJC").getLocal() pos_R = model.getSegment("Pelvis").getReferential("TF").static.getNode_byLabel("RHJC").getLocal() # ---- tests ---- np.testing.assert_equal(model.getSegment("Pelvis").getReferential("TF").static.getNode_byLabel("LHJC").getDescription() ,"us") np.testing.assert_equal(model.getSegment("Left Thigh").getReferential("TF").static.getNode_byLabel("LHJC").getDescription() ,"us") np.testing.assert_equal(model.getSegment("Pelvis").getReferential("TF").static.getNode_byLabel("RHJC").getDescription() ,"us") np.testing.assert_equal(model.getSegment("Right Thigh").getReferential("TF").static.getNode_byLabel("RHJC").getDescription() ,"us") np.testing.assert_equal(np.all(pos_L == pos0_L) == False, True) np.testing.assert_equal(np.all(pos_R == pos0_R) ==False, True)
def calibration_FlatFoot(cls): MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM2\\cgm2.4\\medial\\" staticFilename = "static.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_4() 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, leftFlatFoot=True, rightFlatFoot=True).compute() # display CS csp = modelFilters.ModelCoordinateSystemProcedure(model) csf = modelFilters.CoordinateSystemDisplayFilter(csp, model, acqStatic) csf.setStatic(True) csf.display() btkTools.smartWriter(acqStatic, "cgm2.4_FlatFoot.c3d")
def advancedCGM11_KneeMedKad_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.CGM1 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() btkTools.smartWriter(acqStatic, "Kad-med-TrueEquinus.c3d")
def advancedCGM11_KneeMedKad(cls): """ """ MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\CGM1.1\medial\\" staticFilename = "static-all.c3d" acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model = cgm.CGM1 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, } optional_mp = { 'InterAsisDistance': 0, 'LeftAsisTrocanterDistance': 0, 'LeftThighRotation': 0, 'LeftShankRotation': 0, 'LeftTibialTorsion': -10, 'RightAsisTrocanterDistance': 0, 'RightThighRotation': 0, 'RightShankRotation': 0, 'RightTibialTorsion': 15 } model.addAnthropoInputParameters(mp, optional=optional_mp) # -----------CGM STATIC CALIBRATION-------------------- scp = modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp, acqStatic, model).compute() # cgm decorator modelDecorator.KneeCalibrationDecorator(model).midCondyles_KAD( acqStatic) #modelDecorator.AnkleCalibrationDecorator(model).midMaleolus(acqStatic, side="both") modelFilters.ModelCalibrationFilter(scp, acqStatic, model).compute() btkTools.smartWriter(acqStatic, "advancedCGM11_KneeMedKad.c3d")
def basicCGM1_manualTibialTorsion(cls): MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\\basic-tibialTorsion\\" staticFilename = "MRI-US-01, 2008-08-08, 3DGA 02.c3d" acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model=cgm.CGM1 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, } optional_mp={ 'LeftTibialTorsion' : -30.0, 'RightTibialTorsion' : -30.0 } model.addAnthropoInputParameters(mp,optional=optional_mp) # -----------CGM STATIC CALIBRATION-------------------- scp=modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp,acqStatic,model, viconCGM1compatible=True).compute() # TESTS ------------------------------------------------ # offset testing offsetTesting(acqStatic,model,display = True, unitTesting=True) # nodes # np.testing.assert_equal(model.getSegment("Left Thigh").getReferential("TF").static.getNode_byLabel("LKJC").m_desc ,"Chord") # np.testing.assert_equal(model.getSegment("Right Thigh").getReferential("TF").static.getNode_byLabel("RKJC").m_desc ,"Chord") # # np.testing.assert_equal(model.getSegment("Left Shank").getReferential("TF").static.getNode_byLabel("LKJC").m_desc ,"Chord") # np.testing.assert_equal(model.getSegment("Right Shank").getReferential("TF").static.getNode_byLabel("RKJC").m_desc ,"Chord") np.testing.assert_equal(model.m_useRightTibialTorsion,True ) np.testing.assert_equal(model.m_useLeftTibialTorsion,True ) # joint centres np.testing.assert_almost_equal(acqStatic.GetPoint("LFEP").GetValues().mean(axis=0),acqStatic.GetPoint("LHJC").GetValues().mean(axis=0),decimal = 3) np.testing.assert_almost_equal(acqStatic.GetPoint("RFEP").GetValues().mean(axis=0),acqStatic.GetPoint("RHJC").GetValues().mean(axis=0),decimal = 3) np.testing.assert_almost_equal(acqStatic.GetPoint("LFEO").GetValues().mean(axis=0),acqStatic.GetPoint("LKJC").GetValues().mean(axis=0),decimal = 3) np.testing.assert_almost_equal(acqStatic.GetPoint("RFEO").GetValues().mean(axis=0),acqStatic.GetPoint("RKJC").GetValues().mean(axis=0),decimal = 3) np.testing.assert_almost_equal(acqStatic.GetPoint("LTIO").GetValues().mean(axis=0),acqStatic.GetPoint("LAJC").GetValues().mean(axis=0),decimal = 3) np.testing.assert_almost_equal(acqStatic.GetPoint("RTIO").GetValues().mean(axis=0),acqStatic.GetPoint("RAJC").GetValues().mean(axis=0),decimal = 3) btkTools.smartWriter(acqStatic, "outStatic_advancedCGM1_kad_manualTibial.c3d")
def basicCGM1_manualTibialTorsion(cls): MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\\KAD-basic\\" 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, } optional_mp={ 'InterAsisDistance' : 0, 'LeftAsisTrocanterDistance' : 0, 'LeftThighRotation' : 0, 'LeftShankRotation' : 0 , 'LeftTibialTorsion' : -10, 'RightAsisTrocanterDistance' : 0, 'RightThighRotation' : 0, 'RightShankRotation' : 0, 'RightTibialTorsion' : 15 } model.addAnthropoInputParameters(mp,optional=optional_mp) # -----------CGM STATIC CALIBRATION-------------------- scp=modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp,acqStatic,model).compute() #TESTS np.testing.assert_equal(model.m_useRightTibialTorsion,True ) np.testing.assert_equal(model.m_useLeftTibialTorsion,True ) # np.testing.assert_almost_equal(model.mp["InterAsisDistance"],model.mp_computed["InterAsisDistance"] , decimal = 3) # np.testing.assert_almost_equal(model.mp["LeftAsisTrocanterDistance"],model.mp_computed["LeftAsisTrocanterDistance"] , decimal = 3) # np.testing.assert_almost_equal(model.mp["LeftThighRotation"],-1.0*model.mp_computed["LeftThighRotationOffset"] , decimal = 3) # np.testing.assert_almost_equal(model.mp["LeftShankRotation"],-1.0*model.mp_computed["LeftShankRotationOffset"] , decimal = 3) np.testing.assert_almost_equal(model.mp["LeftTibialTorsion"],-1.0*model.mp_computed["LeftTibialTorsionOffset"] , decimal = 3) # np.testing.assert_almost_equal(model.mp["RightAsisTrocanterDistance"],model.mp_computed["RightAsisTrocanterDistance"] , decimal = 3) # np.testing.assert_almost_equal(model.mp["RightThighRotation"],model.mp_computed["RightThighRotationOffset"] , decimal = 3) # np.testing.assert_almost_equal(model.mp["RightShankRotation"],model.mp_computed["RightShankRotationOffset"] , decimal = 3) np.testing.assert_almost_equal(model.mp["RightTibialTorsion"],model.mp_computed["RightTibialTorsionOffset"] , decimal = 3)
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 CGM1_UpperLimb(cls): MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\\full-PiG\\" staticFilename = "PN01NORMSTAT.c3d" acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model=cgm.CGM1() model.configure(bodyPart=enums.BodyPart.UpperLimb) markerDiameter=14 mp={ 'LeftShoulderOffset' : 50, 'LeftElbowWidth' : 91, 'LeftWristWidth' : 56 , 'LeftHandThickness' : 28 , 'RightShoulderOffset' : 45, 'RightElbowWidth' : 90, 'RightWristWidth' : 55 , 'RightHandThickness' : 30 } model.addAnthropoInputParameters(mp) # -----------CGM STATIC CALIBRATION-------------------- scp=modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp,acqStatic,model,headFlat= True).compute() csp = modelFilters.ModelCoordinateSystemProcedure(model) # --- motion ---- gaitFilename="PN01NORMSS01.c3d" acqGait = btkTools.smartReader(str(MAIN_PATH + gaitFilename)) modMotion=modelFilters.ModelMotionFilter(scp,acqGait,model,enums.motionMethod.Determinist) modMotion.compute() csdf = modelFilters.CoordinateSystemDisplayFilter(csp,model,acqGait) csdf.setStatic(False) csdf.display() # thorax R_thorax= model.getSegment("Thorax").anatomicalFrame.motion[10].getRotation() R_thorax_vicon = getViconRmatrix(10, acqGait, "TRXO", "TRXA", "TRXL", "XZY") np.testing.assert_almost_equal( R_thorax, R_thorax_vicon, decimal =3) # head R_head= model.getSegment("Head").anatomicalFrame.motion[10].getRotation() R_head_vicon = getViconRmatrix(10, acqGait, "HEDO", "HEDA", "HEDL", "XZY") np.testing.assert_almost_equal( R_head, R_head_vicon, decimal =2)
def cgm1(cls): """ GOAL : compare Joint centres and foot Offset """ MAIN_PATH = pyCGM2.TEST_DATA_PATH + "operations\\markerDecomposition\\CGM1decomposeTracking\\" # staticFilename = "static.c3d" acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model = cgm.CGM1LowerLimbs() model.configure() markerDiameter = 14 mp = { 'Bodymass': 36.9, 'LeftLegLength': 665, 'RightLegLength': 655.0, 'LeftKneeWidth': 102.7, 'RightKneeWidth': 100.2, 'LeftAnkleWidth': 64.5, 'RightAnkleWidth': 63.4, 'LeftSoleDelta': 0, 'RightSoleDelta': 0, } model.addAnthropoInputParameters(mp) # CALIBRATION scp = modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp, acqStatic, model).compute() print model.m_useRightTibialTorsion # --- Test 1 Motion Axe X ------- gaitFilename = "gait trial 01.c3d" acqGait = btkTools.smartReader(str(MAIN_PATH + gaitFilename)) modMotion = modelFilters.ModelMotionFilter( scp, acqGait, model, pyCGM2Enums.motionMethod.Determinist, useForMotionTest=True) modMotion.compute() mtf = modelFilters.TrackingMarkerDecompositionFilter(model, acqGait) mtf.decompose() btkTools.smartWriter(acqGait, "cgm1-decompose.c3d")
def basicCGM1(cls): 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.CGM1 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) # -----------CGM STATIC CALIBRATION-------------------- scp=modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp,acqStatic,model).compute() #btkTools.smartWriter(acqStatic, "CGM1_calibrationTest-basicCGM1.c3d") # TESTS ------------------------------------------------ # offset testing offsetTesting(acqStatic,model,display = True, unitTesting=True) np.testing.assert_equal(model.m_useRightTibialTorsion,False ) np.testing.assert_equal(model.m_useLeftTibialTorsion,False ) # joint centres np.testing.assert_almost_equal(acqStatic.GetPoint("LFEP").GetValues().mean(axis=0),acqStatic.GetPoint("LHJC").GetValues().mean(axis=0),decimal = 3) np.testing.assert_almost_equal(acqStatic.GetPoint("RFEP").GetValues().mean(axis=0),acqStatic.GetPoint("RHJC").GetValues().mean(axis=0),decimal = 3) np.testing.assert_almost_equal(acqStatic.GetPoint("LFEO").GetValues().mean(axis=0),acqStatic.GetPoint("LKJC").GetValues().mean(axis=0),decimal = 3) np.testing.assert_almost_equal(acqStatic.GetPoint("RFEO").GetValues().mean(axis=0),acqStatic.GetPoint("RKJC").GetValues().mean(axis=0),decimal = 3) np.testing.assert_almost_equal(acqStatic.GetPoint("LTIO").GetValues().mean(axis=0),acqStatic.GetPoint("LAJC").GetValues().mean(axis=0),decimal = 3) np.testing.assert_almost_equal(acqStatic.GetPoint("RTIO").GetValues().mean(axis=0),acqStatic.GetPoint("RAJC").GetValues().mean(axis=0),decimal = 3)
def GeneralScoreTest(cls): """ GOAL : compare Joint centres and foot Offset """ 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() 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, enums.motionMethod.Determinist) modMotion.compute() # score msrp = modelQualityFilter.GeneralScoreResidualProcedure(model) msrp.setDefinition("LHJC", "Pelvis", "Left Thigh") srf = modelQualityFilter.ScoreResidualFilter(acqGait, msrp) srf.compute()
def kadMedCGM1_proximal(cls, plotFlag=False): MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\PIG advanced\\KAD-tibialTorsion\\" staticFilename = "MRI-US-01, 2008-08-08, 3DGA 02.c3d" acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model = cgm.CGM1 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() # cgm decorator modelDecorator.Kad(model, acqStatic).compute() modelDecorator.AnkleCalibrationDecorator(model).midMaleolus( acqStatic, side="both") modelFilters.ModelCalibrationFilter(scp, acqStatic, model).compute() # ------ Test 1 Motion Axe X ------- gaitFilename = "MRI-US-01, 2008-08-08, 3DGA 14.Proximal.c3d" acqGait = btkTools.smartReader(str(MAIN_PATH + gaitFilename)) # Motion FILTER # optimisation segmentaire et calibration fonctionnel modMotion = modelFilters.ModelMotionFilter( scp, acqGait, model, pyCGM2Enums.motionMethod.Determinist, viconCGM1compatible=False) modMotion.compute() # Joint kinematics modelFilters.ModelJCSFilter(model, acqGait).compute( description="vectoriel", pointLabelSuffix="cgm1_6dof") # BSP model bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() # force plate -- construction du wrench attribue au pied forceplates.appendForcePlateCornerAsMarker(acqGait) mappedForcePlate = forceplates.matchingFootSideOnForceplate(acqGait) modelFilters.ForcePlateAssemblyFilter( model, acqGait, "RL", leftSegmentLabel="Left Foot", rightSegmentLabel="Right Foot").compute() idp = modelFilters.CGMLowerlimbInverseDynamicProcedure() modelFilters.InverseDynamicFilter( model, acqGait, procedure=idp, projection=pyCGM2Enums.MomentProjection.Proximal, viconCGM1compatible=True).compute(pointLabelSuffix="cgm1_6dof") modelFilters.JointPowerFilter( model, acqGait).compute(pointLabelSuffix="cgm1_6dof") # writer btkTools.smartWriter(acqGait, "testInvDyn_kadMed.c3d") if plotFlag: plotMoment(acqGait, "LAnkleMoment", "LAnkleMoment_cgm1_6dof", "kadMedCGM1_proximal-LAnkleMoment") plotMoment(acqGait, "RAnkleMoment", "RAnkleMoment_cgm1_6dof", "kadMedCGM1_proximal-RAnkleMoment") plt.show()
def basicCGM1_global(cls, plotFlag=False): MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\\basic-filtered\\" staticFilename = "MRI-US-01, 2008-08-08, 3DGA 02.c3d" acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model = cgm.CGM1 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, } 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.global.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() # Joint kinematics modelFilters.ModelJCSFilter(model, acqGait).compute( description="vectoriel", pointLabelSuffix="cgm1_6dof") # BSP model bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() # force plate -- construction du wrench attribue au pied forceplates.appendForcePlateCornerAsMarker(acqGait) mappedForcePlate = forceplates.matchingFootSideOnForceplate(acqGait) modelFilters.ForcePlateAssemblyFilter( model, acqGait, "RL", leftSegmentLabel="Left Foot", rightSegmentLabel="Right Foot").compute() idp = modelFilters.CGMLowerlimbInverseDynamicProcedure() modelFilters.InverseDynamicFilter( model, acqGait, procedure=idp, projection=pyCGM2Enums.MomentProjection.Global).compute( pointLabelSuffix="cgm1_6dof") modelFilters.JointPowerFilter( model, acqGait).compute(pointLabelSuffix="cgm1_6dof") #btkTools.smartWriter(acqGait,"testInvDyn.c3d") if plotFlag: plotMoment(acqGait, "LHipMoment", "LHipMoment_cgm1_6dof") plotMoment(acqGait, "LKneeMoment", "LKneeMoment_cgm1_6dof") plotMoment(acqGait, "LAnkleMoment", "LAnkleMoment_cgm1_6dof") plotMoment(acqGait, "RHipMoment", "RHipMoment_cgm1_6dof") plotMoment(acqGait, "RKneeMoment", "RKneeMoment_cgm1_6dof") plotMoment(acqGait, "RAnkleMoment", "RAnkleMoment_cgm1_6dof") plt.show() # TEST ------ compareKinetics(acqGait, 5, -5, 0.2, 40.0, 0.1)
def calibrate(DATA_PATH,calibrateFilenameLabelled,translators,weights, required_mp,optional_mp, ik_flag,leftFlatFoot,rightFlatFoot,headFlat, markerDiameter,hjcMethod, pointSuffix,**kwargs): """ Calibration of the CGM2.3 :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 """ # --------------------------STATIC FILE WITH TRANSLATORS -------------------------------------- if "Fitting" in weights.keys(): weights = weights["Fitting"]["Weight"] # --- btk acquisition ---- if "forceBtkAcq" in kwargs.keys(): acqStatic = kwargs["forceBtkAcq"] else: acqStatic = btkTools.smartReader((DATA_PATH+calibrateFilenameLabelled)) btkTools.checkMultipleSubject(acqStatic) if btkTools.isPointExist(acqStatic,"SACR"): translators["LPSI"] = "SACR" translators["RPSI"] = "SACR" logging.info("[pyCGM2] Sacrum marker detected") acqStatic = btkTools.applyTranslators(acqStatic,translators) # ---check marker set used---- dcm = cgm.CGM.detectCalibrationMethods(acqStatic) # --------------------------MODEL-------------------------------------- # ---definition--- model=cgm2.CGM2_3() 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 "noKinematicsCalculation" in kwargs.keys() and kwargs["noKinematicsCalculation"]: logging.warning("[pyCGM2] No Kinematic calculation done for the static file") return model, acqStatic else: if model.getBodyPart() == enums.BodyPart.UpperLimb: ik_flag = False logging.warning("[pyCGM2] Fitting only applied for the upper limb") 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_3\\cgm2_3-markerset.xml" # markerset cgmCalibrationprocedure = opensimFilters.CgmOpensimCalibrationProcedures(model) # procedure oscf = opensimFilters.opensimCalibrationFilter(osimfile, model, cgmCalibrationprocedure, (DATA_PATH)) oscf.addMarkerSet(markersetFile) scalingOsim = oscf.build() # --- opensim Fitting Filter --- iksetupFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_3\\cgm2_3-ikSetUp_template.xml" # ik tool file cgmFittingProcedure = opensimFilters.CgmOpensimFittingProcedure(model) # procedure cgmFittingProcedure.updateMarkerWeight("LASI",weights["LASI"]) cgmFittingProcedure.updateMarkerWeight("RASI",weights["RASI"]) cgmFittingProcedure.updateMarkerWeight("LPSI",weights["LPSI"]) cgmFittingProcedure.updateMarkerWeight("RPSI",weights["RPSI"]) cgmFittingProcedure.updateMarkerWeight("RTHI",weights["RTHI"]) cgmFittingProcedure.updateMarkerWeight("RKNE",weights["RKNE"]) cgmFittingProcedure.updateMarkerWeight("RTIB",weights["RTIB"]) cgmFittingProcedure.updateMarkerWeight("RANK",weights["RANK"]) cgmFittingProcedure.updateMarkerWeight("RHEE",weights["RHEE"]) cgmFittingProcedure.updateMarkerWeight("RTOE",weights["RTOE"]) cgmFittingProcedure.updateMarkerWeight("LTHI",weights["LTHI"]) cgmFittingProcedure.updateMarkerWeight("LKNE",weights["LKNE"]) cgmFittingProcedure.updateMarkerWeight("LTIB",weights["LTIB"]) cgmFittingProcedure.updateMarkerWeight("LANK",weights["LANK"]) cgmFittingProcedure.updateMarkerWeight("LHEE",weights["LHEE"]) cgmFittingProcedure.updateMarkerWeight("LTOE",weights["LTOE"]) cgmFittingProcedure.updateMarkerWeight("LTHAP",weights["LTHAP"]) cgmFittingProcedure.updateMarkerWeight("LTHAD",weights["LTHAD"]) cgmFittingProcedure.updateMarkerWeight("LTIAP",weights["LTIAP"]) cgmFittingProcedure.updateMarkerWeight("LTIAD",weights["LTIAD"]) cgmFittingProcedure.updateMarkerWeight("RTHAP",weights["RTHAP"]) cgmFittingProcedure.updateMarkerWeight("RTHAD",weights["RTHAD"]) cgmFittingProcedure.updateMarkerWeight("RTIAP",weights["RTIAP"]) cgmFittingProcedure.updateMarkerWeight("RTIAD",weights["RTIAD"]) osrf = opensimFilters.opensimFittingFilter(iksetupFile, scalingOsim, cgmFittingProcedure, (DATA_PATH) ) acqStaticIK = osrf.run(acqStatic,(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: pfp = progressionFrame.PelvisProgressionFrameProcedure() else: pfp = progressionFrame.ThoraxProgressionFrameProcedure() pff = progressionFrame.ProgressionFrameFilter(finalAcqStatic,pfp) pff.compute() globalFrame = pff.outputs["globalFrame"] forwardProgression = pff.outputs["forwardProgression"] 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 calibration2Dof(model, DATA_PATH, reconstructFilenameLabelled, translators, side, beginFrame, endFrame, jointRange, **kwargs): # --- btk acquisition ---- if "forceBtkAcq" in kwargs.keys(): acqFunc = kwargs["forceBtkAcq"] else: acqFunc = btkTools.smartReader( (DATA_PATH + reconstructFilenameLabelled)) btkTools.checkMultipleSubject(acqFunc) acqFunc = btkTools.applyTranslators(acqFunc, translators) # filtering # ----------------------- if "fc_lowPass_marker" in kwargs.keys( ) and kwargs["fc_lowPass_marker"] != 0: trackingMarkers = model.getTrackingMarkers(acqFunc) fc = kwargs["fc_lowPass_marker"] order = 4 if "order_lowPass_marker" in kwargs.keys(): order = kwargs["order_lowPass_marker"] signal_processing.markerFiltering(acqFunc, trackingMarkers, order=order, fc=fc) #---get frame range of interest--- ff = acqFunc.GetFirstFrame() lf = acqFunc.GetLastFrame() # motion if side is None: side = detectSide(acqFunc, "LANK", "RANK") LOGGER.logger.info("Detected motion side : %s" % (side)) start, end = btkTools.getStartEndEvents(acqFunc, side) if start is not None: LOGGER.logger.info("Start event detected") initFrame = start else: initFrame = beginFrame if beginFrame is not None else ff if end is not None: LOGGER.logger.info("End event detected") endFrame = end else: endFrame = endFrame if endFrame is not None else lf iff = initFrame - ff ilf = endFrame - ff if model.version in ["CGM1.0", "CGM1.1", "CGM2.1", "CGM2.2"]: validFrames, vff, vlf = btkTools.findValidFrames( acqFunc, cgm.CGM1.LOWERLIMB_TRACKING_MARKERS) # --------------------------RESET OF THE STATIC File--------- # load btkAcq from static file staticFilename = model.m_staticFilename acqStatic = btkTools.smartReader((DATA_PATH + staticFilename)) btkTools.checkMultipleSubject(acqStatic) acqStatic = btkTools.applyTranslators(acqStatic, translators) # initial calibration ( i.e calibration from Calibration operation) leftFlatFoot = model.m_properties["CalibrationParameters"]["leftFlatFoot"] rightFlatFoot = model.m_properties["CalibrationParameters"][ "rightFlatFoot"] headFlat = model.m_properties["CalibrationParameters"]["headFlat"] markerDiameter = model.m_properties["CalibrationParameters"][ "markerDiameter"] if side == "Left": # remove other functional calibration model.mp_computed["LeftKneeFuncCalibrationOffset"] = 0 if side == "Right": # remove other functional calibration model.mp_computed["RightKneeFuncCalibrationOffset"] = 0 # no rotation on both thigh - re init anatonical frame scp = modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter( scp, acqStatic, model, leftFlatFoot=leftFlatFoot, rightFlatFoot=rightFlatFoot, headFlat=headFlat, markerDiameter=markerDiameter).compute() if model.version in ["CGM1.0", "CGM1.1", "CGM2.1", "CGM2.2"]: modMotion = modelFilters.ModelMotionFilter( scp, acqFunc, model, enums.motionMethod.Determinist) modMotion.compute() elif model.version in ["CGM2.3", "CGM2.4", "CGM2.5"]: if side == "Left": thigh_markers = model.getSegment("Left Thigh").m_tracking_markers shank_markers = model.getSegment("Left Shank").m_tracking_markers elif side == "Right": thigh_markers = model.getSegment("Right Thigh").m_tracking_markers shank_markers = model.getSegment("Right Shank").m_tracking_markers validFrames, vff, vlf = btkTools.findValidFrames( acqFunc, thigh_markers + shank_markers) proximalSegmentLabel = (side + " Thigh") distalSegmentLabel = (side + " Shank") # Motion modMotion = modelFilters.ModelMotionFilter( scp, acqFunc, model, enums.motionMethod.Sodervisk) modMotion.segmentalCompute([proximalSegmentLabel, distalSegmentLabel]) # calibration decorators modelDecorator.KneeCalibrationDecorator(model).calibrate2dof( side, indexFirstFrame=iff, indexLastFrame=ilf, jointRange=jointRange) # --------------------------FINAL CALIBRATION OF THE STATIC File--------- # ---- Calibration modelFilters.ModelCalibrationFilter( scp, acqStatic, model, leftFlatFoot=leftFlatFoot, rightFlatFoot=rightFlatFoot, headFlat=headFlat, markerDiameter=markerDiameter).compute() return model, acqFunc, side
def calibrate(DATA_PATH, calibrateFilenameLabelled, translators, required_mp, optional_mp, leftFlatFoot, rightFlatFoot, headFlat, markerDiameter, pointSuffix, **kwargs): """ Calibration of the CGM1.1 :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 ------------------------------------ # --- btk acquisition ---- if "forceBtkAcq" in kwargs.keys(): acqStatic = kwargs["forceBtkAcq"] else: acqStatic = btkTools.smartReader( (DATA_PATH + calibrateFilenameLabelled)) btkTools.checkMultipleSubject(acqStatic) if btkTools.isPointExist(acqStatic, "SACR"): translators["LPSI"] = "SACR" translators["RPSI"] = "SACR" logging.info("[pyCGM2] Sacrum marker detected") acqStatic = btkTools.applyTranslators(acqStatic, translators) # ---detectedCalibrationMethods---- dcm = cgm.CGM.detectCalibrationMethods(acqStatic) # ---definition--- model = cgm.CGM1() model.setVersion("CGM1.1") 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, headFlat=headFlat, markerDiameter=markerDiameter, ).compute() # ---- Decorators ----- decorators.applyBasicDecorators(dcm, model, acqStatic, optional_mp, markerDiameter) # ----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---- # 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() if "displayCoordinateSystem" in kwargs.keys( ) and kwargs["displayCoordinateSystem"]: csp = modelFilters.ModelCoordinateSystemProcedure(model) csdf = modelFilters.CoordinateSystemDisplayFilter( csp, model, acqStatic) csdf.setStatic(False) csdf.display() if "noKinematicsCalculation" in kwargs.keys( ) and kwargs["noKinematicsCalculation"]: logging.warning( "[pyCGM2] No Kinematic calculation done for the static file") return model, acqStatic else: #---- 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: pfp = progressionFrame.PelvisProgressionFrameProcedure() else: pfp = progressionFrame.ThoraxProgressionFrameProcedure() pff = progressionFrame.ProgressionFrameFilter(acqStatic, pfp) pff.compute() globalFrame = pff.outputs["globalFrame"] forwardProgression = pff.outputs["forwardProgression"] if model.m_bodypart != enums.BodyPart.UpperLimb: 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) 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 advancedCGM1_kad_midMaleolus_markerDiameter(cls): MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\\KAD-Med-markerDiameter\\" staticFilename = "MRI-US-01, 2008-08-08, 3DGA 02.c3d" acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model=cgm.CGM1 model.configure() markerDiameter=25.0 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) # -----------CGM STATIC CALIBRATION-------------------- scp=modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp,acqStatic,model,markerDiameter=markerDiameter, leftFlatFoot = False, rightFlatFoot = False).compute() # cgm decorator modelDecorator.Kad(model,acqStatic).compute(markerDiameter=markerDiameter, side="both") modelDecorator.AnkleCalibrationDecorator(model).midMaleolus(acqStatic,markerDiameter=markerDiameter, side="both") modelFilters.ModelCalibrationFilter(scp,acqStatic,model, markerDiameter=markerDiameter).compute() # TESTS ------------------------------------------------ offsetTesting(acqStatic,model,display = True, unitTesting=True) np.testing.assert_equal(model.getSegment("Left Thigh").getReferential("TF").static.getNode_byLabel("LKJC").m_desc ,"KAD") np.testing.assert_equal(model.getSegment("Right Thigh").getReferential("TF").static.getNode_byLabel("RKJC").m_desc ,"KAD") np.testing.assert_equal(model.getSegment("Left Shank").getReferential("TF").static.getNode_byLabel("LKJC").m_desc ,"KAD") np.testing.assert_equal(model.getSegment("Right Shank").getReferential("TF").static.getNode_byLabel("RKJC").m_desc ,"KAD") np.testing.assert_equal(model.getSegment("Left Shank").getReferential("TF").static.getNode_byLabel("LAJC").m_desc ,"mid") np.testing.assert_equal(model.getSegment("Right Shank").getReferential("TF").static.getNode_byLabel("RAJC").m_desc ,"mid") np.testing.assert_equal(model.getSegment("Left Foot").getReferential("TF").static.getNode_byLabel("LAJC").m_desc ,"mid") np.testing.assert_equal(model.getSegment("Right Foot").getReferential("TF").static.getNode_byLabel("RAJC").m_desc ,"mid") np.testing.assert_equal(model.m_useRightTibialTorsion,True ) np.testing.assert_equal(model.m_useLeftTibialTorsion,True ) # joint centres np.testing.assert_almost_equal(acqStatic.GetPoint("LFEP").GetValues().mean(axis=0),acqStatic.GetPoint("LHJC").GetValues().mean(axis=0),decimal = 3) np.testing.assert_almost_equal(acqStatic.GetPoint("RFEP").GetValues().mean(axis=0),acqStatic.GetPoint("RHJC").GetValues().mean(axis=0),decimal = 3) np.testing.assert_almost_equal(acqStatic.GetPoint("LFEO").GetValues().mean(axis=0),acqStatic.GetPoint("LKJC").GetValues().mean(axis=0),decimal = 3) np.testing.assert_almost_equal(acqStatic.GetPoint("RFEO").GetValues().mean(axis=0),acqStatic.GetPoint("RKJC").GetValues().mean(axis=0),decimal = 3) np.testing.assert_almost_equal(acqStatic.GetPoint("LTIO").GetValues().mean(axis=0),acqStatic.GetPoint("LAJC").GetValues().mean(axis=0),decimal = 3) np.testing.assert_almost_equal(acqStatic.GetPoint("RTIO").GetValues().mean(axis=0),acqStatic.GetPoint("RAJC").GetValues().mean(axis=0),decimal = 3) btkTools.smartWriter(acqStatic, "outStatic_advancedCGM1_kad_midMaleolus_markerDiameter.c3d")
def basicCGM1_manualOffset_thighRotationON_shankRotationOFF_tibialTorsionON(cls): """ CGM1 manual offset behaviour : => - Manual Thigh Rotation must modify ShankRotation. - If zero TibialTorsion inputs -> flag RightTibialTorsion must be off and TibialTorsion keep zero value """ MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\\basic-manualOffsets-thiON_shaOFF_torsionON\\" staticFilename = "MRI-US-01, 2008-08-08, 3DGA 02.c3d" acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model=cgm.CGM1 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, } optional_mp={ 'InterAsisDistance' : 0, 'LeftAsisTrocanterDistance' : 0, 'LeftThighRotation' : 10, 'LeftShankRotation' : 0, 'LeftTibialTorsion' : -30.0, 'RightAsisTrocanterDistance' : 0, 'RightThighRotation' : 10, 'RightShankRotation' : 0, 'RightTibialTorsion' : -30.0 } model.addAnthropoInputParameters(mp,optional=optional_mp) # -----------CGM STATIC CALIBRATION-------------------- scp=modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp,acqStatic,model).compute() # decorators modelDecorator.Cgm1ManualOffsets(model).compute(acqStatic,"left",model.mp["LeftThighRotation"],markerDiameter,model.mp["LeftTibialTorsion"],model.mp["LeftShankRotation"]) modelDecorator.Cgm1ManualOffsets(model).compute(acqStatic,"right",model.mp["RightThighRotation"],markerDiameter,model.mp["RightTibialTorsion"],model.mp["RightShankRotation"]) # finql calibration modelFilters.ModelCalibrationFilter(scp,acqStatic,model,viconCGM1compatible=True ).compute() # TESTS # offset testing offsetTesting(acqStatic,model,display = True, unitTesting=True) np.testing.assert_equal(model.getSegment("Left Thigh").getReferential("TF").static.getNode_byLabel("LKJC").m_desc ,"manual ThighOffset") np.testing.assert_equal(model.getSegment("Right Thigh").getReferential("TF").static.getNode_byLabel("RKJC").m_desc ,"manual ThighOffset") np.testing.assert_equal(model.getSegment("Left Shank").getReferential("TF").static.getNode_byLabel("LKJC").m_desc ,"manual ThighOffset") np.testing.assert_equal(model.getSegment("Right Shank").getReferential("TF").static.getNode_byLabel("RKJC").m_desc ,"manual ThighOffset") np.testing.assert_equal(model.getSegment("Left Shank").getReferential("TF").static.getNode_byLabel("LAJC").m_desc ,"manualTHIoffset-manualTT") np.testing.assert_equal(model.getSegment("Right Shank").getReferential("TF").static.getNode_byLabel("RAJC").m_desc ,"manualTHIoffset-manualTT") np.testing.assert_equal(model.getSegment("Left Foot").getReferential("TF").static.getNode_byLabel("LAJC").m_desc ,"manualTHIoffset-manualTT") np.testing.assert_equal(model.getSegment("Right Foot").getReferential("TF").static.getNode_byLabel("RAJC").m_desc ,"manualTHIoffset-manualTT") np.testing.assert_equal(model.m_useRightTibialTorsion,True ) np.testing.assert_equal(model.m_useLeftTibialTorsion,True )
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 basicCGM1_global(cls): MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\\basic_pathologicalSubject\\" staticFilename = "BOVE Vincent Cal 01.c3d" acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename)) model = cgm.CGM1 model.configure() markerDiameter = 14 mp = { 'Bodymass': 72.0, 'LeftLegLength': 840.0, 'RightLegLength': 850.0, 'LeftKneeWidth': 105.0, 'RightKneeWidth': 110.4, 'LeftAnkleWidth': 74.0, 'RightAnkleWidth': 74.0, } model.addAnthropoInputParameters(mp) scp = modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp, acqStatic, model).compute() # ------ Travelling Axis Y ------- gaitFilename = "20120213_BV-PRE-S-NNNN-I-dyn 04.global2.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() # Joint kinematics modelFilters.ModelJCSFilter(model, acqGait).compute( description="vectoriel", pointLabelSuffix="cgm1_6dof") # BSP model bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() # force plate -- construction du wrench attribue au pied forceplates.appendForcePlateCornerAsMarker(acqGait) mappedForcePlate = forceplates.matchingFootSideOnForceplate(acqGait) modelFilters.ForcePlateAssemblyFilter( model, acqGait, mappedForcePlate, leftSegmentLabel="Left Foot", rightSegmentLabel="Right Foot").compute() idp = modelFilters.CGMLowerlimbInverseDynamicProcedure() modelFilters.InverseDynamicFilter( model, acqGait, procedure=idp, projection=pyCGM2Enums.MomentProjection.Global).compute( pointLabelSuffix="cgm1_6dof") modelFilters.JointPowerFilter( model, acqGait).compute(pointLabelSuffix="cgm1_6dof") btkTools.smartWriter(acqGait, "testInvDynPatho.c3d") # TEST ------ compareKinetics(acqGait, 5, -5, 0.2, 40.0, 0.1)
'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) #----CALIBRATION---- # initial calibration scp = modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter(scp, acqStatic, model).compute() # motion gaitFilename = "MRI-US-01, 2008-08-08, 3DGA 14.c3d" acqGait = btkTools.smartReader(str(MAIN_PATH + gaitFilename)) modMotion = modelFilters.ModelMotionFilter(scp, acqGait, model, enums.motionMethod.Determinist, usePyCGM2_coordinateSystem=True) modMotion.compute() # calibration decorators modelDecorator.KneeCalibrationDecorator(model).calibrate2dof("Left") modelDecorator.KneeCalibrationDecorator(model).calibrate2dof("Right")
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_4() 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") 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, enums.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, enums.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).compute() # save static c3d with update KJC btkTools.smartWriter(acqStatic, "Static-SARA.c3d") # print functional Offsets print model.mp_computed["LeftKneeFuncCalibrationOffset"] print model.mp_computed["RightKneeFuncCalibrationOffset"]
def sara(model, DATA_PATH, reconstructFilenameLabelled, translators, side, beginFrame, endFrame, **kwargs): # --- btk acquisition ---- if "forceBtkAcq" in kwargs.keys(): acqFunc = kwargs["forceBtkAcq"] else: acqFunc = btkTools.smartReader( str(DATA_PATH + reconstructFilenameLabelled)) btkTools.checkMultipleSubject(acqFunc) acqFunc = btkTools.applyTranslators(acqFunc, translators) #---get frame range of interest--- ff = acqFunc.GetFirstFrame() lf = acqFunc.GetLastFrame() start, end = btkTools.getStartEndEvents(acqFunc, side) if start is not None: logging.info("Start event detected") initFrame = start else: initFrame = beginFrame if beginFrame is not None else ff if end is not None: logging.info("End event detected") endFrame = end else: endFrame = endFrame if endFrame is not None else lf iff = initFrame - ff ilf = endFrame - ff #---motion side of the lower limb--- if side is None: side = detectSide(acqFunc, "LANK", "RANK") logging.info("Detected motion side : %s" % (side)) # --------------------------RESET OF THE STATIC File--------- # load btkAcq from static file staticFilename = model.m_staticFilename acqStatic = btkTools.smartReader(str(DATA_PATH + staticFilename)) btkTools.checkMultipleSubject(acqStatic) acqStatic = btkTools.applyTranslators(acqStatic, translators) # initial calibration ( i.e calibration from Calibration operation) leftFlatFoot = model.m_properties["CalibrationParameters"]["leftFlatFoot"] rightFlatFoot = model.m_properties["CalibrationParameters"][ "rightFlatFoot"] markerDiameter = model.m_properties["CalibrationParameters"][ "markerDiameter"] headFlat = model.m_properties["CalibrationParameters"]["headFlat"] if side == "Left": model.mp_computed["LeftKneeFuncCalibrationOffset"] = 0 if side == "Right": model.mp_computed["RightKneeFuncCalibrationOffset"] = 0 # initial calibration ( zero previous KneeFunc offset on considered side ) scp = modelFilters.StaticCalibrationProcedure(model) modelFilters.ModelCalibrationFilter( scp, acqStatic, model, leftFlatFoot=leftFlatFoot, rightFlatFoot=rightFlatFoot, headFlat=headFlat, markerDiameter=markerDiameter).compute() if model.version in ["CGM2.3", "CGM2.4", "CGM2.5"]: if side == "Left": thigh_markers = model.getSegment("Left Thigh").m_tracking_markers shank_markers = model.getSegment("Left Shank").m_tracking_markers elif side == "Right": thigh_markers = model.getSegment("Right Thigh").m_tracking_markers shank_markers = model.getSegment("Right Shank").m_tracking_markers validFrames, vff, vlf = btkTools.findValidFrames( acqFunc, thigh_markers + shank_markers) proximalSegmentLabel = str(side + " Thigh") distalSegmentLabel = str(side + " Shank") # segment Motion modMotion = modelFilters.ModelMotionFilter( scp, acqFunc, model, enums.motionMethod.Sodervisk) modMotion.segmentalCompute([proximalSegmentLabel, distalSegmentLabel]) # decorator modelDecorator.KneeCalibrationDecorator(model).sara( side, indexFirstFrame=iff, indexLastFrame=ilf) # --------------------------FINAL CALIBRATION OF THE STATIC File--------- modelFilters.ModelCalibrationFilter( scp, acqStatic, model, leftFlatFoot=leftFlatFoot, rightFlatFoot=rightFlatFoot, headFlat=headFlat, markerDiameter=markerDiameter).compute() return model, acqFunc, side
def advancedCGM1_kadMed_manualTibialTorsion(cls): """ - constraints on both tibial Torsion But application of a KAD-med calibration => tibial Torsion has to be udpated """ 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() 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, } optional_mp={ 'InterAsisDistance' : 0, 'LeftAsisTrocanterDistance' : 0, 'LeftThighRotation' : 0, 'LeftShankRotation' : 0 , 'LeftTibialTorsion' : -10, 'RightAsisTrocanterDistance' : 0, 'RightThighRotation' : 0, 'RightShankRotation' : 0, 'RightTibialTorsion' : 15 } 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() np.testing.assert_equal(model.m_useRightTibialTorsion,True ) np.testing.assert_equal(model.m_useLeftTibialTorsion,True ) np.testing.assert_equal(model.mp["LeftTibialTorsion"],0 ) # cancel by the decorator np.testing.assert_equal(model.mp["RightTibialTorsion"],0) 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]) np.testing.assert_almost_equal(-1.0*model.mp_computed["LeftTibialTorsionOffset"],ltt_vicon, decimal = 3) np.testing.assert_almost_equal(model.mp_computed["RightTibialTorsionOffset"],rtt_vicon, decimal = 3)
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")