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
10from pyrocko.io.io_common import get_stats, touch # noqa
11from ... import model
14logger = logging.getLogger('psq.io.stationxml')
17Y = 60*60*24*365
20def provided_formats():
21 return ['stationxml']
24def detect(first512):
25 if first512.find(b'<FDSNStationXML') != -1:
26 return 'stationxml'
28 return None
31def iload(format, file_path, segment, content):
32 assert format == 'stationxml'
34 far_future = time.time() + 20*Y
36 from pyrocko.io import stationxml
37 value_or_none = stationxml.value_or_none
39 sx = stationxml.load_xml(filename=file_path)
41 inut = 0
43 for network in sx.network_list:
44 for station in network.station_list:
45 net = network.code
46 sta = station.code
47 agn = ''
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 agency=agn,
58 network=net,
59 station=sta,
60 location='*',
61 tmin=tmin,
62 tmax=tmax)
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)
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 agency=agn,
93 network=net,
94 station=sta,
95 location=loc,
96 channel=cha,
97 tmin=tmin,
98 tmax=tmax,
99 deltat=deltat)
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)
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 agency=agn,
122 network=net,
123 station=sta,
124 location=loc,
125 channel=cha,
126 tmin=tmin,
127 tmax=tmax,
128 deltat=deltat)
130 try:
131 resp = channel.response.get_squirrel_response(
132 context, **nut.response_kwargs)
134 if 'response' in content:
135 nut.content = resp
137 yield nut
138 inut += 1
140 except stationxml.StationXMLError as e:
141 logger.debug('Bad instrument response: %s' % str(e))