def main(sessionFilename, createPDFReport=True): logging.info("------------------------------------------------") logging.info("------------QTM - pyCGM2 Workflow---------------") logging.info("------------------------------------------------") sessionXML = files.readXml(os.getcwd() + "\\", sessionFilename) sessionDate = files.getFileCreationDate(os.getcwd() + "\\" + sessionFilename) #--------------------------------------------------------------------------- #management of the Processed folder DATA_PATH = os.getcwd() + "\\" + "processed\\" files.createDir(DATA_PATH) staticMeasurement = qtmTools.findStatic(sessionXML) calibrateFilenameLabelled = qtmTools.getFilename(staticMeasurement) if not os.path.isfile(DATA_PATH + calibrateFilenameLabelled): shutil.copyfile(os.getcwd() + "\\" + calibrateFilenameLabelled, DATA_PATH + calibrateFilenameLabelled) logging.info( "qualisys exported c3d file [%s] copied to processed folder" % (calibrateFilenameLabelled)) dynamicMeasurements = qtmTools.findDynamic(sessionXML) for dynamicMeasurement in dynamicMeasurements: reconstructFilenameLabelled = qtmTools.getFilename(dynamicMeasurement) if not os.path.isfile(DATA_PATH + reconstructFilenameLabelled): shutil.copyfile(os.getcwd() + "\\" + reconstructFilenameLabelled, DATA_PATH + reconstructFilenameLabelled) logging.info( "qualisys exported c3d file [%s] copied to processed folder" % (reconstructFilenameLabelled)) acq = btkTools.smartReader( str(DATA_PATH + reconstructFilenameLabelled)) acq, zeniState = eventDetector.zeni(acq) if zeniState: btkTools.smartWriter( acq, str(DATA_PATH + reconstructFilenameLabelled)) cmd = "Mokka.exe \"%s\"" % (str(DATA_PATH + reconstructFilenameLabelled)) os.system(cmd) # --------------------------GLOBAL SETTINGS ------------------------------------ # global setting ( in user/AppData) if os.path.isfile(pyCGM2.PYCGM2_APPDATA_PATH + "CGM2_3-pyCGM2.settings"): settings = files.openFile(pyCGM2.PYCGM2_APPDATA_PATH, "CGM2_3-pyCGM2.settings") else: settings = files.openFile(pyCGM2.PYCGM2_SETTINGS_FOLDER, "CGM2_3-pyCGM2.settings") # --------------------------MP ------------------------------------ required_mp, optional_mp = qtmTools.SubjectMp(sessionXML) # --Check MP inspectprocedure = inspectProcedures.AnthropometricDataQualityProcedure( required_mp) inspector = inspectFilters.QualityFilter(inspectprocedure) inspector.run() # translators management translators = files.getTranslators(os.getcwd() + "\\", "CGM2_3.translators") if not translators: translators = settings["Translators"] # ikweight ikWeight = files.getIKweightSet(DATA_PATH, "CGM2_3.ikw") if not ikWeight: ikWeight = settings["Fitting"]["Weight"] # --------------------------MODEL CALIBRATION ----------------------- logging.info( "--------------------------MODEL CALIBRATION -----------------------") staticMeasurement = qtmTools.findStatic(sessionXML) calibrateFilenameLabelled = qtmTools.getFilename(staticMeasurement) logging.info("----- CALIBRATION- static file [%s]--" % (calibrateFilenameLabelled)) leftFlatFoot = utils.toBool( sessionXML.Left_foot_normalised_to_static_trial.text) rightFlatFoot = utils.toBool( sessionXML.Right_foot_normalised_to_static_trial.text) headFlat = utils.toBool(sessionXML.Head_normalised_to_static_trial.text) markerDiameter = float(sessionXML.Marker_diameter.text) * 1000.0 hjcMethod = settings["Calibration"]["HJC"] pointSuffix = None # Calibration checking # -------------------- acqStatic = btkTools.smartReader(DATA_PATH + calibrateFilenameLabelled) for key in MARKERSETS.keys(): logging.info("[pyCGM2] Checking of the %s" % (key)) # presence ip_presence = inspectProcedures.MarkerPresenceQualityProcedure( acqStatic, markers=MARKERSETS[key]) inspector = inspectFilters.QualityFilter(ip_presence) inspector.run() if ip_presence.markersIn != []: ip_gap = inspectProcedures.GapQualityProcedure( acqStatic, markers=ip_presence.markersIn) inspector = inspectFilters.QualityFilter(ip_gap) inspector.run() ip_swap = inspectProcedures.SwappingMarkerQualityProcedure( acqStatic, markers=ip_presence.markersIn) inspector = inspectFilters.QualityFilter(ip_swap) inspector.run() ip_pos = inspectProcedures.MarkerPositionQualityProcedure( acqStatic, markers=ip_presence.markersIn) inspector = inspectFilters.QualityFilter(ip_pos) # Calibration operation # -------------------- logging.info("[pyCGM2] --- calibration operation ---") model, acqStatic = cgm2_3.calibrate(DATA_PATH, calibrateFilenameLabelled, translators, settings, required_mp, optional_mp, False, leftFlatFoot, rightFlatFoot, headFlat, markerDiameter, hjcMethod, pointSuffix) logging.info("----- CALIBRATION- static file [%s]-----> DONE" % (calibrateFilenameLabelled)) # --------------------------MODEL FITTING ---------------------------------- logging.info( "--------------------------MODEL FITTING ----------------------------------" ) dynamicMeasurements = qtmTools.findDynamic(sessionXML) ik_flag = True modelledC3ds = list() eventInspectorStates = list() for dynamicMeasurement in dynamicMeasurements: # reconstructFilenameLabelled = qtmTools.getFilename(dynamicMeasurement) reconstructFilenameLabelled = qtmTools.getFilename(dynamicMeasurement) logging.info("----Processing of [%s]-----" % (reconstructFilenameLabelled)) mfpa = qtmTools.getForcePlateAssigment(dynamicMeasurement) momentProjection_text = sessionXML.Moment_Projection.text if momentProjection_text == "Default": momentProjection_text = settings["Fitting"]["Moment Projection"] if momentProjection_text == "Distal": momentProjection = enums.MomentProjection.Distal elif momentProjection_text == "Proximal": momentProjection = enums.MomentProjection.Proximal elif momentProjection_text == "Global": momentProjection = enums.MomentProjection.Global elif momentProjection_text == "JCS": momentProjection = enums.MomentProjection.JCS acq = btkTools.smartReader(DATA_PATH + reconstructFilenameLabelled) # Fitting checking # -------------------- for key in MARKERSETS.keys(): if key != "Calibration markers": logging.info("[pyCGM2] Checking of the %s" % (key)) # presence ip_presence = inspectProcedures.MarkerPresenceQualityProcedure( acq, markers=MARKERSETS[key]) inspector = inspectFilters.QualityFilter(ip_presence) inspector.run() if ip_presence.markersIn != []: ip_gap = inspectProcedures.GapQualityProcedure( acq, markers=ip_presence.markersIn) inspector = inspectFilters.QualityFilter(ip_gap) inspector.run() ip_swap = inspectProcedures.SwappingMarkerQualityProcedure( acq, markers=ip_presence.markersIn) inspector = inspectFilters.QualityFilter(ip_swap) inspector.run() ip_pos = inspectProcedures.MarkerPositionQualityProcedure( acq, markers=ip_presence.markersIn) inspector = inspectFilters.QualityFilter(ip_pos) # filtering # ----------------------- # marker order_marker = int( float(dynamicMeasurement.Marker_lowpass_filter_order.text)) fc_marker = float( dynamicMeasurement.Marker_lowpass_filter_frequency.text) # force plate order_fp = int( float(dynamicMeasurement.Forceplate_lowpass_filter_order.text)) fc_fp = float( dynamicMeasurement.Forceplate_lowpass_filter_frequency.text) # event checking # ----------------------- inspectprocedureEvents = inspectProcedures.GaitEventQualityProcedure( acq) inspector = inspectFilters.QualityFilter(inspectprocedureEvents) inspector.run() eventInspectorStates.append(inspectprocedureEvents.state) # fitting operation # ----------------------- logging.info("[pyCGM2] --- Fitting operation ---") acqGait = cgm2_3.fitting(model, DATA_PATH, reconstructFilenameLabelled, translators, settings, ik_flag, markerDiameter, pointSuffix, mfpa, momentProjection, fc_lowPass_marker=fc_marker, order_lowPass_marker=order_marker, fc_lowPass_forcePlate=fc_fp, order_lowPass_forcePlate=order_fp) outFilename = reconstructFilenameLabelled btkTools.smartWriter(acqGait, str(DATA_PATH + outFilename)) modelledC3ds.append(outFilename) logging.info("----Processing of [%s]-----> DONE" % (reconstructFilenameLabelled)) # --------------------------GAIT PROCESSING ----------------------- if not all(eventInspectorStates): raise Exception( "[pyCGM2] Impossible to run Gait processing. Badly gait event detection. check the log file" ) logging.info( "---------------------GAIT PROCESSING -----------------------") if createPDFReport: nds = normativeDatasets.Schwartz2008("Free") types = qtmTools.detectMeasurementType(sessionXML) for type in types: modelledTrials = list() for dynamicMeasurement in dynamicMeasurements: if qtmTools.isType(dynamicMeasurement, type): filename = qtmTools.getFilename(dynamicMeasurement) modelledTrials.append(filename) report.pdfGaitReport(DATA_PATH, model, modelledTrials, nds, pointSuffix, title=type) logging.info("----- Gait Processing -----> DONE")
def main(): parser = argparse.ArgumentParser(description='CGM2-3 Fitting') parser.add_argument( '--proj', type=str, help='Moment Projection. Choice : Distal, Proximal, Global') parser.add_argument('-md', '--markerDiameter', type=float, help='marker diameter') parser.add_argument('--noIk', action='store_true', help='cancel inverse kinematic') parser.add_argument('-ps', '--pointSuffix', type=str, help='suffix of model outputs') parser.add_argument('--check', action='store_true', help='force model output suffix') parser.add_argument('-a', '--accuracy', type=float, help='Inverse Kinematics accuracy') parser.add_argument('-ae', '--anomalyException', action='store_true', help='stop if anomaly detected ') parser.add_argument('-fi', '--frameInit', type=int, help='first frame to process') parser.add_argument('-fe', '--frameEnd', type=int, help='last frame to process') args = parser.parse_args() NEXUS = ViconNexus.ViconNexus() NEXUS_PYTHON_CONNECTED = NEXUS.Client.IsConnected() if NEXUS_PYTHON_CONNECTED: # run Operation # --------------------GLOBAL SETTINGS ------------------------------ # global setting ( in user/AppData) if os.path.isfile(pyCGM2.PYCGM2_APPDATA_PATH + "CGM2_3-pyCGM2.settings"): settings = files.openFile(pyCGM2.PYCGM2_APPDATA_PATH, "CGM2_3-pyCGM2.settings") else: settings = files.openFile(pyCGM2.PYCGM2_SETTINGS_FOLDER, "CGM2_3-pyCGM2.settings") # --------------------------CONFIG ------------------------------------ argsManager = CgmArgsManager.argsManager_cgm(settings, args) markerDiameter = argsManager.getMarkerDiameter() pointSuffix = argsManager.getPointSuffix("cgm2.3") momentProjection = argsManager.getMomentProjection() ik_flag = argsManager.enableIKflag ikAccuracy = argsManager.getIkAccuracy() # ----------------------LOADING------------------------------------------- DATA_PATH, reconstructFilenameLabelledNoExt = NEXUS.GetTrialName() reconstructFilenameLabelled = reconstructFilenameLabelledNoExt + ".c3d" LOGGER.logger.info("data Path: " + DATA_PATH) LOGGER.set_file_handler(DATA_PATH + "pyCGM2-Fitting.log") LOGGER.logger.info("calibration file: " + reconstructFilenameLabelled) # --------------------------SUBJECT ----------------------------------- # Notice : Work with ONE subject by session subjects = NEXUS.GetSubjectNames() subject = nexusTools.getActiveSubject(NEXUS) LOGGER.logger.info("Subject name : " + subject) # --------------------pyCGM2 MODEL ------------------------------ model = files.loadModel(DATA_PATH, subject) # -------------------------- MP ------------------------------------ # allow alteration of thigh offset model.mp_computed[ "LeftThighRotationOffset"] = NEXUS.GetSubjectParamDetails( subject, "LeftThighRotation")[0] model.mp_computed[ "RightThighRotationOffset"] = NEXUS.GetSubjectParamDetails( subject, "RightThighRotation")[0] # --------------------------CHECKING ----------------------------------- # check model LOGGER.logger.info("loaded model : %s" % (model.version)) if model.version != "CGM2.3": raise Exception( "%s-pyCGM2.model file was not calibrated from the CGM2.3 calibration pipeline" % subject) # --------------------------SESSION INFOS ------------------------------------ # translators management translators = files.getTranslators(DATA_PATH, "CGM2_3.translators") if not translators: translators = settings["Translators"] # ikweight ikWeight = files.getIKweightSet(DATA_PATH, "CGM2_3.ikw") if not ikWeight: ikWeight = settings["Fitting"]["Weight"] #force plate assignement from Nexus mfpa = nexusTools.getForcePlateAssignment(NEXUS) # btkAcquisition nacf = nexusFilters.NexusConstructAcquisitionFilter( DATA_PATH, reconstructFilenameLabelledNoExt, subject) acq = nacf.build() # --------------------------MODELLING PROCESSING ----------------------- finalAcqGait, detectAnomaly = cgm2_3.fitting( model, DATA_PATH, reconstructFilenameLabelled, translators, settings, ik_flag, markerDiameter, pointSuffix, mfpa, momentProjection, forceBtkAcq=acq, ikAccuracy=ikAccuracy, anomalyException=args.anomalyException, frameInit=args.frameInit, frameEnd=args.frameEnd) # ----------------------DISPLAY ON VICON------------------------------- nexusFilters.NexusModelFilter(NEXUS, model, finalAcqGait, subject, pointSuffix).run() nexusTools.createGeneralEvents(NEXUS, subject, finalAcqGait, ["Left-FP", "Right-FP"]) # ========END of the nexus OPERATION if run from Nexus ========= else: raise Exception("NO Nexus connection. Turn on Nexus")
def main(args): DATA_PATH = os.getcwd() + "\\" # User Settings if os.path.isfile(DATA_PATH + args.userFile): userSettings = files.openFile(DATA_PATH, args.userFile) else: raise Exception("user setting file not found") # internal (expert) Settings if args.expertFile: if os.path.isfile(DATA_PATH + args.expertFile): internalSettings = files.openFile(DATA_PATH, args.expertFile) else: raise Exception("expert setting file not found") else: internalSettings = None # translators if os.path.isfile(DATA_PATH + "CGM2_3.translators"): translators = files.openFile(DATA_PATH, "CGM2_3.translators") else: translators = None # localIkWeight if os.path.isfile(DATA_PATH + "CGM2_3.ikw"): localIkWeight = files.openFile(DATA_PATH, "CGM2_3.ikw") else: localIkWeight = None if args.vskFile: vsk = vskTools.Vsk(str(DATA_PATH + args.vskFile)) else: vsk = None # --- Manager ---- manager = ModelManager.CGM2_3ConfigManager( userSettings, localInternalSettings=internalSettings, localTranslators=translators, localIkWeight=localIkWeight, vsk=vsk) manager.contruct() finalSettings = manager.getFinalSettings() files.prettyDictPrint(finalSettings) logging.info("=============Calibration=============") model, finalAcqStatic = cgm2_3.calibrate(DATA_PATH, manager.staticTrial, manager.translators, finalSettings, manager.requiredMp, manager.optionalMp, manager.enableIK, manager.leftFlatFoot, manager.rightFlatFoot, manager.headFlat, manager.markerDiameter, manager.hjcMethod, manager.pointSuffix, displayCoordinateSystem=True) btkTools.smartWriter( finalAcqStatic, str(DATA_PATH + finalSettings["Calibration"]["StaticTrial"][:-4] + "-pyCGM2modelled.c3d")) logging.info("Static Calibration -----> Done") manager.updateMp(model) #files.prettyDictPrint(manager.finalSettings) logging.info("=============Fitting=============") for trial in manager.dynamicTrials: mfpa = None if trial["Mfpa"] == "Auto" else trial["Mfpa"] reconstructFilenameLabelled = trial["File"] acqGait = cgm2_3.fitting(model, DATA_PATH, reconstructFilenameLabelled, manager.translators, finalSettings, manager.enableIK, manager.markerDiameter, manager.pointSuffix, mfpa, manager.momentProjection, displayCoordinateSystem=True) btkTools.smartWriter( acqGait, str(DATA_PATH + reconstructFilenameLabelled[:-4] + "-pyCGM2modelled.c3d")) logging.info("---->dynamic trial (%s) processed" % (reconstructFilenameLabelled)) logging.info("=============Writing of final Settings=============") i = 0 while os.path.exists("CGM2.3 [%s].completeSettings" % i): i += 1 filename = "CGM2.3 [" + str(i) + "].completeSettings" files.saveJson(DATA_PATH, filename, finalSettings) logging.info("---->complete settings (%s) exported" % (filename)) raw_input("Press return to exit..")
def main(args): NEXUS = ViconNexus.ViconNexus() NEXUS_PYTHON_CONNECTED = NEXUS.Client.IsConnected() if NEXUS_PYTHON_CONNECTED: # run Operation # --------------------GLOBAL SETTINGS ------------------------------ # global setting ( in user/AppData) if os.path.isfile(pyCGM2.PYCGM2_APPDATA_PATH + "CGM2_3-pyCGM2.settings"): settings = files.openFile(pyCGM2.PYCGM2_APPDATA_PATH, "CGM2_3-pyCGM2.settings") else: settings = files.openFile(pyCGM2.PYCGM2_SETTINGS_FOLDER, "CGM2_3-pyCGM2.settings") # --------------------------CONFIG ------------------------------------ argsManager = CgmArgsManager.argsManager_cgm(settings, args) markerDiameter = argsManager.getMarkerDiameter() pointSuffix = argsManager.getPointSuffix("cgm2.3") momentProjection = argsManager.getMomentProjection() ik_flag = argsManager.enableIKflag() # ----------------------LOADING------------------------------------------- DATA_PATH, reconstructFilenameLabelledNoExt = NEXUS.GetTrialName() reconstructFilenameLabelled = reconstructFilenameLabelledNoExt + ".c3d" logging.info("data Path: " + DATA_PATH) logging.info("calibration file: " + reconstructFilenameLabelled) # --------------------------SUBJECT ----------------------------------- # Notice : Work with ONE subject by session subjects = NEXUS.GetSubjectNames() subject = nexusTools.checkActivatedSubject(NEXUS, subjects) logging.info("Subject name : " + subject) # --------------------pyCGM2 MODEL ------------------------------ model = files.loadModel(DATA_PATH, subject) # --------------------------CHECKING ----------------------------------- # check model logging.info("loaded model : %s" % (model.version)) if model.version != "CGM2.3": raise Exception( "%s-pyCGM2.model file was not calibrated from the CGM2.3 calibration pipeline" % subject) # --------------------------SESSION INFOS ------------------------------------ # translators management translators = files.getTranslators(DATA_PATH, "CGM2_3.translators") if not translators: translators = settings["Translators"] # ikweight ikWeight = files.getIKweightSet(DATA_PATH, "CGM2_3.ikw") if not ikWeight: ikWeight = settings["Fitting"]["Weight"] #force plate assignement from Nexus mfpa = nexusTools.getForcePlateAssignment(NEXUS) # btkAcquisition nacf = nexusFilters.NexusConstructAcquisitionFilter( DATA_PATH, reconstructFilenameLabelledNoExt, subject) acq = nacf.build() # --------------------------MODELLING PROCESSING ----------------------- finalAcqGait = cgm2_3.fitting(model, DATA_PATH, reconstructFilenameLabelled, translators, settings, ik_flag, markerDiameter, pointSuffix, mfpa, momentProjection, forceBtkAcq=acq) # ----------------------DISPLAY ON VICON------------------------------- nexusFilters.NexusModelFilter(NEXUS, model, finalAcqGait, subject, pointSuffix).run() nexusTools.createGeneralEvents(NEXUS, subject, finalAcqGait, ["Left-FP", "Right-FP"]) # ========END of the nexus OPERATION if run from Nexus ========= else: raise Exception("NO Nexus connection. Turn on Nexus")
def main(sessionFilename, createPDFReport=True, checkEventsInMokka=True, anomalyException=False): detectAnomaly = False LOGGER.set_file_handler("pyCGM2-QTM-Workflow.log") LOGGER.logger.info("------------QTM - pyCGM2 Workflow---------------") sessionXML = files.readXml(os.getcwd() + "\\", sessionFilename) sessionDate = files.getFileCreationDate(os.getcwd() + "\\" + sessionFilename) #--------------------------------------------------------------------------- #management of the Processed folder DATA_PATH = os.getcwd() + "\\" + "processed\\" files.createDir(DATA_PATH) staticMeasurement = qtmTools.findStatic(sessionXML) calibrateFilenameLabelled = qtmTools.getFilename(staticMeasurement) if not os.path.isfile(DATA_PATH + calibrateFilenameLabelled): shutil.copyfile(os.getcwd() + "\\" + calibrateFilenameLabelled, DATA_PATH + calibrateFilenameLabelled) LOGGER.logger.info( "qualisys exported c3d file [%s] copied to processed folder" % (calibrateFilenameLabelled)) if qtmTools.findKneeCalibration( sessionXML, "Left") is not None or qtmTools.findKneeCalibration( sessionXML, "Right") is not None: LOGGER.logger.info( " the %s not accept functional knee calibration !!" % (MODEL)) dynamicMeasurements = qtmTools.findDynamic(sessionXML) for dynamicMeasurement in dynamicMeasurements: reconstructFilenameLabelled = qtmTools.getFilename(dynamicMeasurement) # marker order_marker = int( float(dynamicMeasurement.Marker_lowpass_filter_order.text)) fc_marker = float( dynamicMeasurement.Marker_lowpass_filter_frequency.text) if not os.path.isfile(DATA_PATH + reconstructFilenameLabelled): shutil.copyfile(os.getcwd() + "\\" + reconstructFilenameLabelled, DATA_PATH + reconstructFilenameLabelled) LOGGER.logger.info( "qualisys exported c3d file [%s] copied to processed folder" % (reconstructFilenameLabelled)) acq = btkTools.smartReader( str(DATA_PATH + reconstructFilenameLabelled)) acq, zeniState = eventDetector.zeni( acq, fc_lowPass_marker=fc_marker, order_lowPass_marker=order_marker) if zeniState: btkTools.smartWriter( acq, str(DATA_PATH + reconstructFilenameLabelled)) if checkEventsInMokka: cmd = "Mokka.exe \"%s\"" % ( str(DATA_PATH + reconstructFilenameLabelled)) os.system(cmd) # --------------------------GLOBAL SETTINGS ------------------------------------ # global setting ( in user/AppData) if os.path.isfile(pyCGM2.PYCGM2_APPDATA_PATH + "CGM2_3-pyCGM2.settings"): settings = files.openFile(pyCGM2.PYCGM2_APPDATA_PATH, "CGM2_3-pyCGM2.settings") else: settings = files.openFile(pyCGM2.PYCGM2_SETTINGS_FOLDER, "CGM2_3-pyCGM2.settings") # --------------------------MP ------------------------------------ required_mp, optional_mp = qtmTools.SubjectMp(sessionXML) # translators management translators = files.getTranslators(os.getcwd() + "\\", "CGM2_3.translators") if not translators: translators = settings["Translators"] # ikweight ikWeight = files.getIKweightSet(DATA_PATH, "CGM2_3.ikw") if not ikWeight: ikWeight = settings["Fitting"]["Weight"] # --------------------------MODEL CALIBRATION ----------------------- LOGGER.logger.info( "--------------------------MODEL CALIBRATION -----------------------") staticMeasurement = qtmTools.findStatic(sessionXML) calibrateFilenameLabelled = qtmTools.getFilename(staticMeasurement) LOGGER.logger.info("----- CALIBRATION- static file [%s]--" % (calibrateFilenameLabelled)) leftFlatFoot = utils.toBool( sessionXML.Left_foot_normalised_to_static_trial.text) rightFlatFoot = utils.toBool( sessionXML.Right_foot_normalised_to_static_trial.text) headFlat = utils.toBool(sessionXML.Head_normalised_to_static_trial.text) markerDiameter = float(sessionXML.Marker_diameter.text) * 1000.0 hjcMethod = settings["Calibration"]["HJC"] pointSuffix = None # Calibration checking # -------------------- acqStatic = btkTools.smartReader(DATA_PATH + calibrateFilenameLabelled) # Calibration operation # -------------------- model, acqStatic, detectAnomaly = cgm2_3.calibrate( DATA_PATH, calibrateFilenameLabelled, translators, settings, required_mp, optional_mp, False, leftFlatFoot, rightFlatFoot, headFlat, markerDiameter, hjcMethod, pointSuffix, anomalyException=anomalyException) LOGGER.logger.info("----- CALIBRATION- static file [%s]-----> DONE" % (calibrateFilenameLabelled)) # --------------------------MODEL FITTING ---------------------------------- LOGGER.logger.info( "--------------------------MODEL FITTING ----------------------------------" ) dynamicMeasurements = qtmTools.findDynamic(sessionXML) ik_flag = True modelledC3ds = list() eventInspectorStates = list() for dynamicMeasurement in dynamicMeasurements: # reconstructFilenameLabelled = qtmTools.getFilename(dynamicMeasurement) reconstructFilenameLabelled = qtmTools.getFilename(dynamicMeasurement) LOGGER.logger.info("----Processing of [%s]-----" % (reconstructFilenameLabelled)) mfpa = qtmTools.getForcePlateAssigment(dynamicMeasurement) momentProjection_text = sessionXML.Moment_Projection.text if momentProjection_text == "Default": momentProjection_text = settings["Fitting"]["Moment Projection"] if momentProjection_text == "Distal": momentProjection = enums.MomentProjection.Distal elif momentProjection_text == "Proximal": momentProjection = enums.MomentProjection.Proximal elif momentProjection_text == "Global": momentProjection = enums.MomentProjection.Global elif momentProjection_text == "JCS": momentProjection = enums.MomentProjection.JCS acq = btkTools.smartReader(DATA_PATH + reconstructFilenameLabelled) # filtering # ----------------------- # marker order_marker = int( float(dynamicMeasurement.Marker_lowpass_filter_order.text)) fc_marker = float( dynamicMeasurement.Marker_lowpass_filter_frequency.text) # force plate order_fp = int( float(dynamicMeasurement.Forceplate_lowpass_filter_order.text)) fc_fp = float( dynamicMeasurement.Forceplate_lowpass_filter_frequency.text) # ik accuracy ikAccuracy = float(dynamicMeasurement.IkAccuracy.text) if dynamicMeasurement.First_frame_to_process.text != "": vff = int(dynamicMeasurement.First_frame_to_process.text) else: vff = None if dynamicMeasurement.Last_frame_to_process.text != "": vlf = int(dynamicMeasurement.Last_frame_to_process.text) else: vlf = None # fitting operation # ----------------------- LOGGER.logger.info("[pyCGM2] --- Fitting operation ---") acqGait, detectAnomaly = cgm2_3.fitting( model, DATA_PATH, reconstructFilenameLabelled, translators, settings, ik_flag, markerDiameter, pointSuffix, mfpa, momentProjection, fc_lowPass_marker=fc_marker, order_lowPass_marker=order_marker, fc_lowPass_forcePlate=fc_fp, order_lowPass_forcePlate=order_fp, anomalyException=anomalyException, ikAccuracy=ikAccuracy, frameInit=vff, frameEnd=vlf) outFilename = reconstructFilenameLabelled btkTools.smartWriter(acqGait, str(DATA_PATH + outFilename)) modelledC3ds.append(outFilename) LOGGER.logger.info("----Processing of [%s]-----> DONE" % (reconstructFilenameLabelled)) LOGGER.logger.info( "---------------------GAIT PROCESSING -----------------------") if createPDFReport: nds = normativeDatasets.NormativeData("Schwartz2008", "Free") types = qtmTools.detectMeasurementType(sessionXML) for type in types: modelledTrials = list() for dynamicMeasurement in dynamicMeasurements: if qtmTools.isType(dynamicMeasurement, type): filename = qtmTools.getFilename(dynamicMeasurement) # event checking # ----------------------- acq = btkTools.smartReader(DATA_PATH + filename) geap = AnomalyDetectionProcedure.GaitEventAnomalyProcedure( ) adf = AnomalyFilter.AnomalyDetectionFilter( acq, filename, geap) anomaly_events = adf.run() if anomaly_events["ErrorState"]: detectAnomaly = True LOGGER.logger.warning( "file [%s] not used for generating the gait report. bad gait event detected" % (filename)) else: modelledTrials.append(filename) try: report.pdfGaitReport(DATA_PATH, model, modelledTrials, nds, pointSuffix, title=type) LOGGER.logger.error("Generation of Gait report complete") except: LOGGER.logger.error("Generation of Gait report failed") LOGGER.logger.info( "-------------------------------------------------------") if detectAnomaly: LOGGER.logger.error( "Anomalies has been detected - Find Error messages, then check warning message in the log file" ) else: LOGGER.logger.info("workflow return with no detected anomalies")
def test_highLevel(self): DATA_PATH = pyCGM2.TEST_DATA_PATH + "GaitModels\CGM2.3\\Hannibal-medial\\" staticFilename = "static.c3d" reconstructFilenameLabelled= "gait1.c3d" markerDiameter=14 required_mp={ 'Bodymass' : 71.0, 'LeftLegLength' : 860.0, 'RightLegLength' : 865.0 , 'LeftKneeWidth' : 102.0, 'RightKneeWidth' : 103.4, 'LeftAnkleWidth' : 75.3, 'RightAnkleWidth' : 72.9, 'LeftSoleDelta' : 0, 'RightSoleDelta' : 0, 'LeftShoulderOffset' : 0, 'RightShoulderOffset' : 0, 'LeftElbowWidth' : 0, 'LeftWristWidth' : 0, 'LeftHandThickness' : 0, 'RightElbowWidth' : 0, 'RightWristWidth' : 0, 'RightHandThickness' : 0 } optional_mp = { 'LeftTibialTorsion' : 0, 'LeftThighRotation' : 0, 'LeftShankRotation' : 0, 'RightTibialTorsion' : 0, 'RightThighRotation' : 0, 'RightShankRotation' : 0 } settings = files.openFile(pyCGM2.PYCGM2_SETTINGS_FOLDER,"CGM2_3-pyCGM2.settings") model,finalAcqStatic,error = cgm2_3.calibrate(DATA_PATH, staticFilename, settings["Translators"], settings["Fitting"]["Weight"], required_mp, optional_mp, True, True, True, True, 14, settings["Calibration"]["HJC"], None, displayCoordinateSystem=True, noKinematicsCalculation=False) acqGait,error = cgm2_3.fitting(model,DATA_PATH, reconstructFilenameLabelled, settings["Translators"], settings, True,14.0, "acc2", "XX", momentProjection = enums.MomentProjection.JCS) outFilename = reconstructFilenameLabelled btkTools.smartWriter(acqGait, str(DATA_PATH + outFilename))
def main(): logging.info("------------------------------------------------") logging.info("------------QTM - pyCGM2 Workflow---------------") logging.info("------------------------------------------------") file="session.xml" sessionXML = files.readXml(os.getcwd()+"\\",file) sessionDate = files.getFileCreationDate(os.getcwd()+"\\"+file) #--------------------------------------------------------------------------- #management of the Processed folder DATA_PATH = os.getcwd()+"\\"+"processed\\" files.createDir(DATA_PATH) staticMeasurement = qtmTools.findStatic(sessionXML) calibrateFilenameLabelled = qtmTools.getFilename(staticMeasurement) if not os.path.isfile(DATA_PATH+calibrateFilenameLabelled): shutil.copyfile(os.getcwd()+"\\"+calibrateFilenameLabelled,DATA_PATH+calibrateFilenameLabelled) logging.info("qualisys exported c3d file [%s] copied to processed folder"%(calibrateFilenameLabelled)) dynamicMeasurements= qtmTools.findDynamic(sessionXML) for dynamicMeasurement in dynamicMeasurements: reconstructFilenameLabelled = qtmTools.getFilename(dynamicMeasurement) if not os.path.isfile(DATA_PATH+reconstructFilenameLabelled): shutil.copyfile(os.getcwd()+"\\"+reconstructFilenameLabelled,DATA_PATH+reconstructFilenameLabelled) logging.info("qualisys exported c3d file [%s] copied to processed folder"%(reconstructFilenameLabelled)) acq=btkTools.smartReader(str(DATA_PATH+reconstructFilenameLabelled)) if btkTools.checkForcePlateExist(acq): if "5" in btkTools.smartGetMetadata(acq,"FORCE_PLATFORM","TYPE"): forceplates.correctForcePlateType5(acq) acq,zeniState = eventDetector.zeni(acq) if zeniState: btkTools.smartWriter(acq, str(DATA_PATH + reconstructFilenameLabelled)) cmd = "Mokka.exe \"%s\""%(str(DATA_PATH + reconstructFilenameLabelled)) os.system(cmd) # --------------------------GLOBAL SETTINGS ------------------------------------ # global setting ( in user/AppData) if os.path.isfile(pyCGM2.PYCGM2_APPDATA_PATH + "CGM2_3-pyCGM2.settings"): settings = files.openFile(pyCGM2.PYCGM2_APPDATA_PATH,"CGM2_3-pyCGM2.settings") else: settings = files.openFile(pyCGM2.PYCGM2_SETTINGS_FOLDER,"CGM2_3-pyCGM2.settings") # --------------------------MP ------------------------------------ required_mp,optional_mp = qtmTools.SubjectMp(sessionXML) # --Check MP inspectprocedure = inspectProcedures.AnthropometricDataQualityProcedure(required_mp) inspector = inspectFilters.QualityFilter(inspectprocedure) inspector.run() # translators management translators = files.getTranslators(os.getcwd()+"\\","CGM2_3.translators") if not translators: translators = settings["Translators"] # ikweight ikWeight = files.getIKweightSet(DATA_PATH,"CGM2_3.ikw") if not ikWeight: ikWeight = settings["Fitting"]["Weight"] # --------------------------MODEL CALIBRATION ----------------------- logging.info("--------------------------MODEL CALIBRATION -----------------------") staticMeasurement = qtmTools.findStatic(sessionXML) calibrateFilenameLabelled = qtmTools.getFilename(staticMeasurement) logging.info("----- CALIBRATION- static file [%s]--"%(calibrateFilenameLabelled)) leftFlatFoot = toBool(staticMeasurement.Left_foot_normalised_to_static_trial.text) rightFlatFoot = toBool(staticMeasurement.Right_foot_normalised_to_static_trial.text) headFlat = toBool(staticMeasurement.Head_normalised_to_static_trial.text) markerDiameter = float(staticMeasurement.Marker_diameter.text)*1000.0 hjcMethod = settings["Calibration"]["HJC"] pointSuffix = None # Calibration checking # -------------------- acqStatic = btkTools.smartReader(DATA_PATH+calibrateFilenameLabelled) for key in MARKERSETS.keys(): logging.info("[pyCGM2] Checking of the %s"%(key)) # presence ip_presence = inspectProcedures.MarkerPresenceQualityProcedure(acqStatic, markers = MARKERSETS[key]) inspector = inspectFilters.QualityFilter(ip_presence) inspector.run() if ip_presence.markersIn !=[]: ip_gap = inspectProcedures.GapQualityProcedure(acqStatic, markers = ip_presence.markersIn) inspector = inspectFilters.QualityFilter(ip_gap) inspector.run() ip_swap = inspectProcedures.SwappingMarkerQualityProcedure(acqStatic, markers = ip_presence.markersIn) inspector = inspectFilters.QualityFilter(ip_swap) inspector.run() ip_pos = inspectProcedures.MarkerPositionQualityProcedure(acqStatic, markers = ip_presence.markersIn) inspector = inspectFilters.QualityFilter(ip_pos) # Calibration operation # -------------------- logging.info("[pyCGM2] --- calibration operation ---") model,acqStatic = cgm2_3.calibrate(DATA_PATH, calibrateFilenameLabelled, translators,settings, required_mp,optional_mp, False, leftFlatFoot,rightFlatFoot,headFlat,markerDiameter, hjcMethod, pointSuffix) logging.info("----- CALIBRATION- static file [%s]-----> DONE"%(calibrateFilenameLabelled)) # --------------------------MODEL FITTING ---------------------------------- logging.info("--------------------------MODEL FITTING ----------------------------------") dynamicMeasurements= qtmTools.findDynamic(sessionXML) ik_flag = True modelledC3ds = list() eventInspectorStates = list() for dynamicMeasurement in dynamicMeasurements: # reconstructFilenameLabelled = qtmTools.getFilename(dynamicMeasurement) reconstructFilenameLabelled = qtmTools.getFilename(dynamicMeasurement) logging.info("----Processing of [%s]-----"%(reconstructFilenameLabelled)) mfpa = qtmTools.getForcePlateAssigment(dynamicMeasurement) momentProjection_text = dynamicMeasurement.Moment_Projection.text if momentProjection_text == "Default": momentProjection_text = settings["Fitting"]["Moment Projection"] if momentProjection_text == "Distal": momentProjection = enums.MomentProjection.Distal elif momentProjection_text == "Proximal": momentProjection = enums.MomentProjection.Proximal elif momentProjection_text == "Global": momentProjection = enums.MomentProjection.Global elif momentProjection_text == "JCS": momentProjection = enums.MomentProjection.JCS acq = btkTools.smartReader(DATA_PATH+reconstructFilenameLabelled) # Fitting checking # -------------------- for key in MARKERSETS.keys(): if key != "Calibration markers": logging.info("[pyCGM2] Checking of the %s"%(key)) # presence ip_presence = inspectProcedures.MarkerPresenceQualityProcedure(acq, markers = MARKERSETS[key]) inspector = inspectFilters.QualityFilter(ip_presence) inspector.run() if ip_presence.markersIn !=[]: ip_gap = inspectProcedures.GapQualityProcedure(acq, markers = ip_presence.markersIn) inspector = inspectFilters.QualityFilter(ip_gap) inspector.run() ip_swap = inspectProcedures.SwappingMarkerQualityProcedure(acq, markers = ip_presence.markersIn) inspector = inspectFilters.QualityFilter(ip_swap) inspector.run() ip_pos = inspectProcedures.MarkerPositionQualityProcedure(acq, markers = ip_presence.markersIn) inspector = inspectFilters.QualityFilter(ip_pos) # filtering # ----------------------- # marker order = int(float(dynamicMeasurement.Marker_lowpass_filter_order.text)) fc = float(dynamicMeasurement.Marker_lowpass_filter_frequency.text) signal_processing.markerFiltering(acq,order=order, fc =fc) # management of force plate type 5 and force plate filtering order = int(float(dynamicMeasurement.Forceplate_lowpass_filter_order.text)) fc = float(dynamicMeasurement.Forceplate_lowpass_filter_frequency.text) if order!=0 and fc!=0: acq = btkTools.smartReader(DATA_PATH+reconstructFilenameLabelled) if btkTools.checkForcePlateExist(acq): if "5" in btkTools.smartGetMetadata(acq,"FORCE_PLATFORM","TYPE"): forceplates.correctForcePlateType5(acq) signal_processing.markerFiltering(acq,order=order, fc =fc) else: if btkTools.checkForcePlateExist(acq): if "5" in btkTools.smartGetMetadata(acq,"FORCE_PLATFORM","TYPE"): forceplates.correctForcePlateType5(acq) btkTools.smartWriter(acq,DATA_PATH+reconstructFilenameLabelled) # event checking # ----------------------- inspectprocedureEvents = inspectProcedures.GaitEventQualityProcedure(acq) inspector = inspectFilters.QualityFilter(inspectprocedureEvents) inspector.run() eventInspectorStates.append(inspectprocedureEvents.state) # fitting operation # ----------------------- logging.info("[pyCGM2] --- Fitting operation ---") acqGait = cgm2_3.fitting(model,DATA_PATH, reconstructFilenameLabelled, translators,settings, ik_flag,markerDiameter, pointSuffix, mfpa, momentProjection) outFilename = reconstructFilenameLabelled#[:-4] + "_CGM1.c3d" btkTools.smartWriter(acqGait, str(DATA_PATH + outFilename)) modelledC3ds.append(outFilename) logging.info("----Processing of [%s]-----> DONE"%(reconstructFilenameLabelled)) # --------------------------GAIT PROCESSING ----------------------- if not all(eventInspectorStates): raise Exception ("[pyCGM2] Impossible to run Gait processing. Badly gait event detection. check the log file") logging.info("---------------------GAIT PROCESSING -----------------------") nds = normativeDatasets.Schwartz2008("Free") types = qtmTools.detectMeasurementType(sessionXML) for type in types: modelledTrials = list() for dynamicMeasurement in dynamicMeasurements: if qtmTools.isType(dynamicMeasurement,type): filename = qtmTools.getFilename(dynamicMeasurement) modelledTrials.append(filename)#.replace(".c3d","_CGM1.c3d")) subjectMd = {"patientName": sessionXML.find("Last_name").text +" "+ sessionXML.find("First_name").text, "bodyHeight": sessionXML.find("Height").text, "bodyWeight": sessionXML.find("Weight").text , "diagnosis": sessionXML.find("Diagnosis").text, "dob": sessionXML.find("Date_of_birth").text, "sex": sessionXML.find("Sex").text, "test condition": type, "gmfcs": sessionXML.find("Gross_Motor_Function_Classification").text, "fms": sessionXML.find("Functional_Mobility_Scale").text} analysisInstance = analysis.makeAnalysis( DATA_PATH,modelledTrials, subjectInfo=None, experimentalInfo=None, modelInfo=None, pointLabelSuffix=None) title = type # spatiotemporal plot.plot_spatioTemporal(DATA_PATH,analysisInstance, exportPdf=True, outputName=title, show=None, title=title) #Kinematics if model.m_bodypart in [enums.BodyPart.LowerLimb,enums.BodyPart.LowerLimbTrunk, enums.BodyPart.FullBody]: plot.plot_DescriptiveKinematic(DATA_PATH,analysisInstance,"LowerLimb", nds, exportPdf=True, outputName=title, pointLabelSuffix=pointSuffix, show=False, title=title) plot.plot_ConsistencyKinematic(DATA_PATH,analysisInstance,"LowerLimb", nds, exportPdf=True, outputName=title, pointLabelSuffix=pointSuffix, show=False, title=title) if model.m_bodypart in [enums.BodyPart.LowerLimbTrunk, enums.BodyPart.FullBody]: plot.plot_DescriptiveKinematic(DATA_PATH,analysisInstance,"Trunk", nds, exportPdf=True, outputName=title, pointLabelSuffix=pointSuffix, show=False, title=title) plot.plot_ConsistencyKinematic(DATA_PATH,analysisInstance,"Trunk", nds, exportPdf=True, outputName=title, pointLabelSuffix=pointSuffix, show=False, title=title) if model.m_bodypart in [enums.BodyPart.UpperLimb, enums.BodyPart.FullBody]: pass # TODO plot upperlimb panel #Kinetics if model.m_bodypart in [enums.BodyPart.LowerLimb,enums.BodyPart.LowerLimbTrunk, enums.BodyPart.FullBody]: plot.plot_DescriptiveKinetic(DATA_PATH,analysisInstance,"LowerLimb", nds, exportPdf=True, outputName=title, pointLabelSuffix=pointSuffix, show=False, title=title) plot.plot_ConsistencyKinetic(DATA_PATH,analysisInstance,"LowerLimb", nds, exportPdf=True, outputName=title, pointLabelSuffix=pointSuffix, show=False, title=title) #MAP plot.plot_MAP(DATA_PATH,analysisInstance, nds, exportPdf=True, outputName=title,pointLabelSuffix=pointSuffix, show=False, title=title) plt.show(False) logging.info("----- Gait Processing -----> DONE")