code: def mean_interval_score(observed, lower, upper, coverage):
      """Calculates the mean interval score.
      If an observed value falls within the interval, the score is simply the width of the interval.
      If an observed value falls outside the interval, the score is the width of the interval plus an error term
      proportional to distance between the actual and its closest interval boundary.
      The proportionality constant is 2.0 / (1.0 - `coverage`).
      See `Strictly Proper Scoring Rules, Prediction, and Estimation, Tilmann Gneiting and Adrian E. Raftery, 2007,
      Journal of the American Statistical Association, Volume 102, 2007 - Issue 477`.
  
      Parameters
      ----------
      observed: `pandas.Series` or `numpy.array`
          Numeric, observed values.
      lower: `pandas.Series` or `numpy.array`
          Numeric, lower bound.
      upper: `pandas.Series` or `numpy.array`
          Numeric, upper bound.
      coverage: `float`
          Intended coverage of the prediction bands (0.0 to 1.0)
  
      Returns
      -------
      mean_interval_score: `float`
          The mean interval score.
      """
      observed, lower, upper = valid_elements_for_evaluation(
          reference_arrays=[observed],
          arrays=[lower, upper],
          reference_array_names="y_true",
          drop_leading_only=False,
          keep_inf=False,
      )
      lower, upper, observed = valid_elements_for_evaluation(
          reference_arrays=[lower, upper],
          arrays=[observed],
          reference_array_names="lower/upper bounds",
          drop_leading_only=False,
          keep_inf=True,
      )
      interval_width = upper - lower
      error_lower = np.where(
          observed < lower,
          2.0 * (lower - observed) / (1.0 - coverage),
          0.0,
      )
      error_upper = np.where(
          observed > upper,
          2.0 * (observed - upper) / (1.0 - coverage),
          0.0,
      )
      interval_score = interval_width + error_lower + error_upper
      return np.mean(interval_score)
  
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 18 for calling a global function with example usage: mean_interval_score(observed, lower, upper, coverage) and returns: np