Skip to content

Port srf2stoch to Python - #128

Open
lispandfound wants to merge 1 commit into
nzvm/domain-fault-bufferfrom
srf2stoch_port
Open

Port srf2stoch to Python#128
lispandfound wants to merge 1 commit into
nzvm/domain-fault-bufferfrom
srf2stoch_port

Conversation

@lispandfound

@lispandfound lispandfound commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Replaces the srf2stoch binary with an in-process conversion, and drops
it from the container build.

The conversion is a box average expressed as a sparse fractional-overlap
matrix: row j of the kernel holds the overlap weights between coarse bin
j and the fine cells it spans. The special case where the two grids span
exactly the same length is what srf2stoch.c implements; the sparse form
generalises it without materialising the empty overlaps, and handles the
padded case where they do not.

That padded case is why this was worth porting. The HF code demands a
single dx/dy across every SRF segment, and nx = ceil(len / dx) means
the coarse grid is generally longer than the plane it covers. The
overhang is split evenly between the two ends, so the grids stay
concentric -- the stoch format records only a centre point and an
nx * dx extent, so off-centre padding would sit the slip distribution
in the wrong place on the plane HF reconstructs. Edge bins then carry
weights summing to the covered fraction rather than to 1, which is what
conserves total slip*area rather than cell value.

Quantities that are not spread over a cell are handled separately.
Rupture time is a time, so it is divided by the covered fraction; every
cell is partially covered because nx and ny round up, so this never
divides by zero. Rise time is slip-averaged, and there the coverage
factor cancels, so it must not be divided out again.

Rake is averaged as a circular mean weighted by slip -- the arithmetic
mean of -179 and 179 degrees is 0, which is the opposite of the right
answer. A plane with no slip anywhere has no slip-weighted mean, so it
falls back to an unweighted average.

This changes every stoch file, and therefore every high-frequency
result. The previous binary's outputs were not moment-conserving for
segments whose length was not an exact multiple of the stoch dx.

Copilot AI review requested due to automatic review settings July 29, 2026 04:34
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR ports stoch generation from the external srf2stoch binary to a pure-Python implementation, integrating SRF→Stoch conversion directly into the generate-stoch CLI and simplifying container tooling.

Changes:

  • Implement SRF→Stoch conversion in Python using NumPy/SciPy (box-averaging slip, rupture time, and slip-weighted rise).
  • Remove the srf2stoch binary dependency from both the CLI and the container build.
  • Bump source_modelling minimum/version pin to 2026.07.3 / 2026.7.3.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.

File Description
workflow/scripts/generate_stoch.py Replaces external srf2stoch invocation with in-process Python conversion and updates CLI/docs accordingly.
container/runner.def Stops building srf2stoch in the runner image.
pyproject.toml Updates source_modelling minimum version requirement.
uv.lock Updates lockfile entries (incl. source-modelling 2026.7.3 and related metadata).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread workflow/scripts/generate_stoch.py
Comment thread workflow/scripts/generate_stoch.py
Comment thread workflow/scripts/generate_stoch.py
@lispandfound
lispandfound changed the base branch from pegasus to nzvm/domain-fault-buffer August 31, 2026 09:09
@lispandfound
lispandfound force-pushed the srf2stoch_port branch 2 times, most recently from 52a9ee3 to b4d0555 Compare September 2, 2026 02:52
Replaces the `srf2stoch` binary with an in-process conversion, and drops
it from the container build.

The conversion is a box average expressed as a sparse fractional-overlap
matrix: row j of the kernel holds the overlap weights between coarse bin
j and the fine cells it spans. The special case where the two grids span
exactly the same length is what srf2stoch.c implements; the sparse form
generalises it without materialising the empty overlaps, and handles the
padded case where they do not.

That padded case is why this was worth porting. The HF code demands a
single dx/dy across every SRF segment, and `nx = ceil(len / dx)` means
the coarse grid is generally *longer* than the plane it covers. The
overhang is split evenly between the two ends, so the grids stay
concentric -- the stoch format records only a centre point and an
`nx * dx` extent, so off-centre padding would sit the slip distribution
in the wrong place on the plane HF reconstructs. Edge bins then carry
weights summing to the covered fraction rather than to 1, which is what
conserves total slip*area rather than cell value.

Quantities that are not spread over a cell are handled separately.
Rupture time is a time, so it is divided by the covered fraction; every
cell is partially covered because nx and ny round up, so this never
divides by zero. Rise time is slip-averaged, and there the coverage
factor cancels, so it must *not* be divided out again.

Rake is averaged as a circular mean weighted by slip -- the arithmetic
mean of -179 and 179 degrees is 0, which is the opposite of the right
answer. A plane with no slip anywhere has no slip-weighted mean, so it
falls back to an unweighted average.

This changes every stoch file, and therefore every high-frequency
result. The previous binary's outputs were not moment-conserving for
segments whose length was not an exact multiple of the stoch dx.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants