Skip to content

[WIP] Initial implementation of logic trees for site models - #11654

Closed
CB-quakemodel wants to merge 101 commits into
masterfrom
site_lt_test
Closed

[WIP] Initial implementation of logic trees for site models#11654
CB-quakemodel wants to merge 101 commits into
masterfrom
site_lt_test

Conversation

@CB-quakemodel

@CB-quakemodel CB-quakemodel commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

This PR adds the ability to specify site model logic trees using the regular NRML XML logic. The user can specify a site model XML file for the site_model_file key in the .ini within which each branch points to a different site model (either CSV or XML version). The site models must have identical lon/lat (and elevation if present), although the site IDs can vary (useful for tracking site param diffs at same locations) and share all site parameters (but of course the values for each parameter within each site model can differ).

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

The approach of specifying different site model files rather than branches with absolute or relative uncertainties for parameters like vs30 is suitable because then we can 1) still specify many epistemic uncertainties in the case of site-specific or "few" sites calculations and 2) within a larger calculation we can incorporate epistemic uncertainties through using different regional Vs30 models.

A new hazardlib module site_lt.py handles the site-model logic tree through two containers: SiteModelLogicTree (parses and validates the site model LT XML) and SiteModelsEpistemic (holds the loaded per-branch site model arrays and uses get_realizations() for full enumeration and sample() for sampling). Therefore everything is handled explicitly in a containerised approach, unlike in my initial implementation using ModifiableGMPE and representing epistemic uncertainty in the site params in the GMM logic tree (see #11650).

We can use the containerised approach in combination with published site-specific methodologies applied through (to be added as needed) ModifiableGMPE functions to explicitly represent the epistemic uncertainties in the site response within a logic tree with a dedicated site model component. An example would be the amplification factors per branch as described in the Rodriguez-Marek et al. (2021) site model logic tree-focused paper - we could specify them in the site model logic tree, and then the application of the factors themselves could be handled in a dedicated ModifiableGMPE capability if passed as site parameters in the context arrays.


QA tests are added for a site model logic tree with a rock site model and a softer soil site model (logictree/case_24 and subtests) in a test with 2 sources and 2 GMMs to ensure the logic tree is sufficiently complex:

  • Classical with full enumeration
  • Classical with sampling
  • Classical with full enumeration and fastmean path (mean only, use_rates=true and individual_rlzs=false)
  • Classical with sampling and fastmean path (mean only, use_rates=true and individual_rlzs=false)
  • Disaggregation with full enumeration
  • Disaggregation with sampling
  • Use of XMLs instead of CSVs to represent the site model (again one per branch in the site model logic tree)
  • Running a calc (classical with sampling) and load the datastore using __fromh5___ into a disagg calc

NB: Both early_weights and late_weights sampling methods are tested in these QA tests.

NB: Most of the files changed in this PR are from these extensive unit tests.

NB: The existing override_vs30 .ini option (via SiteCollection.multiply()) also produces multiple hazard results at the same location, but it clones each site once per vs30 value as an unweighted set of contexts (the curves are never combined and remain as separate results) - the site-model LT in this PR instead adds a weighted third leg to the logic tree so all site params (not just vs30) vary per branch and contribute to hcurves-stats/mean and to sampling.


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

  • The SiteModelLogicTree XML parser accepts both flat and <logicTreeBranchingLevel>-wrapped NRML nestings
  • The SiteModelLogicTree XML parser rejects non-siteModel branchsets
  • The SiteModelLogicTree XML parser rejects weights that don't sum to 1
  • The SiteModelLogicTree XML parser rejects duplicate branchIDs within a branchset
  • The SiteModelLogicTree XML parser rejects a <logicTree> with no siteModel branchset
  • The SiteModelsEpistemic container rejects branches with mismatched site coordinates
  • The SiteModelsEpistemic container rejects branches with mismatched depth values
  • The SiteModelsEpistemic container rejects branches with differing site-parameter field sets (e.g. one branch declares z1pt0, another does not)
  • The SiteModelsEpistemic container assigns every branch a unique BASE183 short character
  • logictree.reduce_full preserves the surviving branch when a cluster uses only one site branch
  • logictree.reduce_full leaves the tree alone when a cluster spans both site branches
  • FullLogicTree.__toh5__/__fromh5__ roundtrip preserves the site LT metadata
  • FullLogicTree.get_realizations under full enumeration builds the SSC × GMM × SITE outer product with correctly multiplied weights
  • FullLogicTree.get_realizations under early_weights sampling gives uniform 1/num_samples weights
  • FullLogicTree.get_realizations under late_weights sampling draws branches by weight and keeps each rlz's tree weight product (rescaled to sum to 1)

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 site model logic trees are only supported in classical and disagg.

@CB-quakemodel CB-quakemodel changed the title Initial implementation of logic trees for site models [WIP] Initial implementation of logic trees for site models Aug 4, 2026
@CB-quakemodel CB-quakemodel linked an issue Aug 15, 2026 that may be closed by this pull request
2 tasks
@CB-quakemodel

CB-quakemodel commented Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

Upon some reflection, I think given the specifics of each site-response methodology that the desired outcome can still be obtained (explicitly) either within ModifiableGMPE-based branchs in the GMM LT (given we are literally modifying the input reference ground-motion), or (less ideally) through the introduction of similar functions within the specific GMMs which we use in these PSHA studies.

For now given this, I will close this PR; if we introduce the site model logic trees into the classical calculator, we will also need to spend considerable time extending the capability into the event-based and scenario calculators, potentially for minimal benefit in terms of real applications given the focus is really for site-specific studies.

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