From bca3c870d11fe9681fdbaf7da546082064bf51e1 Mon Sep 17 00:00:00 2001 From: Fahrettin Kuran Date: Wed, 27 May 2026 15:15:13 +0200 Subject: [PATCH 1/6] Add missing equations and unit tests for Thingbaijam2017 --- .../hazardlib/scalerel/thingbaijam2017.py | 156 +++++++++--------- .../tests/scalerel/thingbaijam2017_test.py | 26 ++- 2 files changed, 107 insertions(+), 75 deletions(-) diff --git a/openquake/hazardlib/scalerel/thingbaijam2017.py b/openquake/hazardlib/scalerel/thingbaijam2017.py index f5dc2588e27d..56120a74ecf8 100644 --- a/openquake/hazardlib/scalerel/thingbaijam2017.py +++ b/openquake/hazardlib/scalerel/thingbaijam2017.py @@ -18,8 +18,10 @@ """ Module :mod:`openquake.hazardlib.scalerel.thingbaijam2017` implements -:class:`Thingbaijam2017_Interface` -:class:`Thingbaijam2017_Crustal` +:class:`ThingbaijamInterface` +:class:`ThingbaijamStrikeSlip` +:class:`ThingbaijamNormalFault` +:class:`ThingbaijamReverseFault` """ from numpy import log10 @@ -32,58 +34,41 @@ class ThingbaijamInterface(BaseMSRSigma, BaseASRSigma): Earthquake Source-Scaling Laws. Bulletin of the Seismological Society of America, 107(5), pp 2225-2946, doi: 10.1785/0120170017. - Implements magnitude-area, area-magnitude,length-magnitude, - width-magnitude scaling relations. + Implements moment magnitude-rupture area, rupture area-moment magnitude, + rupture length-magnitude, rupture width-magnitude scaling relations + for subduction interface. """ def get_median_area(self, mag, rake): - """ - Calculates median fault area from magnitude. - """ + """Calculates median area from magnitude.""" return 10**(-3.292 + 0.949 * mag) def get_std_dev_area(self, mag, rake): - """ - Returns std - """ + """Returns std for rupture area.""" return 0.150 def get_median_mag(self, area, rake): - """ - Returns magnitude for a given fault area - """ + """Calculates median magnitude from area.""" return (log10(area) + 3.292) / 0.949 def get_std_dev_mag(self, area, rake): - """ - Returns std - """ + """Returns std for magnitude.""" return 0.150 def get_median_length(self, mag): - """ - Get median length of the rupture given moment magnitude - """ + """Calculates median length from magnitude.""" return 10.0 ** (-2.412 + 0.583 * mag) def get_std_dev_length(self, mag): - """ - Get median length standard deviation of the rupture given moment - magnitude - """ + """Returns std for rupture length.""" return 0.107 def get_median_width(self, mag): - """ - Get median width of the rupture given moment magnitude - """ + """Calculates median width from magnitude.""" return 10.0 ** (-0.880 + 0.366 * mag) def get_std_dev_width(self, mag): - """ - Get median width standard deviation of the rupture given moment - magnitude - """ + """Returns std for rupture width.""" return 0.099 @@ -93,39 +78,42 @@ class ThingbaijamStrikeSlip(BaseMSRSigma, BaseASRSigma): Earthquake Source-Scaling Laws. Bulletin of the Seismological Society of America, 107(5), pp 2225-2946, doi: 10.1785/0120170017. - Implements both magnitude-area and area-magnitude scaling relationships. + Implements moment magnitude-rupture area, rupture area-moment magnitude, + rupture length-magnitude, rupture width-magnitude scaling relations + for strike-slip faulting. """ def get_median_area(self, mag, rake): - """ - Calculates median fault area from magnitude. - """ + """Calculates median area from magnitude.""" return 10**(-3.486 + 0.942 * mag) def get_std_dev_area(self, mag, rake): - """ - Returns std - """ + """Returns std for rupture area.""" return 0.184 def get_median_mag(self, area, rake): - """ - Returns magnitude for a given fault area - """ + """Calculates median magnitude from area.""" return (log10(area) + 3.486) / 0.942 def get_std_dev_mag(self, area, rake): - """ - Returns std - """ + """Returns std for magnitude.""" return 0.184 + + def get_median_length(self, mag): + """Calculates median length from magnitude.""" + return 10.0 ** (-2.943 + 0.681 * mag) + + def get_std_dev_length(self, mag): + """RReturns std for rupture length.""" + return 0.151 + + def get_median_width(self, mag): + """Calculates median width from magnitude.""" + return 10.0 ** (-0.543 + 0.261 * mag) def get_std_dev_width(self, mag): - """ - Get median width standard deviation of the rupture given moment - magnitude - """ - return 0.099 + """Returns std for rupture width.""" + return 0.105 class ThingbaijamNormalFault(BaseMSRSigma, BaseASRSigma): @@ -134,32 +122,42 @@ class ThingbaijamNormalFault(BaseMSRSigma, BaseASRSigma): Earthquake Source-Scaling Laws. Bulletin of the Seismological Society of America, 107(5), pp 2225-2946, doi: 10.1785/0120170017. - Implements both magnitude-area and area-magnitude scaling relationships. + Implements moment magnitude-rupture area, rupture area-moment magnitude, + rupture length-magnitude, rupture width-magnitude scaling relations + for normal faulting. """ def get_median_area(self, mag, rake): - """ - Calculates median fault area from magnitude. - """ + """Calculates median area from magnitude.""" return 10**(-2.551 + 0.808 * mag) def get_std_dev_area(self, mag, rake): - """ - Returns std - """ + """Returns std for rupture area.""" return 0.181 def get_median_mag(self, area, rake): - """ - Returns magnitude for a given fault area - """ + """Calculates median magnitude from area.""" return (log10(area) + 2.551) / 0.808 def get_std_dev_mag(self, area, rake): - """ - Returns std - """ + """Returns std for magnitude.""" return 0.181 + + def get_median_length(self, mag): + """Calculates median length from magnitude.""" + return 10.0 ** (-1.722 + 0.485 * mag) + + def get_std_dev_length(self, mag): + """Returns std for rupture length.""" + return 0.128 + + def get_median_width(self, mag): + """Calculates median width from magnitude.""" + return 10.0 ** (-0.829 + 0.323 * mag) + + def get_std_dev_width(self, mag): + """Returns std for rupture width.""" + return 0.128 class ThingbaijamReverseFault(BaseMSRSigma, BaseASRSigma): @@ -168,29 +166,39 @@ class ThingbaijamReverseFault(BaseMSRSigma, BaseASRSigma): Earthquake Source-Scaling Laws. Bulletin of the Seismological Society of America, 107(5), pp 2225-2946, doi: 10.1785/0120170017. - Implements both magnitude-area and area-magnitude scaling relationships. + Implements moment magnitude-rupture area, rupture area-moment magnitude, + rupture length-magnitude, rupture width-magnitude scaling relations + for reverse faulting. """ def get_median_area(self, mag, rake): - """ - Calculates median fault area from magnitude. - """ + """Calculates median area from magnitude.""" return 10**(-4.362 + 1.049 * mag) def get_std_dev_area(self, mag, rake): - """ - Returns std - """ + """Returns std for rupture area.""" return 0.121 def get_median_mag(self, area, rake): - """ - Returns magnitude for a given fault area - """ + """Calculates median magnitude from area.""" return (log10(area) + 4.362) / 1.049 def get_std_dev_mag(self, area, rake): - """ - Returns std - """ + """Returns std for magnitude.""" return 0.121 + + def get_median_length(self, mag): + """Calculates median length from magnitude.""" + return 10.0 ** (-2.693 + 0.614 * mag) + + def get_std_dev_length(self, mag): + """Returns std for rupture length.""" + return 0.083 + + def get_median_width(self, mag): + """Calculates median width from magnitude.""" + return 10.0 ** (-1.669 + 0.435 * mag) + + def get_std_dev_width(self, mag): + """Returns std for rupture width.""" + return 0.087 \ No newline at end of file diff --git a/openquake/hazardlib/tests/scalerel/thingbaijam2017_test.py b/openquake/hazardlib/tests/scalerel/thingbaijam2017_test.py index 4aee2c74efdb..58fb00fa00fa 100644 --- a/openquake/hazardlib/tests/scalerel/thingbaijam2017_test.py +++ b/openquake/hazardlib/tests/scalerel/thingbaijam2017_test.py @@ -52,11 +52,23 @@ def test_median_magnitude(self): self._test_get_median_mag(19952.6231496888, None, 8.00, places=2) self._test_get_median_mag(2243.8819237828, None, 7.00, places=2) + def test_length_and_width(self): + """ + Tests length and width relationships + """ + msr = ThingbaijamInterface() + numpy.testing.assert_allclose(msr.get_median_length(7.0), 46.665938, rtol=0.0001) + numpy.testing.assert_allclose(msr.get_median_width(7.0), 48.083934, rtol=0.0001) + + # Test of standard deviations for length and width + self.assertEqual(msr.get_std_dev_length(7.0), 0.107) + self.assertEqual(msr.get_std_dev_width(7.0), 0.099) + class ThingbaijamStrikeSlipTestCase(BaseMSRTestCase): ''' Tests for the magnitude-scaling relationship Thingbaijam et al. (2017) for - interface events. + strike-slip events. ''' MSR_CLASS = ThingbaijamStrikeSlip @@ -82,3 +94,15 @@ def test_median_magnitude(self): self._test_get_median_mag(11220.184543, None, 8.00, places=2) self._test_get_median_mag(1282.33058266, None, 7.00, places=2) + def test_length_and_width(self): + """ + Tests length and width relationships + """ + msr = ThingbaijamStrikeSlip() + numpy.testing.assert_allclose(msr.get_median_length(7.0), 66.6806769, rtol=0.0001) + numpy.testing.assert_allclose(msr.get_median_width(7.0), 19.2309173, rtol=0.0001) + + # Test of standard deviations for length and width + self.assertEqual(msr.get_std_dev_length(7.0), 0.151) + self.assertEqual(msr.get_std_dev_width(7.0), 0.105) + From d51837a7e15eaeb3b2fd897d44f8065a82007693 Mon Sep 17 00:00:00 2001 From: Fahrettin Kuran Date: Thu, 28 May 2026 11:52:15 +0200 Subject: [PATCH 2/6] fixing small typo Small typo is fixed in line 107. --- openquake/hazardlib/scalerel/thingbaijam2017.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openquake/hazardlib/scalerel/thingbaijam2017.py b/openquake/hazardlib/scalerel/thingbaijam2017.py index 56120a74ecf8..21d700adc19a 100644 --- a/openquake/hazardlib/scalerel/thingbaijam2017.py +++ b/openquake/hazardlib/scalerel/thingbaijam2017.py @@ -104,7 +104,7 @@ def get_median_length(self, mag): return 10.0 ** (-2.943 + 0.681 * mag) def get_std_dev_length(self, mag): - """RReturns std for rupture length.""" + """Returns std for rupture length.""" return 0.151 def get_median_width(self, mag): @@ -201,4 +201,4 @@ def get_median_width(self, mag): def get_std_dev_width(self, mag): """Returns std for rupture width.""" - return 0.087 \ No newline at end of file + return 0.087 From 40c042624772fefb7c3f201ed41a6663275bf320 Mon Sep 17 00:00:00 2001 From: Fahrettin Kuran Date: Thu, 28 May 2026 11:54:54 +0200 Subject: [PATCH 3/6] Update changelog --- debian/changelog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/debian/changelog b/debian/changelog index 7e82933e0b64..6708c2f567d2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7103,3 +7103,6 @@ python-oq-engine (0.3.9-1) natty; urgency=low * Upstream OpenQuake python sources. -- Muharem Hrnjadovic Mon, 06 Jun 2011 11:42:24 +0200 + + [Fahrettin Kuran] + * The new MSRs added here to the existing thingbaijam2017.py From 8171b37574b3e7442367254e13a0c1f893d31017 Mon Sep 17 00:00:00 2001 From: Fahrettin Kuran Date: Thu, 28 May 2026 13:18:39 +0200 Subject: [PATCH 4/6] Update order of the description in changelog --- debian/changelog | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index 6708c2f567d2..763f3dbd5c63 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,6 @@ + [Fahrettin Kuran] + * Added additional magnitude-scaling relationships to thingbaijam2017.py + [Michele Simionato] * Implemented a workflow to run the 2026 Global Risk Model @@ -7103,6 +7106,3 @@ python-oq-engine (0.3.9-1) natty; urgency=low * Upstream OpenQuake python sources. -- Muharem Hrnjadovic Mon, 06 Jun 2011 11:42:24 +0200 - - [Fahrettin Kuran] - * The new MSRs added here to the existing thingbaijam2017.py From dad7acbc05b966fb13b00b91502240b2f23bcc40 Mon Sep 17 00:00:00 2001 From: Michele Simionato Date: Fri, 29 May 2026 08:25:24 +0200 Subject: [PATCH 5/6] Better logging --- openquake/calculators/event_based.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openquake/calculators/event_based.py b/openquake/calculators/event_based.py index 93e7af8e3cfe..e7d90d66edc3 100644 --- a/openquake/calculators/event_based.py +++ b/openquake/calculators/event_based.py @@ -671,7 +671,8 @@ def build_events_from_sources(self): eff_ruptures = AccumDict(accum=0) # grp_id => potential ruptures source_data = AccumDict(accum=[]) allargs = [] - logging.info('Building ruptures') + logging.info('Building ruptures from %d groups', + len(self.csm.src_groups)) g_index = 0 for sg_id, sg in enumerate(self.csm.src_groups): if not sg.sources: From 4a0a32fc23802a705b27ece0065f0f5f7da7dc80 Mon Sep 17 00:00:00 2001 From: Michele Simionato Date: Fri, 29 May 2026 08:26:54 +0200 Subject: [PATCH 6/6] Added Kuran to the contributors --- CONTRIBUTORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 0a6653df2f5a..0bbc02c4f34f 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -107,6 +107,7 @@ Maoxin Wang (@MaoxinWang) December 2025 Antonio Scala (@antonio-scala) January 2026 Nicholas Clemett (@nc-hsu) January 2026 Thuany Costa de Lima (@thuanycostadelima) May 2026 +Fahrettin Kuran (@kurannn) May 2026 Project management ------------------