def _get_time_segments(starttime, endtime, minmag): if starttime is None: starttime = HistoricTime.utcnow() - timedelta(days=30) if endtime is None: endtime = HistoricTime.utcnow() # earthquake frequency table: minmag:earthquakes per day freq_table = {0: 3000 / 7, 1: 3500 / 14, 2: 3000 / 18, 3: 4000 / 59, 4: 9000 / 151, 5: 3000 / 365, 6: 210 / 365, 7: 20 / 365, 8: 5 / 365, 9: 0.05 / 365} floormag = int(np.floor(minmag)) ndays = (endtime - starttime).days + 1 freq = freq_table[floormag] nsegments = int(np.ceil((freq * ndays) / SEARCH_LIMIT)) days_per_segment = int(np.ceil(ndays / nsegments)) segments = [] startseg = starttime endseg = starttime while startseg <= endtime: endseg = min(endtime, startseg + timedelta(days_per_segment)) segments.append((startseg, endseg)) startseg += timedelta(days=days_per_segment, microseconds=1) return segments
def test_rupture_from_dict(): # Grab an EdgeRupture origin = Origin({ 'id': 'test', 'lat': 0, 'lon': 0, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time()) }) file = os.path.join(homedir, 'rupture_data/cascadia.json') rup_original = get_rupture(origin, file) d = rup_original._geojson rup_from_dict = rupture_from_dict(d) assert rup_from_dict._mesh_dx == 0.5 # Specify mesh_dx rup_original = get_rupture(origin, file, mesh_dx=1.0) d = rup_original._geojson rup_from_dict = rupture_from_dict(d) assert rup_from_dict._mesh_dx == 1.0 # Quad rupture file = os.path.join(homedir, 'rupture_data/izmit.json') rup_original = get_rupture(origin, file) d = rup_original._geojson rup_from_dict = rupture_from_dict(d) assert rup_from_dict.getArea() == rup_original.getArea() # Note, there's a bit of an inconsistency highlighted here because # magnitude has key 'magnitude' in the izmit file, but 'mag' in # the origin and both get retained. # Point rupture origin = Origin({ 'id': 'test', 'lon': -122.5, 'lat': 37.3, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time()) }) rup_original = get_rupture(origin) d = rup_original._geojson rup_from_dict = rupture_from_dict(d) assert rup_from_dict.lats == 37.3 assert rup_from_dict.lons == -122.5
def maketime(timestring): outtime = None try: outtime = HistoricTime.strptime(timestring, TIMEFMT1) except Exception: try: outtime = HistoricTime.strptime(timestring, TIMEFMT2) except Exception: try: outtime = HistoricTime.strptime(timestring, DATEFMT) except Exception: raise Exception("Could not parse time or date from %s" % timestring) return outtime
def maketime(timestring): outtime = None try: outtime = HistoricTime.strptime(timestring,TIMEFMT1) except: try: outtime = HistoricTime.strptime(timestring,TIMEFMT2) except: try: outtime = HistoricTime.strptime(timestring,DATEFMT) except: raise Exception('Could not parse time or date from %s' % timestring) return outtime
def test_slip(): # Rupture requires an origin even when not used: origin = Origin({ 'id': 'test', 'lon': 0, 'lat': 0, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time()) }) # Make a rupture lat0 = np.array([34.1]) lon0 = np.array([-118.2]) lat1 = np.array([34.2]) lon1 = np.array([-118.15]) z = np.array([1.0]) W = np.array([3.0]) dip = np.array([30.]) rup = QuadRupture.fromTrace(lon0, lat0, lon1, lat1, z, W, dip, origin) slp = get_quad_slip(rup.getQuadrilaterals()[0], 30).getArray() slpd = np.array([0.80816457, 0.25350787, 0.53160491]) np.testing.assert_allclose(slp, slpd) slp = get_local_unit_slip_vector(22, 30, 86).getArray() slpd = np.array([0.82714003, 0.38830563, 0.49878203]) np.testing.assert_allclose(slp, slpd)
def rupture_from_dict(d): """ Method returns either a Rupture subclass (QuadRupture, EdgeRupture, or PointRupture) object based on a GeoJSON dictionary. .. seealso:: :func:`rupture_from_dict_and_origin` Args: d (dict): Rupture GeoJSON dictionary, which must contain origin information in the 'metadata' field. Returns: a Rupture subclass. """ validate_json(d) # We don't want to mess with the input just in case it gets used again d = copy.deepcopy(d) try: d['metadata']['time'] = HistoricTime.strptime(d['metadata']['time'], constants.TIMEFMT) except ValueError: d['metadata']['time'] = HistoricTime.strptime(d['metadata']['time'], constants.ALT_TIMEFMT) origin = Origin(d['metadata']) # What type of rupture is this? geo_type = d['features'][0]['geometry']['type'] if geo_type == 'MultiPolygon': valid_quads = is_quadrupture_class(d) if valid_quads is True: rupt = QuadRupture(d, origin) elif 'mesh_dx' in d['metadata']: # EdgeRupture will have 'mesh_dx' in metadata mesh_dx = d['metadata']['mesh_dx'] rupt = EdgeRupture(d, origin, mesh_dx=mesh_dx) else: raise ValueError('Invalid rupture dictionary.') elif geo_type == 'Point': rupt = PointRupture(origin) return rupt
def test_slip(): # Rupture requires an origin even when not used: origin = Origin({ 'id': 'test', 'lon': 0, 'lat': 0, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time()) }) # Make a rupture lat0 = np.array([34.1]) lon0 = np.array([-118.2]) lat1 = np.array([34.2]) lon1 = np.array([-118.15]) z = np.array([1.0]) W = np.array([3.0]) dip = np.array([30.]) rup = QuadRupture.fromTrace(lon0, lat0, lon1, lat1, z, W, dip, origin) slp = get_quad_slip(rup.getQuadrilaterals()[0], 30).getArray() slpd = np.array([0.80816457, 0.25350787, 0.53160491]) np.testing.assert_allclose(slp, slpd) slp = get_quad_strike_vector(rup.getQuadrilaterals()[0]).getArray() slpd = np.array([0.58311969, 0.27569625, 0.76417472]) np.testing.assert_allclose(slp, slpd) slp = get_quad_down_dip_vector(rup.getQuadrilaterals()[0]).getArray() slpd = np.array([0.81219873, -0.17763484, -0.55567895]) np.testing.assert_allclose(slp, slpd) slp = get_local_unit_slip_vector(22, 30, 86).getArray() slpd = np.array([0.82714003, 0.38830563, 0.49878203]) np.testing.assert_allclose(slp, slpd) slp = get_local_unit_slip_vector_DS(22, 30, -86).getArray() slpd = np.array([-0.80100879, -0.32362856, -0.49878203]) np.testing.assert_allclose(slp, slpd) slp = get_local_unit_slip_vector_SS(22, 80, 5).getArray() slpd = np.array([0.3731811, 0.92365564, 0.]) np.testing.assert_allclose(slp, slpd) mech = rake_to_mech(-160) assert mech == 'SS' mech = rake_to_mech(0) assert mech == 'SS' mech = rake_to_mech(160) assert mech == 'SS' mech = rake_to_mech(-80) assert mech == 'NM' mech = rake_to_mech(80) assert mech == 'RS'
def test_ss3_m4p5(): magnitude = 4.5 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]) epix = np.array([0]) epiy = np.array([0.2 * rupy[1]]) # Convert to lat/lon proj = OrthographicProjection(-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': 10, 'mag': magnitude, 'id': 'ss3', 'netid': '', 'network': '', 'locstring': '', 'rake': rake, 'time': HistoricTime.utcfromtimestamp(int(time.time()))}) rup = 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) # Test fd fd = test1.getFd() fd_test = np.array( [[0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.]]) np.testing.assert_allclose( fd, fd_test, rtol=1e-4)
def test_EdgeRupture_vs_QuadRupture(): # Sites stuff sites = Sites.fromCenter(-122.15, 37.15, 1.5, 1.5, 0.01, 0.01) sm_dict = sites._GeoDict west = sm_dict.xmin east = sm_dict.xmax south = sm_dict.ymin north = sm_dict.ymax nx = sm_dict.nx ny = sm_dict.ny lats = np.linspace(north, south, ny) lons = np.linspace(west, east, nx) lon, lat = np.meshgrid(lons, lats) dep = np.zeros_like(lon) # Construct QuadRupture xp0 = np.array([-122.0, -122.5]) yp0 = np.array([37.1, 37.4]) xp1 = np.array([-121.7, -122.3]) yp1 = np.array([37.2, 37.2]) zp = np.array([0, 6]) widths = np.array([30, 20]) dips = np.array([30, 40]) origin = Origin({ 'lat': 33.15, 'lon': -122.15, 'depth': 0, 'mag': 7.2, 'id': '', 'netid': '', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time()) }) qrup = QuadRupture.fromTrace(xp0, yp0, xp1, yp1, zp, widths, dips, origin) rrup_q = qrup.computeRrup(lon, lat, dep) rjb_q = qrup.computeRjb(lon, lat, dep) # Construct equivalent EdgeRupture toplons = np.array([-122.0, -121.7, -122.5, -122.3]) toplats = np.array([37.1, 37.2, 37.4, 37.2]) topdeps = np.array([0, 0, 6, 6]) botlons = np.array([-121.886864, -121.587568, -122.635467, -122.435338]) botlats = np.array([36.884527, 36.984246, 37.314035, 37.114261]) botdeps = np.array([15.0000, 14.9998, 18.8558, 18.8559]) group_index = [0, 0, 1, 1] erup = EdgeRupture.fromArrays(toplons, toplats, topdeps, botlons, botlats, botdeps, origin, group_index) rrup_e = erup.computeRrup(lon, lat, dep) rjb_e = erup.computeRjb(lon, lat, dep) # Check that QuadRupture and EdgeRupture give the same result # (we check the absolute values of QuadRupture elsewhere) np.testing.assert_allclose(rrup_e, rrup_q, atol=0.35) np.testing.assert_allclose(rjb_e, rjb_q, atol=0.35)
def _get_time_segments(starttime, endtime, minmag): if starttime is None: starttime = HistoricTime.utcnow() - timedelta(days=30) if endtime is None: endtime = HistoricTime.utcnow() # carve out an exception here for historic events (pre-1900), # as there are only a few hundred of these in the database. if endtime < datetime(1951, 1, 1): return [(starttime, endtime)] # earthquake frequency table: minmag:earthquakes per day freq_table = { 0: 10000 / 7, 1: 3500 / 14, 2: 3000 / 18, 3: 4000 / 59, 4: 9000 / 151, 5: 3000 / 365, 6: 210 / 365, 7: 20 / 365, 8: 5 / 365, 9: 0.05 / 365 } floormag = int(np.floor(minmag)) ndays = (endtime - starttime).days + 1 freq = freq_table[floormag] nsegments = int(np.ceil((freq * ndays) / SEARCH_LIMIT)) days_per_segment = int(np.ceil(ndays / nsegments)) segments = [] startseg = starttime endseg = starttime while startseg <= endtime: endseg = startseg + timedelta(days_per_segment) if endseg > endtime: endseg = endtime segments.append((startseg, endseg)) startseg += timedelta(days=days_per_segment, microseconds=1) return segments
def test_fromTrace(): xp0 = [0.0] xp1 = [0.0] yp0 = [0.0] yp1 = [0.05] zp = [0.0] widths = [10.0] dips = [45.0] # Rupture requires an origin even when not used: origin = Origin({ 'id': 'test', 'lon': 0, 'lat': 0, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time()) }) rupture = QuadRupture.fromTrace( xp0, yp0, xp1, yp1, zp, widths, dips, origin, reference='From J Smith, (personal communication)') fstr = io.StringIO() rupture.writeTextFile(fstr) xp0 = [-121.81529, -121.82298] xp1 = [-121.82298, -121.83068] yp0 = [37.73707, 37.74233] yp1 = [37.74233, 37.74758] zp = [10, 15] widths = [15.0, 20.0] dips = [30.0, 45.0] rupture = QuadRupture.fromTrace( xp0, yp0, xp1, yp1, zp, widths, dips, origin, reference='From J Smith, (personal communication)')
def test_northridge(): rupture_text = """# Source: Wald, D. J., T. H. Heaton, and K. W. Hudnut (1996). The Slip History of the 1994 Northridge, California, Earthquake Determined from Strong-Motion, Teleseismic, GPS, and Leveling Data, Bull. Seism. Soc. Am. 86, S49-S70. -118.421 34.315 5.000 -118.587 34.401 5.000 -118.693 34.261 20.427 -118.527 34.175 20.427 -118.421 34.315 5.000 """ # noqa # Rupture requires an origin even when not used: origin = Origin({ 'id': 'test', 'lon': 0, 'lat': 0, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time()) }) cbuf = io.StringIO(rupture_text) rupture = get_rupture(origin, cbuf) strike = rupture.getStrike() np.testing.assert_allclose(strike, 122.06, atol=0.01) dip = rupture.getDip() np.testing.assert_allclose(dip, 40.21, atol=0.01) L = rupture.getLength() np.testing.assert_allclose(L, 17.99, atol=0.01) W = rupture.getWidth() np.testing.assert_allclose(W, 23.94, atol=0.01) nq = rupture.getNumQuads() np.testing.assert_allclose(nq, 1) ng = rupture.getNumGroups() np.testing.assert_allclose(ng, 1) sind = rupture._getGroupIndex() np.testing.assert_allclose(sind, [0]) ztor = rupture.getDepthToTop() np.testing.assert_allclose(ztor, 5, atol=0.01) itl = rupture.getIndividualTopLengths() np.testing.assert_allclose(itl, 17.99, atol=0.01) iw = rupture.getIndividualWidths() np.testing.assert_allclose(iw, 23.94, atol=0.01) lats = rupture.lats lats_d = np.array([34.401, 34.315, 34.175, 34.261, 34.401, np.nan]) np.testing.assert_allclose(lats, lats_d, atol=0.01) lons = rupture.lons lons_d = np.array( [-118.587, -118.421, -118.527, -118.693, -118.587, np.nan]) np.testing.assert_allclose(lons, lons_d, atol=0.01)
def test_plot_rupture(interactive=False): xp0 = np.array([-90.898000]) xp1 = np.array([-91.308000]) yp0 = np.array([12.584000]) yp1 = np.array([12.832000]) zp = [0.0] strike = azimuth(yp0[0], xp0[0], yp1[0], xp1[0]) origin = Origin({ 'lat': 0.0, 'lon': 0.0, 'depth': 0.0, 'mag': 5.5, 'id': '', 'netid': 'abcd', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time()) }) interface_width = MAX_DEPTH / np.sin(np.radians(DIP)) widths = np.ones(xp0.shape) * interface_width dips = np.ones(xp0.shape) * DIP strike = [strike] rupture = QuadRupture.fromTrace(xp0, yp0, xp1, yp1, zp, widths, dips, origin, strike=strike) plot_rupture_wire3d(rupture) if interactive: fname = os.path.join(os.path.expanduser('~'), 'rupture_wire_plot.png') plt.savefig(fname) print('Wire 3D plot saved to %s. Delete this file if you wish.' % fname) # Need to get tests to check exception for if an axis is handed off fig = plt.figure() ax = fig.add_subplot(111, projection='3d') plot_rupture_wire3d(rupture, ax) # And raise the exception if it is not a 3d axis with pytest.raises(TypeError): ax = fig.add_subplot(111) plot_rupture_wire3d(rupture, ax)
def test_incorrect(): rupture_text = """# Source: Ji, C., D. V. Helmberger, D. J. Wald, and K.-F. Ma (2003). Slip history and dynamic implications of the 1999 Chi-Chi, Taiwan, earthquake, J. Geophys. Res. 108, 2412, doi:10.1029/2002JB001764. 120.72300 24.27980 0 121.00000 24.05000 17 121.09300 24.07190 17 121.04300 24.33120 17 121.04300 24.33120 17 120.72300 24.27980 0 > 120.72300 24.27980 0 120.68000 23.70000 0 120.97200 23.60400 17 121.00000 24.05000 17 120.72300 24.27980 0 > 120.97200 23.60400 17 120.68000 23.70000 0 120.58600 23.58850 0 120.78900 23.40240 17 120.97200 23.60400 17""" # noqa # Rupture requires an origin even when not used: origin = Origin({ 'id': 'test', 'lon': 0, 'lat': 0, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time()) }) cbuf = io.StringIO(rupture_text) with pytest.raises(Exception): get_rupture(origin, cbuf)
def test_map_rupture(interactive=False): xp0 = np.array([-90.898000]) xp1 = np.array([-91.308000]) yp0 = np.array([12.584000]) yp1 = np.array([12.832000]) zp = [0.0] strike = azimuth(yp0[0], xp0[0], yp1[0], xp1[0]) origin = Origin({ 'lat': 0.0, 'lon': 0.0, 'depth': 0.0, 'mag': 5.5, 'id': '', 'netid': 'abcd', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time()) }) interface_width = MAX_DEPTH / np.sin(np.radians(DIP)) widths = np.ones(xp0.shape) * interface_width dips = np.ones(xp0.shape) * DIP strike = [strike] rupture = QuadRupture.fromTrace(xp0, yp0, xp1, yp1, zp, widths, dips, origin, strike=strike) map_rupture(rupture) if interactive: fname = os.path.join(os.path.expanduser('~'), 'rupture_map.png') plt.savefig(fname) print('Rupture map plot saved to %s. Delete this file if you wish.' % fname)
def rupture_from_dict(d): """ Method returns either a Rupture subclass (QuadRupture, EdgeRupture, or PointRupture) object based on a GeoJSON dictionary. .. seealso:: :func:`rupture_from_dict_and_origin` Args: d (dict): Rupture GeoJSON dictionary, which must contain origin information in the 'metadata' field. Returns: a Rupture subclass. """ validate_json(d) d['metadata']['time'] = HistoricTime.strptime(d['metadata']['time'], constants.TIMEFMT) origin = Origin(d['metadata']) # What type of rupture is this? geo_type = d['features'][0]['geometry']['type'] if geo_type == 'MultiPolygon': # EdgeRupture will have 'mesh_dx' in metadata if 'mesh_dx' in d['metadata']: mesh_dx = d['metadata']['mesh_dx'] rupt = EdgeRupture(d, origin, mesh_dx=mesh_dx) else: rupt = QuadRupture(d, origin) elif geo_type == 'Point': rupt = PointRupture(origin) return rupt
def test_fromOrientation(): py = [0, 0.5] px = [0, 0.5] pz = [10, 20] dx = [5, 7] dy = [8, 5] width = [10, 40] length = [20, 50] strike = [0, 90] dip = [30, 20] # Rupture requires an origin even when not used: origin = Origin({'id': 'test', 'lon': 0, 'lat': 0, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time())}) rupture = QuadRupture.fromOrientation(px, py, pz, dx, dy, length, width, strike, dip, origin) p1 = rupture._geojson['features'][0]['geometry']['coordinates'][0][0][0] p2 = rupture._geojson['features'][0]['geometry']['coordinates'][0][0][1] p3 = rupture._geojson['features'][0]['geometry']['coordinates'][0][0][2] p4 = rupture._geojson['features'][0]['geometry']['coordinates'][0][0][3] p5 = rupture._geojson['features'][0]['geometry']['coordinates'][0][1][0] p6 = rupture._geojson['features'][0]['geometry']['coordinates'][0][1][1] p7 = rupture._geojson['features'][0]['geometry']['coordinates'][0][1][2] p8 = rupture._geojson['features'][0]['geometry']['coordinates'][0][1][3] # Check depths np.testing.assert_allclose(p1[2], 6) np.testing.assert_allclose(p2[2], 6) np.testing.assert_allclose(p3[2], 11) np.testing.assert_allclose(p4[2], 11) np.testing.assert_allclose(p5[2], 18.2898992834) np.testing.assert_allclose(p6[2], 18.2898992834) np.testing.assert_allclose(p7[2], 31.9707050164) np.testing.assert_allclose(p8[2], 31.9707050164) # Exception raised if no origin with pytest.raises(Exception) as a: rupture = QuadRupture.fromOrientation(px, py, pz, dx, dy, length, width, strike, dip, None) print(str(a)) # Exception raised if different lengths of arrays with pytest.raises(Exception) as a: py = [0, 2] px = [0] pz = [10] dx = [5] dy = [8] width = [10] length = [20] strike = [0] dip = [30] origin = Origin({'id': 'test', 'lon': 0, 'lat': 0, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time())}) rupture = QuadRupture.fromOrientation(px, py, pz, dx, dy, length, width, strike, dip, origin) print(str(a))
def test_fromTrace(): xp0 = [0.0] xp1 = [0.0] yp0 = [0.0] yp1 = [0.05] zp = [0.0] widths = [10.0] dips = [45.0] # Rupture requires an origin even when not used: origin = Origin({ 'id': 'test', 'lon': -121.81529, 'lat': 37.73707, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time()) }) # Error: unequal array lengths with pytest.raises(ShakeLibException) as e: rupture = QuadRupture.fromTrace( xp0, yp0, xp1, yp1, zp[:-1], widths, dips, origin, reference='From J Smith, (personal communication)') print(str(e)) # Error: invalid strike with pytest.raises(ShakeLibException) as e: rupture = QuadRupture.fromTrace( xp0, yp0, xp1, yp1, zp, widths, dips, origin, strike=[236.0, 250.0], reference='From J Smith, (personal communication)') print(str(e)) # TODO: These write tests exercise code, but we don't check the results rupture = QuadRupture.fromTrace( xp0, yp0, xp1, yp1, zp, widths, dips, origin, reference='From J Smith, (personal communication)') fstr = io.StringIO() rupture.writeTextFile(fstr) tfile = tempfile.NamedTemporaryFile() tname = tfile.name tfile.close() rupture.writeTextFile(tname) os.remove(tname) tfile = tempfile.NamedTemporaryFile() tname = tfile.name tfile.close() rupture.writeGeoJson(tname) os.remove(tname) xp0 = [-121.81529, -121.82298] xp1 = [-121.82298, -121.83068] yp0 = [37.73707, 37.74233] yp1 = [37.74233, 37.74758] zp = [10, 15] widths = [15.0, 20.0] dips = [30.0, 45.0] rupture = QuadRupture.fromTrace( xp0, yp0, xp1, yp1, zp, widths, dips, origin, reference='From J Smith, (personal communication)') assert rupture.getReference() == 'From J Smith, (personal communication)' rorigin = rupture.getOrigin() assert rorigin.id == origin.id assert rorigin.mag == origin.mag assert rorigin.depth == origin.depth rx = rupture.getRuptureContext([]) np.testing.assert_allclose([rx.strike, rx.dip, rx.ztor, rx.width], [-49.183708644954905, 37.638322472702534, 9.999999999371358, 17.47024205615428]) rhyp = rupture.computeRhyp(np.array([-121.5]), np.array([37.0]), np.array([0])) repi = rupture.computeRepi(np.array([-121.5]), np.array([37.0]), np.array([0])) np.testing.assert_allclose([rhyp[0], repi[0]], [86.709236, 86.564956])
def test_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 = OrthographicProjection(-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', 'netid': 'us', 'network': '', 'locstring': '', 'rake': rake, 'time': HistoricTime.utcfromtimestamp(int(time.time()))}) # Rupture rup = 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', 'netid': 'us', 'network': '', 'locstring': '', 'rake': rake, 'time': HistoricTime.utcfromtimestamp(int(time.time()))}) 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 = OrthographicProjection(-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', 'netid': 'us', 'network': '', 'locstring': '', 'rake': rake, 'time': HistoricTime.utcfromtimestamp(int(time.time()))}) # Rupture rup = 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', 'netid': 'us', 'network': '', 'locstring': '', 'rake': rake, 'time': HistoricTime.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) 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_rupture_from_dict(): # Grab an EdgeRupture origin = Origin({'id': 'test', 'lat': 0, 'lon': 0, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time())}) file = os.path.join(homedir, 'rupture_data/cascadia.json') rup_original = get_rupture(origin, file) d = rup_original._geojson rup_from_dict = rupture_from_dict(d) assert rup_from_dict._mesh_dx == 0.5 # Specify mesh_dx rup_original = get_rupture(origin, file, mesh_dx=1.0) d = rup_original._geojson rup_from_dict = rupture_from_dict(d) assert rup_from_dict._mesh_dx == 1.0 # Quad rupture file = os.path.join(homedir, 'rupture_data/izmit.json') rup_original = get_rupture(origin, file) d = rup_original._geojson rup_from_dict = rupture_from_dict(d) assert rup_from_dict.getArea() == rup_original.getArea() # Note, there's a bit of an inconsistency highlighted here because # magnitude has key 'magnitude' in the izmit file, but 'mag' in # the origin and both get retained. # Point rupture from json file = os.path.join(homedir, 'rupture_data/point.json') rup = get_rupture(origin, file) assert rup.lats == 0 assert rup.lons == 0 # Point rupture origin = Origin({ 'id': 'test', 'lon': -122.5, 'lat': 37.3, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time()) }) rup_original = get_rupture(origin) d = rup_original._geojson rup_from_dict = rupture_from_dict(d) assert rup_from_dict.lats == 37.3 assert rup_from_dict.lons == -122.5 assert rup_original.getLength() is None assert rup_original.getWidth() == constants.DEFAULT_WIDTH assert rup_original.getArea() is None assert rup_original.getStrike() == constants.DEFAULT_STRIKE assert rup_original.getDip() == constants.DEFAULT_DIP assert rup_original.getDepthToTop() == constants.DEFAULT_ZTOR assert rup_original.getQuadrilaterals() is None assert rup_original.depths == 5.0 # No mech, no tectonic region rjb, _ = rup_original.computeRjb(np.array([-122.0]), np.array([37.0]), np.array([0.0])) rrup, _ = rup_original.computeRrup(np.array([-122.0]), np.array([37.0]), np.array([0.0])) if do_tests is True: np.testing.assert_allclose([rjb[0], rrup[0]], [42.757296, 46.614723]) else: print(rjb[0], rrup[0]) # Various combinations of mech and tectonic region... rup_original._origin._tectonic_region = 'Active Shallow Crust' rup_original._origin.mech = 'ALL' rjb, _ = rup_original.computeRjb(np.array([-122.0]), np.array([37.0]), np.array([0.0])) rrup, _ = rup_original.computeRrup(np.array([-122.0]), np.array([37.0]), np.array([0.0])) if do_tests is True: np.testing.assert_allclose([rjb[0], rrup[0]], [42.757296, 46.614723]) else: print(rjb[0], rrup[0]) rup_original._origin.mech = 'RS' rjb, _ = rup_original.computeRjb(np.array([-122.0]), np.array([37.0]), np.array([0.0])) rrup, _ = rup_original.computeRrup(np.array([-122.0]), np.array([37.0]), np.array([0.0])) if do_tests is True: np.testing.assert_allclose([rjb[0], rrup[0]], [39.779893, 44.033556]) else: print(rjb[0], rrup[0]) rup_original._origin.mech = 'NM' rjb, _ = rup_original.computeRjb(np.array([-122.0]), np.array([37.0]), np.array([0.0])) rrup, _ = rup_original.computeRrup(np.array([-122.0]), np.array([37.0]), np.array([0.0])) if do_tests is True: np.testing.assert_allclose([rjb[0], rrup[0]], [40.937772, 45.254891]) else: print(rjb[0], rrup[0]) rup_original._origin.mech = 'SS' rjb, _ = rup_original.computeRjb(np.array([-122.0]), np.array([37.0]), np.array([0.0])) rrup, _ = rup_original.computeRrup(np.array([-122.0]), np.array([37.0]), np.array([0.0])) if do_tests is True: np.testing.assert_allclose([rjb[0], rrup[0]], [46.750567, 48.108934]) else: print(rjb[0], rrup[0]) rup_original._origin._tectonic_region = 'Stable Shallow Crust' rup_original._origin.mech = 'ALL' rjb, _ = rup_original.computeRjb(np.array([-122.0]), np.array([37.0]), np.array([0.0])) rrup, _ = rup_original.computeRrup(np.array([-122.0]), np.array([37.0]), np.array([0.0])) if do_tests is True: np.testing.assert_allclose([rjb[0], rrup[0]], [43.676648, 48.008276]) else: print(rjb[0], rrup[0]) rup_original._origin.mech = 'RS' rjb, _ = rup_original.computeRjb(np.array([-122.0]), np.array([37.0]), np.array([0.0])) rrup, _ = rup_original.computeRrup(np.array([-122.0]), np.array([37.0]), np.array([0.0])) if do_tests is True: np.testing.assert_allclose([rjb[0], rrup[0]], [42.445057, 46.865434]) else: print(rjb[0], rrup[0]) rup_original._origin.mech = 'NM' rjb, _ = rup_original.computeRjb(np.array([-122.0]), np.array([37.0]), np.array([0.0])) rrup, _ = rup_original.computeRrup(np.array([-122.0]), np.array([37.0]), np.array([0.0])) if do_tests is True: np.testing.assert_allclose([rjb[0], rrup[0]], [43.233314, 47.563079]) else: print(rjb[0], rrup[0]) rup_original._origin.mech = 'SS' rjb, _ = rup_original.computeRjb(np.array([-122.0]), np.array([37.0]), np.array([0.0])) rrup, _ = rup_original.computeRrup(np.array([-122.0]), np.array([37.0]), np.array([0.0])) if do_tests is True: np.testing.assert_allclose([rjb[0], rrup[0]], [47.829729, 50.087485]) else: print(rjb[0], rrup[0]) rup_original._origin._tectonic_region = 'Somewhere Else' rup_original._origin.mech = 'ALL' rjb, var = rup_original.computeRjb(np.array([-122.0]), np.array([37.0]), np.array([0.0])) rrup, var = rup_original.computeRrup(np.array([-122.0]), np.array([37.0]), np.array([0.0])) if do_tests is True: np.testing.assert_allclose([rjb[0], rrup[0]], [42.757296, 46.614723]) else: print(rjb[0], rrup[0]) # This is just zeroes now, so there's not much to check gc2 = rup_original.computeGC2(np.array([-122.0]), np.array([37.0]), np.array([0.0])) assert gc2['rx'][0] == 0
def test_QuadRupture(): # Rupture requires an origin even when not used: origin = Origin({'id': 'test', 'lon': 0, 'lat': 0, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time())}) # First with json file file = os.path.join(homedir, 'rupture_data/izmit.json') rupj = get_rupture(origin, file) # Then with text file: file = os.path.join(homedir, 'rupture_data/Barkaetal02_fault.txt') rupt = get_rupture(origin, file) np.testing.assert_allclose(rupj.lats, rupt.lats, atol=1e-5) np.testing.assert_allclose(rupj.lons, rupt.lons, atol=1e-5) np.testing.assert_allclose(rupj._depth, rupt._depth, atol=1e-5) np.testing.assert_allclose(rupt.getArea(), 2391.2822653900268, atol=1e-5) target = np.array( [29.51528, 29.3376, 29.3376, 29.51528005, 29.51528, np.nan, 29.87519, 29.61152, 29.61152, 29.87519021, 29.87519, np.nan, 30.11126, 29.88662, 30.11126, 30.11126, 29.88662, 30.11126, 30.11126, np.nan, 30.4654, 30.30494, 30.4654, 30.4654, 30.30494, 30.4654, 30.4654, np.nan, 30.63731, 30.57658, 30.57658, 30.63731011, 30.63731, np.nan, 30.93655, 30.729, 30.729, 30.93655103, 30.93655, np.nan, 31.01799, 30.94688, 30.94688, 31.0179905, 31.01799, np.nan] ) np.testing.assert_allclose(rupj.lons, target, atol=1e-5) target = np.array( [40.72733, 40.70985, 40.71185, 40.72932969, 40.72733, np.nan, 40.74903, 40.70513, 40.70713, 40.75102924, 40.74903, np.nan, 40.72336, 40.72582, 40.72336, 40.72536, 40.72782, 40.72536004, 40.72336, np.nan, 40.71081, 40.7121, 40.71081, 40.71281, 40.7141, 40.71281002, 40.71081, np.nan, 40.70068, 40.71621, 40.71821, 40.70268025, 40.70068, np.nan, 40.79654, 40.69947, 40.70147, 40.79853872, 40.79654, np.nan, 40.84501, 40.80199, 40.80399, 40.84700952, 40.84501, np.nan] ) np.testing.assert_allclose(rupj.lats, target, atol=1e-5) target = np.array( [-0.00000000e+00, -0.00000000e+00, 2.00000000e+01, 1.99999325e+01, -0.00000000e+00, np.nan, -9.31322575e-13, -0.00000000e+00, 2.00000000e+01, 1.99998304e+01, -9.31322575e-13, np.nan, 9.31322575e-13, -0.00000000e+00, 9.31322575e-13, 2.00000000e+01, 2.00000000e+01, 2.00000095e+01, 9.31322575e-13, np.nan, -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, 2.00000000e+01, 2.00000000e+01, 2.00000050e+01, -0.00000000e+00, np.nan, -0.00000000e+00, -0.00000000e+00, 2.00000000e+01, 2.00000600e+01, -0.00000000e+00, np.nan, -0.00000000e+00, -0.00000000e+00, 2.00000000e+01, 1.99996249e+01, -0.00000000e+00, np.nan, -0.00000000e+00, -0.00000000e+00, 2.00000000e+01, 1.99998338e+01, -0.00000000e+00, np.nan]) np.testing.assert_allclose(rupj.depths, target, atol=1e-5)
def read_event_file(eventxml): """ Read event.xml file from disk, returning a dictionary of attributes. Input XML format looks like this: .. code-block:: xml <earthquake id="2008ryan " lat="30.9858" lon="103.3639" mag="7.9" year="2008" month="05" day="12" hour="06" minute="28" second="01" timezone="GMT" depth="19.0" locstring="EASTERN SICHUAN, CHINA" created="1211173621" otime="1210573681" type="" /> Args: eventxml (str): Path to event XML file OR file-like object. Returns: dict: Dictionary with keys: - eventsourcecode Origin network and origin code (i.e., us2017abcd). - eventsource Origin network ("us"). - time Origin time as an HistoricTime object. - lat Origin latitude - lon Origin longitude - depth Origin depth - mag Origin magnitude - created Process time as an HistoricTime object. - locstring Location string - mechanism Moment mechanism, one of: - 'RS' (Reverse) - 'SS' (Strike-Slip) - 'NM' (Normal) - 'ALL' (Undetermined) """ # fill in default values for mechanism, rake and dip # these may be overriden by values in event.xml, source.txt, or by values # passed in after reading input data. # event = {'mech': DEFAULT_MECH, # 'rake': DEFAULT_RAKE, # 'dip': DEFAULT_DIP} if isinstance(eventxml, str): root = minidom.parse(eventxml) else: data = eventxml.read() root = minidom.parseString(data) # Turn XML content into dictionary eq = root.getElementsByTagName('earthquake')[0] xmldict = dict(eq.attributes.items()) root.unlink() eqdict = {} eqdict['eventsourcecode'] = xmldict['id'] if 'network' in xmldict: eqdict['eventsource'] = xmldict['network'] else: eqdict['eventsource'] = 'us' #?? #look for the productcode attribute if 'productcode' in xmldict: eqdict['productcode'] = xmldict['productcode'] # fix eventsourcecode if not specified correctly if not eqdict['eventsourcecode'].startswith(eqdict['eventsource']): eqdict['eventsourcecode'] = eqdict['eventsource'] + eqdict['eventsourcecode'] year = int(xmldict['year']) month = int(xmldict['month']) day = int(xmldict['day']) hour = int(xmldict['hour']) minute = int(xmldict['minute']) second = int(xmldict['second']) microseconds = int((second - int(xmldict['second']))*1e6) eqdict['time'] = HistoricTime(year,month,day,hour,minute,second,microseconds) eqdict['lat'] = float(xmldict['lat']) eqdict['lon'] = float(xmldict['lon']) eqdict['depth'] = float(xmldict['depth']) eqdict['mag'] = float(xmldict['mag']) # make created field in event.xml optional - set to current UTC time if not # supplied. if 'created' in xmldict: eqdict['created'] = HistoricTime.utcfromtimestamp(int(xmldict['created'])) else: eqdict['created'] = HistoricTime.utcnow() eqdict['locstring'] = xmldict['locstring'] if 'mech' in xmldict: eqdict['mech'] = xmldict['mech'] return eqdict
def test_parse_complicated_rupture(): rupture_text = """# SOURCE: Barka, A., H. S. Akyz, E. Altunel, G. Sunal, \ Z. Akir, A. Dikbas, B. Yerli, R. Armijo, B. Meyer, J. B. d. Chabalier, \ T. Rockwell, J. R. Dolan, R. Hartleb, T. Dawson, S. Christofferson, \ A. Tucker, T. Fumal, R. Langridge, H. Stenner, W. Lettis, J. Bachhuber, \ and W. Page (2002). The Surface Rupture and Slip Distribution of the \ 17 August 1999 Izmit Earthquake (M 7.4), North Anatolian Fault, Bull. \ Seism. Soc. Am. 92, 43-60. 29.33760 40.70985 0 29.51528 40.72733 0 29.51528 40.72933 20 29.33760 40.71185 20 29.33760 40.70985 0 > 29.61152 40.70513 0 29.87519 40.74903 0 29.87519 40.75103 20 29.61152 40.70713 20 29.61152 40.70513 0 > 29.88662 40.72582 0 30.11126 40.72336 0 30.19265 40.73432 0 30.19265 40.73632 20 30.11126 40.72536 20 29.88662 40.72782 20 29.88662 40.72582 0 > 30.30494 40.71210 0 30.46540 40.71081 0 30.56511 40.70739 0 30.56511 40.70939 20 30.46540 40.71281 20 30.30494 40.71410 20 30.30494 40.71210 0 > 30.57658 40.71621 0 30.63731 40.70068 0 30.63731 40.70268 20 30.57658 40.71821 20 30.57658 40.71621 0 > 30.72900 40.69947 0 30.93655 40.79654 0 30.93655 40.79854 20 30.72900 40.70147 20 30.72900 40.69947 0 > 30.94688 40.80199 0 31.01799 40.84501 0 31.01799 40.84701 20 30.94688 40.80399 20 30.94688 40.80199 0""" # noqa # Rupture requires an origin even when not used: origin = Origin({'id': 'test', 'lon': 0, 'lat': 0, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time())}) cbuf = io.StringIO(rupture_text) rupture = get_rupture(origin, cbuf) strike = rupture.getStrike() np.testing.assert_allclose(strike, -100.46, atol=0.01) dip = rupture.getDip() np.testing.assert_allclose(dip, 89.40, atol=0.01) L = rupture.getLength() np.testing.assert_allclose(L, 119.56, atol=0.01) W = rupture.getWidth() np.testing.assert_allclose(W, 20.0, atol=0.01) nq = rupture.getNumQuads() np.testing.assert_allclose(nq, 9) ng = rupture.getNumGroups() np.testing.assert_allclose(ng, 7) sind = rupture._getGroupIndex() np.testing.assert_allclose(sind, [0, 1, 2, 2, 3, 3, 4, 5, 6]) ztor = rupture.getDepthToTop() np.testing.assert_allclose(ztor, 0, atol=0.01) itl = rupture.getIndividualTopLengths() itl_d = np.array([15.13750778, 22.80237887, 18.98053425, 6.98263853, 13.55978731, 8.43444811, 5.41399812, 20.57788056, 7.66869463]) np.testing.assert_allclose(itl, itl_d, atol=0.01) iw = rupture.getIndividualWidths() iw_d = np.array([20.00122876, 20.00122608, 20.00120173, 20.00121028, 20.00121513, 20.00121568, 20.00107293, 20.00105498, 20.00083348]) np.testing.assert_allclose(iw, iw_d, atol=0.01) lats = rupture.lats lats_d = np.array([40.72733, 40.70985, 40.71185, 40.72932969, 40.72733, np.nan, 40.74903, 40.70513, 40.70713, 40.75102924, 40.74903, np.nan, 40.72336, 40.72582, 40.72336, 40.72536, 40.72782, 40.72536004, 40.72336, np.nan, 40.71081, 40.7121, 40.71081, 40.71281, 40.7141, 40.71281002, 40.71081, np.nan, 40.70068, 40.71621, 40.71821, 40.70268025, 40.70068, np.nan, 40.79654, 40.69947, 40.70147, 40.79853872, 40.79654, np.nan, 40.84501, 40.80199, 40.80399, 40.84700952, 40.84501, np.nan]) np.testing.assert_allclose(lats, lats_d, atol=0.001) lons = rupture.lons lons_d = np.array([29.51528, 29.3376, 29.3376, 29.51528005, 29.51528, np.nan, 29.87519, 29.61152, 29.61152, 29.87519021, 29.87519, np.nan, 30.11126, 29.88662, 30.11126, 30.11126, 29.88662, 30.11126, 30.11126, np.nan, 30.4654, 30.30494, 30.4654, 30.4654, 30.30494, 30.4654, 30.4654, np.nan, 30.63731, 30.57658, 30.57658, 30.63731011, 30.63731, np.nan, 30.93655, 30.729, 30.729, 30.93655103, 30.93655, np.nan, 31.01799, 30.94688, 30.94688, 31.0179905, 31.01799, np.nan]) np.testing.assert_allclose(lons, lons_d, atol=0.001)
def test_EdgeRupture(): # Rupture requires an origin even when not used: origin = Origin({'id': 'test', 'lon': 0, 'lat': 0, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time())}) file = os.path.join(homedir, 'rupture_data/cascadia.json') rup = get_rupture(origin, file) np.testing.assert_allclose(rup.getArea(), 105635.92827547337) # Force read Northridge as EdgeRupture file = os.path.join(homedir, 'rupture_data/northridge_fault.txt') d = text_to_json(file, new_format=True) rupt = EdgeRupture(d, origin) strike = rupt.getStrike() np.testing.assert_allclose(strike, 121.97, atol=0.01) dip = rupt.getDip() np.testing.assert_allclose(dip, 40.12, atol=0.01) L = rupt.getLength() np.testing.assert_allclose(L, 17.99, atol=0.01) W = rupt.getWidth() np.testing.assert_allclose(W, 23.92, atol=0.01) ztor = rupt.getDepthToTop() np.testing.assert_allclose(ztor, 5, atol=0.01) # And again for the same vertices but reversed order file = os.path.join(homedir, 'rupture_data/northridge_fixed_fault.txt') d = text_to_json(file, new_format=True) rupt = EdgeRupture(d, origin) strike = rupt.getStrike() np.testing.assert_allclose(strike, 121.97, atol=0.01) dip = rupt.getDip() np.testing.assert_allclose(dip, 40.12, atol=0.01) L = rupt.getLength() np.testing.assert_allclose(L, 17.99, atol=0.01) W = rupt.getWidth() np.testing.assert_allclose(W, 23.92, atol=0.01) ztor = rupt.getDepthToTop() np.testing.assert_allclose(ztor, 5, atol=0.01) # Test for fromArrays method toplats = np.array([37.0, 38.0]) toplons = np.array([-120.0, -120.0]) topdeps = np.array([0.0, 0.0]) botlats = copy.copy(toplats) botlons = copy.copy(toplons) botdeps = np.array([10.0, 10.0]) erup = EdgeRupture.fromArrays(toplons, toplats, topdeps, botlons, botlats, botdeps, origin) # Error: array lengths differ with pytest.raises(ShakeLibException) as e: qrup = QuadRupture.fromVertices( [toplons[0]], [toplats[0]], [topdeps[0]], [toplons[1]], [toplats[1]], [topdeps[1]], [botlons[1]], [botlats[1]], [botdeps[1]], [botlons[0]], [botlats[0]], [botdeps[0]][:-1], origin) print(str(e)) # Error: group index too long with pytest.raises(ShakeLibException) as e: qrup = QuadRupture.fromVertices( [toplons[0]], [toplats[0]], [topdeps[0]], [toplons[1]], [toplats[1]], [topdeps[1]], [botlons[1]], [botlats[1]], [botdeps[1]], [botlons[0]], [botlats[0]], [botdeps[0]], origin, group_index=[0, 0, 0, 0, 0, 0]) print(str(e)) qrup = QuadRupture.fromVertices( [toplons[0]], [toplats[0]], [topdeps[0]], [toplons[1]], [toplats[1]], [topdeps[1]], [botlons[1]], [botlats[1]], [botdeps[1]], [botlons[0]], [botlats[0]], [botdeps[0]], origin) np.testing.assert_allclose(erup.getArea(), 1108.9414759967776) np.testing.assert_allclose(erup.getDepthToTop(), 0) np.testing.assert_allclose(erup.getLength(), 111.19492664455889) np.testing.assert_allclose( erup.lats, np.array([37., 38., 38., 37., 37., np.nan])) np.testing.assert_allclose( erup.lons, np.array([-120., -120., -120., -120., -120., np.nan])) np.testing.assert_allclose( erup.depths, np.array([0., 0., 10., 10., 0., np.nan])) np.testing.assert_allclose( erup._getGroupIndex(), np.array([0., 0.])) quads = erup.getQuadrilaterals() np.testing.assert_allclose(quads[0][0].x, -120.0) # Need to also test the distances with EdgeRupture lons = np.linspace(-120.1, -121.0, 10) lats = np.linspace(37.0, 38, 10) deps = np.zeros_like(lons) rrup1, _ = qrup.computeRrup(lons, lats, deps) rrup2, _ = erup.computeRrup(lons, lats, deps) np.testing.assert_allclose(rrup1, rrup2, atol=2e-2) rjb1, _ = qrup.computeRjb(lons, lats, deps) rjb2, _ = erup.computeRjb(lons, lats, deps) np.testing.assert_allclose(rjb1, rjb2, atol=2e-2) gc2 = erup.computeGC2(lons, lats, deps) targetRy0 = np.array( [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.67335931]) targetRx = np.array( [-8.88024949, -17.73390996, -26.56167797, -35.3634266, -44.13902929, -52.88835984, -61.61129242, -70.30770154, -78.97746209, -87.6204493]) np.testing.assert_allclose(gc2['ry0'], targetRy0) np.testing.assert_allclose(gc2['rx'], targetRx)
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, 'eventsourcecode': 'ss3', 'rake': rake}) rup = 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 = 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, 'eventsourcecode': '', 'locstring': 'test', 'type': 'SS', 'timezone': 'UTC'} event['time'] = HistoricTime.utcfromtimestamp(int(time.time())) event['created'] = HistoricTime.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_rupture_depth(interactive=False): DIP = 17.0 WIDTH = 20.0 GRIDRES = 0.1 names = ['single', 'double', 'triple', 'concave', 'concave_simple', 'ANrvSA'] means = [3.1554422780092461, 2.9224454569459781, 3.0381968625073563, 2.0522694624400271, 2.4805390352818755, 2.8740121776209673] stds = [2.1895293825074575, 2.0506459673526174, 2.0244588429154402, 2.0112565876976416, 2.1599789955270019, 1.6156220309120068] xp0list = [np.array([118.3]), np.array([10.1, 10.1]), np.array([10.1, 10.1, 10.3]), np.array([10.9, 10.5, 10.9]), np.array([10.9, 10.6]), np.array([-76.483, -76.626, -76.757, -76.99, -77.024, -76.925, -76.65, -76.321, -75.997, -75.958])] xp1list = [np.array([118.3]), np.array([10.1, 10.3]), np.array([10.1, 10.3, 10.1]), np.array([10.5, 10.9, 11.3]), np.array([10.6, 10.9]), np.array([-76.626, -76.757, -76.99, -77.024, -76.925, -76.65, -76.321, -75.997, -75.958, -76.006])] yp0list = [np.array([34.2]), np.array([34.2, 34.5]), np.array([34.2, 34.5, 34.8]), np.array([34.2, 34.5, 34.8]), np.array([35.1, 35.2]), np.array([-52.068, -51.377, -50.729, -49.845, -49.192, -48.507, -47.875, -47.478, -47.08, -46.422])] yp1list = [np.array([34.5]), np.array([34.5, 34.8]), np.array([34.5, 34.8, 35.1]), np.array([34.5, 34.8, 34.6]), np.array([35.2, 35.4]), np.array([-51.377, -50.729, -49.845, -49.192, -48.507, -47.875, -47.478, -47.08, -46.422, -45.659])] for i in range(0, len(xp0list)): xp0 = xp0list[i] xp1 = xp1list[i] yp0 = yp0list[i] yp1 = yp1list[i] name = names[i] mean_value = means[i] std_value = stds[i] zp = np.zeros(xp0.shape) strike = azimuth(xp0[0], yp0[0], xp1[-1], yp1[-1]) widths = np.ones(xp0.shape) * WIDTH dips = np.ones(xp0.shape) * DIP strike = [strike] origin = Origin({'id': 'test', 'lon': 0, 'lat': 0, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time())}) rupture = QuadRupture.fromTrace( xp0, yp0, xp1, yp1, zp, widths, dips, origin, strike=strike) # make a grid of points over both quads, ask for depths ymin = np.nanmin(rupture.lats) ymax = np.nanmax(rupture.lats) xmin = np.nanmin(rupture.lons) xmax = np.nanmax(rupture.lons) xmin = np.floor(xmin * (1 / GRIDRES)) / (1 / GRIDRES) xmax = np.ceil(xmax * (1 / GRIDRES)) / (1 / GRIDRES) ymin = np.floor(ymin * (1 / GRIDRES)) / (1 / GRIDRES) ymax = np.ceil(ymax * (1 / GRIDRES)) / (1 / GRIDRES) geodict = GeoDict.createDictFromBox( xmin, xmax, ymin, ymax, GRIDRES, GRIDRES) nx = geodict.nx ny = geodict.ny depths = np.zeros((ny, nx)) for row in range(0, ny): for col in range(0, nx): lat, lon = geodict.getLatLon(row, col) depth = rupture.getDepthAtPoint(lat, lon) depths[row, col] = depth np.testing.assert_almost_equal(np.nanmean(depths), mean_value) np.testing.assert_almost_equal(np.nanstd(depths), std_value) if interactive: fig, axes = plt.subplots(nrows=2, ncols=1) ax1, ax2 = axes xdata = np.append(xp0, xp1[-1]) ydata = np.append(yp0, yp1[-1]) plt.sca(ax1) plt.plot(xdata, ydata, 'b') plt.sca(ax2) im = plt.imshow(depths, cmap='viridis_r') # noqa ch = plt.colorbar() # noqa fname = os.path.join(os.path.expanduser('~'), 'quad_%s_test.png' % name) print('Saving image for %s quad test... %s' % (name, fname)) plt.savefig(fname) plt.close()
def test_EdgeRupture_vs_QuadRupture(): # Sites stuff cx = -122.15 cy = 37.15 dx = 0.01 dy = 0.01 xspan = 1.5 yspan = 1.5 west = cx - xspan / 2.0 east = cx + xspan / 2.0 south = cy - yspan / 2.0 north = cy + yspan / 2.0 nx = np.ceil(((east - west - EPS) / dx) + 1) ny = np.ceil(((north - south - EPS) / dy) + 1) lats = np.linspace(north, south, ny) lons = np.linspace(west, east, nx) lon, lat = np.meshgrid(lons, lats) dep = np.zeros_like(lon) # Construct QuadRupture xp0 = np.array([-122.0, -122.5]) yp0 = np.array([37.1, 37.4]) xp1 = np.array([-121.7, -122.3]) yp1 = np.array([37.2, 37.2]) zp = np.array([0, 6]) widths = np.array([30, 20]) dips = np.array([30, 40]) origin = Origin({ 'lat': 33.15, 'lon': -122.15, 'depth': 0, 'mag': 7.2, 'id': '', 'netid': '', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time()) }) qrup = QuadRupture.fromTrace(xp0, yp0, xp1, yp1, zp, widths, dips, origin) rrup_q, _ = qrup.computeRrup(lon, lat, dep) rjb_q, _ = qrup.computeRjb(lon, lat, dep) # Construct equivalent EdgeRupture toplons = np.array([-122.0, -121.7, -122.5, -122.3]) toplats = np.array([37.1, 37.2, 37.4, 37.2]) topdeps = np.array([0, 0, 6, 6]) botlons = np.array([-121.886864, -121.587568, -122.635467, -122.435338]) botlats = np.array([36.884527, 36.984246, 37.314035, 37.114261]) botdeps = np.array([15.0000, 14.9998, 18.8558, 18.8559]) group_index = [0, 0, 1, 1] erup = EdgeRupture.fromArrays(toplons, toplats, topdeps, botlons, botlats, botdeps, origin, group_index) rrup_e, _ = erup.computeRrup(lon, lat, dep) rjb_e, _ = erup.computeRjb(lon, lat, dep) # Check that QuadRupture and EdgeRupture give the same result # (we check the absolute values of QuadRupture elsewhere) np.testing.assert_allclose(rrup_e, rrup_q, atol=0.35) np.testing.assert_allclose(rjb_e, rjb_q, atol=0.35)
def test_incorrect(): # Number of points in polyon is even rupture_text = """# Source: Ji, C., D. V. Helmberger, D. J. Wald, and \ K.-F. Ma (2003). Slip history and dynamic implications of the 1999 Chi-Chi, \ Taiwan, earthquake, J. Geophys. Res. 108, 2412, doi:10.1029/2002JB001764. 120.72300 24.27980 0 121.00000 24.05000 17 121.09300 24.07190 17 121.04300 24.33120 17 121.04300 24.33120 17 120.72300 24.27980 0 > 120.72300 24.27980 0 120.68000 23.70000 0 120.97200 23.60400 17 121.00000 24.05000 17 120.72300 24.27980 0 > 120.97200 23.60400 17 120.68000 23.70000 0 120.58600 23.58850 0 120.78900 23.40240 17 120.97200 23.60400 17""" # noqa # Rupture requires an origin even when not used: origin = Origin({'id': 'test', 'lon': 0, 'lat': 0, 'depth': 5.0, 'mag': 7.0, 'netid': 'us', 'network': '', 'locstring': '', 'time': HistoricTime.utcfromtimestamp(time.time())}) cbuf = io.StringIO(rupture_text) with pytest.raises(Exception): get_rupture(origin, cbuf) # Top points must be first rupture_text = """# Test 120.72300 24.27980 0 121.00000 24.05000 17 121.09300 24.07190 17 121.04300 24.33120 17 120.72300 24.27980 0""" # noqa cbuf = io.StringIO(rupture_text) with pytest.raises(Exception): get_rupture(origin, cbuf) # Wrong order of lat/lon rupture_text = """# Test -118.421 34.315 5.000 -118.587 34.401 5.000 -118.693 34.261 20.427 -118.527 34.175 20.427 -118.421 34.315 5.000 """ # noqa cbuf = io.StringIO(rupture_text) with pytest.raises(Exception): get_rupture(origin, cbuf, new_format=False) # Wrong order of lat/lon rupture_text = """# Test 34.315 -118.421 5.000 34.401 -118.587 5.000 34.261 -118.693 20.427 34.175 -118.527 20.427 34.315 -118.421 5.000 """ # noqa cbuf = io.StringIO(rupture_text) with pytest.raises(Exception): get_rupture(origin, cbuf, new_format=True) # Unclosed segments rupture_text = """# Test 34.315 -118.421 5.000 34.401 -118.587 5.000 34.261 -118.693 20.427 34.175 -118.527 20.427 34.315 -118.6 5.000 """ # noqa cbuf = io.StringIO(rupture_text) with pytest.raises(Exception): get_rupture(origin, cbuf, new_format=False) # incorrect delimiter rupture_text = """#Test 34.315;-118.421;5.000 34.401;-118.587;5.000 34.261;-118.693;20.427 34.175;-118.527;20.427 34.315;-118.421;5.000 """ # noqa cbuf = io.StringIO(rupture_text) with pytest.raises(Exception): get_rupture(origin, cbuf, new_format=False) # incorrect delimiter, new format rupture_text = """#Test 34.315;-118.421;5.000 34.401;-118.587;5.000 34.261;-118.693;20.427 34.175;-118.527;20.427 34.315;-118.421;5.000 """ # noqa cbuf = io.StringIO(rupture_text) with pytest.raises(Exception): get_rupture(origin, cbuf, new_format=True) # Not 3 columns rupture_text = """#Test 34.315 -118.421;5.000 34.401 -118.587;5.000 34.261 -118.693;20.427 34.175 -118.527;20.427 34.315 -118.421;5.000 """ # noqa cbuf = io.StringIO(rupture_text) with pytest.raises(Exception): get_rupture(origin, cbuf, new_format=False) # Json incorrect test = { "metadata": { "id": "test", "mag": 7.0, "lon": 0, "mech": "ALL", "depth": 5.0, "time": "2018-07-02T22:50:03Z", "netid": "us", "rake": 0.0, "lat": 0, "network": "", "locstring": "", "reference": "Test" }, "features": [{ "type": "Feature", "geometry": { "coordinates": [[ [[-118.421, 34.315, 5.0], [-118.587, 34.401, 5.0], [-118.693, 34.261, 20.427], [-118.527, 34.175, 20.427], [-118.421, 34.315, 5.0]]]], "type": "MultiPolygon" }, "properties":{ "rupture type": "rupture extent" } }], "type": "FeatureCollection" } # incorrect type test_incorrect = copy.deepcopy(test) test_incorrect['type'] = 'Feature' with pytest.raises(Exception) as e: validate_json(test_incorrect) print(str(e)) # Incorrect number of features test_incorrect = copy.deepcopy(test) test_incorrect['features'].append(['wrong']) with pytest.raises(Exception) as e: validate_json(test_incorrect) print(str(e)) # no reference test_incorrect = copy.deepcopy(test) test_incorrect['metadata'].pop('reference', None) with pytest.raises(Exception) as e: validate_json(test_incorrect) print(str(e)) # incorrect feature type test_incorrect = copy.deepcopy(test) test_incorrect['features'][0]['type'] = 'fred' with pytest.raises(Exception) as e: validate_json(test_incorrect) print(str(e)) # incorrect feature geometry type test_incorrect = copy.deepcopy(test) test_incorrect['features'][0]['geometry']['type'] = 'fred' with pytest.raises(Exception) as e: validate_json(test_incorrect) print(str(e)) # no coordinates test_incorrect = copy.deepcopy(test) test_incorrect['features'][0]['geometry'].pop('coordinates', None) with pytest.raises(Exception) as e: validate_json(test_incorrect) print(str(e))
def read_event_xml(file): """ Read event.xml. Args: file (str): Path to event.xml file. Returns: dict: Dictionary with event info. """ eventtree = ET.parse(file) eventroot = eventtree.getroot() for eq in eventroot.iter('earthquake'): id_str = eq.attrib['id'] magnitude = float(eq.attrib['mag']) hlat = float(eq.attrib['lat']) hlon = float(eq.attrib['lon']) hdepth = float(eq.attrib['depth']) if 'rake' in eq.attrib.keys(): rake = float(eq.attrib['rake']) else: rake = None lstring = eq.attrib['locstring'] if 'description' in eq.attrib.keys(): description = eq.attrib['description'] else: description = "" if 'type' in eq.attrib.keys(): mech = eq.attrib['type'] else: mech = "ALL" year = int(eq.attrib['year']) month = int(eq.attrib['month']) day = int(eq.attrib['day']) hour = int(eq.attrib['hour']) minute = int(eq.attrib['minute']) second = int(eq.attrib['second']) if 'directivity' in eq.attrib.keys(): directivity = ast.literal_eval(eq.attrib['directivity']) else: directivity = False if 'eventsourcecode' in eq.attrib.keys(): eventsourcecode = eq.attrib['eventsourcecode'] else: eventsourcecode = None sdt = ShakeDateTime(year, month, day, hour, minute, second, int(0)) event = { 'lat': hlat, 'lon': hlon, 'depth': hdepth, 'mag': magnitude, 'rake': rake, 'id': id_str, 'locstring': lstring, 'type': mech, 'mech': mech, 'time': sdt.strftime('%Y-%m-%dT%H:%M:%SZ'), 'timezone': 'UTC', 'directivity': directivity, 'description': description, 'eventsourcecode': eventsourcecode, 'sdt': sdt } return event
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, 'eventsourcecode': 'ss3', 'rake': rake }) rup = 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 = 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, 'eventsourcecode': '', 'locstring': 'test', 'type': 'SS', 'timezone': 'UTC' } event['time'] = HistoricTime.utcfromtimestamp(int(time.time())) event['created'] = HistoricTime.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_ss3(): 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]) epix = np.array([0]) epiy = np.array([0.2 * rupy[1]]) # Convert to lat/lon proj = OrthographicProjection(-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': 10, 'mag': magnitude, 'id': 'ss3', 'netid': 'us', 'network': '', 'locstring': '', 'rake': rake, 'time': HistoricTime.utcfromtimestamp(int(time.time()))}) rup = 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(-60, 60, 21) y = np.linspace(-60, 138, 34) 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) # Test fd fd = test1.getFd() fd_test = np.array( [[0.00000000e+00, 0.00000000e+00, 2.14620746e-03, 6.47899336e-03, 1.23119791e-02, 1.91676140e-02, 2.64009788e-02, 3.32427846e-02, 3.88863288e-02, 4.26104002e-02, 4.39120296e-02, 4.26104002e-02, 3.88863288e-02, 3.32427846e-02, 2.64009788e-02, 1.91676140e-02, 1.23119791e-02, 6.47899336e-03, 2.14620746e-03, 0.00000000e+00, 0.00000000e+00], [0.00000000e+00, 8.57780996e-04, 3.99405791e-03, 9.31948105e-03, 1.65406113e-02, 2.51316805e-02, 3.43205435e-02, 4.31274592e-02, 5.04747209e-02, 5.53634169e-02, 5.70796092e-02, 5.53634169e-02, 5.04747209e-02, 4.31274592e-02, 3.43205435e-02, 2.51316805e-02, 1.65406113e-02, 9.31948105e-03, 3.99405791e-03, 8.57780996e-04, 0.00000000e+00], [-7.32594549e-04, 1.80425497e-04, 3.76908220e-03, 1.00175179e-02, 1.86854835e-02, 2.92291145e-02, 4.07487277e-02, 5.20057177e-02, 6.15509770e-02, 6.79776087e-02, 7.02477931e-02, 6.79776087e-02, 6.15509770e-02, 5.20057177e-02, 4.07487277e-02, 2.92291145e-02, 1.86854835e-02, 1.00175179e-02, 3.76908220e-03, 1.80425497e-04, -7.32594549e-04], [-3.29238561e-03, -2.60643191e-03, 1.16635260e-03, 8.15185259e-03, 1.82290773e-02, 3.08983182e-02, 4.51608038e-02, 5.94769126e-02, 7.18919113e-02, 8.03888307e-02, 8.34165399e-02, 8.03888307e-02, 7.18919113e-02, 5.94769126e-02, 4.51608038e-02, 3.08983182e-02, 1.82290773e-02, 8.15185259e-03, 1.16635260e-03, -2.60643191e-03, -3.29238561e-03], [-7.68543266e-03, -7.63179286e-03, -4.08866637e-03, 3.27605236e-03, 1.45558215e-02, 2.94068040e-02, 4.68176355e-02, 6.49397159e-02, 7.72066272e-02, 8.50445368e-02, 8.77974692e-02, 8.50445368e-02, 7.72066272e-02, 6.49397159e-02, 4.68176355e-02, 2.94068040e-02, 1.45558215e-02, 3.27605236e-03, -4.08866637e-03, -7.63179286e-03, -7.68543266e-03], [-1.38078234e-02, -1.49011067e-02, -1.21731364e-02, -5.02168047e-03, 6.98177526e-03, 2.38268531e-02, 4.30419205e-02, 6.00041964e-02, 7.44541603e-02, 8.42939552e-02, 8.77989590e-02, 8.42939552e-02, 7.44541603e-02, 6.00041964e-02, 4.30419205e-02, 2.38268531e-02, 6.98177526e-03, -5.02168047e-03, -1.21731364e-02, -1.49011067e-02, -1.38078234e-02], [-2.13780396e-02, -2.42165379e-02, -2.30613142e-02, -1.70011475e-02, -5.15036128e-03, 1.25885635e-02, 3.24536739e-02, 5.25619351e-02, 7.05100243e-02, 8.31900906e-02, 8.78003567e-02, 8.31900906e-02, 7.05100243e-02, 5.25619351e-02, 3.24536739e-02, 1.25885635e-02, -5.15036128e-03, -1.70011475e-02, -2.30613142e-02, -2.42165379e-02, -2.13780396e-02], [-2.98882710e-02, -3.50862342e-02, -3.63793490e-02, -3.25716319e-02, -2.22546618e-02, -3.59274163e-03, 1.83064517e-02, 4.20112440e-02, 6.46115966e-02, 8.14746164e-02, 8.78016623e-02, 8.14746164e-02, 6.46115966e-02, 4.20112440e-02, 1.83064517e-02, -3.59274163e-03, -2.22546618e-02, -3.25716319e-02, -3.63793490e-02, -3.50862342e-02, -2.98882710e-02], [-3.85810679e-02, -4.66488633e-02, -5.12430987e-02, -5.10089462e-02, -4.20856023e-02, -2.36905234e-02, -6.33876287e-04, 2.66765430e-02, 5.53289928e-02, 7.86066125e-02, 8.78028757e-02, 7.86066125e-02, 5.53289928e-02, 2.66765430e-02, -6.33876287e-04, -2.36905234e-02, -4.20856023e-02, -5.10089462e-02, -5.12430987e-02, -4.66488633e-02, -3.85810679e-02], [-4.64803335e-02, -5.76615888e-02, -6.61458422e-02, -7.06512643e-02, -6.38427394e-02, -4.77258398e-02, -2.55483969e-02, 4.05840724e-03, 3.98470070e-02, 7.33053399e-02, 8.78039969e-02, 7.33053399e-02, 3.98470070e-02, 4.05840724e-03, -2.55483969e-02, -4.77258398e-02, -6.38427394e-02, -7.06512643e-02, -6.61458422e-02, -5.76615888e-02, -4.64803335e-02], [-5.25038299e-02, -6.66129442e-02, -7.90147081e-02, -8.87629178e-02, -8.59653118e-02, -7.42828398e-02, -5.64316505e-02, -2.87083225e-02, 1.25945312e-02, 6.19971667e-02, 8.78050260e-02, 6.19971667e-02, 1.25945312e-02, -2.87083225e-02, -5.64316505e-02, -7.42828398e-02, -8.59653118e-02, -8.87629178e-02, -7.90147081e-02, -6.66129442e-02, -5.25038299e-02], [-5.69779111e-02, -7.36791817e-02, -8.97495345e-02, -1.04799583e-01, -1.07737239e-01, -1.02875880e-01, -9.46568471e-02, -7.95630162e-02, -4.96285112e-02, 6.59954795e-03, 5.25569882e-02, 6.59954795e-03, -4.96285112e-02, -7.95630162e-02, -9.46568471e-02, -1.02875880e-01, -1.07737239e-01, -1.04799583e-01, -8.97495345e-02, -7.36791817e-02, -5.69779111e-02], [-5.90357675e-02, -7.69727119e-02, -9.48442826e-02, -1.12607620e-01, -1.18744885e-01, -1.18201834e-01, -1.17217017e-01, -1.15152899e-01, -1.09694433e-01, -8.82341332e-02, -1.61624035e-02, -8.82341332e-02, -1.09694433e-01, -1.15152899e-01, -1.17217017e-01, -1.18201834e-01, -1.18744885e-01, -1.12607620e-01, -9.48442826e-02, -7.69727119e-02, -5.90357675e-02], [-5.92189452e-02, -7.72680305e-02, -9.53051857e-02, -1.13322519e-01, -1.19770917e-01, -1.19670660e-01, -1.19486798e-01, -1.19092639e-01, -1.17989113e-01, -1.12555820e-01, -4.50009776e-02, -1.12555820e-01, -1.17989113e-01, -1.19092639e-01, -1.19486798e-01, -1.19670660e-01, -1.19770917e-01, -1.13322519e-01, -9.53051857e-02, -7.72680305e-02, -5.92189452e-02], [-5.79249958e-02, -7.51927112e-02, -9.20842554e-02, -1.08361430e-01, -1.12722790e-01, -1.09732675e-01, -1.04531672e-01, -9.44729544e-02, -7.23277773e-02, -2.05699911e-02, 3.58249631e-02, -2.05699911e-02, -7.23277773e-02, -9.44729544e-02, -1.04531672e-01, -1.09732675e-01, -1.12722790e-01, -1.08361430e-01, -9.20842554e-02, -7.51927112e-02, -5.79249958e-02], [-5.42527703e-02, -6.93641123e-02, -8.31684773e-02, -9.49114165e-02, -9.41989454e-02, -8.48645354e-02, -7.00894708e-02, -4.58286259e-02, -6.37563061e-03, 4.68887998e-02, 7.77968419e-02, 4.68887998e-02, -6.37563061e-03, -4.58286259e-02, -7.00894708e-02, -8.48645354e-02, -9.41989454e-02, -9.49114165e-02, -8.31684773e-02, -6.93641123e-02, -5.42527703e-02], [-4.82490057e-02, -5.99997941e-02, -6.91786120e-02, -7.44891242e-02, -6.73705808e-02, -5.13001284e-02, -2.84188057e-02, 3.60143816e-03, 4.47470123e-02, 8.58663851e-02, 1.04548354e-01, 8.58663851e-02, 4.47470123e-02, 3.60143816e-03, -2.84188057e-02, -5.13001284e-02, -6.73705808e-02, -7.44891242e-02, -6.91786120e-02, -5.99997941e-02, -4.82490057e-02], [-4.03203010e-02, -4.79063206e-02, -5.16352259e-02, -4.98707253e-02, -3.67295509e-02, -1.57342058e-02, 1.13668830e-02, 4.46551184e-02, 8.10450840e-02, 1.11780747e-01, 1.24226598e-01, 1.11780747e-01, 8.10450840e-02, 4.46551184e-02, 1.13668830e-02, -1.57342058e-02, -3.67295509e-02, -4.98707253e-02, -5.16352259e-02, -4.79063206e-02, -4.03203010e-02], [-3.10250239e-02, -3.40796094e-02, -3.22089254e-02, -2.37094100e-02, -5.85463114e-03, 1.77402761e-02, 4.57786845e-02, 7.69637052e-02, 1.07537652e-01, 1.30906328e-01, 1.39800436e-01, 1.30906328e-01, 1.07537652e-01, 7.69637052e-02, 4.57786845e-02, 1.77402761e-02, -5.85463114e-03, -2.37094100e-02, -3.22089254e-02, -3.40796094e-02, -3.10250239e-02], [-2.09301700e-02, -1.94475962e-02, -1.22970199e-02, 2.07296407e-03, 2.31516868e-02, 4.74574033e-02, 7.44743481e-02, 1.02380049e-01, 1.27776301e-01, 1.46003379e-01, 1.52690015e-01, 1.46003379e-01, 1.27776301e-01, 1.02380049e-01, 7.44743481e-02, 4.74574033e-02, 2.31516868e-02, 2.07296407e-03, -1.22970199e-02, -1.94475962e-02, -2.09301700e-02], [-1.05257992e-02, -4.74329696e-03, 7.12107274e-03, 2.63431361e-02, 4.93709790e-02, 7.31527220e-02, 9.82233938e-02, 1.22728059e-01, 1.43894925e-01, 1.58465026e-01, 1.63685984e-01, 1.58465026e-01, 1.43894925e-01, 1.22728059e-01, 9.82233938e-02, 7.31527220e-02, 4.93709790e-02, 2.63431361e-02, 7.12107274e-03, -4.74329696e-03, -1.05257992e-02], [-1.89098657e-04, 9.52392382e-03, 2.54577716e-02, 4.85730869e-02, 7.26048516e-02, 9.51726659e-02, 1.17988523e-01, 1.39380421e-01, 1.57176612e-01, 1.69076915e-01, 1.73274075e-01, 1.69076915e-01, 1.57176612e-01, 1.39380421e-01, 1.17988523e-01, 9.51726659e-02, 7.26048516e-02, 4.85730869e-02, 2.54577716e-02, 9.52392382e-03, -1.89098657e-04], [9.81732797e-03, 2.30419581e-02, 4.24234701e-02, 6.86213308e-02, 9.30164618e-02, 1.14050063e-01, 1.34620894e-01, 1.53304069e-01, 1.68420867e-01, 1.78321253e-01, 1.81774183e-01, 1.78321253e-01, 1.68420867e-01, 1.53304069e-01, 1.34620894e-01, 1.14050063e-01, 9.30164618e-02, 6.86213308e-02, 4.24234701e-02, 2.30419581e-02, 9.81732797e-03], [1.93290725e-02, 3.56493099e-02, 5.79271157e-02, 8.65611122e-02, 1.10914315e-01, 1.30317702e-01, 1.48798006e-01, 1.65173224e-01, 1.78147031e-01, 1.86513895e-01, 1.89408199e-01, 1.86513895e-01, 1.78147031e-01, 1.65173224e-01, 1.48798006e-01, 1.30317702e-01, 1.10914315e-01, 8.65611122e-02, 5.79271157e-02, 3.56493099e-02, 1.93290725e-02], [2.68168937e-02, 4.52356810e-02, 6.92261217e-02, 9.89630241e-02, 1.23093435e-01, 1.40640067e-01, 1.56998943e-01, 1.71215219e-01, 1.82297185e-01, 1.89360704e-01, 1.91789146e-01, 1.89360704e-01, 1.82297185e-01, 1.71215219e-01, 1.56998943e-01, 1.40640067e-01, 1.23093435e-01, 9.89630241e-02, 6.92261217e-02, 4.52356810e-02, 2.68168937e-02], [3.19403269e-02, 5.15051953e-02, 7.61032066e-02, 1.05705197e-01, 1.31722206e-01, 1.47466588e-01, 1.61892450e-01, 1.74235616e-01, 1.83735386e-01, 1.89735533e-01, 1.91788616e-01, 1.89735533e-01, 1.83735386e-01, 1.74235616e-01, 1.61892450e-01, 1.47466588e-01, 1.31722206e-01, 1.05705197e-01, 7.61032066e-02, 5.15051953e-02, 3.19403269e-02], [3.48604070e-02, 5.49292382e-02, 7.94274234e-02, 1.08149011e-01, 1.38923419e-01, 1.53070440e-01, 1.65849067e-01, 1.76646162e-01, 1.84871647e-01, 1.90029617e-01, 1.91787948e-01, 1.90029617e-01, 1.84871647e-01, 1.76646162e-01, 1.65849067e-01, 1.53070440e-01, 1.38923419e-01, 1.08149011e-01, 7.94274234e-02, 5.49292382e-02, 3.48604070e-02], [3.53402022e-02, 5.53653759e-02, 7.91965502e-02, 1.06486934e-01, 1.36563003e-01, 1.57713955e-01, 1.69087164e-01, 1.78598269e-01, 1.85784340e-01, 1.90264452e-01, 1.91787141e-01, 1.90264452e-01, 1.85784340e-01, 1.78598269e-01, 1.69087164e-01, 1.57713955e-01, 1.36563003e-01, 1.06486934e-01, 7.91965502e-02, 5.53653759e-02, 3.53402022e-02], [3.32889822e-02, 5.28319225e-02, 7.55769079e-02, 1.01077605e-01, 1.28592068e-01, 1.57023616e-01, 1.71766715e-01, 1.80199729e-01, 1.86528091e-01, 1.90454829e-01, 1.91786196e-01, 1.90454829e-01, 1.86528091e-01, 1.80199729e-01, 1.71766715e-01, 1.57023616e-01, 1.28592068e-01, 1.01077605e-01, 7.55769079e-02, 5.28319225e-02, 3.32889822e-02], [2.87295370e-02, 4.74613283e-02, 6.88388861e-02, 9.23568989e-02, 1.17254645e-01, 1.42483223e-01, 1.66695764e-01, 1.81528776e-01, 1.87141877e-01, 1.90611190e-01, 1.91785112e-01, 1.90611190e-01, 1.87141877e-01, 1.81528776e-01, 1.66695764e-01, 1.42483223e-01, 1.17254645e-01, 9.23568989e-02, 6.88388861e-02, 4.74613283e-02, 2.87295370e-02], [2.17650266e-02, 3.94568191e-02, 5.93023344e-02, 8.07720575e-02, 1.03124482e-01, 1.25394282e-01, 1.46405870e-01, 1.64828303e-01, 1.79288925e-01, 1.88553222e-01, 1.91747252e-01, 1.88553222e-01, 1.79288925e-01, 1.64828303e-01, 1.46405870e-01, 1.25394282e-01, 1.03124482e-01, 8.07720575e-02, 5.93023344e-02, 3.94568191e-02, 2.17650266e-02], [1.25495284e-02, 2.90572166e-02, 4.72972116e-02, 6.67423656e-02, 8.66951873e-02, 1.06290296e-01, 1.24520131e-01, 1.40293247e-01, 1.52531693e-01, 1.60303860e-01, 1.62970689e-01, 1.60303860e-01, 1.52531693e-01, 1.40293247e-01, 1.24520131e-01, 1.06290296e-01, 8.66951873e-02, 6.67423656e-02, 4.72972116e-02, 2.90572166e-02, 1.25495284e-02], [1.26441934e-03, 1.65114811e-02, 3.31390978e-02, 5.06407706e-02, 6.83765492e-02, 8.55839448e-02, 1.01408074e-01, 1.14955639e-01, 1.25373662e-01, 1.31946425e-01, 1.34193829e-01, 1.31946425e-01, 1.25373662e-01, 1.14955639e-01, 1.01408074e-01, 8.55839448e-02, 6.83765492e-02, 5.06407706e-02, 3.31390978e-02, 1.65114811e-02, 1.26441934e-03], [0.00000000e+00, 2.06213867e-03, 1.71162845e-02, 3.27888240e-02, 4.85026462e-02, 6.35932476e-02, 7.73387997e-02, 8.90069217e-02, 9.79166934e-02, 1.03509489e-01, 1.05416736e-01, 1.03509489e-01, 9.79166934e-02, 8.90069217e-02, 7.73387997e-02, 6.35932476e-02, 4.85026462e-02, 3.27888240e-02, 1.71162845e-02, 2.06213867e-03, 0.00000000e+00]] ) np.testing.assert_allclose(fd, fd_test, rtol=1e-4)
def __init__(self, event): """ Construct an Origin object. Args: event (dict): Dictionary of values. See list above for required keys. Returns: Origin object. Raises: ValueError: When input time is not and cannot be converted to HistoricTime object. """ # --------------------------------------------------------------------- # Check for missing keys # --------------------------------------------------------------------- missing = [] for req in constants.ORIGIN_REQUIRED_KEYS: if req not in list(event.keys()): missing.append(req) if len(missing): raise Exception('Input event dictionary is missing the following ' 'required keys: "%s"' % (','.join(missing))) # --------------------------------------------------------------------- # Check some types, ranges, and defaults # --------------------------------------------------------------------- if not type(event['eventsourcecode']) is str: raise Exception('eventsourcecode must be a string.') if (event['lat'] > 90) or (event['lat'] < -90): raise Exception('lat must be between -90 and 90 degrees.') if (event['lon'] > 180) or (event['lon'] < -180): raise Exception('lat must be between -180 and 180 degrees.') # make sure that time is an HistoricTime instance if 'time' in event: if isinstance(event['time'],str): try: event['time'] = HistoricTime.strptime(event['time'],TIMEFMT) except ValueError: fmt = 'Input time string %s cannot be converted to datetime.' raise ValueError(fmt % event['time']) if 'mech' in event.keys(): if event['mech'] == '': event['mech'] = constants.DEFAULT_MECH if not event['mech'] in constants.RAKEDICT.keys(): raise Exception('mech must be SS, NM, RS, or ALL.') elif 'type' in event.keys(): event['mech'] = event['type'] if event['mech'] == '': event['mech'] = constants.DEFAULT_MECH if not event['mech'] in constants.RAKEDICT.keys(): raise Exception('mech must be SS, NM, RS, or ALL.') else: event['mech'] = constants.DEFAULT_MECH # --------------------------------------------------------------------- # Add keys as class attributes # --------------------------------------------------------------------- for k, v in event.items(): if k == 'rake': setattr(self, k, float(v)) else: setattr(self, k, v) # What about rake? if not hasattr(self, 'rake'): if hasattr(self, 'mech'): mech = self.mech self.rake = constants.RAKEDICT[mech] else: self.rake = constants.RAKEDICT['ALL'] if self.rake is None: self.rake = 0.0
def test_ss3_m6(): magnitude = 6.0 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]) epix = np.array([0]) epiy = np.array([0.2 * rupy[1]]) # Convert to lat/lon proj = OrthographicProjection(-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': 10, 'mag': magnitude, 'id': 'ss3', 'netid': '', 'network': '', 'locstring': '', 'rake': rake, 'time': HistoricTime.utcfromtimestamp(int(time.time()))}) rup = 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) # Test fd fd = test1.getFd() fd_test = np.array( [[0.05853668, 0.05032323, 0.0306438, 0.00839635, -0.01102162, -0.02621319], [0.01720501, -0.00687296, -0.03804823, -0.05547473, -0.0644932, -0.06947135], [-0.03000065, -0.07006634, -0.07708165, -0.07865941, -0.0792369, -0.07950887], [0.0398062, 0.02571145, -0.0018651, -0.0255418, -0.04176278, -0.05235095], [0.0696989, 0.06389524, 0.04890304, 0.02983134, 0.01098535, -0.00545921], [0.088278, 0.08511069, 0.07628596, 0.06350294, 0.04875897, 0.03373495], [0.10179334, 0.09978475, 0.09401676, 0.0851842, 0.07422509, 0.06210369], [0.11242209, 0.11102701, 0.10696056, 0.10055471, 0.09229027, 0.08271454], [0.12118279, 0.12015315, 0.11712653, 0.11228058, 0.10588323, 0.09825795], [0.12785957, 0.12706892, 0.12473264, 0.12095384, 0.11589197, 0.10974684], [0.12785908, 0.12724852, 0.12543819, 0.12249026, 0.11850249, 0.11360047]]) np.testing.assert_allclose( fd, fd_test, rtol=1e-4)