def grid_point_sources(sources, ps_grid_spacing): """ :param sources: a list of sources with the same grp_id (point sources and not) :param ps_grid_spacing: value of the point source grid spacing in km; if None, do nothing :returns: a dict grp_id -> list of non-point sources and collapsed point sources """ grp_id = sources[0].grp_id for src in sources[1:]: assert src.grp_id == grp_id, (src.grp_id, grp_id) if ps_grid_spacing is None: return {grp_id: sources} out = [src for src in sources if not hasattr(src, 'location')] ps = numpy.array([src for src in sources if hasattr(src, 'location')]) if len(ps) < 2: # nothing to collapse return {grp_id: out + list(ps)} coords = _coords(ps) deltax = angular_distance(ps_grid_spacing, lat=coords[:, 1].mean()) deltay = angular_distance(ps_grid_spacing) grid = groupby_grid(coords[:, 0], coords[:, 1], deltax, deltay) for idxs in grid.values(): cps = CollapsedPointSource(ps[idxs]) cps.num_ruptures = cps.count_ruptures() cps.id = ps[0].id cps.grp_id = ps[0].grp_id cps.et_id = ps[0].et_id cps.nsites = sum(p.nsites for p in ps) out.append(cps) return {sources[0].grp_id: out}
def grid_point_sources(sources, ps_grid_spacing, monitor=Monitor()): """ :param sources: a list of sources with the same grp_id (point sources and not) :param ps_grid_spacing: value of the point source grid spacing in km; if None, do nothing :returns: a dict grp_id -> list of non-point sources and collapsed point sources """ grp_id = sources[0].grp_id for src in sources[1:]: assert src.grp_id == grp_id, (src.grp_id, grp_id) if ps_grid_spacing is None: return {grp_id: sources} out = [src for src in sources if not hasattr(src, 'location')] ps = numpy.array([src for src in sources if hasattr(src, 'location')]) if len(ps) < 2: # nothing to collapse return {grp_id: out + list(ps)} coords = _coords(ps) deltax = angular_distance(ps_grid_spacing, lat=coords[:, 1].mean()) deltay = angular_distance(ps_grid_spacing) grid = groupby_grid(coords[:, 0], coords[:, 1], deltax, deltay) task_no = getattr(monitor, 'task_no', 0) for i, idxs in enumerate(grid.values()): if len(idxs) > 1: cps = CollapsedPointSource('cps-%d-%d' % (task_no, i), ps[idxs]) cps.id = ps[0].id cps.grp_id = ps[0].grp_id cps.trt_smrlz = ps[0].trt_smrlz out.append(cps) else: # there is a single source out.append(ps[idxs[0]]) return {grp_id: out}
def close_sids(self, rec, trt, mag): """ :param rec: a record with fields minlon, minlat, maxlon, maxlat :param trt: tectonic region type string :param mag: magnitude :returns: the site indices within the bounding box enlarged by the integration distance for the given TRT and magnitude """ if self.sitecol is None: return [] elif not self.integration_distance: # do not filter return self.sitecol.sids if hasattr(rec, 'dtype'): bbox = rec['minlon'], rec['minlat'], rec['maxlon'], rec['maxlat'] else: bbox = rec # assume it is a 4-tuple maxdist = self.integration_distance(trt, mag) a1 = min(maxdist * KM_TO_DEGREES, 90) a2 = min(angular_distance(maxdist, bbox[1], bbox[3]), 180) bb = bbox[0] - a2, bbox[1] - a1, bbox[2] + a2, bbox[3] + a1 if hasattr(self, 'index'): # RtreeFilter return within(bb, self.index) return self.sitecol.within_bbox(bb)
def close_sids(self, rec, trt, mag): """ :param rec: a record with fields minlon, minlat, maxlon, maxlat :param trt: tectonic region type string :param mag: magnitude :returns: the site indices within the bounding box enlarged by the integration distance for the given TRT and magnitude """ if self.sitecol is None: return [] elif not self.integration_distance: # do not filter return self.sitecol.sids if hasattr(rec, 'dtype'): bbox = rec['minlon'], rec['minlat'], rec['maxlon'], rec['maxlat'] else: bbox = rec # assume it is a 4-tuple maxdist = self.integration_distance(trt, mag) a1 = min(maxdist * KM_TO_DEGREES, 90) a2 = min(angular_distance(maxdist, bbox[1], bbox[3]), 180) bb = bbox[0] - a2, bbox[1] - a1, bbox[2] + a2, bbox[3] + a1 return self.sitecol.within_bbox(bb)
def get_bounding_box(self, maxdist): """ Bounding box containing all points, enlarged by the maximum distance """ west, east, north, south = self.surface.get_bounding_box() a1 = maxdist * KM_TO_DEGREES a2 = angular_distance(maxdist, north, south) return west - a2, south - a1, east + a2, north + a1
def get_bounding_box(self, maxdist): """ Bounding box containing all points, enlarged by the maximum distance """ west, east, north, south = self.surface.get_bounding_box() a1 = maxdist * KM_TO_DEGREES a2 = angular_distance(maxdist, north, south) return west - a2, south - a1, east + a2, north + a1
def get_bounding_box(self, maxdist): """ :returns: min_lon, min_lat, max_lon, max_lat """ with h5py.File(self.source_file, 'r') as hdf5: locations = hdf5["Grid/Locations"][()] lons, lats = locations[:, 0], locations[:, 1] bbox = lons.min(), lats.min(), lons.max(), lats.max() a1 = min(maxdist * KM_TO_DEGREES, 90) a2 = angular_distance(maxdist, bbox[1], bbox[3]) return bbox[0] - a2, bbox[1] - a1, bbox[2] + a2, bbox[3] + a1
def get_bounding_box(self, maxdist): """ Bounding box containing all points, enlarged by the maximum distance and the maximum rupture projection radius (upper limit). """ lon = self.location.longitude lat = self.location.latitude maxradius = self._get_max_rupture_projection_radius() a1 = (maxdist + maxradius) * KM_TO_DEGREES a2 = angular_distance(maxdist + maxradius, lat) return lon - a2, lat - a1, lon + a2, lat + a1
def get_bounding_box(self, maxdist): """ Bounding box containing all surfaces, enlarged by the maximum distance """ surfaces = [] for rup, _ in self.data: if isinstance(rup.surface, MultiSurface): for s in rup.surface.surfaces: surfaces.append(s) else: surfaces.append(rup.surface) multi_surf = MultiSurface(surfaces) west, east, north, south = multi_surf.get_bounding_box() a1 = maxdist * KM_TO_DEGREES a2 = angular_distance(maxdist, north, south) return west - a2, south - a1, east + a2, north + a1
def get_bounding_box(self, maxdist): """ Bounding box containing all surfaces, enlarged by the maximum distance """ surfaces = [] for rup, _ in self.data: if isinstance(rup.surface, MultiSurface): for s in rup.surface.surfaces: surfaces.append(s) else: surfaces.append(rup.surface) multi_surf = MultiSurface(surfaces) west, east, north, south = multi_surf.get_bounding_box() a1 = maxdist * KM_TO_DEGREES a2 = angular_distance(maxdist, north, south) return west - a2, south - a1, east + a2, north + a1
def get_bounding_box(self, lon, lat, trt=None): """ Build a bounding box around the given lon, lat by computing the maximum_distance at the given tectonic region type and magnitude. :param lon: longitude :param lat: latitude :param trt: tectonic region type, possibly None :returns: min_lon, min_lat, max_lon, max_lat """ if trt is None: # take the greatest integration distance maxdist = max(self.max().values()) else: # get the integration distance for the given TRT maxdist = self[trt][-1][1] a1 = min(maxdist * KM_TO_DEGREES, 90) a2 = min(angular_distance(maxdist, lat), 180) return lon - a2, lat - a1, lon + a2, lat + a1
def get_bounding_box(self, lon, lat, trt=None, mag=None): """ Build a bounding box around the given lon, lat by computing the maximum_distance at the given tectonic region type and magnitude. :param lon: longitude :param lat: latitude :param trt: tectonic region type, possibly None :param mag: magnitude, possibly None :returns: min_lon, min_lat, max_lon, max_lat """ if trt is None: # take the greatest integration distance maxdist = max(self(trt, mag) for trt in self.dic) else: # get the integration distance for the given TRT maxdist = self(trt, mag) a1 = min(maxdist * KM_TO_DEGREES, 90) a2 = min(angular_distance(maxdist, lat), 180) return lon - a2, lat - a1, lon + a2, lat + a1
def close_sids(self, rec, trt): """ :param rec: a record with fields mag, minlon, minlat, maxlon, maxlat :param trt: tectonic region type string :returns: the site indices within the bounding box enlarged by the integration distance for the given TRT and magnitude """ if self.sitecol is None: return [] elif not self.integration_distance: # do not filter return self.sitecol.sids bbox = rec['minlon'], rec['minlat'], rec['maxlon'], rec['maxlat'] maxdist = self.integration_distance(trt, rec['mag']) a1 = min(maxdist * KM_TO_DEGREES, 90) a2 = min(angular_distance(maxdist, bbox[1], bbox[3]), 180) bb = bbox[0] - a2, bbox[1] - a1, bbox[2] + a2, bbox[3] + a1 return self.sitecol.within_bbox(bb)
def lon_lat_bins(lon, lat, size_km, coord_bin_width): """ Define lon, lat bin edges for disaggregation histograms. :param lon: longitude of the site :param lat: latitude of the site :param size_km: total size of the bins in km :param coord_bin_width: bin width in degrees :returns: two arrays lon bins, lat bins """ nbins = numpy.ceil(size_km * KM_TO_DEGREES / coord_bin_width) delta_lon = min(angular_distance(size_km, lat), 180) delta_lat = min(size_km * KM_TO_DEGREES, 90) EPS = .001 # avoid discarding the last edgebdata.pnes.shape lon_bins = lon + numpy.arange(-delta_lon, delta_lon + EPS, delta_lon / nbins) lat_bins = lat + numpy.arange(-delta_lat, delta_lat + EPS, delta_lat / nbins) if cross_idl(*lon_bins): lon_bins %= 360 return lon_bins, lat_bins