class_docstr: The class is a collection of utilities to write images to disk.
  
  Main aspects to be considered are:
  
      - dimensionality of the data array, arrangements of spatial dimensions and channel/time dimensions
          - ``convert_to_channel_last()``
      - metadata of the current affine and output affine, the data array should be converted accordingly
          - ``get_meta_info()``
          - ``resample_if_needed()``
      - data type handling of the output image (as part of ``resample_if_needed()``)
  
  Subclasses of this class should implement the backend-specific functions:
  
      - ``set_data_array()`` to set the data array (input must be numpy array or torch tensor)
          - this method sets the backend object's data part
      - ``set_metadata()`` to set the metadata and output affine
          - this method sets the metadata including affine handling and image resampling
      - backend-specific data object ``create_backend_obj()``
      - backend-specific writing function ``write()``
  
  The primary usage of subclasses of ``ImageWriter`` is:
  
  .. code-block:: python
  
      writer = MyWriter()  # subclass of ImageWriter
      writer.set_data_array(data_array)
      writer.set_metadata(meta_dict)
      writer.write(filename)
  
  This creates an image writer object based on ``data_array`` and ``meta_dict`` and write to ``filename``.
  
  It supports up to three spatial dimensions (with the resampling step supports for both 2D and 3D).
  When saving multiple time steps or multiple channels `data_array`, time
  and/or modality axes should be the at the `channel_dim`. For example,
  the shape of a 2D eight-class and ``channel_dim=0``, the segmentation
  probabilities to be saved could be `(8, 64, 64)`; in this case
  ``data_array`` will be converted to `(64, 64, 1, 8)` (the third
  dimension is reserved as a spatial dimension).
  
  The ``metadata`` could optionally have the following keys:
  
      - ``'original_affine'``: for data original affine, it will be the
          affine of the output object, defaulting to an identity matrix.
      - ``'affine'``: it should specify the current data affine, defaulting to an identity matrix.
      - ``'spatial_shape'``: for data output spatial shape.
  
  When ``metadata`` is specified, the saver will may resample data from the space defined by
  `"affine"` to the space defined by `"original_affine"`, for more details, please refer to the
  ``resample_if_needed`` method.
class_docstr_tok: ["The","class","is","a","collection","of","utilities","to","write","images","to","disk",".","Main","aspects","to","be","considered","are",":","-","dimensionality","of","the","data","array",",","arrangements","of","spatial","dimensions","and","channel\/time","dimensions","-","``","convert_to_channel_last","(",")","``","-","metadata","of","the","current","affine","and","output","affine",",","the","data","array","should","be","converted","accordingly","-","``","get_meta_info","(",")","``","-","``","resample_if_needed","(",")","``","-","data","type","handling","of","the","output","image","(","as","part","of","``","resample_if_needed","(",")","``",")","Subclasses","of","this","class","should","implement","the","backend-specific","functions",":","-","``","set_data_array","(",")","``","to","set","the","data","array","(","input","must","be","numpy","array","or","torch","tensor",")","-","this","method","sets","the","backend","object","'s","data","part","-","``","set_metadata","(",")","``","to","set","the","metadata","and","output","affine","-","this","method","sets","the","metadata","including","affine","handling","and","image","resampling","-","backend-specific","data","object","``","create_backend_obj","(",")","``","-","backend-specific","writing","function","``","write","(",")","``","The","primary","usage","of","subclasses","of","``","ImageWriter","``","is",":","..","code-block",":",":","python","writer","=","MyWriter","(",")","#","subclass","of","ImageWriter","writer.set_data_array","(","data_array",")","writer.set_metadata","(","meta_dict",")","writer.write","(","filename",")","This","creates","an","image","writer","object","based","on","``","data_array","``","and","``","meta_dict","``","and","write","to","``","filename","``",".","It","supports","up","to","three","spatial","dimensions","(","with","the","resampling","step","supports","for","both","2D","and","3D",")",".","When","saving","multiple","time","steps","or","multiple","channels","`","data_array","`",",","time","and\/or","modality","axes","should","be","the","at","the","`","channel_dim","`",".","For","example",",","the","shape","of","a","2D","eight-class","and","``","channel_dim=0","``",",","the","segmentation","probabilities","to","be","saved","could","be","`","(","8",",","64",",","64",")","`",";","in","this","case","``","data_array","``","will","be","converted","to","`","(","64",",","64",",","1",",","8",")","`","(","the","third","dimension","is","reserved","as","a","spatial","dimension",")",".","The","``","metadata","``","could","optionally","have","the","following","keys",":","-","``","'original_affine","'","``",":","for","data","original","affine",",","it","will","be","the","affine","of","the","output","object",",","defaulting","to","an","identity","matrix",".","-","``","'affine","'","``",":","it","should","specify","the","current","data","affine",",","defaulting","to","an","identity","matrix",".","-","``","'spatial_shape","'","``",":","for","data","output","spatial","shape",".","When","``","metadata","``","is","specified",",","the","saver","will","may","resample","data","from","the","space","defined","by","`","``","affine","''","`","to","the","space","defined","by","`","``","original_affine","''","`",",","for","more","details",",","please","refer","to","the","``","resample_if_needed","``","method","."]
docstr: Rearrange the data array axes to make the `channel_dim`-th dim the last
  dimension and ensure there are ``spatial_ndim`` number of spatial
  dimensions.
  
  When ``squeeze_end_dims`` is ``True``, a postprocessing step will be
  applied to remove any trailing singleton dimensions.
  
  Args:
      data: input data to be converted to "channel-last" format.
      channel_dim: specifies the channel axes of the data array to move to the last.
          ``None`` indicates no channel dimension, a new axis will be appended as the channel dimension.
          a sequence of integers indicates multiple non-spatial dimensions.
      squeeze_end_dims: if ``True``, any trailing singleton dimensions will be removed (after the channel
          has been moved to the end). So if input is `(H,W,D,C)` and C==1, then it will be saved as `(H,W,D)`.
          If D is also 1, it will be saved as `(H,W)`. If ``False``, image will always be saved as `(H,W,D,C)`.
      spatial_ndim: modifying the spatial dims if needed, so that output to have at least
          this number of spatial dims. If ``None``, the output will have the same number of
          spatial dimensions as the input.
      contiguous: if ``True``, the output will be contiguous.
docstr_tok: ["Rearrange","the","data","array","axes","to","make","the","`","channel_dim","`","-th","dim","the","last","dimension","and","ensure","there","are","``","spatial_ndim","``","number","of","spatial","dimensions",".","When","``","squeeze_end_dims","``","is","``","True","``",",","a","postprocessing","step","will","be","applied","to","remove","any","trailing","singleton","dimensions",".","Args",":","data",":","input","data","to","be","converted","to","``","channel-last","''","format",".","channel_dim",":","specifies","the","channel","axes","of","the","data","array","to","move","to","the","last",".","``","None","``","indicates","no","channel","dimension",",","a","new","axis","will","be","appended","as","the","channel","dimension",".","a","sequence","of","integers","indicates","multiple","non-spatial","dimensions",".","squeeze_end_dims",":","if","``","True","``",",","any","trailing","singleton","dimensions","will","be","removed","(","after","the","channel","has","been","moved","to","the","end",")",".","So","if","input","is","`","(","H",",","W",",","D",",","C",")","`","and","C==1",",","then","it","will","be","saved","as","`","(","H",",","W",",","D",")","`",".","If","D","is","also","1",",","it","will","be","saved","as","`","(","H",",","W",")","`",".","If","``","False","``",",","image","will","always","be","saved","as","`","(","H",",","W",",","D",",","C",")","`",".","spatial_ndim",":","modifying","the","spatial","dims","if","needed",",","so","that","output","to","have","at","least","this","number","of","spatial","dims",".","If","``","None","``",",","the","output","will","have","the","same","number","of","spatial","dimensions","as","the","input",".","contiguous",":","if","``","True","``",",","the","output","will","be","contiguous","."]
code: def convert_to_channel_last(
      cls,
      data: NdarrayOrTensor,
      channel_dim: None | int | Sequence[int] = 0,
      squeeze_end_dims: bool = True,
      spatial_ndim: int | None = 3,
      contiguous: bool = False,
  ):
      """
      Rearrange the data array axes to make the `channel_dim`-th dim the last
      dimension and ensure there are ``spatial_ndim`` number of spatial
      dimensions.
  
      When ``squeeze_end_dims`` is ``True``, a postprocessing step will be
      applied to remove any trailing singleton dimensions.
  
      Args:
          data: input data to be converted to "channel-last" format.
          channel_dim: specifies the channel axes of the data array to move to the last.
              ``None`` indicates no channel dimension, a new axis will be appended as the channel dimension.
              a sequence of integers indicates multiple non-spatial dimensions.
          squeeze_end_dims: if ``True``, any trailing singleton dimensions will be removed (after the channel
              has been moved to the end). So if input is `(H,W,D,C)` and C==1, then it will be saved as `(H,W,D)`.
              If D is also 1, it will be saved as `(H,W)`. If ``False``, image will always be saved as `(H,W,D,C)`.
          spatial_ndim: modifying the spatial dims if needed, so that output to have at least
              this number of spatial dims. If ``None``, the output will have the same number of
              spatial dimensions as the input.
          contiguous: if ``True``, the output will be contiguous.
      """
      # change data to "channel last" format
      if channel_dim is not None:
          _chns = ensure_tuple(channel_dim)
          data = moveaxis(data, _chns, tuple(range(-len(_chns), 0)))
      else:  # adds a channel dimension
          data = data[..., None]
      # To ensure at least ``spatial_ndim`` number of spatial dims
      if spatial_ndim:
          while (
              len(data.shape) < spatial_ndim + 1
          ):  # assuming the data has spatial + channel dims
              data = data[..., None, :]
          while len(data.shape) > spatial_ndim + 1:
              data = data[..., 0, :]
      # if desired, remove trailing singleton dimensions
      while squeeze_end_dims and data.shape[-1] == 1:
          data = np.squeeze(data, -1)
      if contiguous:
          data = ascontiguousarray(data)
      return data
  
imports: from __future__ import annotations
  from collections.abc import Mapping, Sequence
  from typing import TYPE_CHECKING, Any, cast
  import numpy
  from monai.apps.utils import get_logger
  from monai.config import DtypeLike, NdarrayOrTensor, PathLike
  from monai.data.meta_tensor import MetaTensor
  from monai.data.utils import affine_to_spacing, ensure_tuple, ensure_tuple_rep, orientation_ras_lps, to_affine_nd
  from monai.transforms.spatial.array import Resize, SpatialResample
  from monai.transforms.utils_pytorch_numpy_unification import ascontiguousarray, moveaxis
  from monai.utils import GridSampleMode, GridSamplePadMode, InterpolateMode, MetaKeys, OptionalImportError, SpaceKeys, convert_data_type, convert_to_tensor, get_equivalent_dtype, look_up_option, optional_import, require_pkg
label_desc: Use image node_id 7 for calling the ImageWriter obj's underlying member method code with example usage: obj.convert_to_channel_last(cls, data, channel_dim, squeeze_end_dims, spatial_ndim, contiguous) and returns: data