Source code for openquake.pfd.secondary_surf_rup.takao2014
# -*- coding: utf-8 -*-
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (C) 2024-2026 Yen-Shin Chen, OGS
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
Module :mod:`openquake.pfd.secondary_surf_rup.takao2014` implements
the model of Takao et al. (2014) in :class:`Takao2014SecondarySR`
References
----------
Takao, M., Ueta, K., Annaka, T., Kurita, T., Nakase, H., Kyoya, T., &
Kato, J. (2014). Reliability improvement of probabilistic fault
displacement hazard analysis. Journal of Japan Association for
Earthquake Engineering, 14(2), 16-36. https://doi.org/10.5610/jaee.14.2_16
(in Japanese with English abstract).
An English description of the model (magnitude-independent logistic
regression on ln(r + c3) for 500/250/100/50 m unit cells) is given by
Nishizaka et al. (2026), Seismological Research Letters,
https://doi.org/10.1785/0220250293.
"""
import numpy as np
from openquake.pfd.params import check_positive
from openquake.pfd.secondary_surf_rup.base import BaseSecondarySurfRup
[docs]class Takao2014SecondarySR(BaseSecondarySurfRup):
"""Implementation of the Takao et al. (2014) model for reverse and strike-slip faults"""
def __init__(self, pixel_size=None):
"""
:param pixel_size: optional pixel (cell) size in meters pinned by
the logic-tree branch; ``None`` defers to the ``get_prob`` call
(legacy default: 100).
"""
self.pixel_size = check_positive(type(self).__name__, "pixel_size",
pixel_size)
def get_prob(self, r: float, pixel_size: int = None):
"""
Calculates probability of surface rupture for reverse and strike-slip faults
:param r:
The distance to the principal fault in km
:param pixel_size:
Size of the square analysis pixel in meters.
Valid options are: 500, 250, 100, 50
:return:
Probability of surface rupture
"""
# Fall back to constructor-pinned value, then legacy default
if pixel_size is None:
pixel_size = (self.pixel_size
if self.pixel_size is not None else 100)
# Coefficients for different pixel sizes
coefficients = {
500: (-3.859, -1.499, 0.2),
250: (-4.903, -1.459, 0.2),
100: (-6.135, -1.427, 0.2),
50: (-6.988, -1.410, 0.2)
}
if pixel_size not in coefficients:
raise ValueError(f"Invalid pixel size. Must be one of {list(coefficients)} meters")
C1, C2, C3 = coefficients[pixel_size]
# Logistic regression z = C1 + C2*ln(r + C3); the model is
# independent of earthquake magnitude (Takao et al., 2014).
fx = C1 + C2 * np.log(r + C3)
prob = np.exp(fx) / (1 + np.exp(fx))
return prob