Skip to content

Commit

Permalink
Merge pull request #10360 from gem/stations-on-request
Browse files Browse the repository at this point in the history
Make it possible to run impact calculations ignoring stations
  • Loading branch information
ptormene authored Feb 20, 2025
2 parents 052124a + 03701de commit 85de0d0
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 22 deletions.
18 changes: 12 additions & 6 deletions openquake/hazardlib/shakemap/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -763,18 +763,25 @@ def _get_rup_dic_from_xml(usgs_id, user, rupture_file, station_data_file):

def get_rup_dic(dic, user=User(), approach='use_shakemap_from_usgs',
use_shakemap=False, rupture_file=None,
station_data_file=None, monitor=performance.Monitor()):
station_data_file=None, download_usgs_stations=True,
monitor=performance.Monitor()):
"""
If the rupture_file is None, download a rupture from the USGS site given
the ShakeMap ID, else build the rupture locally with the given usgs_id.
NOTE: this function is called twice by impact_validate: first when retrieving
rupture data, then when running the job. Only in the former case, if stations
have not been loaded yet, we try to download them from the USGS
:param dic: dictionary with ShakeMap ID and other parameters
:param user: User instance
:param approach: the workflow selected by the user
(default: 'use_shakemap_from_usgs')
:param use_shakemap: download the ShakeMap only if True
:param rupture_file: None
:param station_data_file: None
:param download_usgs_stations: download USGS stations, only if
station_data_file is None and the ShakeMap is not used
:returns: (rupture object or None, rupture dictionary, error dictionary or {})
"""
rupdic = {}
Expand Down Expand Up @@ -838,15 +845,15 @@ def get_rup_dic(dic, user=User(), approach='use_shakemap_from_usgs',
usgs_id, contents, user)
if not rupdic:
rupdic = convert_rup_data(rup_data, usgs_id, rupture_file, shakemap)
if (user.level == 2 and not station_data_file
and approach != 'use_shakemap_from_usgs'):
if (approach != 'use_shakemap_from_usgs' and not station_data_file
and download_usgs_stations):
with monitor('Downloading stations'):
rupdic['station_data_file'], rupdic['station_data_issue'] = (
download_station_data_file(usgs_id, contents, user))
rupdic['station_data_file_from_usgs'] = True
else:
rupdic['station_data_file'], rupdic['station_data_issue'] = (
station_data_file, None)
rupdic['station_data_file'] = station_data_file
rupdic['station_data_issue'] = None
rupdic['station_data_file_from_usgs'] = False
if not rup_data:
# in parsers_test
Expand All @@ -855,7 +862,6 @@ def get_rup_dic(dic, user=User(), approach='use_shakemap_from_usgs',
except ValueError as exc:
err = {"status": "failed", "error_msg": str(exc)}
return rup, rupdic, err

rup = convert_to_oq_rupture(rup_data)
if rup is None:
# in parsers_test for us6000jllz
Expand Down
5 changes: 4 additions & 1 deletion openquake/hazardlib/shakemap/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,13 +251,16 @@ def get_tmap_keys(exposure_hdf5, countries):


def impact_validate(POST, user, rupture_file=None, station_data_file=None,
download_usgs_stations=True,
monitor=performance.Monitor()):
"""
This is called by `impact_get_rupture_data` and `impact_run`.
In the first case the form contains only usgs_id and rupture_file and
returns (rup, rupdic, [station_file], error).
In the second case the form contains all fields and returns
(rup, rupdic, params, error).
Only in the former case, if stations have not been downloaded yet, we try to
download station data from the USGS
"""
err = {}
dic, params, err = _validate(POST)
Expand All @@ -275,7 +278,7 @@ def impact_validate(POST, user, rupture_file=None, station_data_file=None,

rup, rupdic, err = get_rup_dic(
dic, user, approach, use_shakemap, rupture_file, station_data_file,
monitor)
download_usgs_stations, monitor)
if err:
return None, None, None, err
# round floats
Expand Down
5 changes: 5 additions & 0 deletions openquake/server/static/css/engine.css
Original file line number Diff line number Diff line change
Expand Up @@ -475,3 +475,8 @@ table#impact-losses th td {
input[type="radio"] {
margin-right: 5px; /* Space between radio button and label text */
}

#clearStationDataFromUsgs {
margin-left: 40px;
margin-bottom: 8px;
}
17 changes: 7 additions & 10 deletions openquake/server/static/js/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,8 @@ function capitalizeFirstLetter(val) {
conversion_issues += '<p>' + data.error + '</p>';
$('#rupture_from_usgs_loaded').val('N.A. (conversion issue)');
}
$('#station_data_file').val(data.station_data_file);
// NOTE: these are stations downloaded from the USGS and not those uploaded by the user
$('#station_data_file_from_usgs').val(data.station_data_file);
if (data.station_data_issue) {
$('#station_data_file_loaded').val('N.A. (conversion issue)');
conversion_issues += '<p>' + data.station_data_issue + '</p>';
Expand Down Expand Up @@ -867,8 +868,11 @@ function capitalizeFirstLetter(val) {
});
$('#clearStationDataFile').click(function() {
$('#station_data_file_input').val('');
$('#maximum_distance_stations').val('');
$('#maximum_distance_stations').prop('disabled', true);
});
$('#clearStationDataFromUsgs').click(function() {
$('#station_data_file_from_usgs').val('');
$('#station_data_file_loaded').val('');
$('#station_data_file').val('');
});
$("#impact_run_form > input").click(function() {
$(this).css("background-color", "white");
Expand Down Expand Up @@ -937,13 +941,6 @@ function capitalizeFirstLetter(val) {
$("#impact_run_form > input").click(function() {
$(this).css("background-color", "white");
});
$('#station_data_file_input').on('change', function() {
if ($(this).get(0).files.length > 0) {
$('#maximum_distance_stations').prop('disabled', false);
} else {
$('#maximum_distance_stations').prop('disabled', true);
}
});
});
})($, Backbone, _, gem_oq_server_url);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,16 @@
<label for"station_data_file_from_usgs">{{ impact_form_labels.station_data_file_from_usgs }}</label>
<input class="impact-input" type="hidden" id="station_data_file_from_usgs" name="station_data_file_from_usgs" placeholder="{{ impact_form_placeholders.station_data_file_from_usgs }}" disabled />
<input class="impact-input" type="text" id="station_data_file_loaded" name="station_data_file_loaded" disabled />
<button type="button" id="clearStationDataFromUsgs">Clear Data</button>
</div>
<div class="impact_form_row hidden-for-shakemap hidden">
<label for"station_data_file">{{ impact_form_labels.station_data_file }}</label>
<input class="impact-input" type="file" id="station_data_file_input" name="station_data_file" placeholder="{{ impact_form_placeholders.station_data_file }}" {% if user_level != 2 %}disabled{% endif %}>
{% if user_level == 2 %}<button type="button" id="clearStationDataFile">Clear File</button>{% endif %}
<button type="button" id="clearStationDataFile">Clear File</button>
</div>
<div class="impact_form_row hidden-for-shakemap hidden">
<label for"maximum_distance_stations">{{ impact_form_labels.maximum_distance_stations }}</label>
<input class="impact-input" type="text" id="maximum_distance_stations" name="maximum_distance_stations" placeholder="{{ impact_form_placeholders.maximum_distance_stations }}" value="" disabled/>
<input class="impact-input" type="text" id="maximum_distance_stations" name="maximum_distance_stations" placeholder="{{ impact_form_placeholders.maximum_distance_stations }}" value=""/>
</div>
<div class="impact_form_row">
<button id="submit_impact_calc" type="submit" class="btn" disabled>Launch impact calculation</button>
Expand Down
15 changes: 12 additions & 3 deletions openquake/server/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -726,11 +726,13 @@ def impact_get_rupture_data(request):
a `django.http.HttpRequest` object containing usgs_id
"""
rupture_path = get_uploaded_file_path(request, 'rupture_file')
station_data_file = get_uploaded_file_path(request, 'station_data_file')
station_data_file = None
user = request.user
user.testdir = None
# NOTE: at this stage, attempt to download station data from USGS
rup, rupdic, _oqparams, err = impact_validate(
request.POST, user, rupture_path, station_data_file)
request.POST, user, rupture_path, station_data_file,
download_usgs_stations=True)
if err:
return HttpResponse(content=json.dumps(err), content_type=JSON,
status=400 if 'invalid_inputs' in err else 500)
Expand Down Expand Up @@ -783,10 +785,17 @@ def impact_run(request):
return HttpResponseForbidden()
rupture_path = get_uploaded_file_path(request, 'rupture_file')
station_data_file = get_uploaded_file_path(request, 'station_data_file')
station_data_file_from_usgs = request.POST.get('station_data_file_from_usgs', '')
# giving priority to the user-uploaded stations
if not station_data_file and station_data_file_from_usgs:
station_data_file = station_data_file_from_usgs
user = request.user
user.testdir = None
# at this stage, do not attempt to re-load station data from the USGS if they are
# missing or if the user explicitly decided to ignore them
_rup, rupdic, params, err = impact_validate(
request.POST, user, rupture_path, station_data_file)
request.POST, user, rupture_path, station_data_file,
download_usgs_stations=False)
if err:
return HttpResponse(content=json.dumps(err), content_type=JSON,
status=400 if 'invalid_inputs' in err else 500)
Expand Down

0 comments on commit 85de0d0

Please sign in to comment.