Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
5.8 kB
5
Indexable
Never
public int HRVCalculationAlgo(Double[] ppgData, int samplingRate, int numFrame, int mean_HR) {
        // Find HRV
        // Find peaks
        double[] dbydt_HR = new double[ppgData.length];
        double[] daRed_HR = new double[ppgData.length];

        // Initialise peak_arr
        for (int z = 0; z < ppgData.length; z++) {
            //dbydt_HR[z] = 0;
            daRed_HR[z] = ppgData[z].doubleValue();
        }


        // Size of one window is mean_HR/60,
        // Since need to take 3 RR in one window, size of one window will be meah_HR*4/60
        // Hence number of samples per window is (mean_HR*4*SamplingRate/60)
        // Example: Lets say framerate 30, samples 900 for 30 seconds, HR is 60

        int window_size_RR = mean_HR * 4 * samplingRate / 60;  // based on number of samples window size 120

        // find peak locations where dbydt = 0
        double[][] RR_peaks = new double[window_size_RR + 1][2];  // Find the peaks of each pulse within the window


        // Window slides with one pulse width
        int sliding_samples_window_RR = mean_HR * samplingRate / 60;


        // Number of sliding window in this example = (900 -120) / 30 = 26
        int num_sliding_window_RR = (int) floor((numFrame - window_size_RR) / sliding_samples_window_RR); //

        double[][] RR_vals = new double[num_sliding_window_RR + 1][3]; // RR1, RR2 and RR3
        int[] category = new int[num_sliding_window_RR]; // identify category for each window

        // Inside window
        for (int iter = 1; iter <= num_sliding_window_RR; iter++) {    // num_sliding_window_RR, loop for 26 times

            int win_start = (iter - 1) * sliding_samples_window_RR; // start of sample in each window
            for (int l = win_start; l <= win_start + window_size_RR; l++) {
                daRed_HR[l - win_start] = ppgData[l];  // store in daRed_HR
            }

            // TODO find out the index of the peaks
            dbydt_HR = PulseShaping.derivative(daRed_HR, window_size_RR, samplingRate); // diffs between consecutive values

            int k = 0;
            for (int j = 1; j < window_size_RR - 1; j++) {
                // Take positive peaks
                if (((dbydt_HR[j] > 0 && dbydt_HR[j + 1] < 0) || dbydt_HR[j] == 0)) {
                    RR_peaks[k][0] = daRed_HR[j];
                    RR_peaks[k][1] = j;
                    k++;
                }
            }

//

            double temp = 0;
            // Sort the RR_peaks and take the maximum, below is the algo to sort in decending order i.e. Max => min
            for (int i = 0; i < window_size_RR; i++) {
                for (int j = 0; j < window_size_RR - i - 1; j++) {

                    if (RR_peaks[j][0] < RR_peaks[j + 1][0]) {
                        temp = RR_peaks[j][0];
                        RR_peaks[j][0] = RR_peaks[j + 1][0];
                        RR_peaks[j + 1][0] = temp;
                    }
                }
            }

//

            double[] RtoR = new double[4];
            RR_vals[iter][0] = Math.abs(RR_peaks[0][1] - RR_peaks[1][1]); // RR1
            RR_vals[iter][1] = Math.abs(RR_peaks[1][1] - RR_peaks[2][1]); // RR2
            RR_vals[iter][2] = Math.abs(RR_peaks[2][1] - RR_peaks[3][1]); //RR3


        }  // End of sliding window if loop

        // Apply the algo for Regular/Irregular Rythm
        // Now iterate through each of the window and find the category

        for (int iter1 = 1; iter1 < num_sliding_window_RR - 3; iter1++) {

            category[iter1] = 1; // Initially set as category 1 by default i.e. Regular - Step - 2

            // If RR2 < .6 sec
            if (((RR_vals[iter1][1] / samplingRate) < .6) && (RR_vals[iter1][1] < RR_vals[iter1][2])) {
                category[iter1] = 5;  // Step - 3
            }


            int pulse = 1;
            for (int i = 0; i <= 3; i++) {   //start of local loop
                if ((RR_vals[iter1 + i][0] / samplingRate) < 0.8 && (RR_vals[iter1 + i][1] / samplingRate) < 0.8 &&
                        (RR_vals[iter1 + i][2] / samplingRate) < 0.8 &&
                        (RR_vals[iter1][0] + RR_vals[iter1][1] + RR_vals[iter1][2]) / samplingRate < 1.8) {
                    category[iter1] = 5;   // Step - 3a
                    pulse++;
                }
            }  // end of local loop

            if (pulse < 4) category[iter1] = 1;  // Step - 3b

            if (RR_vals[iter1][1] < .9 * RR_vals[iter1][0] && RR_vals[iter1][0] < .9 * RR_vals[iter1][2]) {

                if ((RR_vals[iter1][1] + RR_vals[iter1][2]) < 2 * RR_vals[iter1][1]) {
                    category[iter1] = 2;
                } else {
                    category[iter1] = 3;
                }
            }   // Step 4a and 4b
//                    Log.v("HouronEarth :", " Iteration category - step-4a & 4b : "  + iter1 + "  " + category[iter1]);

            if (RR_vals[iter1][1] > 1.5 * RR_vals[iter1][0]) {
                category[iter1] = 4;   // Step - 5
            }

//                    Log.v("HouronEarth :", " Iteration category - step-5 : "  + iter1 + "  " + category[iter1]);


        }  // End of sliding window algo loop Rythm
//        Log.v("HouronEarth :", " num_sliding_window_RR : "   + "  " + num_sliding_window_RR);
        int count = 0;
        for (int iter2 = 1; iter2 < num_sliding_window_RR - 3; iter2++) {
            if (category[iter2] == 1) count++;
//                    Log.v("HouronEarth :", " category - final : "   + "  " + category[iter2]);
        }
//        Log.v("HouronEarth :", " Count of 1 in Rythm : "   + "  " + count);

        int Rythm = 0;
        if (count >= .95 * num_sliding_window_RR) {
            Rythm = 1;
        }
        //Log.v(TAG, " Rythm : " + Rythm);
        return Rythm;

    }