Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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": {
Expand Down
46 changes: 45 additions & 1 deletion openquake/hme/reporting/reporting.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,48 @@ def _init_env() -> Environment:
return env


def _format_completeness_table(completeness_table: list) -> str:
rows = "\n".join(
f"<tr><td>{row[0]}</td><td>{row[1]}</td></tr>"
for row in completeness_table
)
return (
"<table>"
"<thead><tr><th>Start Year</th><th>Min. Magnitude</th></tr></thead>"
f"<tbody>{rows}</tbody>"
"</table>"
)


def _build_eval_info(cfg: dict) -> dict:
bins = cfg.get("input", {}).get("bins", {})
seis_catalog = cfg.get("input", {}).get("seis_catalog", {})

settings = {
"min_magnitude": bins.get("mfd_bin_min"),
"max_magnitude": bins.get("mfd_bin_max"),
"bin_width": bins.get("mfd_bin_width"),
"h3_resolution": bins.get("h3_res"),
}

completeness_table = seis_catalog.get("completeness_table")
if completeness_table is not None:
comp_table_html = _format_completeness_table(completeness_table)
start_date = None
else:
comp_table_html = None
start_date = seis_catalog.get("start_date")

catalog = {
"name": seis_catalog.get("seis_catalog_file"),
"start_date": start_date,
"completeness_table": comp_table_html,
"stop_date": seis_catalog.get("stop_date"),
}

return {"settings": settings, "catalog": catalog}


def generate_basic_report(
cfg: dict,
results: dict,
Expand Down Expand Up @@ -94,7 +136,9 @@ def generate_basic_report(
env=env, cfg=cfg, results=results, input_data=input_data
)

report = report_template.render(cfg=cfg, results=results)
eval_info = _build_eval_info(cfg)

report = report_template.render(cfg=cfg, results=results, eval_info=eval_info)

with open(cfg["report"]["basic"]["outfile"], "w") as report_file:
report_file.write(report)
Expand Down
25 changes: 25 additions & 0 deletions openquake/hme/reporting/templates/basic_report.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,31 @@ <h2>Evaluation info</h2>
<p>Branch analyzed: {{ cfg.input.ssm.branch }}</p>
<p>Tectonic region types analyzed: {{ cfg.input.ssm.tectonic_region_types }}</p>

{% if eval_info is defined %}
<h3>Settings</h3>
<table>
<tbody>
{% if eval_info.settings.min_magnitude is not none %}<tr><td>Minimum magnitude:</td><td>{{ eval_info.settings.min_magnitude }}</td></tr>{% endif %}
{% if eval_info.settings.max_magnitude is not none %}<tr><td>Maximum magnitude:</td><td>{{ eval_info.settings.max_magnitude }}</td></tr>{% endif %}
{% if eval_info.settings.bin_width is not none %}<tr><td>Bin width:</td><td>{{ eval_info.settings.bin_width }}</td></tr>{% endif %}
{% if eval_info.settings.h3_resolution is not none %}<tr><td>H3 resolution:</td><td>{{ eval_info.settings.h3_resolution }}</td></tr>{% endif %}
</tbody>
</table>

<h3>Catalog</h3>
<table>
<tbody>
{% if eval_info.catalog.name is not none %}<tr><td>Catalog:</td><td>{{ eval_info.catalog.name }}</td></tr>{% endif %}
{% if eval_info.catalog.completeness_table is not none %}
<tr><td>Completeness table:</td><td>{{ eval_info.catalog.completeness_table | safe }}</td></tr>
{% elif eval_info.catalog.start_date is not none %}
<tr><td>Start date:</td><td>{{ eval_info.catalog.start_date }}</td></tr>
{% endif %}
{% if eval_info.catalog.stop_date is not none %}<tr><td>Stop date:</td><td>{{ eval_info.catalog.stop_date }}</td></tr>{% endif %}
</tbody>
</table>
{% endif %}

<h2>Results</h2>
{% if branches is defined and branches %}
{% for branch_name, branch_data in branches.items() %}
Expand Down
5 changes: 4 additions & 1 deletion openquake/hme/reporting/templates/m_test.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@ <h3> GEM M-Test</h3>
Observed catalog fractile (compared to stochastic event sets): {{ res.fractile
}} </br>
Critical fractile: {{ res.critical_frac }} </br>
Test pass: {{ res.test_res }} </br>
Test pass: {{ res.test_res }} </br>
{% if res.N_norm is defined and res.N_norm != 1.0 %}
N normalization factor (N_obs / N_pred): {{ "%.3f"|format(res.N_norm) }} </br>
{% endif %}
3 changes: 3 additions & 0 deletions openquake/hme/reporting/templates/s_test.html
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ <h3>GEM S-Test</h3>
<p>Observed catalog fractile (compared to stochastic event sets): {{ res.fractile }}</p>
<p>Critical fractile: {{ res.critical_frac }}</p>
<p>Test pass: {{ res.test_res }}</p>
{% if res.N_norm is defined and res.N_norm != 1.0 %}
<p>N normalization factor (N_obs / N_pred): {{ "%.3f"|format(res.N_norm) }}</p>
{% endif %}
</div>


Expand Down
48 changes: 29 additions & 19 deletions openquake/hme/utils/plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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")

Expand Down Expand Up @@ -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")

Expand All @@ -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}")
Expand Down Expand Up @@ -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")
Expand Down
Loading