1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6import time
7import logging
9from pyrocko import util, model
10from pyrocko.util import urlopen_ssl_check
11from .base_catalog import EarthquakeCatalog
13logger = logging.getLogger('pyrocko.client.usgs')
15km = 1000.
18class USGS(EarthquakeCatalog):
20 def __init__(self, catalog=None):
21 self.catalog = catalog
22 self.events = {}
24 def flush(self):
25 self.events = {}
27 def iter_event_names(
28 self,
29 time_range=None,
30 magmin=0.,
31 magmax=10.,
32 latmin=-90.,
33 latmax=90.,
34 lonmin=-180.,
35 lonmax=180.):
37 yearbeg, monbeg, daybeg = time.gmtime(time_range[0])[:3]
38 yearend, monend, dayend = time.gmtime(time_range[1])[:3]
40 p = []
41 a = p.append
42 a('format=geojson')
43 if self.catalog is not None:
44 a('catalog=%s' % self.catalog.lower())
46 a('starttime=%s' % util.time_to_str(
47 time_range[0], format='%Y-%m-%dT%H:%M:%S'))
49 a('endtime=%s' % util.time_to_str(
50 time_range[1], format='%Y-%m-%dT%H:%M:%S'))
52 if latmin != -90.:
53 a('minlatitude=%g' % latmin)
54 if latmax != 90.:
55 a('maxlatitude=%g' % latmax)
56 if lonmin != -180.:
57 a('minlongitude=%g' % lonmin)
58 if lonmax != 180.:
59 a('maxlongitude=%g' % lonmax)
60 if magmin != 0.:
61 a('minmagnitude=%g' % magmin)
62 if magmax != 10.:
63 a('maxmagnitude=%g' % magmax)
65 url = 'https://earthquake.usgs.gov/fdsnws/event/1/query?' + '&'.join(p)
67 logger.debug('Opening URL: %s' % url)
68 page = urlopen_ssl_check(url).read()
69 logger.debug('Received page (%i bytes)' % len(page))
71 events = self._parse_events_page(page)
73 for ev in events:
74 self.events[ev.name] = ev
76 for ev in events:
77 if time_range[0] <= ev.time and ev.time <= time_range[1]:
78 yield ev.name
80 def _parse_events_page(self, page):
82 import json
83 doc = json.loads(page.decode('utf-8'))
85 events = []
86 for feat in doc['features']:
87 props = feat['properties']
88 geo = feat['geometry']
89 lon, lat, depth = [float(x) for x in geo['coordinates']]
90 t = util.str_to_time('1970-01-01 00:00:00') + \
91 props['time'] * 0.001
93 if props['mag'] is not None:
94 mag = float(props['mag'])
95 else:
96 mag = None
98 if props['place'] is not None:
99 region = props['place'].encode('ascii', 'replace').decode()
100 else:
101 region = None
103 catalog = str(props['net'].upper())
104 name = 'USGS-%s-' % catalog + util.time_to_str(
105 t, format='%Y-%m-%d_%H-%M-%S.3FRAC')
107 ev = model.Event(
108 lat=lat,
109 lon=lon,
110 time=t,
111 name=name,
112 depth=depth*1000.,
113 magnitude=mag,
114 region=region,
115 catalog=catalog)
117 events.append(ev)
119 return events
121 def get_event(self, name):
122 if name not in self.events:
123 t = self._name_to_date(name)
124 for name2 in self.iter_event_names(
125 time_range=(t-24*60*60, t+24*60*60)):
127 if name2 == name:
128 break
130 return self.events[name]
132 def _name_to_date(self, name):
133 ds = name[-23:]
134 t = util.str_to_time(ds, format='%Y-%m-%d_%H-%M-%S.3FRAC')
135 return t