specmod 0.2.1__tar.gz → 0.2.2__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.2}/.github/workflows/docs.yml +6 -1
- {specmod-0.2.1 → specmod-0.2.2}/.gitignore +11 -3
- {specmod-0.2.1 → specmod-0.2.2}/.readthedocs.yaml +7 -1
- specmod-0.2.2/.release-please-manifest.json +3 -0
- {specmod-0.2.1 → specmod-0.2.2}/CHANGELOG.md +12 -0
- {specmod-0.2.1 → specmod-0.2.2}/PKG-INFO +1 -1
- {specmod-0.2.1 → specmod-0.2.2}/docs/conf.py +61 -7
- {specmod-0.2.1 → specmod-0.2.2}/docs/documentation.md +39 -2
- {specmod-0.2.1 → specmod-0.2.2}/docs/index.md +6 -0
- {specmod-0.2.1 → specmod-0.2.2}/docs/roadmap.md +14 -5
- specmod-0.2.2/tutorial/SpecModTutorial.ipynb +1032 -0
- specmod-0.2.1/.release-please-manifest.json +0 -3
- 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.2}/.git-blame-ignore-revs +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/.github/workflows/build.yml +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/.github/workflows/release.yml +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/.github/workflows/test.yml +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/.pre-commit-config.yaml +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/AGENTS.md +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/CITATION.cff +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/CLAUDE.md +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/CONTRIBUTING.md +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/LICENSE +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/README.md +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/datasets/magna_2020.toml +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/datasets/pnr_2019.toml +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/docs/REFACTOR_PLAN.md +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/docs/api.md +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/docs/choosing-a-transform.md +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/docs/development.md +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/docs/notebooks/_build_notebook.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/docs/notebooks/choosing-a-transform.ipynb +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/docs/notes/api-audit.md +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/docs/notes/window-position.md +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/docs/pick-formats.md +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/docs/processing.md +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/docs/releasing-data.md +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/docs/releasing.md +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/pyproject.toml +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/release-please-config.json +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/requirements.txt +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/_vendor/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/_vendor/qiinv.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/acquire.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/api.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/cli.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/config/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/config/layers.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/config/provenance.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/config/sections.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/config/serialize.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/core/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/core/bandwidth.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/core/collection.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/core/noise.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/core/scalogram.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/core/spectrum.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/core/units.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/datasets.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/distance.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/exceptions.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/fitting/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/fitting/base.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/fitting/event.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/fitting/guess.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/fitting/spectrum.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/io.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/magnitude.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/picks/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/picks/base.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/picks/delimited.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/picks/events.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/picks/resolution.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/picks/snuffler.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/pipeline.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/plotting.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/preprocess.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/smoothing/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/smoothing/base.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/smoothing/konno_ohmachi.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/smoothing/log_bins.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/sources/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/sources/attenuation.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/sources/composite.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/sources/motion.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/sources/source.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/spreading.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/staged.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/tables.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/transforms/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/transforms/base.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/transforms/cwt.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/transforms/fft.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/transforms/multitaper.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/transforms/prieto.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/transforms/quadratic.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/src/specmod/utils.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/README.md +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/lmfit/__init__.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/lmfit/model.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/lmfit/parameter.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/obspy/__init__.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/obspy/clients/__init__.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/obspy/clients/fdsn/__init__.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/obspy/core/__init__.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/obspy/core/event.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/obspy/core/inventory.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/obspy/core/stream.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/obspy/core/trace.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/obspy/core/utcdatetime.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/obspy/core/util/__init__.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/obspy/core/util/base.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/obspy/geodetics/__init__.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/obspy/signal/__init__.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/stubs/obspy/signal/konnoohmachismoothing.pyi +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/studies/magna_2020_paper.toml +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/__init__.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/conftest.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/golden/motion_reference.json +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/golden/pipeline_reference.json +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/golden/window_reference.json +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_acquire.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_ambient_state.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_api_surface.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_collection.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_config.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_cwt.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_datasets.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_docs_are_current.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_end_to_end.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_fitting_defaults.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_golden_reference.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_import.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_io_and_plotting.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_legacy_fixes.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_magnitude.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_make_golden.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_pick_plugins.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_pick_readers.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_picks.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_pipeline.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_pipeline_smoke.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_preprocess.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_prieto.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_quadratic.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_release_config.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_smoothing.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_sources.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_spectral_wiring.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_staged.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_stubs.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_transforms.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_tutorial.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_typing_backlog.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_utils.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tests/test_versioning.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tools/check_built_version.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tools/check_floors.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tools/make_golden.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/tools/measure_docs.py +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/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.2}/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.2}/tutorial/data/events/2019-08-26T07:30:47.000000Z/stations/inventory.xml +0 -0
- {specmod-0.2.1 → specmod-0.2.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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.2}/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,18 @@ 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.2](https://github.com/sgjholt/SpecMod/compare/v0.2.1...v0.2.2) (2026-09-05)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* ignore the tutorial output at the path it is actually written to ([ad34cc7](https://github.com/sgjholt/SpecMod/commit/ad34cc7d44208e5bd49a2d1f1277516670848dc7))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Documentation
|
|
21
|
+
|
|
22
|
+
* publish the tutorial, executed on every build ([ccd1842](https://github.com/sgjholt/SpecMod/commit/ccd18429b9da5db875885d88269fb70686e6eaa3))
|
|
23
|
+
|
|
12
24
|
## [0.2.1](https://github.com/sgjholt/SpecMod/compare/v0.2.0...v0.2.1) (2026-08-23)
|
|
13
25
|
|
|
14
26
|
|
|
@@ -14,7 +14,9 @@ gives.
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
+
import shutil
|
|
17
18
|
from importlib.metadata import PackageNotFoundError, version
|
|
19
|
+
from pathlib import Path
|
|
18
20
|
|
|
19
21
|
project = "SpecMod"
|
|
20
22
|
author = "James Holt"
|
|
@@ -32,7 +34,9 @@ except PackageNotFoundError: # pragma: no cover - docs built without an install
|
|
|
32
34
|
version = ".".join(release.split(".")[:2])
|
|
33
35
|
|
|
34
36
|
extensions = [
|
|
35
|
-
|
|
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",
|
|
36
40
|
"sphinx.ext.autodoc",
|
|
37
41
|
"sphinx.ext.napoleon",
|
|
38
42
|
"sphinx.ext.intersphinx",
|
|
@@ -45,9 +49,10 @@ extensions = [
|
|
|
45
49
|
|
|
46
50
|
#: `REFACTOR_PLAN.md` is a working document, not documentation — it is written
|
|
47
51
|
#: for whoever is doing the refactor and records decisions and their evidence.
|
|
48
|
-
#: `notebooks/`
|
|
49
|
-
#:
|
|
50
|
-
#:
|
|
52
|
+
#: `notebooks/` holds the source for the transform comparison, which
|
|
53
|
+
#: `tools/measure_docs.py` renders into `choosing-a-transform.md`; the page is
|
|
54
|
+
#: what is published, so building the notebook too would duplicate it.
|
|
55
|
+
#: `notes/` *is* included: `choosing-a-transform.md` links to it for a
|
|
51
56
|
#: per-trace table, so excluding it broke that link.
|
|
52
57
|
exclude_patterns = [
|
|
53
58
|
"_build",
|
|
@@ -57,9 +62,58 @@ exclude_patterns = [
|
|
|
57
62
|
".DS_Store",
|
|
58
63
|
]
|
|
59
64
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
# ------------------------------------------------------- the tutorial notebook
|
|
66
|
+
|
|
67
|
+
#: The tutorial lives in `tutorial/`, outside this source directory, next to the
|
|
68
|
+
#: 1 MB of PNR waveforms it reads through paths relative to itself. Sphinx only
|
|
69
|
+
#: builds what is under `docs/`, so it is copied in here.
|
|
70
|
+
#:
|
|
71
|
+
#: A copy rather than a move, and rather than executing it where it sits,
|
|
72
|
+
#: because **the notebook writes**: cell 53 saves an HDF5 file under
|
|
73
|
+
#: `data/events/<event>/spectra/` and cell 54 writes flatfiles beside it. Run in
|
|
74
|
+
#: place, a docs build would leave those artefacts in the working tree — which
|
|
75
|
+
#: is why `tests/test_tutorial.py` executes it in a `tmp_path` copy too. This is
|
|
76
|
+
#: the same trick, and the copy is what the artefacts land in.
|
|
77
|
+
#:
|
|
78
|
+
#: Copying the data with it is what keeps the notebook's `Path("data/events")`
|
|
79
|
+
#: working, so the notebook is identical whether opened from `tutorial/`, run by
|
|
80
|
+
#: pytest, or built here. `tutorial/` stays canonical: eight other files name
|
|
81
|
+
#: `tutorial/data/events/`, and the CI job that executes it records that a
|
|
82
|
+
#: renamed data directory has already broken this once.
|
|
83
|
+
_HERE = Path(__file__).parent
|
|
84
|
+
_TUTORIAL_SRC = _HERE.parent / "tutorial"
|
|
85
|
+
_TUTORIAL_DST = _HERE / "tutorial"
|
|
86
|
+
|
|
87
|
+
if _TUTORIAL_SRC.is_dir():
|
|
88
|
+
shutil.rmtree(_TUTORIAL_DST, ignore_errors=True)
|
|
89
|
+
shutil.copytree(_TUTORIAL_SRC, _TUTORIAL_DST)
|
|
90
|
+
|
|
91
|
+
#: `force`, not `auto`. `auto` executes only notebooks that arrive without
|
|
92
|
+
#: outputs, and the tutorial is committed *with* 28 cells of them — so `auto`
|
|
93
|
+
#: would publish whatever was last saved by hand, which is the silent rot this
|
|
94
|
+
#: is meant to end. Forcing it means the page can only show output the code
|
|
95
|
+
#: actually produced against the code being documented.
|
|
96
|
+
nb_execution_mode = "force"
|
|
97
|
+
#: Matches `tests/test_tutorial.py`. The whole notebook runs in ~40s; the
|
|
98
|
+
#: default 30s is per cell, and the two-stage fit is the one that would trip it.
|
|
99
|
+
nb_execution_timeout = 600
|
|
100
|
+
#: A notebook that raises fails the build. That is the point: an executed
|
|
101
|
+
#: tutorial is only a guarantee if a broken one is loud.
|
|
102
|
+
nb_execution_raise_on_error = True
|
|
103
|
+
#: `False` keeps the kernel's working directory at the notebook's own, which is
|
|
104
|
+
#: what `Path("data/events")` resolves against.
|
|
105
|
+
nb_execution_in_temp = False
|
|
106
|
+
|
|
107
|
+
#: Markdown for the prose pages — every one in `docs/` is written that way, and
|
|
108
|
+
#: allowing reStructuredText too would mean two syntaxes for the same job — plus
|
|
109
|
+
#: `.ipynb` for the tutorial.
|
|
110
|
+
#:
|
|
111
|
+
#: Both map to `myst-nb`, which is the only parser name `myst_nb` 1.4 registers:
|
|
112
|
+
#: it does not re-register `myst_parser`'s `markdown`, so leaving `.md` pointing
|
|
113
|
+
#: at that fails the build outright with "Source parser for markdown not
|
|
114
|
+
#: registered". The `myst-nb` parser is a superset and reads the prose pages
|
|
115
|
+
#: identically.
|
|
116
|
+
source_suffix = {".md": "myst-nb", ".ipynb": "myst-nb"}
|
|
63
117
|
|
|
64
118
|
#: `linkify` is deliberately absent: it needs `linkify-it-py` and every link in
|
|
65
119
|
#: these pages is already explicit.
|
|
@@ -195,8 +195,11 @@ pages can link to each other's sections.
|
|
|
195
195
|
those work; without it MyST does not read `$` at all.
|
|
196
196
|
- `amsmath` is **not** enabled — nothing here uses a bare `\begin{align}`
|
|
197
197
|
outside `$` delimiters. A `\begin{cases}` inside `$$` renders without it.
|
|
198
|
-
- Markdown
|
|
199
|
-
`docs/`, so there is one
|
|
198
|
+
- Markdown and notebooks. `source_suffix` maps `.md` and `.ipynb`, both to
|
|
199
|
+
`myst-nb` — there is no reStructuredText in `docs/`, so there is one prose
|
|
200
|
+
syntax rather than two. Both suffixes name `myst-nb` because that is the only
|
|
201
|
+
parser `myst_nb` registers; pointing `.md` at `myst_parser`'s `markdown`
|
|
202
|
+
fails the build with "Source parser for markdown not registered".
|
|
200
203
|
- For a Sphinx directive that has no MyST spelling, drop into rST:
|
|
201
204
|
|
|
202
205
|
````markdown
|
|
@@ -225,6 +228,40 @@ Type hints come from the annotations via `autodoc_typehints = "description"`.
|
|
|
225
228
|
`sphinx-autodoc-typehints` is deliberately **not** used: measured, it produced
|
|
226
229
|
the same 367 documented objects while calling an API Sphinx 10 removes.
|
|
227
230
|
|
|
231
|
+
### The tutorial notebook
|
|
232
|
+
|
|
233
|
+
`tutorial/SpecModTutorial.ipynb` is published as part of the site and
|
|
234
|
+
**executed on every build** (`nb_execution_mode = "force"`). Every figure and
|
|
235
|
+
number on the page came from running that code against the code being
|
|
236
|
+
documented, and a notebook that raises fails the build
|
|
237
|
+
(`nb_execution_raise_on_error = True`). That is the whole point: a tutorial
|
|
238
|
+
nobody runs is the first thing to rot, and this one broke three times before
|
|
239
|
+
anything executed it.
|
|
240
|
+
|
|
241
|
+
Three things about the arrangement are worth knowing before changing it.
|
|
242
|
+
|
|
243
|
+
**It is copied into `docs/tutorial/` by `conf.py`, not moved.** Sphinx builds
|
|
244
|
+
only what is under `docs/`, and the notebook reads its 1 MB of waveforms
|
|
245
|
+
through paths relative to itself — so the data has to travel with it. The copy
|
|
246
|
+
is gitignored. `tutorial/` stays canonical because eight other files name
|
|
247
|
+
`tutorial/data/events/`, and a renamed data directory has broken this before.
|
|
248
|
+
|
|
249
|
+
**The copy is also what the notebook writes into.** It saves an HDF5 file and
|
|
250
|
+
two flatfiles as part of the lesson. Executed where it lives, a docs build
|
|
251
|
+
would leave those in your working tree; `tests/test_tutorial.py` copies to
|
|
252
|
+
`tmp_path` for exactly the same reason.
|
|
253
|
+
|
|
254
|
+
**Outputs are stripped in git**, by the `nbstripout` pre-commit hook, and
|
|
255
|
+
regenerated at build time. Do not commit them back: `force` ignores them, so a
|
|
256
|
+
committed output is never what a reader sees — only a stale diff.
|
|
257
|
+
|
|
258
|
+
The kernel comes from the `tutorial` extra. Both `.readthedocs.yaml` and
|
|
259
|
+
`.github/workflows/docs.yml` install `[docs,io,tutorial]`; keep them in step or
|
|
260
|
+
one of the two builds fails on a missing kernel. This does mean the notebook
|
|
261
|
+
executes twice per pull request — once here and once in the `notebook` CI job,
|
|
262
|
+
which also checks imports and that deleted modules stay unmentioned. Roughly
|
|
263
|
+
40 seconds, paid twice, for two genuinely different failures.
|
|
264
|
+
|
|
228
265
|
### Numbers in prose
|
|
229
266
|
|
|
230
267
|
Any table that came from a measurement is generated, not typed. Edit
|
|
@@ -45,6 +45,11 @@ print(fits.table[["id", "llpsp", "fc", "ts"]])
|
|
|
45
45
|
|
|
46
46
|
## Where to start
|
|
47
47
|
|
|
48
|
+
[Tutorial](tutorial/SpecModTutorial.ipynb)
|
|
49
|
+
: One event end to end — waveforms and picks in, source parameters out. Every
|
|
50
|
+
figure and number on the page is produced by running the notebook at build
|
|
51
|
+
time, so it cannot describe an API that no longer exists.
|
|
52
|
+
|
|
48
53
|
[Processing](processing.md)
|
|
49
54
|
: Every step of the pipeline with the equation it implements — what a window
|
|
50
55
|
is, how the noise is compared against it, and what the bandwidth selector
|
|
@@ -97,6 +102,7 @@ one either way.
|
|
|
97
102
|
:maxdepth: 2
|
|
98
103
|
:hidden:
|
|
99
104
|
|
|
105
|
+
tutorial/SpecModTutorial
|
|
100
106
|
processing
|
|
101
107
|
choosing-a-transform
|
|
102
108
|
pick-formats
|
|
@@ -102,15 +102,24 @@ What is left: `io.py` and `plotting.py` are still single modules, and the
|
|
|
102
102
|
operations that mutate in place need to return new objects instead. Neither is
|
|
103
103
|
large — the split is about responsibilities, not line count.
|
|
104
104
|
|
|
105
|
+
### The tutorial, executed
|
|
106
|
+
|
|
107
|
+
The tutorial is published as part of this site and **re-executed on every
|
|
108
|
+
build**, so every figure and number on the page came from running the code
|
|
109
|
+
being documented. A notebook that stops working fails the build rather than
|
|
110
|
+
going quietly stale, which is what it was listed as a 1.0 requirement for.
|
|
111
|
+
|
|
105
112
|
## Planned
|
|
106
113
|
|
|
107
114
|
### 1.0 — the API stops moving
|
|
108
115
|
|
|
109
|
-
|
|
110
|
-
explicitly,
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
116
|
+
Two things left: the theory page that states the normalisation and units
|
|
117
|
+
conventions explicitly, and a "what changed since 0.1" guide for anyone
|
|
118
|
+
upgrading. Then the 1.0 release, which is the promise that names and
|
|
119
|
+
signatures stop moving without a deprecation cycle.
|
|
120
|
+
|
|
121
|
+
The third — the tutorial rebuilt as an executed notebook, so it cannot rot
|
|
122
|
+
silently — is merged and sits under *In progress* above until it ships.
|
|
114
123
|
|
|
115
124
|
That promise is the whole content of the number, which is why it has to be a
|
|
116
125
|
decision rather than something a breaking commit does on its way past. Until
|