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

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

# http://pyrocko.org - GPLv3 

# 

# The Pyrocko Developers, 21st Century 

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

 

from __future__ import absolute_import, print_function 

 

import logging 

from builtins import str as newstr 

 

from pyrocko.io.io_common import get_stats, touch # noqa 

from ... import model 

 

logger = logging.getLogger('pyrocko.squirrel.io.textfiles') 

 

 

def provided_formats(): 

return ['pyrocko_stations', 'pyrocko_events'] 

 

 

def detect_pyrocko_stations(first512): 

try: 

first512 = first512.decode('utf-8') 

except UnicodeDecodeError: 

return False 

 

for line in first512.splitlines(): 

t = line.split(None, 5) 

if len(t) in (5, 6): 

if len(t[0].split('.')) != 3: 

return False 

 

try: 

lat, lon, ele, dep = map(float, t[1:5]) 

if lat < -90. or 90 < lat: 

return False 

if lon < -180. or 180 < lon: 

return False 

 

return True 

 

except Exception: 

raise 

return False 

 

return False 

 

 

g_event_keys = set(''' 

name region catalog magnitude_type latitude longitude magnitude depth duration 

north_shift east_shift mnn mee mdd mne mnd med strike1 dip1 rake1 strike2 dip2 

rake2 duration time tags moment 

'''.split()) 

 

 

def detect_pyrocko_events(first512): 

try: 

first512 = first512.decode('utf-8') 

except UnicodeDecodeError: 

return False 

 

lines = first512.splitlines()[:-1] 

ok = 0 

for line in lines: 

line = line.strip() 

if not line or line.startswith('#'): 

continue 

 

t = line.split(' = ', 1) 

if len(t) == 2: 

if t[0].strip() in g_event_keys: 

ok += 1 

continue 

else: 

return False 

 

if line.startswith('---'): 

ok += 1 

continue 

 

return False 

 

return ok > 2 

 

 

def detect(first512): 

if detect_pyrocko_stations(first512): 

return 'pyrocko_stations' 

 

elif detect_pyrocko_events(first512): 

return 'pyrocko_events' 

 

return None 

 

 

def float_or_none(s): 

if s.lower() == 'nan': 

return None 

else: 

return float(s) 

 

 

def iload(format, file_path, segment, content): 

if format == 'pyrocko_stations': 

return iload_pyrocko_stations(file_path, segment, content) 

 

if format == 'pyrocko_events': 

return iload_pyrocko_events(file_path, segment, content) 

 

 

def iload_pyrocko_stations(file_path, segment, content): 

 

inut = 0 

tmin = None 

tmax = None 

with open(file_path, 'r') as f: 

 

have_station = False 

for (iline, line) in enumerate(f): 

try: 

toks = line.split(None, 5) 

if len(toks) == 5 or len(toks) == 6: 

net, sta, loc = toks[0].split('.') 

lat, lon, elevation, depth = [float(x) for x in toks[1:5]] 

if len(toks) == 5: 

description = u'' 

else: 

description = newstr(toks[5]) 

 

agn = '' 

 

nut = model.make_station_nut( 

file_segment=0, 

file_element=inut, 

agency=agn, 

network=net, 

station=sta, 

location=loc, 

tmin=tmin, 

tmax=tmax) 

 

if 'station' in content: 

nut.content = model.Station( 

lat=lat, 

lon=lon, 

elevation=elevation, 

depth=depth, 

description=description, 

**nut.station_kwargs) 

 

yield nut 

inut += 1 

 

have_station = True 

 

elif len(toks) == 4 and have_station: 

cha = toks[0] 

azi = float_or_none(toks[1]) 

dip = float_or_none(toks[2]) 

gain = float(toks[3]) 

 

if gain != 1.0: 

logger.warning( 

'%s.%s.%s.%s gain value from stations ' 

'file ignored - please check' % ( 

net, sta, loc, cha)) 

 

nut = model.make_channel_nut( 

file_segment=0, 

file_element=inut, 

agency=agn, 

network=net, 

station=sta, 

location=loc, 

channel=cha, 

tmin=tmin, 

tmax=tmax) 

 

if 'channel' in content: 

nut.content = model.Channel( 

lat=lat, 

lon=lon, 

elevation=elevation, 

depth=depth, 

azimuth=azi, 

dip=dip, 

**nut.channel_kwargs) 

 

yield nut 

inut += 1 

 

else: 

raise Exception('invalid syntax') 

 

except Exception as e: 

logger.warning( 

'skipping invalid station/channel definition: %s ' 

'(line: %i, file: %s' % (str(e), iline, file_path)) 

 

 

def iload_pyrocko_events(file_path, segment, content): 

from pyrocko import model as pmodel 

 

for iev, ev in enumerate(pmodel.Event.load_catalog(file_path)): 

nut = model.make_event_nut( 

file_segment=0, 

file_element=iev, 

name=ev.name or '', 

tmin=ev.time, 

tmax=ev.time) 

 

if 'event' in content: 

nut.content = ev 

 

yield nut