code: def test_greykite_detector_daily_outlier(
      daily_data, forecast_config_info_daily
  ):
      """Tests ``GreykiteDetector`` with data injected with large outlier.
      It is worth noting the optimal params and test values have not changed
      dramatically compared to the case without the injected outlier in this test:
      `test_greykite_detector_detector_daily_f1`.
      """
      df_train = daily_data["df_train"].copy()
      df_test = daily_data["df_test"]
      df = daily_data["df"]
      # Creates a very large outlier.
      df_train.loc[1, "y"] = 10 * max(abs(df["y"]))
      fig = plot_lines_markers(
          df=df_train, x_col=TIME_COL, line_cols=["y"]
      )
      if FIG_SHOW:
          fig.show()
  
      forecast_config = forecast_config_info_daily
      ad_config = ADConfig(
          volatility_features_list=[["dow"], ["is_weekend"]],
          coverage_grid=[
              0.5,
              0.55,
              0.6,
              0.65,
              0.7,
              0.75,
              0.9,
              0.95,
              0.99,
              0.999,
          ],
          target_anomaly_percent=None,
          variance_scaling=True,
      )
  
      train_data = DetectorData(df=df_train)
  
      def reward_func(data):
          return calc_f1(y_true=data.y_true, y_pred=data.y_pred)
  
      reward = Reward(reward_func)
  
      detector = GreykiteDetector(
          forecast_config=forecast_config,
          ad_config=ad_config,
          reward=reward,
      )
  
      detector.fit(data=train_data)
      # Checks optimal parameter.
      assert detector.fit_info["param"] == {
          "coverage": 0.99,
          "volatility_features": ["is_weekend"],
      }
  
      # Checks parameter grid.
      param_obj_list = detector.fit_info["param_obj_list"]
      param_eval_df = pd.DataFrame.from_records(param_obj_list)
  
      assert list(param_eval_df.columns) == [
          "coverage",
          "volatility_features",
          "obj_value",
      ]
  
      param_eval_df["volatility_features"] = param_eval_df[
          "volatility_features"
      ].map(str)
      fig = px.line(
          param_eval_df,
          x="coverage",
          y="obj_value",
          color="volatility_features",
          title="'GreykiteDetector' result of parameter search: reward=f1, daily data",
      )
      assert fig is not None
      if FIG_SHOW:
          fig.show()
  
      test_data = DetectorData(df=df_test, y_true=df_test[ANOMALY_COL])
  
      test_data = detector.predict(test_data)
      test_obj_value = detector.reward.apply(test_data)
  
      test_recall = calc_recall(
          y_true=test_data.y_true, y_pred=test_data.y_pred
      )
  
      test_precision = calc_precision(
          y_true=test_data.y_true, y_pred=test_data.y_pred
      )
  
      fit_data = detector.fit_info["best_calc_result"].data
      fit_df = fit_data.pred_df
      pred_df = test_data.pred_df
      # Checks if we get the expected columns in the fit / prediction data.
      assert list(pred_df.columns) == DETECTOR_PREDICT_COLS + [
          ANOMALY_COL
      ]
      assert list(fit_df.columns) == DETECTOR_PREDICT_COLS + [
          ANOMALY_COL
      ]
  
      fit_obj_value = detector.reward.apply(fit_data)
  
      fit_recall = calc_recall(
          y_true=fit_data.y_true, y_pred=fit_data.y_pred
      )
  
      fit_precision = calc_precision(
          y_true=fit_data.y_true, y_pred=fit_data.y_pred
      )
  
      assert test_obj_value == pytest.approx(0.95, 0.01)
      assert fit_obj_value == pytest.approx(1.0, 0.01)
      assert test_recall == pytest.approx(0.95, 0.01)
      assert test_precision == pytest.approx(0.95, 0.01)
      assert fit_recall == pytest.approx(1.0, 0.01)
      assert fit_precision == pytest.approx(1.0, 0.01)
  
      fit_pred_df = pd.concat([fit_df, pred_df], axis=0).reset_index(
          drop=True
      )
      fit_pred_df[ANOMALY_COL] = df[ANOMALY_COL]
  
      fig = plt_compare_series_annotations(
          df=fit_pred_df,
          x_col=TIME_COL,
          actual_col=ACTUAL_COL,
          actual_label_col=ANOMALY_COL,
          forecast_label_col=PREDICTED_ANOMALY_COL,
          keep_cols=[PREDICTED_LOWER_COL, PREDICTED_UPPER_COL],
          forecast_col=PREDICTED_COL,
          standardize_col=None,
          title="test_greykite_detector_detector_daily_f1_outlier",
      )
  
      fig.add_vline(
          x=fit_df[TIME_COL].max(),
          line_width=1,
          line_dash="dash",
          line_color="green",
      )
  
      fig.add_annotation(
          x=fit_df[TIME_COL].max(),
          y=fit_pred_df[ACTUAL_COL].max(),
          text="end of training",
      )
      assert fig is not None
      if FIG_SHOW:
          fig.show()
  
      # Tests plot method.
      fig = detector.plot(
          phase="train",
          title="test_greykite_detector_detector_daily_f1_outlier - fit phase",
      )
      assert fig is not None
      if FIG_SHOW:
          fig.show()
  
      fig = detector.plot(
          title="test_greykite_detector_detector_daily_f1_outlier - predict phase"
      )
      assert fig is not None
      if FIG_SHOW:
          fig.show()
  
imports: import datetime
  import numpy
  import pandas
  import plotly.express
  import pytest
  from greykite.common.constants import ACTUAL_COL
  from greykite.common.constants import ANOMALY_COL
  from greykite.common.constants import END_TIME_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 START_TIME_COL
  from greykite.common.constants import TIME_COL
  from greykite.common.constants import VALUE_COL
  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.common.viz.timeseries_annotate import plot_lines_markers
  from greykite.common.viz.timeseries_annotate import plt_compare_series_annotations
  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.detector.ad_utils import partial_return
  from greykite.detection.detector.config import F1
  from greykite.detection.detector.config import ADConfig
  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 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
label_desc: Use image node_id 9 for calling a global function with example usage: test_greykite_detector_daily_outlier(daily_data, forecast_config_info_daily) and returns: calc_f1