Example #1
0
def plot_cdf(cfg, psi_cube, ecs_cube, obs_cube):
    """Plot cumulative distribution function of ECS."""
    confidence_level = cfg.get('confidence_level', 0.66)
    (ecs_lin, ecs_pdf) = ec.gaussian_pdf(psi_cube.data, ecs_cube.data,
                                         np.mean(obs_cube.data),
                                         np.std(obs_cube.data))
    ecs_cdf = ec.cdf(ecs_lin, ecs_pdf)

    # Provenance
    filename = 'cdf_{}'.format(obs_cube.attributes['dataset'])
    netcdf_path = get_diagnostic_filename(filename, cfg)
    cube = iris.cube.Cube(ecs_cdf,
                          var_name='cdf',
                          long_name='Cumulative distribution function',
                          units='1')
    cube.add_aux_coord(
        iris.coords.AuxCoord(ecs_lin, **ih.convert_to_iris(ECS_ATTRS)), 0)
    io.iris_save(cube, netcdf_path)
    project = _get_project(cfg)
    provenance_record = get_provenance_record(
        "The CDF for ECS. The horizontal dot-dashed lines show the {}% "
        "confidence limits. The orange histograms show the prior "
        "distributions that arise from equal weighting of the {} models in "
        "0.5 K bins.".format(int(confidence_level * 100), project), ['mean'],
        ['other'], _get_ancestor_files(cfg, obs_cube.attributes['dataset']))

    # Plot
    if cfg['write_plots']:
        AXES.plot(ecs_lin,
                  ecs_cdf,
                  color='black',
                  linewidth=2.0,
                  label='Emergent constraint')
        AXES.hist(ecs_cube.data,
                  bins=6,
                  range=(2.0, 5.0),
                  cumulative=True,
                  density=True,
                  color='orange',
                  label='{} models'.format(project))
        AXES.axhline((1.0 - confidence_level) / 2.0,
                     color='black',
                     linestyle='dashdot')
        AXES.axhline((1.0 + confidence_level) / 2.0,
                     color='black',
                     linestyle='dashdot')

        # Plot appearance
        AXES.set_title('CDF of emergent constraint')
        AXES.set_xlabel('ECS / K')
        AXES.set_ylabel('CDF')
        legend = AXES.legend(loc='upper left')

        # Save plot
        provenance_record['plot_file'] = _save_fig(cfg, filename, legend)

    # Write provenance
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(netcdf_path, provenance_record)
Example #2
0
def plot_pdf(cfg, psi_cube, ecs_cube, obs_cube):
    """Plot probability density function of ECS."""
    obs_mean = np.mean(obs_cube.data)
    obs_std = np.std(obs_cube.data)
    (ecs_lin, ecs_pdf) = ec.gaussian_pdf(psi_cube.data, ecs_cube.data,
                                         obs_mean, obs_std)

    # Provenance
    filename = 'pdf_{}'.format(obs_cube.attributes['dataset'])
    netcdf_path = get_diagnostic_filename(filename, cfg)
    cube = iris.cube.Cube(ecs_pdf,
                          var_name='pdf',
                          long_name='Probability density function',
                          units='K-1')
    cube.add_aux_coord(
        iris.coords.AuxCoord(ecs_lin, **ih.convert_to_iris(ECS_ATTRS)), 0)
    io.iris_save(cube, netcdf_path)
    project = _get_project(cfg)
    provenance_record = get_provenance_record(
        "The PDF for ECS. The orange histograms show the prior distributions "
        "that arise from equal weighting of the {} models in 0.5 K bins.".
        format(project), ['mean'], ['other'],
        _get_ancestor_files(cfg, obs_cube.attributes['dataset']))

    # Plot
    if cfg['write_plots']:
        AXES.plot(ecs_lin,
                  ecs_pdf,
                  color='black',
                  linewidth=2.0,
                  label='Emergent constraint')
        AXES.hist(ecs_cube.data,
                  bins=6,
                  range=(2.0, 5.0),
                  density=True,
                  color='orange',
                  label='{} models'.format(project))

        # Plot appearance
        AXES.set_title('PDF of emergent constraint')
        AXES.set_xlabel('ECS / K')
        AXES.set_ylabel('Probability density')
        legend = AXES.legend(loc='upper left')

        # Save plot
        provenance_record['plot_file'] = _save_fig(cfg, filename, legend)

    # Write provenance
    with ProvenanceLogger(cfg) as provenance_logger:
        provenance_logger.log(netcdf_path, provenance_record)
def get_constraint(x_data, y_data, x_ref, x_ref_err):
    """Print constraint value for Y axis."""
    (feature, feature_units, label, label_units) = _get_tags(x_data, y_data)
    x_data = x_data.values.squeeze()
    y_data = y_data.values.squeeze()
    x_ref = x_ref.values.squeeze()
    x_ref_err = x_ref_err.values.squeeze()
    (y_data_lin, y_pdf) = ec.gaussian_pdf(x_data, y_data, x_ref, x_ref_err**2)
    y_mean = np.sum(y_data_lin * y_pdf) / np.sum(y_pdf)
    y_var = np.sum((y_data_lin - y_mean)**2 * y_pdf) / np.sum(y_pdf)
    y_std = np.sqrt(y_var)
    lines = ec.regression_surface(x_data, y_data)
    logger.info("Observational constraint on '%s': (%.3f ± %.3f) %s", feature,
                x_ref, x_ref_err, feature_units)
    logger.info("Constraint on target variable '%s': (%.3f ± %.3f) %s", label,
                y_mean, y_std, label_units)
    logger.info("R2 of emergent relationship: %.3f (p = %.4f)", lines['R2'],
                lines['p'][0])
    return (y_mean, y_std)
Example #4
0
def get_ecs_range(cfg, psi_cube, ecs_cube, obs_cube):
    """Get constrained ecs range."""
    confidence_level = cfg.get('confidence_level', 0.66)
    conf_low = (1.0 - confidence_level) / 2.0
    conf_high = (1.0 + confidence_level) / 2.0

    # Calculate PDF and CDF
    (ecs_lin, ecs_pdf) = ec.gaussian_pdf(psi_cube.data, ecs_cube.data,
                                         np.mean(obs_cube.data),
                                         np.std(obs_cube.data))
    ecs_cdf = ec.cdf(ecs_lin, ecs_pdf)

    # Calculate constrained ECS range
    ecs_mean = ecs_lin[np.argmax(ecs_pdf)]
    ecs_index_range = np.where((ecs_cdf >= conf_low)
                               & (ecs_cdf <= conf_high))[0]
    ecs_range = ecs_lin[ecs_index_range]
    ecs_low = min(ecs_range)
    ecs_high = max(ecs_range)
    return (ecs_mean, ecs_low, ecs_high)
Example #5
0
def main(cfg):
    """Run the diagnostic."""
    input_data = (
        select_metadata(cfg['input_data'].values(), short_name='tas') +
        select_metadata(cfg['input_data'].values(), short_name='tasa'))
    if not input_data:
        raise ValueError("This diagnostics needs 'tas' or 'tasa' variable")

    # Get time-dependent data
    (tas_cubes, tas_obs) = get_tas(input_data)
    (psi_cubes, psi_obs) = get_psi(cfg)

    # Get scalar psi, ECS and climate feedback parameter for models
    (psi_cube, ecs_cube, lambda_cube) = get_external_cubes(cfg)

    # Plots
    for obs_name in tas_obs:
        logger.info("Observation for tas: %s", obs_name)
        plot_temperature_anomaly(cfg, tas_cubes, lambda_cube, obs_name)
    for obs_name in psi_obs:
        logger.info("Observation for psi: %s", obs_name)
        plot_psi(cfg, psi_cubes, lambda_cube, obs_name)
        obs_cube = psi_cubes[obs_name]
        plot_emergent_relationship(cfg, psi_cube, ecs_cube, lambda_cube,
                                   obs_cube)
        (ecs_lin, ecs_pdf) = ec.gaussian_pdf(psi_cube.data, ecs_cube.data,
                                             np.mean(obs_cube.data),
                                             np.var(obs_cube.data))
        plot_pdf(cfg, ecs_lin, ecs_pdf, ecs_cube, obs_name)
        plot_cdf(cfg, ecs_lin, ecs_pdf, ecs_cube, obs_name)

        # Print ECS range
        ecs_range = get_ecs_range(cfg, ecs_lin, ecs_pdf)
        logger.info("Observational constraint: Ψ = (%.2f ± %.2f) K",
                    np.mean(obs_cube.data), np.std(obs_cube.data))
        logger.info(
            "Constrained ECS range: (%.2f - %.2f) K with best "
            "estimate %.2f K", ecs_range[1], ecs_range[2], ecs_range[0])