wfdb / mimic_wfdb_tutorials

Tutorials on using the MIMIC Waveform Database
https://wfdb.io/mimic_wfdb_tutorials/
26 stars 6 forks source link

Fix soundfile error in notebooks #84

Closed tompollard closed 2 years ago

tompollard commented 2 years ago

Several of the notebooks (e.g. https://wfdb.io/mimic_wfdb_tutorials/tutorial/notebooks/data-visualisation.html ) are displaying the following error message in the rendered notebooks (even though the notebook runs fine in Colab). I think the fix is to install the soundfile package in the build script.

---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
Input In [8], in <cell line: 4>()
      1 sampfrom = fs * start_seconds
      2 sampto = fs * (start_seconds + n_seconds_to_load)
----> 4 segment_data = wfdb.rdrecord(record_name=rel_segment_name,
      5                              sampfrom=sampfrom,
      6                              sampto=sampto,
      7                              pn_dir=rel_segment_dir)
      9 print(f"{n_seconds_to_load} seconds of data extracted from segment {rel_segment_name}")

File /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages/wfdb/io/record.py:2065, in rdrecord(record_name, sampfrom, sampto, channels, physical, pn_dir, m2s, smooth_frames, ignore_skew, return_res, force_channels, channel_names, warn_empty)
   2062 no_file = False
   2063 sig_data = None
-> 2065 record.e_d_signal = _signal._rd_segment(
   2066     file_name=record.file_name,
   2067     dir_name=dir_name,
   2068     pn_dir=pn_dir,
   2069     fmt=record.fmt,
   2070     n_sig=record.n_sig,
   2071     sig_len=record.sig_len,
   2072     byte_offset=record.byte_offset,
   2073     samps_per_frame=record.samps_per_frame,
   2074     skew=record.skew,
   2075     init_value=record.init_value,
   2076     sampfrom=sampfrom,
   2077     sampto=sampto,
   2078     channels=channels,
   2079     ignore_skew=ignore_skew,
   2080     no_file=no_file,
   2081     sig_data=sig_data,
   2082     return_res=return_res,
   2083 )
   2085 # Only 1 sample/frame, or frames are smoothed. Return uniform numpy array
   2086 if smooth_frames:
   2087     # Arrange/edit the object fields to reflect user channel
   2088     # and/or signal range input

File /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages/wfdb/io/_signal.py:1202, in _rd_segment(file_name, dir_name, pn_dir, fmt, n_sig, sig_len, byte_offset, samps_per_frame, skew, init_value, sampfrom, sampto, channels, ignore_skew, no_file, sig_data, return_res)
   1198 signals = [None] * len(channels)
   1200 for fn in w_file_name:
   1201     # Get the list of all signals contained in the dat file
-> 1202     datsignals = _rd_dat_signals(
   1203         file_name=fn,
   1204         dir_name=dir_name,
   1205         pn_dir=pn_dir,
   1206         fmt=w_fmt[fn],
   1207         n_sig=len(datchannel[fn]),
   1208         sig_len=sig_len,
   1209         byte_offset=w_byte_offset[fn],
   1210         samps_per_frame=w_samps_per_frame[fn],
   1211         skew=w_skew[fn],
   1212         init_value=w_init_value[fn],
   1213         sampfrom=sampfrom,
   1214         sampto=sampto,
   1215         no_file=no_file,
   1216         sig_data=sig_data,
   1217     )
   1219     # Copy over the wanted signals
   1220     for cn in range(len(out_dat_channel[fn])):

File /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages/wfdb/io/_signal.py:1330, in _rd_dat_signals(file_name, dir_name, pn_dir, fmt, n_sig, sig_len, byte_offset, samps_per_frame, skew, init_value, sampfrom, sampto, no_file, sig_data)
   1328     data_to_read = sig_data
   1329 elif fmt in COMPRESSED_FMTS:
-> 1330     data_to_read = _rd_compressed_file(
   1331         file_name=file_name,
   1332         dir_name=dir_name,
   1333         pn_dir=pn_dir,
   1334         fmt=fmt,
   1335         sample_offset=byte_offset,
   1336         n_sig=n_sig,
   1337         samps_per_frame=samps_per_frame,
   1338         start_frame=sampfrom,
   1339         end_frame=sampto,
   1340     )
   1341 else:
   1342     data_to_read = _rd_dat_file(
   1343         file_name, dir_name, pn_dir, fmt, start_byte, n_read_samples
   1344     )

File /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages/wfdb/io/_signal.py:1828, in _rd_compressed_file(file_name, dir_name, pn_dir, fmt, sample_offset, n_sig, samps_per_frame, start_frame, end_frame)
   1776 def _rd_compressed_file(
   1777     file_name,
   1778     dir_name,
   (...)
   1785     end_frame,
   1786 ):
   1787     """
   1788     Read data from a compressed file into a 1D numpy array.
   1789 
   (...)
   1826 
   1827     """
-> 1828     import soundfile
   1830     if any(spf != samps_per_frame[0] for spf in samps_per_frame):
   1831         raise ValueError(
   1832             "All channels in a FLAC signal file must have the same "
   1833             "sampling rate and samples per frame"
   1834         )

File /opt/hostedtoolcache/Python/3.9.13/x64/lib/python3.9/site-packages/soundfile.py:142, in <module>
    140     _libname = _find_library('sndfile')
    141     if _libname is None:
--> 142         raise OSError('sndfile library not found')
    143     _snd = _ffi.dlopen(_libname)
    144 except OSError:

OSError: sndfile library not found