I've got some basic filter code setup (but not yet tested).
Dependencies: BLE_API Queue mbed nRF51822
Fork of BLE_HeartRate by
Diff: postclas.cpp
- Revision:
- 62:8e2fbe131b53
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/postclas.cpp Sun Jun 28 03:06:00 2015 +0000 @@ -0,0 +1,234 @@ +/***************************************************************************** +FILE: postclas.cpp +AUTHOR: Patrick S. Hamilton +REVISED: 5/13/2002 + ___________________________________________________________________________ + +postclas.cpp: Post classifier +Copywrite (C) 2002 Patrick S. Hamilton + +This file is free software; you can redistribute it and/or modify it under +the terms of the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) any +later version. + +This software is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU Library General Public License for more +details. + +You should have received a copy of the GNU Library General Public License along +with this library; if not, write to the Free Software Foundation, Inc., 59 +Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +You may contact the author by e-mail (pat@eplimited.edu) or postal mail +(Patrick Hamilton, E.P. Limited, 35 Medford St., Suite 204 Somerville, +MA 02143 USA). For updates to this software, please visit our website +(http://www.eplimited.com). + __________________________________________________________________________ + +This file contains functions for classifying beats based after the +following beat is detected. + + ResetPostClassify() -- Resets static variables used by + PostClassify() + PostClassify() -- classifies each beat based on six preceding + beats and the following beat. + CheckPostClass() -- classifys beat type based on the last + eight post classifications of that beat. + CheckPCRhythm() -- returns the classification of the RR interval + for this type of beat based its previous eight RR intervals. + +****************************************************************/ + +#include <mbed.h> +#include "bdac.h" +#include "ecgcodes.h" + +// External Prototypes. + +double DomCompare(int newType, int domType) ; +int GetBeatTypeCount(int type) ; + +// Records of post classifications. + +int PostClass[MAXTYPES][8], PCInitCount = 0 ; +int PCRhythm[MAXTYPES][8] ; + +/********************************************************************** + Resets post classifications for beats. +**********************************************************************/ + +void ResetPostClassify() + { + int i, j ; + for(i = 0; i < MAXTYPES; ++i) + for(j = 0; j < 8; ++j) + { + PostClass[i][j] = 0 ; + PCRhythm[i][j] = 0 ; + } + PCInitCount = 0 ; + } + +/*********************************************************************** + Classify the previous beat type and rhythm type based on this beat + and the preceding beat. This classifier is more sensitive + to detecting premature beats followed by compensitory pauses. +************************************************************************/ + +void PostClassify(int *recentTypes, int domType, int *recentRRs, int width, double mi2, + int rhythmClass) + { + static int lastRC, lastWidth ; + static double lastMI2 ; + int i, regCount, pvcCount, normRR ; + double mi3 ; + + // If the preceeding and following beats are the same type, + // they are generally regular, and reasonably close in shape + // to the dominant type, consider them to be dominant. + + if((recentTypes[0] == recentTypes[2]) && (recentTypes[0] != domType) + && (recentTypes[0] != recentTypes[1])) + { + mi3 = DomCompare(recentTypes[0],domType) ; + for(i = regCount = 0; i < 8; ++i) + if(PCRhythm[recentTypes[0]][i] == NORMAL) + ++regCount ; + if((mi3 < 2.0) && (regCount > 6)) + domType = recentTypes[0] ; + } + + // Don't do anything until four beats have gone by. + + if(PCInitCount < 3) + { + ++PCInitCount ; + lastWidth = width ; + lastMI2 = 0 ; + lastRC = 0 ; + return ; + } + + if(recentTypes[1] < MAXTYPES) + { + + // Find first NN interval. + for(i = 2; (i < 7) && (recentTypes[i] != recentTypes[i+1]); ++i) ; + if(i == 7) normRR = 0 ; + else normRR = recentRRs[i] ; + + // Shift the previous beat classifications to make room for the + // new classification. + for(i = pvcCount = 0; i < 8; ++i) + if(PostClass[recentTypes[1]][i] == PVC) + ++pvcCount ; + + for(i = 7; i > 0; --i) + { + PostClass[recentTypes[1]][i] = PostClass[recentTypes[1]][i-1] ; + PCRhythm[recentTypes[1]][i] = PCRhythm[recentTypes[1]][i-1] ; + } + + // If the beat is premature followed by a compensitory pause and the + // previous and following beats are normal, post classify as + // a PVC. + + if(((normRR-(normRR>>3)) >= recentRRs[1]) && ((recentRRs[0]-(recentRRs[0]>>3)) >= normRR)// && (lastMI2 > 3) + && (recentTypes[0] == domType) && (recentTypes[2] == domType) + && (recentTypes[1] != domType)) + PostClass[recentTypes[1]][0] = PVC ; + + // If previous two were classified as PVCs, and this is at least slightly + // premature, classify as a PVC. + + else if(((normRR-(normRR>>4)) > recentRRs[1]) && ((normRR+(normRR>>4)) < recentRRs[0]) && + (((PostClass[recentTypes[1]][1] == PVC) && (PostClass[recentTypes[1]][2] == PVC)) || + (pvcCount >= 6) ) && + (recentTypes[0] == domType) && (recentTypes[2] == domType) && (recentTypes[1] != domType)) + PostClass[recentTypes[1]][0] = PVC ; + + // If the previous and following beats are the dominant beat type, + // and this beat is significantly different from the dominant, + // call it a PVC. + + else if((recentTypes[0] == domType) && (recentTypes[2] == domType) && (lastMI2 > 2.5)) + PostClass[recentTypes[1]][0] = PVC ; + + // Otherwise post classify this beat as UNKNOWN. + + else PostClass[recentTypes[1]][0] = UNKNOWN ; + + // If the beat is premature followed by a compensitory pause, post + // classify the rhythm as PVC. + + if(((normRR-(normRR>>3)) > recentRRs[1]) && ((recentRRs[0]-(recentRRs[0]>>3)) > normRR)) + PCRhythm[recentTypes[1]][0] = PVC ; + + // Otherwise, post classify the rhythm as the same as the + // regular rhythm classification. + + else PCRhythm[recentTypes[1]][0] = lastRC ; + } + + lastWidth = width ; + lastMI2 = mi2 ; + lastRC = rhythmClass ; + } + + +/************************************************************************* + CheckPostClass checks to see if three of the last four or six of the + last eight of a given beat type have been post classified as PVC. +*************************************************************************/ + +int CheckPostClass(int type) + { + int i, pvcs4 = 0, pvcs8 ; + + if(type == MAXTYPES) + return(UNKNOWN) ; + + for(i = 0; i < 4; ++i) + if(PostClass[type][i] == PVC) + ++pvcs4 ; + for(pvcs8=pvcs4; i < 8; ++i) + if(PostClass[type][i] == PVC) + ++pvcs8 ; + + if((pvcs4 >= 3) || (pvcs8 >= 6)) + return(PVC) ; + else return(UNKNOWN) ; + } + +/**************************************************************************** + Check classification of previous beats' rhythms based on post beat + classification. If 7 of 8 previous beats were classified as NORMAL + (regular) classify the beat type as NORMAL (regular). + Call it a PVC if 2 of the last 8 were regular. +****************************************************************************/ + +int CheckPCRhythm(int type) + { + int i, normCount, n ; + + + if(type == MAXTYPES) + return(UNKNOWN) ; + + if(GetBeatTypeCount(type) < 9) + n = GetBeatTypeCount(type)-1 ; + else n = 8 ; + + for(i = normCount = 0; i < n; ++i) + if(PCRhythm[type][i] == NORMAL) + ++normCount; + if(normCount >= 7) + return(NORMAL) ; + if(((normCount == 0) && (n < 4)) || + ((normCount <= 1) && (n >= 4) && (n < 7)) || + ((normCount <= 2) && (n >= 7))) + return(PVC) ; + return(UNKNOWN) ; + } \ No newline at end of file