예제 #1
0
    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)
예제 #2
0
    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())])
예제 #4
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(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())])
예제 #5
0
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)
예제 #6
0
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)