code: def get_df_from_curve_series(
      experiment: Experiment,
      all_curve_series: Dict[Union[int, str], Dict[str, pd.Series]],
      metrics: Iterable[Metric],
      trial_idx_to_id: Dict[int, Union[int, str]],
      map_key: str,
  ) -> Optional[pd.DataFrame]:
      """Convert a `all_curve_series` dict (from `get_curves_from_ids`) into
      a dataframe. For each metric, we get one curve (of name `curve_name`).
  
      Args:
          experiment: The experiment.
          all_curve_series: A dict containing curve data, as output from
              `get_curves_from_ids`.
          metrics: The metrics from which data is being fetched.
          trial_idx_to_id: A dict mapping trial index to ids.
  
      Returns:
          A dataframe containing curve data or None if no curve data could be found.
      """
      dfs = []
      for trial_idx, id_ in trial_idx_to_id.items():
          if id_ not in all_curve_series:
              logger.info(
                  f"Could not get curve data for id {id_}. Ignoring."
              )
              continue
          curve_series = all_curve_series[id_]
          for m in metrics:
              if m.curve_name in curve_series:  # pyre-ignore[16]
                  dfi = _get_single_curve(
                      curve_series=curve_series,
                      curve_name=m.curve_name,
                      metric_name=m.name,
                      map_key=map_key,
                      trial=experiment.trials[trial_idx],
                      cumulative_best=m.cumulative_best,  # pyre-ignore[16]
                      lower_is_better=m.lower_is_better,  # pyre-ignore[6]
                      smoothing_window=m.smoothing_window,  # pyre-ignore[16]
                  )
                  dfs.append(dfi)
              else:
                  logger.info(
                      f"{m.curve_name} not yet present in curves from {id_}. "
                      "Returning without this metric."
                  )
      if len(dfs) == 0:
          return None
      return pd.concat(dfs, axis=0, ignore_index=True)
  
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 for calling a global function with example usage: get_df_from_curve_series(experiment, all_curve_series, metrics, trial_idx_to_id, map_key) and returns: pd, None