def test_convert_to_iris(dict_in, dict_out):
    """Test converting metadata dictionary checking of coordinates."""
    if 'short_name' in dict_in and 'var_name' in dict_in:
        with pytest.raises(KeyError):
            ih.convert_to_iris(dict_in)
        return
    new_dict = ih.convert_to_iris(dict_in)
    assert new_dict == dict_out
    assert new_dict is not dict_in
Пример #2
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)
Пример #3
0
def test_convert_to_iris(mock_logger, dict_in, dict_out):
    """Test converting metadata dictionary checking of coordinates."""
    new_dict = ih.convert_to_iris(dict_in)
    assert new_dict == dict_out
    assert new_dict is not dict_in
    if 'short_name' in dict_in and 'var_name' in dict_in:
        mock_logger.warning.assert_called()
    else:
        mock_logger.warning.assert_not_called()
Пример #4
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)
Пример #5
0
def plot_emergent_relationship(cfg, psi_cube, ecs_cube, lambda_cube, obs_cube):
    """Plot emergent relationship."""
    filename = 'emergent_relationship_{}'.format(
        obs_cube.attributes['dataset'])
    cube = ecs_cube.copy()
    cube.add_aux_coord(
        iris.coords.AuxCoord(psi_cube.data, **ih.convert_to_iris(PSI_ATTRS)),
        0)
    netcdf_path = get_diagnostic_filename(filename, cfg)
    io.iris_save(cube, netcdf_path)
    provenance_record = get_provenance_record(
        "Emergent relationship between ECS and the psi metric. The black dot-"
        "dashed line shows the best-fit linear regression across the model "
        "ensemble, with the prediction error for the fit given by the black "
        "dashed lines. The vertical blue lines show the observational "
        "constraint from the {} observations: the mean (dot-dashed line) and "
        "the mean plus and minus one standard deviation (dashed lines).".
        format(obs_cube.attributes['dataset']), ['mean', 'corr', 'var'],
        ['scatter'], _get_ancestor_files(cfg, obs_cube.attributes['dataset']))

    # Plot
    if cfg['write_plots']:
        obs_mean = np.mean(obs_cube.data)
        obs_std = np.std(obs_cube.data)

        # Calculate regression line
        lines = ec.regression_surface(psi_cube.data, ecs_cube.data,
                                      n_points=1000)
        logger.info("Found emergent relationship with slope %.2f (R2 = %.2f)",
                    lines['coef'], lines['R2'])

        # Plot points
        for model in psi_cube.coord('dataset').points:
            _plot_model_point(model, psi_cube, ecs_cube, lambda_cube)

        # Plot lines
        AXES.set_xlim(auto=False)
        AXES.set_ylim(auto=False)
        AXES.plot(lines['x'],
                  lines['y'],
                  color='black',
                  linestyle='dashdot',
                  label='Linear regression')
        AXES.plot(lines['x'],
                  lines['y_minus_err'],
                  color='black',
                  linestyle='dashed')
        AXES.plot(lines['x'],
                  lines['y_plus_err'],
                  color='black',
                  linestyle='dashed')
        AXES.axvline(obs_mean,
                     color='blue',
                     linestyle='dashdot',
                     label='Observational constraint')
        AXES.axvline(obs_mean - obs_std, color='blue', linestyle='dashed')
        AXES.axvline(obs_mean + obs_std, color='blue', linestyle='dashed')

        # Plot appearance
        AXES.set_title('Emergent relationship fit')
        AXES.set_xlabel(r'$\Psi$ / K')
        AXES.set_ylabel('ECS / K')
        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)