1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
5from __future__ import absolute_import, division
7import time
8import logging
10from pyrocko import util, model
11from pyrocko.util import urlopen_ssl_check
12from .base_catalog import EarthquakeCatalog
14logger = logging.getLogger('pyrocko.client.usgs')
16km = 1000.
19class USGS(EarthquakeCatalog):
21 def __init__(self, catalog=None):
22 self.catalog = catalog
23 self.events = {}
25 def flush(self):
26 self.events = {}
28 def iter_event_names(
29 self,
30 time_range=None,
31 magmin=0.,
32 magmax=10.,
33 latmin=-90.,
34 latmax=90.,
35 lonmin=-180.,
36 lonmax=180.):
38 yearbeg, monbeg, daybeg = time.gmtime(time_range[0])[:3]
39 yearend, monend, dayend = time.gmtime(time_range[1])[:3]
41 p = []
42 a = p.append
43 a('format=geojson')
44 if self.catalog is not None:
45 a('catalog=%s' % self.catalog.lower())
47 a('starttime=%s' % util.time_to_str(
48 time_range[0], format='%Y-%m-%dT%H:%M:%S'))
50 a('endtime=%s' % util.time_to_str(
51 time_range[1], format='%Y-%m-%dT%H:%M:%S'))
53 if latmin != -90.:
54 a('minlatitude=%g' % latmin)
55 if latmax != 90.:
56 a('maxlatitude=%g' % latmax)
57 if lonmin != -180.:
58 a('minlongitude=%g' % lonmin)
59 if lonmax != 180.:
60 a('maxlongitude=%g' % lonmax)
61 if magmin != 0.:
62 a('minmagnitude=%g' % magmin)
63 if magmax != 10.:
64 a('maxmagnitude=%g' % magmax)
66 url = 'https://earthquake.usgs.gov/fdsnws/event/1/query?' + '&'.join(p)
68 logger.debug('Opening URL: %s' % url)
69 page = urlopen_ssl_check(url).read()
70 logger.debug('Received page (%i bytes)' % len(page))
72 events = self._parse_events_page(page)
74 for ev in events:
75 self.events[ev.name] = ev
77 for ev in events:
78 if time_range[0] <= ev.time and ev.time <= time_range[1]:
79 yield ev.name
81 def _parse_events_page(self, page):
83 import json
84 doc = json.loads(page.decode('utf-8'))
86 events = []
87 for feat in doc['features']:
88 props = feat['properties']
89 geo = feat['geometry']
90 lon, lat, depth = [float(x) for x in geo['coordinates']]
91 t = util.str_to_time('1970-01-01 00:00:00') + \
92 props['time'] * 0.001
94 if props['mag'] is not None:
95 mag = float(props['mag'])
96 else:
97 mag = None
99 if props['place'] is not None:
100 region = props['place'].encode('ascii', 'replace').decode()
101 else:
102 region = None
104 catalog = str(props['net'].upper())
105 name = 'USGS-%s-' % catalog + util.time_to_str(
106 t, format='%Y-%m-%d_%H-%M-%S.3FRAC')
108 ev = model.Event(
109 lat=lat,
110 lon=lon,
111 time=t,
112 name=name,
113 depth=depth*1000.,
114 magnitude=mag,
115 region=region,
116 catalog=catalog)
118 events.append(ev)
120 return events
122 def get_event(self, name):
123 if name not in self.events:
124 t = self._name_to_date(name)
125 for name2 in self.iter_event_names(
126 time_range=(t-24*60*60, t+24*60*60)):
128 if name2 == name:
129 break
131 return self.events[name]
133 def _name_to_date(self, name):
134 ds = name[-23:]
135 t = util.str_to_time(ds, format='%Y-%m-%d_%H-%M-%S.3FRAC')
136 return t