calculateBaseLine method
Implementation
List<int?> calculateBaseLine(List<int?> millisecondsEpoch) {
int size = millisecondsEpoch.length;
List<int?> baselineArray = List.filled(size, null, growable: false);
int buckets = 1001, modeIndex = 0;
List<int?> freq = List.filled(buckets, null, growable: false);
int? modeValue = 0,
sumOfValues = 0,
selectedPeak = 0; // 60-220 bpm = 1000-272 ms
/** calculate frequency distribution of intervals**/
for (int i = 0; i < buckets; i++) {
freq[i] = 0;
}
for (int j = 0; j < millisecondsEpoch.length; j++) {
int? epoch = millisecondsEpoch[j];
if (epoch == 0 || epoch! >= buckets) {
freq[0] = freq[0]!+1;
continue;
}
freq[epoch] = freq[epoch]! + 1;
}
/** calculate peak frequency or mode **/
for (int i = 1; i < buckets - 1; i++) {
if (freq[i]! > modeValue!) {
modeValue = freq[i];
modeIndex = i;
}
}
int peak = 0;
/** calculate limiting parameter **/
for (int i = buckets - 1; i >= 5; i--) {
if (sumOfValues! > (0.125 * (size - freq[0]!))) {
if (freq[i]! >= freq[i - 5]! &&
freq[i]! >= freq[i - 4]! &&
freq[i]! >= freq[i - 3]! &&
freq[i]! >= freq[i - 2]! &&
freq[i]! >= freq[i - 1]!) {
if (freq[i]! > 0.005 * (size - freq[0]!) ||
(modeIndex - i).abs() <= 30) {
selectedPeak = i;
peak = i;
break;
}
}
}
sumOfValues += freq[i]!;
}
/*if the peak is selected; other- wise, the mode is used*/
if (selectedPeak == 0) selectedPeak = modeIndex;
/** apply band filter with the use of limiting value
* low-pass filter are then set to 60 milliseconds below and above the selected peak or mode
* **/
baselineArray[0] = millisecondsEpoch[0];
for (int i = 0; i < size - 1; i++) { // change i from 1 to 0
if (millisecondsEpoch[i] == 0) {
baselineArray[i] =
millisecondsEpoch[i]; //avgLastMin(baselineFHRDR, i - 1);;
} else {
if (millisecondsEpoch[i]! >= (selectedPeak! + 100) ){
baselineArray[i] = (selectedPeak + 100); // 60 is given in the literature
}
if(millisecondsEpoch[i]! <= (selectedPeak - 100)){
baselineArray[i] = (selectedPeak - 100);
}
else {
baselineArray[i] = millisecondsEpoch[i];
}
}
//if (Double.isNaN(_baselineArray[i]))
//_baselineArray[i] = _baselineArray[i - 1];
}
//_baselineArray[0] = _millisecondsEpoch[0];
for (int i = 1; i < size - 1; i++) {
if (baselineArray[i] == 0) {
baselineArray[i] =
baselineArray[i-1]; //avgLastMin(baselineFHRDR, i - 1);;
} else {
if (baselineArray[i]! >= (selectedPeak! - 50) &&
baselineArray[i]! <=
(selectedPeak + 50)) {
// 60 is given in the literature
baselineArray[i] = baselineArray[i];
} else {
baselineArray[i] = baselineArray[i -
1]; //avgLastMin(baselineFHRDR, i - 1); //interpolate over previous values
}
}
//if (Double.isNaN(_baselineArray[i]))
//_baselineArray[i] = _baselineArray[i - 1];
}
baselineArray[size - 1] =
baselineArray[size - 2]; //avgLastMin(baselineFHRDR, size - 2);
double aTiny = 0.75;
for (int i = 0; i < baselineArray.length - 1; i++) {
baselineArray[i + 1] = (aTiny * baselineArray[i + 1]! + (1.0 - aTiny) * selectedPeak!).toInt();
}
int window = 2;
for (int i = window; i < baselineArray.length - window - 1; i++) {
baselineArray[i] =
getBaselineWindowSmoothAverage(baselineArray, i, window);
}
int avgHR;
avgHR = calculateAvgHeartRate(baselineArray);
// smoothing last min
double tiny = 0.3;
int start = baselineArray.length - window * 2;
for (int i = 0; i < baselineArray.length - 1; i++) {
baselineArray[i + 1] =
(tiny * avgHR + (1.0 - tiny) * baselineArray[i + 1]!).truncate();
}
start = 0;
for (int i = start; i < (window * 2) - 1; i++) {
baselineArray[i] =
(tiny * avgHR + (1.0 - tiny) * baselineArray[i + 1]!).truncate();
}
//int index = 1 * NO_OF_SAMPLES_PER_MINUTE;
//window = index;
avgHR = calculateLowVariationAvg(baselineArray, avgHR);
/*avgHR = calculateLowVariationAvg(_baselineArray,avgHR);
Log.i("avgHR",avgHR+"");
if(avgHR <=300 || avgHR > 700)
avgHR = calculateBasalHeartRate(_baselineArray);
Log.i("avgHR",avgHR+"");*/
tiny = 0.25;
for (int i = start; i < baselineArray.length - 1; i++) {
baselineArray[i] =
(tiny * avgHR + (1.0 - tiny) * baselineArray[i + 1]!).truncate();
}
return baselineArray;
}