Port srf2stoch to Python - #128
Open
lispandfound wants to merge 1 commit into
Open
Conversation
Contributor
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
Contributor
There was a problem hiding this comment.
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
srf2stochbinary dependency from both the CLI and the container build. - Bump
source_modellingminimum/version pin to2026.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.
lispandfound
force-pushed
the
srf2stoch_port
branch
from
August 31, 2026 09:09
15bce20 to
fcbdd14
Compare
lispandfound
force-pushed
the
srf2stoch_port
branch
2 times, most recently
from
September 2, 2026 02:52
52a9ee3 to
b4d0555
Compare
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>
lispandfound
force-pushed
the
srf2stoch_port
branch
from
September 4, 2026 01:44
b4d0555 to
fcf9906
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces the
srf2stochbinary with an in-process conversion, and dropsit 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)meansthe 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 * dxextent, so off-centre padding would sit the slip distributionin 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.