specmod 0.2.1__tar.gz → 0.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {specmod-0.2.1 → specmod-0.2.3}/.github/workflows/docs.yml +6 -1
- {specmod-0.2.1 → specmod-0.2.3}/.gitignore +11 -3
- {specmod-0.2.1 → specmod-0.2.3}/.readthedocs.yaml +7 -1
- specmod-0.2.3/.release-please-manifest.json +3 -0
- {specmod-0.2.1 → specmod-0.2.3}/CHANGELOG.md +29 -0
- {specmod-0.2.1 → specmod-0.2.3}/CITATION.cff +1 -1
- {specmod-0.2.1 → specmod-0.2.3}/PKG-INFO +4 -3
- {specmod-0.2.1 → specmod-0.2.3}/README.md +2 -2
- {specmod-0.2.1 → specmod-0.2.3}/docs/choosing-a-transform.md +2 -5
- specmod-0.2.3/docs/conf.py +190 -0
- specmod-0.2.3/docs/contributing.md +31 -0
- {specmod-0.2.1 → specmod-0.2.3}/docs/development.md +9 -6
- {specmod-0.2.1 → specmod-0.2.3}/docs/documentation.md +59 -9
- specmod-0.2.3/docs/getting-started.md +41 -0
- specmod-0.2.3/docs/guides.md +55 -0
- {specmod-0.2.1 → specmod-0.2.3}/docs/index.md +23 -44
- {specmod-0.2.1 → specmod-0.2.3}/docs/processing.md +155 -28
- {specmod-0.2.1 → specmod-0.2.3}/docs/releasing-data.md +10 -9
- {specmod-0.2.1 → specmod-0.2.3}/docs/releasing.md +32 -16
- {specmod-0.2.1 → specmod-0.2.3}/docs/roadmap.md +38 -13
- specmod-0.2.3/docs/upgrading.md +151 -0
- {specmod-0.2.1 → specmod-0.2.3}/pyproject.toml +4 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/core/collection.py +10 -6
- specmod-0.2.3/tutorial/SpecModTutorial.ipynb +1032 -0
- specmod-0.2.1/.release-please-manifest.json +0 -3
- specmod-0.2.1/docs/conf.py +0 -110
- specmod-0.2.1/tutorial/SpecModTutorial.ipynb +0 -2000
- specmod-0.2.1/tutorial/data/events/2019-08-26T07:30:47.000000Z/spectra/2019-08-26T07:30:47.000000Z.h5 +0 -0
- specmod-0.2.1/tutorial/data/events/2019-08-26T07:30:47.000000Z/spectra/flatfiles/2019-08-26T07:30:47.000000Z.csv +0 -29
- specmod-0.2.1/tutorial/data/events/2019-08-26T07:30:47.000000Z/spectra/flatfiles/2019-08-26T07:30:47.000000Z.parquet +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/.git-blame-ignore-revs +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/.github/workflows/build.yml +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/.github/workflows/release.yml +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/.github/workflows/test.yml +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/.pre-commit-config.yaml +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/AGENTS.md +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/CLAUDE.md +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/CONTRIBUTING.md +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/LICENSE +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/datasets/magna_2020.toml +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/datasets/pnr_2019.toml +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/docs/REFACTOR_PLAN.md +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/docs/api.md +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/docs/notebooks/_build_notebook.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/docs/notebooks/choosing-a-transform.ipynb +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/docs/notes/api-audit.md +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/docs/notes/window-position.md +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/docs/pick-formats.md +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/release-please-config.json +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/requirements.txt +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/_vendor/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/_vendor/qiinv.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/acquire.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/api.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/cli.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/config/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/config/layers.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/config/provenance.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/config/sections.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/config/serialize.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/core/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/core/bandwidth.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/core/noise.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/core/scalogram.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/core/spectrum.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/core/units.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/datasets.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/distance.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/exceptions.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/fitting/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/fitting/base.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/fitting/event.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/fitting/guess.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/fitting/spectrum.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/io.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/magnitude.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/picks/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/picks/base.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/picks/delimited.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/picks/events.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/picks/resolution.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/picks/snuffler.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/pipeline.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/plotting.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/preprocess.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/smoothing/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/smoothing/base.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/smoothing/konno_ohmachi.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/smoothing/log_bins.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/sources/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/sources/attenuation.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/sources/composite.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/sources/motion.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/sources/source.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/spreading.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/staged.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/tables.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/transforms/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/transforms/base.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/transforms/cwt.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/transforms/fft.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/transforms/multitaper.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/transforms/prieto.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/transforms/quadratic.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/src/specmod/utils.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/README.md +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/lmfit/__init__.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/lmfit/model.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/lmfit/parameter.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/obspy/__init__.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/obspy/clients/__init__.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/obspy/clients/fdsn/__init__.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/obspy/core/__init__.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/obspy/core/event.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/obspy/core/inventory.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/obspy/core/stream.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/obspy/core/trace.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/obspy/core/utcdatetime.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/obspy/core/util/__init__.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/obspy/core/util/base.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/obspy/geodetics/__init__.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/obspy/signal/__init__.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/stubs/obspy/signal/konnoohmachismoothing.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/studies/magna_2020_paper.toml +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/conftest.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/golden/motion_reference.json +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/golden/pipeline_reference.json +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/golden/window_reference.json +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_acquire.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_ambient_state.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_api_surface.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_collection.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_config.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_cwt.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_datasets.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_docs_are_current.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_end_to_end.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_fitting_defaults.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_golden_reference.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_import.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_io_and_plotting.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_legacy_fixes.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_magnitude.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_make_golden.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_pick_plugins.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_pick_readers.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_picks.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_pipeline.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_pipeline_smoke.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_preprocess.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_prieto.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_quadratic.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_release_config.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_smoothing.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_sources.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_spectral_wiring.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_staged.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_stubs.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_transforms.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_tutorial.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_typing_backlog.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_utils.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tests/test_versioning.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tools/check_built_version.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tools/check_floors.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tools/make_golden.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tools/measure_docs.py +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/picks/2019-08-26T07:30:47.000000Z.picks +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/picks/2019-08-26T07:30:47.000000Z.xml +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/stations/inventory.xml +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L001..HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L001..HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L001..HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L002..HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L002..HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L002..HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L006..HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L006..HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L006..HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L007..HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L007..HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L007..HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L008..HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L008..HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L008..HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L009..HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L009..HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L009..HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.LD06..HH1_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.LD06..HH2_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.LD06..HH3_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ01.00.HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ01.00.HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ01.00.HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ02.00.HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ03.00.HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ03.00.HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ03.00.HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ04.00.HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ04.00.HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ04.00.HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ05.00.HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ05.00.HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ05.00.HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ06.00.HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ06.00.HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ06.00.HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ07.00.HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ07.00.HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ07.00.HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ09.00.HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ09.00.HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ09.00.HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ10.00.HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ10.00.HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.1 → specmod-0.2.3}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ10.00.HHZ_2019-08-26T07:30:47.000000Z +0 -0
|
@@ -33,7 +33,12 @@ jobs:
|
|
|
33
33
|
|
|
34
34
|
# The package itself, not just the docs extra: autodoc imports every
|
|
35
35
|
# module it documents, so a docs build is also an import check.
|
|
36
|
-
|
|
36
|
+
#
|
|
37
|
+
# `tutorial` supplies the Jupyter kernel. `docs/conf.py` executes the
|
|
38
|
+
# tutorial notebook on every build instead of trusting committed outputs,
|
|
39
|
+
# so without ipykernel the build fails on a missing kernel. Keep this list
|
|
40
|
+
# in step with `.readthedocs.yaml`, which installs the same three.
|
|
41
|
+
- run: uv pip install -e ".[docs,io,tutorial]"
|
|
37
42
|
|
|
38
43
|
- name: Build
|
|
39
44
|
# No -W. Intersphinx resolves seven inventories over the network and
|
|
@@ -26,6 +26,11 @@ htmlcov/
|
|
|
26
26
|
|
|
27
27
|
# Docs
|
|
28
28
|
docs/_build/
|
|
29
|
+
# `docs/conf.py` copies `tutorial/` here so Sphinx can build the notebook from
|
|
30
|
+
# inside its source directory, with the data it reads by relative path. The
|
|
31
|
+
# copy is also what the notebook's own output lands in, which is the point —
|
|
32
|
+
# executing it where it lives would write into the working tree.
|
|
33
|
+
docs/tutorial/
|
|
29
34
|
|
|
30
35
|
# Editors / OS
|
|
31
36
|
.ftpconfig
|
|
@@ -39,9 +44,12 @@ docs/_build/
|
|
|
39
44
|
|
|
40
45
|
# Tutorial output. Regenerated by running the notebook; committing it means a
|
|
41
46
|
# diff every time anyone executes it, and a stale copy the moment the pipeline
|
|
42
|
-
# changes. The inputs
|
|
43
|
-
|
|
44
|
-
Tutorial/Spectra
|
|
47
|
+
# changes. The inputs — waveforms, stations, picks — *are* committed.
|
|
48
|
+
#
|
|
49
|
+
# These patterns named `Tutorial/Spectra/` until now, the capitalised layout
|
|
50
|
+
# from before the `src/` move, so they had matched nothing for the whole
|
|
51
|
+
# refactor and the three files below were tracked in spite of the rule above.
|
|
52
|
+
tutorial/data/events/*/spectra/
|
|
45
53
|
|
|
46
54
|
# Created by `uv run` without --no-sync; this project resolves fresh on
|
|
47
55
|
# purpose so the floors job can test the declared minimums.
|
|
@@ -42,6 +42,12 @@ python:
|
|
|
42
42
|
extra_requirements:
|
|
43
43
|
# `io` alongside `docs` because autodoc imports every module it
|
|
44
44
|
# documents, and `specmod.io` imports h5py and pyarrow. Without it the
|
|
45
|
-
# API reference loses those pages to import errors
|
|
45
|
+
# API reference loses those pages to import errors — and the tutorial
|
|
46
|
+
# saves an HDF5 file, so it needs them at execution time too.
|
|
46
47
|
- docs
|
|
47
48
|
- io
|
|
49
|
+
# `tutorial` supplies the Jupyter kernel. `docs/conf.py` executes the
|
|
50
|
+
# notebook on every build rather than trusting committed outputs, which
|
|
51
|
+
# needs ipykernel, nbclient and nbformat present. Without it the build
|
|
52
|
+
# fails on a missing kernel rather than quietly publishing stale cells.
|
|
53
|
+
- tutorial
|
|
@@ -9,6 +9,35 @@ release could have this problem — every later one has a real predecessor tag
|
|
|
9
9
|
so leave subsequent headings as generated. release-please only prepends to this
|
|
10
10
|
file, so this edit survives. -->
|
|
11
11
|
|
|
12
|
+
## [0.2.3](https://github.com/sgjholt/SpecMod/compare/v0.2.2...v0.2.3) (2026-09-05)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* correct four documented equations and behaviours that the code contradicts ([821792b](https://github.com/sgjholt/SpecMod/commit/821792b66d418b9c0048d717975b5a3716c52c20))
|
|
18
|
+
* point the DOI badge at the concept DOI, not v0.2.0's ([11e7f7a](https://github.com/sgjholt/SpecMod/commit/11e7f7a056fc17c91b22c1dc9d834f19b8b6dbe3))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Documentation
|
|
22
|
+
|
|
23
|
+
* an upgrade guide, and a table of contents with a shape ([4f35388](https://github.com/sgjholt/SpecMod/commit/4f353885cfd0768edeac225d7db4672a20c9120e))
|
|
24
|
+
* derive the roadmap's version, and say when its entries move ([1917d43](https://github.com/sgjholt/SpecMod/commit/1917d432c6fdae1969dacb506bdac986152e40d8))
|
|
25
|
+
* document moment and magnitude, which the page said were absent ([026abec](https://github.com/sgjholt/SpecMod/commit/026abecb9c6ed33017b306e825a6f84db2b343e4))
|
|
26
|
+
* state what is true now, not what the page used to say ([b17339b](https://github.com/sgjholt/SpecMod/commit/b17339b6ad383afd936f7f2a972549b313e19906))
|
|
27
|
+
* the documentation 1.0 was waiting on is done ([9693334](https://github.com/sgjholt/SpecMod/commit/9693334434738ae000bf61f1908524ee983ced17))
|
|
28
|
+
|
|
29
|
+
## [0.2.2](https://github.com/sgjholt/SpecMod/compare/v0.2.1...v0.2.2) (2026-09-05)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### Bug Fixes
|
|
33
|
+
|
|
34
|
+
* ignore the tutorial output at the path it is actually written to ([ad34cc7](https://github.com/sgjholt/SpecMod/commit/ad34cc7d44208e5bd49a2d1f1277516670848dc7))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
### Documentation
|
|
38
|
+
|
|
39
|
+
* publish the tutorial, executed on every build ([ccd1842](https://github.com/sgjholt/SpecMod/commit/ccd18429b9da5db875885d88269fb70686e6eaa3))
|
|
40
|
+
|
|
12
41
|
## [0.2.1](https://github.com/sgjholt/SpecMod/compare/v0.2.0...v0.2.1) (2026-08-23)
|
|
13
42
|
|
|
14
43
|
|
|
@@ -12,7 +12,7 @@ identifiers:
|
|
|
12
12
|
# mints a version DOI per release; cite that one instead when reproducibility
|
|
13
13
|
# matters and you need the reader to land on the exact version you ran.
|
|
14
14
|
- type: doi
|
|
15
|
-
value: "10.5281/zenodo.
|
|
15
|
+
value: "10.5281/zenodo.22071454"
|
|
16
16
|
description: "Concept DOI — resolves to the latest release."
|
|
17
17
|
keywords:
|
|
18
18
|
- seismology
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: specmod
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: A Python toolbox for processing and modelling seismic spectra
|
|
5
5
|
Project-URL: Homepage, https://github.com/sgjholt/SpecMod
|
|
6
6
|
Project-URL: Repository, https://github.com/sgjholt/SpecMod
|
|
@@ -38,6 +38,7 @@ Provides-Extra: docs
|
|
|
38
38
|
Requires-Dist: myst-nb>=1.1; extra == 'docs'
|
|
39
39
|
Requires-Dist: myst-parser>=3.0; extra == 'docs'
|
|
40
40
|
Requires-Dist: pydata-sphinx-theme>=0.15; extra == 'docs'
|
|
41
|
+
Requires-Dist: sphinx-togglebutton>=0.3; extra == 'docs'
|
|
41
42
|
Requires-Dist: sphinx>=7.3; extra == 'docs'
|
|
42
43
|
Provides-Extra: io
|
|
43
44
|
Requires-Dist: h5py>=3.11; extra == 'io'
|
|
@@ -58,7 +59,7 @@ Description-Content-Type: text/markdown
|
|
|
58
59
|
|
|
59
60
|
[](https://pypi.org/project/specmod/)
|
|
60
61
|
[](https://specmod.readthedocs.io/en/stable/)
|
|
61
|
-
[](https://doi.org/10.5281/zenodo.22071454)
|
|
62
63
|
|
|
63
64
|
A Python toolbox for processing and modelling seismic spectra, following the
|
|
64
65
|
method of Edwards *et al.* (2010).
|
|
@@ -237,7 +238,7 @@ The full documentation — the pipeline with its equations, the estimator
|
|
|
237
238
|
comparison, pick formats, and an API reference — builds with Sphinx:
|
|
238
239
|
|
|
239
240
|
```bash
|
|
240
|
-
uv pip install -e '.[docs]'
|
|
241
|
+
uv pip install -e '.[docs,io,tutorial]'
|
|
241
242
|
sphinx-build -b html docs docs/_build/html
|
|
242
243
|
```
|
|
243
244
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://pypi.org/project/specmod/)
|
|
4
4
|
[](https://specmod.readthedocs.io/en/stable/)
|
|
5
|
-
[](https://doi.org/10.5281/zenodo.22071454)
|
|
6
6
|
|
|
7
7
|
A Python toolbox for processing and modelling seismic spectra, following the
|
|
8
8
|
method of Edwards *et al.* (2010).
|
|
@@ -181,7 +181,7 @@ The full documentation — the pipeline with its equations, the estimator
|
|
|
181
181
|
comparison, pick formats, and an API reference — builds with Sphinx:
|
|
182
182
|
|
|
183
183
|
```bash
|
|
184
|
-
uv pip install -e '.[docs]'
|
|
184
|
+
uv pip install -e '.[docs,io,tutorial]'
|
|
185
185
|
sphinx-build -b html docs docs/_build/html
|
|
186
186
|
```
|
|
187
187
|
|
|
@@ -253,11 +253,8 @@ or **0.03 magnitude units**. Against the 0.13 m.u. scatter quoted for spectral
|
|
|
253
253
|
`Mw` that is small, but it is systematic rather than random, so it does not
|
|
254
254
|
average away across stations at similar distance.
|
|
255
255
|
|
|
256
|
-
>
|
|
257
|
-
>
|
|
258
|
-
> gone. The remaining figures come from a differently-constructed sweep than
|
|
259
|
-
> the original and are not directly comparable to it; this table is the one
|
|
260
|
-
> `tools/measure_docs.py` reproduces.
|
|
256
|
+
> Every figure in this table is regenerated by `tools/measure_docs.py`, and
|
|
257
|
+
> `tests/test_docs_are_current.py` fails if the page and the code disagree.
|
|
261
258
|
|
|
262
259
|
### It costs you a diagnostic
|
|
263
260
|
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"""Sphinx configuration for the SpecMod documentation.
|
|
2
|
+
|
|
3
|
+
Build with::
|
|
4
|
+
|
|
5
|
+
uv pip install -e '.[docs,io,tutorial]'
|
|
6
|
+
sphinx-build -b html docs docs/_build/html
|
|
7
|
+
|
|
8
|
+
``-W`` is deliberately **not** used. Intersphinx resolves seven inventories
|
|
9
|
+
over the network, and a warning is emitted whenever one of them is briefly
|
|
10
|
+
unreachable — turning a third party's downtime into a red build. The docs job
|
|
11
|
+
fails on a non-zero exit instead, which is what a genuinely broken build
|
|
12
|
+
gives.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import shutil
|
|
18
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
project = "SpecMod"
|
|
22
|
+
author = "James Holt"
|
|
23
|
+
#: Sphinx substitutes `%Y` with the build year, so this does not need editing
|
|
24
|
+
#: — and it honours `SOURCE_DATE_EPOCH`, so a reproducible build stamps the
|
|
25
|
+
#: source date rather than the day it happened to run. 2020 is the year in
|
|
26
|
+
#: `LICENSE` and the year the history starts.
|
|
27
|
+
copyright = "2020-%Y, James Holt"
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
release = version("specmod")
|
|
31
|
+
except PackageNotFoundError: # pragma: no cover - docs built without an install
|
|
32
|
+
release = "0.0.0"
|
|
33
|
+
#: The short X.Y form, which is what the sidebar shows.
|
|
34
|
+
version = ".".join(release.split(".")[:2])
|
|
35
|
+
|
|
36
|
+
extensions = [
|
|
37
|
+
#: `myst_nb` supersedes `myst_parser` — it is a superset, and loading both
|
|
38
|
+
#: makes Sphinx complain that the `.md` parser is registered twice.
|
|
39
|
+
"myst_nb",
|
|
40
|
+
"sphinx.ext.autodoc",
|
|
41
|
+
"sphinx.ext.napoleon",
|
|
42
|
+
"sphinx.ext.intersphinx",
|
|
43
|
+
"sphinx.ext.viewcode",
|
|
44
|
+
#: Makes `:class: dropdown` collapse an admonition. The alpha warning on the
|
|
45
|
+
#: landing page is the reason: it has to be read once and then stops earning
|
|
46
|
+
#: the screen it occupies, and a caveat nobody scrolls past is worse than
|
|
47
|
+
#: one folded behind its own headline.
|
|
48
|
+
"sphinx_togglebutton",
|
|
49
|
+
]
|
|
50
|
+
#: `sphinx_autodoc_typehints` is deliberately not used. `autodoc_typehints`
|
|
51
|
+
#: below is built into `sphinx.ext.autodoc` and does the same job here, and the
|
|
52
|
+
#: extension calls an API Sphinx 10 removes — it emits a deprecation warning
|
|
53
|
+
#: per module on Sphinx 9. One less dependency for no loss.
|
|
54
|
+
|
|
55
|
+
#: `REFACTOR_PLAN.md` is a working document, not documentation — it is written
|
|
56
|
+
#: for whoever is doing the refactor and records decisions and their evidence.
|
|
57
|
+
#: `notebooks/` holds the source for the transform comparison, which
|
|
58
|
+
#: `tools/measure_docs.py` renders into `choosing-a-transform.md`; the page is
|
|
59
|
+
#: what is published, so building the notebook too would duplicate it.
|
|
60
|
+
#: `notes/` *is* included: `choosing-a-transform.md` links to it for a
|
|
61
|
+
#: per-trace table, so excluding it broke that link.
|
|
62
|
+
exclude_patterns = [
|
|
63
|
+
"_build",
|
|
64
|
+
"REFACTOR_PLAN.md",
|
|
65
|
+
"notebooks/*",
|
|
66
|
+
"Thumbs.db",
|
|
67
|
+
".DS_Store",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
# ------------------------------------------------------- the tutorial notebook
|
|
71
|
+
|
|
72
|
+
#: The tutorial lives in `tutorial/`, outside this source directory, next to the
|
|
73
|
+
#: 1 MB of PNR waveforms it reads through paths relative to itself. Sphinx only
|
|
74
|
+
#: builds what is under `docs/`, so it is copied in here.
|
|
75
|
+
#:
|
|
76
|
+
#: A copy rather than a move, and rather than executing it where it sits,
|
|
77
|
+
#: because **the notebook writes**: cell 53 saves an HDF5 file under
|
|
78
|
+
#: `data/events/<event>/spectra/` and cell 54 writes flatfiles beside it. Run in
|
|
79
|
+
#: place, a docs build would leave those artefacts in the working tree — which
|
|
80
|
+
#: is why `tests/test_tutorial.py` executes it in a `tmp_path` copy too. This is
|
|
81
|
+
#: the same trick, and the copy is what the artefacts land in.
|
|
82
|
+
#:
|
|
83
|
+
#: Copying the data with it is what keeps the notebook's `Path("data/events")`
|
|
84
|
+
#: working, so the notebook is identical whether opened from `tutorial/`, run by
|
|
85
|
+
#: pytest, or built here. `tutorial/` stays canonical: eight other files name
|
|
86
|
+
#: `tutorial/data/events/`, and the CI job that executes it records that a
|
|
87
|
+
#: renamed data directory has already broken this once.
|
|
88
|
+
_HERE = Path(__file__).parent
|
|
89
|
+
_TUTORIAL_SRC = _HERE.parent / "tutorial"
|
|
90
|
+
_TUTORIAL_DST = _HERE / "tutorial"
|
|
91
|
+
|
|
92
|
+
if _TUTORIAL_SRC.is_dir():
|
|
93
|
+
shutil.rmtree(_TUTORIAL_DST, ignore_errors=True)
|
|
94
|
+
shutil.copytree(_TUTORIAL_SRC, _TUTORIAL_DST)
|
|
95
|
+
|
|
96
|
+
#: `force`, not `auto`. The `nbstripout` hook means the notebook arrives with no
|
|
97
|
+
#: outputs, so `auto` would execute it today and quietly stop the moment anyone
|
|
98
|
+
#: committed a notebook with outputs saved — publishing whatever was last run by
|
|
99
|
+
#: hand. Forcing it means the page can only ever show output the code produced
|
|
100
|
+
#: against the code being documented, whatever is in the file.
|
|
101
|
+
nb_execution_mode = "force"
|
|
102
|
+
#: Matches `tests/test_tutorial.py`. The whole notebook runs in ~40s; the
|
|
103
|
+
#: default 30s is per cell, and the two-stage fit is the one that would trip it.
|
|
104
|
+
nb_execution_timeout = 600
|
|
105
|
+
#: A notebook that raises fails the build. That is the point: an executed
|
|
106
|
+
#: tutorial is only a guarantee if a broken one is loud.
|
|
107
|
+
nb_execution_raise_on_error = True
|
|
108
|
+
#: `False` keeps the kernel's working directory at the notebook's own, which is
|
|
109
|
+
#: what `Path("data/events")` resolves against.
|
|
110
|
+
nb_execution_in_temp = False
|
|
111
|
+
|
|
112
|
+
#: Markdown for the prose pages — every one in `docs/` is written that way, and
|
|
113
|
+
#: allowing reStructuredText too would mean two syntaxes for the same job — plus
|
|
114
|
+
#: `.ipynb` for the tutorial.
|
|
115
|
+
#:
|
|
116
|
+
#: Both map to `myst-nb`, which is the only parser name `myst_nb` 1.4 registers:
|
|
117
|
+
#: it does not re-register `myst_parser`'s `markdown`, so leaving `.md` pointing
|
|
118
|
+
#: at that fails the build outright with "Source parser for markdown not
|
|
119
|
+
#: registered". The `myst-nb` parser is a superset and reads the prose pages
|
|
120
|
+
#: identically.
|
|
121
|
+
source_suffix = {".md": "myst-nb", ".ipynb": "myst-nb"}
|
|
122
|
+
|
|
123
|
+
#: `linkify` is deliberately absent: it needs `linkify-it-py` and every link in
|
|
124
|
+
#: these pages is already explicit.
|
|
125
|
+
myst_enable_extensions = [
|
|
126
|
+
"colon_fence", # ::: fences, so a directive can hold a code block
|
|
127
|
+
"deflist",
|
|
128
|
+
"dollarmath",
|
|
129
|
+
"substitution",
|
|
130
|
+
]
|
|
131
|
+
#: Heading anchors down to h3, so `docs/*.md` can link to each other's sections.
|
|
132
|
+
myst_heading_anchors = 3
|
|
133
|
+
|
|
134
|
+
#: `{{ release }}` in a page resolves to the version this site was built from.
|
|
135
|
+
#: The roadmap used to state it in prose, which meant it was wrong from the
|
|
136
|
+
#: moment of the next release — it said v0.2.0 through two that followed. A
|
|
137
|
+
#: version is derivable, so deriving it removes the only part of that page that
|
|
138
|
+
#: went stale on a timetable rather than on a decision.
|
|
139
|
+
myst_substitutions = {"release": release}
|
|
140
|
+
|
|
141
|
+
# ------------------------------------------------------------------ autodoc
|
|
142
|
+
|
|
143
|
+
autodoc_typehints = "description"
|
|
144
|
+
autodoc_member_order = "bysource"
|
|
145
|
+
autodoc_default_options = {
|
|
146
|
+
"members": True,
|
|
147
|
+
"show-inheritance": True,
|
|
148
|
+
"member-order": "bysource",
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
napoleon_google_docstring = False
|
|
152
|
+
napoleon_numpy_docstring = True
|
|
153
|
+
|
|
154
|
+
intersphinx_mapping = {
|
|
155
|
+
"python": ("https://docs.python.org/3", None),
|
|
156
|
+
"numpy": ("https://numpy.org/doc/stable", None),
|
|
157
|
+
"scipy": ("https://docs.scipy.org/doc/scipy", None),
|
|
158
|
+
"pandas": ("https://pandas.pydata.org/docs", None),
|
|
159
|
+
"matplotlib": ("https://matplotlib.org/stable", None),
|
|
160
|
+
"obspy": ("https://docs.obspy.org", None),
|
|
161
|
+
"lmfit": ("https://lmfit.github.io/lmfit-py", None),
|
|
162
|
+
}
|
|
163
|
+
#: Resolving these needs the network. A build without it still produces a
|
|
164
|
+
#: site, with the cross-references left as plain text.
|
|
165
|
+
intersphinx_disabled_reftypes = ["*"]
|
|
166
|
+
|
|
167
|
+
# --------------------------------------------------------------------- html
|
|
168
|
+
|
|
169
|
+
html_theme = "pydata_sphinx_theme"
|
|
170
|
+
html_title = f"{project} {version}"
|
|
171
|
+
html_theme_options = {
|
|
172
|
+
"github_url": "https://github.com/sgjholt/SpecMod",
|
|
173
|
+
"show_prev_next": True,
|
|
174
|
+
"navigation_with_keys": False,
|
|
175
|
+
#: This theme puts *top-level* toctree entries in the header and gives the
|
|
176
|
+
#: sidebar the current section's children. A flat toctree therefore
|
|
177
|
+
#: produces a header of ten items and an empty sidebar, with `:caption:`
|
|
178
|
+
#: nowhere to render — which is what this site had. The four section pages
|
|
179
|
+
#: are what give the sidebar something to nest.
|
|
180
|
+
#:
|
|
181
|
+
#: `show_nav_level: 1` expands each section's own entries rather than
|
|
182
|
+
#: leaving them behind a disclosure triangle, so a reader can see a
|
|
183
|
+
#: section's contents without a click.
|
|
184
|
+
"show_nav_level": 1,
|
|
185
|
+
#: Deep enough for a section, its pages, and their headings — which is what
|
|
186
|
+
#: makes a long page like `processing` navigable from the sidebar rather
|
|
187
|
+
#: than by scrolling.
|
|
188
|
+
"navigation_depth": 3,
|
|
189
|
+
}
|
|
190
|
+
html_static_path: list[str] = []
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Working on SpecMod
|
|
2
|
+
|
|
3
|
+
Where the project is going, how to work on it, and how a merged commit becomes
|
|
4
|
+
a release.
|
|
5
|
+
|
|
6
|
+
[Roadmap](roadmap.md)
|
|
7
|
+
: What has shipped and in which version, what is being worked on, and what 1.0
|
|
8
|
+
will mean. Milestones, not dates.
|
|
9
|
+
|
|
10
|
+
[Developer guide](development.md)
|
|
11
|
+
: Quick start, the repository mapped, the daily loop, every tool and check, and
|
|
12
|
+
where development stops and releasing begins. Includes working with coding
|
|
13
|
+
agents.
|
|
14
|
+
|
|
15
|
+
[Documentation workflow](documentation.md)
|
|
16
|
+
: Building this site locally, previewing a pull request's build, how the
|
|
17
|
+
tutorial is executed into it, and how to add a page.
|
|
18
|
+
|
|
19
|
+
[Releasing the software](releasing.md)
|
|
20
|
+
: How a merged commit becomes a tag, a PyPI release and a DOI — and the
|
|
21
|
+
one-time repository settings none of it works without.
|
|
22
|
+
|
|
23
|
+
```{toctree}
|
|
24
|
+
:maxdepth: 2
|
|
25
|
+
:hidden:
|
|
26
|
+
|
|
27
|
+
roadmap
|
|
28
|
+
development
|
|
29
|
+
documentation
|
|
30
|
+
releasing
|
|
31
|
+
```
|
|
@@ -246,12 +246,12 @@ bounded rather than explained, and says so in as many words.
|
|
|
246
246
|
|
|
247
247
|
## What CI runs
|
|
248
248
|
|
|
249
|
-
|
|
250
|
-
request.
|
|
249
|
+
Six jobs in `test.yml`, plus three more workflows. All of them run on every
|
|
250
|
+
pull request except `release.yml`, which fires only on a push to `main`.
|
|
251
251
|
|
|
252
252
|
| Job | Workflow | Does |
|
|
253
253
|
|---|---|---|
|
|
254
|
-
| `lint` | `test.yml` | `ruff check
|
|
254
|
+
| `lint` | `test.yml` | `ruff check` and `ruff format --check` over `src/ tests/ tools/` |
|
|
255
255
|
| `typecheck` | `test.yml` | `mypy`, strict, over the whole package |
|
|
256
256
|
| `test` | `test.yml` | pytest on 3.11/3.12/3.13 × ubuntu/macOS, coverage to Codecov from one cell |
|
|
257
257
|
| `floors` | `test.yml` | installs the *declared minimum* versions and runs the suite |
|
|
@@ -403,9 +403,12 @@ has happened here:
|
|
|
403
403
|
not there. Three commits went out with session trailers before this was
|
|
404
404
|
noticed; the config now installs both hook types from one command, and the
|
|
405
405
|
first thing `AGENTS.md` says is to run it.
|
|
406
|
-
- **An agent's token
|
|
407
|
-
|
|
408
|
-
|
|
406
|
+
- **An agent's token may not be able to push `.github/workflows/`.** The
|
|
407
|
+
permission is granted here now, and the `ci/` mirror that used to work around
|
|
408
|
+
it is gone — keeping two copies of every workflow in step cost more than the
|
|
409
|
+
problem it solved. If the permission is ever withdrawn the push is rejected
|
|
410
|
+
loudly, naming `workflows`; the answer is to ask for it back, not to rebuild
|
|
411
|
+
the mirror.
|
|
409
412
|
- **A development container often lacks the optional extras**, so an agent's
|
|
410
413
|
green run can be greener than CI's. `--without-optional-extras` is the check.
|
|
411
414
|
- **A harness may append its own commit trailers.** The repository's rules take
|
|
@@ -32,7 +32,7 @@ those are separate clocks.
|
|
|
32
32
|
## Building it locally
|
|
33
33
|
|
|
34
34
|
```sh
|
|
35
|
-
uv pip install -e '.[docs]'
|
|
35
|
+
uv pip install -e '.[docs,io,tutorial]'
|
|
36
36
|
sphinx-build -b html docs docs/_build/html
|
|
37
37
|
python -m http.server -d docs/_build/html 8000 # then open localhost:8000
|
|
38
38
|
```
|
|
@@ -136,9 +136,11 @@ Two things in it are load-bearing and easy to lose:
|
|
|
136
136
|
clones shallow to save time, and `hatch-vcs` derives the version from
|
|
137
137
|
`git describe`. Without those two lines every build — including a tagged one
|
|
138
138
|
— reports the fallback `0.0.0` in the sidebar.
|
|
139
|
-
- **`extra_requirements: [docs, io]`.**
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
- **`extra_requirements: [docs, io, tutorial]`.** `io` because autodoc imports
|
|
140
|
+
`specmod.io`, which imports h5py and pyarrow — and because the tutorial saves
|
|
141
|
+
an HDF5 file while executing. `tutorial` for the Jupyter kernel that executes
|
|
142
|
+
it. The CI `docs` job installs the same three for the same reasons; keep them
|
|
143
|
+
in step or one of the two builds fails on a missing kernel.
|
|
142
144
|
|
|
143
145
|
## Versions, and what to link to
|
|
144
146
|
|
|
@@ -168,11 +170,19 @@ page depends on is documentation whatever its folder is called.
|
|
|
168
170
|
### Adding a page
|
|
169
171
|
|
|
170
172
|
1. Write `docs/<name>.md` in MyST Markdown.
|
|
171
|
-
2. Add it to the `toctree`
|
|
172
|
-
|
|
173
|
+
2. **Add it to the `toctree` of the section it belongs to** — not to
|
|
174
|
+
`index.md`. The site has four section pages, each owning its own toctree:
|
|
175
|
+
`getting-started.md`, `guides.md`, `api.md` and `contributing.md`. Add a
|
|
176
|
+
description to the list on that page too, since the sidebar shows titles
|
|
177
|
+
only.
|
|
173
178
|
3. Build. A page in no toctree builds but warns, and is reachable only by a
|
|
174
179
|
direct link.
|
|
175
180
|
|
|
181
|
+
`index.md`'s toctree holds only those four. That is what gives the sidebar its
|
|
182
|
+
nesting: this theme puts top-level toctree entries in the header and gives the
|
|
183
|
+
sidebar the current section's children, so a page added at the top level lands
|
|
184
|
+
in the header and flattens the navigation for everything else.
|
|
185
|
+
|
|
176
186
|
If a page is a supporting note rather than a top-level one, put it in a hidden
|
|
177
187
|
toctree on the page that cites it — that is how `notes/window-position.md` is
|
|
178
188
|
attached to `choosing-a-transform.md`:
|
|
@@ -195,8 +205,11 @@ pages can link to each other's sections.
|
|
|
195
205
|
those work; without it MyST does not read `$` at all.
|
|
196
206
|
- `amsmath` is **not** enabled — nothing here uses a bare `\begin{align}`
|
|
197
207
|
outside `$` delimiters. A `\begin{cases}` inside `$$` renders without it.
|
|
198
|
-
- Markdown
|
|
199
|
-
`docs/`, so there is one
|
|
208
|
+
- Markdown and notebooks. `source_suffix` maps `.md` and `.ipynb`, both to
|
|
209
|
+
`myst-nb` — there is no reStructuredText in `docs/`, so there is one prose
|
|
210
|
+
syntax rather than two. Both suffixes name `myst-nb` because that is the only
|
|
211
|
+
parser `myst_nb` registers; pointing `.md` at `myst_parser`'s `markdown`
|
|
212
|
+
fails the build with "Source parser for markdown not registered".
|
|
200
213
|
- For a Sphinx directive that has no MyST spelling, drop into rST:
|
|
201
214
|
|
|
202
215
|
````markdown
|
|
@@ -223,7 +236,44 @@ the first build:
|
|
|
223
236
|
|
|
224
237
|
Type hints come from the annotations via `autodoc_typehints = "description"`.
|
|
225
238
|
`sphinx-autodoc-typehints` is deliberately **not** used: measured, it produced
|
|
226
|
-
the same
|
|
239
|
+
the same number of documented objects while calling an API Sphinx 10 removes.
|
|
240
|
+
|
|
241
|
+
### The tutorial notebook
|
|
242
|
+
|
|
243
|
+
`tutorial/SpecModTutorial.ipynb` is published as part of the site and
|
|
244
|
+
**executed on every build** (`nb_execution_mode = "force"`). Every figure and
|
|
245
|
+
number on the page came from running that code against the code being
|
|
246
|
+
documented, and a notebook that raises fails the build
|
|
247
|
+
(`nb_execution_raise_on_error = True`). That is the whole point: a tutorial
|
|
248
|
+
nobody runs is the first thing to rot, and this one broke three times before
|
|
249
|
+
anything executed it.
|
|
250
|
+
|
|
251
|
+
Three things about the arrangement are worth knowing before changing it.
|
|
252
|
+
|
|
253
|
+
**It is copied into `docs/tutorial/` by `conf.py`, not moved.** Sphinx builds
|
|
254
|
+
only what is under `docs/`, and the notebook reads its 1 MB of waveforms
|
|
255
|
+
through paths relative to itself — so the data has to travel with it. The copy
|
|
256
|
+
is gitignored. `tutorial/` stays canonical because eight other files name
|
|
257
|
+
`tutorial/data/events/`, and a renamed data directory has broken this before.
|
|
258
|
+
|
|
259
|
+
**The copy is also what the notebook writes into.** It saves an HDF5 file and
|
|
260
|
+
two flatfiles as part of the lesson. Executed where it lives, a docs build
|
|
261
|
+
would leave those in your working tree; `tests/test_tutorial.py` copies to
|
|
262
|
+
`tmp_path` for exactly the same reason.
|
|
263
|
+
|
|
264
|
+
**Outputs are stripped in git**, by the `nbstripout` pre-commit hook, and
|
|
265
|
+
regenerated at build time. Do not commit them back: `force` ignores them, so a
|
|
266
|
+
committed output is never what a reader sees — only a stale diff.
|
|
267
|
+
|
|
268
|
+
The kernel comes from the `tutorial` extra. Both `.readthedocs.yaml` and
|
|
269
|
+
`.github/workflows/docs.yml` install `[docs,io,tutorial]`; keep them in step or
|
|
270
|
+
one of the two builds fails on a missing kernel. This does mean the notebook
|
|
271
|
+
executes twice per pull request — once here, and once in the `notebook` CI job,
|
|
272
|
+
which runs the single `-m notebook` test that executes it in a `tmp_path` copy.
|
|
273
|
+
Roughly 40 seconds, paid twice, to catch a broken notebook either as a failed
|
|
274
|
+
build or as a failed test. The cheaper checks around it — that every name the
|
|
275
|
+
notebook imports resolves, and that deleted modules stay unmentioned even in
|
|
276
|
+
prose — are unmarked, so they run in the `test` matrix job instead.
|
|
227
277
|
|
|
228
278
|
### Numbers in prose
|
|
229
279
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Getting started
|
|
2
|
+
|
|
3
|
+
Install it, run one event end to end, and find out what moved if you have code
|
|
4
|
+
written against `0.1`.
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
pip install specmod
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Python 3.11 or newer. Saving and loading spectra needs the `io` extra —
|
|
11
|
+
`pip install "specmod[io]"` — without which SpecMod computes and plots normally
|
|
12
|
+
but cannot write a result. The other extras are listed in the
|
|
13
|
+
[README](https://github.com/sgjholt/SpecMod#installation).
|
|
14
|
+
|
|
15
|
+
While this is `0.x`, pin an exact version in anything you intend to publish.
|
|
16
|
+
The [roadmap](roadmap.md) says what has shipped and what 1.0 will mean.
|
|
17
|
+
|
|
18
|
+
[Tutorial](tutorial/SpecModTutorial.ipynb)
|
|
19
|
+
: One event from waveforms and picks to source parameters. Every figure and
|
|
20
|
+
number on the page is produced by executing the notebook when this site is
|
|
21
|
+
built, so it cannot describe an API that no longer exists. **Start here.**
|
|
22
|
+
|
|
23
|
+
[Upgrading from 0.1](upgrading.md)
|
|
24
|
+
: For code written against the pre-refactor `0.1.1` on `master`. Modules moved,
|
|
25
|
+
were renamed to snake_case, and several were deleted, so old code fails at
|
|
26
|
+
its imports rather than running and quietly giving different numbers.
|
|
27
|
+
|
|
28
|
+
## Then
|
|
29
|
+
|
|
30
|
+
[How a spectrum is processed](processing.md) is the reference for what each
|
|
31
|
+
stage does and the conventions it uses — the amplitude convention, the Parseval
|
|
32
|
+
contract, and the moment and magnitude equations. It is the page to read once
|
|
33
|
+
the tutorial has run.
|
|
34
|
+
|
|
35
|
+
```{toctree}
|
|
36
|
+
:maxdepth: 2
|
|
37
|
+
:hidden:
|
|
38
|
+
|
|
39
|
+
tutorial/SpecModTutorial
|
|
40
|
+
upgrading
|
|
41
|
+
```
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Guides
|
|
2
|
+
|
|
3
|
+
What each stage does, why it is done that way, and what the choices cost.
|
|
4
|
+
|
|
5
|
+
## The pipeline, and the conventions
|
|
6
|
+
|
|
7
|
+
[How a spectrum is processed](processing.md)
|
|
8
|
+
: Every step from a raw waveform to a moment magnitude, with the equation it
|
|
9
|
+
applies and a pointer to the code that applies it.
|
|
10
|
+
|
|
11
|
+
This is also where the conventions are stated, deliberately in the sections
|
|
12
|
+
that apply them rather than on a page of their own:
|
|
13
|
+
|
|
14
|
+
[Amplitude convention](processing.md#4-amplitude-convention)
|
|
15
|
+
: `FAS` is the folded $2\lvert X\rvert$; `MAGNITUDE` is the unfolded
|
|
16
|
+
$\lvert X\rvert$, **and that is the one $\Omega$ is defined in**. Reading a
|
|
17
|
+
folded plateau as $\Omega$ puts $M_0$ out by two — 0.2 magnitude units.
|
|
18
|
+
|
|
19
|
+
[The Parseval contract](processing.md#the-parseval-contract)
|
|
20
|
+
: The one energy check every estimator is held to, which is what lets
|
|
21
|
+
multitaper, Welch, FFT and the CWT be interchangeable rather than merely
|
|
22
|
+
similar.
|
|
23
|
+
|
|
24
|
+
[Moment and magnitude](processing.md#9-moment-and-magnitude)
|
|
25
|
+
: The $M_0$ and $M_w$ equations, the medium constants and where they come
|
|
26
|
+
from, and the two distances that are in different units on purpose.
|
|
27
|
+
|
|
28
|
+
## Choices that change the answer
|
|
29
|
+
|
|
30
|
+
[Choosing a transform](choosing-a-transform.md)
|
|
31
|
+
: What each estimator does to your data, measured. On real windows the plateau
|
|
32
|
+
moves by 7–15% between estimators — about 0.03 magnitude units — and window
|
|
33
|
+
position alone reaches 0.08. Small against the 0.13 m.u. scatter quoted for
|
|
34
|
+
spectral $M_w$, but systematic rather than random, so it does not average
|
|
35
|
+
away across stations at similar distance.
|
|
36
|
+
|
|
37
|
+
[Reading picks](pick-formats.md)
|
|
38
|
+
: What arrival formats are read out of the box, how to add one, and how a pick
|
|
39
|
+
is matched to a trace.
|
|
40
|
+
|
|
41
|
+
## Working with data
|
|
42
|
+
|
|
43
|
+
[Publishing a dataset](releasing-data.md)
|
|
44
|
+
: Taking an event from an FDSN archive to a hash-pinned entry in the registry,
|
|
45
|
+
so a result can be reproduced from the same bytes.
|
|
46
|
+
|
|
47
|
+
```{toctree}
|
|
48
|
+
:maxdepth: 2
|
|
49
|
+
:hidden:
|
|
50
|
+
|
|
51
|
+
processing
|
|
52
|
+
choosing-a-transform
|
|
53
|
+
pick-formats
|
|
54
|
+
releasing-data
|
|
55
|
+
```
|