code: def generate_model_space_decomposition(
      decomposition: Dict[str, List[str]], feature_names: List[str]
  ) -> Dict[str, List[int]]:
      # validate input decomposition
      for param_list in decomposition.values():
          for param in param_list:
              assert (
                  param in feature_names
              ), f"cannot find parameter {param} in search space"
  
      # generate parameter index list align with the input arrays
      decomp_index = {}
      for context, param_names in decomposition.items():
          decomp_index[context] = [
              feature_names.index(p) for p in param_names
          ]
      return decomp_index
  
imports: from logging import Logger
  from typing import Any, Dict, List, Optional
  from ax.core.search_space import SearchSpaceDigest
  from ax.core.types import TCandidateMetadata
  from ax.models.torch.botorch import BotorchModel
  from ax.models.torch_base import TorchModel
  from ax.utils.common.docutils import copy_doc
  from ax.utils.common.logger import get_logger
  from botorch.fit import fit_gpytorch_mll
  from botorch.models.contextual import SACGP
  from botorch.models.gpytorch import GPyTorchModel
  from botorch.models.model_list_gp_regression import ModelListGP
  from botorch.utils.datasets import SupervisedDataset
  from gpytorch.mlls.exact_marginal_log_likelihood import ExactMarginalLogLikelihood
  from torch import Tensor
label_desc: Use image node_id 1 for calling a global function with example usage: generate_model_space_decomposition(decomposition, feature_names) and returns: decomp_index