Coverage for /usr/local/lib/python3.11/dist-packages/pyrocko/client/usgs.py: 90%
77 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-10-06 15:01 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2023-10-06 15:01 +0000
1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6'''
7Client to get earthquake catalog information from
8`USGS <https://earthquake.usgs.gov/>`_.
9'''
11import time
12import logging
14from pyrocko import util, model
15from pyrocko.util import urlopen_ssl_check
16from .base_catalog import EarthquakeCatalog
18logger = logging.getLogger('pyrocko.client.usgs')
20km = 1000.
23class USGS(EarthquakeCatalog):
24 '''
25 Client to get earthquake catalog information from
26 `USGS <https://earthquake.usgs.gov/>`_.
27 '''
29 def __init__(self, catalog=None):
30 self.catalog = catalog
31 self.events = {}
33 def flush(self):
34 self.events = {}
36 def iter_event_names(
37 self,
38 time_range=None,
39 magmin=0.,
40 magmax=10.,
41 latmin=-90.,
42 latmax=90.,
43 lonmin=-180.,
44 lonmax=180.):
46 yearbeg, monbeg, daybeg = time.gmtime(time_range[0])[:3]
47 yearend, monend, dayend = time.gmtime(time_range[1])[:3]
49 p = []
50 a = p.append
51 a('format=geojson')
52 if self.catalog is not None:
53 a('catalog=%s' % self.catalog.lower())
55 a('starttime=%s' % util.time_to_str(
56 time_range[0], format='%Y-%m-%dT%H:%M:%S'))
58 a('endtime=%s' % util.time_to_str(
59 time_range[1], format='%Y-%m-%dT%H:%M:%S'))
61 if latmin != -90.:
62 a('minlatitude=%g' % latmin)
63 if latmax != 90.:
64 a('maxlatitude=%g' % latmax)
65 if lonmin != -180.:
66 a('minlongitude=%g' % lonmin)
67 if lonmax != 180.:
68 a('maxlongitude=%g' % lonmax)
69 if magmin != 0.:
70 a('minmagnitude=%g' % magmin)
71 if magmax != 10.:
72 a('maxmagnitude=%g' % magmax)
74 url = 'https://earthquake.usgs.gov/fdsnws/event/1/query?' + '&'.join(p)
76 logger.debug('Opening URL: %s' % url)
77 page = urlopen_ssl_check(url).read()
78 logger.debug('Received page (%i bytes)' % len(page))
80 events = self._parse_events_page(page)
82 for ev in events:
83 self.events[ev.name] = ev
85 for ev in events:
86 if time_range[0] <= ev.time and ev.time <= time_range[1]:
87 yield ev.name
89 def _parse_events_page(self, page):
91 import json
92 doc = json.loads(page.decode('utf-8'))
94 events = []
95 for feat in doc['features']:
96 props = feat['properties']
97 geo = feat['geometry']
98 lon, lat, depth = [float(x) for x in geo['coordinates']]
99 t = util.str_to_time('1970-01-01 00:00:00') + \
100 props['time'] * 0.001
102 if props['mag'] is not None:
103 mag = float(props['mag'])
104 else:
105 mag = None
107 if props['place'] is not None:
108 region = props['place'].encode('ascii', 'replace').decode()
109 else:
110 region = None
112 catalog = str(props['net'].upper())
113 name = 'USGS-%s-' % catalog + util.time_to_str(
114 t, format='%Y-%m-%d_%H-%M-%S.3FRAC')
116 ev = model.Event(
117 lat=lat,
118 lon=lon,
119 time=t,
120 name=name,
121 depth=depth*1000.,
122 magnitude=mag,
123 region=region,
124 catalog=catalog)
126 events.append(ev)
128 return events
130 def get_event(self, name):
131 if name not in self.events:
132 t = self._name_to_date(name)
133 for name2 in self.iter_event_names(
134 time_range=(t-24*60*60, t+24*60*60)):
136 if name2 == name:
137 break
139 return self.events[name]
141 def _name_to_date(self, name):
142 ds = name[-23:]
143 t = util.str_to_time(ds, format='%Y-%m-%d_%H-%M-%S.3FRAC')
144 return t