code: def observed_hypervolume(
      modelbridge: modelbridge_module.torch.TorchModelBridge,
      objective_thresholds: Optional[TRefPoint] = None,
      optimization_config: Optional[
          MultiObjectiveOptimizationConfig
      ] = None,
      selected_metrics: Optional[List[str]] = None,
  ) -> float:
      """Calculate hypervolume of a pareto frontier based on observed data.
  
      Given observed data, return the hypervolume of the pareto frontier formed from
      those outcomes.
  
      Args:
          modelbridge: Modelbridge that holds previous training data.
          objective_thresholds: Point defining the origin of hyperrectangles that
              can contribute to hypervolume. Note that if this is None,
              `objective_thresholds` must be present on the
              `modelbridge.optimization_config`.
          observation_features: observation features to predict. Model's training
              data used by default if unspecified.
          optimization_config: Optimization config
          selected_metrics: If specified, hypervolume will only be evaluated on
              the specified subset of metrics. Otherwise, all metrics will be used.
  
      Returns:
          (float) calculated hypervolume.
      """
      # Get observation_data from current training data.
      obs_feats, obs_data, _ = _get_modelbridge_training_data(
          modelbridge=modelbridge
      )
  
      return hypervolume(
          modelbridge=modelbridge,
          objective_thresholds=objective_thresholds,
          observation_features=obs_feats,
          observation_data=obs_data,
          optimization_config=optimization_config,
          selected_metrics=selected_metrics,
          use_model_predictions=False,
      )
  
imports: from __future__ import annotations
  import warnings
  from copy import deepcopy
  from functools import partial
  from logging import Logger
  from typing import Any, Callable, Dict, Iterable, List, Mapping, MutableMapping, Optional, Tuple, Type, TYPE_CHECKING, Union
  import numpy
  import torch
  from ax.core.data import Data
  from ax.core.experiment import Experiment
  from ax.core.objective import MultiObjective, Objective, ScalarizedObjective
  from ax.core.observation import Observation, ObservationData, ObservationFeatures
  from ax.core.optimization_config import MultiObjectiveOptimizationConfig, OptimizationConfig, TRefPoint
  from ax.core.outcome_constraint import ComparisonOp, OutcomeConstraint, ScalarizedOutcomeConstraint
  from ax.core.parameter import ChoiceParameter, Parameter, ParameterType, RangeParameter
  from ax.core.parameter_constraint import ParameterConstraint
  from ax.core.risk_measures import RiskMeasure
  from ax.core.search_space import RobustSearchSpace, RobustSearchSpaceDigest, SearchSpace, SearchSpaceDigest
  from ax.core.types import TBounds, TCandidateMetadata
  from ax.core.utils import get_pending_observation_features, get_pending_observation_features_based_on_trial_status
  from ax.exceptions.core import DataRequiredError, UnsupportedError, UserInputError
  from ax.modelbridge.transforms.base import Transform
  from ax.modelbridge.transforms.utils import derelativize_optimization_config_with_raw_status_quo
  from ax.models.torch.botorch_moo_defaults import pareto_frontier_evaluator
  from ax.models.torch.frontier_utils import get_weighted_mc_objective_and_objective_thresholds
  from ax.utils.common.logger import get_logger
  from ax.utils.common.typeutils import checked_cast, checked_cast_optional, checked_cast_to_tuple, not_none
  from botorch.acquisition.multi_objective.multi_output_risk_measures import IndependentCVaR, IndependentVaR, MARS, MultiOutputExpectation, MVaR
  from botorch.acquisition.risk_measures import CVaR, Expectation, RiskMeasureMCObjective, VaR, WorstCase
  from botorch.utils.datasets import ContextualDataset, SupervisedDataset
  from botorch.utils.multi_objective.box_decompositions.dominated import DominatedPartitioning
  from torch import Tensor
label_desc: Use image node_id 21 for calling a global function with example usage: observed_hypervolume(modelbridge, objective_thresholds, optimization_config, selected_metrics) and returns: hypervolume