1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

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

5 

6import sys 

7import numpy as num 

8 

9from .io_common import FileLoadError 

10from pyrocko import util, trace 

11 

12 

13class GSE1LoadError(FileLoadError): 

14 pass 

15 

16 

17class EOF(Exception): 

18 pass 

19 

20 

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

26 

27 f.readline() 

28 

29 

30def read_wid1(f): 

31 line = f.readline() 

32 if not line.strip(): 

33 raise EOF() 

34 

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

39 

40 if wid1 != 'WID1': 

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

42 

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

44 

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

49 

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) 

54 

55 

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

60 

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

62 samples = [] 

63 while len(samples) < nsamples: 

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

65 

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

67 

68 else: 

69 raise GSE1LoadError( 

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

71 (data_format, diff_flag)) 

72 

73 line = f.readline() 

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

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

76 

77 t = line.split() 

78 try: 

79 checksum = int(t[1]) 

80 except Exception: 

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

82 

83 f.readline() 

84 

85 return data, checksum 

86 

87 

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

92 

93 while True: 

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

95 break 

96 

97 f.readline() 

98 

99 

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] 

108 

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 

118 

119 yield trace.Trace( 

120 '', sta, '', cha, 

121 tmin=tmin, 

122 tmax=tmax, 

123 deltat=deltat, 

124 ydata=ydata) 

125 

126 except EOF: 

127 pass 

128 

129 

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 

136 

137 return False 

138 

139 

140if __name__ == '__main__': 

141 all_traces = [] 

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

143 all_traces.extend(iload(fn)) 

144 

145 trace.snuffle(all_traces)