Пример #1
0
 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
Пример #2
0
    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
Пример #3
0
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
Пример #4
0
 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
Пример #5
0
 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
Пример #6
0
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
Пример #7
0
    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)
Пример #8
0
 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
Пример #9
0
 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
Пример #10
0
 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
Пример #11
0
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
Пример #12
0
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