code: def get_post_processing_func(
      rounding_func: Optional[Callable[[Tensor], Tensor]],
      optimizer_options: Dict[str, Any],
  ) -> Optional[Callable[[Tensor], Tensor]]:
      """Get the post processing function by combining the rounding function
      with the post processing function provided as part of the optimizer
      options. If both are given, the post processing function is applied before
      applying the rounding function. If only one of them is given, then
      it is used as the post processing function.
      """
      if "post_processing_func" in optimizer_options:
          provided_func: Callable[
              [Tensor], Tensor
          ] = optimizer_options.pop("post_processing_func")
          if rounding_func is None:
              # No rounding function is given. We can use the post processing
              # function directly.
              return provided_func
          else:
              # Both post processing and rounding functions are given. We need
              # to chain them and apply the post processing function first.
              base_rounding_func: Callable[
                  [Tensor], Tensor
              ] = rounding_func
  
              def combined_func(x: Tensor) -> Tensor:
                  return base_rounding_func(provided_func(x))
  
              return combined_func
  
      else:
          return rounding_func
  
imports: import warnings
  from logging import Logger
  from typing import Any, Callable, Dict, List, Optional, OrderedDict, Tuple, Type
  import torch
  from ax.core.search_space import SearchSpaceDigest
  from ax.exceptions.core import AxError, AxWarning, UnsupportedError
  from ax.models.types import TConfig
  from ax.utils.common.constants import Keys
  from ax.utils.common.logger import get_logger
  from ax.utils.common.typeutils import checked_cast, not_none
  from botorch.acquisition.acquisition import AcquisitionFunction
  from botorch.acquisition.logei import qLogNoisyExpectedImprovement
  from botorch.acquisition.multi_objective.logei import qLogNoisyExpectedHypervolumeImprovement
  from botorch.fit import fit_fully_bayesian_model_nuts, fit_gpytorch_mll
  from botorch.models.fully_bayesian import SaasFullyBayesianSingleTaskGP
  from botorch.models.gp_regression import SingleTaskGP
  from botorch.models.gp_regression_fidelity import SingleTaskMultiFidelityGP
  from botorch.models.gp_regression_mixed import MixedSingleTaskGP
  from botorch.models.gpytorch import BatchedMultiOutputGPyTorchModel, GPyTorchModel
  from botorch.models.model import Model, ModelList
  from botorch.models.multitask import MultiTaskGP
  from botorch.models.pairwise_gp import PairwiseGP
  from botorch.utils.datasets import SupervisedDataset
  from botorch.utils.transforms import is_fully_bayesian
  from gpytorch.mlls.marginal_log_likelihood import MarginalLogLikelihood
  from torch import Tensor
label_desc: Use image node_id 9 for calling a global function with example usage: get_post_processing_func(rounding_func, optimizer_options) and returns: rounding_func, provided_func, combined_func, base_rounding_func