code: def test_silverkite_template_custom(model_components_param):
      """ "Tests simple_silverkite_template with custom parameters,
      and data that has regressors"""
      data = generate_df_with_reg_for_tests(
          freq="H",
          periods=300 * 24,
          remove_extra_cols=True,
          mask_test_actuals=True,
      )
      df = data["df"]
      time_col = "some_time_col"
      value_col = "some_value_col"
      df.rename(
          {TIME_COL: time_col, VALUE_COL: value_col},
          axis=1,
          inplace=True,
      )
  
      metric = EvaluationMetricEnum.MeanAbsoluteError
      # anomaly adjustment adds 10.0 to every record
      adjustment_size = 10.0
      anomaly_df = pd.DataFrame(
          {
              START_TIME_COL: [df[time_col].min()],
              END_TIME_COL: [df[time_col].max()],
              ADJUSTMENT_DELTA_COL: [adjustment_size],
              METRIC_COL: [value_col],
          }
      )
      anomaly_info = {
          "value_col": VALUE_COL,
          "anomaly_df": anomaly_df,
          "start_time_col": START_TIME_COL,
          "end_time_col": END_TIME_COL,
          "adjustment_delta_col": ADJUSTMENT_DELTA_COL,
          "filter_by_dict": {METRIC_COL: VALUE_COL},
          "adjustment_method": "add",
      }
      metadata = MetadataParam(
          time_col=time_col,
          value_col=value_col,
          freq="H",
          date_format="%Y-%m-%d-%H",
          train_end_date=datetime.datetime(2019, 7, 1),
          anomaly_info=anomaly_info,
      )
      evaluation_metric = EvaluationMetricParam(
          cv_selection_metric=metric.name,
          cv_report_metrics=[
              EvaluationMetricEnum.MedianAbsolutePercentError.name
          ],
          agg_periods=24,
          agg_func=np.max,
          null_model_params={
              "strategy": "quantile",
              "constant": None,
              "quantile": 0.8,
          },
          relative_error_tolerance=0.01,
      )
      evaluation_period = EvaluationPeriodParam(
          test_horizon=1,
          periods_between_train_test=2,
          cv_horizon=3,
          cv_min_train_periods=4,
          cv_expanding_window=True,
          cv_use_most_recent_splits=True,
          cv_periods_between_splits=5,
          cv_periods_between_train_test=6,
          cv_max_splits=7,
      )
      computation = ComputationParam(
          hyperparameter_budget=10, n_jobs=None, verbose=1
      )
      forecast_horizon = 20
      coverage = 0.7
      template = SilverkiteTemplate()
      params = template.apply_template_for_pipeline_params(
          df=df,
          config=ForecastConfig(
              model_template=ModelTemplateEnum.SK.name,
              metadata_param=metadata,
              forecast_horizon=forecast_horizon,
              coverage=coverage,
              evaluation_metric_param=evaluation_metric,
              evaluation_period_param=evaluation_period,
              model_components_param=model_components_param,
              computation_param=computation,
          ),
      )
      pipeline = params.pop("pipeline", None)
      expected_params = dict(
          df=df,
          time_col=time_col,
          value_col=value_col,
          date_format=metadata.date_format,
          freq=metadata.freq,
          train_end_date=metadata.train_end_date,
          anomaly_info=metadata.anomaly_info,
          # model
          regressor_cols=template.regressor_cols,
          lagged_regressor_cols=template.lagged_regressor_cols,
          estimator=None,
          hyperparameter_grid=template.hyperparameter_grid,
          hyperparameter_budget=computation.hyperparameter_budget,
          n_jobs=computation.n_jobs,
          verbose=computation.verbose,
          # forecast
          forecast_horizon=forecast_horizon,
          coverage=coverage,
          test_horizon=evaluation_period.test_horizon,
          periods_between_train_test=evaluation_period.periods_between_train_test,
          agg_periods=evaluation_metric.agg_periods,
          agg_func=evaluation_metric.agg_func,
          relative_error_tolerance=evaluation_metric.relative_error_tolerance,
          # evaluation
          score_func=metric.name,
          score_func_greater_is_better=metric.get_metric_greater_is_better(),
          cv_report_metrics=evaluation_metric.cv_report_metrics,
          null_model_params=evaluation_metric.null_model_params,
          # CV
          cv_horizon=evaluation_period.cv_horizon,
          cv_min_train_periods=evaluation_period.cv_min_train_periods,
          cv_expanding_window=evaluation_period.cv_expanding_window,
          cv_use_most_recent_splits=evaluation_period.cv_use_most_recent_splits,
          cv_periods_between_splits=evaluation_period.cv_periods_between_splits,
          cv_periods_between_train_test=evaluation_period.cv_periods_between_train_test,
          cv_max_splits=evaluation_period.cv_max_splits,
      )
      assert_basic_pipeline_equal(pipeline, template.pipeline)
      assert_equal(params, expected_params)
  
imports: import dataclasses
  import datetime
  import warnings
  import numpy
  import pandas
  import pytest
  from greykite.algo.forecast.silverkite.forecast_silverkite import SilverkiteForecast
  from greykite.algo.forecast.silverkite.forecast_simple_silverkite_helper import generate_holiday_events
  from greykite.algo.forecast.silverkite.forecast_simple_silverkite_helper import get_event_pred_cols
  from greykite.common.constants import ADJUSTMENT_DELTA_COL
  from greykite.common.constants import END_TIME_COL
  from greykite.common.constants import METRIC_COL
  from greykite.common.constants import PREDICTION_BAND_COVERAGE
  from greykite.common.constants import START_TIME_COL
  from greykite.common.constants import TIME_COL
  from greykite.common.constants import VALUE_COL
  from greykite.common.evaluation import EvaluationMetricEnum
  from greykite.common.python_utils import assert_equal
  from greykite.common.testing_utils import generate_df_for_tests
  from greykite.common.testing_utils import generate_df_with_reg_for_tests
  from greykite.framework.constants import COMPUTATION_N_JOBS
  from greykite.framework.constants import CV_REPORT_METRICS_ALL
  from greykite.framework.templates.autogen.forecast_config import ComputationParam
  from greykite.framework.templates.autogen.forecast_config import EvaluationMetricParam
  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.templates.silverkite_template import SilverkiteTemplate
  from greykite.framework.templates.silverkite_template import apply_default_model_components
  from greykite.framework.templates.silverkite_template import get_extra_pred_cols
  from greykite.framework.utils.framework_testing_utils import assert_basic_pipeline_equal
  from greykite.framework.utils.framework_testing_utils import check_forecast_pipeline_result
  from greykite.sklearn.estimator.silverkite_estimator import SilverkiteEstimator
label_desc: Use image node_id 11 for calling a global function with example usage: test_silverkite_template_custom(model_components_param) without return types