code: def zoom_affine(
      affine: np.ndarray,
      scale: np.ndarray | Sequence[float],
      diagonal: bool = True,
  ):
      """
      To make column norm of `affine` the same as `scale`.  If diagonal is False,
      returns an affine that combines orthogonal rotation and the new scale.
      This is done by first decomposing `affine`, then setting the zoom factors to
      `scale`, and composing a new affine; the shearing factors are removed.  If
      diagonal is True, returns a diagonal matrix, the scaling factors are set
      to the diagonal elements.  This function always return an affine with zero
      translations.
  
      Args:
          affine (nxn matrix): a square matrix.
          scale: new scaling factor along each dimension. if the components of the `scale` are non-positive values,
              will use the corresponding components of the original pixdim, which is computed from the `affine`.
          diagonal: whether to return a diagonal scaling matrix.
              Defaults to True.
  
      Raises:
          ValueError: When ``affine`` is not a square matrix.
          ValueError: When ``scale`` contains a nonpositive scalar.
  
      Returns:
          the updated `n x n` affine.
  
      """
  
      affine = np.array(affine, dtype=float, copy=True)
      if len(affine) != len(affine[0]):
          raise ValueError(
              f"affine must be n x n, got {len(affine)} x {len(affine[0])}."
          )
      scale_np = np.array(scale, dtype=float, copy=True)
  
      d = len(affine) - 1
      # compute original pixdim
      norm = affine_to_spacing(affine, r=d)
      if len(scale_np) < d:  # defaults based on affine
          scale_np = np.append(scale_np, norm[len(scale_np) :])
      scale_np = scale_np[:d]
      scale_np = np.asarray(fall_back_tuple(scale_np, norm))
  
      scale_np[scale_np == 0] = 1.0
      if diagonal:
          return np.diag(np.append(scale_np, [1.0]))
      rzs = affine[:-1, :-1]  # rotation zoom scale
      zs = np.linalg.cholesky(rzs.T @ rzs).T
      rotation = rzs @ np.linalg.inv(zs)
      s = np.sign(np.diag(zs)) * np.abs(scale_np)
      # construct new affine with rotation and zoom
      new_affine = np.eye(len(affine))
      new_affine[:-1, :-1] = rotation @ np.diag(s)
      return new_affine
  
imports: from __future__ import annotations
  import hashlib
  import json
  import logging
  import math
  import os
  import pickle
  import sys
  from collections import abc, defaultdict
  from collections.abc import Generator, Iterable, Mapping, Sequence, Sized
  from copy import deepcopy
  from functools import reduce
  from itertools import product, starmap, zip_longest
  from pathlib import PurePath
  from typing import Any
  import numpy
  import torch
  from torch.utils.data._utils.collate import default_collate
  from monai import config
  from monai.config.type_definitions import NdarrayOrTensor, NdarrayTensor, PathLike
  from monai.data.meta_obj import MetaObj
  from monai.utils import MAX_SEED, BlendMode, Method, NumpyPadMode, TraceKeys, convert_data_type, convert_to_dst_type, ensure_tuple, ensure_tuple_rep, ensure_tuple_size, fall_back_tuple, first, get_equivalent_dtype, issequenceiterable, look_up_option, optional_import, pytorch_after
label_desc: Use image node_id 21 for calling a global function with example usage: zoom_affine(affine, scale, diagonal) and returns: new_affine, np