Skip to content

Use the last RR interval in compute_hr - #601

Merged
tompollard merged 2 commits into
MIT-LCP:mainfrom
TheNetherWatcher:fix/compute-hr-last-interval
Oct 31, 2026
Merged

tompollard merged 2 commits into
MIT-LCP:mainfrom
TheNetherWatcher:fix/compute-hr-last-interval

Conversation

@TheNetherWatcher

Copy link
Copy Markdown
Contributor

compute_hr loops over range(len(qrs_inds) - 2) and then copies the rate at the last beat forward (heart_rate[qrs_inds[-1]:] = heart_rate[qrs_inds[-1]]). So the interval between the last two beats is never used:

  • compute_hr(14, [0, 2, 6, 12], fs=60) gives 900 bpm after sample 12 (from the 2-sample interval before it) instead of 600 bpm (from the last interval, 6 samples).
  • compute_hr(10, [2, 6], fs=1) returns only NaN, although the len(qrs_inds) < 2 check implies two beats are enough.

The loop now runs over every RR interval, and the last one fills up to the end of the signal. Everything before the last beat is unchanged. For record 100 with the reference annotations, the only differences are the 8 samples after the last beat.

Two tests are added in TestComputeHr, and both fail on main. ruff check is clean and pytest -m "not network" passes.

Related to #185, but that report was mostly caused by non-beat annotations (see the comments there), so this doesn't close it.

@tompollard tompollard left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this looks good! I checked record 100 and only the samples after the last beat change, as you said. It also fixes an IndexError when the last beat is past the end of the signal.

Could you rebase on main? #599 just added a changelog entry in the same place.

Optional: a sentence in the docstring explaining which interval each sample's rate comes from (like your code comment) would help users.

@TheNetherWatcher

Copy link
Copy Markdown
Contributor Author

Thanks! I've rebased onto main, and:

  • Added a docstring paragraph saying which RR interval each sample's rate comes from.
  • Added test_last_beat_past_end for the IndexError you found. It fails on main with index 12 is out of bounds for axis 0 with size 8.

Tests (89) and the docs build pass.

The loop stopped one interval early and copied the previous rate past
the last beat, so the last RR interval was never used and two beats gave
only NaN.
@TheNetherWatcher
TheNetherWatcher force-pushed the fix/compute-hr-last-interval branch from 836a01d to b9e0542 Compare October 31, 2026 17:03
@TheNetherWatcher

Copy link
Copy Markdown
Contributor Author

#600 was merged while I was pushing, so I've rebased once more. It's mergeable again, and tests pass (99).

@tompollard tompollard left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for all of these fixes! It's Halloween here today, so feels very appropriate to have @TheNetherWatcher digging up old bugs 🎃

@TheNetherWatcher

Copy link
Copy Markdown
Contributor Author

It's weekend, and I'm mostly free the entire weekend, so I go up issue fixing, bug hunting and performance improving in the OSS space every weekend.
btw, Happy Halloween!! 👻🎃

@tompollard
tompollard merged commit 577a18b into MIT-LCP:main Oct 31, 2026
18 checks passed
@TheNetherWatcher
TheNetherWatcher deleted the fix/compute-hr-last-interval branch November 1, 2026 06:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants