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 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 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")
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")
def calibrate(DATA_PATH, calibrateFilenameLabelled, translators, required_mp, optional_mp, leftFlatFoot, rightFlatFoot, headFlat, markerDiameter, pointSuffix, **kwargs): """ Calibration of the CGM1 :param DATA_PATH [str]: path to your data :param calibrateFilenameLabelled [str]: c3d file :param translators [dict]: translators to apply :param required_mp [dict]: required anthropometric data :param optional_mp [dict]: optional anthropometric data (ex: LThighOffset,...) :param leftFlatFoot [bool]: enable of the flat foot option for the left foot :param rightFlatFoot [bool]: enable of the flat foot option for the right foot :param headFlat [bool]: enable of the head flat option :param markerDiameter [double]: marker diameter (mm) :param pointSuffix [str]: suffix to add to model outputs """ # --------------------------ACQUISITION ------------------------------------ if "forceBtkAcq" in kwargs.keys(): acqStatic = kwargs["forceBtkAcq"] else: # ---btk acquisition--- acqStatic = btkTools.smartReader( str(DATA_PATH + calibrateFilenameLabelled)) btkTools.checkMultipleSubject(acqStatic) acqStatic = btkTools.applyTranslators(acqStatic, translators) # ---check marker set used---- dcm = cgm.CGM.detectCalibrationMethods(acqStatic) # ---definition--- model = cgm.CGM1() model.configure(acq=acqStatic, detectedCalibrationMethods=dcm) model.addAnthropoInputParameters(required_mp, optional=optional_mp) # --store calibration parameters-- model.setStaticFilename(calibrateFilenameLabelled) model.setCalibrationProperty("leftFlatFoot", leftFlatFoot) model.setCalibrationProperty("rightFlatFoot", rightFlatFoot) model.setCalibrationProperty("headFlat", headFlat) model.setCalibrationProperty("markerDiameter", markerDiameter) # --------------------------STATIC CALBRATION-------------------------- scp = modelFilters.StaticCalibrationProcedure( model) # load calibration procedure # ---initial calibration filter---- modelFilters.ModelCalibrationFilter(scp, acqStatic, model, leftFlatFoot=leftFlatFoot, rightFlatFoot=rightFlatFoot, markerDiameter=markerDiameter, headFlat=headFlat, viconCGM1compatible=True).compute() # ---- Decorators ----- decorators.applyBasicDecorators(dcm, model, acqStatic, optional_mp, markerDiameter, cgm1only=True) pigStaticMarkers = cgm.CGM.get_markerLabelForPiGStatic(dcm) # ----Final Calibration filter if model previously decorated ----- if model.decoratedModel: # initial static filter modelFilters.ModelCalibrationFilter( scp, acqStatic, model, leftFlatFoot=leftFlatFoot, rightFlatFoot=rightFlatFoot, headFlat=headFlat, markerDiameter=markerDiameter, viconCGM1compatible=True).compute() # ----------------------CGM MODELLING---------------------------------- # ----motion filter---- # notice : viconCGM1compatible option duplicate error on Construction of the foot coordinate system modMotion = modelFilters.ModelMotionFilter( scp, acqStatic, model, enums.motionMethod.Determinist, markerDiameter=markerDiameter, viconCGM1compatible=False, pigStatic=True, useLeftKJCmarker=pigStaticMarkers[0], useLeftAJCmarker=pigStaticMarkers[1], useRightKJCmarker=pigStaticMarkers[2], useRightAJCmarker=pigStaticMarkers[3]) modMotion.compute() if "displayCoordinateSystem" in kwargs.keys( ) and kwargs["displayCoordinateSystem"]: csp = modelFilters.ModelCoordinateSystemProcedure(model) csdf = modelFilters.CoordinateSystemDisplayFilter( csp, model, acqStatic) csdf.setStatic(False) csdf.display() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model, acqStatic).compute( description="vectoriel", pointLabelSuffix=pointSuffix) # detection of traveling axis + absolute angle if model.m_bodypart != enums.BodyPart.UpperLimb: longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromPelvicMarkers( acqStatic, ["LASI", "LPSI", "RASI", "RPSI"]) else: longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromLongAxis( acqStatic, "C7", "CLAV") if model.m_bodypart != enums.BodyPart.UpperLimb: modelFilters.ModelAbsoluteAnglesFilter( model, acqStatic, segmentLabels=["Left Foot", "Right Foot", "Pelvis"], angleLabels=["LFootProgress", "RFootProgress", "Pelvis"], eulerSequences=["TOR", "TOR", "TOR"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.LowerLimbTrunk: modelFilters.ModelAbsoluteAnglesFilter( model, acqStatic, segmentLabels=["Thorax"], angleLabels=["Thorax"], eulerSequences=["YXZ"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.UpperLimb or model.m_bodypart == enums.BodyPart.FullBody: modelFilters.ModelAbsoluteAnglesFilter( model, acqStatic, segmentLabels=["Thorax", "Head"], angleLabels=["Thorax", "Head"], eulerSequences=["YXZ", "TOR"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) # BSP model bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() if model.m_bodypart == enums.BodyPart.FullBody: modelFilters.CentreOfMassFilter( model, acqStatic).compute(pointLabelSuffix=pointSuffix) return model, acqStatic
def 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")
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
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")
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")
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")
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")