def iter_ruptures(self): """ See :meth: `openquake.hazardlib.source.base.BaseSeismicSource.iter_ruptures`. Uses :func:`_float_ruptures` for finding possible rupture locations on the whole fault surface. """ whole_fault_surface = ComplexFaultSurface.from_fault_data( self.edges, self.rupture_mesh_spacing) whole_fault_mesh = whole_fault_surface.mesh cell_center, cell_length, cell_width, cell_area = ( whole_fault_mesh.get_cell_dimensions()) for mag, mag_occ_rate in self.get_annual_occurrence_rates(): # min_mag is inside get_annual_occurrence_rates if mag_occ_rate == 0: continue rupture_area = self.magnitude_scaling_relationship.get_median_area( mag, self.rake) rupture_length = numpy.sqrt( rupture_area * self.rupture_aspect_ratio) rupture_slices = _float_ruptures( rupture_area, rupture_length, cell_area, cell_length) occurrence_rate = mag_occ_rate / float(len(rupture_slices)) for rupture_slice in rupture_slices: mesh = whole_fault_mesh[rupture_slice] # XXX: use surface centroid as rupture's hypocenter # XXX: instead of point with middle index hypocenter = mesh.get_middle_point() try: surface = ComplexFaultSurface(mesh) except ValueError as e: raise ValueError("Invalid source with id=%s. %s" % ( self.source_id, str(e))) rup = ParametricProbabilisticRupture( mag, self.rake, self.tectonic_region_type, hypocenter, surface, occurrence_rate, self.temporal_occurrence_model) rup.mag_occ_rate = mag_occ_rate yield rup
def get_ucerf_rupture(self, iloc, src_filter): """ :param iloc: Location of the rupture plane in the hdf5 file :param src_filter: Sites for consideration and maximum distance """ trt = self.tectonic_region_type ridx = self.get_ridx(iloc) mag = self.orig.mags[iloc] surface_set = [] indices = src_filter.get_indices(self, ridx, mag) if len(indices) == 0: return None for trace, plane in self.gen_trace_planes(ridx): # build simple fault surface for jloc in range(0, plane.shape[2]): top_left = Point(plane[0, 0, jloc], plane[0, 1, jloc], plane[0, 2, jloc]) top_right = Point(plane[1, 0, jloc], plane[1, 1, jloc], plane[1, 2, jloc]) bottom_right = Point(plane[2, 0, jloc], plane[2, 1, jloc], plane[2, 2, jloc]) bottom_left = Point(plane[3, 0, jloc], plane[3, 1, jloc], plane[3, 2, jloc]) try: surface_set.append( ImperfectPlanarSurface.from_corner_points( top_left, top_right, bottom_right, bottom_left)) except ValueError as err: raise ValueError(err, trace, top_left, top_right, bottom_right, bottom_left) rupture = ParametricProbabilisticRupture( mag, self.orig.rake[iloc], trt, surface_set[len(surface_set) // 2].get_middle_point(), MultiSurface(surface_set), self.orig.rate[iloc], self.tom) return rupture
def _iter_ruptures_at_location(self, temporal_occurrence_model, location, rate_scaling_factor=1): """ The common part of :meth: `openquake.hazardlib.source.point.Point.iter_ruptures` shared between point source and :class:`~openquake.hazardlib.source.area.AreaSource`. :param temporal_occurrence_model: The same object as given to :meth: `openquake.hazardlib.source.base.BaseSeismicSource.iter_ruptures`. :param location: A :class:`~openquake.hazardlib.geo.point.Point` object representing the hypocenter location. In case of :class:`PointSource` it is the one provided to constructor, and for area source the location points are taken from polygon discretization. :param rate_scaling_factor: Positive float number to multiply occurrence rates by. It is used by area source to scale the occurrence rates with respect to number of locations. Point sources use no scaling (``rate_scaling_factor = 1``). """ assert 0 < rate_scaling_factor, rate_scaling_factor for mag, mag_occ_rate in self.get_annual_occurrence_rates(): for np_prob, np in self.nodal_plane_distribution.data: for hc_prob, hc_depth in self.hypocenter_distribution.data: hypocenter = Point(latitude=location.latitude, longitude=location.longitude, depth=hc_depth) occurrence_rate = (mag_occ_rate * np_prob * hc_prob * rate_scaling_factor) surface = self._get_rupture_surface(mag, np, hypocenter) yield ParametricProbabilisticRupture( mag, np.rake, self.tectonic_region_type, hypocenter, surface, occurrence_rate, self.temporal_occurrence_model)
def iter_ruptures(self): """ See :meth: `openquake.hazardlib.source.base.BaseSeismicSource.iter_ruptures`. Uses :func:`_float_ruptures` for finding possible rupture locations on the whole fault surface. """ whole_fault_surface = ComplexFaultSurface.from_fault_data( self.edges, self.rupture_mesh_spacing) whole_fault_mesh = whole_fault_surface.get_mesh() cell_center, cell_length, cell_width, cell_area = ( whole_fault_mesh.get_cell_dimensions()) for (mag, mag_occ_rate) in self.get_annual_occurrence_rates(): rupture_area = self.magnitude_scaling_relationship.get_median_area( mag, self.rake) rupture_length = numpy.sqrt(rupture_area * self.rupture_aspect_ratio) rupture_slices = _float_ruptures(rupture_area, rupture_length, cell_area, cell_length) occurrence_rate = mag_occ_rate / float(len(rupture_slices)) for rupture_slice in rupture_slices[self.start:self.stop]: mesh = whole_fault_mesh[rupture_slice] # XXX: use surface centroid as rupture's hypocenter # XXX: instead of point with middle index hypocenter = mesh.get_middle_point() try: surface = ComplexFaultSurface(mesh) except ValueError as e: raise ValueError("Invalid source with id=%s. %s" % (self.source_id, str(e))) yield ParametricProbabilisticRupture( mag, self.rake, self.tectonic_region_type, hypocenter, surface, type(self), occurrence_rate, self.temporal_occurrence_model)
def get_rupture(self): """ If a rupture is provided then it is returned, otherwise it will use a synthetic rupture generator """ if self.rupture: return rupture else: if len(self.mechanism) >= 1: # Define a set of rupture mechanisms with weight mechanisms = [] for mech, weight in self.mechanism: npd = NodalPlane(self.mechanism["strike"], self.mechanism["dip"], self.mechanism["rake"]) mechanisms.append((weight, npd)) mechanisms = PMF(mechanisms) else: if self.rake: if self.rake >= 45.0 and self.rake <= 135.0: mechanisms = "R" elif self.rake >= -135.0 and self.rake <= -45.: mechanisms = "N" else: mechanisms = "SS" else: mechanisms = "U" # Build planar rupture planar_surface = self.generator.sample_ruptures( Point(self.lon, self.lat, self.depth), self.mag, nsamples=1, mechanisms=mechanisms, dimensions=None)[0] return ParametricProbabilisticRupture( self.mag, self.rake, None, Point(self.lon, self.lat, self.depth), planar_surface, 1.0, None)
def iter_ruptures(self, hcdist=True, npdist=True): """ Generate one rupture for each combination of magnitude, nodal plane and hypocenter depth. """ for mag, mag_occ_rate in self.get_annual_occurrence_rates(): for np_prob, np in self.nodal_plane_distribution.data: for hc_prob, hc_depth in self.hypocenter_distribution.data: hypocenter = Point(latitude=self.location.latitude, longitude=self.location.longitude, depth=hc_depth) occurrence_rate = (mag_occ_rate * (np_prob if npdist else 1) * (hc_prob if hcdist else 1)) surface = self._get_rupture_surface(mag, np, hypocenter) yield ParametricProbabilisticRupture( mag, np.rake, self.tectonic_region_type, hypocenter, surface, occurrence_rate, self.temporal_occurrence_model) if not hcdist: break if not npdist: break
def make_rupture(self): # Create the rupture surface. upper_seismogenic_depth = 3. lower_seismogenic_depth = 15. dip = 90. mesh_spacing = 1. fault_trace_start = Point(28.531397, 40.8790859336) fault_trace_end = Point(28.85, 40.9) fault_trace = Line([fault_trace_start, fault_trace_end]) default_arguments = { 'mag': 6.5, 'rake': 180., 'tectonic_region_type': const.TRT.STABLE_CONTINENTAL, 'hypocenter': Point(28.709146553353872, 40.890863701462457, 11.0), 'surface': SimpleFaultSurface.from_fault_data(fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip=dip, mesh_spacing=mesh_spacing), 'source_typology': object(), 'rupture_slip_direction': 0., 'occurrence_rate': 0.01, 'temporal_occurrence_model': PoissonTOM(50) } kwargs = default_arguments rupture = ParametricProbabilisticRupture(**kwargs) return rupture
def create_ses_ruptures(job, ses_collection, num): """ :param job: the current job, an instance of `openquake.engine.db.models.OqJob` :param ses_collection: an instance of :class:`openquake.engine.db.models.SESCollection` to be associated with the newly created SES object :param int num: the number of ruptures to create :returns: a list of newly created ruptures associated with `job`. It also creates a father :class:`openquake.engine.db.models.SES`. Each rupture has a magnitude ranging from 0 to 10 and no geographic information. """ rupture = ParametricProbabilisticRupture( mag=1 + 10. / float(num), rake=0, tectonic_region_type="test region type", hypocenter=Point(0, 0, 0.1), surface=PlanarSurface( 10, 11, 12, Point(0, 0, 1), Point(1, 0, 1), Point(1, 0, 2), Point(0, 0, 2)), occurrence_rate=1, temporal_occurrence_model=PoissonTOM(10), source_typology=object()) ses_ordinal = 1 seed = 42 pr = models.ProbabilisticRupture.create(rupture, ses_collection) sesruptures = [] for i in range(num): tag = 'col=%02d|ses=%04d|src=test|rup=001-%02d' % ( pr.ses_collection.ordinal, ses_ordinal, i) sr = models.SESRupture.objects.create( rupture=pr, ses_id=ses_ordinal, tag=tag, seed=seed + i) sesruptures.append(sr) return sesruptures
def iter_ruptures(self, **kwargs): """ See :meth: `openquake.hazardlib.source.base.BaseSeismicSource.iter_ruptures` for description of parameters and return value. Area sources are treated as a collection of point sources (see :mod:`openquake.hazardlib.source.point`) with uniform parameters. Ruptures of area source are just a union of ruptures of those point sources. The actual positions of the implied point sources form a uniformly spaced mesh on the polygon. Polygon's method :meth: `~openquake.hazardlib.geo.polygon.Polygon.discretize` is used for creating a mesh of points on the source's area. Constructor's parameter ``area_discretization`` is used as polygon's discretization spacing (not to be confused with rupture surface's mesh spacing which is as well provided to the constructor). The ruptures' occurrence rates are rescaled with respect to number of points the polygon discretizes to. """ polygon_mesh = self.polygon.discretize(self.area_discretization) scaling_rate_factor = 1. / len(polygon_mesh) # take the very first point of the polygon mesh [epicenter0] = polygon_mesh[0:1] # generate "reference ruptures" -- all the ruptures that have the same # epicenter location (first point of the polygon's mesh) but different # magnitudes, nodal planes, hypocenters' depths and occurrence rates # NB: all this mumbo-jumbo is done to avoid multiple calls to # PointSource._get_rupture_surface ref_ruptures = [] for mag, mag_occ_rate in self.get_annual_occurrence_rates(): for np_prob, np in self.nodal_plane_distribution.data: for hc_prob, hc_depth in self.hypocenter_distribution.data: hypocenter = geo.Point(latitude=epicenter0.latitude, longitude=epicenter0.longitude, depth=hc_depth) occurrence_rate = (mag_occ_rate * np_prob * hc_prob * scaling_rate_factor) surface, nhc = PointSource._get_rupture_surface( self, mag, np, hypocenter) if kwargs.get('shift_hypo'): hc_depth = nhc.depth ref_ruptures.append((mag, np.rake, hc_depth, surface, occurrence_rate)) # for each of the epicenter positions generate as many ruptures # as we generated "reference" ones: new ruptures differ only # in hypocenter and surface location for epicenter in polygon_mesh: for mag, rake, hc_depth, surface, occ_rate in ref_ruptures: # translate the surface from first epicenter position # to the target one preserving it's geometry surface = surface.translate(epicenter0, epicenter) hypocenter = deepcopy(epicenter) hypocenter.depth = hc_depth rupture = ParametricProbabilisticRupture( mag, rake, self.tectonic_region_type, hypocenter, surface, occ_rate, self.temporal_occurrence_model) yield rupture
def iter_ruptures(self): """ See :meth: `openquake.hazardlib.source.base.BaseSeismicSource.iter_ruptures`. Generates a ruptures using the "floating" algorithm: for all the magnitude values of assigned MFD calculates the rupture size with respect to MSR and aspect ratio and then places ruptures of that size on the surface of the whole fault source. The occurrence rate of each of those ruptures is the magnitude occurrence rate divided by the number of ruptures that can be placed in a fault. """ whole_fault_surface = SimpleFaultSurface.from_fault_data( self.fault_trace, self.upper_seismogenic_depth, self.lower_seismogenic_depth, self.dip, self.rupture_mesh_spacing) whole_fault_mesh = whole_fault_surface.get_mesh() mesh_rows, mesh_cols = whole_fault_mesh.shape fault_length = float((mesh_cols - 1) * self.rupture_mesh_spacing) fault_width = float((mesh_rows - 1) * self.rupture_mesh_spacing) for (mag, mag_occ_rate) in self.get_annual_occurrence_rates(): rup_cols, rup_rows = self._get_rupture_dimensions( fault_length, fault_width, mag) num_rup_along_length = mesh_cols - rup_cols + 1 num_rup_along_width = mesh_rows - rup_rows + 1 num_rup = num_rup_along_length * num_rup_along_width occurrence_rate = mag_occ_rate / float(num_rup) for first_row in range(num_rup_along_width): for first_col in range(num_rup_along_length): mesh = whole_fault_mesh[first_row:first_row + rup_rows, first_col:first_col + rup_cols] if not len(self.hypo_list) and not len(self.slip_list): hypocenter = mesh.get_middle_point() occurrence_rate_hypo = occurrence_rate surface = SimpleFaultSurface(mesh) yield ParametricProbabilisticRupture( mag, self.rake, self.tectonic_region_type, hypocenter, surface, type(self), occurrence_rate_hypo, self.temporal_occurrence_model) else: for hypo in self.hypo_list: for slip in self.slip_list: surface = SimpleFaultSurface(mesh) hypocenter = surface.get_hypo_location( self.rupture_mesh_spacing, hypo[:2]) occurrence_rate_hypo = occurrence_rate * \ hypo[2] * slip[1] rupture_slip_direction = slip[0] yield ParametricProbabilisticRupture( mag, self.rake, self.tectonic_region_type, hypocenter, surface, type(self), occurrence_rate_hypo, self.temporal_occurrence_model, rupture_slip_direction)
def get_ucerf_rupture(hdf5, iloc, idx_set, tom, sites, integration_distance, mesh_spacing=DEFAULT_MESH_SPACING, trt=DEFAULT_TRT): """ :param hdf5: Source Model hdf5 object as instance of :class: h5py.File :param int iloc: Location of the rupture plane in the hdf5 file :param dict idx_set: Set of indices for the branch Generates a rupture set from a sample of the background model :param tom: Temporal occurrence model as instance of :class: openquake.hazardlib.tom.TOM :param sites: Sites for consideration (can be None!) """ ridx = hdf5[idx_set["geol_idx"] + "/RuptureIndex"][iloc] surface_set = [] if not prefilter_ruptures(hdf5, ridx, idx_set, sites, integration_distance): return None, None for idx in ridx: # Build simple fault surface trace_idx = "{:s}/{:s}".format(idx_set["sec_idx"], str(idx)) rup_plane = hdf5[trace_idx + "/RupturePlanes"][:].astype("float64") for jloc in range(0, rup_plane.shape[2]): top_left = Point(rup_plane[0, 0, jloc], rup_plane[0, 1, jloc], rup_plane[0, 2, jloc]) top_right = Point(rup_plane[1, 0, jloc], rup_plane[1, 1, jloc], rup_plane[1, 2, jloc]) bottom_right = Point(rup_plane[2, 0, jloc], rup_plane[2, 1, jloc], rup_plane[2, 2, jloc]) bottom_left = Point(rup_plane[3, 0, jloc], rup_plane[3, 1, jloc], rup_plane[3, 2, jloc]) try: surface_set.append( PlanarSurface.from_corner_points(mesh_spacing, top_left, top_right, bottom_right, bottom_left)) except ValueError as evl: raise ValueError(evl, trace_idx, top_left, top_right, bottom_right, bottom_left) rupture = ParametricProbabilisticRupture( hdf5[idx_set["mag_idx"]][iloc], # Magnitude hdf5[idx_set["rake_idx"]][iloc], # Rake trt, # Tectonic Region Type surface_set[len(surface_set) / 2].get_middle_point(), # Hypocentre MultiSurface(surface_set), CharacteristicFaultSource, hdf5[idx_set["rate_idx"]][iloc], # Rate of events tom) # Get rupture index code string ridx_string = "-".join(str(val) for val in ridx) return rupture, ridx_string