1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6from __future__ import absolute_import, print_function
8from pyrocko.io.io_common import get_stats, touch # noqa
9from pyrocko import trace
10from ... import model
13km = 1000.
16def provided_formats():
17 return ['sac']
20def detect(first512):
21 from pyrocko.io import sac
23 if sac.detect(first512):
24 return 'sac'
25 else:
26 return None
29def agg(*ds):
30 out = {}
31 for d in ds:
32 out.update(d)
34 return out
37def nonetoempty(x):
38 if x is None:
39 return x
40 else:
41 return x.strip()
44def iload(format, file_path, segment, content):
45 assert format == 'sac'
47 from pyrocko.io import sac
49 load_data = 'waveform' in content
51 s = sac.SacFile(file_path, load_data=load_data)
53 codes = model.CodesNSLCE(
54 nonetoempty(s.knetwk),
55 nonetoempty(s.kstnm),
56 nonetoempty(s.khole),
57 nonetoempty(s.kcmpnm))
59 tmin = s.get_ref_time() + s.b
60 tmax = tmin + s.delta * s.npts
62 tspan = dict(
63 tmin=tmin,
64 tmax=tmax,
65 deltat=s.delta)
67 inut = 0
68 nut = model.make_waveform_nut(
69 file_segment=0,
70 file_element=inut,
71 codes=codes,
72 **tspan)
74 if 'waveform' in content:
75 nut.content = trace.Trace(
76 ydata=s.data[0],
77 **nut.waveform_kwargs)
79 yield nut
80 inut += 1
82 if None not in (s.stla, s.stlo):
83 position = dict(
84 lat=s.stla,
85 lon=s.stlo,
86 elevation=s.stel,
87 depth=s.stdp)
89 nut = model.make_station_nut(
90 file_segment=0,
91 file_element=inut,
92 codes=model.CodesNSL(*codes.nsl),
93 **tspan)
95 if 'station' in content:
96 nut.content = model.Station(
97 **agg(position, nut.station_kwargs))
99 yield nut
100 inut += 1
102 dip = None
103 if s.cmpinc is not None:
104 dip = s.cmpinc - 90.
106 nut = model.make_channel_nut(
107 file_segment=0,
108 file_element=inut,
109 codes=codes,
110 **tspan)
112 if 'channel' in content:
113 nut.content = model.Channel(
114 azimuth=s.cmpaz,
115 dip=dip,
116 **agg(position, nut.channel_kwargs))
118 yield nut
119 inut += 1
121 if None not in (s.evla, s.evlo, s.o):
122 etime = s.get_ref_time() + s.o
123 depth = None
124 if s.evdp is not None:
125 depth = s.evdp # * km # unclear specs
127 nut = model.make_event_nut(
128 codes=model.CodesX(''),
129 # name=nonetoempty(s.kevnm),
130 file_segment=0,
131 file_element=inut,
132 tmin=etime,
133 tmax=etime)
135 if 'event' in content:
136 nut.content = model.Event(
137 lat=s.evla,
138 lon=s.evlo,
139 depth=depth,
140 magnitude=s.mag,
141 **nut.event_kwargs)
143 yield nut
144 inut += 1