Source code for openquake.cat.tests.converter_test

# ------------------- The OpenQuake Model Building Toolkit --------------------
# Copyright (C) 2026 GEM Foundation and Électricité de France
#           _______  _______        __   __  _______  _______  ___   _
#          |       ||       |      |  |_|  ||  _    ||       ||   | | |
#          |   _   ||   _   | ____ |       || |_|   ||_     _||   |_| |
#          |  | |  ||  | |  ||____||       ||       |  |   |  |      _|
#          |  |_|  ||  |_|  |      |       ||  _   |   |   |  |     |_
#          |       ||      |       | ||_|| || |_|   |  |   |  |    _  |
#          |_______||____||_|      |_|   |_||_______|  |___|  |___| |_|
#
# 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 <http://www.gnu.org/licenses/>.
#
# This script is produced within the scope of Work Package 5, named Simulation 
# platform, under SIGMA3 project. For more detailed information about 
# the project, please visit to https://sigma-programs.com/.
# -----------------------------------------------------------------------------
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# coding: utf-8

"""
Testing methods and functions in the converter.py
"""

import os
import unittest
import pandas as pd
import numpy as np
import tempfile
import shutil

from openquake.cat.converter import GallahueAbrahamson2023Model1, GallahueAbrahamson2023Model2

[docs] class TestGallahueAbrahamson2023(unittest.TestCase):
[docs] def setUp(self): """Initialize temporary directory and create structured array for testing.""" self.test_dir = tempfile.mkdtemp() # Sample data for testing self.sample_data = pd.DataFrame({ "pga": [0.07, 0.20, 0.46], # g "mag": [6.0, 6.5, 7.3], "rhypo": [10.0, 50.0, 100.0], # km "rjb": [9.0, 45.0, 95.0], # km "intensity": [3.9, 5.8, 8.0] }) self.structured_data = self.sample_data.to_records(index=False)
[docs] def tearDown(self): shutil.rmtree(self.test_dir) if os.path.exists("output"): shutil.rmtree("output")
[docs] def test_model1_eq19_success(self): """Testing if equation 19 calculates intensity and saves correctly.""" model = GallahueAbrahamson2023Model1(self.structured_data) model.get_intensity(mode='eq19') output_path = os.path.join("output", "test_gmice.csv") model.save(output_path) self.assertTrue(os.path.exists(output_path)) df_res = pd.read_csv(output_path) # Checking if the result column 'intensity' exists self.assertIn("intensity", df_res.columns) self.assertEqual(len(df_res), 3)
[docs] def test_model1_eq20_with_epsilon(self): """Testing if equation 20 handles epsilon shifts correctly.""" model = GallahueAbrahamson2023Model1(self.structured_data) # Calculation with epsilon=0 and epsilon=1 mean_results = model.get_intensity(mode='eq20', epsilon=0).copy() eps_results = model.get_intensity(mode='eq20', epsilon=1) # Eq 20 has h4 = -0.568. If epsilon=1, intensity should be lower than the mean. self.assertTrue(np.all(eps_results < mean_results))
[docs] def test_model1_missing_column_error(self): bad_dt = np.dtype([('pga', 'f8'), ('mag', 'f8')]) bad_data = np.array([(0.1, 6.0)], dtype=bad_dt) model = GallahueAbrahamson2023Model1(bad_data) with self.assertRaises(ValueError) as cm: model.get_intensity(mode='eq19') self.assertIn("Missing required columns", str(cm.exception))
[docs] def test_model2_eq22_success(self): """Testing if equation 22 calculates PGA and saves correctly.""" model = GallahueAbrahamson2023Model2(self.structured_data) model.get_pga(mode='eq22') output_path = os.path.join("output", "test_igmce.csv") model.save(output_path) self.assertTrue(os.path.exists(output_path)) df_res = pd.read_csv(output_path) self.assertIn("pga", df_res.columns) self.assertTrue((df_res["pga"] > 0).all())
[docs] def test_model2_eq23_with_epsilon(self): """Verifies equation 23 shifts PGA when epsilon is changed.""" model = GallahueAbrahamson2023Model2(self.structured_data) pga_mean = model.get_pga(mode='eq23', epsilon=0).copy() pga_eps = model.get_pga(mode='eq23', epsilon=1) # Confirming results are different self.assertFalse(np.array_equal(pga_mean, pga_eps))
[docs] def test_invalid_mode_error(self): """Verifies that an invalid mode string raises a ValueError.""" model = GallahueAbrahamson2023Model1(self.structured_data) with self.assertRaises(ValueError) as cm: model.get_intensity(mode='wrong_mode') self.assertIn("Invalid mode", str(cm.exception))
[docs] def test_save_before_calculation_error(self): """Verifies that saving before calculation triggers an error.""" model = GallahueAbrahamson2023Model2(self.structured_data) with self.assertRaises(ValueError) as cm: model.save("failure.csv") self.assertIn("run 'get_pga' before saving", str(cm.exception))