1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6import sys
7import numpy as num
9from .io_common import FileLoadError
10from pyrocko import util, trace
13class GSE1LoadError(FileLoadError):
14 pass
17class EOF(Exception):
18 pass
21def read_xw01(f):
22 line = f.readline()
23 if not line[:4] == 'XW01':
24 raise GSE1LoadError(
25 '"XW01" marker not found, maybe this is not a GSE1 file')
27 f.readline()
30def read_wid1(f):
31 line = f.readline()
32 if not line.strip():
33 raise EOF()
35 (wid1, stmin, imilli, nsamples, sta, channel_id, channel_name, sample_rate,
36 system_type, data_format, diff_flag) = util.unpack_fixed(
37 'a4,x1,a17,x1,i3,x1,i8,x1,a6,x1,a8,x1,a2,x1,f11,x1,a6,x1,a4,x1,i1',
38 line[:80])
40 if wid1 != 'WID1':
41 raise GSE1LoadError('"WID1" marker expected but not found.')
43 tmin = util.str_to_time(stmin, format='%Y%j %H %M %S') + 0.001*imilli
45 line = f.readline()
46 (gain, units, calib_period, lat, lon, elevation, depth, beam_azimuth,
47 beam_slowness, horizontal_orientation) = util.unpack_fixed(
48 'f9,i1,f7,x1,f9,x1,f9,x1,f9,x1,f9,x1,f7,x1,f7,x1,f6', line[:80])
50 return (tmin, nsamples, sta, channel_id, channel_name, sample_rate,
51 system_type, data_format, diff_flag, gain, units, calib_period,
52 lat, lon, elevation, depth, beam_azimuth, beam_slowness,
53 horizontal_orientation)
56def read_dat1_chk1(f, data_format, diff_flag, nsamples):
57 dat1 = f.readline()[:4]
58 if dat1 != 'DAT1':
59 raise GSE1LoadError('"DAT1" marker expected but not found.')
61 if data_format == 'INTV' and diff_flag == 0:
62 samples = []
63 while len(samples) < nsamples:
64 samples.extend(map(float, f.readline().split()))
66 data = num.array(samples[:nsamples], dtype=int)
68 else:
69 raise GSE1LoadError(
70 'GSE1 data format %s with differencing=%i not supported.' %
71 (data_format, diff_flag))
73 line = f.readline()
74 if not line.startswith('CHK1'):
75 raise GSE1LoadError('"CHK1" marker expected but not found.')
77 t = line.split()
78 try:
79 checksum = int(t[1])
80 except Exception:
81 raise GSE1LoadError('could not parse CHK1 section')
83 f.readline()
85 return data, checksum
88def skip_dat1_chk1(f, data_format, diff_flag, nsamples):
89 dat1 = f.readline()[:4]
90 if dat1 != 'DAT1':
91 raise GSE1LoadError('"DAT1" marker expected but not found.')
93 while True:
94 if f.readline().startswith('CHK1'):
95 break
97 f.readline()
100def iload(filename, load_data=True):
101 with open(filename, 'r') as f:
102 read_xw01(f)
103 try:
104 while True:
105 h = read_wid1(f)
106 (tmin, nsamples, sta, chid, cha, sample_rate, _, data_format,
107 diff_flag, gain) = h[:10]
109 deltat = 1.0/sample_rate
110 if load_data:
111 ydata, checksum = read_dat1_chk1(
112 f, data_format, diff_flag, nsamples)
113 tmax = None
114 else:
115 skip_dat1_chk1(f, data_format, diff_flag, nsamples)
116 ydata = None
117 tmax = tmin + (nsamples-1)*deltat
119 yield trace.Trace(
120 '', sta, '', cha,
121 tmin=tmin,
122 tmax=tmax,
123 deltat=deltat,
124 ydata=ydata)
126 except EOF:
127 pass
130def detect(first512):
131 lines = first512.splitlines()
132 if len(lines) >= 5 and \
133 lines[0].startswith(b'XW01') and lines[2].startswith(b'WID1') and \
134 lines[4].startswith(b'DAT1'):
135 return True
137 return False
140if __name__ == '__main__':
141 all_traces = []
142 for fn in sys.argv[1:]:
143 all_traces.extend(iload(fn))
145 trace.snuffle(all_traces)