code: def test_infer_objective_thresholds(
      self, _, cuda: bool = False
  ) -> None:
      # lightweight test
      exp = get_branin_experiment_with_multi_objective(
          has_optimization_config=True,
          with_batch=True,
          with_status_quo=True,
      )
      for trial in exp.trials.values():
          trial.mark_running(no_runner_required=True).mark_completed()
      exp.attach_data(
          get_branin_data_multi_objective(
              trial_indices=exp.trials.keys()
          )
      )
      data = exp.fetch_data()
      modelbridge = TorchModelBridge(
          search_space=exp.search_space,
          model=MultiObjectiveBotorchModel(),
          optimization_config=exp.optimization_config,
          transforms=Cont_X_trans + Y_trans,
          torch_device=torch.device("cuda" if cuda else "cpu"),
          experiment=exp,
          data=data,
      )
      fixed_features = ObservationFeatures(parameters={"x1": 0.0})
      search_space = exp.search_space.clone()
      param_constraints = [
          ParameterConstraint(constraint_dict={"x1": 1.0}, bound=10.0)
      ]
      search_space.add_parameter_constraints(param_constraints)
      oc = not_none(exp.optimization_config).clone()
      oc.objective._objectives[0].minimize = True
  
      for use_partial_thresholds in (False, True):
          if use_partial_thresholds:
              checked_cast(
                  MultiObjectiveOptimizationConfig, oc
              )._objective_thresholds = [
                  ObjectiveThreshold(
                      metric=oc.objective.metrics[0],
                      bound=2.0,
                      relative=False,
                      op=ComparisonOp.LEQ,
                  )
              ]
          expected_base_gen_args = (
              modelbridge._get_transformed_gen_args(
                  search_space=search_space.clone(),
                  optimization_config=oc,
                  fixed_features=fixed_features,
              )
          )
          with ExitStack() as es:
              mock_model_infer_obj_t = es.enter_context(
                  patch(
                      "ax.modelbridge.torch.infer_objective_thresholds",
                      wraps=infer_objective_thresholds,
                  )
              )
              mock_get_transformed_gen_args = es.enter_context(
                  patch.object(
                      modelbridge,
                      "_get_transformed_gen_args",
                      wraps=modelbridge._get_transformed_gen_args,
                  )
              )
              mock_get_transformed_model_gen_args = es.enter_context(
                  patch.object(
                      modelbridge,
                      "_get_transformed_model_gen_args",
                      wraps=modelbridge._get_transformed_model_gen_args,
                  )
              )
              mock_untransform_objective_thresholds = es.enter_context(
                  patch.object(
                      modelbridge,
                      "_untransform_objective_thresholds",
                      wraps=modelbridge._untransform_objective_thresholds,
                  )
              )
              obj_thresholds = modelbridge.infer_objective_thresholds(
                  search_space=search_space,
                  optimization_config=oc,
                  fixed_features=fixed_features,
              )
              expected_obj_weights = torch.tensor(
                  [-1.0, -1.0], dtype=torch.double
              )
              ckwargs = mock_model_infer_obj_t.call_args[1]
              self.assertTrue(
                  torch.equal(
                      ckwargs["objective_weights"], expected_obj_weights
                  )
              )
              # check that transforms have been applied (at least UnitX)
              self.assertEqual(
                  ckwargs["bounds"], [(0.0, 1.0), (0.0, 1.0)]
              )
              lc = ckwargs["linear_constraints"]
              self.assertTrue(
                  torch.equal(
                      lc[0],
                      torch.tensor([[15.0, 0.0]], dtype=torch.double),
                  )
              )
              self.assertTrue(
                  torch.equal(
                      lc[1], torch.tensor([[15.0]], dtype=torch.double)
                  )
              )
              self.assertEqual(
                  ckwargs["fixed_features"], {0: 1.0 / 3.0}
              )
              mock_get_transformed_gen_args.assert_called_once()
              mock_get_transformed_model_gen_args.assert_called_once_with(
                  search_space=expected_base_gen_args.search_space,
                  fixed_features=expected_base_gen_args.fixed_features,
                  pending_observations=expected_base_gen_args.pending_observations,
                  optimization_config=expected_base_gen_args.optimization_config,
              )
              mock_untransform_objective_thresholds.assert_called_once()
              ckwargs = mock_untransform_objective_thresholds.call_args[
                  1
              ]
  
              self.assertTrue(
                  torch.equal(
                      ckwargs["objective_weights"], expected_obj_weights
                  )
              )
          self.assertEqual(obj_thresholds[0].metric.name, "branin_a")
          self.assertEqual(obj_thresholds[1].metric.name, "branin_b")
          self.assertEqual(obj_thresholds[0].op, ComparisonOp.LEQ)
          self.assertEqual(obj_thresholds[1].op, ComparisonOp.LEQ)
          self.assertFalse(obj_thresholds[0].relative)
          self.assertFalse(obj_thresholds[1].relative)
          df = exp_to_df(exp)
          Y = np.stack([df.branin_a.values, df.branin_b.values]).T
          Y = torch.from_numpy(Y)
          Y[:, 0] *= -1
          pareto_Y = Y[is_non_dominated(Y)]
          nadir = pareto_Y.min(dim=0).values
          self.assertTrue(
              np.all(
                  -np.array(
                      [obj_thresholds[0].bound, obj_thresholds[1].bound]
                  )
                  < nadir.numpy()
              )
          )
  
      # test using MTGP
      sobol_generator = get_sobol(
          search_space=exp.search_space,
          seed=TEST_SOBOL_SEED,
          # set initial position equal to the number of sobol arms generated
          # so far. This means that new sobol arms will complement the previous
          # arms in a space-filling fashion
          init_position=len(exp.arms_by_name) - 1,
      )
      sobol_run = sobol_generator.gen(n=2)
      trial = exp.new_batch_trial(optimize_for_power=True)
      trial.add_generator_run(sobol_run)
      trial.mark_running(no_runner_required=True).mark_completed()
      data = exp.fetch_data()
      torch.manual_seed(0)  # make model fitting deterministic
      modelbridge = TorchModelBridge(
          search_space=exp.search_space,
          model=MultiObjectiveBotorchModel(),
          optimization_config=exp.optimization_config,
          transforms=ST_MTGP_trans,
          experiment=exp,
          data=data,
      )
      fixed_features = ObservationFeatures(parameters={}, trial_index=1)
      expected_base_gen_args = modelbridge._get_transformed_gen_args(
          search_space=search_space.clone(),
          optimization_config=exp.optimization_config,
          fixed_features=fixed_features,
      )
      with ExitStack() as es:
          mock_model_infer_obj_t = es.enter_context(
              patch(
                  "ax.modelbridge.torch.infer_objective_thresholds",
                  wraps=infer_objective_thresholds,
              )
          )
          mock_untransform_objective_thresholds = es.enter_context(
              patch.object(
                  modelbridge,
                  "_untransform_objective_thresholds",
                  wraps=modelbridge._untransform_objective_thresholds,
              )
          )
          obj_thresholds = modelbridge.infer_objective_thresholds(
              search_space=search_space,
              optimization_config=exp.optimization_config,
              fixed_features=fixed_features,
          )
          ckwargs = mock_model_infer_obj_t.call_args[1]
          self.assertEqual(ckwargs["fixed_features"], {2: 1.0})
          mock_untransform_objective_thresholds.assert_called_once()
      self.assertEqual(obj_thresholds[0].metric.name, "branin_a")
      self.assertEqual(obj_thresholds[1].metric.name, "branin_b")
      self.assertEqual(obj_thresholds[0].op, ComparisonOp.LEQ)
      self.assertEqual(obj_thresholds[1].op, ComparisonOp.LEQ)
      self.assertFalse(obj_thresholds[0].relative)
      self.assertFalse(obj_thresholds[1].relative)
      df = exp_to_df(exp)
      trial_mask = df.trial_index == 1
      Y = np.stack(
          [
              df.branin_a.values[trial_mask],
              df.branin_b.values[trial_mask],
          ]
      ).T
      Y = torch.from_numpy(Y)
      pareto_Y = Y[is_non_dominated(Y)]
      nadir = pareto_Y.min(dim=0).values
      self.assertTrue(
          np.all(
              np.array(
                  [obj_thresholds[0].bound, obj_thresholds[1].bound]
              )
              < nadir.numpy()
          )
      )
  
      # test with HSS
      hss = get_hierarchical_search_space(with_fixed_parameter=True)
      exp = get_branin_experiment_with_multi_objective(
          has_optimization_config=True
      )
      data = get_branin_data_multi_objective(trial_indices=[0, 1])
      # Update trials to match the search space.
      exp._search_space = hss
      exp._trials = get_hss_trials_with_fixed_parameter(exp=exp)
      modelbridge = TorchModelBridge(
          search_space=hss,
          model=MultiObjectiveBotorchModel(),
          optimization_config=exp.optimization_config,
          transforms=Cont_X_trans + Y_trans,
          torch_device=torch.device("cuda" if cuda else "cpu"),
          experiment=exp,
          data=data,
          # [T143911996] The trials get ignored without fit_out_of_design.
          fit_out_of_design=True,
      )
      self.assertIn("Cast", modelbridge.transforms)
      with patch.object(
          modelbridge,
          "_untransform_objective_thresholds",
          wraps=modelbridge._untransform_objective_thresholds,
      ) as mock_untransform, patch.object(
          modelbridge.transforms["Cast"],
          "untransform_observation_features",
          wraps=modelbridge.transforms[
              "Cast"
          ].untransform_observation_features,
      ) as wrapped_cast:
          obj_thresholds = modelbridge.infer_objective_thresholds(
              search_space=hss,
              optimization_config=exp.optimization_config,
              fixed_features=None,
          )
      mock_untransform.assert_called_once()
      self.assertEqual(wrapped_cast.call_count, 0)
      self.assertEqual(obj_thresholds[0].metric.name, "branin_a")
      self.assertEqual(obj_thresholds[1].metric.name, "branin_b")
      self.assertEqual(obj_thresholds[0].op, ComparisonOp.LEQ)
      self.assertEqual(obj_thresholds[1].op, ComparisonOp.LEQ)
      self.assertFalse(obj_thresholds[0].relative)
      self.assertFalse(obj_thresholds[1].relative)
  
      # test with MBM
      exp = get_branin_experiment_with_multi_objective(
          has_optimization_config=True,
          with_batch=True,
          with_status_quo=True,
      )
      for trial in exp.trials.values():
          trial.mark_running(no_runner_required=True).mark_completed()
      exp.attach_data(
          get_branin_data_multi_objective(
              trial_indices=exp.trials.keys()
          )
      )
      data = exp.fetch_data()
      modelbridge = TorchModelBridge(
          search_space=exp.search_space,
          model=BoTorchModel(),
          optimization_config=exp.optimization_config,
          transforms=Cont_X_trans + Y_trans,
          torch_device=torch.device("cuda" if cuda else "cpu"),
          experiment=exp,
          data=data,
          # [T143911996] The trials get ignored without fit_out_of_design.
          fit_out_of_design=True,
      )
      obj_thresholds = modelbridge.infer_objective_thresholds(
          search_space=exp.search_space,
          optimization_config=exp.optimization_config,
          fixed_features=None,
      )
      self.assertEqual(obj_thresholds[0].metric.name, "branin_a")
      self.assertEqual(obj_thresholds[1].metric.name, "branin_b")
      self.assertEqual(obj_thresholds[0].op, ComparisonOp.LEQ)
      self.assertEqual(obj_thresholds[1].op, ComparisonOp.LEQ)
      self.assertFalse(obj_thresholds[0].relative)
      self.assertFalse(obj_thresholds[1].relative)
  
imports: from contextlib import ExitStack
  from typing import List, Optional
  from unittest.mock import patch
  import numpy
  import torch
  from ax.core.metric import Metric
  from ax.core.observation import ObservationData, ObservationFeatures
  from ax.core.optimization_config import MultiObjectiveOptimizationConfig
  from ax.core.outcome_constraint import ComparisonOp, ObjectiveThreshold, OutcomeConstraint
  from ax.core.parameter_constraint import ParameterConstraint
  from ax.exceptions.core import UnsupportedError
  from ax.modelbridge.factory import get_sobol
  from ax.modelbridge.modelbridge_utils import get_pareto_frontier_and_configs, observed_hypervolume, observed_pareto_frontier, pareto_frontier, predicted_hypervolume, predicted_pareto_frontier
  from ax.modelbridge.registry import Cont_X_trans, ST_MTGP_trans, Y_trans
  from ax.modelbridge.torch import TorchModelBridge
  from ax.models.torch.botorch_modular.model import BoTorchModel
  from ax.models.torch.botorch_moo import MultiObjectiveBotorchModel
  from ax.models.torch.botorch_moo_defaults import infer_objective_thresholds, pareto_frontier_evaluator
  from ax.service.utils.report_utils import exp_to_df
  from ax.utils.common.testutils import TestCase
  from ax.utils.common.typeutils import checked_cast, not_none
  from ax.utils.testing.core_stubs import get_branin_data_multi_objective, get_branin_experiment_with_multi_objective, get_hierarchical_search_space, get_hss_trials_with_fixed_parameter, get_non_monolithic_branin_moo_data, TEST_SOBOL_SEED
  from ax.utils.testing.mock import fast_botorch_optimize
  from ax.utils.testing.modeling_stubs import transform_1, transform_2
  from botorch.utils.multi_objective.pareto import is_non_dominated
label_desc: Use image node_id 6 for calling the MultiObjectiveTorchModelBridgeTest obj's underlying member method code with example usage: obj.test_infer_objective_thresholds(_, cuda) without return types