diff --git a/.github/workflows/demos_ltr_latest.yml b/.github/workflows/demos_ltr_latest.yml index f3915e758ba..31a252d35a6 100644 --- a/.github/workflows/demos_ltr_latest.yml +++ b/.github/workflows/demos_ltr_latest.yml @@ -9,7 +9,7 @@ on: required: true push: # TODO: it would be better to point to ltr and latest - branches: [ engine-3.16, engine-3.17, engine-3.18, engine-3.19, engine-3.20, engine-3.21, engine-3.22 ] + branches: [ engine-3.16, engine-3.17, engine-3.18, engine-3.19, engine-3.20, engine-3.21, engine-3.22, engine-3.23 ] jobs: demos: runs-on: ubuntu-latest diff --git a/openquake/hazardlib/shakemap/parsers.py b/openquake/hazardlib/shakemap/parsers.py index ab45c916ea2..cdaafbd82ad 100644 --- a/openquake/hazardlib/shakemap/parsers.py +++ b/openquake/hazardlib/shakemap/parsers.py @@ -773,7 +773,7 @@ def _get_rup_from_json(usgs_id, rupture_file, station_data_file): return rup, rupdic, rup_data -def get_rup_dic(dic, user=User(), approach='use_shakemap_from_usgs', +def get_rup_dic(dic, user=User(), use_shakemap=False, rupture_file=None, station_data_file=None, download_usgs_stations=True, monitor=performance.Monitor()): @@ -787,8 +787,6 @@ def get_rup_dic(dic, user=User(), approach='use_shakemap_from_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 @@ -800,6 +798,7 @@ def get_rup_dic(dic, user=User(), approach='use_shakemap_from_usgs', rup_data = {} err = {} usgs_id = dic['usgs_id'] + approach = dic['approach'] rup = None if approach == 'provide_rup_params': rupdic = dic.copy() @@ -811,7 +810,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 - if rupture_file: if rupture_file.endswith('.xml'): rup, rupdic, err = _get_rup_dic_from_xml( @@ -828,9 +826,19 @@ def get_rup_dic(dic, user=User(), approach='use_shakemap_from_usgs', if err: return None, None, err if approach in ['use_pnt_rup_from_usgs', 'build_rup_from_usgs']: - rupdic, err = load_rupdic_from_origin(usgs_id, properties['products']) - if err: - return None, None, err + if dic.get('lon', None) is None: # don't override user-inserted values + rupdic, err = load_rupdic_from_origin(usgs_id, properties['products']) + if err: + return None, None, err + if approach == 'build_rup_from_usgs': + rupdic['nodal_planes'], err = _get_nodal_planes(properties) + if err: + return None, None, err + else: + rupdic.update(rupdic['nodal_planes']['NP1']) + else: + rupdic = dic.copy() + rupdic['require_dip_strike'] = True elif ('download/rupture.json' not in contents or approach == 'use_finite_rup_from_usgs'): # happens for us6000f65h in parsers_test @@ -839,18 +847,10 @@ def get_rup_dic(dic, user=User(), approach='use_shakemap_from_usgs', if err: return None, None, err - if approach == 'build_rup_from_usgs': - rupdic['nodal_planes'], err = _get_nodal_planes(properties) - rupdic['aspect_ratio'] = dic['aspect_ratio'] - rupdic['msr'] = dic['msr'] - if err: - return None, rupdic, err - if not rup_data and approach not in ['use_pnt_rup_from_usgs', 'build_rup_from_usgs']: with monitor('Downloading rupture json'): - rup_data, rupture_file = download_rupture_data( - usgs_id, contents, user) + rup_data, rupture_file = download_rupture_data(usgs_id, contents, user) if not rupdic: rupdic = convert_rup_data(rup_data, usgs_id, rupture_file, shakemap) if (approach != 'use_shakemap_from_usgs' and not station_data_file diff --git a/openquake/hazardlib/shakemap/validate.py b/openquake/hazardlib/shakemap/validate.py index 85b14f78947..cf8a39693cd 100644 --- a/openquake/hazardlib/shakemap/validate.py +++ b/openquake/hazardlib/shakemap/validate.py @@ -163,11 +163,18 @@ def get_oqparams(self, usgs_id, mosaic_models, trts, use_shakemap): } validators = { + 'approach': valid.Choice('use_shakemap_from_usgs', + 'use_pnt_rup_from_usgs', + 'build_rup_from_usgs', + 'use_finite_rup_from_usgs', + 'provide_rup', + 'provide_rup_params'), 'usgs_id': valid.simple_id, 'lon': valid.longitude, 'lat': valid.latitude, 'dep': valid.positivefloat, 'mag': valid.positivefloat, + 'msr': valid.utf8, 'aspect_ratio': valid.positivefloat, 'rake': valid.rake_range, 'dip': valid.dip_range, @@ -190,7 +197,7 @@ def _validate(POST): validation_errs = {} invalid_inputs = [] params = {} - dic = dict(usgs_id=None, lon=None, lat=None, dep=None, + dic = dict(approach=None, usgs_id=None, lon=None, lat=None, dep=None, mag=None, msr=None, aspect_ratio=None, rake=None, dip=None, strike=None) for field, validation_func in validators.items(): if field not in POST: @@ -198,7 +205,7 @@ def _validate(POST): try: value = validation_func(POST.get(field)) except Exception as exc: - blankable = ['dip', 'strike', + blankable = ['dip', 'strike', 'msr', 'maximum_distance_stations', 'local_timestamp'] if field in blankable and POST.get(field) == '': if field in dic: @@ -272,12 +279,9 @@ def impact_validate(POST, user, rupture_file=None, station_data_file=None, use_shakemap = user.level == 1 if 'use_shakemap' in POST: use_shakemap = POST['use_shakemap'] == 'true' - approach = POST['approach'] - if approach == 'build_rup_from_usgs': - dic['msr'] = POST['msr'] rup, rupdic, err = get_rup_dic( - dic, user, approach, use_shakemap, rupture_file, station_data_file, + dic, user, use_shakemap, rupture_file, station_data_file, download_usgs_stations, monitor) if err: return None, None, None, err diff --git a/openquake/hazardlib/tests/shakemap/parsers_test.py b/openquake/hazardlib/tests/shakemap/parsers_test.py index a394f33e9fb..537275e4d73 100644 --- a/openquake/hazardlib/tests/shakemap/parsers_test.py +++ b/openquake/hazardlib/tests/shakemap/parsers_test.py @@ -41,25 +41,25 @@ def test_utc_to_local_time(self): def test_1(self): # wrong usgs_id _rup, _rupdic, err = get_rup_dic( - {'usgs_id': 'usp0001cc'}, User(level=2, testdir=''), - 'use_shakemap_from_usgs', use_shakemap=True) + {'usgs_id': 'usp0001cc', 'approach': 'use_shakemap_from_usgs'}, + User(level=2, testdir=''), use_shakemap=True) self.assertIn('Unable to download from https://earthquake.usgs.gov/fdsnws/' 'event/1/query?eventid=usp0001cc&', err['error_msg']) def test_2(self): _rup, dic, _err = get_rup_dic( - {'usgs_id': 'usp0001ccb'}, user=user, approach='use_shakemap_from_usgs', - use_shakemap=True) + {'usgs_id': 'usp0001ccb', 'approach': 'use_shakemap_from_usgs'}, + user=user, use_shakemap=True) self.assertIsNotNone(dic['shakemap_array']) _rup, dic, _err = get_rup_dic( - {'usgs_id': 'usp0001ccb'}, user=user, approach='use_shakemap_from_usgs', - use_shakemap=False) + {'usgs_id': 'usp0001ccb', 'approach': 'use_shakemap_from_usgs'}, + user=user, use_shakemap=False) self.assertIsNone(dic['shakemap_array']) def test_3(self): _rup, dic, _err = get_rup_dic( - {'usgs_id': 'us6000f65h'}, user=user, approach='use_pnt_rup_from_usgs', - use_shakemap=True) + {'usgs_id': 'us6000f65h', 'approach': 'use_pnt_rup_from_usgs'}, + user=user, use_shakemap=True) self.assertEqual(dic['lon'], -73.4822) self.assertEqual(dic['lat'], 18.4335) self.assertEqual(dic['dep'], 10.0) @@ -78,8 +78,8 @@ def test_3(self): def test_4(self): # point_rup _rup, dic, _err = get_rup_dic( - {'usgs_id': 'us6000jllz'}, user=user, approach='use_shakemap_from_usgs', - use_shakemap=True) + {'usgs_id': 'us6000jllz', 'approach': 'use_shakemap_from_usgs'}, + user=user, use_shakemap=True) self.assertEqual(dic['lon'], 37.0143) self.assertEqual(dic['lat'], 37.2256) self.assertEqual(dic['dep'], 10.) @@ -88,8 +88,8 @@ def test_4(self): def test_5(self): # 12 vertices instead of 4 in rupture.json rup, dic, _err = get_rup_dic( - {'usgs_id': 'us20002926'}, user=user, approach='use_shakemap_from_usgs', - use_shakemap=True) + {'usgs_id': 'us20002926', 'approach': 'use_shakemap_from_usgs'}, + user=user, use_shakemap=True) self.assertIsNone(rup) self.assertEqual(dic['require_dip_strike'], True) self.assertEqual(dic['rupture_issue'], @@ -97,8 +97,8 @@ def test_5(self): def test_6(self): _rup, dic, _err = get_rup_dic( - {'usgs_id': 'usp0001ccb'}, user=user, approach='use_pnt_rup_from_usgs', - use_shakemap=True) + {'usgs_id': 'usp0001ccb', 'approach': 'use_pnt_rup_from_usgs'}, + user=user, use_shakemap=True) self.assertEqual(dic['mag'], 6.7) self.assertEqual(dic['require_dip_strike'], True) self.assertEqual(dic['station_data_issue'], @@ -106,26 +106,58 @@ def test_6(self): def test_7(self): dic_in = {'usgs_id': 'us6000jllz', 'lon': None, 'lat': None, 'dep': None, - 'mag': None, 'msr': '', 'aspect_ratio': 2.0, 'rake': None, - 'dip': None, 'strike': None} - _rup, dic, _err = get_rup_dic( - dic_in, user=user, approach='build_rup_from_usgs', use_shakemap=True) + 'mag': None, 'msr': '', 'aspect_ratio': 2, 'rake': None, + 'dip': None, 'strike': None, 'approach': 'build_rup_from_usgs'} + _rup, dic, _err = get_rup_dic(dic_in, user=user, use_shakemap=True) self.assertEqual( dic['nodal_planes'], {'NP1': {'dip': 88.71, 'rake': -179.18, 'strike': 317.63}, 'NP2': {'dip': 89.18, 'rake': -1.29, 'strike': 227.61}}) - self.assertEqual(dic['msr'], '') - self.assertEqual(dic['aspect_ratio'], 2.0) def test_8(self): dic_in = {'usgs_id': 'us6000jllz', 'lon': 37.0143, 'lat': 37.2256, - 'dep': 10.0, 'mag': 7.8, 'rake': 0.0} - rup, dic, _err = get_rup_dic( - dic_in, user=user, approach='use_pnt_rup_from_usgs', use_shakemap=True) + 'dep': 10.0, 'mag': 7.8, 'rake': 0.0, + 'approach': 'use_pnt_rup_from_usgs'} + rup, dic, _err = get_rup_dic(dic_in, user=user, use_shakemap=True) self.assertEqual(dic['msr'], 'PointMSR') self.assertAlmostEqual(rup.surface.length, 0.0133224) self.assertAlmostEqual(rup.surface.width, 0.0070800) + def test_9(self): + dic_in = {'usgs_id': 'us6000jllz', 'lon': 37.0143, 'lat': 37.2256, 'dep': 10, + 'mag': 7.8, 'msr': 'WC1994', 'aspect_ratio': 3, + 'rake': -179.18, 'dip': 88.71, 'strike': 317.63, + 'approach': 'build_rup_from_usgs'} + _rup, dic, _err = get_rup_dic(dic_in, user=user, use_shakemap=True) + self.assertEqual(dic['dep'], 10) + self.assertEqual(dic['dip'], 88.71) + self.assertEqual(dic['lat'], 37.2256) + self.assertEqual(dic['lon'], 37.0143) + self.assertEqual(dic['mag'], 7.8) + self.assertEqual(dic['msr'], 'WC1994') + self.assertEqual(dic['rake'], -179.18) + self.assertEqual(dic['strike'], 317.63) + self.assertEqual(dic['require_dip_strike'], True) + self.assertEqual(dic['aspect_ratio'], 3) + + def test_10(self): + dic_in = {'usgs_id': 'us6000jllz', 'lon': 37.0143, 'lat': 37.2256, 'dep': 10.0, + 'mag': 7.8, 'msr': 'WC1994', 'aspect_ratio': 2.0, + 'rake': -179.18, 'dip': 88.71, 'strike': 317.63, + 'approach': 'build_rup_from_usgs'} + _rup, _dic, err = get_rup_dic( + dic_in, user=user, use_shakemap=True) + self.assertIn('The depth must be greater', err['error_msg']) + + def test_11(self): + dic_in = {'usgs_id': 'UserProvided', 'lon': -9, 'lat': 43, 'dep': 10, + 'mag': 8.5, 'msr': 'WC1994', 'aspect_ratio': 1, + 'rake': 90, 'dip': 90, 'strike': 0, + 'approach': 'provide_rup_params'} + _rup, _dic, err = get_rup_dic( + dic_in, user=user, use_shakemap=False) + self.assertIn('The depth must be greater', err['error_msg']) + """ NB: to profile a test you can use diff --git a/openquake/hazardlib/tests/shakemap/validate_test.py b/openquake/hazardlib/tests/shakemap/validate_test.py index 2f97c2c13b6..a1da1d507a6 100644 --- a/openquake/hazardlib/tests/shakemap/validate_test.py +++ b/openquake/hazardlib/tests/shakemap/validate_test.py @@ -61,13 +61,6 @@ def test_1b(self): self.assertIn('stations', rupdic['station_data_file']) self.assertEqual(err, {}) - def test_1c(self): - # giving a ValueError with aspect_ratio 2 - POST = {'usgs_id': 'us6000jllz', 'approach': 'build_rup_from_usgs', - 'msr': 'WC1994', 'aspect_ratio': '2'} - _rup, _rupdic, _params, err = impact_validate(POST, user) - self.assertIn('The depth must be greater', err['error_msg']) - def test_2(self): POST = {'usgs_id': 'us7000n05d', 'approach': 'build_rup_from_usgs', 'msr': ''} diff --git a/openquake/server/static/js/engine.js b/openquake/server/static/js/engine.js index b51c45ee880..6b11df97ff2 100644 --- a/openquake/server/static/js/engine.js +++ b/openquake/server/static/js/engine.js @@ -751,8 +751,6 @@ function capitalizeFirstLetter(val) { else if (data.require_dip_strike) { $('#dip').prop('disabled', false); $('#strike').prop('disabled', false); - $('#dip').val('90'); - $('#strike').val('0'); } else { $('#dip').prop('disabled', true); $('#strike').prop('disabled', true);