1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

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

5from __future__ import absolute_import, division 

6 

7import sys 

8import numpy as num 

9 

10from .io_common import FileLoadError 

11from pyrocko import util, trace 

12 

13 

14class GSE1LoadError(FileLoadError): 

15 pass 

16 

17 

18class EOF(Exception): 

19 pass 

20 

21 

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') 

27 

28 f.readline() 

29 

30 

31def read_wid1(f): 

32 line = f.readline() 

33 if not line.strip(): 

34 raise EOF() 

35 

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]) 

40 

41 if wid1 != 'WID1': 

42 raise GSE1LoadError('"WID1" marker expected but not found.') 

43 

44 tmin = util.str_to_time(stmin, format='%Y%j %H %M %S') + 0.001*imilli 

45 

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]) 

50 

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) 

55 

56 

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.') 

61 

62 if data_format == 'INTV' and diff_flag == 0: 

63 samples = [] 

64 while len(samples) < nsamples: 

65 samples.extend(map(float, f.readline().split())) 

66 

67 data = num.array(samples[:nsamples], dtype=int) 

68 

69 else: 

70 raise GSE1LoadError( 

71 'GSE1 data format %s with differencing=%i not supported.' % 

72 (data_format, diff_flag)) 

73 

74 line = f.readline() 

75 if not line.startswith('CHK1'): 

76 raise GSE1LoadError('"CHK1" marker expected but not found.') 

77 

78 t = line.split() 

79 try: 

80 checksum = int(t[1]) 

81 except Exception: 

82 raise GSE1LoadError('could not parse CHK1 section') 

83 

84 f.readline() 

85 

86 return data, checksum 

87 

88 

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.') 

93 

94 while True: 

95 if f.readline().startswith('CHK1'): 

96 break 

97 

98 f.readline() 

99 

100 

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] 

109 

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 

119 

120 yield trace.Trace( 

121 '', sta, '', cha, 

122 tmin=tmin, 

123 tmax=tmax, 

124 deltat=deltat, 

125 ydata=ydata) 

126 

127 except EOF: 

128 pass 

129 

130 

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 

137 

138 return False 

139 

140 

141if __name__ == '__main__': 

142 all_traces = [] 

143 for fn in sys.argv[1:]: 

144 all_traces.extend(iload(fn)) 

145 

146 trace.snuffle(all_traces)