'Read a chunk of raw data.'

@verbose
def _read_segment_file(self, data, idx, fi, start, stop, cals, mult):

    from scipy.interpolate import interp1d
    if (mult is not None):
        raise NotImplementedError('mult    is    not    supported    yet')
    exclude = self._raw_extras[fi]['exclude']
    sel = np.arange(self.info['nchan'])[idx]
    n_samps = self._raw_extras[fi]['n_samps']
    buf_len = int(self._raw_extras[fi]['max_samp'])
    sfreq = self.info['sfreq']
    dtype = self._raw_extras[fi]['dtype_np']
    dtype_byte = self._raw_extras[fi]['dtype_byte']
    data_offset = self._raw_extras[fi]['data_offset']
    stim_channel = self._raw_extras[fi]['stim_channel']
    tal_channels = self._raw_extras[fi]['tal_channel']
    annot = self._raw_extras[fi]['annot']
    annotmap = self._raw_extras[fi]['annotmap']
    subtype = self._raw_extras[fi]['subtype']
    stim_data = self._raw_extras[fi].get('stim_data', None)
    if (np.size(dtype_byte) > 1):
        if (len(np.unique(dtype_byte)) > 1):
            warn('Multiple    data    type    not    supported')
        dtype = dtype[0]
        dtype_byte = dtype_byte[0]
    physical_range = np.array([ch['range'] for ch in self.info['chs']])
    cal = np.array([ch['cal'] for ch in self.info['chs']])
    cal = np.atleast_2d((physical_range / cal))
    gains = np.atleast_2d(self._raw_extras[fi]['units'])
    physical_min = self._raw_extras[fi]['physical_min']
    digital_min = self._raw_extras[fi]['digital_min']
    offsets = np.atleast_2d((physical_min - (digital_min * cal))).T
    if (tal_channels is not None):
        for tal_channel in tal_channels:
            offsets[tal_channel] = 0
    selection = sel.copy()
    idx_map = np.argsort(selection)
    for ei in sorted(exclude):
        for (ii, si) in enumerate(sorted(selection)):
            if (si >= ei):
                selection[idx_map[ii]] += 1
        if (tal_channels is not None):
            tal_channels = [((tc + 1) if (tc >= ei) else tc) for tc in sorted(tal_channels)]
    ch_offsets = np.cumsum(np.concatenate([[0], n_samps]))
    (block_start_idx, r_lims, d_lims) = _blk_read_lims(start, stop, buf_len)
    n_per = max((((10 * 1024) * 1024) // (ch_offsets[(-1)] * dtype_byte)), 1)
    with open(self._filenames[fi], 'rb', buffering=0) as fid:
        start_offset = (data_offset + ((block_start_idx * ch_offsets[(-1)]) * dtype_byte))
        for ai in range(0, len(r_lims), n_per):
            block_offset = ((ai * ch_offsets[(-1)]) * dtype_byte)
            n_read = min((len(r_lims) - ai), n_per)
            fid.seek((start_offset + block_offset), 0)
            many_chunk = _read_ch(fid, subtype, (ch_offsets[(-1)] * n_read), dtype_byte, dtype).reshape(n_read, (-1))
            for (ii, ci) in enumerate(selection):
                ch_data = many_chunk[:, ch_offsets[ci]:ch_offsets[(ci + 1)]]
                r_sidx = r_lims[ai][0]
                r_eidx = ((buf_len * (n_read - 1)) + r_lims[((ai + n_read) - 1)][1])
                d_sidx = d_lims[ai][0]
                d_eidx = d_lims[((ai + n_read) - 1)][1]
                if (n_samps[ci] != buf_len):
                    if ((tal_channels is not None) and (ci in tal_channels)):
                        if (n_samps[ci] < buf_len):
                            z = np.zeros((len(ch_data), (buf_len - n_samps[ci])))
                            ch_data = np.append(ch_data, z, (-1))
                        else:
                            ch_data = ch_data[:, :buf_len]
                    elif (ci == stim_channel):
                        if ((annot and annotmap) or (stim_data is not None) or (tal_channels is not None)):
                            ch_data = np.zeros((len(ch_data), buf_len))
                        else:
                            old = np.linspace(0, 1, (n_samps[ci] + 1), True)
                            new = np.linspace(0, 1, buf_len, False)
                            ch_data = np.append(ch_data, np.zeros((len(ch_data), 1)), (-1))
                            ch_data = interp1d(old, ch_data, kind='zero', axis=(-1))(new)
                    else:
                        ch_data = resample(ch_data, buf_len, n_samps[ci], npad=0, axis=(-1))
                assert (ch_data.shape == (len(ch_data), buf_len))
                data[ii, d_sidx:d_eidx] = ch_data.ravel()[r_sidx:r_eidx]
    data *= cal.T[sel]
    data += offsets[sel]
    data *= gains.T[sel]
    read_size = (len(r_lims) * buf_len)
    if ((stim_channel is not None) and ((sel == stim_channel).sum() > 0)):
        stim_channel_idx = np.where((sel == stim_channel))[0]
        if (annot and annotmap):
            evts = _read_annot(annot, annotmap, sfreq, self._last_samps[fi])
            data[stim_channel_idx, :] = evts[start:(stop + 1)]
        elif (tal_channels is not None):
            tal_channel_idx = np.intersect1d(sel, tal_channels)
            evts = _parse_tal_channel(np.atleast_2d(data[tal_channel_idx]))
            self._raw_extras[fi]['events'] = evts
            unique_annots = sorted(set([e[2] for e in evts]))
            mapping = dict(((a, (n + 1)) for (n, a) in enumerate(unique_annots)))
            stim = np.zeros(read_size)
            for (t_start, t_duration, annotation) in evts:
                evid = mapping[annotation]
                n_start = int((t_start * sfreq))
                n_stop = ((int((t_duration * sfreq)) + n_start) - 1)
                n_stop = (n_stop if (n_stop > n_start) else (n_start + 1))
                if any(stim[n_start:n_stop]):
                    warn('EDF+    with    overlapping    events    are    not    fully    supported')
                stim[n_start:n_stop] += evid
            data[stim_channel_idx, :] = stim[start:stop]
        elif (stim_data is not None):
            data[stim_channel_idx, :] = stim_data[start:stop]
        else:
            stim = np.bitwise_and(data[stim_channel_idx].astype(int), ((2 ** 17) - 1))
            data[stim_channel_idx, :] = stim
