def test_consistency_merge(self): data = [ ('a', 1, 2, 3.), ('a', 2, 2, 3.), ('a', 1, 2, 3.)] merged = util.consistency_merge(data, error='ignore') assert merged == (1, 2, 3.0)
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(sxml.Channel( code=cha, location_code=loc, start_date=cr.tmin, end_date=cr.tmax, latitude=sxml.Latitude(cr.lat), longitude=sxml.Longitude(cr.lon), elevation=sxml.Distance(cr.elevation), depth=sxml.Distance(cr.depth), response=make_stationxml_response( cr.response, cr.input_unit, cr.output_unit))) for (net, sta), v in sorted(station_coords.items()): lat, lon, elevation = util.consistency_merge( v, message='channel lat/lon/elevation values differ', error=inconsistencies) if net not in networks: networks[net] = sxml.Network(code=net) stations[net, sta] = sxml.Station( code=sta, latitude=sxml.Latitude(lat), longitude=sxml.Longitude(lon), elevation=sxml.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 sxml.FDSNStationXML( source='Converted from "enhanced" SACPZ 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())])
def pyrocko_station_from_channels(nsl, channels, inconsistencies='warn'): pos = lat, lon, elevation, depth = \ channels[0].position_values if not all(pos == x.position_values for x in channels): info = '\n'.join( ' %s: %s' % (x.code, x.position_values) for x in channels) mess = 'encountered inconsistencies in channel ' \ 'lat/lon/elevation/depth ' \ 'for %s.%s.%s: \n%s' % (nsl + (info,)) if inconsistencies == 'raise': raise InconsistentChannelLocations(mess) elif inconsistencies == 'warn': logger.warn(mess) logger.warn(' -> using mean values') apos = num.array([x.position_values for x in channels], dtype=num.float) mlat, mlon, mele, mdep = num.nansum(apos, axis=0) \ / num.sum(num.isfinite(apos), axis=0) groups = {} for channel in channels: if channel.code not in groups: groups[channel.code] = [] groups[channel.code].append(channel) pchannels = [] for code in sorted(groups.keys()): data = [ (channel.code, value_or_none(channel.azimuth), value_or_none(channel.dip)) for channel in groups[code]] azimuth, dip = util.consistency_merge( data, message='channel orientation values differ:', error=inconsistencies) pchannels.append( pyrocko.model.Channel(code, azimuth=azimuth, dip=dip)) return pyrocko.model.Station( *nsl, lat=mlat, lon=mlon, elevation=mele, depth=mdep, channels=pchannels)