0

Had an array with HR data in the form of BPMs (beats per minute).

Need to split the data into segments where the HR was increasing, decreasing, and stayed the same to find the up/down amplitude and the associated times as well as the times when the heart rate did not change.

To do so, tried using find_peaks to find the peaks and troughs of the HR data. To find troughs, I did a transformation of the original HR by multiplying it by -1 to find its peaks which in turn is the real troughs of the original HR data.

find_peaks while specifying plateau and height, gives outputs that contains the peak location as well as the plateau locations and the peak values, example from below:

find_peaks(arr, height=0.5, prominence=0.1, plateau_size=0.5)

(array([ 9, 18, 33, 64, 70, 80, 87]),
{'plateau_sizes': array([5, 2, 2, 3, 1, 3, 2]),
'left_edges': array([ 7, 18, 33, 63, 70, 79, 87]),
'right_edges': array([11, 19, 34, 65, 70, 81, 88]),
'peak_heights': array([ 80.,  87.,  81., 107., 106., 105., 105.]),
'prominences': array([ 2., 11.,  2., 18.,  3.,  8.,  8.]),
'left_bases': array([ 3,  3, 29, 43, 68, 74, 74]),
'right_bases': array([13, 40, 40, 98, 98, 98, 98])})

however, upon specifying height for the negative version of the original Heart rate Data to find the troughs and the heights, it returned empty array. If I remove the height=0.5, it outputs valid values except the peak_heights.

find_peaks(trougharr,plateau_size=0.5,height=0.5) 
(array([], dtype=int64),
{'plateau_sizes': array([], dtype=int64),
'left_edges': array([], dtype=int64),
'right_edges': array([], dtype=int64),
'peak_heights': array([], dtype=float64)})

Is there something wrong calling height with negative numbered arrays? If there's a easier method or simpler method for splitting up the data into up and down and constant portions, that would be much appreciated.

the original sample HR data is as such:

HR
    array([ 77,  77,  77,  76,  77,  78,  79,  80,  80,  80,  80,  80,  79,
            78,  78,  79,  83,  85,  87,  87,  86,  86,  86,  85,  83,  81,
            80,  79,  79,  79,  80,  80,  80,  81,  81,  80,  79,  79,  79,
            74,  69,  69,  69,  69,  70,  70,  70,  70,  70,  71,  72,  80,
            82,  89,  92,  95,  97,  99, 100, 102, 103, 105, 106, 107, 107,
           107, 105, 104, 103, 105, 106, 102, 100,  97,  97,  98, 101, 102,
           104, 105, 105, 105, 104, 104, 104, 104, 104, 105, 105, 104, 104,
           104, 104,  98,  96,  93,  92,  90,  89])

-1*HR. (the problematic one)

    array([ -77,  -77,  -77,  -76,  -77,  -78,  -79,  -80,  -80,  -80,  -80,
            -80,  -79,  -78,  -78,  -79,  -83,  -85,  -87,  -87,  -86,  -86,
            -86,  -85,  -83,  -81,  -80,  -79,  -79,  -79,  -80,  -80,  -80,
            -81,  -81,  -80,  -79,  -79,  -79,  -74,  -69,  -69,  -69,  -69,
            -70,  -70,  -70,  -70,  -70,  -71,  -72,  -80,  -82,  -89,  -92,
            -95,  -97,  -99, -100, -102, -103, -105, -106, -107, -107, -107,
           -105, -104, -103, -105, -106, -102, -100,  -97,  -97,  -98, -101,
           -102, -104, -105, -105, -105, -104, -104, -104, -104, -104, -105,
           -105, -104, -104, -104, -104,  -98,  -96,  -93,  -92,  -90,  -89])

Tried to split Heart Rate data into sections where it was increasing/decreasing/staying constant to find the up_amplitude,up_time, down_amplitude, down_time, time_constant. Found find_peaks to do it but it may not be the simplest, if there's a simpler method, please point me to it.

Tried to use peak_prominences, but it did not detect all prominences for some reason, the codes tried were:

peaks, _ = find_peaks(x)
prominences = peak_prominences(x, peaks)[0]

contour_heights = x[peaks] - prominences
plt.plot(x)
plt.plot(peaks, x[peaks], "x")
plt.vlines(x=peaks, ymin=contour_heights, ymax=x[peaks])
plt.show()

The prominences missed several locations.

enter image description here

Dragonthoughts
  • 2,180
  • 8
  • 25
  • 28
SG443
  • 1

0 Answers0