class_docstr: Inference on patches instead of the whole image based on Splitter and Merger.
  This splits the input image into patches and then merge the resulted patches.
  
  Args:
      splitter: a `Splitter` object that split the inputs into patches. Defaults to None.
          If not provided or None, the inputs are considered to be already split into patches.
          In this case, the output `merged_shape` and the optional `cropped_shape` cannot be inferred
          and should be explicitly provided.
      merger_cls: a `Merger` subclass that can be instantiated to merges patch outputs.
          It can also be a string that matches the name of a class inherited from `Merger` class.
          Defaults to `AvgMerger`.
      batch_size: batch size for patches. If the input tensor is already batched [BxCxWxH],
          this adds additional batching [(Bp*B)xCxWpxHp] for inference on patches.
          Defaults to 1.
      preprocessing: a callable that process patches before the being fed to the network.
          Defaults to None.
      postprocessing: a callable that process the output of the network.
          Defaults to None.
      output_keys: if the network output is a dictionary, this defines the keys of
          the output dictionary to be used for merging.
          Defaults to None, where all the keys are used.
      match_spatial_shape: whether to crop the output to match the input shape. Defaults to True.
      buffer_size: number of patches to be held in the buffer with a separate thread for batch sampling. Defaults to 0.
      merger_kwargs: arguments to be passed to `merger_cls` for instantiation.
          `merged_shape` is calculated automatically based on the input shape and
          the output patch shape unless it is passed here.
class_docstr_tok: ["Inference","on","patches","instead","of","the","whole","image","based","on","Splitter","and","Merger",".","This","splits","the","input","image","into","patches","and","then","merge","the","resulted","patches",".","Args",":","splitter",":","a","`","Splitter","`","object","that","split","the","inputs","into","patches",".","Defaults","to","None",".","If","not","provided","or","None",",","the","inputs","are","considered","to","be","already","split","into","patches",".","In","this","case",",","the","output","`","merged_shape","`","and","the","optional","`","cropped_shape","`","can","not","be","inferred","and","should","be","explicitly","provided",".","merger_cls",":","a","`","Merger","`","subclass","that","can","be","instantiated","to","merges","patch","outputs",".","It","can","also","be","a","string","that","matches","the","name","of","a","class","inherited","from","`","Merger","`","class",".","Defaults","to","`","AvgMerger","`",".","batch_size",":","batch","size","for","patches",".","If","the","input","tensor","is","already","batched","[","BxCxWxH","]",",","this","adds","additional","batching","[","(","Bp","*","B",")","xCxWpxHp","]","for","inference","on","patches",".","Defaults","to","1.","preprocessing",":","a","callable","that","process","patches","before","the","being","fed","to","the","network",".","Defaults","to","None",".","postprocessing",":","a","callable","that","process","the","output","of","the","network",".","Defaults","to","None",".","output_keys",":","if","the","network","output","is","a","dictionary",",","this","defines","the","keys","of","the","output","dictionary","to","be","used","for","merging",".","Defaults","to","None",",","where","all","the","keys","are","used",".","match_spatial_shape",":","whether","to","crop","the","output","to","match","the","input","shape",".","Defaults","to","True",".","buffer_size",":","number","of","patches","to","be","held","in","the","buffer","with","a","separate","thread","for","batch","sampling",".","Defaults","to","0.","merger_kwargs",":","arguments","to","be","passed","to","`","merger_cls","`","for","instantiation",".","`","merged_shape","`","is","calculated","automatically","based","on","the","input","shape","and","the","output","patch","shape","unless","it","is","passed","here","."]
code: def __init__(
      self,
      splitter: Splitter | None = None,
      merger_cls: type[Merger] | str = AvgMerger,
      batch_size: int = 1,
      preprocessing: Callable | None = None,
      postprocessing: Callable | None = None,
      output_keys: Sequence | None = None,
      match_spatial_shape: bool = True,
      buffer_size: int = 0,
      **merger_kwargs: Any,
  ) -> None:
      Inferer.__init__(self)
      # splitter
      if not isinstance(splitter, (Splitter, type(None))):
          if not isinstance(splitter, Splitter):
              raise TypeError(
                  f"'splitter' should be a `Splitter` object that returns: "
                  "an iterable of pairs of (patch, location) or a MetaTensor that has `PatchKeys.LOCATION` metadata)."
                  f"{type(splitter)} is given."
              )
      self.splitter = splitter
  
      # merger
      if isinstance(merger_cls, str):
          valid_merger_cls: type[Merger]
          # search amongst implemented mergers in MONAI
          valid_merger_cls, merger_found = optional_import(
              "monai.inferers.merger", name=merger_cls
          )
          if not merger_found:
              # try to locate the requested merger class (with dotted path)
              valid_merger_cls = locate(merger_cls)  # type: ignore
          if valid_merger_cls is None:
              raise ValueError(
                  f"The requested `merger_cls` ['{merger_cls}'] does not exist."
              )
          merger_cls = valid_merger_cls
      if not issubclass(merger_cls, Merger):
          raise TypeError(
              f"'merger' should be a subclass of `Merger`, {merger_cls} is given."
          )
      self.merger_cls = merger_cls
      self.merger_kwargs = merger_kwargs
  
      # pre-processor (process patch before the network)
      if preprocessing is not None and not callable(preprocessing):
          raise TypeError(
              f"'preprocessing' should be a callable object, {type(preprocessing)} is given."
          )
      self.preprocessing = preprocessing
  
      # post-processor (process the output of the network)
      if postprocessing is not None and not callable(postprocessing):
          raise TypeError(
              f"'postprocessing' should be a callable object, {type(postprocessing)} is given."
          )
      self.postprocessing = postprocessing
  
      # batch size for patches
      if batch_size < 1:
          raise ValueError(
              f"`batch_size` must be a positive number, {batch_size} is given."
          )
      self.batch_size = batch_size
  
      # model output keys
      self.output_keys = output_keys
  
      # whether to crop the output to match the input shape
      self.match_spatial_shape = match_spatial_shape
  
      # buffer size for multithreaded batch sampling
      self.buffer_size = buffer_size
  
imports: from __future__ import annotations
  import warnings
  from abc import ABC, abstractmethod
  from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence
  from pydoc import locate
  from typing import Any
  import torch
  import torch.nn
  from monai.apps.utils import get_logger
  from monai.data.meta_tensor import MetaTensor
  from monai.data.thread_buffer import ThreadBuffer
  from monai.inferers.merger import AvgMerger, Merger
  from monai.inferers.splitter import Splitter
  from monai.inferers.utils import compute_importance_map, sliding_window_inference
  from monai.utils import BlendMode, PatchKeys, PytorchPadMode, ensure_tuple, optional_import
  from monai.visualize import CAM, GradCAM, GradCAMpp
label_desc: Use image node_id 1 to create a new PatchInferer object from inherited base classes: Inferer with example: obj = PatchInferer(splitter, merger_cls, batch_size, preprocessing, postprocessing, output_keys, match_spatial_shape, buffer_size)