diff --git a/.gitignore b/.gitignore index 4ac47683..6cf83e29 100644 --- a/.gitignore +++ b/.gitignore @@ -93,6 +93,7 @@ packrat/* # exclude data from source control by default data/external/* +!/data/external/empatica/empatica1/E4 Data.zip !/data/external/.gitkeep !/data/external/stachl_application_genre_catalogue.csv !/data/external/timesegments*.csv diff --git a/config.yaml b/config.yaml index 381e5cb0..290b8b89 100644 --- a/config.yaml +++ b/config.yaml @@ -509,7 +509,14 @@ EMPATICA_ELECTRODERMAL_ACTIVITY: SRC_SCRIPT: src/features/empatica_electrodermal_activity/dbdp/main.py CF: COMPUTE: True - FEATURES: ['mean', 'std', 'q25', 'q75', 'qd'] # To-Do add remaining features from CF helper file. + FEATURES: ['mean', 'std', 'q25', 'q75', 'qd', 'deriv', 'power', 'numPeaks', 'ratePeaks', 'powerPeaks', + 'sumPosDeriv', 'propPosDeriv', 'derivTonic', 'sigTonicDifference', 'freqFeats', + 'maxPeakAmplitudeChangeBefore', 'maxPeakAmplitudeChangeAfter', + 'avgPeakAmplitudeChangeBefore', 'avgPeakAmplitudeChangeAfter', 'avgPeakChangeRatio', + 'maxPeakIncreaseTime', 'maxPeakDecreaseTime', 'maxPeakDuration', 'maxPeakChangeRatio', + 'avgPeakIncreaseTime', 'avgPeakDecreaseTime', 'avgPeakDuration', 'maxPeakResponseSlopeBefore', + 'maxPeakResponseSlopeAfter', 'signalOverallChange', 'changeDuration', 'changeRate', + 'significantIncrease', 'significantDecrease'] SRC_SCRIPT: src/features/empatica_electrodermal_activity/cf/main.py # See https://www.rapids.science/latest/features/empatica-blood-volume-pulse/ diff --git a/data/external/empatica/empatica1/E4 Data.zip b/data/external/empatica/empatica1/E4 Data.zip index 40691f5f..bb1e36fe 100644 Binary files a/data/external/empatica/empatica1/E4 Data.zip and b/data/external/empatica/empatica1/E4 Data.zip differ diff --git a/src/features/empatica_electrodermal_activity/cf/main.py b/src/features/empatica_electrodermal_activity/cf/main.py index 524ebd99..54cb417d 100644 --- a/src/features/empatica_electrodermal_activity/cf/main.py +++ b/src/features/empatica_electrodermal_activity/cf/main.py @@ -1,57 +1,29 @@ import pandas as pd from scipy.stats import entropy +import sys +sys.path.insert(1, '/workspaces/rapids/calculatingfeatures') +from CalculatingFeatures.helper_functions import convert1DEmpaticaToArray, convertInputInto2d, gsrFeatureNames +from CalculatingFeatures.calculate_features import calculateFeatures -def statsFeatures(eda_data, features, eda_features): - col_name = "electrodermal_activity" - if "sumeda" in features: - eda_features["sumeda"] = eda_data[["local_segment", col_name]].groupby(["local_segment"])[ - col_name].sum() - if "maxeda" in features: - eda_features["maxeda"] = eda_data[["local_segment", col_name]].groupby(["local_segment"])[ - col_name].max() - if "mineda" in features: - eda_features["mineda"] = eda_data[["local_segment", col_name]].groupby(["local_segment"])[ - col_name].min() - if "avgeda" in features: - eda_features["avgeda"] = eda_data[["local_segment", col_name]].groupby(["local_segment"])[ - col_name].mean() - if "medianeda" in features: - eda_features["medianeda"] = eda_data[["local_segment", col_name]].groupby(["local_segment"])[ - col_name].median() - if "modeeda" in features: - eda_features["modeeda"] = eda_data[["local_segment", col_name]].groupby(["local_segment"])[ - col_name].agg(lambda x: pd.Series.mode(x)[0]) - if "stdeda" in features: - eda_features["stdeda"] = eda_data[["local_segment", col_name]].groupby(["local_segment"])[ - col_name].std() - if "diffmaxmodeeda" in features: - eda_features["diffmaxmodeeda"] = eda_data[["local_segment", col_name]].groupby(["local_segment"])[ - col_name].max() - \ - eda_data[["local_segment", col_name]].groupby(["local_segment"])[ - col_name].agg(lambda x: pd.Series.mode(x)[0]) - if "diffminmodeeda" in features: - eda_features["diffminmodeeda"] = eda_data[["local_segment", col_name]].groupby(["local_segment"])[ - col_name].agg(lambda x: pd.Series.mode(x)[0]) - \ - eda_data[["local_segment", col_name]].groupby(["local_segment"])[ - col_name].min() - if "entropyeda" in features: - eda_features["entropyeda"] = eda_data[["local_segment", col_name]].groupby(["local_segment"])[ - col_name].agg(entropy) +pd.set_option('display.max_columns', None) - return eda_features def extractEDAFeaturesFromIntradayData(eda_intraday_data, features, time_segment, filter_data_by_segment): eda_intraday_features = pd.DataFrame(columns=["local_segment"] + features) - if not eda_intraday_data.empty: + + if not eda_intraday_data.empty: eda_intraday_data = filter_data_by_segment(eda_intraday_data, time_segment) if not eda_intraday_data.empty: + eda_intraday_features = pd.DataFrame() - # get stats of eda - eda_intraday_features = statsFeatures(eda_intraday_data, features, eda_intraday_features) + # apply a method from calculate features module + eda_intraday_features = \ + eda_intraday_data.groupby('local_segment').apply(\ + lambda x: calculateFeatures(convertInputInto2d(x['electrodermal_activity'], x.shape[0]), fs=4, featureNames=features)) eda_intraday_features.reset_index(inplace=True) @@ -63,8 +35,7 @@ def cf_features(sensor_data_files, time_segment, provider, filter_data_by_segmen requested_intraday_features = provider["FEATURES"] # name of the features this function can compute - base_intraday_features_names = ["maxeda", "mineda", "avgeda", "medianeda", "modeeda", "stdeda", "diffmaxmodeeda", - "diffminmodeeda", "entropyeda"] + base_intraday_features_names = gsrFeatureNames # the subset of requested features this function can compute intraday_features_to_compute = list(set(requested_intraday_features) & set(base_intraday_features_names))