Untitled
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; }