Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added CoeffsTable.fromtoml #10022

Merged
merged 5 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[Michele Simionato]
* Internal: made it possible to override CoeffsTable
* Added a memory check in disaggregation calculations
* Made `scientific_format` resilient against encoding errors

Expand Down
41 changes: 40 additions & 1 deletion openquake/hazardlib/gsim/coeffs_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import re
import math
import copy
import toml
import scipy
import numpy as np
from openquake.baselib.general import RecordBuilder
Expand Down Expand Up @@ -151,6 +153,13 @@ def fromdict(cls, ddic, logratio=True, opt=0):
self.opt = opt
return self

@classmethod
def fromtoml(cls, string):
"""
Builds a CoeffsTable from a TOML string
"""
return cls.fromdict(toml.loads(string))

def __init__(self, table, **kwargs):
self._coeffs = {} # cache
self.opt = kwargs.pop('opt', 0)
Expand Down Expand Up @@ -279,6 +288,36 @@ def __getitem__(self, imt):
self._coeffs[imt] = c = self.rb(*vals)
return c

def update_coeff(self, coeff_name, value_by_imt):
"""
Update a coefficient in the table.

:param coeff_name: name of the coefficient
:param value_by_imt: dictionary imt -> coeff_value
"""
for imt, coeff_value in value_by_imt.items():
self._coeffs[imt][coeff_name] = coeff_value

def __or__(self, other):
"""
:param other: a subtable of self
:returns: a new table obtained by overriding self with other
"""
for imt in other._coeffs:
assert imt in self._coeffs, imt
new = copy.deepcopy(self)
for name in other.rb.names:
by_imt = {imt: rec[name] for imt, rec in other._coeffs.items()}
new.update_coeff(name, by_imt)
return new

def __ior__(self, other):
"""
:param other: a subtable of self
:returns: a new table obtained by overriding self with other
"""
return self | other

def to_array(self):
"""
:returns: a composite array with the coefficient names as columns
Expand All @@ -291,7 +330,7 @@ def to_ddic(self):
"""
ddic = {}
for imt, rec in self._coeffs.items():
ddic[imt.string] = dict(zip(rec.dtype.names, rec))
ddic[imt.string] = dict(zip(rec.dtype.names, map(float, rec)))
return ddic

def __repr__(self):
Expand Down
24 changes: 15 additions & 9 deletions openquake/hazardlib/tests/gsim/coeffs_table_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import toml
import numpy as np
from openquake.hazardlib.gsim.coeffs_table import CoeffsTable
from openquake.hazardlib.imt import SA


class TestGetCoefficient(unittest.TestCase):
Expand Down Expand Up @@ -50,22 +51,27 @@ def test_ddic(self):
ddic = self.ctab.to_ddic()
self.assertEqual(toml.dumps(ddic), '''\
[PGA]
a1 = "0.1"
a2 = "0.2"
a3 = "0.3"
a1 = 0.1
a2 = 0.2
a3 = 0.3

["SA(0.01)"]
a1 = "0.4"
a2 = "0.5"
a3 = "0.6"
a1 = 0.4
a2 = 0.5
a3 = 0.6

["SA(0.05)"]
a1 = "0.7"
a2 = "0.8"
a3 = "0.9"
a1 = 0.7
a2 = 0.8
a3 = 0.9
''')
self.ctab.fromdict(ddic)

def test_update_coeff(self):
self.ctab |= CoeffsTable.fromtoml('["SA(0.01)"]\na1 = 0.11')
coeffs = self.ctab[SA(0.01)]
np.testing.assert_array_equal(list(coeffs), [0.11, 0.5, 0.6])

def test_get_coeffs(self):
pof, cff = self.ctab.get_coeffs(['a1', 'a2'])
expected = np.array([[0.4, 0.5], [0.7, 0.8]])
Expand Down
Loading