aromring / MAX30102_by_RF

Arduino C code for MAX30102 pulse oximetry sensor (MAXIM Integrated, Inc.)
166 stars 73 forks source link

some abnormal data #14

Closed GOKUandVEGET closed 4 years ago

GOKUandVEGET commented 4 years ago

1. Use your latest code My parameters 50hz 3s raw data.xlsx

2. I have some questions about the following code

if(LOWEST_PERIOD==n_last_peak_interval) rf_initialize_periodicity_search(an_x, BUFFER_SIZE, &n_last_peak_interval, HIGHEST_PERIOD, min_autocorrelation_ratio, f_ir_sumsq); / At this time n_last_peak_interval !=0,and then if(n_last_peak_interval!=0) rf_signal_periodicity(an_x, BUFFER_SIZE, &n_last_peak_interval, LOWEST_PERIOD, HIGHEST_PERIOD, min_autocorrelation_ratio, f_ir_sumsq, ratio); Calculated twice?????????? /

// Find signal periodicity if(*correl>=min_pearson_correlation) { // At the beginning of oximetry run the exact range of heart rate is unknown. This may lead to wrong rate if the next call does not find the first // peak of the autocorrelation function. E.g., second peak would yield only 50% of the true rate. if(LOWEST_PERIOD==n_last_peak_interval) rf_initialize_periodicity_search(an_x, BUFFER_SIZE, &n_last_peak_interval, HIGHEST_PERIOD, min_autocorrelation_ratio, f_ir_sumsq); // RF, If correlation os good, then find average periodicity of the IR signal. If aperiodic, return periodicity of 0 if(n_last_peak_interval!=0) rf_signal_periodicity(an_x, BUFFER_SIZE, &n_last_peak_interval, LOWEST_PERIOD, HIGHEST_PERIOD, min_autocorrelation_ratio, f_ir_sumsq, ratio); } else n_last_peak_interval=0;

GOKUandVEGET commented 4 years ago

thank you!

GOKUandVEGET commented 4 years ago

Calculated twice means It will be calculated twice during the first test

aromring commented 4 years ago

No, the heart rate (HR) is not calculated twice. Apparently, you haven't even bothered to look inside the new function, have you? Its role is to find the approximate range of the true HR. In other words, the neighborhood of the first autocorrelation peak. The algorithm uses relative autocorrelation function defined as:

rel_aut(n) = aut(n) / aut(0)

where aut(n) = autocorrelation at lag = n. Below, is a plot of rel_aut(n) calculated from one of your signals: image During the first pass rf_initialize_periodicity_search() always starts from starts from MAX_HR which corresponds to lag = LOWEST_PERIOD. In this example MAX_HR=200, FS=50, so LOWEST_PERIOD=15. In the first iteration the algorithm thus calculates rel_aut(15) (orange circle with label "1") and checks if it's smaller than min_autocorrelation_ratio. The default value for min_autocorrelation_ratio parameter is 0.5. In this example rel_aut(15) is smaller, indeed, and the algorithm advances to the next lag in two steps, i.e., lag 17. Once, again rel_aut(17) (orange circle with label "2") is calculated and compared against min_autocorrelation_ratio. This iterative process advances in 2 lag steps until either rel_aut(n) >= min_autocorrelation_ratio, or the lag for MIN_HR is reached. In this example MIN_HR=40 and HIGHEST_PERIOD=75. But as you can see, in the 8th iteration the algorithm finds rel_aut(29) >= min_autocorrelation_ratio and terminates. The n = 29 is returned as a viable starting point for the existing routine rf_signal_periodicity(), whose progress is indicated by green circles. It finds lag = 32 in its 3rd iteration as the tip of the autocorrelation peak and converts it to HR = 93.75. Now, 32 is used as a starting point for the second pass and rf_initialize_periodicity_search() is not called. Lastly, if MAX_HR is so high that the rel_aut(LOWEST_PERIOD) happens to be >= min_autocorrelation_ratio at the beginning (this would be lag = 3 in this example), the rf_initialize_periodicity_search() can detect it in its "Check sanity" section and properly advance to a lag = k with appropriately lower rel_aut(k).

aromring commented 4 years ago

If you know of a better initialization algorithm that is at least equally robust and significantly faster, then let me know - I will gladly consider it. In addition, any bug reports with raw data are welcome.

GOKUandVEGET commented 4 years ago

如果您知道一个更好的初始化算法,该算法至少具有同等的鲁棒性并且明显更快,那么请告诉我-我将很乐意考虑。此外,欢迎提供任何包含原始数据的错误报告。

There is some abnormal data in the first point I put forward. It seems that it is not the problem of the algorithm, but perhaps the problem of the sensor. Can you check it?

aromring commented 4 years ago

"Abnormal data"? You mean, HR = 96 instantly followed by HR = 71? I've checked it - this is the same problem I have already described in https://github.com/aromring/MAX30102_by_RF/issues/11#issuecomment-616244499

GOKUandVEGET commented 4 years ago

algorithm bug:if your hr=MAX_HR or your hr lag =lag(MAX_HR +1),your hr little a half

aromring commented 4 years ago

Thank you, but huh? I don't understand what you are trying to say. Can you formulate your report more clearly?