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

71 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-10-23 09:03 +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 

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

38 

39 from pyrocko.io import stationxml 

40 value_or_none = stationxml.value_or_none 

41 

42 sx = stationxml.load_xml(filename=file_path) 

43 

44 inut = 0 

45 

46 for network in sx.network_list: 

47 for station in network.station_list: 

48 net = network.code 

49 sta = station.code 

50 

51 tmin = station.start_date 

52 tmax = station.end_date 

53 if tmax is not None and tmax > far_future: 

54 tmax = None 

55 

56 station_nut = model.make_station_nut( 

57 file_segment=0, 

58 file_element=inut, 

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

60 tmin=tmin, 

61 tmax=tmax) 

62 

63 if 'station' in content: 

64 station_nut.content = model.Station( 

65 lat=station.latitude.value, 

66 lon=station.longitude.value, 

67 elevation=value_or_none(station.elevation), 

68 **station_nut.station_kwargs) 

69 

70 station_copy = copy.copy(station) 

71 station_copy.channel_list = [] 

72 

73 station_nut.raw_content['stationxml'] = station_copy 

74 

75 yield station_nut 

76 inut += 1 

77 

78 for channel in station.channel_list: 

79 cha = channel.code 

80 loc = channel.location_code.strip() 

81 

82 tmin = channel.start_date 

83 tmax = channel.end_date 

84 if tmax is not None and tmax > far_future: 

85 tmax = None 

86 

87 deltat = None 

88 if channel.sample_rate is not None \ 

89 and channel.sample_rate.value != 0.0: 

90 

91 deltat = 1.0 / channel.sample_rate.value 

92 

93 if deltat is None and channel.response: 

94 out_rate_resp = channel.response.output_sample_rate 

95 if out_rate_resp: 

96 deltat = 1.0 / out_rate_resp 

97 

98 nut = model.make_channel_nut( 

99 file_segment=0, 

100 file_element=inut, 

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

102 tmin=tmin, 

103 tmax=tmax, 

104 deltat=deltat) 

105 

106 if 'channel' in content: 

107 nut.content = model.Channel( 

108 lat=channel.latitude.value, 

109 lon=channel.longitude.value, 

110 elevation=value_or_none(channel.elevation), 

111 depth=value_or_none(channel.depth), 

112 azimuth=value_or_none(channel.azimuth), 

113 dip=value_or_none(channel.dip), 

114 **nut.channel_kwargs) 

115 

116 channel_copy = copy.copy(channel) 

117 channel_copy.response = None 

118 nut.raw_content['stationxml'] = channel_copy 

119 

120 yield nut 

121 inut += 1 

122 

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

124 

125 if channel.response: 

126 

127 nut = model.make_response_nut( 

128 file_segment=0, 

129 file_element=inut, 

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

131 tmin=tmin, 

132 tmax=tmax, 

133 deltat=deltat) 

134 

135 try: 

136 resp = channel.response.get_squirrel_response( 

137 context, **nut.response_kwargs) 

138 

139 if 'response' in content: 

140 nut.content = resp 

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

142 

143 yield nut 

144 inut += 1 

145 

146 except stationxml.StationXMLError as e: 

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