def make_stationxml(pyrocko_stations, channel_responses): '''Create stationxml from pyrocko station list and RESP information. :param pyrocko_stations: list of :py:class:`pyrocko.model.Station` objects :param channel_responses: iterable yielding :py:class:`ChannelResponse` objects :returns: :py:class:`pyrocko.fdsn.station.FDSNStationXML` object with merged information If no station information is available for any response information, it is skipped and a warning is emitted. ''' pstations = dict((s.nsl(), s) for s in pyrocko_stations) networks = {} stations = {} for (net, sta, loc) in sorted(pstations.keys()): pstation = pstations[net, sta, loc] if net not in networks: networks[net] = fs.Network(code=net) if (net, sta) not in stations: stations[net, sta] = fs.Station( code=sta, latitude=fs.Latitude(pstation.lat), longitude=fs.Longitude(pstation.lon), elevation=fs.Distance(pstation.elevation)) networks[net].station_list.append(stations[net, sta]) for cr in channel_responses: net, sta, loc, cha = cr.codes if (net, sta, loc) in pstations: pstation = pstations[net, sta, loc] channel = fs.Channel( code=cha, location_code=loc, start_date=cr.start_date, end_date=cr.end_date, latitude=fs.Latitude(pstation.lat), longitude=fs.Longitude(pstation.lon), elevation=fs.Distance(pstation.elevation), depth=fs.Distance(pstation.depth), response=cr.response) stations[net, sta].channel_list.append(channel) else: logger.warn('no station information for %s.%s.%s' % (net, sta, loc)) for station in stations.values(): station.channel_list.sort(key=lambda c: (c.location_code, c.code)) return fs.FDSNStationXML( source='Converted from Pyrocko stations file and RESP information', created=time.time(), network_list=[networks[net_] for net_ in sorted(networks.keys())])
def make_stationxml(responses, inconsistencies='warn'): ''' Create stationxml from "enhanced" SACPZ information. :param responses: iterable yielding :py:class:`EnhancedSacPzResponse` objects :returns: :py:class:`pyrocko.fdsn.station.FDSNStationXML` object ''' networks = {} stations = {} station_coords = defaultdict(list) station_channels = defaultdict(list) for cr in responses: net, sta, loc, cha = cr.codes station_coords[net, sta].append( (cr.codes, cr.lat, cr.lon, cr.elevation)) station_channels[net, sta].append(fs.Channel( code=cha, location_code=loc, start_date=cr.tmin, end_date=cr.tmax, latitude=fs.Latitude(cr.lat), longitude=fs.Longitude(cr.lon), elevation=fs.Distance(cr.elevation), depth=fs.Distance(cr.depth), response=make_stationxml_response( cr.response, cr.input_unit, cr.output_unit))) for (net, sta), v in sorted(station_coords.iteritems()): lat, lon, elevation = util.consistency_merge( v, message='channel lat/lon/elevation values differ', error=inconsistencies) if net not in networks: networks[net] = fs.Network(code=net) stations[net, sta] = fs.Station( code=sta, latitude=fs.Latitude(lat), longitude=fs.Longitude(lon), elevation=fs.Distance(elevation), channel_list=sorted( station_channels[net, sta], key=lambda c: (c.location_code, c.code))) networks[net].station_list.append(stations[net, sta]) return fs.FDSNStationXML( source='Converted from "enhanced" SACPZ information', created=time.time(), network_list=[networks[net_] for net_ in sorted(networks.keys())])