def computeRjb(self, lon, lat, depth, var=False): """ Method for computing Joyner-Boore distance. Args: lon (array): Numpy array of longitudes. lat (array): Numpy array of latitudes. depth (array): Numpy array of depths (km; positive down). var (bool): Also return variance of prediction. Unused, and will raise an exception if not False. Returns: array: Joyner-Boore distance (km). """ if var is True: raise ValueError('var must be False for EdgeRupture') # --------------------------------------------------------------------- # Sort out sites # --------------------------------------------------------------------- oldshape = lon.shape if len(oldshape) == 2: newshape = (oldshape[0] * oldshape[1], 1) else: newshape = (oldshape[0], 1) x, y, z = latlon2ecef(lat, lon, depth) x.shape = newshape y.shape = newshape z.shape = newshape sites_ecef = np.hstack((x, y, z)) minrjb = np.ones(newshape, dtype=lon.dtype) * 1e16 quads = self.getQuadrilaterals() for i in range(len(quads)): P0, P1, P2, P3 = quads[i] S0 = copy.deepcopy(P0) S1 = copy.deepcopy(P1) S2 = copy.deepcopy(P2) S3 = copy.deepcopy(P3) S0.depth = 0.0 S1.depth = 0.0 S2.depth = 0.0 S3.depth = 0.0 squad = [S0, S1, S2, S3] rjbdist = utils._quad_distance(squad, sites_ecef, horizontal=True) minrjb = np.minimum(minrjb, rjbdist) minrjb = minrjb.reshape(oldshape) return minrjb
def computeRjb(self, lon, lat, depth): """ Method for computing Joyner-Boore distance. Args: lon (array): Numpy array of longitudes. lat (array): Numpy array of latitudes. depth (array): Numpy array of depths (km; positive down). Returns: tuple: A tuple of an array of Joyner-Boore distance (km), and None. """ # --------------------------------------------------------------------- # Sort out sites # --------------------------------------------------------------------- oldshape = lon.shape if len(oldshape) == 2: newshape = (oldshape[0] * oldshape[1], 1) else: newshape = (oldshape[0], 1) x, y, z = latlon2ecef(lat, lon, depth) x.shape = newshape y.shape = newshape z.shape = newshape sites_ecef = np.hstack((x, y, z)) minrjb = np.ones(newshape, dtype=lon.dtype) * 1e16 quads = self.getQuadrilaterals() for i in range(len(quads)): P0, P1, P2, P3 = quads[i] S0 = copy.deepcopy(P0) S1 = copy.deepcopy(P1) S2 = copy.deepcopy(P2) S3 = copy.deepcopy(P3) S0.depth = 0.0 S1.depth = 0.0 S2.depth = 0.0 S3.depth = 0.0 squad = [S0, S1, S2, S3] rjbdist = utils._quad_distance(squad, sites_ecef, horizontal=True) minrjb = np.minimum(minrjb, rjbdist) minrjb = minrjb.reshape(oldshape) return minrjb, None
def computeRrup(self, lon, lat, depth, var=False): """ Method for computing rupture distance. Args: lon (array): Numpy array of longitudes. lat (array): Numpy array of latitudes. depth (array): Numpy array of depths (km; positive down). var (bool): Also return variance of prediction. Unused, and will raise an exception if not False. Returns: array: Rupture distance (km). """ if var is True: raise ValueError('var must be False for EdgeRupture') # --------------------------------------------------------------------- # Sort out sites # --------------------------------------------------------------------- oldshape = lon.shape if len(oldshape) == 2: newshape = (oldshape[0] * oldshape[1], 1) else: newshape = (oldshape[0], 1) x, y, z = latlon2ecef(lat, lon, depth) x.shape = newshape y.shape = newshape z.shape = newshape sites_ecef = np.hstack((x, y, z)) minrrup = np.ones(newshape, dtype=lon.dtype) * 1e16 quads = self.getQuadrilaterals() for i in range(len(quads)): rrupdist = utils._quad_distance(quads[i], sites_ecef) minrrup = np.minimum(minrrup, rrupdist) minrrup = minrrup.reshape(oldshape) return minrrup
def __computeWrup(self): """ Compute the the portion (in km) of the width of the rupture which ruptures up-dip from the hypocenter to the top of the rupture. Wrup is the portion (in km) of the width of the rupture which ruptures up-dip from the hypocenter to the top of the rupture. * This is ambiguous for ruptures with varible top of rupture (not allowed in NGA). For now, lets just compute this for the quad where the hypocenter is located. * Alternative is to compute max Wrup for the different quads. """ nquad = len(self._rup.getQuadrilaterals()) # --------------------------------------------------------------------- # First find which quad the hypocenter is on # --------------------------------------------------------------------- x, y, z = latlon2ecef(self._hyp.latitude, self._hyp.longitude, self._hyp.depth) hyp_ecef = np.array([[x, y, z]]) qdist = np.zeros(nquad) for i in range(0, nquad): qdist[i] = utils._quad_distance(self._rup.getQuadrilaterals()[i], hyp_ecef) ind = int(np.where(qdist == np.min(qdist))[0][0]) # *** check that this doesn't break with more than one quad q = self._rup.getQuadrilaterals()[ind] # --------------------------------------------------------------------- # Compute Wrup on that quad # --------------------------------------------------------------------- pp0 = Vector.fromPoint( geo.point.Point(q[0].longitude, q[0].latitude, q[0].depth)) hyp_ecef = Vector.fromPoint( geo.point.Point(self._hyp.longitude, self._hyp.latitude, self._hyp.depth)) hp0 = hyp_ecef - pp0 ddv = utils.get_quad_down_dip_vector(q) self._Wrup = Vector.dot(ddv, hp0) / 1000
def __computeWrup(self): """ Compute the the portion (in km) of the width of the rupture which ruptures up-dip from the hypocenter to the top of the rupture. Wrup is the portion (in km) of the width of the rupture which ruptures up-dip from the hypocenter to the top of the rupture. * This is ambiguous for ruptures with varible top of rupture (not allowed in NGA). For now, lets just compute this for the quad where the hypocenter is located. * Alternative is to compute max Wrup for the different quads. """ nquad = len(self._rup.getQuadrilaterals()) # --------------------------------------------------------------------- # First find which quad the hypocenter is on # --------------------------------------------------------------------- x, y, z = latlon2ecef( self._hyp.latitude, self._hyp.longitude, self._hyp.depth) hyp_ecef = np.array([[x, y, z]]) qdist = np.zeros(nquad) for i in range(0, nquad): qdist[i] = utils._quad_distance( self._rup.getQuadrilaterals()[i], hyp_ecef) ind = int(np.where(qdist == np.min(qdist))[0][0]) # *** check that this doesn't break with more than one quad q = self._rup.getQuadrilaterals()[ind] # --------------------------------------------------------------------- # Compute Wrup on that quad # --------------------------------------------------------------------- pp0 = Vector.fromPoint(geo.point.Point( q[0].longitude, q[0].latitude, q[0].depth)) hyp_ecef = Vector.fromPoint(geo.point.Point( self._hyp.longitude, self._hyp.latitude, self._hyp.depth)) hp0 = hyp_ecef - pp0 ddv = utils.get_quad_down_dip_vector(q) self._Wrup = Vector.dot(ddv, hp0) / 1000
def computeRrup(self, lon, lat, depth): """ Method for computing rupture distance. Args: lon (array): Numpy array of longitudes. lat (array): Numpy array of latitudes. depth (array): Numpy array of depths (km; positive down). Returns: tuple: A tuple of an array of Rupture distance (km), and None. """ # --------------------------------------------------------------------- # Sort out sites # --------------------------------------------------------------------- oldshape = lon.shape if len(oldshape) == 2: newshape = (oldshape[0] * oldshape[1], 1) else: newshape = (oldshape[0], 1) x, y, z = latlon2ecef(lat, lon, depth) x.shape = newshape y.shape = newshape z.shape = newshape sites_ecef = np.hstack((x, y, z)) minrrup = np.ones(newshape, dtype=lon.dtype) * 1e16 quads = self.getQuadrilaterals() for i in range(len(quads)): rrupdist = utils._quad_distance(quads[i], sites_ecef) minrrup = np.minimum(minrrup, rrupdist) minrrup = minrrup.reshape(oldshape) return minrrup, None
def getDepthAtPoint(self, lat, lon): SMALL_DISTANCE = 2e-03 # 2 meters depth = np.nan tmp, _ = self.computeRjb(np.array([lon]), np.array([lat]), np.array([0])) if tmp > SMALL_DISTANCE: return depth i = 0 imin = -1 dmin = 9999999999999999 for quad in self.getQuadrilaterals(): pX = Vector.fromPoint(Point(lon, lat, 0)) points = np.reshape(np.array([pX.x, pX.y, pX.z]), (1, 3)) rjb = utils._quad_distance(quad, points, horizontal=True) if rjb[0][0] < dmin: dmin = rjb[0][0] imin = i i += 1 quad = self._quadrilaterals[imin] P0, P1, P2, P3 = quad # project the quad and the point in question to orthographic defined by # quad xmin = np.min([P0.x, P1.x, P2.x, P3.x]) xmax = np.max([P0.x, P1.x, P2.x, P3.x]) ymin = np.min([P0.y, P1.y, P2.y, P3.y]) ymax = np.max([P0.y, P1.y, P2.y, P3.y]) proj = OrthographicProjection(xmin, xmax, ymax, ymin) # project each vertex of quad (at 0 depth) s0x, s0y = proj(P0.x, P0.y) s1x, s1y = proj(P1.x, P1.y) s2x, s2y = proj(P2.x, P2.y) s3x, s3y = proj(P3.x, P3.y) sxx, sxy = proj(lon, lat) # turn these to vectors s0 = Vector(s0x, s0y, 0) s1 = Vector(s1x, s1y, 0) s3 = Vector(s3x, s3y, 0) sx = Vector(sxx, sxy, 0) # Compute vector from s0 to s1 s0s1 = s1 - s0 # Compute the vector from s0 to s3 s0s3 = s3 - s0 # Compute the vector from s0 to sx s0sx = sx - s0 # cross products s0normal = s0s3.cross(s0s1) dd = s0s1.cross(s0normal) # normalize dd (down dip direction) ddn = dd.norm() # dot product sxdd = ddn.dot(s0sx) # get width of quad (convert from km to m) w = utils.get_quad_width(quad) * 1000 # Get weights for top and bottom edge depths N = utils.get_quad_normal(quad) V = utils.get_vertical_vector(quad) dip = np.degrees(np.arccos(Vector.dot(N, V))) ws = (w * np.cos(np.radians(dip))) wtt = (ws - sxdd) / ws wtb = sxdd / ws # Compute the depth of of the plane at Px: depth = wtt * P0.z + wtb * P3.z * 1000 return depth