def test_CGM24_FullBody_noOptions_uncorrectLowerLimbMarker(self): DATA_PATH = pyCGM2.TEST_DATA_PATH + "Scenarii\\different static and dynamic marker set\\CGM24-fullBody\\" staticFilename = "static.c3d" acqStatic = btkTools.smartReader(DATA_PATH + staticFilename) markerDiameter=14 leftFlatFoot = False rightFlatFoot = False headStraight = False pointSuffix = "test" vskFile = vskTools.getVskFiles(DATA_PATH) vsk = vskTools.Vsk(DATA_PATH + "PN07.vsk") required_mp,optional_mp = vskTools.getFromVskSubjectMp(vsk, resetFlag=True) settings = files.openFile(pyCGM2.PYCGM2_SETTINGS_FOLDER,"CGM2_4-pyCGM2.settings") hjcMethod = settings["Calibration"]["HJC"] translators = files.getTranslators(DATA_PATH,"CGM2_4.translators") # if not translators: translators = settings["Translators"] model,finalAcqStatic = cgm2_4.calibrate(DATA_PATH, staticFilename, translators, settings, required_mp, optional_mp, False, leftFlatFoot, rightFlatFoot, headStraight, markerDiameter, hjcMethod, pointSuffix, displayCoordinateSystem=True) # btkTools.smartWriter(finalAcqStatic, str( staticFilename[:-4]+"-pyCGM2modelled.c3d")) logging.info("Static Calibration -----> Done") gaitFilename="gait1_noLASI.c3d" mfpa = None reconstructFilenameLabelled = gaitFilename acqGait = cgm2_4.fitting(model,DATA_PATH, reconstructFilenameLabelled, translators, settings, False, markerDiameter, pointSuffix, mfpa, enums.MomentProjection.Proximal, displayCoordinateSystem=True) assert model.m_bodypart == enums.BodyPart.UpperLimb
def main(): parser = argparse.ArgumentParser(description='CGM2.4 Calibration') parser.add_argument('-l','--leftFlatFoot', type=int, help='left flat foot option') parser.add_argument('-r','--rightFlatFoot',type=int, help='right flat foot option') parser.add_argument('-hf','--headFlat',type=int, help='head flat option') parser.add_argument('-md','--markerDiameter', type=float, help='marker diameter') 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('--noIk', action='store_true', help='cancel inverse kinematic') parser.add_argument('--resetMP', action='store_true', help='reset optional mass parameters') parser.add_argument('--forceLHJC', nargs='+') parser.add_argument('--forceRHJC', nargs='+') parser.add_argument('-ae','--anomalyException', action='store_true', help='stop if anomaly detected ') args = parser.parse_args() NEXUS = ViconNexus.ViconNexus() NEXUS_PYTHON_CONNECTED = NEXUS.Client.IsConnected() if NEXUS_PYTHON_CONNECTED: # run Operation # --------------------GLOBAL SETTINGS ------------------------------ # ( in user/AppData) if os.path.isfile(pyCGM2.PYCGM2_APPDATA_PATH + "CGM2_4-pyCGM2.settings"): settings = files.openFile(pyCGM2.PYCGM2_APPDATA_PATH,"CGM2_4-pyCGM2.settings") else: settings = files.openFile(pyCGM2.PYCGM2_SETTINGS_FOLDER,"CGM2_4-pyCGM2.settings") argsManager = CgmArgsManager.argsManager_cgm(settings,args) leftFlatFoot = argsManager.getLeftFlatFoot() rightFlatFoot = argsManager.getRightFlatFoot() headFlat = argsManager.getHeadFlat() markerDiameter = argsManager.getMarkerDiameter() pointSuffix = argsManager.getPointSuffix("cgm2.4") ik_flag = argsManager.enableIKflag() hjcMethod = settings["Calibration"]["HJC"] lhjc = argsManager.forceHjc("left") rhjc = argsManager.forceHjc("right") if lhjc is not None: hjcMethod["Left"] = lhjc if rhjc is not None: hjcMethod["Right"] = rhjc # --------------------------LOADING------------------------------ DATA_PATH, calibrateFilenameLabelledNoExt = NEXUS.GetTrialName() calibrateFilenameLabelled = calibrateFilenameLabelledNoExt+".c3d" LOGGER.logger.info( "data Path: "+ DATA_PATH ) LOGGER.set_file_handler(DATA_PATH+"pyCGM2-Calibration.log") LOGGER.logger.info( "calibration file: "+ calibrateFilenameLabelled) # --------------------------SUBJECT ----------------------------------- # Notice : Work with ONE subject by session subjects = NEXUS.GetSubjectNames() subject = nexusTools.getActiveSubject(NEXUS) Parameters = NEXUS.GetSubjectParamNames(subject) required_mp,optional_mp = nexusUtils.getNexusSubjectMp(NEXUS,subject,resetFlag=args.resetMP) # --------------------------SESSION INFOS ----------------------------- # --------------------------SESSIONS INFOS ----------------------------------- mpInfo,mpFilename = files.getMpFileContent(DATA_PATH,"mp.pyCGM2",subject) # translators management translators = files.getTranslators(DATA_PATH,"CGM2_4.translators") if not translators: translators = settings["Translators"] # btkAcq builder nacf = nexusFilters.NexusConstructAcquisitionFilter(DATA_PATH,calibrateFilenameLabelledNoExt,subject) acq = nacf.build() # --------------------------CONFIG ------------------------------------ model,finalAcqStatic,detectAnomaly = cgm2_4.calibrate(DATA_PATH,calibrateFilenameLabelled,translators,settings, required_mp,optional_mp, ik_flag,leftFlatFoot,rightFlatFoot,headFlat, markerDiameter, hjcMethod, pointSuffix,forceBtkAcq=acq, anomalyException=args.anomalyException) # ----------------------SAVE------------------------------------------- files.saveModel(model,DATA_PATH,subject) # save mp files.saveMp(mpInfo,model,DATA_PATH,mpFilename) # ----------------------DISPLAY ON VICON------------------------------- nexusUtils.updateNexusSubjectMp(NEXUS,model,subject) nexusFilters.NexusModelFilter(NEXUS, model,finalAcqStatic,subject, pointSuffix, staticProcessing=True).run() # ========END of the nexus OPERATION if run from Nexus ========= else: raise Exception("NO Nexus connection. Turn on Nexus")
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_4-pyCGM2.settings"): settings = files.openFile(pyCGM2.PYCGM2_APPDATA_PATH, "CGM2_4-pyCGM2.settings") else: settings = files.openFile(pyCGM2.PYCGM2_SETTINGS_FOLDER, "CGM2_4-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_4.translators") if not translators: translators = settings["Translators"] # ikweight ikWeight = files.getIKweightSet(DATA_PATH, "CGM2_4.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_4.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) 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_4.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(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_4-pyCGM2.settings"): settings = files.openFile(pyCGM2.PYCGM2_APPDATA_PATH, "CGM2_4-pyCGM2.settings") else: settings = files.openFile(pyCGM2.PYCGM2_SETTINGS_FOLDER, "CGM2_4-pyCGM2.settings") # --------------------------MP ------------------------------------ required_mp, optional_mp = qtmTools.SubjectMp(sessionXML) # translators management translators = files.getTranslators(os.getcwd() + "\\", "CGM2_4.translators") if not translators: translators = settings["Translators"] # ikweight ikWeight = files.getIKweightSet(DATA_PATH, "CGM2_4.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 # -------------------- LOGGER.logger.info("[pyCGM2] --- calibration operation ---") model, acqStatic, detectAnomaly = cgm2_4.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) 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_4.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 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_4.translators"): translators = files.openFile(DATA_PATH, "CGM2_4.translators") else: translators = None # localIkWeight if os.path.isfile(DATA_PATH + "CGM2_4.ikw"): localIkWeight = files.openFile(DATA_PATH, "CGM2_4.ikw") else: localIkWeight = None if args.vskFile: vsk = vskTools.Vsk(str(DATA_PATH + args.vskFile)) else: vsk = None # --- Manager ---- manager = ModelManager.CGM2_4ConfigManager( userSettings, localInternalSettings=internalSettings, localTranslators=translators, localIkWeight=localIkWeight, vsk=vsk) manager.contruct() finalSettings = manager.getFinalSettings() files.prettyDictPrint(finalSettings) logging.info("=============Calibration=============") model, finalAcqStatic = cgm2_4.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_4.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.4 [%s].completeSettings" % i): i += 1 filename = "CGM2.4 [" + 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 ------------------------------ # ( in user/AppData) if os.path.isfile(pyCGM2.PYCGM2_APPDATA_PATH + "CGM2_4-pyCGM2.settings"): settings = files.openFile(pyCGM2.PYCGM2_APPDATA_PATH, "CGM2_4-pyCGM2.settings") else: settings = files.openFile(pyCGM2.PYCGM2_SETTINGS_FOLDER, "CGM2_4-pyCGM2.settings") argsManager = CgmArgsManager.argsManager_cgm(settings, args) leftFlatFoot = argsManager.getLeftFlatFoot() rightFlatFoot = argsManager.getRightFlatFoot() headFlat = argsManager.getHeadFlat() markerDiameter = argsManager.getMarkerDiameter() pointSuffix = argsManager.getPointSuffix("cgm2.4") ik_flag = argsManager.enableIKflag() hjcMethod = settings["Calibration"]["HJC"] lhjc = argsManager.forceHjc("left") rhjc = argsManager.forceHjc("right") if lhjc is not None: hjcMethod["Left"] = lhjc if rhjc is not None: hjcMethod["Right"] = rhjc # --------------------------LOADING------------------------------ DATA_PATH, calibrateFilenameLabelledNoExt = NEXUS.GetTrialName() calibrateFilenameLabelled = calibrateFilenameLabelledNoExt + ".c3d" logging.info("data Path: " + DATA_PATH) logging.info("calibration file: " + calibrateFilenameLabelled) # --------------------------SUBJECT ----------------------------------- # Notice : Work with ONE subject by session subjects = NEXUS.GetSubjectNames() subject = nexusTools.checkActivatedSubject(NEXUS, subjects) Parameters = NEXUS.GetSubjectParamNames(subject) required_mp, optional_mp = nexusUtils.getNexusSubjectMp( NEXUS, subject, resetFlag=args.resetMP) # --------------------------SESSION INFOS ----------------------------- # --------------------------SESSIONS INFOS ----------------------------------- mpInfo, mpFilename = files.getMpFileContent(DATA_PATH, "mp.pyCGM2", subject) # translators management translators = files.getTranslators(DATA_PATH, "CGM2_4.translators") if not translators: translators = settings["Translators"] # btkAcq builder nacf = nexusFilters.NexusConstructAcquisitionFilter( DATA_PATH, calibrateFilenameLabelledNoExt, subject) acq = nacf.build() # --------------------------CONFIG ------------------------------------ model, finalAcqStatic = cgm2_4.calibrate(DATA_PATH, calibrateFilenameLabelled, translators, settings, required_mp, optional_mp, ik_flag, leftFlatFoot, rightFlatFoot, headFlat, markerDiameter, hjcMethod, pointSuffix, forceBtkAcq=acq) # ----------------------SAVE------------------------------------------- files.saveModel(model, DATA_PATH, subject) # save mp files.saveMp(mpInfo, model, DATA_PATH, mpFilename) # ----------------------DISPLAY ON VICON------------------------------- nexusUtils.updateNexusSubjectMp(NEXUS, model, subject) nexusFilters.NexusModelFilter(NEXUS, model, finalAcqStatic, subject, pointSuffix, staticProcessing=True).run() # ========END of the nexus OPERATION if run from Nexus ========= else: raise Exception("NO Nexus connection. Turn on Nexus")
def test_issue_jointForce_CGM24(self): """ synopsis : inverted sign of the x-component of the joint force with CGM1.1 to CGM2.4 """ DATA_PATH = MAIN_PATH = pyCGM2.TEST_DATA_PATH + "Issues\\StephenM\\sign_jointForce_CGM24\\" staticFilename = "FullBody CGM2 data Cal 01.c3d" acqStatic = btkTools.smartReader(DATA_PATH + staticFilename) markerDiameter = 14 leftFlatFoot = False rightFlatFoot = False headStraight = False pointSuffix = "test" vskFile = vskTools.getVskFiles(DATA_PATH) vsk = vskTools.Vsk(DATA_PATH + "Nick.vsk") required_mp, optional_mp = vskTools.getFromVskSubjectMp(vsk, resetFlag=True) settings = files.openFile(pyCGM2.PYCGM2_APPDATA_PATH, "CGM2_4-pyCGM2.settings") model, finalAcqStatic = cgm2_4.calibrate(DATA_PATH, staticFilename, None, settings, required_mp, optional_mp, True, leftFlatFoot, rightFlatFoot, headStraight, markerDiameter, { "Left": "Hara", "Right": "Hara" }, pointSuffix, displayCoordinateSystem=True) # btkTools.smartWriter(finalAcqStatic, str( staticFilename[:-4]+"-pyCGM2modelled.c3d")) # logging.info("Static Calibration -----> Done") gaitFilename = "Capture 02.Distal.c3d" mfpa = "R" reconstructFilenameLabelled = gaitFilename acqGait = cgm2_4.fitting(model, DATA_PATH, reconstructFilenameLabelled, None, settings, True, markerDiameter, pointSuffix, mfpa, enums.MomentProjection.Distal, displayCoordinateSystem=True) testingUtils.plotComparisonOfPoint(acqGait, "RAnkleForce", "test", title="RAnkleForce PiG - CGM24") testingUtils.plotComparisonOfPoint(acqGait, "RKneeForce", "test", title="RKneeForce PiG - CGM24") testingUtils.plotComparisonOfPoint(acqGait, "RHipForce", "test", title="RHipForce PiG - CGM24")
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_4-pyCGM2.settings"): settings = files.openFile(pyCGM2.PYCGM2_APPDATA_PATH, "CGM2_4-pyCGM2.settings") else: settings = files.openFile(pyCGM2.PYCGM2_SETTINGS_FOLDER, "CGM2_4-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_4.translators") if not translators: translators = settings["Translators"] # ikweight ikWeight = files.getIKweightSet(DATA_PATH, "CGM2_4.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_4.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) 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_4.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")