Skip to content

Logic trees for site amplification model - #11726

Open
CB-quakemodel wants to merge 3 commits into
masterfrom
amp_lt
Open

Logic trees for site amplification model#11726
CB-quakemodel wants to merge 3 commits into
masterfrom
amp_lt

Conversation

@CB-quakemodel

@CB-quakemodel CB-quakemodel commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

This PR adds the ability to specify amplification model logic trees using the regular NRML XML logic. The user can specify an amplification LT XML file for the amplification_csv key in the .ini within which each branch points to a different amplification model CSV.

Each branch must define AFs for all sitecol ampcodes and for all IMTs in intensity_measure_types_and_levels, but beyond that all parameters (the actual AF and sigma values, the rock-IML level grid, and the from_mag/from_rrup grids) are permitted to differ across branches so users can represent alternative discretisations and value sets as epistemic choices for site amplfication.

Full enumeration and sampling of amp branches are supported. Under full enumeration realizations become the product of R_SSC × R_GMM × R_amp; when sampling all three legs are drawn num_samples times independently (the amp leg uses the same lt.random / lt.sample methods as the SSC and GSIM parts so both early_weights and late_weights are supported).

Adding the ability to specify different amplification models per branch is important for supporting site response methodologies (e.g., Liou et al. 2024's BSSA methodologies) . The engine already supports the convolution approach with a single amplification model, so expanding this capability (as done so in this PR) to support epistemic uncertainty on the amplification model is a viable (and logical) option to support more advanced site response methodologies.

A new hazardlib module amp_lt.py handles the amplification logic tree through two containers: AmpLogicTree (parses and validates the amp LT XML) and AmpFunctionsEpistemic (holds the loaded per-branch amplification dataframes and uses get_realizations() for full enumeration and sample() for sampling).

QA tests are added (logictree/case_26) for a 3-branch amp LT (low, med, high AF) covering 2 IMTs (PGA + SA(0.2)) each with 2 rock levels plus from_mag/from_rrup columns:

  • Classical with full enumeration
  • Classical with sampling
  • Disaggregation with full enumeration
  • Disaggregation with sampling

Example of results for the classical with full enumeration:

{32BA5CE3-ABC7-47DE-8A80-996309B2619E}

NB: A pre-existing bug in extract_disagg is also fixed as part of this PR: numpy.interp was being called against the stored mean hazard curve using oq.imtls[imt] as xp, but the stored curve is on oq.soil_intensities levels whenever amplification is active. This mismatch prevented any disagg calc which included an amplification model being applied from exported (regression test through logictree/case_26).


Extensive unit tests are also added for the new amp_lt.py hazardlib module which test:

  • The AmpLogicTree XML parser accepts both flat and <logicTreeBranchingLevel>-wrapped NRML nestings
  • The AmpLogicTree XML parser rejects non-amplificationModel branchsets
  • The AmpLogicTree XML parser rejects weights that don't sum to 1
  • The AmpLogicTree XML parser rejects duplicate branchIDs within a branchset
  • The AmpLogicTree XML parser rejects a <logicTree> with no amplificationModel branchset
  • AmpLogicTree.is_amp_lt returns True for a valid amplification LT XML and false for an invalid amplification LT XML
  • The AmpFunctionsEpistemic container assigns every branch a unique BASE183 short character
  • FullLogicTree.__toh5__/__fromh5__ roundtrip preserves the amp LT metadata
  • FullLogicTree.get_realizations under full enumeration builds the SSC × GMM × amp product with correctly multiplied weights and a three-leg path
  • FullLogicTree.get_realizations under early_weights sampling gives uniform 1/num_samples weights
  • FullLogicTree.get_realizations under late_weights sampling draws branches by weight

Documentation is added for this feature.

It is not yet supported outside of classical and disaggregation: an error is intentionally raised to warn the user that amplification logic trees are currently only supported in these calculators. Support for other calc types will be added later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant