Class: PostRunner::HRV_Analyzer
- Inherits:
-
Object
- Object
- PostRunner::HRV_Analyzer
- Defined in:
- lib/postrunner/HRV_Analyzer.rb
Overview
This class analyzes the heart rate variablity based on the R-R intervals in the given FIT file. It can compute RMSSD and a HRV score if the data quality is good enough.
Instance Attribute Summary collapse
-
#rr_intervals ⇒ Object
readonly
Returns the value of attribute rr_intervals.
-
#timestamps ⇒ Object
readonly
Returns the value of attribute timestamps.
Instance Method Summary collapse
-
#has_hrv_data? ⇒ Boolean
The method can be used to check if we have valid HRV data.
-
#initialize(fit_file) ⇒ HRV_Analyzer
constructor
Create a new HRV_Analyzer object.
-
#lnrmssdx20(start_time = 0.0, duration = nil) ⇒ Object
The RMSSD value is not very easy to memorize.
-
#lnrmssdx20_1sigma ⇒ Object
This method is similar to lnrmssdx20 but it tries to search the data for the best time period to compute the lnrmssdx20 value from.
-
#rmssd(start_time = 0.0, duration = nil) ⇒ Object
Compute the root mean square of successive differences.
-
#total_duration ⇒ Object
Return the total duration of all measured intervals in seconds.
Constructor Details
#initialize(fit_file) ⇒ HRV_Analyzer
Create a new HRV_Analyzer object.
26 27 28 29 |
# File 'lib/postrunner/HRV_Analyzer.rb', line 26 def initialize(fit_file) @fit_file = fit_file collect_rr_intervals end |
Instance Attribute Details
#rr_intervals ⇒ Object (readonly)
Returns the value of attribute rr_intervals.
22 23 24 |
# File 'lib/postrunner/HRV_Analyzer.rb', line 22 def rr_intervals @rr_intervals end |
#timestamps ⇒ Object (readonly)
Returns the value of attribute timestamps.
22 23 24 |
# File 'lib/postrunner/HRV_Analyzer.rb', line 22 def end |
Instance Method Details
#has_hrv_data? ⇒ Boolean
The method can be used to check if we have valid HRV data. The FIT file must have HRV data and the measurement duration must be at least 30 seconds.
34 35 36 |
# File 'lib/postrunner/HRV_Analyzer.rb', line 34 def has_hrv_data? !@fit_file.hrv.empty? && total_duration > 30.0 end |
#lnrmssdx20(start_time = 0.0, duration = nil) ⇒ Object
The RMSSD value is not very easy to memorize. Alternatively, we can multiply the natural logarithm of RMSSD by -20. This usually results in values between 1.0 (for untrained) and 100.0 (for higly trained) athletes. Values larger than 100.0 are rare but possible.
91 92 93 |
# File 'lib/postrunner/HRV_Analyzer.rb', line 91 def lnrmssdx20(start_time = 0.0, duration = nil) -20.0 * Math.log(rmssd(start_time, duration)) end |
#lnrmssdx20_1sigma ⇒ Object
This method is similar to lnrmssdx20 but it tries to search the data for the best time period to compute the lnrmssdx20 value from.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/postrunner/HRV_Analyzer.rb', line 97 def lnrmssdx20_1sigma # Create a new Array that consists of rr_intervals and timestamps # tuples. set = [] 0.upto(@rr_intervals.length - 1) do |i| set << [ @rr_intervals[i] ? @rr_intervals[i] : 0.0, [i] ] end percentiles = Percentiles.new(set) # Compile a list of all tuples with rr_intervals that are outside of the # PT84 (aka +1sigma range. Sort the list by time. not_1sigma = percentiles.not_tp_x(84.13).sort { |e1, e2| e1[1] <=> e2[1] } # Then find the largest time gap in that list. So all the values in that # gap are within TP84. gap_start = gap_end = 0 last = nil not_1sigma.each do |e| if last if (e[1] - last) > (gap_end - gap_start) gap_start = last gap_end = e[1] end end last = e[1] end # That gap should be at least 30 seconds long. Otherwise we'll just use # all the values. return lnrmssdx20 if gap_end - gap_start < 30 lnrmssdx20(gap_start, gap_end - gap_start) end |
#rmssd(start_time = 0.0, duration = nil) ⇒ Object
Compute the root mean square of successive differences.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/postrunner/HRV_Analyzer.rb', line 49 def rmssd(start_time = 0.0, duration = nil) # Find the start index based on the requested interval start time. start_idx = 0 .each do |ts| break if ts >= start_time start_idx += 1 end # Find the end index based on the requested interval duration. if duration end_time = start_time + duration end_idx = start_idx while end_idx < (.length - 1) && [end_idx] < end_time end_idx += 1 end else end_idx = -1 end last_i = nil sum = 0.0 cnt = 0 @rr_intervals[start_idx..end_idx].each do |i| if i && last_i sum += (last_i - i) ** 2.0 cnt += 1 end last_i = i end Math.sqrt(sum / cnt) end |
#total_duration ⇒ Object
Return the total duration of all measured intervals in seconds.
39 40 41 |
# File 'lib/postrunner/HRV_Analyzer.rb', line 39 def total_duration [-1] end |