def test_get_extent_no_rup(): origin = Origin({ 'id': 'test', 'lat': 37.1, 'lon': -122.1, 'depth': 5.0, 'mag': 8.5 }) extent = np.array(get_extent(origin)) np.testing.assert_allclose( extent, np.array([[-126.5981497], [-117.13214326], [33.23305437], [40.77859864]])) origin = Origin({ 'id': 'test', 'lat': 37.1, 'lon': -122.1, 'depth': 5.0, 'mag': 6 }) extent = np.array(get_extent(origin)) np.testing.assert_allclose( extent, np.array([[-123.21199895], [-120.9613286], [36.19336348], [37.99597076]]))
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 test_extent_config(): eventfile = os.path.join(datadir, 'event_oklahoma_large.xml') origin = Origin.fromFile(eventfile) rupture = get_rupture(origin) config = { 'extent': { 'magnitude_spans': { 'span1': [0, 6, 4, 3], 'span2': [6, 10, 6, 4] } } } extent = get_extent(rupture, config) cmp_extent = (-99.4166667, -95.4083333, 32.675, 38.6833333) np.testing.assert_almost_equal(cmp_extent, extent) # Test for relative_offset config = { 'extent': { 'magnitude_spans': { 'span1': [0, 6, 4, 3], 'span2': [6, 10, 6, 4] }, 'relative_offset': [0.25, 0.5], } } extent = get_extent(rupture, config) cmp_extent = (-98.4166667, -94.4083333, 35.675, 41.6833333) np.testing.assert_almost_equal(cmp_extent, extent) config = {'extent': {'bounds': {'extent': [-100, 32, -95, 37]}}} extent = get_extent(rupture, config) cmp_extent = [-100, -95, 32, 37] np.testing.assert_almost_equal(extent, cmp_extent)
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, 'eventsourcecode': 'abcd' }) 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 updateRupture(self,eventxml = None, rupturefile = None): """Update rupture/origin information in container. Args: eventxml (str): Path to event.xml file. rupturefile (str): Path to rupture file (JSON or txt format). """ if eventxml is None and rupturefile is None: return # the container is guaranteed to have at least a Point rupture # and the origin. rupture = self.getRuptureObject() origin = rupture.getOrigin() if eventxml is not None: origin = Origin.fromFile(eventxml) if rupturefile is not None: rupture = get_rupture(origin,file=rupturefile) else: rupture_dict = rupture._geojson rupture = rupture_from_dict_and_origin(rupture_dict,origin) else: #no event.xml file, but we do have a rupture file rupture = get_rupture(origin,file=rupturefile) self.setRupture(rupture)
def test_extent_config(): eventfile = os.path.join(datadir, 'event_oklahoma_large.xml') origin = Origin.fromFile(eventfile) rupture = get_rupture(origin) config = {'extent': {'coefficients': {'coeffs': [27.24, 250.4, 579.1]}}} cmp_extent = (-100.61666666666666, -93.95, 32.916666666666664, 38.35) extent = get_extent(rupture, config) np.testing.assert_almost_equal(cmp_extent, extent) config = { 'extent': { 'magnitude_spans': { 'span1': [0, 6, 4, 3], 'span2': [6, 10, 6, 4] } } } extent = get_extent(rupture, config) cmp_extent = (-99.416, -95.416, 32.679, 38.679) np.testing.assert_almost_equal(cmp_extent, extent) config = {'extent': {'bounds': {'extent': [-100, 32, -95, 37]}}} extent = get_extent(rupture, config) cmp_extent = [-100, -95, 32, 37] np.testing.assert_almost_equal(extent, cmp_extent)
def updateRupture(self, eventxml=None, rupturefile=None): """Update rupture/origin information in container. Args: eventxml (str): Path to event.xml file. rupturefile (str): Path to rupture file (JSON or txt format). """ if eventxml is None and rupturefile is None: return # the container is guaranteed to have at least a Point rupture # and the origin. rupture = self.getRuptureObject() origin = rupture.getOrigin() if eventxml is not None: origin = Origin.fromFile(eventxml) if rupturefile is not None: rupture = get_rupture(origin, file=rupturefile) else: rupture_dict = rupture._geojson rupture = rupture_from_dict_and_origin(rupture_dict, origin) else: # no event.xml file, but we do have a rupture file rupture = get_rupture(origin, file=rupturefile) self.setRupture(rupture)
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) 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_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({'eventsourcecode': 'test', 'lat': 0, 'lon': 0, 'depth': 5.0, 'mag': 7.0}) 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_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. 24.27980 120.72300 0 24.05000 121.00000 17 24.07190 121.09300 17 24.33120 121.04300 17 24.33120 121.04300 17 24.27980 120.72300 0 > 24.27980 120.72300 0 23.70000 120.68000 0 23.60400 120.97200 17 24.05000 121.00000 17 24.27980 120.72300 0 > 23.60400 120.97200 17 23.70000 120.68000 0 23.58850 120.58600 0 23.40240 120.78900 17 23.60400 120.97200 17""" # noqa # Rupture requires an origin even when not used: origin = Origin({'eventsourcecode': 'test', 'lat': 0, 'lon': 0, 'depth': 5.0, 'mag': 7.0}) cbuf = io.StringIO(rupture_text) with pytest.raises(Exception): get_rupture(origin, cbuf)
def test_with_quakeml(): np1 = NodalPlane(strike=259, dip=74, rake=10) np2 = NodalPlane(strike=166, dip=80, rake=164) nodal_planes = NodalPlanes(nodal_plane_1=np1, nodal_plane_2=np2) focal = FocalMechanism(nodal_planes=nodal_planes) event = Event(focal_mechanisms=[focal]) catalog = Catalog(events=[event]) event_text = '''<shakemap-data code_version="4.0" map_version="1"> <earthquake id="us2000cmy3" lat="56.046" lon="-149.073" mag="7.9" time="2018-01-23T09:31:42Z" depth="25.00" locstring="280km SE of Kodiak, Alaska" netid="us" network=""/> </shakemap-data>''' try: tempdir = tempfile.mkdtemp() xmlfile = os.path.join(tempdir, 'quakeml.xml') catalog.write(xmlfile, format="QUAKEML") eventfile = os.path.join(tempdir, 'event.xml') f = open(eventfile, 'wt') f.write(event_text) f.close() params = read_moment_quakeml(xmlfile) origin = Origin.fromFile(eventfile, momentfile=xmlfile) x = 1 except Exception as e: assert 1 == 2 finally: shutil.rmtree(tempdir)
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 test_get_extent_small_complex(): # # Do a complex rupture # eventfile = os.path.join(datadir, 'event_wenchuan.xml') origin = Origin.fromFile(eventfile) faultfile = os.path.join(datadir, 'Hartzell11_fault.txt') rupture = get_rupture(origin, faultfile) W, E, S, N = get_extent(rupture) assert W == 100.03333333333333 assert E == 108.93333333333334 assert S == 27.9 assert N == 35.55
def test_get_extent_stable_small(): # # Do an event in a stable region # Small magnitude # eventfile = os.path.join(datadir, 'event_oklahoma.xml') origin = Origin.fromFile(eventfile) rupture = get_rupture(origin) W, E, S, N = get_extent(rupture) assert W == -98.5 assert E == -96.28333333333333 assert S == 34.766666666666666 assert N == 36.583333333333336
def test_get_extent_small_point(): # # Do a point rupture # Small magnitude # eventfile = os.path.join(datadir, 'event_wenchuan_small.xml') origin = Origin.fromFile(eventfile) rupture = get_rupture(origin) W, E, S, N = get_extent(rupture) assert W == 102.33333333333333 assert E == 104.41666666666667 assert S == 30.083333333333332 assert N == 31.883333333333333
def test_get_extent_stable_large(): # # Do an event in a stable region # Large magnitude # eventfile = os.path.join(datadir, 'event_oklahoma_large.xml') origin = Origin.fromFile(eventfile) rupture = get_rupture(origin) W, E, S, N = get_extent(rupture) assert W == -106.14999999999999 assert E == -86.76666666666667 assert S == 27.55 assert N == 43.03333333333333
def test_get_extent_small_complex(): # # Do a complex rupture # eventfile = os.path.join(datadir, 'event_wenchuan.xml') origin = Origin.fromFile(eventfile) faultfile = os.path.join(datadir, 'Hartzell11_fault.txt') rupture = get_rupture(origin, faultfile) W, E, S, N = get_extent(rupture) np.testing.assert_allclose(W, 95.28333333333333) np.testing.assert_allclose(E, 115.1) np.testing.assert_allclose(S, 23.083333333333332) np.testing.assert_allclose(N, 39.75)
def test_get_extent_stable_small(): # # Do an event in a stable region # Small magnitude # eventfile = os.path.join(datadir, 'event_oklahoma.xml') origin = Origin.fromFile(eventfile) rupture = get_rupture(origin) W, E, S, N = get_extent(rupture) np.testing.assert_allclose(W, -98.5) np.testing.assert_allclose(E, -96.28333333333333) np.testing.assert_allclose(S, 34.766666666666666) np.testing.assert_allclose(N, 36.583333333333336)
def test_get_extent_stable_large(): # # Do an event in a stable region # Large magnitude # eventfile = os.path.join(datadir, 'event_oklahoma_large.xml') origin = Origin.fromFile(eventfile) rupture = get_rupture(origin) W, E, S, N = get_extent(rupture) np.testing.assert_allclose(W, -107.45) np.testing.assert_allclose(E, -84.8) np.testing.assert_allclose(S, 26.166666666666668) np.testing.assert_allclose(N, 44.15)
def test_get_extent_small_point(): # # Do a point rupture # Small magnitude # eventfile = os.path.join(datadir, 'event_wenchuan_small.xml') origin = Origin.fromFile(eventfile) rupture = get_rupture(origin) W, E, S, N = get_extent(rupture) np.testing.assert_allclose(W, 102.33333333333333) np.testing.assert_allclose(E, 104.41666666666667) np.testing.assert_allclose(S, 30.083333333333332) np.testing.assert_allclose(N, 31.883333333333333)
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 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_probs(): install_path, config_path = get_config_paths() config = ConfigObj(os.path.join(install_path, 'config', 'select.conf')) validate_config(config, install_path) # # Real event: M 6.9 - 151km SSW of Kokopo, Papua New Guinea # 2018-03-29 21:25:36 UTC # Note: slab model depth is 33.4638 km # datadir = os.path.join( homedir, '..', '..', 'data', 'eventdata', 'us1000db40', 'current') eventxml = os.path.join(datadir, 'event.xml') org = Origin.fromFile(eventxml) gmpe_list, weight_list, strec_results = get_weights(org, config) assert len(gmpe_list) == 1 assert len(weight_list) == 1 assert gmpe_list[0] == 'subduction_interface_nshmp2014' np.testing.assert_allclose(weight_list[0], 1.0, rtol=1e-05) # move hypo to the surface: org.depth = 0 gmpe_list, weight_list, strec_results = get_weights(org, config) # dz is 33.4638 # slab uncertainty is 10, so x2 in int|abs(dz) is 29 # so m_{int|abs(dz)} = 0.15 np.testing.assert_allclose( weight_list, np.array([0.85, 0.15]), rtol=1e-05) assert gmpe_list[0] == 'subduction_crustal' assert gmpe_list[1] == 'subduction_interface_nshmp2014' # move hypo to be deeper: org.depth = 65 gmpe_list, weight_list, strec_results = get_weights(org, config) # dz is 33.4638 # slab uncertainty is 10, so x2 in int|abs(dz) is 29 # so m_{int|abs(dz)} = 0.15 np.testing.assert_allclose( weight_list, np.array([0.15, 0.85]), rtol=1e-05) assert gmpe_list[0] == 'subduction_interface_nshmp2014' assert gmpe_list[1] == 'subduction_slab_nshmp2014'
def test_with_quakeml(): np1 = NodalPlane(strike=259, dip=74, rake=10) np2 = NodalPlane(strike=166, dip=80, rake=164) nodal_planes = NodalPlanes(nodal_plane_1=np1, nodal_plane_2=np2) taxis = Axis(plunge=40, azimuth=70) naxis = Axis(plunge=50, azimuth=80) paxis = Axis(plunge=60, azimuth=90) paxes = PrincipalAxes(t_axis=taxis, n_axis=naxis, p_axis=paxis) focal = FocalMechanism(nodal_planes=nodal_planes, principal_axes=paxes) event = Event(focal_mechanisms=[focal]) catalog = Catalog(events=[event]) event_text = '''<shakemap-data code_version="4.0" map_version="1"> <earthquake id="us2000cmy3" lat="56.046" lon="-149.073" mag="7.9" time="2018-01-23T09:31:42Z" depth="25.00" locstring="280km SE of Kodiak, Alaska" netid="us" network=""/> </shakemap-data>''' try: tempdir = tempfile.mkdtemp() xmlfile = os.path.join(tempdir, 'quakeml.xml') catalog.write(xmlfile, format="QUAKEML") eventfile = os.path.join(tempdir, 'event.xml') f = open(eventfile, 'wt') f.write(event_text) f.close() params = read_moment_quakeml(xmlfile) assert params['moment']['NP1']['strike'] == 259.0 assert params['moment']['NP1']['dip'] == 74.0 assert params['moment']['NP1']['rake'] == 10.0 assert params['moment']['NP2']['strike'] == 166.0 assert params['moment']['NP2']['dip'] == 80.0 assert params['moment']['NP2']['rake'] == 164.0 origin = Origin.fromFile(eventfile, momentfile=xmlfile) assert origin.mag == 7.9 assert origin.lat == 56.046 assert origin.lon == -149.073 assert origin.id == 'us2000cmy3' except Exception: assert False finally: shutil.rmtree(tempdir)
def test_get_extent_aspect(): # # Test ruptures with weird aspect ratios # eventfile = os.path.join(datadir, 'event_wenchuan.xml') origin = Origin.fromFile(eventfile) # # Long horizontal rupture # rrep = io.StringIO( """ 30.0 100.0 0.0 30.0 110.0 0.0 30.0 110.0 5.0 30.0 100.0 5.0 30.0 100.0 0.0 """ ) rupture = get_rupture(origin, rrep) W, E, S, N = get_extent(rupture) assert W == 97.18333333333334 assert E == 113.51666666666667 assert S == 25.616666666666667 assert N == 34.06666666666666 # # Long vertical rupture # rrep = io.StringIO( """ 24.0 100.0 0.0 36.0 100.0 0.0 36.0 100.0 5.0 24.0 100.0 5.0 24.0 100.0 0.0 """ ) rupture = get_rupture(origin, rrep) W, E, S, N = get_extent(rupture) assert W == 92.53333333333333 assert E == 108.89999999999999 assert S == 21.03333333333333 assert N == 38.46666666666667
def test_get_extent_aspect(): # # Test ruptures with weird aspect ratios # eventfile = os.path.join(datadir, 'event_wenchuan.xml') origin = Origin.fromFile(eventfile) # # Long horizontal rupture # rrep = io.StringIO( """ 100.0 30.0 0.0 110.0 30.0 0.0 110.0 30.0 5.0 100.0 30.0 5.0 100.0 30.0 0.0 """ ) rupture = get_rupture(origin, rrep) W, E, S, N = get_extent(rupture) assert W == 97.18333333333334 assert E == 113.51666666666667 assert S == 25.616666666666667 assert N == 34.06666666666666 # # Long vertical rupture # rrep = io.StringIO( """ 100.0 24.0 0.0 100.0 36.0 0.0 100.0 36.0 5.0 100.0 24.0 5.0 100.0 24.0 0.0 """ ) rupture = get_rupture(origin, rrep) W, E, S, N = get_extent(rupture) assert W == 92.53333333333333 assert E == 108.89999999999999 assert S == 21.03333333333333 assert N == 38.46666666666667
def test_get_extent_aspect(): # # Test ruptures with weird aspect ratios # eventfile = os.path.join(datadir, 'event_wenchuan.xml') origin = Origin.fromFile(eventfile) # # Long horizontal rupture # rrep = io.StringIO( """ 100.0 30.0 0.0 110.0 30.0 0.0 110.0 30.0 5.0 100.0 30.0 5.0 100.0 30.0 0.0 """ ) rupture = get_rupture(origin, rrep) W, E, S, N = get_extent(rupture) np.testing.assert_allclose(W, 92.65) np.testing.assert_allclose(E, 119.98333333333333) np.testing.assert_allclose(S, 19.833333333333332) np.testing.assert_allclose(N, 38.96666666666667) # # Long vertical rupture # rrep = io.StringIO( """ 100.0 24.0 0.0 100.0 36.0 0.0 100.0 36.0 5.0 100.0 24.0 5.0 100.0 24.0 0.0 """ ) rupture = get_rupture(origin, rrep) W, E, S, N = get_extent(rupture) np.testing.assert_allclose(W, 88.48333333333333) np.testing.assert_allclose(E, 115.08333333333333) np.testing.assert_allclose(S, 16.1) np.testing.assert_allclose(N, 42.583333333333336)
def createFromInput(cls, filename, config, eventfile, version_history, rupturefile=None, sourcefile=None, momentfile=None, datafiles=None): """ Instantiate an InputContainer from ShakeMap input data. Args: filename (str): Path to HDF5 file that will be created to encapsulate all input data. config (dict): Dictionary containing all configuration information necessary for ShakeMap ground motion and other calculations. eventfile (str): Path to ShakeMap event.xml file. rupturefile (str): Path to ShakeMap rupture text or JSON file. sourcefile (str): Path to ShakeMap source.txt file. momentfile (str): Path to ShakeMap moment.xml file. datafiles (list): List of ShakeMap data (DYFI, strong motion) files. version_history (dict): Dictionary containing version history. Returns: InputContainer: Instance of InputContainer. """ container = cls.create(filename) container.setConfig(config) # create an origin from the event file origin = Origin.fromFile(eventfile, sourcefile=sourcefile, momentfile=momentfile) # create a rupture object from the origin and the rupture file # (if present). rupture = get_rupture(origin, file=rupturefile) # store the rupture object in the container container.setRupture(rupture) if datafiles is not None and len(datafiles) > 0: container.setStationData(datafiles) container.setVersionHistory(version_history) return container
def createFromInput(cls, filename, config, eventfile, version_history, rupturefile=None, datafiles=None): """ Instantiate an InputContainer from ShakeMap input data. Args: filename (str): Path to HDF5 file that will be created to encapsulate all input data. config (dict): Dictionary containing all configuration information necessary for ShakeMap ground motion and other calculations. eventfile (str): Path to ShakeMap event.xml file. rupturefile (str): Path to ShakeMap rupture text or JSON file. datafiles (list): List of ShakeMap data (DYFI, strong motion) files. version_history (dict): Dictionary containing version history. Returns: InputContainer: Instance of InputContainer. """ container = cls.create(filename) container.setConfig(config) # create an origin from the event file origin = Origin.fromFile(eventfile) # create a rupture object from the origin and the rupture file # (if present). rupture = get_rupture(origin,file=rupturefile) # store the rupture object in the container container.setRupture(rupture) if datafiles is not None: container.setStationData(datafiles) container.setVersionHistory(version_history) return container
def test_origin(): fault_text = """30.979788 103.454422 1 31.691615 104.419160 1 31.723569 104.374760 1 32.532213 105.220821 1 32.641450 105.135050 20 31.846790 104.246202 20 31.942158 104.205286 20 31.290105 103.284388 20 30.979788 103.454422 1""" event_text = """<?xml version="1.0" encoding="US-ASCII" standalone="yes"?> <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="" />""" source_text = "mech=RS" ffile = io.StringIO(fault_text) # noqa efile = io.StringIO(event_text) sfile = io.StringIO(source_text) origin = Origin.fromFile(efile, sourcefile=sfile) testdict = {'mag': 7.9, 'eventsourcecode': 'us2008ryan', 'locstring': 'EASTERN SICHUAN, CHINA', 'mech': 'RS', 'lon': 103.3639, 'lat': 30.9858, 'depth': 19.0} for key in testdict.keys(): value = eval('origin.%s' % key) if type(value) is str: assert testdict[key] == value if type(value) is float: np.testing.assert_almost_equal(testdict[key], value) assert origin.mech == "RS" origin.setMechanism("SS") assert origin.mech == "SS" origin.setMechanism("SS", rake=10) assert origin.mech == "SS" assert origin.rake == 10.0 assert origin.dip == 90.0 origin.setMechanism("SS", rake=-350) assert origin.rake == 10.0 origin.setMechanism("SS", rake=370) assert origin.rake == 10.0 with pytest.raises(Exception) as a: origin.setMechanism("SS", dip=100) with pytest.raises(Exception) as a: origin.setMechanism("Strike slip") # Rake too large with pytest.raises(Exception) as a: origin.setMechanism("SS", rake=1111) # Lat is greater than 90 with pytest.raises(Exception) as a: event_text = """<?xml version="1.0" encoding="US-ASCII" standalone="yes"?> <earthquake id="2008" lat="91.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="" />""" efile = io.StringIO(event_text) origin = Origin.fromFile(efile) # Lon is greater than 180 with pytest.raises(Exception) as a: event_text = """<?xml version="1.0" encoding="US-ASCII" standalone="yes"?> <earthquake id="2008" lat="31.9858" lon="183.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="" />""" efile = io.StringIO(event_text) origin = Origin.fromFile(efile) # No event id with pytest.raises(Exception) as a: event_text = """<?xml version="1.0" encoding="US-ASCII" standalone="yes"?> <earthquake 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="" />""" efile = io.StringIO(event_text) origin = Origin.fromFile(efile) # Put mech in event keys event_text = """<?xml version="1.0" encoding="US-ASCII" standalone="yes"?> <earthquake id="2008" 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="" mech="SS"/>""" efile = io.StringIO(event_text) origin = Origin.fromFile(efile) assert origin.mech == 'SS' # Empty mech event_text = """<?xml version="1.0" encoding="US-ASCII" standalone="yes"?> <earthquake id="2008" 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="" mech=""/>""" efile = io.StringIO(event_text) origin = Origin.fromFile(efile) assert origin.mech == 'ALL' # Mech not acceptable value with pytest.raises(Exception) as a: # noqa event_text = """<?xml version="1.0" encoding="US-ASCII" standalone="yes"?> <earthquake id="2008" lat="31.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="" mech="Strike slip"/>""" efile = io.StringIO(event_text) origin = Origin.fromFile(efile)
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 execute(self): ''' Parses the output of STREC in accordance with the configuration file, creates a new GMPE set specific to the event, and writes model_zc.conf in the event's 'current' directory. Configuration file: select.conf Raises: NotADirectoryError -- the event's current directory doesn't exist FileNotFoundError -- the event.xml file doesn't exist ValidateError -- problems with the configuration file RuntimeError -- various problems matching the event to a gmpe set ''' # --------------------------------------------------------------------- # Get the install and data paths and verify that the even directory # exists # --------------------------------------------------------------------- install_path, data_path = cfg.get_config_paths() datadir = os.path.join(data_path, self._eventid, 'current') if not os.path.isdir(datadir): raise NotADirectoryError('%s is not a valid directory' % datadir) # --------------------------------------------------------------------- # Open event.xml and make an Origin object # --------------------------------------------------------------------- eventxml = os.path.join(datadir, 'event.xml') if not os.path.isfile(eventxml): raise FileNotFoundError('%s does not exist.' % eventxml) org = Origin.fromFile(eventxml) # # Clear away results from previous runs # products_path = os.path.join(datadir, 'products') if os.path.isdir(products_path): shutil.rmtree(products_path, ignore_errors=True) # --------------------------------------------------------------------- # Get config file from install_path/config, parse and # validate it # --------------------------------------------------------------------- config = ConfigObj(os.path.join(install_path, 'config', 'select.conf')) validate_config(config, install_path) # --------------------------------------------------------------------- # Get the strec results # --------------------------------------------------------------------- strec_out = get_tectonic_regions(org.lon, org.lat, org.depth, self._eventid) # --------------------------------------------------------------------- # Get the default weighting for this event # --------------------------------------------------------------------- cfg_tr = config['tectonic_regions'] str_tr = strec_out['tectonic_regions'] gmpe_list, weight_list = get_gmpes_by_region(str_tr, cfg_tr, org) # --------------------------------------------------------------------- # Now look at the geographic layers to see if we need to modify or # replace the gmpe list # --------------------------------------------------------------------- # # Find the first configured layer the event is within (if any) or the # closest layer # min_dist_to_layer = 999999.9 nearest_layer_name = None if 'layers' in config and 'layer_dir' in config['layers']: layer_dir = config['layers']['layer_dir'] if layer_dir and layer_dir != 'None': geo_layers = get_layer_distances(org.lon, org.lat, layer_dir) else: geo_layers = {} for layer in config['layers']: if layer == 'layer_dir': continue if layer not in geo_layers: self.logger.warning('Error: cannot find layer %s in %s' % (layer, layer_dir)) continue ldist = geo_layers[layer] if ldist < min_dist_to_layer: min_dist_to_layer = ldist nearest_layer_name = layer if min_dist_to_layer == 0: break # # If we are in or near a geographic layer, update the gmpe and weight # lists # if nearest_layer_name is not None and \ (min_dist_to_layer == 0 or min_dist_to_layer <= config['layers'][nearest_layer_name]['horizontal_buffer']): lcfg = config['layers'][nearest_layer_name] # # Overwrite the tectonic regions with the layer's custom region # settings # for thing in lcfg: if thing == 'horizontal_buffer': layer_buff = lcfg[thing] continue layer = thing for element in lcfg[layer]: cfg_tr[layer][element] = lcfg[layer][element] # # Now get the gmpes and weights for the custom layer # layer_gmpes, layer_weights = get_gmpes_by_region( str_tr, cfg_tr, org) if layer_buff == 0: # # If we're here, min_dist_to_layer must be 0, # so the weight is 1 # lwgt = 1.0 else: lwgt = 1.0 - min_dist_to_layer / layer_buff # # If we're inside the region's boundaries, we just use the custom # gmpe and weights. If we are outside the region (but still inside # the buffer), we blend the custom gmpe and weights with the # generic ones we computed earlier. # if min_dist_to_layer == 0: gmpe_list = layer_gmpes weight_list = layer_weights else: gmpe_list = np.append(gmpe_list, layer_gmpes) weight_list = np.append(weight_list * (1.0 - lwgt), layer_weights * lwgt) # --------------------------------------------------------------------- # Create ConfigObj object for output to model_zc.conf # --------------------------------------------------------------------- zc_file = os.path.join(datadir, 'model_zc.conf') zc_conf = ConfigObj(indent_type=' ') zc_conf.filename = zc_file # # Add the new gmpe set to the object # gmpe_set = 'gmpe_' + str(self._eventid) + '_custom' zc_conf['gmpe_sets'] = OrderedDict([ (gmpe_set, OrderedDict([ ('gmpes', list(gmpe_list)), ('weights', list(weight_list)), ('weights_larage_dist', 'None'), ('dist_cutoff', 'nan'), ('site_gmpes', 'None'), ('weights_site_gmpes', 'None') ])) ]) # # Set gmpe to use the new gmpe set # zc_conf['modeling'] = OrderedDict([ ('gmpe', gmpe_set), ('mechanism', strec_out['focal_mech']) ]) zc_conf.write()