I've got some basic filter code setup (but not yet tested).

Dependencies:   BLE_API Queue mbed nRF51822

Fork of BLE_HeartRate by Bluetooth Low Energy

Committer:
roysandberg
Date:
Sun Jun 28 03:06:00 2015 +0000
Revision:
62:8e2fbe131b53
Working Beat Detection and Analysis

Who changed what in which revision?

UserRevisionLine numberNew contents of line
roysandberg 62:8e2fbe131b53 1 /*****************************************************************************
roysandberg 62:8e2fbe131b53 2 FILE: postclas.cpp
roysandberg 62:8e2fbe131b53 3 AUTHOR: Patrick S. Hamilton
roysandberg 62:8e2fbe131b53 4 REVISED: 5/13/2002
roysandberg 62:8e2fbe131b53 5 ___________________________________________________________________________
roysandberg 62:8e2fbe131b53 6
roysandberg 62:8e2fbe131b53 7 postclas.cpp: Post classifier
roysandberg 62:8e2fbe131b53 8 Copywrite (C) 2002 Patrick S. Hamilton
roysandberg 62:8e2fbe131b53 9
roysandberg 62:8e2fbe131b53 10 This file is free software; you can redistribute it and/or modify it under
roysandberg 62:8e2fbe131b53 11 the terms of the GNU Library General Public License as published by the Free
roysandberg 62:8e2fbe131b53 12 Software Foundation; either version 2 of the License, or (at your option) any
roysandberg 62:8e2fbe131b53 13 later version.
roysandberg 62:8e2fbe131b53 14
roysandberg 62:8e2fbe131b53 15 This software is distributed in the hope that it will be useful, but WITHOUT ANY
roysandberg 62:8e2fbe131b53 16 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
roysandberg 62:8e2fbe131b53 17 PARTICULAR PURPOSE. See the GNU Library General Public License for more
roysandberg 62:8e2fbe131b53 18 details.
roysandberg 62:8e2fbe131b53 19
roysandberg 62:8e2fbe131b53 20 You should have received a copy of the GNU Library General Public License along
roysandberg 62:8e2fbe131b53 21 with this library; if not, write to the Free Software Foundation, Inc., 59
roysandberg 62:8e2fbe131b53 22 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
roysandberg 62:8e2fbe131b53 23
roysandberg 62:8e2fbe131b53 24 You may contact the author by e-mail (pat@eplimited.edu) or postal mail
roysandberg 62:8e2fbe131b53 25 (Patrick Hamilton, E.P. Limited, 35 Medford St., Suite 204 Somerville,
roysandberg 62:8e2fbe131b53 26 MA 02143 USA). For updates to this software, please visit our website
roysandberg 62:8e2fbe131b53 27 (http://www.eplimited.com).
roysandberg 62:8e2fbe131b53 28 __________________________________________________________________________
roysandberg 62:8e2fbe131b53 29
roysandberg 62:8e2fbe131b53 30 This file contains functions for classifying beats based after the
roysandberg 62:8e2fbe131b53 31 following beat is detected.
roysandberg 62:8e2fbe131b53 32
roysandberg 62:8e2fbe131b53 33 ResetPostClassify() -- Resets static variables used by
roysandberg 62:8e2fbe131b53 34 PostClassify()
roysandberg 62:8e2fbe131b53 35 PostClassify() -- classifies each beat based on six preceding
roysandberg 62:8e2fbe131b53 36 beats and the following beat.
roysandberg 62:8e2fbe131b53 37 CheckPostClass() -- classifys beat type based on the last
roysandberg 62:8e2fbe131b53 38 eight post classifications of that beat.
roysandberg 62:8e2fbe131b53 39 CheckPCRhythm() -- returns the classification of the RR interval
roysandberg 62:8e2fbe131b53 40 for this type of beat based its previous eight RR intervals.
roysandberg 62:8e2fbe131b53 41
roysandberg 62:8e2fbe131b53 42 ****************************************************************/
roysandberg 62:8e2fbe131b53 43
roysandberg 62:8e2fbe131b53 44 #include <mbed.h>
roysandberg 62:8e2fbe131b53 45 #include "bdac.h"
roysandberg 62:8e2fbe131b53 46 #include "ecgcodes.h"
roysandberg 62:8e2fbe131b53 47
roysandberg 62:8e2fbe131b53 48 // External Prototypes.
roysandberg 62:8e2fbe131b53 49
roysandberg 62:8e2fbe131b53 50 double DomCompare(int newType, int domType) ;
roysandberg 62:8e2fbe131b53 51 int GetBeatTypeCount(int type) ;
roysandberg 62:8e2fbe131b53 52
roysandberg 62:8e2fbe131b53 53 // Records of post classifications.
roysandberg 62:8e2fbe131b53 54
roysandberg 62:8e2fbe131b53 55 int PostClass[MAXTYPES][8], PCInitCount = 0 ;
roysandberg 62:8e2fbe131b53 56 int PCRhythm[MAXTYPES][8] ;
roysandberg 62:8e2fbe131b53 57
roysandberg 62:8e2fbe131b53 58 /**********************************************************************
roysandberg 62:8e2fbe131b53 59 Resets post classifications for beats.
roysandberg 62:8e2fbe131b53 60 **********************************************************************/
roysandberg 62:8e2fbe131b53 61
roysandberg 62:8e2fbe131b53 62 void ResetPostClassify()
roysandberg 62:8e2fbe131b53 63 {
roysandberg 62:8e2fbe131b53 64 int i, j ;
roysandberg 62:8e2fbe131b53 65 for(i = 0; i < MAXTYPES; ++i)
roysandberg 62:8e2fbe131b53 66 for(j = 0; j < 8; ++j)
roysandberg 62:8e2fbe131b53 67 {
roysandberg 62:8e2fbe131b53 68 PostClass[i][j] = 0 ;
roysandberg 62:8e2fbe131b53 69 PCRhythm[i][j] = 0 ;
roysandberg 62:8e2fbe131b53 70 }
roysandberg 62:8e2fbe131b53 71 PCInitCount = 0 ;
roysandberg 62:8e2fbe131b53 72 }
roysandberg 62:8e2fbe131b53 73
roysandberg 62:8e2fbe131b53 74 /***********************************************************************
roysandberg 62:8e2fbe131b53 75 Classify the previous beat type and rhythm type based on this beat
roysandberg 62:8e2fbe131b53 76 and the preceding beat. This classifier is more sensitive
roysandberg 62:8e2fbe131b53 77 to detecting premature beats followed by compensitory pauses.
roysandberg 62:8e2fbe131b53 78 ************************************************************************/
roysandberg 62:8e2fbe131b53 79
roysandberg 62:8e2fbe131b53 80 void PostClassify(int *recentTypes, int domType, int *recentRRs, int width, double mi2,
roysandberg 62:8e2fbe131b53 81 int rhythmClass)
roysandberg 62:8e2fbe131b53 82 {
roysandberg 62:8e2fbe131b53 83 static int lastRC, lastWidth ;
roysandberg 62:8e2fbe131b53 84 static double lastMI2 ;
roysandberg 62:8e2fbe131b53 85 int i, regCount, pvcCount, normRR ;
roysandberg 62:8e2fbe131b53 86 double mi3 ;
roysandberg 62:8e2fbe131b53 87
roysandberg 62:8e2fbe131b53 88 // If the preceeding and following beats are the same type,
roysandberg 62:8e2fbe131b53 89 // they are generally regular, and reasonably close in shape
roysandberg 62:8e2fbe131b53 90 // to the dominant type, consider them to be dominant.
roysandberg 62:8e2fbe131b53 91
roysandberg 62:8e2fbe131b53 92 if((recentTypes[0] == recentTypes[2]) && (recentTypes[0] != domType)
roysandberg 62:8e2fbe131b53 93 && (recentTypes[0] != recentTypes[1]))
roysandberg 62:8e2fbe131b53 94 {
roysandberg 62:8e2fbe131b53 95 mi3 = DomCompare(recentTypes[0],domType) ;
roysandberg 62:8e2fbe131b53 96 for(i = regCount = 0; i < 8; ++i)
roysandberg 62:8e2fbe131b53 97 if(PCRhythm[recentTypes[0]][i] == NORMAL)
roysandberg 62:8e2fbe131b53 98 ++regCount ;
roysandberg 62:8e2fbe131b53 99 if((mi3 < 2.0) && (regCount > 6))
roysandberg 62:8e2fbe131b53 100 domType = recentTypes[0] ;
roysandberg 62:8e2fbe131b53 101 }
roysandberg 62:8e2fbe131b53 102
roysandberg 62:8e2fbe131b53 103 // Don't do anything until four beats have gone by.
roysandberg 62:8e2fbe131b53 104
roysandberg 62:8e2fbe131b53 105 if(PCInitCount < 3)
roysandberg 62:8e2fbe131b53 106 {
roysandberg 62:8e2fbe131b53 107 ++PCInitCount ;
roysandberg 62:8e2fbe131b53 108 lastWidth = width ;
roysandberg 62:8e2fbe131b53 109 lastMI2 = 0 ;
roysandberg 62:8e2fbe131b53 110 lastRC = 0 ;
roysandberg 62:8e2fbe131b53 111 return ;
roysandberg 62:8e2fbe131b53 112 }
roysandberg 62:8e2fbe131b53 113
roysandberg 62:8e2fbe131b53 114 if(recentTypes[1] < MAXTYPES)
roysandberg 62:8e2fbe131b53 115 {
roysandberg 62:8e2fbe131b53 116
roysandberg 62:8e2fbe131b53 117 // Find first NN interval.
roysandberg 62:8e2fbe131b53 118 for(i = 2; (i < 7) && (recentTypes[i] != recentTypes[i+1]); ++i) ;
roysandberg 62:8e2fbe131b53 119 if(i == 7) normRR = 0 ;
roysandberg 62:8e2fbe131b53 120 else normRR = recentRRs[i] ;
roysandberg 62:8e2fbe131b53 121
roysandberg 62:8e2fbe131b53 122 // Shift the previous beat classifications to make room for the
roysandberg 62:8e2fbe131b53 123 // new classification.
roysandberg 62:8e2fbe131b53 124 for(i = pvcCount = 0; i < 8; ++i)
roysandberg 62:8e2fbe131b53 125 if(PostClass[recentTypes[1]][i] == PVC)
roysandberg 62:8e2fbe131b53 126 ++pvcCount ;
roysandberg 62:8e2fbe131b53 127
roysandberg 62:8e2fbe131b53 128 for(i = 7; i > 0; --i)
roysandberg 62:8e2fbe131b53 129 {
roysandberg 62:8e2fbe131b53 130 PostClass[recentTypes[1]][i] = PostClass[recentTypes[1]][i-1] ;
roysandberg 62:8e2fbe131b53 131 PCRhythm[recentTypes[1]][i] = PCRhythm[recentTypes[1]][i-1] ;
roysandberg 62:8e2fbe131b53 132 }
roysandberg 62:8e2fbe131b53 133
roysandberg 62:8e2fbe131b53 134 // If the beat is premature followed by a compensitory pause and the
roysandberg 62:8e2fbe131b53 135 // previous and following beats are normal, post classify as
roysandberg 62:8e2fbe131b53 136 // a PVC.
roysandberg 62:8e2fbe131b53 137
roysandberg 62:8e2fbe131b53 138 if(((normRR-(normRR>>3)) >= recentRRs[1]) && ((recentRRs[0]-(recentRRs[0]>>3)) >= normRR)// && (lastMI2 > 3)
roysandberg 62:8e2fbe131b53 139 && (recentTypes[0] == domType) && (recentTypes[2] == domType)
roysandberg 62:8e2fbe131b53 140 && (recentTypes[1] != domType))
roysandberg 62:8e2fbe131b53 141 PostClass[recentTypes[1]][0] = PVC ;
roysandberg 62:8e2fbe131b53 142
roysandberg 62:8e2fbe131b53 143 // If previous two were classified as PVCs, and this is at least slightly
roysandberg 62:8e2fbe131b53 144 // premature, classify as a PVC.
roysandberg 62:8e2fbe131b53 145
roysandberg 62:8e2fbe131b53 146 else if(((normRR-(normRR>>4)) > recentRRs[1]) && ((normRR+(normRR>>4)) < recentRRs[0]) &&
roysandberg 62:8e2fbe131b53 147 (((PostClass[recentTypes[1]][1] == PVC) && (PostClass[recentTypes[1]][2] == PVC)) ||
roysandberg 62:8e2fbe131b53 148 (pvcCount >= 6) ) &&
roysandberg 62:8e2fbe131b53 149 (recentTypes[0] == domType) && (recentTypes[2] == domType) && (recentTypes[1] != domType))
roysandberg 62:8e2fbe131b53 150 PostClass[recentTypes[1]][0] = PVC ;
roysandberg 62:8e2fbe131b53 151
roysandberg 62:8e2fbe131b53 152 // If the previous and following beats are the dominant beat type,
roysandberg 62:8e2fbe131b53 153 // and this beat is significantly different from the dominant,
roysandberg 62:8e2fbe131b53 154 // call it a PVC.
roysandberg 62:8e2fbe131b53 155
roysandberg 62:8e2fbe131b53 156 else if((recentTypes[0] == domType) && (recentTypes[2] == domType) && (lastMI2 > 2.5))
roysandberg 62:8e2fbe131b53 157 PostClass[recentTypes[1]][0] = PVC ;
roysandberg 62:8e2fbe131b53 158
roysandberg 62:8e2fbe131b53 159 // Otherwise post classify this beat as UNKNOWN.
roysandberg 62:8e2fbe131b53 160
roysandberg 62:8e2fbe131b53 161 else PostClass[recentTypes[1]][0] = UNKNOWN ;
roysandberg 62:8e2fbe131b53 162
roysandberg 62:8e2fbe131b53 163 // If the beat is premature followed by a compensitory pause, post
roysandberg 62:8e2fbe131b53 164 // classify the rhythm as PVC.
roysandberg 62:8e2fbe131b53 165
roysandberg 62:8e2fbe131b53 166 if(((normRR-(normRR>>3)) > recentRRs[1]) && ((recentRRs[0]-(recentRRs[0]>>3)) > normRR))
roysandberg 62:8e2fbe131b53 167 PCRhythm[recentTypes[1]][0] = PVC ;
roysandberg 62:8e2fbe131b53 168
roysandberg 62:8e2fbe131b53 169 // Otherwise, post classify the rhythm as the same as the
roysandberg 62:8e2fbe131b53 170 // regular rhythm classification.
roysandberg 62:8e2fbe131b53 171
roysandberg 62:8e2fbe131b53 172 else PCRhythm[recentTypes[1]][0] = lastRC ;
roysandberg 62:8e2fbe131b53 173 }
roysandberg 62:8e2fbe131b53 174
roysandberg 62:8e2fbe131b53 175 lastWidth = width ;
roysandberg 62:8e2fbe131b53 176 lastMI2 = mi2 ;
roysandberg 62:8e2fbe131b53 177 lastRC = rhythmClass ;
roysandberg 62:8e2fbe131b53 178 }
roysandberg 62:8e2fbe131b53 179
roysandberg 62:8e2fbe131b53 180
roysandberg 62:8e2fbe131b53 181 /*************************************************************************
roysandberg 62:8e2fbe131b53 182 CheckPostClass checks to see if three of the last four or six of the
roysandberg 62:8e2fbe131b53 183 last eight of a given beat type have been post classified as PVC.
roysandberg 62:8e2fbe131b53 184 *************************************************************************/
roysandberg 62:8e2fbe131b53 185
roysandberg 62:8e2fbe131b53 186 int CheckPostClass(int type)
roysandberg 62:8e2fbe131b53 187 {
roysandberg 62:8e2fbe131b53 188 int i, pvcs4 = 0, pvcs8 ;
roysandberg 62:8e2fbe131b53 189
roysandberg 62:8e2fbe131b53 190 if(type == MAXTYPES)
roysandberg 62:8e2fbe131b53 191 return(UNKNOWN) ;
roysandberg 62:8e2fbe131b53 192
roysandberg 62:8e2fbe131b53 193 for(i = 0; i < 4; ++i)
roysandberg 62:8e2fbe131b53 194 if(PostClass[type][i] == PVC)
roysandberg 62:8e2fbe131b53 195 ++pvcs4 ;
roysandberg 62:8e2fbe131b53 196 for(pvcs8=pvcs4; i < 8; ++i)
roysandberg 62:8e2fbe131b53 197 if(PostClass[type][i] == PVC)
roysandberg 62:8e2fbe131b53 198 ++pvcs8 ;
roysandberg 62:8e2fbe131b53 199
roysandberg 62:8e2fbe131b53 200 if((pvcs4 >= 3) || (pvcs8 >= 6))
roysandberg 62:8e2fbe131b53 201 return(PVC) ;
roysandberg 62:8e2fbe131b53 202 else return(UNKNOWN) ;
roysandberg 62:8e2fbe131b53 203 }
roysandberg 62:8e2fbe131b53 204
roysandberg 62:8e2fbe131b53 205 /****************************************************************************
roysandberg 62:8e2fbe131b53 206 Check classification of previous beats' rhythms based on post beat
roysandberg 62:8e2fbe131b53 207 classification. If 7 of 8 previous beats were classified as NORMAL
roysandberg 62:8e2fbe131b53 208 (regular) classify the beat type as NORMAL (regular).
roysandberg 62:8e2fbe131b53 209 Call it a PVC if 2 of the last 8 were regular.
roysandberg 62:8e2fbe131b53 210 ****************************************************************************/
roysandberg 62:8e2fbe131b53 211
roysandberg 62:8e2fbe131b53 212 int CheckPCRhythm(int type)
roysandberg 62:8e2fbe131b53 213 {
roysandberg 62:8e2fbe131b53 214 int i, normCount, n ;
roysandberg 62:8e2fbe131b53 215
roysandberg 62:8e2fbe131b53 216
roysandberg 62:8e2fbe131b53 217 if(type == MAXTYPES)
roysandberg 62:8e2fbe131b53 218 return(UNKNOWN) ;
roysandberg 62:8e2fbe131b53 219
roysandberg 62:8e2fbe131b53 220 if(GetBeatTypeCount(type) < 9)
roysandberg 62:8e2fbe131b53 221 n = GetBeatTypeCount(type)-1 ;
roysandberg 62:8e2fbe131b53 222 else n = 8 ;
roysandberg 62:8e2fbe131b53 223
roysandberg 62:8e2fbe131b53 224 for(i = normCount = 0; i < n; ++i)
roysandberg 62:8e2fbe131b53 225 if(PCRhythm[type][i] == NORMAL)
roysandberg 62:8e2fbe131b53 226 ++normCount;
roysandberg 62:8e2fbe131b53 227 if(normCount >= 7)
roysandberg 62:8e2fbe131b53 228 return(NORMAL) ;
roysandberg 62:8e2fbe131b53 229 if(((normCount == 0) && (n < 4)) ||
roysandberg 62:8e2fbe131b53 230 ((normCount <= 1) && (n >= 4) && (n < 7)) ||
roysandberg 62:8e2fbe131b53 231 ((normCount <= 2) && (n >= 7)))
roysandberg 62:8e2fbe131b53 232 return(PVC) ;
roysandberg 62:8e2fbe131b53 233 return(UNKNOWN) ;
roysandberg 62:8e2fbe131b53 234 }