예제 #1
0
 def test_parse_region_list_to_tuples(self):
     '''
     Tests the function to parse a region list to a set of tuples
     '''
     self.data = {
         'Shear_Modulus': {'Value': [30.], 'Weight': [1.0]},
         'Displacement_Length_Ratio': {'Value': [1.25E-5], 'Weight': [1.0]},
         'Magnitude_Scaling_Relation': {'Value': [WC1994()], 
                                        'Weight': [1.0]}}
     expected_output = {'Shear_Modulus': [(30., 1.0)],
                        'Displacement_Length_Ratio': [(1.25E-5, 1.0)],
                        'Magnitude_Scaling_Relation': [(WC1994(), 1.0)]}
     output = parse_tect_region_dict_to_tuples([self.data])
     self.assertAlmostEqual(expected_output['Shear_Modulus'][0][0],
                             output[0]['Shear_Modulus'][0][0])
     self.assertAlmostEqual(expected_output['Shear_Modulus'][0][1],
                             output[0]['Shear_Modulus'][0][1])
     self.assertAlmostEqual(
         expected_output['Displacement_Length_Ratio'][0][0],
         output[0]['Displacement_Length_Ratio'][0][0])
     self.assertAlmostEqual(
         expected_output['Displacement_Length_Ratio'][0][1],
         output[0]['Displacement_Length_Ratio'][0][1])
     
     self.assertTrue(isinstance(
         output[0]['Magnitude_Scaling_Relation'][0][0],
         WC1994))
     self.assertAlmostEqual(
         expected_output['Magnitude_Scaling_Relation'][0][1],
         output[0]['Shear_Modulus'][0][1])
예제 #2
0
    def test_get_recurrence_simple_characteristic(self):
        '''
        Tests the function to get the recurrence calculation for a simple
        characteristic earthquake
        '''
        self.mfd_config = {'MFD_spacing': 0.1,
                           'Model_Name': 'Characteristic',
                           'Model_Weight': 1.0,
                           'Maximum_Magnitude': None,
                           'Maximum_Uncertainty': None,
                           'Lower_Bound': -2.,
                           'Upper_Bound': 2., 'Sigma': 0.12}

        self.model = RecurrenceBranch(8500., 5., WC1994(), 0., 30.)
        self.model.get_recurrence(self.mfd_config)
        # Test the same process using just the hmtk.faults.mfd.characteristic
        # Implementation
        test_model = Characteristic()
        test_model.setUp(self.mfd_config)
        test_model.get_mmax(self.mfd_config, WC1994(), 0., 8500.)
        _ = test_model.get_mfd(5.0, 8500., 30.)
        self.assertTrue(isinstance(self.model.recurrence, IncrementalMFD))
        self.assertAlmostEqual(self.model.recurrence.min_mag,
                               test_model.mmin)
        self.assertAlmostEqual(self.model.recurrence.bin_width,
                               test_model.bin_width)
        np.testing.assert_array_almost_equal(self.model.recurrence.occur_rates,
                                             test_model.occurrence_rate)
예제 #3
0
def example_calc(apply):
    sitecol = SiteCollection([
        Site(Point(30.0, 30.0), 760., 1.0, 1.0),
        Site(Point(30.25, 30.25), 760., 1.0, 1.0),
        Site(Point(30.4, 30.4), 760., 1.0, 1.0)
    ])
    mfd_1 = TruncatedGRMFD(4.5, 8.0, 0.1, 4.0, 1.0)
    mfd_2 = TruncatedGRMFD(4.5, 7.5, 0.1, 3.5, 1.1)
    sources = [
        PointSource('001', 'Point1', 'Active Shallow Crust', mfd_1, 1.0,
                    WC1994(), 1.0, PoissonTOM(50.0), 0.0, 30.0,
                    Point(30.0, 30.5), PMF([(1.0, NodalPlane(0.0, 90.0,
                                                             0.0))]),
                    PMF([(1.0, 10.0)])),
        PointSource('002', 'Point2', 'Active Shallow Crust', mfd_2, 1.0,
                    WC1994(), 1.0, PoissonTOM(50.0), 0.0, 30.0,
                    Point(30.0, 30.5), PMF([(1.0, NodalPlane(0.0, 90.0,
                                                             0.0))]),
                    PMF([(1.0, 10.0)]))
    ]
    imtls = {
        'PGA': [0.01, 0.1, 0.2, 0.5, 0.8],
        'SA(0.5)': [0.01, 0.1, 0.2, 0.5, 0.8]
    }
    gsims = {'Active Shallow Crust': AkkarBommer2010()}
    return calc_hazard_curves(sources,
                              sitecol,
                              imtls,
                              gsims,
                              apply=apply,
                              filter_distance='rrup')
예제 #4
0
파일: hazard_test.py 프로젝트: lcui24/hmtk
 def setUp(self):
     """
     """
     mfd_1 = TruncatedGRMFD(4.5, 8.0, 0.1, 4.0, 1.0)
     mfd_2 = TruncatedGRMFD(4.5, 7.5, 0.1, 3.5, 1.1)
     self.source_model = [
         PointSource('001', 'Point1', 'Active Shallow Crust', mfd_1, 1.0,
                     WC1994(), 1.0, PoissonTOM(50.0), 0.0, 30.0,
                     Point(30.0, 30.5),
                     PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))]),
                     PMF([(1.0, 10.0)])),
         PointSource('002', 'Point2', 'Active Shallow Crust', mfd_2, 1.0,
                     WC1994(), 1.0, PoissonTOM(50.0), 0.0, 30.0,
                     Point(30.0, 30.5),
                     PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))]),
                     PMF([(1.0, 10.0)]))
     ]
     self.sites = SiteCollection([
         Site(Point(30.0, 30.0), 760., True, 1.0, 1.0, 1),
         Site(Point(30.25, 30.25), 760., True, 1.0, 1.0, 2),
         Site(Point(30.4, 30.4), 760., True, 1.0, 1.0, 2)
     ])
     self.gsims = {'Active Shallow Crust': 'AkkarBommer2010'}
     self.imts = ['PGA', 'SA(0.5)']
     self.imls = [[0.01, 0.1, 0.2, 0.5, 0.8]]
예제 #5
0
파일: hazard_test.py 프로젝트: lcui24/hmtk
def reference_psha_calculation_openquake():
    """
    Sets up the reference PSHA calculation calling OpenQuake directly. All
    subsequent implementations should match this example
    """
    # Site model - 3 Sites
    site_model = SiteCollection([
        Site(Point(30.0, 30.0), 760., True, 1.0, 1.0, 1),
        Site(Point(30.25, 30.25), 760., True, 1.0, 1.0, 2),
        Site(Point(30.4, 30.4), 760., True, 1.0, 1.0, 2)
    ])
    # Source Model Two Point Sources
    mfd_1 = TruncatedGRMFD(4.5, 8.0, 0.1, 4.0, 1.0)
    mfd_2 = TruncatedGRMFD(4.5, 7.5, 0.1, 3.5, 1.1)
    source_model = [
        PointSource('001', 'Point1', 'Active Shallow Crust', mfd_1, 1.0,
                    WC1994(), 1.0, PoissonTOM(50.0), 0.0, 30.0,
                    Point(30.0, 30.5), PMF([(1.0, NodalPlane(0.0, 90.0,
                                                             0.0))]),
                    PMF([(1.0, 10.0)])),
        PointSource('002', 'Point2', 'Active Shallow Crust', mfd_2, 1.0,
                    WC1994(), 1.0, PoissonTOM(50.0), 0.0, 30.0,
                    Point(30.0, 30.5), PMF([(1.0, NodalPlane(0.0, 90.0,
                                                             0.0))]),
                    PMF([(1.0, 10.0)]))
    ]
    imts = {
        'PGA': [0.01, 0.1, 0.2, 0.5, 0.8],
        'SA(0.5)': [0.01, 0.1, 0.2, 0.5, 0.8]
    }
    # Akkar & Bommer (2010) GMPE
    gsims = {'Active Shallow Crust': gsim.akkar_bommer_2010.AkkarBommer2010()}
    truncation_level = None
    return calc_hazard_curves(source_model, site_model, imts, gsims,
                              truncation_level)
예제 #6
0
    def test_generate_fault_source_model_complex(self):
        '''
        Tests the function to turn fault model into mtkSimpleFault or
        mtkComplexFault
        '''
        self.fault = mtkActiveFault(
            '001',
            'A Fault',
            self.complex_fault,
            [(5.0, 1.0)],
            0.,
            None,
            aseismic=0.,
            msr_sigma=[(0.0, 1.0)],
            neotectonic_fault=None,
            scale_rel=[(WC1994(), 1.0)],
            aspect_ratio=1.0,
            shear_modulus=[(30., 1.0)],
            disp_length_ratio=[(1.25E-5, 1.0)])
        # Define simple placeholder MFD
        rec_models = [IncrementalMFD(5.0, 0.1, 1.0 * np.ones(10)),
                      IncrementalMFD(5.0, 0.1, 2.0 * np.ones(10))]
        self.fault.mfd = (rec_models, [0.5, 0.5], [WC1994(), WC1994()])

        # Run model
        source_model, weights = self.fault.generate_fault_source_model()
        self.assertEqual(len(source_model), 2)
        self.assertTrue(isinstance(source_model[0], mtkComplexFaultSource))
        for iloc, model in enumerate(source_model):
            self.assertEqual(model.id, '001')
            self.assertTrue(isinstance(model.mfd, EvenlyDiscretizedMFD))
            np.testing.assert_array_almost_equal(model.mfd.occurrence_rates,
                                                 rec_models[iloc].occur_rates)
            self.assertAlmostEqual(weights[iloc], 0.5)
예제 #7
0
    def test_recurrence_collapse_branches(self):
        '''
        Tests the recurrence model generated by collapsing branches
        '''

        self.fault = mtkActiveFault('001',
                                    'A Fault',
                                    self.simple_fault, [(5., 0.5), (7., 0.5)],
                                    0.,
                                    None,
                                    aseismic=0.,
                                    msr_sigma=[(0.0, 1.0)],
                                    neotectonic_fault=None,
                                    scale_rel=[(WC1994(), 1.0)],
                                    aspect_ratio=1.0,
                                    shear_modulus=[(30., 1.0)],
                                    disp_length_ratio=[(1.25E-5, 1.0)])
        mfd_config = [{
            'MFD_spacing': 0.1,
            'Maximum_Magnitude': None,
            'Minimum_Magnitude': 5.0,
            'Model_Name': 'AndersonLucoArbitrary',
            'Model_Weight': 0.7,
            'Model_Type': 'First',
            'b_value': [0.8, 0.05]
        }, {
            'MFD_spacing': 0.1,
            'Maximum_Magnitude': None,
            'Maximum_Magnitude_Uncertainty': None,
            'Minimum_Magnitude': 5.0,
            'Model_Name': 'YoungsCoppersmithExponential',
            'Model_Weight': 0.3,
            'b_value': [0.8, 0.05]
        }]

        # Enumerated branches should have four models
        self.fault.generate_recurrence_models(collapse=True,
                                              rendered_msr=WC1994(),
                                              config=mfd_config)

        expected_rates = 0.
        expected_weights = np.array([0.35, 0.15, 0.35, 0.15])
        for iloc in range(0, 4):
            expected_rates = expected_rates + (expected_weights[iloc] *
                                               10.**FAULT_RATE_DATA[iloc, :])
        np.testing.assert_array_almost_equal(
            np.log10(self.fault.mfd[0][0].occur_rates),
            np.log10(expected_rates))
예제 #8
0
 def __init__(self,
              source_file,
              investigation_time,
              start_date,
              min_mag,
              npd,
              hdd,
              aspect=1.5,
              upper_seismogenic_depth=0.0,
              lower_seismogenic_depth=15.0,
              msr=WC1994(),
              mesh_spacing=1.0,
              trt="Active Shallow Crust",
              integration_distance=1000):
     assert os.path.exists(source_file), source_file
     self.source_file = source_file
     self.source_id = None  # unset until .new is called
     self.inv_time = investigation_time
     self.start_date = start_date
     self.temporal_occurrence_model = PoissonTOM(self.inv_time)
     self.min_mag = min_mag
     self.npd = npd
     self.hdd = hdd
     self.aspect = aspect
     self.usd = upper_seismogenic_depth
     self.lsd = lower_seismogenic_depth
     self.msr = msr
     self.mesh_spacing = mesh_spacing
     self.tectonic_region_type = trt
     self.stop = None
     self.start = None
예제 #9
0
def prefilter_background_model(hdf5,
                               sites,
                               integration_distance,
                               msr=WC1994(),
                               aspect=1.5):
    """
    Identify those points within the integration distance
    :param sites:
        Sites for consideration (can be None!)
    :param float integration_distance:
        Maximum distance from rupture to site for consideration
    :param msr:
        Magnitude scaling relation
    :param float aspect:
        Aspect ratio
    :returns:
        Boolean vector indicating if sites are within (True) or outside (False)
        the integration distance
    """
    bg_locations = hdf5["Grid/Locations"][:].astype("float64")
    n_locations = bg_locations.shape[0]
    if not sites:
        # Apply no filtering - all sources valid
        return numpy.ones(n_locations, dtype=bool)
    distances = min_distance(sites.lons, sites.lats,
                             numpy.zeros_like(sites.lons), bg_locations[:, 0],
                             bg_locations[:, 1], numpy.zeros(n_locations))
    # Add buffer equal to half of length of median area from Mmax
    mmax_areas = msr.get_median_area(hdf5["Grid/MMax"][:], 0.0)
    mmax_lengths = numpy.sqrt(mmax_areas / aspect)
    return distances <= (0.5 * mmax_lengths + integration_distance)
예제 #10
0
 def test_generate_branching_index(self):
     '''
     Simple test to check that a correct branching index is raised
     Slip - 2 values
     MSR - 1 value 
     Shear Modulus - 2 value
     DLR - 1 value
     MSR_Sigma - 3 Values
     Config - 1 value
     '''
     self.fault = mtkActiveFault('001',
                                 'A Fault',
                                 self.simple_fault, [(5., 0.5), (7., 0.5)],
                                 0.,
                                 None,
                                 msr_sigma=[(-1.5, 0.15), (0., 0.7),
                                            (1.5, 0.15)],
                                 neotectonic_fault=None,
                                 scale_rel=[(WC1994(), 1.0)],
                                 aspect_ratio=1.0,
                                 shear_modulus=[(28., 0.5), (30., 0.5)],
                                 disp_length_ratio=[(1.25E-5, 1.0)])
     # Set with only one config - no data input
     self.fault.generate_config_set({})
     expected_result = np.array(
         [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 2, 0],
          [0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 1, 0], [0, 0, 1, 0, 2, 0],
          [1, 0, 0, 0, 0, 0], [1, 0, 0, 0, 1, 0], [1, 0, 0, 0, 2, 0],
          [1, 0, 1, 0, 0, 0], [1, 0, 1, 0, 1, 0], [1, 0, 1, 0, 2, 0]],
         dtype=int)
     branch_index, number_branches = \
         self.fault._generate_branching_index()
     np.testing.assert_array_equal(branch_index, expected_result)
     self.assertEqual(number_branches, 12)
예제 #11
0
 def __init__(self, magnitude, dip, aspect,
              tectonic_region='Active Shallow Crust', rake=0., ztor=0.,
              strike=0., msr=WC1994(), initial_point=DEFAULT_POINT,
              hypocentre_location=None):
     """
     Instantiate the rupture - requires a minimum of a magnitude, dip
     and aspect ratio
     """
     self.magnitude = magnitude
     self.dip = dip
     self.aspect = aspect
     self.rake = rake
     self.strike = strike
     self.location = initial_point
     self.ztor = ztor
     self.trt = tectonic_region
     self.hypo_loc = hypocentre_location
     # If the top of rupture depth in the initial
     if fabs(self.location.depth - self.ztor) > 1E-9:
         self.location.depth = ztor
     self.msr = msr
     self.area = self.msr.get_median_area(self.magnitude, self.rake)
     self.surface = create_planar_surface(self.location,
                                          self.strike,
                                          self.dip,
                                          self.area,
                                          self.aspect)
     self.hypocentre = get_hypocentre_on_planar_surface(self.surface,
                                                        self.hypo_loc)
     self.rupture = self.get_rupture()
     self.target_sites_config = None
     self.target_sites = None
예제 #12
0
 def setUp(self):
     '''
     '''
     self.fault = None
     self.regionalisation = None
     self.msr = [(WC1994(), 1.0)]
     self.msr_sigma = [(-1.5, 0.15), (0.0, 0.7), (1.5, 0.15)]
     self.shear_mod = [(30.0, 0.8), (35.0, 0.2)]
     self.dlr = [(1.25E-5, 1.0)]
     self.config = [{}]
     self.slip = [(10.0, 1.0)]
     x0 = Point(30., 30., 0.)
     x1 = x0.point_at(30., 0., 30.)
     x2 = x1.point_at(30., 0., 60.)
     # Total length is 60 km
     self.trace = Line([x0, x1, x2])
     self.dip = 90.
     self.upper_depth = 0.
     self.lower_depth = 20.
     self.simple_fault = SimpleFaultGeometry(self.trace,
                                             self.dip,
                                             self.upper_depth,
                                             self.lower_depth)
             # Creates a trace ~60 km long made of 3 points
     upper_edge = Line([x0, x1, x2])
     lower_edge = Line([x0.point_at(40., 20., 130.),
                        x1.point_at(42., 25., 130.),
                        x2.point_at(41., 22., 130.)])
     self.complex_fault = ComplexFaultGeometry([upper_edge, lower_edge],
                                               2.0)
예제 #13
0
    def build_fault_model(self,
                          collapse=False,
                          rendered_msr=WC1994(),
                          mfd_config=None):
        '''
        Constructs a full fault model with epistemic uncertainty by
        enumerating all the possible recurrence models of each fault as 
        separate faults, with the recurrence rates multiplied by the 
        corresponding weights. 
        :param bool collapse:
            Determines whether or not to collapse the branches
        :param rendered_msr:
            If the option is taken to collapse the branches then a recurrence
            model for rendering must be defined
        :param list/dict mfd_config:
            Universal list or dictionay of configuration parameters for the
            magnitude frequency distribution - will overwrite whatever is 
            previously defined for the fault!
        '''
        self.source_model = mtkSourceModel(self.id, self.name)
        for fault in self.faults:
            fault.generate_recurrence_models(collapse,
                                             config=mfd_config,
                                             rendered_msr=rendered_msr)
            src_model, src_weight = fault.generate_fault_source_model()
            for iloc, model in enumerate(src_model):

                new_model = deepcopy(model)
                new_model.id = str(model.id) + '_%g' % (iloc + 1)
                new_model.mfd.occurrence_rates = \
                    (np.array(new_model.mfd.occurrence_rates) *
                     src_weight[iloc]).tolist()
                self.source_model.sources.append(new_model)
예제 #14
0
    def setUp(self):

        mfd = TruncatedGRMFD(min_mag=4.0, max_mag=6.0, bin_width=0.1,
                             a_val=2.0, b_val=1.0)
        msr = WC1994()
        tom = PoissonTOM(1.0)
        pol = Polygon([Point(longitude=0.0, latitude=0.0),
                       Point(longitude=1.0, latitude=0.0),
                       Point(longitude=1.0, latitude=1.0),
                       Point(longitude=0.0, latitude=1.0)])
        npd = PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))])
        hpd = PMF([(0.7, 10.), (0.3, 20.0)])

        self.src1 = AreaSource(source_id='1',
                               name='1',
                               tectonic_region_type='Test',
                               mfd=mfd,
                               rupture_mesh_spacing=1,
                               magnitude_scaling_relationship=msr,
                               rupture_aspect_ratio=1.,
                               temporal_occurrence_model=tom,
                               upper_seismogenic_depth=0,
                               lower_seismogenic_depth=100.,
                               nodal_plane_distribution=npd,
                               hypocenter_distribution=hpd,
                               polygon=pol,
                               area_discretization=10.)
예제 #15
0
    def _parse_event_data(self, metadata):
        """
        Read in the distance related metadata and return an instance of the
        :class: smtk.sm_database.Earthquake

        """
        metadata["MODY"] = metadata["MODY"].zfill(4)
        metadata["HRMN"] = metadata["HRMN"].zfill(4)
        # Date and Time
        year = get_int(metadata["YEAR"])
        month = get_int(metadata["MODY"][:2])
        day = get_int(metadata["MODY"][2:])
        hour = get_int(metadata["HRMN"][:2])
        minute = get_int(metadata["HRMN"][2:])
        eq_datetime = datetime(year, month, day, hour, minute)
        # Event ID and Name
        eq_id = metadata["EQID"]
        eq_name = metadata["Earthquake Name"]
        # Focal Mechanism
        focal_mechanism = self._get_focal_mechanism(eq_id, eq_name, metadata)
        focal_mechanism.scalar_moment = get_float(metadata["Mo (dyne.cm)"]) *\
            1E-7
        # Read magnitude
        pref_mag = Magnitude(get_float(metadata["Earthquake Magnitude"]),
                             metadata["Magnitude Type"],
                             sigma=get_float(metadata["Uncertainty"]))
        # Create Earthquake Class
        eqk = Earthquake(eq_id, eq_name, eq_datetime,
                         get_float(metadata["Hypocenter Longitude (deg)"]),
                         get_float(metadata["Hypocenter Latitude (deg)"]),
                         get_float(metadata["Hypocenter Depth (km)"]),
                         pref_mag, focal_mechanism, metadata["Country"])
        hypo_loc = (0.5, 0.7)  # Hypocentre Location
        msr = WC1994()
        # Warning rake set to 0.0 in scaling relationship
        area = msr.get_median_area(pref_mag.value, 0.0)
        aspect_ratio = 1.5  # Assumed Fixed
        width_model = np.sqrt(area / aspect_ratio)
        length_model = aspect_ratio * width_model
        ztor_model = eqk.depth - width_model / 2.
        if ztor_model < 0:
            ztor_model = 0.0

        length = get_float(metadata["Fault Rupture Length (km)"])
        if length is None:
            length = length_model
        width = get_float(metadata["Fault Rupture Width (km)"])
        if width is None:
            width = width_model
        ztor = get_float(metadata["Depth to Top Of Fault Rupture Model"])
        if ztor is None:
            ztor = ztor_model
        # Rupture
        eqk.rupture = Rupture(eq_id, eq_name, pref_mag, length, width, ztor)
        #    get_float(metadata["Fault Rupture Length (km)"]),
        #    get_float(metadata["Fault Rupture Width (km)"]),
        #    get_float(metadata["Depth to Top Of Fault Rupture Model"]))
        eqk.rupture.get_area()
        return eqk
예제 #16
0
def plot_planes_at(x,
                   y,
                   strikes,
                   dips,
                   magnitudes,
                   strike_cs,
                   dip_cs,
                   aratio=1.0,
                   msr=None,
                   ax=None,
                   zorder=20,
                   color='None',
                   linewidth=1,
                   axis=None):
    """
    This plots a cross-section and number of rupture planes defined in terms
    of a strike and a dip.

    :parameter x:
        Coordinates x on the cross-section
    :parameter y:
        Coordinates y on the cross-section (it corresponds to a depth)
    :parameter strikes:
        Strike values of the planes
    :parameter dips:
        Dip values of the planes
    :parameter strike_cs:
        Strike angle of the cross-section plane [in degrees]
    :parameter dip_cs:
        Dip angle of the cross-section plane [in degrees]
    """

    if axis is None:
        ax = plt.gca()
    else:
        plt.sca(axis)

    if msr is None:
        msr = WC1994()

    cols = ['red', 'blue', 'green']

    for strike, dip, col, mag in zip(strikes, dips, cols, magnitudes):

        area = msr.get_median_area(mag, None)
        width = (area / aratio)**.5
        t = np.arange(-width / 2, width / 2, 0.1)

        inter = get_line_of_intersection(strike, dip, strike_cs, dip_cs)
        xl = t * inter[0]
        yl = t * inter[1]
        zl = t * inter[2]
        ds = -np.sign(t) * (xl**2 + yl**2)**.5 + x

        if color is not None:
            col = color

        plt.plot(ds, zl + y, zorder=zorder, color=col, linewidth=linewidth)
예제 #17
0
def sample_background_model(
        hdf5, branch_key, tom, eff_num_ses, seed, filter_idx, min_mag, npd,
        hdd, upper_seismogenic_depth, lower_seismogenic_depth, msr=WC1994(),
        aspect=1.5, trt=DEFAULT_TRT):
    """
    Generates a rupture set from a sample of the background model

    :param branch_key:
        Key to indicate the branch for selecting the background model
    :param tom:
        Temporal occurrence model as instance of :class:
        openquake.hazardlib.tom.TOM
    :param seed:
        Random seed to use in the call to tom.sample_number_of_occurrences
    :param filter_idx:
        Sites for consideration (can be None!)
    :param float min_mag:
        Minimim magnitude for consideration of background sources
    :param npd:
        Nodal plane distribution as instance of :class:
        openquake.hazardlib.pmf.PMF
    :param hdd:
        Hypocentral depth distribution as instance of :class:
        openquake.hazardlib.pmf.PMF
    :param float aspect:
        Aspect ratio
    :param float upper_seismogenic_depth:
        Upper seismogenic depth (km)
    :param float lower_seismogenic_depth:
        Lower seismogenic depth (km)
    :param msr:
        Magnitude scaling relation
    :param float integration_distance:
        Maximum distance from rupture to site for consideration
    """
    bg_magnitudes = hdf5["/".join(["Grid", branch_key, "Magnitude"])][()]
    # Select magnitudes above the minimum magnitudes
    mag_idx = bg_magnitudes >= min_mag
    mags = bg_magnitudes[mag_idx]
    rates = hdf5["/".join(["Grid", branch_key, "RateArray"])][filter_idx, :]
    rates = rates[:, mag_idx]
    valid_locs = hdf5["Grid/Locations"][filter_idx, :]
    # Sample remaining rates
    sampler = tom.sample_number_of_occurrences(rates * eff_num_ses, seed)
    background_ruptures = []
    background_n_occ = []
    for i, mag in enumerate(mags):
        rate_idx = numpy.where(sampler[:, i])[0]
        rate_cnt = sampler[rate_idx, i]
        occurrence = rates[rate_idx, i]
        locations = valid_locs[rate_idx, :]
        ruptures = generate_background_ruptures(
            tom, locations, occurrence,
            mag, npd, hdd, upper_seismogenic_depth,
            lower_seismogenic_depth, msr, aspect, trt)
        background_ruptures.extend(ruptures)
        background_n_occ.extend(rate_cnt.tolist())
    return background_ruptures, background_n_occ
예제 #18
0
def generate_background_ruptures(tom,
                                 locations,
                                 occurrence,
                                 mag,
                                 npd,
                                 hdd,
                                 upper_seismogenic_depth,
                                 lower_seismogenic_depth,
                                 msr=WC1994(),
                                 aspect=1.5,
                                 trt=DEFAULT_TRT):
    """
    :param tom:
        Temporal occurrence model as instance of :class:
        openquake.hazardlib.tom.TOM
    :param numpy.ndarray locations:
        Array of locations [Longitude, Latitude] of the point sources
    :param numpy.ndarray occurrence:
        Annual rates of occurrence
    :param float mag:
        Magnitude
    :param npd:
        Nodal plane distribution as instance of :class:
        openquake.hazardlib.pmf.PMF
    :param hdd:
        Hypocentral depth distribution as instance of :class:
        openquake.hazardlib.pmf.PMF
    :param float upper_seismogenic_depth:
        Upper seismogenic depth (km)
    :param float lower_seismogenic_depth:
        Lower seismogenic depth (km)
    :param msr:
        Magnitude scaling relation
    :param float aspect:
        Aspect ratio
    :param str trt:
        Tectonic region type
    :returns:
        List of ruptures
    """
    ruptures = []
    n_vals = len(locations)
    depths = hdd.sample_pairs(n_vals)
    nodal_planes = npd.sample_pairs(n_vals)
    for i, (x, y) in enumerate(locations):
        hypocentre = Point(x, y, depths[i][1])
        surface = get_rupture_surface(mag, nodal_planes[i][1], hypocentre, msr,
                                      aspect, upper_seismogenic_depth,
                                      lower_seismogenic_depth)
        rupture_probability = (occurrence[i] * nodal_planes[i][0] *
                               depths[i][0])
        ruptures.append(
            ParametricProbabilisticRupture(mag, nodal_planes[i][1].rake, trt,
                                           hypocentre, surface, PointSource,
                                           rupture_probability, tom))
    return ruptures
예제 #19
0
def nrml_from_shapefile(shapefile, shapefile_faultname_attribute,
                        shapefile_dip_attribute, shapefile_sliprate_attribute,
                        source_model_name, simple_fault_tectonic_region,
                        magnitude_scaling_relation, rupture_aspect_ratio,
                        upper_depth, lower_depth, a_value, b_value, min_mag,
                        max_mag, rake, output_dir, quiet):
    """Driver routine to convert nrml to shapefile
     
    """
    # Get geometry
    fault_traces, faultnames, dips, \
    sliprate, fault_lengths = parse_line_shapefile(shapefile,
                                                  shapefile_faultname_attribute,
                                                  shapefile_dip_attribute,
                                                  shapefile_sliprate_attribute)

    # Output is written line-by-line to this list
    output_xml = []

    append_xml_header(output_xml, source_model_name)

    # Loop through each fault and add source specific info
    for i in range(len(fault_traces)):
        simple_fault_id = i
        A = fault_lengths[i] * (float(lower_depth) - float(upper_depth))
        # Calculate M_max from scaling relations
        scalrel = WC1994()
        max_mag = scalrel.get_median_mag(A, float(rake))
        #        print A
        # Calculate GR a values from slip rate
        if sliprate[i] != '""':
            print sliprate[i]
            a_value, moment_rate = fault_slip_rate_GR_conversion.slip2GR(
                sliprate[i], A, float(b_value), float(max_mag), M_min=0.0)
        append_rupture_geometry(output_xml, fault_traces[i], dips[i],
                                simple_fault_id, faultnames[i], upper_depth,
                                lower_depth, simple_fault_tectonic_region)

        append_earthquake_information(output_xml, magnitude_scaling_relation,
                                      rupture_aspect_ratio, a_value, b_value,
                                      min_mag, max_mag, rake)

    # Close xml
    output_xml.append('  </sourceModel>')
    output_xml.append('</nrml>')

    # Add newlines
    output_xml = [oxml + '\n' for oxml in output_xml]

    return output_xml
예제 #20
0
 def test_collapse_fault_model(self):
     input_file = os.path.join(
         BASE_DATA_PATH, "collapse_test_simple_fault_example_4branch.yml")
     mesh_spacing = 1.0
     reader = FaultYmltoSource(input_file)
     fault_model, tectonic_region = reader.read_file(mesh_spacing)
     fault_model.build_fault_model(collapse=True,
                                   bin_width=0.05,
                                   rendered_msr=WC1994())
     expected_mfd = self.src.incrementalMFD
     model_mfd = fault_model.faults[0].mfd[0][0]
     self.assertAlmostEqual(expected_mfd["binWidth"], model_mfd.bin_width,
                            7)
     self.assertAlmostEqual(expected_mfd["minMag"], model_mfd.min_mag, 7)
     expected_rates = np.array(expected_mfd.occurRates.text)
     np.testing.assert_array_almost_equal(model_mfd.occur_rates,
                                          expected_rates, 7)
예제 #21
0
    def test_generate_recurrence_models_no_collapse(self):
        '''
        Tests the generate recurrence models option without collapsing
        branches: simple example with two slip rates and two mfd configurations
        '''
        self.fault = mtkActiveFault(
            '001',
            'A Fault',
            self.simple_fault,
            [(5., 0.5), (7., 0.5)],
            0.,
            None,
            aseismic=0.,
            msr_sigma=[(0.0, 1.0)],
            neotectonic_fault=None,
            scale_rel=[(WC1994(), 1.0)],
            aspect_ratio=1.0,
            shear_modulus=[(30., 1.0)],
            disp_length_ratio=[(1.25E-5, 1.0)])
        mfd_config = [{'MFD_spacing': 0.1,
                       'Maximum_Magnitude': None,
                       'Minimum_Magnitude': 5.0,
                        'Model_Name': 'AndersonLucoArbitrary',
                        'Model_Weight': 0.7,
                        'Model_Type': 'First',
                        'b_value': [0.8, 0.05]},
                       {'MFD_spacing': 0.1,
                        'Maximum_Magnitude': None,
                        'Maximum_Magnitude_Uncertainty': None,
                        'Minimum_Magnitude': 5.0,
                        'Model_Name': 'YoungsCoppersmithExponential',
                        'Model_Weight': 0.3,
                        'b_value': [0.8, 0.05]}]

        # Enumerates branches should have four models
        self.fault.generate_recurrence_models(config=mfd_config)
        mfds = self.fault.mfd[0]
        weights = self.fault.mfd[1]
        np.testing.assert_array_almost_equal(
            weights,
            np.array([0.35, 0.15, 0.35, 0.15]))
        for (iloc, occur) in enumerate(mfds):
            np.testing.assert_array_almost_equal(
                np.log10(occur.occur_rates),
                FAULT_RATE_DATA[iloc, :])
예제 #22
0
 def test_rupture_close_to_south_pole(self):
     # data taken from real example and causing "surface's angles are not
     # right" error
     mfd = EvenlyDiscretizedMFD(
         min_mag=5., bin_width=0.1, occurrence_rates=[2.180e-07]
     )
     nodal_plane_dist = PMF([(1., NodalPlane(135., 20., 90.))])
     src = PointSource(source_id='1', name='pnt', tectonic_region_type='asc',
              mfd=mfd, rupture_mesh_spacing=1,
              magnitude_scaling_relationship=WC1994(),
              rupture_aspect_ratio=1.,
              temporal_occurrence_model=PoissonTOM(50.),
              upper_seismogenic_depth=0, lower_seismogenic_depth=26,
              location=Point(-165.125, -83.600),
              nodal_plane_distribution=nodal_plane_dist,
              hypocenter_distribution=PMF([(1., 9.)]))
     ruptures = list(src.iter_ruptures())
     self.assertEqual(len(ruptures), 1)
예제 #23
0
 def setUp(self):
     """
     """
     #
     # coordinates of point sources
     lons = [10.00, 10.10, 10.20, 10.00, 10.10, 10.20, 10.00, 10.10, 10.20]
     lats = [45.10, 45.10, 45.10, 45.05, 45.05, 45.05, 45.00, 45.00, 45.00]
     deps = [10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00]
     self.lons = lons
     self.lats = lats
     #
     # set main parameters
     mfd = TruncatedGRMFD(min_mag=4.0,
                          max_mag=6.0,
                          bin_width=0.1,
                          a_val=2.0,
                          b_val=1.0)
     msr = WC1994()
     tom = PoissonTOM(1.0)
     npd = PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))])
     hdd = PMF([(0.7, 4.), (0.3, 8.0)])
     #
     # create the list of sources
     srcs = []
     for idx, (lon, lat, dep) in enumerate(zip(lons, lats, deps)):
         src = PointSource(source_id='1',
                           name='Test',
                           tectonic_region_type=TRT.ACTIVE_SHALLOW_CRUST,
                           mfd=mfd,
                           rupture_mesh_spacing=5.0,
                           magnitude_scaling_relationship=msr,
                           rupture_aspect_ratio=1.0,
                           temporal_occurrence_model=tom,
                           upper_seismogenic_depth=0,
                           lower_seismogenic_depth=10.,
                           location=Point(lon, lat, dep),
                           nodal_plane_distribution=npd,
                           hypocenter_distribution=hdd)
         srcs.append(src)
     self.points = srcs
예제 #24
0
 def test(self):
     sitecol = SiteCollection([Site(Point(30.0, 30.0), 760., 1.0, 1.0)])
     mfd = TruncatedGRMFD(4.5, 8.0, 0.1, 4.0, 1.0)
     sources = [
         PointSource('001', 'Point1', 'Active Shallow Crust', mfd, 1.0,
                     WC1994(), 1.0, PoissonTOM(50.0), 0.0, 30.0,
                     Point(30.0, 30.5),
                     PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))]),
                     PMF([(1.0, 10.0)]))
     ]
     imtls = {'PGA': [0.01, 0.1, 0.2, 0.5, 0.8]}
     hc1 = calc_hazard_curves(
         sources, sitecol, imtls,
         {'Active Shallow Crust': AkkarBommer2010()})['PGA']
     hc2 = calc_hazard_curves(
         sources, sitecol, imtls,
         {'Active Shallow Crust': SadighEtAl1997()})['PGA']
     hc = .6 * hc1 + .4 * hc2
     ag = AvgGMPE(b1=dict(AkkarBommer2010={'weight': .6}),
                  b2=dict(SadighEtAl1997={'weight': .4}))
     hcm = calc_hazard_curves(sources, sitecol, imtls,
                              {'Active Shallow Crust': ag})['PGA']
     # the AvgGMPE is not producing real means!!
     numpy.testing.assert_almost_equal(hc, hcm, decimal=3)
예제 #25
0
    def _parse_distance_data(self, event, site, metadata):
        """
        Read in the distance related metadata and return an instance of the
        :class: smtk.sm_database.RecordDistance
        """
        # Compute various distance metrics
        # Add calculation of Repi, Rhypo from event and station localizations
        # (latitudes, longitudes, depth, elevation)?
        target_site = Mesh(np.array([site.longitude]),
                           np.array([site.latitude]),
                           np.array([-site.altitude / 1000.0]))
        # Warning ratio fixed to 1.5
        ratio = 1.5
        if not event.rupture.area:
            event.rupture.area = WC1994().get_median_area(
                event.magnitude.value, None)
        surface_modeled = rcfg.create_planar_surface(
            Point(event.longitude, event.latitude, event.depth),
            event.mechanism.nodal_planes.nodal_plane_1['strike'],
            event.mechanism.nodal_planes.nodal_plane_1['dip'],
            event.rupture.area, ratio)
        hypocenter = rcfg.get_hypocentre_on_planar_surface(
            surface_modeled, event.rupture.hypo_loc)
        try:
            surface_modeled._create_mesh()
        except:
            dip = surface_modeled.get_dip()
            dip_dir = (surface_modeled.get_strike() - 90.) % 360.
            ztor = surface_modeled.top_left.depth
            d_x = ztor * np.tan(np.radians(90.0 - dip))
            top_left_surface = surface_modeled.top_left.point_at(
                d_x, -ztor, dip_dir)
            top_left_surface.depth = 0.
            top_right_surface = surface_modeled.top_right.point_at(
                d_x, -ztor, dip_dir)
            top_right_surface.depth = 0.
            surface_modeled = SimpleFaultSurface.from_fault_data(
                Line([top_left_surface,
                      top_right_surface]), surface_modeled.top_left.depth,
                surface_modeled.bottom_left.depth, surface_modeled.get_dip(),
                1.0)

        # Rhypo
        Rhypo, Repi, Rrup, Rjb, Ry0 = tuple(
            map(get_positive_float, [
                metadata[key] for key in [
                    "Hypocentral Distance (km)", "Epicentral Distance (km)",
                    "Rupture Distance (km)", "Joyner-Boore Distance (km)",
                    "Ry0 (km)"
                ]
            ]))
        Rx = get_float(metadata["Rx (km)"])  # Rx can be negative

        #Rhypo = get_float(metadata["Hypocentral Distance (km)"])
        if Rhypo is None or Rhypo < 0.0:
            Rhypo = hypocenter.distance_to_mesh(target_site)
        # Repi
        #Repi = get_float(metadata["Epicentral Distance (km)"])
        if Repi is None or Repi < 0.0:
            Repi = hypocenter.distance_to_mesh(target_site, with_depths=False)
        # Rrup
        #Rrup = get_float(metadata["Rupture Distance (km)"])
        if Rrup is None or Rrup < 0.0:
            Rrup = surface_modeled.get_min_distance(target_site)[0]
        # Rjb
        #Rjb = get_float(metadata["Joyner-Boore Distance (km)"])
        if Rjb is None or Rjb < 0.0:
            Rjb = surface_modeled.get_joyner_boore_distance(target_site)[0]
        # Need to check if Rx and Ry0 are consistant with the other metrics
        # when those are coming from the flatfile?
        # Rx
        #Rx = get_float(metadata["Rx (km)"])
        if Rx is None or Rx < 0.0:
            Rx = surface_modeled.get_rx_distance(target_site)[0]
        # Ry0
        Ry0 = get_float(metadata["Ry0 (km)"])
        if Ry0 is None or Ry0 < 0.0:
            Ry0 = surface_modeled.get_ry0_distance(target_site)[0]

        distance = RecordDistance(repi=Repi,
                                  rhypo=Rhypo,
                                  rjb=Rjb,
                                  rrup=Rrup,
                                  r_x=Rx,
                                  ry0=Ry0)
        distance.azimuth = get_float(metadata["Source to Site Azimuth (deg)"])
        #distance.hanging_wall = get_float(metadata["FW/HW Indicator"])
        if metadata["FW/HW Indicator"] == "HW":
            distance.hanging_wall = True
        elif metadata["FW/HW Indicator"] == "FW":
            distance.hanging_wall = False
        else:
            pass

        return distance

        return
예제 #26
0
# The GEM Foundation, and the authors of the software, assume no
# liability for use of the software.
'''
:mod: hmtk.regionalisation.tectonic_regionalisation implements the 
hmtk.ancillary.tectonic_regionalisation.TectonicRegion :class:, defining
the methods and attributes associated with a region, and the 
hmtk.ancillary.tectonic_regionalisation.TectonicRegionalisation :class:
defining a regionalisation as a set of regions
'''
from math import fabs
import numpy as np
from openquake.hazardlib.scalerel.wc1994 import WC1994

DEFAULT_SHEAR_MODULUS = [(30.0, 1.0)]
DEFAULT_DLR = [(1.25E-5, 1.0)]
DEFAULT_MSR = [(WC1994(), 1.0)]


def _check_list_weights(parameter, name):
    '''
    Checks that the weights in a list of tuples sums to 1.0
    '''
    if not isinstance(parameter, list):
        raise ValueError('%s must be formulated with a list of tuples' % name)
    weight = np.sum([val[1] for val in parameter])
    if fabs(weight - 1.) > 1E-8:
        raise ValueError('%s weights do not sum to 1.0!' % name)
    return parameter

    #~ if isinstance(parameter, dict):
    #~ if isinstance(parameter['Model'], float):
예제 #27
0
 def setUp(self):
     """
     """
     self.msr = WC1994()
    def _parse_event_data(self, metadata):
        """
        Read in the distance related metadata and return an instance of the
        :class: smtk.sm_database.Earthquake

        """
        data_fields = ['Month', 'Day', 'Hour', 'Minute', 'Second']
        for f in data_fields:
            metadata[f] = metadata[f].zfill(2)

        # Date and Time
        year = get_int(metadata["Year"])
        month = get_int(metadata["Month"])
        day = get_int(metadata["Day"])
        hour = get_int(metadata["Hour"])
        minute = get_int(metadata["Minute"])
        second = get_int(metadata["Second"])
        eq_datetime = datetime(year, month, day, hour, minute, second)
        # Event ID and Name
        eq_id = metadata["EQID"]
        eq_name = metadata["Earthquake Name"]
        # Focal Mechanism
        focal_mechanism = self._get_focal_mechanism(eq_id, eq_name, metadata)
        
        focal_mechanism.scalar_moment = get_float(metadata["Mo (dyne.cm)"]) *\
            1E-7
        # Read magnitude
        pref_mag = Magnitude(get_float(metadata["Magnitude"]),
                             metadata["Magnitude type"],
                             sigma=get_float(metadata["Magnitude uncertainty"]))
        # Create Earthquake Class
        eqk = Earthquake(eq_id, eq_name, eq_datetime,
            get_float(metadata["Epicenter Longitude (deg; positive E)"]),
            get_float(metadata["Epicenter Latitude (deg; positive N)"]),
            get_float(metadata["Hypocenter Depth (km)"]),
            pref_mag,
            focal_mechanism,
            metadata["Country"])

        # hypocenter location
        f1 = get_float(metadata[
            "Along-strike Hypocenter location " +
            "on the fault (fraction between 0 and 1)"])
        f2 = get_float(metadata[
            "Along-width Hypocenter location " +
            "on the fault (fraction between 0 and 1)"])
        if f1 is None or f2 is None:
            hypo_loc = (0.5, 0.7)
        else:
            hypo_loc = (f1, f2)

        evt_tectonic_region = metadata["Tectonic environment (Crustal; Inslab; Interface; Stable; Geothermal; Volcanic; Oceanic_crust)"]
        if evt_tectonic_region == "Stable" or evt_tectonic_region == "Crustal":
            msr=WC1994()
        elif evt_tectonic_region == "Inslab":
            msr=StrasserIntraslab()
        elif evt_tectonic_region == "Interface":
            msr=StrasserInterface()

        # Warning rake set to 0.0 in scaling relationship - applies only
        # to WC1994
        area = msr.get_median_area(pref_mag.value, 0.0)
        aspect_ratio = 1.5
        width_model = np.sqrt(area / aspect_ratio)
        length_model = aspect_ratio * width_model
        ztor_model = eqk.depth - width_model / 2.
        if ztor_model < 0:
            ztor_model = 0.0

        length = get_float(metadata["Fault Rupture Length (km)"])
        if length is None:
            length = length_model
        width = get_float(metadata["Fault Rupture Width (km)"])
        if width is None:
            width = width_model
        ztor = get_float(metadata["Depth to Top Of Fault Rupture Model"])
        if ztor is None:
            ztor=ztor_model

        # Rupture
        eqk.rupture = Rupture(eq_id,
                              length,
                              width,
                              ztor,
                              hypo_loc=hypo_loc)
#            get_float(metadata["Fault Rupture Length (km)"]),
#            get_float(metadata["Fault Rupture Width (km)"]),
#            get_float(metadata["Depth to Top Of Fault Rupture Model"]),
#            hypo_loc=hypo_loc)
        eqk.rupture.get_area()
        return eqk