Post

Replies

Boosts

Views

Activity

Reply to Accuracy of IBI Values Measured by Apple Watch
Hi, came across this while working with the same API and wanted to flag something in the snippet that's easy to miss. The precededByGap handling drops the flagged beat, but the interval loop still diffs every consecutive pair: swift if !precededByGap { timePoints.append(timeSinceSeriesStart) } So if beats land at t₁, t₂, [gap], t₅, t₆: t₅ gets discarded, and the loop then computes t₆ − t₂ and reports it as a single IBI. That value spans both the gap and the dropped beat, so you end up with intervals roughly 2–3× a normal one scattered through the output. The flag is telling you the interval leading into this beat isn't valid, not that the beat's timestamp is bad. So keep every timestamp and skip the interval instead: swift struct Beat { let time: TimeInterval let precededByGap: Bool } var beats: [Beat] = [] // in the HKHeartbeatSeriesQuery handler: beats.append(Beat(time: timeSinceSeriesStart, precededByGap: precededByGap)) if done { for i in 1..<beats.count { guard !beats[i].precededByGap else { continue } // interval spans a gap let ibi = (beats[i].time - beats[i-1].time) * 1000 self.ibiValues.append(ibi) } } Two benefits: the invalid interval goes away, and you recover the valid t₆ − t₅ interval the original version was throwing out. Worth sorting before you benchmark against the Galaxy values, given you're computing stress from HRV. RMSSD squares successive differences, so one inflated interval can dominate a window, and in the frequency domain it injects broadband energy right across the LF/HF boundary. A couple of these per window will move your metric more than any real difference between the two devices.
9h
Reply to Accuracy of IBI Values Measured by Apple Watch
Hi, came across this while working with the same API and wanted to flag something in the snippet that's easy to miss. The precededByGap handling drops the flagged beat, but the interval loop still diffs every consecutive pair: swift if !precededByGap { timePoints.append(timeSinceSeriesStart) } So if beats land at t₁, t₂, [gap], t₅, t₆: t₅ gets discarded, and the loop then computes t₆ − t₂ and reports it as a single IBI. That value spans both the gap and the dropped beat, so you end up with intervals roughly 2–3× a normal one scattered through the output. The flag is telling you the interval leading into this beat isn't valid, not that the beat's timestamp is bad. So keep every timestamp and skip the interval instead: swift struct Beat { let time: TimeInterval let precededByGap: Bool } var beats: [Beat] = [] // in the HKHeartbeatSeriesQuery handler: beats.append(Beat(time: timeSinceSeriesStart, precededByGap: precededByGap)) if done { for i in 1..<beats.count { guard !beats[i].precededByGap else { continue } // interval spans a gap let ibi = (beats[i].time - beats[i-1].time) * 1000 self.ibiValues.append(ibi) } } Two benefits: the invalid interval goes away, and you recover the valid t₆ − t₅ interval the original version was throwing out. Worth sorting before you benchmark against the Galaxy values, given you're computing stress from HRV. RMSSD squares successive differences, so one inflated interval can dominate a window, and in the frequency domain it injects broadband energy right across the LF/HF boundary. A couple of these per window will move your metric more than any real difference between the two devices.
Replies
Boosts
Views
Activity
9h
Reply to Accuracy of IBI Values Measured by Apple Watch
Are HKHeartbeatSeriesSample objects generated during an active HKWorkoutSession, or only as companions to system-computed heartRateVariabilitySDNN samples during stationary periods — and is there any supported path to receiving them with sub-5-second latency?
Replies
Boosts
Views
Activity
9h