Skip to content

Commit def0bc8

Browse files
committed
added gcmt accessor from ISC API. Follows the same logic than comcat and bsi readers. Created test for an event search and summary info from a request.
1 parent c19ce9f commit def0bc8

File tree

3 files changed

+336
-76
lines changed

3 files changed

+336
-76
lines changed

csep/__init__.py

Lines changed: 98 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@
6161
'__version__'
6262
]
6363

64-
def load_stochastic_event_sets(filename, type='csv', format='native', **kwargs):
64+
65+
def load_stochastic_event_sets(filename, type='csv', format='native',
66+
**kwargs):
6567
""" General function to load stochastic event sets
6668
6769
This function returns a generator to iterate through a collection of catalogs.
@@ -106,7 +108,8 @@ def load_stochastic_event_sets(filename, type='csv', format='native', **kwargs):
106108
raise ValueError('format must be either "native" or "csep!')
107109

108110

109-
def load_catalog(filename, type='csep-csv', format='native', loader=None, apply_filters=False, **kwargs):
111+
def load_catalog(filename, type='csep-csv', format='native', loader=None,
112+
apply_filters=False, **kwargs):
110113
""" General function to load single catalog
111114
112115
See corresponding class documentation for additional parameters.
@@ -122,9 +125,12 @@ def load_catalog(filename, type='csep-csv', format='native', loader=None, apply_
122125
Returns (:class:`~csep.core.catalogs.AbstractBaseCatalog`)
123126
"""
124127

125-
126-
if type not in ('ucerf3', 'csep-csv', 'zmap', 'jma-csv', 'ingv_horus', 'ingv_emrcmt', 'ndk') and loader is None:
127-
raise ValueError("type must be one of the following: ('ucerf3', 'csep-csv', 'zmap', 'jma-csv', 'ndk', 'ingv_horus', 'ingv_emrcmt').")
128+
if type not in (
129+
'ucerf3', 'csep-csv', 'zmap', 'jma-csv', 'ingv_horus',
130+
'ingv_emrcmt',
131+
'ndk') and loader is None:
132+
raise ValueError(
133+
"type must be one of the following: ('ucerf3', 'csep-csv', 'zmap', 'jma-csv', 'ndk', 'ingv_horus', 'ingv_emrcmt').")
128134

129135
# map to correct catalog class, at some point these could be abstracted into configuration file
130136
# this maps a human readable string to the correct catalog class and the correct loader function
@@ -167,7 +173,8 @@ def load_catalog(filename, type='csep-csv', format='native', loader=None, apply_
167173
if loader is None:
168174
loader = class_loader_mapping[type]['loader']
169175

170-
catalog = catalog_class.load_catalog(filename=filename, loader=loader, **kwargs)
176+
catalog = catalog_class.load_catalog(filename=filename, loader=loader,
177+
**kwargs)
171178

172179
# convert to csep format if needed
173180
if format == 'native':
@@ -213,12 +220,15 @@ def query_comcat(start_time, end_time, min_magnitude=2.50,
213220
# Timezone should be in UTC
214221
t0 = time.time()
215222
eventlist = readers._query_comcat(start_time=start_time, end_time=end_time,
216-
min_magnitude=min_magnitude,
217-
min_latitude=min_latitude, max_latitude=max_latitude,
218-
min_longitude=min_longitude, max_longitude=max_longitude,
219-
max_depth=max_depth)
223+
min_magnitude=min_magnitude,
224+
min_latitude=min_latitude,
225+
max_latitude=max_latitude,
226+
min_longitude=min_longitude,
227+
max_longitude=max_longitude,
228+
max_depth=max_depth)
220229
t1 = time.time()
221-
comcat = catalogs.CSEPCatalog(data=eventlist, date_accessed=utc_now_datetime(), **kwargs)
230+
comcat = catalogs.CSEPCatalog(data=eventlist,
231+
date_accessed=utc_now_datetime(), **kwargs)
222232
print("Fetched ComCat catalog in {} seconds.\n".format(t1 - t0))
223233

224234
if apply_filters:
@@ -229,9 +239,13 @@ def query_comcat(start_time, end_time, min_magnitude=2.50,
229239

230240
if verbose:
231241
print("Downloaded catalog from ComCat with following parameters")
232-
print("Start Date: {}\nEnd Date: {}".format(str(comcat.start_time), str(comcat.end_time)))
233-
print("Min Latitude: {} and Max Latitude: {}".format(comcat.min_latitude, comcat.max_latitude))
234-
print("Min Longitude: {} and Max Longitude: {}".format(comcat.min_longitude, comcat.max_longitude))
242+
print("Start Date: {}\nEnd Date: {}".format(str(comcat.start_time),
243+
str(comcat.end_time)))
244+
print(
245+
"Min Latitude: {} and Max Latitude: {}".format(comcat.min_latitude,
246+
comcat.max_latitude))
247+
print("Min Longitude: {} and Max Longitude: {}".format(
248+
comcat.min_longitude, comcat.max_longitude))
235249
print("Min Magnitude: {}".format(comcat.min_magnitude))
236250
print(f"Found {comcat.event_count} events in the ComCat catalog.")
237251

@@ -266,11 +280,14 @@ def query_bsi(start_time, end_time, min_magnitude=2.50,
266280
t0 = time.time()
267281
eventlist = readers._query_bsi(start_time=start_time, end_time=end_time,
268282
min_magnitude=min_magnitude,
269-
min_latitude=min_latitude, max_latitude=max_latitude,
270-
min_longitude=min_longitude, max_longitude=max_longitude,
283+
min_latitude=min_latitude,
284+
max_latitude=max_latitude,
285+
min_longitude=min_longitude,
286+
max_longitude=max_longitude,
271287
max_depth=max_depth)
272288
t1 = time.time()
273-
bsi = catalogs.CSEPCatalog(data=eventlist, date_accessed=utc_now_datetime(), **kwargs)
289+
bsi = catalogs.CSEPCatalog(data=eventlist,
290+
date_accessed=utc_now_datetime(), **kwargs)
274291
print("Fetched BSI catalog in {} seconds.\n".format(t1 - t0))
275292

276293
if apply_filters:
@@ -280,10 +297,15 @@ def query_bsi(start_time, end_time, min_magnitude=2.50,
280297
bsi = bsi.filter()
281298

282299
if verbose:
283-
print("Downloaded catalog from Bollettino Sismico Italiano (BSI) with following parameters")
284-
print("Start Date: {}\nEnd Date: {}".format(str(bsi.start_time), str(bsi.end_time)))
285-
print("Min Latitude: {} and Max Latitude: {}".format(bsi.min_latitude, bsi.max_latitude))
286-
print("Min Longitude: {} and Max Longitude: {}".format(bsi.min_longitude, bsi.max_longitude))
300+
print(
301+
"Downloaded catalog from Bollettino Sismico Italiano (BSI) with following parameters")
302+
print("Start Date: {}\nEnd Date: {}".format(str(bsi.start_time),
303+
str(bsi.end_time)))
304+
print("Min Latitude: {} and Max Latitude: {}".format(bsi.min_latitude,
305+
bsi.max_latitude))
306+
print(
307+
"Min Longitude: {} and Max Longitude: {}".format(bsi.min_longitude,
308+
bsi.max_longitude))
287309
print("Min Magnitude: {}".format(bsi.min_magnitude))
288310
print(f"Found {bsi.event_count} events in the BSI catalog.")
289311

@@ -338,6 +360,41 @@ def query_gns(start_time, end_time, min_magnitude=2.950,
338360

339361
return gns
340362

363+
def query_gcmt(start_time, end_time, min_magnitude=5.0, min_depth=None,
364+
max_depth=None,
365+
catalog_id=None, verbose=True,
366+
min_latitude=None, max_latitude=None,
367+
min_longitude=None, max_longitude=None):
368+
if min_latitude:
369+
searchshape = 'RECT'
370+
else:
371+
searchshape = 'GLOBAL'
372+
events, creation_time = readers._query_gcmt(
373+
start_year=start_time.year,
374+
start_month=start_time.month,
375+
start_day=start_time.day,
376+
searchshape=searchshape,
377+
start_time=start_time.time().isoformat(),
378+
end_year=end_time.year,
379+
end_month=end_time.month,
380+
end_day=end_time.day,
381+
end_time=end_time.time().isoformat(),
382+
min_mag=min_magnitude,
383+
min_dep=min_depth,
384+
max_dep=max_depth,
385+
left_lon=min_longitude,
386+
right_lon=max_longitude,
387+
bot_lat=min_latitude,
388+
top_lat=max_latitude,
389+
verbose=verbose
390+
)
391+
catalog = catalogs.CSEPCatalog(data=events, name='ISC Bulletin - gCMT',
392+
catalog_id=catalog_id,
393+
date_accessed=creation_time)
394+
catalog.filter([f'magnitude >= {min_magnitude}'], in_place=True)
395+
return catalog
396+
397+
341398
def load_evaluation_result(fname):
342399
""" Load evaluation result stored as json file
343400
@@ -361,7 +418,8 @@ def load_evaluation_result(fname):
361418
evaluation_type = json_dict['type']
362419
except:
363420
evaluation_type = 'default'
364-
eval_result = evaluation_result_factory[evaluation_type].from_dict(json_dict)
421+
eval_result = evaluation_result_factory[evaluation_type].from_dict(
422+
json_dict)
365423
return eval_result
366424

367425

@@ -404,15 +462,18 @@ class with the region and magnitude members correctly assigned.
404462

405463
# sanity checks
406464
if not os.path.exists(fname):
407-
raise FileNotFoundError(f"Could not locate file {fname}. Unable to load forecast.")
465+
raise FileNotFoundError(
466+
f"Could not locate file {fname}. Unable to load forecast.")
408467
# sanity checks
409468
if loader is not None and not callable(loader):
410-
raise AttributeError("Loader must be callable. Unable to load forecast.")
469+
raise AttributeError(
470+
"Loader must be callable. Unable to load forecast.")
411471
extension = os.path.splitext(fname)[-1][1:]
412472
if extension not in forecast_loader_mapping.keys() and loader is None:
413-
raise AttributeError("File extension should be in ('dat','xml','h5','bin') if loader not provided.")
473+
raise AttributeError(
474+
"File extension should be in ('dat','xml','h5','bin') if loader not provided.")
414475

415-
if extension in ('xml','h5','bin'):
476+
if extension in ('xml', 'h5', 'bin'):
416477
raise NotImplementedError
417478

418479
# assign default loader
@@ -425,7 +486,8 @@ class with the region and magnitude members correctly assigned.
425486
return forecast
426487

427488

428-
def load_catalog_forecast(fname, catalog_loader=None, format='native', type='ascii', **kwargs):
489+
def load_catalog_forecast(fname, catalog_loader=None, format='native',
490+
type='ascii', **kwargs):
429491
""" General function to handle loading catalog forecasts.
430492
431493
Currently, just a simple wrapper, but can contain more complex logic in the future.
@@ -444,10 +506,12 @@ def load_catalog_forecast(fname, catalog_loader=None, format='native', type='asc
444506
"""
445507
# sanity checks
446508
if not os.path.exists(fname):
447-
raise FileNotFoundError(f"Could not locate file {fname}. Unable to load forecast.")
509+
raise FileNotFoundError(
510+
f"Could not locate file {fname}. Unable to load forecast.")
448511
# sanity checks
449512
if catalog_loader is not None and not callable(catalog_loader):
450-
raise AttributeError("Loader must be callable. Unable to load forecast.")
513+
raise AttributeError(
514+
"Loader must be callable. Unable to load forecast.")
451515
# factory methods for loading different types of catalogs
452516
catalog_loader_mapping = {
453517
'ascii': catalogs.CSEPCatalog.load_ascii_catalogs,
@@ -456,17 +520,18 @@ def load_catalog_forecast(fname, catalog_loader=None, format='native', type='asc
456520
if catalog_loader is None:
457521
catalog_loader = catalog_loader_mapping[type]
458522
# try and parse information from filename and send to forecast constructor
459-
if format == 'native' and type=='ascii':
523+
if format == 'native' and type == 'ascii':
460524
try:
461525
basename = str(os.path.basename(fname.rstrip('/')).split('.')[0])
462526
split_fname = basename.split('_')
463527
name = split_fname[0]
464-
start_time = strptime_to_utc_datetime(split_fname[1], format="%Y-%m-%dT%H-%M-%S-%f")
528+
start_time = strptime_to_utc_datetime(split_fname[1],
529+
format="%Y-%m-%dT%H-%M-%S-%f")
465530
# update kwargs
466531
_ = kwargs.setdefault('name', name)
467532
_ = kwargs.setdefault('start_time', start_time)
468533
except:
469534
pass
470535
# create observed_catalog forecast
471-
return CatalogForecast(filename=fname, loader=catalog_loader, catalog_format=format, catalog_type=type, **kwargs)
472-
536+
return CatalogForecast(filename=fname, loader=catalog_loader,
537+
catalog_format=format, catalog_type=type, **kwargs)

0 commit comments

Comments
 (0)