TEAP (Toolbox for Emotion Analysis using Physiological Signals) doc
PLETtoBPM.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 PLETtoBPM.m
17 %> @brief calcul le heart rate bpm a partir du fichier des donn�es data
18 %> le signal a une frequence d'echantillonage fe. Search for the upper peak,
19 %> if systolic upstroke is desired, simply negate the signal
20 %
21 %> @param data the pletysmograph data
22 %> @param fe sampling frequency
23 %> @param methodPeak detection method for choice in case of many peak (default 'max')
24 %> 'sharp': the shapest peak
25 %> 'max: the highest peak
26 %> 'first': the first peak of the two
27 %> @param SizeWindow for mean filtering, 0-> no fitlering (default fe/50)
28 %> @param verbose display a graph of the result if 1 (default 0)
29 %
30 %> @retval bpm Heart rate in bpm
31 %> @retval delta Heart rate in time
32 %> @retval t vecteur contenant les samples central des deux pics ayant servi a
33 %> calculer le bpm
34 %> @retval listePic liste des echantillon ou il y a eu des pics detect�
35 %> Ver 2 : n'utilise pas les wavlet mais seulement la d�riv�e du signal
36 %> Ver 3 : plus de gros filtrage et choix des pics suivant differetes methodes
37 %
38 %> @author Guillaume Chanel 2015
39 
40 function [bpm, delta_t, t, listePic] = PLETtoBPM(data, fe, methodPeak, SizeWindow, verbose)
41 
42 if(nargin < 3)
43  methodPeak = 'max';
44 end
45 if(nargin < 4)
46  SizeWindow = round(fe/50);
47 end
48 if(nargin < 5)
49  verbose = 0;
50 end
51 
52 data = data - mean(data);
53 if(SizeWindow ~= 0)
54  dataS = filtfilt(ones(1, SizeWindow)/SizeWindow, 1, [repmat(data(1),SizeWindow,1);data]);
55  dataS = dataS(SizeWindow+1:end);
56 % dataS = medfilt1(data,SizeWindow);
57 else
58  dataS = data;
59 end
60 
61 diffS = diff(dataS);
62 
63 %recherche des pics postif : deriv decroissante = 0
64 listePic = [];
65 for(iSpl = 1:length(diffS)-1)
66  if((diffS(iSpl) > 0) & (diffS(iSpl+1) < 0)) %si il y a une derive == 0 sur le dernier sample elle n'est pas prise en compte
67  listePic = [listePic iSpl+(diffS(iSpl) / (diffS(iSpl) - diffS(iSpl+1)))];
68  elseif ((diffS(iSpl)==0) & (diffS(iSpl+1) < 0))
69  listePic = [listePic iSpl];
70  end
71 end
72 %Sure to keep that ?
73 listePic = round(listePic);
74 
75 
76 %Procedure to keep only peaks that are separated by at least 0.5 seconds
77 %other are considered as the same peak and one of the two is selected
78 %according to the choosen method. Also peaks that are lie alone in the
79 %first 0.5 seconds are removed (cannot dentermine wich peak it is...)
80 limit = round(0.5*fe);
81 
82 %Remove too early first peak
83 if((listePic(1) < limit) && (listePic(2) - listePic(1) >= limit))
84  listePic = listePic(2:end);
85 end
86 
87 %remove other peaks
88 iPic = 1;
89 while(iPic<=length(listePic)-1)
90  %If two peaks are too close keep the one depending on the method
91  if( (listePic(iPic+1) - listePic(iPic)) < limit)
92  switch(methodPeak)
93  case 'sharp'
94  nbSplFwd = round(0.05*fe);
95  if(listePic(iPic+1)+nbSplFwd > length(dataS))
96  nbSplFwd = length(dataS) - listePic(iPic+1);
97  warning(['Not enough signal to look 0.05s ahead, looking at ' num2str(nbSplFwd/fe) 's ahead'])
98  end
99  sharp2 = dataS(listePic(iPic+1)) - dataS(listePic(iPic+1)+nbSplFwd);
100  sharp1 = dataS(listePic(iPic)) - dataS(listePic(iPic)+nbSplFwd);
101  if(sharp1 < sharp2)
102  choice = 2;
103  else
104  choice = 1;
105  end
106  case 'max'
107  [dummy, choice] = max([data(listePic(iPic)) data(listePic(iPic+1))]);
108  case 'first'
109  choice = 1;
110  otherwise
111  error([methodPeak ' method is unknown']);
112  end
113  if(choice==1)
114  listePic(iPic+1) = [];
115  else
116  listePic(iPic) = [];
117  end
118  else
119  iPic = iPic + 1;
120  end
121 
122 end
123 
124 
125 if (length(listePic) < 2)
126  error('There should be at least 2 peaks to detect');
127 end
128 
129 %Compute bpm from the pic list
130 [bpm delta_t t] = PICtoBPM(listePic, fe);
131 
132 if(verbose)
133  figure; hold on;
134  plot(data);
135  plot(dataS,'r');
136  plot(diffS,'g');
137  plot(listePic,data(round(listePic)),'+')
138  plot(listePic,dataS(round(listePic)),'+r')
139  plot(listePic,diffS(round(listePic)),'+g')
140  plot(t,bpm,'c*-')
141 end
PICtoBPM
function PICtoBPM(in listePic, in fe)
PLETtoBPM
function PLETtoBPM(in data, in fe, in methodPeak, in SizeWindow, in verbose)