1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6from pyrocko.io.io_common import get_stats, touch # noqa
7from pyrocko import trace
8from ... import model
11km = 1000.
14def provided_formats():
15 return ['sac']
18def detect(first512):
19 from pyrocko.io import sac
21 if sac.detect(first512):
22 return 'sac'
23 else:
24 return None
27def agg(*ds):
28 out = {}
29 for d in ds:
30 out.update(d)
32 return out
35def nonetoempty(x):
36 if x is None:
37 return x
38 else:
39 return x.strip()
42def iload(format, file_path, segment, content):
43 assert format == 'sac'
45 from pyrocko.io import sac
47 load_data = 'waveform' in content
49 s = sac.SacFile(file_path, load_data=load_data)
51 codes = model.CodesNSLCE(
52 nonetoempty(s.knetwk),
53 nonetoempty(s.kstnm),
54 nonetoempty(s.khole),
55 nonetoempty(s.kcmpnm))
57 tmin = s.get_ref_time() + s.b
58 tmax = tmin + s.delta * s.npts
60 tspan = dict(
61 tmin=tmin,
62 tmax=tmax,
63 deltat=s.delta)
65 inut = 0
66 nut = model.make_waveform_nut(
67 file_segment=0,
68 file_element=inut,
69 codes=codes,
70 **tspan)
72 if 'waveform' in content:
73 nut.content = trace.Trace(
74 ydata=s.data[0],
75 **nut.waveform_kwargs)
77 yield nut
78 inut += 1
80 if None not in (s.stla, s.stlo):
81 position = dict(
82 lat=s.stla,
83 lon=s.stlo,
84 elevation=s.stel,
85 depth=s.stdp)
87 nut = model.make_station_nut(
88 file_segment=0,
89 file_element=inut,
90 codes=model.CodesNSL(*codes.nsl),
91 **tspan)
93 if 'station' in content:
94 nut.content = model.Station(
95 **agg(position, nut.station_kwargs))
97 yield nut
98 inut += 1
100 dip = None
101 if s.cmpinc is not None:
102 dip = s.cmpinc - 90.
104 nut = model.make_channel_nut(
105 file_segment=0,
106 file_element=inut,
107 codes=codes,
108 **tspan)
110 if 'channel' in content:
111 nut.content = model.Channel(
112 azimuth=s.cmpaz,
113 dip=dip,
114 **agg(position, nut.channel_kwargs))
116 yield nut
117 inut += 1
119 if None not in (s.evla, s.evlo, s.o):
120 etime = s.get_ref_time() + s.o
121 depth = None
122 if s.evdp is not None:
123 depth = s.evdp # * km # unclear specs
125 nut = model.make_event_nut(
126 codes=model.CodesX(''),
127 # name=nonetoempty(s.kevnm),
128 file_segment=0,
129 file_element=inut,
130 tmin=etime,
131 tmax=etime)
133 if 'event' in content:
134 nut.content = model.Event(
135 lat=s.evla,
136 lon=s.evlo,
137 depth=depth,
138 magnitude=s.mag,
139 **nut.event_kwargs)
141 yield nut
142 inut += 1