def spoints():
    return [
        SpherePoint(10, 10, "point1"),
        SpherePoint(10, -10, "point2"),
        SpherePoint(-10, -10, "point3"),
        SpherePoint(-10, 10, "point4")
    ]
예제 #2
0
def calculate_source_weights_on_location(points, search_ratio, plot_flag,
                                         outputdir):
    """
    :param outputdir: output directory for figures
    """
    # set a fake center point
    center = SpherePoint(0, 180.0, tag="Center")
    weightobj = SphereDistRel(points, center=center)

    if plot_flag:
        scan_figname = os.path.join(outputdir, "source_weights.smart_scan.png")
    else:
        scan_figname = None

    ref_distance, cond_number = weightobj.smart_scan(max_ratio=search_ratio,
                                                     start=0.1,
                                                     gap=0.2,
                                                     drop_ratio=0.95,
                                                     plot=plot_flag,
                                                     figname=scan_figname)

    print("Reference distance and condition number: %f, %f" %
          (ref_distance, cond_number))

    if plot_flag:
        map_figname = os.path.join(outputdir, "source_weights.global_map.pdf")
        weightobj.plot_global_map(figname=map_figname, lon0=180.0)

    return ref_distance, cond_number
예제 #3
0
def determine_receiver_weighting(src,
                                 stations,
                                 windows,
                                 search_ratio=0.35,
                                 weight_flag=True,
                                 plot_flag=False,
                                 figname_prefix=None):
    """
    Given one station and window information, determine the receiver
    weighting
    In one asdf file, there are still 3 components, for example,
    ["BHR", "BHT", "BHZ"]. These three components should be treated
    indepandently and weights will be calculated independantly.

    :return: dict of weights which contains 3 components. Each components
        contains weights values
    """
    center = SpherePoint(src["latitude"], src["longitude"], tag="source")

    rec_wcounts, cat_wcounts = calculate_receiver_window_counts(windows)

    weights = {}
    # in each components, calculate weight
    ref_dists = {}
    cond_nums = {}
    for comp, comp_info in rec_wcounts.items():
        print("-" * 10 + "\nComponent: %s" % comp)
        points = assign_receiver_to_points(comp_info, stations)
        print("Number of receivers: %d" % len(points))
        print("Number of windows: %d" % cat_wcounts[comp])

        if weight_flag:
            ref_dists[comp], cond_nums[comp] = \
                get_receiver_weights(comp, center, points, search_ratio,
                                     plot=plot_flag,
                                     figname_prefix=figname_prefix)
        else:
            # if not weight the receiver, then just leave the weight
            # values all to the default values(1.0). Leave the ref_dists
            # and cond_nums to None since there is no weighting
            # procedures. However, normalization still needs to be
            # applied later.
            ref_dists[comp] = None
            cond_nums[comp] = None

        # normlalize the receiver weights according to the reciever
        # window counts(normalization requirements)
        weights[comp] = normalize_receiver_weights(points, rec_wcounts[comp])

        _receiver_validator(weights[comp], rec_wcounts[comp],
                            cat_wcounts[comp])

    return {
        "rec_weights": weights,
        "rec_wcounts": rec_wcounts,
        "cat_wcounts": cat_wcounts,
        "rec_ref_dists": ref_dists,
        "rec_cond_nums": cond_nums
    }
예제 #4
0
def assign_receiver_to_points(channels, stations):
    """
    Assign the receiver information to SpherePoint

    :param rec_wcounts:
    :param stations:
    :return:
    """
    points = []
    for chan in channels:
        component = chan.split(".")[-1][-1]
        if component == "Z":
            # it is important to set the default weight value to
            # 1.0 here. Becuase if there is no receiver weightings,
            # then this default weights will be used
            point = SpherePoint(stations[chan]["latitude"],
                                stations[chan]["longitude"],
                                tag=chan,
                                weight=1.0)
        else:
            # for R and T component. In station file, there
            # are only `EN` or `12`
            echan = chan[:-1] + "E"
            chan1 = chan[:-1] + "1"
            zchan = chan[:-1] + "Z"

            if echan in stations:
                point = SpherePoint(stations[echan]["latitude"],
                                    stations[echan]["longitude"],
                                    tag=chan,
                                    weight=1.0)
            elif chan1 in stations:
                point = SpherePoint(stations[chan1]["latitude"],
                                    stations[chan1]["longitude"],
                                    tag=chan,
                                    weight=1.0)
            elif zchan in stations:
                point = SpherePoint(stations[zchan]["latitude"],
                                    stations[zchan]["longitude"],
                                    tag=chan,
                                    weight=1.0)
            else:
                raise ValueError("Can't find station information(%s)" % (chan))
        points.append(point)
    return points
예제 #5
0
def assign_source_to_points(sources):
    points = []
    for event, cat in sources.iteritems():
        origin = cat[0].preferred_origin()
        point = SpherePoint(origin.latitude,
                            origin.longitude,
                            tag=event,
                            weight=1.0)
        points.append(point)

    assert len(points) == len(sources)
    return points
    def __init__(self, cmtsource, data_container, config):

        self.cmtsource = cmtsource
        self.data_container = data_container

        self.config = config

        # center point set for cmtsource
        self.center = SpherePoint(
            self.cmtsource.latitude, self.cmtsource.longitude,
            tag="cmtsource")
        # keep category information
        self.point_bins = {}

        # init meta list for store weight information
        self._init_metas()
def parse_station_file(filename):
    pts = []
    with open(filename) as fh:
        content = fh.readlines()

    for line in content:
        info = line.split()
        sta = info[0]
        nw = info[1]
        tag = "%s_%s" % (nw, sta)
        lat = float(info[2])
        lon = float(info[3])
        pt = SpherePoint(lat, lon, tag)
        pts.append(pt)

    return pts
예제 #8
0
def read_points(filename):
    points = []
    with open(filename) as fh:
        content = fh.readlines()

    for line in content:
        info = line.split()
        sta = info[0]
        nw = info[1]
        tag = "%s_%s" % (nw, sta)
        lat = float(info[2])
        lon = float(info[3])
        coord = np.array([lat, lon])
        point = SpherePoint(lat, lon, tag)
        points.append(point)

    return points
예제 #9
0
def test_get_receiver_weights():
    center = SpherePoint(0, 0, tag="source")

    rec_counts, _ = ww.calculate_receiver_window_counts(windows)

    points = ww.assign_receiver_to_points(rec_counts["BHZ"], stations)
    ref_distance, cond_number = ww.get_receiver_weights(
        "BHZ", center, points, 0.35, plot=False)
    for p in points:
        npt.assert_almost_equal(p.weight, 1.0)
    npt.assert_almost_equal(cond_number, 1.0)

    points = ww.assign_receiver_to_points(rec_counts["BHT"], stations)
    ref_distance, cond_number = ww.get_receiver_weights(
        "BHZ", center, points, 0.35, plot=False)
    for p in points:
        npt.assert_almost_equal(p.weight, 1.0)
    npt.assert_almost_equal(cond_number, 1.0)
    def sort_into_category(self):
        """
        Sort data into different cateogeries, by the trwin.tag and
        trwin.channel. trwin.tag is usually the period band, so
        category would be like "27_60.BHZ", "27_60.BHR", "27_60.BHT",
        and "60_120.BHZ", "60_120.BHR", "60_120.BHT".
        """
        pbins = {}
        for idx, trwin in enumerate(self.data_container):
            if self.config.normalize_by_category:
                cat = get_trwin_tag(trwin)
            else:
                cat = "all"
            if cat not in pbins:
                pbins[cat] = []
            pbins[cat].append(
                SpherePoint(trwin.latitude, trwin.longitude, tag=idx))

        logger.info("Category: %s" % pbins.keys())

        self.point_bins = pbins
예제 #11
0
def determine_source_weighting(src_info, src_wcounts, max_ratio=0.35,
                               flag=True, plot=False,
                               figname_prefix=None):
    """
    Determine the source weighting based on source distribution and
    window counts.
    Attention here, there is still 3 components and each category
    should be weighting independently with the window count information
    in this components.
    """
    logger.info("Number of sources: %s" % len(src_info))
    logger.info("Window counts information: %s" % src_wcounts)

    # determine the weightins based on location
    points = []
    for eventname, event_info in src_info.iteritems():
        point = SpherePoint(event_info["latitude"],
                            event_info["longitude"],
                            tag=eventname,
                            weight=1.0)
        points.append(point)

    if flag:
        weightobj = SphereDistRel(points)
        scan_figname = figname_prefix + ".smart_scan.png"
        _ref_dist, _cond_num = weightobj.smart_scan(
            max_ratio=max_ratio, start=0.5, gap=0.5,
            drop_ratio=0.80, plot=plot,
            figname=scan_figname)
        if plot:
            figname = figname_prefix + ".weight.png"
            weightobj.plot_global_map(figname=figname, lon0=180.0)

    # stats window counts in category level
    cat_wcounts = {}
    for event, event_info in src_wcounts.iteritems():
        for comp, comp_info in event_info.iteritems():
            cat_wcounts.setdefault(comp, 0)
            cat_wcounts[comp] += comp_info

    weights = {}
    ref_dists = {}
    cond_nums = {}
    # nomalization
    for comp in cat_wcounts:
        # ref dist and condition number are the same for different components
        # because the source distribution is exactly the same
        ref_dists[comp] = _ref_dist
        cond_nums[comp] = _cond_num
        wsum = 0
        for point in points:
            nwin = src_wcounts[point.tag][comp]
            wsum += point.weight * nwin
        norm_factor = cat_wcounts[comp] / wsum
        weights[comp] = {}
        for point in points:
            eventname = point.tag
            weights[comp][eventname] = point.weight * norm_factor

    _source_validator(weights, src_wcounts, cat_wcounts)
    return {"src_weights": weights, "cat_wcounts": cat_wcounts,
            "src_ref_dists": ref_dists, "src_cond_nums": cond_nums}
예제 #12
0
def determine_receiver_weighting(src, stations, windows, max_ratio=0.35,
                                 flag=True, plot=False,
                                 figname_prefix=None):
    """
    Given one station and window information, determine the receiver
    weighting
    In one asdf file, there are still 3 components, for example,
    ["BHR", "BHT", "BHZ"]. These three components should be treated
    indepandently and weights will be calculated independantly.

    :return: dict of weights which contains 3 components. Each components
        contains weights values
    """
    center = SpherePoint(src["latitude"], src["longitude"],
                         tag="source")

    # extract window information
    weights = {}
    rec_wcounts = {}
    src_wcounts = defaultdict(lambda: 0)
    for sta, sta_window in windows.iteritems():
        for chan, chan_win in sta_window.iteritems():
            comp = chan.split(".")[-1]
            _nwin = len(chan_win)
            if _nwin == 0:
                continue
            weights.setdefault(comp, {}).update({chan: 0.0})
            rec_wcounts[chan] = _nwin
            src_wcounts[comp] += _nwin

    # in each components, calculate weight
    ref_dists = {}
    cond_nums = {}
    for comp, comp_info in weights.iteritems():
        points = []
        logger.info("Components:%s" % comp)
        for chan in comp_info:
            _comp = chan[-1]
            if _comp == "Z":
                point = SpherePoint(stations[chan]["latitude"],
                                    stations[chan]["longitude"],
                                    tag=chan, weight=1.0)
            else:
                # for R and T component. In station file, there
                # are only E and N component. So we need transfer
                echan = chan[:-1] + "E"
                chan1 = chan[:-1] + "1"
                zchan = chan[:-1] + "Z"
                if echan in stations:
                    point = SpherePoint(stations[echan]["latitude"],
                                        stations[echan]["longitude"],
                                        tag=chan, weight=1.0)
                elif chan1 in stations:
                    point = SpherePoint(stations[chan1]["latitude"],
                                        stations[chan1]["longitude"],
                                        tag=chan, weight=1.0)
                elif zchan in stations:
                    point = SpherePoint(stations[zchan]["latitude"],
                                        stations[zchan]["longitude"],
                                        tag=chan, weight=1.0)
            points.append(point)

        if flag:
            # calculate weight; otherwise, leave it as default value(1)
            weightobj = SphereDistRel(points, center=center)
            scan_figname = figname_prefix + "%s.smart_scan.png" % comp
            ref_dists[comp], cond_nums[comp] = weightobj.smart_scan(
                max_ratio=max_ratio, start=0.5, gap=0.5,
                drop_ratio=0.95, plot=plot,
                figname=scan_figname)
            if plot:
                figname = figname_prefix + "%s.weight.png" % comp
                weightobj.plot_global_map(figname=figname, lon0=180.0)
        else:
            ref_dists[comp] = None
            cond_nums[comp] = None

        wsum = 0
        for point in points:
            nwin = rec_wcounts[point.tag]
            wsum += point.weight * nwin
        norm_factor = src_wcounts[comp] / wsum

        for point in points:
            weights[comp][point.tag] = point.weight * norm_factor

    _receiver_validator(weights, rec_wcounts, src_wcounts)

    return {"rec_weights": weights, "rec_wcounts": rec_wcounts,
            "src_wcounts": src_wcounts, "rec_ref_dists": ref_dists,
            "rec_cond_nums": cond_nums}
예제 #13
0
def test_calculate_distance_array(spoints):
    center = SpherePoint(0, 0, "center")
    obj = SphereWeightBase(spoints, center=center)
    dists = obj._calculate_distance_array()
    npt.assert_allclose(dists, [10, 10, 10, 10])
예제 #14
0
def test_calculate_azimuth_array(spoints):
    center = SpherePoint(0, 0, "center")
    obj = SphereWeightBase(spoints, center=center)
    azis = obj._calculate_azimuth_array()
    trues = np.array([0, 90, 180, 270])
    npt.assert_allclose(azis, trues)
예제 #15
0
                          center=center,
                          bin_order=bin_order,
                          nbins=nbins)
    weight.calculate_weight()
    weight.plot_global_map()
    weight.plot_weight_histogram()


def test_sphereazirel(points, center, ref_azi=5.0):

    weight = SphereAziRel(points, center=center)
    ref_azi, _ = weight.smart_scan(plot=True)
    weight.calculate_weight(ref_azi)
    weight.plot_exp_matrix()
    weight.plot_global_map()
    weight.plot_weight_histogram()
    #weight.scan(plot=True)
    # weight.write_weight(filename="azirel.txt")
    # weight.plot_station_weight_distribution(nbins=12)
    weight.calculate_weight(30)
    weight.plot_exp_matrix()
    weight.plot_global_map()


if __name__ == "__main__":
    points = read_points("./STATIONS_waveforms")
    center = SpherePoint(0, 0, "center")

    test_sphereazibin(points, center)
    test_sphereazirel(points, center)
예제 #16
0
def plot_global_map(points, figname=None):
    weightobj = SphereDistRel(points, SpherePoint(0, 180.0, tag="Center"))
    weightobj.plot_global_map(figname=figname, lon0=180.0, figsize=(20, 8))