class_docstr: Transform the values to look as normally distributed as possible.
  
  This fits a power transform to the data with the goal of making the transformed
  values look as normally distributed as possible. We use Yeo-Johnson
  (https://www.stat.umn.edu/arc/yjpower.pdf), which can handle both positive and
  negative values.
  
  While the transform seems to be quite robust, it probably makes sense to apply a
  bit of winsorization and also standardize the inputs before applying the power
  transform. The power transform will automatically standardize the data so the
  data will remain standardized.
  
  The transform can't be inverted for all values, so we apply clipping to move
  values to the image of the transform. This behavior can be controlled via the
  `clip_mean` setting.
class_docstr_tok: ["Transform","the","values","to","look","as","normally","distributed","as","possible",".","This","fits","a","power","transform","to","the","data","with","the","goal","of","making","the","transformed","values","look","as","normally","distributed","as","possible",".","We","use","Yeo-Johnson","(","https",":","\/\/www.stat.umn.edu\/arc\/yjpower.pdf",")",",","which","can","handle","both","positive","and","negative","values",".","While","the","transform","seems","to","be","quite","robust",",","it","probably","makes","sense","to","apply","a","bit","of","winsorization","and","also","standardize","the","inputs","before","applying","the","power","transform",".","The","power","transform","will","automatically","standardize","the","data","so","the","data","will","remain","standardized",".","The","transform","ca","n't","be","inverted","for","all","values",",","so","we","apply","clipping","to","move","values","to","the","image","of","the","transform",".","This","behavior","can","be","controlled","via","the","`","clip_mean","`","setting","."]
code: def untransform_outcome_constraints(
      self,
      outcome_constraints: List[OutcomeConstraint],
      fixed_features: Optional[ObservationFeatures] = None,
  ) -> List[OutcomeConstraint]:
      for c in outcome_constraints:
          if isinstance(c, ScalarizedOutcomeConstraint):
              raise ValueError(
                  "ScalarizedOutcomeConstraint not supported here"
              )
          elif c.metric.name in self.metric_names:
              if c.relative:
                  raise ValueError(
                      "Relative constraints not supported here."
                  )
              else:
                  transform = self.power_transforms[
                      c.metric.name
                  ].inverse_transform
                  c.bound = transform(np.array(c.bound, ndmin=2)).item()
      return outcome_constraints
  
imports: from __future__ import annotations
  from collections import defaultdict
  from logging import Logger
  from typing import Dict, List, Optional, Tuple, TYPE_CHECKING
  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.modelbridge.transforms.base import Transform
  from ax.modelbridge.transforms.utils import get_data, match_ci_width_truncated
  from ax.models.types import TConfig
  from ax.utils.common.logger import get_logger
  from ax.utils.common.typeutils import checked_cast_list
  from sklearn.preprocessing import PowerTransformer
label_desc: Use image node_id 5 for calling the PowerTransformY obj's underlying member method code with example usage: obj.untransform_outcome_constraints(outcome_constraints, fixed_features) and returns: outcome_constraints