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

74 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2024-03-07 11:54 +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.stationxml`. 

8''' 

9 

10import logging 

11import time 

12import copy 

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

14from ... import model 

15 

16 

17logger = logging.getLogger('psq.io.stationxml') 

18 

19 

20Y = 60*60*24*365 

21 

22 

23def provided_formats(): 

24 return ['stationxml'] 

25 

26 

27def detect(first512): 

28 if first512.find(b'<FDSNStationXML') != -1: 

29 return 'stationxml' 

30 

31 return None 

32 

33 

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

35 assert format == 'stationxml' 

36 from pyrocko.io import stationxml 

37 sx = stationxml.load_xml(filename=file_path) 

38 yield from iload_stationxml(sx, 0, content) 

39 

40 

41def iload_stationxml(sx, segment, content): 

42 inut = 0 

43 

44 far_future = time.time() + 20*Y 

45 

46 from pyrocko.io import stationxml 

47 value_or_none = stationxml.value_or_none 

48 

49 for network in sx.network_list: 

50 for station in network.station_list: 

51 net = network.code 

52 sta = station.code 

53 

54 tmin = station.start_date 

55 tmax = station.end_date 

56 if tmax is not None and tmax > far_future: 

57 tmax = None 

58 

59 station_nut = model.make_station_nut( 

60 file_segment=segment, 

61 file_element=inut, 

62 codes=model.CodesNSL(net, sta, '*'), 

63 tmin=tmin, 

64 tmax=tmax) 

65 

66 if 'station' in content: 

67 station_nut.content = model.Station( 

68 lat=station.latitude.value, 

69 lon=station.longitude.value, 

70 elevation=value_or_none(station.elevation), 

71 **station_nut.station_kwargs) 

72 

73 station_copy = copy.copy(station) 

74 station_copy.channel_list = [] 

75 

76 station_nut.raw_content['stationxml'] = station_copy 

77 

78 yield station_nut 

79 inut += 1 

80 

81 for channel in station.channel_list: 

82 cha = channel.code 

83 loc = channel.location_code.strip() 

84 

85 tmin = channel.start_date 

86 tmax = channel.end_date 

87 if tmax is not None and tmax > far_future: 

88 tmax = None 

89 

90 deltat = None 

91 if channel.sample_rate is not None \ 

92 and channel.sample_rate.value != 0.0: 

93 

94 deltat = 1.0 / channel.sample_rate.value 

95 

96 if deltat is None and channel.response: 

97 out_rate_resp = channel.response.output_sample_rate 

98 if out_rate_resp: 

99 deltat = 1.0 / out_rate_resp 

100 

101 nut = model.make_channel_nut( 

102 file_segment=segment, 

103 file_element=inut, 

104 codes=model.CodesNSLCE(net, sta, loc, cha, ''), 

105 tmin=tmin, 

106 tmax=tmax, 

107 deltat=deltat) 

108 

109 if 'channel' in content: 

110 nut.content = model.Channel( 

111 lat=channel.latitude.value, 

112 lon=channel.longitude.value, 

113 elevation=value_or_none(channel.elevation), 

114 depth=value_or_none(channel.depth), 

115 azimuth=value_or_none(channel.azimuth), 

116 dip=value_or_none(channel.dip), 

117 **nut.channel_kwargs) 

118 

119 channel_copy = copy.copy(channel) 

120 channel_copy.response = None 

121 nut.raw_content['stationxml'] = channel_copy 

122 

123 yield nut 

124 inut += 1 

125 

126 context = '%s.%s.%s.%s' % (net, sta, loc, cha) 

127 

128 if channel.response: 

129 

130 nut = model.make_response_nut( 

131 file_segment=segment, 

132 file_element=inut, 

133 codes=model.CodesNSLCE(net, sta, loc, cha, ''), 

134 tmin=tmin, 

135 tmax=tmax, 

136 deltat=deltat) 

137 

138 try: 

139 resp = channel.response.get_squirrel_response( 

140 context, **nut.response_kwargs) 

141 

142 if 'response' in content: 

143 nut.content = resp 

144 nut.raw_content['stationxml'] = channel.response 

145 

146 yield nut 

147 inut += 1 

148 

149 except stationxml.StationXMLError as e: 

150 logger.debug('Bad instrument response: %s' % str(e))