def _get_box(latlon0, azimuth, length, width=_LARGE_BOX_WIDTH, offset=0): """Create a single box.""" from shapely.geometry import Polygon start = direct_geodetic(latlon0, azimuth, offset) azis = ((azimuth - 90) % 360, azimuth, (azimuth + 90) % 360, (azimuth + 180) % 360) dists = (width/2, length, width, length) latlon = start corners = [] for a, d in zip(azis, dists): latlon = direct_geodetic(latlon, a, d) corners.append(latlon[::-1]) box = {'poly': Polygon(corners), 'length': length, 'pos': offset + length/2, 'latlon': direct_geodetic(start, azimuth, length/2)} return box
def _get_box(latlon0, azimuth, length, width=_LARGE_BOX_WIDTH, offset=0): """Create a single box.""" from shapely.geometry import Polygon start = direct_geodetic(latlon0, azimuth, offset) azis = ((azimuth - 90) % 360, azimuth, (azimuth + 90) % 360, (azimuth + 180) % 360) dists = (width/2, length, width, length) latlon = start corners = [] for a, d in zip(azis, dists): latlon = direct_geodetic(latlon, a, d) corners.append(latlon[::-1]) box = {'poly': Polygon(corners), 'length': length, 'pos': offset + length/2, 'latlon': direct_geodetic(start, azimuth, length/2)} return box
def ppoint(self, stats, depth, phase='S'): """ Calculate latitude and longitude of piercing point. Piercing point coordinates and depth are saved in the pp_latitude, pp_longitude and pp_depth entries of the stats object or dictionary. :param stats: Stats object or dictionary with entries slowness, back_azimuth, station_latitude and station_longitude :param depth: depth of interface in km :param phase: 'P' for piercing point of P wave, 'S' for piercing point of S wave. Multiples are possible, too. :return: latitude and longitude of piercing point """ dr = self.ppoint_distance(depth, stats['slowness'], phase=phase) lat = stats['station_latitude'] lon = stats['station_longitude'] az = stats['back_azimuth'] plat, plon = direct_geodetic((lat, lon), az, dr) stats['pp_depth'] = depth stats['pp_latitude'] = plat stats['pp_longitude'] = plon return plat, plon
def ppoint(self, stats, depth, phase='S'): """ Calculate latitude and longitude of piercing point. Piercing point coordinates and depth are saved in the pp_latitude, pp_longitude and pp_depth entries of the stats object or dictionary. :param stats: Stats object or dictionary with entries slowness, back_azimuth, station_latitude and station_longitude :param depth: depth of interface in km :param phase: 'P' for piercing point of P wave, 'S' for piercing point of S wave. Multiples are possible, too. :return: latitude and longitude of piercing point """ dr = self.ppoint_distance(depth, stats['slowness'], phase=phase) lat = stats['station_latitude'] lon = stats['station_longitude'] az = stats['back_azimuth'] plat, plon = direct_geodetic((lat, lon), az, dr) stats['pp_depth'] = depth stats['pp_latitude'] = plat stats['pp_longitude'] = plon return plat, plon
def generateGrids(self): # Start mesh generation============================================== sll = self._start_lat_lon result = [] resultCart = [] dx = self._length / float(self._nx - 1) dy = self._width / float(self._ny - 1) dz = self._depth / float(self._nz - 1) runLengthll = sll runWidthll = sll # cx = cy = cz = 0 for ix in range(self._nx): runWidthll = runLengthll for iy in range(self._ny): for iz in range(self._nz): result.append([runWidthll[1], runWidthll[0], iz * dz]) resultCart.append([ix * dx, iy * dy, iz * dz]) # end for runWidthll = direct_geodetic(runLengthll, self._ortho, iy * dy) # end for runLengthll = direct_geodetic(runLengthll, self._azimuth, dx) # end for result = np.array(result).reshape(self._nx, self._ny, self._nz, 3) resultCart = np.array(resultCart).reshape(self._nx, self._ny, self._nz, 3) glon = result[:, :, :, 0].reshape(self._nx, self._ny, self._nz) glat = result[:, :, :, 1].reshape(self._nx, self._ny, self._nz) # Create local cartesian axis-aligned grids # Naming convention (Grid [XYZ] Axis-Aligned) gxaa = resultCart[:, :, :, 0].reshape(self._nx, self._ny, self._nz) gyaa = resultCart[:, :, :, 1].reshape(self._nx, self._ny, self._nz) gzaa = resultCart[:, :, :, 2].reshape(self._nx, self._ny, self._nz) # Create cartesian mesh with spherical curvature # Naming convention (Grid [XYZ] Spherical) ts = (90 - glat.flatten()) / 180. * np.pi ps = glon.flatten() / 180. * np.pi rs = (self._earth_radius - gzaa.flatten()) * np.ones(ts.shape) rtps = np.array([rs, ts, ps]).T xyzs = rtp2xyz(rtps[:, 0], rtps[:, 1], rtps[:, 2]) xyzs = np.array(xyzs).reshape(self._nx, self._ny, self._nz, 3) gxs = xyzs[:, :, :, 0].reshape(self._nx, self._ny, self._nz) gys = xyzs[:, :, :, 1].reshape(self._nx, self._ny, self._nz) gzs = xyzs[:, :, :, 2].reshape(self._nx, self._ny, self._nz) if (self._debug): print(np.min(gxs.flatten()), np.max(gxs.flatten())) print(np.min(gys.flatten()), np.max(gys.flatten())) print(np.min(gzs.flatten()), np.max(gzs.flatten())) # Compute cell-centre coordinates # Naming convention (Grid [XYZ] Spherical Centre) gxsc = (gxs[:-1, :-1, :-1] + gxs[1:, 1:, 1:]) / 2. gysc = (gys[:-1, :-1, :-1] + gys[1:, 1:, 1:]) / 2. gzsc = (gzs[:-1, :-1, :-1] + gzs[1:, 1:, 1:]) / 2. if (self._debug): print('\n') print(np.min(gxsc.flatten()), np.max(gxsc.flatten())) print(np.min(gysc.flatten()), np.max(gysc.flatten())) print(np.min(gzsc.flatten()), np.max(gzsc.flatten())) return glon, glat, gzaa, gxaa, gyaa, gzaa, gxs, gys, gzs, gxsc, gysc, gzsc