def get_fault_sources(filename,
                      slip_rate_class,
                      bin_width=0.1,
                      m_low=6.5,
                      b_gr=1.0,
                      rupture_mesh_spacing=2.0,
                      upper_seismogenic_depth=0.0,
                      lower_seismogenic_depth=10.0,
                      msr=WC1994(),
                      rupture_aspect_ratio=2.0,
                      temporal_occurrence_model=PoissonTOM(1.0),
                      aseismic_coeff=0.9,
                      oqsource=False):
    """
    :parameter filename:
        The name of the .geojson file with fault data
    :parameter slip_rate_class:

    TODO: so far works only for slip_rate_class = "suggested/preferred"
    """

    logging.info('Reading %s and slip_type = %s' % (filename, slip_rate_class))
    with open(filename, 'r') as data_file:
        data = json.load(data_file)

    print('---------------------------------------'
          '---------------------------------------')

    # Configuration parameters to create the sources
    # TODO:
    # use b_gr values from the area_sources and not a generic value
    # to test the whole processing

    # LOOP over the faults/traces
    srcl = []
    for idf, feature in enumerate(data['features']):

        source_id = '{0:d}'.format(idf)
        tectonic_region_type = TRT.ACTIVE_SHALLOW_CRUST

        fs_name = ''
        ns_name = ''

        # get fault name[s] - id
        if feature['properties']['fs_name'] is not None:
            fs_name = feature['properties']['fs_name']
        if feature['properties']['fs_name'] is not None:
            ns_name = feature['properties']['fs_name']
        name = '{0:s} | {1:s}'.format(fs_name, ns_name)
        if 'ogc_fid' in feature['properties']:
            id_fault = feature['properties']['ogc_fid']
        else:
            id_fault = '%d' % (idf)

        # get fault slip type
        if feature['properties']['slip_type'] is not None:
            slipt = feature['properties']['slip_type']
            msg = 'Slip type value is [%s] for fault with name' % slipt
            msg += '%s and id %s' % (name, id_fault)
            logging.info(msg)
        else:
            msg = 'Slip type value is missing for fault with name'
            msg += '%s and id %s' % (name, id_fault)
            logging.warning(msg)

        # get dip direction
        if feature['properties']['ns_dip_dir'] is not None:
            dip_dir = feature['properties']['ns_dip_dir']
            print("'dip_dir'= ", dip_dir)
        else:
            msg = 'Dip direction value is missing for fault with name'
            msg += '%s and id %s' % (name, id_fault)
            logging.warning(msg)
            # JUST FOR TESTING REASONS
            dip_dir = "N"
            print("dip_dir fazzula= ", dip_dir)
            # continue

        # Get the tuples
        dipt = get_tples(feature['properties']['ns_average_dip'])
        print("dipt= ", dipt)
        raket = get_tples(feature['properties']['ns_average_rake'])
        print("raket= ", raket)
        sliprt = get_tples(feature['properties']['ns_net_slip_rate'])
        print("sliprt= ", sliprt)
        shor_rd = get_tples(feature['properties']['ns_shortening_rate'])
        print("shortening_rate= ", shor_rd)
        vert_rd = get_tples(feature['properties']['ns_vert_slip_rate'])
        print("vertical_slip_rate= ", vert_rd)
        stk_rd = get_tples(feature['properties']['ns_strike_slip_rate'])
        print("strike_slip_rate= ", stk_rd)

        # Set the value to be used [suggested, min, max]
        if slip_rate_class is 'suggested':
            valid_dip = False
            # Dip values
            dip = dipt[0]
            if dip is not None:
                valid_dip = _is_valid_dip(dip)
                if valid_dip:
                    print("Dip value = ", dip)
                    msg = 'Dip value is [%s] for fault with name' % (dip)
                    msg += '%s and id %s' % (name, id_fault)
                    logging.info(msg)
            # if dip is None, but slip_type is available
            elif (dip) is None and (slipt) is not None:
                dip = get_dip_from_slip_type(slipt)
                print('Dip value for id= %s is missing and was computed using '
                      'slipt= %s, new dip= %s ' % (id_fault, slipt, dip))
            # if dip is None, but slip_type is available
            elif (dip) is None and (slipt) is None:
                msg = ('Dip value is missing and could not be computed for'
                       ' fault with name ')
                msg += '%s and id %s' % (name, id_fault)
                logging.warning(msg)
                continue

            valid_rake = False
            # Rake values
            rake = raket[0]
            if rake is not None:
                valid_rake = _is_valid_rake(rake)
                if valid_rake:
                    print("Rake value = ", dip)
                    msg = 'Rake value is [%s] for fault with name' % rake
                    msg += '%s and id %s' % (name, id_fault)
                    logging.info(msg)
            # if rake is None, but slip_type is available
            elif (rake) is None and (slipt) is not None:
                rake = get_rake_from_rup_type(RAKE_CLASS, slipt)
                print('Rake value for id= %s is missing and was computed using'
                      ' slipt= %s, new rake= %s ' % (id_fault, slipt, rake))
                msg = ('Rake value is [%s] for slip_type= %s for fault with'
                       ' name' % (rake, slipt))
                msg += '%s and id %s' % (name, id_fault)
                logging.info(msg)
            # if rake and slip_type are not available
            elif (rake) is None and (slipt) is None:
                msg = ('Rake value is missing or could not be computed for'
                       ' fault with name ')
                msg += '%s and id %s' % (name, id_fault)
                logging.warning(msg)
                continue

            # Slip rate values [shortening, vertical, strike_slip, net_slip]
            # If net_slip value is not available, a value is computed when
            # other component are present in the database
            slipr = sliprt[0]
            shor_rv = shor_rd[0]
            stk_rv = stk_rd[0]
            vert_rv = vert_rd[0]

            msg = ('slipr= %s,  shor_rv= %s , stk_rv= %s, vert_rv= %s  for'
                   ' fault with name ' % (slipr, shor_rv, stk_rv, vert_rv))
            msg += '%s and id %s' % (name, id_fault)
            logging.info(msg)

            if (slipr) is None and (shor_rv, stk_rv, vert_rv):
                print('slipr= %s' % slipr)
                print('shor_rv= %s , stk_rv= %s, vert_rv= %s ' %
                      (shor_rv, stk_rv, vert_rv))
                slipr = get_net_slip(dip, rake, shor_rv, stk_rv, vert_rv)

            if slipr is None:
                msg = 'net_slip  value is missing or can not be computed'
                msg += 'for fault with name %s and id %s' % (name, id_fault)
                logging.warning(msg)
                continue

            # Finally the net_slip is penalized using the aseismic_coeff
            net_slip = aseismic_coeff * float(slipr)
            print('net_slip value for id= %s is net_slip= %s [slipr = %s] ' %
                  (id_fault, net_slip, slipt))

            msg = ('net_slip value [%.2f] computed for fault with name ' %
                   (net_slip))
            msg += ' %s and id %s' % (name, id_fault)
            logging.info(msg)

        elif slip_rate_class is 'min':

            # Dip values
            dip = dipt[1]
            if (dip) is None and (slipt):
                # MN: get_dip_from_slip_dir UNDEFINED, probably the
                #     method name is changed
                dip = get_dip_from_slip_dir(slipt)
                print('Dip value for id= %s is missing and was computed using'
                      ' slipt= %s, new dip= %s ' % (id_fault, slipt, dip))
            else:
                msg = 'Dip value is missing for fault with name '
                msg += '%s and id %s' % (name, id_fault)
                logging.warning(msg)
                # continue

            # Rake values
            rake = raket[1]
            if (rake) is None and (slipt):
                rake = get_rake_from_rup_type(RAKE_CLASS, slipt)
                print('Rake value for id= %s is missing and was computed using'
                      ' slipt= %s, new rake= %s ' % (id_fault, slipt, rake))
            else:
                msg = 'Rake value is missing for fault with name '
                msg += '%s and id %s' % (name, id_fault)
                logging.warning(msg)
                # continue
            # Slip rate values [shortening, vertical, strike_slip, net_slip]
            # If net_slip value is not available, a value is computed when
            # other component are present in the database
            slipr = sliprt[1]
            shor_rd = shor_rv[1]
            stk_rd = stk_rv[1]
            vert_rv = vert_rd[1]

            if (slipr) is None and (shor_rv, stk_rv, vert_rv):
                slipr = get_net_slip(shor_rv, stk_rv, vert_rv)
            else:
                msg = 'net_slip  value is missing or not can be computed'
                msg += 'for fault with name %s and id %s' % (name, id_fault)
                logging.warning(msg)
                continue
            # Finally the net_slip is penalized using the aseismic_coeff
            net_slip = aseismic_coeff * float(slipr)

        elif slip_rate_class is 'max':

            # Dip values
            dip = dipt[2]
            if (dip) is None and (slipt):
                # MN: get_dip_from_slip_dir undefined
                dip = get_dip_from_slip_dir(slipt)
                print('Dip value for id= %s is missing and was computed using '
                      'slipt= %s, new dip= %s ' % (id_fault, slipt, dip))
            else:
                msg = 'Dip value is missing for fault with name '
                msg += '%s and id %s' % (name, id_fault)
                logging.warning(msg)
                # continue

            # Rake values
            rake = raket[2]
            if (rake) is None and (slipt):
                rake = get_rake_from_rup_type(RAKE_CLASS, slipt)
                print('Rake value for id= %s is missing and was computed '
                      'using slipt= %s, new rake= %s ' %
                      (id_fault, slipt, rake))
            else:
                msg = 'Rake value is missing for fault with name '
                msg += '%s and id %s' % (name, id_fault)
                logging.warning(msg)
                # continue

            # Slip rate values [shortening, vertical, strike_slip, net_slip]
            # If net_slip value is not available, a value is computed when
            # other component are present in the database
            slipr = sliprt[2]
            shor_rd = shor_rv[2]
            stk_rd = stk_rv[2]
            vert_rv = vert_rd[0]

            if (slipr) is None and (shor_rv, stk_rv, vert_rv):
                slipr = get_net_slip(shor_rv, stk_rv, vert_rv)
            else:
                msg = 'net_slip  value is missing or not can be computed'
                msg += 'for fault with name %s and id %s' % (name, id_fault)
                logging.warning(msg)
                continue

            # Finally the net_slip is penalized using the aseismic_coeff
            net_slip = aseismic_coeff * float(slipr)

        else:
            raise ValueError('Invalid slip_rate_class')

        # Get fault trace geometry
        fault_trace = get_line(numpy.array(feature['geometry']['coordinates']))

        # Get dip direction angle from literal and strike from trace geometry
        mean_az_from_trace = _get_mean_az_from_trace(fault_trace)
        valid_az = False
        valid_az = _is_valid_strike(mean_az_from_trace)
        if valid_az:
            # print("Mean azimuth value from trace = ", mean_az_from_trace)
            msg = ('Mean azimuth value is [%s] for fault with name' %
                   (mean_az_from_trace))
            msg += '%s and id %s' % (name, id_fault)
            logging.info(msg)

        dip_dir_angle = _get_dip_dir_from_literal(dip_dir)

        # Check if it's necessary to revert the fault trace
        if (dip_dir_angle is not None
                and _need_to_revert(mean_az_from_trace, dip_dir_angle)):
            new_fault_trace = _revert_fault_trace(fault_trace)
            logging.info('The fault trace for id= %s was reverted' % id_fault)
        else:
            new_fault_trace = fault_trace

        if new_fault_trace:
            fault_trace = new_fault_trace

        # Get L from srl - See Table 5 of Leonard 2010
        # SRL: surface rupture length [km]
        # RLD: Subsurface horizontal rupture length [km]
        # IF SRL/RLD < 5. km the fault will be exclused
        srl = fault_trace.get_length()
        rld = 10**((numpy.log10(srl) + 0.275) / 1.1)

        if rld < 5.0:
            msg = 'SRL/RLD value is < 5.0 km for fault with name '
            msg += '%s and id %s' % (name, id_fault)
            logging.warning(msg)
            continue

        # Witdh
        width, cl = get_width_from_length(rld, slipt)
        # print("id=, %s, srl=, %.2f,  rld=, %.2f, width=, %.2f,
        # slipt=, %s, cl=,%s "%(id_fault, srl, rld, width, slipt,cl))
        msg = ("id=, %s, srl=, %.2f,  rld=, %.2f, width=, %.2f, slipt=, %s,"
               " cl=,%s " % (id_fault, srl, rld, width, slipt, cl))
        logging.info(msg)

        # Get lower seismogenic depth from length
        lsd = width * numpy.sin(numpy.radians(float(dip)))
        lower_seismogenic_depth = lsd

        # create the surface from fault data
        sfce = SimpleFaultSurface.from_fault_data(fault_trace,
                                                  upper_seismogenic_depth,
                                                  lower_seismogenic_depth, dip,
                                                  rupture_mesh_spacing)
        # compute the area of the surface
        area = sfce.get_area()

        # compute the Mmax
        m_upp = msr.get_median_mag(sfce.get_area(), rake)
        if m_upp < m_low:
            msg = 'Mx [%.2f] is lesser than Mmin [%.2f] for fault with name '\
                  % (m_upp, m_low)
            msg += '%s and id %s' % (name, id_fault)
            logging.warning(msg)

        tstr = '%3s - %-40s %5.2f' % (id_fault, name, m_upp)
        logging.info(tstr)

        if net_slip is not None:
            slip_rate = net_slip
            print("slip_rate= ", slip_rate)
        else:
            continue

        # constrainig the computation
        # Mx > Mmin=m_low
        # slip_rate >= 1e-10
        if slip_rate is not None and slip_rate >= 1e-10 and m_upp > m_low:

            # compute rates
            rates = rates_for_double_truncated_mfd(area, slip_rate, m_low,
                                                   m_upp, b_gr, bin_width)
            # MFD
            mfd = EvenlyDiscretizedMFD(m_low + bin_width / 2, bin_width, rates)

            # Source
            if oqsource:
                src = SimpleFaultSource(
                    source_id, name, tectonic_region_type, mfd,
                    rupture_mesh_spacing, msr, rupture_aspect_ratio,
                    temporal_occurrence_model, upper_seismogenic_depth,
                    lower_seismogenic_depth, fault_trace, dip, rake)
            else:
                src = OQtSource(source_id, source_type='SimpleFaultSource')
                src.name = name
                src.tectonic_region_type = tectonic_region_type
                src.mfd = mfd
                src.rupture_mesh_spacing = rupture_mesh_spacing
                src.slip_rate = slip_rate
                src.msr = msr
                src.rupture_aspect_ratio = rupture_aspect_ratio
                src.temporal_occurrence_model = temporal_occurrence_model
                src.upper_seismogenic_depth = upper_seismogenic_depth
                src.lower_seismogenic_depth = lower_seismogenic_depth
                src.trace = fault_trace
                src.dip = dip
                src.rake = rake
                print('right')

            srcl.append(src)

    return srcl
Exemple #2
0
 def setUpClass(cls):
     RuptureContext.temporal_occurrence_model = PoissonTOM(50.)
from openquake.hazardlib.geo.nodalplane import NodalPlane
from openquake.hazardlib.geo.point import Point
from openquake.hazardlib.geo.polygon import Polygon
from openquake.hazardlib.geo.line import Line
from openquake.hazardlib.scalerel.point import PointMSR
from openquake.hazardlib.scalerel.peer import PeerMSR
from openquake.hazardlib.tom import PoissonTOM
from openquake.hazardlib.geo.surface.simple_fault import SimpleFaultSurface
from openquake.hmtk.comparison.rate_grids import RateGrid, RatePolygon

SOURCE_MODEL_FILE = os.path.join(os.path.dirname(__file__),
                                 "rate_grid_test_model.xml")

POINT_SOURCE = PointSource("PNT000", "Point 000", "Active Shallow Crust",
                           EvenlyDiscretizedMFD(5.0, 0.1, [1.0]), 1.0,
                           PointMSR(), 1.0, PoissonTOM(1.0), 0.0, 20.0,
                           Point(15.05, 15.05),
                           PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))]),
                           PMF([(1.0, 5.0)]))

BORDER_POINT_SOURCE = PointSource("PNT000", "Point 000",
                                  "Active Shallow Crust",
                                  EvenlyDiscretizedMFD(5.0, 0.1, [1.0]), 1.0,
                                  PointMSR(), 1.0, PoissonTOM(1.0), 0.0, 20.0,
                                  Point(15.0, 15.0),
                                  PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))]),
                                  PMF([(1.0, 5.0)]))

OUTSIDE_POINT_SOURCE = PointSource("PNT000", "Point 000",
                                   "Active Shallow Crust",
                                   EvenlyDiscretizedMFD(5.0, 0.1, [1.0]), 1.0,
Exemple #4
0
 def test_get_probability_one_occurrence(self):
     rupture = make_rupture(ParametricProbabilisticRupture,
                            occurrence_rate=0.4,
                            temporal_occurrence_model=PoissonTOM(10))
     self.assertAlmostEqual(rupture.get_probability_one_occurrence(),
                            0.0732626)
Exemple #5
0
from openquake.hazardlib.scalerel.point import PointMSR
from openquake.hazardlib.scalerel.peer import PeerMSR
from openquake.hazardlib.tom import PoissonTOM
from openquake.hazardlib.geo.surface.simple_fault import SimpleFaultSurface
from hmtk.comparison.rate_grids import RateGrid, RatePolygon

SOURCE_MODEL_FILE = os.path.join(os.path.dirname(__file__),
                                 "rate_grid_test_model.xml")

POINT_SOURCE = PointSource("PNT000", "Point 000",
                           "Active Shallow Crust",
                           EvenlyDiscretizedMFD(5.0, 0.1, [1.0]),
                           1.0,
                           PointMSR(),
                           1.0,
                           PoissonTOM(1.0),
                           0.0,
                           20.0,
                           Point(15.05, 15.05),
                           PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))]),
                           PMF([(1.0, 5.0)]))

BORDER_POINT_SOURCE = PointSource("PNT000", "Point 000",
                                  "Active Shallow Crust",
                                  EvenlyDiscretizedMFD(5.0, 0.1, [1.0]),
                                  1.0,
                                  PointMSR(),
                                  1.0,
                                  PoissonTOM(1.0),
                                  0.0,
                                  20.0,
def compute_disagg(dstore, rctx, cmaker, hmap4, trti, bin_edges, oq, monitor):
    # see https://bugs.launchpad.net/oq-engine/+bug/1279247 for an explanation
    # of the algorithm used
    """
    :param dstore:
        a DataStore instance
    :param rctx:
        an array of rupture parameters
    :param cmaker:
        a :class:`openquake.hazardlib.gsim.base.ContextMaker` instance
    :param hmap4:
        an ArrayWrapper of shape (N, M, P, Z)
    :param trti:
        tectonic region type index
    :param magi:
        magnitude bin index
    :param bin_egdes:
        a quartet (dist_edges, lon_edges, lat_edges, eps_edges)
    :param monitor:
        monitor of the currently running job
    :returns:
        a dictionary sid, imti -> 6D-array
    """
    RuptureContext.temporal_occurrence_model = PoissonTOM(
        oq.investigation_time)
    with monitor('reading contexts', measuremem=True):
        dstore.open('r')
        ctxs, close_ctxs = read_ctxs(
            dstore, rctx, req_site_params=cmaker.REQUIRES_SITES_PARAMETERS)

    magi = numpy.searchsorted(bin_edges[0], rctx[0]['mag']) - 1
    if magi == -1:  # when the magnitude is on the edge
        magi = 0
    dis_mon = monitor('disaggregate', measuremem=False)
    ms_mon = monitor('disagg mean_std', measuremem=True)
    N, M, P, Z = hmap4.shape
    g_by_z = AccumDict(accum={})  # dict s -> z -> g
    for g, rlzs in enumerate(cmaker.gsims.values()):
        for (s, z), r in numpy.ndenumerate(hmap4.rlzs):
            if r in rlzs:
                g_by_z[s][z] = g
    eps3 = disagg._eps3(cmaker.trunclevel, oq.num_epsilon_bins)
    res = {'trti': trti, 'magi': magi}
    imts = [from_string(im) for im in oq.imtls]
    with ms_mon:
        # compute mean and std for a single IMT to save memory
        # the size is N * U * G * 16 bytes
        disagg.set_mean_std(ctxs, imts, cmaker.gsims)

    # disaggregate by site, IMT
    for s, iml3 in enumerate(hmap4):
        if not g_by_z[s] or not close_ctxs[s]:
            # g_by_z[s] is empty in test case_7
            continue
        # dist_bins, lon_bins, lat_bins, eps_bins
        bins = (bin_edges[1], bin_edges[2][s], bin_edges[3][s], bin_edges[4])
        iml2 = dict(zip(imts, iml3))
        with dis_mon:
            # 7D-matrix #distbins, #lonbins, #latbins, #epsbins, M, P, Z
            matrix = disagg.disaggregate(close_ctxs[s], g_by_z[s], iml2, eps3,
                                         s, bins)  # 7D-matrix
            for m in range(M):
                mat6 = matrix[..., m, :, :]
                if mat6.any():
                    res[s, m] = output(mat6)
    return res
Exemple #7
0
:class: hmtk.sources.source_model.mtkSourceModel
'''

import os
import unittest
import operator
from openquake.hazardlib.tom import PoissonTOM
from hmtk.parsers.source_model.nrml04_parser import nrmlSourceModelParser
from hmtk.sources.source_model import mtkSourceModel
from openquake.hazardlib.source.point import PointSource
from openquake.hazardlib.source.area import AreaSource
from openquake.hazardlib.source.simple_fault import SimpleFaultSource
from openquake.hazardlib.source.complex_fault import ComplexFaultSource
from hmtk.sources.point_source import mtkPointSource

TOM = PoissonTOM(1.0)

BASE_PATH = os.path.join(os.path.dirname(__file__), 'test_source_files')

MODEL_PATH = os.path.join(BASE_PATH, 'mixed_source_model_nrml4_2.xml')
TEST_PATH = os.path.join(BASE_PATH, 'source_model_writer_test.xml')


class TestSourceModel(unittest.TestCase):
    '''
    Module to test the :class: hmtk.sources.source_model.mtkSourceModel
    '''
    def setUp(self):
        self.source_model = None

    def test_core_instantiation(self):
def compute_disagg(dstore, idxs, cmaker, iml4, trti, magi, bin_edges, oq,
                   monitor):
    # see https://bugs.launchpad.net/oq-engine/+bug/1279247 for an explanation
    # of the algorithm used
    """
    :param dstore:
        a DataStore instance
    :param idxs:
        an array of indices to ruptures
    :param cmaker:
        a :class:`openquake.hazardlib.gsim.base.ContextMaker` instance
    :param iml4:
        an ArrayWrapper of shape (N, M, P, Z)
    :param trti:
        tectonic region type index
    :param magi:
        magnitude bin index
    :param bin_egdes:
        a quartet (dist_edges, lon_edges, lat_edges, eps_edges)
    :param monitor:
        monitor of the currently running job
    :returns:
        a dictionary sid -> 7D-array
    """
    res = {'trti': trti, 'magi': magi}
    with monitor('reading rupdata', measuremem=True):
        dstore.open('r')
        sitecol = dstore['sitecol']
        # NB: using dstore['rup/' + k][idxs] would be ultraslow!
        a, b = idxs.min(), idxs.max() + 1
        rupdata = {k: dstore['rup/' + k][a:b][idxs-a] for k in dstore['rup']}
    RuptureContext.temporal_occurrence_model = PoissonTOM(
        oq.investigation_time)
    pne_mon = monitor('disaggregate_pne', measuremem=False)
    mat_mon = monitor('build_disagg_matrix', measuremem=False)
    ms_mon = monitor('disagg mean_std', measuremem=True)
    eps3 = disagg._eps3(cmaker.trunclevel, oq.num_epsilon_bins)
    with ms_mon:
        ctxs = _prepare_ctxs(rupdata, cmaker, sitecol)  # ultra-fast
        mean_std = disagg.get_mean_std(ctxs, oq.imtls, cmaker.gsims)

    for s, iml3 in enumerate(iml4):
        iml2dict = {imt: iml3[m] for m, imt in enumerate(oq.imtls)}

        # z indices by gsim
        M, P, Z = iml3.shape
        zs_by_g = AccumDict(accum=[])
        for g, rlzs in enumerate(cmaker.gsims.values()):
            for z in range(Z):
                if iml4.rlzs[s, z] in rlzs:
                    zs_by_g[g].append(z)

        # sanity check: the zs are disjoint
        counts = numpy.zeros(Z, numpy.uint8)
        for zs in zs_by_g.values():
            counts[zs] += 1
        assert (counts <= 1).all(), counts

        # dist_bins, lon_bins, lat_bins, eps_bins
        bins = bin_edges[0], bin_edges[1][s], bin_edges[2][s], bin_edges[3]
        # build 7D-matrix #distbins, #lonbins, #latbins, #epsbins, M, P, Z
        matrix = disagg.disaggregate(
            ctxs, mean_std, zs_by_g, iml2dict, eps3, s, bins, pne_mon, mat_mon)
        if matrix.any():
            res[s] = matrix
    return res
Exemple #9
0
    """
    boundary_lons = numpy.concatenate((mesh.lons[0, :], mesh.lons[1:, -1], mesh.lons[-1,:-1][::-1], mesh.lons[:-1, 0][::-1]))
    boundary_lats = numpy.concatenate((mesh.lats[0, :], mesh.lats[1:, -1], mesh.lats[-1,:-1][::-1], mesh.lats[:-1, 0][::-1]))
    
    return boundary_lons, boundary_lats

# define area source
src = AreaSource(
    source_id='1',
    name='area',
    tectonic_region_type='Active Shallow Crust',
    mfd=TruncatedGRMFD(min_mag=5., max_mag=6.5, bin_width=0.2, a_val=3.45, b_val=0.98),
    rupture_mesh_spacing=2.,
    magnitude_scaling_relationship=WC1994(),
    rupture_aspect_ratio=1.,
    temporal_occurrence_model=PoissonTOM(50.),
    upper_seismogenic_depth=2.,
    lower_seismogenic_depth=12.,
    nodal_plane_distribution=PMF([(1, NodalPlane(strike=45, dip=30, rake=0))]),
    hypocenter_distribution=PMF([(1, 7.)]),
    polygon=Polygon([Point(133.5, -22.5), Point(133.5, -23.0), Point(130.75, -23.75), Point(130.75, -24.5),
                     Point(133.5, -26.0), Point(133.5, -27.0), Point(130.75, -27.0), Point(128.977, -25.065),
                     Point(128.425, -23.436), Point(126.082, -23.233), Point(125.669, -22.351), Point(125.4, -20.5),
                     Point(125.75, -20.25), Point(126.7, -21.25), Point(128.5, -21.25), Point(129.25, -20.6),
                     Point(130.0, -20.6), Point(130.9, -22.25), Point(133.0, -22.0), Point(133.5, -22.5)]),
    area_discretization=20.
)


src = area_model
Exemple #10
0
    def test_areasource(self):
        nodalplane = NodalPlane(strike=0.0, dip=90.0, rake=0.0)
        src = AreaSource(source_id='src_1',
                         name='area source',
                         tectonic_region_type='Active Shallow Crust',
                         mfd=TruncatedGRMFD(a_val=3.5,
                                            b_val=1.0,
                                            min_mag=5.0,
                                            max_mag=6.5,
                                            bin_width=0.1),
                         nodal_plane_distribution=PMF([(1.0, nodalplane)]),
                         hypocenter_distribution=PMF([(1.0, 5.0)]),
                         upper_seismogenic_depth=0.0,
                         lower_seismogenic_depth=10.0,
                         magnitude_scaling_relationship=WC1994(),
                         rupture_aspect_ratio=1.0,
                         polygon=Polygon([
                             Point(-0.5, -0.5),
                             Point(-0.5, 0.5),
                             Point(0.5, 0.5),
                             Point(0.5, -0.5)
                         ]),
                         area_discretization=9.0,
                         rupture_mesh_spacing=1.0,
                         temporal_occurrence_model=PoissonTOM(50.))
        site = Site(location=Point(0.0, 0.0),
                    vs30=800.0,
                    vs30measured=True,
                    z1pt0=500.0,
                    z2pt5=2.0)
        gsims = {'Active Shallow Crust': BooreAtkinson2008()}
        imt = SA(period=0.1, damping=5.0)
        iml = 0.2
        truncation_level = 3.0
        n_epsilons = 3
        mag_bin_width = 0.2
        # in km
        dist_bin_width = 10.0
        # in decimal degree
        coord_bin_width = 0.2

        # compute disaggregation
        bin_edges, diss_matrix = disagg.disaggregation(
            [src], site, imt, iml, gsims, truncation_level, n_epsilons,
            mag_bin_width, dist_bin_width, coord_bin_width)
        mag_bins, dist_bins, lon_bins, lat_bins, eps_bins, trt_bins = bin_edges
        numpy.testing.assert_almost_equal(
            mag_bins, [5., 5.2, 5.4, 5.6, 5.8, 6., 6.2, 6.4, 6.6])
        numpy.testing.assert_almost_equal(
            dist_bins, [0., 10., 20., 30., 40., 50., 60., 70., 80.])
        numpy.testing.assert_almost_equal(lat_bins, [
            -6.5544231e-01, -4.9158173e-01, -3.2772115e-01, -1.6386058e-01,
            1.1102230e-16, 1.6386058e-01, 3.2772115e-01, 4.9158173e-01,
            6.5544231e-01
        ])
        numpy.testing.assert_almost_equal(lon_bins, [
            -6.5544231e-01, -4.9158173e-01, -3.2772115e-01, -1.6386058e-01,
            1.1102230e-16, 1.6386058e-01, 3.2772115e-01, 4.9158173e-01,
            6.5544231e-01
        ])
        numpy.testing.assert_almost_equal(eps_bins, [-3., -1., 1., 3.])
        self.assertEqual(trt_bins, ['Active Shallow Crust'])

        self.assertEqual(diss_matrix.shape, (8, 8, 8, 8, 3, 1))
        expected = [
            0.0245487, 0.0231275, 0.0210702, 0.0185196, 0.0157001, 0.0130175,
            0.0107099, 0.0045489
        ]
        numpy.testing.assert_almost_equal(
            diss_matrix.sum(axis=(1, 2, 3, 4, 5)), expected)
Exemple #11
0
def compute_disagg(dstore, slc, cmaker, hmap4, magi, bin_edges, monitor):
    # see https://bugs.launchpad.net/oq-engine/+bug/1279247 for an explanation
    # of the algorithm used
    """
    :param dstore:
        a DataStore instance
    :param slc:
        a slice of ruptures
    :param cmaker:
        a :class:`openquake.hazardlib.gsim.base.ContextMaker` instance
    :param hmap4:
        an ArrayWrapper of shape (N, M, P, Z)
    :param magi:
        magnitude bin indices
    :param bin_egdes:
        a quartet (dist_edges, lon_edges, lat_edges, eps_edges)
    :param monitor:
        monitor of the currently running job
    :returns:
        a dictionary sid, imti -> 6D-array
    """
    RuptureContext.temporal_occurrence_model = PoissonTOM(
        cmaker.investigation_time)
    with monitor('reading contexts', measuremem=True):
        dstore.open('r')
        allctxs, ctxs_around_site = read_ctxs(dstore, slc)
        for magidx, ctx in zip(magi, allctxs):
            ctx.magi = magidx
    dis_mon = monitor('disaggregate', measuremem=False)
    ms_mon = monitor('disagg mean_std', measuremem=True)
    N, M, P, Z = hmap4.shape
    g_by_z = AccumDict(accum={})  # dict s -> z -> g
    for g, rlzs in enumerate(cmaker.gsims.values()):
        for (s, z), r in numpy.ndenumerate(hmap4.rlzs):
            if r in rlzs:
                g_by_z[s][z] = g
    eps3 = disagg._eps3(cmaker.trunclevel, cmaker.num_epsilon_bins)
    imts = [from_string(im) for im in cmaker.imtls]
    for magi, ctxs in groupby(allctxs, operator.attrgetter('magi')).items():
        res = {'trti': cmaker.trti, 'magi': magi}
        with ms_mon:
            # compute mean and std (N * U * M * G * 16 bytes)
            disagg.set_mean_std(ctxs, imts, cmaker.gsims)

        # disaggregate by site, IMT
        for s, iml3 in enumerate(hmap4):
            close = [ctx for ctx in ctxs_around_site[s] if ctx.magi == magi]
            if not g_by_z[s] or not close:
                # g_by_z[s] is empty in test case_7
                continue
            # dist_bins, lon_bins, lat_bins, eps_bins
            bins = (bin_edges[1], bin_edges[2][s], bin_edges[3][s],
                    bin_edges[4])
            iml2 = dict(zip(imts, iml3))
            with dis_mon:
                # 7D-matrix #distbins, #lonbins, #latbins, #epsbins, M, P, Z
                matrix = disagg.disaggregate(close, g_by_z[s], iml2, eps3, s,
                                             bins)  # 7D-matrix
                for m in range(M):
                    mat6 = matrix[..., m, :, :]
                    if mat6.any():
                        res[s, m] = output(mat6)
        yield res
class _BaseFaultSourceTestCase(unittest.TestCase):
    TRT = TRT.ACTIVE_SHALLOW_CRUST
    RAKE = 0
    TOM = PoissonTOM(1.)

    def _make_source(self, mfd, aspect_ratio, profiles=None,
                     floating_x_step=0.5, floating_y_step=0.5):
        """
        Utility method for creating quickly fault instances
        :param mfd:
            An instance of :class:`openquake.hazardlib.scalerel.base.`
        :param aspect_ratio:
            The rupture aspect ratio
        :param profiles:
            A list of profiles used to build the fault surface
        """

        # Set the fault source parameter
        source_id = name = 'test-source'
        trt = self.TRT
        rake = self.RAKE
        rupture_mesh_spacing = 2.5
        magnitude_scaling_relationship = PeerMSR()
        rupture_aspect_ratio = aspect_ratio
        tom = self.TOM
        if profiles is None:
            profiles = [Line([Point(0.0, 0.0, 0.0), Point(0.0, 0.01, 15.0)]),
                        Line([Point(0.3, 0.0, 0.0), Point(0.3, 0.01, 15.0)])]

        # Create the source instance
        kfs = KiteFaultSource(source_id, name, trt, mfd, rupture_mesh_spacing,
                              magnitude_scaling_relationship,
                              rupture_aspect_ratio, tom, profiles, rake,
                              floating_x_step=floating_x_step,
                              floating_y_step=floating_y_step)

        # Check we can create a pickled version of this object
        assert_pickleable(kfs)
        return kfs

    def _ruptures_animation(self, lab, surface, ruptures, profiles,
                            first_azi=70):

        # Create the figure
        fig = plt.figure(figsize=(15, 8))
        ax = fig.add_subplot(111, projection='3d')
        ax.set_facecolor((0.5, 0.5, 0.5))

        # Plot the fault surface
        mesh = surface.mesh
        x = mesh.lons.flatten()
        y = mesh.lats.flatten()
        z = mesh.depths.flatten()*0.01
        plt.plot(x, y, z, 'o', markersize=1)

        # Plot the first rupture
        x = ruptures[0].surface.mesh.lons.flatten()
        y = ruptures[0].surface.mesh.lats.flatten()
        z = ruptures[0].surface.mesh.depths.flatten()*0.01
        sctt = ax.scatter(x, y, z, marker='s', s=10, c='red')

        fmt = 'Rupture num: {:d} magnitude: {:3.1f}'
        tmp = fmt.format(0, ruptures[0].mag)
        txt = ax.text2D(0.05, 0.95, tmp, transform=ax.transAxes)

        for pro in profiles:
            coo = [(p.longitude, p.latitude, p.depth) for p in pro.points]
            coo = numpy.array(coo)
            plt.plot(coo[:, 0], coo[:, 1], coo[:, 2]*0.01, '--g', lw=3)

        ax.invert_zaxis()

        def animate(i, ruptures, sctt, ax, txt):
            ax.view_init(elev=10., azim=first_azi+i*0.25 % 360)
            x = ruptures[i].surface.mesh.lons.flatten()
            y = ruptures[i].surface.mesh.lats.flatten()
            z = ruptures[i].surface.mesh.depths.flatten()*0.01
            sctt._offsets3d = (x, y, z)
            tmp = fmt.format(i, ruptures[i].mag)
            txt.set_text(tmp)
            return sctt, txt

        anim = animation.FuncAnimation(fig, animate, frames=len(ruptures),
                                       repeat=False,
                                       fargs=(ruptures, sctt, ax, txt),
                                       blit=False, interval=1000)

        Writer = animation.writers['ffmpeg']
        writer = Writer(fps=2, metadata=dict(artist='GEM'),
                        bitrate=1800, extra_args=['-vcodec', 'libx264'])
        fname = '/tmp/kite_fault_source_{:s}.mp4'.format(lab)
        anim.save(fname, writer=writer)

        fname = '/tmp/kite_fault_source_{:s}.html'.format(lab)
        with open(fname, "w") as f:
            print(anim.to_html5_video(), file=f)
def create_nrml_sources(fname_input_pattern: str, fname_config: str, 
                        folder_out: str, fname_subzone_shp: str="", 
                        fname_subzone_config: str=""):

    create_folder(folder_out)
    
    # If true we take some of the information from subzones
    subzones = (len(fname_subzone_shp) > 0 and len(fname_subzone_config) > 0)
    if subzones:
        polygons_gdf = gpd.read_file(fname_subzone_shp)
        model_subz = toml.load(fname_subzone_config) 

    # This is used to instantiate the MSR
    module = importlib.import_module('openquake.hazardlib.scalerel')

    # Parsing config
    model = toml.load(fname_config)

    rms = model['rupture_mesh_spacing']
    mmin = model['mmin']
    bwid = model['bin_width']
    tom = PoissonTOM(1.0)

    # Processing files
    for fname in glob(fname_input_pattern):

        src_id = os.path.basename(fname).split('.')[0]
        rc_id = _get_src_id(fname)
        
        df = pd.read_csv(fname)
        
        # Create a geodataframe with the points in a given zone
        if subzones:

            # Create a geodataframe with points
            geom = [PointShapely(xy) for xy in zip(df.lon, df.lat)]
            gdf = gpd.GeoDataFrame(df, crs='epsg:4326', geometry=geom)

            # Select subzones within a zone
            tdf = polygons_gdf[polygons_gdf["parent"] == src_id]

            # Should contain the points within
            df = gpd.sjoin(gdf, tdf, op='within')

        # This is the information on the source in the config file
        srcd = model['sources'][src_id]

        # Looping over the points
        srcs = []
        for idx, pnt in df.iterrows():

            if subzones:
                srcd_sz = model_subz['sources'][pnt.id]

            pfx = model.get("source_prefix", "")
            pfx += "_" if len(pfx) else pfx
            sid = '{:s}{:s}_{:d}'.format(pfx, src_id, idx)
            name = ""

            trt = srcd['tectonic_region_type']
            msr_str = model['msr'][trt]

            my_class = getattr(module, msr_str)
            msr = my_class()

            # Get mmax and set the MFD
            mmx = srcd['mmax']
            mfd = TruncatedGRMFD(mmin, mmx, bwid, pnt.agr, pnt.bgr)

            key = 'rupture_aspect_ratio'
            rar = get_param(srcd, model['default'], key)

            key = 'upper_seismogenic_depth'
            usd = get_param(srcd, model['default'], key)

            key = 'lower_seismogenic_depth'
            lsd = get_param(srcd, model['default'], key)

            key = 'nodal_plane_distribution'
            tmp = get_param(srcd, model['default'], key)
            npd = _get_nodal_plane_distribution(tmp)

            key = 'hypocenter_distribution'
            tmp = get_param(srcd, model['default'], key)
            hyd = _get_hypocenter_distribution(tmp)

            if subzones:
                tmp = get_param(srcd_sz, model['default'], key)
                npd = _get_nodal_plane_distribution(tmp)

            loc = Point(pnt.lon, pnt.lat)
            src = PointSource(sid, name, trt, mfd, rms, msr, rar, tom,
                              usd, lsd, loc, npd, hyd)
            srcs.append(src)

        # Write output file
        fname_out = os.path.join(folder_out, 'src_{:s}.xml'.format(src_id))
        write_source_model(fname_out, srcs, 'Zone {:s}'.format(src_id))
Exemple #14
0
def run_smoothing(grid_lims, config, catalogue, completeness_table, map_config,
                  run):
    """Run all the smoothing
    :params config:
        Dictionary of configuration parameters.
        For more info see helmstetter_werner_2012 code 
        and docs.
    """

    completeness_string = 'comp'
    for ym in completeness_table:
        completeness_string += '_%i_%.1f' % (ym[0], ym[1])
    smoother_filename = "Australia_Adaptive_K%i_b%.3f_mmin%.1f_%s.csv" % (
        config['k'], config['bvalue'], config['mmin'], completeness_string)

    filename = smoother_filename[:-4] + '.xml'
    if os.path.exists(filename) and not overwrite:
        print '%s already created, not overwriting!' % filename
        return

    smoother = h_w.HelmstetterEtAl2007(grid_lims,
                                       config,
                                       catalogue,
                                       storage_file=("Aus1_tmp2%.3f_%s.hdf5" %
                                                     (config['bvalue'], run)))
    smoother._get_catalogue_completeness_weights(completeness_table)
    smoother.build_distance_arrays()
    smoother.build_catalogue_2_grid_array()
    # Exhaustive smoothing
    exhaustive = False
    if exhaustive == True:
        params, poiss_llh = smoother.exhaustive_smoothing(
            np.arange(2, 10, 1), np.arange(1.0e-6, 1.0e-5, 2.0e-6))
        print params, poiss_llh
        smoother.config["k"] = params[0]
        smoother.config["r_min"] = params[1]
    #print 'Exiting now, re-run using optimised parameters'
    #sys.exit()
    d_i = smoother.optimise_bandwidths()
    smoother.run_smoothing(config["r_min"], d_i)
    data = np.column_stack([smoother.grid, smoother.rates])
    np.savetxt(
        smoother_filename,
        data,
        #               np.column_stack([smoother.grid, smoother.rates]),
        delimiter=",",
        fmt=["%.4f", "%.4f", "%.8e"],
        header="longitude,latitude,rate")

    # Creating a basemap - input a cconfiguration and (if desired) a title
    title = 'Smoothed seismicity rate for learning \nperiod %i %i, K=%i, Mmin=%.1f' % (
        config['learning_start'], config['learning_end'], smoother.config['k'],
        smoother.config['mmin'])
    basemap1 = HMTKBaseMap(map_config, title)
    basemap1.m.drawmeridians(
        np.arange(map_config['min_lat'], map_config['max_lat'], 5))
    basemap1.m.drawparallels(
        np.arange(map_config['min_lon'], map_config['max_lon'], 5))
    # Adding the smoothed grip to the basemap
    sym = (2., 3., 'cx')
    x, y = basemap1.m(smoother.grid[:, 0], smoother.grid[:, 1])
    if smoother.config['mmin'] == 3.5:
        vmax = -1.0
    elif smoother.config['mmin'] == 4.0:
        vmax = -2.5
    else:
        vmax = -1.0
    basemap1.m.scatter(x,
                       y,
                       marker='s',
                       c=np.log10(smoother.rates),
                       cmap=plt.cm.coolwarm,
                       zorder=10,
                       lw=0,
                       vmin=-7.0,
                       vmax=vmax)
    basemap1.m.drawcoastlines(linewidth=1, zorder=50)  # Add coastline on top
    #basemap1.m.drawmeridians(np.arange(llat, ulat, 5))
    #basemap1.m.drawparallels(np.arange(llon, ulon, 5))
    plt.colorbar(label='Log10(Smoothed rate per cell)')
    #plt.colorbar()#label='log10(Smoothed rate per cell)')
    plt.legend()
    #basemap1.m.scatter(x, y, marker = 's', c = smoother.data[:,4], cmap = plt.cm.coolwarm, zorder=10)
    #basemap1.m.scatter([150],[22], marker='o')
    #basemap1.fig.show()

    #(smoother.data[0], smoother.data[1])
    #basemap1.add_catalogue(catalogue_depth_clean, erlay=False)
    figname = smoother_filename[:-4] + '_smoothed_rates_map.png'
    plt.savefig(figname)

    source_list = []
    #i=0
    min_mag = 4.5
    max_mag = 7.2
    # Read in data again to solve number fomatting issue in smoother.data
    # For some reason it just returns 0 for all a values
    #data = np.genfromtxt(smoother_filename, delimiter = ',', skip_header = 1)

    tom = PoissonTOM(
        50)  # Dummy temporal occurence model for building pt sources
    msr = Leonard2014_SCR()
    for j in range(len(data[:, 2])):
        identifier = 'ASS' + str(j) + '_' + str(run)
        name = 'Helmstetter' + str(j) + '_' + str(run)
        point = Point(data[j, 0], data[j, 1], 10)
        rate = data[j, 2]
        # Convert rate to a value
        aval = np.log10(rate) + config['bvalue'] * config["mmin"]

        mfd = TruncatedGRMFD(min_mag, max_mag, 0.1, aval, config['bvalue'])
        hypo_depth_dist = PMF([(0.5, 10.0), (0.25, 5.0), (0.25, 15.0)])
        nodal_plane_dist = PMF([(0.3, NodalPlane(0, 30, 90)),
                                (0.2, NodalPlane(90, 30, 90)),
                                (0.3, NodalPlane(180, 30, 90)),
                                (0.2, NodalPlane(270, 30, 90))])
        point_source = PointSource(identifier, name, 'Non_cratonic', mfd, 2,
                                   msr, 2.0, tom, 0.1, 20.0, point,
                                   nodal_plane_dist, hypo_depth_dist)
        source_list.append(point_source)

    mod_name = "Australia_Adaptive_K%i_b%.3f" % (smoother.config['k'],
                                                 smoother.config['bvalue'])
    nodes = list(map(obj_to_node, sorted(source_list)))
    source_model = Node("sourceModel", {"name": name}, nodes=nodes)
    with open(filename, 'wb') as f:
        nrml.write([source_model], f, '%s', xmlns=NAMESPACE)
Exemple #15
0
 def _get_tom(self):
     """
     Returns the temporal occurence model as a Poisson TOM
     """
     return PoissonTOM(self.inv_time)
Exemple #16
0
 def setUp(self):
     """
     """
     mspa = 2.5
     #
     # Simple fault source
     mfd = EvenlyDiscretizedMFD(6.0, 0.1, [1.])
     msr = WC1994()
     tom = PoissonTOM(1.0)
     trace = Line([Point(10, 45.), Point(10., 45.2)])
     sfs = SimpleFaultSource(source_id='1',
                             name='1',
                             tectonic_region_type='none',
                             mfd=mfd,
                             rupture_mesh_spacing=mspa,
                             magnitude_scaling_relationship=msr,
                             rupture_aspect_ratio=1.0,
                             temporal_occurrence_model=tom,
                             upper_seismogenic_depth=0.,
                             lower_seismogenic_depth=10.,
                             fault_trace=trace,
                             dip=90.,
                             rake=90)
     self.srcs = [sfs]
     #
     #
     mfd = EvenlyDiscretizedMFD(6.0, 0.1, [1.])
     msr = WC1994()
     tom = PoissonTOM(1.0)
     trace = Line([Point(10.2, 45.), Point(10.2, 45.2)])
     sfs = SimpleFaultSource(source_id='2',
                             name='2',
                             tectonic_region_type='none',
                             mfd=mfd,
                             rupture_mesh_spacing=mspa,
                             magnitude_scaling_relationship=msr,
                             rupture_aspect_ratio=1.0,
                             temporal_occurrence_model=tom,
                             upper_seismogenic_depth=0.,
                             lower_seismogenic_depth=10.,
                             fault_trace=trace,
                             dip=90.,
                             rake=90)
     self.srcs.append(sfs)
     #
     #
     mfd = EvenlyDiscretizedMFD(6.0, 0.1, [1.])
     msr = WC1994()
     tom = PoissonTOM(1.0)
     trace = Line([Point(10.4, 45.), Point(10.4, 45.2)])
     sfs = SimpleFaultSource(source_id='3',
                             name='3',
                             tectonic_region_type='none',
                             mfd=mfd,
                             rupture_mesh_spacing=mspa,
                             magnitude_scaling_relationship=msr,
                             rupture_aspect_ratio=1.0,
                             temporal_occurrence_model=tom,
                             upper_seismogenic_depth=0.,
                             lower_seismogenic_depth=10.,
                             fault_trace=trace,
                             dip=90.,
                             rake=90)
     self.srcs.append(sfs)
     #
     #
     mfd = EvenlyDiscretizedMFD(6.0, 0.1, [1.])
     msr = WC1994()
     tom = PoissonTOM(1.0)
     trace = Line([Point(10.5, 45.), Point(10.6, 45.2)])
     sfs = SimpleFaultSource(source_id='4',
                             name='4',
                             tectonic_region_type='none',
                             mfd=mfd,
                             rupture_mesh_spacing=mspa,
                             magnitude_scaling_relationship=msr,
                             rupture_aspect_ratio=1.0,
                             temporal_occurrence_model=tom,
                             upper_seismogenic_depth=0.,
                             lower_seismogenic_depth=10.,
                             fault_trace=trace,
                             dip=90.,
                             rake=90)
     self.srcs.append(sfs)
Exemple #17
0
def run_smoothing(grid_lims,
                  smoothing_config,
                  catalogue,
                  completeness_table,
                  map_config,
                  run,
                  overwrite=True):
    """Run all the smoothing
    """
    ystart = completeness_table[-1][0]
    yend = catalogue.end_year
    catalogue_comp = deepcopy(catalogue)
    # Ensuring that catalogue is cleaned of earthquakes outside of
    # completeness period
    index = catalogue_comp.data['year'] >= ystart
    catalogue_comp.purge_catalogue(index)

    completeness_string = 'comp'
    for ym in completeness_table:
        completeness_string += '_%i_%.1f' % (ym[0], ym[1])
    smoother_filename = 'Australia_Fixed_%i_%i_b%.3f_mmin_%.1f_0.1%s.csv' % (
        smoothing_config["BandWidth"], smoothing_config["Length_Limit"],
        bvalue, completeness_table[0][1], completeness_string)
    filename = smoother_filename[:-4] + '.xml'
    if os.path.exists(filename) and not overwrite:
        print '%s already created, not overwriting!' % filename
        return
    smoother = SmoothedSeismicity(
        [105., 160., 0.1, -47., -5, 0.1, 0., 20., 20.],
        bvalue=smoothing_config['bvalue'])
    print 'Running smoothing'
    smoothed_grid = smoother.run_analysis(
        catalogue_comp,
        smoothing_config,
        completeness_table=completeness_table)

    smoother.write_to_csv(smoother_filename)

    from openquake.hazardlib.nrml import SourceModelParser, write, NAMESPACE
    from openquake.baselib.node import Node
    from openquake.hazardlib import nrml
    from openquake.hazardlib.sourcewriter import obj_to_node
    # Build nrml input file of point sources
    source_list = []
    #i=0
    min_mag = 4.5
    max_mag = 7.8
    bval = bvalue  # just define as 1 for time being
    # Read in data again to solve number fomatting issue in smoother.data
    # For some reason it just returns 0 for all a values
    try:
        data = np.genfromtxt(smoother_filename, delimiter=',', skip_header=1)
    except ValueError:
        print 'Something wrong with file %s' % smoother_filename
        sys.exit()
    tom = PoissonTOM(
        50)  # Dummy temporal occurence model for building pt sources
    msr = Leonard2014_SCR()
    for j in range(len(data[:, 4])):
        #    print smoother.data[j,:]
        identifier = 'FSS' + str(j) + '_' + str(run)
        name = 'Frankel' + str(j) + '_' + str(run)
        point = Point(data[j, 0], data[j, 1], data[j, 2])
        annual_rate = data[j, 4] / (yend - ystart + 1)
        aval = np.log10(annual_rate) + smoothing_config[
            'bvalue'] * completeness_table[0][1]
        mfd = TruncatedGRMFD(min_mag, max_mag, 0.1, aval, bval)
        hypo_depth_dist = PMF([(0.5, 10.0), (0.25, 5.0), (0.25, 15.0)])
        nodal_plane_dist = PMF([(0.3, NodalPlane(0, 30, 90)),
                                (0.2, NodalPlane(90, 30, 90)),
                                (0.3, NodalPlane(180, 30, 90)),
                                (0.2, NodalPlane(270, 30, 90))])
        point_source = PointSource(identifier, name, 'Non_cratonic', mfd, 2,
                                   msr, 2.0, tom, 0.1, 20.0, point,
                                   nodal_plane_dist, hypo_depth_dist)
        source_list.append(point_source)

    nodes = list(map(obj_to_node, sorted(source_list)))
    source_model = Node("sourceModel", {"name": name}, nodes=nodes)
    with open(filename, 'wb') as f:
        nrml.write([source_model], f, '%s', xmlns=NAMESPACE)

    # Creating a basemap - input a cconfiguration and (if desired) a title
    title = 'Smoothed seismicity rate for learning \nperiod %i 2017, Mmin = %.1f' % (
        completeness_table[0][0], completeness_table[0][1])
    basemap1 = HMTKBaseMap(map_config, 'Smoothed seismicity rate')
    # Adding the smoothed grip to the basemap
    sym = (2., 3., 'cx')
    x, y = basemap1.m(smoother.data[:, 0], smoother.data[:, 1])
    basemap1.m.scatter(x,
                       y,
                       marker='s',
                       c=np.log10(smoother.data[:, 4]),
                       cmap=plt.cm.coolwarm,
                       zorder=10,
                       lw=0,
                       vmin=-6.5,
                       vmax=1.5)
    basemap1.m.drawcoastlines(linewidth=1, zorder=50)  # Add coastline on top
    basemap1.m.drawmeridians(
        np.arange(map_config['min_lat'], map_config['max_lat'], 5))
    basemap1.m.drawparallels(
        np.arange(map_config['min_lon'], map_config['max_lon'], 5))
    plt.colorbar(label='log10(Smoothed rate per cell)')
    plt.legend()
    figname = smoother_filename[:-4] + '_smoothed_rates_map.png'
    plt.savefig(figname)
 def setUp(self):
     """
     Builds a simple dipping/bending fault source with a characteristic
     source model. Compares the curves for four sites, two on the hanging
     wall and two on the footwall.
     The source model is taken from the PEER Tests
     """
     point_order_dipping_east = [
         Point(-64.78365, -0.45236),
         Point(-64.80164, -0.45236),
         Point(-64.90498, -0.36564),
         Point(-65.0000, -0.16188),
         Point(-65.0000, 0.0000)
     ]
     trace_dip_east = Line(point_order_dipping_east)
     site_1 = Site(Point(-64.98651, -0.15738), 760.0, True, 48.0, 0.607)
     site_2 = Site(Point(-64.77466, -0.45686), 760.0, True, 48.0, 0.607)
     site_3 = Site(Point(-64.92747, -0.38363), 760.0, True, 48.0, 0.607)
     site_4 = Site(Point(-65.05396, -0.17088), 760.0, True, 48.0, 0.607)
     self.sites = SiteCollection([site_1, site_2, site_3, site_4])
     self.imtls = {
         "PGA": [
             0.001, 0.01, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45,
             0.5, 0.55, 0.6, 0.7, 0.8, 0.9, 1.0
         ]
     }
     fault_surface1 = SimpleFaultSurface.from_fault_data(
         trace_dip_east, 0.0, 12.0, 60., 0.5)
     mfd1 = EvenlyDiscretizedMFD(6.75, 0.01, [0.01])
     tom = PoissonTOM(1.0)
     self.sources = [
         CharacteristicFaultSource(
             "PEER_CHAR_FLT_EAST",
             "Peer Bending Fault Dipping East - Characteristic",
             "Active Shallow Crust", mfd1, tom, fault_surface1, 90.0)
     ]
     # We will check all the GMPEs
     self.gsim_set = {
         "ASK": [
             AbrahamsonEtAl2014NSHMPMean(),
             (0.185, AbrahamsonEtAl2014NSHMPLower()),
             (0.63, AbrahamsonEtAl2014()),
             (0.185, AbrahamsonEtAl2014NSHMPUpper())
         ],
         "BSSA": [
             BooreEtAl2014NSHMPMean(), (0.185, BooreEtAl2014NSHMPLower()),
             (0.63, BooreEtAl2014()), (0.185, BooreEtAl2014NSHMPUpper())
         ],
         "CB": [
             CampbellBozorgnia2014NSHMPMean(),
             (0.185, CampbellBozorgnia2014NSHMPLower()),
             (0.63, CampbellBozorgnia2014()),
             (0.185, CampbellBozorgnia2014NSHMPUpper())
         ],
         "CY": [
             ChiouYoungs2014NSHMPMean(),
             (0.185, ChiouYoungs2014NSHMPLower()),
             (0.63, ChiouYoungs2014()), (0.185, ChiouYoungs2014NSHMPUpper())
         ],
         "ID": [
             Idriss2014NSHMPMean(), (0.185, Idriss2014NSHMPLower()),
             (0.63, Idriss2014()), (0.185, Idriss2014NSHMPUpper())
         ]
     }
Exemple #19
0
 def test_get_probability_one_occurrence(self):
     pdf = PoissonTOM(time_span=30)
     aae = self.assertAlmostEqual
     aae(pdf.get_probability_one_occurrence(10), 0)
     aae(pdf.get_probability_one_occurrence(0.1), 0.1493612)
     aae(pdf.get_probability_one_occurrence(0.01), 0.2222455)
Exemple #20
0
from openquake.baselib.node import Node
from openquake.hazardlib import nrml
from openquake.hazardlib.sourcewriter import obj_to_node
# Build nrml input file of point sources
source_list = []
#i=0
min_mag = 4.5
max_mag = 7.8
bval = bvalue  # just define as 1 for time being
# Read in data again to solve number fomatting issue in smoother.data
# For some reason it just returns 0 for all a values
data = np.genfromtxt(smoother_filename, delimiter=',', skip_header=1)
#print max(data[:,4])
#print data[:,4]
#print len(data[:,4])
tom = PoissonTOM(50)  # Dummy temporal occurence model for building pt sources
msr = Leonard2014_SCR()
for j in range(len(data[:, 4])):
    #    print smoother.data[j,:]
    identifier = 'FSS' + str(j)
    name = 'Frankel' + str(j)
    point = Point(data[j, 0], data[j, 1], data[j, 2])
    rate = data[j, 4]
    aval = np.log10(rate)
    # aval = rate # trying this based on some testing
    #    aval = np.log10(rate) #+ bval*completeness_table_a[0][1]
    # print aval
    mfd = TruncatedGRMFD(min_mag, max_mag, 0.1, aval, bval)
    hypo_depth_dist = PMF([(0.5, 10.0), (0.25, 5.0), (0.25, 15.0)])
    nodal_plane_dist = PMF([(0.3, NodalPlane(0, 30, 90)),
                            (0.2, NodalPlane(90, 30, 90)),
Exemple #21
0
    def test_point_sources(self):
        sources = [
            openquake.hazardlib.source.PointSource(
                source_id='point1',
                name='point1',
                tectonic_region_type=const.TRT.ACTIVE_SHALLOW_CRUST,
                mfd=openquake.hazardlib.mfd.EvenlyDiscretizedMFD(
                    min_mag=4, bin_width=1, occurrence_rates=[5]),
                nodal_plane_distribution=openquake.hazardlib.pmf.PMF([
                    (1,
                     openquake.hazardlib.geo.NodalPlane(strike=0.0,
                                                        dip=90.0,
                                                        rake=0.0))
                ]),
                hypocenter_distribution=openquake.hazardlib.pmf.PMF([(1, 10)]),
                upper_seismogenic_depth=0.0,
                lower_seismogenic_depth=10.0,
                magnitude_scaling_relationship=openquake.hazardlib.scalerel.
                PeerMSR(),
                rupture_aspect_ratio=2,
                temporal_occurrence_model=PoissonTOM(1.),
                rupture_mesh_spacing=1.0,
                location=Point(10, 10)),
            openquake.hazardlib.source.PointSource(
                source_id='point2',
                name='point2',
                tectonic_region_type=const.TRT.ACTIVE_SHALLOW_CRUST,
                mfd=openquake.hazardlib.mfd.EvenlyDiscretizedMFD(
                    min_mag=4, bin_width=2, occurrence_rates=[5, 6, 7]),
                nodal_plane_distribution=openquake.hazardlib.pmf.PMF([
                    (1,
                     openquake.hazardlib.geo.NodalPlane(strike=0,
                                                        dip=90,
                                                        rake=0.0)),
                ]),
                hypocenter_distribution=openquake.hazardlib.pmf.PMF([(1, 10)]),
                upper_seismogenic_depth=0.0,
                lower_seismogenic_depth=10.0,
                magnitude_scaling_relationship=openquake.hazardlib.scalerel.
                PeerMSR(),
                rupture_aspect_ratio=2,
                temporal_occurrence_model=PoissonTOM(1.),
                rupture_mesh_spacing=1.0,
                location=Point(10, 11)),
        ]
        sites = [
            openquake.hazardlib.site.Site(Point(11, 10), 1, 2, 3),
            openquake.hazardlib.site.Site(Point(10, 16), 2, 2, 3),
            openquake.hazardlib.site.Site(Point(10, 10.6, 1), 3, 2, 3),
            openquake.hazardlib.site.Site(Point(10, 10.7, -1), 4, 2, 3)
        ]
        sitecol = openquake.hazardlib.site.SiteCollection(sites)
        gsims = {const.TRT.ACTIVE_SHALLOW_CRUST: SadighEtAl1997()}
        truncation_level = 1
        imts = {'PGA': [0.1, 0.5, 1.3]}
        s_filter = SourceFilter(sitecol, {const.TRT.ACTIVE_SHALLOW_CRUST: 30})
        result = calc_hazard_curves(sources, s_filter, imts, gsims,
                                    truncation_level)['PGA']
        # there are two sources and four sites. The first source contains only
        # one rupture, the second source contains three ruptures.
        #
        # the first source has 'maximum projection radius' of 0.707 km
        # the second source has 'maximum projection radius' of 500.0 km
        #
        # the epicentral distances for source 1 are: [ 109.50558394,
        # 667.16955987,   66.71695599,   77.83644865]
        # the epicentral distances for source 2 are: [ 155.9412148 ,
        # 555.97463322,   44.47797066,   33.35847799]
        #
        # Considering that the source site filtering distance is set to 30 km,
        # for source 1, all sites have epicentral distance larger than
        # 0.707 + 30 km. This means that source 1 ('point 1') is not considered
        # in the calculation because too far.
        # for source 2, the 1st, 3rd and 4th sites have epicentral distances
        # smaller than 500.0 + 30 km. This means that source 2 ('point 2') is
        # considered in the calculation for site 1, 3, and 4.
        #
        # JB distances for rupture 1 in source 2 are: [ 155.43860273,
        #  555.26752644,   43.77086388,   32.65137121]
        # JB distances for rupture 2 in source 2 are: [ 150.98882575,
        #  548.90356541,   37.40690285,   26.28741018]
        # JB distances for rupture 3 in source 2 are: [ 109.50545819,
        # 55.97463322,    0.        ,    0.        ]
        #
        # Considering that the rupture site filtering distance is set to 30 km,
        # rupture 1 (magnitude 4) is not considered because too far, rupture 2
        # (magnitude 6) affect only the 4th site, rupture 3 (magnitude 8)
        # affect the 3rd and 4th sites.

        self.assertEqual(result.shape, (4, 3))  # 4 sites, 3 levels
        numpy.testing.assert_allclose(result[0], 0)  # no contrib to site 1
        numpy.testing.assert_allclose(result[1], 0)  # no contrib to site 2

        # test that depths are kept after filtering (sites 3 and 4 remain)
        s_filter = SourceFilter(sitecol, {'default': 100})
        numpy.testing.assert_array_equal(
            s_filter.get_close_sites(sources[0]).depths, ([1, -1]))
Exemple #22
0
    def test_case_5(self):
        # only mfd differs from case 2
        sources = [
            SimpleFaultSource(
                source_id='fault1',
                name='fault1',
                tectonic_region_type=const.TRT.ACTIVE_SHALLOW_CRUST,
                mfd=test_data.SET1_CASE5_MFD,
                rupture_mesh_spacing=1.0,
                magnitude_scaling_relationship=PeerMSR(),
                rupture_aspect_ratio=test_data.SET1_RUPTURE_ASPECT_RATIO,
                temporal_occurrence_model=PoissonTOM(1.),
                upper_seismogenic_depth=test_data.
                SET1_CASE1TO9_UPPER_SEISMOGENIC_DEPTH,
                lower_seismogenic_depth=test_data.
                SET1_CASE1TO9_LOWER_SEISMOGENIC_DEPTH,
                fault_trace=test_data.SET1_CASE1TO9_FAULT_TRACE,
                dip=test_data.SET1_CASE1TO9_DIP,
                rake=test_data.SET1_CASE1TO9_RAKE)
        ]
        sites = SiteCollection([
            test_data.SET1_CASE1TO9_SITE1, test_data.SET1_CASE1TO9_SITE2,
            test_data.SET1_CASE1TO9_SITE3, test_data.SET1_CASE1TO9_SITE4,
            test_data.SET1_CASE1TO9_SITE5, test_data.SET1_CASE1TO9_SITE6,
            test_data.SET1_CASE1TO9_SITE7
        ])
        gsims = {const.TRT.ACTIVE_SHALLOW_CRUST: SadighEtAl1997()}
        truncation_level = 0
        imts = {str(test_data.IMT): test_data.SET1_CASE5_IMLS}

        curves = calc_hazard_curves(sources, sites, imts, gsims,
                                    truncation_level)
        s1hc, s2hc, s3hc, s4hc, s5hc, s6hc, s7hc = curves[str(test_data.IMT)]

        assert_hazard_curve_is(self,
                               s1hc,
                               test_data.SET1_CASE5_SITE1_POES,
                               atol=1e-3,
                               rtol=1e-5)
        assert_hazard_curve_is(self,
                               s2hc,
                               test_data.SET1_CASE5_SITE2_POES,
                               atol=1e-3,
                               rtol=1e-5)
        assert_hazard_curve_is(self,
                               s3hc,
                               test_data.SET1_CASE5_SITE3_POES,
                               atol=1e-3,
                               rtol=1e-5)
        assert_hazard_curve_is(self,
                               s4hc,
                               test_data.SET1_CASE5_SITE4_POES,
                               atol=1e-3,
                               rtol=1e-5)
        assert_hazard_curve_is(self,
                               s5hc,
                               test_data.SET1_CASE5_SITE5_POES,
                               atol=1e-3,
                               rtol=1e-5)
        assert_hazard_curve_is(self,
                               s6hc,
                               test_data.SET1_CASE5_SITE6_POES,
                               atol=1e-3,
                               rtol=1e-5)
        assert_hazard_curve_is(self,
                               s7hc,
                               test_data.SET1_CASE5_SITE7_POES,
                               atol=1e-3,
                               rtol=1e-5)
'''

import unittest
import warnings
import numpy as np
from openquake.hazardlib.geo import point, polygon
from openquake.hazardlib.source.area import AreaSource
from openquake.hazardlib.pmf import PMF
from openquake.hazardlib.tom import PoissonTOM
from openquake.hazardlib.mfd.truncated_gr import TruncatedGRMFD
from openquake.hazardlib.scalerel.wc1994 import WC1994
from openquake.hmtk.sources.area_source import mtkAreaSource
from openquake.hmtk.seismicity.catalogue import Catalogue
from openquake.hmtk.seismicity.selector import CatalogueSelector

TOM = PoissonTOM(50.0)
SOURCE_ATTRIBUTES = [
    'mfd', 'name', 'geometry', 'nodal_plane_dist', 'typology', 'upper_depth',
    'catalogue', 'rupt_aspect_ratio', 'lower_depth', 'id', 'hypo_depth_dist',
    'mag_scale_rel', 'trt'
]


class TestAreaSource(unittest.TestCase):
    '''
    Tester class for openquake.hmtk.sources.area_source.mtkAreaSource
    '''
    def setUp(self):
        warnings.simplefilter("ignore")
        self.catalogue = Catalogue()
        self.area_source = mtkAreaSource('101', 'A Source')
Exemple #24
0
from openquake.hazardlib.geo import Line, Point
from openquake.hazardlib.source import ComplexFaultSource
from openquake.hazardlib.tom import PoissonTOM
from openquake.hazardlib.const import TRT
from openquake.hazardlib.mfd import TruncatedGRMFD
from openquake.hazardlib.scalerel.strasser2010 import StrasserInterface

DEFAULTS = {
    'source_id': '0',
    'name': 'None',
    'tectonic_region_type': TRT.SUBDUCTION_INTERFACE,
    'mfd': TruncatedGRMFD(5.0, 6.0, 0.1, 5.0, 1.0),
    'rupture_mesh_spacing': 2,
    'magnitude_scaling_relationship': StrasserInterface(),
    'rupture_aspect_ratio': 4.,
    'temporal_occurrence_model': PoissonTOM(1.0),
    'rake': 90,
}


class EdgesSet():
    """
    :param edges:
        A list of :class:`openquake.hazardlib.geo.line.Line` instances
    """
    def __init__(self, edges=[]):
        self.edges = edges

    @classmethod
    def from_files(cls, fname):
        """
    def test_areasource(self):
        nodalplane = NodalPlane(strike=0.0, dip=90.0, rake=0.0)
        src = AreaSource(source_id='src_1',
                         name='area source',
                         tectonic_region_type='Active Shallow Crust',
                         mfd=TruncatedGRMFD(a_val=3.5,
                                            b_val=1.0,
                                            min_mag=5.0,
                                            max_mag=6.5,
                                            bin_width=0.1),
                         nodal_plane_distribution=PMF([(1.0, nodalplane)]),
                         hypocenter_distribution=PMF([(1.0, 5.0)]),
                         upper_seismogenic_depth=0.0,
                         lower_seismogenic_depth=10.0,
                         magnitude_scaling_relationship=WC1994(),
                         rupture_aspect_ratio=1.0,
                         polygon=Polygon([
                             Point(-0.5, -0.5),
                             Point(-0.5, 0.5),
                             Point(0.5, 0.5),
                             Point(0.5, -0.5)
                         ]),
                         area_discretization=9.0,
                         rupture_mesh_spacing=1.0,
                         temporal_occurrence_model=PoissonTOM(50.))
        site = Site(location=Point(0.0, 0.0),
                    vs30=800.0,
                    vs30measured=True,
                    z1pt0=500.0,
                    z2pt5=2.0)
        gsims = {'Active Shallow Crust': BooreAtkinson2008()}
        imt = SA(period=0.1, damping=5.0)
        iml = 0.2
        truncation_level = 3.0
        n_epsilons = 3
        mag_bin_width = 0.2
        # in km
        dist_bin_width = 10.0
        # in decimal degree
        coord_bin_width = 0.2

        # compute disaggregation
        bin_edges, diss_matrix = disagg.disaggregation(
            [src], site, imt, iml, gsims, truncation_level, n_epsilons,
            mag_bin_width, dist_bin_width, coord_bin_width)
        mag_bins, dist_bins, lon_bins, lat_bins, eps_bins, trt_bins = bin_edges
        numpy.testing.assert_almost_equal(
            mag_bins, [5., 5.2, 5.4, 5.6, 5.8, 6., 6.2, 6.4, 6.6])
        numpy.testing.assert_almost_equal(
            dist_bins, [0., 10., 20., 30., 40., 50., 60., 70., 80.])
        numpy.testing.assert_almost_equal(
            lat_bins, [-0.6, -0.4, -0.2, 0., 0.2, 0.4, 0.6])
        numpy.testing.assert_almost_equal(
            lon_bins, [-0.6, -0.4, -0.2, 0., 0.2, 0.4, 0.6])
        numpy.testing.assert_almost_equal(eps_bins, [-3., -1., 1., 3.])
        self.assertEqual(trt_bins, ['Active Shallow Crust'])

        expected_matrix = numpy.fromstring(
            codecs.decode(
                codecs.decode(
                    b"""\
eJztnXlcTdv7x3eSJuVEKSWOg5LSPVEZytm7lESl5Ia4nG6GuF1FdUWGTcpYMpZolEa5hwgN7OIm
lEYNKOeWBlNFyZDqd/q9vq+v8717da99zz5N9vs/S6+1nr3Ws/Y6e33W8ywIoiCVcM+brec1YbSo
fvtn5mYYmsTNHN+wGP7v/591TK2FLWEoO1H1caMJ/Dc1kcupjGMOYWy8PRQU/REWFiS31xqGLsZ2
ii9e+9WfsZAw3S0TeOUlR+7RFvWgn5clIg/vs6AGh2O0JfZf22VvFJ3UaQhDl1W0LgQtoeYdxd9j
PV05eIIW3k+4j4I37lMSnv8EialczZ2Br/9EveoLNSN8uaeJ8uHYefhyJ5G0dT5Mwe3c35GQ7j8N
X8+8s/uhaB18edO8xfa2k/HlKCQr7kYXXr/N864wHm4IqL947M5VDGq+9xZIcI651SB8/2Pqj/UX
jMOXIwr6MoNGAvxHIzM/4zNLYHs4z+oSz2gL7g9cnzFwNcB+ooQnaLY6jxK8HvRjdtpyEvwclR4/
J08SMK9PmGP6gOcN74BFa8YDxuvLb+MzAOM+YCk5rqDyFuCfT94uPs8V3G+7xbkmbm0bvn705Rsl
pBXQbpLYFI13gPIIkzSVJsHtRH6OzvQdTIIfhlfVlrcA7Pl4ycUA9Fzd1fNcOb+dhPdGt1zMTJz+
5tvrx/Q6tDslAO/DZeLQKwgwj56J7b4C8Ct0j/sSxS9CfK7egmYejFwi4bmwe/HrQ0ioJ3bwoFsY
CfUw20xFrgDq4Ry6axADKOcefm2X24fG13XcuGG3+5A93cHZvWT3eRLsnGfhUpUCqqfO0ecaCfUv
LaiVB/kVp0R9HRn2U1BQUFBQUHx30INWx2VpwZDdp2v2u9fDkEX1xNG/zP/6fREuXxpdaQFDzB+M
tjrP6rnvdLVAhuKHn/D2UFD0R4Zr3R+WugSGRJ4u2juN/dWfZ/wSxkEMet7PnV5XltyYAUP175ct
zLP92u6KJQwDlgkMmdB2Xv/Rlpp3FH+PUo495AvQdxB4/nLvscLznya2vrPPbHz97rki6UXG+PLt
lon2BxYA9qslMcm3uoLbmW3XFtg5HV9PUHJeYwRAF6NZGjvdBOgL+ZnPO/+cILx+G5oXFpKFAMYr
eu9qfTVqvvcW2K+DG2yHAvzEwci6aRK+3Fo91FMToJOim8N/ow8RfBzZ0tCaVD0S/CHrED0aoPMS
xTplUPMdEnSrAO0y2w4S7GEf2Jl3fzi+Hva7qT7VgPFyrb0lrg84JwDdXHVbTOb7mXdIR2nSQoB/
ouJxbl6fhLefyX6EaCbSAP18lKNYDtKd3bSdZoB0lkR1mxIieiVt/89aZfjn4vpHnFsmT4K+bLjl
QhlABycK6qCeWScleD3YQ79pEiTouYiVtTdHGTC/LIwbReUA49Li9X6bKGAcy9pyG2UH4PwqeKSx
8TkJ8wVNkRCpIFCPu4mxeAbg76MfZiyrJMGeJT768wjoy2ipwrtUkJ7eW8yvM9/V2IfsOexok3kP
YM+tnKvL6gS3E82wcLf4SMLzcs30FUC64ZszcVqgcwgpFZ7qQP9fftXkOgn20PfboEG9MI50o1V/
HO1D/kPxDxx8JgfS5UmDVmkXTEL9+QkSjAgyzkvsefDam/JPCgqKAUCLMqdNDYYYjsmH3BxgKGCD
W2UC3/5Yi8tcl+B5MITR3NdfIOGc/LdyZWPKe42leHsoKPoj8fAGiyZ7GMpWassp5otndAqoXllh
CkO6unrtkHnP+Xnsa/kVaYB2PdVKtMvn97w9FP0Tp3Q35R8A+g5X8oL9JRLiPv4Kus61QL+FBbnG
Htu1aM7X+tHS+TbxCjA0I27U2myYL74ydqihthRvHalfvXU7QC9jJ10UXQHQrb6ZABns6WMWxB1j
an5+Jl+7wWefOYgD1s1aucK2KhaUr/vn/lxQfM1rxTs26sKbd1r67PB7gPi4cK85bEyI7VL8PeyN
YrEsgJ4SdH67r+tUfHnAtgmH5QA6KeL3a8BlEvSU/SPjxxQBdG2izJh4pkiMBH3ZdWgA4kOCfyqp
M6FnJPyORe+tj0YUATqXquvBHYB5vbT8WpMioD/ZNum61wDjPlDhzhr5+BJAv8DMo6XlxYTXD9yM
m7PSVb69fuz3I5LHATodlqh0bjWR+WVprrcBsH+LXnh/Q3YMCXqT2V2ddAUC9ayZW7CyGqDH+foc
fDWChHlx3My1FKDjE6VpjJcoHfR+u1z3NhcQV464ag12A4wL223hwXOAedrvaa/1ciUQ39cdaKP9
L8tA+kJ33MSedzwF/L3atftBVSTsi24+G5klQmC8ZGWj9PpQfB/KyMs1e9937IHWJe5K+RNgT7K7
9j0y+s1c9vY6QBw0YeLznuwA6LDYPo8YR5Cefj9z+xtQP684rXkQcN6gW5o8ntvHAf4+asveWaTE
FWpnXCYSDxhbUz/tQR/yH4q/pzg4vpCIvxHF+Xb2JzL80Hdic84jEup5bSiS1JfibSkoehL0PkMF
pfx/oND08K7xI953Bm01G8u3gyF0jb6OFN+534DTmSmMOTAUTqsNk5rYc98RhXNMM1QX4e2hoOiP
zI2MLlCzh6FYF6mCUIuv/ky7ZK1RbgZDElEPz/nDPefnOU9PYlMB7ebIxyaWzO95eyj6Ga5Bzluj
WZDneF13LmB/nu3e8qVICPpXd9C0WtqVdWAoKIQZqWvGp0MZpGvFM/DrCJq1eiVDHIayrcPGnyJh
f/6vBDRI6pV3xYF4zP1Thl+Pk/L+tGE4fj1FfVRVrJtZEPPJuI2hU8i3BztYtLFqKAyVNW2WOcHi
q99OBJFu5LX7QTbUSwjtUgjGdW3vk+yZ+HGhBZ5I/gz4PYbZ3bazAegLRKnPVA8JJuF3F2eEy9pA
fRLirWyqtg0jIW4roPS8RxYoDosgaKFhmFYHQNc455paAXhe9pU2QytAuwgd9ZlCRL/o56B5ErGg
eCWkxkGvTlqI/bBp3yEjQP5MZENj5c8A3Q0bkT69BRAPxZ12qaONgF6J/ToOcgTEJbG1d62UIkH/
oudHrTkzmkA9498FVwHiNZCcSgMREvKLYhVPdEVI0NEQy5BP4gDdCouRbXfUwJfTM4fM2QcYF/qT
Y4ExQswn3Gv4Lc52ewnYh7lmWuYMyofZDeiJNyG3iOggK98ahtQD/n6vVo0/gfyW3ZI171EegThE
tKV+tEF739mPQgM5P9kR6H9hg86OKzb4ALDnaHTHIRLixBGbwAqHYUI8t+D8ec1cQNwuOjZPxgQQ
nwu16nqNrCHQ//mMhGE5gL9HbibdIxIX2R0nkh6sKiVQD313SwpIX6bom8Sn6wQUCnG87KLLnMiI
q0WqP3mA3ttEqTBiZADOz1BQfBfEjvkoe5Py/4ECbYiDcxoDhkzulDrnWMAQtne5jV/XPoNr1Pjy
CBY040lc7gsD3r/H7ozzA+SjEBbudUvd8sz57PkPQTqpMX76PW8PBYUgWFnbrnppB0PyxrEt9Xxx
KxwDyysHTGHItfhVygtAHI2w0B3l0XDaBN8u2+ij0fXp+HlHQcEP+uVyWLIs3k/QhWWJGl15rIT1
fn7fWmb8mgVh7Wvj9oh/rT87+XoQrMfz5yrliMN8eXq5RxJ9IzXwdobHpQ5NoQvPzz/qz/dYNhU/
v5D6iuVzlfHrF1cy5aysovDsYZoarL8+AW8PvXU5I3sENd/7HDF1E31535meGl6GF/nvudv5MXIJ
73ubxrw34QeA/oVaOV1QEiSe6Nqr2V9qWFDsxaRXMwRZj2K1mIw6FsTep8deIIj+tWuV7SqePfWs
kNkzSIjbYnN1jQaTcY4rw2fbDv59P8zhpxN/sCDmojrYEvC8tE8ni0sA939x6y7bn/yO9C8koLg4
DaRDTSp/JwbKT0gSaFyrv7wqYL5U6UiFigPaHbUzKwYQx4Rsb7jZSeRey1tbTPcD8u9h9/zC75Cg
N3HdOr/sJqDvoL8PSTsC0G2R04r1UiTEcWBr6otaSPBnROHP8AjAeyz/zcTVNzUB41hpVIYC8kly
tnjMlgHkI+3voAtii+eD7jsz9Z5eRCAfHbbqwqwtBPJVop0Fu84B8hOicpwjBs2C7wthR6QmvCCi
f4VcfbcSpO/0EmizilOkEPO4Eia5QCakEzBej390lyUhThz5bFUeKcT7K9mbT+hKgfLEmjVuVQXd
nxjxoN3uNYH+58zeMhsUv6NvdSeUiI7WHfmiqiWg+Lvu2PLpzQwy2qXoGRiqQz+QoZN2R+vLdSNq
SYjzvXleHiES59sdszKXvGqg/JPiO+WKvfOBPMr/BwxBultcpWGI/eatwpSpMIQFuqhm8L5Dsfqm
tN+6vmM2ZLpqGfP+//XSz1gPnqOrH5PAyDDCtxu7OXfKMeZXOyko+gMfnxx55jEfhoLqrs09wxcv
wzyaVrLUEoY8RX+62iSEOJTuKE44tCjOhNduqtYVjG9fERnM9Niu2/PznaJ/gWS4wcMl8O9h9EuB
ir+i8PyHu3rv7x5yMETPybmjybcPuX947J6maTx7lBwNc/jimCQ2fnHJ4pVbT9a8zOXbN0PWnl6y
m/ddjeqVplwQRC84/kuU2UcWhB67MSqB7xyy9ahtm8ep4/uBOyI1KkaN167D+pWn+O5Hw5j0UB0a
CfZ0R9V7I7oGz56WauNxfOfn2YO/HKscTc33XkfcW8yl7av/IJLiS+dKwlDTUb/G4XzvZ6w5yD95
EM+fQxpH2P4AGK+GlUp3iOSP+iv7Jmac72RBNLHAYUYCxElhuYtDSnj+zJlzvH2hIHGFL4sUXgzm
Pa+mGCtGkHvxypm38jp4z6Wy8MsNQfycuwrec5MFIVctIyP4dY0xv4Smy8BQuJap2Qr+dVxLZPn5
z7z3g5u5/f/kc5s/1X1NAa/8x3P5F4S4f9jXCJfIma0OOBeBbb3mfkaIv+extQUxoqC8eVYXvJsB
+hcWkV3RLgGwR/OAuSGBeCtuQmpCEWD/FvWWnCYKqp8gtBEuyTcIxFmzg1+IyoDiKSaavrUj4/4v
un9aIAn5BrHJ+2PEQHrWw+vX3ADvgfA/CmVeA+Lp2NWGR6yEeJ9mb4GqqYxktQF0jatTT6gByiE/
/SSdF4C/r5IKuk0gfgqt2n3AHlT/log2lIR8jJA9XOkCiuvpDvOLUfqgODiK/wc9PduRBYg/Df8k
eraYhPctUqpxNpuEfKdQ9Qrvba8A4zj4tHk1QE/H3lyazQa9r27LDdHgEvAHL8fEB6C//zx5dHY5
CX4VdcNXlcg9a/a36sLIaJeiZ0h80alKxj2MZJGtoekDuu9vt8bEPDLy0yrb5k/pQ/GtFBQ9irvF
pF1/UP4/UEBbI2KRITCEJkXfydKHIXro724TeL83kDuXpAOHw5BrZ7XnLQMYYtfYOxWScF7xH4m9
+5BZxoKyNQt2mXXpXHcuH0W79hnq0mAd3jrD1ttxspHPTgqK/kCUwqiK0cYwxDG7q+HFd4/JidUx
rX/M482vvfViyaD9TCFBu5w17cGsrn1FlQW5DL44Gi8xuzm8+c6c06o3lUHNLwowiNP0yHWK+Pcw
ZhkdtVVJeO9n9uaRe91U8fUjUQc2hmnAUPhvZScl+O55obfaTk9k4v2cTS9m7JLjW1/+JdyLJibG
8vh60GOpc/W64qpehh2ZwJdfK99npNlFgJ2odmZ9Vtc55oehetfJOKf3F7AkzhITBn4dz18jcqZD
jbfem4R5J4+l5nuPM2aNz6A6Fs5PkMLbgYHS+HHBVnq5K/DGj1taqv4rf7yekqnK4SLB/QfFGCuC
5QV//2PwpWWdvPlAF9CvkOpRxZpS+PlCuB7Dw2sSZAWvB53sd3BwM3686AlvLh0egX/P0B3uF5cr
89r9y7oPXTUrbKnF1zPQYZ+UEFcG6COI6ya5sUTiqgiCPTgmKcV/roAzpm3FQxaErF/1YBh//wf8
Wm2fwZs/tr575PnjC7AnLSP9eeU+l2UTBVnXhlbPSs5iQahXQPNkQXTYWp9powt59j8ZciRIkPxj
nMhNbXEsiHvjrl2iIHlTG1Qm7ijg9c+BNOVkUFzGt3L9mWRCHu+5zJ1H3+Xvn4CT6/MjWVB4UdjP
ufzzly1rOP8uC8rXds00A+WDPZs1U2IA3q+H/rbHtIKIbj5h39YrgLgkdKTIherPgv/e4HKm6+iR
oKegxVNuJ/Wl+7MGKOhWy0FnSMhbiDh9WKpPxrmFF9cDFRpBeTXLnFUA9dNTfMWtQO9hd2tmJRn5
A2XGmdiQEYeVeb3k/mPKn787trcvlwScN+g15j7x1ichPhdt1nF8AYj/paCgoOh33K+pePCBBQVI
xz4a1/W9UbKJkd7O+z7bNszZprPrXpDfj0ydBEOYlmeeJQn5ov+RJP/ArdWAdn0Daz3zeXa5M1vH
df0e2jqHmU5GvnEKih6AFpn20pQJQ4huqMopvu/xj375nD16MIRWXTQS68l8ntOOyd1V582vuIdD
0vnyYCA05LDTJHw5BQU/aIamQrPY1/XivzS7PTWmCW+9QB1tIz7I4+vnwvHlfnJ4e7ifqy/Tafhy
bOZTnWeSAPuJMnRT4X1pQD273FqsB+HXKWxLYLwSBFi/8gvFarr2p4S0rnGV1qB2yoD5blFy6qMU
Cf1A8e+w0nlzuAYw7nVWCyoH48cLHV5LfwAoh+6lumzjCu4/yKuk955igs9fjFMrFi8u+DqCGp1T
3N91P42g/mnaKtokSsJ7qUYcm/ka0M9YwqQECfzzYifC94ZJAfrhqqmjSa3w5nuf5ZC9wQNQvIAK
Tf+ZILpJdzTkTBnVdZ4eHvqY8y33i9E5doHFgHGZd+Dontsk+OEw0/cNXXp3T31P/RMrV5g/fEbC
c5GFf9WB1V268MyfPF7x63F35rVpVbHw82hPnuKYYkB/ordPde07I1qO7ZsGoL6Mnt7RdpqM/UwF
Nel7gDyKhBkqLaZERnxB8LlDUkTiZSj+HXUbExBQHB9RpN59KCcjHiSn9r0WIA4LlV3x5CJgXUAP
NpRJAfK4Qs8XqReSkY+u6eonXVBeRAqK/ohy3LXjZOi5/h2he0qoeUFB0Qv8H5mRW2E=\
""", 'base64'), 'zip')).reshape((8, 8, 6, 6, 3, 1))
        numpy.testing.assert_almost_equal(diss_matrix, expected_matrix)
Exemple #26
0
from openquake.hazardlib.geo import Line, Point
from openquake.hazardlib.site import Site, SiteCollection
from openquake.hazardlib.source import PointSource
from openquake.hazardlib.mfd import ArbitraryMFD
from openquake.hazardlib.scalerel import WC1994
from openquake.hazardlib.geo.nodalplane import NodalPlane

aac = numpy.testing.assert_allclose
dists = numpy.array([0, 10, 20, 30, 40, 50])
intensities = {
    '4.5': numpy.array([1.0, .95, .7, .6, .5, .3]),
    '5.0': numpy.array([1.2, 1.1, .7, .69, .6, .5]),
    '5.5': numpy.array([1.5, 1.2, .89, .85, .82, .6]),
    '6.0': numpy.array([2.0, 1.5, .9, .85, .81, .6])
}
tom = PoissonTOM(50.)


class ClosestPointOnTheRuptureTestCase(unittest.TestCase):
    def setUp(self):

        # Create surface
        trc = Line([Point(0.0, 0.0), Point(0.5, 0.0)])
        usd = 0.0
        lsd = 20.0
        dip = 90.0
        spc = 2.5
        self.srfc1 = SFS.from_fault_data(trc, usd, lsd, dip, spc)

        # Create surface
        trc = Line([Point(0.0, 0.0), Point(0.5, 0.0)])
Exemple #27
0
    def test_7_many_ruptures(self):
        source_id = name = 'test7-source'
        trt = TRT.VOLCANIC
        mag1 = 4.5
        mag2 = 5.5
        mag1_rate = 9e-3
        mag2_rate = 9e-4
        hypocenter1 = 9.0
        hypocenter2 = 10.0
        hypocenter1_weight = Decimal('0.8')
        hypocenter2_weight = Decimal('0.2')
        nodalplane1 = NodalPlane(strike=45, dip=90, rake=0)
        nodalplane2 = NodalPlane(strike=0, dip=45, rake=10)
        nodalplane1_weight = Decimal('0.3')
        nodalplane2_weight = Decimal('0.7')
        upper_seismogenic_depth = 2
        lower_seismogenic_depth = 16
        rupture_aspect_ratio = 2
        rupture_mesh_spacing = 0.5
        location = Point(0, 0)
        magnitude_scaling_relationship = PeerMSR()
        tom = PoissonTOM(time_span=50)

        mfd = EvenlyDiscretizedMFD(min_mag=mag1,
                                   bin_width=(mag2 - mag1),
                                   occurrence_rates=[mag1_rate, mag2_rate])
        nodal_plane_distribution = PMF([(nodalplane1_weight, nodalplane1),
                                        (nodalplane2_weight, nodalplane2)])
        hypocenter_distribution = PMF([(hypocenter1_weight, hypocenter1),
                                       (hypocenter2_weight, hypocenter2)])
        point_source = PointSource(
            source_id, name, trt, mfd, rupture_mesh_spacing,
            magnitude_scaling_relationship, rupture_aspect_ratio, tom,
            upper_seismogenic_depth, lower_seismogenic_depth, location,
            nodal_plane_distribution, hypocenter_distribution)
        actual_ruptures = list(point_source.iter_ruptures())
        self.assertEqual(len(actual_ruptures), point_source.count_ruptures())
        expected_ruptures = {
            (mag1, nodalplane1.rake, hypocenter1): (
                # probabilistic rupture's occurrence rate
                9e-3 * 0.3 * 0.8,
                # rupture surface corners
                planar_surface_test_data.TEST_7_RUPTURE_1_CORNERS),
            (mag2, nodalplane1.rake, hypocenter1):
            (9e-4 * 0.3 * 0.8,
             planar_surface_test_data.TEST_7_RUPTURE_2_CORNERS),
            (mag1, nodalplane2.rake, hypocenter1):
            (9e-3 * 0.7 * 0.8,
             planar_surface_test_data.TEST_7_RUPTURE_3_CORNERS),
            (mag2, nodalplane2.rake, hypocenter1):
            (9e-4 * 0.7 * 0.8,
             planar_surface_test_data.TEST_7_RUPTURE_4_CORNERS),
            (mag1, nodalplane1.rake, hypocenter2):
            (9e-3 * 0.3 * 0.2,
             planar_surface_test_data.TEST_7_RUPTURE_5_CORNERS),
            (mag2, nodalplane1.rake, hypocenter2):
            (9e-4 * 0.3 * 0.2,
             planar_surface_test_data.TEST_7_RUPTURE_6_CORNERS),
            (mag1, nodalplane2.rake, hypocenter2):
            (9e-3 * 0.7 * 0.2,
             planar_surface_test_data.TEST_7_RUPTURE_7_CORNERS),
            (mag2, nodalplane2.rake, hypocenter2):
            (9e-4 * 0.7 * 0.2,
             planar_surface_test_data.TEST_7_RUPTURE_8_CORNERS)
        }
        for actual_rupture in actual_ruptures:
            expected_occurrence_rate, expected_corners = expected_ruptures[(
                actual_rupture.mag, actual_rupture.rake,
                actual_rupture.hypocenter.depth)]
            self.assertTrue(
                isinstance(actual_rupture, ParametricProbabilisticRupture))
            self.assertEqual(actual_rupture.occurrence_rate,
                             expected_occurrence_rate)
            self.assertIs(actual_rupture.temporal_occurrence_model, tom)
            self.assertEqual(actual_rupture.tectonic_region_type, trt)
            surface = actual_rupture.surface

            tl, tr, br, bl = expected_corners
            self.assertEqual(tl, surface.top_left)
            self.assertEqual(tr, surface.top_right)
            self.assertEqual(bl, surface.bottom_left)
            self.assertEqual(br, surface.bottom_right)
Exemple #28
0
    def test_point_sources(self):
        sources = [
            openquake.hazardlib.source.PointSource(
                source_id='point1',
                name='point1',
                tectonic_region_type=const.TRT.ACTIVE_SHALLOW_CRUST,
                mfd=openquake.hazardlib.mfd.EvenlyDiscretizedMFD(
                    min_mag=4, bin_width=1, occurrence_rates=[5]),
                nodal_plane_distribution=openquake.hazardlib.pmf.PMF([
                    (1,
                     openquake.hazardlib.geo.NodalPlane(strike=0.0,
                                                        dip=90.0,
                                                        rake=0.0))
                ]),
                hypocenter_distribution=openquake.hazardlib.pmf.PMF([(1, 10)]),
                upper_seismogenic_depth=0.0,
                lower_seismogenic_depth=10.0,
                magnitude_scaling_relationship=openquake.hazardlib.scalerel.
                PeerMSR(),
                rupture_aspect_ratio=2,
                temporal_occurrence_model=PoissonTOM(1.),
                rupture_mesh_spacing=1.0,
                location=Point(10, 10)),
            openquake.hazardlib.source.PointSource(
                source_id='point2',
                name='point2',
                tectonic_region_type=const.TRT.ACTIVE_SHALLOW_CRUST,
                mfd=openquake.hazardlib.mfd.EvenlyDiscretizedMFD(
                    min_mag=4, bin_width=2, occurrence_rates=[5, 6, 7]),
                nodal_plane_distribution=openquake.hazardlib.pmf.PMF([
                    (1,
                     openquake.hazardlib.geo.NodalPlane(strike=0,
                                                        dip=90,
                                                        rake=0.0)),
                ]),
                hypocenter_distribution=openquake.hazardlib.pmf.PMF([(1, 10)]),
                upper_seismogenic_depth=0.0,
                lower_seismogenic_depth=10.0,
                magnitude_scaling_relationship=openquake.hazardlib.scalerel.
                PeerMSR(),
                rupture_aspect_ratio=2,
                temporal_occurrence_model=PoissonTOM(1.),
                rupture_mesh_spacing=1.0,
                location=Point(10, 11)),
        ]
        sites = [
            openquake.hazardlib.site.Site(Point(11, 10), 1, True, 2, 3),
            openquake.hazardlib.site.Site(Point(10, 16), 2, True, 2, 3),
            openquake.hazardlib.site.Site(Point(10, 10.6), 3, True, 2, 3),
            openquake.hazardlib.site.Site(Point(10, 10.7), 4, True, 2, 3)
        ]
        sitecol = openquake.hazardlib.site.SiteCollection(sites)

        from openquake.hazardlib.gsim.sadigh_1997 import SadighEtAl1997
        gsims = {const.TRT.ACTIVE_SHALLOW_CRUST: SadighEtAl1997()}
        truncation_level = 1
        imts = {'PGA': [0.1, 0.5, 1.3]}

        from openquake.hazardlib.calc import filters
        source_site_filter = self.SitesCounterSourceFilter(
            filters.source_site_distance_filter(30))
        rupture_site_filter = self.SitesCounterRuptureFilter(
            filters.rupture_site_distance_filter(30))
        calc_hazard_curves(sources,
                           sitecol,
                           imts,
                           gsims,
                           truncation_level,
                           source_site_filter=source_site_filter,
                           rupture_site_filter=rupture_site_filter)
        # there are two sources and four sites. The first source contains only
        # one rupture, the second source contains three ruptures.
        #
        # the first source has 'maximum projection radius' of 0.707 km
        # the second source has 'maximum projection radius' of 500.0 km
        #
        # the epicentral distances for source 1 are: [ 109.50558394,
        # 667.16955987,   66.71695599,   77.83644865]
        # the epicentral distances for source 2 are: [ 155.9412148 ,
        # 555.97463322,   44.47797066,   33.35847799]
        #
        # Considering that the source site filtering distance is set to 30 km,
        # for source 1, all sites have epicentral distance larger than
        # 0.707 + 30 km. This means that source 1 ('point 1') is not considered
        # in the calculation because too far.
        # for source 2, the 1st, 3rd and 4th sites have epicentral distances
        # smaller than 500.0 + 30 km. This means that source 2 ('point 2') is
        # considered in the calculation for site 1, 3, and 4.
        #
        # JB distances for rupture 1 in source 2 are: [ 155.43860273,
        #  555.26752644,   43.77086388,   32.65137121]
        # JB distances for rupture 2 in source 2 are: [ 150.98882575,
        #  548.90356541,   37.40690285,   26.28741018]
        # JB distances for rupture 3 in source 2 are: [ 109.50545819,
        # 55.97463322,    0.        ,    0.        ]
        #
        # Considering that the rupture site filtering distance is set to 30 km,
        # rupture 1 (magnitude 4) is not considered because too far, rupture 2
        # (magnitude 6) affect only the 4th site, rupture 3 (magnitude 8)
        # affect the 3rd and 4th sites.
        self.assertEqual(source_site_filter.counts, [('point2', [1, 3, 4])])
        self.assertEqual(rupture_site_filter.counts, [(6, [4]), (8, [3, 4])])
Exemple #29
0
 def test_probabilistic_rupture_zero_occurrence_rate(self):
     self.assert_failed_creation(
         ParametricProbabilisticRupture, ValueError,
         'occurrence rate must be positive',
         occurrence_rate=0, temporal_occurrence_model=PoissonTOM(10)
     )
Exemple #30
0
def hazard_curves_poissonian(
        sources,
        sites,
        imts,
        time_span,
        gsims,
        truncation_level,
        source_site_filter=filters.source_site_noop_filter,
        rupture_site_filter=filters.rupture_site_noop_filter):
    """
    Compute hazard curves on a list of sites, given a set of seismic sources
    and a set of ground shaking intensity models (one per tectonic region type
    considered in the seismic sources).

    The calculator assumes
    :class:`Poissonian <openquake.hazardlib.tom.PoissonTOM>` temporal
    occurrence model.

    The calculator computes probability of ground motion exceedance according
    to the equation as described in pag. 419 of "OpenSHA: A Developing
    Community-modeling Environment for Seismic Hazard Analysis, Edward
    H. Field, Thomas H. Jordan and C. Allin Cornell. Seismological Research
    Letters July/August 2003 v. 74 no. 4 p. 406-419".

    :param sources:
        An iterator of seismic sources objects (instances of subclasses
        of :class:`~openquake.hazardlib.source.base.SeismicSource`).
    :param sites:
        Instance of :class:`~openquake.hazardlib.site.SiteCollection` object,
        representing sites of interest.
    :param imts:
        Dictionary mapping intensity measure type objects (see
        :mod:`openquake.hazardlib.imt`) to lists of intensity measure levels.
    :param time_span:
        An investigation period for Poissonian temporal occurrence model,
        floating point number in years.
    :param gsims:
        Dictionary mapping tectonic region types (members
        of :class:`openquake.hazardlib.const.TRT`) to
        :class:`~openquake.hazardlib.gsim.base.GMPE` or
        :class:`~openquake.hazardlib.gsim.base.IPE` objects.
    :param trunctation_level:
        Float, number of standard deviations for truncation of the intensity
        distribution.
    :param source_site_filter:
        Optional source-site filter function. See
        :mod:`openquake.hazardlib.calc.filters`.
    :param rupture_site_filter:
        Optional rupture-site filter function. See
        :mod:`openquake.hazardlib.calc.filters`.

    :returns:
        Dictionary mapping intensity measure type objects (same keys
        as in parameter ``imts``) to 2d numpy arrays of float, where
        first dimension differentiates sites (the order and length
        are the same as in ``sites`` parameter) and the second one
        differentiates IMLs (the order and length are the same as
        corresponding value in ``imts`` dict).
    """
    curves = dict(
        (imt, numpy.ones([len(sites), len(imts[imt])])) for imt in imts)
    tom = PoissonTOM(time_span)

    total_sites = len(sites)
    sources_sites = ((source, sites) for source in sources)
    for source, s_sites in source_site_filter(sources_sites):
        try:
            ruptures_sites = ((rupture, s_sites)
                              for rupture in source.iter_ruptures(tom))
            for rupture, r_sites in rupture_site_filter(ruptures_sites):
                prob = rupture.get_probability_one_or_more_occurrences()
                gsim = gsims[rupture.tectonic_region_type]
                sctx, rctx, dctx = gsim.make_contexts(r_sites, rupture)
                for imt in imts:
                    poes = gsim.get_poes(sctx, rctx, dctx, imt, imts[imt],
                                         truncation_level)
                    curves[imt] *= r_sites.expand((1 - prob)**poes,
                                                  total_sites,
                                                  placeholder=1)
        except Exception, err:
            msg = 'An error occurred with source id=%s. Error: %s'
            msg %= (source.source_id, err.message)
            raise RuntimeError(msg)