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-23 09:03 +0000

1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

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

5 

6''' 

7Client to get earthquake catalog information from 

8`USGS <https://earthquake.usgs.gov/>`_. 

9''' 

10 

11import time 

12import logging 

13 

14from pyrocko import util, model 

15from pyrocko.util import urlopen_ssl_check 

16from .base_catalog import EarthquakeCatalog 

17 

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

19 

20km = 1000. 

21 

22 

23class USGS(EarthquakeCatalog): 

24 ''' 

25 Client to get earthquake catalog information from 

26 `USGS <https://earthquake.usgs.gov/>`_. 

27 ''' 

28 

29 def __init__(self, catalog=None): 

30 self.catalog = catalog 

31 self.events = {} 

32 

33 def flush(self): 

34 self.events = {} 

35 

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

45 

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

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

48 

49 p = [] 

50 a = p.append 

51 a('format=geojson') 

52 if self.catalog is not None: 

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

54 

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

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

57 

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

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

60 

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) 

73 

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

75 

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

77 page = urlopen_ssl_check(url).read() 

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

79 

80 events = self._parse_events_page(page) 

81 

82 for ev in events: 

83 self.events[ev.name] = ev 

84 

85 for ev in events: 

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

87 yield ev.name 

88 

89 def _parse_events_page(self, page): 

90 

91 import json 

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

93 

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 

101 

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

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

104 else: 

105 mag = None 

106 

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

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

109 else: 

110 region = None 

111 

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

115 

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) 

125 

126 events.append(ev) 

127 

128 return events 

129 

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

135 

136 if name2 == name: 

137 break 

138 

139 return self.events[name] 

140 

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