code: def get_forecast(
      df,
      trained_model: Pipeline,
      train_end_date=None,
      test_start_date=None,
      forecast_horizon=None,
      xlabel=cst.TIME_COL,
      ylabel=cst.VALUE_COL,
      relative_error_tolerance=None,
  ) -> UnivariateForecast:
      """Runs model predictions on ``df`` and creates a
      `~greykite.framework.output.univariate_forecast.UnivariateForecast` object.
  
      Parameters
      ----------
      df: `pandas.DataFrame`
          Has columns cst.TIME_COL, cst.VALUE_COL, to forecast.
      trained_model: `sklearn.pipeline`
          A fitted Pipeline with ``estimator`` step and predict function.
      train_end_date: `datetime.datetime`, default `None`
          Train end date. Passed to
          `~greykite.framework.output.univariate_forecast.UnivariateForecast`.
      test_start_date: `datetime.datetime`, default `None`
          Test start date. Passed to
          `~greykite.framework.output.univariate_forecast.UnivariateForecast`.
      forecast_horizon : `int` or None, default None
          Number of periods forecasted into the future. Must be > 0. Passed to
          `~greykite.framework.output.univariate_forecast.UnivariateForecast`.
      xlabel: `str`
          Time column to use in representing forecast (e.g. x-axis in plots).
      ylabel: `str`
          Time column to use in representing forecast (e.g. y-axis in plots).
      relative_error_tolerance : `float` or None, default None
          Threshold to compute the ``Outside Tolerance`` metric,
          defined as the fraction of forecasted values whose relative
          error is strictly greater than ``relative_error_tolerance``.
          For example, 0.05 allows for 5% relative error.
          If `None`, the metric is not computed.
  
      Returns
      -------
      univariate_forecast : `~greykite.framework.output.univariate_forecast.UnivariateForecast`
          Forecasts represented as a ``UnivariateForecast`` object.
      """
      predicted_df = trained_model.predict(df)
      # This is more robust than using trained_model.named_steps["estimator"] e.g.
      # if the user calls forecast_pipeline with a custom pipeline, where the last
      # step isn't named "estimator".
      trained_estimator = trained_model.steps[-1][-1]
      coverage = trained_estimator.coverage
  
      # combines actual with predictions
      union_df = pd.DataFrame(
          {
              cst.TIME_COL: df[cst.TIME_COL].values,
              # .values here, since df and predicted_df have different indexes
              cst.ACTUAL_COL: df[cst.VALUE_COL].values,
              # evaluation and plots are done on the values *before* any transformations
              cst.PREDICTED_COL: predicted_df[cst.PREDICTED_COL].values,
          }
      )
  
      predicted_lower_col = None
      predicted_upper_col = None
      null_model_predicted_col = None
  
      # adds lower bound if available
      if cst.PREDICTED_LOWER_COL in predicted_df.columns:
          predicted_lower_col = cst.PREDICTED_LOWER_COL
          union_df[cst.PREDICTED_LOWER_COL] = predicted_df[
              cst.PREDICTED_LOWER_COL
          ].values
          if coverage is None:
              raise Exception("coverage must be provided")
  
      # adds upper bound if available
      if cst.PREDICTED_UPPER_COL in predicted_df.columns:
          predicted_upper_col = cst.PREDICTED_UPPER_COL
          union_df[cst.PREDICTED_UPPER_COL] = predicted_df[
              cst.PREDICTED_UPPER_COL
          ].values
          if coverage is None:
              raise Exception("coverage must be provided")
  
      # adds null prediction if available
      if trained_estimator.null_model is not None:
          null_model_predicted_col = cst.NULL_PREDICTED_COL
          null_predicted_df = trained_estimator.null_model.predict(df)
          union_df[cst.NULL_PREDICTED_COL] = null_predicted_df[
              cst.PREDICTED_COL
          ].values
  
      return UnivariateForecast(
          union_df,
          time_col=cst.TIME_COL,
          actual_col=cst.ACTUAL_COL,
          predicted_col=cst.PREDICTED_COL,
          predicted_lower_col=predicted_lower_col,
          predicted_upper_col=predicted_upper_col,
          null_model_predicted_col=null_model_predicted_col,
          ylabel=ylabel,
          train_end_date=train_end_date,
          test_start_date=test_start_date,
          forecast_horizon=forecast_horizon,
          coverage=coverage,
          r2_loss_function=trained_estimator.score_func,  # this score_func includes preaggregation if requested
          estimator=trained_estimator,
          relative_error_tolerance=relative_error_tolerance,
      )
  
imports: import math
  from functools import partial
  import pandas
  from sklearn.base import clone
  from sklearn.model_selection import ParameterGrid
  from sklearn.model_selection import RandomizedSearchCV
  from sklearn.pipeline import Pipeline
  from greykite.common import constants
  from greykite.common.constants import FRACTION_OUTSIDE_TOLERANCE
  from greykite.common.constants import TIME_COL
  from greykite.common.constants import VALUE_COL
  from greykite.common.evaluation import EvaluationMetricEnum
  from greykite.common.evaluation import add_finite_filter_to_scorer
  from greykite.common.evaluation import add_preaggregation_to_scorer
  from greykite.common.evaluation import fraction_outside_tolerance
  from greykite.common.logging import LoggingLevelEnum
  from greykite.common.logging import log_message
  from greykite.common.python_utils import get_integer
  from greykite.common.python_utils import unique_elements_in_list
  from greykite.common.time_properties_forecast import get_default_horizon_from_period
  from greykite.framework.constants import CUSTOM_SCORE_FUNC_NAME
  from greykite.framework.constants import CV_REPORT_METRICS_ALL
  from greykite.framework.constants import FRACTION_OUTSIDE_TOLERANCE_NAME
  from greykite.framework.output.univariate_forecast import UnivariateForecast
  from greykite.sklearn.estimator.simple_silverkite_estimator import SimpleSilverkiteEstimator
  from greykite.sklearn.sklearn_scorer import make_scorer_df
  from greykite.sklearn.transform.column_selector import ColumnSelector
  from greykite.sklearn.transform.difference_based_outlier_transformer import DifferenceBasedOutlierTransformer
  from greykite.sklearn.transform.drop_degenerate_transformer import DropDegenerateTransformer
  from greykite.sklearn.transform.dtype_column_selector import DtypeColumnSelector
  from greykite.sklearn.transform.normalize_transformer import NormalizeTransformer
  from greykite.sklearn.transform.null_transformer import NullTransformer
  from greykite.sklearn.transform.pandas_feature_union import PandasFeatureUnion
label_desc: Use image node_id 7 for calling a global function with example usage: get_forecast(df, trained_model, train_end_date, test_start_date, forecast_horizon, xlabel, ylabel, relative_error_tolerance) and returns: UnivariateForecast