Software for computing Heart Rate Fragmentation 1.0.0

File: <base>/HRF.awk (4,659 bytes)
{
    ### Input file: two columns, time of the R peak in seconds and beat type
    ### Ex.: 0.000 1
    ###      0.808 1
    ###      1.618 1
    ###      2.458 1
 
    CONVFMT = "%.3lf";
    
    NN_min = .300;  # NN intervals <= 0.3 s will be excluded
    NN_max = 1.800; # NN intervals >= 1.8 s will be excluded
    SF = 250;    # ECG sampling frequency
    t = $1;      # Time of the R peak in seconds
    ann = $2     # Annotation: beat type (1: sinus; 2: PVC; 3: PAC)

    #### The time of each R peak is rounded (up or down) to the closest multiple of 1/SF.                                          
    #### Ex.: Let SF = 250 Hz (1/SF = 0.004 s). The time of each R peak should be multiples of 0.004 but sometimes it is not due to conversion/export problems.
    #### If, for example, the time of the R peak was 0.809, this value would be rounded down to 0.808.
    #### Users not interested in this "correction," should comment the next five lines.
    
    aux = int(sprintf(CONVFMT, t*SF));
    if (t - aux/SF > 0.5)
	t = (aux+1)/SF;
    if (t - aux/SF  <= 0.5 && t - aux/SF > 0)
	t = aux/SF;
   
    #### Calculation of NN and delta NN intervals after reading 4 data points
    NN = t - t_1;     # Current NN interval
    NN_1 = t_1 - t_2; # Previous NN interval
    NN_2 = t_2 - t_3; # NN interval preceeding the "previous NN interval"
    dNN_formatted = sprintf(CONVFMT, t - 2*t_1 + t_2);      # Current delta NN interval
    dNN = dNN_formatted + 0;
    dNN_1_formatted = sprintf(CONVFMT, t_1 - 2*t_2 + t_3);  # Previous delta NN interval
    dNN_1 = dNN_1_formatted + 0;
    
    #### Verification of whether the current beat and the 3 preceeding ones are "normal sinus" beats (ann == 1)                                        
    if (ann == 1  &&  ann_1 == 1  &&  ann_2 == 1  &&  ann_3 == 1)
	flag_1 = 0;
    else{
	flag_1 = 1;
	non_sinus = 1;
    }
    if (NR <= 4 && (ann < 1 || ann_1 < 1 || ann_2 < 1 || ann_3 < 1))
	non_sinus = 0;

    #### Verification of whether current NN interval and the 3 preceeding one are between NN_min (0.3 sec) and NN_max (1.8 sec)
    if (NN < NN_max  &&  NN > NN_min  &&  NN_1 < NN_max  &&  NN_1 > NN_min  &&  NN_2 < NN_max  &&  NN_2 > NN_min)
	flag_2 = 0;
    else{
	flag_2 = 1;
	outlier = 1; 
    }
    if (NR <= 4 && (NN == 0 || NN_1 == 0 || NN_2 == 0 || NN_3 == 0))
	outlier = 0;

    # Counter for the number of inflection points: IP 
    # Counter for the number of delta NN intervals: n_dNN
    # Counter for the number of delta NN intervals in short (long) accelerative and decelerative segments: short (long) 
    # Counter for the number of delta NN intervals between consecutive inflection points: cont

    #### Hard inflection point criterion: dNN_current * dNN_previous < 0. 
    if (NR > 3 && flag_1 == 0 && flag_2 == 0 && dNN * dNN_1 < 0){
	IP++;
	if (non_sinus != 1 && outlier != 1){
	    if (IP > 1)
		n_dNN += cont;   
	    if (cont <= 2 && IP > 1)
		short += cont;
	    if (cont > 2 && IP > 1)
		long += cont;
#	    print "Hard IP: time =", t_1, " \#  Beat =", NR-2, "  NN =", NN_1;
	    if (IP == 1)
		NN_total = 1;
	    else
		NN_total += cont;
#	    print ("NN_total =", NN_total); 
	}
	if(non_sinus == 1 || outlier == 1){
	    non_sinus = 0; 
	    outlier = 0;
	    NN_total += 1
#	    print "Hard IP: time =", t_1, "  \# Beat =", NR-2, "  NN =", NN_1;
#	    print "NN_total =", NN_total;
	}
	cont = 0;
    }

    #### Soft inflection point criterion: dNN * dNN_prev == 0 and dNN != dNN_prev
    if (NR > 3 && flag_1 == 0 && flag_2 == 0 && dNN * dNN_1 == 0  &&  dNN != dNN_1){
	IP++;
	if (non_sinus != 1 && outlier != 1){
	    if (IP > 1)
		n_dNN += cont;
	    if (dNN_1 != 0) 
		if (cont <= 2 && IP > 1)
		    short += cont;
	    if (cont > 2 && IP > 1)
		    long += cont;
#	    print "Soft IP: time =", t_1, "  \# Beat =", NR-2, "  NN =", NN_1;
	    if (IP == 1)
		NN_total = 1;
	    else
		NN_total += cont;
#	    print ("NN_total =", NN_total); 
	}
	if((non_sinus == 1 || outlier == 1)){
	    non_sinus = 0;
	    outlier = 0;
	    NN_total += 1;
#	    print "Soft IP: time =", t_1, "  \# Beat =", NR-2, "  NN =", NN_1;
#	    print "NN_total =", NN_total;
	}
	cont = 0;
    }
    
    if (NR > 1)
	cont++;
    
    ann_3 = ann_2;
    ann_2 = ann_1;
    ann_1 = ann;
    t_3 = t_2;
    t_2 = t_1;
    t_1 = t;
    N_acc_dec = short + long;

    if (n_dNN > 0)
	PIP = (sprintf(CONVFMT,IP/NN_total*100));
    if (N_acc_dec > 0)
	PNNSS = (sprintf(CONVFMT,short/N_acc_dec*100));
    if (n_dNN > 0)
	PNNLS = (sprintf(CONVFMT,long/n_dNN*100));
}
END{print "PIP =", IP"/"NN_total, "=", PIP";", "  PNNSS =", short"/"N_acc_dec"*100 =", PNNSS";", "  PNNLS =", long"/"n_dNN"*100 =", PNNLS}