1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

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

5 

6import time 

7import logging 

8 

9from pyrocko import util, model 

10from pyrocko.util import urlopen_ssl_check 

11from .base_catalog import EarthquakeCatalog 

12 

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

14 

15km = 1000. 

16 

17 

18class USGS(EarthquakeCatalog): 

19 

20 def __init__(self, catalog=None): 

21 self.catalog = catalog 

22 self.events = {} 

23 

24 def flush(self): 

25 self.events = {} 

26 

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

36 

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

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

39 

40 p = [] 

41 a = p.append 

42 a('format=geojson') 

43 if self.catalog is not None: 

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

45 

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

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

48 

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

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

51 

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) 

64 

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

66 

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

68 page = urlopen_ssl_check(url).read() 

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

70 

71 events = self._parse_events_page(page) 

72 

73 for ev in events: 

74 self.events[ev.name] = ev 

75 

76 for ev in events: 

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

78 yield ev.name 

79 

80 def _parse_events_page(self, page): 

81 

82 import json 

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

84 

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 

92 

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

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

95 else: 

96 mag = None 

97 

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

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

100 else: 

101 region = None 

102 

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

106 

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) 

116 

117 events.append(ev) 

118 

119 return events 

120 

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

126 

127 if name2 == name: 

128 break 

129 

130 return self.events[name] 

131 

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