class_docstr: Does Bayesian optimization with Latent Context Embedding Additive (LCE-A) GP.
  The parameter space decomposition must be provided.
  
  Args:
      decomposition: Keys are context names. Values are the lists of parameter
          names belong to the context, e.g.
          {'context1': ['p1_c1', 'p2_c1'],'context2': ['p1_c2', 'p2_c2']}.
      gp_model_args: Dictionary of kwargs to pass to GP model training.
          - train_embedding: Boolen. If true, we will train context embedding;
          otherwise, we use pre-trained embeddings from embds_feature_dict only.
          Default is True.
docstr: Get a fitted LCEAGP model for each outcome.
  Args:
      Xs: X for each outcome.
      Ys: Y for each outcome.
      Yvars: Noise variance of Y for each outcome.
  Returns: Fitted LCEAGP model.
docstr_tok: ["Get","a","fitted","LCEAGP","model","for","each","outcome",".","Args",":","Xs",":","X","for","each","outcome",".","Ys",":","Y","for","each","outcome",".","Yvars",":","Noise","variance","of","Y","for","each","outcome",".","Returns",":","Fitted","LCEAGP","model","."]
code: def get_and_fit_model(
      self,
      Xs: List[Tensor],
      Ys: List[Tensor],
      Yvars: List[Tensor],
      task_features: List[int],
      fidelity_features: List[int],
      metric_names: List[str],
      state_dict: Optional[Dict[str, Tensor]] = None,
      fidelity_model_id: Optional[int] = None,
      **kwargs: Any,
  ) -> GPyTorchModel:
      """Get a fitted LCEAGP model for each outcome.
      Args:
          Xs: X for each outcome.
          Ys: Y for each outcome.
          Yvars: Noise variance of Y for each outcome.
      Returns: Fitted LCEAGP model.
      """
      # generate model space decomposition dict
      decomp_index = generate_model_space_decomposition(
          decomposition=self.decomposition,
          feature_names=self.feature_names,
      )
  
      models = []
      for i, X in enumerate(Xs):
          Yvar = Yvars[i].clamp_min_(MIN_OBSERVED_NOISE_LEVEL)
          gp_m, _ = get_map_model(
              train_X=X,
              train_Y=Ys[i],
              train_Yvar=Yvar,
              decomposition=decomp_index,
              train_embedding=self.train_embedding,
              cat_feature_dict=self.cat_feature_dict,
              embs_feature_dict=self.embs_feature_dict,
              embs_dim_list=self.embs_dim_list,
              context_weight_dict=self.context_weight_dict,
          )
          models.append(gp_m)
  
      if len(models) == 1:
          model = models[0]
      else:
          model = ModelListGP(*models)
      model.to(Xs[0])
      return model
  
imports: from logging import Logger
  from typing import Any, cast, Dict, List, Optional, Tuple, Union
  from ax.core.search_space import SearchSpaceDigest
  from ax.core.types import TCandidateMetadata
  from ax.models.torch.alebo import ei_or_nei
  from ax.models.torch.botorch import BotorchModel
  from ax.models.torch.cbo_sac import generate_model_space_decomposition
  from ax.models.torch_base import TorchModel, TorchOptConfig
  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 LCEAGP
  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 4 for calling the LCEABO obj's underlying member method code with example usage: obj.get_and_fit_model(Xs, Ys, Yvars, task_features, fidelity_features, metric_names, state_dict, fidelity_model_id) and returns: model