def test_functions(self): filename = pyCGM2.TEST_DATA_PATH + "LowLevel\\IO\\Hånnibøl_c3d\\gait1.c3d" acq = btkTools.smartReader(filename, translators=None) btkTools.GetMarkerNames(acq) btkTools.findNearestMarker(acq, 0, "LASI") btkTools.GetAnalogNames(acq) btkTools.isGap(acq, "LASI") btkTools.findMarkerGap(acq) btkTools.isPointExist(acq, "LASI") btkTools.isPointsExist(acq, ["LASI", "RASI"]) btkTools.clearPoints(acq, ["LASI", "RASI"]) btkTools.checkFirstAndLastFrame(acq, "LASI") btkTools.isGap_inAcq(acq, ["LASI", "RASI"]) btkTools.findValidFrames(acq, ["LASI", "RASI"]) btkTools.checkMultipleSubject(acq) btkTools.checkMarkers(acq, ["LASI", "RASI"]) btkTools.clearEvents(acq, ["Foot Strike"]) btkTools.modifyEventSubject(acq, "Hän") btkTools.modifySubject(acq, "Han") btkTools.getVisibleMarkersAtFrame(acq, ["LASI", "RASI"], 0) btkTools.isAnalogExist(acq, "emg-Hän") btkTools.createZeros(acq, ["LASI", "RASI"]) btkTools.constructEmptyMarker(acq, "zéros", desc="Hän") btkTools.getStartEndEvents(acq, "Left") btkTools.changeSubjectName(acq, "Hän") btkTools.smartGetMetadata(acq, "SUBJECTS", "USED") btkTools.smartSetMetadata(acq, "SUBJECTS", "USED", 0, "Hän")
def fill(self, acq): logging.info("----LowDimensionalKalmanFilter gap filling----") btkmarkersLoaded = btkTools.GetMarkerNames(acq) ff = acq.GetFirstFrame() lf = acq.GetLastFrame() pfn = acq.GetPointFrameNumber() btkmarkers = [] for ml in btkmarkersLoaded: if btkTools.isPointExist(acq, ml): btkmarkers.append(ml) # -------- logging.debug("Populating data matrix") rawDatabtk = np.zeros((pfn, len(btkmarkers) * 3)) for i in range(0, len(btkmarkers)): values = acq.GetPoint(btkmarkers[i]).GetValues() residualValues = acq.GetPoint(btkmarkers[i]).GetResiduals() rawDatabtk[:, 3 * i - 3] = values[:, 0] rawDatabtk[:, 3 * i - 2] = values[:, 1] rawDatabtk[:, 3 * i - 1] = values[:, 2] E = residualValues[:, 0] rawDatabtk[np.asarray(E) == -1, 3 * i - 3] = np.nan rawDatabtk[np.asarray(E) == -1, 3 * i - 2] = np.nan rawDatabtk[np.asarray(E) == -1, 3 * i - 1] = np.nan Y2 = self._smooth(rawDatabtk, tol=1e-2, sigR=1e-3, keepOriginal=True) logging.debug("writing trajectories") # Create new smoothed trjectories filledMarkers = list() for i in range(0, len(btkmarkers)): targetMarker = btkmarkers[i] if btkTools.isGap(acq, targetMarker): logging.info("marker (%s) --> filled" % (targetMarker)) filledMarkers.append(targetMarker) val_final = np.zeros((pfn, 3)) val_final[:, 0] = Y2[:, 3 * i - 3] val_final[:, 1] = Y2[:, 3 * i - 2] val_final[:, 2] = Y2[:, 3 * i - 1] btkTools.smartAppendPoint(acq, targetMarker, val_final) logging.info( "----LowDimensionalKalmanFilter gap filling [complete]----") return acq, filledMarkers
def compute(self, acq): if not btkTools.isPointExist(acq, self.m_marker): raise Exception("[pyCGM2] : origin point doesnt exist") vff, vlf = btkTools.getFrameBoundaries(acq, [self.m_marker]) ff = acq.GetFirstFrame() values = acq.GetPoint(self.m_marker).GetValues()[vff - ff:vlf - ff + 1, 0:3] MaxValues = [ values[-1, 0] - values[0, 0], values[-1, 1] - values[0, 1] ] absMaxValues = [ np.abs(values[-1, 0] - values[0, 0]), np.abs(values[-1, 1] - values[0, 1]) ] ind = np.argmax(absMaxValues) diff = MaxValues[ind] if ind == 0: progressionAxis = "X" lateralAxis = "Y" else: progressionAxis = "Y" lateralAxis = "X" forwardProgression = True if diff > 0 else False globalFrame = (progressionAxis + lateralAxis + "Z") LOGGER.logger.debug("Progression axis : %s" % (progressionAxis)) LOGGER.logger.debug("forwardProgression : %s" % (forwardProgression)) LOGGER.logger.debug("globalFrame : %s" % (globalFrame)) return progressionAxis, forwardProgression, globalFrame
def temporalPlot(figAxis, acq, pointLabel, axis, pointLabelSuffix=None, color=None, title=None, xlabel=None, ylabel=None, ylim=None, legendLabel=None, customLimits=None): ''' **Description :** plot descriptive statistical (average and sd corridor) gait traces from a pyCGM2.Processing.analysis.Analysis instance :Parameters: - `figAxis` (matplotlib::Axis ) - `acq` (ma.Trial) - a Structure item of an Analysis instance built from AnalysisFilter :Return: - matplotlib figure **Usage** .. code:: python ''' pointLabel = pointLabel + "_" + pointLabelSuffix if pointLabelSuffix is not None else pointLabel flag = btkTools.isPointExist(acq, pointLabel) if flag: point = acq.GetPoint(pointLabel) lines = figAxis.plot(point.GetValues()[:, axis], '-', color=color) appf = 1 else: flag = btkTools.isAnalogExist(acq, pointLabel) if flag: analog = acq.GetAnalog(pointLabel) lines = figAxis.plot(analog.GetValues()[:, axis], '-', color=color) appf = acq.GetNumberAnalogSamplePerFrame() if legendLabel is not None and flag: lines[0].set_label(legendLabel) if title is not None: figAxis.set_title(title, size=8) figAxis.tick_params(axis='x', which='major', labelsize=6) figAxis.tick_params(axis='y', which='major', labelsize=6) if xlabel is not None: figAxis.set_xlabel(xlabel, size=8) if ylabel is not None: figAxis.set_ylabel(ylabel, size=8) if ylim is not None: figAxis.set_ylim(ylim) if flag: for ev in btk.Iterate(acq.GetEvents()): colorContext = plotUtils.colorContext(ev.GetContext()) if ev.GetLabel() == "Foot Strike": figAxis.axvline(x=(ev.GetFrame() - acq.GetFirstFrame()) * appf, color=colorContext, linestyle="-") if ev.GetLabel() == "Foot Off": figAxis.axvline(x=(ev.GetFrame() - acq.GetFirstFrame()) * appf, color=colorContext, linestyle="--")
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 calibrate(DATA_PATH,calibrateFilenameLabelled,translators,weights, required_mp,optional_mp, ik_flag,leftFlatFoot,rightFlatFoot,headFlat, markerDiameter,hjcMethod, pointSuffix,**kwargs): """ Calibration of the CGM2.3 :param DATA_PATH [str]: path to your data :param calibrateFilenameLabelled [str]: c3d file :param translators [dict]: translators to apply :param required_mp [dict]: required anthropometric data :param optional_mp [dict]: optional anthropometric data (ex: LThighOffset,...) :param ik_flag [bool]: enable the inverse kinematic solver :param leftFlatFoot [bool]: enable of the flat foot option for the left foot :param rightFlatFoot [bool]: enable of the flat foot option for the right foot :param headFlat [bool]: enable of the head flat option :param markerDiameter [double]: marker diameter (mm) :param hjcMethod [str or list of 3 float]: method for locating the hip joint centre :param pointSuffix [str]: suffix to add to model outputs """ # --------------------------STATIC FILE WITH TRANSLATORS -------------------------------------- if "Fitting" in weights.keys(): weights = weights["Fitting"]["Weight"] # --- btk acquisition ---- if "forceBtkAcq" in kwargs.keys(): acqStatic = kwargs["forceBtkAcq"] else: acqStatic = btkTools.smartReader((DATA_PATH+calibrateFilenameLabelled)) btkTools.checkMultipleSubject(acqStatic) if btkTools.isPointExist(acqStatic,"SACR"): translators["LPSI"] = "SACR" translators["RPSI"] = "SACR" logging.info("[pyCGM2] Sacrum marker detected") acqStatic = btkTools.applyTranslators(acqStatic,translators) # ---check marker set used---- dcm = cgm.CGM.detectCalibrationMethods(acqStatic) # --------------------------MODEL-------------------------------------- # ---definition--- model=cgm2.CGM2_3() model.configure(acq=acqStatic,detectedCalibrationMethods=dcm) model.addAnthropoInputParameters(required_mp,optional=optional_mp) # --store calibration parameters-- model.setStaticFilename(calibrateFilenameLabelled) model.setCalibrationProperty("leftFlatFoot",leftFlatFoot) model.setCalibrationProperty("rightFlatFoot",rightFlatFoot) model.setCalibrationProperty("headFlat",headFlat) model.setCalibrationProperty("markerDiameter",markerDiameter) # --------------------------STATIC CALBRATION-------------------------- scp=modelFilters.StaticCalibrationProcedure(model) # load calibration procedure # ---initial calibration filter---- # use if all optional mp are zero modelFilters.ModelCalibrationFilter(scp,acqStatic,model, leftFlatFoot = leftFlatFoot, rightFlatFoot = rightFlatFoot, headFlat= headFlat, markerDiameter=markerDiameter, ).compute() # ---- Decorators ----- decorators.applyBasicDecorators(dcm, model,acqStatic,optional_mp,markerDiameter) decorators.applyHJCDecorators(model,hjcMethod) # ----Final Calibration filter if model previously decorated ----- if model.decoratedModel: # initial static filter modelFilters.ModelCalibrationFilter(scp,acqStatic,model, leftFlatFoot = leftFlatFoot, rightFlatFoot = rightFlatFoot, headFlat= headFlat, markerDiameter=markerDiameter).compute() # ----------------------CGM MODELLING---------------------------------- # ----motion filter---- modMotion=modelFilters.ModelMotionFilter(scp,acqStatic,model,enums.motionMethod.Sodervisk, markerDiameter=markerDiameter) modMotion.compute() if "noKinematicsCalculation" in kwargs.keys() and kwargs["noKinematicsCalculation"]: logging.warning("[pyCGM2] No Kinematic calculation done for the static file") return model, acqStatic else: if model.getBodyPart() == enums.BodyPart.UpperLimb: ik_flag = False logging.warning("[pyCGM2] Fitting only applied for the upper limb") if ik_flag: # ---OPENSIM IK--- # --- opensim calibration Filter --- osimfile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\osim\\lowerLimb_ballsJoints.osim" # osimfile markersetFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_3\\cgm2_3-markerset.xml" # markerset cgmCalibrationprocedure = opensimFilters.CgmOpensimCalibrationProcedures(model) # procedure oscf = opensimFilters.opensimCalibrationFilter(osimfile, model, cgmCalibrationprocedure, (DATA_PATH)) oscf.addMarkerSet(markersetFile) scalingOsim = oscf.build() # --- opensim Fitting Filter --- iksetupFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_3\\cgm2_3-ikSetUp_template.xml" # ik tool file cgmFittingProcedure = opensimFilters.CgmOpensimFittingProcedure(model) # procedure cgmFittingProcedure.updateMarkerWeight("LASI",weights["LASI"]) cgmFittingProcedure.updateMarkerWeight("RASI",weights["RASI"]) cgmFittingProcedure.updateMarkerWeight("LPSI",weights["LPSI"]) cgmFittingProcedure.updateMarkerWeight("RPSI",weights["RPSI"]) cgmFittingProcedure.updateMarkerWeight("RTHI",weights["RTHI"]) cgmFittingProcedure.updateMarkerWeight("RKNE",weights["RKNE"]) cgmFittingProcedure.updateMarkerWeight("RTIB",weights["RTIB"]) cgmFittingProcedure.updateMarkerWeight("RANK",weights["RANK"]) cgmFittingProcedure.updateMarkerWeight("RHEE",weights["RHEE"]) cgmFittingProcedure.updateMarkerWeight("RTOE",weights["RTOE"]) cgmFittingProcedure.updateMarkerWeight("LTHI",weights["LTHI"]) cgmFittingProcedure.updateMarkerWeight("LKNE",weights["LKNE"]) cgmFittingProcedure.updateMarkerWeight("LTIB",weights["LTIB"]) cgmFittingProcedure.updateMarkerWeight("LANK",weights["LANK"]) cgmFittingProcedure.updateMarkerWeight("LHEE",weights["LHEE"]) cgmFittingProcedure.updateMarkerWeight("LTOE",weights["LTOE"]) cgmFittingProcedure.updateMarkerWeight("LTHAP",weights["LTHAP"]) cgmFittingProcedure.updateMarkerWeight("LTHAD",weights["LTHAD"]) cgmFittingProcedure.updateMarkerWeight("LTIAP",weights["LTIAP"]) cgmFittingProcedure.updateMarkerWeight("LTIAD",weights["LTIAD"]) cgmFittingProcedure.updateMarkerWeight("RTHAP",weights["RTHAP"]) cgmFittingProcedure.updateMarkerWeight("RTHAD",weights["RTHAD"]) cgmFittingProcedure.updateMarkerWeight("RTIAP",weights["RTIAP"]) cgmFittingProcedure.updateMarkerWeight("RTIAD",weights["RTIAD"]) osrf = opensimFilters.opensimFittingFilter(iksetupFile, scalingOsim, cgmFittingProcedure, (DATA_PATH) ) acqStaticIK = osrf.run(acqStatic,(DATA_PATH + calibrateFilenameLabelled )) # eventual static acquisition to consider for joint kinematics finalAcqStatic = acqStaticIK if ik_flag else acqStatic # --- final pyCGM2 model motion Filter --- # use fitted markers modMotionFitted=modelFilters.ModelMotionFilter(scp,finalAcqStatic,model,enums.motionMethod.Sodervisk) modMotionFitted.compute() if "displayCoordinateSystem" in kwargs.keys() and kwargs["displayCoordinateSystem"]: csp = modelFilters.ModelCoordinateSystemProcedure(model) csdf = modelFilters.CoordinateSystemDisplayFilter(csp,model,finalAcqStatic) csdf.setStatic(False) csdf.display() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model,finalAcqStatic).compute(description="vectoriel", pointLabelSuffix=pointSuffix) # detection of traveling axis + absolute angle if model.m_bodypart != enums.BodyPart.UpperLimb: pfp = progressionFrame.PelvisProgressionFrameProcedure() else: pfp = progressionFrame.ThoraxProgressionFrameProcedure() pff = progressionFrame.ProgressionFrameFilter(finalAcqStatic,pfp) pff.compute() globalFrame = pff.outputs["globalFrame"] forwardProgression = pff.outputs["forwardProgression"] if model.m_bodypart != enums.BodyPart.UpperLimb: modelFilters.ModelAbsoluteAnglesFilter(model,finalAcqStatic, segmentLabels=["Left Foot","Right Foot","Pelvis"], angleLabels=["LFootProgress", "RFootProgress","Pelvis"], eulerSequences=["TOR","TOR", "ROT"], globalFrameOrientation = globalFrame, forwardProgression = forwardProgression).compute(pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.LowerLimbTrunk: modelFilters.ModelAbsoluteAnglesFilter(model,finalAcqStatic, segmentLabels=["Thorax"], angleLabels=["Thorax"], eulerSequences=["YXZ"], globalFrameOrientation = globalFrame, forwardProgression = forwardProgression).compute(pointLabelSuffix=pointSuffix) if model.m_bodypart == enums.BodyPart.UpperLimb or model.m_bodypart == enums.BodyPart.FullBody: modelFilters.ModelAbsoluteAnglesFilter(model,finalAcqStatic, segmentLabels=["Thorax","Head"], angleLabels=["Thorax", "Head"], eulerSequences=["YXZ","TOR"], globalFrameOrientation = globalFrame, forwardProgression = forwardProgression).compute(pointLabelSuffix=pointSuffix) # BSP model bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() if model.m_bodypart == enums.BodyPart.FullBody: modelFilters.CentreOfMassFilter(model,finalAcqStatic).compute(pointLabelSuffix=pointSuffix) return model, finalAcqStatic
def 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 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 calibrate(self, aquiStatic, dictRef, dictAnatomic, options=None): """ static calibration :Parameters: - `aquiStatic` (btkAcquisition) - acquisition - `dictRef` (dict) - instance of Model - `options` (kwargs) - use to pass option altering the standard construction .. todo:: shrink and clone the aquisition to seleted frames """ logging.info("=====================================================") logging.info("===================CGM CALIBRATION===================") logging.info("=====================================================") ff = aquiStatic.GetFirstFrame() lf = aquiStatic.GetLastFrame() frameInit = ff - ff frameEnd = lf - ff + 1 if not self.decoratedModel: logging.warning(" Native CGM") if not btkTools.isPointExist(aquiStatic, "LKNE"): btkTools.smartAppendPoint( aquiStatic, "LKNE", np.zeros((aquiStatic.GetPointFrameNumber(), 3))) if not btkTools.isPointExist(aquiStatic, "RKNE"): btkTools.smartAppendPoint( aquiStatic, "RKNE", np.zeros((aquiStatic.GetPointFrameNumber(), 3))) else: logging.warning(" Decorated CGM") # --- PELVIS - THIGH - SHANK #------------------------------------- # calibration of technical Referentials logging.info(" --- Pelvis - TF calibration ---") logging.info(" -------------------------------") self._pelvis_calibrate(aquiStatic, dictRef, frameInit, frameEnd, options=options) # from CGM1 logging.info(" --- Left Thigh - TF calibration ---") logging.info(" -----------------------------------") self._left_thigh_calibrate(aquiStatic, dictRef, frameInit, frameEnd, options=options) # from CGM1 logging.info(" --- Right Thigh - TF calibration ---") logging.info(" ------------------------------------") self._right_thigh_calibrate(aquiStatic, dictRef, frameInit, frameEnd, options=options) # from CGM1 logging.info(" --- Left Shank - TF calibration ---") logging.info(" -----------------------------------") self._left_shank_calibrate(aquiStatic, dictRef, frameInit, frameEnd, options=options) # from CGM1 logging.info(" --- Right Shank - TF calibration ---") logging.info(" ------------------------------------") self._right_shank_calibrate(aquiStatic, dictRef, frameInit, frameEnd, options=options) # from CGM1 # calibration of anatomical Referentials logging.info(" --- Pelvis - AF calibration ---") logging.info(" -------------------------------") self._pelvis_Anatomicalcalibrate(aquiStatic, dictAnatomic, frameInit, frameEnd) self.displayStaticCoordinateSystem( aquiStatic, "Pelvis", "Pelvis", referential="Anatomical") # from CGM1 logging.info(" --- Left Thigh - AF calibration ---") logging.info(" -----------------------------------") self._left_thigh_Anatomicalcalibrate(aquiStatic, dictAnatomic, frameInit, frameEnd) self.displayStaticCoordinateSystem( aquiStatic, "Left Thigh", "LThigh", referential="Anatomical") # from CGM1 logging.info(" --- Right Thigh - AF calibration ---") logging.info(" ------------------------------------") self._right_thigh_Anatomicalcalibrate(aquiStatic, dictAnatomic, frameInit, frameEnd) self.displayStaticCoordinateSystem( aquiStatic, "Right Thigh", "RThigh", referential="Anatomical") # from CGM1 logging.info(" --- Left Shank - AF calibration ---") logging.info(" -----------------------------------") self._left_shank_Anatomicalcalibrate(aquiStatic, dictAnatomic, frameInit, frameEnd) self.displayStaticCoordinateSystem( aquiStatic, "Left Shank", "LShank", referential="Anatomical") # from CGM1 logging.info(" --- Right Shank - AF calibration ---") logging.info(" ------------------------------------") self._right_shank_Anatomicalcalibrate(aquiStatic, dictAnatomic, frameInit, frameEnd) self.displayStaticCoordinateSystem( aquiStatic, "Right Shank", "RShank", referential="Anatomical") # from CGM1 #offsets logging.info(" --- Compute Offsets ---") logging.info(" -----------------------") self.getThighOffset(side="left") self.getThighOffset(side="right") self.getShankOffsets( side="both") # compute TibialRotation and Shank offset self.getAbdAddAnkleJointOffset(side="both") # --- FOOT segment # --------------- # need anatomical flexion axis of the shank. # --- hind foot # -------------- logging.info(" --- Right Hind Foot - TF calibration ---") logging.info(" -----------------------------------------") self._rightHindFoot_calibrate(aquiStatic, dictRef, frameInit, frameEnd, options=options) #self.displayStaticCoordinateSystem( aquiStatic, "Right Hindfoot","RHindFootUncorrected",referential = "technic" ) logging.info(" --- Right Hind Foot - AF calibration ---") logging.info(" -----------------------------------------") self._rightHindFoot_anatomicalCalibrate(aquiStatic, dictAnatomic, frameInit, frameEnd, options=options) self.displayStaticCoordinateSystem(aquiStatic, "Right Hindfoot", "RHindFoot", referential="Anatomical") logging.info(" --- Hind foot Offset---") logging.info(" -----------------------") self.getHindFootOffset(side="both") # --- fore foot # ---------------- logging.info(" --- Right Fore Foot - TF calibration ---") logging.info(" -----------------------------------------") self._rightForeFoot_calibrate(aquiStatic, dictRef, frameInit, frameEnd, options=options) self.displayStaticCoordinateSystem(aquiStatic, "Right Forefoot", "RTechnicForeFoot", referential="Technical") logging.info(" --- Right Fore Foot - AF calibration ---") logging.info(" -----------------------------------------") self._rightForeFoot_anatomicalCalibrate(aquiStatic, dictAnatomic, frameInit, frameEnd) self.displayStaticCoordinateSystem(aquiStatic, "Right Forefoot", "RForeFoot", referential="Anatomical") btkTools.smartWriter(aquiStatic, "tmp-static.c3d")
def compute(self, acq): if not btkTools.isPointExist(acq, self.m_marker): raise Exception("[pyCGM2] : marker %s doesn't exist" % (self.m_marker)) # find valid frames and get the first one vff, vlf = btkTools.getFrameBoundaries(acq, [self.m_marker]) ff = acq.GetFirstFrame() values = acq.GetPoint(self.m_marker).GetValues()[vff - ff:vlf - ff + 1, :] MaxValues = [ values[-1, 0] - values[0, 0], values[-1, 1] - values[0, 1] ] absMaxValues = [ np.abs(values[-1, 0] - values[0, 0]), np.abs(values[-1, 1] - values[0, 1]) ] ind = np.argmax(absMaxValues) if absMaxValues[ind] > self.__threshold: LOGGER.logger.debug( "progression axis detected from displacement of the marker (%s)" % (self.m_marker)) diff = MaxValues[ind] if ind == 0: progressionAxis = "X" lateralAxis = "Y" else: progressionAxis = "Y" lateralAxis = "X" forwardProgression = True if diff > 0 else False globalFrame = (progressionAxis + lateralAxis + "Z") else: LOGGER.logger.debug( "progression axis detected from pelvis longitudinal axis") for marker in self.m_frontmarkers + self.m_backmarkers: if not btkTools.isPointExist(acq, marker): raise Exception("[pyCGM2] : marker %s doesn't exist" % (marker)) # find valid frames and get the first one vff, vlf = btkTools.getFrameBoundaries( acq, self.m_frontmarkers + self.m_backmarkers) ff = acq.GetFirstFrame() index = vff - ff # barycentres values = np.zeros((acq.GetPointFrameNumber(), 3)) count = 0 for marker in self.m_frontmarkers: values = values + acq.GetPoint(marker).GetValues() count += 1 frontValues = values / count values = np.zeros((acq.GetPointFrameNumber(), 3)) count = 0 for marker in self.m_backmarkers: values = values + acq.GetPoint(marker).GetValues() count += 1 backValues = values / count # axes back = backValues[index, :] front = frontValues[index, :] front[2] = back[ 2] # allow to avoid detecting Z axis if pelvs anterior axis point dowwnward z = np.array([0, 0, 1]) a1 = (front - back) a1 = a1 / np.linalg.norm(a1) a2 = np.cross(a1, z) a2 = a2 / np.linalg.norm(a2) globalAxes = { "X": np.array([1, 0, 0]), "Y": np.array([0, 1, 0]), "Z": np.array([0, 0, 1]) } # longitudinal axis tmp = [] for axis in globalAxes.keys(): res = np.dot(a1, globalAxes[axis]) tmp.append(res) maxIndex = np.argmax(np.abs(tmp)) progressionAxis = list(globalAxes.keys())[maxIndex] forwardProgression = True if tmp[maxIndex] > 0 else False # lateral axis tmp = [] for axis in globalAxes.keys(): res = np.dot(a2, globalAxes[axis]) tmp.append(res) maxIndex = np.argmax(np.abs(tmp)) lateralAxis = list(globalAxes.keys())[maxIndex] # global frame if "X" not in (progressionAxis + lateralAxis): globalFrame = (progressionAxis + lateralAxis + "X") if "Y" not in (progressionAxis + lateralAxis): globalFrame = (progressionAxis + lateralAxis + "Y") if "Z" not in (progressionAxis + lateralAxis): globalFrame = (progressionAxis + lateralAxis + "Z") LOGGER.logger.info("Progression axis : %s" % (progressionAxis)) LOGGER.logger.info("forwardProgression : %s" % ((forwardProgression))) LOGGER.logger.info("globalFrame : %s" % ((globalFrame))) return progressionAxis, forwardProgression, globalFrame
calibration_markers=[], tracking_markers=trackingMarkers) gcp = modelFilters.GeneralCalibrationProcedure() gcp.setDefinition('segment', "TF", sequence='XYZ', pointLabel1=trackingMarkers[0], pointLabel2=trackingMarkers[1], pointLabel3=trackingMarkers[2], pointLabelOrigin=trackingMarkers[0]) modCal = modelFilters.ModelCalibrationFilter(gcp, acqStatic, mod) modCal.compute() if not btkTools.isPointExist(acqGait, targetMarker): print "targer Marker not in the c3d" mod.getSegment("segment").m_tracking_markers.remove(targetMarker) modMotion = modelFilters.ModelMotionFilter( gcp, acqGait, mod, enums.motionMethod.Sodervisk) modMotion.compute() #populate values valReconstruct = mod.getSegment('segment').getReferential( 'TF').getNodeTrajectory(targetMarker) if btkTools.isPointExist(acqGait, targetMarker): val0 = acqGait.GetPoint(targetMarker).GetValues() val_final = copy.deepcopy(val0) val_final[selectInitialFrame - ff:selectLastFrame + 1 -
def fitting(model,DATA_PATH, reconstructFilenameLabelled, translators, markerDiameter, pointSuffix, mfpa, momentProjection,**kwargs): """ Fitting of the CGM2.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 """ detectAnomaly = False if "anomalyException" in kwargs.keys(): anomalyException = kwargs["anomalyException"] else: anomalyException=False # --------------------------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" LOGGER.logger.info("[pyCGM2] Sacrum marker detected") acqGait = btkTools.applyTranslators(acqGait,translators) trackingMarkers = cgm.CGM1.LOWERLIMB_TRACKING_MARKERS + cgm.CGM1.THORAX_TRACKING_MARKERS+ cgm.CGM1.UPPERLIMB_TRACKING_MARKERS actual_trackingMarkers,phatoms_trackingMarkers = btkTools.createPhantoms(acqGait, trackingMarkers) vff,vlf = btkTools.getFrameBoundaries(acqGait,actual_trackingMarkers) if "frameInit" in kwargs.keys() and kwargs["frameInit"] is not None: vff = kwargs["frameInit"] LOGGER.logger.info("[pyCGM2] first frame forced to frame [%s]"%(vff)) if "frameEnd" in kwargs.keys() and kwargs["frameEnd"] is not None: vlf = kwargs["frameEnd"] LOGGER.logger.info("[pyCGM2] end frame forced to frame [%s]"%(vlf)) flag = btkTools.getValidFrames(acqGait,actual_trackingMarkers,frameBounds=[vff,vlf]) LOGGER.logger.info("[pyCGM2] Computation from frame [%s] to frame [%s]"%(vff,vlf)) # --------------------ANOMALY------------------------------ for marker in actual_trackingMarkers: if marker not in model.getStaticTrackingMarkers(): LOGGER.logger.warning("[pyCGM2-Anomaly] marker [%s] - not used during static calibration - wrong kinematic for the segment attached to this marker. "%(marker)) # --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(acqGait,reconstructFilenameLabelled,ipdp) inspector = idf.run() # --marker outliers if inspector["In"] !=[]: madp = AnomalyDetectionProcedure.MarkerAnomalyDetectionRollingProcedure( inspector["In"], plot=False, window=5,threshold = 3) adf = AnomalyFilter.AnomalyDetectionFilter(acqGait,reconstructFilenameLabelled,madp, frameRange=[vff,vlf]) anomaly = adf.run() anomalyIndexes = anomaly["Output"] if anomaly["ErrorState"]: detectAnomaly = True if btkTools.checkForcePlateExist(acqGait): afpp = AnomalyDetectionProcedure.ForcePlateAnomalyProcedure() adf = AnomalyFilter.AnomalyDetectionFilter(acqGait,reconstructFilenameLabelled,afpp, frameRange=[vff,vlf]) anomaly = adf.run() if anomaly["ErrorState"]: detectAnomaly = True if detectAnomaly and anomalyException: raise Exception ("Anomalies has been detected - Check Warning message of the log file") # --------------------MODELLING------------------------------ # 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) # ---Motion filter---- modMotion=modelFilters.ModelMotionFilter(scp,acqGait,model,enums.motionMethod.Determinist, markerDiameter=markerDiameter) modMotion.compute() progressionFlag = False if btkTools.isPointExist(acqGait, 'LHEE',ignorePhantom=False) or btkTools.isPointExist(acqGait, 'RHEE',ignorePhantom=False): pfp = progressionFrame.PointProgressionFrameProcedure(marker="LHEE") \ if btkTools.isPointExist(acqGait, 'LHEE',ignorePhantom=False) \ else progressionFrame.PointProgressionFrameProcedure(marker="RHEE") pff = progressionFrame.ProgressionFrameFilter(acqGait,pfp) pff.compute() progressionAxis = pff.outputs["progressionAxis"] globalFrame = pff.outputs["globalFrame"] forwardProgression = pff.outputs["forwardProgression"] progressionFlag = True elif btkTools.isPointsExist(acqGait, ['LASI', 'RASI', 'RPSI', 'LPSI'],ignorePhantom=False) and not progressionFlag: LOGGER.logger.info("[pyCGM2] - progression axis detected from Pelvic markers ") pfp = progressionFrame.PelvisProgressionFrameProcedure() pff = progressionFrame.ProgressionFrameFilter(acqGait,pfp) pff.compute() globalFrame = pff.outputs["globalFrame"] forwardProgression = pff.outputs["forwardProgression"] progressionFlag = True elif btkTools.isPointsExist(acqGait, ['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(acqGait,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,acqGait) csdf.setStatic(False) csdf.display() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model,acqGait).compute(description="vectoriel", pointLabelSuffix=pointSuffix) modelFilters.ModelAbsoluteAnglesFilter(model,acqGait, 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) #---- Body segment parameters---- bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() 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) LOGGER.logger.info("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) btkTools.cleanAcq(acqGait) btkTools.applyOnValidFrames(acqGait,flag) if detectAnomaly and not anomalyException: LOGGER.logger.error("Anomalies has been detected - Check Warning messages of the log file") return acqGait,detectAnomaly
def calibrate(DATA_PATH,calibrateFilenameLabelled,translators, required_mp,optional_mp, leftFlatFoot,rightFlatFoot,headFlat, markerDiameter,hjcMethod, pointSuffix,**kwargs): """ Calibration of the CGM2.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 hjcMethod [str or list of 3 float]: method for locating the hip joint centre :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------------------------------ # ---check marker set used---- dcm = cgm.CGM.detectCalibrationMethods(acqStatic) # ---definition--- model=cgm2.CGM2_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---- # use if all optional mp are zero modelFilters.ModelCalibrationFilter(scp,acqStatic,model, leftFlatFoot = leftFlatFoot, rightFlatFoot = rightFlatFoot, headFlat= headFlat, markerDiameter=markerDiameter, ).compute() # ---- Decorators ----- decorators.applyBasicDecorators(dcm, model,acqStatic,optional_mp,markerDiameter) decorators.applyHJCDecorators(model,hjcMethod) # ----Final Calibration filter if model previously decorated ----- if model.decoratedModel: # initial static filter modelFilters.ModelCalibrationFilter(scp,acqStatic,model, leftFlatFoot = leftFlatFoot, rightFlatFoot = rightFlatFoot, markerDiameter=markerDiameter, headFlat= headFlat, ).compute() 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() # ----------------------CGM MODELLING---------------------------------- # ----motion filter---- # notice : viconCGM1compatible option duplicate error on Construction of the foot coordinate system 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 fitting(model, DATA_PATH, reconstructFilenameLabelled, translators, weights, ik_flag, markerDiameter, pointSuffix, mfpa, momentProjection, **kwargs): """ Fitting of the CGM2.5 :param model [str]: pyCGM2 model previously calibrated :param DATA_PATH [str]: path to your data :param reconstructFilenameLabelled [string list]: c3d files :param translators [dict]: translators to apply :param ik_flag [bool]: enable the inverse kinematic solver :param mfpa [str]: manual force plate assignement :param markerDiameter [double]: marker diameter (mm) :param pointSuffix [str]: suffix to add to model outputs :param momentProjection [str]: Coordinate system in which joint moment is expressed """ detectAnomaly = False if "anomalyException" in kwargs.keys(): anomalyException = kwargs["anomalyException"] else: anomalyException = False if "forceFoot6DoF" in kwargs.keys() and kwargs["forceFoot6DoF"]: forceFoot6DoF_flag = True else: forceFoot6DoF_flag = False if "Fitting" in weights.keys(): weights = weights["Fitting"]["Weight"] # --- 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" LOGGER.logger.info("[pyCGM2] Sacrum marker detected") acqGait = btkTools.applyTranslators(acqGait, translators) trackingMarkers = cgm2.CGM2_5.LOWERLIMB_TRACKING_MARKERS + cgm2.CGM2_5.THORAX_TRACKING_MARKERS + cgm2.CGM2_5.UPPERLIMB_TRACKING_MARKERS actual_trackingMarkers, phatoms_trackingMarkers = btkTools.createPhantoms( acqGait, trackingMarkers) vff, vlf = btkTools.getFrameBoundaries(acqGait, actual_trackingMarkers) if "frameInit" in kwargs.keys() and kwargs["frameInit"] is not None: vff = kwargs["frameInit"] LOGGER.logger.info("[pyCGM2] first frame forced to frame [%s]" % (vff)) if "frameEnd" in kwargs.keys() and kwargs["frameEnd"] is not None: vlf = kwargs["frameEnd"] LOGGER.logger.info("[pyCGM2] end frame forced to frame [%s]" % (vlf)) flag = btkTools.getValidFrames(acqGait, actual_trackingMarkers, frameBounds=[vff, vlf]) LOGGER.logger.info("[pyCGM2] Computation from frame [%s] to frame [%s]" % (vff, vlf)) # --------------------ANOMALY------------------------------ for marker in actual_trackingMarkers: if marker not in model.getStaticTrackingMarkers(): LOGGER.logger.warning( "[pyCGM2-Anomaly] marker [%s] - not used during static calibration - wrong kinematic for the segment attached to this marker. " % (marker)) # --marker presence markersets = [ cgm2.CGM2_5.LOWERLIMB_TRACKING_MARKERS, cgm2.CGM2_5.THORAX_TRACKING_MARKERS, cgm2.CGM2_5.UPPERLIMB_TRACKING_MARKERS ] for markerset in markersets: ipdp = InspectorProcedure.MarkerPresenceDetectionProcedure(markerset) idf = InspectorFilter.InspectorFilter(acqGait, reconstructFilenameLabelled, ipdp) inspector = idf.run() # --marker outliers if inspector["In"] != []: madp = AnomalyDetectionProcedure.MarkerAnomalyDetectionRollingProcedure( inspector["In"], plot=False, window=5, threshold=3) adf = AnomalyFilter.AnomalyDetectionFilter( acqGait, reconstructFilenameLabelled, madp, frameRange=[vff, vlf]) anomaly = adf.run() anomalyIndexes = anomaly["Output"] if anomaly["ErrorState"]: detectAnomaly = True if btkTools.checkForcePlateExist(acqGait): afpp = AnomalyDetectionProcedure.ForcePlateAnomalyProcedure() adf = AnomalyFilter.AnomalyDetectionFilter(acqGait, reconstructFilenameLabelled, afpp, frameRange=[vff, vlf]) anomaly = adf.run() if anomaly["ErrorState"]: detectAnomaly = True if detectAnomaly and anomalyException: raise Exception( "Anomalies has been detected - Check Warning message of the log file" ) # --------------------MODELLING------------------------------ # 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) modMotion = modelFilters.ModelMotionFilter(scp, acqGait, model, enums.motionMethod.Sodervisk) modMotion.compute() progressionFlag = False if btkTools.isPointExist(acqGait, 'LHEE', ignorePhantom=False) or btkTools.isPointExist( acqGait, 'RHEE', ignorePhantom=False): pfp = progressionFrame.PointProgressionFrameProcedure(marker="LHEE") \ if btkTools.isPointExist(acqGait, 'LHEE',ignorePhantom=False) \ else progressionFrame.PointProgressionFrameProcedure(marker="RHEE") pff = progressionFrame.ProgressionFrameFilter(acqGait, pfp) pff.compute() progressionAxis = pff.outputs["progressionAxis"] globalFrame = pff.outputs["globalFrame"] forwardProgression = pff.outputs["forwardProgression"] progressionFlag = True elif btkTools.isPointsExist(acqGait, ['LASI', 'RASI', 'RPSI', 'LPSI'], ignorePhantom=False) and not progressionFlag: LOGGER.logger.info( "[pyCGM2] - progression axis detected from Pelvic markers ") pfp = progressionFrame.PelvisProgressionFrameProcedure() pff = progressionFrame.ProgressionFrameFilter(acqGait, pfp) pff.compute() globalFrame = pff.outputs["globalFrame"] forwardProgression = pff.outputs["forwardProgression"] progressionFlag = True elif btkTools.isPointsExist(acqGait, ['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(acqGait, 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 " ) for target in weights.keys(): if target not in actual_trackingMarkers or target not in model.getStaticIkTargets( ): weights[target] = 0 LOGGER.logger.warning( "[pyCGM2] - the IK targeted marker [%s] is not labelled in the acquisition [%s]" % (target, reconstructFilenameLabelled)) 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, 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", 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"]) cgmFittingProcedure.updateMarkerWeight("LSMH", weights["LSMH"]) cgmFittingProcedure.updateMarkerWeight("LFMH", weights["LFMH"]) cgmFittingProcedure.updateMarkerWeight("LVMH", weights["LVMH"]) cgmFittingProcedure.updateMarkerWeight("RSMH", weights["RSMH"]) cgmFittingProcedure.updateMarkerWeight("RFMH", weights["RFMH"]) cgmFittingProcedure.updateMarkerWeight("RVMH", weights["RVMH"]) # cgmFittingProcedure.updateMarkerWeight("LTHL",weights["LTHL"]) # cgmFittingProcedure.updateMarkerWeight("LTHLD",weights["LTHLD"]) # cgmFittingProcedure.updateMarkerWeight("LPAT",weights["LPAT"]) # cgmFittingProcedure.updateMarkerWeight("LTIBL",weights["LTIBL"]) # cgmFittingProcedure.updateMarkerWeight("RTHL",weights["RTHL"]) # cgmFittingProcedure.updateMarkerWeight("RTHLD",weights["RTHLD"]) # cgmFittingProcedure.updateMarkerWeight("RPAT",weights["RPAT"]) # cgmFittingProcedure.updateMarkerWeight("RTIBL",weights["RTIBL"]) osrf = opensimFilters.opensimFittingFilter(iksetupFile, scalingOsim, cgmFittingProcedure, DATA_PATH, acqGait) osrf.setTimeRange(acqGait, beginFrame=vff, lastFrame=vlf) if "ikAccuracy" in kwargs.keys(): osrf.setAccuracy(kwargs["ikAccuracy"]) LOGGER.logger.info("-------INVERSE KINEMATICS IN PROGRESS----------") try: acqIK = osrf.run(DATA_PATH + reconstructFilenameLabelled, progressionAxis=progressionAxis, forwardProgression=forwardProgression) LOGGER.logger.info("[pyCGM2] - IK solver complete") except: LOGGER.logger.error("[pyCGM2] - IK solver fails") acqIK = acqGait detectAnomaly = True LOGGER.logger.info( "---------------------------------------------------") # eventual gait acquisition to consider for joint kinematics finalAcqGait = acqIK if ik_flag else acqGait if "displayCoordinateSystem" in kwargs.keys( ) and kwargs["displayCoordinateSystem"]: csp = modelFilters.ModelCoordinateSystemProcedure(model) csdf = modelFilters.CoordinateSystemDisplayFilter( csp, model, finalAcqGait) csdf.setStatic(False) csdf.display() # --- final pyCGM2 model motion Filter --- # use fitted markers modMotionFitted = modelFilters.ModelMotionFilter( scp, finalAcqGait, model, enums.motionMethod.Sodervisk, markerDiameter=markerDiameter, forceFoot6DoF=forceFoot6DoF_flag) modMotionFitted.compute() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model, finalAcqGait).compute( description="vectoriel", pointLabelSuffix=pointSuffix) modelFilters.ModelAbsoluteAnglesFilter( model, finalAcqGait, 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) #---- Body segment parameters---- bspModel = bodySegmentParameters.Bsp(model) bspModel.compute() modelFilters.CentreOfMassFilter( model, finalAcqGait).compute(pointLabelSuffix=pointSuffix) # Inverse dynamics if btkTools.checkForcePlateExist(acqGait): # --- force plate handling---- # find foot in contact mappedForcePlate = forceplates.matchingFootSideOnForceplate( finalAcqGait, mfpa=mfpa) forceplates.addForcePlateGeneralEvents(finalAcqGait, mappedForcePlate) LOGGER.logger.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.cleanAcq(finalAcqGait) btkTools.applyOnValidFrames(finalAcqGait, flag) if detectAnomaly and not anomalyException: LOGGER.logger.error( "Anomalies has been detected - Check Warning messages of the log file" ) return finalAcqGait, detectAnomaly
def calibrate(DATA_PATH, calibrateFilenameLabelled, translators, weights, required_mp, optional_mp, ik_flag, leftFlatFoot, rightFlatFoot, headFlat, markerDiameter, hjcMethod, pointSuffix, **kwargs): """ Calibration of the CGM2.5 :param DATA_PATH [str]: path to your data :param calibrateFilenameLabelled [str]: c3d file :param translators [dict]: translators to apply :param required_mp [dict]: required anthropometric data :param optional_mp [dict]: optional anthropometric data (ex: LThighOffset,...) :param ik_flag [bool]: enable the inverse kinematic solver :param leftFlatFoot [bool]: enable of the flat foot option for the left foot :param rightFlatFoot [bool]: enable of the flat foot option for the right foot :param headFlat [bool]: enable of the head flat option :param markerDiameter [double]: marker diameter (mm) :param hjcMethod [str or list of 3 float]: method for locating the hip joint centre :param pointSuffix [str]: suffix to add to model outputs """ detectAnomaly = False if "anomalyException" in kwargs.keys(): anomalyException = kwargs["anomalyException"] else: anomalyException = False if "Fitting" in weights.keys(): weights = weights["Fitting"]["Weight"] # ---btk acquisition--- if "forceBtkAcq" in kwargs.keys(): acqStatic = kwargs["forceBtkAcq"] else: acqStatic = btkTools.smartReader( (DATA_PATH + calibrateFilenameLabelled)) btkTools.checkMultipleSubject(acqStatic) if btkTools.isPointExist(acqStatic, "SACR"): translators["LPSI"] = "SACR" translators["RPSI"] = "SACR" LOGGER.logger.info("[pyCGM2] Sacrum marker detected") acqStatic = btkTools.applyTranslators(acqStatic, translators) trackingMarkers = cgm2.CGM2_5.LOWERLIMB_TRACKING_MARKERS + cgm2.CGM2_5.THORAX_TRACKING_MARKERS + cgm2.CGM2_5.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 = [ cgm2.CGM2_5.LOWERLIMB_TRACKING_MARKERS, cgm2.CGM2_5.THORAX_TRACKING_MARKERS, cgm2.CGM2_5.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------------------------------ # ---check marker set used---- dcm = cgm.CGM.detectCalibrationMethods(acqStatic) # --------------------------MODEL-------------------------------------- # ---definition--- model = cgm2.CGM2_5() 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---- # use if all optional mp are zero modelFilters.ModelCalibrationFilter( scp, acqStatic, model, leftFlatFoot=leftFlatFoot, rightFlatFoot=rightFlatFoot, headFlat=headFlat, markerDiameter=markerDiameter, ).compute() # ---- Decorators ----- decorators.applyBasicDecorators(dcm, model, acqStatic, optional_mp, markerDiameter) decorators.applyHJCDecorators(model, hjcMethod) # ----Final Calibration filter if model previously decorated ----- if model.decoratedModel: # initial static filter modelFilters.ModelCalibrationFilter( scp, acqStatic, model, leftFlatFoot=leftFlatFoot, rightFlatFoot=rightFlatFoot, headFlat=headFlat, markerDiameter=markerDiameter).compute() # ----------------------CGM MODELLING---------------------------------- # ----motion filter---- modMotion = modelFilters.ModelMotionFilter(scp, acqStatic, model, enums.motionMethod.Sodervisk, markerDiameter=markerDiameter) modMotion.compute() # ----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 " ) # ----manage IK Targets---- ikTargets = list() for target in weights.keys(): if target not in actual_trackingMarkers: weights[target] = 0 LOGGER.logger.warning( "[pyCGM2] - the IK targeted marker [%s] is not labelled in the acquisition [%s]" % (target, calibrateFilenameLabelled)) else: ikTargets.append(target) model.setStaticIkTargets(ikTargets) if "noKinematicsCalculation" in kwargs.keys( ) and kwargs["noKinematicsCalculation"]: LOGGER.logger.warning( "[pyCGM2] No Kinematic calculation done for the static file") return model, acqStatic, detectAnomaly else: 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, DATA_PATH) oscf.addMarkerSet(markersetFile) scalingOsim = oscf.build() # --- opensim Fitting Filter --- iksetupFile = pyCGM2.OPENSIM_PREBUILD_MODEL_PATH + "models\\settings\\cgm2_4\\cgm2_4-ikSetUp_template.xml" # ik tool file cgmFittingProcedure = opensimFilters.CgmOpensimFittingProcedure( model) # procedure cgmFittingProcedure.updateMarkerWeight("LASI", 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"]) cgmFittingProcedure.updateMarkerWeight("LSMH", weights["LSMH"]) cgmFittingProcedure.updateMarkerWeight("LFMH", weights["LFMH"]) cgmFittingProcedure.updateMarkerWeight("LVMH", weights["LVMH"]) cgmFittingProcedure.updateMarkerWeight("RSMH", weights["RSMH"]) cgmFittingProcedure.updateMarkerWeight("RFMH", weights["RFMH"]) cgmFittingProcedure.updateMarkerWeight("RVMH", weights["RVMH"]) # cgmFittingProcedure.updateMarkerWeight("LTHL",weights["LTHL"]) # cgmFittingProcedure.updateMarkerWeight("LTHLD",weights["LTHLD"]) # cgmFittingProcedure.updateMarkerWeight("LPAT",weights["LPAT"]) # cgmFittingProcedure.updateMarkerWeight("LTIBL",weights["LTIBL"]) # cgmFittingProcedure.updateMarkerWeight("RTHL",weights["RTHL"]) # cgmFittingProcedure.updateMarkerWeight("RTHLD",weights["RTHLD"]) # cgmFittingProcedure.updateMarkerWeight("RPAT",weights["RPAT"]) # cgmFittingProcedure.updateMarkerWeight("RTIBL",weights["RTIBL"]) osrf = opensimFilters.opensimFittingFilter(iksetupFile, scalingOsim, cgmFittingProcedure, DATA_PATH, acqStatic, accuracy=1e-5) LOGGER.logger.info( "-------INVERSE KINEMATICS IN PROGRESS----------") try: acqStaticIK = osrf.run(DATA_PATH + calibrateFilenameLabelled, progressionAxis=progressionAxis, forwardProgression=forwardProgression) LOGGER.logger.info("[pyCGM2] - IK solver complete") except: LOGGER.logger.error("[pyCGM2] - IK solver fails") acqStaticIK = acqStatic detectAnomaly = True LOGGER.logger.info( "-----------------------------------------------") # eventual static acquisition to consider for joint kinematics finalAcqStatic = acqStaticIK if ik_flag else acqStatic # --- final pyCGM2 model motion Filter --- # use fitted markers modMotionFitted = modelFilters.ModelMotionFilter( scp, finalAcqStatic, model, enums.motionMethod.Sodervisk) modMotionFitted.compute() if "displayCoordinateSystem" in kwargs.keys( ) and kwargs["displayCoordinateSystem"]: csp = modelFilters.ModelCoordinateSystemProcedure(model) csdf = modelFilters.CoordinateSystemDisplayFilter( csp, model, finalAcqStatic) csdf.setStatic(False) csdf.display() #---- Joint kinematics---- # relative angles modelFilters.ModelJCSFilter(model, finalAcqStatic).compute( description="vectoriel", pointLabelSuffix=pointSuffix) modelFilters.ModelAbsoluteAnglesFilter( model, finalAcqStatic, 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, finalAcqStatic).compute(pointLabelSuffix=pointSuffix) btkTools.cleanAcq(finalAcqStatic) if detectAnomaly and not anomalyException: LOGGER.logger.error( "Anomalies has been detected - Check Warning messages of the log file" ) return model, finalAcqStatic, detectAnomaly
def nexus_x2d(cls): NEXUS = ViconNexus.ViconNexus() NEXUS_PYTHON_CONNECTED = NEXUS.Client.IsConnected() DATA_PATH = "C:\\Users\\HLS501\\Documents\\VICON DATA\\pyCGM2-Data\\operations\\gapFilling\\gaitWithGaps_withX2d\\" filenameNoExt = "gait_GAP" NEXUS.OpenTrial(str(DATA_PATH + filenameNoExt), 30) acq_filled = btkTools.smartReader( str(DATA_PATH + "gait_GAP.-moGap.c3d")) subject = NEXUS.GetSubjectNames()[0] print "Gap filling for subject ", subject markersLoaded = NEXUS.GetMarkerNames( subject) # nexus2.7 return all makers, even calibration only frames = NEXUS.GetFrameCount() markers = [] for i in range(0, len(markersLoaded)): data = NEXUS.GetTrajectory(subject, markersLoaded[i]) if data != ([], [], [], []): markers.append(markersLoaded[i]) #--------- acq = btkTools.smartReader(str(DATA_PATH + filenameNoExt + ".c3d")) btkmarkersLoaded = btkTools.GetMarkerNames(acq) ff = acq.GetFirstFrame() lf = acq.GetLastFrame() pfn = acq.GetPointFrameNumber() btkmarkers = [] for ml in btkmarkersLoaded: if btkTools.isPointExist(acq, ml): btkmarkers.append(ml) #--------- print "Populating data matrix" rawData = np.zeros((frames, len(markers) * 3)) for i in range(0, len(markers)): print i rawData[:, 3 * i - 3], rawData[:, 3 * i - 2], rawData[:, 3 * i - 1], E = NEXUS.GetTrajectory( subject, markers[i]) rawData[np.asarray(E) == 0, 3 * i - 3] = np.nan rawData[np.asarray(E) == 0, 3 * i - 2] = np.nan rawData[np.asarray(E) == 0, 3 * i - 1] = np.nan Y = smooth(rawData, tol=1e-2, sigR=1e-3, keepOriginal=True) print "Writing new trajectories" # Create new smoothed trjectories for i in range(0, len(markers)): if markers[i] == "LTHAD": E = np.ones((len(E), 1)).tolist() val0 = Y[:, 3 * i - 3].tolist() val1 = Y[:, 3 * i - 2].tolist() val2 = Y[:, 3 * i - 1].tolist() #NEXUS.SetTrajectory(subject,markers[i],Y[:,3*i-3].tolist(),Y[:,3*i-2].tolist(),Y[:,3*i-1].tolist(),E) print "Done" # -------- print "Populating data matrix" rawDatabtk = np.zeros((pfn, len(btkmarkers) * 3)) for i in range(0, len(btkmarkers)): values = acq.GetPoint(btkmarkers[i]).GetValues() residualValues = acq.GetPoint(btkmarkers[i]).GetResiduals() rawDatabtk[:, 3 * i - 3] = values[:, 0] rawDatabtk[:, 3 * i - 2] = values[:, 1] rawDatabtk[:, 3 * i - 1] = values[:, 2] E = residualValues[:, 0] rawDatabtk[np.asarray(E) == -1, 3 * i - 3] = np.nan rawDatabtk[np.asarray(E) == -1, 3 * i - 2] = np.nan rawDatabtk[np.asarray(E) == -1, 3 * i - 1] = np.nan Y2 = smooth(rawDatabtk, tol=1e-2, sigR=1e-3, keepOriginal=True) print "Writing new trajectories" # Create new smoothed trjectories for i in range(0, len(btkmarkers)): targetMarker = btkmarkers[i] if btkTools.isGap(acq, targetMarker): val_final = np.zeros((pfn, 3)) val_final[:, 0] = Y2[:, 3 * i - 3] val_final[:, 1] = Y2[:, 3 * i - 2] val_final[:, 2] = Y2[:, 3 * i - 1] btkTools.smartAppendPoint(acq, targetMarker, val_final) nexusTools.setTrajectoryFromAcq(NEXUS, subject, targetMarker, acq) print "Done"