Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
5bd305c
refactor(defaults): add PGD and im calc periods
lispandfound Feb 16, 2026
59f986f
Merge branch 'rvfac' into im_calc_nzgmdb_alignment
lispandfound Feb 16, 2026
f15a07f
include rx/ry, source geometry, domain geometry, magnitudes
lispandfound Jul 20, 2026
4ef0ffd
add PGD as default IM
lispandfound Jul 20, 2026
3e9c11a
Merge remote-tracking branch 'origin/im_calc_nzgmdb_alignment' into i…
lispandfound Jul 20, 2026
2048160
fix hypocentre calculations
lispandfound Jul 20, 2026
ae2dfe3
fix rx, ry ordering
lispandfound Jul 20, 2026
3fe834b
Apply suggestions from code review
lispandfound Jul 20, 2026
f71466c
fix name
lispandfound Jul 20, 2026
b5095a4
Add in total magnitude
lispandfound Jul 20, 2026
51657dc
ignore transform type error
lispandfound Jul 20, 2026
17ee277
ignore numpydoc error
lispandfound Jul 20, 2026
e01b502
add empirical class
lispandfound Jul 20, 2026
985c4a4
Merge branch 'pegasus' into empirical_ims
lispandfound Jul 20, 2026
b2eec42
Merge branch 'pegasus' into empirical_ims
lispandfound Jul 20, 2026
f59df67
extract out datatree logic
lispandfound Jul 20, 2026
7f2e90b
add empricial measure calculations to ims
lispandfound Jul 21, 2026
33ab6d2
include empirical parameter tectonic type
lispandfound Jul 21, 2026
bc2fbe4
fix empirical tect type attributes
lispandfound Jul 21, 2026
aced5d1
Potential fix for pull request finding
lispandfound Jul 21, 2026
01772c5
Potential fix for pull request finding
lispandfound Jul 21, 2026
06617f3
fix ci checks
lispandfound Jul 21, 2026
3a59db0
Merge branch 'empirical_ims' of github.com:ucgmsim/workflow into empi…
lispandfound Jul 21, 2026
11c8727
bump lock file
lispandfound Jul 21, 2026
a514a22
bump oq wrapper properly
lispandfound Jul 21, 2026
5508803
bump lock file
lispandfound Jul 21, 2026
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
11 changes: 6 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ dependencies = [
"im-calculation>=2025.12.5",
"velocity-modelling>=2026.2.1",
"nshmdb>=2025.12.1",
"oq_wrapper>=2025.12.3",
"oq_wrapper>=2026.05.2",
"qcore-utils>=2025.12.2",
"source_modelling>=2026.07.2",
# Data Formats
"geopandas",
"netCDF4", # Required for openquake shenanigans
"pandas[parquet, hdf5]",
"pyyaml",
"xarray[io]",
Expand All @@ -30,10 +31,10 @@ dependencies = [
"tqdm",
"typer",
# Misc.
"requests", # For gcmt-to-realisation
"schema", # For loading realisations
"structlog", # Logging.
"psutil", # To get the CPU affinity for jobs
"requests", # For gcmt-to-realisation
"schema", # For loading realisations
"structlog", # Logging.
"psutil", # To get the CPU affinity for jobs
"parse>=1.21.0",
"rich>=14.3.2",
]
Expand Down
13 changes: 8 additions & 5 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions workflow/default_parameters/root/defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,9 @@ velocity_model_1d:
rho: 3.33
Qp: 394.80
Qs: 197.40
empirical:
tect_type: "active_shallow"
models: ["NSHM2022"]
im:
ims: ["PGA", "PGV", "PGD", "CAV", "AI", "Ds575", "Ds595", "pSA", "FAS"]
valid_periods:
Expand Down
64 changes: 64 additions & 0 deletions workflow/realisations.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,23 @@ class Rakes(RealisationConfiguration):
rakes: dict[str, float]
"""A map from faults to their rake angles."""

def as_vectors(self) -> dict[str, npt.NDArray[np.float64]]:
"""Represent each rake angle as a unit vector.

Rakes are angles, so they cannot be averaged directly (the mean of
-179° and 179° is 0°, not 180°). Averaging the unit vectors and
recovering the angle with `arctan2` avoids this.

Returns
-------
dict
A map from faults to the unit vector of their rake angle.
"""
return {
k: np.array([np.cos(np.radians(r)), np.sin(np.radians(r))])
for k, r in self.rakes.items()
}

def __getitem__(self, key: str) -> float:
"""Get the rake for a fault name.

Expand Down Expand Up @@ -687,6 +704,38 @@ def __getitem__(self, key: str) -> BoldM:
"""
return self.magnitudes[key]

@property
def moments(self) -> dict[str, float]: # numpydoc ignore=RT01
"""dict: a map from faults to their moment."""
return {
k: moment.magnitude_to_moment(mag, bold_m=True)
for k, mag in self.magnitudes.items()
}

def moment_averaged(self, values: dict[str, Any]) -> Any:
"""Average per-fault quantities, weighted by fault moment.

Parameters
----------
values : dict
A map from faults to the quantity to average. Every fault in
this realisation must be present. Values may be scalars or
arrays, provided they all share the same shape.

Returns
-------
Any
The moment-weighted average of `values`, with the same shape as
the individual values.
"""
keys = list(self.magnitudes)
moments = self.moments
return np.average(
[values[key] for key in keys],
weights=[moments[key] for key in keys],
axis=0,
)

@property
def total_moment(self) -> float: # numpydoc ignore=RT01
"""float: total moment of realisation"""
Expand Down Expand Up @@ -1223,6 +1272,21 @@ def to_dict(self) -> dict[str, Any]:
return _dict


@dataclasses.dataclass
class EmpiricalParameters(RealisationConfiguration):
"""Empirical (ground motion model) intensity measure parameters."""

_config_key: ClassVar[str] = "empirical"
_schema: ClassVar[Schema] = schemas.EMPIRICAL_PARAMETERS

# Types here are not explicitly declared so we do not pay the openquake tax
# importing this module.
tect_type: Any
"""The tectonic type of the source (an `oq_wrapper.constants.TectType`)."""
models: list[Any]
"""The ground motion models or logic trees to evaluate."""


@dataclasses.dataclass
class LogEntry:
"""Log entry for workflow utilities."""
Expand Down
22 changes: 22 additions & 0 deletions workflow/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,28 @@ def _corners_to_array(corners_spec: list[dict[str, float]]) -> np.ndarray:
)


EMPIRICAL_PARAMETERS = Schema(
{
Literal(
"tect_type",
description="Tectonic type of the source (one of oq_wrapper.constants.TectType)",
): str,
Literal(
"models",
description=(
"Ground motion models or ground motion model logic trees to "
"evaluate (members of oq_wrapper.constants.GMM or "
"oq_wrapper.constants.GMMLogicTree)"
),
): [str],
}
)
# NOTE: The values of this schema are validated as plain strings rather than
# `oq_wrapper.constants` enum members. Importing `oq_wrapper.constants` pulls in
# OpenQuake, which is expensive (and must be precompiled), so the strings are
# only resolved to enum members inside the IM calculation stage.


LOG_ENTRY_SCHEMA = Schema(
{
Literal(
Expand Down
1 change: 1 addition & 0 deletions workflow/scripts/bb_sim.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ def combine_hf_and_lf(
"y": ("station", lf.y.values),
"latitude": ("station", lf.lat.values),
"longitude": ("station", lf.lon.values),
"vs30": vs30_df["vsite"].to_xarray(),
},
attrs={
"units": "g",
Expand Down
Loading
Loading