code: def test_silverkite_forecast_result():
      """Tests pickling and unpickling of Silverkite ForecastResult."""
      df = generate_df_for_tests(freq="D", periods=365)["df"]
      forecaster = Forecaster()
      # Run the forecast
      result = forecaster.run_forecast_config(
          df=df,  # includes the regressor
          config=ForecastConfig(
              model_template=ModelTemplateEnum.SILVERKITE.name,
              forecast_horizon=7,
              coverage=0.8,
              metadata_param=MetadataParam(
                  time_col="ts", value_col="y", freq="D"
              ),
              evaluation_period_param=EvaluationPeriodParam(
                  cv_max_splits=1,
                  cv_horizon=7,
                  test_horizon=7,
                  cv_min_train_periods=80,
              ),
              model_components_param=ModelComponentsParam(
                  custom={
                      "fit_algorithm_dict": {"fit_algorithm": "linear"}
                  },
                  autoregression={"autoreg_dict": "auto"},
              ),
              computation_param=ComputationParam(n_jobs=-1),
          ),
      )
      pickler = GreykitePickler()
      serialized = pickler.dumps(result)
      deserialized = pickler.loads(serialized)
  
      # Tests loaded results.
      # Grid search cv results.
      assert_equal(
          summarize_grid_search_results(result.grid_search),
          summarize_grid_search_results(deserialized.grid_search),
      )
      # Grid search attributes.
      for key in result.grid_search.__dict__.keys():
          if key not in [
              "scoring",
              "estimator",
              "refit",
              "cv",
              "error_score",
              "cv_results_",
              "scorer_",
              "best_estimator_",
          ]:
              assert_equal(
                  result.grid_search.__dict__[key],
                  deserialized.grid_search.__dict__[key],
              )
  
      # Model.
      assert_equal(
          result.model[-1].predict(df),
          deserialized.model[-1].predict(df),
      )
      assert result.model[-1].model_dict["x_design_info"] is not None
      # Model: estimator.
      for key in result.model[-1].__dict__.keys():
          if key not in [
              "score_func",
              "silverkite",
              "silverkite_diagnostics",
              "model_dict",
          ]:
              assert_equal(
                  result.model[-1].__dict__[key],
                  deserialized.model[-1].__dict__[key],
              )
      assert_equal(
          inspect.getsource(result.model[-1].__dict__["score_func"]),
          inspect.getsource(
              deserialized.model[-1].__dict__["score_func"]
          ),
      )
      # Model: estimator/model_dict.
      for key in result.model[-1].model_dict.keys():
          # Functions and classes are not testable.
          if key not in [
              "x_design_info",
              "fs_func",
              "ml_model",
              "plt_pred",
              "autoreg_dict",
              "changepoint_detector",
              "autoreg_func",
              "normalize_df_func",
          ]:
              assert_equal(
                  result.model[-1].model_dict[key],
                  deserialized.model[-1].model_dict[key],
              )
          # Tests function source code.
          elif key in [
              "fs_func",
              "plt_pred",
              "autoreg_func",
              "normalize_df_func",
          ]:
              assert_equal(
                  inspect.getsource(result.model[-1].model_dict[key]),
                  inspect.getsource(
                      deserialized.model[-1].model_dict[key]
                  ),
              )
      # Model: estimator/model_dict/autoreg_dict.
      for key in result.model[-1].model_dict["autoreg_dict"].keys():
          if key not in ["series_na_fill_func"]:
              assert_equal(
                  result.model[-1].model_dict["autoreg_dict"][key],
                  deserialized.model[-1].model_dict["autoreg_dict"][
                      key
                  ],
              )
      assert_equal(
          inspect.getsource(
              result.model[-1].model_dict["autoreg_dict"][
                  "series_na_fill_func"
              ]
          ),
          inspect.getsource(
              deserialized.model[-1].model_dict["autoreg_dict"][
                  "series_na_fill_func"
              ]
          ),
      )
  
      # Forecast.
      assert_equal(
          result.forecast.estimator.predict(df),
          deserialized.forecast.estimator.predict(df),
      )
      assert (
          result.forecast.estimator.model_dict["x_design_info"]
          is not None
      )
      # Forecast: attributes.
      for key in result.forecast.__dict__.keys():
          if key not in ["r2_loss_function", "estimator"]:
              assert_equal(
                  result.forecast.__dict__[key],
                  deserialized.forecast.__dict__[key],
              )
      assert_equal(
          inspect.getsource(
              result.forecast.__dict__["r2_loss_function"]
          ),
          inspect.getsource(
              deserialized.forecast.__dict__["r2_loss_function"]
          ),
      )
      # Forecast: estimator.
      for key in result.forecast.estimator.__dict__.keys():
          if key not in [
              "score_func",
              "silverkite",
              "silverkite_diagnostics",
              "model_dict",
          ]:
              assert_equal(
                  result.forecast.estimator.__dict__[key],
                  deserialized.forecast.estimator.__dict__[key],
              )
      assert_equal(
          inspect.getsource(
              result.forecast.estimator.__dict__["score_func"]
          ),
          inspect.getsource(
              deserialized.forecast.estimator.__dict__["score_func"]
          ),
      )
      # Model: estimator/model_dict
      for key in result.forecast.estimator.model_dict.keys():
          # Functions and classes are not testable.
          if key not in [
              "x_design_info",
              "fs_func",
              "ml_model",
              "plt_pred",
              "autoreg_dict",
              "changepoint_detector",
              "autoreg_func",
              "normalize_df_func",
          ]:
              assert_equal(
                  result.forecast.estimator.model_dict[key],
                  deserialized.forecast.estimator.model_dict[key],
              )
          # Tests function source code.
          elif key in [
              "fs_func",
              "plt_pred",
              "autoreg_func",
              "normalize_df_func",
          ]:
              assert_equal(
                  inspect.getsource(
                      result.forecast.estimator.model_dict[key]
                  ),
                  inspect.getsource(
                      deserialized.forecast.estimator.model_dict[key]
                  ),
              )
      # Model: estimator/model_dict/autoreg_dict.
      for key in result.forecast.estimator.model_dict[
          "autoreg_dict"
      ].keys():
          if key not in ["series_na_fill_func"]:
              assert_equal(
                  result.forecast.estimator.model_dict["autoreg_dict"][
                      key
                  ],
                  deserialized.forecast.estimator.model_dict[
                      "autoreg_dict"
                  ][key],
              )
      assert_equal(
          inspect.getsource(
              result.forecast.estimator.model_dict["autoreg_dict"][
                  "series_na_fill_func"
              ]
          ),
          inspect.getsource(
              deserialized.forecast.estimator.model_dict[
                  "autoreg_dict"
              ]["series_na_fill_func"]
          ),
      )
  
      # Backtest.
      assert_equal(
          result.backtest.estimator.predict(df),
          deserialized.backtest.estimator.predict(df),
      )
      assert (
          result.backtest.estimator.model_dict["x_design_info"]
          is not None
      )
      # Backtest: attributes.
      for key in result.backtest.__dict__.keys():
          if key not in ["r2_loss_function", "estimator"]:
              assert_equal(
                  result.backtest.__dict__[key],
                  deserialized.backtest.__dict__[key],
              )
      assert_equal(
          inspect.getsource(
              result.backtest.__dict__["r2_loss_function"]
          ),
          inspect.getsource(
              deserialized.backtest.__dict__["r2_loss_function"]
          ),
      )
      # Backtest: estimator.
      for key in result.backtest.estimator.__dict__.keys():
          if key not in [
              "score_func",
              "silverkite",
              "silverkite_diagnostics",
              "model_dict",
          ]:
              assert_equal(
                  result.backtest.estimator.__dict__[key],
                  deserialized.backtest.estimator.__dict__[key],
              )
      assert_equal(
          inspect.getsource(
              result.backtest.estimator.__dict__["score_func"]
          ),
          inspect.getsource(
              deserialized.backtest.estimator.__dict__["score_func"]
          ),
      )
      # Model: estimator/model_dict.
      for key in result.backtest.estimator.model_dict.keys():
          # Functions and classes are not testable.
          if key not in [
              "x_design_info",
              "fs_func",
              "ml_model",
              "plt_pred",
              "autoreg_dict",
              "changepoint_detector",
              "autoreg_func",
              "normalize_df_func",
          ]:
              assert_equal(
                  result.backtest.estimator.model_dict[key],
                  deserialized.backtest.estimator.model_dict[key],
              )
          # Tests function source code.
          elif key in [
              "fs_func",
              "plt_pred",
              "autoreg_func",
              "normalize_df_func",
          ]:
              assert_equal(
                  inspect.getsource(
                      result.backtest.estimator.model_dict[key]
                  ),
                  inspect.getsource(
                      deserialized.backtest.estimator.model_dict[key]
                  ),
              )
      # Model: estimator/model_dict/autoreg_dict.
      for key in result.backtest.estimator.model_dict[
          "autoreg_dict"
      ].keys():
          if key not in ["series_na_fill_func"]:
              assert_equal(
                  result.backtest.estimator.model_dict["autoreg_dict"][
                      key
                  ],
                  deserialized.backtest.estimator.model_dict[
                      "autoreg_dict"
                  ][key],
              )
      assert_equal(
          inspect.getsource(
              result.backtest.estimator.model_dict["autoreg_dict"][
                  "series_na_fill_func"
              ]
          ),
          inspect.getsource(
              deserialized.backtest.estimator.model_dict[
                  "autoreg_dict"
              ]["series_na_fill_func"]
          ),
      )
  
      # Timeseries.
      for key in result.timeseries.__dict__.keys():
          assert_equal(
              result.timeseries.__dict__[key],
              deserialized.timeseries.__dict__[key],
          )
  
      # Checks the size of the serialized object in megabytes.
      memory_size_mb = sys.getsizeof(serialized) * 1e-6
      assert memory_size_mb < 64.0
  
imports: import datetime
  import inspect
  import sys
  from collections import OrderedDict
  import dill
  import numpy
  import pandas
  import pytest
  from patsy.desc import Term
  from greykite.common.constants import ACTUAL_COL
  from greykite.common.constants import ANOMALY_COL
  from greykite.common.constants import PREDICTED_ANOMALY_COL
  from greykite.common.constants import PREDICTED_COL
  from greykite.common.constants import PREDICTED_LOWER_COL
  from greykite.common.constants import PREDICTED_UPPER_COL
  from greykite.common.constants import TIME_COL
  from greykite.common.constants import VALUE_COL
  from greykite.common.python_utils import assert_equal
  from greykite.common.testing_utils import generate_df_for_tests
  from greykite.common.testing_utils_anomalies import contaminate_df_with_anomalies
  from greykite.common.viz.timeseries_annotate import plot_anomalies_over_forecast_vs_actual
  from greykite.detection.common.ad_evaluation import f1_score
  from greykite.detection.common.ad_evaluation import precision_score
  from greykite.detection.common.ad_evaluation import recall_score
  from greykite.detection.common.pickler import GreykitePickler
  from greykite.detection.detector.ad_utils import partial_return
  from greykite.detection.detector.config import ADConfig
  from greykite.detection.detector.constants import FIG_SHOW
  from greykite.detection.detector.data import DetectorData
  from greykite.detection.detector.greykite import DETECTOR_PREDICT_COLS
  from greykite.detection.detector.greykite import GreykiteDetector
  from greykite.detection.detector.reward import Reward
  from greykite.framework.templates.autogen.forecast_config import ComputationParam
  from greykite.framework.templates.autogen.forecast_config import EvaluationPeriodParam
  from greykite.framework.templates.autogen.forecast_config import ForecastConfig
  from greykite.framework.templates.autogen.forecast_config import MetadataParam
  from greykite.framework.templates.autogen.forecast_config import ModelComponentsParam
  from greykite.framework.templates.forecaster import Forecaster
  from greykite.framework.templates.model_templates import ModelTemplateEnum
  from greykite.framework.utils.result_summary import summarize_grid_search_results
label_desc: Use image node_id 10 for calling a global function with example usage: test_silverkite_forecast_result() without return types