Пример #1
0
def test_cwt():
    # Load/format data
    src = os.path.abspath(__file__ + '/../../')+'/demo/demo_data.csv'
    raw_data = pd.read_csv(src, skiprows=99, names=['timestamps', 'x', 'y', 'z'], usecols=[0, 1, 2, 3])
    raw_data = raw_data.iloc[3500:3700,:]
    raw_data['y'] = raw_data['y'] * 9.80665

    # Run function being tested
    obtained_ic_peaks, obtained_fc_peaks = util._cwt(raw_data.y, 50, 5, 10)

    # Confirm expected results
    np.testing.assert_array_equal(obtained_ic_peaks, [10,  43,  75, 110, 141, 171])
    np.testing.assert_array_equal(obtained_fc_peaks, [19,  50,  84, 117, 148, 179])
Пример #2
0
    def extract_features(self,
                         subject_height,
                         subject_height_units='centimeter',
                         sensor_height_ratio=0.53,
                         result_file=None,
                         classified_gait=None,
                         ic_prom=5,
                         fc_prom=25):
        ''' Continuous wavelet transform based method of gait feature detection optimization methods

        Parameters
        ----------
        subject_height : int or float
            Height of the subject. Accepts centimeters by default.

        subject_height_units : str
            Units of provided subject height. Centimeters by default.
            - options: 'centimeter', 'inches', 'meter'

        sensor_height_ratio : float
            Height of the sensor relative to subject height. Calculated: sensor height / subject height

        result_file : str
            Optional argument that accepts .csv filepath string to save resulting gait feature dataframe to.
            None by default. (ie. myfolder/myfile.csv)

        classified_gait : str or pandas.core.frame.DataFrame
            Pandas dataframe containing results of gait bout classification procedure (classify_bouts)
            OR
            File path of .h5 file containing results of gait bout classification procedure (classify_bouts)

        ic_prom : int
            Prominance of initial contact peak detection

        fc_prom : int
            Prominance of final contact peak detection

        '''
        import pandas as pd
        import gaitpy.util as util
        import warnings

        print('\tExtracting features...')

        # Load data
        y_accel, timestamps = util._load_data(self, self.down_sample)

        # If classified gait is provided, load pandas dataframe or h5 file
        if classified_gait is not None:
            if type(classified_gait) is str:
                gait_predictions = pd.read_hdf(classified_gait)
            elif type(classified_gait) is pd.core.frame.DataFrame:
                gait_predictions = classified_gait
            else:
                print(
                    'Unable to load classified gait: Please make sure the data is in the correct format, aborting...'
                )
                return
            # Isolate gait bouts
            gait_windows = gait_predictions[gait_predictions['prediction'] ==
                                            1]
            if gait_windows.empty:
                print(
                    'The classified_gait data indicates no bouts of gait were detected, aborting...'
                )
                return

            # Concatenate concurrent bouts
            gait_bouts = util._concatenate_windows(gait_windows,
                                                   window_length=3)
        else:
            # if classified_gait is not provided, assume entire timeseries is 1 bout of gait
            start_time = timestamps[0].astype('datetime64[ms]')
            end_time = timestamps.iloc[-1].astype('datetime64[ms]')
            gait_bouts = pd.DataFrame(
                data={
                    'start_time': [start_time],
                    'end_time': [end_time],
                    'bout_length': [(end_time -
                                     start_time).item().total_seconds()]
                })

        all_bout_gait_features = pd.DataFrame()
        bout_n = 1
        # Loop through gait bouts
        for row_n, bout in gait_bouts.iterrows():
            bout_indices = (
                timestamps.astype('datetime64[ms]') >= bout.start_time) & (
                    timestamps.astype('datetime64[ms]') <= bout.end_time)
            bout_data = pd.DataFrame([])
            bout_data['y'] = pd.DataFrame(
                y_accel.loc[bout_indices].reset_index(drop=True))
            bout_data['ts'] = timestamps.loc[bout_indices].reset_index(
                drop=True)
            if len(bout_data.y) < 15:
                warnings.warn('There are too few data points between ' +
                              str(bout.start_time) + ' and ' +
                              str(bout.end_time) + ', skipping bout...')
                continue

            # Run CWT Gait Model IC and FC detection
            ic_peaks, fc_peaks = util._cwt(bout_data.y, self.down_sample,
                                           ic_prom, fc_prom)

            # Run gait cycle optimization procedure
            pd.options.mode.chained_assignment = None
            optimized_gait = util._optimization(bout_data['ts'], ic_peaks,
                                                fc_peaks)
            if optimized_gait.empty or 1 not in list(
                    optimized_gait.Gait_Cycle):
                continue

            # Calculate changes in height of the center of mass
            optimized_gait = util._height_change_com(optimized_gait,
                                                     bout_data['ts'],
                                                     bout_data['y'],
                                                     self.down_sample)

            # Calculate gait features
            sensor_height = util._calculate_sensor_height(
                subject_height, subject_height_units, sensor_height_ratio)
            gait_features = util._cwt_feature_extraction(
                optimized_gait, sensor_height)

            # remove center of mass height and gait cycle boolean columns, remove rows with NAs
            gait_features.dropna(inplace=True)
            gait_features.drop(['CoM_height', 'Gait_Cycle', 'FC_opp_foot'],
                               axis=1,
                               inplace=True)

            gait_features.insert(0, 'bout_number', bout_n)
            gait_features.insert(1, 'bout_length_sec', bout.bout_length)
            gait_features.insert(2, 'bout_start_time', bout.start_time)
            gait_features.insert(5, 'gait_cycles', len(gait_features))
            all_bout_gait_features = all_bout_gait_features.append(
                gait_features)

            bout_n += 1
        all_bout_gait_features.reset_index(drop=True, inplace=True)
        all_bout_gait_features.iloc[:,
                                    7:] = all_bout_gait_features.iloc[:,
                                                                      7:].round(
                                                                          3)

        # Save results
        if result_file:
            try:
                if not result_file.endswith('.csv'):
                    result_file += '.csv'
                all_bout_gait_features.to_csv(result_file,
                                              index=False,
                                              float_format='%.3f')
            except:
                print(
                    'Unable to save data: Please make sure your results directory exists, aborting...'
                )
                return

        if all_bout_gait_features.empty:
            print(
                '\tFeature extraction complete. No gait cycles detected...\n')
        else:
            print('\tFeature extraction complete!\n')

        return all_bout_gait_features