1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

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

5 

6from __future__ import absolute_import, print_function 

7 

8import logging 

9import time 

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

11from ... import model 

12 

13 

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

15 

16 

17Y = 60*60*24*365 

18 

19 

20def provided_formats(): 

21 return ['stationxml'] 

22 

23 

24def detect(first512): 

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

26 return 'stationxml' 

27 

28 return None 

29 

30 

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

32 assert format == 'stationxml' 

33 

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

35 

36 from pyrocko.io import stationxml 

37 value_or_none = stationxml.value_or_none 

38 

39 sx = stationxml.load_xml(filename=file_path) 

40 

41 inut = 0 

42 

43 for network in sx.network_list: 

44 for station in network.station_list: 

45 net = network.code 

46 sta = station.code 

47 agn = '' 

48 

49 tmin = station.start_date 

50 tmax = station.end_date 

51 if tmax is not None and tmax > far_future: 

52 tmax = None 

53 

54 station_nut = model.make_station_nut( 

55 file_segment=0, 

56 file_element=inut, 

57 agency=agn, 

58 network=net, 

59 station=sta, 

60 location='*', 

61 tmin=tmin, 

62 tmax=tmax) 

63 

64 if 'station' in content: 

65 station_nut.content = model.Station( 

66 lat=station.latitude.value, 

67 lon=station.longitude.value, 

68 elevation=value_or_none(station.elevation), 

69 **station_nut.station_kwargs) 

70 

71 yield station_nut 

72 inut += 1 

73 

74 for channel in station.channel_list: 

75 cha = channel.code 

76 loc = channel.location_code.strip() 

77 

78 tmin = channel.start_date 

79 tmax = channel.end_date 

80 if tmax is not None and tmax > far_future: 

81 tmax = None 

82 

83 deltat = None 

84 if channel.sample_rate is not None \ 

85 and channel.sample_rate.value != 0.0: 

86 

87 deltat = 1.0 / channel.sample_rate.value 

88 

89 nut = model.make_channel_nut( 

90 file_segment=0, 

91 file_element=inut, 

92 agency=agn, 

93 network=net, 

94 station=sta, 

95 location=loc, 

96 channel=cha, 

97 tmin=tmin, 

98 tmax=tmax, 

99 deltat=deltat) 

100 

101 if 'channel' in content: 

102 nut.content = model.Channel( 

103 lat=channel.latitude.value, 

104 lon=channel.longitude.value, 

105 elevation=value_or_none(channel.elevation), 

106 depth=value_or_none(channel.depth), 

107 azimuth=value_or_none(channel.azimuth), 

108 dip=value_or_none(channel.dip), 

109 **nut.channel_kwargs) 

110 

111 yield nut 

112 inut += 1 

113 

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

115 

116 if channel.response: 

117 

118 nut = model.make_response_nut( 

119 file_segment=0, 

120 file_element=inut, 

121 agency=agn, 

122 network=net, 

123 station=sta, 

124 location=loc, 

125 channel=cha, 

126 tmin=tmin, 

127 tmax=tmax, 

128 deltat=deltat) 

129 

130 try: 

131 resp = channel.response.get_squirrel_response( 

132 context, **nut.response_kwargs) 

133 

134 if 'response' in content: 

135 nut.content = resp 

136 

137 yield nut 

138 inut += 1 

139 

140 except stationxml.StationXMLError as e: 

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