# Buggy code
def estimate_shift1D(
    self,
    start=None,
    end=None,
    reference_indices=None,
    max_shift=None,
    interpolate=True,
    number_of_interpolation_points=5,
    mask=None,
    parallel=None,
    show_progressbar=None,
):
    """Estimate the shifts in the current signal axis using
     cross-correlation.
    This method can only estimate the shift by comparing
    unidimensional features that should not change the position in
    the signal axis. To decrease the memory usage, the time of
    computation and the accuracy of the results it is convenient to
    select the feature of interest providing sensible values for
    `start` and `end`. By default interpolation is used to obtain
    subpixel precision.
    Parameters
    ----------
    start, end : {int | float | None}
        The limits of the interval. If int they are taken as the
        axis index. If float they are taken as the axis value.
    reference_indices : tuple of ints or None
        Defines the coordinates of the spectrum that will be used
        as eference. If None the spectrum at the current
        coordinates is used for this purpose.
    max_shift : int
        "Saturation limit" for the shift.
    interpolate : bool
        If True, interpolation is used to provide sub-pixel
        accuracy.
    number_of_interpolation_points : int
        Number of interpolation points. Warning: making this number
        too big can saturate the memory
    mask : BaseSignal of bool data type.
        It must have signal_dimension = 0 and navigation_shape equal to the
        current signal. Where mask is True the shift is not computed
        and set to nan.
    parallel : {None, bool}
    show_progressbar : None or bool
        If True, display a progress bar. If None the default is set in
        `preferences`.
    Returns
    -------
    An array with the result of the estimation in the axis units.
    Raises
    ------
    SignalDimensionError if the signal dimension is not 1.
    """
    if show_progressbar is None:
        show_progressbar = preferences.General.show_progressbar
    self._check_signal_dimension_equals_one()
    ip = number_of_interpolation_points + 1
    axis = self.axes_manager.signal_axes[0]
    self._check_navigation_mask(mask)
    # we compute for now
    if isinstance(start, da.Array):
        start = start.compute()
    if isinstance(end, da.Array):
        end = end.compute()
    i1, i2 = axis._get_index(start), axis._get_index(end)
    if reference_indices is None:
        reference_indices = self.axes_manager.indices
    ref = self.inav[reference_indices].data[i1:i2]

    if interpolate is True:
        ref = interpolate1D(ip, ref)
    iterating_kwargs = ()
    if mask is not None:
        iterating_kwargs += (("mask", mask),)
    shift_signal = self._map_iterate(
        _estimate_shift1D,
        iterating_kwargs=iterating_kwargs,
        data_slice=slice(i1, i2),
        mask=None,
        ref=ref,
        ip=ip,
        interpolate=interpolate,
        ragged=False,
        parallel=parallel,
        inplace=False,
        show_progressbar=show_progressbar,
    )
    shift_array = shift_signal.data
    if max_shift is not None:
        if interpolate is True:
            max_shift *= ip
        shift_array.clip(-max_shift, max_shift)
    if interpolate is True:
        shift_array = shift_array / ip
    shift_array *= axis.scale
    return shift_array


# Traceback (IndexError)
s
<LazyEELSSpectrum, title: EELS Spectrum Image 0eV, dimensions: (3, 3|2048)>
s.align_zero_loss_peak(True) # Or False
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-4-8925d1fde6ab> in <module>()
----> 1 s.align_zero_loss_peak(True) # or False

c:\users\thomasaar\documents\hyperspy\hyperspy\_signals\eels.py in align_zero_loss_peak(self, calibrate, also_align, print_stats, subpixel, mask, signal_range, show_progressbar, **kwargs)
266
267         zlpc = estimate_zero_loss_peak_centre(self, mask, signal_range)
--> 268         mean_ = without_nans(zlpc.data).mean()
269         if print_stats is True:
270             print()

c:\users\thomasaar\documents\hyperspy\hyperspy\misc\utils.py in without_nans(data)
756
757 def without_nans(data):
--> 758     return data[~np.isnan(data)]
759
760

C:\Users\thomasaar\AppData\Local\Continuum\Anaconda3\lib\site-packages\dask\array\core.py in __getitem__(self, index)
1239             return self
1240
-> 1241         dsk, chunks = slice_array(out, self.name, self.chunks, index)
1242
1243         dsk2 = sharedict.merge(self.dask, (out, dsk))

C:\Users\thomasaar\AppData\Local\Continuum\Anaconda3\lib\site-packages\dask\array\slicing.py in slice_array(out_name, in_name, blockdims, index)
137
138     # Pass down to next function
--> 139     dsk_out, bd_out = slice_with_newaxes(out_name, in_name, blockdims, index)
140
141     bd_out = tuple(map(tuple, bd_out))

C:\Users\thomasaar\AppData\Local\Continuum\Anaconda3\lib\site-packages\dask\array\slicing.py in slice_with_newaxes(out_name, in_name, blockdims, index)
159
160     # Pass down and do work
--> 161     dsk, blockdims2 = slice_wrap_lists(out_name, in_name, blockdims, index2)
162
163     if where_none:

C:\Users\thomasaar\AppData\Local\Continuum\Anaconda3\lib\site-packages\dask\array\slicing.py in slice_wrap_lists(out_name, in_name, blockdims, index)
200         raise IndexError("Too many indices for array")
201     for bd, i in zip(blockdims, index):
--> 202         check_index(i, sum(bd))
203
204     # Change indices like -1 to 9

C:\Users\thomasaar\AppData\Local\Continuum\Anaconda3\lib\site-packages\dask\array\slicing.py in check_index(ind, dimension)
711         x = np.array(ind)
712         if (x >= dimension).any() or (x <= -dimension).any():
--> 713             raise IndexError("Index out of bounds %s" % dimension)
714     elif isinstance(ind, slice):
715         return

IndexError: Index out of bounds 200

# Fixed code
def estimate_shift1D(
    self,
    start=None,
    end=None,
    reference_indices=None,
    max_shift=None,
    interpolate=True,
    number_of_interpolation_points=5,
    mask=None,
    parallel=None,
    show_progressbar=None,
):
    """Estimate the shifts in the current signal axis using
     cross-correlation.
    This method can only estimate the shift by comparing
    unidimensional features that should not change the position in
    the signal axis. To decrease the memory usage, the time of
    computation and the accuracy of the results it is convenient to
    select the feature of interest providing sensible values for
    `start` and `end`. By default interpolation is used to obtain
    subpixel precision.
    Parameters
    ----------
    start, end : {int | float | None}
        The limits of the interval. If int they are taken as the
        axis index. If float they are taken as the axis value.
    reference_indices : tuple of ints or None
        Defines the coordinates of the spectrum that will be used
        as eference. If None the spectrum at the current
        coordinates is used for this purpose.
    max_shift : int
        "Saturation limit" for the shift.
    interpolate : bool
        If True, interpolation is used to provide sub-pixel
        accuracy.
    number_of_interpolation_points : int
        Number of interpolation points. Warning: making this number
        too big can saturate the memory
    mask : BaseSignal of bool data type.
        It must have signal_dimension = 0 and navigation_shape equal to the
        current signal. Where mask is True the shift is not computed
        and set to nan.
    parallel : {None, bool}
    show_progressbar : None or bool
        If True, display a progress bar. If None the default is set in
        `preferences`.
    Returns
    -------
    An array with the result of the estimation in the axis units.
    Raises
    ------
    SignalDimensionError if the signal dimension is not 1.
    """
    if show_progressbar is None:
        show_progressbar = preferences.General.show_progressbar
    self._check_signal_dimension_equals_one()
    ip = number_of_interpolation_points + 1
    axis = self.axes_manager.signal_axes[0]
    self._check_navigation_mask(mask)
    # we compute for now
    if isinstance(start, da.Array):
        start = start.compute()
    if isinstance(end, da.Array):
        end = end.compute()
    i1, i2 = axis._get_index(start), axis._get_index(end)
    if reference_indices is None:
        reference_indices = self.axes_manager.indices
    ref = self.inav[reference_indices].data[i1:i2]

    if interpolate is True:
        ref = interpolate1D(ip, ref)
    iterating_kwargs = ()
    if mask is not None:
        iterating_kwargs += (("mask", mask),)
    shift_signal = self._map_iterate(
        _estimate_shift1D,
        iterating_kwargs=iterating_kwargs,
        data_slice=slice(i1, i2),
        ref=ref,
        ip=ip,
        interpolate=interpolate,
        ragged=False,
        parallel=parallel,
        inplace=False,
        show_progressbar=show_progressbar,
    )
    shift_array = shift_signal.data
    if max_shift is not None:
        if interpolate is True:
            max_shift *= ip
        shift_array.clip(-max_shift, max_shift)
    if interpolate is True:
        shift_array = shift_array / ip
    shift_array *= axis.scale
    if self._lazy:
        shift_array = shift_array.compute()
    return shift_array