code: def adaptor(function, outputs, inputs=None):
      def must_be_types_or_none(variable_name, variable, types):
          if variable is not None:
              if not isinstance(variable, types):
                  raise TypeError(
                      f"'{variable_name}' must be None or one of {types} but is {type(variable)}"
                  )
  
      def must_be_types(variable_name, variable, types):
          if not isinstance(variable, types):
              raise TypeError(
                  f"'{variable_name}' must be one of {types} but is {type(variable)}"
              )
  
      def map_names(ditems, input_map):
          return {input_map(k, k): v for k, v in ditems.items()}
  
      def map_only_names(ditems, input_map):
          return {v: ditems[k] for k, v in input_map.items()}
  
      def _inner(ditems):
          sig = FunctionSignature(function)
  
          if sig.found_kwargs:
              must_be_types_or_none("inputs", inputs, (dict,))
              # we just forward all arguments unless we have been provided an input map
              if inputs is None:
                  dinputs = dict(ditems)
              else:
                  # dict
                  dinputs = map_names(ditems, inputs)
  
          else:
              # no **kwargs
              # select only items from the method signature
              dinputs = {
                  k: v
                  for k, v in ditems.items()
                  if k in sig.non_var_parameters
              }
              must_be_types_or_none(
                  "inputs", inputs, (str, list, tuple, dict)
              )
              if inputs is None:
                  pass
              elif isinstance(inputs, str):
                  if len(sig.non_var_parameters) != 1:
                      raise ValueError(
                          "if 'inputs' is a string, function may only have a single non-variadic parameter"
                      )
                  dinputs = {inputs: ditems[inputs]}
              elif isinstance(inputs, (list, tuple)):
                  dinputs = {k: dinputs[k] for k in inputs}
              else:
                  # dict
                  dinputs = map_only_names(ditems, inputs)
  
          ret = function(**dinputs)
  
          # now the mapping back to the output dictionary depends on outputs and what was returned from the function
          op = outputs
          if isinstance(ret, dict):
              must_be_types_or_none("outputs", op, (dict,))
              if op is not None:
                  ret = {v: ret[k] for k, v in op.items()}
          elif isinstance(ret, (list, tuple)):
              if len(ret) == 1:
                  must_be_types("outputs", op, (str, list, tuple))
              else:
                  must_be_types("outputs", op, (list, tuple))
  
              if isinstance(op, str):
                  op = [op]
  
              if len(ret) != len(outputs):
                  raise ValueError(
                      "'outputs' must have the same length as the number of elements that were returned"
                  )
  
              ret = dict(zip(op, ret))
          else:
              must_be_types("outputs", op, (str, list, tuple))
              if isinstance(op, (list, tuple)):
                  if len(op) != 1:
                      raise ValueError(
                          "'outputs' must be of length one if it is a list or tuple"
                      )
                  op = op[0]
              ret = {op: ret}
  
          ditems = dict(ditems)
          for k, v in ret.items():
              ditems[k] = v
  
          return ditems
  
      return _inner
  
file_path: MONAI/monai/transforms/adaptors.py
imports: from __future__ import annotations
  from typing import Callable
  from monai.utils import export
label_desc: Use image node_id 1 for calling a global function with example usage: adaptor(function, outputs, inputs) and returns: _inner, unknown, unknown, ditems