Exemple #1
0
def example_calc(apply):
    sitecol = SiteCollection([
        Site(Point(30.0, 30.0), 760., 1.0, 1.0),
        Site(Point(30.25, 30.25), 760., 1.0, 1.0),
        Site(Point(30.4, 30.4), 760., 1.0, 1.0)
    ])
    mfd_1 = TruncatedGRMFD(4.5, 8.0, 0.1, 4.0, 1.0)
    mfd_2 = TruncatedGRMFD(4.5, 7.5, 0.1, 3.5, 1.1)
    sources = [
        PointSource('001', 'Point1', 'Active Shallow Crust', mfd_1, 1.0,
                    WC1994(), 1.0, PoissonTOM(50.0), 0.0, 30.0,
                    Point(30.0, 30.5), PMF([(1.0, NodalPlane(0.0, 90.0,
                                                             0.0))]),
                    PMF([(1.0, 10.0)])),
        PointSource('002', 'Point2', 'Active Shallow Crust', mfd_2, 1.0,
                    WC1994(), 1.0, PoissonTOM(50.0), 0.0, 30.0,
                    Point(30.0, 30.5), PMF([(1.0, NodalPlane(0.0, 90.0,
                                                             0.0))]),
                    PMF([(1.0, 10.0)]))
    ]
    imtls = {
        'PGA': [0.01, 0.1, 0.2, 0.5, 0.8],
        'SA(0.5)': [0.01, 0.1, 0.2, 0.5, 0.8]
    }
    gsims = {'Active Shallow Crust': AkkarBommer2010()}
    return calc_hazard_curves(sources,
                              sitecol,
                              imtls,
                              gsims,
                              apply=apply,
                              filter_distance='rrup')
Exemple #2
0
 def setUp(self):
     """
     """
     mfd_1 = TruncatedGRMFD(4.5, 8.0, 0.1, 4.0, 1.0)
     mfd_2 = TruncatedGRMFD(4.5, 7.5, 0.1, 3.5, 1.1)
     self.source_model = [
         PointSource('001', 'Point1', 'Active Shallow Crust', mfd_1, 1.0,
                     WC1994(), 1.0, PoissonTOM(50.0), 0.0, 30.0,
                     Point(30.0, 30.5),
                     PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))]),
                     PMF([(1.0, 10.0)])),
         PointSource('002', 'Point2', 'Active Shallow Crust', mfd_2, 1.0,
                     WC1994(), 1.0, PoissonTOM(50.0), 0.0, 30.0,
                     Point(30.0, 30.5),
                     PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))]),
                     PMF([(1.0, 10.0)]))
     ]
     self.sites = SiteCollection([
         Site(Point(30.0, 30.0), 760., True, 1.0, 1.0, 1),
         Site(Point(30.25, 30.25), 760., True, 1.0, 1.0, 2),
         Site(Point(30.4, 30.4), 760., True, 1.0, 1.0, 2)
     ])
     self.gsims = {'Active Shallow Crust': 'AkkarBommer2010'}
     self.imts = ['PGA', 'SA(0.5)']
     self.imls = [[0.01, 0.1, 0.2, 0.5, 0.8]]
Exemple #3
0
def reference_psha_calculation_openquake():
    """
    Sets up the reference PSHA calculation calling OpenQuake directly. All
    subsequent implementations should match this example
    """
    # Site model - 3 Sites
    site_model = SiteCollection([
        Site(Point(30.0, 30.0), 760., True, 1.0, 1.0, 1),
        Site(Point(30.25, 30.25), 760., True, 1.0, 1.0, 2),
        Site(Point(30.4, 30.4), 760., True, 1.0, 1.0, 2)
    ])
    # Source Model Two Point Sources
    mfd_1 = TruncatedGRMFD(4.5, 8.0, 0.1, 4.0, 1.0)
    mfd_2 = TruncatedGRMFD(4.5, 7.5, 0.1, 3.5, 1.1)
    source_model = [
        PointSource('001', 'Point1', 'Active Shallow Crust', mfd_1, 1.0,
                    WC1994(), 1.0, PoissonTOM(50.0), 0.0, 30.0,
                    Point(30.0, 30.5), PMF([(1.0, NodalPlane(0.0, 90.0,
                                                             0.0))]),
                    PMF([(1.0, 10.0)])),
        PointSource('002', 'Point2', 'Active Shallow Crust', mfd_2, 1.0,
                    WC1994(), 1.0, PoissonTOM(50.0), 0.0, 30.0,
                    Point(30.0, 30.5), PMF([(1.0, NodalPlane(0.0, 90.0,
                                                             0.0))]),
                    PMF([(1.0, 10.0)]))
    ]
    imts = {
        'PGA': [0.01, 0.1, 0.2, 0.5, 0.8],
        'SA(0.5)': [0.01, 0.1, 0.2, 0.5, 0.8]
    }
    # Akkar & Bommer (2010) GMPE
    gsims = {'Active Shallow Crust': gsim.akkar_bommer_2010.AkkarBommer2010()}
    truncation_level = None
    return calc_hazard_curves(source_model, site_model, imts, gsims,
                              truncation_level)
    def __init__(
        self,
        source_id,
        name,
        tectonic_region_type,
        mfd,
        rupture_mesh_spacing,
        magnitude_scaling_relationship,
        rupture_aspect_ratio,
        temporal_occurrence_model,
        # complex fault specific parameters
        edges,
        rake,
    ):
        super(ComplexFaultSource, self).__init__(
            source_id,
            name,
            tectonic_region_type,
            mfd,
            rupture_mesh_spacing,
            magnitude_scaling_relationship,
            rupture_aspect_ratio,
            temporal_occurrence_model,
        )

        NodalPlane.check_rake(rake)
        ComplexFaultSurface.check_fault_data(edges, rupture_mesh_spacing)
        self.edges = edges
        self.rake = rake
    def __init__(self, source_id, name, tectonic_region_type,
                 mfd, rupture_mesh_spacing,
                 magnitude_scaling_relationship, rupture_aspect_ratio,
                 # simple fault specific parameters
                 upper_seismogenic_depth, lower_seismogenic_depth,
                 fault_trace, dip, rake):
        super(SimpleFaultSource, self).__init__(
            source_id, name, tectonic_region_type, mfd, rupture_mesh_spacing,
            magnitude_scaling_relationship, rupture_aspect_ratio
        )

        NodalPlane.check_rake(rake)
        SimpleFaultSurface.check_fault_data(
            fault_trace, upper_seismogenic_depth, lower_seismogenic_depth,
            dip, rupture_mesh_spacing
        )
        self.fault_trace = fault_trace
        self.upper_seismogenic_depth = upper_seismogenic_depth
        self.lower_seismogenic_depth = lower_seismogenic_depth
        self.dip = dip
        self.rake = rake

        min_mag = self.mfd.get_min_mag()
        cols_rows = self._get_rupture_dimensions(float('inf'), float('inf'),
                                                 min_mag)
        if 1 in cols_rows:
            raise ValueError('mesh spacing %s is too low to represent '
                             'ruptures of magnitude %s' %
                             (rupture_mesh_spacing, min_mag))
    def setUp(self):
        """
        """
        #~ self.npd_as_list = [models.NodalPlane(0.5, 0., 90., 0.),
                            #~ models.NodalPlane(0.5, 90., 90., 180.)]
        self.npd_as_pmf = PMF([(0.5, NodalPlane(0., 90., 0.)),
                               (0.5, NodalPlane(90., 90., 180.))])

        self.npd_as_pmf_bad = PMF([(0.5, None),
                                    (0.5, NodalPlane(90., 90., 180.))])
Exemple #7
0
 def __init__(self, mag, rake, tectonic_region_type, hypocenter,
              surface, rupture_slip_direction=None):
     if not mag > 0:
         raise ValueError('magnitude must be positive')
     NodalPlane.check_rake(rake)
     self.tectonic_region_type = tectonic_region_type
     self.rake = rake
     self.mag = mag
     self.hypocenter = hypocenter
     self.surface = surface
     self.rupture_slip_direction = rupture_slip_direction
Exemple #8
0
    def __init__(self,
                 strike,
                 dip,
                 top_left,
                 top_right,
                 bottom_right,
                 bottom_left,
                 check=True):
        if check:
            if not (top_left.depth == top_right.depth
                    and bottom_left.depth == bottom_right.depth):
                raise ValueError("top and bottom edges must be parallel "
                                 "to the earth surface")
            NodalPlane.check_dip(dip)
            NodalPlane.check_strike(strike)
        self.dip = dip
        self.strike = strike

        self.corner_lons = numpy.array([
            top_left.longitude, top_right.longitude, bottom_left.longitude,
            bottom_right.longitude
        ])
        self.corner_lats = numpy.array([
            top_left.latitude, top_right.latitude, bottom_left.latitude,
            bottom_right.latitude
        ])
        self.corner_depths = numpy.array([
            top_left.depth, top_right.depth, bottom_left.depth,
            bottom_right.depth
        ])
        # now set the attributes normal, d, uv1, uv2, zero_zero
        self._init_plane()

        # now we can check surface for validity
        dists, xx, yy = self._project(self.mesh.xyz)
        # "length" of the rupture is measured along the top edge
        length1, length2 = xx[1] - xx[0], xx[3] - xx[2]
        # "width" of the rupture is measured along downdip direction
        width1, width2 = yy[2] - yy[0], yy[3] - yy[1]
        self.width = (width1 + width2) / 2.0
        self.length = (length1 + length2) / 2.0

        if check:
            # calculate the imperfect rectangle tolerance
            # relative to surface's area
            tolerance = (self.width * self.length *
                         self.IMPERFECT_RECTANGLE_TOLERANCE)
            if numpy.max(numpy.abs(dists)) > tolerance:
                logging.warning("corner points do not lie on the same plane")
            if length2 < 0:
                raise ValueError("corners are in the wrong order")
            if abs(length1 - length2) > tolerance:
                raise ValueError("top and bottom edges have different lengths")
Exemple #9
0
 def __init__(self, mag, rake, tectonic_region_type, hypocenter, surface, source_typology):
     if not mag > 0:
         raise ValueError("magnitude must be positive")
     if not hypocenter.depth > 0:
         raise ValueError("rupture hypocenter must have positive depth")
     NodalPlane.check_rake(rake)
     self.tectonic_region_type = tectonic_region_type
     self.rake = rake
     self.mag = mag
     self.hypocenter = hypocenter
     self.surface = surface
     self.source_typology = source_typology
Exemple #10
0
 def __init__(self, mag, rake, tectonic_region_type, hypocenter,
              surface, rupture_slip_direction=None, weight=None):
     if not mag > 0:
         raise ValueError('magnitude must be positive')
     NodalPlane.check_rake(rake)
     self.tectonic_region_type = tectonic_region_type
     self.rake = rake
     self.mag = mag
     self.hypocenter = hypocenter
     self.surface = surface
     self.rupture_slip_direction = rupture_slip_direction
     self.weight = weight
Exemple #11
0
    def __init__(self, mesh_spacing, strike, dip,
                 top_left, top_right, bottom_right, bottom_left):
        super(PlanarSurface, self).__init__()
        if not (top_left.depth == top_right.depth
                and bottom_left.depth == bottom_right.depth):
            raise ValueError("top and bottom edges must be parallel "
                             "to the earth surface")

        if not mesh_spacing > 0:
            raise ValueError("mesh spacing must be positive")
        self.mesh_spacing = mesh_spacing

        NodalPlane.check_dip(dip)
        NodalPlane.check_strike(strike)
        self.dip = dip
        self.strike = strike

        self.corner_lons = numpy.array([
            top_left.longitude, top_right.longitude,
            bottom_left.longitude, bottom_right.longitude
        ])
        self.corner_lats = numpy.array([
            top_left.latitude, top_right.latitude,
            bottom_left.latitude, bottom_right.latitude
        ])
        self.corner_depths = numpy.array([
            top_left.depth, top_right.depth,
            bottom_left.depth, bottom_right.depth
        ])
        self._init_plane()

        # now we can check surface for validity
        dists, xx, yy = self._project(self.corner_lons, self.corner_lats,
                                      self.corner_depths)
        # "length" of the rupture is measured along the top edge
        length1, length2 = xx[1] - xx[0], xx[3] - xx[2]
        # "width" of the rupture is measured along downdip direction
        width1, width2 = yy[2] - yy[0], yy[3] - yy[1]
        self.width = (width1 + width2) / 2.0
        self.length = (length1 + length2) / 2.0
        # calculate the imperfect rectangle tolerance
        # relative to surface's area
        tolerance = (self.width * self.length
                     * self.IMPERFECT_RECTANGLE_TOLERANCE)
        if numpy.max(numpy.abs(dists)) > tolerance:
            raise ValueError("corner points do not lie on the same plane")
        if length2 < 0:
            raise ValueError("corners are in the wrong order")
        if abs(length1 - length2) > tolerance:
            raise ValueError("top and bottom edges have different lengths")
        if abs(xx[0] - xx[2]) > tolerance:
            raise ValueError("surface's angles are not right")
Exemple #12
0
 def __init__(self, mag, rake, tectonic_region_type, hypocenter, surface,
              source_typology):
     if not mag > 0:
         raise ValueError('magnitude must be positive')
     if not hypocenter.depth > 0:
         raise ValueError('rupture hypocenter must have positive depth')
     NodalPlane.check_rake(rake)
     self.tectonic_region_type = tectonic_region_type
     self.rake = rake
     self.mag = mag
     self.hypocenter = hypocenter
     self.surface = surface
     self.source_typology = source_typology
 def __init__(self, source_id, name, tectonic_region_type, mfd,
              rupture_mesh_spacing, magnitude_scaling_relationship,
              rupture_aspect_ratio, temporal_occurrence_model,
              # complex fault specific parameters
              edges, rake):
     super().__init__(
         source_id, name, tectonic_region_type, mfd, rupture_mesh_spacing,
         magnitude_scaling_relationship, rupture_aspect_ratio,
         temporal_occurrence_model)
     NodalPlane.check_rake(rake)
     ComplexFaultSurface.check_fault_data(edges, rupture_mesh_spacing)
     self.edges = edges
     self.rake = rake
Exemple #14
0
    def __init__(
        self,
        source_id,
        name,
        tectonic_region_type,
        mfd,
        rupture_mesh_spacing,
        magnitude_scaling_relationship,
        rupture_aspect_ratio,
        temporal_occurrence_model,
        # simple fault specific parameters
        upper_seismogenic_depth,
        lower_seismogenic_depth,
        fault_trace,
        dip,
        rake,
        hypo_list=(),
        slip_list=()):
        super(SimpleFaultSource,
              self).__init__(source_id, name, tectonic_region_type, mfd,
                             rupture_mesh_spacing,
                             magnitude_scaling_relationship,
                             rupture_aspect_ratio, temporal_occurrence_model)

        NodalPlane.check_rake(rake)
        SimpleFaultSurface.check_fault_data(fault_trace,
                                            upper_seismogenic_depth,
                                            lower_seismogenic_depth, dip,
                                            rupture_mesh_spacing)
        self.fault_trace = fault_trace
        self.upper_seismogenic_depth = upper_seismogenic_depth
        self.lower_seismogenic_depth = lower_seismogenic_depth
        self.dip = dip
        self.rake = rake

        min_mag, max_mag = self.mfd.get_min_max_mag()
        cols_rows = self._get_rupture_dimensions(float('inf'), float('inf'),
                                                 min_mag)
        self.slip_list = slip_list
        self.hypo_list = hypo_list

        if (len(self.hypo_list) and not len(self.slip_list)
                or not len(self.hypo_list) and len(self.slip_list)):
            raise ValueError('hypo_list and slip_list have to be both given '
                             'or neither given')

        if 1 in cols_rows:
            raise ValueError('mesh spacing %s is too high to represent '
                             'ruptures of magnitude %s' %
                             (rupture_mesh_spacing, min_mag))
Exemple #15
0
 def __init__(self, mag, rake, tectonic_region_type, hypocenter,
              surface, source_typology, rupture_slip_direction=None, surface_nodes=()):
     if not mag > 0:
         raise ValueError('magnitude must be positive')
     if not hypocenter.depth > 0:
         raise ValueError('rupture hypocenter must have positive depth')
     NodalPlane.check_rake(rake)
     self.tectonic_region_type = tectonic_region_type
     self.rake = rake
     self.mag = mag
     self.hypocenter = hypocenter
     self.surface = surface
     self.source_typology = source_typology
     self.surface_nodes = surface_nodes
     self.rupture_slip_direction = rupture_slip_direction
Exemple #16
0
    def setUp(self):

        mfd = TruncatedGRMFD(min_mag=4.0, max_mag=6.0, bin_width=0.1,
                             a_val=2.0, b_val=1.0)
        msr = WC1994()
        tom = PoissonTOM(1.0)
        pol = Polygon([Point(longitude=0.0, latitude=0.0),
                       Point(longitude=1.0, latitude=0.0),
                       Point(longitude=1.0, latitude=1.0),
                       Point(longitude=0.0, latitude=1.0)])
        npd = PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))])
        hpd = PMF([(0.7, 10.), (0.3, 20.0)])

        self.src1 = AreaSource(source_id='1',
                               name='1',
                               tectonic_region_type='Test',
                               mfd=mfd,
                               rupture_mesh_spacing=1,
                               magnitude_scaling_relationship=msr,
                               rupture_aspect_ratio=1.,
                               temporal_occurrence_model=tom,
                               upper_seismogenic_depth=0,
                               lower_seismogenic_depth=100.,
                               nodal_plane_distribution=npd,
                               hypocenter_distribution=hpd,
                               polygon=pol,
                               area_discretization=10.)
Exemple #17
0
    def __init__(self, strike, dip,
                 top_left, top_right, bottom_right, bottom_left, check=True):
        if check:
            if not (top_left.depth == top_right.depth and
                    bottom_left.depth == bottom_right.depth):
                raise ValueError("top and bottom edges must be parallel "
                                 "to the earth surface")
            NodalPlane.check_dip(dip)
            NodalPlane.check_strike(strike)
        self.dip = dip
        self.strike = strike

        self.corner_lons = numpy.array([
            top_left.longitude, top_right.longitude,
            bottom_left.longitude, bottom_right.longitude
        ])
        self.corner_lats = numpy.array([
            top_left.latitude, top_right.latitude,
            bottom_left.latitude, bottom_right.latitude
        ])
        self.corner_depths = numpy.array([
            top_left.depth, top_right.depth,
            bottom_left.depth, bottom_right.depth
        ])
        # now set the attributes normal, d, uv1, uv2, zero_zero
        self._init_plane()

        # now we can check surface for validity
        dists, xx, yy = self._project(self.mesh.xyz)
        # "length" of the rupture is measured along the top edge
        length1, length2 = xx[1] - xx[0], xx[3] - xx[2]
        # "width" of the rupture is measured along downdip direction
        width1, width2 = yy[2] - yy[0], yy[3] - yy[1]
        self.width = (width1 + width2) / 2.0
        self.length = (length1 + length2) / 2.0

        if check:
            # calculate the imperfect rectangle tolerance
            # relative to surface's area
            tolerance = (self.width * self.length *
                         self.IMPERFECT_RECTANGLE_TOLERANCE)
            if numpy.max(numpy.abs(dists)) > tolerance:
                logging.warning("corner points do not lie on the same plane")
            if length2 < 0:
                raise ValueError("corners are in the wrong order")
            if abs(length1 - length2) > tolerance:
                raise ValueError("top and bottom edges have different lengths")
def npd_to_pmf(nodal_plane_dist, use_default=False):
    """
    Returns the nodal plane distribution as an instance of the PMF class
    """
    if isinstance(nodal_plane_dist, PMF):
        # Aready in PMF format - return
        return nodal_plane_dist
    elif isinstance(nodal_plane_dist, list):
        npd_list = []
        for npd in nodal_plane_dist:
            assert isinstance(npd, models.NodalPlane)
            npd_list.append(
                (npd.probability, NodalPlane(npd.strike, npd.dip, npd.rake)))
        return PMF(npd_list)
    else:
        if use_default:
            return PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))])
        else:
            raise ValueError('Nodal Plane distribution not defined')
 def test_render_nodal_planes_as_pmf_bad_2(self):
     '''
     Tests the workflow when nodal planes input as a PMF without
     probabilities summing to 1.0
     '''
     self.npd_as_pmf.data[1] = (0.4, NodalPlane(90., 90., 180.))
     with self.assertRaises(ValueError) as ae:
         output = conv.render_npd(self.npd_as_pmf)
         self.assertEqual(ae.exception.message,
                          'Nodal Plane probabilities do not sum to 1.0')
Exemple #20
0
    def _test_broken_input(self, broken_parameter, **kwargs):
        with self.assertRaises(ValueError) as ae:
            NodalPlane(**kwargs)
        self.assertTrue(str(ae.exception).startswith(broken_parameter),
                        str(ae.exception))

        checker = getattr(NodalPlane, 'check_%s' % broken_parameter)
        with self.assertRaises(ValueError) as ae:
            checker(kwargs[broken_parameter])
        self.assertTrue(str(ae.exception).startswith(broken_parameter),
                        str(ae.exception))
def npd_to_pmf(nodal_plane_dist, use_default=False):
    """
    Returns the nodal plane distribution as an instance of the PMF class
    """
    if isinstance(nodal_plane_dist, PMF):
        # Aready in PMF format - return
        return nodal_plane_dist
    else:
        if use_default:
            return PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))])
        else:
            raise ValueError('Nodal Plane distribution not defined')
    def __init__(self, source_id, name, tectonic_region_type,
                 mfd, rupture_mesh_spacing,
                 magnitude_scaling_relationship, rupture_aspect_ratio,
                 temporal_occurrence_model,
                 # simple fault specific parameters
                 upper_seismogenic_depth, lower_seismogenic_depth,
                 fault_trace, dip, rake, hypo_list=(), slip_list=()):
        super(SimpleFaultSource, self).__init__(
            source_id, name, tectonic_region_type, mfd, rupture_mesh_spacing,
            magnitude_scaling_relationship, rupture_aspect_ratio,
            temporal_occurrence_model
        )

        NodalPlane.check_rake(rake)
        SimpleFaultSurface.check_fault_data(
            fault_trace, upper_seismogenic_depth, lower_seismogenic_depth,
            dip, rupture_mesh_spacing
        )
        self.fault_trace = fault_trace
        self.upper_seismogenic_depth = upper_seismogenic_depth
        self.lower_seismogenic_depth = lower_seismogenic_depth
        self.dip = dip
        self.rake = rake

        min_mag, max_mag = self.mfd.get_min_max_mag()
        cols_rows = self._get_rupture_dimensions(float('inf'), float('inf'),
                                                 min_mag)
        self.slip_list = slip_list
        self.hypo_list = hypo_list

        if (len(self.hypo_list) and not len(self.slip_list) or
           not len(self.hypo_list) and len(self.slip_list)):
            raise ValueError('hypo_list and slip_list have to be both given '
                             'or neither given')

        if 1 in cols_rows:
            raise ValueError('mesh spacing %s is too high to represent '
                             'ruptures of magnitude %s' %
                             (rupture_mesh_spacing, min_mag))
Exemple #23
0
    def __init__(
            self,
            source_id,
            name,
            tectonic_region_type,
            mfd,
            rupture_mesh_spacing,
            magnitude_scaling_relationship,
            rupture_aspect_ratio,
            # simple fault specific parameters
            upper_seismogenic_depth,
            lower_seismogenic_depth,
            fault_trace,
            dip,
            rake):
        super(SimpleFaultSource,
              self).__init__(source_id, name, tectonic_region_type, mfd,
                             rupture_mesh_spacing,
                             magnitude_scaling_relationship,
                             rupture_aspect_ratio)

        NodalPlane.check_rake(rake)
        SimpleFaultSurface.check_fault_data(fault_trace,
                                            upper_seismogenic_depth,
                                            lower_seismogenic_depth, dip,
                                            rupture_mesh_spacing)
        self.fault_trace = fault_trace
        self.upper_seismogenic_depth = upper_seismogenic_depth
        self.lower_seismogenic_depth = lower_seismogenic_depth
        self.dip = dip
        self.rake = rake

        min_mag = self.mfd.get_min_mag()
        cols_rows = self._get_rupture_dimensions(float('inf'), float('inf'),
                                                 min_mag)
        if 1 in cols_rows:
            raise ValueError('mesh spacing %s is too low to represent '
                             'ruptures of magnitude %s' %
                             (rupture_mesh_spacing, min_mag))
Exemple #24
0
def make_rupture(trt, mag, msr=PointMSR(), aspect_ratio=1.0, seismo=(10, 30),
                 nodal_plane_tup=(0, 90, 0), hc_tup=(0, 0, 20),
                 occurrence_rate=1, tom=None):
    hc = Point(*hc_tup)
    np = NodalPlane(*nodal_plane_tup)
    ps = object.__new__(PointSource)
    ps.magnitude_scaling_relationship = msr
    ps.upper_seismogenic_depth = seismo[0]
    ps.lower_seismogenic_depth = seismo[1]
    ps.rupture_aspect_ratio = aspect_ratio
    surface, nhc = ps._get_rupture_surface(mag, np, hc)
    rup = ParametricProbabilisticRupture(
        mag, np.rake, trt, hc, surface, occurrence_rate, tom)
    return rup
Exemple #25
0
def node_to_nodal_planes(node):
    """
    Parses the nodal plane distribution to a PMF
    """
    if not len(node):
        return None
    npd_pmf = []
    for plane in node.nodes:
        if not all(plane.attrib[key] for key in plane.attrib):
            # One plane fails - return None
            return None
        npd = NodalPlane(float(plane.attrib["strike"]),
                         float(plane.attrib["dip"]),
                         float(plane.attrib["rake"]))
        npd_pmf.append((float(plane.attrib["probability"]), npd))
    return PMF(npd_pmf)
 def test(self):
     sitecol = SiteCollection([Site(Point(30.0, 30.0), 760., 1.0, 1.0)])
     mfd = TruncatedGRMFD(4.5, 8.0, 0.1, 4.0, 1.0)
     sources = [PointSource('001', 'Point1', 'Active Shallow Crust',
                            mfd, 1.0, WC1994(), 1.0, PoissonTOM(50.0),
                            0.0, 30.0, Point(30.0, 30.5),
                            PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))]),
                            PMF([(1.0, 10.0)]))]
     imtls = {'PGA': [0.01, 0.1, 0.2, 0.5, 0.8]}
     hc1 = calc_hazard_curves(sources, sitecol, imtls, {
         'Active Shallow Crust': AkkarBommer2010()})['PGA']
     hc2 = calc_hazard_curves(sources, sitecol, imtls, {
         'Active Shallow Crust': SadighEtAl1997()})['PGA']
     hc = .6 * hc1 + .4 * hc2
     ag = AvgGMPE(b1=dict(AkkarBommer2010={'weight': .6}),
                  b2=dict(SadighEtAl1997={'weight': .4}))
     hcm = calc_hazard_curves(sources, sitecol, imtls, {
         'Active Shallow Crust': ag})['PGA']
     # the AvgGMPE is not producing real means!!
     numpy.testing.assert_almost_equal(hc, hcm, decimal=3)
Exemple #27
0
 def setUp(self):
     """
     """
     #
     # coordinates of point sources
     lons = [10.00, 10.10, 10.20, 10.00, 10.10, 10.20, 10.00, 10.10, 10.20]
     lats = [45.10, 45.10, 45.10, 45.05, 45.05, 45.05, 45.00, 45.00, 45.00]
     deps = [10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00]
     self.lons = lons
     self.lats = lats
     #
     # set main parameters
     mfd = TruncatedGRMFD(min_mag=4.0,
                          max_mag=6.0,
                          bin_width=0.1,
                          a_val=2.0,
                          b_val=1.0)
     msr = WC1994()
     tom = PoissonTOM(1.0)
     npd = PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))])
     hdd = PMF([(0.7, 4.), (0.3, 8.0)])
     #
     # create the list of sources
     srcs = []
     for idx, (lon, lat, dep) in enumerate(zip(lons, lats, deps)):
         src = PointSource(source_id='1',
                           name='Test',
                           tectonic_region_type=TRT.ACTIVE_SHALLOW_CRUST,
                           mfd=mfd,
                           rupture_mesh_spacing=5.0,
                           magnitude_scaling_relationship=msr,
                           rupture_aspect_ratio=1.0,
                           temporal_occurrence_model=tom,
                           upper_seismogenic_depth=0,
                           lower_seismogenic_depth=10.,
                           location=Point(lon, lat, dep),
                           nodal_plane_distribution=npd,
                           hypocenter_distribution=hdd)
         srcs.append(src)
     self.points = srcs
Exemple #28
0
    def test_point_surface(self):

        sid = 0
        name = 'test'
        trt = TRT.ACTIVE_SHALLOW_CRUST
        mfd = ArbitraryMFD([7.0], [1.])
        rms = 2.5
        msr = WC1994()
        rar = 1.0
        tom = PoissonTOM(1.)
        usd = 0.0
        lsd = 20.0
        loc = Point(0.0, 0.0)
        npd = PMF([(1.0, NodalPlane(90., 90., 90.))])
        hyd = PMF([(1.0, 10.)])
        src = PointSource(sid, name, trt, mfd, rms, msr, rar, tom, usd, lsd,
                          loc, npd, hyd)
        rups = [r for r in src.iter_ruptures()]

        # Compute distances
        param = 'closest_point'
        sites = SiteCollection(
            [Site(Point(0.0, 0.0, 0.0)),
             Site(Point(-0.2, 0.0, 0.0))])
        dsts = get_distances(rups[0], sites, param)

        # Check first point
        msg = 'The longitude of the first point is wrong'
        self.assertTrue(abs(dsts[0, 0] - 0.0) < 1e-2, msg)
        msg = 'The latitude of the first point is wrong'
        self.assertTrue(abs(dsts[0, 1] - 0.0) < 1e-2, msg)

        # Check second point
        msg = 'The longitude of the second point is wrong'
        self.assertTrue(abs(dsts[1, 0] + 0.1666) < 1e-2, msg)
        msg = 'The latitude of the second point is wrong'
        self.assertTrue(abs(dsts[1, 1] - 0.0) < 1e-2, msg)
Exemple #29
0
     dom['DEP_LOWER'] = 15
 hypo_depth_dist = PMF([(0.5, dom['DEP_BEST']),
                        (0.25, dom['DEP_LOWER']),
                        (0.25, dom['DEP_UPPER'])])
 # Define nodal planes as thrusts except for special cases
 str1 = dom['SHMAX'] + 90.
 str2 = dom['SHMAX'] + 270.
 str3 = dom['SHMAX'] + dom['SHMAX_SIG'] + 90.
 str4 = dom['SHMAX'] + dom['SHMAX_SIG'] + 270.
 str5 = dom['SHMAX'] - dom['SHMAX_SIG'] + 90.
 str6 = dom['SHMAX'] - dom['SHMAX_SIG'] + 270.
 strikes = [str1, str2, str3, str4, str5, str6]
 for i, strike in enumerate(strikes):
     if strike >= 360:
         strikes[i] = strike - 360
 nodal_plane_dist = PMF([(0.34, NodalPlane(strikes[0], 30, 90)),
                         (0.34, NodalPlane(strikes[1], 30, 90)),
                         (0.08, NodalPlane(strikes[2], 30, 90)),
                         (0.08, NodalPlane(strikes[3], 30, 90)),
                         (0.08, NodalPlane(strikes[4], 30, 90)),
                         (0.08, NodalPlane(strikes[5], 30, 90))])
 if dom['CODE'] == 'WARM' or dom['CODE'] == 'WAPM':
     print 'Define special case for WARM'
     nodal_plane_dist = PMF([(0.75, NodalPlane(45, 90, 0)),
                             (0.125, NodalPlane(strikes[0], 30,
                                                90)),
                             (0.125, NodalPlane(strikes[1], 30,
                                                90))])
 if dom['CODE'] == 'FMLR':
     print 'Define special case for FMLR, 0.5 thrust, 0.5 SS'
     nodal_plane_dist = PMF([(0.17, NodalPlane(strikes[0], 30, 90)),
Exemple #30
0
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)]))
def _get_nodal_plane_distribution(data):
    out = []
    for tmp in data:
        out.append([tmp[0], NodalPlane(tmp[1], tmp[2], tmp[3])])
    return PMF(out)
Exemple #32
0
    def setUp(self):
        self.npd_as_pmf = PMF([(0.5, NodalPlane(0., 90., 0.)),
                               (0.5, NodalPlane(90., 90., 180.))])

        self.npd_as_pmf_bad = PMF([(0.5, None),
                                   (0.5, NodalPlane(90., 90., 180.))])
Exemple #33
0
def combine_ss_models(filename_stem,
                      domains_shp,
                      params,
                      lt,
                      bval_key,
                      output_dir='./',
                      nrml_version='04',
                      weight=1.):  #, id_base = 'ASS'):
    """ Combine smoothed seismicity models based on tectonic region types
    :params filename_stem:
        String for the start of the xml filename for the source model,
        assuming generic components (non generic are inferred, 
        e.g. bvalue and completeness model)
    :params domains_shp:
        shapefile defining tectonic domain regions
    :params params:
        list of dicts containing parameters derivded from the shapefile
     :bval_key
         key for the dicts in params  as we are merging by 
         bvalues  (best, lower, upper)
    :params lt:
        LogicTree object containing relevant values and weights for Mmax
    :params outfile:
        output nrml formatted file
    """

    dsf = shapefile.Reader(domains_shp)
    dom_shapes = dsf.shapes()
    # Get indicies of relevant fields
    for i, f in enumerate(dsf.fields):
        if f[0] == 'CODE':
            code_index = i - 1
        if f[0] == 'TRT':
            trt_index = i - 1

    hypo_depth_dist_nc = PMF([(0.5, 10.0), (0.25, 5.0), (0.25, 15.0)])
    hypo_depth_dist_c = PMF([(0.5, 5.0), (0.25, 2.5), (0.25, 10.0)])
    hypo_depth_dist_ex = hypo_depth_dist_c
    hypo_depth_dict = {
        'Cratonic': hypo_depth_dist_c,
        'Non_cratonic': hypo_depth_dist_nc,
        'Extended': hypo_depth_dist_ex
    }
    # FIXME! - Temporary solution until nodal plan logic tree
    # info can be read directly from shapefile attributes
    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))])

    merged_pts = []

    # Get mmax values and weights
    mmaxs = {}
    mmaxs_w = {}
    for dom in params:
        print 'Processing source %s' % dom['CODE']
        print dom['TRT']
        if dom['TRT'] == 'NCratonic':
            dom['TRT'] = 'Non_cratonic'
        # For the moment, only consider regions within AUstralia
        if dom['TRT'] == 'Active' or dom['TRT'] == 'Interface' or \
                dom['TRT'] == 'Oceanic' or \
                dom['TRT'] == 'Intraslab' or dom['CODE'] == 'NECS' or \
                dom['CODE'] == 'NWO':
            print 'Source %s not on continental Australia, skipping' % dom[
                'CODE']
            continue
        elif dom['TRT'] == 'Cratonic':
            if dom['DOMAIN'] == 1:
                mmax_values, mmax_weights = lt.get_weights('Mmax', 'Archean')
            else:
                mmax_values, mmax_weights = lt.get_weights(
                    'Mmax', 'Proterozoic')


#        elif dom['TRT'] == 'Active':
#            print 'MMax logic tree not yet defined for active crust, using extended crust'
#            mmax_values, mmax_weights = lt.get_weights('Mmax', 'Extended')
        else:
            mmax_values, mmax_weights = lt.get_weights('Mmax', dom['TRT'])
        mmax_values = [float(i) for i in mmax_values]
        mmax_weights = [float(i) for i in mmax_weights]
        print mmax_values
        print mmax_weights
        mmaxs[dom['CODE']] = mmax_values
        mmaxs_w[dom['CODE']] = mmax_weights

        pt_ids = []
        #for trt, filename in filedict.iteritems():
        #    print trt
        completeness_string = 'comp'
        for ym in dom['COMPLETENESS']:
            completeness_string += '_%i_%.1f' % (ym[0], ym[1])
        mmin = dom['COMPLETENESS'][0][1]
        filename = "%s_b%.3f_mmin%.1f_%s.xml" % (filename_stem, dom[bval_key],
                                                 mmin, completeness_string)
        print 'Parsing %s' % filename

        # TA kluge - hardwire jdg547 path
        jdgpath = '/short/w84/NSHA18/sandpit/jdg547/NSHA2018/source_models/smoothed_seismicity/'

        print filename

        # Only keep points within domain
        pts = read_pt_source(filename)

        #        shapes = np.where(trt_types
        for shape in dsf.shapeRecords():
            #            print code_index
            print shape.record[code_index]
            if shape.record[code_index] == dom['CODE']:
                # Check for undefined depths (-999 values)
                if dom['DEP_BEST'] < 0:
                    print 'Setting best depth to 10 km'
                    dom['DEP_BEST'] = 10
                if dom['DEP_UPPER'] < 0:
                    print 'Setting upper depth to 5 km'
                    dom['DEP_UPPER'] = 5
                if dom['DEP_LOWER'] < 0:
                    print 'Setting lower depth to 15 km'
                    dom['DEP_LOWER'] = 15
                hypo_depth_dist = PMF([(0.5, dom['DEP_BEST']),
                                       (0.25, dom['DEP_LOWER']),
                                       (0.25, dom['DEP_UPPER'])])
                # Define nodal planes as thrusts except for special cases
                str1 = dom['SHMAX'] + 90.
                str2 = dom['SHMAX'] + 270.
                str3 = dom['SHMAX'] + dom['SHMAX_SIG'] + 90.
                str4 = dom['SHMAX'] + dom['SHMAX_SIG'] + 270.
                str5 = dom['SHMAX'] - dom['SHMAX_SIG'] + 90.
                str6 = dom['SHMAX'] - dom['SHMAX_SIG'] + 270.
                strikes = [str1, str2, str3, str4, str5, str6]
                for i, strike in enumerate(strikes):
                    if strike >= 360:
                        strikes[i] = strike - 360
        #           if strikes[i] >=360:
        #               strikes[i]=strikes[i]-360
                nodal_plan_dist = PMF([(0.34, NodalPlane(strikes[0], 30, 90)),
                                       (0.34, NodalPlane(strikes[1], 30, 90)),
                                       (0.08, NodalPlane(strikes[2], 30, 90)),
                                       (0.08, NodalPlane(strikes[3], 30, 90)),
                                       (0.08, NodalPlane(strikes[4], 30, 90)),
                                       (0.08, NodalPlane(strikes[5], 30, 90))])
                if dom['CODE'] == 'WARM' or dom['CODE'] == 'WAPM':
                    print 'Define special case for WARM'
                    nodal_plan_dist = PMF([
                        (0.75, NodalPlane(45, 90, 0)),
                        (0.125, NodalPlane(strikes[0], 30, 90)),
                        (0.125, NodalPlane(strikes[1], 30, 90))
                    ])
                if dom['CODE'] == 'FMLR':
                    print 'Define special case for FMLR, 0.5 thrust, 0.5 SS'
                    nodal_plan_dist = PMF([
                        (0.17, NodalPlane(strikes[0], 30, 90)),
                        (0.17, NodalPlane(strikes[1], 30, 90)),
                        (0.04, NodalPlane(strikes[2], 30, 90)),
                        (0.04, NodalPlane(strikes[3], 30, 90)),
                        (0.04, NodalPlane(strikes[4], 30, 90)),
                        (0.04, NodalPlane(strikes[5], 30, 90)),
                        (0.17, NodalPlane(strikes[0], 90, 0)),
                        (0.17, NodalPlane(strikes[1], 90, 0)),
                        (0.04, NodalPlane(strikes[2], 90, 0)),
                        (0.04, NodalPlane(strikes[3], 90, 0)),
                        (0.04, NodalPlane(strikes[4], 90, 0)),
                        (0.04, NodalPlane(strikes[5], 90, 0))
                    ])
                dom_poly = Polygon(shape.shape.points)
                for pt in pts:
                    pt_loc = Point(pt.location.x, pt.location.y)
                    if pt_loc.within(dom_poly):
                        pt.tectonic_region_type = dom['TRT']
                        pt.nodal_plane_distribution = nodal_plane_dist  # FIXME! update based on data extracted from shapefile
                        pt.hypocenter_distribution = hypo_depth_dist
                        pt.rupture_aspect_ratio = 2
                        mfd = pt.mfd
                        new_mfd = gr2inc_mmax(mfd, mmaxs[dom['CODE']],
                                              mmaxs_w[dom['CODE']], weight)
                        pt.mfd = new_mfd
                        if pt.source_id in pt_ids:
                            print 'Point source %s already exists!' % pt.source_id
                            print 'Skipping this source for trt %s' % zone_trt
                        else:
                            merged_pts.append(pt)
                            pt_ids.append(pt.source_id)

    outfile = "%s_%s.xml" % (filename_stem, bval_key)
    outfile = os.path.join(output_dir, outfile)
    name = outfile.rstrip('.xml')
    if nrml_version == '04':
        nodes = list(map(obj_to_node, sorted(merged_pts)))
        source_model = Node("sourceModel", {"name": name}, nodes=nodes)
        with open(outfile, 'wb') as f:
            nrml.write([source_model], f, '%s', xmlns=NAMESPACE)
    return outfile
Exemple #34
0
#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)),
                            (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)
#    i+=1
#    if j==1000:
#        break

filename = "smoothed_frankel_50_3_mmin_%.1f_b%.3f_0.1.xml" % (
    completeness_table_a[0][-1], bvalue)
mod_name = 'smoothed_frankel_50_3_mmin_%.1f_b%.3f_0.1' % (
    completeness_table_a[0][-1], bvalue)
Exemple #35
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)
from openquake.hazardlib.calc.filters import SourceFilter, FarAwayRupture
from openquake.hazardlib.mfd import EvenlyDiscretizedMFD
from openquake.hazardlib.sourceconverter import SourceConverter

# ######################## rupture calculator ############################ #

U16 = numpy.uint16
U32 = numpy.uint32
U64 = numpy.uint64
F32 = numpy.float32

# DEFAULT VALUES FOR UCERF BACKGROUND MODELS
DEFAULT_MESH_SPACING = 1.0
DEFAULT_TRT = "Active Shallow Crust"
HDD = PMF([(0.2, 3.0), (0.6, 6.0), (0.2, 9.0)])
NPD = PMF([(0.15, NodalPlane(0.0, 90.0, 0.0)),
           (0.15, NodalPlane(45.0, 90.0, 0.0)),
           (0.15, NodalPlane(90.0, 90.0, 0.0)),
           (0.15, NodalPlane(135.0, 90.0, 0.0)),
           (0.05, NodalPlane(0.0, 45.0, 90.)),
           (0.05, NodalPlane(45.0, 45.0, 90.)),
           (0.05, NodalPlane(90.0, 45.0, 90.)),
           (0.05, NodalPlane(135.0, 45.0, 90.)),
           (0.05, NodalPlane(180.0, 45.0, 90.)),
           (0.05, NodalPlane(225.0, 45.0, 90.)),
           (0.05, NodalPlane(270.0, 45.0, 90.)),
           (0.05, NodalPlane(325.0, 45.0, 90.))])


class ImperfectPlanarSurface(PlanarSurface):
    """
Exemple #37
0
 def test_corner_cases(self):
     np = NodalPlane(strike=0, dip=0.001, rake=-180 + 1e-5)
     self.assertEqual((np.strike, np.dip, np.rake), (0, 0.001, -180 + 1e-5))
     np = NodalPlane(strike=360 - 1e-5, dip=90, rake=+180)
     self.assertEqual((np.strike, np.dip, np.rake), (360 - 1e-5, 90, +180))
Exemple #38
0
def pt2fault_distance(pt_sources,
                      fault_sources,
                      min_distance=5.0,
                      filename='source_model.xml',
                      buffer_distance=100.,
                      nrml_version='04',
                      name=None):
    """Calculate distances from a pt source rupture plane
    to the fault sources to then reduce Mmax on events that are 
    within a certain distance
    :param pt_sources:
        list of PointSource objects
    :param fault_sources:
        List of FaultSource objects
    :param min_distance:
        Minimum distance (km) within which we want a point source 
        rupture to be from a fault.
    :param filename:
        Name of output nrml file for revised pt source model
    :param buffer_distance:
        Km, initial filter to only process pts within this
        distance from the fault
    """

    if name is None:
        name = filename[:-4] + '_geom_filtered'
    id_index = 0  # We need to re-number all sources to avoid duplicate ids
    # Extract the points of the fault source mesh
    fault_lons = []
    fault_lats = []
    fault_depths = []
    for fault in fault_sources:
        whole_fault_surface = SimpleFaultSurface.from_fault_data(
            fault.fault_trace, fault.upper_seismogenic_depth,
            fault.lower_seismogenic_depth, fault.dip,
            fault.rupture_mesh_spacing)
        fault_lons.append(whole_fault_surface.mesh.lons.flatten())
        fault_lats.append(whole_fault_surface.mesh.lats.flatten())
        fault_depths.append(whole_fault_surface.mesh.depths.flatten())
    fault_lons = np.concatenate(fault_lons)
    fault_lats = np.concatenate(fault_lats)
    fault_depths = np.concatenate(fault_depths)
    min_fault_lon = np.min(fault_lons)
    max_fault_lon = np.max(fault_lons)
    min_fault_lat = np.min(fault_lats)
    max_fault_lat = np.max(fault_lats)

    # Generate ruptures for point sources
    minimum_distance_list = []
    revised_point_sources = {
        'Cratonic': [],
        'Non_cratonic': [],
        'Extended': [],
        'Banda': []
    }
    for pt in pt_sources:
        print 'Looping over point sources'
        # For speeding things up filter based on initial distances
        # to find points very far from or very close to a fault
        mfd_type = type(pt.mfd).__name__
        pt_depths = []
        for probs, depths in pt.hypocenter_distribution.data:
            pt_depths.append(depths)
        np_probs = []
        np_list = []
        for prob, nodal_plane in pt.nodal_plane_distribution.data:
            np_probs.append(prob)
            np_list.append(nodal_plane)
        centroid_distances = []
        for pt_depth in pt_depths:
            centroid_distances.append(
                distance(pt.location.longitude, pt.location.latitude, pt_depth,
                         fault_lons, fault_lats, fault_depths))
        centroid_distances = np.array(centroid_distances).flatten()
        #      print 'Minimum distance', min(centroid_distances)
        #      print 'Maximum distance', max(centroid_distances)
        if (min(centroid_distances)) > buffer_distance:
            # Keep point as it, not within buffer distance of any faults
            revised_point_sources[pt.tectonic_region_type].append(pt)
            continue
        if (min(centroid_distances)) < min_distance:
            # Discard point sources as too close to a fault
            print 'Discarding point source, too close to a fault'
            continue
        rupture_mags = []
        rupture_lons = []
        rupture_lats = []
        rupture_depths = []
        rupture_strikes = []
        rupture_dips = []
        ruptures = pt.iter_ruptures()
        for rupture in ruptures:
            rupture_mags.append(rupture.mag)
            rupture_lons.append(rupture.surface.corner_lons)
            rupture_lats.append(rupture.surface.corner_lats)
            rupture_depths.append(rupture.surface.corner_depths)
            rupture_strikes.append(rupture.surface.strike)
            rupture_dips.append(rupture.surface.dip)
        rupture_mags = np.array(rupture_mags).flatten()
        # make the same length as the corners
        rupture_mags = np.repeat(rupture_mags, 4)
        rupture_strikes = np.repeat(rupture_strikes, 4)
        rupture_dips = np.repeat(rupture_dips, 4)
        rupture_lons = np.array(rupture_lons).flatten()
        rupture_lats = np.array(rupture_lats).flatten()
        rupture_depths = np.array(rupture_depths).flatten()
        print 'Doing meshgrid'
        lons1, lons2 = np.meshgrid(fault_lons, rupture_lons)
        lats1, lats2 = np.meshgrid(fault_lats, rupture_lats)
        depths1, depths2 = np.meshgrid(fault_depths, rupture_depths)

        # Calculate distance from pt to all fault
        print 'Distance calculations'
        distances = distance(lons1, lats1, depths1, lons2, lats2, depths2)
        closest_distance_to_faults = np.min(distances)
        print 'Shortest pt to fault distance is', closest_distance_to_faults
        minimum_distance_list.append(closest_distance_to_faults)

        # Find where the distance is less than the threshold min_distance
        too_close_lons = lons2[np.where(distances < min_distance)]
        too_close_lats = lats2[np.where(distances < min_distance)]
        if too_close_lons.size > 0:
            lon_indices = np.where(np.in1d(rupture_lons, too_close_lons))[0]
            lat_indices = np.where(np.in1d(rupture_lats, too_close_lats))[0]
            too_close_mags = rupture_mags[np.intersect1d(
                lon_indices, lat_indices)]
            too_close_strikes = rupture_strikes[np.intersect1d(
                lon_indices, lat_indices)]
            too_close_dips = rupture_dips[np.intersect1d(
                lon_indices, lat_indices)]
            #    print 'Magnitudes of rupture close to fault', too_close_mags
            #    print 'Strikes of rupture close to fault', too_close_strikes
            #    print 'Dips of rupture close to fault', too_close_dips
            unique_strikes = np.unique(rupture_strikes)
            unique_dips = np.unique(rupture_dips)
            src_name_index = 0
            for prob, nodal_plane in pt.nodal_plane_distribution.data:
                id_index += 1
                src_name_index += 1
                # We are now splitting the source into many with different
                # combinations of Mmaxs and nodal planes
                new_pt = copy.deepcopy(pt)
                new_pt.source_id = "%i" % id_index
                new_pt.name = new_pt.name + ("_%i" % src_name_index)
                new_np = NodalPlane(nodal_plane.strike, nodal_plane.dip,
                                    nodal_plane.rake)
                new_np_distribution = PMF([
                    (1.0, new_np)
                ])  # weight of nodal plane is 1 as making
                # a separate source
                # Calculate new rates based on probability of original nodal plane
                new_pt.nodal_plane_distribution = new_np_distribution
                if mfd_type == 'TruncatedGRMFD':
                    b_val = pt.mfd.b_val
                    # rescale a value in log sapce
                    a_val = np.log10(np.power(10, pt.mfd.a_val) *
                                     prob)  #*area_src_weight))
                    new_pt.mfd.modify_set_ab(a_val, b_val)
                elif mfd_type == 'EvenlyDiscretizedMFD':
                    mag_bins, rates = zip(
                        *pt.mfd.get_annual_occurrence_rates())
                    mag_bins = np.array(mag_bins)
                    rates = np.array(rates)
                    new_rates = rates * prob  #*area_src_weight)
                    new_pt.mfd.modify_set_mfd(new_pt.mfd.min_mag,
                                              new_pt.mfd.bin_width,
                                              list(new_rates))
                else:
                    msg = 'Weighting method for mfd type %s not yet defined' % mfd_type
                    raise (msg)
                pair_index = np.where(
                    np.logical_and(too_close_strikes == nodal_plane.strike,
                                   too_close_dips == nodal_plane.dip))
                # Deal with intersecting cases
                if len(pair_index[0]) > 0:
                    intersecting_magnitudes = too_close_mags[pair_index]
                    minimum_magnitude_intersecting_fault = min(
                        intersecting_magnitudes)
                    if minimum_magnitude_intersecting_fault >= \
                            (pt.mfd.min_mag + pt.mfd.bin_width):
                        new_mmax = minimum_magnitude_intersecting_fault - \
                                pt.mfd.bin_width
                        if mfd_type == 'TruncatedGRMFD':
                            new_pt.mfd.max_mag = new_mmax
                        if mfd_type == 'EvenlyDiscretizedMFD':
                            trimmed_rates = new_rates[np.where(
                                mag_bins <= new_mmax)]
                    else:
                        print 'Minimum magnitude intersects fault, discarding source'
                        continue

                else:
                    pass
                # Append revised source for given nodal plane distribution to
                # list of revised sources
                print 'Appending revised source'
                revised_point_sources[pt.tectonic_region_type].append(new_pt)
        else:
            id_index += 1
            pt.source_id = "%i" % id_index
            'Appending original source'
            revised_point_sources[pt.tectonic_region_type].append(pt)
    if len(minimum_distance_list) > 0:
        print 'Overall minimum distance (km):', min(minimum_distance_list)

    # Write pts to source model on their own
    source_model_file = filename
    print 'Writing to source model file %s' % source_model_file
    if nrml_version == '04':
        source_list = []
        for trt, sources in revised_point_sources.iteritems():
            for source in sources:
                source_list.append(source)
        nodes = list(map(obj_to_node, sorted(source_list)))
        source_model = Node("sourceModel", {"name": name}, nodes=nodes)
        with open(source_model_file, 'wb') as f:
            nrml.write([source_model], f, '%s', xmlns=NAMESPACE)
    elif nrml_version == '05':
        source_group_list = []
        id = 0
        for trt, sources in revised_point_sources.iteritems():
            source_group = SourceGroup(trt, sources=sources, id=id)
            id += 1
            source_group_list.append(source_group)
        write_source_model(source_model_file, source_group_list, name=name)
    else:
        print 'Warning: nrml version not specfied, xml not created'

    # Write pts to source model with faults
    source_model_file = filename[:-4] + '_inc_faults.xml'
    name = name + '_inc_faults'
    write_combined_faults_points(revised_point_sources,
                                 fault_sources,
                                 source_model_file,
                                 name,
                                 nrml_version='04')