TEAP (Toolbox for Emotion Analysis using Physiological Signals) doc
GSR_feat_peaks.m
Go to the documentation of this file.
1 %This file is part of TEAP.
2 %
3 %TEAP is free software: you can redistribute it and/or modify
4 %it under the terms of the GNU General Public License as published by
5 %the Free Software Foundation, either version 3 of the License, or
6 %(at your option) any later version.
7 %
8 %TEAP is distributed in the hope that it will be useful,
9 %but WITHOUT ANY WARRANTY; without even the implied warranty of
10 %MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 %GNU General Public License for more details.
12 %
13 %You should have received a copy of the GNU General Public License
14 %along with TEAP. If not, see <http://www.gnu.org/licenses/>.
15 %
16 %> @file GSR_feat_peaks.m
17 %> @brief Computes the number of peaks from a GSR signal. It is based on the analysis of
18 %> local minima and local maxima preceding the local minima.
19 %
20 %> @param GSRsignal: the GSR signal.
21 %> @param ampThresh: the amplitude threshold in Ohms from which a peak is detected.
22 %> Default is 100 Ohm
23 %
24 %> @retval nbPeaks: the # of peaks in the signal
25 %> @retval ampPeaks [1xP]: the amplitude of the peaks (maxima - minima)
26 %> @retval riseTime [1xP]: the duration of the rise time of each peak
27 %> @retval posPeaks [1xP]: index of the detected peaks in the GSR signal
28 %
29 %> @author Copyright XXX 2011
30 %> @author Copyright Frank Villaro-Dixon, 2014
31 function [nbPeaks, ampPeaks, riseTime, posPeaks] = GSR_feat_peaks(GSRsignal, ampThresh)
32 
33 
34 %Make sure we have a GSR signal
35 GSRsignal = GSR__assert_type(GSRsignal);
36 
37 if(~Signal__has_preproc_lowpass(GSRsignal))
38  warning(['For the function to work well, you should low-pass the signal' ...
39  '. Preferably with a median filter']);
40 end
41 
42 if(nargin < 2)
43  ampThresh = 100;%Ohm
44 end
45 
46 if(nargin < 1)
47  error('Usage: [nbPeaks, ampPeaks, riseTime, posPeaks, GSRsignal] = GSR_feat_peaks(GSRsignal, ampThresh)');
48 end
49 
50 tThreshLow = 1;
51 tThreshUp = 10;
52 
53 
54 
55 %Search low and high peaks
56 %low peaks are the GSR appex reactions (highest sudation)
57 %High peaks are used as starting points for the reaction
58 GSR = Signal__get_raw(GSRsignal);
59 %GSR = detrend(GSR);
60 dN = diff(diff(GSR) <= 0);
61 idxL = find(dN < 0) + 1; %+1 to account for the double derivative
62 idxH = find(dN > 0) + 1;
63 
64 samprate = Signal__get_samprate(GSRsignal);
65 
66 %For each low peaks find it's nearest high peak and check that there is no
67 %low peak between them, if there is one, reject the peak (OR SEARCH FOR CURVATURE)
68 riseTime = []; %vector of rise time for each detected peak
69 ampPeaks = []; %vector of amplitude for each detected peak
70 posPeaks = []; %vector of final indexes of low peaks
71 for(iP = [1:length(idxL)])
72  %get list of high peaks before the current low peak
73  nearestHP = idxH(idxH < idxL(iP));
74 
75  %if no high peak before (first peak detected in the signal) do nothing
76  if(~isempty(nearestHP))
77  %Get nearest high peak
78  nearestHP = nearestHP(end);
79 
80  %check if there is no other low peaks between the nearest high and
81  %the current low peaks. If not the case then compute peak features
82  if(~any((idxL > nearestHP) & (idxL < idxL(iP))))
83  rt = (idxL(iP) - nearestHP)/samprate;
84  amp = GSR(nearestHP) - GSR(idxL(iP));
85 
86  %if rise time and amplitude fits threshold then the peak is
87  %considered and stored
88  if((rt >= tThreshLow) && (rt <= tThreshUp) && (amp >= ampThresh))
89  riseTime = [riseTime rt];
90  ampPeaks = [ampPeaks amp];
91  posPeaks = [posPeaks idxL(iP)];
92  end
93  end
94  end
95 end
96 
97 nbPeaks = length(posPeaks);
98 
99 end
100 
Signal__get_samprate
function Signal__get_samprate(in Signal)
Signal__has_preproc_lowpass
function Signal__has_preproc_lowpass(in Signal)
Signal__get_raw
function Signal__get_raw(in Signal)
GSR__assert_type
function GSR__assert_type(in Signal)
GSR_feat_peaks
function GSR_feat_peaks(in GSRsignal, in ampThresh)