def test_ecef(): print('Testing ECEF conversion code...') lat = 32.1 lon = 118.5 dep = 10.0 x, y, z = latlon2ecef(lat, lon, dep) TESTX = -2576515.419 TESTY = 4745351.087 TESTZ = 3364516.124 np.testing.assert_almost_equal(x, TESTX, decimal=2) np.testing.assert_almost_equal(y, TESTY, decimal=2) np.testing.assert_almost_equal(z, TESTZ, decimal=2) lat2, lon2, dep2 = ecef2latlon(x, y, z) np.testing.assert_almost_equal(lat2, lat, decimal=2) np.testing.assert_almost_equal(lon2, lon, decimal=2) np.testing.assert_almost_equal(dep2, dep, decimal=2) print('Passed tests of ECEF conversion code.')
def _get_quad_slip_ds_ss(q, rake, cp, p): """ Compute the DIP SLIP and STRIKE SLIP components of the unit slip vector in ECEF coords for a quad and rake angle. :param q: A quadrilateral. :param rake: Direction of motion of the hanging wall relative to the foot wall, as measured by the angle (deg) from the strike vector. :param cp: A 3x(n sub fault) array giving center points of each sub fault in ECEF coords. :param p: A 3x(n sub fault) array giving the unit vectors of the propagation vector on each sub fault in ECEF coords. :returns: List of dip slip and strike slip components (each is a matrix) of the unit slip vector in ECEF space. """ # Get quad vertices, strike, dip P0, P1, P2 = q[0:3] strike = P0.azimuth(P1) dip = fault.get_quad_dip(q) # Slip unit vectors in 'local' (i.e., z-up, x-east) coordinates d1_local = fault.get_local_unit_slip_vector_DS(strike, dip, rake) s1_local = fault.get_local_unit_slip_vector_SS(strike, dip, rake) # Convert to a column array d1_col = np.array([[d1_local.x], [d1_local.y], [d1_local.z]]) s1_col = np.array([[s1_local.x], [s1_local.y], [s1_local.z]]) # Define 'local' coordinate system qlats = [a.latitude for a in q] qlons = [a.longitude for a in q] proj = get_orthographic_projection( np.min(qlons), np.max(qlons), np.min(qlats), np.max(qlats)) # Convert p and cp to geographic coords p0lat, p0lon, p0z = ecef2latlon(cp[0, ], cp[1, ], cp[2, ]) p1lat, p1lon, p1z = ecef2latlon(cp[0, ] + p[0, ], cp[1, ] + p[1, ], cp[2, ] + p[2, ]) # Convert p to 'local' coords p0x, p0y = proj(p0lon, p0lat) p1x, p1y = proj(p1lon, p1lat) px = p1x - p0x py = p1y - p0y pz = p1z - p0z # Apply sign changes in 'local' coords s1mat = np.array([[np.abs(s1_col[0]) * np.sign(px)], [np.abs(s1_col[1]) * np.sign(py)], [np.abs(s1_col[2]) * np.sign(pz)]]) # [np.abs(s1_col[2])*np.ones_like(pz)]]) dipsign = -np.sign(np.sin(np.radians(rake))) d1mat = np.array([[d1_col[0] * np.ones_like(px) * dipsign], [d1_col[1] * np.ones_like(py) * dipsign], [d1_col[2] * np.ones_like(pz) * dipsign]]) # Need to track 'origin' s0 = np.array([[0], [0], [0]]) # Convert from 'local' to geographic coords s1_ll = proj(s1mat[0, ], s1mat[1, ], reverse=True) d1_ll = proj(d1mat[0, ], d1mat[1, ], reverse=True) s0_ll = proj(s0[0], s0[1], reverse=True) # And then back to ECEF: s1_ecef = latlon2ecef(s1_ll[1], s1_ll[0], s1mat[2, ]) d1_ecef = latlon2ecef(d1_ll[1], d1_ll[0], d1mat[2, ]) s0_ecef = latlon2ecef(s0_ll[1], s0_ll[0], s0[2]) s00 = s0_ecef[0].reshape(-1) s01 = s0_ecef[1].reshape(-1) s02 = s0_ecef[2].reshape(-1) d_mat = np.array([d1_ecef[0].reshape(-1) - s00, d1_ecef[1].reshape(-1) - s01, d1_ecef[2].reshape(-1) - s02]) s_mat = np.array([s1_ecef[0].reshape(-1) - s00, s1_ecef[1].reshape(-1) - s01, s1_ecef[2].reshape(-1) - s02]) return d_mat, s_mat
def __computeThetaAndS(self, i): """ :param i: Compute d for the i-th quad/segment. """ # self.phyp is in ECEF tmp = ecef.ecef2latlon(self.phyp[i].x, self.phyp[i].y, self.phyp[i].z) epi_ecef = Vector.fromPoint(geo.point.Point(tmp[1], tmp[0], 0.0)) epi_col = np.array([[epi_ecef.x], [epi_ecef.y], [epi_ecef.z]]) # First compute along strike vector P0, P1, P2, P3 = self._rup.getQuadrilaterals()[i] p0 = Vector.fromPoint(P0) # convert to ECEF p1 = Vector.fromPoint(P1) e01 = p1 - p0 e01norm = e01.norm() hp0 = p0 - epi_ecef hp1 = p1 - epi_ecef strike_min = Vector.dot(hp0, e01norm) / 1000.0 # convert to km strike_max = Vector.dot(hp1, e01norm) / 1000.0 # convert to km strike_col = np.array([[e01norm.x], [e01norm.y], [e01norm.z]]) # ECEF coords # Sites slat = self._lat slon = self._lon # Convert sites to ECEF: site_ecef_x = np.ones_like(slat) site_ecef_y = np.ones_like(slat) site_ecef_z = np.ones_like(slat) # Make a 3x(#number of sites) matrix of site locations # (rows are x, y, z) in ECEF site_ecef_x, site_ecef_y, site_ecef_z = ecef.latlon2ecef( slat, slon, np.zeros(slon.shape)) site_mat = np.array([ np.reshape(site_ecef_x, (-1, )), np.reshape(site_ecef_y, (-1, )), np.reshape(site_ecef_z, (-1, )) ]) # Epicenter-to-site matrix e2s_mat = site_mat - epi_col # in ECEF mag = np.sqrt(np.sum(e2s_mat * e2s_mat, axis=0)) # Avoid division by zero mag[mag == 0] = 1e-12 e2s_norm = e2s_mat / mag # Dot epicenter-to-site with along-strike vector s_raw = np.sum(e2s_mat * strike_col, axis=0) / 1000.0 # conver to km # Put back into a 2d array s_raw = np.reshape(s_raw, self._lat.shape) self.s = np.abs(s_raw.clip(min=strike_min, max=strike_max)).clip(min=np.exp(1)) # Compute theta sdots = np.sum(e2s_norm * strike_col, axis=0) theta_raw = np.arccos(sdots) # But theta is defined to be the reference angle # (i.e., the equivalent angle between 0 and 90 deg) sintheta = np.abs(np.sin(theta_raw)) costheta = np.abs(np.cos(theta_raw)) theta = np.arctan2(sintheta, costheta) self.theta = np.reshape(theta, self._lat.shape)
def test_so6(): event_name = 'so6' magnitude = 7.2 dip = np.array([70]) rake = 135 width = np.array([15]) L = 80 rupx = np.array([0, 0]) rupy = np.array([0, L]) zp = np.array([0]) # Convert to lat/lon proj = geo.utils.get_orthographic_projection(-122, -120, 39, 37) tlon,tlat = proj(rupx, rupy, reverse = True) # Dummy origin origin = Origin({'lat':0, 'lon':0, 'depth':0, 'mag':0, 'id':'so6', 'rake':rake}) # Rupture rup = rupture.QuadRupture.fromTrace( np.array([tlon[0]]), np.array([tlat[0]]), np.array([tlon[1]]), np.array([tlat[1]]), zp, width, dip, origin, reference = 'rv4') # Sites x = np.linspace(-80, 80, 21) y = np.linspace(-50, 130, 21) site_x,site_y = np.meshgrid(x, y) slon,slat = proj(site_x, site_y, reverse = True) sdepth = np.zeros_like(slon) # Fix origin tmp = rup.getQuadrilaterals()[0] pp0 = Vector.fromPoint(point.Point(tmp[0].longitude, tmp[0].latitude, tmp[0].depth)) pp1 = Vector.fromPoint(point.Point(tmp[1].longitude, tmp[1].latitude, tmp[1].depth)) pp2 = Vector.fromPoint(point.Point(tmp[2].longitude, tmp[2].latitude, tmp[2].depth)) pp3 = Vector.fromPoint(point.Point(tmp[3].longitude, tmp[3].latitude, tmp[3].depth)) dxp = 10/L dyp = (width-5)/width mp0 = pp0 + (pp1 - pp0)*dxp mp1 = pp3 + (pp2 - pp3)*dxp rp = mp0 + (mp1 - mp0)*dyp epilat,epilon,epidepth = ecef2latlon(rp.x, rp.y, rp.z) epix,epiy = proj(epilon, epilat, reverse = False) origin = Origin({'lat':epilat, 'lon':epilon, 'depth':epidepth, 'mag':magnitude, 'id':'so6', 'rake':rake}) ruplat = [a.latitude for a in rup.getQuadrilaterals()[0]] ruplon = [a.longitude for a in rup.getQuadrilaterals()[0]] ruplat = np.append(ruplat, ruplat[0]) ruplon = np.append(ruplon, ruplon[0]) rupx,rupy = proj(ruplon, ruplat, reverse = False) test1 = Bayless2013(origin, rup, slat, slon, sdepth, T = 5) fd = test1.getFd() fd_test = np.array( [[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, -8.92879772e-03, -1.74526918e-02, -2.22981746e-02, -2.34350450e-02, -2.13620062e-02, -1.72712346e-02, -1.29509613e-02, -1.02545064e-02, -1.03010185e-02, -1.28847597e-02, -1.66274727e-02, -1.96984070e-02, -2.05377743e-02, -1.81831337e-02, -1.21881814e-02, -2.64862879e-03, 0.00000000e+00, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, -8.73221519e-03, -2.21421374e-02, -3.18438939e-02, -3.71488270e-02, -3.76239913e-02, -3.35015951e-02, -2.61748968e-02, -1.83864728e-02, -1.34793002e-02, -1.36687799e-02, -1.85727143e-02, -2.55527671e-02, -3.14227568e-02, -3.38933995e-02, -3.19289607e-02, -2.53396980e-02, -1.45943649e-02, -3.71405488e-04, 0.00000000e+00], [ 0.00000000e+00, -2.54621422e-03, -2.11428566e-02, -3.68609103e-02, -4.87464747e-02, -5.56539037e-02, -5.64419387e-02, -5.05331157e-02, -3.52919381e-02, -2.18782050e-02, -1.40858125e-02, -1.47354546e-02, -2.35727189e-02, -3.74838465e-02, -4.75915414e-02, -5.13000399e-02, -4.87882409e-02, -4.05716321e-02, -2.77368254e-02, -1.13542729e-02, 0.00000000e+00], [ 0.00000000e+00, -1.21642958e-02, -3.33747360e-02, -5.21661817e-02, -6.74724509e-02, -7.77628842e-02, -8.00243748e-02, -6.42496853e-02, -4.38124530e-02, -1.97027426e-02, -1.45897731e-02, -1.07427056e-02, -3.08235222e-02, -4.82656988e-02, -6.67692677e-02, -7.35152908e-02, -6.85574283e-02, -5.71811573e-02, -4.12138780e-02, -2.20396726e-02, -6.24121310e-04], [ 0.00000000e+00, -2.00643401e-02, -4.39827328e-02, -6.62722434e-02, -8.60268414e-02, -1.01730306e-01, -9.86277741e-02, -9.82914922e-02, -5.22335876e-02, -1.54622435e-02, -1.57487554e-02, -3.06190808e-03, -4.81481586e-02, -8.92480491e-02, -8.63776477e-02, -9.98130440e-02, -8.95491230e-02, -7.33553695e-02, -5.34401725e-02, -3.11601812e-02, -7.33715103e-03], [ 0.00000000e+00, -2.50053614e-02, -5.11695772e-02, -7.65997026e-02, -1.00809054e-01, -1.22877573e-01, -1.18738178e-01, -1.55236782e-01, -7.45388001e-02, 1.92779182e-03, -1.94380016e-02, 1.94922939e-02, -7.66669920e-02, -1.53909722e-01, -1.10846875e-01, -1.19746768e-01, -1.07680300e-01, -8.59905101e-02, -6.22042294e-02, -3.71802472e-02, -1.13867485e-02], [ 0.00000000e+00, -2.63645827e-02, -5.37984901e-02, -8.11337022e-02, -1.08298371e-01, -1.35146441e-01, -1.34825430e-01, -1.85836050e-01, -1.10730875e-01, -3.18861095e-02, 4.14395701e-02, -1.52711946e-02, -1.31840763e-01, -1.96794707e-01, -1.33453212e-01, -1.34989129e-01, -1.17922385e-01, -9.21637323e-02, -6.58369237e-02, -3.91646838e-02, -1.22685698e-02], [ 0.00000000e+00, -2.64622244e-02, -5.40483999e-02, -8.16190336e-02, -1.09162854e-01, -1.36656677e-01, -1.37081504e-01, -1.89522811e-01, -1.17723634e-01, -4.88765748e-02, -5.04529015e-03, -5.76414497e-02, -1.45712183e-01, -2.03062804e-01, -1.36859828e-01, -1.37107390e-01, -1.19124650e-01, -9.28263279e-02, -6.61800709e-02, -3.93088682e-02, -1.22842049e-02], [ 0.00000000e+00, -2.58466495e-02, -5.24858827e-02, -7.86086164e-02, -1.03856343e-01, -1.27529509e-01, -1.23794779e-01, -1.68810613e-01, -8.22602627e-02, 1.74236964e-02, 9.38708725e-02, 4.23208284e-02, -8.46343723e-02, -1.70476759e-01, -1.17547884e-01, -1.24569752e-01, -1.11518670e-01, -8.84736806e-02, -6.38037151e-02, -3.81874381e-02, -1.19867610e-02], [ 0.00000000e+00, -2.42186547e-02, -4.84175525e-02, -7.09428614e-02, -9.07754575e-02, -1.06117824e-01, -9.50228292e-02, -1.29781980e-01, -3.08573454e-02, 7.39058739e-02, 1.30478117e-01, 8.28181149e-02, -2.70389535e-02, -1.20837502e-01, -8.02081725e-02, -9.70274506e-02, -9.35853383e-02, -7.77422806e-02, -5.77817530e-02, -3.53067886e-02, -1.12414659e-02], [ 0.00000000e+00, -2.16818717e-02, -4.22363856e-02, -5.96909893e-02, -7.24805224e-02, -7.81867829e-02, -6.11838569e-02, -9.05679744e-02, 9.95934969e-03, 1.07503875e-01, 1.52073917e-01, 1.05894634e-01, 8.68652263e-03, -7.98571818e-02, -4.16548658e-02, -6.40511838e-02, -6.99337160e-02, -6.26305633e-02, -4.89098800e-02, -3.09284566e-02, -1.00919381e-02], [ 0.00000000e+00, -1.84940182e-02, -3.47054606e-02, -4.65278129e-02, -5.22037664e-02, -4.93977115e-02, -2.95395230e-02, -5.82421092e-02, 3.91025654e-02, 1.29337956e-01, 1.67436703e-01, 1.21969296e-01, 3.20823547e-02, -5.00287386e-02, -9.22993907e-03, -3.27186625e-02, -4.52706958e-02, -4.57409325e-02, -3.84701291e-02, -2.55751405e-02, -8.64950254e-03], [ 0.00000000e+00, -1.49431380e-02, -2.65887341e-02, -3.29162158e-02, -3.22994323e-02, -2.29081781e-02, -2.60259636e-03, -3.29856530e-02, 6.02631314e-02, 1.45003704e-01, 1.79361264e-01, 1.34292814e-01, 4.88007115e-02, -2.82328554e-02, 1.64212421e-02, -5.72391847e-03, -2.23438861e-02, -2.90246794e-02, -2.76054402e-02, -1.97779758e-02, -7.03945406e-03], [ 0.00000000e+00, -1.12771143e-02, -1.84737590e-02, -1.98228664e-02, -1.40092305e-02, 1.84580818e-04, 1.95817303e-02, -1.32608487e-02, 7.62783168e-02, 1.57076433e-01, 1.89083905e-01, 1.44259188e-01, 6.15722813e-02, -1.17505212e-02, 3.65938109e-02, 1.66937711e-02, -2.18970818e-03, -1.35507683e-02, -1.70890527e-02, -1.39519424e-02, -5.37036892e-03], [ 0.00000000e+00, -7.67615215e-03, -1.07348257e-02, -7.75276739e-03, 2.22351695e-03, 1.98662250e-02, 3.77611177e-02, 2.42018661e-03, 8.89036172e-02, 1.66855206e-01, 1.97260700e-01, 1.52590263e-01, 7.17981256e-02, 1.18005972e-03, 5.26852303e-02, 3.51638855e-02, 1.51012176e-02, 2.69654076e-04, -7.33815554e-03, -8.36639665e-03, -3.72176313e-03], [ 0.00000000e+00, -4.50552324e-03, -4.32262850e-03, 1.73559158e-03, 1.42670366e-02, 3.35040699e-02, 4.97279358e-02, 1.85410528e-02, 9.39950666e-02, 1.46646579e-01, 9.13474746e-02, 1.37004651e-01, 7.74648339e-02, 1.59777072e-02, 6.25334939e-02, 4.74577418e-02, 2.72155518e-02, 1.06174952e-02, 3.94103899e-04, -3.68465400e-03, -2.19830733e-03], [ 0.00000000e+00, -1.74629916e-03, 5.44471813e-04, 8.22933499e-03, 2.15699287e-02, 4.04232250e-02, 5.69678048e-02, 5.52408259e-02, 9.04381272e-02, 1.08204635e-01, 9.14439984e-02, 1.06884511e-01, 8.17241884e-02, 5.55282924e-02, 6.78528399e-02, 5.47188925e-02, 3.35251483e-02, 1.69615982e-02, 5.72048628e-03, -8.81437278e-05, -7.36518436e-04], [ 0.00000000e+00, 4.07838765e-05, 3.63933766e-03, 1.20080876e-02, 2.51274691e-02, 4.25687176e-02, 6.25685606e-02, 7.33480475e-02, 8.37515545e-02, 9.52500287e-02, 9.15135660e-02, 9.66442834e-02, 8.66659913e-02, 8.10325633e-02, 7.18836713e-02, 5.45548434e-02, 3.55884875e-02, 2.00142359e-02, 8.71200201e-03, 2.04407846e-03, -6.53680674e-06], [ 0.00000000e+00, 2.40054729e-04, 4.44975227e-03, 1.27572519e-02, 2.49362989e-02, 4.03831326e-02, 5.80039988e-02, 7.61280192e-02, 8.37404162e-02, 8.89634569e-02, 9.15651607e-02, 9.13586235e-02, 8.83589144e-02, 8.27804032e-02, 6.75666471e-02, 5.00483249e-02, 3.36733366e-02, 1.96758691e-02, 9.00603204e-03, 2.18370401e-03, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, 2.78776980e-03, 1.05086036e-02, 2.13238822e-02, 3.45577738e-02, 4.91570145e-02, 6.36787133e-02, 7.63710088e-02, 8.54072310e-02, 8.92960200e-02, 8.75702197e-02, 8.07095447e-02, 6.97999389e-02, 5.63787286e-02, 4.20734776e-02, 2.83073312e-02, 1.61614525e-02, 6.56194125e-03, 1.00721924e-04, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 5.49667845e-03, 1.47563319e-02, 2.57955743e-02, 3.76689418e-02, 4.91861917e-02, 5.90108907e-02, 6.58478416e-02, 6.87018515e-02, 6.73174642e-02, 6.20270643e-02, 5.35456385e-02, 4.29400416e-02, 3.14129728e-02, 2.00795162e-02, 9.84001885e-03, 1.53992995e-03, 0.00000000e+00, 0.00000000e+00]] ) np.testing.assert_allclose(fd, fd_test, rtol=1e-4)
def test_rv4(): magnitude = 7.0 rake = 90.0 width = np.array([28]) rupx = np.array([0, 0]) rupy = np.array([0, 32]) zp = np.array([0]) dip = np.array([30]) # Convert to lat/lon proj = geo.utils.get_orthographic_projection(-122, -120, 39, 37) tlon, tlat = proj(rupx, rupy, reverse=True) # Dummy Origin origin = Origin({'lat':0, 'lon':0, 'depth':0, 'mag':0, 'id':'rv4', 'rake':rake}) # Rupture rup = rupture.QuadRupture.fromTrace( np.array([tlon[0]]), np.array([tlat[0]]), np.array([tlon[1]]), np.array([tlat[1]]), zp, width, dip, origin, reference='') L = rup.getLength() # Figure out epicenter tmp = rup.getQuadrilaterals()[0] pp0 = Vector.fromPoint(point.Point( tmp[0].longitude, tmp[0].latitude, tmp[0].depth)) pp1 = Vector.fromPoint(point.Point( tmp[1].longitude, tmp[1].latitude, tmp[1].depth)) pp2 = Vector.fromPoint(point.Point( tmp[2].longitude, tmp[2].latitude, tmp[2].depth)) pp3 = Vector.fromPoint(point.Point( tmp[3].longitude, tmp[3].latitude, tmp[3].depth)) dxp = 6/L dyp = (width-8)/width mp0 = pp0 + (pp1 - pp0)*dxp mp1 = pp3 + (pp2 - pp3)*dxp rp = mp0 + (mp1 - mp0)*dyp epilat,epilon,epidepth = ecef2latlon(rp.x, rp.y, rp.z) # Fix Origin: origin = Origin({'lat':epilat, 'lon':epilon, 'depth':epidepth, 'mag':magnitude, 'id':'rv4', 'rake':rake}) x = np.linspace(-50, 50, 11) y = np.linspace(-50, 50, 11) site_x, site_y = np.meshgrid(x, y) slon, slat = proj(site_x, site_y, reverse=True) deps = np.zeros_like(slon) test1 = Bayless2013(origin, rup, slat, slon, deps, T=2.0) # Test fd fd = test1.getFd() fd_test = np.array( [[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.72143257e-03, 1.34977260e-03, 4.33616224e-15, 1.24446253e-03, 1.16142357e-03, 2.25464716e-03, 7.05281751e-04, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, 7.62610242e-03, 1.25133844e-02, 5.61896104e-03, 7.63126014e-15, 4.52266194e-03, 4.67970900e-03, 1.02820316e-02, 5.13160096e-03, -6.13926251e-03], [ 0.00000000e+00, 4.00495234e-03, 2.37608386e-02, 2.37139333e-02, 9.55224050e-03, 5.66364910e-15, 7.70344813e-03, 7.36466362e-03, 1.48239704e-02, 8.40388145e-03, -1.58592485e-02], [ 8.08385547e-19, 9.38150101e-03, 3.38610620e-02, 3.85351492e-02, 1.91044918e-02, 3.98697802e-15, 1.54321666e-02, 1.21913760e-02, 2.04435166e-02, 1.04931859e-02, -1.85935894e-02], [ 2.12025421e-18, 1.37316085e-02, 4.40193799e-02, 6.16562477e-02, 4.77612496e-02, 2.60257085e-15, 3.86322888e-02, 1.97965887e-02, 2.64882038e-02, 1.23335908e-02, -2.07389932e-02], [ 2.64338576e-18, 1.45898292e-02, 4.89104213e-02, 7.70703166e-02, 9.55225258e-02, 1.01875104e-01, 7.73459329e-02, 2.50275508e-02, 2.93537540e-02, 1.30949577e-02, -2.15685454e-02], [ 2.64330042e-18, 1.45898262e-02, 4.89104186e-02, 7.70703146e-02, 9.55225248e-02, 1.01910945e-01, 7.74050835e-02, 2.52307946e-02, 2.92970736e-02, 1.30880504e-02, -2.15685424e-02], [ 2.64318867e-18, 1.45898259e-02, 4.89104184e-02, 7.70703144e-02, 9.55225247e-02, 1.01933432e-01, 7.74421258e-02, 2.53572923e-02, 2.92615130e-02, 1.30837284e-02, -2.15685422e-02], [ 2.64305117e-18, 1.45898284e-02, 4.89104206e-02, 7.70703161e-02, 9.55225256e-02, 1.01942593e-01, 7.74571359e-02, 2.54081640e-02, 2.92472117e-02, 1.30819985e-02, -2.15685446e-02], [ 2.30141673e-18, 1.40210825e-02, 4.56205547e-02, 6.63109661e-02, 5.79266964e-02, 2.33044622e-15, 4.69672564e-02, 2.18401553e-02, 2.72864925e-02, 1.25728575e-02, -2.10227772e-02], [ 1.10672535e-18, 1.04777076e-02, 3.59041065e-02, 4.24614318e-02, 2.24217216e-02, 3.66914762e-15, 1.81728517e-02, 1.39301504e-02, 2.14956836e-02, 1.08711460e-02, -1.90802849e-02]] ) np.testing.assert_allclose(fd, fd_test, rtol=2e-4)
def test_ss3_move_hypo1(): magnitude = 7.2 dip = np.array([90]) rake = 180.0 width = np.array([15]) rupx = np.array([0, 0]) rupy = np.array([0, 80]) zp = np.array([0.0]) epix = np.array([1.0]) epiy = np.array([-1.0]) # Convert to lat/lon proj = geo.utils.get_orthographic_projection(-122, -120, 39, 37) tlon, tlat = proj(rupx, rupy, reverse=True) epilon, epilat = proj(epix, epiy, reverse=True) # Origin origin = Origin({'lat':epilat[0], 'lon':epilon[0], 'depth':-1, 'mag':magnitude, 'id':'ss3', 'rake':rake}) rup = rupture.QuadRupture.fromTrace( np.array([tlon[0]]), np.array([tlat[0]]), np.array([tlon[1]]), np.array([tlat[1]]), zp, width, dip, origin, reference='ss3') x = np.linspace(0, 20, 6) y = np.linspace(0, 90, 11) site_x, site_y = np.meshgrid(x, y) slon, slat = proj(site_x, site_y, reverse=True) deps = np.zeros_like(slon) test1 = Bayless2013(origin, rup, slat, slon, deps, T=1.0) phyp = copy.deepcopy(test1.phyp[0]) plat, plon, pdep = ecef2latlon(phyp.x, phyp.y, phyp.z) px, py = proj(plon, plat, reverse=False) np.testing.assert_allclose(plat, 38.004233219183604, rtol=1e-4) np.testing.assert_allclose(plon, -120.98636122402166, rtol=1e-4) np.testing.assert_allclose(pdep, 7.4999999989205968, rtol=1e-4) #--------------------------------------------------------------------------- # Also for multiple segments #--------------------------------------------------------------------------- dip = np.array([90., 90., 90.]) rake = 180.0 width = np.array([15., 15., 10.]) rupx = np.array([0., 0., 10., 20.]) rupy = np.array([0., 20., 60., 80.]) zp = np.array([0., 0., 0.]) epix = np.array([0.]) epiy = np.array([0.]) # Convert to lat/lon proj = geo.utils.get_orthographic_projection(-122, -120, 39, 37) tlon, tlat = proj(rupx, rupy, reverse=True) epilon, epilat = proj(epix, epiy, reverse=True) rup = rupture.QuadRupture.fromTrace( np.array(tlon[0:3]), np.array(tlat[0:3]), np.array(tlon[1:4]), np.array(tlat[1:4]), zp, width, dip, origin, reference='') event = {'lat': epilat[0], 'lon': epilon[0], 'depth': 1.0, 'mag': magnitude, 'id': '', 'locstring': 'test', 'type': 'SS', 'timezone': 'UTC'} event['time'] = ShakeDateTime.utcfromtimestamp(int(time.time())) event['created'] = ShakeDateTime.utcfromtimestamp(int(time.time())) x = np.linspace(0, 20, 6) y = np.linspace(0, 90, 11) site_x, site_y = np.meshgrid(x, y) slon, slat = proj(site_x, site_y, reverse=True) deps = np.zeros_like(slon) origin = Origin(event) origin.rake = rake test1 = Bayless2013(origin, rup, slat, slon, deps, T=1.0) # 1st pseudo-hyp phyp = copy.deepcopy(test1.phyp[0]) plat, plon, pdep = ecef2latlon(phyp.x, phyp.y, phyp.z) px, py = proj(plon, plat, reverse=False) np.testing.assert_allclose(plat, 38.004233219183604, rtol=1e-4) np.testing.assert_allclose(plon, -120.98636122402166, rtol=1e-4) np.testing.assert_allclose(pdep, 7.4999999989205968, rtol=1e-4) # 2nd pseudo-hyp phyp = copy.deepcopy(test1.phyp[1]) plat, plon, pdep = ecef2latlon(phyp.x, phyp.y, phyp.z) px, py = proj(plon, plat, reverse=False) np.testing.assert_allclose(plat, 38.184097835787796, rtol=1e-4) np.testing.assert_allclose(plon, -120.98636122402166, rtol=1e-4) np.testing.assert_allclose(pdep, 7.4999999989103525, rtol=1e-4) # 3rd pseudo-hyp phyp = copy.deepcopy(test1.phyp[2]) plat, plon, pdep = ecef2latlon(phyp.x, phyp.y, phyp.z) px, py = proj(plon, plat, reverse=False) np.testing.assert_allclose(plat, 38.543778594535752, rtol=1e-4) np.testing.assert_allclose(plon, -120.87137783362499, rtol=1e-4) np.testing.assert_allclose(pdep, 4.9999999995063993, rtol=1e-4)
def test_rv4(): magnitude = 7.0 rake = 90.0 width = np.array([28]) fltx = np.array([0, 0]) flty = np.array([0, 32]) zp = np.array([0]) dip = np.array([30]) # Convert to lat/lon proj = geo.utils.get_orthographic_projection(-122, -120, 39, 37) tlon, tlat = proj(fltx, flty, reverse=True) flt = fault.Fault.fromTrace(np.array([tlon[0]]), np.array([tlat[0]]), np.array([tlon[1]]), np.array([tlat[1]]), zp, width, dip, reference='') L = flt.getFaultLength() # Try to figure out epicenter tmp = flt.getQuadrilaterals()[0] pp0 = Vector.fromPoint(point.Point(tmp[0].longitude, tmp[0].latitude, tmp[0].depth)) pp1 = Vector.fromPoint(point.Point(tmp[1].longitude, tmp[1].latitude, tmp[1].depth)) pp2 = Vector.fromPoint(point.Point(tmp[2].longitude, tmp[2].latitude, tmp[2].depth)) pp3 = Vector.fromPoint(point.Point(tmp[3].longitude, tmp[3].latitude, tmp[3].depth)) dxp = 6/L dyp = (width-8)/width mp0 = pp0 + (pp1 - pp0)*dxp mp1 = pp3 + (pp2 - pp3)*dxp rp = mp0 + (mp1 - mp0)*dyp epilat,epilon,epidepth = ecef2latlon(rp.x, rp.y, rp.z) event = {'lat': epilat, 'lon': epilon, 'depth': epidepth, 'mag': magnitude, 'id': 'test', 'locstring': 'rv4', 'type': 'DS', 'timezone': 'UTC'} event['time'] = ShakeDateTime.utcfromtimestamp(int(time.time())) event['created'] = ShakeDateTime.utcfromtimestamp(int(time.time())) x = np.linspace(-50, 50, 11) y = np.linspace(-50, 50, 11) site_x, site_y = np.meshgrid(x, y) slon, slat = proj(site_x, site_y, reverse=True) deps = np.zeros_like(slon) source = Source(event, flt) source.setEventParam('rake', rake) test1 = Bayless2013(source, slat, slon, deps, T=2.0) # Test fd fd = test1.getFd() fd_test = np.array( [[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.72147747e-03, 1.34981119e-03, 8.95673480e-29, 1.24449087e-03, 1.16145147e-03, 2.25470229e-03, 7.05301515e-04, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, 7.62625126e-03, 1.25136528e-02, 5.61909403e-03, 3.18694606e-28, 4.52275052e-03, 4.67980272e-03, 1.02822365e-02, 5.13171639e-03, -6.13935060e-03], [ 0.00000000e+00, 4.00499692e-03, 2.37611880e-02, 2.37143264e-02, 9.55241972e-03, 5.65693221e-28, 7.70357238e-03, 7.36477919e-03, 1.48241947e-02, 8.40402367e-03, -1.58594139e-02], [ 8.08392720e-19, 9.38156493e-03, 3.38613859e-02, 3.85355818e-02, 1.91047521e-02, 1.27066310e-27, 1.54323543e-02, 1.21915074e-02, 2.04437211e-02, 1.04933053e-02, -1.85937074e-02], [ 2.12026318e-18, 1.37316424e-02, 4.40195705e-02, 6.16565712e-02, 4.77616016e-02, 5.07336347e-27, 3.86325509e-02, 1.97966900e-02, 2.64883302e-02, 1.23336661e-02, -2.07390404e-02], [ 2.64338576e-18, 1.45898071e-02, 4.89104103e-02, 7.70703129e-02, 9.55225254e-02, 1.01875104e-01, 7.73459333e-02, 2.50275520e-02, 2.93537605e-02, 1.30949772e-02, -2.15685118e-02], [ 2.64330042e-18, 1.45898071e-02, 4.89104103e-02, 7.70703129e-02, 9.55225254e-02, 1.01910945e-01, 7.74050830e-02, 2.52307951e-02, 2.92970785e-02, 1.30880672e-02, -2.15685118e-02], [ 2.64318867e-18, 1.45898071e-02, 4.89104103e-02, 7.70703129e-02, 9.55225254e-02, 1.01933432e-01, 7.74421253e-02, 2.53572928e-02, 2.92615177e-02, 1.30837449e-02, -2.15685118e-02], [ 2.64305117e-18, 1.45898071e-02, 4.89104103e-02, 7.70703129e-02, 9.55225254e-02, 1.01942593e-01, 7.74571361e-02, 2.54081650e-02, 2.92472178e-02, 1.30820173e-02, -2.15685118e-02], [ 2.30140686e-18, 1.40209885e-02, 4.56202616e-02, 6.63103459e-02, 5.79255225e-02, 7.72925496e-27, 4.69663059e-02, 2.18399567e-02, 2.72863359e-02, 1.25728195e-02, -2.10226512e-02], [ 1.10671369e-18, 1.04775558e-02, 3.59035524e-02, 4.24605614e-02, 2.24210618e-02, 1.53459722e-27, 1.81723013e-02, 1.39298662e-02, 2.14953705e-02, 1.08710398e-02, -1.90800441e-02]] ) np.testing.assert_allclose(fd, fd_test, rtol=1e-5)
def test_so6(): event_name = 'so6' magnitude = 7.2 dip = np.array([70]) rake = 135 width = np.array([15]) L = 80 fltx = np.array([0, 0]) flty = np.array([0, L]) zp = np.array([0]) # Convert to lat/lon proj = geo.utils.get_orthographic_projection(-122, -120, 39, 37) tlon, tlat = proj(fltx, flty, reverse=True) flt = fault.Fault.fromTrace(np.array([tlon[0]]), np.array([tlat[0]]), np.array([tlon[1]]), np.array([tlat[1]]), zp, width, dip, reference='rv4') x = np.linspace(-80, 80, 21) y = np.linspace(-50, 130, 21) site_x, site_y = np.meshgrid(x, y) slon, slat = proj(site_x, site_y, reverse=True) sdepth = np.zeros_like(slon) tmp = flt.getQuadrilaterals()[0] pp0 = Vector.fromPoint( point.Point(tmp[0].longitude, tmp[0].latitude, tmp[0].depth)) pp1 = Vector.fromPoint( point.Point(tmp[1].longitude, tmp[1].latitude, tmp[1].depth)) pp2 = Vector.fromPoint( point.Point(tmp[2].longitude, tmp[2].latitude, tmp[2].depth)) pp3 = Vector.fromPoint( point.Point(tmp[3].longitude, tmp[3].latitude, tmp[3].depth)) dxp = 10 / L dyp = (width - 5) / width mp0 = pp0 + (pp1 - pp0) * dxp mp1 = pp3 + (pp2 - pp3) * dxp rp = mp0 + (mp1 - mp0) * dyp epilat, epilon, epidepth = ecef2latlon(rp.x, rp.y, rp.z) epix, epiy = proj(epilon, epilat, reverse=False) event = { 'lat': epilat, 'lon': epilon, 'depth': epidepth, 'mag': magnitude, 'id': 'so6', 'locstring': 'so6', 'type': 'RV', 'timezone': 'UTC' } event['time'] = ShakeDateTime.utcfromtimestamp(int(time.time())) event['created'] = ShakeDateTime.utcfromtimestamp(int(time.time())) fltlat = [a.latitude for a in flt.getQuadrilaterals()[0]] fltlon = [a.longitude for a in flt.getQuadrilaterals()[0]] fltlat = np.append(fltlat, fltlat[0]) fltlon = np.append(fltlon, fltlon[0]) fltx, flty = proj(fltlon, fltlat, reverse=False) source = Source(event, flt) source.setEventParam('rake', rake) test1 = Bayless2013(source, slat, slon, sdepth, T=5) fd = test1.getFd() fd_test = np.array([ [ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, -8.92879772e-03, -1.74526918e-02, -2.22981746e-02, -2.34350450e-02, -2.13620062e-02, -1.72712346e-02, -1.29509613e-02, -1.02545064e-02, -1.03010185e-02, -1.28847597e-02, -1.66274727e-02, -1.96984070e-02, -2.05377743e-02, -1.81831337e-02, -1.21881814e-02, -2.64862879e-03, 0.00000000e+00, 0.00000000e+00 ], [ 0.00000000e+00, 0.00000000e+00, -8.73221519e-03, -2.21421374e-02, -3.18438939e-02, -3.71488270e-02, -3.76239913e-02, -3.35015951e-02, -2.61748968e-02, -1.83864728e-02, -1.34793002e-02, -1.36687799e-02, -1.85727143e-02, -2.55527671e-02, -3.14227568e-02, -3.38933995e-02, -3.19289607e-02, -2.53396980e-02, -1.45943649e-02, -3.71405488e-04, 0.00000000e+00 ], [ 0.00000000e+00, -2.54621422e-03, -2.11428566e-02, -3.68609103e-02, -4.87464747e-02, -5.56539037e-02, -5.64419387e-02, -5.05331157e-02, -3.52919381e-02, -2.18782050e-02, -1.40858125e-02, -1.47354546e-02, -2.35727189e-02, -3.74838465e-02, -4.75915414e-02, -5.13000399e-02, -4.87882409e-02, -4.05716321e-02, -2.77368254e-02, -1.13542729e-02, 0.00000000e+00 ], [ 0.00000000e+00, -1.21642958e-02, -3.33747360e-02, -5.21661817e-02, -6.74724509e-02, -7.77628842e-02, -8.00243748e-02, -6.42496853e-02, -4.38124530e-02, -1.97027426e-02, -1.45897731e-02, -1.07427056e-02, -3.08235222e-02, -4.82656988e-02, -6.67692677e-02, -7.35152908e-02, -6.85574283e-02, -5.71811573e-02, -4.12138780e-02, -2.20396726e-02, -6.24121310e-04 ], [ 0.00000000e+00, -2.00643401e-02, -4.39827328e-02, -6.62722434e-02, -8.60268414e-02, -1.01730306e-01, -9.86277741e-02, -9.82914922e-02, -5.22335876e-02, -1.54622435e-02, -1.57487554e-02, -3.06190808e-03, -4.81481586e-02, -8.92480491e-02, -8.63776477e-02, -9.98130440e-02, -8.95491230e-02, -7.33553695e-02, -5.34401725e-02, -3.11601812e-02, -7.33715103e-03 ], [ 0.00000000e+00, -2.50053614e-02, -5.11695772e-02, -7.65997026e-02, -1.00809054e-01, -1.22877573e-01, -1.18738178e-01, -1.55236782e-01, -7.45388001e-02, 1.92779182e-03, -1.94380016e-02, 1.94922939e-02, -7.66669920e-02, -1.53909722e-01, -1.10846875e-01, -1.19746768e-01, -1.07680300e-01, -8.59905101e-02, -6.22042294e-02, -3.71802472e-02, -1.13867485e-02 ], [ 0.00000000e+00, -2.63645827e-02, -5.37984901e-02, -8.11337022e-02, -1.08298371e-01, -1.35146441e-01, -1.34825430e-01, -1.85836050e-01, -1.10730875e-01, -3.18861095e-02, 4.14395701e-02, -1.52711946e-02, -1.31840763e-01, -1.96794707e-01, -1.33453212e-01, -1.34989129e-01, -1.17922385e-01, -9.21637323e-02, -6.58369237e-02, -3.91646838e-02, -1.22685698e-02 ], [ 0.00000000e+00, -2.64622244e-02, -5.40483999e-02, -8.16190336e-02, -1.09162854e-01, -1.36656677e-01, -1.37081504e-01, -1.89522811e-01, -1.17723634e-01, -4.88765748e-02, -5.04529015e-03, -5.76414497e-02, -1.45712183e-01, -2.03062804e-01, -1.36859828e-01, -1.37107390e-01, -1.19124650e-01, -9.28263279e-02, -6.61800709e-02, -3.93088682e-02, -1.22842049e-02 ], [ 0.00000000e+00, -2.58466495e-02, -5.24858827e-02, -7.86086164e-02, -1.03856343e-01, -1.27529509e-01, -1.23794779e-01, -1.68810613e-01, -8.22602627e-02, 1.74236964e-02, 9.38708725e-02, 4.23208284e-02, -8.46343723e-02, -1.70476759e-01, -1.17547884e-01, -1.24569752e-01, -1.11518670e-01, -8.84736806e-02, -6.38037151e-02, -3.81874381e-02, -1.19867610e-02 ], [ 0.00000000e+00, -2.42186547e-02, -4.84175525e-02, -7.09428614e-02, -9.07754575e-02, -1.06117824e-01, -9.50228292e-02, -1.29781980e-01, -3.08573454e-02, 7.39058739e-02, 1.30478117e-01, 8.28181149e-02, -2.70389535e-02, -1.20837502e-01, -8.02081725e-02, -9.70274506e-02, -9.35853383e-02, -7.77422806e-02, -5.77817530e-02, -3.53067886e-02, -1.12414659e-02 ], [ 0.00000000e+00, -2.16818717e-02, -4.22363856e-02, -5.96909893e-02, -7.24805224e-02, -7.81867829e-02, -6.11838569e-02, -9.05679744e-02, 9.95934969e-03, 1.07503875e-01, 1.52073917e-01, 1.05894634e-01, 8.68652263e-03, -7.98571818e-02, -4.16548658e-02, -6.40511838e-02, -6.99337160e-02, -6.26305633e-02, -4.89098800e-02, -3.09284566e-02, -1.00919381e-02 ], [ 0.00000000e+00, -1.84940182e-02, -3.47054606e-02, -4.65278129e-02, -5.22037664e-02, -4.93977115e-02, -2.95395230e-02, -5.82421092e-02, 3.91025654e-02, 1.29337956e-01, 1.67436703e-01, 1.21969296e-01, 3.20823547e-02, -5.00287386e-02, -9.22993907e-03, -3.27186625e-02, -4.52706958e-02, -4.57409325e-02, -3.84701291e-02, -2.55751405e-02, -8.64950254e-03 ], [ 0.00000000e+00, -1.49431380e-02, -2.65887341e-02, -3.29162158e-02, -3.22994323e-02, -2.29081781e-02, -2.60259636e-03, -3.29856530e-02, 6.02631314e-02, 1.45003704e-01, 1.79361264e-01, 1.34292814e-01, 4.88007115e-02, -2.82328554e-02, 1.64212421e-02, -5.72391847e-03, -2.23438861e-02, -2.90246794e-02, -2.76054402e-02, -1.97779758e-02, -7.03945406e-03 ], [ 0.00000000e+00, -1.12771143e-02, -1.84737590e-02, -1.98228664e-02, -1.40092305e-02, 1.84580818e-04, 1.95817303e-02, -1.32608487e-02, 7.62783168e-02, 1.57076433e-01, 1.89083905e-01, 1.44259188e-01, 6.15722813e-02, -1.17505212e-02, 3.65938109e-02, 1.66937711e-02, -2.18970818e-03, -1.35507683e-02, -1.70890527e-02, -1.39519424e-02, -5.37036892e-03 ], [ 0.00000000e+00, -7.67615215e-03, -1.07348257e-02, -7.75276739e-03, 2.22351695e-03, 1.98662250e-02, 3.77611177e-02, 2.42018661e-03, 8.89036172e-02, 1.66855206e-01, 1.97260700e-01, 1.52590263e-01, 7.17981256e-02, 1.18005972e-03, 5.26852303e-02, 3.51638855e-02, 1.51012176e-02, 2.69654076e-04, -7.33815554e-03, -8.36639665e-03, -3.72176313e-03 ], [ 0.00000000e+00, -4.50552324e-03, -4.32262850e-03, 1.73559158e-03, 1.42670366e-02, 3.35040699e-02, 4.97279358e-02, 1.85410528e-02, 9.39950666e-02, 1.46646579e-01, 9.13474746e-02, 1.37004651e-01, 7.74648339e-02, 1.59777072e-02, 6.25334939e-02, 4.74577418e-02, 2.72155518e-02, 1.06174952e-02, 3.94103899e-04, -3.68465400e-03, -2.19830733e-03 ], [ 0.00000000e+00, -1.74629916e-03, 5.44471813e-04, 8.22933499e-03, 2.15699287e-02, 4.04232250e-02, 5.69678048e-02, 5.52408259e-02, 9.04381272e-02, 1.08204635e-01, 9.14439984e-02, 1.06884511e-01, 8.17241884e-02, 5.55282924e-02, 6.78528399e-02, 5.47188925e-02, 3.35251483e-02, 1.69615982e-02, 5.72048628e-03, -8.81437278e-05, -7.36518436e-04 ], [ 0.00000000e+00, 4.07838765e-05, 3.63933766e-03, 1.20080876e-02, 2.51274691e-02, 4.25687176e-02, 6.25685606e-02, 7.33480475e-02, 8.37515545e-02, 9.52500287e-02, 9.15135660e-02, 9.66442834e-02, 8.66659913e-02, 8.10325633e-02, 7.18836713e-02, 5.45548434e-02, 3.55884875e-02, 2.00142359e-02, 8.71200201e-03, 2.04407846e-03, -6.53680674e-06 ], [ 0.00000000e+00, 2.40054729e-04, 4.44975227e-03, 1.27572519e-02, 2.49362989e-02, 4.03831326e-02, 5.80039988e-02, 7.61280192e-02, 8.37404162e-02, 8.89634569e-02, 9.15651607e-02, 9.13586235e-02, 8.83589144e-02, 8.27804032e-02, 6.75666471e-02, 5.00483249e-02, 3.36733366e-02, 1.96758691e-02, 9.00603204e-03, 2.18370401e-03, 0.00000000e+00 ], [ 0.00000000e+00, 0.00000000e+00, 2.78776980e-03, 1.05086036e-02, 2.13238822e-02, 3.45577738e-02, 4.91570145e-02, 6.36787133e-02, 7.63710088e-02, 8.54072310e-02, 8.92960200e-02, 8.75702197e-02, 8.07095447e-02, 6.97999389e-02, 5.63787286e-02, 4.20734776e-02, 2.83073312e-02, 1.61614525e-02, 6.56194125e-03, 1.00721924e-04, 0.00000000e+00 ], [ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 5.49667845e-03, 1.47563319e-02, 2.57955743e-02, 3.76689418e-02, 4.91861917e-02, 5.90108907e-02, 6.58478416e-02, 6.87018515e-02, 6.73174642e-02, 6.20270643e-02, 5.35456385e-02, 4.29400416e-02, 3.14129728e-02, 2.00795162e-02, 9.84001885e-03, 1.53992995e-03, 0.00000000e+00, 0.00000000e+00 ] ]) np.testing.assert_allclose(fd, fd_test, rtol=1e-4)
def test_rv4(): magnitude = 7.0 rake = 90.0 width = np.array([28]) fltx = np.array([0, 0]) flty = np.array([0, 32]) zp = np.array([0]) dip = np.array([30]) # Convert to lat/lon proj = geo.utils.get_orthographic_projection(-122, -120, 39, 37) tlon, tlat = proj(fltx, flty, reverse=True) flt = fault.Fault.fromTrace(np.array([tlon[0]]), np.array([tlat[0]]), np.array([tlon[1]]), np.array([tlat[1]]), zp, width, dip, reference='') L = flt.getFaultLength() # Try to figure out epicenter tmp = flt.getQuadrilaterals()[0] pp0 = Vector.fromPoint( point.Point(tmp[0].longitude, tmp[0].latitude, tmp[0].depth)) pp1 = Vector.fromPoint( point.Point(tmp[1].longitude, tmp[1].latitude, tmp[1].depth)) pp2 = Vector.fromPoint( point.Point(tmp[2].longitude, tmp[2].latitude, tmp[2].depth)) pp3 = Vector.fromPoint( point.Point(tmp[3].longitude, tmp[3].latitude, tmp[3].depth)) dxp = 6 / L dyp = (width - 8) / width mp0 = pp0 + (pp1 - pp0) * dxp mp1 = pp3 + (pp2 - pp3) * dxp rp = mp0 + (mp1 - mp0) * dyp epilat, epilon, epidepth = ecef2latlon(rp.x, rp.y, rp.z) event = { 'lat': epilat, 'lon': epilon, 'depth': epidepth, 'mag': magnitude, 'id': 'test', 'locstring': 'rv4', 'type': 'DS', 'timezone': 'UTC' } event['time'] = ShakeDateTime.utcfromtimestamp(int(time.time())) event['created'] = ShakeDateTime.utcfromtimestamp(int(time.time())) x = np.linspace(-50, 50, 11) y = np.linspace(-50, 50, 11) site_x, site_y = np.meshgrid(x, y) slon, slat = proj(site_x, site_y, reverse=True) deps = np.zeros_like(slon) source = Source(event, flt) source.setEventParam('rake', rake) test1 = Bayless2013(source, slat, slon, deps, T=2.0) # Test fd fd = test1.getFd() fd_test = np.array( [[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.72143257e-03, 1.34977260e-03, 4.33616224e-15, 1.24446253e-03, 1.16142357e-03, 2.25464716e-03, 7.05281751e-04, 0.00000000e+00 ], [ 0.00000000e+00, 0.00000000e+00, 7.62610242e-03, 1.25133844e-02, 5.61896104e-03, 7.63126014e-15, 4.52266194e-03, 4.67970900e-03, 1.02820316e-02, 5.13160096e-03, -6.13926251e-03 ], [ 0.00000000e+00, 4.00495234e-03, 2.37608386e-02, 2.37139333e-02, 9.55224050e-03, 5.66364910e-15, 7.70344813e-03, 7.36466362e-03, 1.48239704e-02, 8.40388145e-03, -1.58592485e-02 ], [ 8.08385547e-19, 9.38150101e-03, 3.38610620e-02, 3.85351492e-02, 1.91044918e-02, 3.98697802e-15, 1.54321666e-02, 1.21913760e-02, 2.04435166e-02, 1.04931859e-02, -1.85935894e-02 ], [ 2.12025421e-18, 1.37316085e-02, 4.40193799e-02, 6.16562477e-02, 4.77612496e-02, 2.60257085e-15, 3.86322888e-02, 1.97965887e-02, 2.64882038e-02, 1.23335908e-02, -2.07389932e-02 ], [ 2.64338576e-18, 1.45898292e-02, 4.89104213e-02, 7.70703166e-02, 9.55225258e-02, 1.01875104e-01, 7.73459329e-02, 2.50275508e-02, 2.93537540e-02, 1.30949577e-02, -2.15685454e-02 ], [ 2.64330042e-18, 1.45898262e-02, 4.89104186e-02, 7.70703146e-02, 9.55225248e-02, 1.01910945e-01, 7.74050835e-02, 2.52307946e-02, 2.92970736e-02, 1.30880504e-02, -2.15685424e-02 ], [ 2.64318867e-18, 1.45898259e-02, 4.89104184e-02, 7.70703144e-02, 9.55225247e-02, 1.01933432e-01, 7.74421258e-02, 2.53572923e-02, 2.92615130e-02, 1.30837284e-02, -2.15685422e-02 ], [ 2.64305117e-18, 1.45898284e-02, 4.89104206e-02, 7.70703161e-02, 9.55225256e-02, 1.01942593e-01, 7.74571359e-02, 2.54081640e-02, 2.92472117e-02, 1.30819985e-02, -2.15685446e-02 ], [ 2.30141673e-18, 1.40210825e-02, 4.56205547e-02, 6.63109661e-02, 5.79266964e-02, 2.33044622e-15, 4.69672564e-02, 2.18401553e-02, 2.72864925e-02, 1.25728575e-02, -2.10227772e-02 ], [ 1.10672535e-18, 1.04777076e-02, 3.59041065e-02, 4.24614318e-02, 2.24217216e-02, 3.66914762e-15, 1.81728517e-02, 1.39301504e-02, 2.14956836e-02, 1.08711460e-02, -1.90802849e-02 ]]) np.testing.assert_allclose(fd, fd_test, rtol=2e-4)
def __computeThetaAndS(self, i): """ :param i: Compute d for the i-th quad/segment. """ # self.phyp is in ECEF tmp = ecef.ecef2latlon(self.phyp[i].x, self.phyp[i].y, self.phyp[i].z) epi_ecef = Vector.fromPoint(geo.point.Point(tmp[1], tmp[0], 0.0)) epi_col = np.array([[epi_ecef.x], [epi_ecef.y], [epi_ecef.z]]) # First compute along strike vector P0, P1, P2, P3 = self._flt.getQuadrilaterals()[i] p0 = Vector.fromPoint(P0) # convert to ECEF p1 = Vector.fromPoint(P1) e01 = p1 - p0 e01norm = e01.norm() hp0 = p0 - epi_ecef hp1 = p1 - epi_ecef strike_min = Vector.dot(hp0, e01norm) / 1000.0 # convert to km strike_max = Vector.dot(hp1, e01norm) / 1000.0 # convert to km strike_col = np.array([[e01norm.x], [e01norm.y], [e01norm.z]]) # ECEF coords # Sites slat = self._lat slon = self._lon # Convert sites to ECEF: site_ecef_x = np.ones_like(slat) site_ecef_y = np.ones_like(slat) site_ecef_z = np.ones_like(slat) # Make a 3x(#number of sites) matrix of site locations # (rows are x, y, z) in ECEF site_ecef_x, site_ecef_y, site_ecef_z = ecef.latlon2ecef( slat, slon, np.zeros(slon.shape)) site_mat = np.array([ np.reshape(site_ecef_x, (-1, )), np.reshape(site_ecef_y, (-1, )), np.reshape(site_ecef_z, (-1, )) ]) # Epicenter-to-site matrix e2s_mat = site_mat - epi_col # in ECEF mag = np.sqrt(np.sum(e2s_mat * e2s_mat, axis=0)) # Avoid division by zero mag[mag == 0] = 1e-12 e2s_norm = e2s_mat / mag # Dot epicenter-to-site with along-strike vector s_raw = np.sum(e2s_mat * strike_col, axis=0) / 1000.0 # conver to km # Put back into a 2d array s_raw = np.reshape(s_raw, self._lat.shape) self.s = np.abs(s_raw.clip(min=strike_min, max=strike_max)).clip(min=np.exp(1)) # Compute theta sdots = np.sum(e2s_norm * strike_col, axis=0) theta_raw = np.arccos(sdots) # But theta is defined to be the reference angle # (i.e., the equivalent angle between 0 and 90 deg) sintheta = np.abs(np.sin(theta_raw)) costheta = np.abs(np.cos(theta_raw)) theta = np.arctan2(sintheta, costheta) self.theta = np.reshape(theta, self._lat.shape)