code: def drop_io_dim(cm, axis_id, fix0=True):
      """Drop dimensions `axis_id` from coordinate map, if orthogonal to others
  
      If you specify an input dimension, drop that dimension and any corresponding
      output dimension, as long as all other outputs are orthogonal to dropped
      input.  If you specify an output dimension, drop that dimension and any
      corresponding input dimension, as long as all other inputs are orthogonal
      to dropped output.
  
      Parameters
      ----------
      cm : class:`AffineTransform`
          Affine coordinate map instance
      axis_id : int or str
          If int, gives index of *input* axis to drop.  If str, gives name of
          input *or* output axis to drop. When specifying an input axis: if given
          input axis does not affect any output axes, just drop input axis.  If
          input axis affects only one output axis, drop both input and
          corresponding output.  Similarly when specifying an output axis.  If
          `axis_id` is a str, it must be unambiguous - if the named axis exists in
          both input and output, and they do not correspond, raises a AxisError.
          See Raises section for checks
      fix0: bool, optional
          Whether to fix potential 0 TR in affine
  
      Returns
      -------
      cm_redux : Affine
          Affine coordinate map with orthogonal input + output dimension dropped
  
      Raises
      ------
      AxisError: if `axis_id` is a str and does not match any no input or output
          coordinate names.
      AxisError: if specified `axis_id` affects more than a single input / output
          axis.
      AxisError: if the named `axis_id` exists in both input and output, and they
          do not correspond.
  
      Examples
      --------
      Typical use is in getting a 3D coordinate map from 4D
  
      >>> cm4d = AffineTransform.from_params('ijkl', 'xyzt', np.diag([1,2,3,4,1]))
      >>> cm3d = drop_io_dim(cm4d, 't')
      >>> cm3d.affine
      array([[ 1.,  0.,  0.,  0.],
             [ 0.,  2.,  0.,  0.],
             [ 0.,  0.,  3.,  0.],
             [ 0.,  0.,  0.,  1.]])
      """
      # Implicit check for affine-type coordinate map
      aff = cm.affine.copy()
      # What dimensions did you ask for?
      in_dim, out_dim = io_axis_indices(cm, axis_id, fix0)
      if None not in (in_dim, out_dim):
          if not orth_axes(in_dim, out_dim, aff, allow_zero=fix0):
              raise AxisError(
                  "Input and output dimensions not orthogonal to "
                  "rest of affine"
              )
      M, N = aff.shape
      rows = list(range(M))
      cols = list(range(N))
      in_dims = list(cm.function_domain.coord_names)
      out_dims = list(cm.function_range.coord_names)
      if in_dim is not None:
          in_dims.pop(in_dim)
          cols.pop(in_dim)
      if out_dim is not None:
          out_dims.pop(out_dim)
          rows.pop(out_dim)
      aff = aff[rows]
      aff = aff[:, cols]
      return AffineTransform.from_params(in_dims, out_dims, aff)
  
imports: import warnings
  import numpy
  import numpy.linalg
  from nibabel import io_orientation
  from nibabel.affines import from_matvec, to_matvec
  from .coordinate_system import CoordinateSystem, is_coordsys, safe_dtype
  from .coordinate_system import product
label_desc: Use image node_id 15 for calling a global function with example usage: drop_io_dim(cm, axis_id, fix0) and returns: AffineTransform