code: def test_slicer(self):
      img_klass = self.image_class
      in_data_template = np.arange(240, dtype=np.int16)
      base_affine = np.eye(4)
      t_axis = None
      for dshape in (
          (4, 5, 6, 2),
          (8, 5, 6),
      ):  # Time series      # Volume
          in_data = in_data_template.copy().reshape(dshape)
          img = img_klass(in_data, base_affine.copy())
  
          # Can't slice into the image object:
          with pytest.raises(TypeError) as exception_manager:
              img[0, 0, 0]
          # Make sure the right message gets raised:
          assert (
              str(exception_manager.value)
              == "Cannot slice image objects; consider using "
              "`img.slicer[slice]` to generate a sliced image (see "
              "documentation for caveats) or slicing image array data "
              "with `img.dataobj[slice]` or `img.get_fdata()[slice]`"
          )
  
          if not spatial_axes_first(img):
              with pytest.raises(ValueError):
                  img.slicer
              continue
  
          assert hasattr(img.slicer, "__getitem__")
  
          # Note spatial zooms are always first 3, even when
          spatial_zooms = img.header.get_zooms()[:3]
  
          # Down-sample with [::2, ::2, ::2] along spatial dimensions
          sliceobj = [slice(None, None, 2)] * 3 + [slice(None)] * (
              len(dshape) - 3
          )
          downsampled_img = img.slicer[tuple(sliceobj)]
          assert (
              downsampled_img.header.get_zooms()[:3]
              == np.array(spatial_zooms) * 2
          ).all()
  
          max4d = (
              hasattr(img.header, "_structarr")
              and "dims" in img.header._structarr.dtype.fields
              and img.header._structarr["dims"].shape == (4,)
          )
          # Check newaxis and single-slice errors
          with pytest.raises(IndexError):
              img.slicer[None]
          with pytest.raises(IndexError):
              img.slicer[0]
          # Axes 1 and 2 are always spatial
          with pytest.raises(IndexError):
              img.slicer[:, None]
          with pytest.raises(IndexError):
              img.slicer[:, 0]
          with pytest.raises(IndexError):
              img.slicer[:, :, None]
          with pytest.raises(IndexError):
              img.slicer[:, :, 0]
          if len(img.shape) == 4:
              if max4d:
                  with pytest.raises(ValueError):
                      img.slicer[:, :, :, None]
              else:
                  # Reorder non-spatial axes
                  assert (
                      img.slicer[:, :, :, None].shape
                      == img.shape[:3] + (1,) + img.shape[3:]
                  )
              # 4D to 3D using ellipsis or slices
              assert img.slicer[..., 0].shape == img.shape[:-1]
              assert img.slicer[:, :, :, 0].shape == img.shape[:-1]
          else:
              # 3D Analyze/NIfTI/MGH to 4D
              assert img.slicer[:, :, :, None].shape == img.shape + (1,)
          if len(img.shape) == 3:
              # Slices exceed dimensions
              with pytest.raises(IndexError):
                  img.slicer[:, :, :, :, None]
          elif max4d:
              with pytest.raises(ValueError):
                  img.slicer[:, :, :, :, None]
          else:
              assert img.slicer[:, :, :, :, None].shape == img.shape + (
                  1,
              )
  
          # Crop by one voxel in each dimension
          sliced_i = img.slicer[1:]
          sliced_j = img.slicer[:, 1:]
          sliced_k = img.slicer[:, :, 1:]
          sliced_ijk = img.slicer[1:, 1:, 1:]
  
          # No scaling change
          assert (sliced_i.affine[:3, :3] == img.affine[:3, :3]).all()
          assert (sliced_j.affine[:3, :3] == img.affine[:3, :3]).all()
          assert (sliced_k.affine[:3, :3] == img.affine[:3, :3]).all()
          assert (sliced_ijk.affine[:3, :3] == img.affine[:3, :3]).all()
          # Translation
          assert (sliced_i.affine[:, 3] == [1, 0, 0, 1]).all()
          assert (sliced_j.affine[:, 3] == [0, 1, 0, 1]).all()
          assert (sliced_k.affine[:, 3] == [0, 0, 1, 1]).all()
          assert (sliced_ijk.affine[:, 3] == [1, 1, 1, 1]).all()
  
          # No change to affines with upper-bound slices
          assert (img.slicer[:1, :1, :1].affine == img.affine).all()
  
          # Yell about step = 0
          with pytest.raises(ValueError):
              img.slicer[:, ::0]
          with pytest.raises(ValueError):
              img.slicer.slice_affine(
                  (slice(None), slice(None, None, 0))
              )
  
          # Don't permit zero-length slices
          with pytest.raises(IndexError):
              img.slicer[:0]
  
          # No fancy indexing
          with pytest.raises(IndexError):
              img.slicer[[0]]
          with pytest.raises(IndexError):
              img.slicer[[-1]]
          with pytest.raises(IndexError):
              img.slicer[[0], [-1]]
  
          # Check data is consistent with slicing numpy arrays
          slice_elems = np.array(
              (
                  None,
                  Ellipsis,
                  0,
                  1,
                  -1,
                  [0],
                  [1],
                  [-1],
                  slice(None),
                  slice(1),
                  slice(-1),
                  slice(1, -1),
              ),
              dtype=object,
          )
          for n_elems in range(6):
              for _ in range(1 if n_elems == 0 else 10):
                  sliceobj = tuple(
                      np.random.choice(slice_elems, n_elems)
                  )
                  try:
                      sliced_img = img.slicer[sliceobj]
                  except (IndexError, ValueError, HeaderDataError):
                      # Skip invalid slices or images that can't be created
                      continue
  
                  sliced_data = in_data[sliceobj]
                  assert np.array_equal(
                      sliced_data, sliced_img.get_fdata()
                  )
                  assert np.array_equal(sliced_data, sliced_img.dataobj)
                  assert np.array_equal(
                      sliced_data, img.dataobj[sliceobj]
                  )
                  assert np.array_equal(
                      sliced_data, img.get_fdata()[sliceobj]
                  )
  
imports: from io import BytesIO
  import numpy
  import pytest
  from numpy.testing import assert_array_almost_equal
  from ..None import load
  from ..imageclasses import spatial_axes_first
  from ..spatialimages import HeaderDataError, SpatialHeader, SpatialImage
  from ..testing import bytesio_round_trip, expires, memmap_after_ufunc
  from ..tmpdirs import InTemporaryDirectory
label_desc: Use image node_id 12 for calling the TestSpatialImage obj's underlying member method code with example usage: obj.test_slicer() without return types