1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

# https://pyrocko.org - GPLv3 

# 

# The Pyrocko Developers, 21st Century 

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

 

from __future__ import absolute_import, print_function, division 

 

try: 

from urllib.request import Request 

from urllib.error import HTTPError 

from urllib.parse import urlencode 

from future.moves.urllib.request import urlopen 

except ImportError: 

from urllib2 import Request, urlopen 

from urllib2 import HTTPError 

from urllib import urlencode 

import calendar 

import logging 

 

from pyrocko import util, model 

from pyrocko.moment_tensor import MomentTensor 

from .base_catalog import EarthquakeCatalog, NotFound 

 

logger = logging.getLogger('pyrocko.client.kinherd') 

 

km = 1000. 

 

 

def ws_request(url, post=False, **kwargs): 

url_values = urlencode(kwargs) 

url = url + '?' + url_values 

logger.debug('Accessing URL %s' % url) 

 

req = Request(url) 

if post: 

req.add_data(post) 

 

req.add_header('Accept', '*/*') 

 

try: 

return urlopen(req) 

 

except HTTPError as e: 

if e.code == 404: 

raise NotFound(url) 

else: 

raise e 

 

 

class Kinherd(EarthquakeCatalog): 

 

def __init__(self, catalog='KPS'): 

self.catalog = catalog 

self.events = {} 

 

def retrieve(self, **kwargs): 

import yaml 

 

kwargs['format'] = 'yaml' 

 

url = 'http://kinherd.org/quakes/%s' % self.catalog 

 

f = ws_request(url, **kwargs) 

 

names = [] 

for eq in yaml.safe_load_all(f): 

pset = eq['parametersets'][0] 

tref = calendar.timegm(pset['reference_time'].timetuple()) 

tpost = calendar.timegm(pset['posted_time'].timetuple()) 

params = pset['parameters'] 

 

mt = MomentTensor( 

strike=params['strike'], 

dip=params['dip'], 

rake=params['slip_rake'], 

scalar_moment=params['moment']) 

 

event = model.Event( 

time=tref + params['time'], 

lat=params['latitude'], 

lon=params['longitude'], 

depth=params['depth'], 

magnitude=params['magnitude'], 

duration=params['rise_time'], 

name=eq['name'], 

catalog=self.catalog, 

moment_tensor=mt) 

 

event.ext_confidence_intervals = {} 

trans = {'latitude': 'lat', 'longitude': 'lon'} 

for par in 'latitude longitude depth magnitude'.split(): 

event.ext_confidence_intervals[trans.get(par, par)] = \ 

(params[par+'_ci_low'], params[par+'_ci_high']) 

 

event.ext_posted_time = tpost 

 

name = eq['name'] 

self.events[name] = event 

names.append(name) 

 

return names 

 

def iter_event_names(self, time_range=None, **kwargs): 

 

qkwargs = {} 

for k in 'magmin magmax latmin latmax lonmin lonmax'.split(): 

if k in kwargs and kwargs[k] is not None: 

qkwargs[k] = '%f' % kwargs[k] 

 

if time_range is not None: 

form = '%Y-%m-%d_%H-%M-%S' 

if time_range[0] is not None: 

qkwargs['tmin'] = util.time_to_str(time_range[0], form) 

if time_range[1] is not None: 

qkwargs['tmax'] = util.time_to_str(time_range[1], form) 

 

for name in self.retrieve(**qkwargs): 

yield name 

 

def get_event(self, name): 

if name not in self.events: 

self.retrieve(name=name) 

 

return self.events[name]