rhenanbartels / hrv

A Python package for heart rate variability analysis
BSD 3-Clause "New" or "Revised" License
196 stars 57 forks source link

frequency_domain call on interpolated RRiDetrended instance fails #22

Open noah10 opened 3 years ago

noah10 commented 3 years ago

Here's some sample code:

from hrv.classical import frequency_domain
from hrv.detrend import smoothness_priors
from hrv.rri import RRi

rr_vals = read_from_text('rest_rri.txt')
smooth_detrended_rr_vals = smoothness_priors(rr_vals)
smooth_fd_results = frequency_domain(smooth_detrended_rr_vals, method="ar", order=16)
print(f'smooth_fd_results: {smooth_fd_results}')

And here is the resulting stack trace:

Traceback (most recent call last):
  File "hrv-bug.py", line 8, in <module>
    smooth_fd_results = frequency_domain(smooth_detrended_rr_vals, method="ar", order=16)
  File "/Users/home/.virtualenvs/hrv-kubios-A4er0XLO/lib/python3.8/site-packages/hrv/classical.py", line 207, in frequency_domain
    fxx, pxx = _calc_pburg_psd(rri=rri, fs=fs, **kwargs)
  File "/Users/home/.virtualenvs/hrv-kubios-A4er0XLO/lib/python3.8/site-packages/hrv/classical.py", line 234, in _calc_pburg_psd
    burg = pburg(data=rri, order=order, NFFT=nfft, sampling=fs)
  File "/Users/home/.virtualenvs/hrv-kubios-A4er0XLO/lib/python3.8/site-packages/spectrum/burg.py", line 129, in __init__
    super(pburg, self).__init__(data, ar_order=order,
  File "/Users/home/.virtualenvs/hrv-kubios-A4er0XLO/lib/python3.8/site-packages/spectrum/psd.py", line 804, in __init__
    super(ParametricSpectrum, self).__init__(data, sampling=sampling,
  File "/Users/home/.virtualenvs/hrv-kubios-A4er0XLO/lib/python3.8/site-packages/spectrum/psd.py", line 282, in __init__
    self.data = data
  File "/Users/home/.virtualenvs/hrv-kubios-A4er0XLO/lib/python3.8/site-packages/spectrum/psd.py", line 445, in _setData
    self.__data = data.copy()
AttributeError: 'RRiDetrended' object has no attribute 'copy'

The problem is here (or at least starts here): https://github.com/rhenanbartels/hrv/blob/190c923250884b1f5632e38658bd8df7d9d5352e/hrv/classical.py#L200

That call to _interpolate_rri returns a numpy.ndarray, meaning that if rri was originally an RRi (or RRiDetrended) instance it isn't any more. That allows the call to data.copy() to succeed, because ndarray has a copy method. If you pass in an RRiDetrended instance where interpolated is True, line 200 is never executed and pburg doesn't get an ndarray, triggering the failure.

noah10 commented 3 years ago

I realized that there's another way this bug can manifest: If the data aren't detrended, polynomial_detrend will be called. This returns an RRiDetrended object, which of course lacks a copy method and triggers this same attribute error.

LoraGee commented 3 months ago

Hey @rhenanbartels and @noah10 , thanks for this amazing package. Is there any bug fix to solve the problem? How to compute AR frequency analysis with detrended and interpolated data when using smoothness_priors()? Thanks