ECG-Kit 1.0
(7,445 bytes)
/*****************************************************************************
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 "bdac.h"
#include <wfdb/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) ;
}