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
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)
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()
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 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)