def split_less(self, sources): """ :yields: pairs (split, sites) """ for src, _sites in self.filter(sources): if src.__class__.__name__.startswith(('Multi', 'Collapsed')): # do not split yield src, _sites elif hasattr(src, 'get_annual_occurrence_rates'): for mag, rate in src.get_annual_occurrence_rates(): new = copy.copy(src) new.mfd = mfd.ArbitraryMFD([mag], [rate]) new.num_ruptures = new.count_ruptures() sites = self.get_close_sites(new) if sites is not None: yield new, sites else: # nonparametric source # data is a list of pairs (rup, pmf) for mag, group in itertools.groupby(src.data, lambda pair: pair[0].mag): new = src.__class__(src.source_id, src.name, src.tectonic_region_type, list(group)) vars(new).update(vars(src)) sites = self.get_close_sites(new) if sites is not None: yield new, sites
def __iter__(self): """ Split an area source into a generator of point sources. MFDs will be rescaled appropriately for the number of points in the area mesh. """ mesh = self.polygon.discretize(self.area_discretization) num_points = len(mesh) area_mfd = self.mfd if isinstance(area_mfd, mfd.TruncatedGRMFD): new_mfd = mfd.TruncatedGRMFD(a_val=area_mfd.a_val - math.log10(num_points), b_val=area_mfd.b_val, bin_width=area_mfd.bin_width, min_mag=area_mfd.min_mag, max_mag=area_mfd.max_mag) elif isinstance(area_mfd, mfd.EvenlyDiscretizedMFD): new_occur_rates = [ x / num_points for x in area_mfd.occurrence_rates ] new_mfd = mfd.EvenlyDiscretizedMFD( min_mag=area_mfd.min_mag, bin_width=area_mfd.bin_width, occurrence_rates=new_occur_rates) elif isinstance(area_mfd, mfd.ArbitraryMFD): new_occur_rates = [ x / num_points for x in area_mfd.occurrence_rates ] new_mfd = mfd.ArbitraryMFD(magnitudes=area_mfd.magnitudes, occurrence_rates=new_occur_rates) elif isinstance(area_mfd, mfd.YoungsCoppersmith1985MFD): new_mfd = mfd.YoungsCoppersmith1985MFD.from_characteristic_rate( area_mfd.min_mag, area_mfd.b_val, area_mfd.char_mag, area_mfd.char_rate / num_points, area_mfd.bin_width) else: raise TypeError('Unknown MFD: %s' % area_mfd) for i, (lon, lat) in enumerate(zip(mesh.lons, mesh.lats)): pt = PointSource( # Generate a new ID and name source_id='%s:%s' % (self.source_id, i), name=self.name, tectonic_region_type=self.tectonic_region_type, mfd=new_mfd, rupture_mesh_spacing=self.rupture_mesh_spacing, magnitude_scaling_relationship=self. magnitude_scaling_relationship, rupture_aspect_ratio=self.rupture_aspect_ratio, upper_seismogenic_depth=self.upper_seismogenic_depth, lower_seismogenic_depth=self.lower_seismogenic_depth, location=geo.Point(lon, lat), nodal_plane_distribution=self.nodal_plane_distribution, hypocenter_distribution=self.hypocenter_distribution, temporal_occurrence_model=self.temporal_occurrence_model) pt.num_ruptures = pt.count_ruptures() yield pt
def area_to_point_sources(area_src): """ Split an area source into a generator of point sources. MFDs will be rescaled appropriately for the number of points in the area mesh. :param area_src: :class:`openquake.hazardlib.source.AreaSource` """ mesh = area_src.polygon.discretize(area_src.area_discretization) num_points = len(mesh) area_mfd = area_src.mfd if isinstance(area_mfd, mfd.TruncatedGRMFD): new_a_val = math.log10(10 ** area_mfd.a_val / float(num_points)) new_mfd = mfd.TruncatedGRMFD( a_val=new_a_val, b_val=area_mfd.b_val, bin_width=area_mfd.bin_width, min_mag=area_mfd.min_mag, max_mag=area_mfd.max_mag) elif isinstance(area_mfd, mfd.EvenlyDiscretizedMFD): new_occur_rates = [float(x) / num_points for x in area_mfd.occurrence_rates] new_mfd = mfd.EvenlyDiscretizedMFD( min_mag=area_mfd.min_mag, bin_width=area_mfd.bin_width, occurrence_rates=new_occur_rates) elif isinstance(area_mfd, mfd.ArbitraryMFD): new_occur_rates = [float(x) / num_points for x in area_mfd.occurrence_rates] new_mfd = mfd.ArbitraryMFD( magnitudes=area_mfd.magnitudes, occurrence_rates=new_occur_rates) for i, (lon, lat) in enumerate(zip(mesh.lons, mesh.lats)): pt = source.PointSource( # Generate a new ID and name source_id='%s-%s' % (area_src.source_id, i), name='%s-%s' % (area_src.name, i), tectonic_region_type=area_src.tectonic_region_type, mfd=new_mfd, rupture_mesh_spacing=area_src.rupture_mesh_spacing, magnitude_scaling_relationship= area_src.magnitude_scaling_relationship, rupture_aspect_ratio=area_src.rupture_aspect_ratio, upper_seismogenic_depth=area_src.upper_seismogenic_depth, lower_seismogenic_depth=area_src.lower_seismogenic_depth, location=geo.Point(lon, lat), nodal_plane_distribution=area_src.nodal_plane_distribution, hypocenter_distribution=area_src.hypocenter_distribution, temporal_occurrence_model=area_src.temporal_occurrence_model) pt.trt_model_id = area_src.trt_model_id pt.num_ruptures = pt.count_ruptures() yield pt
def __iter__(self): mag_rates = self.get_annual_occurrence_rates() if len(mag_rates) == 1: # not splittable yield self return for i, (mag, rate) in enumerate(mag_rates): src = copy.copy(self) del src._nr src.mfd = mfd.ArbitraryMFD([mag], [rate]) src.num_ruptures = self._nr[i] yield src
def __iter__(self): if self.num_ruptures <= MINWEIGHT: yield self # not splittable return mag_rates = self.get_annual_occurrence_rates() for i, (mag, rate) in enumerate(mag_rates): src = copy.copy(self) del src._nr src.mfd = mfd.ArbitraryMFD([mag], [rate]) src.num_ruptures = self._nr[i] for s in split(src): yield s
def split(src, chunksize=MINWEIGHT): """ Split a complex fault source in chunks """ for i, block in enumerate(block_splitter(src.iter_ruptures(), chunksize, key=operator.attrgetter('mag'))): rup = block[0] source_id = '%s:%d' % (src.source_id, i) amfd = mfd.ArbitraryMFD([rup.mag], [rup.mag_occ_rate]) rcs = RuptureCollectionSource( source_id, src.name, src.tectonic_region_type, amfd, block) yield rcs
def convert_mfdist(self, node): """ Convert the given node into a Magnitude-Frequency Distribution object. :param node: a node of kind incrementalMFD or truncGutenbergRichterMFD :returns: a :class:`openquake.hazardlib.mfd.EvenlyDiscretizedMFD.` or :class:`openquake.hazardlib.mfd.TruncatedGRMFD` instance """ with context(self.fname, node): [mfd_node] = [ subnode for subnode in node if subnode.tag.endswith(('incrementalMFD', 'truncGutenbergRichterMFD', 'arbitraryMFD', 'YoungsCoppersmithMFD', 'multiMFD')) ] if mfd_node.tag.endswith('incrementalMFD'): return mfd.EvenlyDiscretizedMFD( min_mag=mfd_node['minMag'], bin_width=mfd_node['binWidth'], occurrence_rates=~mfd_node.occurRates) elif mfd_node.tag.endswith('truncGutenbergRichterMFD'): return mfd.TruncatedGRMFD(a_val=mfd_node['aValue'], b_val=mfd_node['bValue'], min_mag=mfd_node['minMag'], max_mag=mfd_node['maxMag'], bin_width=self.width_of_mfd_bin) elif mfd_node.tag.endswith('arbitraryMFD'): return mfd.ArbitraryMFD(magnitudes=~mfd_node.magnitudes, occurrence_rates=~mfd_node.occurRates) elif mfd_node.tag.endswith('YoungsCoppersmithMFD'): if "totalMomentRate" in mfd_node.attrib.keys(): # Return Youngs & Coppersmith from the total moment rate return mfd.YoungsCoppersmith1985MFD.from_total_moment_rate( min_mag=mfd_node["minMag"], b_val=mfd_node["bValue"], char_mag=mfd_node["characteristicMag"], total_moment_rate=mfd_node["totalMomentRate"], bin_width=mfd_node["binWidth"]) elif "characteristicRate" in mfd_node.attrib.keys(): # Return Youngs & Coppersmith from the total moment rate return mfd.YoungsCoppersmith1985MFD.\ from_characteristic_rate( min_mag=mfd_node["minMag"], b_val=mfd_node["bValue"], char_mag=mfd_node["characteristicMag"], char_rate=mfd_node["characteristicRate"], bin_width=mfd_node["binWidth"]) elif mfd_node.tag.endswith('multiMFD'): return mfd.multi_mfd.MultiMFD.from_node( mfd_node, self.width_of_mfd_bin)
def __iter__(self): mag_rates = self.get_annual_occurrence_rates() if len(mag_rates) == 1: # not splittable yield self return if not hasattr(self, '_nr'): self.count_ruptures() for i, (mag, rate) in enumerate(mag_rates): src = copy.copy(self) src.mfd = mfd.ArbitraryMFD([mag], [rate]) src.num_ruptures = self._nr[i] src.source_id = '%s:%d' % (self.source_id, i) yield src
def __iter__(self): mag_rates = self.get_annual_occurrence_rates() if len(mag_rates) == 1: # not splittable yield self return if not hasattr(self, '_nr'): self.count_ruptures() for i, (mag, rate) in enumerate(mag_rates): # This is needed in order to reproduce the logic in the # `rupture_count` method if rate == 0: continue src = copy.copy(self) src.mfd = mfd.ArbitraryMFD([mag], [rate]) src.num_ruptures = self._nr[i] yield src
def __iter__(self): """ This method splits the ruptures by magnitude and yields as many sources as the number of magnitude bins admitted by the original source. """ if not hasattr(self, '_rupture_rates'): self.count_ruptures() if len(self._rupture_rates) == 1: # not splittable yield self return for mag_lab in self._rupture_count: if self._rupture_rates[mag_lab] == 0: continue src = copy.copy(self) mag = float(mag_lab) src.mfd = mfd.ArbitraryMFD([mag], [self._rupture_rates[mag_lab]]) src.num_ruptures = self._rupture_count[mag_lab] yield src
def split_by_mag(sources): """ Split sources by magnitude """ out = [] for src in sources: if hasattr(src, 'get_annual_occurrence_rates'): for mag, rate in src.get_annual_occurrence_rates(): new = copy.copy(src) new.mfd = mfd.ArbitraryMFD([mag], [rate]) new.num_ruptures = new.count_ruptures() out.append(new) else: # nonparametric source # data is a list of pairs (rup, pmf) for mag, group in itertools.groupby(src.data, lambda pair: pair[0].mag): new = src.__class__(src.source_id, src.name, src.tectonic_region_type, list(group)) out.append(new) return out
def split_fault_source(src): """ Generator splitting a fault source into several fault sources. :param src: an instance of :class:`openquake.hazardlib.source.base.SeismicSource` """ # NB: the splitting is tricky; if you don't split, you will not # take advantage of the multiple cores; if you split too much, # the data transfer will kill you, i.e. multiprocessing/celery # will fail to transmit to the workers the generated sources. i = 0 splitlist = [] mag_rates = [(mag, rate) for (mag, rate) in src.mfd.get_annual_occurrence_rates() if rate] if len(mag_rates) > 1: # split by magnitude bin for mag, rate in mag_rates: new_src = copy.copy(src) new_src.source_id = '%s:%s' % (src.source_id, i) new_src.mfd = mfd.ArbitraryMFD([mag], [rate]) new_src.num_ruptures = new_src.count_ruptures() i += 1 splitlist.append(new_src) elif hasattr(src, 'start'): # split by slice of ruptures for start, stop in _split_start_stop(src.num_ruptures, MAXWEIGHT): new_src = copy.copy(src) new_src.start = start new_src.stop = stop new_src.num_ruptures = stop - start new_src.source_id = '%s:%s' % (src.source_id, i) i += 1 splitlist.append(new_src) else: splitlist.append(src) return splitlist