Пример #1
0
    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)
Пример #2
0
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
Пример #3
0
    def CGM1_fullbody_static(cls):

        MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\\full-PiG\\"
        staticFilename = "PN01NORMSTAT.c3d"

        # CALIBRATION ###############################
        acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename))

        markerDiameter = 14

        # Lower Limb
        mp = {
            'Bodymass': 83,
            'LeftLegLength': 874,
            'RightLegLength': 876.0,
            'LeftKneeWidth': 106.0,
            'RightKneeWidth': 103.0,
            'LeftAnkleWidth': 74.0,
            'RightAnkleWidth': 72.0,
            'LeftSoleDelta': 0,
            'RightSoleDelta': 0,
            'LeftShoulderOffset': 50,
            'LeftElbowWidth': 91,
            'LeftWristWidth': 56,
            'LeftHandThickness': 28,
            'RightShoulderOffset': 45,
            'RightElbowWidth': 90,
            'RightWristWidth': 55,
            'RightHandThickness': 30
        }

        model = cgm.CGM1()
        model.configure(bodyPart=enums.BodyPart.FullBody)
        model.addAnthropoInputParameters(mp)

        scp = modelFilters.StaticCalibrationProcedure(
            model)  # load calibration procedure

        modelFilters.ModelCalibrationFilter(
            scp,
            acqStatic,
            model,
            leftFlatFoot=True,
            rightFlatFoot=True,
            markerDiameter=14,
            viconCGM1compatible=True).compute()

        # MOTION ###############################
        gaitFilename = "PN01NORMSTAT.c3d"
        acqGait = btkTools.smartReader(str(MAIN_PATH + gaitFilename))

        modMotion = modelFilters.ModelMotionFilter(
            scp,
            acqGait,
            model,
            enums.motionMethod.Determinist,
            markerDiameter=14,
            viconCGM1compatible=False)
        modMotion.compute()

        csp = modelFilters.ModelCoordinateSystemProcedure(model)
        csdf = modelFilters.CoordinateSystemDisplayFilter(csp, model,
                                                          acqGait).display()

        modelFilters.ModelJCSFilter(model, acqGait).compute(
            description="vectoriel", pointLabelSuffix="cgm1_6dof")

        plot("RSpineAngles", acqGait, "cgm1_6dof")
        plot("LSpineAngles", acqGait, "cgm1_6dof")

        np.testing.assert_almost_equal(
            acqGait.GetPoint("RSpineAngles").GetValues(),
            acqGait.GetPoint("RSpineAngles_cgm1_6dof").GetValues(),
            decimal=2)
        np.testing.assert_almost_equal(
            acqGait.GetPoint("LSpineAngles").GetValues(),
            acqGait.GetPoint("LSpineAngles_cgm1_6dof").GetValues(),
            decimal=2)

        btkTools.smartWriter(acqGait, "fullbody.c3d")
Пример #4
0
    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,
                                            headHorizontal=False).compute()

        # --- motion ----
        gaitFilename = "PN01NORMSS01.c3d"
        acqGait = btkTools.smartReader(str(MAIN_PATH + gaitFilename))

        modMotion = modelFilters.ModelMotionFilter(
            scp, acqGait, model, enums.motionMethod.Determinist)
        modMotion.compute()

        csp = modelFilters.ModelCoordinateSystemProcedure(model)
        csdf = modelFilters.CoordinateSystemDisplayFilter(csp, model, acqGait)
        csdf.setStatic(False)
        csdf.display()

        modelFilters.ModelJCSFilter(model, acqGait).compute(
            description="vectoriel", pointLabelSuffix="cgm1_6dof")

        #plot("LNeckAngles",acqGait,"cgm1_6dof")

        np.testing.assert_almost_equal(
            acqGait.GetPoint("LShoulderAngles").GetValues(),
            acqGait.GetPoint("LShoulderAngles_cgm1_6dof").GetValues(),
            decimal=3)
        np.testing.assert_almost_equal(
            acqGait.GetPoint("RShoulderAngles").GetValues(),
            acqGait.GetPoint("RShoulderAngles_cgm1_6dof").GetValues(),
            decimal=3)

        np.testing.assert_almost_equal(
            acqGait.GetPoint("RElbowAngles").GetValues(),
            acqGait.GetPoint("RElbowAngles_cgm1_6dof").GetValues(),
            decimal=3)
        np.testing.assert_almost_equal(
            acqGait.GetPoint("LElbowAngles").GetValues(),
            acqGait.GetPoint("LElbowAngles_cgm1_6dof").GetValues(),
            decimal=3)

        np.testing.assert_almost_equal(
            acqGait.GetPoint("RWristAngles").GetValues(),
            acqGait.GetPoint("RWristAngles_cgm1_6dof").GetValues(),
            decimal=3)  # fail on transverse
        np.testing.assert_almost_equal(
            acqGait.GetPoint("LWristAngles").GetValues(),
            acqGait.GetPoint("LWristAngles_cgm1_6dof").GetValues(),
            decimal=3)  # fail on transverse

        np.testing.assert_almost_equal(
            acqGait.GetPoint("RNeckAngles").GetValues(),
            acqGait.GetPoint("RNeckAngles_cgm1_6dof").GetValues(),
            decimal=1)  # fail on coronal
        np.testing.assert_almost_equal(
            acqGait.GetPoint("LNeckAngles").GetValues(),
            acqGait.GetPoint("LNeckAngles_cgm1_6dof").GetValues(),
            decimal=1)  # fail on coronal

        btkTools.smartWriter(acqGait, "upperLimb_angle.c3d")
Пример #5
0
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
Пример #6
0
    def CGM1_upperLimb_absoluteAngles_static(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,
                                            headHorizontal=False).compute()

        # --- motion ----
        gaitFilename = "PN01NORMSTAT.c3d"
        acqGait = btkTools.smartReader(str(MAIN_PATH + gaitFilename))

        modMotion = modelFilters.ModelMotionFilter(
            scp, acqGait, model, enums.motionMethod.Determinist)
        modMotion.compute()

        longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromLongAxis(
            acqGait, "C7", "CLAV")
        modelFilters.ModelAbsoluteAnglesFilter(
            model,
            acqGait,
            segmentLabels=["Thorax"],
            angleLabels=[
                "Thorax",
            ],
            eulerSequences=["YXZ"],
            globalFrameOrientation=globalFrame,
            forwardProgression=forwardProgression).compute(
                pointLabelSuffix="cgm1_6dof")

        np.testing.assert_equal(longitudinalAxis, "X")
        np.testing.assert_equal(forwardProgression, True)
        np.testing.assert_equal(globalFrame, "XYZ")

        # plot("LHeadAngles",acqGait,"cgm1_6dof")
        # plot("RHeadAngles",acqGait,"cgm1_6dof")
        plot("RThoraxAngles", acqGait, "cgm1_6dof")
        plot("LThoraxAngles", acqGait, "cgm1_6dof")
Пример #7
0
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

    """
    detectAnomaly = False

    if "anomalyException" in kwargs.keys():
        anomalyException = kwargs["anomalyException"]
    else:
        anomalyException = False
    # --------------------------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"
        LOGGER.logger.info("[pyCGM2] Sacrum marker detected")

    acqStatic = btkTools.applyTranslators(acqStatic, translators)

    trackingMarkers = cgm.CGM1.LOWERLIMB_TRACKING_MARKERS + cgm.CGM1.THORAX_TRACKING_MARKERS + cgm.CGM1.UPPERLIMB_TRACKING_MARKERS
    actual_trackingMarkers, phatoms_trackingMarkers = btkTools.createPhantoms(
        acqStatic, trackingMarkers)

    vff = acqStatic.GetFirstFrame()
    vlf = acqStatic.GetLastFrame()
    # vff,vlf = btkTools.getFrameBoundaries(acqStatic,actual_trackingMarkers)
    flag = btkTools.getValidFrames(acqStatic,
                                   actual_trackingMarkers,
                                   frameBounds=[vff, vlf])

    gapFlag = btkTools.checkGap(acqStatic,
                                actual_trackingMarkers,
                                frameBounds=[vff, vlf])
    if gapFlag:
        raise Exception(
            "[pyCGM2] Calibration aborted. Gap find during interval [%i-%i]. Crop your c3d "
            % (vff, vlf))

    # --------------------ANOMALY------------------------------
    # --Check MP
    adap = AnomalyDetectionProcedure.AnthropoDataAnomalyProcedure(required_mp)
    adf = AnomalyFilter.AnomalyDetectionFilter(None, None, adap)
    mp_anomaly = adf.run()
    if mp_anomaly["ErrorState"]: detectAnomaly = True

    # --marker presence
    markersets = [
        cgm.CGM1.LOWERLIMB_TRACKING_MARKERS, cgm.CGM1.THORAX_TRACKING_MARKERS,
        cgm.CGM1.UPPERLIMB_TRACKING_MARKERS
    ]
    for markerset in markersets:
        ipdp = InspectorProcedure.MarkerPresenceDetectionProcedure(markerset)
        idf = InspectorFilter.InspectorFilter(acqStatic,
                                              calibrateFilenameLabelled, ipdp)
        inspector = idf.run()

        # # --marker outliers
        if inspector["In"] != []:
            madp = AnomalyDetectionProcedure.MarkerAnomalyDetectionRollingProcedure(
                inspector["In"], plot=False, window=4, threshold=3)
            adf = AnomalyFilter.AnomalyDetectionFilter(
                acqStatic, calibrateFilenameLabelled, madp)
            anomaly = adf.run()
            anomalyIndexes = anomaly["Output"]
            if anomaly["ErrorState"]: detectAnomaly = True

    if detectAnomaly and anomalyException:
        raise Exception(
            "Anomalies has been detected - Check Warning message of the log file"
        )

    # --------------------MODELLING------------------------------

    # ---detectedCalibrationMethods----
    dcm = cgm.CGM.detectCalibrationMethods(acqStatic)

    # ---definition---
    model = cgm.CGM1()
    model.setVersion("CGM1.1")
    model.configure(detectedCalibrationMethods=dcm)
    model.addAnthropoInputParameters(required_mp, optional=optional_mp)

    if dcm["Left Knee"] == enums.JointCalibrationMethod.KAD:
        actual_trackingMarkers.append("LKNE")
    if dcm["Right Knee"] == enums.JointCalibrationMethod.KAD:
        actual_trackingMarkers.append("RKNE")
    model.setStaticTrackingMarkers(actual_trackingMarkers)

    # --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()

    # ----progression Frame----
    progressionFlag = False
    if btkTools.isPointsExist(acqStatic, ['LASI', 'RASI', 'RPSI', 'LPSI'],
                              ignorePhantom=False):
        LOGGER.logger.info(
            "[pyCGM2] - progression axis detected from Pelvic markers ")
        pfp = progressionFrame.PelvisProgressionFrameProcedure()
        pff = progressionFrame.ProgressionFrameFilter(acqStatic, pfp)
        pff.compute()
        progressionAxis = pff.outputs["progressionAxis"]
        globalFrame = pff.outputs["globalFrame"]
        forwardProgression = pff.outputs["forwardProgression"]
        progressionFlag = True
    elif btkTools.isPointsExist(acqStatic, ['C7', 'T10', 'CLAV', 'STRN'],
                                ignorePhantom=False) and not progressionFlag:
        LOGGER.logger.info(
            "[pyCGM2] - progression axis detected from Thoracic markers ")
        pfp = progressionFrame.ThoraxProgressionFrameProcedure()
        pff = progressionFrame.ProgressionFrameFilter(acqStatic, pfp)
        pff.compute()
        progressionAxis = pff.outputs["progressionAxis"]
        globalFrame = pff.outputs["globalFrame"]
        forwardProgression = pff.outputs["forwardProgression"]

    else:
        globalFrame = "XYZ"
        progressionAxis = "X"
        forwardProgression = True
        LOGGER.logger.error(
            "[pyCGM2] - impossible to detect progression axis - neither pelvic nor thoracic markers are present. Progression set to +X by default "
        )

    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"]:
        LOGGER.logger.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)

        modelFilters.ModelAbsoluteAnglesFilter(
            model,
            acqStatic,
            segmentLabels=[
                "Left Foot", "Right Foot", "Pelvis", "Thorax", "Head"
            ],
            angleLabels=[
                "LFootProgress", "RFootProgress", "Pelvis", "Thorax", "Head"
            ],
            eulerSequences=["TOR", "TOR", "ROT", "YXZ", "TOR"],
            globalFrameOrientation=globalFrame,
            forwardProgression=forwardProgression).compute(
                pointLabelSuffix=pointSuffix)

        # BSP model
        bspModel = bodySegmentParameters.Bsp(model)
        bspModel.compute()

        modelFilters.CentreOfMassFilter(
            model, acqStatic).compute(pointLabelSuffix=pointSuffix)

        btkTools.cleanAcq(acqStatic)
        if detectAnomaly and not anomalyException:
            LOGGER.logger.error(
                "Anomalies has been detected - Check Warning messages of the log file"
            )

        return model, acqStatic, detectAnomaly
Пример #8
0
    def CGM1_fullbody_onStatic(cls):

        MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\\Full PIG - StephenL5_C7\\"
        staticFilename = "PN01NORMSTAT.c3d"

        # CALIBRATION ###############################
        acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename))

        markerDiameter = 14

        # Lower Limb
        mp = {
            'Bodymass': 83,
            'LeftLegLength': 874,
            'RightLegLength': 876.0,
            'LeftKneeWidth': 106.0,
            'RightKneeWidth': 103.0,
            'LeftAnkleWidth': 74.0,
            'RightAnkleWidth': 72.0,
            'LeftSoleDelta': 0,
            'RightSoleDelta': 0,
            'LeftShoulderOffset': 50,
            'LeftElbowWidth': 91,
            'LeftWristWidth': 56,
            'LeftHandThickness': 28,
            'RightShoulderOffset': 45,
            'RightElbowWidth': 90,
            'RightWristWidth': 55,
            'RightHandThickness': 30
        }

        model = cgm.CGM1()
        model.configure(bodyPart=enums.BodyPart.FullBody)
        model.addAnthropoInputParameters(mp)

        scp = modelFilters.StaticCalibrationProcedure(
            model)  # load calibration procedure
        csp = modelFilters.ModelCoordinateSystemProcedure(model)

        modelFilters.ModelCalibrationFilter(
            scp,
            acqStatic,
            model,
            leftFlatFoot=False,
            rightFlatFoot=False,
            markerDiameter=14,
            viconCGM1compatible=True,
        ).compute()
        #headHorizontal=True

        # --- motion ----
        gaitFilename = "PN01NORMSTAT_stephen.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()

        # angles
        modelFilters.ModelJCSFilter(model, acqGait).compute(
            description="vectoriel", pointLabelSuffix="cgm1_6dof")

        longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromLongAxis(
            acqGait, "C7", "CLAV")
        modelFilters.ModelAbsoluteAnglesFilter(
            model,
            acqGait,
            segmentLabels=["Thorax"],
            angleLabels=[
                "Thorax",
            ],
            eulerSequences=["YXZ"],
            globalFrameOrientation=globalFrame,
            forwardProgression=forwardProgression).compute(
                pointLabelSuffix="cgm1_6dof")

        # testing
        np.testing.assert_equal(longitudinalAxis, "X")
        np.testing.assert_equal(forwardProgression, True)
        np.testing.assert_equal(globalFrame, "XYZ")

        # BSP model
        bspModel = bodySegmentParameters.Bsp(model)
        bspModel.compute()

        btkTools.smartAppendPoint(
            acqGait, "pelvisCOM_py",
            model.getSegment("Pelvis").getComTrajectory())
        btkTools.smartAppendPoint(acqGait, "headCOM_py",
                                  model.getSegment("Head").getComTrajectory())
        btkTools.smartAppendPoint(
            acqGait, "ThoraxCOM_py",
            model.getSegment("Thorax").getComTrajectory())
        btkTools.smartAppendPoint(
            acqGait, "LhumCOM_py",
            model.getSegment("Left UpperArm").getComTrajectory())
        btkTools.smartAppendPoint(
            acqGait, "LforeCom_py",
            model.getSegment("Left ForeArm").getComTrajectory())
        btkTools.smartAppendPoint(
            acqGait, "LhandCom_py",
            model.getSegment("Left Hand").getComTrajectory())
        btkTools.smartAppendPoint(
            acqGait, "RhumCOM_py",
            model.getSegment("Right UpperArm").getComTrajectory())
        btkTools.smartAppendPoint(
            acqGait, "RforeCom_py",
            model.getSegment("Right ForeArm").getComTrajectory())
        btkTools.smartAppendPoint(
            acqGait, "RhandCom_py",
            model.getSegment("Right Hand").getComTrajectory())

        modelFilters.CentreOfMassFilter(
            model, acqGait).compute(pointLabelSuffix="py2")

        TL5_pelvis = model.getSegment(
            "Pelvis").anatomicalFrame.getNodeTrajectory("TL5")
        TL5_thorax = model.getSegment(
            "Thorax").anatomicalFrame.getNodeTrajectory("TL5")
        C7o_thorax = model.getSegment(
            "Thorax").anatomicalFrame.getNodeTrajectory("C7o")
        C7_thorax = model.getSegment(
            "Thorax").anatomicalFrame.getNodeTrajectory("C7")
        C7_head = model.getSegment("Head").anatomicalFrame.getNodeTrajectory(
            "C7")
        btkTools.smartAppendPoint(acqGait, "TL5_pelvis", TL5_pelvis, desc="")
        btkTools.smartAppendPoint(acqGait, "TL5_thorax", TL5_thorax, desc="")
        btkTools.smartAppendPoint(acqGait, "C7o_thorax", C7o_thorax, desc="")
        btkTools.smartAppendPoint(acqGait, "C7_thorax", C7_thorax, desc="")
        btkTools.smartAppendPoint(acqGait, "C7_head", C7_thorax, desc="")

        btkTools.smartWriter(acqGait,
                             "FullBody_COM_CGM1_fullbody_onStatic.c3d")
Пример #9
0
    def CGM1_fullbody(cls):

        MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\\Full PIG - StephenL5_C7\\"
        staticFilename = "PN01NORMSTAT.c3d"

        # CALIBRATION ###############################
        acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename))

        markerDiameter = 14

        # Lower Limb
        mp = {
            'Bodymass': 83,
            'LeftLegLength': 874,
            'RightLegLength': 876.0,
            'LeftKneeWidth': 106.0,
            'RightKneeWidth': 103.0,
            'LeftAnkleWidth': 74.0,
            'RightAnkleWidth': 72.0,
            'LeftSoleDelta': 0,
            'RightSoleDelta': 0,
            'LeftShoulderOffset': 50,
            'LeftElbowWidth': 91,
            'LeftWristWidth': 56,
            'LeftHandThickness': 28,
            'RightShoulderOffset': 45,
            'RightElbowWidth': 90,
            'RightWristWidth': 55,
            'RightHandThickness': 30
        }

        model = cgm.CGM1()
        model.configure(bodyPart=enums.BodyPart.FullBody)
        model.addAnthropoInputParameters(mp)

        scp = modelFilters.StaticCalibrationProcedure(
            model)  # load calibration procedure

        modelFilters.ModelCalibrationFilter(
            scp,
            acqStatic,
            model,
            leftFlatFoot=False,
            rightFlatFoot=False,
            markerDiameter=14,
            viconCGM1compatible=True,
        ).compute()
        #headHorizontal=True

        csp = modelFilters.ModelCoordinateSystemProcedure(model)
        csdf = modelFilters.CoordinateSystemDisplayFilter(
            csp, model, acqStatic)
        csdf.setStatic(True)
        csdf.display()

        # joint centres
        np.testing.assert_almost_equal(
            acqStatic.GetPoint("TRXO").GetValues().mean(axis=0),
            acqStatic.GetPoint("OT").GetValues().mean(axis=0),
            decimal=3)

        np.testing.assert_almost_equal(
            acqStatic.GetPoint("LCLO").GetValues().mean(axis=0),
            acqStatic.GetPoint("LSJC").GetValues().mean(axis=0),
            decimal=3)
        np.testing.assert_almost_equal(
            acqStatic.GetPoint("LHUO").GetValues().mean(axis=0),
            acqStatic.GetPoint("LEJC").GetValues().mean(axis=0),
            decimal=3)
        np.testing.assert_almost_equal(
            acqStatic.GetPoint("LCLO").GetValues().mean(axis=0),
            acqStatic.GetPoint("LSJC").GetValues().mean(axis=0),
            decimal=3)

        np.testing.assert_almost_equal(
            acqStatic.GetPoint("RCLO").GetValues().mean(axis=0),
            acqStatic.GetPoint("RSJC").GetValues().mean(axis=0),
            decimal=3)
        np.testing.assert_almost_equal(
            acqStatic.GetPoint("RHUO").GetValues().mean(axis=0),
            acqStatic.GetPoint("REJC").GetValues().mean(axis=0),
            decimal=3)
        np.testing.assert_almost_equal(
            acqStatic.GetPoint("RCLO").GetValues().mean(axis=0),
            acqStatic.GetPoint("RSJC").GetValues().mean(axis=0),
            decimal=3)

        btkTools.smartWriter(acqStatic, "FullBody_Static_CGM1_fullbody.c3d")
Пример #10
0
    def CGM1_fullbody(cls):

        MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\\Full PIG - StephenL5_C7\\"
        staticFilename = "PN01NORMSTAT.c3d"

        # CALIBRATION ###############################
        acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename))

        markerDiameter = 14

        # Lower Limb
        mp = {
            'Bodymass': 83,
            'LeftLegLength': 874,
            'RightLegLength': 876.0,
            'LeftKneeWidth': 106.0,
            'RightKneeWidth': 103.0,
            'LeftAnkleWidth': 74.0,
            'RightAnkleWidth': 72.0,
            'LeftSoleDelta': 0,
            'RightSoleDelta': 0,
            'LeftShoulderOffset': 50,
            'LeftElbowWidth': 91,
            'LeftWristWidth': 56,
            'LeftHandThickness': 28,
            'RightShoulderOffset': 45,
            'RightElbowWidth': 90,
            'RightWristWidth': 55,
            'RightHandThickness': 30
        }

        model = cgm.CGM1()
        model.configure(bodyPart=enums.BodyPart.FullBody)
        model.addAnthropoInputParameters(mp)

        scp = modelFilters.StaticCalibrationProcedure(
            model)  # load calibration procedure
        csp = modelFilters.ModelCoordinateSystemProcedure(model)

        modelFilters.ModelCalibrationFilter(
            scp,
            acqStatic,
            model,
            leftFlatFoot=False,
            rightFlatFoot=False,
            markerDiameter=14,
            viconCGM1compatible=True,
        ).compute()
        #headHorizontal=True

        # --- motion ----
        gaitFilename = "PN01NORMSS01_stephen.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()

        # angles
        modelFilters.ModelJCSFilter(model, acqGait).compute(
            description="vectoriel", pointLabelSuffix="cgm1_6dof")

        longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromLongAxis(
            acqGait, "C7", "CLAV")
        modelFilters.ModelAbsoluteAnglesFilter(
            model,
            acqGait,
            segmentLabels=["Thorax"],
            angleLabels=[
                "Thorax",
            ],
            eulerSequences=["YXZ"],
            globalFrameOrientation=globalFrame,
            forwardProgression=forwardProgression).compute(
                pointLabelSuffix="cgm1_6dof")

        # testing
        np.testing.assert_equal(longitudinalAxis, "X")
        np.testing.assert_equal(forwardProgression, False)
        np.testing.assert_equal(globalFrame, "XYZ")

        #plot("LNeckAngles",acqGait,"cgm1_6dof")

        # relative angles
        np.testing.assert_almost_equal(
            acqGait.GetPoint("RSpineAngles").GetValues(),
            acqGait.GetPoint("RSpineAngles_cgm1_6dof").GetValues(),
            decimal=2)
        np.testing.assert_almost_equal(
            acqGait.GetPoint("LSpineAngles").GetValues(),
            acqGait.GetPoint("LSpineAngles_cgm1_6dof").GetValues(),
            decimal=2)

        np.testing.assert_almost_equal(
            acqGait.GetPoint("LShoulderAngles").GetValues(),
            acqGait.GetPoint("LShoulderAngles_cgm1_6dof").GetValues(),
            decimal=3)
        np.testing.assert_almost_equal(
            acqGait.GetPoint("RShoulderAngles").GetValues(),
            acqGait.GetPoint("RShoulderAngles_cgm1_6dof").GetValues(),
            decimal=3)

        np.testing.assert_almost_equal(
            acqGait.GetPoint("RElbowAngles").GetValues(),
            acqGait.GetPoint("RElbowAngles_cgm1_6dof").GetValues(),
            decimal=3)
        np.testing.assert_almost_equal(
            acqGait.GetPoint("LElbowAngles").GetValues(),
            acqGait.GetPoint("LElbowAngles_cgm1_6dof").GetValues(),
            decimal=3)

        # np.testing.assert_almost_equal( acqGait.GetPoint("RWristAngles").GetValues(),
        #                             acqGait.GetPoint("RWristAngles_cgm1_6dof").GetValues(), decimal =3) # fail on transverse
        # np.testing.assert_almost_equal( acqGait.GetPoint("LWristAngles").GetValues(),
        #                             acqGait.GetPoint("LWristAngles_cgm1_6dof").GetValues(), decimal =3)# fail on transverse
        #
        # np.testing.assert_almost_equal( acqGait.GetPoint("RNeckAngles").GetValues(),
        #                             acqGait.GetPoint("RNeckAngles_cgm1_6dof").GetValues(), decimal =1) # fail on coronal
        # np.testing.assert_almost_equal( acqGait.GetPoint("LNeckAngles").GetValues(),
        #                             acqGait.GetPoint("LNeckAngles_cgm1_6dof").GetValues(), decimal =1) # fail on coronal

        # absolute angles
        np.testing.assert_almost_equal(
            acqGait.GetPoint("LThoraxAngles").GetValues(),
            acqGait.GetPoint("LThoraxAngles_cgm1_6dof").GetValues(),
            decimal=3)
        np.testing.assert_almost_equal(
            acqGait.GetPoint("RThoraxAngles").GetValues(),
            acqGait.GetPoint("RThoraxAngles_cgm1_6dof").GetValues(),
            decimal=3)

        btkTools.smartWriter(acqStatic, "FullBody_Angles_CGM1_fullbody.c3d")
Пример #11
0
    def CGM1_fullbody(cls):

        MAIN_PATH = pyCGM2.TEST_DATA_PATH + "CGM1\\CGM1-TESTS\\Full PIG - StephenL5_C7\\"
        staticFilename = "PN01NORMSTAT.c3d"

        # CALIBRATION ###############################
        acqStatic = btkTools.smartReader(str(MAIN_PATH + staticFilename))

        markerDiameter = 14

        # Lower Limb
        mp = {
            'Bodymass': 83,
            'LeftLegLength': 874,
            'RightLegLength': 876.0,
            'LeftKneeWidth': 106.0,
            'RightKneeWidth': 103.0,
            'LeftAnkleWidth': 74.0,
            'RightAnkleWidth': 72.0,
            'LeftSoleDelta': 0,
            'RightSoleDelta': 0,
            'LeftShoulderOffset': 50,
            'LeftElbowWidth': 91,
            'LeftWristWidth': 56,
            'LeftHandThickness': 28,
            'RightShoulderOffset': 45,
            'RightElbowWidth': 90,
            'RightWristWidth': 55,
            'RightHandThickness': 30
        }

        model = cgm.CGM1()
        model.configure(bodyPart=enums.BodyPart.FullBody)
        model.addAnthropoInputParameters(mp)

        scp = modelFilters.StaticCalibrationProcedure(
            model)  # load calibration procedure
        csp = modelFilters.ModelCoordinateSystemProcedure(model)

        modelFilters.ModelCalibrationFilter(
            scp,
            acqStatic,
            model,
            leftFlatFoot=False,
            rightFlatFoot=False,
            markerDiameter=14,
            viconCGM1compatible=True,
        ).compute()
        #headHorizontal=True

        # --- motion ----
        gaitFilename = "PN01NORMSS01_stephen.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()

        # TESTING
        #   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)

        btkTools.smartWriter(acqStatic, "FullBody_motion_CGM1_fullbody.c3d")