code: def get_pending_observation_features(
      experiment: Experiment,
      *,
      include_out_of_design_points: bool = False,
  ) -> Optional[Dict[str, List[ObservationFeatures]]]:
      """Computes a list of pending observation features (corresponding to:
      - arms that have been generated and run in the course of the experiment,
      but have not been completed with data,
      - arms that have been abandoned or belong to abandoned trials).
  
      NOTE: Pending observation features are passed to the model to
      instruct it to not generate the same points again.
  
      Args:
          experiment: Experiment, pending features on which we seek to compute.
          include_out_of_design_points: By default, this function will not include
              "out of design" points (those that are not in the search space) among
              the pending points. This is because pending points are generally used to
              help the model avoid re-suggesting the same points again. For points
              outside of the search space, this will not happen, so they typically do
              not need to be included. However, if the user wants to include them,
              they can be included by setting this flag to ``True``.
  
      Returns:
          An optional mapping from metric names to a list of observation features,
          pending for that metric (i.e. do not have evaluation data for that metric).
          If there are no pending features for any of the metrics, return is None.
      """
  
      def _is_in_design(arm: Arm) -> bool:
          return experiment.search_space.check_membership(
              parameterization=arm.parameters
          )
  
      pending_features = {}
      # Note that this assumes that if a metric appears in fetched data, the trial is
      # not pending for the metric. Where only the most recent data matters, this will
      # work, but may need to add logic to check previously added data objects, too.
      for trial_index, trial in experiment.trials.items():
          dat = trial.lookup_data()
          for metric_name in experiment.metrics:
              if metric_name not in pending_features:
                  pending_features[metric_name] = []
  
              if trial.status.is_abandoned or (
                  trial.status.is_deployed
                  and metric_name not in dat.df.metric_name.values
                  and trial.arms is not None
              ):
                  for arm in trial.arms:
                      # Do not add out-of-design points unless requested.
                      if (
                          not include_out_of_design_points
                          and not _is_in_design(arm=arm)
                      ):
                          continue
                      pending_features[metric_name].append(
                          ObservationFeatures.from_arm(
                              arm=arm,
                              trial_index=trial_index,
                              metadata=trial._get_candidate_metadata(
                                  arm_name=arm.name
                              ),
                          )
                      )
  
              # Also add abandoned arms as pending for all metrics.
              if isinstance(trial, BatchTrial):
                  for arm in trial.abandoned_arms:
                      if (
                          not include_out_of_design_points
                          and not _is_in_design(arm=arm)
                      ):
                          continue
                      not_none(
                          pending_features.get(metric_name)
                      ).append(
                          ObservationFeatures.from_arm(
                              arm=arm,
                              trial_index=trial_index,
                              metadata=trial._get_candidate_metadata(
                                  arm_name=arm.name
                              ),
                          )
                      )
  
      return (
          pending_features
          if any(x for x in pending_features.values())
          else None
      )
  
imports: from collections import defaultdict
  from typing import Dict, Iterable, List, NamedTuple, Optional, Set, Tuple
  import numpy
  from ax.core.arm import Arm
  from ax.core.base_trial import BaseTrial, TrialStatus
  from ax.core.batch_trial import BatchTrial
  from ax.core.data import Data
  from ax.core.experiment import Experiment
  from ax.core.generator_run import GeneratorRun
  from ax.core.objective import MultiObjective
  from ax.core.observation import ObservationFeatures
  from ax.core.optimization_config import OptimizationConfig
  from ax.core.trial import Trial
  from ax.core.types import ComparisonOp
  from ax.utils.common.typeutils import not_none
  from pyre_extensions import none_throws
label_desc: Use image node_id 9 for calling a global function with example usage: get_pending_observation_features(experiment) and returns: unknown, experiment