Source code for pyrocko.client.isc
# http://pyrocko.org - GPLv3
#
# The Pyrocko Developers, 21st Century
# ---|P------/S----------~Lg----------
'''
Client to get earthquake catalog information from
`ISC <http://www.isc.ac.uk/>`_.
'''
import logging
import re
from pyrocko import util
from pyrocko.util import urlopen
from pyrocko.io import quakeml
from .base_catalog import EarthquakeCatalog
logger = logging.getLogger('pyrocko.client.isc')
km = 1000.
class ISCError(Exception):
pass
class ISCBlocked(ISCError):
pass
[docs]class ISC(EarthquakeCatalog):
'''
Interfacing the catalog of the Internation Seismological Centre (ISC).
'''
def __init__(self, catalog=None):
self.events = {}
def flush(self):
self.events = {}
def append_time_params(self, a, time_range):
date_start_s, tstart_s = util.time_to_str(
time_range[0], format='%Y-%m-%d %H:%M:%S').split()
date_end_s, tend_s = util.time_to_str(
time_range[1], format='%Y-%m-%d %H:%M:%S').split()
date_start_s = date_start_s.split('-')
date_end_s = date_end_s.split('-')
a('start_year=%s' % date_start_s[0])
a('start_month=%s' % date_start_s[1])
a('start_day=%s' % date_start_s[2])
a('start_time=%s' % tstart_s)
a('end_year=%s' % date_end_s[0])
a('end_month=%s' % date_end_s[1])
a('end_day=%s' % date_end_s[2])
a('end_time=%s' % tend_s)
def iter_event_names(
self,
time_range=None,
magmin=None,
magmax=None,
latmin=-90.,
latmax=90.,
lonmin=-180.,
lonmax=180.):
p = []
a = p.append
a('out_format=CATQuakeML')
a('request=REVIEWED')
a('searchshape=RECT')
self.append_time_params(a, time_range)
if magmin:
a('min_mag=%g' % magmin)
if magmax:
a('max_mag=%g' % magmax)
a('bot_lat=%g' % latmin)
a('top_lat=%g' % latmax)
a('left_lon=%g' % lonmin)
a('right_lon=%g' % lonmax)
url = 'http://www.isc.ac.uk/cgi-bin/web-db-v4?' + '&'.join(p)
logger.debug('Opening URL: %s' % url)
page = urlopen(url).read().decode()
logger.debug('Received page (%i bytes)' % len(page))
if 'The search could not be run due to problems' in page:
logger.warning('%s\nurl: %s' % (page, url))
return
elif 'No events were found.' in page:
logger.info('No events were found.')
events = []
else:
try:
data = quakeml.QuakeML.load_xml(string=page)
except Exception:
if page[:500].find(
'Please try again in a few minutes') != -1:
raise ISCBlocked(
'Apparently, we have queried ISC too eagerly:\n'
+ '-' * 79 + '\n' + page + '\n' + '-' * 79)
else:
raise ISCError(
"Couldn't parse XML results from ISC:\n"
+ '-' * 79 + '\n' + page + '\n' + '-' * 79)
events = data.get_pyrocko_events()
for ev in events:
self.events[ev.name] = ev
for ev in events:
if time_range[0] <= ev.time and ev.time <= time_range[1]:
yield ev.name
def get_event(self, name):
if name not in self.events:
t = self._name_to_date(name)
for name2 in self.iter_event_names(
time_range=(t-24*60*60, t+24*60*60)):
if name2 == name:
break
return self.events[name]
[docs] def get_phase_markers(self, time_range, station_codes, phases):
'''
Download phase picks from ISC catalog and return them as a list
of `pyrocko.gui.PhaseMarker` instances.
:param time_range: Tuple with (tmin tmax)
:param station_codes: List with ISC station codes
(see http://www.isc.ac.uk/cgi-bin/stations?lista).
If `station_codes` is 'global', query all ISC stations.
:param phases: List of seismic phases. (e.g. ['P', 'PcP']
'''
p = []
a = p.append
a('out_format=QuakeML')
a('request=STNARRIVALS')
if station_codes == 'global':
a('stnsearch=GLOBAL')
else:
a('stnsearch=STN')
a('sta_list=%s' % ','.join(station_codes))
a('phaselist=%s' % ','.join(phases))
self.append_time_params(a, time_range)
url = 'http://www.isc.ac.uk/cgi-bin/web-db-v4?' + '&'.join(p)
logger.debug('Opening URL: %s' % url)
page = urlopen(url)
page = page.read().decode()
if 'No stations were found.' in page:
logger.info('No stations were found.')
return []
logger.debug('Received page (%i bytes)' % len(page))
if -1 != page.find(
'Sorry, but your request cannot be processed at the present '
'time'):
raise ISCBlocked(
'Apparently, we have queried ISC too eagerly:\n'
+ '-' * 79 + '\n' + re.sub(r'<[^>]+>', ' ', page)
+ '\n' + '-' * 79)
data = quakeml.QuakeML.load_xml(string=page)
markers = data.get_pyrocko_phase_markers()
markers = self.replace_isc_codes(markers)
return markers
def replace_isc_codes(self, markers):
for m in markers:
new_nslc_ids = []
for (n, s, l_, c) in m.get_nslc_ids():
l_ = l_.replace('--', '')
c = c.replace('???', '*')
new_nslc_ids.append((n, s, l_, c))
m.nslc_ids = new_nslc_ids
return markers
def _name_to_date(self, name):
ds = name[-23:]
t = util.str_to_time(ds, format='%Y-%m-%d_%H-%M-%S.3FRAC')
return t