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

postclas.cpp

Committer:
roysandberg
Date:
2015-06-28
Revision:
62:8e2fbe131b53

File content as of revision 62:8e2fbe131b53:

/*****************************************************************************
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) ;
    }