Skip to content

Dev - #4

Merged
danikiev merged 4 commits into
mainfrom
dev
Sep 9, 2026
Merged

Dev#4
danikiev merged 4 commits into
mainfrom
dev

Conversation

@danikiev

@danikiev danikiev commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Fix seismic moment underestimated by a factor of 2pif

calculate_M0 applied the amplitude-to-displacement spectral conversion a
second time, after retrieve_min_amps had already applied it through
get_scaling_displacement. The seismic moment was therefore too small by
2pif_r and all minimum detectable moment magnitudes were too low by
dMw = (2/3)log10(2pif_r), between about 1.0 and 1.9 magnitude units.
Because f_r = min(v
Q/(pi*r), f_c) depends on the source-receiver distance
the error varies across the grid, so it changed the shape of the
sensitivity maps and not only their colour scale.

Verified against the reference implementation on test case 1 with the free
surface correction disabled in both: over all 81000 grid points the
corrected output now reproduces the reference to within 1e-15, up to the
known constant 2/3*log10(0.52/sqrt(4/15)) = 0.0020 that comes from the
different radiation pattern constants.

Fixes #3

  • drop the spurious 1/(2pif) factor in calculate_M0 and document the
    relation M0 = 4pirhov^3r/|R| * |U(f)| * exp(pift*) that it
    evaluates, stating that amps is the displacement amplitude spectrum and
    giving units for the other arguments
  • add pytests/test_magnitude.py covering the seismic moment relation, the
    moment magnitude conversion and its inverse, the amplitude-type scaling
    coefficients, the peak frequency and its corner clamp, and the DAS strain
    and strain-rate thresholds; the closed-form checks fail on the previous
    formula
  • remove loc_uncertainty_grid, which called calculate_pdf and
    get_uncertainty_from_pdf; neither has ever been part of the package, so
    every call raised NameError
  • replace the match statement in plot_sensitivity_slice with if/elif so the
    visualization module imports on Python 3.9, which the CI matrix covers
  • record the release in CHANGELOG.md and .zenodo.json, and link the new
    Zenodo deposit to the manual v1.0.0 record with isNewVersionOf

Set up the GitHub Actions and documentation needed to run releases through
GitHub and Zenodo automatically, following the same pattern as LayTracer.
PyNetDesign is not published to PyPI, so the packaging jobs stop after
building and checking the distributions.

- add validate-zenodo.yml, which validates .zenodo.json on every push and
  pull request to main and dev, and is reusable from other workflows
- add validate-tag.yml, a reusable workflow enforcing strict vMAJOR.MINOR.PATCH
  tags that point at a commit contained in main
- add pytest.yml, running pytest on Python 3.9 through 3.12
- add release-on-published.yml, which validates the tag and the Zenodo
  metadata, then builds the distributions and asserts that the built version
  matches the tag
- add RELEASE.md documenting the versioning rules, the release flow, the
  Zenodo integration and how the pre-integration v1.0.0 record is
  cross-linked to the new concept record
calculate_M0 applied the amplitude-to-displacement spectral conversion a
second time, after retrieve_min_amps had already applied it through
get_scaling_displacement. The seismic moment was therefore too small by
2*pi*f_r and all minimum detectable moment magnitudes were too low by
dMw = (2/3)*log10(2*pi*f_r), between about 1.0 and 1.9 magnitude units.
Because f_r = min(v*Q/(pi*r), f_c) depends on the source-receiver distance
the error varies across the grid, so it changed the shape of the
sensitivity maps and not only their colour scale.

Verified against the reference implementation on test case 1 with the free
surface correction disabled in both: over all 81000 grid points the
corrected output now reproduces the reference to within 1e-15, up to the
known constant 2/3*log10(0.52/sqrt(4/15)) = 0.0020 that comes from the
different radiation pattern constants.

Fixes #3

- drop the spurious 1/(2*pi*f) factor in calculate_M0 and document the
  relation M0 = 4*pi*rho*v^3*r/|R| * |U(f)| * exp(pi*f*t*) that it
  evaluates, stating that amps is the displacement amplitude spectrum and
  giving units for the other arguments
- add pytests/test_magnitude.py covering the seismic moment relation, the
  moment magnitude conversion and its inverse, the amplitude-type scaling
  coefficients, the peak frequency and its corner clamp, and the DAS strain
  and strain-rate thresholds; the closed-form checks fail on the previous
  formula
- remove loc_uncertainty_grid, which called calculate_pdf and
  get_uncertainty_from_pdf; neither has ever been part of the package, so
  every call raised NameError
- replace the match statement in plot_sensitivity_slice with if/elif so the
  visualization module imports on Python 3.9, which the CI matrix covers
- record the release in CHANGELOG.md and .zenodo.json, and link the new
  Zenodo deposit to the manual v1.0.0 record with isNewVersionOf
@danikiev
danikiev merged commit 7738d35 into main Sep 9, 2026
9 of 10 checks passed
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.

Seismic moment underestimated by a factor of 2*pi*f: amplitude-to-displacement conversion applied twice

1 participant