paradigma 0.3.2__py3-none-any.whl → 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- paradigma/assets/gait_detection_clf_package.pkl +0 -0
- paradigma/assets/gait_filtering_clf_package.pkl +0 -0
- paradigma/assets/ppg_quality_clf_package.pkl +0 -0
- paradigma/assets/tremor_detection_clf_package.pkl +0 -0
- paradigma/classification.py +115 -0
- paradigma/config.py +314 -0
- paradigma/constants.py +48 -7
- paradigma/feature_extraction.py +811 -547
- paradigma/pipelines/__init__.py +0 -0
- paradigma/pipelines/gait_pipeline.py +727 -0
- paradigma/pipelines/heart_rate_pipeline.py +426 -0
- paradigma/pipelines/heart_rate_utils.py +780 -0
- paradigma/pipelines/tremor_pipeline.py +299 -0
- paradigma/preprocessing.py +363 -0
- paradigma/segmenting.py +396 -0
- paradigma/testing.py +416 -0
- paradigma/util.py +393 -16
- {paradigma-0.3.2.dist-info → paradigma-0.4.0.dist-info}/METADATA +58 -14
- paradigma-0.4.0.dist-info/RECORD +22 -0
- {paradigma-0.3.2.dist-info → paradigma-0.4.0.dist-info}/WHEEL +1 -1
- paradigma/gait_analysis.py +0 -415
- paradigma/gait_analysis_config.py +0 -266
- paradigma/heart_rate_analysis.py +0 -127
- paradigma/heart_rate_analysis_config.py +0 -9
- paradigma/heart_rate_util.py +0 -173
- paradigma/imu_preprocessing.py +0 -232
- paradigma/ppg/classifier/LR_PPG_quality.pkl +0 -0
- paradigma/ppg/classifier/LR_model.mat +0 -0
- paradigma/ppg/feat_extraction/acc_feature.m +0 -20
- paradigma/ppg/feat_extraction/peakdet.m +0 -64
- paradigma/ppg/feat_extraction/ppg_features.m +0 -53
- paradigma/ppg/glob_functions/extract_hr_segments.m +0 -37
- paradigma/ppg/glob_functions/extract_overlapping_segments.m +0 -23
- paradigma/ppg/glob_functions/jsonlab/AUTHORS.txt +0 -41
- paradigma/ppg/glob_functions/jsonlab/ChangeLog.txt +0 -74
- paradigma/ppg/glob_functions/jsonlab/LICENSE_BSD.txt +0 -25
- paradigma/ppg/glob_functions/jsonlab/LICENSE_GPLv3.txt +0 -699
- paradigma/ppg/glob_functions/jsonlab/README.txt +0 -394
- paradigma/ppg/glob_functions/jsonlab/examples/.svn/entries +0 -368
- paradigma/ppg/glob_functions/jsonlab/examples/.svn/text-base/demo_jsonlab_basic.m.svn-base +0 -180
- paradigma/ppg/glob_functions/jsonlab/examples/.svn/text-base/demo_ubjson_basic.m.svn-base +0 -180
- paradigma/ppg/glob_functions/jsonlab/examples/.svn/text-base/example1.json.svn-base +0 -23
- paradigma/ppg/glob_functions/jsonlab/examples/.svn/text-base/example2.json.svn-base +0 -22
- paradigma/ppg/glob_functions/jsonlab/examples/.svn/text-base/example3.json.svn-base +0 -11
- paradigma/ppg/glob_functions/jsonlab/examples/.svn/text-base/example4.json.svn-base +0 -34
- paradigma/ppg/glob_functions/jsonlab/examples/.svn/text-base/jsonlab_basictest.matlab.svn-base +0 -662
- paradigma/ppg/glob_functions/jsonlab/examples/.svn/text-base/jsonlab_selftest.m.svn-base +0 -27
- paradigma/ppg/glob_functions/jsonlab/examples/.svn/text-base/jsonlab_selftest.matlab.svn-base +0 -144
- paradigma/ppg/glob_functions/jsonlab/examples/.svn/text-base/jsonlab_speedtest.m.svn-base +0 -21
- paradigma/ppg/glob_functions/jsonlab/examples/demo_jsonlab_basic.m +0 -180
- paradigma/ppg/glob_functions/jsonlab/examples/demo_ubjson_basic.m +0 -180
- paradigma/ppg/glob_functions/jsonlab/examples/example1.json +0 -23
- paradigma/ppg/glob_functions/jsonlab/examples/example2.json +0 -22
- paradigma/ppg/glob_functions/jsonlab/examples/example3.json +0 -11
- paradigma/ppg/glob_functions/jsonlab/examples/example4.json +0 -34
- paradigma/ppg/glob_functions/jsonlab/examples/jsonlab_basictest.matlab +0 -662
- paradigma/ppg/glob_functions/jsonlab/examples/jsonlab_selftest.m +0 -27
- paradigma/ppg/glob_functions/jsonlab/examples/jsonlab_selftest.matlab +0 -144
- paradigma/ppg/glob_functions/jsonlab/examples/jsonlab_speedtest.m +0 -21
- paradigma/ppg/glob_functions/jsonlab/jsonopt.m +0 -32
- paradigma/ppg/glob_functions/jsonlab/loadjson.m +0 -566
- paradigma/ppg/glob_functions/jsonlab/loadubjson.m +0 -528
- paradigma/ppg/glob_functions/jsonlab/mergestruct.m +0 -33
- paradigma/ppg/glob_functions/jsonlab/savejson.m +0 -475
- paradigma/ppg/glob_functions/jsonlab/saveubjson.m +0 -504
- paradigma/ppg/glob_functions/jsonlab/varargin2struct.m +0 -40
- paradigma/ppg/glob_functions/sample_prob_final.m +0 -49
- paradigma/ppg/glob_functions/synchronization.m +0 -76
- paradigma/ppg/glob_functions/tsdf_scan_meta.m +0 -22
- paradigma/ppg/hr_functions/Long_TFD_JOT.m +0 -37
- paradigma/ppg/hr_functions/PPG_TFD_HR.m +0 -59
- paradigma/ppg/hr_functions/TFD toolbox JOT/.gitignore +0 -4
- paradigma/ppg/hr_functions/TFD toolbox JOT/CHANGELOG.md +0 -23
- paradigma/ppg/hr_functions/TFD toolbox JOT/LICENCE.md +0 -27
- paradigma/ppg/hr_functions/TFD toolbox JOT/README.md +0 -251
- paradigma/ppg/hr_functions/TFD toolbox JOT/README.pdf +0 -0
- paradigma/ppg/hr_functions/TFD toolbox JOT/common/gen_Doppler_kern.m +0 -142
- paradigma/ppg/hr_functions/TFD toolbox JOT/common/gen_Doppler_lag_kern.m +0 -314
- paradigma/ppg/hr_functions/TFD toolbox JOT/common/gen_lag_kern.m +0 -123
- paradigma/ppg/hr_functions/TFD toolbox JOT/dec_tfd.m +0 -154
- paradigma/ppg/hr_functions/TFD toolbox JOT/decimated_TFDs/dec_di_gdtfd.m +0 -194
- paradigma/ppg/hr_functions/TFD toolbox JOT/decimated_TFDs/dec_li_gdtfd.m +0 -200
- paradigma/ppg/hr_functions/TFD toolbox JOT/decimated_TFDs/dec_nonsep_gdtfd.m +0 -229
- paradigma/ppg/hr_functions/TFD toolbox JOT/decimated_TFDs/dec_sep_gdtfd.m +0 -241
- paradigma/ppg/hr_functions/TFD toolbox JOT/full_TFDs/di_gdtfd.m +0 -157
- paradigma/ppg/hr_functions/TFD toolbox JOT/full_TFDs/li_gdtfd.m +0 -190
- paradigma/ppg/hr_functions/TFD toolbox JOT/full_TFDs/nonsep_gdtfd.m +0 -196
- paradigma/ppg/hr_functions/TFD toolbox JOT/full_TFDs/sep_gdtfd.m +0 -199
- paradigma/ppg/hr_functions/TFD toolbox JOT/full_tfd.m +0 -144
- paradigma/ppg/hr_functions/TFD toolbox JOT/load_curdir.m +0 -13
- paradigma/ppg/hr_functions/TFD toolbox JOT/pics/decimated_TFDs_examples.png +0 -0
- paradigma/ppg/hr_functions/TFD toolbox JOT/pics/full_TFDs_examples.png +0 -0
- paradigma/ppg/hr_functions/TFD toolbox JOT/utils/check_dec_params_seq.m +0 -79
- paradigma/ppg/hr_functions/TFD toolbox JOT/utils/dispEE.m +0 -9
- paradigma/ppg/hr_functions/TFD toolbox JOT/utils/dispVars.m +0 -26
- paradigma/ppg/hr_functions/TFD toolbox JOT/utils/disp_bytes.m +0 -25
- paradigma/ppg/hr_functions/TFD toolbox JOT/utils/fold_vector_full.m +0 -40
- paradigma/ppg/hr_functions/TFD toolbox JOT/utils/fold_vector_half.m +0 -34
- paradigma/ppg/hr_functions/TFD toolbox JOT/utils/gen_LFM.m +0 -29
- paradigma/ppg/hr_functions/TFD toolbox JOT/utils/get_analytic_signal.m +0 -76
- paradigma/ppg/hr_functions/TFD toolbox JOT/utils/get_window.m +0 -176
- paradigma/ppg/hr_functions/TFD toolbox JOT/utils/isreal_fn.m +0 -11
- paradigma/ppg/hr_functions/TFD toolbox JOT/utils/padWin.m +0 -97
- paradigma/ppg/hr_functions/TFD toolbox JOT/utils/vtfd.m +0 -149
- paradigma/ppg/preprocessing/preprocessing_imu.m +0 -15
- paradigma/ppg/preprocessing/preprocessing_ppg.m +0 -13
- paradigma/ppg_preprocessing.py +0 -313
- paradigma/preprocessing_config.py +0 -69
- paradigma/quantification.py +0 -58
- paradigma/tremor/TremorFeaturesAndClassification.m +0 -345
- paradigma/tremor/feat_extraction/DerivativesExtract.m +0 -22
- paradigma/tremor/feat_extraction/ExtractBandSignalsRMS.m +0 -72
- paradigma/tremor/feat_extraction/MFCCExtract.m +0 -100
- paradigma/tremor/feat_extraction/PSDBandPower.m +0 -52
- paradigma/tremor/feat_extraction/PSDEst.m +0 -63
- paradigma/tremor/feat_extraction/PSDExtrAxis.m +0 -88
- paradigma/tremor/feat_extraction/PSDExtrOpt.m +0 -95
- paradigma/tremor/preprocessing/InterpData.m +0 -32
- paradigma/tremor/weekly_aggregates/WeeklyAggregates.m +0 -295
- paradigma/windowing.py +0 -219
- paradigma-0.3.2.dist-info/RECORD +0 -108
- {paradigma-0.3.2.dist-info → paradigma-0.4.0.dist-info}/LICENSE +0 -0
|
@@ -1,345 +0,0 @@
|
|
|
1
|
-
% #########################################################################
|
|
2
|
-
% Input
|
|
3
|
-
% Conf - Structure
|
|
4
|
-
% .WindowSizeTime - scalar - double - time of the window in seconds
|
|
5
|
-
% .Fs - scalar - double - sampling frequency in Hz
|
|
6
|
-
%
|
|
7
|
-
% Data_In - cell - array - double - Nsamples x Nchannels - IMU signal in
|
|
8
|
-
% columns [x y z]
|
|
9
|
-
%
|
|
10
|
-
% t - cell - array - double - Nsamples x 1 - IMU time stamp -
|
|
11
|
-
% Unix time corrected (interpolated)
|
|
12
|
-
%
|
|
13
|
-
% Type of the signal - string - IMU type of signal 'Gy' - gyroscope
|
|
14
|
-
% 'Ac' - acceleration
|
|
15
|
-
%
|
|
16
|
-
% #########################################################################
|
|
17
|
-
% Output
|
|
18
|
-
% Features - structure
|
|
19
|
-
% .WindowIniTime - array - double - Nwindows x 1 - Unix Corrected Time (after interpolation) -
|
|
20
|
-
% Initial time stamp of the window
|
|
21
|
-
%
|
|
22
|
-
% .Derivatives - table - double - Nwindows x 3 - Mean angular velocity absolute derivatives for each axis (columns):
|
|
23
|
-
% .GyMeanDx - x-axis
|
|
24
|
-
% .GyMeanDy - y-axis
|
|
25
|
-
% .GyMeanDz - z-axis
|
|
26
|
-
%
|
|
27
|
-
% .PowerAxis - table - double - Nwindows x 3 - Full band power axis (0.5-25 Hz) (columns):
|
|
28
|
-
% .GyPowerX - x-axis
|
|
29
|
-
% .GyPowerY - y-axis
|
|
30
|
-
% .GyPowerZ - z-axis
|
|
31
|
-
%
|
|
32
|
-
% .DomTremorPowerAxis - table - double - Nwindows x 3 - Tremor dominant power (3-7 Hz) for each axis (columns):
|
|
33
|
-
% .GyLTreDomPowerX - x-axis
|
|
34
|
-
% .GyLTreDomPowerY - y-axis
|
|
35
|
-
% .GyLTreDomPowerZ - z-axis
|
|
36
|
-
%
|
|
37
|
-
% .FreqPeak - table - double - Nwindows x 1 - Dominant
|
|
38
|
-
% frequency in the PSD summed spectrum (PSD = PSDx + PSDy + PSDz) within the range 1-25Hz per
|
|
39
|
-
% window
|
|
40
|
-
% .GyFreqPeak - frequency of
|
|
41
|
-
% the PSD peak
|
|
42
|
-
|
|
43
|
-
% .PSDTremorFeatures - table - double - Nwindows x 3 - PSD-based
|
|
44
|
-
% featured extracted in the tremor range (3-7) Hz per window
|
|
45
|
-
% - orientation invariant (PSD = PSDx + PSDy + PSDz)
|
|
46
|
-
% .GyLTreBandPower - power in the tremor range
|
|
47
|
-
% .GyLTreFreqPeak - dominant frequency in the tremor range
|
|
48
|
-
% .GyLTreDomPower - dominant power 1.25 Hz around the tremor peak
|
|
49
|
-
%
|
|
50
|
-
% .PSDHighTremorFeatures - table - double - Nwindows x 3 - PSD-based
|
|
51
|
-
% featured extracted in the high tremor range (7-12) Hz per window
|
|
52
|
-
% - orientation invariant (PSD = PSDx + PSDy + PSDz)
|
|
53
|
-
% .GyHTreBandPower - power in the high tremor range
|
|
54
|
-
% .GyHTreFreqPeak - dominant frequency in the high tremor range
|
|
55
|
-
% .GyHTreDomPower - dominant power 1.25 Hz around the high tremor peak
|
|
56
|
-
%
|
|
57
|
-
% .MelCepsCoeff - table - double - Nwindows x 12 -
|
|
58
|
-
% Mel-Frequency cepstral coefficients from 1 to 12 per window -
|
|
59
|
-
% orientation invariant (sum spectrograms x, y, z)
|
|
60
|
-
% .GyMFCC1 - 1st MFCC coefficient
|
|
61
|
-
% .GyMFCC2 - 2nd MFCC coefficient
|
|
62
|
-
% ...
|
|
63
|
-
% .GyMFCC12 - 12th MFCC coefficient
|
|
64
|
-
%
|
|
65
|
-
%
|
|
66
|
-
% .PowerArmActv - table - double Nwindows x 1 - Power in the Arm Activity
|
|
67
|
-
% frequency range (0.5 - 3 Hz)
|
|
68
|
-
% .GyArmActvPower - power in the range (0.5 - 3 Hz)
|
|
69
|
-
%
|
|
70
|
-
%
|
|
71
|
-
% .PowerHighFreq - table - double Nwindows x 1 - Power in the high frequency domain (12-25 Hz)
|
|
72
|
-
% .GyHighFreqPower - power in the
|
|
73
|
-
% range (12-25 Hz)
|
|
74
|
-
%
|
|
75
|
-
% .TremorProb - array - double - Nwindows x 1 - tremor
|
|
76
|
-
% probability obtained by logistic regression based on MFCCs
|
|
77
|
-
% features
|
|
78
|
-
%
|
|
79
|
-
% .TremorHat - array - double - Nwindows x 1 - tremor label obtained after applying threshold in the tremor probability
|
|
80
|
-
% .RestTremorHat - array - double - Nwindows x 1 - rest tremor
|
|
81
|
-
% label after logical AND operation between TremorHat and SpectralCheck (PSD peak falls within tremor domain [3 - 7 Hz])
|
|
82
|
-
% #########################################################################
|
|
83
|
-
|
|
84
|
-
function [Features] = TremorFeaturesAndClassification(Conf,Data_In,t,TypeOfSignal)
|
|
85
|
-
|
|
86
|
-
% Load Classifiers obtained from PD@Home
|
|
87
|
-
load('TremorClassifier2.mat'); % Load the updated tremor model
|
|
88
|
-
load('Threshold_total.mat'); % Load the threshold
|
|
89
|
-
|
|
90
|
-
TremorThr = Threshold_total; % Threshold at 95% specificity
|
|
91
|
-
|
|
92
|
-
load('MeanVectorPDhome.mat'); % Scaling parameters
|
|
93
|
-
load('SigmaVectorPDhome.mat'); % Scaling parameters
|
|
94
|
-
|
|
95
|
-
% Getting parameters
|
|
96
|
-
Fs = Conf.Fs; % Sampling frequency
|
|
97
|
-
WindowSizeTime = Conf.WindowSizeTime; % window interval in seconds
|
|
98
|
-
|
|
99
|
-
% Evaluating slicing parameters
|
|
100
|
-
DeltaSample = floor(WindowSizeTime*Fs); % number of samples for skipping to get the next window
|
|
101
|
-
% Introduce overlap between samples if needed
|
|
102
|
-
NumWindows = floor(length(Data_In(:,1))/DeltaSample); % number of windows given the segment size (Data_In)
|
|
103
|
-
|
|
104
|
-
% Initialize variables
|
|
105
|
-
WindowIniTime = [];
|
|
106
|
-
DomTremorPowerAxis = [];
|
|
107
|
-
PowerAxis = [];
|
|
108
|
-
|
|
109
|
-
MelCepsCoeff = [];
|
|
110
|
-
Derivatives = [];
|
|
111
|
-
PSDTremorFeatures = [];
|
|
112
|
-
PSDHighTremorFeatures = [];
|
|
113
|
-
FreqPeak = [];
|
|
114
|
-
ArmActvPower = [];
|
|
115
|
-
HighFreqPower = [];
|
|
116
|
-
|
|
117
|
-
TremorProb = [];
|
|
118
|
-
TremorHat = [];
|
|
119
|
-
PeakFreqTremorCheck = [];
|
|
120
|
-
RestTremorHat = [];
|
|
121
|
-
|
|
122
|
-
% Loop across the windows
|
|
123
|
-
for kk = 1:NumWindows
|
|
124
|
-
|
|
125
|
-
% Get the inital time stamp
|
|
126
|
-
WindowIniTime(kk) = t((kk-1)*DeltaSample+1);
|
|
127
|
-
|
|
128
|
-
% Slice data according WindowSizeTime
|
|
129
|
-
sig_x = Data_In(((kk-1)*DeltaSample+1):kk*DeltaSample,1);
|
|
130
|
-
sig_y = Data_In(((kk-1)*DeltaSample+1):kk*DeltaSample,2);
|
|
131
|
-
sig_z = Data_In(((kk-1)*DeltaSample+1):kk*DeltaSample,3);
|
|
132
|
-
|
|
133
|
-
DataMatrix = [sig_x sig_y sig_z]; % Concatenating Data - Signal Matrix
|
|
134
|
-
|
|
135
|
-
%% PSD estimation - Welch periodogram function parameters - Evaluate the Spectrum
|
|
136
|
-
% Configuration for power spectrum density (PSD) estimation
|
|
137
|
-
ConfPSD.Fs = Fs; % sampling frequency in Hz
|
|
138
|
-
ConfPSD.pwelchwin = 3*Fs; % number of samples for the subwindows used in the periodogram
|
|
139
|
-
ConfPSD.noverlap = round(0.8*ConfPSD.pwelchwin); % number of samples for overlapping subwindows
|
|
140
|
-
ConfPSD.nfft = 4*Fs; % NFFT number of samples - keep spectral resolution in 0.25 Hz
|
|
141
|
-
ConfPSD.freqmax = 25; % Maximum frequency to be considered
|
|
142
|
-
ConfPSD.freqmin = 1; % Lower frequency limit used in PSDest
|
|
143
|
-
% for estimating the dominant frequency in
|
|
144
|
-
% the range [freqmin freqmax] Hz. This low
|
|
145
|
-
% frequency cut is due to gyroscope drift and the presence of enhanced low frequency components in this case.
|
|
146
|
-
|
|
147
|
-
[PSDMatrix,FreqVect,FreqPeak(kk)] = PSDEst(ConfPSD,DataMatrix); % Get the PSD Matrix
|
|
148
|
-
|
|
149
|
-
% Check extra criterion for rest tremor: Does the dominant peak within
|
|
150
|
-
% 1-25 Hz falls into the tremor range (3-7) Hz
|
|
151
|
-
|
|
152
|
-
PeakFreqTremorCheck(kk) = (FreqPeak(kk) >= 3 & FreqPeak(kk) <= 7);
|
|
153
|
-
|
|
154
|
-
%% Mel-Cepstrum Coefficients Feature Extraction
|
|
155
|
-
% Configuration for MFCCs extraction
|
|
156
|
-
ConfMFCC.Fs = Fs; % Sampling Frequency
|
|
157
|
-
ConfMFCC.numFilters = 15; % Number of filters to be used in the Mel-scale
|
|
158
|
-
ConfMFCC.NumMelCoeff = 12; % number of MFCCs coefficients
|
|
159
|
-
ConfMFCC.StrAxis = 'Sum'; % Evaluation based on a summed spectrogram, i.e., orientation independent
|
|
160
|
-
ConfMFCC.MaxFreqFilter = 25; % Maximal frequency in the bank filter
|
|
161
|
-
ConfMFCC.MFCCwin = 2; % Subwindow in seconds for evaluating the spectrogram
|
|
162
|
-
|
|
163
|
-
[MelCepsCoeffAux] = MFCCExtract(ConfMFCC,DataMatrix); % Perform MFCC extraction
|
|
164
|
-
|
|
165
|
-
%% Tremor classification
|
|
166
|
-
DataScaled = (MelCepsCoeffAux - MeanVector)./SigmaVector; % Scale MFCCs features for classification
|
|
167
|
-
TremorProb(kk) = predict(Mdl,DataScaled); % Tremor probability based on logistic regression classifier
|
|
168
|
-
|
|
169
|
-
TremorHat(kk) = (TremorProb(kk) > TremorThr); % Boolean
|
|
170
|
-
RestTremorHat(kk) = (TremorProb(kk) > TremorThr) & (PeakFreqTremorCheck(kk)); % Boolean
|
|
171
|
-
|
|
172
|
-
MelCepsCoeff = vertcat(MelCepsCoeff,MelCepsCoeffAux); % Concatenate values
|
|
173
|
-
clear('MelCepsCoeffAux'); % clear temp variable
|
|
174
|
-
|
|
175
|
-
%% Tremor Severity and arm activity features (step 5 for eScience toolbox)
|
|
176
|
-
|
|
177
|
-
% Derivatives Evaluation - Get the mean absolute derivative values
|
|
178
|
-
DerivativesAux = DerivativesExtract(sig_x,sig_y,sig_z,Fs); % Evaluate mean signals' absolute derivatives values
|
|
179
|
-
Derivatives = vertcat(Derivatives,DerivativesAux); % Concatenate values - store Derivatives
|
|
180
|
-
clear('DerivativesAux'); % Clear the auxiliar strucuture
|
|
181
|
-
|
|
182
|
-
% Parameters for obtaning spectral features
|
|
183
|
-
fSpectResol = Fs/ConfPSD.nfft; % Spectral resolution: fixed Fs/(4*Fs) = 0.25 Hz
|
|
184
|
-
ConfPSDExtr.SpectralIntervalPeak = round(0.5/fSpectResol); % The interval for calculating the dominant power
|
|
185
|
-
% is 0.5 Hz for each side of the peak,
|
|
186
|
-
% which implies in different number of
|
|
187
|
-
% samples in the freq domain depending
|
|
188
|
-
% on the spectral resolution
|
|
189
|
-
|
|
190
|
-
ConfPSDExtr.StrAxis = 'Sum'; % PSD features will be evaluated in the PSDsum domain, i.e., PSDx+PSDy+PSDz: orientation independent
|
|
191
|
-
ConfPSDExtr.nfft = 4*Fs; % Number of points FFT
|
|
192
|
-
ConfPSDExtr.Fs = Fs; % Sampling frequency
|
|
193
|
-
ConfPSDExtr.MaxFreqOverallBand = 25; % Maximal frequency for evaluating total power
|
|
194
|
-
|
|
195
|
-
% Low Tremor Features
|
|
196
|
-
ConfPSDExtr.freqrange = [3 7]; % IMPORTANT - define here the bandwidth for tremor band
|
|
197
|
-
[PSDTremorFeaturesAux] = PSDExtrOpt(ConfPSDExtr,PSDMatrix,FreqVect); % Get Low Freq Tremor Features
|
|
198
|
-
PSDTremorFeatures = vertcat(PSDTremorFeatures,PSDTremorFeaturesAux); % Store low freq tremor features
|
|
199
|
-
clear('PSDTremorFeaturesAux'); % Clear temp variable
|
|
200
|
-
|
|
201
|
-
% In the tremor range: get PSD Dominant power for each axis
|
|
202
|
-
|
|
203
|
-
ConfAxis.StrAxis = 'X';
|
|
204
|
-
ConfAxis.freqrange = [3 7]; % Frequency range to get tremor dominant power
|
|
205
|
-
ConfAxis.nfft = 4*Fs; % Number of points FFT
|
|
206
|
-
ConfAxis.Fs = Fs; % Sampling frequency
|
|
207
|
-
ConfAxis.SpectralIntervalPeak = round(0.5/fSpectResol); % The interval for calculating the dominant power
|
|
208
|
-
ConfAxis.MinFreqOverallBand = 0.5; % Minimal frequency for evaluating total power
|
|
209
|
-
ConfAxis.MaxFreqOverallBand = 25; % Maximal frequency for evaluating total power
|
|
210
|
-
|
|
211
|
-
[PSD_X] = PSDExtrAxis(ConfAxis,PSDMatrix,FreqVect);
|
|
212
|
-
|
|
213
|
-
ConfAxis.StrAxis = 'Y';
|
|
214
|
-
[PSD_Y] = PSDExtrAxis(ConfAxis,PSDMatrix,FreqVect);
|
|
215
|
-
|
|
216
|
-
ConfAxis.StrAxis = 'Z';
|
|
217
|
-
[PSD_Z] = PSDExtrAxis(ConfAxis,PSDMatrix,FreqVect);
|
|
218
|
-
|
|
219
|
-
% Get the fixed bandwith dominant power 1.25 Hz around the peak in the
|
|
220
|
-
% tremor range
|
|
221
|
-
|
|
222
|
-
PSDPowerAxisAux = [PSD_X(1) PSD_Y(1) PSD_Z(1)];
|
|
223
|
-
PSDTremorDomPowerAxisAux = [PSD_X(2) PSD_Y(2) PSD_Z(2)];
|
|
224
|
-
|
|
225
|
-
PowerAxis = vertcat(PowerAxis,PSDPowerAxisAux);
|
|
226
|
-
DomTremorPowerAxis = vertcat(DomTremorPowerAxis,PSDTremorDomPowerAxisAux);
|
|
227
|
-
|
|
228
|
-
clear('PSD_X','PSD_Y','PSD_Z','PSDTremorDomPowerAxisAux','PSDPowerAxisAux');
|
|
229
|
-
|
|
230
|
-
% Get features in the high tremor range
|
|
231
|
-
ConfPSDExtr.freqrange = [7 12]; % IMPORTANT - define here the bandwidth
|
|
232
|
-
[PSDHighTremorFeaturesAux] = PSDExtrOpt(ConfPSDExtr,PSDMatrix,FreqVect); % Get High Freq Tremor Features
|
|
233
|
-
PSDHighTremorFeatures = vertcat(PSDHighTremorFeatures,PSDHighTremorFeaturesAux); % Store
|
|
234
|
-
clear('PSDHighTremorFeaturesAux'); % Clear temp variable
|
|
235
|
-
|
|
236
|
-
% Get Power in the arm-activity
|
|
237
|
-
ConfBP.freqrange = [0.5 3]; % Frequency range
|
|
238
|
-
ConfBP.StrAxis = 'Sum'; % Axis or sum
|
|
239
|
-
ConfBP.nfft = 4*Fs; % number of samples for FFT
|
|
240
|
-
ConfBP.Fs = Fs; % Sampling frequency
|
|
241
|
-
|
|
242
|
-
[ArmActvPowerAux] = PSDBandPower(ConfBP,PSDMatrix,FreqVect); % Get arm-activity bandpower
|
|
243
|
-
ArmActvPower = vertcat(ArmActvPower,ArmActvPowerAux); % Store
|
|
244
|
-
clear('ArmActvPowerAux'); % Clear temp variable
|
|
245
|
-
|
|
246
|
-
% Get Power in high frequency band
|
|
247
|
-
ConfBP.freqrange = [12 25]; % Frequency range
|
|
248
|
-
[HighFreqPowerAux] = PSDBandPower(ConfBP,PSDMatrix,FreqVect); % Get high frequency bandpower
|
|
249
|
-
HighFreqPower = vertcat(HighFreqPower,HighFreqPowerAux); % Store
|
|
250
|
-
clear('HighFreqPowerAux'); % Clear temp variable
|
|
251
|
-
|
|
252
|
-
end
|
|
253
|
-
% Organizing Output as a table
|
|
254
|
-
|
|
255
|
-
%% Frequency Peak
|
|
256
|
-
VarName = {'GyFreqPeak'};
|
|
257
|
-
FreqPeak = array2table(FreqPeak','VariableNames',VarName);
|
|
258
|
-
|
|
259
|
-
%% MFCCs
|
|
260
|
-
% Creating MFCCs names to be used
|
|
261
|
-
for pp = 1:ConfMFCC.NumMelCoeff
|
|
262
|
-
CepsName{1,pp} = [TypeOfSignal,'MFCC',num2str(pp)];
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
VarName = CepsName;
|
|
266
|
-
% Defining the output
|
|
267
|
-
MelCepsCoeff = array2table(MelCepsCoeff,'VariableNames',VarName);
|
|
268
|
-
clear('VarName');
|
|
269
|
-
|
|
270
|
-
%% Derivatives
|
|
271
|
-
VarName = [{[TypeOfSignal,'MeanDx']},{[TypeOfSignal,'MeanDy']},{[TypeOfSignal,'MeanDz']}];
|
|
272
|
-
|
|
273
|
-
% Converting array to table
|
|
274
|
-
Derivatives = array2table(Derivatives,"VariableNames",VarName);
|
|
275
|
-
clear('VarName');
|
|
276
|
-
|
|
277
|
-
%% PSD Features Arm Activity Band
|
|
278
|
-
VarName = {[TypeOfSignal,'ArmActvPower']};
|
|
279
|
-
ArmActvPower = array2table(ArmActvPower,"VariableNames",VarName);
|
|
280
|
-
clear('VarName');
|
|
281
|
-
|
|
282
|
-
%% PSD Features High Frequency Band
|
|
283
|
-
VarName = {[TypeOfSignal,'HighFreqPower']};
|
|
284
|
-
HighFreqPower = array2table(HighFreqPower,"VariableNames",VarName);
|
|
285
|
-
clear('VarName');
|
|
286
|
-
|
|
287
|
-
% Tremor Band
|
|
288
|
-
StrBand = 'LTre'; % String specifying the bandwidth in
|
|
289
|
-
% the obtained features name
|
|
290
|
-
|
|
291
|
-
VarName = {[TypeOfSignal,StrBand,'BandPower'], ...
|
|
292
|
-
[TypeOfSignal,StrBand,'FreqPeak'],...
|
|
293
|
-
[TypeOfSignal,StrBand,'DomPower']};
|
|
294
|
-
|
|
295
|
-
PSDTremorFeatures = array2table(PSDTremorFeatures,'VariableNames',VarName);
|
|
296
|
-
clear('VarName');
|
|
297
|
-
|
|
298
|
-
%% Dominant tremor power in each axis
|
|
299
|
-
VarName = {[TypeOfSignal,StrBand,'DomPowerX'],...
|
|
300
|
-
[TypeOfSignal,StrBand,'DomPowerY'],...
|
|
301
|
-
[TypeOfSignal,StrBand,'DomPowerZ']};
|
|
302
|
-
|
|
303
|
-
DomTremorPowerAxis = array2table(DomTremorPowerAxis ,'VariableNames',VarName);
|
|
304
|
-
clear('VarName');
|
|
305
|
-
|
|
306
|
-
%% Full band: (0.5-25 Hz) in each axis
|
|
307
|
-
VarName = {[TypeOfSignal,'PowerX'],...
|
|
308
|
-
[TypeOfSignal,'PowerY'],...
|
|
309
|
-
[TypeOfSignal,'PowerZ']};
|
|
310
|
-
|
|
311
|
-
PowerAxis = array2table(PowerAxis ,'VariableNames',VarName);
|
|
312
|
-
clear('VarName');
|
|
313
|
-
|
|
314
|
-
%% Features in High Tremor Band (7 - 12 Hz)
|
|
315
|
-
StrBand = 'HTre'; % String specifying the bandwidth in the obtained features name
|
|
316
|
-
VarName = {[TypeOfSignal,StrBand,'BandPower'], ...
|
|
317
|
-
[TypeOfSignal,StrBand,'FreqPeak'],...
|
|
318
|
-
[TypeOfSignal,StrBand,'DomPower']};
|
|
319
|
-
|
|
320
|
-
PSDHighTremorFeatures = array2table(PSDHighTremorFeatures,'VariableNames',VarName);
|
|
321
|
-
clear('VarName');
|
|
322
|
-
|
|
323
|
-
if NumWindows == 0 % If there are not enough samples for having at least one window, the output structure is empty
|
|
324
|
-
|
|
325
|
-
Features = [];
|
|
326
|
-
else % otherwise, Features receive the concatenated arrays and tables evaluated for the windows
|
|
327
|
-
|
|
328
|
-
Features.WindowIniTime = WindowIniTime';
|
|
329
|
-
Features.Derivatives = Derivatives;
|
|
330
|
-
Features.PowerAxis = PowerAxis;
|
|
331
|
-
Features.DomTremorPowerAxis = DomTremorPowerAxis;
|
|
332
|
-
|
|
333
|
-
Features.FreqPeak = FreqPeak;
|
|
334
|
-
Features.PSDTremorFeatures = PSDTremorFeatures;
|
|
335
|
-
Features.PSDHighTremorFeatures = PSDHighTremorFeatures;
|
|
336
|
-
|
|
337
|
-
Features.MelCepsCoeff = MelCepsCoeff;
|
|
338
|
-
Features.PowerArmActv = ArmActvPower;
|
|
339
|
-
Features.PowerHighFreq = HighFreqPower;
|
|
340
|
-
|
|
341
|
-
Features.TremorProb = TremorProb';
|
|
342
|
-
Features.TremorHat = TremorHat';
|
|
343
|
-
Features.RestTremorHat = RestTremorHat';
|
|
344
|
-
|
|
345
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
% Feature Extraction
|
|
2
|
-
% Estimate the mean absolute derivative values for a given IMU axes window
|
|
3
|
-
% #########################################################################
|
|
4
|
-
% Input:
|
|
5
|
-
% x - x-axis signal (array) - double
|
|
6
|
-
% y - y-axis signal (array) - double
|
|
7
|
-
% z - z-axis signal (array) - double
|
|
8
|
-
% Fs - Sampling frequency (scalar) - double
|
|
9
|
-
%
|
|
10
|
-
% #########################################################################
|
|
11
|
-
% Output:
|
|
12
|
-
% DerivativesOut - array - double
|
|
13
|
-
% [MeanAbsDx MeanAbsDy MeanAbsDz]: 1 x 3
|
|
14
|
-
% #########################################################################
|
|
15
|
-
function DerivativesOut = DerivativesExtract(x,y,z,Fs)
|
|
16
|
-
|
|
17
|
-
Ts = 1/Fs; % sampling step
|
|
18
|
-
dx = mean((1/Ts)*abs(diff(x,1,1))); % get the mean dx/dt
|
|
19
|
-
dy = mean((1/Ts)*abs(diff(y,1,1))); % get the mean dy/dt
|
|
20
|
-
dz = mean((1/Ts)*abs(diff(z,1,1))); % get the mean dz/dt
|
|
21
|
-
|
|
22
|
-
DerivativesOut = [dx dy dz]; % Defining output values
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
function [RMSValuesOut] = ExtractBandSignalsRMS(Conf,Data,TremorHatLabel)
|
|
2
|
-
|
|
3
|
-
% Input ###################################################################
|
|
4
|
-
% Conf - Configuration Structure
|
|
5
|
-
% .Fs - scalar - double - sampling frequency
|
|
6
|
-
%
|
|
7
|
-
% Data - matrix (Nsamples x Nsignals) - double - columns: IMU signals ([x y and z])
|
|
8
|
-
%
|
|
9
|
-
% TremorHatLabel - scalar - double - rest tremor label
|
|
10
|
-
%
|
|
11
|
-
% Output
|
|
12
|
-
% RMSValuesOut - matrix - double - (1 x 7) .'TypeOfSignal'TremorRMSx - root mean square value in the tremor range (3 - 7) Hz - x axis
|
|
13
|
-
% .'TypeOfSignal'TremorRMSy - root mean square value in the tremor range (3 - 7) Hz - y axis
|
|
14
|
-
% .'TypeOfSignal'TremorRMSz - root mean square value in the tremor range (3 - 7) Hz - z axis
|
|
15
|
-
% .'TypeOfSignal'SumTremorRMS - root mean square value in the tremor range (3 - 7) Hz - sum: (RMSx + RMSy + RMSz)
|
|
16
|
-
% .'TypeOfSignal'SumGaitRMS - root mean square value in the gait range (0.4 - 2) Hz - sum: (RMSx + RMSy + RMSz)
|
|
17
|
-
% .'TypeOfSignal'SumHighTremorRMS - root mean square value in the high tremor range (7 - 12) Hz - sum: (RMSx + RMSy + RMSz)
|
|
18
|
-
% .'TypeOfSignal'VeryHighBandRMS - root mean square value in the high tremor range (12- 20) Hz - sum: (RMSx + RMSy + RMSz)
|
|
19
|
-
% #########################################################################
|
|
20
|
-
|
|
21
|
-
if TremorHatLabel == 1
|
|
22
|
-
|
|
23
|
-
Fs = Conf.Fs; % Sampling frequency
|
|
24
|
-
|
|
25
|
-
% Load filter coefficients previously designed and saved in matlab
|
|
26
|
-
% 6th order bandpass Butterworth filters
|
|
27
|
-
|
|
28
|
-
switch Fs % Check the sampling frequency and load the corresponding filter
|
|
29
|
-
case 100
|
|
30
|
-
load('BP_Butter_filter_0_4_2_fs_100Hz.mat');
|
|
31
|
-
load('BP_Butter_filter_3_7_fs_100Hz.mat');
|
|
32
|
-
load('BP_Butter_filter_7_12_fs_100Hz.mat');
|
|
33
|
-
load('BP_Butter_filter_12_20_fs_100Hz.mat');
|
|
34
|
-
|
|
35
|
-
case 50
|
|
36
|
-
|
|
37
|
-
load('BP_Butter_filter_0_4_2_fs_50Hz.mat');
|
|
38
|
-
load('BP_Butter_filter_3_7_fs_50Hz.mat');
|
|
39
|
-
load('BP_Butter_filter_7_12_fs_50Hz.mat');
|
|
40
|
-
load('BP_Butter_filter_12_20_fs_50Hz.mat');
|
|
41
|
-
end
|
|
42
|
-
%% Filtering on the required ranges
|
|
43
|
-
FilGaitBand = filtfilt(SOSGait,GGait,Data);
|
|
44
|
-
FilTremorBand = filtfilt(SOSTre,GTre,Data);
|
|
45
|
-
FilHighTremorBand = filtfilt(SOSHTre,GHTre,Data);
|
|
46
|
-
FilVeryHighBand = filtfilt(SOSVHTre,GVHTre,Data);
|
|
47
|
-
|
|
48
|
-
%% Evaluating RMS value
|
|
49
|
-
GaitRMS = rms(FilGaitBand); % returns a vector [RMSx RMSy RMSz]
|
|
50
|
-
TremorRMS = rms(FilTremorBand);
|
|
51
|
-
HighTremorRMS = rms(FilHighTremorBand);
|
|
52
|
-
VeryHighBandRMS = rms(FilVeryHighBand);
|
|
53
|
-
|
|
54
|
-
% Sum across axes
|
|
55
|
-
SumGaitRMS = sum(GaitRMS);
|
|
56
|
-
SumTremorRMS = sum(TremorRMS);
|
|
57
|
-
SumHighTremorRMS = sum(HighTremorRMS);
|
|
58
|
-
SumVeryHighBandRMS = sum(VeryHighBandRMS);
|
|
59
|
-
|
|
60
|
-
% Getting the RMS in the tremor range for each axis to be included in the output
|
|
61
|
-
TremorRMSx = TremorRMS(1);
|
|
62
|
-
TremorRMSy = TremorRMS(2);
|
|
63
|
-
TremorRMSz = TremorRMS(3);
|
|
64
|
-
|
|
65
|
-
% Concatenate the features
|
|
66
|
-
RMSValuesOut = [TremorRMSx TremorRMSy TremorRMSz SumTremorRMS SumGaitRMS SumHighTremorRMS SumVeryHighBandRMS];
|
|
67
|
-
|
|
68
|
-
else
|
|
69
|
-
|
|
70
|
-
RMSValuesOut = NaN(1,7);
|
|
71
|
-
|
|
72
|
-
end
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
function [MFCCFeatureOut] = MFCCExtract(Conf,Data)
|
|
2
|
-
% Input ###################################################################
|
|
3
|
-
% Conf - Structure
|
|
4
|
-
% .Fs - scalar - double - sampling frequency in Hz
|
|
5
|
-
% .numFilters - scalar - double - number of filters in the mel scale
|
|
6
|
-
% .NumMelCoeff - scalar - double - number of MFCCs coefficients
|
|
7
|
-
% .StrAxis - string - specifying axis (or sum) to be considered for evaluating the spectrogram
|
|
8
|
-
% .MaxFreqFilter - scalar - double - maximal frequency (Hz) to be considred in the bank filter
|
|
9
|
-
% .MFCCwin - scalar - double - subwindow in seconds adopted for evaluating the spectrogram
|
|
10
|
-
%
|
|
11
|
-
% Data - matrix (Nsamples x Nsignals) - double - columns: IMU signals ([x y and z])
|
|
12
|
-
%
|
|
13
|
-
%
|
|
14
|
-
% Output
|
|
15
|
-
% MFCCFeatureOut - matrix - double - .'TypeOfSignal'MFCC'coefficient number'
|
|
16
|
-
% #########################################################################
|
|
17
|
-
|
|
18
|
-
[Nsamples,Nsignals] = size(Data); % get number of samples and number of signals
|
|
19
|
-
|
|
20
|
-
Fs = Conf.Fs; % sampling rate
|
|
21
|
-
numFilters = Conf.numFilters; % number of filters
|
|
22
|
-
NumMelCoeff = Conf.NumMelCoeff; % number of MFCCs coefficients
|
|
23
|
-
StrAxis = Conf.StrAxis; % axis or sum of axes to be considered in the spectrogram
|
|
24
|
-
|
|
25
|
-
filterbankStart = 0; % frequency for starting the bank filter
|
|
26
|
-
filterbankEnd = Conf.MaxFreqFilter; % maximum frequency in the bank filter
|
|
27
|
-
|
|
28
|
-
numBandEdges = numFilters + 2; % number of filter edges
|
|
29
|
-
|
|
30
|
-
NFFT = Conf.MFCCwin*Fs; % number of samples for FFT = number of samples of the adopted subwindow to evaluate the spectrogram
|
|
31
|
-
|
|
32
|
-
fresol = Fs/NFFT; % frequency resolution if 0.5 Hz
|
|
33
|
-
|
|
34
|
-
filterBank = zeros(numFilters,NFFT); % initializing the bank filter
|
|
35
|
-
|
|
36
|
-
x = filterbankStart:0.01:filterbankEnd; % linear spacing in the bank filter frequency range
|
|
37
|
-
|
|
38
|
-
melscale = 64.875*log10( 1 + x./17.5); % creating mel scale
|
|
39
|
-
|
|
40
|
-
xlinmel = linspace(melscale(1),melscale(end),numBandEdges); % equally intervals in the mel scale
|
|
41
|
-
|
|
42
|
-
bandEdges = 17.5*(10.^(xlinmel/64.875) - 1); % getting the edges in the frequency domain
|
|
43
|
-
|
|
44
|
-
bandEdgesBins = round((bandEdges/Fs)*NFFT) + 1; % rouding the edges
|
|
45
|
-
|
|
46
|
-
% Getting each filter in the frequency domain
|
|
47
|
-
for ii = 1:numFilters
|
|
48
|
-
filt = triang(bandEdgesBins(ii+2)-bandEdgesBins(ii)); % Triangular filters based on the edges
|
|
49
|
-
leftPad = bandEdgesBins(ii); % introduce zero padding on the left
|
|
50
|
-
rightPad = NFFT - numel(filt) - leftPad; % introduce zero padding on the right
|
|
51
|
-
filterBank(ii,:) = [zeros(1,leftPad),filt',zeros(1,rightPad)]; % concatenate the vector
|
|
52
|
-
filterBank(ii,:) = filterBank(ii,:)/(fresol*sum(filterBank(ii,:))); % Normalize the filter coefficients by the bandpass area
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
% Check the filter profiles if needed
|
|
56
|
-
% frequencyVector = (Fs/NFFT)*(0:NFFT-1);
|
|
57
|
-
% plot(frequencyVector,filterBank');
|
|
58
|
-
% xlabel('Hz')
|
|
59
|
-
% axis([0 frequencyVector(NFFT/2) 0 1])
|
|
60
|
-
|
|
61
|
-
overlap = round(0.8*NFFT); % ovelap between each subwindow for evaluating the spectrogram
|
|
62
|
-
|
|
63
|
-
% Extracting the MFCC according to axis (or sum) specified when evaluating
|
|
64
|
-
% the spectrogram
|
|
65
|
-
switch StrAxis
|
|
66
|
-
case 'X'
|
|
67
|
-
Signal = Data(:,1); % Get the signal
|
|
68
|
-
% Evaluate the spectrogram
|
|
69
|
-
[S1,f,t] = stft(Signal,Fs,"Window",hann(NFFT,'periodic'),...
|
|
70
|
-
'OverlapLength',overlap,"FrequencyRange","twosided");
|
|
71
|
-
S = abs(S1); % Get the absolute value
|
|
72
|
-
case 'Y'
|
|
73
|
-
Signal = Data(:,2);
|
|
74
|
-
[S2,f,t] = stft(Signal,Fs,"Window",hann(NFFT,'periodic'),...
|
|
75
|
-
'OverlapLength',overlap,"FrequencyRange","twosided");
|
|
76
|
-
S = abs(S2);
|
|
77
|
-
case 'Z'
|
|
78
|
-
Signal = Data(:,3);
|
|
79
|
-
[S3,f,t] = stft(Signal,Fs,"Window",hann(NFFT,'periodic'),...
|
|
80
|
-
'OverlapLength',overlap,"FrequencyRange","twosided");
|
|
81
|
-
S = abs(S3);
|
|
82
|
-
case 'Sum'
|
|
83
|
-
[S1,f,t] = stft(Data(:,1),Fs,"Window",hann(NFFT,'periodic'),...
|
|
84
|
-
'OverlapLength',overlap,"FrequencyRange","twosided");
|
|
85
|
-
[S2,f,t] = stft(Data(:,2),Fs,"Window",hann(NFFT,'periodic'),...
|
|
86
|
-
'OverlapLength',overlap,"FrequencyRange","twosided");
|
|
87
|
-
[S3,f,t] = stft(Data(:,3),Fs,"Window",hann(NFFT,'periodic'),...
|
|
88
|
-
'OverlapLength',overlap,"FrequencyRange","twosided");
|
|
89
|
-
S = abs(S1) + abs(S2) + abs(S3); % Get the sum of the absolute values across axes
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
% Applying the filter bank
|
|
93
|
-
Spec = filterBank*S;
|
|
94
|
-
|
|
95
|
-
% Obtaning the cepstral coefficients
|
|
96
|
-
CepsCoeff = cepstralCoefficients(Spec,'NumCoeffs',NumMelCoeff);
|
|
97
|
-
|
|
98
|
-
Ceps = mean(CepsCoeff); % Taking the average of the cepstral coefficients across time
|
|
99
|
-
|
|
100
|
-
MFCCFeatureOut = Ceps; % Defining the output
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
function [PSDBandPowerOut] = PSDBandPower(Conf,Data,freq)
|
|
2
|
-
% #########################################################################
|
|
3
|
-
% Input
|
|
4
|
-
% Conf - Structure
|
|
5
|
-
% .freqrange - array - double - Frequency Range for feature Extraction
|
|
6
|
-
% .StrAxis - string - signal axis (or Sum) specified to be considered for feature extraction
|
|
7
|
-
% .nfft - scalar - double - number of points for the
|
|
8
|
-
% FFT (number of samples)
|
|
9
|
-
% .Fs - scalar - double - sampling Rate
|
|
10
|
-
%
|
|
11
|
-
% Data - PSD Matrix - matrix - double - N frequency values x (Nsignals + 1) - last column is the PSD sum (PSDx + PSDy + PSDz)
|
|
12
|
-
%
|
|
13
|
-
% freq - array - double - frequency vector associsted to the PSD;
|
|
14
|
-
%
|
|
15
|
-
%
|
|
16
|
-
%
|
|
17
|
-
% Output - Table with PSD features for the axis (or sum of the axis)
|
|
18
|
-
% selected
|
|
19
|
-
% PSDFeaturesOut - scalar - double (1 x 1)
|
|
20
|
-
% BandPower - power in the range
|
|
21
|
-
|
|
22
|
-
% Get the estimation parameters
|
|
23
|
-
freqrange = Conf.freqrange;
|
|
24
|
-
StrAxis = Conf.StrAxis;
|
|
25
|
-
nfft = Conf.nfft;
|
|
26
|
-
Fs = Conf.Fs;
|
|
27
|
-
|
|
28
|
-
% Getting the signal axis or sum according to what specified in the input
|
|
29
|
-
switch StrAxis
|
|
30
|
-
case 'X'
|
|
31
|
-
Pxx = Data(:,1);
|
|
32
|
-
case 'Y'
|
|
33
|
-
Pxx = Data(:,2);
|
|
34
|
-
case 'Z'
|
|
35
|
-
Pxx = Data(:,3);
|
|
36
|
-
case 'Sum'
|
|
37
|
-
Pxx = Data(:,4);
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
f0 = Fs/nfft; % Spectral Resolution
|
|
41
|
-
|
|
42
|
-
FreqLowerBound = freqrange(1); % lower frequency bound
|
|
43
|
-
FreqUpperBound = freqrange(2); % upper frequency bound
|
|
44
|
-
|
|
45
|
-
% Total Power - area under PSD using an approximation by the left
|
|
46
|
-
|
|
47
|
-
InitialIndexBandForPower = find(freq == FreqLowerBound); % Initial index for bandpower estimation
|
|
48
|
-
FinalIndexBandForPower = find(freq == (FreqUpperBound-f0)); % Final index for bandpower estimation: area will be estimated using approximation by the left
|
|
49
|
-
|
|
50
|
-
BandPower = f0*sum(Pxx(InitialIndexBandForPower:FinalIndexBandForPower)); % Power in the band specified
|
|
51
|
-
|
|
52
|
-
PSDBandPowerOut = BandPower; % Defining the output
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
% #########################################################################
|
|
2
|
-
% Input
|
|
3
|
-
% Conf - Configuration Strucutre
|
|
4
|
-
% .pwelchwin - (scalar) - double - number of samples - window for Welch periodogram
|
|
5
|
-
% .noverlap - (scalar) - double - number of samples - ovserlap between windows
|
|
6
|
-
% .Fs - (scalar) - double - sampling frequency
|
|
7
|
-
% .nfft - (scalar) - double - number of samples for FFT evaluation
|
|
8
|
-
% .freqmax - (scalar) - double - maximal frequency of interest
|
|
9
|
-
%
|
|
10
|
-
% Data - (matrix) - double - IMU time series (Nsamples x 3 columns - x y z arrays)
|
|
11
|
-
|
|
12
|
-
% Output
|
|
13
|
-
% PSDMatrix - (matrix) - double - (Nfreq x 4 columns) - PSD coefficients for x, y
|
|
14
|
-
% and z and sum (fourth column: PSDx + PSDy + PSDz)
|
|
15
|
-
%
|
|
16
|
-
% FreqVect - array - double - Frequency array in Hz;
|
|
17
|
-
%
|
|
18
|
-
% FreqPeak - scalar - double - Frequency (Hz) of the spectral peak
|
|
19
|
-
% #########################################################################
|
|
20
|
-
|
|
21
|
-
function [PSDMatrix,FreqVect,FreqPeak] = PSDEst(Conf,Data)
|
|
22
|
-
|
|
23
|
-
% Get PSD estimating parameters from the configuration structure
|
|
24
|
-
pwelchwin = Conf.pwelchwin;
|
|
25
|
-
noverlap = Conf.noverlap;
|
|
26
|
-
Fs = Conf.Fs;
|
|
27
|
-
nfft = Conf.nfft;
|
|
28
|
-
freqmax = Conf.freqmax;
|
|
29
|
-
freqmin = Conf.freqmin;
|
|
30
|
-
|
|
31
|
-
% Get number of samples and number of signals to be manipulated
|
|
32
|
-
[Nsamples,Nsignals] = size(Data);
|
|
33
|
-
|
|
34
|
-
% Estimate the PSD coefficients (Pxx) for the frequencies (freqlong)
|
|
35
|
-
% hann - Hanning window
|
|
36
|
-
[Pxx,freqlong] = pwelch(Data,hann(pwelchwin),noverlap,nfft,Fs);
|
|
37
|
-
|
|
38
|
-
% Finding the index of the maximal frequency to be considered
|
|
39
|
-
indcutfreq = find(freqlong == freqmax);
|
|
40
|
-
|
|
41
|
-
% Get the frequency vector up to be maximal frequency
|
|
42
|
-
FreqVect = freqlong(1:indcutfreq);
|
|
43
|
-
|
|
44
|
-
% Store the PSD coefficients for each IMU signal [x y z] up the maximal
|
|
45
|
-
% frequncy into a matrix (PSDMatrix)
|
|
46
|
-
PSDMatrix = Pxx(1:indcutfreq,:);
|
|
47
|
-
|
|
48
|
-
% Fourth column of PSDMatrix: sum of the PSD (PSDx + PSDy + PSDz)
|
|
49
|
-
% This sum is used to work with a single orientation
|
|
50
|
-
% independent spectrum
|
|
51
|
-
PSDMatrix(:,Nsignals+1) = sum(PSDMatrix,2);
|
|
52
|
-
|
|
53
|
-
% Get maximum PSD value in the range [freqmin freqmax]
|
|
54
|
-
[CoeffPeak,IndPeak] = max(PSDMatrix(FreqVect>=freqmin,Nsignals+1));
|
|
55
|
-
|
|
56
|
-
% Add the minimum frequency to obtain the correct dominant frequency
|
|
57
|
-
FreqPeak = FreqVect(IndPeak) + freqmin;
|
|
58
|
-
|
|
59
|
-
% Inspection Spectrum;
|
|
60
|
-
% figure; plot(FreqVect,PSDMatrix);
|
|
61
|
-
% xlabel('Freq (Hz)'); ylabel('PSD');
|
|
62
|
-
% set(gca,'fontsize',20,'fontweight','bold','LineWidth',2);
|
|
63
|
-
% grid on; legend('PSDx','PSDy','PSDz','PSDsum');
|