Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions openquake/calculators/export/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
DISPLAY_NAME = {
'asce07': 'ASCE 7 Parameters',
'asce41': 'ASCE 41 Parameters',
'asce41_sa_final': 'ASCE41 BSE Spectra',
'spectra_asce41': 'ASCE41 Calculations',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm using the display names suggested by @ManuelaVillani. Please @kejohnso double-check if they look fine to you as well.

'mag_dst_eps_sig': "Deterministic Earthquake Scenarios",
'job': 'job.zip',
'asset_risk': 'Exposure + Risk',
Expand Down
28 changes: 21 additions & 7 deletions openquake/server/templates/engine/get_outputs.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ <h2>{{ site_name }}, Lat: {{ lat }}, Lon: {{ lon }}, Site Class: {{ site_class }
{% else %}
<h2>Outputs from calculation {{ calc_id }}</h2>
{% endif %}
{% if warnings %}
<div id="warnings-box" class="alert alert-warning" style=>
WARNING: {{ warnings }}
</div>
{% endif %}
{% if notes %}
<div id="notes-box" class="alert alert-info" style=>
NOTE: {{ notes }}
</div>
{% endif %}
<div id="my-outputs" class="well"></div>
<div class="outputs-general-btns-left">
{% if application_mode == 'AELO' %}
Expand All @@ -24,50 +34,54 @@ <h2>Outputs from calculation {{ calc_id }}</h2>
{% endif %}
</div>
<div class="outputs-general-btns-center">
{% if hmaps %}
{% if pngs.hmaps %}
<div class="my-pngs">
<a href="{{ oq_engine_server_url }}/v1/calc/{{ calc_id }}/download_png/hmap_0_0" class="btn btn-sm">
Show hazard map</a>
</div>
{% endif %}
{% for img in avg_gmf %}
{% if application_mode == 'ARISTOTLE' %}
{% for img in pngs.avg_gmf %}
<div class="my-pngs">
<a href="{{ oq_engine_server_url }}/v1/calc/{{ calc_id }}/download_png/{{img}}" class="btn btn-sm">
Show average GMF - {{ img|get_imt }}</a>
</div>
{% endfor %}
{% if assets %}
{% if pngs.assets %}
<div class="my-pngs">
<a href="{{ oq_engine_server_url }}/v1/calc/{{ calc_id }}/download_png/assets.png" class="btn btn-sm">
Show assets</a>
</div>
{% endif %}
{% if mce %}
{% endif %} {# end if ARISTOTLE #}
{% if application_mode == 'AELO' %}
{% if pngs.mce %}
<div class="my-pngs">
<a href="{{ oq_engine_server_url }}/v1/calc/{{ calc_id }}/download_png/mce.png" class="btn btn-sm">
Show MCE</a>
</div>
{% endif %}
{% if mce_spectra %}
{% if pngs.mce_spectra %}
<div class="my-pngs">
<a href="{{ oq_engine_server_url }}/v1/calc/{{ calc_id }}/download_png/mce_spectra.png" class="btn btn-sm">
Show MCE spectra</a>
</div>
{% endif %}
{% if hcurves %}
{% if pngs.hcurves %}
<div class="my-pngs">
<a href="{{ oq_engine_server_url }}/v1/calc/{{ calc_id }}/download_png/hcurves.png" class="btn btn-sm">
Show hazard curves</a>
</div>
{% endif %}
{% for img in disagg_by_src %}
{% for img in pngs.disagg_by_src %}
<div class="my-pngs">
<a href="{{ oq_engine_server_url }}/v1/calc/{{ calc_id }}/download_png/{{img}}" class="btn btn-sm">
{# NOTE: uncomment below to show the IMT #}
{# Show hazard curves per source - {{ img|get_imt }}</a> #}
Show hazard curves per source</a>
</div>
{% endfor %}
{% endif %} {# end if AELO #}
</div>
<div class="outputs-general-btns-right">
<div id="my-datastore">
Expand Down
4 changes: 2 additions & 2 deletions openquake/server/templates/engine/get_outputs_aelo.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ <h2>{{ site_name }}, Lat: {{ lat }}, Lon: {{ lon }}, Site Class: {{ site_class }
</div>
</div>
<div class="outputs-general-btns-center">
{% if site %}
{% if pngs.site %}
<div class="my-pngs">
<a href="{{ oq_engine_server_url }}/v1/calc/{{ calc_id }}/download_png/site.png" class="btn btn-sm">
Show site</a>
</div>
{% endif %}
{% if governing_mce %}
{% if pngs.governing_mce %}
<div class="my-pngs">
<a href="{{ oq_engine_server_url }}/v1/calc/{{ calc_id }}/download_png/governing_mce.png" class="btn btn-sm">
Show Multi-Period MCEr Spectrum</a>
Expand Down
4 changes: 2 additions & 2 deletions openquake/server/templates/engine/get_outputs_impact.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ <h2>Outputs from calculation {{ calc_id }}: {{ description }}{% if local_timesta
</div>
{% endcomment %}
<div class="outputs-general-btns-left">
{% for img in avg_gmf %}
{% for img in pngs.avg_gmf %}
<div class="my-pngs">
<a href="{{ oq_engine_server_url }}/v1/calc/{{ calc_id }}/download_png/{{img}}" class="btn btn-sm">
Show average GMF - {{ img|get_imt }}</a>
</div>
{% endfor %}
{% if assets %}
{% if pngs.assets %}
<div class="my-pngs">
<a href="{{ oq_engine_server_url }}/v1/calc/{{ calc_id }}/download_png/assets.png" class="btn btn-sm">
Show assets</a>
Expand Down
152 changes: 78 additions & 74 deletions openquake/server/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1655,48 +1655,47 @@ def web_engine_get_outputs(request, calc_id, **kwargs):
job = logs.dbcmd('get_job', calc_id)
if job is None:
return HttpResponseNotFound()
avg_gmf = []
disagg_by_src = []
size_mb = '?' if job.size_mb is None else '%.2f' % job.size_mb
kwargs = dict(calc_id=calc_id, size_mb=size_mb)
pngs = dict(hmaps=False)
with datastore.read(job.ds_calc_dir + '.hdf5') as ds:
if 'png' in ds:
# NOTE: only one hmap can be visualized currently
hmaps = any([k.startswith('hmap') for k in ds['png']])
avg_gmf = [k for k in ds['png'] if k.startswith('avg_gmf-')]
assets = 'assets.png' in ds['png']
hcurves = 'hcurves.png' in ds['png']
# NOTE: remove "and 'All' in k" to show the individual plots
disagg_by_src = [k for k in ds['png']
if k.startswith('disagg_by_src-') and 'All' in k]
mce = 'mce.png' in ds['png']
mce_spectra = 'mce_spectra.png' in ds['png']
else:
hmaps = assets = hcurves = mce = mce_spectra = False
size_mb = '?' if job.size_mb is None else '%.2f' % job.size_mb
lon = lat = site_name = asce_version_full = calc_aelo_version = None
site_class_display_name = None
pngs['hmaps'] = any([k.startswith('hmap') for k in ds['png']])
if application_mode == 'ARISTOTLE':
pngs['avg_gmf'] = [
k for k in ds['png'] if k.startswith('avg_gmf-')]
pngs['assets'] = 'assets.png' in ds['png']
if application_mode == 'AELO':
pngs['hcurves'] = 'hcurves.png' in ds['png']
# NOTE: remove "and 'All' in k" to show the individual plots
pngs['disagg_by_src'] = [
k for k in ds['png']
if k.startswith('disagg_by_src-') and 'All' in k]
pngs['mce'] = 'mce.png' in ds['png']
pngs['mce_spectra'] = 'mce_spectra.png' in ds['png']
kwargs['pngs'] = pngs
if application_mode == 'AELO':
lon, lat = ds['oqparam'].sites[0][:2] # e.g. [[-61.071, 14.686, 0.0]]
site_class_display_name = get_site_class_display_name(ds)
site_name = ds['oqparam'].description[9:] # e.g. 'AELO for CCA'->'CCA'
# e.g. [[-61.071, 14.686, 0.0]]
kwargs['lon'], kwargs['lat'] = ds['oqparam'].sites[0][:2]
kwargs['site_class'] = get_site_class_display_name(ds)
# e.g. 'AELO for CCA'->'CCA'
kwargs['site_name'] = ds['oqparam'].description[9:]
try:
asce_version = ds['oqparam'].asce_version
except AttributeError:
# for backwards compatibility on old calculations
asce_version = oqvalidation.OqParam.asce_version.default
kwargs['asce_version'] = oqvalidation.ASCE_VERSIONS[asce_version]
try:
calc_aelo_version = ds.get_attr('/', 'aelo_version')
kwargs['calc_aelo_version'] = ds.get_attr('/', 'aelo_version')
except KeyError:
calc_aelo_version = '1.0.0'
asce_version_full = oqvalidation.ASCE_VERSIONS[asce_version]
return render(request, "engine/get_outputs.html",
dict(calc_id=calc_id, size_mb=size_mb, hmaps=hmaps,
avg_gmf=avg_gmf, assets=assets, hcurves=hcurves,
disagg_by_src=disagg_by_src,
mce=mce, mce_spectra=mce_spectra,
calc_aelo_version=calc_aelo_version,
asce_version=asce_version_full,
lon=lon, lat=lat, site_class=site_class_display_name, site_name=site_name)
)
kwargs['calc_aelo_version'] = '1.0.0'
kwargs['asce_version'] = oqvalidation.ASCE_VERSIONS[asce_version]
kwargs['notes'], kwargs['warnings'] = get_aelo_notes_and_warnings(ds)
elif application_mode == 'ARISTOTLE':
kwargs['warnings'] = get_aristotle_warnings(ds)
return render(request, "engine/get_outputs.html", kwargs)


def is_model_preliminary(ds):
Expand Down Expand Up @@ -1749,6 +1748,40 @@ def group_keys_by_value(d):
return result


def get_aelo_notes_and_warnings(ds):
notifications = numpy.array([], dtype=notification_dtype)
sid_to_vs30 = {}
notes = {}
warnings = {}
if is_model_preliminary(ds):
# sid -1 means it is not associated to a specific site
preliminary_model_warning = numpy.array([
(-1, b'warning', b'preliminary_model',
PRELIMINARY_MODEL_WARNING_MSG.encode('utf8'))],
dtype=notification_dtype)
notifications = numpy.concatenate(
(notifications, preliminary_model_warning))
sid_to_vs30.update({-1: ''}) # warning about preliminary model
if 'notifications' in ds:
notifications = numpy.concatenate((notifications, ds['notifications']))
sitecol = ds['sitecol']
# NOTE: the variable name 'site' is already used
sid_to_vs30.update({site_item.id: site_item.vs30 for site_item in sitecol})
for notification in notifications:
vs30 = sid_to_vs30[notification['sid']]
if notification['level'] == b'info':
notes[vs30] = notification['description'].decode('utf8')
elif notification['level'] == b'warning':
warnings[vs30] = notification['description'].decode('utf8')
notes = group_keys_by_value(notes)
warnings = group_keys_by_value(warnings)
# NOTE: we decided to avoid specifying which vs30 values are relevant with
# respect to the notifications (either for notes and warnings)
notes_str = '\n'.join([note for note in notes.values()])
warnings_str = '\n'.join([warning for warning in warnings.values()])
return notes_str, warnings_str


# this is extracting only the first site and it is okay
@cross_domain_ajax
@require_http_methods(['GET'])
Expand All @@ -1758,6 +1791,7 @@ def web_engine_get_outputs_aelo(request, calc_id, **kwargs):
asce07 = asce41 = site = governing_mce = None
asce07_with_units = {}
asce41_with_units = {}
notes_str = warnings_str = ''
with datastore.read(job.ds_calc_dir + '.hdf5') as ds:
try:
asce_version = ds['oqparam'].asce_version
Expand Down Expand Up @@ -1824,36 +1858,7 @@ def web_engine_get_outputs_aelo(request, calc_id, **kwargs):
lon, lat = ds['oqparam'].sites[0][:2] # e.g. [[-61.071, 14.686, 0.0]]
site_class_str = get_site_class_display_name(ds)
site_name = ds['oqparam'].description[9:] # e.g. 'AELO for CCA'->'CCA'
notifications = numpy.array([], dtype=notification_dtype)
sid_to_vs30 = {}
if is_model_preliminary(ds):
# sid -1 means it is not associated to a specific site
preliminary_model_warning = numpy.array([
(-1, b'warning', b'preliminary_model',
PRELIMINARY_MODEL_WARNING_MSG.encode('utf8'))],
dtype=notification_dtype)
notifications = numpy.concatenate(
(notifications, preliminary_model_warning))
sid_to_vs30.update({-1: ''}) # warning about preliminary model
sitecol = ds['sitecol']
if 'notifications' in ds:
notifications = numpy.concatenate((notifications, ds['notifications']))
# NOTE: the variable name 'site' is already used
sid_to_vs30.update({site_item.id: site_item.vs30 for site_item in sitecol})
notes = {}
warnings = {}
for notification in notifications:
vs30 = sid_to_vs30[notification['sid']]
if notification['level'] == b'info':
notes[vs30] = notification['description'].decode('utf8')
elif notification['level'] == b'warning':
warnings[vs30] = notification['description'].decode('utf8')
notes = group_keys_by_value(notes)
warnings = group_keys_by_value(warnings)
# NOTE: we decided to avoid specifying which vs30 values are relevant with
# respect to the notifications (either for notes and warnings)
notes_str = '\n'.join([note for note in notes.values()])
warnings_str = '\n'.join([warning for warning in warnings.values()])
notes_str, warnings_str = get_aelo_notes_and_warnings(ds)
return render(request, "engine/get_outputs_aelo.html",
dict(calc_id=calc_id, size_mb=size_mb,
asce07=asce07_with_units, asce41=asce41_with_units,
Expand Down Expand Up @@ -1888,6 +1893,13 @@ def determine_precision(weights):
return max_decimal_places


def get_aristotle_warnings(ds):
warnings = None
if 'warnings' in ds:
warnings = '\n'.join(s.decode('utf8') for s in ds['warnings'])
return warnings


@cross_domain_ajax
@require_http_methods(['GET'])
def web_engine_get_outputs_impact(request, calc_id):
Expand All @@ -1900,7 +1912,7 @@ def web_engine_get_outputs_impact(request, calc_id):
local_timestamp_str = None
time_job_after_event = None
time_job_after_event_str = None
warnings = None
pngs = {}
with datastore.read(job.ds_calc_dir + '.hdf5') as ds:
try:
losses = views.view('aggrisk', ds)
Expand All @@ -1919,23 +1931,15 @@ def web_engine_get_outputs_impact(request, calc_id):
for field in losses.dtype.names]
weights_precision = determine_precision(losses['weight'])
if 'png' in ds:
avg_gmf = [k for k in ds['png'] if k.startswith('avg_gmf-')]
assets = 'assets.png' in ds['png']
else:
assets = False
avg_gmf = []
pngs['avg_gmf'] = [k for k in ds['png'] if k.startswith('avg_gmf-')]
pngs['assets'] = 'assets.png' in ds['png']
oqparam = ds['oqparam']
if hasattr(oqparam, 'local_timestamp'):
local_timestamp_str = (
oqparam.local_timestamp if oqparam.local_timestamp != 'None'
else None)
size_mb = '?' if job.size_mb is None else '%.2f' % job.size_mb
if 'warnings' in ds:
ds_warnings = '\n'.join(s.decode('utf8') for s in ds['warnings'])
if warnings is None:
warnings = ds_warnings
else:
warnings += '\n' + ds_warnings
warnings = get_aristotle_warnings(ds)
mmi_tags = 'mmi_tags' in ds
# NOTE: aggrisk_tags is not available as an attribute of the datastore
try:
Expand All @@ -1959,7 +1963,7 @@ def web_engine_get_outputs_impact(request, calc_id):
size_mb=size_mb, losses=losses,
losses_header=losses_header,
weights_precision=weights_precision,
avg_gmf=avg_gmf, assets=assets,
pngs=pngs,
warnings=warnings, mmi_tags=mmi_tags,
aggrisk_tags=aggrisk_tags)
)
Expand Down