def test_normal_ppf_compare_with_scipy(self):
        """Compare the percentiles function to the scipy ppf function."""
        from helpers import metrics
        cdf_fun = norm.cdf

        # PDF parameters
        mean = 0
        standard_deviation = 1

        # Percentiles to estimate
        percentiles = np.arange(1, 99, 1) / 100

        # Percentile search parameters
        search_start_value = -50
        search_increment_value = 0.01
        search_probability_threshold = 0.001

        # Do comparison
        target_percentiles = \
            norm.ppf(percentiles, loc=mean, scale=standard_deviation)
        comparison_percentiles = \
            metrics.percentiles(
                cdf_fun, percentiles,
                search_start_value, search_increment_value,
                search_probability_threshold)
        assert_almost_equal(target_percentiles, comparison_percentiles, 2)
def add_model_predictions(dataframe, model, test_observation,
                          persistence_forecast, row_index,
                          element_name, percentiles):
    """Add model predictions to the dataframe."""
    # Local constants
    ZERO_DEGREES_KELVIN = 273.15
    THRESHOLDS = np.arange(-30, 30, 0.5) + 273.15
    # Ensemble PDF
    dataframe.loc[row_index, element_name + '_ENSEMBLE_PDF'] = \
        model.pdf(test_observation)
    # Ensemble CDF
    dataframe.loc[row_index, element_name + '_ENSEMBLE_CDF'] = \
        model.cdf(test_observation)
    # Ensemble CDF freezing
    dataframe.loc[row_index, element_name + '_ENSEMBLE_CDF_FREEZE'] = \
        model.cdf(ZERO_DEGREES_KELVIN)
    # CRPS
    threshold_cdfs = model.cdf(THRESHOLDS)
    dataframe.loc[row_index, element_name + '_CRPS'] = \
        metrics.crps(THRESHOLDS, threshold_cdfs, test_observation)
    # Ensemble mean
    dataframe.loc[row_index, element_name + '_ENSEMBLE_MEAN'] = \
        model.mean()
    # Persistence forecast
    dataframe.loc[row_index, element_name + '_PERSISTENCE_FORECAST'] = \
        persistence_forecast
    # Observation rank
    dataframe.loc[row_index, element_name + '_OBS_RANK'] = \
        metrics.rank(test_observation, model.get_member_means())
    # Percentiles
    search_initialization = test_observation - 15
    perc_values = metrics.percentiles(
        model.cdf, percentiles / 100, search_initialization)
    for percentile, value in zip(percentiles, perc_values):
        name = element_name + '_ENSEMBLE_PERC' + str(percentile)
        dataframe.loc[row_index, name] = value