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: Subclass should implement this method to return a backend-specific data representation object.
  This method is used by ``cls.write`` and the input ``data_array`` is assumed 'channel-last'.
docstr_tok: ["Subclass","should","implement","this","method","to","return","a","backend-specific","data","representation","object",".","This","method","is","used","by","``","cls.write","``","and","the","input","``","data_array","``","is","assumed","'channel-last","'","."]
code: def create_backend_obj(
      cls, data_array: NdarrayOrTensor, **kwargs
  ) -> np.ndarray:
      """
      Subclass should implement this method to return a backend-specific data representation object.
      This method is used by ``cls.write`` and the input ``data_array`` is assumed 'channel-last'.
      """
      return convert_data_type(data_array, np.ndarray)[0]
  
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 5 for calling the ImageWriter obj's underlying member method code with example usage: obj.create_backend_obj(cls, data_array) and returns: convert_data_type