def fitting(model,DATA_PATH, reconstructFilenameLabelled, translators,weights, ik_flag,markerDiameter, pointSuffix, mfpa, momentProjection,**kwargs): """ Fitting of the CGM2.3 :param model [str]: pyCGM2 model previously calibrated :param DATA_PATH [str]: path to your data :param reconstructFilenameLabelled [string list]: c3d files :param translators [dict]: translators to apply :param ik_flag [bool]: enable the inverse kinematic solver :param mfpa [str]: manual force plate assignement :param markerDiameter [double]: marker diameter (mm) :param pointSuffix [str]: suffix to add to model outputs :param momentProjection [str]: Coordinate system in which joint moment is expressed """ if "Fitting" in weights.keys(): weights = weights["Fitting"]["Weight"] # --------------------------ACQ WITH TRANSLATORS -------------------------------------- # --- btk acquisition ---- if "forceBtkAcq" in kwargs.keys(): acqGait = kwargs["forceBtkAcq"] else: acqGait = btkTools.smartReader((DATA_PATH + reconstructFilenameLabelled)) btkTools.checkMultipleSubject(acqGait) if btkTools.isPointExist(acqGait,"SACR"): translators["LPSI"] = "SACR" translators["RPSI"] = "SACR" logging.info("[pyCGM2] Sacrum marker detected") acqGait = btkTools.applyTranslators(acqGait,translators) trackingMarkers = model.getTrackingMarkers(acqGait) validFrames,vff,vlf = btkTools.findValidFrames(acqGait,trackingMarkers) # filtering # ----------------------- if "fc_lowPass_marker" in kwargs.keys() and kwargs["fc_lowPass_marker"]!=0 : fc = kwargs["fc_lowPass_marker"] order = 4 if "order_lowPass_marker" in kwargs.keys(): order = kwargs["order_lowPass_marker"] signal_processing.markerFiltering(acqGait,trackingMarkers,order=order, fc =fc) if "fc_lowPass_forcePlate" in kwargs.keys() and kwargs["fc_lowPass_forcePlate"]!=0 : fc = kwargs["fc_lowPass_forcePlate"] order = 4 if "order_lowPass_forcePlate" in kwargs.keys(): order = kwargs["order_lowPass_forcePlate"] signal_processing.forcePlateFiltering(acqGait,order=order, fc =fc) # --- initial motion Filter --- scp=modelFilters.StaticCalibrationProcedure(model) # section to remove : - copy motion of ProximalShank from Shank with Sodervisk modMotion=modelFilters.ModelMotionFilter(scp,acqGait,model,enums.motionMethod.Sodervisk) modMotion.compute() # /section to remove 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 tl 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) ) logging.info("-------INVERSE KINEMATICS IN PROGRESS----------") acqIK = osrf.run(acqGait,(DATA_PATH + reconstructFilenameLabelled )) logging.info("-------INVERSE KINEMATICS DONE-----------------") # eventual gait acquisition to consider for joint kinematics finalAcqGait = acqIK if ik_flag else acqGait # --- final pyCGM2 model motion Filter --- # use fitted markers modMotionFitted=modelFilters.ModelMotionFilter(scp,finalAcqGait,model,enums.motionMethod.Sodervisk , markerDiameter=markerDiameter) modMotionFitted.compute() if "displayCoordinateSystem" in kwargs.keys() and kwargs["displayCoordinateSystem"]: csp = modelFilters.ModelCoordinateSystemProcedure(model) csdf = modelFilters.CoordinateSystemDisplayFilter(csp,model,finalAcqGait) csdf.setStatic(False) csdf.display() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model,finalAcqGait).compute(description="vectoriel", pointLabelSuffix=pointSuffix) # detection of traveling axis + absolute angle if model.m_bodypart != enums.BodyPart.UpperLimb: pfp = progressionFrame.PelvisProgressionFrameProcedure() else: pfp = progressionFrame.ThoraxProgressionFrameProcedure() pff = progressionFrame.ProgressionFrameFilter(finalAcqGait,pfp) pff.compute() globalFrame = pff.outputs["globalFrame"] forwardProgression = pff.outputs["forwardProgression"] if model.m_bodypart != enums.BodyPart.UpperLimb: modelFilters.ModelAbsoluteAnglesFilter(model,finalAcqGait, segmentLabels=["Left Foot","Right Foot","Pelvis"], angleLabels=["LFootProgress", "RFootProgress","Pelvis"], eulerSequences=["TOR","TOR", "ROT"], globalFrameOrientation = globalFrame, forwardProgression = forwardProgression).compute(pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.LowerLimbTrunk: modelFilters.ModelAbsoluteAnglesFilter(model,finalAcqGait, segmentLabels=["Thorax"], angleLabels=["Thorax"], eulerSequences=["YXZ"], globalFrameOrientation = globalFrame, forwardProgression = forwardProgression).compute(pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.UpperLimb or model.m_bodypart == enums.BodyPart.FullBody: modelFilters.ModelAbsoluteAnglesFilter(model,finalAcqGait, segmentLabels=["Thorax","Head"], angleLabels=["Thorax", "Head"], eulerSequences=["YXZ","TOR"], globalFrameOrientation = globalFrame, forwardProgression = forwardProgression).compute(pointLabelSuffix=pointSuffix) #---- Body segment parameters---- bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() if model.m_bodypart == enums.BodyPart.FullBody: modelFilters.CentreOfMassFilter(model,finalAcqGait).compute(pointLabelSuffix=pointSuffix) # Inverse dynamics if btkTools.checkForcePlateExist(acqGait): if model.m_bodypart != enums.BodyPart.UpperLimb: # --- force plate handling---- # find foot in contact mappedForcePlate = forceplates.matchingFootSideOnForceplate(finalAcqGait,mfpa=mfpa) forceplates.addForcePlateGeneralEvents(finalAcqGait,mappedForcePlate) logging.warning("Manual Force plate assignment : %s" %mappedForcePlate) # assembly foot and force plate modelFilters.ForcePlateAssemblyFilter(model,finalAcqGait,mappedForcePlate, leftSegmentLabel="Left Foot", rightSegmentLabel="Right Foot").compute(pointLabelSuffix=pointSuffix) #---- Joint kinetics---- idp = modelFilters.CGMLowerlimbInverseDynamicProcedure() modelFilters.InverseDynamicFilter(model, finalAcqGait, procedure = idp, projection = momentProjection, globalFrameOrientation = globalFrame, forwardProgression = forwardProgression ).compute(pointLabelSuffix=pointSuffix) #---- Joint energetics---- modelFilters.JointPowerFilter(model,finalAcqGait).compute(pointLabelSuffix=pointSuffix) #---- zero unvalid frames --- btkTools.applyValidFramesOnOutput(finalAcqGait,validFrames) return finalAcqGait
def fitting(model, DATA_PATH, reconstructFilenameLabelled, translators, markerDiameter, pointSuffix, mfpa, momentProjection, **kwargs): """ Fitting of the CGM1.1 :param model [str]: pyCGM2 model previously calibrated :param DATA_PATH [str]: path to your data :param reconstructFilenameLabelled [string list]: c3d files :param translators [dict]: translators to apply :param mfpa [str]: manual force plate assignement :param markerDiameter [double]: marker diameter (mm) :param pointSuffix [str]: suffix to add to model outputs :param momentProjection [str]: Coordinate system in which joint moment is expressed """ # --------------------------ACQUISITION ------------------------------------ # --- btk acquisition ---- if "forceBtkAcq" in kwargs.keys(): acqGait = kwargs["forceBtkAcq"] else: acqGait = btkTools.smartReader( (DATA_PATH + reconstructFilenameLabelled)) btkTools.checkMultipleSubject(acqGait) if btkTools.isPointExist(acqGait, "SACR"): translators["LPSI"] = "SACR" translators["RPSI"] = "SACR" logging.info("[pyCGM2] Sacrum marker detected") acqGait = btkTools.applyTranslators(acqGait, translators) trackingMarkers = model.getTrackingMarkers(acqGait) validFrames, vff, vlf = btkTools.findValidFrames(acqGait, trackingMarkers) # filtering # ----------------------- if "fc_lowPass_marker" in kwargs.keys( ) and kwargs["fc_lowPass_marker"] != 0: fc = kwargs["fc_lowPass_marker"] order = 4 if "order_lowPass_marker" in kwargs.keys(): order = kwargs["order_lowPass_marker"] signal_processing.markerFiltering(acqGait, trackingMarkers, order=order, fc=fc) if "fc_lowPass_forcePlate" in kwargs.keys( ) and kwargs["fc_lowPass_forcePlate"] != 0: fc = kwargs["fc_lowPass_forcePlate"] order = 4 if "order_lowPass_forcePlate" in kwargs.keys(): order = kwargs["order_lowPass_forcePlate"] signal_processing.forcePlateFiltering(acqGait, order=order, fc=fc) scp = modelFilters.StaticCalibrationProcedure(model) # procedure # ---Motion filter---- modMotion = modelFilters.ModelMotionFilter(scp, acqGait, 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, acqGait) csdf.setStatic(False) csdf.display() if "NaimKneeCorrection" in kwargs.keys() and kwargs["NaimKneeCorrection"]: # Apply Naim 2019 method if type(kwargs["NaimKneeCorrection"]) is float: nmacp = modelFilters.Naim2019ThighMisaligmentCorrectionProcedure( model, "Both", threshold=(kwargs["NaimKneeCorrection"])) else: nmacp = modelFilters.Naim2019ThighMisaligmentCorrectionProcedure( model, "Both") mmcf = modelFilters.ModelMotionCorrectionFilter(nmacp) mmcf.correct() # btkTools.smartAppendPoint(acqGait,"LNaim",mmcf.m_procedure.m_virtual["Left"]) # btkTools.smartAppendPoint(acqGait,"RNaim",mmcf.m_procedure.m_virtual["Right"]) #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model, acqGait).compute(description="vectoriel", pointLabelSuffix=pointSuffix) # detection of traveling axis + absolute angle if model.m_bodypart != enums.BodyPart.UpperLimb: pfp = progressionFrame.PelvisProgressionFrameProcedure() else: pfp = progressionFrame.ThoraxProgressionFrameProcedure() pff = progressionFrame.ProgressionFrameFilter(acqGait, pfp) pff.compute() globalFrame = pff.outputs["globalFrame"] forwardProgression = pff.outputs["forwardProgression"] if model.m_bodypart != enums.BodyPart.UpperLimb: modelFilters.ModelAbsoluteAnglesFilter( model, acqGait, segmentLabels=["Left Foot", "Right Foot", "Pelvis"], angleLabels=["LFootProgress", "RFootProgress", "Pelvis"], eulerSequences=["TOR", "TOR", "ROT"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.LowerLimbTrunk: modelFilters.ModelAbsoluteAnglesFilter( model, acqGait, segmentLabels=["Thorax"], angleLabels=["Thorax"], eulerSequences=["YXZ"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.UpperLimb or model.m_bodypart == enums.BodyPart.FullBody: modelFilters.ModelAbsoluteAnglesFilter( model, acqGait, segmentLabels=["Thorax", "Head"], angleLabels=["Thorax", "Head"], eulerSequences=["YXZ", "TOR"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) #---- Body segment parameters---- bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() if model.m_bodypart == enums.BodyPart.FullBody: modelFilters.CentreOfMassFilter( model, acqGait).compute(pointLabelSuffix=pointSuffix) # Inverse dynamics if btkTools.checkForcePlateExist(acqGait): if model.m_bodypart != enums.BodyPart.UpperLimb: # --- force plate handling---- # find foot in contact mappedForcePlate = forceplates.matchingFootSideOnForceplate( acqGait, mfpa=mfpa) forceplates.addForcePlateGeneralEvents(acqGait, mappedForcePlate) logging.warning("Manual Force plate assignment : %s" % mappedForcePlate) # assembly foot and force plate modelFilters.ForcePlateAssemblyFilter( model, acqGait, mappedForcePlate, leftSegmentLabel="Left Foot", rightSegmentLabel="Right Foot").compute( pointLabelSuffix=pointSuffix) #---- Joint kinetics---- idp = modelFilters.CGMLowerlimbInverseDynamicProcedure() modelFilters.InverseDynamicFilter( model, acqGait, procedure=idp, projection=momentProjection, globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) #---- Joint energetics---- modelFilters.JointPowerFilter( model, acqGait).compute(pointLabelSuffix=pointSuffix) #---- zero unvalid frames --- btkTools.applyValidFramesOnOutput(acqGait, validFrames) return acqGait
def fitting(model,DATA_PATH, reconstructFilenameLabelled, translators,settings, ik_flag,markerDiameter, pointSuffix, mfpa, momentProjection): # --- btk acquisition ---- acqGait = btkTools.smartReader(str(DATA_PATH + reconstructFilenameLabelled)) btkTools.checkMultipleSubject(acqGait) acqGait = btkTools.applyTranslators(acqGait,translators) validFrames,vff,vlf = btkTools.findValidFrames(acqGait,cgm2.CGM2_4LowerLimbs.TRACKING_MARKERS) # --- initial motion Filter --- scp=modelFilters.StaticCalibrationProcedure(model) modMotion=modelFilters.ModelMotionFilter(scp,acqGait,model,enums.motionMethod.Sodervisk) modMotion.compute() if ik_flag: # ---OPENSIM IK--- # --- opensim calibration Filter --- osimfile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\osim\\lowerLimb_ballsJoints.osim" # osimfile markersetFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_4\\cgm2_4-markerset.xml" # markerset cgmCalibrationprocedure = opensimFilters.CgmOpensimCalibrationProcedures(model) # procedure oscf = opensimFilters.opensimCalibrationFilter(osimfile, model, cgmCalibrationprocedure, str(DATA_PATH)) oscf.addMarkerSet(markersetFile) scalingOsim = oscf.build() # --- opensim Fitting Filter --- iksetupFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_4\\cgm2_4-ikSetUp_template.xml" # ik tl file cgmFittingProcedure = opensimFilters.CgmOpensimFittingProcedure(model) # procedure cgmFittingProcedure.updateMarkerWeight("LASI",settings["Fitting"]["Weight"]["LASI"]) cgmFittingProcedure.updateMarkerWeight("RASI",settings["Fitting"]["Weight"]["RASI"]) cgmFittingProcedure.updateMarkerWeight("LPSI",settings["Fitting"]["Weight"]["LPSI"]) cgmFittingProcedure.updateMarkerWeight("RPSI",settings["Fitting"]["Weight"]["RPSI"]) cgmFittingProcedure.updateMarkerWeight("RTHI",settings["Fitting"]["Weight"]["RTHI"]) cgmFittingProcedure.updateMarkerWeight("RKNE",settings["Fitting"]["Weight"]["RKNE"]) cgmFittingProcedure.updateMarkerWeight("RTIB",settings["Fitting"]["Weight"]["RTIB"]) cgmFittingProcedure.updateMarkerWeight("RANK",settings["Fitting"]["Weight"]["RANK"]) cgmFittingProcedure.updateMarkerWeight("RHEE",settings["Fitting"]["Weight"]["RHEE"]) cgmFittingProcedure.updateMarkerWeight("RTOE",settings["Fitting"]["Weight"]["RTOE"]) cgmFittingProcedure.updateMarkerWeight("LTHI",settings["Fitting"]["Weight"]["LTHI"]) cgmFittingProcedure.updateMarkerWeight("LKNE",settings["Fitting"]["Weight"]["LKNE"]) cgmFittingProcedure.updateMarkerWeight("LTIB",settings["Fitting"]["Weight"]["LTIB"]) cgmFittingProcedure.updateMarkerWeight("LANK",settings["Fitting"]["Weight"]["LANK"]) cgmFittingProcedure.updateMarkerWeight("LHEE",settings["Fitting"]["Weight"]["LHEE"]) cgmFittingProcedure.updateMarkerWeight("LTOE",settings["Fitting"]["Weight"]["LTOE"]) cgmFittingProcedure.updateMarkerWeight("LTHAP",settings["Fitting"]["Weight"]["LTHAP"]) cgmFittingProcedure.updateMarkerWeight("LTHAD",settings["Fitting"]["Weight"]["LTHAD"]) cgmFittingProcedure.updateMarkerWeight("LTIAP",settings["Fitting"]["Weight"]["LTIAP"]) cgmFittingProcedure.updateMarkerWeight("LTIAD",settings["Fitting"]["Weight"]["LTIAD"]) cgmFittingProcedure.updateMarkerWeight("RTHAP",settings["Fitting"]["Weight"]["RTHAP"]) cgmFittingProcedure.updateMarkerWeight("RTHAD",settings["Fitting"]["Weight"]["RTHAD"]) cgmFittingProcedure.updateMarkerWeight("RTIAP",settings["Fitting"]["Weight"]["RTIAP"]) cgmFittingProcedure.updateMarkerWeight("RTIAD",settings["Fitting"]["Weight"]["RTIAD"]) cgmFittingProcedure.updateMarkerWeight("LSMH",settings["Fitting"]["Weight"]["LSMH"]) cgmFittingProcedure.updateMarkerWeight("LFMH",settings["Fitting"]["Weight"]["LFMH"]) cgmFittingProcedure.updateMarkerWeight("LVMH",settings["Fitting"]["Weight"]["LVMH"]) cgmFittingProcedure.updateMarkerWeight("RSMH",settings["Fitting"]["Weight"]["RSMH"]) cgmFittingProcedure.updateMarkerWeight("RFMH",settings["Fitting"]["Weight"]["RFMH"]) cgmFittingProcedure.updateMarkerWeight("RVMH",settings["Fitting"]["Weight"]["RVMH"]) # cgmFittingProcedure.updateMarkerWeight("LTHL",settings["Fitting"]["Weight"]["LTHL"]) # cgmFittingProcedure.updateMarkerWeight("LTHLD",settings["Fitting"]["Weight"]["LTHLD"]) # cgmFittingProcedure.updateMarkerWeight("LPAT",settings["Fitting"]["Weight"]["LPAT"]) # cgmFittingProcedure.updateMarkerWeight("LTIBL",settings["Fitting"]["Weight"]["LTIBL"]) # cgmFittingProcedure.updateMarkerWeight("RTHL",settings["Fitting"]["Weight"]["RTHL"]) # cgmFittingProcedure.updateMarkerWeight("RTHLD",settings["Fitting"]["Weight"]["RTHLD"]) # cgmFittingProcedure.updateMarkerWeight("RPAT",settings["Fitting"]["Weight"]["RPAT"]) # cgmFittingProcedure.updateMarkerWeight("RTIBL",settings["Fitting"]["Weight"]["RTIBL"]) osrf = opensimFilters.opensimFittingFilter(iksetupFile, scalingOsim, cgmFittingProcedure, str(DATA_PATH) ) logging.info("-------INVERSE KINEMATICS IN PROGRESS----------") acqIK = osrf.run(acqGait,str(DATA_PATH + reconstructFilenameLabelled )) logging.info("-------INVERSE KINEMATICS DONE-----------------") # eventual gait acquisition to consider for joint kinematics finalAcqGait = acqIK if ik_flag else acqGait # --- final pyCGM2 model motion Filter --- # use fitted markers modMotionFitted=modelFilters.ModelMotionFilter(scp,finalAcqGait,model,enums.motionMethod.Sodervisk , markerDiameter=markerDiameter) modMotionFitted.compute() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model,finalAcqGait).compute(description="vectoriel", pointLabelSuffix=pointSuffix) # detection of traveling axis longitudinalAxis,forwardProgression,globalFrame = btkTools.findProgressionAxisFromPelvicMarkers(finalAcqGait,["LASI","LPSI","RASI","RPSI"]) # absolute angles modelFilters.ModelAbsoluteAnglesFilter(model,finalAcqGait, segmentLabels=["Left Foot","Right Foot","Pelvis"], angleLabels=["LFootProgress", "RFootProgress","Pelvis"], eulerSequences=["TOR","TOR", "ROT"], globalFrameOrientation = globalFrame, forwardProgression = forwardProgression).compute(pointLabelSuffix=pointSuffix) #---- Body segment parameters---- bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() # --- force plate handling---- # find foot in contact mappedForcePlate = forceplates.matchingFootSideOnForceplate(finalAcqGait) forceplates.addForcePlateGeneralEvents(finalAcqGait,mappedForcePlate) logging.info("Force plate assignment : %s" %mappedForcePlate) if mfpa is not None: if len(mfpa) != len(mappedForcePlate): raise Exception("[pyCGM2] manual force plate assignment badly sets. Wrong force plate number. %s force plate require" %(str(len(mappedForcePlate)))) else: mappedForcePlate = mfpa forceplates.addForcePlateGeneralEvents(finalAcqGait,mappedForcePlate) logging.warning("Manual Force plate assignment : %s" %mappedForcePlate) # assembly foot and force plate modelFilters.ForcePlateAssemblyFilter(model,finalAcqGait,mappedForcePlate, leftSegmentLabel="Left Foot", rightSegmentLabel="Right Foot").compute() #---- Joint kinetics---- idp = modelFilters.CGMLowerlimbInverseDynamicProcedure() modelFilters.InverseDynamicFilter(model, finalAcqGait, procedure = idp, projection = momentProjection ).compute(pointLabelSuffix=pointSuffix) #---- Joint energetics---- modelFilters.JointPowerFilter(model,finalAcqGait).compute(pointLabelSuffix=pointSuffix) #---- zero unvalid frames --- btkTools.applyValidFramesOnOutput(finalAcqGait,validFrames) return finalAcqGait
def fitting(model, DATA_PATH, reconstructFilenameLabelled, translators, markerDiameter, pointSuffix, mfpa, momentProjection): # --------------------------ACQUISITION ------------------------------------ # --- btk acquisition ---- acqGait = btkTools.smartReader(str(DATA_PATH + reconstructFilenameLabelled)) btkTools.checkMultipleSubject(acqGait) acqGait = btkTools.applyTranslators(acqGait, translators) validFrames, vff, vlf = btkTools.findValidFrames( acqGait, cgm.CGM1LowerLimbs.TRACKING_MARKERS) scp = modelFilters.StaticCalibrationProcedure(model) # ---Motion filter---- modMotion = modelFilters.ModelMotionFilter(scp, acqGait, model, enums.motionMethod.Determinist, markerDiameter=markerDiameter) modMotion.compute() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model, acqGait).compute(description="vectoriel", pointLabelSuffix=pointSuffix) # detection of traveling axis longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromPelvicMarkers( acqGait, ["LASI", "LPSI", "RASI", "RPSI"]) # absolute angles modelFilters.ModelAbsoluteAnglesFilter( model, acqGait, segmentLabels=["Left Foot", "Right Foot", "Pelvis"], angleLabels=["LFootProgress", "RFootProgress", "Pelvis"], eulerSequences=["TOR", "TOR", "ROT"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) #---- Body segment parameters---- bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() # --- force plate handling---- # find foot in contact mappedForcePlate = forceplates.matchingFootSideOnForceplate(acqGait) forceplates.addForcePlateGeneralEvents(acqGait, mappedForcePlate) logging.info("Automatic Force plate assignment : %s" % mappedForcePlate) if mfpa is not None: if len(mfpa) != len(mappedForcePlate): raise Exception( "[pyCGM2] manual force plate assignment badly sets. Wrong force plate number. %s force plate require" % (str(len(mappedForcePlate)))) else: mappedForcePlate = mfpa forceplates.addForcePlateGeneralEvents(acqGait, mappedForcePlate) logging.warning("Manual Force plate assignment : %s" % mappedForcePlate) # assembly foot and force plate modelFilters.ForcePlateAssemblyFilter( model, acqGait, mappedForcePlate, leftSegmentLabel="Left Foot", rightSegmentLabel="Right Foot").compute() #---- Joint kinetics---- idp = modelFilters.CGMLowerlimbInverseDynamicProcedure() modelFilters.InverseDynamicFilter( model, acqGait, procedure=idp, projection=momentProjection).compute(pointLabelSuffix=pointSuffix) #---- Joint energetics---- modelFilters.JointPowerFilter( model, acqGait).compute(pointLabelSuffix=pointSuffix) #---- zero unvalid frames --- btkTools.applyValidFramesOnOutput(acqGait, validFrames) return acqGait
def fitting(model, DATA_PATH, reconstructFilenameLabelled, translators, markerDiameter, pointSuffix, mfpa, momentProjection, **kwargs): """ Fitting of the CGM1 :param model [str]: pyCGM2 model previously calibrated :param DATA_PATH [str]: path to your data :param reconstructFilenameLabelled [string list]: c3d files :param translators [dict]: translators to apply :param mfpa [str]: manual force plate assignement :param markerDiameter [double]: marker diameter (mm) :param pointSuffix [str]: suffix to add to model outputs :param momentProjection [str]: Coordinate system in which joint moment is expressed """ # --------------------------ACQUISITION ------------------------------------ if "forceBtkAcq" in kwargs.keys(): acqGait = kwargs["forceBtkAcq"] else: # --- btk acquisition ---- acqGait = btkTools.smartReader( str(DATA_PATH + reconstructFilenameLabelled)) btkTools.checkMultipleSubject(acqGait) acqGait = btkTools.applyTranslators(acqGait, translators) trackingMarkers = model.getTrackingMarkers() validFrames, vff, vlf = btkTools.findValidFrames(acqGait, trackingMarkers) scp = modelFilters.StaticCalibrationProcedure(model) # procedure # ---Motion filter---- modMotion = modelFilters.ModelMotionFilter(scp, acqGait, model, enums.motionMethod.Determinist, markerDiameter=markerDiameter, viconCGM1compatible=True) modMotion.compute() if "displayCoordinateSystem" in kwargs.keys( ) and kwargs["displayCoordinateSystem"]: csp = modelFilters.ModelCoordinateSystemProcedure(model) csdf = modelFilters.CoordinateSystemDisplayFilter(csp, model, acqGait) csdf.setStatic(False) csdf.display() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model, acqGait).compute(description="vectoriel", pointLabelSuffix=pointSuffix) # detection of traveling axis + absolute angle if model.m_bodypart != enums.BodyPart.UpperLimb: longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromPelvicMarkers( acqGait, ["LASI", "LPSI", "RASI", "RPSI"]) else: longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromLongAxis( acqGait, "C7", "CLAV") if model.m_bodypart != enums.BodyPart.UpperLimb: modelFilters.ModelAbsoluteAnglesFilter( model, acqGait, segmentLabels=["Left Foot", "Right Foot", "Pelvis"], angleLabels=["LFootProgress", "RFootProgress", "Pelvis"], eulerSequences=["TOR", "TOR", "TOR"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.LowerLimbTrunk: modelFilters.ModelAbsoluteAnglesFilter( model, acqGait, segmentLabels=["Thorax"], angleLabels=["Thorax"], eulerSequences=["YXZ"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.UpperLimb or model.m_bodypart == enums.BodyPart.FullBody: modelFilters.ModelAbsoluteAnglesFilter( model, acqGait, segmentLabels=["Thorax", "Head"], angleLabels=["Thorax", "Head"], eulerSequences=["YXZ", "TOR"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) #---- Body segment parameters---- bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() #---- CentreOfMass---- if model.m_bodypart == enums.BodyPart.FullBody: modelFilters.CentreOfMassFilter( model, acqGait).compute(pointLabelSuffix=pointSuffix) # Inverse dynamics if model.m_bodypart != enums.BodyPart.UpperLimb: # --- force plate handling---- # find foot in contact mappedForcePlate = forceplates.matchingFootSideOnForceplate(acqGait, mfpa=mfpa) forceplates.addForcePlateGeneralEvents(acqGait, mappedForcePlate) logging.warning("Manual Force plate assignment : %s" % mappedForcePlate) # assembly foot and force plate modelFilters.ForcePlateAssemblyFilter( model, acqGait, mappedForcePlate, leftSegmentLabel="Left Foot", rightSegmentLabel="Right Foot").compute() #---- Joint kinetics---- idp = modelFilters.CGMLowerlimbInverseDynamicProcedure() modelFilters.InverseDynamicFilter( model, acqGait, procedure=idp, projection=momentProjection, viconCGM1compatible=True).compute(pointLabelSuffix=pointSuffix) #---- Joint energetics---- modelFilters.JointPowerFilter( model, acqGait).compute(pointLabelSuffix=pointSuffix) #---- zero unvalid frames --- btkTools.applyValidFramesOnOutput(acqGait, validFrames) return acqGait
def fitting(model, DATA_PATH, reconstructFilenameLabelled, translators, settings, markerDiameter, pointSuffix, mfpa, momentProjection, **kwargs): """ Fitting of the CGM2.2 :param model [str]: pyCGM2 model previously calibrated :param DATA_PATH [str]: path to your data :param reconstructFilenameLabelled [string list]: c3d files :param translators [dict]: translators to apply :param mfpa [str]: manual force plate assignement :param markerDiameter [double]: marker diameter (mm) :param pointSuffix [str]: suffix to add to model outputs :param momentProjection [str]: Coordinate system in which joint moment is expressed """ # --------------------------ACQUISITION ------------------------------------ # --- btk acquisition ---- if "forceBtkAcq" in kwargs.keys(): acqGait = kwargs["forceBtkAcq"] else: acqGait = btkTools.smartReader( str(DATA_PATH + reconstructFilenameLabelled)) btkTools.checkMultipleSubject(acqGait) acqGait = btkTools.applyTranslators(acqGait, translators) trackingMarkers = model.getTrackingMarkers() validFrames, vff, vlf = btkTools.findValidFrames(acqGait, trackingMarkers) # --- initial motion Filter --- scp = modelFilters.StaticCalibrationProcedure(model) modMotion = modelFilters.ModelMotionFilter(scp, acqGait, model, enums.motionMethod.Determinist) modMotion.compute() # ---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\\cgm1\\cgm1-markerset.xml" # markerset cgmCalibrationprocedure = opensimFilters.CgmOpensimCalibrationProcedures( model) # procedure oscf = opensimFilters.opensimCalibrationFilter(osimfile, model, cgmCalibrationprocedure, str(DATA_PATH)) oscf.addMarkerSet(markersetFile) scalingOsim = oscf.build() # --- opensim Fitting Filter --- iksetupFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm1\\cgm1-ikSetUp_template.xml" # ik tool file cgmFittingProcedure = opensimFilters.CgmOpensimFittingProcedure( model) # procedure cgmFittingProcedure.updateMarkerWeight( "LASI", settings["Fitting"]["Weight"]["LASI"]) cgmFittingProcedure.updateMarkerWeight( "RASI", settings["Fitting"]["Weight"]["RASI"]) cgmFittingProcedure.updateMarkerWeight( "LPSI", settings["Fitting"]["Weight"]["LPSI"]) cgmFittingProcedure.updateMarkerWeight( "RPSI", settings["Fitting"]["Weight"]["RPSI"]) cgmFittingProcedure.updateMarkerWeight( "RTHI", settings["Fitting"]["Weight"]["RTHI"]) cgmFittingProcedure.updateMarkerWeight( "RKNE", settings["Fitting"]["Weight"]["RKNE"]) cgmFittingProcedure.updateMarkerWeight( "RTIB", settings["Fitting"]["Weight"]["RTIB"]) cgmFittingProcedure.updateMarkerWeight( "RANK", settings["Fitting"]["Weight"]["RANK"]) cgmFittingProcedure.updateMarkerWeight( "RHEE", settings["Fitting"]["Weight"]["RHEE"]) cgmFittingProcedure.updateMarkerWeight( "RTOE", settings["Fitting"]["Weight"]["RTOE"]) cgmFittingProcedure.updateMarkerWeight( "LTHI", settings["Fitting"]["Weight"]["LTHI"]) cgmFittingProcedure.updateMarkerWeight( "LKNE", settings["Fitting"]["Weight"]["LKNE"]) cgmFittingProcedure.updateMarkerWeight( "LTIB", settings["Fitting"]["Weight"]["LTIB"]) cgmFittingProcedure.updateMarkerWeight( "LANK", settings["Fitting"]["Weight"]["LANK"]) cgmFittingProcedure.updateMarkerWeight( "LHEE", settings["Fitting"]["Weight"]["LHEE"]) cgmFittingProcedure.updateMarkerWeight( "LTOE", settings["Fitting"]["Weight"]["LTOE"]) osrf = opensimFilters.opensimFittingFilter(iksetupFile, scalingOsim, cgmFittingProcedure, str(DATA_PATH)) logging.info("-------INVERSE KINEMATICS IN PROGRESS----------") acqIK = osrf.run(acqGait, str(DATA_PATH + reconstructFilenameLabelled)) logging.info("-------INVERSE KINEMATICS DONE-----------------") # --- final pyCGM2 model motion Filter --- # use fitted markers modMotionFitted = modelFilters.ModelMotionFilter( scp, acqIK, model, enums.motionMethod.Determinist, markerDiameter=markerDiameter) modMotionFitted.compute() if "displayCoordinateSystem" in kwargs.keys( ) and kwargs["displayCoordinateSystem"]: csp = modelFilters.ModelCoordinateSystemProcedure(model) csdf = modelFilters.CoordinateSystemDisplayFilter(csp, model, acqIK) csdf.setStatic(False) csdf.display() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model, acqIK).compute(description="vectoriel", pointLabelSuffix=pointSuffix) # detection of traveling axis + absolute angle if model.m_bodypart != enums.BodyPart.UpperLimb: longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromPelvicMarkers( acqIK, ["LASI", "LPSI", "RASI", "RPSI"]) else: longitudinalAxis, forwardProgression, globalFrame = btkTools.findProgressionAxisFromLongAxis( acqIK, "C7", "CLAV") if model.m_bodypart != enums.BodyPart.UpperLimb: modelFilters.ModelAbsoluteAnglesFilter( model, acqIK, 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, acqIK, 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, acqIK, segmentLabels=["Thorax", "Head"], angleLabels=["Thorax", "Head"], eulerSequences=["YXZ", "TOR"], globalFrameOrientation=globalFrame, forwardProgression=forwardProgression).compute( pointLabelSuffix=pointSuffix) #---- Body segment parameters---- bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() if model.m_bodypart == enums.BodyPart.FullBody: modelFilters.CentreOfMassFilter( model, acqIK).compute(pointLabelSuffix=pointSuffix) # Inverse dynamics if model.m_bodypart != enums.BodyPart.UpperLimb: # --- force plate handling---- # find foot in contact mappedForcePlate = forceplates.matchingFootSideOnForceplate(acqIK, mfpa=mfpa) forceplates.addForcePlateGeneralEvents(acqIK, mappedForcePlate) logging.warning("Manual Force plate assignment : %s" % mappedForcePlate) # assembly foot and force plate modelFilters.ForcePlateAssemblyFilter( model, acqIK, mappedForcePlate, leftSegmentLabel="Left Foot", rightSegmentLabel="Right Foot").compute() #---- Joint kinetics---- idp = modelFilters.CGMLowerlimbInverseDynamicProcedure() modelFilters.InverseDynamicFilter( model, acqIK, procedure=idp, projection=momentProjection, ).compute(pointLabelSuffix=pointSuffix) #---- Joint energetics---- modelFilters.JointPowerFilter( model, acqIK).compute(pointLabelSuffix=pointSuffix) #---- zero unvalid frames --- btkTools.applyValidFramesOnOutput(acqIK, validFrames) return acqIK