# Buggy code
def get_pyramid_and_rgb(data, pyramid=None, rgb=None):
    """Check if data is or needs to be a pyramid and make one if needed.

    Parameters
    ----------
    data : array or list
        Data to be checked if pyramid or if needs to be turned into a pyramid.
    pyramid : bool, optional
        Value that can force data to be considered as a pyramid or not,
        otherwise computed.
    rgb : bool, optional
        Value that can force data to be considered as a rgb, otherwise
        computed.

    Returns
    -------
    ndim : int
        Dimensionality of the data.
    rgb : bool
        If data is rgb.
    pyramid : bool
        If data is a pyramid or a pyramid has been generated.
    data_pyramid : list or None
        If None then data is not and does not need to be a pyramid. Otherwise
        is a list of arrays where each array is a level of the pyramid.
    """
    # Determine if data currently is a pyramid
    currently_pyramid = is_pyramid(data)
    if currently_pyramid:
        init_shape = data[0].shape
    else:
        init_shape = data.shape

    # Determine if rgb, and determine dimensionality
    if rgb is False:
        pass
    else:
        # If rgb is True or None then guess if rgb
        # allowed or not, and if allowed set it to be True
        rgb = is_rgb(init_shape)

    if rgb:
        ndim = len(init_shape) - 1
    else:
        ndim = len(init_shape)

    if pyramid is False:
        if currently_pyramid:
            raise ValueError(
                """Non pyramided data was requested, but pyramid
                             data was passed"""
            )
        else:
            data_pyramid = None
    else:
        if currently_pyramid:
            data_pyramid = trim_pyramid(data)
            pyramid = True
        else:
            # Guess if data should be pyramid
            pyr_axes = should_be_pyramid(data.shape)
            if np.any(pyr_axes):
                pyramid = True
                # Set axes to be downsampled to have a factor of 2
                downscale = np.ones(len(data.shape))
                downscale[pyr_axes] = 2
                largest = np.min(np.array(data.shape)[pyr_axes])
                # Determine number of downsample steps needed
                max_layer = np.floor(np.log2(largest) - 9).astype(int)
                data_pyramid = fast_pyramid(
                    data, downscale=downscale, max_layer=max_layer
                )
                data_pyramid = trim_pyramid(data_pyramid)
            else:
                data_pyramid = None
                pyramid = False

    return ndim, rgb, pyramid, data_pyramid


# Traceback (ValueError)
regions
<xarray.Regions 'array-baa123768d7ef2a6d2cdfa885e8f3eaa' (x_region: 31725, y_region: 51669)>
array([[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]], dtype=int16)
Dimensions without coordinates: x_region, y_region
Attributes:
assay:             osmFISH
authors:           ['Simone Codeluppi', 'Lars E. Borm', 'Amit Zeisel', 'G...
organism:          mouse
publication_name:  Spatial organization of the somatosensory cortex revea...
publication_url:   https://www.nature.com/articles/s41592-018-0175-z
sample_type:       somatosensory cortex
year:              2018

pyramid = tuple(pyramid_gaussian(regions), multichannel=False)

[i.shape for i in pyramid]
[(31725, 51669),
(15863, 25835),
(7932, 12918),
(3966, 6459),
(1983, 3230),
(992, 1615),
(496, 808),
(248, 404),
(124, 202),
(62, 101),
(31, 51),
(16, 26),
(8, 13),
(4, 7),
(2, 4),
(1, 2),
(1, 1)]

viewer = napari.Viewer()

viewer.add_image(np.asarray(pyramid), is_pyramid=True)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-35-665dfea0cb05> in <module>
----> 1 viewer.add_image(np.asarray(pyramid), is_pyramid=True)

/usr/local/lib/python3.7/site-packages/napari/components/viewer_model.py in add_image(self, data, rgb, is_pyramid, colormap, contrast_limits, interpolation, rendering, name, metadata, scale, translate, opacity, blending, visible)
426             opacity=opacity,
427             blending=blending,
--> 428             visible=visible,
429         )
430         self.add_layer(layer)

/usr/local/lib/python3.7/site-packages/napari/layers/image/image.py in __init__(self, data, rgb, is_pyramid, colormap, contrast_limits, interpolation, rendering, name, metadata, scale, translate, opacity, blending, visible)
185             else:
186                 input_data = self.data
--> 187             self._contrast_limits_range = calc_data_range(input_data)
188         else:
189             self._contrast_limits_range = contrast_limits

/usr/local/lib/python3.7/site-packages/napari/util/misc.py in calc_data_range(data)
268         reduced_data = data
269
--> 270     min_val = reduced_data.min()
271     max_val = reduced_data.max()
272

/usr/local/lib/python3.7/site-packages/numpy/core/_methods.py in _amin(a, axis, out, keepdims, initial)
30 def _amin(a, axis=None, out=None, keepdims=False,
31           initial=_NoValue):
---> 32     return umr_minimum(a, axis, None, out, keepdims, initial)
33
34 def _sum(a, axis=None, dtype=None, out=None, keepdims=False,

ValueError: operands could not be broadcast together with shapes (31725,51669) (15863,25835)

# Fixed code
def get_pyramid_and_rgb(data, pyramid=None, rgb=None):
    """Check if data is or needs to be a pyramid and make one if needed.

    Parameters
    ----------
    data : array, list, or tuple
        Data to be checked if pyramid or if needs to be turned into a pyramid.
    pyramid : bool, optional
        Value that can force data to be considered as a pyramid or not,
        otherwise computed.
    rgb : bool, optional
        Value that can force data to be considered as a rgb, otherwise
        computed.

    Returns
    -------
    ndim : int
        Dimensionality of the data.
    rgb : bool
        If data is rgb.
    pyramid : bool
        If data is a pyramid or a pyramid has been generated.
    data_pyramid : list or None
        If None then data is not and does not need to be a pyramid. Otherwise
        is a list of arrays where each array is a level of the pyramid.
    """
    # Determine if data currently is a pyramid
    currently_pyramid = is_pyramid(data)
    if currently_pyramid:
        shapes = [d.shape for d in data]
        init_shape = shapes[0]
    else:
        init_shape = data.shape

    # Determine if rgb, and determine dimensionality
    if rgb is False:
        pass
    else:
        # If rgb is True or None then guess if rgb
        # allowed or not, and if allowed set it to be True
        rgb_guess = is_rgb(init_shape)
        if rgb and rgb_guess is False:
            raise ValueError(
                "Non rgb or rgba data was passed, but rgb data was requested."
            )
        else:
            rgb = rgb_guess

    if rgb:
        ndim = len(init_shape) - 1
    else:
        ndim = len(init_shape)

    if pyramid is False:
        if currently_pyramid:
            raise ValueError(
                "Non pyramided data was requested, but pyramid data was passed"
            )
        else:
            data_pyramid = None
    else:
        if currently_pyramid:
            data_pyramid = trim_pyramid(data)
            pyramid = True
        else:
            # Guess if data should be pyramid or if a pyramid was requested
            if pyramid:
                pyr_axes = [True] * ndim
            else:
                pyr_axes = should_be_pyramid(data.shape)

            if np.any(pyr_axes):
                pyramid = True
                # Set axes to be downsampled to have a factor of 2
                downscale = np.ones(len(data.shape))
                downscale[pyr_axes] = 2
                largest = np.min(np.array(data.shape)[pyr_axes])
                # Determine number of downsample steps needed
                max_layer = np.floor(np.log2(largest) - 9).astype(int)
                data_pyramid = fast_pyramid(
                    data, downscale=downscale, max_layer=max_layer
                )
                data_pyramid = trim_pyramid(data_pyramid)
            else:
                data_pyramid = None
                pyramid = False

    return ndim, rgb, pyramid, data_pyramid