예제 #1
0
 def test_get_mean_table(self, idx=0):
     """
     Test the retrieval of the mean amplification tables for a given
     magnitude and IMT
     """
     rctx = RuptureContext()
     rctx.mag = 6.0
     # PGA
     expected_table = np.ones([10, 2])
     expected_table[:, self.IDX] *= 1.5
     np.testing.assert_array_almost_equal(
         self.amp_table.get_mean_table(imt_module.PGA(), rctx),
         expected_table)
     # SA
     expected_table[:, self.IDX] = 2.0 * np.ones(10)
     np.testing.assert_array_almost_equal(
         self.amp_table.get_mean_table(imt_module.SA(0.5), rctx),
         expected_table)
     # SA (period interpolation)
     interpolator = interp1d(np.log10(self.amp_table.periods),
                             np.log10(np.array([1.5, 2.0, 0.5])))
     period = 0.3
     expected_table[:, self.IDX] = (10.0**interpolator(
         np.log10(period))) * np.ones(10.)
     np.testing.assert_array_almost_equal(
         self.amp_table.get_mean_table(imt_module.SA(period), rctx),
         expected_table)
예제 #2
0
 def test_retreival_tables_good_no_interp(self):
     """
     Tests the retreival of the IML tables for 'good' conditions without
     applying magnitude interpolations
     """
     gsim = GMPETable(gmpe_table=self.TABLE_FILE)
     # PGA
     np.testing.assert_array_almost_equal(
         gsim._return_tables(6.0, imt_module.PGA(), "IMLs"),
         np.array([2., 1., 0.5]))
     # PGV
     np.testing.assert_array_almost_equal(
         gsim._return_tables(6.0, imt_module.PGV(), "IMLs"),
         np.array([20., 10., 5.]), 5)
     # SA(1.0)
     np.testing.assert_array_almost_equal(
         gsim._return_tables(6.0, imt_module.SA(1.0), "IMLs"),
         np.array([2.0, 1., 0.5]))
     # Also for standard deviations
     np.testing.assert_array_almost_equal(
         gsim._return_tables(6.0, imt_module.PGA(), "Total"),
         0.5 * np.ones(3))
     np.testing.assert_array_almost_equal(
         gsim._return_tables(6.0, imt_module.SA(1.0), "Total"),
         0.8 * np.ones(3))
예제 #3
0
 def test_get_amplification_factors(self):
     """
     Tests the amplification tables
     """
     ctx = RuptureContext()
     ctx.rake = 45.0
     ctx.mag = 6.0
     # Takes distances at the values found in the table (not checking
     # distance interpolation)
     ctx.rjb = np.copy(self.amp_table.distances[:, 0, 0])
     # Test Vs30 is 700.0 m/s midpoint between the 400 m/s and 1000 m/s
     # specified in the table
     stddevs = [const.StdDev.TOTAL]
     expected_mean = np.ones_like(ctx.rjb)
     # Check PGA and PGV
     mean_amp, sigma_amp = self.amp_table.get_amplification_factors(
         imt_module.PGA(), ctx, ctx.rjb, stddevs)
     np.testing.assert_array_almost_equal(
         mean_amp,
         midpoint(1.0, 1.5) * expected_mean)
     np.testing.assert_array_almost_equal(sigma_amp[0], 0.9 * expected_mean)
     mean_amp, sigma_amp = self.amp_table.get_amplification_factors(
         imt_module.PGV(), ctx, ctx.rjb, stddevs)
     np.testing.assert_array_almost_equal(
         mean_amp,
         midpoint(1.0, 0.5) * expected_mean)
     np.testing.assert_array_almost_equal(sigma_amp[0], 0.9 * expected_mean)
     # Sa (0.5)
     mean_amp, sigma_amp = self.amp_table.get_amplification_factors(
         imt_module.SA(0.5), ctx, ctx.rjb, stddevs)
     np.testing.assert_array_almost_equal(
         mean_amp,
         midpoint(1.0, 2.0) * expected_mean)
     np.testing.assert_array_almost_equal(sigma_amp[0], 0.9 * expected_mean)
예제 #4
0
 def test_get_mean_and_stddevs(self):
     """
     Tests mean and standard deviations without amplification
     """
     gsim = GMPETable(gmpe_table=self.TABLE_FILE)
     rctx = RuptureContext()
     rctx.mag = 6.0
     dctx = DistancesContext()
     # Test values at the given distances and those outside range
     dctx.rjb = np.array([0.5, 1.0, 10.0, 100.0, 500.0])
     sctx = SitesContext()
     stddevs = [const.StdDev.TOTAL]
     expected_mean = np.array([2.0, 2.0, 1.0, 0.5, 1.0E-20])
     # PGA
     mean, sigma = gsim.get_mean_and_stddevs(sctx, rctx, dctx,
                                             imt_module.PGA(), stddevs)
     np.testing.assert_array_almost_equal(np.exp(mean), expected_mean, 5)
     np.testing.assert_array_almost_equal(sigma[0], 0.5 * np.ones(5), 5)
     # SA
     mean, sigma = gsim.get_mean_and_stddevs(sctx, rctx, dctx,
                                             imt_module.SA(1.0), stddevs)
     np.testing.assert_array_almost_equal(np.exp(mean), expected_mean, 5)
     np.testing.assert_array_almost_equal(sigma[0], 0.8 * np.ones(5), 5)
     # PGV
     mean, sigma = gsim.get_mean_and_stddevs(sctx, rctx, dctx,
                                             imt_module.PGV(), stddevs)
     np.testing.assert_array_almost_equal(np.exp(mean), 10. * expected_mean,
                                          5)
     np.testing.assert_array_almost_equal(sigma[0], 0.5 * np.ones(5), 5)
예제 #5
0
 def test_get_mean_and_stddevs_good_amplified(self):
     """
     Tests the full execution of the GMPE tables for valid data with
     amplification
     """
     gsim = GMPETable(gmpe_table=self.TABLE_FILE)
     rctx = RuptureContext()
     rctx.mag = 6.0
     dctx = DistancesContext()
     # Test values at the given distances and those outside range
     dctx.rjb = np.array([0.5, 1.0, 10.0, 100.0, 500.0])
     sctx = SitesContext()
     sctx.vs30 = 100. * np.ones(5)
     stddevs = [const.StdDev.TOTAL]
     expected_mean = np.array([20., 20., 10., 5., 1.0E-19])
     expected_sigma = 0.25 * np.ones(5)
     # PGA
     mean, sigma = gsim.get_mean_and_stddevs(sctx, rctx, dctx,
                                             imt_module.PGA(), stddevs)
     np.testing.assert_array_almost_equal(np.exp(mean), expected_mean, 5)
     np.testing.assert_array_almost_equal(sigma[0], expected_sigma, 5)
     # SA
     mean, sigma = gsim.get_mean_and_stddevs(sctx, rctx, dctx,
                                             imt_module.SA(1.0), stddevs)
     np.testing.assert_array_almost_equal(np.exp(mean), expected_mean, 5)
     np.testing.assert_array_almost_equal(sigma[0], 0.4 * np.ones(5), 5)
예제 #6
0
 def _setup_table_from_str(self, table, sa_damping):
     """
     Builds the input tables from a string definition
     """
     table = table.strip().splitlines()
     header = table.pop(0).split()
     if not header[0].upper() == "IMT":
         raise ValueError('first column in a table must be IMT')
     coeff_names = header[1:]
     for row in table:
         row = row.split()
         imt_name = row[0].upper()
         if imt_name == 'SA':
             raise ValueError('specify period as float value '
                              'to declare SA IMT')
         imt_coeffs = dict(zip(coeff_names, map(float, row[1:])))
         try:
             sa_period = float(imt_name)
         except Exception:
             if not hasattr(imt_module, imt_name):
                 raise ValueError('unknown IMT %r' % imt_name)
             imt = getattr(imt_module, imt_name)()
             self.non_sa_coeffs[imt] = imt_coeffs
         else:
             if sa_damping is None:
                 raise TypeError('attribute "sa_damping" is required '
                                 'for tables defining SA')
             imt = imt_module.SA(sa_period, sa_damping)
             self.sa_coeffs[imt] = imt_coeffs
예제 #7
0
 def __init__(self, **kwargs):
     if not 'table' in kwargs:
         raise TypeError('CoeffsTable requires "table" kwarg')
     table = kwargs.pop('table').strip().splitlines()
     sa_damping = kwargs.pop('sa_damping', None)
     if kwargs:
         raise TypeError('CoeffsTable got unexpected kwargs: %r' % kwargs)
     header = table.pop(0).split()
     if not header[0].upper() == "IMT":
         raise ValueError('first column in a table must be IMT')
     coeff_names = header[1:]
     self.sa_coeffs = {}
     self.non_sa_coeffs = {}
     for row in table:
         row = row.split()
         imt_name = row[0].upper()
         if imt_name == 'SA':
             raise ValueError('specify period as float value '
                              'to declare SA IMT')
         imt_coeffs = dict(zip(coeff_names, map(float, row[1:])))
         try:
             sa_period = float(imt_name)
         except:
             if not hasattr(imt_module, imt_name):
                 raise ValueError('unknown IMT %r' % imt_name)
             imt = getattr(imt_module, imt_name)()
             self.non_sa_coeffs[imt] = imt_coeffs
         else:
             if sa_damping is None:
                 raise TypeError('attribute "sa_damping" is required '
                                 'for tables defining SA')
             imt = imt_module.SA(sa_period, sa_damping)
             self.sa_coeffs[imt] = imt_coeffs
예제 #8
0
    def test_get_mean_and_stddevs_good(self):
        """
        Tests the full execution of the GMPE tables for valid data
        """
        gsim = GMPETable(gmpe_table=self.TABLE_FILE)
        ctx = RuptureContext()
        ctx.mag = 6.0
        # Test values at the given distances and those outside range
        ctx.rjb = np.array([0.5, 1.0, 10.0, 100.0, 500.0])
        ctx.vs30 = 1000. * np.ones(5)
        ctx.sids = np.arange(5)
        stddevs = [const.StdDev.TOTAL]
        expected_mean = np.array([2.0, 2.0, 1.0, 0.5, 1.0E-20])
        expected_sigma = 0.25 * np.ones(5)
        imts = [imt_module.PGA(), imt_module.SA(1.0), imt_module.PGV()]
        # PGA
        mean, sigma = gsim.get_mean_and_stddevs(ctx, ctx, ctx, imts[0],
                                                stddevs)
        np.testing.assert_array_almost_equal(np.exp(mean), expected_mean, 5)
        np.testing.assert_array_almost_equal(sigma[0], expected_sigma, 5)
        # SA
        mean, sigma = gsim.get_mean_and_stddevs(ctx, ctx, ctx, imts[1],
                                                stddevs)
        np.testing.assert_array_almost_equal(np.exp(mean), expected_mean, 5)
        np.testing.assert_array_almost_equal(sigma[0], 0.4 * np.ones(5), 5)
        # PGV
        mean, sigma = gsim.get_mean_and_stddevs(ctx, ctx, ctx, imts[2],
                                                stddevs)
        np.testing.assert_array_almost_equal(np.exp(mean), 10. * expected_mean,
                                             5)
        np.testing.assert_array_almost_equal(sigma[0], expected_sigma, 5)

        # StdDev.ALL check
        contexts.get_mean_stds([gsim], ctx, imts)
예제 #9
0
 def test_retreival_tables_outside_period_range(self):
     """
     Tests that an error is raised when inputting a period value
     outside the supported range
     """
     gsim = GMPETable(gmpe_table=self.TABLE_FILE)
     with self.assertRaises(ValueError) as ve:
         gsim._return_tables(6.0, imt_module.SA(2.5), "IMLs")
     self.assertEqual(
         str(ve.exception),
         "Spectral period 2.500 outside of valid range (0.100 to 2.000)")
예제 #10
0
    def test_calculation_mean(self):

        DATA_FILE = data / "AMERI2017/A17_Rjb_Homoscedastic_MEAN.csv"
        stddev_types = [const.StdDev.TOTAL]  # Unused here

        sctx = gsim.base.SitesContext()
        rctx = gsim.base.RuptureContext()
        dctx = gsim.base.DistancesContext()

        with open(DATA_FILE, 'r') as f:

            # Read periods from header:
            header = f.readline()
            periods = header.strip().split(',')[7:]  # Periods in s.

            for line in f:
                arr_str = line.strip().split(',')
                arr_str[
                    5] = "9999"  # Replace result_type string by any float-convertible value
                arr = np.float_(arr_str)

                # Setting ground-motion attributes:
                setattr(rctx, 'mag', arr[0])
                setattr(rctx, 'rake', arr[1])
                stress_drop = arr[2]
                setattr(dctx, 'rjb', arr[3])
                setattr(sctx, 'vs30', np.array([arr[4]]))
                damp = arr[6]

                # Compute ground-motion:
                gmpe = gsim.ameri_2017.AmeriEtAl2017RjbStressDrop(
                    norm_stress_drop=stress_drop)
                for k in range(len(periods)):
                    per = periods[k]
                    value = np.log(arr[
                        7 +
                        k])  # convert value to ln(SA) with SA in units of g
                    if per == 'pga':
                        P = imt.PGA()
                    else:
                        P = imt.SA(period=np.float_(per), damping=damp)
                    mean = gmpe.get_mean_and_stddevs(sctx, rctx, dctx, P,
                                                     stddev_types)[0]
                    np.testing.assert_almost_equal(mean,
                                                   value,
                                                   decimal=MEAN_DECIMAL)
예제 #11
0
 def test_get_sigma_table(self):
     """
     Test the retrieval of the standard deviation modification tables
     for a given magnitude and IMT
     """
     rctx = RuptureContext()
     rctx.mag = 6.0
     # PGA
     expected_table = np.ones([10, 2])
     expected_table[:, self.IDX] *= 0.8
     stddevs = ["Total"]
     pga_table = self.amp_table.get_sigma_tables(imt_module.PGA(), rctx,
                                                 stddevs)[0]
     np.testing.assert_array_almost_equal(pga_table, expected_table)
     # SA (for coverage)
     sa_table = self.amp_table.get_sigma_tables(imt_module.SA(0.3), rctx,
                                                stddevs)[0]
     np.testing.assert_array_almost_equal(sa_table, expected_table)
예제 #12
0
    def test_calculation_std_inter(self):

        DATA_FILE = (data /
                     "AMERI2017/A17_Repi_Homoscedastic_INTER_EVENT_STDDEV.csv")
        stddev_types = [const.StdDev.INTER_EVENT]

        ctx = gsim.base.RuptureContext()

        with open(DATA_FILE, 'r') as f:

            # Read periods from header:
            header = f.readline()
            periods = header.strip().split(',')[7:]  # Periods in s.

            for line in f:
                arr_str = line.strip().split(',')
                arr_str[5] = "9999"
                # Replace result_type string by any float-convertible value
                arr = np.float_(arr_str)

                # Setting ground-motion attributes:
                setattr(ctx, 'mag', arr[0])
                setattr(ctx, 'rake', arr[1])
                stress_drop = arr[2]
                setattr(ctx, 'repi', arr[3])
                setattr(ctx, 'vs30', np.array([arr[4]]))
                damp = arr[6]
                ctx.sids = [0]

                # Compute ground-motion:
                gmpe = gsim.ameri_2017.AmeriEtAl2017RepiStressDrop(
                    norm_stress_drop=stress_drop)
                for k in range(len(periods)):
                    per = periods[k]
                    value = arr[7 + k]
                    if per == 'pga':
                        P = imt.PGA()
                    else:
                        P = imt.SA(period=np.float_(per), damping=damp)
                    std = gmpe.get_mean_and_stddevs(ctx, ctx, ctx, P,
                                                    stddev_types)[1][0]
                    np.testing.assert_almost_equal(std,
                                                   value,
                                                   decimal=STDDEV_DECIMAL)
예제 #13
0
 def test_retreival_tables_good_interp(self):
     """
     Tests the retreival of the IML tables for 'good' conditions with
     magnitude interpolations
     """
     gsim = GMPETable(gmpe_table=self.TABLE_FILE)
     expected_table_pgv = np.array([midpoint(20., 40.),
                                    midpoint(10., 20.),
                                    midpoint(5., 10.)])
     np.testing.assert_array_almost_equal(
         gsim._return_tables(6.5, imt_module.PGV(), "IMLs"),
         expected_table_pgv,
         5)
     expected_table_sa1 = np.array([midpoint(2., 4.),
                                    midpoint(1., 2.),
                                    midpoint(0.5, 1.)])
     np.testing.assert_array_almost_equal(
         gsim._return_tables(6.5, imt_module.SA(1.0), "IMLs"),
         expected_table_sa1)
예제 #14
0
def compute_rho_avgsa(per, avg_periods, sctx, rctx, dctx, stddvs_avgsa, bgmpe,
                      corr_type):
    """
    """
    # Import libraries
    from openquake.hazardlib import imt, const, gsim
    from .modified_akkar_correlation_model import ModifiedAkkarCorrelationModel

    sum_numeratore = 0
    for i1 in avg_periods:
        rho = []
        if corr_type == 'baker_jayaram':
            rho = gsim.mgmpe.generic_gmpe_avgsa. \
                    BakerJayaramCorrelationModel([per, i1])(0, 1)
        if corr_type == 'akkar':
            rho = ModifiedAkkarCorrelationModel([per, i1])(0, 1)
        s = [const.StdDev.TOTAL]
        mean1, std1 = bgmpe().get_mean_and_stddevs(sctx, rctx, dctx,
                                                   imt.SA(i1), s)
        sum_numeratore = sum_numeratore + rho * std1[0]

    denominatore = len(avg_periods) * stddvs_avgsa
    rho_avgsa = sum_numeratore / denominatore
    return rho_avgsa
예제 #15
0
def get_extent(rupture=None, config=None):
    """
    Method to compute map extent from rupture. There are numerous methods for
    getting the extent:
        - It can be specified directly in the config file,
        - it can be hard coded for specific magnitude ranges in the config
          file, or
        - it can be based on the MultiGMPE for the event.

    All methods except for the first requires a rupture object.

    If no config is provided then a rupture is required and the extent is based
    on a generic set of active/stable.

    Args:
        rupture (Rupture): A ShakeMap Rupture instance.
        config (ConfigObj): ShakeMap config object.

    Returns:
        tuple: lonmin, lonmax, latmin, latmax rounded to the nearest
        arc-minute..

    """

    # -------------------------------------------------------------------------
    # Check to see what parameters are specified in the extent config
    # -------------------------------------------------------------------------
    spans = {}
    bounds = []
    if config is not None:
        if 'extent' in config:
            if 'magnitude_spans' in config['extent']:
                if len(config['extent']['magnitude_spans']):
                    if isinstance(config['extent']['magnitude_spans'], dict):
                        spans = config['extent']['magnitude_spans']
            if 'bounds' in config['extent']:
                if 'extent' in config['extent']['bounds']:
                    if config['extent']['bounds']['extent'][0] != -999.0:
                        bounds = config['extent']['bounds']['extent']

    # -------------------------------------------------------------------------
    # Simplest option: extent was specified in the config, use that and exit.
    # -------------------------------------------------------------------------
    if len(bounds):
        xmin, ymin, xmax, ymax = bounds
        return (xmin, xmax, ymin, ymax)

    if not rupture or not isinstance(rupture, Rupture):
        raise TypeError('get_extent() requires a rupture object if the extent '
                        'is not specified in the config object.')

    # Find the central point
    origin = rupture.getOrigin()
    if isinstance(rupture, (QuadRupture, EdgeRupture)):
        # For an extended rupture, it is the midpoint between the extent of the
        # verticies
        lats = rupture.lats
        lons = rupture.lons

        # Remove nans
        lons = lons[~np.isnan(lons)]
        lats = lats[~np.isnan(lats)]

        clat = 0.5 * (np.nanmax(lats) + np.nanmin(lats))
        clon = 0.5 * (np.nanmax(lons) + np.nanmin(lons))
    else:
        # For a point source, it is just the epicenter
        clat = origin.lat
        clon = origin.lon

    mag = origin.mag

    # -------------------------------------------------------------------------
    # Second simplest option: spans are hardcoded based on magnitude
    # -------------------------------------------------------------------------
    if len(spans):
        xmin = None
        xmax = None
        ymin = None
        ymax = None
        for spankey, span in spans.items():
            if mag > span[0] and mag <= span[1]:
                ymin = clat - span[2] / 2
                ymax = clat + span[2] / 2
                xmin = clon - span[3] / 2
                xmax = clon + span[3] / 2
                break
        if xmin is not None:
            return (xmin, xmax, ymin, ymax)

    # -------------------------------------------------------------------------
    # Use MultiGMPE to get spans
    # -------------------------------------------------------------------------
    if config is not None:
        gmpe = MultiGMPE.from_config(config)
        gmice = get_object_from_config('gmice', 'modeling', config)
    else:
        # Put in some default values for conf
        config = {
            'extent': {
                'mmi': {
                    'threshold': 4.5,
                    'mindist': 100,
                    'maxdist': 1000
                }
            }
        }

        # Generic GMPEs choices based only on active vs stable
        # as defaults...
        stable = is_stable(origin.lon, origin.lat)
        if not stable:
            ASK14 = AbrahamsonEtAl2014()
            CB14 = CampbellBozorgnia2014()
            CY14 = ChiouYoungs2014()
            gmpes = [ASK14, CB14, CY14]
            site_gmpes = None
            weights = [1 / 3.0, 1 / 3.0, 1 / 3.0]
            gmice = WGRW12()
        else:
            Fea96 = FrankelEtAl1996MwNSHMP2008()
            Tea97 = ToroEtAl1997MwNSHMP2008()
            Sea02 = SilvaEtAl2002MwNSHMP2008()
            C03 = Campbell2003MwNSHMP2008()
            TP05 = TavakoliPezeshk2005MwNSHMP2008()
            AB06p = AtkinsonBoore2006Modified2011()
            Pea11 = PezeshkEtAl2011()
            Atk08p = Atkinson2008prime()
            Sea01 = SomervilleEtAl2001NSHMP2008()
            gmpes = [
                Fea96, Tea97, Sea02, C03, TP05, AB06p, Pea11, Atk08p, Sea01
            ]
            site_gmpes = [AB06p]
            weights = [0.16, 0.0, 0.0, 0.17, 0.17, 0.3, 0.2, 0.0, 0.0]
            gmice = AK07()

        gmpe = MultiGMPE.from_list(gmpes,
                                   weights,
                                   default_gmpes_for_site=site_gmpes)

    min_mmi = config['extent']['mmi']['threshold']
    default_imt = imt.SA(1.0)
    sd_types = [const.StdDev.TOTAL]

    # Distance context
    dx = DistancesContext()
    # This imposes minimum/ maximum distances of:
    #   80 and 800 km; could make this configurable
    d_min = config['extent']['mmi']['mindist']
    d_max = config['extent']['mmi']['maxdist']
    dx.rjb = np.logspace(np.log10(d_min), np.log10(d_max), 2000)
    # Details don't matter for this; assuming vertical surface rupturing fault
    # with epicenter at the surface.
    dx.rrup = dx.rjb
    dx.rhypo = dx.rjb
    dx.repi = dx.rjb
    dx.rx = np.zeros_like(dx.rjb)
    dx.ry0 = np.zeros_like(dx.rjb)
    dx.rvolc = np.zeros_like(dx.rjb)

    # Sites context
    sx = SitesContext()
    # Set to soft soil conditions
    sx.vs30 = np.full_like(dx.rjb, 180)
    sx = MultiGMPE.set_sites_depth_parameters(sx, gmpe)
    sx.vs30measured = np.full_like(sx.vs30, False, dtype=bool)
    sx = Sites._addDepthParameters(sx)
    sx.backarc = np.full_like(sx.vs30, False, dtype=bool)

    # Rupture context
    rx = RuptureContext()
    rx.mag = origin.mag
    rx.rake = 0.0
    # From WC94...
    rx.width = 10**(-0.76 + 0.27 * rx.mag)
    rx.dip = 90.0
    rx.ztor = origin.depth
    rx.hypo_depth = origin.depth

    gmpe_imt_mean, _ = gmpe.get_mean_and_stddevs(sx, rx, dx, default_imt,
                                                 sd_types)

    # Convert to MMI
    gmpe_to_mmi, _ = gmice.getMIfromGM(gmpe_imt_mean, default_imt)

    # Minimum distance that exceeds threshold MMI?
    dists_exceed_mmi = dx.rjb[gmpe_to_mmi > min_mmi]
    if len(dists_exceed_mmi):
        mindist_km = np.max(dists_exceed_mmi)
    else:
        mindist_km = d_min

    # Get a projection
    proj = OrthographicProjection(clon - 4, clon + 4, clat + 4, clat - 4)
    if isinstance(rupture, (QuadRupture, EdgeRupture)):
        ruptx, rupty = proj(lons, lats)
    else:
        ruptx, rupty = proj(clon, clat)

    xmin = np.nanmin(ruptx) - mindist_km
    ymin = np.nanmin(rupty) - mindist_km
    xmax = np.nanmax(ruptx) + mindist_km
    ymax = np.nanmax(rupty) + mindist_km

    # Put a limit on range of aspect ratio
    dx = xmax - xmin
    dy = ymax - ymin
    ar = dy / dx
    if ar > 1.2:
        # Inflate x
        dx_target = dy / 1.2
        ddx = dx_target - dx
        xmax = xmax + ddx / 2
        xmin = xmin - ddx / 2
    if ar < 0.83:
        # Inflate y
        dy_target = dx * 0.83
        ddy = dy_target - dy
        ymax = ymax + ddy / 2
        ymin = ymin - ddy / 2

    lonmin, latmin = proj(np.array([xmin]), np.array([ymin]), reverse=True)
    lonmax, latmax = proj(np.array([xmax]), np.array([ymax]), reverse=True)

    #
    # Round coordinates to the nearest minute -- that should make the
    # output grid register with common grid resolutions (60c, 30c,
    # 15c, 7.5c)
    #
    logging.debug("Extent: %f, %f, %f, %f" % (lonmin, lonmax, latmin, latmax))
    return _round_coord(lonmin[0]), _round_coord(lonmax[0]), \
        _round_coord(latmin[0]), _round_coord(latmax[0])
예제 #16
0
    dx.rx = np.array([ztest[i, 10]])

    dx.ry0 = np.array([0])
    sx.z1pt0 = np.array([ztest[i, 3]])
    sx.z2pt5 = np.array([ztest[i, 4]])

    # Evaluate GMPE
    #Unit of measure for Z1.0 is [m] (ASK)
    #lmean, lsd = gmpeASK.get_mean_and_stddevs(sx, rx, dx, imt.PGV(), stddev_types)

    #for period1 in period:
    for ii in range(0, 6):
        sx.vs30measured = 0
        period1 = period[ii]
        gmpeBSSAdata[i, ii], g = gmpeBSSA.get_mean_and_stddevs(
            sx, rx, dx, imt.SA(period1), stddev_types)
        gmpeBSSAstd[i, ii] = g[0][0]

        gmpeCBdata[i, ii], g = gmpeCB.get_mean_and_stddevs(
            sx, rx, dx, imt.SA(period1), stddev_types)
        gmpeCBstd[i, ii] = g[0][0]

        gmpeCYdata[i, ii], g = gmpeCY.get_mean_and_stddevs(
            sx, rx, dx, imt.SA(period1), stddev_types)
        gmpeCYstd[i, ii] = g[0][0]

        sx.vs30measured = [0]
        gmpeASKdata[i, ii], g = gmpeASK.get_mean_and_stddevs(
            sx, rx, dx, imt.SA(period1), stddev_types)
        gmpeASKstd[i, ii] = g[0][0]
예제 #17
0
    def get_mean_and_stddevs(self, sites, rx, dists, imt, stddev_types):
        # List of GMPE weights, which is the product of the the branch weights
        # for the seed models vs the NGA East resampled models as well as the
        # weights for the indivudual GMPES as defined by Petersen et al. (2019)
        #
        # Note that the NGA East resampled models are a function of spectral
        # period.
        #
        # NGA East Seeds (1/3)
        #     ├── B_bca10d (0.06633), wts = 0.333 * 0.06633 = 0.02208789
        #     ├── B_ab95 (0.02211), wts = 0.333 * 0.02211 = 0.00736263
        #     ...
        # NGA East Resampled or "USGS" (2/3)
        #     ├── Model 1 (0.1009 for PGA), wts = 0.667 * 0.1009 = 0.0673003
        #     ├── Model 2 (0.1606 for PGA), wts = 0.667 * 0.1606 = 0.1071202
        #     ...
        #
        wts = [0] * len(self.gmpes)

        # Is IMT PGA or PGV?
        is_pga = imt == IMT.PGA()
        is_pgv = imt == IMT.PGV()

        # Is magnitude less than 4? If so, we will need to set it to 4.0 and
        # then extrapolate the tables at the end.
        # But... in the brave new world of new OpenQuake, sites, rx, and
        # dists are all exactly the same object, so when we copy rx to
        # rup, and change it, as well as when we change the distances
        # below, we need to do it all in rup, then pass rup as all three
        # contexts when we call the gmpe.get_mean_and_stddevs()
        rup = copy.deepcopy(rx)
        if rup.mag < 4.0:
            is_small_mag = True
            delta_mag = rup.mag - 4.0
            rup.mag = 4.0
        else:
            is_small_mag = False

        for i, tp in enumerate(self.ALL_TABLE_PATHS):
            if 'usgs' in tp:
                # Get model number from i-th path using regex
                mod_num = int(re.search(r'\d+', tp).group())
                coefs = np.array(self.NGA_EAST_USGS.iloc[mod_num - 1])
                # Is the IMT PGA, PGA, or SA?
                if is_pga:
                    iweight = coefs[-2]
                elif is_pgv:
                    iweight = coefs[-1]
                else:
                    # For SA, need to interpolate; we'll use log-period and
                    # linear-weight interpolation.
                    iweight = np.interp(
                        np.log(imt.period), np.log(self.per_array),
                        coefs[self.per_idx_start:self.per_idx_end])
                wts[i] = self.NGA_EAST_USGS_WEIGHT * iweight
            else:
                # Strip off the cruft to get the string we need to match
                str_match = tp.replace('nga_east_', '').replace('.hdf5', '')
                matched = self.NGA_EAST_SEEDS[self.NGA_EAST_SEEDS['model'] ==
                                              str_match]
                if len(matched):
                    iweight = self.NGA_EAST_SEEDS[self.NGA_EAST_SEEDS['model']
                                                  == str_match].iloc[0, 1]
                    wts[i] = self.NGA_EAST_SEED_WEIGHT * iweight

        total_gmpe_weights = self.sigma_weights * wts

        if not np.allclose(np.sum(total_gmpe_weights), 1.0):
            raise ValueError('Weights must sum to 1.0.')

        mean = np.full_like(sites.vs30, 0)
        stddevs = []
        for i in range(len(stddev_types)):
            stddevs.append(np.full_like(sites.vs30, 0))

        # Apply max distance to dists.rrup -->> now rup.rrup
        np.clip(rup.rrup, 0, MAX_RRUP)

        #
        # Some models don't have PGV terms, so we will make PSA for them
        # and then use the conditional conversion to get PGV
        #
        if is_pgv:
            ab2020 = AbrahamsonBhasin2020(rup.mag)
            vimt = IMT.SA(ab2020.getTref())

        # Loop over gmpes
        for i, gm in enumerate(self.gmpes):
            if is_pgv:
                # Is PGV and also not available for gm?
                try:
                    _ = _return_tables(gm, rup.mag, imt, "IMLs")
                except KeyError:
                    #
                    # No table for PGV, compute vimt, then convert to PGV
                    #
                    vmean, vstddevs = gm.get_mean_and_stddevs(
                        rup, rup, rup, vimt, stddev_types)
                    tmean, tstddevs = ab2020.getPGVandSTDDEVS(
                        vmean, vstddevs, stddev_types, rup.rrup, rup.vs30)
                except Exception:
                    logging.error("Unexpected error:", sys.exc_info()[0])
                else:
                    #
                    # Table exists for PGV, proceed normally
                    #
                    tmean, tstddevs = gm.get_mean_and_stddevs(
                        rup, rup, rup, imt, stddev_types)
            else:
                tmean, tstddevs = gm.get_mean_and_stddevs(
                    rup, rup, rup, imt, stddev_types)

            mean += tmean * total_gmpe_weights[i]
            for j, sd in enumerate(tstddevs):
                stddevs[j] += sd * total_gmpe_weights[i]

        # Zero out values at distances beyond the range for which NGA East
        # was defined. -->> was dists.rrup, now rup.rrup
        mean[rup.rrup > MAX_RRUP] = -999.0

        # Do we need to extrapolate for small magnitude factor?
        if is_small_mag:
            if is_pga:
                slopes = np.interp(np.log(rup.rrup), np.log(self.SMALL_M_DIST),
                                   self.SMALL_M_SLOPE_PGA)
            elif is_pgv:
                slopes = np.interp(np.log(rup.rrup), np.log(self.SMALL_M_DIST),
                                   self.SMALL_M_SLOPE_PGV)
            else:
                interp_obj = RectBivariateSpline(np.log(self.SMALL_M_DIST),
                                                 np.log(self.SMALL_M_PER),
                                                 self.SMALL_M_SLOPE,
                                                 kx=1,
                                                 ky=1)
                slopes = interp_obj.ev(np.log(rup.rrup), np.log(imt.period))
            mean = mean + slopes * delta_mag

        return mean, stddevs
예제 #18
0
def gmpe_avg(ztest):
    '''
    transforms cybershake dips and Rx
    
    Parameters
    ----------
    ztest: 2d numpy array of 12 feature data
    
    Returns
    -------
    model_avg: average of base model predictions in ln m/s2
    '''
    import numpy as np
    import openquake
    from openquake.hazardlib.gsim.abrahamson_2014 import AbrahamsonEtAl2014  #ASK
    from openquake.hazardlib.gsim.campbell_bozorgnia_2014 import CampbellBozorgnia2014  #CB
    from openquake.hazardlib.gsim.chiou_youngs_2014 import ChiouYoungs2014  #CY
    from openquake.hazardlib.gsim.boore_2014 import BooreEtAl2014  #BSSA
    import openquake.hazardlib.imt as imt
    from openquake.hazardlib.const import StdDev
    import openquake.hazardlib.gsim.base as base

    stddev_types = [StdDev.TOTAL]

    period = [10, 7.5, 5, 4, 3, 2, 1, 0.5, 0.2, 0.1]

    gmpeBSSAdata = np.zeros((ztest.shape[0], len(period)))
    gmpeASKdata = np.zeros((ztest.shape[0], len(period)))
    gmpeCBdata = np.zeros((ztest.shape[0], len(period)))
    gmpeCYdata = np.zeros((ztest.shape[0], len(period)))

    gmpeBSSAstd = np.zeros((ztest.shape[0], len(period)))
    gmpeASKstd = np.zeros((ztest.shape[0], len(period)))
    gmpeCBstd = np.zeros((ztest.shape[0], len(period)))
    gmpeCYstd = np.zeros((ztest.shape[0], len(period)))

    gmpeASK = AbrahamsonEtAl2014()
    gmpeCB = CampbellBozorgnia2014()
    gmpeCY = ChiouYoungs2014()
    gmpeBSSA = BooreEtAl2014()

    for i in range(ztest.shape[0]):
        dx = base.DistancesContext()
        dx.rjb = np.array([ztest[i, 9]])

        #dx.rjb = np.logspace(-1, 2, 10)
        # Magnitude and rake
        rx = base.RuptureContext()
        rx.mag = np.array([ztest[i, 0]])
        rx.rake = np.array([ztest[i, 5]])
        rx.hypo_depth = np.array([ztest[i, 7]])
        # Vs30
        sx = base.SitesContext()
        sx.vs30 = np.array([ztest[i, 2]])
        sx.vs30measured = 0

        dx.rrup = np.array([ztest[i, 1]])
        rx.ztor = np.array([ztest[i, 11]])
        rx.dip = np.array([ztest[i, 6]])
        rx.width = np.array([ztest[i, 8]])
        # dx.rx=np.array([rxkeep[i]])
        dx.rx = np.array([ztest[i, 10]])

        dx.ry0 = np.array([0])
        sx.z1pt0 = np.array([ztest[i, 3]])
        sx.z2pt5 = np.array([ztest[i, 4]])

        # Evaluate GMPE
        #Unit of measure for Z1.0 is [m] (ASK)

        #for period1 in period:
        for ii in range(len(period)):
            sx.vs30measured = 0
            period1 = period[ii]
            gmpeBSSAdata[i, ii], g = gmpeBSSA.get_mean_and_stddevs(
                sx, rx, dx, imt.SA(period1), stddev_types)
            gmpeBSSAstd[i, ii] = g[0][0]

            gmpeCBdata[i, ii], g = gmpeCB.get_mean_and_stddevs(
                sx, rx, dx, imt.SA(period1), stddev_types)
            gmpeCBstd[i, ii] = g[0][0]

            gmpeCYdata[i, ii], g = gmpeCY.get_mean_and_stddevs(
                sx, rx, dx, imt.SA(period1), stddev_types)
            gmpeCYstd[i, ii] = g[0][0]

            sx.vs30measured = [0]
            gmpeASKdata[i, ii], g = gmpeASK.get_mean_and_stddevs(
                sx, rx, dx, imt.SA(period1), stddev_types)
            gmpeASKstd[i, ii] = g[0][0]

    model_avg = np.log(9.81 * np.exp(
        np.mean([gmpeBSSAdata, gmpeCBdata, gmpeCYdata, gmpeASKdata], axis=0)))

    #outputs ln m/s2
    return model_avg
예제 #19
0
def oq_run(
    model: Enum,
    tect_type: Enum,
    rupture_df: pd.DataFrame,
    im: str,
    periods: Sequence[Union[int, float]] = None,
    **kwargs,
):
    """Run an openquake model with dataframe
    model: Enum
        OQ model name
    tect_type: Enum
        One of the tectonic types from
        ACTIVE_SHALLOW, SUBDUCTION_SLAB and SUBDUCTION_INTERFACE
    rupture_df: Rupture DF
        Columns for properties. E.g., vs30, z1pt0, rrup, rjb, mag, rake, dip....
        Rows be the separate site-fault pairs
        But Site information must be identical across the rows,
        only the faults can be different.
    im: string
        intensity measure
    periods: Sequence[Union[int, float]]
        for spectral acceleration, openquake tables automatically
        interpolate values between specified values, fails if outside range
    kwargs: pass extra (model specific) parameters to models
    """
    model = (OQ_MODELS[model][tect_type](
        **kwargs) if not model.name.endswith("_NZ") else
             OQ_MODELS[model][tect_type](region="NZL", **kwargs))

    # Check the given tect_type with its model's tect type
    trt = model.DEFINED_FOR_TECTONIC_REGION_TYPE
    if trt == const.TRT.SUBDUCTION_INTERFACE:
        assert tect_type == TectType.SUBDUCTION_INTERFACE
    elif trt == const.TRT.SUBDUCTION_INTRASLAB:
        assert tect_type == TectType.SUBDUCTION_SLAB
    elif trt == const.TRT.ACTIVE_SHALLOW_CRUST:
        assert tect_type == TectType.ACTIVE_SHALLOW
    else:
        raise ValueError("unknown tectonic region: " + trt)

    stddev_types = [
        std for std in SPT_STD_DEVS
        if std in model.DEFINED_FOR_STANDARD_DEVIATION_TYPES
    ]

    # Make a copy in case the original rupture_df used with other functions
    rupture_df = rupture_df.copy()

    # Check if df contains what model requires
    rupture_ctx_properties = set(rupture_df.columns.values)
    extra_site_parameters = set(
        model.REQUIRES_SITES_PARAMETERS).difference(rupture_ctx_properties)
    if len(extra_site_parameters) > 0:
        raise ValueError("unknown site property: " + extra_site_parameters)

    extra_rup_properties = set(
        model.REQUIRES_RUPTURE_PARAMETERS).difference(rupture_ctx_properties)
    if len(extra_rup_properties) > 0:
        raise ValueError("unknown rupture property: " +
                         " ".join(extra_rup_properties))

    extra_dist_properties = set(
        model.REQUIRES_DISTANCES).difference(rupture_ctx_properties)
    if len(extra_dist_properties) > 0:
        raise ValueError("unknown distance property: " +
                         " ".join(extra_dist_properties))

    # Convert z1pt0 from km to m
    rupture_df["z1pt0"] *= 1000
    # OQ's single new-style context which contains all site, distance and rupture's information
    rupture_ctx = contexts.RuptureContext(
        tuple([
            # Openquake requiring occurrence_rate attribute to exist
            ("occurrence_rate", None),
            # sids is the number of sites provided (OQ term)
            # This term needs to be repeated for the number of rows in the df
            ("sids", [1] * rupture_df.shape[0]),
            *((
                column,
                rupture_df.loc[:, column].values,
            ) for column in rupture_df.columns.values),
        ]))

    if periods is not None:
        assert imt.SA in model.DEFINED_FOR_INTENSITY_MEASURE_TYPES
        # use sorted instead of max for full list
        avail_periods = np.asarray([
            im.period
            for im in (model.COEFFS.sa_coeffs.keys() if not isinstance(
                model,
                (
                    gsim.zhao_2006.ZhaoEtAl2006Asc,
                    gsim.zhao_2006.ZhaoEtAl2006SSlab,
                    gsim.zhao_2006.ZhaoEtAl2006SInter,
                ),
            ) else model.COEFFS_ASC.sa_coeffs.keys())
        ])
        max_period = max(avail_periods)
        if not hasattr(periods, "__len__"):
            periods = [periods]
        results = []
        for period in periods:
            im = imt.SA(period=min(period, max_period))
            try:
                result = oq_mean_stddevs(model, rupture_ctx, im, stddev_types)
            except KeyError as ke:
                cause = ke.args[0]
                # To make sure the KeyError is about missing pSA's period
                if (isinstance(cause, imt.IMT) and str(cause).startswith("SA")
                        and cause.period > 0.0):
                    # Period is smaller than model's supported min_period E.g., ZA_06
                    # Interpolate between PGA(0.0) and model's min_period
                    low_result = oq_mean_stddevs(model, rupture_ctx, imt.PGA(),
                                                 stddev_types)
                    high_period = avail_periods[period <= avail_periods][0]
                    high_result = oq_mean_stddevs(model, rupture_ctx,
                                                  imt.SA(period=high_period),
                                                  stddev_types)

                    result = interpolate_with_pga(period, high_period,
                                                  low_result, high_result)
                else:
                    # KeyError that we cannot handle
                    logging.exception(ke)
                    raise
            except Exception as e:
                # Any other exceptions that we cannot handle
                logging.exception(e)
                raise

            # extrapolate pSA value up based on maximum available period
            if period > max_period:
                result.loc[:,
                           result.columns.str.endswith("mean")] += 2 * np.log(
                               max_period / period)
                # Updating the period from max_period to the given period
                # E.g with ZA_06, replace 5.0 to period > 5.0
                result.columns = result.columns.str.replace(str(max_period),
                                                            str(period),
                                                            regex=False)
            results.append(result)

        return pd.concat(results, axis=1)
    else:
        imc = getattr(imt, im)
        assert imc in model.DEFINED_FOR_INTENSITY_MEASURE_TYPES
        return oq_mean_stddevs(model, rupture_ctx, imc(), stddev_types)
예제 #20
0
def oq_run(model, site, fault, im, period=None, **kwargs):
    """
    Run an openquake model using Empirical_Engine input structures.
    model: model or value from empirical.util.classdef.GMM or openquake class:
           GMM.P_20 gsim.parker_2020.ParkerEtAl2020SInter
    site / fault: instances from empirical.classdef -- A tect_type must be able to be set to retrieve the correct model
    im: intensity measure name
    period: for spectral acceleration, openquake tables automatically
            interpolate values between specified values, fails if outside range
    kwargs: pass extra (model specific) parameters to models
    """
    if not OQ:
        raise ImportError("openquake is not installed, models not available")

    # model can be given multiple ways
    if type(model).__name__ == "GMM":
        model = oq_models[model][fault.tect_type](**kwargs)
    elif type(model).__name__ == "MetaGSIM":
        model = model(**kwargs)

    trt = model.DEFINED_FOR_TECTONIC_REGION_TYPE
    if trt == const.TRT.SUBDUCTION_INTERFACE:
        assert fault.tect_type == TectType.SUBDUCTION_INTERFACE
    elif trt == const.TRT.SUBDUCTION_INTRASLAB:
        assert fault.tect_type == TectType.SUBDUCTION_SLAB
    elif trt == const.TRT.ACTIVE_SHALLOW_CRUST:
        assert fault.tect_type == TectType.ACTIVE_SHALLOW
    else:
        raise ValueError("unknown tectonic region: " + trt)

    stddev_types = []
    for st in [
            const.StdDev.TOTAL, const.StdDev.INTER_EVENT,
            const.StdDev.INTRA_EVENT
    ]:
        if st in model.DEFINED_FOR_STANDARD_DEVIATION_TYPES:
            stddev_types.append(st)

    location = Point(
        0.0, 0.0, 0.0
    )  # Create a dummy location as OQ calculation doesn't use a location
    oq_site = Site(location)
    extra_site_parameters = set(model.REQUIRES_SITES_PARAMETERS).difference(
        list(zip(*SITE_PROPERTIES))[0])
    if len(extra_site_parameters) > 0:
        raise ValueError("unknown site property: " + extra_site_parameters)
    oq_site = check_properties(
        site,
        model,
        model.REQUIRES_SITES_PARAMETERS,
        SITE_PROPERTIES,
        oq_site,
        np_array=True,
    )
    if hasattr(oq_site, "z1pt0"):
        oq_site.z1pt0 *= 1000

    sites = SiteCollection([oq_site])

    extra_rup_properties = set(model.REQUIRES_RUPTURE_PARAMETERS).difference(
        list(zip(*RUPTURE_PROPERTIES))[0])
    if len(extra_rup_properties) > 0:
        raise ValueError("unknown rupture property: " +
                         " ".join(extra_rup_properties))
    rupture = check_properties(
        fault,
        model,
        model.REQUIRES_RUPTURE_PARAMETERS,
        RUPTURE_PROPERTIES,
        Properties(),
    )
    # Openquake requiring occurrence_rate attribute to exist
    rupture.occurrence_rate = None
    extra_dist_properties = set(model.REQUIRES_DISTANCES).difference(
        list(zip(*DISTANCE_PROPERTIES))[0])
    if len(extra_dist_properties) > 0:
        raise ValueError("unknown distance property: " +
                         " ".join(extra_dist_properties))
    dists = check_properties(
        site,
        model,
        model.REQUIRES_DISTANCES,
        DISTANCE_PROPERTIES,
        Properties(),
        np_array=True,
    )

    if period is not None:
        assert imt.SA in model.DEFINED_FOR_INTENSITY_MEASURE_TYPES
        # use sorted instead of max for full list
        max_period = max([i.period for i in model.COEFFS.sa_coeffs.keys()])
        single = False
        if not hasattr(period, "__len__"):
            single = True
            period = [period]
        results = []
        for p in period:
            imr = imt.SA(period=min(p, max_period))
            m, s = oq_mean_stddevs(model, sites, rupture, dists, imr,
                                   stddev_types)
            # interpolate pSA value up based on maximum available period
            if p > max_period:
                m = m * (max_period / p)**2
            results.append((m, s))
        if single:
            return results[0]
        return results
    else:
        imc = getattr(imt, im)
        assert imc in model.DEFINED_FOR_INTENSITY_MEASURE_TYPES
        return oq_mean_stddevs(model, sites, rupture, dists, imc(),
                               stddev_types)
예제 #21
0
def compute_cs(t_cs, bgmpe, sctx, rctx, dctx, im_type, t_star, rrup, mag,
               avg_periods, corr_type, im_star, gmpe_input):
    """
    Compute the conditional spectrum according to the procedure outlined
    in Baker JW, Lee C. An Improved Algorithm for Selecting Ground Motions
    to Match a Conditional Spectrum. J Earthq Eng 2018;22:708-23.
    https://doi.org/10.1080/13632469.2016.1264334.

    When the IM and the GMM are defined for the maximum of the two horizontal
    components, the The Boore and Kishida (2017) relationship is applied to
    convert the maximum of the two horizontal components into `RotD50`. This is
    done only for `PGA` and `SA`.
    """
    import numpy as np
    import sys
    from openquake.hazardlib import imt, const, gsim
    from .compute_avgSA import compute_rho_avgsa
    from .modified_akkar_correlation_model import ModifiedAkkarCorrelationModel

    # Use the same periods as the available spectra to construct the
    # conditional spectrum

    p = []
    s = [const.StdDev.TOTAL]
    if im_type == 'AvgSA':
        _ = gsim.get_available_gsims()
        p = imt.AvgSA()
        mgmpe = gsim.mgmpe.generic_gmpe_avgsa.GenericGmpeAvgSA \
            (gmpe_name=gmpe_input, avg_periods=avg_periods, corr_func=corr_type)
        mu_im_cond, sigma_im_cond = mgmpe.get_mean_and_stddevs(
            sctx, rctx, dctx, p, s)
    else:
        if im_type == 'PGA':
            p = imt.PGA()
        else:
            p = imt.SA(t_star)
        s = [const.StdDev.TOTAL]
        mu_im_cond, sigma_im_cond = bgmpe().get_mean_and_stddevs(
            sctx, rctx, dctx, p, s)
    sigma_im_cond = sigma_im_cond[0]

    if (bgmpe.DEFINED_FOR_INTENSITY_MEASURE_COMPONENT ==
            'Greater of two horizontal'):
        if im_type == 'PGA' or im_type == 'SA':
            from shakelib.conversions.imc.boore_kishida_2017 import \
                BooreKishida2017

            bk17 = BooreKishida2017(const.IMC.GREATER_OF_TWO_HORIZONTAL,
                                    const.IMC.RotD50)
            mu_im_cond = bk17.convertAmps(p, mu_im_cond, rrup, float(mag))
            sigma_im_cond = bk17.convertSigmas(p, sigma_im_cond[0])
        else:
            sys.exit('Error: conversion between intensity measures is not '
                     'possible for AvgSA')

    # Compute how many standard deviations the PSHA differs from
    # the GMPE value
    epsilon = (np.log(im_star) - mu_im_cond) / sigma_im_cond

    mu_im = np.zeros(len(t_cs))
    sigma_im = np.zeros(len(t_cs))
    rho_t_tstar = np.zeros(len(t_cs))
    mu_im_im_cond = np.zeros(len(t_cs))

    for i in range(len(t_cs)):
        # Get the GMPE ouput for a rupture scenario
        if t_cs[i] == 0.:
            p = imt.PGA()
        else:
            p = imt.SA(t_cs[i])
        s = [const.StdDev.TOTAL]
        mu0, sigma0 = bgmpe().get_mean_and_stddevs(sctx, rctx, dctx, p, s)

        if (bgmpe.DEFINED_FOR_INTENSITY_MEASURE_COMPONENT ==
                'Greater of two horizontal'):
            if im_type == 'PGA' or im_type == 'SA':
                from shakelib.conversions.imc.boore_kishida_2017 \
                    import BooreKishida2017

                bk17 = BooreKishida2017(const.IMC.GREATER_OF_TWO_HORIZONTAL,
                                        const.IMC.RotD50)

                mu0 = bk17.convertAmps(p, mu0, rrup, float(mag))
                sigma0 = bk17.convertSigmas(p, sigma0[0])

        mu_im[i] = mu0[0]
        sigma_im[i] = sigma0[0][0]
        rho = None
        if im_type == 'AvgSA':
            rho = compute_rho_avgsa(t_cs[i], avg_periods, sctx, rctx, dctx,
                                    sigma_im_cond, bgmpe, corr_type)
            rho = rho[0]

        else:
            if corr_type == 'baker_jayaram':
                rho = gsim.mgmpe.generic_gmpe_avgsa. \
                    BakerJayaramCorrelationModel([t_cs[i], t_star])(0, 1)
            if corr_type == 'akkar':
                rho = ModifiedAkkarCorrelationModel([t_cs[i], t_star])(0, 1)
        rho_t_tstar[i] = rho
        # Get the value of the CMS
        mu_im_im_cond[i] = \
            mu_im[i] + rho_t_tstar[i] * epsilon[0] * sigma_im[i]

    # Compute covariances and correlations at all periods
    cov = np.zeros((len(t_cs), len(t_cs)))
    for i in np.arange(len(t_cs)):
        for j in np.arange(len(t_cs)):
            var1 = sigma_im[i]**2
            var2 = sigma_im[j]**2
            var_tstar = sigma_im_cond**2

            sigma_corr = []
            if corr_type == 'baker_jayaram':
                sigma_corr = gsim.mgmpe.generic_gmpe_avgsa. \
                    BakerJayaramCorrelationModel([t_cs[i], t_cs[j]])(0, 1) * \
                    np.sqrt(var1 * var2)
            if corr_type == 'akkar':
                sigma_corr = ModifiedAkkarCorrelationModel([t_cs[i], t_cs[j]])(0, 1) * \
                    np.sqrt(var1 * var2)
            sigma11 = np.matrix([[var1, sigma_corr], [sigma_corr, var2]])
            sigma22 = np.array(var_tstar)
            sigma12 = np.array([
                rho_t_tstar[i] * np.sqrt(var1 * var_tstar),
                rho_t_tstar[j] * np.sqrt(var_tstar * var2)
            ])
            sigma_cond = sigma11 - sigma12 * 1. / (sigma22) * sigma12.T
            cov[i, j] = sigma_cond[0, 1]

    # find covariance values of zero and set them to a small number
    # so that random number generation can be performed
    cov[np.absolute(cov) < 1e-10] = 1e-10
    stdevs = np.sqrt(np.diagonal(cov))

    return mu_im_im_cond, cov, stdevs
예제 #22
0
 def test_pickeable(self):
     for imt in (imt_module.PGA(), imt_module.SA(0.2)):
         imt_pik = pickle.dumps(imt, pickle.HIGHEST_PROTOCOL)
         self.assertEqual(pickle.loads(imt_pik), imt)
예제 #23
0
def _get_extent_from_multigmpe(rupture, config=None):
    """
    Use MultiGMPE to determine extent
    """
    (clon, clat) = _rupture_center(rupture)
    origin = rupture.getOrigin()
    if config is not None:
        gmpe = MultiGMPE.from_config(config)
        gmice = get_object_from_config('gmice', 'modeling', config)
        if imt.SA in gmice.DEFINED_FOR_INTENSITY_MEASURE_TYPES:
            default_imt = imt.SA(1.0)
        elif imt.PGV in gmice.DEFINED_FOR_INTENSITY_MEASURE_TYPES:
            default_imt = imt.PGV()
        else:
            default_imt = imt.PGA()
    else:
        # Put in some default values for conf
        config = {
            'extent': {
                'mmi': {
                    'threshold': 4.5,
                    'mindist': 100,
                    'maxdist': 1000
                }
            }
        }

        # Generic GMPEs choices based only on active vs stable
        # as defaults...
        stable = is_stable(origin.lon, origin.lat)
        if not stable:
            ASK14 = AbrahamsonEtAl2014()
            CB14 = CampbellBozorgnia2014()
            CY14 = ChiouYoungs2014()
            gmpes = [ASK14, CB14, CY14]
            site_gmpes = None
            weights = [1/3.0, 1/3.0, 1/3.0]
            gmice = WGRW12()
        else:
            Fea96 = FrankelEtAl1996MwNSHMP2008()
            Tea97 = ToroEtAl1997MwNSHMP2008()
            Sea02 = SilvaEtAl2002MwNSHMP2008()
            C03 = Campbell2003MwNSHMP2008()
            TP05 = TavakoliPezeshk2005MwNSHMP2008()
            AB06p = AtkinsonBoore2006Modified2011()
            Pea11 = PezeshkEtAl2011()
            Atk08p = Atkinson2008prime()
            Sea01 = SomervilleEtAl2001NSHMP2008()
            gmpes = [Fea96, Tea97, Sea02, C03,
                     TP05, AB06p, Pea11, Atk08p, Sea01]
            site_gmpes = [AB06p]
            weights = [0.16, 0.0, 0.0, 0.17, 0.17, 0.3, 0.2, 0.0, 0.0]
            gmice = AK07()

        gmpe = MultiGMPE.from_list(
            gmpes, weights, default_gmpes_for_site=site_gmpes)
        default_imt = imt.SA(1.0)

    min_mmi = config['extent']['mmi']['threshold']
    sd_types = [const.StdDev.TOTAL]

    # Distance context
    dx = DistancesContext()
    # This imposes minimum/ maximum distances of:
    #   80 and 800 km; could make this configurable
    d_min = config['extent']['mmi']['mindist']
    d_max = config['extent']['mmi']['maxdist']
    dx.rjb = np.logspace(np.log10(d_min), np.log10(d_max), 2000)
    # Details don't matter for this; assuming vertical surface rupturing fault
    # with epicenter at the surface.
    dx.rrup = dx.rjb
    dx.rhypo = dx.rjb
    dx.repi = dx.rjb
    dx.rx = np.zeros_like(dx.rjb)
    dx.ry0 = np.zeros_like(dx.rjb)
    dx.rvolc = np.zeros_like(dx.rjb)

    # Sites context
    sx = SitesContext()
    # Set to soft soil conditions
    sx.vs30 = np.full_like(dx.rjb, 180)
    sx = MultiGMPE.set_sites_depth_parameters(sx, gmpe)
    sx.vs30measured = np.full_like(sx.vs30, False, dtype=bool)
    sx = Sites._addDepthParameters(sx)
    sx.backarc = np.full_like(sx.vs30, False, dtype=bool)

    # Rupture context
    rx = RuptureContext()
    rx.mag = origin.mag
    rx.rake = 0.0
    # From WC94...
    rx.width = 10**(-0.76 + 0.27*rx.mag)
    rx.dip = 90.0
    rx.ztor = origin.depth
    rx.hypo_depth = origin.depth

    gmpe_imt_mean, _ = gmpe.get_mean_and_stddevs(
        sx, rx, dx, default_imt, sd_types)

    # Convert to MMI
    gmpe_to_mmi, _ = gmice.getMIfromGM(gmpe_imt_mean, default_imt)

    # Minimum distance that exceeds threshold MMI?
    dists_exceed_mmi = dx.rjb[gmpe_to_mmi > min_mmi]
    if len(dists_exceed_mmi):
        mindist_km = np.max(dists_exceed_mmi)
    else:
        mindist_km = d_min

    # Get a projection
    proj = OrthographicProjection(clon - 4, clon + 4, clat + 4, clat - 4)
    if isinstance(rupture, (QuadRupture, EdgeRupture)):
        ruptx, rupty = proj(
            rupture.lons[~np.isnan(rupture.lons)],
            rupture.lats[~np.isnan(rupture.lats)]
        )
    else:
        ruptx, rupty = proj(clon, clat)

    xmin = np.nanmin(ruptx) - mindist_km
    ymin = np.nanmin(rupty) - mindist_km
    xmax = np.nanmax(ruptx) + mindist_km
    ymax = np.nanmax(rupty) + mindist_km

    # Put a limit on range of aspect ratio
    dx = xmax - xmin
    dy = ymax - ymin
    ar = dy / dx
    if ar > 1.2:
        # Inflate x
        dx_target = dy / 1.2
        ddx = dx_target - dx
        xmax = xmax + ddx / 2
        xmin = xmin - ddx / 2
    if ar < 0.83:
        # Inflate y
        dy_target = dx * 0.83
        ddy = dy_target - dy
        ymax = ymax + ddy / 2
        ymin = ymin - ddy / 2

    lonmin, latmin = proj(np.array([xmin]), np.array([ymin]), reverse=True)
    lonmax, latmax = proj(np.array([xmax]), np.array([ymax]), reverse=True)

    #
    # Round coordinates to the nearest minute -- that should make the
    # output grid register with common grid resolutions (60c, 30c,
    # 15c, 7.5c)
    #
    logging.debug("Extent: %f, %f, %f, %f" %
                  (lonmin, lonmax, latmin, latmax))
    return _round_coord(lonmin[0]), _round_coord(lonmax[0]), \
        _round_coord(latmin[0]), _round_coord(latmax[0])
예제 #24
0
from shakelib.gmpe.nga_east import NGAEast

home_dir = os.path.dirname(os.path.abspath(__file__))
data_dir = os.path.join(home_dir, 'nga_east_data')

stddev_types = [StdDev.TOTAL]
gmpe = NGAEast()

dx = base.DistancesContext()
dx.rrup = np.logspace(-1, np.log10(2000), 100)

rx = base.RuptureContext()
sx = base.SitesContext()

IMTS = [imt.PGA(), imt.PGV(), imt.SA(0.3), imt.SA(1.0), imt.SA(3.0)]

MAGS = [3, 5, 6, 7]

VS30 = [180, 380, 760, 2000]


def update_results():
    # To build the data for testing
    result = {}
    for i in IMTS:
        ikey = i.__str__()
        result[ikey] = {}
        for mag in MAGS:
            rx.mag = mag
            result[ikey][str(mag)] = {}
예제 #25
0
def test_scr_rlme():
    old_gmpe = set_gmpe('stable_continental_nshmp2014_rlme')
    spec_file = pkg_resources.resource_filename(
        'scenarios', os.path.join('data', 'configspec.conf'))
    validator = get_custom_validator()
    config = ConfigObj(os.path.join(os.path.expanduser('~'), 'scenarios.conf'),
                       configspec=spec_file)
    tmp = pkg_resources.resource_filename(
        'scenarios', os.path.join('..', 'data', 'gmpe_sets.conf'))
    config.merge(ConfigObj(tmp, configspec=spec_file))
    tmp = pkg_resources.resource_filename(
        'scenarios', os.path.join('..', 'data', 'modules.conf'))
    config.merge(ConfigObj(tmp, configspec=spec_file))
    results = config.validate(validator)
    if results != True:
        config_error(config, results)

    # MultiGMPE from config
    config = config.dict()
    gmpe = MultiGMPE.from_config(config)

    # Input stuff
    IMT = imt.SA(1.0)
    rctx = RuptureContext()
    dctx = DistancesContext()
    sctx = SitesContext()

    rctx.rake = 0.0
    rctx.dip = 90.0
    rctx.ztor = 0.0
    rctx.mag = 8.0
    rctx.width = 10.0
    rctx.hypo_depth = 8.0

    dctx.rjb = np.logspace(1, np.log10(800), 100)
    dctx.rrup = dctx.rjb
    dctx.rhypo = dctx.rjb
    dctx.rx = dctx.rjb
    dctx.ry0 = dctx.rjb

    sctx.vs30 = np.ones_like(dctx.rjb) * 275.0
    sctx.vs30measured = np.full_like(dctx.rjb, False, dtype='bool')
    sctx = MultiGMPE.set_sites_depth_parameters(sctx, gmpe)

    # Evaluate
    conf_lmean, dummy = gmpe.get_mean_and_stddevs(sctx, rctx, dctx, IMT,
                                                  [const.StdDev.TOTAL])

    target_lmean = np.array([
        0.10556736, 0.0839267, 0.06189444, 0.03945984, 0.01661264, -0.006657,
        -0.03035844, -0.05450058, -0.07909179, -0.10413995, -0.1296524,
        -0.15563655, -0.1821091, -0.20909381, -0.23661405, -0.26469259,
        -0.29335086, -0.32257956, -0.35232905, -0.38254639, -0.41317807,
        -0.44417017, -0.47549552, -0.5071888, -0.53929293, -0.57185042,
        -0.60490345, -0.63848027, -0.67255251, -0.70707712, -0.74201096,
        -0.77731091, -0.81293906, -0.84889737, -0.88520644, -0.92188724,
        -0.95899471, -0.99699613, -1.03583184, -1.07530664, -1.11531737,
        -1.15576129, -1.19653696, -1.23757689, -1.2772327, -1.2915098,
        -1.30576498, -1.32001713, -1.33429606, -1.3486727, -1.36322545,
        -1.37803346, -1.39317668, -1.40677752, -1.42081409, -1.43538898,
        -1.45056417, -1.46640223, -1.48327111, -1.50656497, -1.53368548,
        -1.56645985, -1.59991327, -1.63399401, -1.66867278, -1.7039438,
        -1.73980246, -1.77624473, -1.81326727, -1.85087166, -1.889066,
        -1.92784814, -1.96721442, -2.0071855, -2.04779304, -2.08909259,
        -2.13114448, -2.17401045, -2.21775376, -2.26243406, -2.30808979,
        -2.35475487, -2.40246494, -2.4512575, -2.50117075, -2.55223495,
        -2.60447754, -2.65792811, -2.71261851, -2.61732716, -2.67007323,
        -2.72399057, -2.77918054, -2.83574666, -2.89379416, -2.95340501,
        -3.01462691, -3.07750731, -3.14209631, -3.20844679
    ])

    np.testing.assert_allclose(conf_lmean, target_lmean, atol=1e-6)

    # Redo for 3 sec so some GMPEs are filtered out
    IMT = imt.SA(3.0)
    gmpe = MultiGMPE.from_config(config, filter_imt=IMT)
    conf_lmean, dummy = gmpe.get_mean_and_stddevs(sctx, rctx, dctx, IMT,
                                                  [const.StdDev.TOTAL])

    target_lmean = np.array([
        -1.26636973, -1.289514, -1.31300386, -1.33683936, -1.36102084,
        -1.38554902, -1.41042497, -1.43565015, -1.46122642, -1.48715602,
        -1.51344154, -1.54008586, -1.56709215, -1.59446375, -1.62220409,
        -1.65031664, -1.6788048, -1.70767178, -1.7369205, -1.76655351,
        -1.79657287, -1.82698005, -1.85777587, -1.88896039, -1.92053288,
        -1.95249175, -1.98483453, -2.01755788, -2.05065755, -2.08412844,
        -2.11796463, -2.15215943, -2.18670547, -2.22159473, -2.25681869,
        -2.29236835, -2.32823441, -2.36453464, -2.40140834, -2.43883442,
        -2.47679132, -2.51525752, -2.55421156, -2.59363211, -2.63112832,
        -2.63336521, -2.63582817, -2.6385319, -2.64147962, -2.64466761,
        -2.64809268, -2.65175214, -2.6556438, -2.65976592, -2.66411721,
        -2.66869673, -2.67350386, -2.67853821, -2.68413311, -2.69604497,
        -2.7124745, -2.73590549, -2.75964098, -2.78367044, -2.80798539,
        -2.8325853, -2.85746998, -2.88263948, -2.90809408, -2.93383429,
        -2.95986073, -2.98617306, -3.01275705, -3.03961495, -3.06675608,
        -3.09419043, -3.12192861, -3.14998191, -3.17836228, -3.20708239,
        -3.23615561, -3.26559604, -3.29541858, -3.32563888, -3.35627343,
        -3.38733956, -3.41885548, -3.4508403, -3.48331409, -3.56476842,
        -3.59987076, -3.63573296, -3.67238872, -3.70987332, -3.74822369,
        -3.78747847, -3.82767809, -3.86886488, -3.91108308, -3.95437899
    ])

    np.testing.assert_allclose(conf_lmean, target_lmean, atol=1e-6)

    # Clean up
    set_gmpe(old_gmpe)