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 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 rupture_from_dict_and_origin(rupdict, origin, mesh_dx=0.5): """ Method returns either a QuadRupture or EdgeRupture object based on a GeoJSON dictionary and an origin. Note that this is very similar to :func:`rupture_from_dict`, except that method is for constructing the rupture objects from a dict that already contains the origin info in the `metadata` field (e.g., from a dict from a Shakemap container), while this method is for construction of the rupture objects from a GeoJSON dict that does not yet include that information (e.g., from a dict that is read in to initially create the shakemap container, along with an Origin that is derived from `event.xml`). .. seealso:: :func:`rupture_from_dict` Args: rupdictd (dict): Rupture GeoJSON dictionary. origin (Origin): A ShakeMap origin object. mesh_dx (float): Target spacing (in km) for rupture discretization; default is 0.5 km and it is only used if the rupture file is an EdgeRupture. Returns: a Rupture subclass. """ validate_json(rupdict) # Is this a QuadRupture or an EdgeRupture? valid_quads = is_quadrupture_class(rupdict) if valid_quads is True: rupt = QuadRupture(rupdict, origin) else: if rupdict['features'][0]['geometry']['type'] == 'Point': rupt = PointRupture(origin) else: rupt = EdgeRupture(rupdict, origin, mesh_dx=mesh_dx) return rupt
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)