code: def add_preaggregation_to_scorer(
      score_func, agg_periods=7, agg_func=np.sum
  ):
      """Takes a scorer and returns a scorer that pre-aggregates input.
  
      :param score_func: function that maps two arrays to a number. E.g. (y_true, y_pred) -> error
      :param agg_periods: number of periods to combine in aggregation
      :param agg_func: function that takes an array and returns a number, e.g. np.max, np.sum. This function should
          handle np.nan without error
      :return: scorer that applies agg_func to data before calling score_func
  
      For example, if have daily data and want to evaluate MSE on weekly totals, the appropriate scorer is:
          add_preaggregation_to_scorer(mean_squared_error, agg_periods=7, agg_func=np.max)
      """
  
      def score_func_preagg(y_true, y_pred, **kwargs):
          y_true_agg = aggregate_array(y_true, agg_periods, agg_func)
          y_pred_agg = aggregate_array(y_pred, agg_periods, agg_func)
          return score_func(y_true_agg, y_pred_agg, **kwargs)
  
      return score_func_preagg
  
imports: import math
  import warnings
  from collections import namedtuple
  from enum import Enum
  from functools import partial
  from typing import List
  from typing import Optional
  from typing import Union
  import numpy
  import pandas
  from scipy.stats import pearsonr
  from sklearn.metrics import mean_absolute_error
  from sklearn.metrics import mean_squared_error
  from sklearn.metrics import median_absolute_error
  from sklearn.metrics import r2_score
  from greykite.common.constants import ACTUAL_COL
  from greykite.common.constants import COVERAGE_VS_INTENDED_DIFF
  from greykite.common.constants import LOWER_BAND_COVERAGE
  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 PREDICTION_BAND_COVERAGE
  from greykite.common.constants import PREDICTION_BAND_WIDTH
  from greykite.common.constants import UPPER_BAND_COVERAGE
  from greykite.common.logging import LoggingLevelEnum
  from greykite.common.logging import log_message
label_desc: Use image node_id 4 for calling a global function with example usage: add_preaggregation_to_scorer(score_func, agg_periods, agg_func) and returns: score_func_preagg, score_func