def _get_v1(imt): """ Calculates Bradley's V1 term. Equation 2 (page 1814) and 6 (page 1816) based on SA period """ if imt == PGA(): v1 = 1800. else: T = imt.period v1a = np.clip((1130 * (T / 0.75)**-0.11), 1130, np.inf) v1 = np.clip(v1a, -np.inf, 1800.) return v1
def setUp(self): d = os.path.dirname(os.path.dirname(__file__)) source_model = os.path.join(d, 'source_model/multi-point-source.xml') [self.sources] = nrml.parse( source_model, SourceConverter(investigation_time=50., rupture_mesh_spacing=2.)) self.site = Site(Point(0.1, 0.1), 800, True, z1pt0=100., z2pt5=1.) self.imt = PGA() self.iml = 0.1 self.truncation_level = 1 self.trt = 'Stable Continental Crust' self.gsims = {self.trt: Campbell2003()}
def test_alatik_youngs_factors(self): self.assertAlmostEqual( self.gsim.get_alatik_youngs_sigma_mu(5.0, -90., PGA()), 0.121) self.assertAlmostEqual( self.gsim.get_alatik_youngs_sigma_mu(5.0, -90., SA(0.5)), 0.121) self.assertAlmostEqual( self.gsim.get_alatik_youngs_sigma_mu(7.5, -90., SA(0.5)), 0.149) self.assertAlmostEqual( self.gsim.get_alatik_youngs_sigma_mu(5.0, -90., SA(np.exp(1))), 0.1381) self.assertAlmostEqual( self.gsim.get_alatik_youngs_sigma_mu(5.0, 90., SA(0.2)), 0.083)
def clip_mean(imt, mean): """ Clip GMPE mean value at 1.5 g for PGA and 3 g for short periods (0.02 < T < 0.55) """ if imt == PGA(): mean[mean > 0.405] = 0.405 if isinstance(imt, SA) and (0.02 < imt.period < 0.55): mean[mean > 1.099] = 1.099 return mean
def test_recarray_conversion(self): # automatic recarray conversion for backward compatibility imt = PGA() gsim = AbrahamsonGulerce2020SInter() ctx = RuptureContext() ctx.mag = 5. ctx.sids = [0, 1] ctx.vs30 = [760., 760.] ctx.rrup = [100., 110.] ctx.occurrence_rate = .000001 mean, _stddevs = gsim.get_mean_and_stddevs(ctx, ctx, ctx, imt, []) numpy.testing.assert_allclose(mean, [-5.81116004, -6.00192455])
def filter_gmpe_list(gmpes, wts, imt): """ Method to remove GMPEs from the GMPE list that are not applicable to a specific IMT. Rescales the weights to sum to one. Args: gmpes (list): List of GMPE instances. wts (list): List of floats indicating the weight of the GMPEs. imt (IMT): OQ IMT to filter GMPE list for. Returns: tuple: List of GMPE instances and list of weights. """ if wts is None: n = len(gmpes) wts = [1 / n] * n per_max = [np.max(get_gmpe_sa_periods(g)) for g in gmpes] per_min = [np.min(get_gmpe_sa_periods(g)) for g in gmpes] if imt == PGA(): sgmpe = [ g for g in gmpes if PGA in g.DEFINED_FOR_INTENSITY_MEASURE_TYPES ] swts = [ w for g, w in zip(gmpes, wts) if PGA in g.DEFINED_FOR_INTENSITY_MEASURE_TYPES ] elif imt == PGV(): sgmpe = [] swts = [] for i in range(len(gmpes)): if (PGV in gmpes[i].DEFINED_FOR_INTENSITY_MEASURE_TYPES) or\ (per_max[i] >= 1.0 and per_min[i] <= 1.0): sgmpe.append(gmpes[i]) swts.append(wts[i]) else: per = imt.period sgmpe = [] swts = [] for i in range(len(gmpes)): if (per_max[i] >= per and per_min[i] <= per): sgmpe.append(gmpes[i]) swts.append(wts[i]) if len(sgmpe) == 0: raise KeyError('No applicable GMPEs from GMPE list for %s' % str(imt)) # Scale weights to sum to one swts = np.array(swts) swts = swts / np.sum(swts) return sgmpe, swts
def compute(self, ctx, imts, mean, sig, tau, phi): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.compute>` for spec of input and result values. """ trt = self.DEFINED_FOR_TECTONIC_REGION_TYPE # extract dictionaries of coefficients specific to PGA # intensity measure type and for PGA C_PGA = self.COEFFS[PGA()] # Get mean PGA on rock (Vs30 760 m/s) pga760 = _get_pga_rock(C_PGA, trt, PGA(), ctx, ctx, ctx) for m, imt in enumerate(imts): # Get the coefficients for the IMT C = self.COEFFS[imt] # Get mean and standard deviations for IMT mean[m] = get_mean_values(C, trt, imt, ctx, ctx, ctx, pga760) tau[m] = C["tau"] phi[m] = C["phi"] sig[:] = np.sqrt(tau**2.0 + phi**2.0)
def setUp(self): self.ctx = ctx = RuptureContext() ctx.mag = 6. ctx.rake = 0. ctx.hypo_depth = 10. ctx.occurrence_rate = .001 sites = Dummy.get_site_collection(4, vs30=760.) for name in sites.array.dtype.names: setattr(ctx, name, sites[name]) ctx.rrup = np.array([1., 10., 30., 70.]) ctx.rjb = np.array([1., 10., 30., 70.]) self.imt = PGA()
def _get_mean_on_soil(self, sctx, rctx, dctx, imt, stddev_types): # Get PGA on rock tmp = PGA() pga_rock = super()._get_mean_on_rock(sctx, rctx, dctx, tmp, stddev_types) pga_rock = np.exp(pga_rock) # Site-effect model: always evaluated for 760 (see HID 2.6.2) vs30_760 = np.zeros_like(sctx.vs30) vs30_760[:] = 760 f_s = get_fs_SeyhanStewart2014(imt, pga_rock, vs30_760) # Compute the mean on soil mean = super()._get_mean_on_rock(sctx, rctx, dctx, imt, stddev_types) mean += f_s return mean
def test_table_string_instantiation(self): # Check that the table instantiates in the conventional way table1 = CoeffsTable(sa_damping=5, table=self.coefficient_string) self.assertDictEqual( table1.non_sa_coeffs, {PGV(): {"a": 0.1, "b": 0.2}, PGA(): {"a": 0.05, "b": 0.1}}) self.assertDictEqual( table1.sa_coeffs, {SA(period=0.1, damping=5): {"a": 1.0, "b": 2.0}, SA(period=1.0, damping=5): {"a": 5.0, "b": 10.0}, SA(period=10.0, damping=5): {"a": 10.0, "b": 20.0}} )
def test_add_delta(self): """Check adding/removing a delta std to the total std""" gmpe_name = 'AkkarEtAlRjb2014' stddevs = [const.StdDev.TOTAL] gmm = ModifiableGMPE(gmpe={gmpe_name: {}}, add_delta_std_to_total_std={"delta": -0.20}) imt = PGA() [stddev] = gmm.get_mean_and_stddevs(self.sites, self.rup, self.dists, imt, stddevs)[1] # Original total std for PGA is 0.7121 np.testing.assert_almost_equal(stddev[0], 0.68344277, decimal=6)
def test_set_total_std_as_tau_plus_phi(self): """Check set total std as between plus phi SS""" gmpe_name = 'AkkarEtAlRjb2014' stddevs = [const.StdDev.TOTAL] gmm = ModifiableGMPE(gmpe={gmpe_name: {}}, set_total_std_as_tau_plus_delta={"delta": 0.45}) imt = PGA() [stddev] = gmm.get_mean_and_stddevs(self.sites, self.rup, self.dists, imt, stddevs)[1] # Original tau for PGA is 0.6201 np.testing.assert_almost_equal(stddev[0], 0.5701491121, decimal=6)
def compute(self, ctx, imts, mean, sig, tau, phi): C_PGA = self.COEFFS[PGA()] pga_rock = _get_pga_on_rock(C_PGA, ctx, ctx) for m, imt in enumerate(imts): C = self.COEFFS[imt] mean[m] = (_get_magnitude_scaling_term(C, ctx) + _get_path_scaling(C, ctx, ctx.mag) + _get_site_scaling(C, pga_rock, ctx)) if imt.string != "PGV": mean[m] = np.log((np.exp(mean[m]) / 981.)) tau[m] = _get_inter_event_tau(C, ctx.mag) phi[m] = C['phi'] sig[:] = np.sqrt(tau**2 + phi**2)
def test_pga(self): sa = SA(period=1e-50, damping=5) pga = PGA() cormo = JB2009CorrelationModel(vs30_clustering=False) corma = cormo._get_correlation_matrix(self.SITECOL, sa) corma2 = cormo._get_correlation_matrix(self.SITECOL, pga) self.assertTrue((corma == corma2).all()) cormo = JB2009CorrelationModel(vs30_clustering=True) corma = cormo._get_correlation_matrix(self.SITECOL, sa) corma2 = cormo._get_correlation_matrix(self.SITECOL, pga) self.assertTrue((corma == corma2).all())
def get_mean_and_stddevs(self, sites, rup, dists, imt, stddev_types): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.get_mean_and_stddevs>` for spec of input and result values. """ # extract dictionaries of coefficients specific to required # intensity measure type and for PGA C = self.COEFFS[imt] dc1 = self._get_delta_c1(imt) C_PGA = self.COEFFS[PGA()] dc1_pga = self._get_delta_c1(PGA()) # compute median pga on rock (vs30=1000), needed for site response # term calculation pga1000 = np.exp( self._compute_pga_rock(C_PGA, dc1_pga, sites, rup, dists)) mean = (self._compute_magnitude_term(C, dc1, rup.mag) + self._compute_distance_term(C, rup.mag, dists) + self._compute_focal_depth_term(C, rup) + self._compute_forearc_backarc_term(C, sites, dists) + self._compute_site_response_term(C, sites, pga1000)) stddevs = self._get_stddevs(C, stddev_types, len(sites.vs30)) return mean, stddevs
def get_mean_and_stddevs(self, sites, rup, dists, imt, stddev_types): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.get_mean_and_stddevs>` for spec of input and result values. """ # extracting dictionary of coefficients (for soil amplification) # specific to required intensity measure type C_SR = self.COEFFS_SOIL_RESPONSE[imt] # compute median PGA on rock (in g), needed to compute non-linear site # amplification C = self.COEFFS_AC10[PGA()] pga4nl = np.exp(self._compute_mean(C, rup.mag, dists.rjb, rup.rake)) * 1e-2 / g # compute full mean value by adding site amplification terms # (but avoiding recomputing mean on rock for PGA) if imt == PGA(): mean = (np.log(pga4nl) + self._get_site_amplification_linear(sites.vs30, C_SR) + self._get_site_amplification_non_linear( sites.vs30, pga4nl, C_SR)) else: C = self.COEFFS_AC10[imt] mean = (self._compute_mean(C, rup.mag, dists.rjb, rup.rake) + self._get_site_amplification_linear(sites.vs30, C_SR) + self._get_site_amplification_non_linear( sites.vs30, pga4nl, C_SR)) # convert from cm/s**2 to g for SA (PGA is already computed in g) if imt.name == "SA": mean = np.log(np.exp(mean) * 1e-2 / g) stddevs = self._get_stddevs(C, stddev_types, num_sites=len(sites.vs30)) return mean, stddevs
def get_mean_and_stddevs(self, sites, rup, dists, imt, stddev_types): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.get_mean_and_stddevs>` for spec of input and result values. """ # extracting dictionary of coefficients specific to required # intensity measure type. C = self.COEFFS_SSLAB[imt] # cap magnitude values at 8.0, see page 1709 mag = rup.mag if mag >= 8.0: mag = 8.0 # compute PGA on rock (needed for site amplification calculation) G = 10 ** (0.301 - 0.01 * mag) pga_rock = self._compute_mean(self.COEFFS_SSLAB[PGA()], G, mag, rup.hypo_depth, dists.rrup, sites.vs30, # by passing pga_rock > 500 the soil # amplification is 0 np.zeros_like(sites.vs30) + 600, PGA()) pga_rock = 10 ** (pga_rock) # compute actual mean and convert from log10 to ln and units from # cm/s**2 to g mean = self._compute_mean(C, G, mag, rup.hypo_depth, dists.rrup, sites.vs30, pga_rock, imt) mean = np.log((10 ** mean) * 1e-2 / g) if isinstance(imt, SA) and imt.period == 4.0: mean /= 0.550 stddevs = self._get_stddevs(C, stddev_types, sites.vs30.shape[0]) return mean, stddevs
def compute(self, ctx, imts, mean, sig, tau, phi): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.compute>` for spec of input and result values. """ C_PGA = self.COEFFS[PGA()] dc1_pga = self.delta_c1 or self.COEFFS_MAG_SCALE[PGA()]["dc1"] # compute median pga on rock (vs30=1000), needed for site response # term calculation pga1000 = np.exp(_compute_pga_rock( self.kind, self.trt, self.theta6_adj, self.faba_model, C_PGA, dc1_pga, ctx)) for m, imt in enumerate(imts): C = self.COEFFS[imt] dc1 = self.delta_c1 or self.COEFFS_MAG_SCALE[imt]["dc1"] mean[m] = ( _compute_magnitude_term( self.kind, C, dc1, ctx.mag) + _compute_distance_term( self.kind, self.trt, self.theta6_adj, C, ctx) + _compute_focal_depth_term( self.trt, C, ctx) + _compute_forearc_backarc_term( self.trt, self.faba_model, C, ctx) + _compute_site_response_term( C, ctx, pga1000)) if self.sigma_mu_epsilon: sigma_mu = get_stress_factor( imt, self.DEFINED_FOR_TECTONIC_REGION_TYPE == const.TRT.SUBDUCTION_INTRASLAB) mean[m] += sigma_mu * self.sigma_mu_epsilon sig[m] = C["sigma"] if self.ergodic else C["sigma_ss"] tau[m] = C['tau'] phi[m] = C["phi"] if self.ergodic else np.sqrt( C["sigma_ss"] ** 2. - C["tau"] ** 2.)
def ground_motion_from_rupture(rupture, sites=None, imts=[PGA()], gsim=ChiouYoungs2014(), truncation_level=4, realizations=1, **kwargs): gm = ground_motion_fields(rupture=rupture, sites=sites, imts=imts, gsim=gsim, truncation_level=truncation_level, realizations=realizations) return gm
def compute(self, ctx, imts, mean, sig, tau, phi): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.compute>` for spec of input and result values. """ ctx_rock = copy.copy(ctx) ctx_rock.vs30 = np.full_like(ctx_rock.vs30, 1100.) mea = contexts.get_mean_stds(self.gmpe, ctx_rock, [PGA()])[0] pga1100 = np.exp(mea[0]) # from shape (M, N) -> N for m, imt in enumerate(imts): C = self.COEFFS[imt] mean[m] = (_compute_base_term(C, ctx) + _compute_faulting_style_term(C, ctx) + _compute_site_response_term(C, imt, ctx, pga1100)) sig[m], tau[m], phi[m] = _get_stddevs(C, ctx)
def get_mean_and_stddevs(self, sites, rup, dists, imt, stddev_types): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.get_mean_and_stddevs>` for spec of input and result values. """ # extract dictionaries of coefficients specific to required # intensity measure type. C_HR = self.COEFFS_HARD_ROCK[imt] C_BC = self.COEFFS_BC[imt] C_SR = self.COEFFS_SOIL_RESPONSE[imt] # clip distances to avoid singularity at 0 rrup = self._clip_distances(dists) # compute factors required for mean value calculation f0 = self._compute_f0_factor(rrup) f1 = self._compute_f1_factor(rrup) f2 = self._compute_f2_factor(rrup) # compute pga for BC boundary (required for soil amplification # calculation on non-hard-rock sites) pga_bc = np.zeros_like(sites.vs30) self._compute_mean(self.COEFFS_BC[PGA()], f0, f1, f2, rup.mag, rrup, sites, sites.vs30 < 2000.0, pga_bc) pga_bc = (10**pga_bc) * 1e-2 / g # compute mean values for hard-rock sites (vs30 >= 2000), # and non-hard-rock sites (vs30 < 2000) and add soil amplification # term mean = np.zeros_like(sites.vs30) self._compute_mean(C_HR, f0, f1, f2, rup.mag, rrup, sites, sites.vs30 >= 2000.0, mean) self._compute_mean(C_BC, f0, f1, f2, rup.mag, rrup, sites, sites.vs30 < 2000.0, mean) self._compute_soil_amplification(C_SR, sites, pga_bc, mean) # convert from base 10 to base e if imt == PGV(): mean = np.log(10**mean) else: # convert from cm/s**2 to g mean = np.log((10**mean) * 1e-2 / g) stddevs = self._get_stddevs(stddev_types, num_sites=len(sites.vs30)) return mean, stddevs
def test_gm_calculationAB06(self): # Modified gmpe mgmpe = NRCan15SiteTerm(gmpe_name='AtkinsonBoore2006') ctx = self.ctx(4, [1000., 1500., 1000., 1500.]) ctx.rrup = np.array([10., 10., 40., 40.]) imt = PGA() stdt = [const.StdDev.TOTAL] # Computes results mean, stds = mgmpe.get_mean_and_stddevs(ctx, ctx, ctx, imt, stdt) # Compute the expected results gmpe = AtkinsonBoore2006() mean_expected, stds_expected = gmpe.get_mean_and_stddevs( ctx, ctx, ctx, imt, stdt) # Test that for reference soil conditions the modified GMPE gives the # same results of the original gmpe np.testing.assert_almost_equal(mean, mean_expected) np.testing.assert_almost_equal(stds, stds_expected)
def test_gm_calculationBA08_vs30variable(self): # Modified gmpe mgmpe = NRCan15SiteTermLinear(gmpe_name='BooreAtkinson2008') ctx = self.ctx(3, vs30=[400., 600, 1000]) ctx.rjb = np.array([10., 10., 10.]) imt = PGA() stdt = [const.StdDev.TOTAL] # Computes results mean, stds = mgmpe.get_mean_and_stddevs(ctx, ctx, ctx, imt, stdt) # Compute the expected results gmpe = BooreAtkinson2008() mean_expected, stds_expected = gmpe.get_mean_and_stddevs( ctx, ctx, ctx, imt, stdt) # Test that for reference soil conditions the modified GMPE gives the # same results of the original gmpe np.testing.assert_almost_equal(mean[:-1], mean_expected[:-1]) np.testing.assert_almost_equal(stds[:-1], stds_expected[:-1])
def test_heteroskedastic_phi(self): mags = self.expected_hetero_pga[:, 0] imt = PGA() # Central Branch phi = [] for mag in mags: phi.append(HETEROSKEDASTIC_PHI["central"](imt, mag)) np.testing.assert_array_almost_equal(np.array(phi), self.expected_hetero_pga[:, 2], 7) imt = SA(1.0) # Central Branch phi = [] for mag in mags: phi.append(HETEROSKEDASTIC_PHI["central"](imt, mag)) np.testing.assert_array_almost_equal(np.array(phi), self.expected_hetero_sa1[:, 2], 7)
def test02(self): avg_periods = [0.05, 0.15, 1.0, 2.0, 4.0] gmm = gsim.mgmpe.generic_gmpe_avgsa.GenericGmpeAvgSA( gmpe_name='AkkarEtAlRepi2014', avg_periods=avg_periods, corr_func='akkar') msg = 'The class name is incorrect' self.assertTrue(gmm.__class__.__name__ == 'GenericGmpeAvgSA', msg=msg) ctx = self.ctx(4, vs30=760.) ctx.repi = np.array([1., 10., 30., 70.]) imtype = PGA() stdt = [const.StdDev.TOTAL] # Computes results mean, _ = gmm.get_mean_and_stddevs(ctx, ctx, ctx, imtype, stdt) expected = np.array([-2.0383581, -2.6548699, -3.767237, -4.7775653]) np.testing.assert_almost_equal(mean, expected)
def test_fixed_total_sigma(self): """Check the assignment of total sigma to a fixed value""" gmpe_name = 'AkkarEtAlRjb2014' stddevs = [const.StdDev.TOTAL] gmm = ModifiableGMPE(gmpe={gmpe_name: {}}, set_fixed_total_sigma={ "total_sigma": { "PGA": 0.6, "SA(0.2)": 0.75 } }) for imt, sfact in zip([PGA(), SA(0.2)], [0.6, 0.75]): [stddev] = gmm.get_mean_and_stddevs(self.sites, self.rup, self.dists, imt, stddevs)[1] np.testing.assert_almost_equal(stddev, sfact * np.ones(stddev.shape))
def test_heteroskedastic_tau(self): mags = self.expected_hetero_pga[:, 0] imt = PGA() # Central Branch tau = [] for mag in mags: tau.append(HETEROSKEDASTIC_TAU["central"](imt, mag)) np.testing.assert_array_almost_equal(np.array(tau), self.expected_hetero_pga[:, 1], 7) imt = SA(1.0) # Central Branch tau = [] for mag in mags: tau.append(HETEROSKEDASTIC_TAU["central"](imt, mag)) np.testing.assert_array_almost_equal(np.array(tau), self.expected_hetero_sa1[:, 1], 7)
def fromFuncs(cls, gmpe, gmice): """ Creates a new VirtualIPE object with the specified MultiGMPE and GMICE. There is no default constructor, you must use this method. Args: gmpe: An instance of the MultiGMPE object. gmice: An instance of a GMICE object. Returns: :class:`VirtualIPE`: A new instance of a VirtualIPE object. """ self = cls() self.gmpe = gmpe self.gmice = gmice if (gmpe.ALL_GMPES_HAVE_PGV is True and PGV in gmice.DEFINED_FOR_INTENSITY_MEASURE_TYPES): self.imt = PGV() elif (PGA in gmpe.DEFINED_FOR_INTENSITY_MEASURE_TYPES and PGA in gmice.DEFINED_FOR_INTENSITY_MEASURE_TYPES): self.imt = PGA() elif (SA in gmpe.DEFINED_FOR_INTENSITY_MEASURE_TYPES and SA in gmice.DEFINED_FOR_INTENSITY_MEASURE_TYPES): self.imt = SA(1.0) else: raise ShakeLibException( 'The supplied GMPE and GMICE do not have a common IMT' ) self.DEFINED_FOR_STANDARD_DEVIATION_TYPES = \ gmpe.DEFINED_FOR_STANDARD_DEVIATION_TYPES.copy() self.REQUIRES_DISTANCES = gmpe.REQUIRES_DISTANCES.copy() self.REQUIRES_RUPTURE_PARAMETERS = \ gmpe.REQUIRES_RUPTURE_PARAMETERS.copy() self.REQUIRES_SITES_PARAMETERS = \ gmpe.REQUIRES_SITES_PARAMETERS.copy() self.DEFINED_FOR_INTENSITY_MEASURE_COMPONENT = \ copy.copy(gmpe.DEFINED_FOR_INTENSITY_MEASURE_COMPONENT) self.DEFINED_FOR_TECTONIC_REGION_TYPE = \ copy.copy(gmpe.DEFINED_FOR_TECTONIC_REGION_TYPE) return self
def get_mean_and_stddevs(self, sctx, rctx, dctx, imt, stddev_types): """ Returns the mean and standard deviations """ # Get the PGA on the reference rock condition if PGA in self.DEFINED_FOR_INTENSITY_MEASURE_TYPES: rock_imt = PGA() else: rock_imt = SA(0.01) pga_r = self.get_hard_rock_mean(rctx, dctx, rock_imt, stddev_types) # Get the desired spectral acceleration on rock if not str(imt) == "PGA": # Calculate the ground motion at required spectral period for # the reference rock imean = self.get_hard_rock_mean(rctx, dctx, imt, stddev_types) else: # Avoid re-calculating PGA if that was already done! imean = np.copy(pga_r) # Get the coefficients for the IMT C_LIN = self.LINEAR_COEFFS[imt] C_F760 = self.F760[imt] C_NL = self.NONLINEAR_COEFFS[imt] site_amp = self.get_site_amplification(imt, np.exp(pga_r), sctx) # Get collapsed amplification model for -sigma, 0, +sigma with weights # of 0.185, 0.63, 0.185 respectively if self.epistemic_site: f_rk = np.log((np.exp(pga_r) + C_NL["f3"]) / C_NL["f3"]) site_amp_sigma = self.get_site_amplification_sigma( sctx, f_rk, C_LIN, C_F760, C_NL) mean = np.log(0.185 * (np.exp(imean + (site_amp - site_amp_sigma))) + 0.63 * (np.exp(imean + site_amp)) + 0.185 * (np.exp(imean + (site_amp + site_amp_sigma)))) else: mean = imean + site_amp # Get standard deviation model nsites = getattr(dctx, self.distance_type).shape stddevs = self.get_stddevs(rctx.mag, sctx.vs30, imt, stddev_types, nsites) return mean, stddevs
def get_mean_and_stddevs(self, sites, rup, dists, imt, stddev_types): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.get_mean_and_stddevs>` for spec of input and result values. """ # extract dictionaries of coefficients specific to required # intensity measure type and for PGA C = self.COEFFS[imt] C_PGA = self.COEFFS[PGA()] # compute median pga on rock (vs30=1100), needed for site response # term calculation # For spectral accelerations at periods between 0.0 and 0.25 s, Sa (T) # cannot be less than PGA on soil, therefore if the IMT is in this # period range it is necessary to calculate PGA on soil if imt.name == 'SA' and imt.period > 0.0 and imt.period < 0.25: get_pga_site = True else: get_pga_site = False pga1100, pga_site = self._compute_imt1100(C_PGA, sites, rup, dists, get_pga_site) # Get the median ground motion mean = (self._compute_magnitude_term(C, rup.mag) + self._compute_distance_term(C, rup, dists) + self._compute_style_of_faulting_term(C, rup) + self._compute_hanging_wall_term(C, rup, dists) + self._compute_shallow_site_response(C, sites, pga1100) + self._compute_basin_response_term(C, sites.z2pt5)) # If it is necessary to ensure that Sa(T) >= PGA (see previous comment) if get_pga_site: idx = mean < np.log(pga_site) mean[idx] = np.log(pga_site[idx]) stddevs = self._get_stddevs(C, sites, pga1100, C_PGA['s_lny'], stddev_types) return mean, stddevs