def get_closest_stations(self, lon, lat, nn=1): """ :param lon: longitude (degree) :param lat: latitude (degrees) :param nn: number of closest stations to fetch :return: A tuple containing a list of closest 'network.station' names and a list of distances (in ascending order) in kms """ assert nn > 0, 'nn must be > 0' xyz = rtp2xyz(np.array([self._earth_radius]), np.array([np.radians(90 - lat)]), np.array([np.radians(lon)])) d, l = self._tree.query(xyz, nn) if isinstance(l, int): l = [l] if (len(d.shape)==1): d = np.expand_dims(d, axis=0) l = l[l<len(self.unique_coordinates)] if isinstance(l, int): l = [l] return (list(self._key_list[l]), d[0, :len(l)])
def __init__(self, asdf_source, logger=None, single_item_read_limit_in_mb=1024): """ Initializer for FederatedASDFDataSet. :param asdf_source: Path to a text file containing a list of ASDF files. \ Entries can be commented out with '#' :param logger: logger instance """ self.logger = logger self.asdf_source = asdf_source self._unique_coordinates = None self._earth_radius = 6371 # km # Instantiate implementation class self.fds = _FederatedASDFDataSetImpl( asdf_source, logger=logger, single_item_read_limit_in_mb=single_item_read_limit_in_mb) # Populate coordinates self._unique_coordinates = defaultdict(list) rtps_dict = defaultdict() for ds_dict in self.fds.asdf_station_coordinates: for key in list(ds_dict.keys()): self._unique_coordinates[key] = [ ds_dict[key][0], ds_dict[key][1] ] rtps_dict[key] = [ self._earth_radius, np.radians(90 - ds_dict[key][1]), np.radians(ds_dict[key][0]) ] # end for # end for rtps_list = [] for k in list(rtps_dict.keys()): rtps_list.append(rtps_dict[k]) # end for rtps = np.array(rtps_list) xyzs = rtp2xyz(rtps[:, 0], rtps[:, 1], rtps[:, 2]) self._tree = cKDTree(xyzs) self._key_list = np.array(list(rtps_dict.keys()))
def __init__(self, asdf_source, variant='db', use_json_db=False, logger=None): """ :param asdf_source: path to a text file containing a list of ASDF files: Entries can be commented out with '#' :param variant: can be either 'mem' or 'db' :param use_json_db: whether to use json db if available. Has no effect if variant is 'db' :param logger: logger instance """ self.variant = variant self.use_json_db = use_json_db self.logger = logger self.asdf_source = asdf_source self._unique_coordinates = None self._earth_radius = 6371 #km if (self.variant == 'mem'): if (HAS_RTREE): self.fds = FederatedASDFDataSetMemVariant( asdf_source, use_json_db, logger) else: raise Exception( "'mem' variant cannot be used, because package rtree is missing" ) # end if elif (self.variant == 'db'): self.fds = FederatedASDFDataSetDBVariant(asdf_source, logger) else: raise Exception("Invalid variant: must be 'mem' or 'db'") # end if # Populate coordinates self._unique_coordinates = defaultdict(list) rtps_dict = defaultdict() for ds_dict in self.fds.asdf_station_coordinates: for key in ds_dict.keys(): self._unique_coordinates[key] = [ ds_dict[key][0], ds_dict[key][1] ] rtps_dict[key] = [ self._earth_radius, np.radians(90 - ds_dict[key][1]), np.radians(ds_dict[key][0]) ] # end for # end for rtps_list = [] for k in rtps_dict.keys(): rtps_list.append(rtps_dict[k]) # end for rtps = np.array(rtps_list) xyzs = rtp2xyz(rtps[:, 0], rtps[:, 1], rtps[:, 2]) self._tree = cKDTree(xyzs) self._key_list = np.array(rtps_dict.keys())