class_docstr: Standardize Y, separately for each metric.
  
  Transform is done in-place.
class_docstr_tok: ["Standardize","Y",",","separately","for","each","metric",".","Transform","is","done","in-place","."]
code: def transform_optimization_config(
      self,
      optimization_config: OptimizationConfig,
      modelbridge: Optional["base_modelbridge.ModelBridge"] = None,
      fixed_features: Optional[ObservationFeatures] = None,
  ) -> OptimizationConfig:
      for c in optimization_config.all_constraints:
          if c.relative:
              raise ValueError(
                  f"StandardizeY transform does not support relative constraint {c}"
              )
          # For required data checks, metrics must be available in Ymean and Ystd.
          available_metrics = set(self.Ymean).intersection(
              set(self.Ystd)
          )
          if isinstance(c, ScalarizedOutcomeConstraint):
              # check metrics are present.
              constraint_metrics = {metric.name for metric in c.metrics}
              if len(constraint_metrics - available_metrics) > 0:
                  raise DataRequiredError(
                      "`StandardizeY` transform requires constraint metric(s) "
                      f"{constraint_metrics} but received only {available_metrics}."
                  )
  
              # transform \sum (wi * yi) <= C to
              # \sum (wi * si * zi) <= C - \sum (wi * mu_i) that zi = (yi - mu_i) / si
  
              # update bound C to new c = C.bound - sum_i (wi * mu_i)
              agg_mean = np.sum(
                  [
                      c.weights[i] * self.Ymean[metric.name]
                      for i, metric in enumerate(c.metrics)
                  ]
              )
              c.bound = float(c.bound - agg_mean)
  
              # update the weights in the scalarized constraint
              # new wi = wi * si
              new_weight = [
                  c.weights[i] * self.Ystd[metric.name]
                  for i, metric in enumerate(c.metrics)
              ]
              c.weights = new_weight
          else:
              if c.metric.name not in available_metrics:
                  raise DataRequiredError(
                      "`StandardizeY` transform requires constraint metric(s) "
                      f"{c.metric.name} but got {available_metrics}"
                  )
              c.bound = float(
                  (c.bound - self.Ymean[c.metric.name])
                  / self.Ystd[c.metric.name]
              )
      return optimization_config
  
imports: from logging import Logger
  from typing import DefaultDict, Dict, List, Optional, Tuple, TYPE_CHECKING, Union
  import numpy
  from ax.core.observation import Observation, ObservationData, ObservationFeatures
  from ax.core.optimization_config import OptimizationConfig
  from ax.core.outcome_constraint import OutcomeConstraint, ScalarizedOutcomeConstraint
  from ax.core.search_space import SearchSpace
  from ax.core.types import TParamValue
  from ax.exceptions.core import DataRequiredError
  from ax.modelbridge.transforms.base import Transform
  from ax.modelbridge.transforms.utils import get_data
  from ax.models.types import TConfig
  from ax.utils.common.logger import get_logger
label_desc: Use image node_id 3 for calling the StandardizeY obj's underlying member method code with example usage: obj.transform_optimization_config(optimization_config, modelbridge, fixed_features) and returns: optimization_config