Coverage for /usr/local/lib/python3.11/dist-packages/pyrocko/squirrel/io/backends/sac.py: 98%

61 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-10-11 13:29 +0000

1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

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

5 

6''' 

7Squirrel IO adaptor to :py:mod:`pyrocko.io.sac`. 

8''' 

9 

10from pyrocko.io.io_common import get_stats, touch # noqa 

11from pyrocko import trace 

12from ... import model 

13 

14 

15km = 1000. 

16 

17 

18def provided_formats(): 

19 return ['sac'] 

20 

21 

22def detect(first512): 

23 from pyrocko.io import sac 

24 

25 if sac.detect(first512): 

26 return 'sac' 

27 else: 

28 return None 

29 

30 

31def agg(*ds): 

32 out = {} 

33 for d in ds: 

34 out.update(d) 

35 

36 return out 

37 

38 

39def nonetoempty(x): 

40 if x is None: 

41 return x 

42 else: 

43 return x.strip() 

44 

45 

46def iload(format, file_path, segment, content): 

47 assert format == 'sac' 

48 

49 from pyrocko.io import sac 

50 

51 load_data = 'waveform' in content 

52 

53 s = sac.SacFile(file_path, load_data=load_data) 

54 

55 codes = model.CodesNSLCE( 

56 nonetoempty(s.knetwk), 

57 nonetoempty(s.kstnm), 

58 nonetoempty(s.khole), 

59 nonetoempty(s.kcmpnm)) 

60 

61 tmin = s.get_ref_time() + s.b 

62 tmax = tmin + s.delta * s.npts 

63 

64 tspan = dict( 

65 tmin=tmin, 

66 tmax=tmax, 

67 deltat=s.delta) 

68 

69 inut = 0 

70 nut = model.make_waveform_nut( 

71 file_segment=0, 

72 file_element=inut, 

73 codes=codes, 

74 **tspan) 

75 

76 if 'waveform' in content: 

77 nut.content = trace.Trace( 

78 ydata=s.data[0], 

79 **nut.waveform_kwargs) 

80 

81 yield nut 

82 inut += 1 

83 

84 if None not in (s.stla, s.stlo): 

85 position = dict( 

86 lat=s.stla, 

87 lon=s.stlo, 

88 elevation=s.stel, 

89 depth=s.stdp) 

90 

91 nut = model.make_station_nut( 

92 file_segment=0, 

93 file_element=inut, 

94 codes=model.CodesNSL(*codes.nsl), 

95 **tspan) 

96 

97 if 'station' in content: 

98 nut.content = model.Station( 

99 **agg(position, nut.station_kwargs)) 

100 

101 yield nut 

102 inut += 1 

103 

104 dip = None 

105 if s.cmpinc is not None: 

106 dip = s.cmpinc - 90. 

107 

108 nut = model.make_channel_nut( 

109 file_segment=0, 

110 file_element=inut, 

111 codes=codes, 

112 **tspan) 

113 

114 if 'channel' in content: 

115 nut.content = model.Channel( 

116 azimuth=s.cmpaz, 

117 dip=dip, 

118 **agg(position, nut.channel_kwargs)) 

119 

120 yield nut 

121 inut += 1 

122 

123 if None not in (s.evla, s.evlo, s.o): 

124 etime = s.get_ref_time() + s.o 

125 depth = None 

126 if s.evdp is not None: 

127 depth = s.evdp # * km # unclear specs 

128 

129 nut = model.make_event_nut( 

130 codes=model.CodesX(''), 

131 # name=nonetoempty(s.kevnm), 

132 file_segment=0, 

133 file_element=inut, 

134 tmin=etime, 

135 tmax=etime) 

136 

137 if 'event' in content: 

138 nut.content = model.Event( 

139 lat=s.evla, 

140 lon=s.evlo, 

141 depth=depth, 

142 magnitude=s.mag, 

143 **nut.event_kwargs) 

144 

145 yield nut 

146 inut += 1