class_docstr: A linear scalarization of (partial) learning curves of ML model training jobs:
  
      scalarized_curve = offset + sum_i(coefficients[i] * curve[i]).
  
  It is assumed that the output of `get_curves_from_ids` contains all of the curves
  necessary for performing the scalarization.
docstr: Construct a AbstractScalarizedCurveMetric.
  
  Args:
      name: Name of metric.
      coefficients: A mapping from learning curve names to their
          scalarization coefficients.
      offset: The offset of the affine scalarization.
      lower_is_better: If True, lower values (of the scalarized metric) are
          considered better.
      cumulative_best: If True, for each trial, apply cumulative best to
          the curve (i.e., if lower is better, then we return a curve
          representing the cumulative min of the raw curve).
      smoothing_window: If not None, specifies the window size used for a
          rolling mean applied to the raw curve data. This can be helpful
          if the underlying data is expected to be very noisy.
code: def __init__(
      self,
      name: str,
      coefficients: Dict[str, float],
      offset: float = 0.0,
      lower_is_better: bool = True,
      cumulative_best: bool = False,
      smoothing_window: Optional[int] = None,
  ) -> None:
      """Construct a AbstractScalarizedCurveMetric.
  
      Args:
          name: Name of metric.
          coefficients: A mapping from learning curve names to their
              scalarization coefficients.
          offset: The offset of the affine scalarization.
          lower_is_better: If True, lower values (of the scalarized metric) are
              considered better.
          cumulative_best: If True, for each trial, apply cumulative best to
              the curve (i.e., if lower is better, then we return a curve
              representing the cumulative min of the raw curve).
          smoothing_window: If not None, specifies the window size used for a
              rolling mean applied to the raw curve data. This can be helpful
              if the underlying data is expected to be very noisy.
      """
      MapMetric.__init__(
          self, name=name, lower_is_better=lower_is_better
      )
      self.coefficients = coefficients
      self.offset = offset
      self.cumulative_best = cumulative_best
      self.smoothing_window = smoothing_window
  
imports: from __future__ import annotations
  from abc import ABC, abstractmethod
  from logging import Logger
  from typing import Any, Dict, Iterable, Optional, Set, Union
  import numpy
  import pandas
  from ax.core.base_trial import BaseTrial
  from ax.core.batch_trial import BatchTrial
  from ax.core.experiment import Experiment
  from ax.core.map_data import MapData, MapKeyInfo
  from ax.core.map_metric import MapMetric
  from ax.core.metric import Metric, MetricFetchE, MetricFetchResult
  from ax.core.trial import Trial
  from ax.early_stopping.utils import align_partial_results
  from ax.exceptions.core import UnsupportedError
  from ax.utils.common.logger import get_logger
  from ax.utils.common.result import Err, Ok
  from ax.utils.common.typeutils import checked_cast
label_desc: Use image node_id 1 to create a new AbstractScalarizedCurveMetric object from inherited base classes: AbstractCurveMetric with example: obj = AbstractScalarizedCurveMetric(name, coefficients, offset, lower_is_better, cumulative_best, smoothing_window)