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