code: def iter_patch(
      arr: NdarrayOrTensor,
      patch_size: Sequence[int] | int = 0,
      start_pos: Sequence[int] = (),
      overlap: Sequence[float] | float = 0.0,
      copy_back: bool = True,
      mode: str | None = NumpyPadMode.WRAP,
      **pad_opts: dict,
  ) -> Generator[tuple[NdarrayOrTensor, np.ndarray], None, None]:
      """
      Yield successive patches from `arr` of size `patch_size`. The iteration can start from position `start_pos` in `arr`
      but drawing from a padded array extended by the `patch_size` in each dimension (so these coordinates can be negative
      to start in the padded region). If `copy_back` is True the values from each patch are written back to `arr`.
  
      Args:
          arr: array to iterate over
          patch_size: size of patches to generate slices for, 0 or None selects whole dimension.
              For 0 or None, padding and overlap ratio of the corresponding dimension will be 0.
          start_pos: starting position in the array, default is 0 for each dimension
          overlap: the amount of overlap of neighboring patches in each dimension (a value between 0.0 and 1.0).
              If only one float number is given, it will be applied to all dimensions. Defaults to 0.0.
          copy_back: if True data from the yielded patches is copied back to `arr` once the generator completes
          mode: available modes: (Numpy) {``"constant"``, ``"edge"``, ``"linear_ramp"``, ``"maximum"``,
              ``"mean"``, ``"median"``, ``"minimum"``, ``"reflect"``, ``"symmetric"``, ``"wrap"``, ``"empty"``}
              (PyTorch) {``"constant"``, ``"reflect"``, ``"replicate"``, ``"circular"``}.
              One of the listed string values or a user supplied function.
              If None, no wrapping is performed. Defaults to ``"wrap"``.
              See also: https://numpy.org/doc/stable/reference/generated/numpy.pad.html
              https://pytorch.org/docs/stable/generated/torch.nn.functional.pad.html
              requires pytorch >= 1.10 for best compatibility.
          pad_opts: other arguments for the `np.pad` or `torch.pad` function.
              note that `np.pad` treats channel dimension as the first dimension.
  
      Yields:
          Patches of array data from `arr` which are views into a padded array which can be modified, if `copy_back` is
          True these changes will be reflected in `arr` once the iteration completes.
  
      Note:
          coordinate format is:
  
              [1st_dim_start, 1st_dim_end,
               2nd_dim_start, 2nd_dim_end,
               ...,
               Nth_dim_start, Nth_dim_end]]
  
      """
  
      from monai.transforms.croppad.functional import (
          pad_nd,
      )  # needs to be here to avoid circular import
  
      # ensure patchSize and startPos are the right length
      patch_size_ = get_valid_patch_size(arr.shape, patch_size)
      start_pos = ensure_tuple_size(start_pos, arr.ndim)
  
      # set padded flag to false if pad mode is None
      padded = bool(mode)
      is_v = [
          bool(p) for p in ensure_tuple_size(patch_size, arr.ndim)
      ]  # whether a valid patch size provided
      _pad_size = tuple(
          p if v and padded else 0 for p, v in zip(patch_size_, is_v)
      )  # pad p if v else 0
      _overlap = [
          op if v else 0.0
          for op, v in zip(ensure_tuple_rep(overlap, arr.ndim), is_v)
      ]  # overlap if v else 0.0
      # pad image by maximum values needed to ensure patches are taken from inside an image
      if padded:
          arrpad = pad_nd(arr, to_pad=[(p, p) for p in _pad_size], mode=mode, **pad_opts)  # type: ignore
          # choose a start position in the padded image
          start_pos_padded = tuple(
              s + p for s, p in zip(start_pos, _pad_size)
          )
  
          # choose a size to iterate over which is smaller than the actual padded image to prevent producing
          # patches which are only in the padded regions
          iter_size = tuple(s + p for s, p in zip(arr.shape, _pad_size))
      else:
          arrpad = arr
          start_pos_padded = start_pos
          iter_size = arr.shape
  
      for slices in iter_patch_slices(
          iter_size,
          patch_size_,
          start_pos_padded,
          _overlap,
          padded=padded,
      ):
          # compensate original image padding
          if padded:
              coords_no_pad = tuple(
                  (coord.start - p, coord.stop - p)
                  for coord, p in zip(slices, _pad_size)
              )
          else:
              coords_no_pad = tuple(
                  (coord.start, coord.stop) for coord in slices
              )
          yield arrpad[slices], np.asarray(
              coords_no_pad
          )  # data and coords (in numpy; works with torch loader)
  
      # copy back data from the padded image if required
      if copy_back:
          slices = tuple(
              slice(p, p + s) for p, s in zip(_pad_size, arr.shape)
          )
          arr[...] = arrpad[slices]
  
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 5 for calling a global function with example usage: iter_patch(arr, patch_size, start_pos, overlap, copy_back, mode) without return types