def spoints(): return [ SpherePoint(10, 10, "point1"), SpherePoint(10, -10, "point2"), SpherePoint(-10, -10, "point3"), SpherePoint(-10, 10, "point4") ]
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
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 }
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
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
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
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
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}
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}
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])
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)
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)
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))