1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
5from __future__ import absolute_import, division
7import logging
9from pyrocko import util
10from pyrocko.util import urlopen
11from pyrocko.io import quakeml
12from .base_catalog import EarthquakeCatalog
14logger = logging.getLogger('pyrocko.client.isc')
16km = 1000.
19class ISC(EarthquakeCatalog):
20 '''
21 Interfacing the catalog of the Internation Seismological Centre (ISC).
22 '''
24 def __init__(self, catalog=None):
25 self.events = {}
27 def flush(self):
28 self.events = {}
30 def append_time_params(self, a, time_range):
31 date_start_s, tstart_s = util.time_to_str(
32 time_range[0], format='%Y-%m-%d %H:%M:%S').split()
33 date_end_s, tend_s = util.time_to_str(
34 time_range[1], format='%Y-%m-%d %H:%M:%S').split()
35 date_start_s = date_start_s.split('-')
36 date_end_s = date_end_s.split('-')
38 a('start_year=%s' % date_start_s[0])
39 a('start_month=%s' % date_start_s[1])
40 a('start_day=%s' % date_start_s[2])
41 a('start_time=%s' % tstart_s)
43 a('end_year=%s' % date_end_s[0])
44 a('end_month=%s' % date_end_s[1])
45 a('end_day=%s' % date_end_s[2])
46 a('end_time=%s' % tend_s)
48 def iter_event_names(
49 self,
50 time_range=None,
51 magmin=None,
52 magmax=None,
53 latmin=-90.,
54 latmax=90.,
55 lonmin=-180.,
56 lonmax=180.):
57 p = []
58 a = p.append
60 a('out_format=CATQuakeML')
61 a('request=REVIEWED')
62 a('searchshape=RECT')
64 self.append_time_params(a, time_range)
66 if magmin:
67 a('min_mag=%g' % magmin)
68 if magmax:
69 a('max_mag=%g' % magmax)
71 a('bot_lat=%g' % latmin)
72 a('top_lat=%g' % latmax)
73 a('left_lon=%g' % lonmin)
74 a('right_lon=%g' % lonmax)
75 url = 'http://www.isc.ac.uk/cgi-bin/web-db-v4?' + '&'.join(p)
77 logger.debug('Opening URL: %s' % url)
78 page = urlopen(url).read().decode()
79 logger.debug('Received page (%i bytes)' % len(page))
81 if 'The search could not be run due to problems' in page:
82 logger.warn('%s\nurl: %s' % (page, url))
83 return
84 elif 'No events were found.' in page:
85 logger.info('No events were found.')
86 events = []
87 else:
88 data = quakeml.QuakeML.load_xml(string=page)
89 events = data.get_pyrocko_events()
91 for ev in events:
92 self.events[ev.name] = ev
94 for ev in events:
95 if time_range[0] <= ev.time and ev.time <= time_range[1]:
96 yield ev.name
98 def get_event(self, name):
99 if name not in self.events:
100 t = self._name_to_date(name)
101 for name2 in self.iter_event_names(
102 time_range=(t-24*60*60, t+24*60*60)):
104 if name2 == name:
105 break
107 return self.events[name]
109 def get_phase_markers(self, time_range, station_codes, phases):
110 '''
111 Download phase picks from ISC catalog and return them as a list
112 of `pyrocko.gui.PhaseMarker` instances.
114 :param time_range: Tuple with (tmin tmax)
115 :param station_codes: List with ISC station codes
116 (see http://www.isc.ac.uk/cgi-bin/stations?lista).
117 If `station_codes` is 'global', query all ISC stations.
118 :param phases: List of seismic phases. (e.g. ['P', 'PcP']
119 '''
121 p = []
122 a = p.append
124 a('out_format=QuakeML')
125 a('request=STNARRIVALS')
126 if station_codes == 'global':
127 a('stnsearch=GLOBAL')
128 else:
129 a('stnsearch=STN')
130 a('sta_list=%s' % ','.join(station_codes))
132 a('phaselist=%s' % ','.join(phases))
134 self.append_time_params(a, time_range)
136 url = 'http://www.isc.ac.uk/cgi-bin/web-db-v4?' + '&'.join(p)
138 logger.debug('Opening URL: %s' % url)
139 page = urlopen(url)
140 page = page.read().decode()
142 if 'No stations were found.' in page:
143 logger.info('No stations were found.')
144 return []
146 logger.debug('Received page (%i bytes)' % len(page))
148 data = quakeml.QuakeML.load_xml(string=page)
150 markers = data.get_pyrocko_phase_markers()
151 markers = self.replace_isc_codes(markers)
153 return markers
155 def replace_isc_codes(self, markers):
156 for m in markers:
157 new_nslc_ids = []
158 for (n, s, l_, c) in m.get_nslc_ids():
159 l_ = l_.replace('--', '')
160 c = c.replace('???', '*')
161 new_nslc_ids.append((n, s, l_, c))
162 m.nslc_ids = new_nslc_ids
164 return markers
166 def _name_to_date(self, name):
167 ds = name[-23:]
168 t = util.str_to_time(ds, format='%Y-%m-%d_%H-%M-%S.3FRAC')
169 return t