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 test_Kistler4_Noraxon1_Xsens1(self): NEXUS = ViconNexus.ViconNexus() DATA_PATH = pyCGM2.TEST_DATA_PATH + "NexusAPI\\BtkAcquisitionCreator\\sample0\\" filenameNoExt = "gait_cropped" NEXUS.OpenTrial(str(DATA_PATH + filenameNoExt), 30) subject = nexusTools.getActiveSubject(NEXUS) # btkAcq builder nacf = nexusFilters.NexusConstructAcquisitionFilter( DATA_PATH, filenameNoExt, subject) acq = nacf.build() acq0 = btkTools.smartReader(str(DATA_PATH + filenameNoExt + ".c3d")) np.testing.assert_array_almost_equal(acq.GetPoint("LTHI").GetValues(), acq0.GetPoint("LTHI").GetValues(), decimal=2) np.testing.assert_array_almost_equal( acq.GetAnalog("Force.Fx1").GetValues(), acq0.GetAnalog("Force.Fx1").GetValues(), decimal=2) np.testing.assert_equal(acq.GetPointFrequency(), acq0.GetPointFrequency()) np.testing.assert_equal(acq.GetNumberAnalogSamplePerFrame(), acq0.GetNumberAnalogSamplePerFrame()) np.testing.assert_equal(acq.GetAnalogFrequency(), acq0.GetAnalogFrequency()) np.testing.assert_equal( btkTools.smartGetMetadata(acq, "FORCE_PLATFORM", "USED"), btkTools.smartGetMetadata(acq0, "FORCE_PLATFORM", "USED")) np.testing.assert_array_almost_equal([ float(x) for x in np.asarray( btkTools.smartGetMetadata(acq, "FORCE_PLATFORM", "CORNERS")) ], [ float(x) for x in np.asarray( btkTools.smartGetMetadata(acq0, "FORCE_PLATFORM", "CORNERS")) ], decimal=2) np.testing.assert_array_almost_equal([ float(x) for x in np.asarray( btkTools.smartGetMetadata(acq, "FORCE_PLATFORM", "ORIGIN")) ], [ float(x) for x in np.asarray( btkTools.smartGetMetadata(acq0, "FORCE_PLATFORM", "ORIGIN")) ], decimal=2) np.testing.assert_array_almost_equal([ float(x) for x in np.asarray( btkTools.smartGetMetadata(acq, "FORCE_PLATFORM", "CHANNEL")) ], [ float(x) for x in np.asarray( btkTools.smartGetMetadata(acq0, "FORCE_PLATFORM", "CHANNEL")) ], decimal=2)
def prepare_folder_and_run_event_detection(sessionXML, work_folder, processed_folder): utils.create_directory_if_needed(processed_folder) staticMeasurement = utils.find_static(sessionXML) filename = qtmTools.getFilename(staticMeasurement) calibrated_file_path = os.path.join(processed_folder, filename) if not os.path.isfile(calibrated_file_path): shutil.copyfile(os.path.join(work_folder, filename), calibrated_file_path) logging.info( "qualisys exported c3d file [%s] copied to processed folder" % (filename)) dynamicMeasurements = qtmTools.findDynamic(sessionXML) for dynamicMeasurement in dynamicMeasurements: filename = qtmTools.getFilename(dynamicMeasurement) no_events_file_path = os.path.join(work_folder, filename) processed_file_path = os.path.join(processed_folder, filename) if not os.path.isfile(processed_file_path): shutil.copyfile(no_events_file_path, processed_file_path) logging.info( "qualisys exported c3d file [%s] copied to processed folder" % (filename)) acq = btkTools.smartReader(processed_file_path) if "5" in btkTools.smartGetMetadata(acq, "FORCE_PLATFORM", "TYPE"): forceplates.correctForcePlateType5(acq) acq, state = eventDetector.zeni(acq) btkTools.smartWriter(acq, processed_file_path)
def Kistler4_Noraxon1_Xsens1(cls): NEXUS = ViconNexus.ViconNexus() NEXUS_PYTHON_CONNECTED = NEXUS.Client.IsConnected() DATA_PATH = "C:\\Users\\HLS501\\Documents\\VICON DATA\\pyCGM2-Data\\NexusAPI\\BtkAcquisitionCreator\\sample0\\" filenameNoExt = "gait_cropped" NEXUS.OpenTrial(str(DATA_PATH + filenameNoExt), 30) subject = NEXUS.GetSubjectNames()[0] acqConstructorFilter = nexusFilters.NexusConstructAcquisitionFilter( filenameNoExt, subject) acq = acqConstructorFilter.build() acq0 = btkTools.smartReader(str(DATA_PATH + filenameNoExt + ".c3d")) np.testing.assert_array_almost_equal(acq.GetPoint("LTHI").GetValues(), acq0.GetPoint("LTHI").GetValues(), decimal=2) np.testing.assert_array_almost_equal( acq.GetAnalog("Force.Fx1").GetValues(), acq0.GetAnalog("Force.Fx1").GetValues(), decimal=2) np.testing.assert_equal(acq.GetPointFrequency(), acq0.GetPointFrequency()) np.testing.assert_equal(acq.GetNumberAnalogSamplePerFrame(), acq0.GetNumberAnalogSamplePerFrame()) np.testing.assert_equal(acq.GetAnalogFrequency(), acq0.GetAnalogFrequency()) np.testing.assert_equal( btkTools.smartGetMetadata(acq, "FORCE_PLATFORM", "USED"), btkTools.smartGetMetadata(acq0, "FORCE_PLATFORM", "USED")) np.testing.assert_array_almost_equal( map(float, btkTools.smartGetMetadata(acq, "FORCE_PLATFORM", "CORNERS")), map(float, btkTools.smartGetMetadata(acq0, "FORCE_PLATFORM", "CORNERS")), decimal=2) np.testing.assert_array_almost_equal( map(float, btkTools.smartGetMetadata(acq, "FORCE_PLATFORM", "ORIGIN")), map(float, btkTools.smartGetMetadata(acq0, "FORCE_PLATFORM", "ORIGIN")), decimal=2) np.testing.assert_equal( map(float, btkTools.smartGetMetadata(acq, "FORCE_PLATFORM", "CHANNEL")), map(float, btkTools.smartGetMetadata(acq0, "FORCE_PLATFORM", "CHANNEL")))
def filter_data(file_path, measurement): acq = btkTools.smartReader(file_path) if "5" in btkTools.smartGetMetadata(acq, "FORCE_PLATFORM", "TYPE"): forceplates.correctForcePlateType5(acq) # marker order = int(float(measurement.Marker_lowpass_filter_order.text)) fc = float(measurement.Marker_lowpass_filter_frequency.text) signal_processing.markerFiltering(acq, order=order, fc=fc) # force plate filtering order = int(float(measurement.Forceplate_lowpass_filter_order.text)) fc = float(measurement.Forceplate_lowpass_filter_frequency.text) if order != 0 and fc != 0: acq = btkTools.smartReader(file_path) if "5" in btkTools.smartGetMetadata(acq, "FORCE_PLATFORM", "TYPE"): forceplates.correctForcePlateType5(acq) signal_processing.markerFiltering(acq, order=order, fc=fc) btkTools.smartWriter(acq, file_path)
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 = utils.find_static(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_2-pyCGM2.settings"): settings = files.openFile(pyCGM2.PYCGM2_APPDATA_PATH, "CGM2_2-pyCGM2.settings") else: settings = files.openFile(pyCGM2.PYCGM2_SETTINGS_FOLDER, "CGM2_2-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_2.translators") if not translators: translators = settings["Translators"] # ikweight ikWeight = files.getIKweightSet(DATA_PATH, "CGM2_2.ikw") if not ikWeight: ikWeight = settings["Fitting"]["Weight"] # --------------------------MODEL CALIBRATION ----------------------- logging.info( "--------------------------MODEL CALIBRATION -----------------------") staticMeasurement = utils.find_static(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_2.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) 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_2.fitting(model, DATA_PATH, reconstructFilenameLabelled, translators, settings, 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 -----------------------") return model
def correctForcePlateType5(btkAcq): pfe = btk.btkForcePlatformsExtractor() pfe.SetInput(btkAcq) pfc = pfe.GetOutput() pfc.Update() md_force_platform = btkAcq.GetMetaData().FindChild( str("FORCE_PLATFORM")).value() md_force_platform_channels = btkAcq.GetMetaData().FindChild( str("FORCE_PLATFORM")).value().FindChild(str("CHANNEL")).value() md_force_platform.RemoveChild("CAL_MATRIX") md_force_platform.RemoveChild("MATRIX_STORE") md_channels = list() for i in btkTools.smartGetMetadata(btkAcq, 'FORCE_PLATFORM', "CHANNEL"): md_channels.append(i) pfds = [pfc.GetItem(0), pfc.GetItem(1)] forcePlateNumber = len(pfds) channel_number_byFp = list() for i in range(0, len(pfds)): if pfds[i].GetType() in [1, 2, 4]: channel_number_byFp.append(6) if pfds[i].GetType() in [3, 5]: channel_number_byFp.append(8) init = 0 channel_indexes_ofAnalog = list() for i in channel_number_byFp: channel_indexes_ofAnalog.append(md_channels[init:init + i]) init = i newChannelIndexes = [] for i in range(0, len(pfds)): if pfds[i].GetType() == 5: numAnalogs = btkAcq.GetAnalogNumber() analogChannels = np.zeros((8, btkAcq.GetAnalogFrameNumber())) j = 0 for index in channel_indexes_ofAnalog[i]: analogChannels[j, :] = btkAcq.GetAnalog(int(index) - 1).GetValues().T md_channels.remove(index) j += 1 wrench = np.dot( pfds[i].GetCalMatrix().T.reshape(8, 6).T, analogChannels ) # warning : storage of cal_matrix of type5 force plate is wrong in btk. force = wrench[0:3, :].T moment = wrench[3:6, :].T origin = pfds[i].GetOrigin() corners = pfds[i].GetCorners() btkTools.smartAppendAnalog(btkAcq, "Force.Fx" + str(i), force[:, 0], desc="virtual Force plate") btkTools.smartAppendAnalog(btkAcq, "Force.Fy" + str(i), force[:, 1], desc="virtual Force plate") btkTools.smartAppendAnalog(btkAcq, "Force.Fz" + str(i), force[:, 2], desc="virtual Force plate") btkTools.smartAppendAnalog(btkAcq, "Moment.Mx" + str(i), moment[:, 0], desc="virtual Force plate") btkTools.smartAppendAnalog(btkAcq, "Moment.My" + str(i), moment[:, 1], desc="virtual Force plate") btkTools.smartAppendAnalog(btkAcq, "Moment.Mz" + str(i), moment[:, 2], desc="virtual Force plate") new_channel_indexes_ofAnalog = range(numAnalogs, numAnalogs + 6) numAnalogs = btkAcq.GetAnalogNumber() btkTools.smartSetMetadata(btkAcq, 'FORCE_PLATFORM', "TYPE", i, str(2)) newChannelIndexes = newChannelIndexes + new_channel_indexes_ofAnalog else: newChannelIndexes = newChannelIndexes + channel_indexes_ofAnalog[i] md_newChannelIndexes = map(lambda x: x + 1, newChannelIndexes) md_force_platform_channels.SetInfo( btk.btkMetaDataInfo([6, int(forcePlateNumber)], md_newChannelIndexes)) btkAcq.GetMetaData().FindChild(str("FORCE_PLATFORM")).value().FindChild( str("ZERO")).value().SetInfo( btk.btkMetaDataInfo(btk.btkDoubleArray(forcePlateNumber, 0))) return btkAcq
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_2-pyCGM2.settings"): settings = files.openFile(pyCGM2.PYCGM2_APPDATA_PATH, "CGM2_2-pyCGM2.settings") else: settings = files.openFile(pyCGM2.PYCGM2_SETTINGS_FOLDER, "CGM2_2-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_2.translators") if not translators: translators = settings["Translators"] # ikweight ikWeight = files.getIKweightSet(DATA_PATH, "CGM2_2.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_2.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) 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_2.fitting(model, DATA_PATH, reconstructFilenameLabelled, translators, settings, 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")