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 

48 tmin = station.start_date 

49 tmax = station.end_date 

50 if tmax is not None and tmax > far_future: 

51 tmax = None 

52 

53 station_nut = model.make_station_nut( 

54 file_segment=0, 

55 file_element=inut, 

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

57 tmin=tmin, 

58 tmax=tmax) 

59 

60 if 'station' in content: 

61 station_nut.content = model.Station( 

62 lat=station.latitude.value, 

63 lon=station.longitude.value, 

64 elevation=value_or_none(station.elevation), 

65 **station_nut.station_kwargs) 

66 

67 yield station_nut 

68 inut += 1 

69 

70 for channel in station.channel_list: 

71 cha = channel.code 

72 loc = channel.location_code.strip() 

73 

74 tmin = channel.start_date 

75 tmax = channel.end_date 

76 if tmax is not None and tmax > far_future: 

77 tmax = None 

78 

79 deltat = None 

80 if channel.sample_rate is not None \ 

81 and channel.sample_rate.value != 0.0: 

82 

83 deltat = 1.0 / channel.sample_rate.value 

84 

85 nut = model.make_channel_nut( 

86 file_segment=0, 

87 file_element=inut, 

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

89 tmin=tmin, 

90 tmax=tmax, 

91 deltat=deltat) 

92 

93 if 'channel' in content: 

94 nut.content = model.Channel( 

95 lat=channel.latitude.value, 

96 lon=channel.longitude.value, 

97 elevation=value_or_none(channel.elevation), 

98 depth=value_or_none(channel.depth), 

99 azimuth=value_or_none(channel.azimuth), 

100 dip=value_or_none(channel.dip), 

101 **nut.channel_kwargs) 

102 

103 yield nut 

104 inut += 1 

105 

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

107 

108 if channel.response: 

109 

110 nut = model.make_response_nut( 

111 file_segment=0, 

112 file_element=inut, 

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

114 tmin=tmin, 

115 tmax=tmax, 

116 deltat=deltat) 

117 

118 try: 

119 resp = channel.response.get_squirrel_response( 

120 context, **nut.response_kwargs) 

121 

122 if 'response' in content: 

123 nut.content = resp 

124 

125 yield nut 

126 inut += 1 

127 

128 except stationxml.StationXMLError as e: 

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