class_docstr: Clip the mean values for each metric to lay within the limits provided in
  the config. The config can contain either or both of two keys:
  - ``"winsorization_config"``, corresponding to either a single
      ``WinsorizationConfig``, which, if provided will be used for all metrics; or
      a mapping ``Dict[str, WinsorizationConfig]`` between each metric name and its
      ``WinsorizationConfig``.
  - ``"derelativize_with_raw_status_quo"``, indicating whether to use the raw
      status-quo value for any derelativization. Note this defaults to ``False``,
      which is unsupported and simply fails if derelativization is necessary. The
      user must specify ``derelativize_with_raw_status_quo = True`` in order for
      derelativization to succeed. Note that this must match the `use_raw_status_quo`
      value in the ``Derelativize`` config if used.
  For example,
  ``{"winsorization_config": WinsorizationConfig(lower_quantile_margin=0.3)}``
  will specify the same 30% winsorization from below for all metrics, whereas
  ```
  {
      "winsorization_config":
      {
          "metric_1": WinsorizationConfig(lower_quantile_margin=0.2),
          "metric_2": WinsorizationConfig(upper_quantile_margin=0.1),
      }
  }
  ```
  will winsorize 20% from below for metric_1 and 10% from above from metric_2.
  Additional metrics won't be winsorized.
  
  You can also determine the winsorization cutoffs automatically without having an
  ``OptimizationConfig`` by passing in AUTO_WINS_QUANTILE for the quantile you want
  to winsorize. For example, to automatically winsorize large values:
      ``"m1": WinsorizationConfig(upper_quantile_margin=AUTO_WINS_QUANTILE)``.
  This may be useful when fitting models in a notebook where there is no corresponding
  ``OptimizationConfig``.
  
  Additionally, you can pass in winsorization boundaries ``lower_boundary`` and
  ``upper_boundary``that specify a maximum allowable amount of winsorization. This
  is discouraged and will eventually be deprecated as we strongly encourage
  that users allow ``Winsorize`` to automatically infer these boundaries from
  the optimization config.
docstr: Winsorize observation data in place.
docstr_tok: ["Winsorize","observation","data","in","place","."]
code: def _transform_observation_data(
      self,
      observation_data: List[ObservationData],
  ) -> List[ObservationData]:
      """Winsorize observation data in place."""
      for obsd in observation_data:
          for idx, metric_name in enumerate(obsd.metric_names):
              if metric_name not in self.cutoffs:
                  raise ValueError(
                      f"Cannot winsorize unknown metric {metric_name}"
                  )
              # Clip on the winsorization bounds.
              obsd.means[idx] = max(
                  obsd.means[idx], self.cutoffs[metric_name][0]
              )
              obsd.means[idx] = min(
                  obsd.means[idx], self.cutoffs[metric_name][1]
              )
      return observation_data
  
imports: import warnings
  from logging import Logger
  from typing import Dict, List, Optional, Tuple, TYPE_CHECKING, Union
  import numpy
  from ax.core.objective import MultiObjective, ScalarizedObjective
  from ax.core.observation import Observation, ObservationData
  from ax.core.optimization_config import MultiObjectiveOptimizationConfig, OptimizationConfig
  from ax.core.outcome_constraint import ComparisonOp, ObjectiveThreshold, OutcomeConstraint, ScalarizedOutcomeConstraint
  from ax.core.search_space import SearchSpace
  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, get_data
  from ax.models.types import TConfig, WinsorizationConfig
  from ax.utils.common.logger import get_logger
  from ax.utils.common.typeutils import checked_cast
label_desc: Use image node_id 2 for calling the Winsorize obj's underlying member method code with example usage: obj._transform_observation_data(observation_data) and returns: observation_data