Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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': 0,  'lon': 0, 'depth': 0, 'mag': 7.2, 'eventsourcecode': ''})
    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)
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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 parse_json_nshmp_sub(rupts, args):
    """
    This is an alternative version of parse_json to use with the Cascadia
    subduction zone JSON rupture file.

    Args:
        rupts (dict): Python translation of rupture json file using json.load
            method.
        args (ArgumentParser): argparse object.

    Returns:
        dict: Dictionary of rupture information.

    """
    rlist = []
    nrup = len(rupts['events'])

    if args.index is not None:
        iter = args.index
        iter = map(int, iter)
    else:
        iter = range(nrup)

    for i in iter:
        event_name = rupts['events'][i]['desc']
        short_name = event_name.split('.xls')[0]
        id = rupts['events'][i]['id']
        magnitude = rupts['events'][i]['mag']
        if 'rake' in rupts['events'][i].keys():
            rake = rupts['events'][i]['rake']
        else:
            rake = None

        toplons = np.array(rupts['events'][i]['toplons'])
        toplats = np.array(rupts['events'][i]['toplats'])
        topdeps = np.array(rupts['events'][i]['topdeps'])
        botlons = np.array(rupts['events'][i]['botlons'])
        botlats = np.array(rupts['events'][i]['botlats'])
        botdeps = np.array(rupts['events'][i]['botdeps'])

        # Dummy origin
        origin = Origin({'mag': 0, 'id': '', 'lat': 0, 'lon': 0, 'depth': 0})

        rupt = EdgeRupture.fromArrays(toplons=toplons,
                                      toplats=toplats,
                                      topdeps=topdeps,
                                      botlons=botlons,
                                      botlats=botlats,
                                      botdeps=botdeps,
                                      origin=origin,
                                      reference=args.reference)
        rupt._segment_index = np.zeros_like(toplons)

        quads = rupt.getQuadrilaterals()
        edges = get_rupture_edges(quads)  # for hypo placement
        hlat, hlon, hdepth = get_hypo(edges, args)

        id_str, eventsourcecode, real_desc = get_event_id(event_name,
                                                          magnitude,
                                                          args.directivity,
                                                          args.dirind,
                                                          quads,
                                                          id=id)

        event = {
            'lat': hlat,
            'lon': hlon,
            'depth': hdepth,
            'mag': magnitude,
            'rake': rake,
            'id': id_str,
            'locstring': event_name,
            'type': 'ALL',  # overwrite later
            'timezone': 'UTC'
        }
        event['time'] = ShakeDateTime.utcfromtimestamp(int(time.time()))
        event['created'] = ShakeDateTime.utcfromtimestamp(int(time.time()))

        # Update rupture with new origin info
        if rupt is not None:
            origin = Origin(event)
            rupt = EdgeRupture.fromArrays(toplons=toplons,
                                          toplats=toplats,
                                          topdeps=topdeps,
                                          botlons=botlons,
                                          botlats=botlats,
                                          botdeps=botdeps,
                                          origin=origin,
                                          reference=args.reference)

        rdict = {
            'rupture': rupt,
            'event': event,
            'edges': edges,
            'id_str': id_str,
            'short_name': short_name,
            'real_desc': real_desc,
            'eventsourcecode': eventsourcecode
        }
        rlist.append(rdict)

    return rlist
Ejemplo n.º 8
0
def test_EdgeRupture():
    # Rupture requires an origin even when not used:
    origin = Origin({'eventsourcecode': 'test', 'lat': 0, 'lon': 0,
                     'depth': 5.0, 'mag': 7.0})

    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)
    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)
    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)
    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)