Read all signals from a WFDB dat file.

    Parameters
    ----------
    file_name : str
        The name of the dat file
    * other params
        See docstring for `_rd_segment`.

    Returns
    -------
    signals : numpy array, or list
        See docstring for `_rd_segment`.

    Notes
    -----
    See docstring notes for `_rd_segment`.

def _rd_dat_signals(file_name, dir_name, pb_dir, fmt, n_sig, sig_len,
                   byte_offset, samps_per_frame, skew, sampfrom, sampto,
                   smooth_frames):
    """
    Read all signals from a WFDB dat file.

    Parameters
    ----------
    file_name : str
        The name of the dat file
    * other params
        See docstring for `_rd_segment`.

    Returns
    -------
    signals : numpy array, or list
        See docstring for `_rd_segment`.

    Notes
    -----
    See docstring notes for `_rd_segment`.

    """

    # Total number of samples per frame
    tsamps_per_frame = sum(samps_per_frame)
    # The signal length to read (per channel)
    read_len = sampto - sampfrom

    # Calculate parameters used to read and process the dat file
    (start_byte, n_read_samples, block_floor_samples,
     extra_flat_samples, nan_replace) = _dat_read_params(fmt, sig_len,
                                                         byte_offset, skew,
                                                         tsamps_per_frame,
                                                         sampfrom, sampto)

    # Number of bytes to be read from the dat file
    total_read_bytes = _required_byte_num('read', fmt, n_read_samples)

    # Total samples to be processed in intermediate step. Includes extra
    # padded samples beyond dat file
    total_process_samples = n_read_samples + extra_flat_samples

    # Total number of bytes to be processed in intermediate step.
    total_process_bytes = _required_byte_num('read', fmt,
                                             total_process_samples)

    # Get the intermediate bytes or samples to process. Bit of a
    # discrepancy. Recall special formats load uint8 bytes, other formats
    # already load samples.

    # Read values from dat file. Append bytes/samples if needed.
    if extra_flat_samples:
        if fmt in UNALIGNED_FMTS:
            # Extra number of bytes to append onto the bytes read from
            # the dat file.
            n_extra_bytes = total_process_bytes - total_read_bytes

            sig_data = np.concatenate((_rd_dat_file(file_name, dir_name,
                                                     pb_dir, fmt, start_byte,
                                                     n_read_samples),
                                        np.zeros(n_extra_bytes,
                                                 dtype=np.dtype(DATA_LOAD_TYPES[fmt]))))
        else:
            sig_data = np.concatenate((_rd_dat_file(file_name, dir_name,
                                                     pb_dir, fmt, start_byte,
                                                     n_read_samples),
                                        np.zeros(extra_flat_samples,
                                                 dtype=np.dtype(DATA_LOAD_TYPES[fmt]))))
    else:
        sig_data = _rd_dat_file(file_name, dir_name, pb_dir, fmt, start_byte,
                                 n_read_samples)

    # Finish processing the read data into proper samples if not already

    # For unaligned fmts, turn the uint8 blocks into actual samples
    if fmt in UNALIGNED_FMTS:
        sig_data = _blocks_to_samples(sig_data, total_process_samples, fmt)
        # Remove extra leading sample read within the byte block if any
        if block_floor_samples:
            sig_data = sig_data[block_floor_samples:]

    # Adjust samples values for byte offset formats
    if fmt in OFFSET_FMTS:
        if fmt == '80':
            sig_data = (sig_data.astype('int16') - 128).astype('int8')
        elif fmt == '160':
            sig_data = (sig_data.astype('int32') - 32768).astype('int16')

    # At this point, dtype of sig_data is the minimum integer format
    # required for storing the final digital samples.

    # No extra samples/frame. Obtain original uniform numpy array
    if tsamps_per_frame == n_sig:
        # Reshape into multiple channels
        signal = sig_data.reshape(-1, n_sig)
        # Skew the signal
        signal = _skew_sig(signal, skew, n_sig, read_len, fmt, nan_replace)
    # Extra frames present to be smoothed. Obtain averaged uniform numpy array
    elif smooth_frames:
        # Allocate memory for smoothed signal.
        signal = np.zeros((int(len(sig_data) / tsamps_per_frame) , n_sig),
                       dtype=sig_data.dtype)

        # Transfer and average samples
        for ch in range(n_sig):
            if samps_per_frame[ch] == 1:
                signal[:, ch] = sig_data[sum(([0] + samps_per_frame)[:ch + 1])::tsamps_per_frame]
            else:
                if ch == 0:
                    startind = 0
                else:
                    startind = np.sum(samps_per_frame[:ch])
                signal[:,ch] = [np.average(sig_data[ind:ind+samps_per_frame[ch]]) for ind in range(startind,len(sig_data),tsamps_per_frame)]
        # Skew the signal
        signal = _skew_sig(signal, skew, n_sig, read_len, fmt, nan_replace)

    # Extra frames present without wanting smoothing. Return all
    # expanded samples.
    else:
        # List of 1d numpy arrays
        signal = []
        # Transfer over samples
        for ch in range(n_sig):
            # Indices of the flat signal that belong to the channel
            ch_indices = np.concatenate([np.array(range(samps_per_frame[ch]))
                                         + sum([0] + samps_per_frame[:ch])
                                         + tsamps_per_frame * framenum for framenum in range(int(len(sig_data)/tsamps_per_frame))])
            signal.append(sig_data[ch_indices])
        # Skew the signal
        signal = _skew_sig(signal, skew, n_sig, read_len, fmt, nan_replace, samps_per_frame)

    # Integrity check of signal shape after reading
    _check_sig_dims(signal, read_len, n_sig, samps_per_frame)

    return signal