1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6from __future__ import absolute_import, print_function
8import logging
9import time
10import copy
11from pyrocko.io.io_common import get_stats, touch # noqa
12from ... import model
15logger = logging.getLogger('psq.io.stationxml')
18Y = 60*60*24*365
21def provided_formats():
22 return ['stationxml']
25def detect(first512):
26 if first512.find(b'<FDSNStationXML') != -1:
27 return 'stationxml'
29 return None
32def iload(format, file_path, segment, content):
33 assert format == 'stationxml'
35 far_future = time.time() + 20*Y
37 from pyrocko.io import stationxml
38 value_or_none = stationxml.value_or_none
40 sx = stationxml.load_xml(filename=file_path)
42 inut = 0
44 for network in sx.network_list:
45 for station in network.station_list:
46 net = network.code
47 sta = station.code
49 tmin = station.start_date
50 tmax = station.end_date
51 if tmax is not None and tmax > far_future:
52 tmax = None
54 station_nut = model.make_station_nut(
55 file_segment=0,
56 file_element=inut,
57 codes=model.CodesNSL(net, sta, '*'),
58 tmin=tmin,
59 tmax=tmax)
61 if 'station' in content:
62 station_nut.content = model.Station(
63 lat=station.latitude.value,
64 lon=station.longitude.value,
65 elevation=value_or_none(station.elevation),
66 **station_nut.station_kwargs)
68 station_copy = copy.copy(station)
69 station_copy.channel_list = []
71 station_nut.raw_content['stationxml'] = station_copy
73 yield station_nut
74 inut += 1
76 for channel in station.channel_list:
77 cha = channel.code
78 loc = channel.location_code.strip()
80 tmin = channel.start_date
81 tmax = channel.end_date
82 if tmax is not None and tmax > far_future:
83 tmax = None
85 deltat = None
86 if channel.sample_rate is not None \
87 and channel.sample_rate.value != 0.0:
89 deltat = 1.0 / channel.sample_rate.value
91 nut = model.make_channel_nut(
92 file_segment=0,
93 file_element=inut,
94 codes=model.CodesNSLCE(net, sta, loc, cha, ''),
95 tmin=tmin,
96 tmax=tmax,
97 deltat=deltat)
99 if 'channel' in content:
100 nut.content = model.Channel(
101 lat=channel.latitude.value,
102 lon=channel.longitude.value,
103 elevation=value_or_none(channel.elevation),
104 depth=value_or_none(channel.depth),
105 azimuth=value_or_none(channel.azimuth),
106 dip=value_or_none(channel.dip),
107 **nut.channel_kwargs)
109 channel_copy = copy.copy(channel)
110 channel_copy.response = None
111 nut.raw_content['stationxml'] = channel_copy
113 yield nut
114 inut += 1
116 context = '%s.%s.%s.%s' % (net, sta, loc, cha)
118 if channel.response:
120 nut = model.make_response_nut(
121 file_segment=0,
122 file_element=inut,
123 codes=model.CodesNSLCE(net, sta, loc, cha, ''),
124 tmin=tmin,
125 tmax=tmax,
126 deltat=deltat)
128 try:
129 resp = channel.response.get_squirrel_response(
130 context, **nut.response_kwargs)
132 if 'response' in content:
133 nut.content = resp
134 nut.raw_content['stationxml'] = channel.response
136 yield nut
137 inut += 1
139 except stationxml.StationXMLError as e:
140 logger.debug('Bad instrument response: %s' % str(e))