1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

4# ---|P------/S----------~Lg---------- 

5from __future__ import absolute_import, division 

6 

7import time 

8import logging 

9 

10from pyrocko import util, model 

11from pyrocko.util import urlopen_ssl_check 

12from .base_catalog import EarthquakeCatalog 

13 

14logger = logging.getLogger('pyrocko.client.usgs') 

15 

16km = 1000. 

17 

18 

19class USGS(EarthquakeCatalog): 

20 

21 def __init__(self, catalog=None): 

22 self.catalog = catalog 

23 self.events = {} 

24 

25 def flush(self): 

26 self.events = {} 

27 

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.): 

37 

38 yearbeg, monbeg, daybeg = time.gmtime(time_range[0])[:3] 

39 yearend, monend, dayend = time.gmtime(time_range[1])[:3] 

40 

41 p = [] 

42 a = p.append 

43 a('format=geojson') 

44 if self.catalog is not None: 

45 a('catalog=%s' % self.catalog.lower()) 

46 

47 a('starttime=%s' % util.time_to_str( 

48 time_range[0], format='%Y-%m-%dT%H:%M:%S')) 

49 

50 a('endtime=%s' % util.time_to_str( 

51 time_range[1], format='%Y-%m-%dT%H:%M:%S')) 

52 

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) 

65 

66 url = 'https://earthquake.usgs.gov/fdsnws/event/1/query?' + '&'.join(p) 

67 

68 logger.debug('Opening URL: %s' % url) 

69 page = urlopen_ssl_check(url).read() 

70 logger.debug('Received page (%i bytes)' % len(page)) 

71 

72 events = self._parse_events_page(page) 

73 

74 for ev in events: 

75 self.events[ev.name] = ev 

76 

77 for ev in events: 

78 if time_range[0] <= ev.time and ev.time <= time_range[1]: 

79 yield ev.name 

80 

81 def _parse_events_page(self, page): 

82 

83 import json 

84 doc = json.loads(page.decode('utf-8')) 

85 

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 

93 

94 if props['mag'] is not None: 

95 mag = float(props['mag']) 

96 else: 

97 mag = None 

98 

99 if props['place'] is not None: 

100 region = props['place'].encode('ascii', 'replace').decode() 

101 else: 

102 region = None 

103 

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') 

107 

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) 

117 

118 events.append(ev) 

119 

120 return events 

121 

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)): 

127 

128 if name2 == name: 

129 break 

130 

131 return self.events[name] 

132 

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