1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6import logging
7import time
8import copy
9from pyrocko.io.io_common import get_stats, touch # noqa
10from ... import model
13logger = logging.getLogger('psq.io.stationxml')
16Y = 60*60*24*365
19def provided_formats():
20 return ['stationxml']
23def detect(first512):
24 if first512.find(b'<FDSNStationXML') != -1:
25 return 'stationxml'
27 return None
30def iload(format, file_path, segment, content):
31 assert format == 'stationxml'
33 far_future = time.time() + 20*Y
35 from pyrocko.io import stationxml
36 value_or_none = stationxml.value_or_none
38 sx = stationxml.load_xml(filename=file_path)
40 inut = 0
42 for network in sx.network_list:
43 for station in network.station_list:
44 net = network.code
45 sta = station.code
47 tmin = station.start_date
48 tmax = station.end_date
49 if tmax is not None and tmax > far_future:
50 tmax = None
52 station_nut = model.make_station_nut(
53 file_segment=0,
54 file_element=inut,
55 codes=model.CodesNSL(net, sta, '*'),
56 tmin=tmin,
57 tmax=tmax)
59 if 'station' in content:
60 station_nut.content = model.Station(
61 lat=station.latitude.value,
62 lon=station.longitude.value,
63 elevation=value_or_none(station.elevation),
64 **station_nut.station_kwargs)
66 station_copy = copy.copy(station)
67 station_copy.channel_list = []
69 station_nut.raw_content['stationxml'] = station_copy
71 yield station_nut
72 inut += 1
74 for channel in station.channel_list:
75 cha = channel.code
76 loc = channel.location_code.strip()
78 tmin = channel.start_date
79 tmax = channel.end_date
80 if tmax is not None and tmax > far_future:
81 tmax = None
83 deltat = None
84 if channel.sample_rate is not None \
85 and channel.sample_rate.value != 0.0:
87 deltat = 1.0 / channel.sample_rate.value
89 nut = model.make_channel_nut(
90 file_segment=0,
91 file_element=inut,
92 codes=model.CodesNSLCE(net, sta, loc, cha, ''),
93 tmin=tmin,
94 tmax=tmax,
95 deltat=deltat)
97 if 'channel' in content:
98 nut.content = model.Channel(
99 lat=channel.latitude.value,
100 lon=channel.longitude.value,
101 elevation=value_or_none(channel.elevation),
102 depth=value_or_none(channel.depth),
103 azimuth=value_or_none(channel.azimuth),
104 dip=value_or_none(channel.dip),
105 **nut.channel_kwargs)
107 channel_copy = copy.copy(channel)
108 channel_copy.response = None
109 nut.raw_content['stationxml'] = channel_copy
111 yield nut
112 inut += 1
114 context = '%s.%s.%s.%s' % (net, sta, loc, cha)
116 if channel.response:
118 nut = model.make_response_nut(
119 file_segment=0,
120 file_element=inut,
121 codes=model.CodesNSLCE(net, sta, loc, cha, ''),
122 tmin=tmin,
123 tmax=tmax,
124 deltat=deltat)
126 try:
127 resp = channel.response.get_squirrel_response(
128 context, **nut.response_kwargs)
130 if 'response' in content:
131 nut.content = resp
132 nut.raw_content['stationxml'] = channel.response
134 yield nut
135 inut += 1
137 except stationxml.StationXMLError as e:
138 logger.debug('Bad instrument response: %s' % str(e))