Esempio n. 1
0
 def test_create_oqhazardlib_source(self):
     # Tests to ensure the hazardlib source is created
     trace = line.Line([point.Point(10., 10.), point.Point(11., 10.)])
     mfd1 = TruncatedGRMFD(5.0, 8.0, 0.1, 3.0, 1.0)
     self.fault_source = mtkSimpleFaultSource(
         '001',
         'A Fault Source',
         trt='Active Shallow Crust',
         geometry=None,
         dip=90.,
         upper_depth=0.,
         lower_depth=20.,
         mag_scale_rel=None,
         rupt_aspect_ratio=1.0,
         mfd=mfd1,
         rake=0.)
     self.fault_source.create_geometry(trace, 90., 0., 20., 1.0)
     test_source = self.fault_source.create_oqhazardlib_source(TOM,
                                                               2.0,
                                                               True)
     self.assertIsInstance(test_source, SimpleFaultSource)
     self.assertIsInstance(test_source.mfd, TruncatedGRMFD)
     self.assertAlmostEqual(test_source.mfd.b_val, 1.0)
     self.assertIsInstance(test_source.magnitude_scaling_relationship,
                           WC1994)
Esempio n. 2
0
 def test_create_oqhazardlib_complex_fault_source(self):
     """
     Tests the conversion of a point source to an instance of the :class:
     openquake.hazardlib.source.complex_fault.ComplexFaultSource
     """
     complex_edges = [
         line.Line([point.Point(11., 10., 0.),
                    point.Point(10., 10., 0.)]),
         line.Line(
             [point.Point(11.5, 10., 21.),
              point.Point(10.0, 10., 21.)])
     ]
     self.fault_source = mtkComplexFaultSource('001',
                                               'A Fault Source',
                                               trt='Active Shallow Crust',
                                               geometry=None,
                                               mag_scale_rel=None,
                                               rupt_aspect_ratio=1.0,
                                               mfd=models.TGRMFD(
                                                   a_val=3.,
                                                   b_val=1.0,
                                                   min_mag=5.0,
                                                   max_mag=8.0),
                                               rake=0.)
     self.fault_source.create_geometry(complex_edges, 2.0)
     test_source = self.fault_source.create_oqhazardlib_source(
         TOM, 5.0, True)
     self.assertIsInstance(test_source, ComplexFaultSource)
     self.assertIsInstance(test_source.mfd, TruncatedGRMFD)
     self.assertAlmostEqual(test_source.mfd.b_val, 1.0)
     self.assertIsInstance(test_source.magnitude_scaling_relationship,
                           WC1994)
Esempio n. 3
0
 def test_create_oqhazardlib_source(self):
     # Define a complete source
     area_geom = polygon.Polygon([
         point.Point(10., 10.),
         point.Point(12., 10.),
         point.Point(12., 8.),
         point.Point(10., 8.)
     ])
     mfd1 = TruncatedGRMFD(5.0, 8.0, 0.1, 3.0, 1.0)
     self.area_source = mtkAreaSource('001',
                                      'A Point Source',
                                      trt='Active Shallow Crust',
                                      geometry=area_geom,
                                      upper_depth=0.,
                                      lower_depth=20.,
                                      mag_scale_rel=None,
                                      rupt_aspect_ratio=1.0,
                                      mfd=mfd1,
                                      nodal_plane_dist=None,
                                      hypo_depth_dist=None)
     test_source = self.area_source.create_oqhazardlib_source(
         TOM, 1.0, 10.0, True)
     self.assertIsInstance(test_source, AreaSource)
     self.assertIsInstance(test_source.mfd, TruncatedGRMFD)
     self.assertAlmostEqual(test_source.mfd.b_val, 1.0)
     self.assertIsInstance(test_source.nodal_plane_distribution, PMF)
     self.assertIsInstance(test_source.hypocenter_distribution, PMF)
     self.assertIsInstance(test_source.magnitude_scaling_relationship,
                           WC1994)
Esempio n. 4
0
def calc_ry0_distance(P0, P1, lat, lon, dep):
    """Calculate Ry0 distance.

    Compute the minimum distance between sites (lat, lon, dep) and the great
    circle arcs perpendicular to the average strike direction of the
    fault trace and passing through the end-points of the trace.
    
    :param P0:
      Point object, representing the first top-edge vertex of a fault quadrilateral.
    :param P1:
      Point object, representing the second top-edge vertex of a fault quadrilateral.
    :param lat: 
      Numpy array of latitude. 
    :param lon: 
      Numpy array of longitude. 
    :param dep: 
      Numpy array of depths (km). 
    :returns:
      Array of size lon.shape of distances (in km) from input points to rupture surface.
    """

    # Strike
    surfaceP0 = point.Point(P0.longitude, P0.latitude, 0.0)
    surfaceP1 = point.Point(P1.longitude, P1.latitude, 0.0)
    strike = P0.azimuth(P1)
    dst1 = geodetic.distance_to_arc(P0.longitude, P0.latitude,
                                    (strike + 90.) % 360, lon, lat)
    dst2 = geodetic.distance_to_arc(P1.longitude, P1.latitude,
                                    (strike + 90.) % 360, lon, lat)
    # Get the shortest distance from the two lines
    idx = np.sign(dst1) == np.sign(dst2)
    dst = np.zeros_like(dst1)
    dst[idx] = np.fmin(np.abs(dst1[idx]), np.abs(dst2[idx]))
    return dst
Esempio n. 5
0
def get_top_edge(lat, lon, dep):
    """
    Determine which edge of a quadrilateral rupture surface is the top.
    :param lat: 
        Sequence of 4 or 5 latitudes defining vertices of rupture surface.
    :param lon: 
        Sequence of 4 or 5 longitudes defining vertices of rupture surface.
    :param dep: 
        Sequence of 4 or 5 depths defining vertices of rupture surface.
    :returns:
        (P0,P1) where P0 and P1 are Vector objects in ECEF coordinates indicating 
        the vertices of the top edge.
    """
    lat = np.array(lat)
    lon = np.array(lon)
    dep = np.array(dep)
    p1 = None
    p2 = None
    if sum(np.diff(dep)) == 0:
        p1 = Vector.fromPoint(point.Point(lon[0], lat[0], dep[0]))
        p2 = Vector.fromPoint(point.Point(lon[1], lat[1], dep[1]))
    else:
        dep2 = dep[0:4]
        dd = np.diff(dep2)
        idx = dd == 0
        idx = np.append(idx, False)
        p1idx = dep2[idx].argmin() + 1
        p2idx = p1idx + 1
        p1 = Vector.fromPoint(point.Point(lon[p1idx], lat[p1idx], 0.0))
        p2 = Vector.fromPoint(point.Point(lon[p2idx], lat[p2idx], 0.0))
    return (p1, p2)
Esempio n. 6
0
    def test_select_within_fault_distance(self):
        # Tests the selection of events within a distance from the fault
        # Set up catalouge
        self.catalogue = Catalogue()
        self.catalogue.data['longitude'] = np.arange(0., 5.5, 0.5)
        self.catalogue.data['latitude'] = np.arange(0., 5.5, 0.5)
        self.catalogue.data['depth'] = np.zeros(11, dtype=float)
        self.catalogue.data['eventID'] = np.arange(0, 11, 1)
        self.fault_source = mtkSimpleFaultSource('101', 'A simple fault')
        trace_as_line = line.Line([point.Point(2.0, 3.0),
                                   point.Point(3.0, 2.0)])
        self.fault_source.create_geometry(trace_as_line, 30., 0., 30.)
        selector0 = CatalogueSelector(self.catalogue)

        # Test 1 - simple case Joyner-Boore distance
        self.fault_source.select_catalogue(selector0, 40.)
        np.testing.assert_array_almost_equal(
            np.array([2., 2.5]),
            self.fault_source.catalogue.data['longitude'])
        np.testing.assert_array_almost_equal(
            np.array([2., 2.5]),
            self.fault_source.catalogue.data['latitude'])

        # Test 2 - simple case Rupture distance
        self.fault_source.catalogue = None
        self.fault_source.select_catalogue(selector0, 40., 'rupture')
        np.testing.assert_array_almost_equal(
            np.array([2.5]),
            self.fault_source.catalogue.data['longitude'])
        np.testing.assert_array_almost_equal(
            np.array([2.5]),
            self.fault_source.catalogue.data['latitude'])

        # Test 3 - for vertical fault ensure that Joyner-Boore distance
        # behaviour is the same as for rupture distance
        fault1 = mtkSimpleFaultSource('102', 'A vertical fault')
        fault1.create_geometry(trace_as_line, 90., 0., 30.)
        self.fault_source.create_geometry(trace_as_line, 90., 0., 30.)

        # Joyner-Boore
        self.fault_source.select_catalogue(selector0, 40.)
        # Rupture
        fault1.select_catalogue(selector0, 40., 'rupture')
        np.testing.assert_array_almost_equal(
            self.fault_source.catalogue.data['longitude'],
            fault1.catalogue.data['longitude'])
        np.testing.assert_array_almost_equal(
            self.fault_source.catalogue.data['latitude'],
            fault1.catalogue.data['latitude'])

        # The usual test to ensure error is raised when no events in catalogue
        self.catalogue = Catalogue()
        selector0 = CatalogueSelector(self.catalogue)
        with self.assertRaises(ValueError) as ver:
            self.fault_source.select_catalogue(selector0, 40.0)
        self.assertEqual(str(ver.exception),
                         'No events found in catalogue!')
Esempio n. 7
0
    def test_geometry_inputs(self):
        # Tests the geometry definition
        simple_polygon = polygon.Polygon([point.Point(2.0, 3.0),
                                          point.Point(3.0, 3.0),
                                          point.Point(3.0, 2.0),
                                          point.Point(2.0, 2.0)])

        simple_polygon_array = np.array([[2.0, 3.0],
                                         [3.0, 3.0],
                                         [3.0, 2.0],
                                         [2.0, 2.0]])
        # Using nhlib.geo.polygon.Polygon class as input
        self.area_source.create_geometry(simple_polygon, 0.0, 30.0)
        # Check that geometry is an instance of nhlib.geo.polygon.Polygon
        self.assertTrue(isinstance(self.area_source.geometry,
                                   polygon.Polygon))

        np.testing.assert_array_almost_equal(self.area_source.geometry.lons,
                                             np.array([2., 3., 3., 2.]))
        np.testing.assert_array_almost_equal(self.area_source.geometry.lats,
                                             np.array([3., 3., 2., 2.]))
        self.assertAlmostEqual(0.0, self.area_source.upper_depth)
        self.assertAlmostEqual(30.0, self.area_source.lower_depth)

        self.area_source = mtkAreaSource('101', 'A Source')
        # Using numpy array as input
        self.area_source.create_geometry(simple_polygon_array, 0.0, 30.0)
        self.assertTrue(isinstance(self.area_source.geometry,
                                   polygon.Polygon))

        # Check that geometry is an instance of nhlib.geo.polygon.Polygon
        np.testing.assert_array_almost_equal(self.area_source.geometry.lons,
                                             np.array([2., 3., 3., 2.]))
        np.testing.assert_array_almost_equal(self.area_source.geometry.lats,
                                             np.array([3., 3., 2., 2.]))

        self.assertAlmostEqual(0.0, self.area_source.upper_depth)
        self.assertAlmostEqual(30.0, self.area_source.lower_depth)

        # For any other input type - check ValueError is raised
        self.area_source = mtkAreaSource('101', 'A Source')
        with self.assertRaises(ValueError) as ver:
            self.area_source.create_geometry('a bad input', 0.0, 30.0)
        self.assertEqual(str(ver.exception),
                         'Unrecognised or unsupported geometry definition')

        # For numpy array with only two rows
        self.area_source = mtkAreaSource('101', 'A Source')
        simple_polygon_array = np.array([[2.0, 3.0],
                                         [3.0, 3.0]])
        with self.assertRaises(ValueError) as ver:
            self.area_source.create_geometry(simple_polygon_array, 0.0, 30.0)
        self.assertEqual(str(ver.exception),
                         'Incorrectly formatted polygon geometry - '
                         'needs three or more vertices')
Esempio n. 8
0
    def test_select_events_in_source(self):
        '''
        Basic test of method to select events from catalogue in polygon
        '''
        self.area_source = mtkAreaSource('101', 'A Source')
        simple_polygon = polygon.Polygon([
            point.Point(2.0, 3.0),
            point.Point(3.0, 3.0),
            point.Point(3.0, 2.0),
            point.Point(2.0, 2.0)
        ])

        self.catalogue.data['eventID'] = np.arange(0, 7, 1)
        self.catalogue.data['longitude'] = np.arange(1.0, 4.5, 0.5)
        self.catalogue.data['latitude'] = np.arange(1.0, 4.5, 0.5)
        self.catalogue.data['depth'] = np.ones(7, dtype=float)
        # Simple Case - No buffer
        selector0 = CatalogueSelector(self.catalogue)
        self.area_source.create_geometry(simple_polygon, 0., 30.)
        self.area_source.select_catalogue(selector0, 0.)
        np.testing.assert_array_almost_equal(
            np.array([2., 2.5, 3.]),
            self.area_source.catalogue.data['longitude'])

        np.testing.assert_array_almost_equal(
            np.array([2., 2.5, 3.]),
            self.area_source.catalogue.data['latitude'])

        np.testing.assert_array_almost_equal(
            np.array([1., 1., 1.]), self.area_source.catalogue.data['depth'])

        # Simple case - dilated by 200 km (selects all)
        self.area_source.select_catalogue(selector0, 200.)
        np.testing.assert_array_almost_equal(
            np.array([1., 1.5, 2., 2.5, 3., 3.5, 4.0]),
            self.area_source.catalogue.data['longitude'])

        np.testing.assert_array_almost_equal(
            np.array([1., 1.5, 2., 2.5, 3., 3.5, 4.0]),
            self.area_source.catalogue.data['latitude'])

        np.testing.assert_array_almost_equal(
            np.ones(7, dtype=float), self.area_source.catalogue.data['depth'])

        # Bad case - no events in catalogue
        self.catalogue = Catalogue()
        selector0 = CatalogueSelector(self.catalogue)

        with self.assertRaises(ValueError) as ver:
            self.area_source.select_catalogue(selector0, 0.0)
            self.assertEqual(ver.exception.message,
                             'No events found in catalogue!')
Esempio n. 9
0
 def setUp(self):
     warnings.simplefilter("ignore")
     self.catalogue = Catalogue()
     self.fault_source = None
     self.trace_line = [line.Line([point.Point(1.0, 0.0, 1.0),
                                   point.Point(0.0, 1.0, 0.9)])]
     self.trace_line.append(line.Line([point.Point(1.2, 0.0, 40.),
                                       point.Point(1.0, 1.0, 45.),
                                       point.Point(0.0, 1.3, 42.)]))
     self.trace_array = [np.array([[1.0, 0.0, 1.0], [0.0, 1.0, 0.9]])]
     self.trace_array.append(np.array([[1.2, 0.0, 40.],
                                       [1.0, 1.0, 45.],
                                       [0.0, 1.3, 42.]]))
Esempio n. 10
0
    def test_create_oqnmrl_simple_fault_source(self):
        '''
        Tests the conversion of a point source to an instance of the :class:
        oqnrmllib.models.SimpleFaultSource 
        '''
        trace = line.Line([point.Point(10., 10.), point.Point(11., 10.)])
        #sflt_geom = SimpleFaultSurface.from_fault_data(trace, 0., 20., 90., 1.)

        # Define a complete source
        self.fault_source = mtkSimpleFaultSource('001',
                                                 'A Fault Source',
                                                 trt='Active Shallow Crust',
                                                 geometry=None,
                                                 dip=90.,
                                                 upper_depth=0.,
                                                 lower_depth=20.,
                                                 mag_scale_rel=None,
                                                 rupt_aspect_ratio=1.0,
                                                 mfd=models.TGRMFD(
                                                     a_val=3.,
                                                     b_val=1.0,
                                                     min_mag=5.0,
                                                     max_mag=8.0),
                                                 rake=0.)
        self.fault_source.create_geometry(trace, 90., 0., 20., 1.0)

        expected_geometry = models.SimpleFaultGeometry(
            wkt='LINESTRING (10.0 10.0, 11.0 10.0)',
            dip=90.,
            upper_seismo_depth=0.,
            lower_seismo_depth=20.)
        expected_source = models.SimpleFaultSource('001',
                                                   'A Fault Source',
                                                   trt='Active Shallow Crust',
                                                   geometry=expected_geometry,
                                                   mag_scale_rel='WC1994',
                                                   rupt_aspect_ratio=1.0,
                                                   mfd=models.TGRMFD(
                                                       a_val=3.,
                                                       b_val=1.0,
                                                       min_mag=5.0,
                                                       max_mag=8.0),
                                                   rake=0.)
        test_source = self.fault_source.create_oqnrml_source(use_defaults=True)
        self.assertTrue(isinstance(test_source, models.SimpleFaultSource))
        self.assertEqual(test_source.id, expected_source.id)
        self.assertEqual(test_source.name, expected_source.name)
        self.assertDictEqual(test_source.geometry.__dict__,
                             expected_source.geometry.__dict__)
        self.assertAlmostEqual(test_source.mfd.b_val,
                               expected_source.mfd.b_val)
Esempio n. 11
0
    def test_create_oqnmrl_complex_fault_source(self):
        '''
        Tests the conversion of a point source to an instance of the :class:
        oqnrmllib.models.AreaSource 
        '''
        # Define a complete source
        complex_edges = [
            line.Line([point.Point(10., 10., 0.),
                       point.Point(11., 10., 0.)]),
            line.Line(
                [point.Point(10., 10., 20.),
                 point.Point(11.5, 10., 21.)])
        ]
        self.fault_source = mtkComplexFaultSource('001',
                                                  'A Fault Source',
                                                  trt='Active Shallow Crust',
                                                  geometry=None,
                                                  mag_scale_rel=None,
                                                  rupt_aspect_ratio=1.0,
                                                  mfd=models.TGRMFD(
                                                      a_val=3.,
                                                      b_val=1.0,
                                                      min_mag=5.0,
                                                      max_mag=8.0),
                                                  rake=0.)
        self.fault_source.create_geometry(complex_edges, 2.0)

        expected_geometry = models.ComplexFaultGeometry(
            top_edge_wkt='LINESTRING (10.0 10.0 0.0, 11.0 10.0 0.0)',
            bottom_edge_wkt='LINESTRING (10.0 10.0 20.0, 11.5 10.0 21.0)')

        expected_source = models.ComplexFaultSource('001',
                                                    'A Fault Source',
                                                    trt='Active Shallow Crust',
                                                    geometry=expected_geometry,
                                                    mag_scale_rel='WC1994',
                                                    rupt_aspect_ratio=1.0,
                                                    mfd=models.TGRMFD(
                                                        a_val=3.,
                                                        b_val=1.0,
                                                        min_mag=5.0,
                                                        max_mag=8.0),
                                                    rake=90.)

        test_source = self.fault_source.create_oqnrml_source(use_defaults=True)
        self.assertTrue(isinstance(test_source, models.ComplexFaultSource))
        self.assertEqual(test_source.id, expected_source.id)
        self.assertEqual(test_source.name, expected_source.name)
        self.assertAlmostEqual(test_source.mfd.b_val,
                               expected_source.mfd.b_val)
Esempio n. 12
0
 def toPoint(self):
     """
     Convert the Vector to a hazardlib Point object, after translating back to lat,lon,depth.
     :returns:
        a Point object as defined at https://github.com/gem/oq-hazardlib/blob/master/openquake/hazardlib/geo/point.py
     """
     lat, lon, dep = ecef2latlon(self.x, self.y, self.z)
     return point.Point(lon, lat, dep)
Esempio n. 13
0
    def test_create_oqnmrl_area_source(self):
        '''
        Tests the conversion of a point source to an instance of the :class:
        oqnrmllib.models.AreaSource
        '''
        # Define a complete source
        area_geom = polygon.Polygon([
            point.Point(10., 10.),
            point.Point(12., 10.),
            point.Point(12., 8.),
            point.Point(10., 8.)
        ])
        self.area_source = mtkAreaSource('001',
                                         'A Point Source',
                                         trt='Active Shallow Crust',
                                         geometry=area_geom,
                                         upper_depth=0.,
                                         lower_depth=20.,
                                         mag_scale_rel=None,
                                         rupt_aspect_ratio=1.0,
                                         mfd=models.TGRMFD(a_val=3.,
                                                           b_val=1.0,
                                                           min_mag=5.0,
                                                           max_mag=8.0),
                                         nodal_plane_dist=None,
                                         hypo_depth_dist=None)

        expected_source = models.AreaSource('001',
                                            'A Point Source',
                                            geometry=models.AreaGeometry(
                                                area_geom.wkt, 0., 20.),
                                            mag_scale_rel='WC1994',
                                            rupt_aspect_ratio=1.0,
                                            mfd=models.TGRMFD(a_val=3.,
                                                              b_val=1.0,
                                                              min_mag=5.0,
                                                              max_mag=8.0),
                                            nodal_plane_dist=None,
                                            hypo_depth_dist=None)
        test_source = self.area_source.create_oqnrml_source(use_defaults=True)
        self.assertTrue(isinstance(test_source, models.AreaSource))
        self.assertEqual(test_source.id, expected_source.id)
        self.assertEqual(test_source.name, expected_source.name)
        self.assertAlmostEqual(test_source.mfd.b_val,
                               expected_source.mfd.b_val)
Esempio n. 14
0
    def test_create_complex_geometry(self):
        '''
        Tests the complex geometry creation
        '''
        self.fault_source = mtkComplexFaultSource('101', 'A complex fault')
        # Test case when input as list of nhlib.geo.line.Line
        self.fault_source.create_geometry(self.trace_line, mesh_spacing=2.0)
        self.assertIsInstance(self.fault_source.geometry, ComplexFaultSurface)
        # Use the dip as a simple indicator of geometrical success!
        self.assertAlmostEqual(self.fault_source.dip, 40.5398531, 2)

        # Create a second instance
        fault2 = mtkComplexFaultSource('101', 'A complex fault')
        fault2.create_geometry(self.trace_array, mesh_spacing=2.0)
        self.assertIsInstance(fault2.geometry, ComplexFaultSurface)
        # Compare it to the first
        self.assertAlmostEqual(self.fault_source.dip, fault2.dip)

        # If less than two edges are input ensure error is raised
        bad_traces = [
            line.Line([point.Point(1.0, 0.0, 3.0),
                       point.Point(1.0, 0.0, 3.0)])
        ]

        self.fault_source = mtkComplexFaultSource('101', 'A complex fault')
        with self.assertRaises(ValueError) as ver:
            self.fault_source.create_geometry(bad_traces)
        self.assertEqual(ver.exception.message, 'Complex fault geometry '
                         'incorrectly defined')

        # If an edge is not defined from either a nhlib.geo.line.Line instance
        # or numpy.ndarray then ensure error is raised

        bad_traces = [
            line.Line([point.Point(1.0, 0.0, 3.0),
                       point.Point(1.0, 0.0, 3.0)])
        ]
        bad_traces.append('a bad input')

        self.fault_source = mtkComplexFaultSource('101', 'A complex fault')
        with self.assertRaises(ValueError) as ver:
            self.fault_source.create_geometry(bad_traces)
        self.assertEqual(ver.exception.message, 'Unrecognised or unsupported '
                         'geometry definition')
Esempio n. 15
0
 def getHypo(self):
     """
     :returns:
        Hypocenter point.
     """
     hyplat = self.getEventParam('lat')
     hyplon = self.getEventParam('lon')
     hypdepth = self.getEventParam('depth')
     hyppoint = point.Point(hyplon, hyplat, hypdepth)
     return hyppoint
    def test_create_fault_geometry(self):
        # Tests the creation of the fault geometry. Testing only behaviour
        # for creating SimpleFaultSurface classes - not the values in the
        # class (assumes nhlib implementation is correct)
        # Case 1 - trace input as instance of nhlib.geo.line.Line class
        self.fault_source = mtkSimpleFaultSource('101', 'A simple fault')
        trace_as_line = line.Line(
            [point.Point(2.0, 3.0),
             point.Point(3.0, 2.0)])
        self.fault_source.create_geometry(trace_as_line, 60., 0., 30.)
        self.assertIsInstance(self.fault_source.geometry, SimpleFaultSurface)

        # Case 2 - trace input as numpy array
        trace_as_array = np.array([[2.0, 3.0], [3.0, 2.0]])
        self.fault_source = mtkSimpleFaultSource('101', 'A simple fault')
        self.fault_source.create_geometry(trace_as_array, 60., 0., 30.)
        self.assertIsInstance(self.fault_source.geometry, SimpleFaultSurface)
        # Case 3 - raises error when something else is input
        with self.assertRaises(ValueError) as ver:
            self.fault_source.create_geometry('a bad input!', 60., 0., 30.)
        self.assertEqual(str(ver.exception),
                         'Unrecognised or unsupported geometry definition')
Esempio n. 17
0
    def _setQuadrilaterals(self):
        """
        Create internal list of N quadrilaterals.
        """
        # Fault QA rules
        # 1) Fault must consist of 1 or more quadrilaterals, where each quad
        #    top/bottom edges are parallel to the surface
        # 2) The strike angle of each quadrilateral is defined by the first two
        #    vertices of that quad
        # 3) The dip angle is defined by segments 2 and 3, or 1 and 4.  This
        #    angle must be clockwise with respect to the strike angle, and
        #    between 0 and 90 degrees.
        # 4) The top edge of each quad must be defined by the first two vertices
        #    of that quad.
        # 5) 4 points of quadrilateral must be co-planar
        self._lon = np.array(self._lon)
        self._lat = np.array(self._lat)
        self._depth = np.array(self._depth)
        inan = np.isnan(self._lon)
        numnans = len(self._lon[inan])
        numsegments = numnans + 1
        # requirements:
        # 1) Coordinate arrays must be same length
        # 2) Polygons must be quadrilaterals
        # 3) Quads must be closed
        # 4) Quads must be planar
        if len(self._lon) != len(self._lat) != len(self._depth):
            raise IndexError(
                'Length of input lon,lat,depth arrays must be equal')

        # Addition: self._segment_index
        #   It is also convenient to create a list of indexes for which 'trace'
        #   each quad is on (i.e, grouped). This information is required for GC2
        #   calculations. Also, in some rare situations, we need to be able to
        #   overwrite the default values.

        istart = 0
        endpoints = list(np.where(np.isnan(self._lon))[0])
        endpoints.append(len(self._lon))
        self._quadrilaterals = []
        self._segment_index = []
        segind = 0
        for iend in endpoints:
            lonseg = self._lon[istart:iend][0:-1]  # remove closing points
            latseg = self._lat[istart:iend][0:-1]
            depthseg = self._depth[istart:iend][0:-1]
            # each segment can have many contiguous quadrilaterals defined in it
            # separations (nans) between segments mean that segments are not
            # contiguous.
            npoints = len(lonseg)
            nquads = int((npoints - 4) / 2) + 1
            startidx = 0
            endidx = -1
            for i in range(0, nquads):
                topLeft = point.Point(lonseg[startidx], latseg[startidx],
                                      depthseg[startidx])
                topRight = point.Point(lonseg[startidx + 1],
                                       latseg[startidx + 1],
                                       depthseg[startidx + 1])
                bottomRight = point.Point(lonseg[endidx - 1],
                                          latseg[endidx - 1],
                                          depthseg[endidx - 1])
                bottomLeft = point.Point(lonseg[endidx], latseg[endidx],
                                         depthseg[endidx])
                surface = self._validateQuad(topLeft, topRight, bottomRight,
                                             bottomLeft)
                self._quadrilaterals.append(surface)
                startidx += 1
                endidx -= 1
            istart = iend + 1
            self._segment_index.extend([segind] * nquads)
            segind = segind + 1
Esempio n. 18
0
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 = geo.utils.get_orthographic_projection(-122, -120, 39, 37)
    tlon, tlat = proj(rupx, rupy, reverse=True)

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

    # 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,
        'eventsourcecode': 'so6',
        'rake': rake
    })

    ruplat = [a.latitude for a in rup.getQuadrilaterals()[0]]
    ruplon = [a.longitude for a in rup.getQuadrilaterals()[0]]
    ruplat = np.append(ruplat, ruplat[0])
    ruplon = np.append(ruplon, ruplon[0])
    rupx, rupy = proj(ruplon, ruplat, reverse=False)

    test1 = Bayless2013(origin, rup, slat, slon, sdepth, T=5)
    fd = test1.getFd()
    fd_test = np.array([
        [
            0.00000000e+00, 0.00000000e+00, 0.00000000e+00, -8.92879772e-03,
            -1.74526918e-02, -2.22981746e-02, -2.34350450e-02, -2.13620062e-02,
            -1.72712346e-02, -1.29509613e-02, -1.02545064e-02, -1.03010185e-02,
            -1.28847597e-02, -1.66274727e-02, -1.96984070e-02, -2.05377743e-02,
            -1.81831337e-02, -1.21881814e-02, -2.64862879e-03, 0.00000000e+00,
            0.00000000e+00
        ],
        [
            0.00000000e+00, 0.00000000e+00, -8.73221519e-03, -2.21421374e-02,
            -3.18438939e-02, -3.71488270e-02, -3.76239913e-02, -3.35015951e-02,
            -2.61748968e-02, -1.83864728e-02, -1.34793002e-02, -1.36687799e-02,
            -1.85727143e-02, -2.55527671e-02, -3.14227568e-02, -3.38933995e-02,
            -3.19289607e-02, -2.53396980e-02, -1.45943649e-02, -3.71405488e-04,
            0.00000000e+00
        ],
        [
            0.00000000e+00, -2.54621422e-03, -2.11428566e-02, -3.68609103e-02,
            -4.87464747e-02, -5.56539037e-02, -5.64419387e-02, -5.05331157e-02,
            -3.52919381e-02, -2.18782050e-02, -1.40858125e-02, -1.47354546e-02,
            -2.35727189e-02, -3.74838465e-02, -4.75915414e-02, -5.13000399e-02,
            -4.87882409e-02, -4.05716321e-02, -2.77368254e-02, -1.13542729e-02,
            0.00000000e+00
        ],
        [
            0.00000000e+00, -1.21642958e-02, -3.33747360e-02, -5.21661817e-02,
            -6.74724509e-02, -7.77628842e-02, -8.00243748e-02, -6.42496853e-02,
            -4.38124530e-02, -1.97027426e-02, -1.45897731e-02, -1.07427056e-02,
            -3.08235222e-02, -4.82656988e-02, -6.67692677e-02, -7.35152908e-02,
            -6.85574283e-02, -5.71811573e-02, -4.12138780e-02, -2.20396726e-02,
            -6.24121310e-04
        ],
        [
            0.00000000e+00, -2.00643401e-02, -4.39827328e-02, -6.62722434e-02,
            -8.60268414e-02, -1.01730306e-01, -9.86277741e-02, -9.82914922e-02,
            -5.22335876e-02, -1.54622435e-02, -1.57487554e-02, -3.06190808e-03,
            -4.81481586e-02, -8.92480491e-02, -8.63776477e-02, -9.98130440e-02,
            -8.95491230e-02, -7.33553695e-02, -5.34401725e-02, -3.11601812e-02,
            -7.33715103e-03
        ],
        [
            0.00000000e+00, -2.50053614e-02, -5.11695772e-02, -7.65997026e-02,
            -1.00809054e-01, -1.22877573e-01, -1.18738178e-01, -1.55236782e-01,
            -7.45388001e-02, 1.92779182e-03, -1.94380016e-02, 1.94922939e-02,
            -7.66669920e-02, -1.53909722e-01, -1.10846875e-01, -1.19746768e-01,
            -1.07680300e-01, -8.59905101e-02, -6.22042294e-02, -3.71802472e-02,
            -1.13867485e-02
        ],
        [
            0.00000000e+00, -2.63645827e-02, -5.37984901e-02, -8.11337022e-02,
            -1.08298371e-01, -1.35146441e-01, -1.34825430e-01, -1.85836050e-01,
            -1.10730875e-01, -3.18861095e-02, 4.14395701e-02, -1.52711946e-02,
            -1.31840763e-01, -1.96794707e-01, -1.33453212e-01, -1.34989129e-01,
            -1.17922385e-01, -9.21637323e-02, -6.58369237e-02, -3.91646838e-02,
            -1.22685698e-02
        ],
        [
            0.00000000e+00, -2.64622244e-02, -5.40483999e-02, -8.16190336e-02,
            -1.09162854e-01, -1.36656677e-01, -1.37081504e-01, -1.89522811e-01,
            -1.17723634e-01, -4.88765748e-02, -5.04529015e-03, -5.76414497e-02,
            -1.45712183e-01, -2.03062804e-01, -1.36859828e-01, -1.37107390e-01,
            -1.19124650e-01, -9.28263279e-02, -6.61800709e-02, -3.93088682e-02,
            -1.22842049e-02
        ],
        [
            0.00000000e+00, -2.58466495e-02, -5.24858827e-02, -7.86086164e-02,
            -1.03856343e-01, -1.27529509e-01, -1.23794779e-01, -1.68810613e-01,
            -8.22602627e-02, 1.74236964e-02, 9.38708725e-02, 4.23208284e-02,
            -8.46343723e-02, -1.70476759e-01, -1.17547884e-01, -1.24569752e-01,
            -1.11518670e-01, -8.84736806e-02, -6.38037151e-02, -3.81874381e-02,
            -1.19867610e-02
        ],
        [
            0.00000000e+00, -2.42186547e-02, -4.84175525e-02, -7.09428614e-02,
            -9.07754575e-02, -1.06117824e-01, -9.50228292e-02, -1.29781980e-01,
            -3.08573454e-02, 7.39058739e-02, 1.30478117e-01, 8.28181149e-02,
            -2.70389535e-02, -1.20837502e-01, -8.02081725e-02, -9.70274506e-02,
            -9.35853383e-02, -7.77422806e-02, -5.77817530e-02, -3.53067886e-02,
            -1.12414659e-02
        ],
        [
            0.00000000e+00, -2.16818717e-02, -4.22363856e-02, -5.96909893e-02,
            -7.24805224e-02, -7.81867829e-02, -6.11838569e-02, -9.05679744e-02,
            9.95934969e-03, 1.07503875e-01, 1.52073917e-01, 1.05894634e-01,
            8.68652263e-03, -7.98571818e-02, -4.16548658e-02, -6.40511838e-02,
            -6.99337160e-02, -6.26305633e-02, -4.89098800e-02, -3.09284566e-02,
            -1.00919381e-02
        ],
        [
            0.00000000e+00, -1.84940182e-02, -3.47054606e-02, -4.65278129e-02,
            -5.22037664e-02, -4.93977115e-02, -2.95395230e-02, -5.82421092e-02,
            3.91025654e-02, 1.29337956e-01, 1.67436703e-01, 1.21969296e-01,
            3.20823547e-02, -5.00287386e-02, -9.22993907e-03, -3.27186625e-02,
            -4.52706958e-02, -4.57409325e-02, -3.84701291e-02, -2.55751405e-02,
            -8.64950254e-03
        ],
        [
            0.00000000e+00, -1.49431380e-02, -2.65887341e-02, -3.29162158e-02,
            -3.22994323e-02, -2.29081781e-02, -2.60259636e-03, -3.29856530e-02,
            6.02631314e-02, 1.45003704e-01, 1.79361264e-01, 1.34292814e-01,
            4.88007115e-02, -2.82328554e-02, 1.64212421e-02, -5.72391847e-03,
            -2.23438861e-02, -2.90246794e-02, -2.76054402e-02, -1.97779758e-02,
            -7.03945406e-03
        ],
        [
            0.00000000e+00, -1.12771143e-02, -1.84737590e-02, -1.98228664e-02,
            -1.40092305e-02, 1.84580818e-04, 1.95817303e-02, -1.32608487e-02,
            7.62783168e-02, 1.57076433e-01, 1.89083905e-01, 1.44259188e-01,
            6.15722813e-02, -1.17505212e-02, 3.65938109e-02, 1.66937711e-02,
            -2.18970818e-03, -1.35507683e-02, -1.70890527e-02, -1.39519424e-02,
            -5.37036892e-03
        ],
        [
            0.00000000e+00, -7.67615215e-03, -1.07348257e-02, -7.75276739e-03,
            2.22351695e-03, 1.98662250e-02, 3.77611177e-02, 2.42018661e-03,
            8.89036172e-02, 1.66855206e-01, 1.97260700e-01, 1.52590263e-01,
            7.17981256e-02, 1.18005972e-03, 5.26852303e-02, 3.51638855e-02,
            1.51012176e-02, 2.69654076e-04, -7.33815554e-03, -8.36639665e-03,
            -3.72176313e-03
        ],
        [
            0.00000000e+00, -4.50552324e-03, -4.32262850e-03, 1.73559158e-03,
            1.42670366e-02, 3.35040699e-02, 4.97279358e-02, 1.85410528e-02,
            9.39950666e-02, 1.46646579e-01, 9.13474746e-02, 1.37004651e-01,
            7.74648339e-02, 1.59777072e-02, 6.25334939e-02, 4.74577418e-02,
            2.72155518e-02, 1.06174952e-02, 3.94103899e-04, -3.68465400e-03,
            -2.19830733e-03
        ],
        [
            0.00000000e+00, -1.74629916e-03, 5.44471813e-04, 8.22933499e-03,
            2.15699287e-02, 4.04232250e-02, 5.69678048e-02, 5.52408259e-02,
            9.04381272e-02, 1.08204635e-01, 9.14439984e-02, 1.06884511e-01,
            8.17241884e-02, 5.55282924e-02, 6.78528399e-02, 5.47188925e-02,
            3.35251483e-02, 1.69615982e-02, 5.72048628e-03, -8.81437278e-05,
            -7.36518436e-04
        ],
        [
            0.00000000e+00, 4.07838765e-05, 3.63933766e-03, 1.20080876e-02,
            2.51274691e-02, 4.25687176e-02, 6.25685606e-02, 7.33480475e-02,
            8.37515545e-02, 9.52500287e-02, 9.15135660e-02, 9.66442834e-02,
            8.66659913e-02, 8.10325633e-02, 7.18836713e-02, 5.45548434e-02,
            3.55884875e-02, 2.00142359e-02, 8.71200201e-03, 2.04407846e-03,
            -6.53680674e-06
        ],
        [
            0.00000000e+00, 2.40054729e-04, 4.44975227e-03, 1.27572519e-02,
            2.49362989e-02, 4.03831326e-02, 5.80039988e-02, 7.61280192e-02,
            8.37404162e-02, 8.89634569e-02, 9.15651607e-02, 9.13586235e-02,
            8.83589144e-02, 8.27804032e-02, 6.75666471e-02, 5.00483249e-02,
            3.36733366e-02, 1.96758691e-02, 9.00603204e-03, 2.18370401e-03,
            0.00000000e+00
        ],
        [
            0.00000000e+00, 0.00000000e+00, 2.78776980e-03, 1.05086036e-02,
            2.13238822e-02, 3.45577738e-02, 4.91570145e-02, 6.36787133e-02,
            7.63710088e-02, 8.54072310e-02, 8.92960200e-02, 8.75702197e-02,
            8.07095447e-02, 6.97999389e-02, 5.63787286e-02, 4.20734776e-02,
            2.83073312e-02, 1.61614525e-02, 6.56194125e-03, 1.00721924e-04,
            0.00000000e+00
        ],
        [
            0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 5.49667845e-03,
            1.47563319e-02, 2.57955743e-02, 3.76689418e-02, 4.91861917e-02,
            5.90108907e-02, 6.58478416e-02, 6.87018515e-02, 6.73174642e-02,
            6.20270643e-02, 5.35456385e-02, 4.29400416e-02, 3.14129728e-02,
            2.00795162e-02, 9.84001885e-03, 1.53992995e-03, 0.00000000e+00,
            0.00000000e+00
        ]
    ])
    np.testing.assert_allclose(fd, fd_test, rtol=1e-4)
Esempio n. 19
0
def test_rv4():
    magnitude = 7.0
    rake = 90.0
    width = np.array([28])
    rupx = np.array([0, 0])
    rupy = np.array([0, 32])
    zp = np.array([0])
    dip = np.array([30])

    # Convert to lat/lon
    proj = geo.utils.get_orthographic_projection(-122, -120, 39, 37)
    tlon, tlat = proj(rupx, rupy, reverse=True)

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

    # 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,
        'eventsourcecode': 'rv4',
        'rake': rake
    })

    x = np.linspace(-50, 50, 11)
    y = np.linspace(-50, 50, 11)
    site_x, site_y = np.meshgrid(x, y)
    slon, slat = proj(site_x, site_y, reverse=True)
    deps = np.zeros_like(slon)

    test1 = Bayless2013(origin, rup, slat, slon, deps, T=2.0)

    # Test fd
    fd = test1.getFd()
    fd_test = np.array(
        [[
            0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.72143257e-03,
            1.34977260e-03, 4.33616224e-15, 1.24446253e-03, 1.16142357e-03,
            2.25464716e-03, 7.05281751e-04, 0.00000000e+00
        ],
         [
             0.00000000e+00, 0.00000000e+00, 7.62610242e-03, 1.25133844e-02,
             5.61896104e-03, 7.63126014e-15, 4.52266194e-03, 4.67970900e-03,
             1.02820316e-02, 5.13160096e-03, -6.13926251e-03
         ],
         [
             0.00000000e+00, 4.00495234e-03, 2.37608386e-02, 2.37139333e-02,
             9.55224050e-03, 5.66364910e-15, 7.70344813e-03, 7.36466362e-03,
             1.48239704e-02, 8.40388145e-03, -1.58592485e-02
         ],
         [
             8.08385547e-19, 9.38150101e-03, 3.38610620e-02, 3.85351492e-02,
             1.91044918e-02, 3.98697802e-15, 1.54321666e-02, 1.21913760e-02,
             2.04435166e-02, 1.04931859e-02, -1.85935894e-02
         ],
         [
             2.12025421e-18, 1.37316085e-02, 4.40193799e-02, 6.16562477e-02,
             4.77612496e-02, 2.60257085e-15, 3.86322888e-02, 1.97965887e-02,
             2.64882038e-02, 1.23335908e-02, -2.07389932e-02
         ],
         [
             2.64338576e-18, 1.45898292e-02, 4.89104213e-02, 7.70703166e-02,
             9.55225258e-02, 1.01875104e-01, 7.73459329e-02, 2.50275508e-02,
             2.93537540e-02, 1.30949577e-02, -2.15685454e-02
         ],
         [
             2.64330042e-18, 1.45898262e-02, 4.89104186e-02, 7.70703146e-02,
             9.55225248e-02, 1.01910945e-01, 7.74050835e-02, 2.52307946e-02,
             2.92970736e-02, 1.30880504e-02, -2.15685424e-02
         ],
         [
             2.64318867e-18, 1.45898259e-02, 4.89104184e-02, 7.70703144e-02,
             9.55225247e-02, 1.01933432e-01, 7.74421258e-02, 2.53572923e-02,
             2.92615130e-02, 1.30837284e-02, -2.15685422e-02
         ],
         [
             2.64305117e-18, 1.45898284e-02, 4.89104206e-02, 7.70703161e-02,
             9.55225256e-02, 1.01942593e-01, 7.74571359e-02, 2.54081640e-02,
             2.92472117e-02, 1.30819985e-02, -2.15685446e-02
         ],
         [
             2.30141673e-18, 1.40210825e-02, 4.56205547e-02, 6.63109661e-02,
             5.79266964e-02, 2.33044622e-15, 4.69672564e-02, 2.18401553e-02,
             2.72864925e-02, 1.25728575e-02, -2.10227772e-02
         ],
         [
             1.10672535e-18, 1.04777076e-02, 3.59041065e-02, 4.24614318e-02,
             2.24217216e-02, 3.66914762e-15, 1.81728517e-02, 1.39301504e-02,
             2.14956836e-02, 1.08711460e-02, -1.90802849e-02
         ]])
    np.testing.assert_allclose(fd, fd_test, rtol=2e-4)
Esempio n. 20
0
 def getHypo(self):
     """
     Returns:
        Hypocenter as OpenQuake Point instance.
     """
     return point.Point(self.lon, self.lat, self.depth)