Skip to content

Commit

Permalink
Merge pull request #10412 from gem/conversionerr
Browse files Browse the repository at this point in the history
Provide a clearer error message in case the rupture can not be converted from the USGS format
  • Loading branch information
ptormene authored Mar 5, 2025
2 parents c15b506 + df7869b commit eb3f509
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 14 deletions.
10 changes: 7 additions & 3 deletions openquake/commonlib/readinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,9 @@ def get_rupture(oqparam):
elif rupture_model and rupture_model.endswith('.json'):
with open(rupture_model) as f:
rup_data = json.load(f)
rup = convert_to_oq_rupture(rup_data)
rup, err_msg = convert_to_oq_rupture(rup_data)
if err_msg:
logging.warning(err_msg)
if rup is None: # assume rupture_dict
rup = build_planar_rupture_from_dict(oqparam.rupture_dict)
return rup
Expand Down Expand Up @@ -1022,7 +1024,8 @@ def _cons_coeffs(df, perils, loss_dt, limit_states):
if len(the_df) == 1:
coeffs[peril][loss_type] = the_df[limit_states].to_numpy()[0]
elif len(the_df) > 1:
raise ValueError(f'Multiple consequences for {loss_type=}, {peril=}\n%s' % the_df)
raise ValueError(
f'Multiple consequences for {loss_type=}, {peril=}\n%s' % the_df)
return coeffs


Expand Down Expand Up @@ -1339,7 +1342,8 @@ def _taxonomy_mapping(filename, taxidx):
if 'conversion' in tmap_df.columns:
# conversion was the old name in the header for engine <= 3.12
tmap_df = tmap_df.rename(columns={'conversion': 'risk_id'})
assert set(tmap_df) == {'country', 'peril', 'taxonomy', 'risk_id', 'weight'}, set(tmap_df)
assert set(tmap_df) == {'country', 'peril', 'taxonomy',
'risk_id', 'weight'}, set(tmap_df)
taxos = set()
for (taxo, per), df in tmap_df.groupby(['taxonomy', 'peril']):
taxos.add(taxo)
Expand Down
28 changes: 19 additions & 9 deletions openquake/hazardlib/shakemap/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ def convert_to_oq_rupture(rup_json):
"""
Convert USGS json (output of download_rupture_data) into an hazardlib rupture
:returns: None if not convertible
:returns: a openquake.hazardlib.source.rupture.BaseRupture object if convertible and
an error message if not convertible
"""
ftype = rup_json['features'][0]['geometry']['type']
multicoords = rup_json['features'][0]['geometry']['coordinates'][0]
Expand All @@ -235,7 +236,14 @@ def convert_to_oq_rupture(rup_json):
trt = 'Active Shallow Crust' if hyp_depth < 50 else 'Subduction IntraSlab'
mag = rup_json['metadata']['mag']
rup = get_multiplanar(multicoords, mag, rake, trt)
return rup
return rup, None
else:
if ftype != 'MultiPolygon':
reason = f'only MultiPolygon geometries are accepted (not {ftype})'
else:
reason = 'at least one surface is not rectangular'
err_msg = f'Unable to convert the rupture from the USGS format: {reason}'
return None, err_msg


def utc_to_local_time(utc_timestamp, lon, lat):
Expand Down Expand Up @@ -379,7 +387,7 @@ def usgs_stations_to_oq_format(stations, exclude_imts=(), seismic_only=False):
imts = []
for col in stations.columns:
if ('_VALUE' in col or '_LN_SIGMA' in col or
'_STDDEV' in col and col != 'DISTANCE_STDDEV'):
'_STDDEV' in col and col != 'DISTANCE_STDDEV'):
imt = col.split('_')[0]
if imt not in exclude_imts:
assert col not in imts
Expand Down Expand Up @@ -779,8 +787,8 @@ def _get_rup_from_json(usgs_id, rupture_file, station_data_file):
if usgs_id == 'FromFile':
rupdic = convert_rup_data(rup_data, usgs_id, rupture_file)
rupdic['station_data_file'] = station_data_file
rup = convert_to_oq_rupture(rup_data)
return rup, rupdic, rup_data
rup, err_msg = convert_to_oq_rupture(rup_data)
return rup, rupdic, rup_data, err_msg


def get_rup_dic(dic, user=User(),
Expand Down Expand Up @@ -824,8 +832,10 @@ def get_rup_dic(dic, user=User(),
rup, rupdic, err = _get_rup_dic_from_xml(
usgs_id, user, rupture_file, station_data_file)
elif rupture_file.endswith('.json'):
rup, rupdic, rup_data = _get_rup_from_json(usgs_id, rupture_file,
station_data_file)
rup, rupdic, rup_data, err_msg = _get_rup_from_json(
usgs_id, rupture_file, station_data_file)
if err_msg:
err = {"status": "failed", "error_msg": err_msg}
if err or usgs_id == 'FromFile':
return rup, rupdic, err
assert usgs_id
Expand Down Expand Up @@ -885,10 +895,10 @@ def get_rup_dic(dic, user=User(),
except ValueError as exc:
err = {"status": "failed", "error_msg": str(exc)}
return rup, rupdic, err
rup = convert_to_oq_rupture(rup_data)
rup, err_msg = convert_to_oq_rupture(rup_data)
if rup is None:
# in parsers_test for us6000jllz
rupdic['rupture_issue'] = 'Unable to convert the rupture from the USGS format'
rupdic['rupture_issue'] = err_msg
rupdic['require_dip_strike'] = True
# in parsers_test for usp0001ccb
return rup, rupdic, err
Expand Down
5 changes: 3 additions & 2 deletions openquake/hazardlib/tests/shakemap/parsers_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,9 @@ def test_5(self):
user=user, use_shakemap=True)
self.assertIsNone(rup)
self.assertEqual(dic['require_dip_strike'], True)
self.assertEqual(dic['rupture_issue'],
'Unable to convert the rupture from the USGS format')
rupture_issue = ('Unable to convert the rupture from the USGS format: at'
' least one surface is not rectangular')
self.assertEqual(dic['rupture_issue'], rupture_issue)

def test_6(self):
_rup, dic, _err = get_rup_dic(
Expand Down

0 comments on commit eb3f509

Please sign in to comment.