specmod 0.2.3__tar.gz → 0.4.0__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.3 → specmod-0.4.0}/.github/workflows/build.yml +7 -3
- {specmod-0.2.3 → specmod-0.4.0}/.github/workflows/docs.yml +7 -3
- {specmod-0.2.3 → specmod-0.4.0}/.github/workflows/release.yml +6 -2
- {specmod-0.2.3 → specmod-0.4.0}/.github/workflows/test.yml +31 -11
- {specmod-0.2.3 → specmod-0.4.0}/.pre-commit-config.yaml +9 -3
- specmod-0.4.0/.release-please-manifest.json +3 -0
- {specmod-0.2.3 → specmod-0.4.0}/CHANGELOG.md +59 -0
- {specmod-0.2.3 → specmod-0.4.0}/PKG-INFO +6 -5
- {specmod-0.2.3 → specmod-0.4.0}/README.md +3 -3
- {specmod-0.2.3 → specmod-0.4.0}/docs/REFACTOR_PLAN.md +100 -21
- specmod-0.4.0/docs/_builders/_notebook.py +162 -0
- specmod-0.2.3/docs/notebooks/_build_notebook.py → specmod-0.4.0/docs/_builders/choosing_a_transform.py +132 -103
- specmod-0.4.0/docs/_builders/specmod_tutorial.py +980 -0
- specmod-0.4.0/docs/_static/academic.css +70 -0
- specmod-0.4.0/docs/_static/fonts/OFL-fira-code.txt +93 -0
- specmod-0.4.0/docs/_static/fonts/OFL-merriweather.txt +93 -0
- specmod-0.4.0/docs/_static/fonts/OFL-open-sans.txt +88 -0
- specmod-0.4.0/docs/_static/fonts/README.md +7 -0
- specmod-0.4.0/docs/_static/fonts/fira-code-400-greek.woff2 +0 -0
- specmod-0.4.0/docs/_static/fonts/fira-code-400-latin-ext.woff2 +0 -0
- specmod-0.4.0/docs/_static/fonts/fira-code-400-latin.woff2 +0 -0
- specmod-0.4.0/docs/_static/fonts/merriweather-latin-ext.woff2 +0 -0
- specmod-0.4.0/docs/_static/fonts/merriweather-latin.woff2 +0 -0
- specmod-0.4.0/docs/_static/fonts/open-sans-greek.woff2 +0 -0
- specmod-0.4.0/docs/_static/fonts/open-sans-latin-ext.woff2 +0 -0
- specmod-0.4.0/docs/_static/fonts/open-sans-latin.woff2 +0 -0
- specmod-0.4.0/docs/_static/fonts.css +134 -0
- specmod-0.4.0/docs/_static/katex/LICENSE +21 -0
- specmod-0.4.0/docs/_static/katex/README.md +9 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- specmod-0.4.0/docs/_static/katex/katex.min.css +1 -0
- specmod-0.4.0/docs/_static/specmod-logo-academic-dark-mark.svg +340 -0
- specmod-0.4.0/docs/_static/specmod-logo-academic-dark.svg +333 -0
- specmod-0.4.0/docs/_static/specmod-logo-academic-mark.svg +340 -0
- specmod-0.4.0/docs/_static/specmod-logo-academic.svg +333 -0
- {specmod-0.2.3 → specmod-0.4.0}/docs/api.md +22 -9
- specmod-0.4.0/docs/branding.md +163 -0
- {specmod-0.2.3 → specmod-0.4.0}/docs/choosing-a-transform.md +84 -0
- {specmod-0.2.3 → specmod-0.4.0}/docs/conf.py +87 -25
- {specmod-0.2.3 → specmod-0.4.0}/docs/development.md +2 -1
- {specmod-0.2.3 → specmod-0.4.0}/docs/documentation.md +114 -1
- {specmod-0.2.3 → specmod-0.4.0}/docs/getting-started.md +3 -3
- {specmod-0.2.3 → specmod-0.4.0}/docs/index.md +2 -2
- {specmod-0.2.3 → specmod-0.4.0}/docs/notebooks/choosing-a-transform.ipynb +4 -4
- {specmod-0.2.3 → specmod-0.4.0}/docs/notes/api-audit.md +2 -2
- {specmod-0.2.3 → specmod-0.4.0}/docs/pick-formats.md +9 -8
- {specmod-0.2.3 → specmod-0.4.0}/docs/processing.md +44 -5
- {specmod-0.2.3 → specmod-0.4.0}/docs/roadmap.md +45 -16
- {specmod-0.2.3 → specmod-0.4.0}/docs/upgrading.md +106 -27
- {specmod-0.2.3 → specmod-0.4.0}/pyproject.toml +5 -1
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/api.py +6 -2
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/config/sections.py +55 -5
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/core/bandwidth.py +122 -4
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/core/collection.py +230 -29
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/core/noise.py +1 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/datasets.py +1 -1
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/distance.py +2 -2
- specmod-0.4.0/src/specmod/io/__init__.py +54 -0
- specmod-0.4.0/src/specmod/io/backend.py +28 -0
- specmod-0.4.0/src/specmod/io/hdf5.py +119 -0
- specmod-0.4.0/src/specmod/io/layout.py +85 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/pipeline.py +67 -1
- specmod-0.4.0/src/specmod/plotting/__init__.py +31 -0
- specmod-0.4.0/src/specmod/plotting/grid.py +60 -0
- specmod-0.2.3/src/specmod/plotting.py → specmod-0.4.0/src/specmod/plotting/pair.py +6 -78
- specmod-0.4.0/src/specmod/plotting/style.py +24 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/preprocess.py +160 -117
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/smoothing/__init__.py +19 -2
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/smoothing/base.py +16 -1
- specmod-0.4.0/src/specmod/smoothing/log_window.py +215 -0
- specmod-0.4.0/src/specmod/smoothing/savitzky_golay.py +127 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/transforms/__init__.py +16 -1
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/utils.py +2 -1
- {specmod-0.2.3 → specmod-0.4.0}/tests/conftest.py +5 -10
- {specmod-0.2.3 → specmod-0.4.0}/tests/golden/motion_reference.json +140 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/golden/pipeline_reference.json +140 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/golden/window_reference.json +140 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_api_surface.py +1 -3
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_collection.py +228 -4
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_config.py +141 -1
- specmod-0.4.0/tests/test_docs_are_current.py +152 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_end_to_end.py +3 -8
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_golden_reference.py +74 -9
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_io_and_plotting.py +8 -3
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_legacy_fixes.py +10 -10
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_pick_plugins.py +1 -1
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_picks.py +4 -4
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_pipeline.py +123 -1
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_preprocess.py +169 -74
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_release_config.py +88 -0
- specmod-0.4.0/tests/test_smoothing.py +431 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_staged.py +1 -1
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_stubs.py +2 -2
- specmod-0.4.0/tests/test_tools_track_the_api.py +125 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_tutorial.py +3 -1
- {specmod-0.2.3 → specmod-0.4.0}/tools/make_golden.py +34 -4
- specmod-0.4.0/tools/make_logo.py +158 -0
- {specmod-0.2.3 → specmod-0.4.0}/tools/measure_docs.py +107 -7
- specmod-0.4.0/tools/vendor_fonts.py +175 -0
- specmod-0.4.0/tools/vendor_katex.py +122 -0
- specmod-0.2.3/tutorial/SpecModTutorial.ipynb → specmod-0.4.0/tutorial/specmod-tutorial.ipynb +241 -54
- specmod-0.2.3/.release-please-manifest.json +0 -3
- specmod-0.2.3/src/specmod/io.py +0 -241
- specmod-0.2.3/tests/test_docs_are_current.py +0 -80
- specmod-0.2.3/tests/test_smoothing.py +0 -226
- {specmod-0.2.3 → specmod-0.4.0}/.git-blame-ignore-revs +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/.gitignore +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/.readthedocs.yaml +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/AGENTS.md +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/CITATION.cff +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/CLAUDE.md +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/CONTRIBUTING.md +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/LICENSE +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/datasets/magna_2020.toml +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/datasets/pnr_2019.toml +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/docs/contributing.md +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/docs/guides.md +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/docs/notes/window-position.md +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/docs/releasing-data.md +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/docs/releasing.md +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/release-please-config.json +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/requirements.txt +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/__init__.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/_vendor/__init__.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/_vendor/qiinv.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/acquire.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/cli.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/config/__init__.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/config/layers.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/config/provenance.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/config/serialize.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/core/__init__.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/core/scalogram.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/core/spectrum.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/core/units.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/exceptions.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/fitting/__init__.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/fitting/base.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/fitting/event.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/fitting/guess.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/fitting/spectrum.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/magnitude.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/picks/__init__.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/picks/base.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/picks/delimited.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/picks/events.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/picks/resolution.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/picks/snuffler.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/smoothing/konno_ohmachi.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/smoothing/log_bins.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/sources/__init__.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/sources/attenuation.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/sources/composite.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/sources/motion.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/sources/source.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/spreading.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/staged.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/tables.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/transforms/base.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/transforms/cwt.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/transforms/fft.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/transforms/multitaper.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/transforms/prieto.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/src/specmod/transforms/quadratic.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/README.md +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/lmfit/__init__.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/lmfit/model.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/lmfit/parameter.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/obspy/__init__.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/obspy/clients/__init__.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/obspy/clients/fdsn/__init__.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/obspy/core/__init__.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/obspy/core/event.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/obspy/core/inventory.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/obspy/core/stream.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/obspy/core/trace.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/obspy/core/utcdatetime.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/obspy/core/util/__init__.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/obspy/core/util/base.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/obspy/geodetics/__init__.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/obspy/signal/__init__.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/stubs/obspy/signal/konnoohmachismoothing.pyi +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/studies/magna_2020_paper.toml +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/__init__.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_acquire.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_ambient_state.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_cwt.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_datasets.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_fitting_defaults.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_import.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_magnitude.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_make_golden.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_pick_readers.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_pipeline_smoke.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_prieto.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_quadratic.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_sources.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_spectral_wiring.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_transforms.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_typing_backlog.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_utils.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tests/test_versioning.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tools/check_built_version.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tools/check_floors.py +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/picks/2019-08-26T07:30:47.000000Z.picks +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/picks/2019-08-26T07:30:47.000000Z.xml +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/stations/inventory.xml +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L001..HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L001..HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L001..HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L002..HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L002..HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L002..HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L006..HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L006..HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L006..HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L007..HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L007..HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L007..HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L008..HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L008..HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L008..HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L009..HHE_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L009..HHN_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.L009..HHZ_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.LD06..HH1_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.LD06..HH2_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/LV.LD06..HH3_2019-08-26T07:30:47.000000Z +0 -0
- {specmod-0.2.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/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.3 → specmod-0.4.0}/tutorial/data/events/2019-08-26T07:30:47.000000Z/waveforms/UR.AQ10.00.HHZ_2019-08-26T07:30:47.000000Z +0 -0
|
@@ -10,10 +10,14 @@ jobs:
|
|
|
10
10
|
build:
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
steps:
|
|
13
|
-
- uses: actions/checkout@
|
|
13
|
+
- uses: actions/checkout@v7
|
|
14
14
|
with:
|
|
15
15
|
fetch-depth: 0 # hatch-vcs derives the version from tags
|
|
16
|
-
|
|
16
|
+
# Pinned to a full version, unlike the other three. `astral-sh/setup-uv`
|
|
17
|
+
# publishes no bare major tag — `@v10` does not resolve, and using it
|
|
18
|
+
# fails every job at "Getting action download info", before a step runs.
|
|
19
|
+
# Bump this deliberately; do not "tidy" it to `@v10`.
|
|
20
|
+
- uses: astral-sh/setup-uv@v10.0.1
|
|
17
21
|
- run: uv python install 3.11
|
|
18
22
|
|
|
19
23
|
- name: Build sdist and wheel
|
|
@@ -34,7 +38,7 @@ jobs:
|
|
|
34
38
|
print('specmod', specmod.__version__, '- wheel imports cleanly')
|
|
35
39
|
"
|
|
36
40
|
|
|
37
|
-
- uses: actions/upload-artifact@
|
|
41
|
+
- uses: actions/upload-artifact@v7
|
|
38
42
|
with:
|
|
39
43
|
name: dist
|
|
40
44
|
path: dist/
|
|
@@ -24,10 +24,14 @@ jobs:
|
|
|
24
24
|
docs:
|
|
25
25
|
runs-on: ubuntu-latest
|
|
26
26
|
steps:
|
|
27
|
-
- uses: actions/checkout@
|
|
27
|
+
- uses: actions/checkout@v7
|
|
28
28
|
with:
|
|
29
29
|
fetch-depth: 0 # hatch-vcs derives the version from tags
|
|
30
|
-
|
|
30
|
+
# Pinned to a full version, unlike the other three. `astral-sh/setup-uv`
|
|
31
|
+
# publishes no bare major tag — `@v10` does not resolve, and using it
|
|
32
|
+
# fails every job at "Getting action download info", before a step runs.
|
|
33
|
+
# Bump this deliberately; do not "tidy" it to `@v10`.
|
|
34
|
+
- uses: astral-sh/setup-uv@v10.0.1
|
|
31
35
|
- run: uv python install 3.11
|
|
32
36
|
- run: uv venv # create a venv to install into
|
|
33
37
|
|
|
@@ -50,7 +54,7 @@ jobs:
|
|
|
50
54
|
|
|
51
55
|
# Not a Pages artefact: this is a plain zip anyone can download from the
|
|
52
56
|
# run and open locally, and it stays useful if Read the Docs is down.
|
|
53
|
-
- uses: actions/upload-artifact@
|
|
57
|
+
- uses: actions/upload-artifact@v7
|
|
54
58
|
with:
|
|
55
59
|
name: docs-html
|
|
56
60
|
path: docs/_build/html
|
|
@@ -77,7 +77,7 @@ jobs:
|
|
|
77
77
|
id-token: write # mandatory for Trusted Publishing
|
|
78
78
|
contents: read
|
|
79
79
|
steps:
|
|
80
|
-
- uses: actions/checkout@
|
|
80
|
+
- uses: actions/checkout@v7
|
|
81
81
|
with:
|
|
82
82
|
# The tag, not the branch. main has already moved on by one commit
|
|
83
83
|
# (the release PR merge), and hatch-vcs would derive a .postN.devN
|
|
@@ -85,7 +85,11 @@ jobs:
|
|
|
85
85
|
ref: ${{ needs.release-please.outputs.tag_name }}
|
|
86
86
|
fetch-depth: 0 # hatch-vcs derives the version by describing tags
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
# Pinned to a full version, unlike the other three. `astral-sh/setup-uv`
|
|
89
|
+
# publishes no bare major tag — `@v10` does not resolve, and using it
|
|
90
|
+
# fails every job at "Getting action download info", before a step runs.
|
|
91
|
+
# Bump this deliberately; do not "tidy" it to `@v10`.
|
|
92
|
+
- uses: astral-sh/setup-uv@v10.0.1
|
|
89
93
|
- run: uv python install 3.11
|
|
90
94
|
- run: uv build
|
|
91
95
|
|
|
@@ -14,8 +14,12 @@ jobs:
|
|
|
14
14
|
lint:
|
|
15
15
|
runs-on: ubuntu-latest
|
|
16
16
|
steps:
|
|
17
|
-
- uses: actions/checkout@
|
|
18
|
-
|
|
17
|
+
- uses: actions/checkout@v7
|
|
18
|
+
# Pinned to a full version, unlike the other three. `astral-sh/setup-uv`
|
|
19
|
+
# publishes no bare major tag — `@v10` does not resolve, and using it
|
|
20
|
+
# fails every job at "Getting action download info", before a step runs.
|
|
21
|
+
# Bump this deliberately; do not "tidy" it to `@v10`.
|
|
22
|
+
- uses: astral-sh/setup-uv@v10.0.1
|
|
19
23
|
with:
|
|
20
24
|
enable-cache: true
|
|
21
25
|
- run: uv python install 3.11
|
|
@@ -28,10 +32,14 @@ jobs:
|
|
|
28
32
|
typecheck:
|
|
29
33
|
runs-on: ubuntu-latest
|
|
30
34
|
steps:
|
|
31
|
-
- uses: actions/checkout@
|
|
35
|
+
- uses: actions/checkout@v7
|
|
32
36
|
with:
|
|
33
37
|
fetch-depth: 0 # hatch-vcs needs history to derive the version
|
|
34
|
-
|
|
38
|
+
# Pinned to a full version, unlike the other three. `astral-sh/setup-uv`
|
|
39
|
+
# publishes no bare major tag — `@v10` does not resolve, and using it
|
|
40
|
+
# fails every job at "Getting action download info", before a step runs.
|
|
41
|
+
# Bump this deliberately; do not "tidy" it to `@v10`.
|
|
42
|
+
- uses: astral-sh/setup-uv@v10.0.1
|
|
35
43
|
with:
|
|
36
44
|
enable-cache: true
|
|
37
45
|
- run: uv python install 3.11
|
|
@@ -48,10 +56,14 @@ jobs:
|
|
|
48
56
|
os: [ubuntu-latest, macos-latest]
|
|
49
57
|
python-version: ["3.11", "3.12", "3.13"]
|
|
50
58
|
steps:
|
|
51
|
-
- uses: actions/checkout@
|
|
59
|
+
- uses: actions/checkout@v7
|
|
52
60
|
with:
|
|
53
61
|
fetch-depth: 0
|
|
54
|
-
|
|
62
|
+
# Pinned to a full version, unlike the other three. `astral-sh/setup-uv`
|
|
63
|
+
# publishes no bare major tag — `@v10` does not resolve, and using it
|
|
64
|
+
# fails every job at "Getting action download info", before a step runs.
|
|
65
|
+
# Bump this deliberately; do not "tidy" it to `@v10`.
|
|
66
|
+
- uses: astral-sh/setup-uv@v10.0.1
|
|
55
67
|
with:
|
|
56
68
|
enable-cache: true
|
|
57
69
|
- run: uv python install ${{ matrix.python-version }}
|
|
@@ -64,7 +76,7 @@ jobs:
|
|
|
64
76
|
# execution is excluded because it costs ~40s and a Jupyter kernel, and
|
|
65
77
|
# is worth paying once rather than six times — see the notebook job.
|
|
66
78
|
run: uv run pytest -m "not dataset and not notebook" --cov=specmod --cov-report=xml --cov-report=term
|
|
67
|
-
- uses: codecov/codecov-action@
|
|
79
|
+
- uses: codecov/codecov-action@v7
|
|
68
80
|
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
|
|
69
81
|
with:
|
|
70
82
|
files: coverage.xml
|
|
@@ -73,10 +85,14 @@ jobs:
|
|
|
73
85
|
floors:
|
|
74
86
|
runs-on: ubuntu-latest
|
|
75
87
|
steps:
|
|
76
|
-
- uses: actions/checkout@
|
|
88
|
+
- uses: actions/checkout@v7
|
|
77
89
|
with:
|
|
78
90
|
fetch-depth: 0
|
|
79
|
-
|
|
91
|
+
# Pinned to a full version, unlike the other three. `astral-sh/setup-uv`
|
|
92
|
+
# publishes no bare major tag — `@v10` does not resolve, and using it
|
|
93
|
+
# fails every job at "Getting action download info", before a step runs.
|
|
94
|
+
# Bump this deliberately; do not "tidy" it to `@v10`.
|
|
95
|
+
- uses: astral-sh/setup-uv@v10.0.1
|
|
80
96
|
- run: uv python install 3.11
|
|
81
97
|
- run: uv venv
|
|
82
98
|
# Exercise the declared minimums. CI otherwise installs the newest of
|
|
@@ -92,10 +108,14 @@ jobs:
|
|
|
92
108
|
# third kind, so it runs per-PR rather than at release.
|
|
93
109
|
runs-on: ubuntu-latest
|
|
94
110
|
steps:
|
|
95
|
-
- uses: actions/checkout@
|
|
111
|
+
- uses: actions/checkout@v7
|
|
96
112
|
with:
|
|
97
113
|
fetch-depth: 0
|
|
98
|
-
|
|
114
|
+
# Pinned to a full version, unlike the other three. `astral-sh/setup-uv`
|
|
115
|
+
# publishes no bare major tag — `@v10` does not resolve, and using it
|
|
116
|
+
# fails every job at "Getting action download info", before a step runs.
|
|
117
|
+
# Bump this deliberately; do not "tidy" it to `@v10`.
|
|
118
|
+
- uses: astral-sh/setup-uv@v10.0.1
|
|
99
119
|
with:
|
|
100
120
|
enable-cache: true
|
|
101
121
|
- run: uv python install 3.11
|
|
@@ -36,12 +36,18 @@ repos:
|
|
|
36
36
|
# running the hooks over one silently stripped six bytes from the middle
|
|
37
37
|
# of it — a corrupted pickle that still looks like a plausible diff.
|
|
38
38
|
# Anything binary has to be excluded by hand; the hooks do not detect it.
|
|
39
|
+
#
|
|
40
|
+
# The two vendored directories under `docs/_static/` are excluded for
|
|
41
|
+
# both reasons at once. Their `.woff2` files are binary, and the licences
|
|
42
|
+
# beside them have to stay byte identical to what upstream publishes —
|
|
43
|
+
# `trailing-whitespace` edited Merriweather's OFL the first time it was
|
|
44
|
+
# staged, which is a licence rewritten to satisfy a linter.
|
|
39
45
|
- id: end-of-file-fixer
|
|
40
|
-
exclude: '\.spec
|
|
46
|
+
exclude: &verbatim '(\.spec$|^docs/_static/(fonts|katex)/)'
|
|
41
47
|
- id: trailing-whitespace
|
|
42
|
-
exclude:
|
|
48
|
+
exclude: *verbatim
|
|
43
49
|
- id: mixed-line-ending
|
|
44
|
-
exclude:
|
|
50
|
+
exclude: *verbatim
|
|
45
51
|
|
|
46
52
|
- repo: https://github.com/kynan/nbstripout
|
|
47
53
|
rev: 0.8.1
|
|
@@ -9,6 +9,65 @@ 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.4.0](https://github.com/sgjholt/SpecMod/compare/v0.3.0...v0.4.0) (2026-09-16)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **smoothing:** wire [smoothing] method up, and add three more methods ([fff3ab1](https://github.com/sgjholt/SpecMod/commit/fff3ab1ef01a7f4d942fd776821d0418a0642a55))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* **config:** refuse a [smoothing] method the pipeline does not apply ([1f18c68](https://github.com/sgjholt/SpecMod/commit/1f18c68a71794c2b1612a7cf0feedcfef39b625b))
|
|
23
|
+
* **test:** compare the roadmap against the published minor, not the proposed one ([1e34b4e](https://github.com/sgjholt/SpecMod/commit/1e34b4e5ab2bdef5d65f6fc0d620a42b9c3891eb))
|
|
24
|
+
* **tools:** call the preprocess API that 0.3.0 left behind ([8501c8e](https://github.com/sgjholt/SpecMod/commit/8501c8ed618e5d652b9eeffc36893115a58fd7d5))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
### Documentation
|
|
28
|
+
|
|
29
|
+
* keep the reasoning out of the docstrings, in comments where it belongs ([2684ec9](https://github.com/sgjholt/SpecMod/commit/2684ec923c8dcf59e882b2d11e9dc11ccbcf3766))
|
|
30
|
+
* say what tagging the frozen commit does and does not trigger ([2273219](https://github.com/sgjholt/SpecMod/commit/2273219e2a78ac1c1562118c2a1b3bce4df597dd))
|
|
31
|
+
* state what the smoothers are, not how they were arrived at ([4c97491](https://github.com/sgjholt/SpecMod/commit/4c97491d50aba5a1468304072ab3c6ed2904f2e0))
|
|
32
|
+
* the 0.3.0 work shipped a week ago, so stop calling it unreleased ([e2aaced](https://github.com/sgjholt/SpecMod/commit/e2aaced546a247b2c5967f01586c19928bcfe297))
|
|
33
|
+
* v0.1.1 is master's tip, which is what freezing it was for ([db50972](https://github.com/sgjholt/SpecMod/commit/db509729f3b7877a20b5691dddec8a6e139fb466))
|
|
34
|
+
|
|
35
|
+
## [0.3.0](https://github.com/sgjholt/SpecMod/compare/v0.2.3...v0.3.0) (2026-09-06)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
### ⚠ BREAKING CHANGES
|
|
39
|
+
|
|
40
|
+
* the tutorial page moves from `/tutorial/SpecModTutorial.html` to `/tutorial/specmod-tutorial.html`.
|
|
41
|
+
* the ten mutating functions in `specmod.preprocess` are renamed and now return a new stream or trace. `get_signal` is removed, and the two undated deprecation shims are gone.
|
|
42
|
+
|
|
43
|
+
### Features
|
|
44
|
+
|
|
45
|
+
* let the fitted band be capped, fixed or corrected by hand ([ba241a9](https://github.com/sgjholt/SpecMod/commit/ba241a95d94a298418b3c6f414a0026b9f310926))
|
|
46
|
+
* preprocess returns new streams instead of mutating ([78aabeb](https://github.com/sgjholt/SpecMod/commit/78aabeb4856eda4208787fcd53b0df77bc50bd1c))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
### Bug Fixes
|
|
50
|
+
|
|
51
|
+
* give the noise and bandwidth registries a documented home ([daeb2cc](https://github.com/sgjholt/SpecMod/commit/daeb2cc43eff2869e9617e4111f281f9bd4d33bb))
|
|
52
|
+
* **transforms:** re-export every public name from base ([67c24c3](https://github.com/sgjholt/SpecMod/commit/67c24c3dda80f7fbc1bd51861861bde48d943eac))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
### Code Refactoring
|
|
56
|
+
|
|
57
|
+
* **docs:** build the tutorial from a script too ([de846c6](https://github.com/sgjholt/SpecMod/commit/de846c6128fc7922df8e1e3c2c1c01f2b8bf95bb))
|
|
58
|
+
* **docs:** one notebook builder per notebook, named after it ([0175f89](https://github.com/sgjholt/SpecMod/commit/0175f890f5f92668341a17bece7149f7d8f8c6b7))
|
|
59
|
+
* split io and plotting into packages ([027b77f](https://github.com/sgjholt/SpecMod/commit/027b77f7d050716b7d98fc873a8a4e93098d1d68))
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
### Documentation
|
|
63
|
+
|
|
64
|
+
* adopt the academic theme from the branding manual ([76f0aa0](https://github.com/sgjholt/SpecMod/commit/76f0aa0a40a134eeb91b8ada04c8f5fa66243c54))
|
|
65
|
+
* kebab-case the tutorial notebook, snake_case its builder ([5a65b73](https://github.com/sgjholt/SpecMod/commit/5a65b7336980bf5d7163c4cad28e7c273715c0a3))
|
|
66
|
+
* measure the MathJax figure instead of asserting it ([cba7e01](https://github.com/sgjholt/SpecMod/commit/cba7e0116a09ba8d4565308ee8c0227d138b20cd))
|
|
67
|
+
* render maths with KaTeX, served from this site ([902d3fe](https://github.com/sgjholt/SpecMod/commit/902d3fec4230e6af17ea1b7a9d32d9e9c153fd8e))
|
|
68
|
+
* self-host the branding fonts ([c1e6f9f](https://github.com/sgjholt/SpecMod/commit/c1e6f9fe16f4ec48c5e788e6b29181c5ffc01bbf))
|
|
69
|
+
* the decomposition is finished ([bbb2b71](https://github.com/sgjholt/SpecMod/commit/bbb2b7189b9f98c3baa48fe907bc2c414455f5d9))
|
|
70
|
+
|
|
12
71
|
## [0.2.3](https://github.com/sgjholt/SpecMod/compare/v0.2.2...v0.2.3) (2026-09-05)
|
|
13
72
|
|
|
14
73
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: specmod
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
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
|
|
@@ -35,11 +35,12 @@ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
|
35
35
|
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
36
36
|
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
37
37
|
Provides-Extra: docs
|
|
38
|
+
Requires-Dist: furo>=2024.1; extra == 'docs'
|
|
38
39
|
Requires-Dist: myst-nb>=1.1; extra == 'docs'
|
|
39
40
|
Requires-Dist: myst-parser>=3.0; extra == 'docs'
|
|
40
|
-
Requires-Dist: pydata-sphinx-theme>=0.15; extra == 'docs'
|
|
41
41
|
Requires-Dist: sphinx-togglebutton>=0.3; extra == 'docs'
|
|
42
42
|
Requires-Dist: sphinx>=7.3; extra == 'docs'
|
|
43
|
+
Requires-Dist: sphinxcontrib-katex>=0.9; extra == 'docs'
|
|
43
44
|
Provides-Extra: io
|
|
44
45
|
Requires-Dist: h5py>=3.11; extra == 'io'
|
|
45
46
|
Requires-Dist: pyarrow>=16.0; extra == 'io'
|
|
@@ -179,13 +180,13 @@ changes nothing else.
|
|
|
179
180
|
|
|
180
181
|
## Reading picks
|
|
181
182
|
|
|
182
|
-
|
|
183
|
-
the file rather than from its name:
|
|
183
|
+
`with_picks` returns a stream with arrivals attached, detecting the format
|
|
184
|
+
from the file rather than from its name:
|
|
184
185
|
|
|
185
186
|
```python
|
|
186
187
|
import specmod.preprocess as pre
|
|
187
188
|
|
|
188
|
-
pre.
|
|
189
|
+
stream = pre.with_picks(stream, "event.xml")
|
|
189
190
|
```
|
|
190
191
|
|
|
191
192
|
Everything `obspy.read_events` parses is read through one delegate — QuakeML,
|
|
@@ -122,13 +122,13 @@ changes nothing else.
|
|
|
122
122
|
|
|
123
123
|
## Reading picks
|
|
124
124
|
|
|
125
|
-
|
|
126
|
-
the file rather than from its name:
|
|
125
|
+
`with_picks` returns a stream with arrivals attached, detecting the format
|
|
126
|
+
from the file rather than from its name:
|
|
127
127
|
|
|
128
128
|
```python
|
|
129
129
|
import specmod.preprocess as pre
|
|
130
130
|
|
|
131
|
-
pre.
|
|
131
|
+
stream = pre.with_picks(stream, "event.xml")
|
|
132
132
|
```
|
|
133
133
|
|
|
134
134
|
Everything `obspy.read_events` parses is read through one delegate — QuakeML,
|
|
@@ -1087,7 +1087,7 @@ and there are presumably more in your working directories.
|
|
|
1087
1087
|
Two ways out, and the first is much better:
|
|
1088
1088
|
|
|
1089
1089
|
1. **Convert in the old environment.** Phase 0 is already building a Docker image
|
|
1090
|
-
where the 0.1.
|
|
1090
|
+
where the 0.1.1 code runs (§6.7). Add a small
|
|
1091
1091
|
`scripts/convert_legacy_spec.py` to it that loads `.spec` files with the old
|
|
1092
1092
|
classes present and writes the new HDF5 format. This is a one-shot migration
|
|
1093
1093
|
with no lasting cost to the codebase.
|
|
@@ -2742,13 +2742,30 @@ Two further problems with reproducing the published run from this repository:
|
|
|
2742
2742
|
manuscript filename (`...SRL3`) suggests a third revision, which would also
|
|
2743
2743
|
explain a 2021 code state behind a 2020 access date.
|
|
2744
2744
|
|
|
2745
|
-
|
|
2745
|
+
The evidence narrows it: **the candidate is `ba3f7ec` or later, not the
|
|
2746
2746
|
pre-November-2020 commits**, because the earlier code cannot perform the
|
|
2747
2747
|
workflow the paper describes. Only `09f57b9` (removed cython) changes
|
|
2748
2748
|
`specmod/` after that, so the realistic candidates are `ba3f7ec` and
|
|
2749
|
-
`453c77c`.
|
|
2750
|
-
|
|
2751
|
-
|
|
2749
|
+
`453c77c`.
|
|
2750
|
+
|
|
2751
|
+
**Answered: `453c77c`** — the tip of `master`, 2021-08-12. On the author's
|
|
2752
|
+
word, and it is why `master` was frozen at that commit rather than at any
|
|
2753
|
+
other: the branch *is* the v0.1.1 record (§6.7). Which of the two the
|
|
2754
|
+
evidence above prefers was never the question it looked like.
|
|
2755
|
+
|
|
2756
|
+
What that settles and what it does not: the code is identified, so §5.2.6
|
|
2757
|
+
step 2 can be run against a known commit. The dating oddity is unchanged —
|
|
2758
|
+
the manuscript's access date still precedes the commit it cites, which the
|
|
2759
|
+
third revision (`...SRL3`) explains without needing the code to have moved.
|
|
2760
|
+
It is recorded rather than resolved, because nothing in the repository can
|
|
2761
|
+
resolve it.
|
|
2762
|
+
|
|
2763
|
+
This is still the strongest possible argument for tagging that commit (§6.7)
|
|
2764
|
+
and for `hatch-vcs` (§6.4): a version that takes a page of archaeology to
|
|
2765
|
+
identify must never happen again. **No `v0.1.1` tag exists yet.** Creating
|
|
2766
|
+
one is safe — `453c77c` is an ancestor of `main`, and every later release
|
|
2767
|
+
tag outranks it for `hatch-vcs`, so nothing derives a version from it — but
|
|
2768
|
+
it is repository state, not something a commit here can carry.
|
|
2752
2769
|
2. **The full published pipeline is not in this repository.** The two-stage
|
|
2753
2770
|
inversion (fit Ω/`f_c`/`t*` free, then fix event `f_c` to the
|
|
2754
2771
|
inverse-hypocentral-distance-weighted mean of station `f_c` and refit) and the
|
|
@@ -3414,6 +3431,31 @@ been audited once is worth more than one that reads confidently throughout.
|
|
|
3414
3431
|
| "`commitlint`-enforced" again, in §6.4 | The §7 instance was corrected and this one was left standing, in the same document. §6.4 corrected. |
|
|
3415
3432
|
| `publish.yml` "GitHub Release published → PyPI" | It would never have run. release-please creates the release with the default `GITHUB_TOKEN`, and events triggered by that token do not start a workflow. The publish job moved into `release.yml`, gated on `release_created`. §6.5 corrected. |
|
|
3416
3433
|
|
|
3434
|
+
**A fourth of the same shape, found later** — the three above were corrected in
|
|
3435
|
+
the prose; this one was a live setting:
|
|
3436
|
+
|
|
3437
|
+
> `[smoothing] method` — "Name -> smoother, for resolving `SmoothingConfig.method`"
|
|
3438
|
+
|
|
3439
|
+
`SMOOTHERS` existed, `method` validated against its `Literal`, and **no code
|
|
3440
|
+
anywhere read it**. The comparison binned with `log_bin` unconditionally.
|
|
3441
|
+
Measured on the 28 PNR windows, `log_bins`, `konno_ohmachi` and `none` produced
|
|
3442
|
+
bit-identical output — `none` included, which reads as "leave my spectra
|
|
3443
|
+
unsmoothed" while every spectrum went on being binned exactly as before.
|
|
3444
|
+
|
|
3445
|
+
**Fixed rather than documented.** `SpectrumPair.compare` now takes a `smoother`,
|
|
3446
|
+
`[smoothing] method` resolves to one, and the registry gained `log_window`
|
|
3447
|
+
(constant-relative-bandwidth smoothing with a selectable window shape, and a
|
|
3448
|
+
median option) and `savitzky_golay` beside the two that were there.
|
|
3449
|
+
`tests/test_config.py::TestEverySmoothingMethodIsWiredUp` and
|
|
3450
|
+
`tests/test_pipeline.py::TestTheConfiguredSmootherReachesTheComparison` are the
|
|
3451
|
+
mechanism the comment claimed: each accepted value resolves, carries its
|
|
3452
|
+
section's parameters, and survives the whole path on real windows.
|
|
3453
|
+
|
|
3454
|
+
`log_bins` stays `core.collection.log_bin` rather than `smoothing.LogBinner` —
|
|
3455
|
+
the two differ in clamping and in what `n_bins` counts, and the difference is
|
|
3456
|
+
every committed golden number. The default path is unchanged, which the golden
|
|
3457
|
+
suite asserts and which is why this could land without moving a number.
|
|
3458
|
+
|
|
3417
3459
|
**A claim whose mechanism is absent but whose property holds — for a different
|
|
3418
3460
|
reason, which matters:**
|
|
3419
3461
|
|
|
@@ -3460,7 +3502,8 @@ of §5.2, and the two-stage fit API of §5.2.5.
|
|
|
3460
3502
|
**`master` is frozen; `main` is the trunk.** `main` was branched from `master` at
|
|
3461
3503
|
`453c77c` and is where all refactor work lands. `master` is never committed to
|
|
3462
3504
|
again — it becomes the permanent, named record of the pre-refactor code, doing
|
|
3463
|
-
the job a `v0.1.
|
|
3505
|
+
the job a `v0.1.1` tag would have done. Its tip, `453c77c`, **is** the v0.1.1
|
|
3506
|
+
the Magna paper cites (§5.2.5, §8).
|
|
3464
3507
|
|
|
3465
3508
|
**Every pull request must target `sgjholt/SpecMod`, never `uofuseismo/SpecMod`.**
|
|
3466
3509
|
This is not a matter of care — it is a GitHub default working against you.
|
|
@@ -3498,7 +3541,7 @@ Two consequences worth acting on:
|
|
|
3498
3541
|
- [ ] Settings → Actions → confirm workflows are enabled
|
|
3499
3542
|
- [ ] Settings → Branches → protect `master` (no pushes, no deletion) so the
|
|
3500
3543
|
frozen record stays frozen
|
|
3501
|
-
- [ ] `git tag -a v0.1.
|
|
3544
|
+
- [ ] `git tag -a v0.1.1 453c77c -m "the version the Magna paper cites" && git push origin v0.1.1`
|
|
3502
3545
|
|
|
3503
3546
|
**No Claude session URLs in commit messages, PR bodies, or any other published
|
|
3504
3547
|
artifact.** The repository is public and those links are private session state. A
|
|
@@ -3516,12 +3559,20 @@ needed and neither can be made from a git client:
|
|
|
3516
3559
|
convention rather than a guarantee — one absent-minded `git push origin
|
|
3517
3560
|
master` and the record is gone.
|
|
3518
3561
|
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3562
|
+
Also tag `453c77c` as `v0.1.1` — no longer optional now that §8 records it as
|
|
3563
|
+
the commit the paper cites. A branch is discoverable and a tag is immutable,
|
|
3564
|
+
and a citation should resolve to the immutable one.
|
|
3565
|
+
|
|
3566
|
+
Tagging it publishes nothing. No workflow triggers on tags; the PyPI upload is
|
|
3567
|
+
gated on release-please's `release_created`, which only a merged release PR on
|
|
3568
|
+
`main` can set; and `git describe` takes the nearest tag, which is a release
|
|
3569
|
+
far ahead of this one. **Do not create a GitHub Release from the tag**, which
|
|
3570
|
+
is the one action that would publish: Zenodo listens to the release webhook and
|
|
3571
|
+
would mint a DOI for the pre-refactor code. The commit has no `pyproject.toml`
|
|
3572
|
+
and is not packageable.
|
|
3522
3573
|
|
|
3523
3574
|
> Note on tooling limits: tag pushes are blocked in the automation environment
|
|
3524
|
-
> this plan was written in (HTTP 403 on `push origin v0.1.
|
|
3575
|
+
> this plan was written in (HTTP 403 on `push origin v0.1.1`, while branch
|
|
3525
3576
|
> pushes to the same remote succeed), which is why `main` exists as a branch
|
|
3526
3577
|
> rather than the state being pinned by a tag. **This does not affect the release
|
|
3527
3578
|
> automation in §6.4** — release-please creates tags from inside GitHub Actions
|
|
@@ -3531,10 +3582,10 @@ The two are complementary — the tag is immutable, the branch is discoverable.
|
|
|
3531
3582
|
|
|
3532
3583
|
Worth being precise about what any of this does and does not preserve: it
|
|
3533
3584
|
preserves the **code**, but the code is not **runnable** — `mtspec` no longer
|
|
3534
|
-
builds on any current toolchain (§2.1). Reproducing a 0.1.
|
|
3585
|
+
builds on any current toolchain (§2.1). Reproducing a 0.1.1 result needs three
|
|
3535
3586
|
things, which is what Phase 0 delivers:
|
|
3536
3587
|
|
|
3537
|
-
1. `master` (and
|
|
3588
|
+
1. `master` (and the `v0.1.1` tag on its tip) — the source.
|
|
3538
3589
|
2. A `Dockerfile` pinning `gfortran`, `python 3.9`, `numpy<2` — the environment
|
|
3539
3590
|
that can still build `mtspec`. Also the only place existing `.spec` pickles
|
|
3540
3591
|
can be read (§4.6).
|
|
@@ -3565,13 +3616,13 @@ Each phase ends green on CI and is independently mergeable.
|
|
|
3565
3616
|
|
|
3566
3617
|
| Phase | Work | Depends on | Rough size |
|
|
3567
3618
|
|---|---|---|---|
|
|
3568
|
-
| **0. Safety net** | Freeze `master`, default branch → `main`, optional `v0.1.
|
|
3619
|
+
| **0. Safety net** | Freeze `master`, default branch → `main`, optional `v0.1.1` tag (§6.7); reproducible legacy env (`Dockerfile`: gfortran + ObsPy 1.2.0 / SciPy 1.4.1 / NumPy 1.18 / pandas 1.0.0 (§5.2.6)); write `datasets/magna_2020.toml` and a first cut of `specmod.acquire`, publish the artifact as a `data-v1` release asset (§5.2); capture golden outputs for PNR **and** Magna; reproduce Table S2 / Figure 2 with 0.1.1 (§5.2.6 step 2); convert any `.spec` files (§4.6) | — | 1.5–2 days |
|
|
3569
3620
|
| **1. Make it installable** | `pyproject.toml` + hatch-vcs, `src/` layout, `__init__.py`; ruff config, one-shot `ruff format` + `.git-blame-ignore-revs`, module renames to snake_case; mypy skeleton; pre-commit; `test`/`build` CI; `.gitignore`, `CITATION.cff`; fix the three hard breakages (§1) and the four `F821` bugs ruff finds (§2.5); delete `Tests/Tutorial/`, strip notebook outputs, subset the inventory (§5.1) | 0 | 3–4 days |
|
|
3570
3621
|
| **2. De-globalise** | `config/` package per §4.8 — semantic groups, layer resolution, `config show`/`freeze`, provenance stamping; remove all module-level config reads (tracked by `PLW0603`); `Motion`/`AmplitudeKind` enums; `Spectrum` as a frozen dataclass with `duration`; mutable class attrs (`RUF012`); `isinstance` checks; `logging`. **Tag `v0.2.0`** | 1 | 3–4 days |
|
|
3571
3622
|
| **2b. Release plumbing** ✅ | ~~Sphinx skeleton + `pydata-sphinx-theme` + autodoc/napoleon/intersphinx~~ ✅; ~~`docs.yml` → a published site~~ ✅ — Read the Docs rather than GH Pages, for versions (§6.3); ~~release-please + PyPI Trusted Publishing~~ ✅ — one `release.yml`, not two workflows (§6.5); ~~Zenodo webhook~~ ✅ documented. Five repository settings have to be turned on by hand: `docs/releasing.md` lists them. The `ci/` mirror that staged workflow files for hand-copying is gone — it existed because an agent token could not push `.github/workflows/`, and that permission is now granted. Parallel with 2 | 1 | 1–2 days |
|
|
3572
3623
|
| **3. Transform layer** | `SpectralEstimator` protocol; `FFTEstimator`, `WelchEstimator`, `MultitaperEstimator`; `smoothing/` incl. Konno–Ohmachi and `LogBinner`; mtspec demoted to optional legacy backend; Tier 1 + Tier 2 tests; theory docs page | 2 | 5–7 days |
|
|
3573
3624
|
| **4. CWT** | `CWTEstimator` + `Scalogram`; COI handling; the Parseval/units calibration and its test; `time_average()`; `ScalogramQC` + the four QC checks; COI floor into `BandwidthSelector`; scalogram plotting; HDF5 scalogram storage | 3 | 6–8 days |
|
|
3574
|
-
| **5. Decompose** | Split `Spectral.py` (655 lines) into `core/` + `snr/` ✅; ~~`Fitting.py` → `fitting/`~~ ✅ — `base`/`guess`/`spectrum`/`event`, 745 lines to four modules of 30–300, public names unchanged; models as objects ✅;
|
|
3625
|
+
| **5. Decompose** ✅ | Split `Spectral.py` (655 lines) into `core/` + `snr/` ✅; ~~`Fitting.py` → `fitting/`~~ ✅ — `base`/`guess`/`spectrum`/`event`, 745 lines to four modules of 30–300, public names unchanged; models as objects ✅; ~~`io/`~~ ✅ — `layout`/`hdf5`/`backend`; ~~`viz/`~~ ✅ — shipped as `plotting/`, `pair`/`grid`/`style`; ~~non-mutating operations~~ ✅ — `preprocess` was the last holdout, and the ten functions were renamed rather than only re-signatured so the break is loud; mypy override list → empty ✅; `picks/` per §4.9 ✅ | 3 | 4–6 days |
|
|
3575
3626
|
| **6. Ship** | Full docs content, tutorial rewritten as an executed `myst-nb` page with no `os.chdir`, 0.1→1.0 "what changed" page, **1.0 release** | 4, 5 | 2–3 days |
|
|
3576
3627
|
|
|
3577
3628
|
**Executing the tutorial was pulled forward out of Phase 6.** The `myst-nb`
|
|
@@ -3658,20 +3709,48 @@ changes anything shipped.
|
|
|
3658
3709
|
### Still open
|
|
3659
3710
|
|
|
3660
3711
|
1. **Default estimator.** Multitaper (matching current behaviour) or FFT +
|
|
3661
|
-
Konno–Ohmachi (
|
|
3712
|
+
Konno–Ohmachi (more conventional in engineering seismology)? **No longer
|
|
3713
|
+
blocked** — §6.6's dead `[smoothing] method` is wired up, so the second
|
|
3714
|
+
option is selectable — and now measured, on the 28 PNR windows with each
|
|
3715
|
+
station fitted freely:
|
|
3716
|
+
|
|
3717
|
+
| Against the shipped multitaper + `log_bins` | Median ΔMw | Per-station range | `fc` ratio |
|
|
3718
|
+
|---|---|---|---|
|
|
3719
|
+
| `fft` + `log_bins` | −0.039 | −0.85 to +1.90 | 0.003 to 5.0 |
|
|
3720
|
+
| `fft` + `konno_ohmachi` | +0.027 | −0.52 to +0.51 | 0.038 to 3.2 |
|
|
3721
|
+
|
|
3722
|
+
**The smoothing is what makes the switch defensible, not the estimator.**
|
|
3723
|
+
FFT with the shipped binner moves a station by up to 1.9 magnitude units,
|
|
3724
|
+
because `log_bins` reduces the axis without reducing the variance — 151 log
|
|
3725
|
+
bins over a few hundred Fourier samples is roughly one sample per bin.
|
|
3726
|
+
Pairing it with a real smoother halves the worst excursion and pulls the
|
|
3727
|
+
`fc` range in by a third. The median station barely moves either way.
|
|
3728
|
+
|
|
3729
|
+
What this event cannot settle: the *event* corner is unconstrained under all
|
|
3730
|
+
three (stage-one spread 895% to 1042% of the event value), so the ensemble
|
|
3731
|
+
number is not evidence. Deciding on the ensemble needs an event where it is
|
|
3732
|
+
constrained.
|
|
3733
|
+
|
|
3734
|
+
Speed, measured rather than assumed and far too small to decide on: the
|
|
3735
|
+
transform is 0.209 s against 0.323 s for the 28 windows, and the smoothing
|
|
3736
|
+
adds 0.14 s (`log_bins`) to 0.83 s (`konno_ohmachi`) on top.
|
|
3737
|
+
|
|
3662
3738
|
2. **Python floor.** 3.11 is proposed. Any users stuck on 3.9/3.10?
|
|
3663
3739
|
3. **History rewrite.** Deleting the 9.9 MB catalog and stripping the notebook
|
|
3664
3740
|
(§5.1) shrinks the *working tree* but leaves both in history, so a fresh clone
|
|
3665
3741
|
still pulls ~15 MiB. Rewriting history with `git-filter-repo` would recover it
|
|
3666
3742
|
— but it rewrites every SHA, which moves what `master` and `main` currently
|
|
3667
|
-
point at and invalidates any `v0.1.
|
|
3743
|
+
point at and invalidates any `v0.1.1` tag. Given the end state is a ~1 MB repo
|
|
3668
3744
|
either way, **the recommendation is to leave history alone**: a one-time 15 MiB
|
|
3669
3745
|
clone is a much smaller cost than an unrecoverable pre-refactor record. Only
|
|
3670
3746
|
worth revisiting if the history genuinely becomes a burden.
|
|
3671
|
-
4.
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3747
|
+
4. ~~**Which commit is "v0.1.1"?**~~ **Resolved: `453c77c`**, the tip of
|
|
3748
|
+
`master`, 2021-08-12 — which is what freezing `master` at that commit was
|
|
3749
|
+
for (§6.7). The archaeology in §5.2.5 narrowed it to two candidates and
|
|
3750
|
+
could not choose between them; the answer did not come from the repository
|
|
3751
|
+
and was never going to. §5.2.6 step 2 now has a known commit to run. No
|
|
3752
|
+
`v0.1.1` tag exists yet, and creating one is repository state rather than
|
|
3753
|
+
something a commit can carry.
|
|
3675
3754
|
5. ~~**Was noise rotation on for the published run?**~~ **Assumed on.** Not
|
|
3676
3755
|
recalled, so `studies/magna_2020_paper.toml` starts from the shipped values —
|
|
3677
3756
|
`ROTATE_NOISE = true`, `ROT_METHOD = 2`, `ROT_PARS = {inc = 0.05, space =
|