def check_gmpe_adjustments(self, adj_gmpe_set, original_gmpe): """ Takes a set of three adjusted GMPEs representing the "low", "middle" and "high" stress drop adjustments for Germany and compares them against the original "target" GMPE for a variety of magnitudes and styles of fauling. """ low_gsim, mid_gsim, high_gsim = adj_gmpe_set tot_std = [const.StdDev.TOTAL] for imt in self.imts: for mag in self.mags: for rake in self.rakes: rctx = RuptureContext() rctx.mag = mag rctx.rake = rake rctx.hypo_depth = 10. rctx.width = 0.0001 # Get "original" values mean = original_gmpe.get_mean_and_stddevs( self.sctx, rctx, self.dctx, imt, tot_std)[0] mean = np.exp(mean) # Get "low" adjustments (0.75 times the original) low_mean = low_gsim.get_mean_and_stddevs( self.sctx, rctx, self.dctx, imt, tot_std)[0] np.testing.assert_array_almost_equal( np.exp(low_mean) / mean, 0.75 * np.ones_like(low_mean)) # Get "middle" adjustments (1.25 times the original) mid_mean = mid_gsim.get_mean_and_stddevs( self.sctx, rctx, self.dctx, imt, tot_std)[0] np.testing.assert_array_almost_equal( np.exp(mid_mean) / mean, 1.25 * np.ones_like(mid_mean)) # Get "high" adjustments (1.5 times the original) high_mean = high_gsim.get_mean_and_stddevs( self.sctx, rctx, self.dctx, imt, tot_std)[0] np.testing.assert_array_almost_equal( np.exp(high_mean) / mean, 1.5 * np.ones_like(high_mean))
## This all works..... ## ASK14 = AbrahamsonEtAl2014() IMT = imt.PGA() rctx = RuptureContext() dctx = DistancesContext() sctx = SitesContext() sctx_rock = SitesContext() rctx.rake = 0.0 rctx.dip = 90.0 rctx.ztor = 7.13 rctx.mag = 3.0 #rctx.mag = np.linspace(0.1,5.) rctx.width = 10.0 rctx.hypo_depth = 8.0 #dctx.rrup = np.logspace(1,np.log10(200),100) dctx.rrup = np.logspace(np.log10(10),np.log10(10.0),1) # Assuming average ztor, get rjb: dctx.rjb = np.sqrt(dctx.rrup**2 - rctx.ztor**2) dctx.rhypo = dctx.rrup dctx.rx = dctx.rjb dctx.ry0 = dctx.rx sctx.vs30 = np.ones_like(dctx.rrup) * 760.0 sctx.vs30measured = np.full_like(dctx.rrup, False, dtype='bool') sctx.z1pt0 = np.ones_like(dctx.rrup) * 0.05
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])
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])
# need a dummy origin origin = Origin({ 'id': '', 'netid': '', 'network': '', 'lat': 0, 'lon': 0, 'depth': 0, 'locstring': '', 'mag': 0, 'time': '' }) rupt = get_rupture(origin, filepath, new_format=False) rx.width = rupt.getWidth() rx.ztor = rupt.getDepthToTop() # If there is no fault file, use hypocentral dist for rrup. else: rx.width = 10**(-0.76 + 0.27 * rx.mag) rx.ztor = rx.hypo_depth # Evaluate the GMPE. for i in range(len(imts)): gmpe_imt_mean, gmpe_imt_sd = gmpe.get_mean_and_stddevs( sx, rx, dx, imts[i], sd_types) spectrals[i].append(gmpe_imt_mean) stds[i].append(gmpe_imt_sd) # Flatten lists .
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)