Esempio n. 1
0
 def _test(self, expected_rates, rate_tolerance, **kwargs):
     mfd = TruncatedGRMFD(**kwargs)
     actual_rates = mfd.get_annual_occurrence_rates()
     self.assertEqual(len(actual_rates), len(expected_rates))
     for i, (mag, rate) in enumerate(actual_rates):
         expected_mag, expected_rate = expected_rates[i]
         self.assertAlmostEqual(mag, expected_mag, delta=1e-14)
         self.assertAlmostEqual(rate, expected_rate, delta=rate_tolerance)
         if i == 0:
             self.assertEqual((mag, mag + 2), mfd.get_min_max_mag())
 def _test(self, expected_rates, rate_tolerance, **kwargs):
     mfd = TruncatedGRMFD(**kwargs)
     actual_rates = mfd.get_annual_occurrence_rates()
     self.assertEqual(len(actual_rates), len(expected_rates))
     for i, (mag, rate) in enumerate(actual_rates):
         expected_mag, expected_rate = expected_rates[i]
         self.assertAlmostEqual(mag, expected_mag, delta=1e-14)
         self.assertAlmostEqual(rate, expected_rate, delta=rate_tolerance)
         if i == 0:
             self.assertEqual((mag, mag + 2), mfd.get_min_max_mag())
Esempio n. 3
0
def mergeinv(agr, bgr, magchar, mfdchar, mwdt):
    """
    """
    mmin = 6.0
    mupp = min(magchar) 
    # get dt mfd
    dtmfd = TruncatedGRMFD(6.0, mupp+mwdt, mwdt, agr, bgr)
    occ = dtmfd.get_annual_occurrence_rates()
    # 
    madt = numpy.array([d[0] for d in occ])
    ocdt = numpy.array([d[1] for d in occ])
    # compute moment 
    modt = sum(mag_to_mo(madt)*ocdt)
    return modt
Esempio n. 4
0
def sliprate2GR_incremental(sliprate,
                            fault_area,
                            b_value,
                            max_mag,
                            min_mag=0.0,
                            bin_width=0.1):
    """Converts a sliprate and b-value into a Gutenberg-
    Richter distribution, then converts this to an
    OpenQuake incremental MFD (to facilitate collapsing of rates
    with other MFDs)
    """
    a_value, moment_rate = fault_slip_rate_GR_conversion.slip2GR(
        sliprate, fault_area, float(b_value), float(max_mag), M_min=min_mag)

    mfd = TruncatedGRMFD(min_mag, max_mag, bin_width, a_value, b_value)
    mags, rates = zip(*mfd.get_annual_occurrence_rates())
    mags = np.array(mags)
    rates = np.array(rates)
    return mags, rates, moment_rate
def _get_mfds(srcs):
    """
    Return sources' magnitude frequency distributions.
    """
    mfds = {}
    tot_occur_rate = 0
    for src in srcs:
        mfd = {}

        if isinstance(src.mfd, IncrementalMFD):
            mfd['min_mag'] = float(src.mfd.min_mag)
            mfd['bin_width'] = float(src.mfd.bin_width)
            mfd['occur_rates'] = map(float, src.mfd.occur_rates)

        elif isinstance(src.mfd, TGRMFD):
            bin_width = 0.1
            mfd = TruncatedGRMFD(
                src.mfd.min_mag,
                src.mfd.max_mag,
                bin_width,
                src.mfd.a_val,
                src.mfd.b_val
            )

            mags_rates = mfd.get_annual_occurrence_rates()
            mags = [m for m, _ in mags_rates]
            occur_rates = [r for _, r in mags_rates]

            mfd['min_mag'] = mags[0]
            mfd['bin_width'] = bin_width
            mfd['occur_rates'] = occur_rates

        else:
            raise ValueError(
                'MFD %s not recognized' % src.mfd.__class__.__name__
            )

        tot_occur_rate += sum(mfd['occur_rates'])

        assert src.id not in mfds
        mfds[src.id] = mfd

    return mfds, tot_occur_rate
Esempio n. 6
0
class TestCCumulativeInterpolation(unittest.TestCase):

    def setUp(self):
        min_mag = 6.5
        max_mag = 7.0
        bin_width = 0.1
        a_val = 3.0
        b_val = 1.0
        self.mfd = TruncatedGRMFD(min_mag, max_mag, bin_width, a_val, b_val)
        self.ms = []
        self.os = []
        #
        # loading information for the original MFD
        for mag, occ in self.mfd.get_annual_occurrence_rates():
            self.ms.append(mag)
            self.os.append(occ)
        self.os = np.array(self.os)

    def test_interpolate_01(self):
        """
        Test calculation of exceedance rate for magnitude equal to bin limit
        """
        exrate = interpolate_ccumul(self.mfd, 6.8)
        self.assertAlmostEqual(exrate, sum(self.os[-2:]))

    def test_interpolate_02(self):
        """
        Test calculation of exceedance rate for a given magnitude
        """
        exrate = interpolate_ccumul(self.mfd, 6.84)
        # rate computed by hand
        self.assertAlmostEqual(exrate, 4.5450608e-05)

    def test_interpolate_03(self):
        """
        Test calculation of exceedance rate within the last bin
        """
        exrate = interpolate_ccumul(self.mfd, 6.94)
        # rate computed by hand
        self.assertAlmostEqual(exrate, 1.285383e-05)
Esempio n. 7
0
class StochasticEventSetTestCase(unittest.TestCase):
    def setUp(self):
        # time span of 10 million years
        self.time_span = 10e6

        nodalplane = NodalPlane(strike=0.0, dip=90.0, rake=0.0)
        self.mfd = TruncatedGRMFD(a_val=3.5,
                                  b_val=1.0,
                                  min_mag=5.0,
                                  max_mag=6.5,
                                  bin_width=0.1)

        # area source of circular shape with radius of 100 km
        # centered at 0., 0.
        self.area1 = AreaSource(
            source_id='src_1',
            name='area source',
            tectonic_region_type='Active Shallow Crust',
            mfd=self.mfd,
            nodal_plane_distribution=PMF([(1.0, nodalplane)]),
            hypocenter_distribution=PMF([(1.0, 5.0)]),
            upper_seismogenic_depth=0.0,
            lower_seismogenic_depth=10.0,
            magnitude_scaling_relationship=WC1994(),
            rupture_aspect_ratio=1.0,
            polygon=Point(0., 0.).to_polygon(100.),
            area_discretization=9.0,
            rupture_mesh_spacing=1.0,
            temporal_occurrence_model=PoissonTOM(self.time_span))

        # area source of circular shape with radius of 100 km
        # centered at 1., 1.
        self.area2 = AreaSource(
            source_id='src_1',
            name='area source',
            tectonic_region_type='Active Shallow Crust',
            mfd=self.mfd,
            nodal_plane_distribution=PMF([(1.0, nodalplane)]),
            hypocenter_distribution=PMF([(1.0, 5.0)]),
            upper_seismogenic_depth=0.0,
            lower_seismogenic_depth=10.0,
            magnitude_scaling_relationship=WC1994(),
            rupture_aspect_ratio=1.0,
            polygon=Point(5., 5.).to_polygon(100.),
            area_discretization=9.0,
            rupture_mesh_spacing=1.0,
            temporal_occurrence_model=PoissonTOM(self.time_span))

        # non-parametric source
        self.np_src, _ = make_non_parametric_source()

    def _extract_rates(self, ses, time_span, bins):
        """
        Extract annual rates of occurence from stochastic event set
        """
        rates, _ = numpy.histogram([r.mag for r in ses], bins=bins)
        return rates / time_span

    def test_ses_generation_from_parametric_source(self):
        # generate stochastic event set (SES) from area source with given
        # magnitude frequency distribution (MFD). Check that the MFD as
        # obtained from the SES (by making an histogram of the magnitude values
        # and normalizing by the total duration of the event set) is
        # approximately equal to the original MFD.
        numpy.random.seed(123)
        ses = stochastic_event_set([self.area1])
        rates = self._extract_rates(ses,
                                    time_span=self.time_span,
                                    bins=numpy.arange(5., 6.6, 0.1))
        expect_rates = numpy.array(
            [r for m, r in self.mfd.get_annual_occurrence_rates()])
        numpy.testing.assert_allclose(rates, expect_rates, rtol=0, atol=1e-4)

    def test_ses_generation_from_parametric_source_with_filtering(self):
        # generate stochastic event set (SES) from 2 area sources (area1,
        # area2). However, by including a single site co-located with the
        # area1 center, and with source site filtering of 100 km (exactly
        # the radius of area1), the second source (area2), which is centered
        # at 5., 5. (that is about 500 km from center of area1), will be
        # excluded. the MFD from the SES will be therefore approximately equal
        # to the one of area1 only.
        numpy.random.seed(123)
        sites = SiteCollection([
            Site(location=Point(0., 0.),
                 vs30=760,
                 vs30measured=True,
                 z1pt0=40.,
                 z2pt5=2.)
        ])
        ses = stochastic_event_set([self.area1, self.area2],
                                   filters.SourceFilter(
                                       sites,
                                       filters.MagDepDistance.new('100')))

        rates = self._extract_rates(ses,
                                    time_span=self.time_span,
                                    bins=numpy.arange(5., 6.6, 0.1))

        expect_rates = numpy.array(
            [r for m, r in self.mfd.get_annual_occurrence_rates()])

        numpy.testing.assert_allclose(rates, expect_rates, rtol=0, atol=1e-4)

    def test_ses_generation_from_non_parametric_source(self):
        # np_src contains two ruptures: rup1 (of magnitude 5) and rup2 (of
        # magnitude 6)
        # rup1 has probability of zero occurences of 0.7 and of one
        # occurrence of 0.3
        # rup2 has probability of zero occurrence of 0.7, of one occurrence of
        # 0.2 and of two occurrences of 0.1
        # the test generate multiple SESs. From the ensamble of SES the
        # probability of 0, 1, and 2, rupture occurrences is computed and
        # compared with the expected value
        numpy.random.seed(123)
        num_sess = 10000
        sess = [stochastic_event_set([self.np_src]) for i in range(num_sess)]

        # loop over ses. For each ses count number of rupture
        # occurrences (for each magnitude)
        n_rups1 = {}
        n_rups2 = {}
        for i, ses in enumerate(sess):
            n_rups1[i] = 0
            n_rups2[i] = 0
            for rup in ses:
                if rup.mag == 5.:
                    n_rups1[i] += 1
                elif rup.mag == 6.:
                    n_rups2[i] += 1

        # count how many SESs have 0,1 or 2 occurrences, and then normalize
        # by the total number of SESs generated. This gives the probability
        # of having 0, 1 or 2 occurrences
        n_occs1 = numpy.fromiter(n_rups1.values(), int)
        n_occs2 = numpy.fromiter(n_rups2.values(), int)

        p_occs1_0 = (n_occs1 == 0).sum() / num_sess
        p_occs1_1 = (n_occs1 == 1).sum() / num_sess

        p_occs2_0 = (n_occs2 == 0).sum() / num_sess
        p_occs2_1 = (n_occs2 == 1).sum() / num_sess
        p_occs2_2 = (n_occs2 == 2).sum() / num_sess

        self.assertAlmostEqual(p_occs1_0, 0.70, places=2)
        self.assertAlmostEqual(p_occs1_1, 0.30, places=2)
        self.assertAlmostEqual(p_occs2_0, 0.70, places=2)
        self.assertAlmostEqual(p_occs2_1, 0.20, places=2)
        self.assertAlmostEqual(p_occs2_2, 0.10, places=2)
Esempio n. 8
0
class StochasticEventSetTestCase(unittest.TestCase):

    def setUp(self):
        # time span of 10 million years
        self.time_span = 10e6

        nodalplane = NodalPlane(strike=0.0, dip=90.0, rake=0.0)
        self.mfd = TruncatedGRMFD(a_val=3.5, b_val=1.0, min_mag=5.0,
                                  max_mag=6.5, bin_width=0.1)

        # area source of circular shape with radius of 100 km
        # centered at 0., 0.
        self.area1 = AreaSource(
            source_id='src_1',
            name='area source',
            tectonic_region_type='Active Shallow Crust',
            mfd=self.mfd,
            nodal_plane_distribution=PMF([(1.0, nodalplane)]),
            hypocenter_distribution=PMF([(1.0, 5.0)]),
            upper_seismogenic_depth=0.0,
            lower_seismogenic_depth=10.0,
            magnitude_scaling_relationship=WC1994(),
            rupture_aspect_ratio=1.0,
            polygon=Point(0., 0.).to_polygon(100.),
            area_discretization=9.0,
            rupture_mesh_spacing=1.0,
            temporal_occurrence_model=PoissonTOM(self.time_span)
        )

        # area source of circular shape with radius of 100 km
        # centered at 1., 1.
        self.area2 = AreaSource(
            source_id='src_1',
            name='area source',
            tectonic_region_type='Active Shallow Crust',
            mfd=self.mfd,
            nodal_plane_distribution=PMF([(1.0, nodalplane)]),
            hypocenter_distribution=PMF([(1.0, 5.0)]),
            upper_seismogenic_depth=0.0,
            lower_seismogenic_depth=10.0,
            magnitude_scaling_relationship=WC1994(),
            rupture_aspect_ratio=1.0,
            polygon=Point(5., 5.).to_polygon(100.),
            area_discretization=9.0,
            rupture_mesh_spacing=1.0,
            temporal_occurrence_model=PoissonTOM(self.time_span)
        )

        # non-parametric source
        self.np_src, _ = make_non_parametric_source()

    def _extract_rates(self, ses, time_span, bins):
        """
        Extract annual rates of occurence from stochastic event set
        """
        mags = []
        for r in ses:
            mags.append(r.mag)

        rates, _ = numpy.histogram(mags, bins=bins)
        rates = rates / time_span

        return rates

    def test_ses_generation_from_parametric_source(self):
        # generate stochastic event set (SES) from area source with given
        # magnitude frequency distribution (MFD). Check that the MFD as
        # obtained from the SES (by making an histogram of the magnitude values
        # and normalizing by the total duration of the event set) is
        # approximately equal to the original MFD.
        numpy.random.seed(123)
        ses = stochastic_event_set([self.area1])

        rates = self._extract_rates(ses, time_span=self.time_span,
                                    bins=numpy.arange(5., 6.6, 0.1))

        expect_rates = numpy.array(
            [r for m, r in self.mfd.get_annual_occurrence_rates()]
        )

        numpy.testing.assert_allclose(rates, expect_rates, rtol=0, atol=1e-4)

    def test_ses_generation_from_parametric_source_with_filtering(self):
        # generate stochastic event set (SES) from 2 area sources (area1,
        # area2). However, by including a single site co-located with the
        # area1 center, and with source site filtering of 100 km (exactly
        # the radius of area1), the second source (area2), which is centered
        # at 5., 5. (that is about 500 km from center of area1), will be
        # excluded. the MFD from the SES will be therefore approximately equal
        # to the one of area1 only.
        numpy.random.seed(123)
        sites = SiteCollection([
            Site(
                location=Point(0., 0.), vs30=760, vs30measured=True,
                z1pt0=40., z2pt5=2.
            )
        ])
        ses = stochastic_event_set(
            [self.area1, self.area2],
            sites=sites,
            source_site_filter=filters.SourceFilter(sites, 100.)
        )

        rates = self._extract_rates(ses, time_span=self.time_span,
                                    bins=numpy.arange(5., 6.6, 0.1))

        expect_rates = numpy.array(
            [r for m, r in self.mfd.get_annual_occurrence_rates()]
        )

        numpy.testing.assert_allclose(rates, expect_rates, rtol=0, atol=1e-4)

    def test_ses_generation_from_non_parametric_source(self):
        # np_src contains two ruptures: rup1 (of magnitude 5) and rup2 (of
        # magnitude 6)
        # rup1 has probability of zero occurences of 0.7 and of one
        # occurrence of 0.3
        # rup2 has probability of zero occurrence of 0.7, of one occurrence of
        # 0.2 and of two occurrences of 0.1
        # the test generate multiple SESs. From the ensamble of SES the
        # probability of 0, 1, and 2, rupture occurrences is computed and
        # compared with the expected value
        numpy.random.seed(123)
        num_sess = 10000
        sess = [stochastic_event_set([self.np_src]) for i in range(num_sess)]

        # loop over ses. For each ses count number of rupture
        # occurrences (for each magnitude)
        n_rups1 = {}
        n_rups2 = {}
        for i, ses in enumerate(sess):
            n_rups1[i] = 0
            n_rups2[i] = 0
            for rup in ses:
                if rup.mag == 5.:
                    n_rups1[i] += 1
                if rup.mag == 6.:
                    n_rups2[i] += 1

        # count how many SESs have 0,1 or 2 occurrences, and then normalize
        # by the total number of SESs generated. This gives the probability
        # of having 0, 1 or 2 occurrences
        n_occs1 = numpy.array(list(n_rups1.values()))
        n_occs2 = numpy.array(list(n_rups2.values()))

        p_occs1_0 = float(len(n_occs1[n_occs1 == 0])) / num_sess
        p_occs1_1 = float(len(n_occs1[n_occs1 == 1])) / num_sess

        p_occs2_0 = float(len(n_occs2[n_occs2 == 0])) / num_sess
        p_occs2_1 = float(len(n_occs2[n_occs2 == 1])) / num_sess
        p_occs2_2 = float(len(n_occs2[n_occs2 == 2])) / num_sess

        self.assertAlmostEqual(p_occs1_0, 0.7, places=2)
        self.assertAlmostEqual(p_occs1_1, 0.3, places=2)
        self.assertAlmostEqual(p_occs2_0, 0.7, places=2)
        self.assertAlmostEqual(p_occs2_1, 0.2, places=2)
        self.assertAlmostEqual(p_occs2_2, 0.1, places=2)