diff --git a/openquake/hme/model_test_frameworks/relm/relm_test_functions.py b/openquake/hme/model_test_frameworks/relm/relm_test_functions.py index 45ce72a..316945a 100644 --- a/openquake/hme/model_test_frameworks/relm/relm_test_functions.py +++ b/openquake/hme/model_test_frameworks/relm/relm_test_functions.py @@ -195,6 +195,7 @@ def m_test_function( "fractile": fractile, "test_pass": test_pass, "test_res": test_res, + "N_norm": N_norm, "test_data": { "stoch_geom_mean_likes": stoch_geom_mean_likes.tolist(), "obs_geom_mean_like": obs_geom_mean_like, @@ -336,6 +337,7 @@ def s_test_function( "fractile": fractile, "test_pass": bool(test_pass), "test_res": test_res, + "N_norm": N_norm, "bad_bins": bad_bins, "unmatched_eqs": unmatched_eqs, "test_data": { diff --git a/openquake/hme/reporting/reporting.py b/openquake/hme/reporting/reporting.py index 3712ed6..fa054ff 100644 --- a/openquake/hme/reporting/reporting.py +++ b/openquake/hme/reporting/reporting.py @@ -51,6 +51,48 @@ def _init_env() -> Environment: return env +def _format_completeness_table(completeness_table: list) -> str: + rows = "\n".join( + f"
| Start Year | Min. Magnitude |
|---|
Branch analyzed: {{ cfg.input.ssm.branch }}
Tectonic region types analyzed: {{ cfg.input.ssm.tectonic_region_types }}
+ {% if eval_info is defined %} +| Minimum magnitude: | {{ eval_info.settings.min_magnitude }} |
| Maximum magnitude: | {{ eval_info.settings.max_magnitude }} |
| Bin width: | {{ eval_info.settings.bin_width }} |
| H3 resolution: | {{ eval_info.settings.h3_resolution }} |
| Catalog: | {{ eval_info.catalog.name }} |
| Completeness table: | {{ eval_info.catalog.completeness_table | safe }} |
| Start date: | {{ eval_info.catalog.start_date }} |
| Stop date: | {{ eval_info.catalog.stop_date }} |
Observed catalog fractile (compared to stochastic event sets): {{ res.fractile }}
Critical fractile: {{ res.critical_frac }}
Test pass: {{ res.test_res }}
+ {% if res.N_norm is defined and res.N_norm != 1.0 %} +N normalization factor (N_obs / N_pred): {{ "%.3f"|format(res.N_norm) }}
+ {% endif %} diff --git a/openquake/hme/utils/plots.py b/openquake/hme/utils/plots.py index 0fb7c39..5554e98 100644 --- a/openquake/hme/utils/plots.py +++ b/openquake/hme/utils/plots.py @@ -15,6 +15,7 @@ from matplotlib.collections import LineCollection from matplotlib.cm import ScalarMappable from matplotlib.colors import Normalize, BoundaryNorm +from mpl_toolkits.axes_grid1 import make_axes_locatable import io from .stats import sample_event_times_in_interval @@ -342,7 +343,11 @@ def plot_mfd( ) ax.legend(loc="upper right") - ylabel = "Annual frequency of exceedance" if annualize else "Frequency of exceedance" + ylabel = ( + "Annual frequency of exceedance" + if annualize + else "Frequency of exceedance" + ) ax.set_ylabel(ylabel) ax.set_xlabel("Magnitude") @@ -447,27 +452,20 @@ def plot_S_test_map( else: bad_bin_gdf = GeoDataFrame(cell_gdf.loc[bad_bins]) + plot_kwargs = dict( + column=f"{model_test_framework}_S_test_frac", + ax=ax, + vmin=0.0, + vmax=1.0, + cmap="OrRd_r", + ) + if map_epsg is None: - cell_gdf.plot( - column=f"{model_test_framework}_S_test_frac", - ax=ax, - vmin=0.0, - vmax=1.0, - cmap="OrRd_r", - legend=True, - ) + cell_gdf.plot(**plot_kwargs) if len(bad_bins) > 0: bad_bin_gdf.plot(ax=ax, color="blue") - else: - cell_gdf.to_crs(epsg=map_epsg).plot( - column=f"{model_test_framework}_S_test_frac", - ax=ax, - vmin=0.0, - vmax=1.0, - cmap="OrRd_r", - legend=True, - ) + cell_gdf.to_crs(epsg=map_epsg).plot(**plot_kwargs) if len(bad_bins) > 0: bad_bin_gdf.plot(ax=ax, color="blue") @@ -484,6 +482,16 @@ def plot_S_test_map( ax.set_xlim(x_lims) ax.set_ylim(y_lims) + # Add a horizontal colorbar the same width as the axes frame + divider = make_axes_locatable(ax) + cax = divider.append_axes("bottom", size="5%", pad=0.4) + sm = ScalarMappable(cmap="OrRd_r", norm=Normalize(vmin=0.0, vmax=1.0)) + sm.set_array([]) + cbar = fig.colorbar(sm, cax=cax, orientation="horizontal") + cbar.set_label( + "Cell fractile (observed likelihood compared to stochastic event sets)" + ) + if save_fig is not False: fig.savefig(save_fig) logging.info(f"S-Test map saved to: {save_fig}") @@ -776,7 +784,9 @@ def plot_rup_match_mag_dist( if save_fig is not False: fig.savefig(save_fig) - logging.info(f"Rupture matching magnitude-distance plot saved to: {save_fig}") + logging.info( + f"Rupture matching magnitude-distance plot saved to: {save_fig}" + ) if return_str: plt.switch_backend("svg")