From e462f7ccece57fc342a173654ef9e09a0a21c02c Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Sat, 4 Jul 2026 05:38:54 +0200 Subject: [PATCH 01/22] Prototype great-docs documentation build Replace the custom doc-build pipeline (scripts/build_api_docs.py and friends) with a great-docs configuration: - Add great-docs.yml: curated, task-grouped API reference, sections, excludes, and bibliography wiring - Move narrative docs to top-level section dirs (tutorial, recipes, notes, contributing, about) so site paths are unchanged; move docs/_static to assets/ - Port the landing page to a root index.qmd - Add a curated AI agent skill (skills/dascore/SKILL.md) published at /.well-known/agent-skills by the build - Rewrite alias-path and module cross-links to canonical documented paths in narrative docs and docstrings - Fix docstring links that used docs/ path prefixes - Update the contributing documentation build instructions - Add a proposed CI workflow sketch The old build system is intentionally left in place for side-by-side comparison. --- .github/workflows/build_docs_greatdocs.yaml | 55 +++ .gitignore | 1 + {docs => about}/acknowledgements.qmd | 0 {docs => about}/contributors.qmd | 0 {docs => about}/supported_formats.qmd | 0 {docs/_static => assets}/diataxis.png | Bin {docs/_static => assets}/logo.png | Bin {docs/_static => assets}/logo.svg | 0 {docs/_static => assets}/patch_n_spool.png | Bin .../adding_test_data.qmd | 0 .../code_of_conduct.qmd | 0 .../contributing.qmd | 0 .../dev_install.qmd | 0 .../documentation.qmd | 20 +- .../extending_dascore.qmd | 0 .../general_guidelines.qmd | 0 .../new_format.qmd | 0 .../profiling_benchmarks.qmd | 0 .../publish_a_new_release.qmd | 0 .../style_and_linting.qmd | 0 .../contributing => contributing}/testing.qmd | 0 dascore/core/coordmanager.py | 2 +- dascore/proc/correlate.py | 4 +- dascore/proc/filter.py | 2 +- dascore/proc/hampel.py | 2 +- dascore/proc/resample.py | 2 +- dascore/proc/whiten.py | 2 +- dascore/transform/fourier.py | 2 +- dascore/transform/integrate.py | 2 +- dascore/transform/strain.py | 4 +- dascore/utils/patch.py | 4 +- great-docs.yml | 334 ++++++++++++++++++ index.qmd | 152 ++++++++ .../notes => notes}/coordinate_internals.qmd | 0 {docs/notes => notes}/dft_notes.qmd | 0 {docs/notes => notes}/doc_strategy.qmd | 2 +- {docs/notes => notes}/notes.qmd | 0 {docs/notes => notes}/patch_attrs.qmd | 2 +- {docs/notes => notes}/spool_chunking.qmd | 0 {docs/notes => notes}/spool_index.qmd | 0 {docs/notes => notes}/spool_selection.qmd | 0 .../velocity_to_strain_rate.qmd | 4 +- .../add_spatial_coordinates_to_patch.qmd | 0 .../contributing_to_documentation.qmd | 0 {docs/recipes => recipes}/correlate.qmd | 0 {docs/recipes => recipes}/despiking.qmd | 2 +- {docs/recipes => recipes}/docker_basic.qmd | 0 {docs/recipes => recipes}/edge_effects.qmd | 0 .../external_conversion.qmd | 0 {docs/recipes => recipes}/fk.qmd | 4 +- .../recipes => recipes}/how_to_contribute.qmd | 0 {docs/recipes => recipes}/low_freq_proc.qmd | 0 {docs/recipes => recipes}/overview.qmd | 0 {docs/recipes => recipes}/parallelization.qmd | 0 .../plotting_channel_number.qmd | 0 {docs/recipes => recipes}/real_time_proc.qmd | 0 {docs/recipes => recipes}/smoothing.qmd | 16 +- skills/dascore/SKILL.md | 95 +++++ {docs/tutorial => tutorial}/concepts.qmd | 2 +- {docs/tutorial => tutorial}/configuration.qmd | 0 {docs/tutorial => tutorial}/coords.qmd | 0 {docs/tutorial => tutorial}/file_io.qmd | 0 {docs/tutorial => tutorial}/patch.qmd | 22 +- {docs/tutorial => tutorial}/processing.qmd | 18 +- .../tutorial => tutorial}/remote_patches.qmd | 0 {docs/tutorial => tutorial}/spool.qmd | 0 .../tutorial => tutorial}/transformations.qmd | 0 {docs/tutorial => tutorial}/visualization.qmd | 2 +- 68 files changed, 696 insertions(+), 61 deletions(-) create mode 100644 .github/workflows/build_docs_greatdocs.yaml rename {docs => about}/acknowledgements.qmd (100%) rename {docs => about}/contributors.qmd (100%) rename {docs => about}/supported_formats.qmd (100%) rename {docs/_static => assets}/diataxis.png (100%) rename {docs/_static => assets}/logo.png (100%) rename {docs/_static => assets}/logo.svg (100%) rename {docs/_static => assets}/patch_n_spool.png (100%) rename {docs/contributing => contributing}/adding_test_data.qmd (100%) rename {docs/contributing => contributing}/code_of_conduct.qmd (100%) rename {docs/contributing => contributing}/contributing.qmd (100%) rename {docs/contributing => contributing}/dev_install.qmd (100%) rename {docs/contributing => contributing}/documentation.qmd (88%) rename {docs/contributing => contributing}/extending_dascore.qmd (100%) rename {docs/contributing => contributing}/general_guidelines.qmd (100%) rename {docs/contributing => contributing}/new_format.qmd (100%) rename {docs/contributing => contributing}/profiling_benchmarks.qmd (100%) rename {docs/contributing => contributing}/publish_a_new_release.qmd (100%) rename {docs/contributing => contributing}/style_and_linting.qmd (100%) rename {docs/contributing => contributing}/testing.qmd (100%) create mode 100644 great-docs.yml create mode 100644 index.qmd rename {docs/notes => notes}/coordinate_internals.qmd (100%) rename {docs/notes => notes}/dft_notes.qmd (100%) rename {docs/notes => notes}/doc_strategy.qmd (97%) rename {docs/notes => notes}/notes.qmd (100%) rename {docs/notes => notes}/patch_attrs.qmd (96%) rename {docs/notes => notes}/spool_chunking.qmd (100%) rename {docs/notes => notes}/spool_index.qmd (100%) rename {docs/notes => notes}/spool_selection.qmd (100%) rename {docs/notes => notes}/velocity_to_strain_rate.qmd (96%) rename {docs/recipes => recipes}/add_spatial_coordinates_to_patch.qmd (100%) rename {docs/recipes => recipes}/contributing_to_documentation.qmd (100%) rename {docs/recipes => recipes}/correlate.qmd (100%) rename {docs/recipes => recipes}/despiking.qmd (97%) rename {docs/recipes => recipes}/docker_basic.qmd (100%) rename {docs/recipes => recipes}/edge_effects.qmd (100%) rename {docs/recipes => recipes}/external_conversion.qmd (100%) rename {docs/recipes => recipes}/fk.qmd (90%) rename {docs/recipes => recipes}/how_to_contribute.qmd (100%) rename {docs/recipes => recipes}/low_freq_proc.qmd (100%) rename {docs/recipes => recipes}/overview.qmd (100%) rename {docs/recipes => recipes}/parallelization.qmd (100%) rename {docs/recipes => recipes}/plotting_channel_number.qmd (100%) rename {docs/recipes => recipes}/real_time_proc.qmd (100%) rename {docs/recipes => recipes}/smoothing.qmd (64%) create mode 100644 skills/dascore/SKILL.md rename {docs/tutorial => tutorial}/concepts.qmd (98%) rename {docs/tutorial => tutorial}/configuration.qmd (100%) rename {docs/tutorial => tutorial}/coords.qmd (100%) rename {docs/tutorial => tutorial}/file_io.qmd (100%) rename {docs/tutorial => tutorial}/patch.qmd (92%) rename {docs/tutorial => tutorial}/processing.qmd (82%) rename {docs/tutorial => tutorial}/remote_patches.qmd (100%) rename {docs/tutorial => tutorial}/spool.qmd (100%) rename {docs/tutorial => tutorial}/transformations.qmd (100%) rename {docs/tutorial => tutorial}/visualization.qmd (94%) diff --git a/.github/workflows/build_docs_greatdocs.yaml b/.github/workflows/build_docs_greatdocs.yaml new file mode 100644 index 000000000..2e83cadbb --- /dev/null +++ b/.github/workflows/build_docs_greatdocs.yaml @@ -0,0 +1,55 @@ +# Proposed replacement for the doc-build workflows using great-docs. +# One command (great-docs build) replaces scripts/build_api_docs.py + +# quarto render, and the output additionally contains llms.txt, +# llms-full.txt, per-page markdown, SKILL.md and .well-known/agent-skills. +# +# NOTE (prototype): kept alongside the old workflows for comparison; a real +# migration would fold this into build_deploy_master_docs.yaml, +# build_deploy_stable_docs.yaml and test_doc_build.yml. + +name: BuildDocsGreatDocs + +on: + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-tags: "true" + fetch-depth: "0" + + - uses: quarto-dev/quarto-actions/setup@v2 + with: + version: 1.8.27 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install dascore and great-docs + run: | + python -m pip install -e ".[docs]" great-docs + + - name: Prepare test data + run: | + python scripts/modify_h5_file.py || true + + - name: Build documentation + run: | + great-docs build + + - uses: actions/upload-artifact@v4 + with: + name: documentation + path: ./great-docs/_site + # .well-known/agent-skills must survive packaging + include-hidden-files: true + retention-days: 7 + + # Deployment: `quarto publish` no longer applies; push great-docs/_site + # with the netlify CLI instead, e.g.: + # npx netlify-cli deploy --prod --dir great-docs/_site + # or use great-docs setup-github-pages for a Pages deployment. diff --git a/.gitignore b/.gitignore index 9bbadd6ab..759de9549 100644 --- a/.gitignore +++ b/.gitignore @@ -114,3 +114,4 @@ prof/ .vscode/ #JetBrains .idea/ +great-docs/ diff --git a/docs/acknowledgements.qmd b/about/acknowledgements.qmd similarity index 100% rename from docs/acknowledgements.qmd rename to about/acknowledgements.qmd diff --git a/docs/contributors.qmd b/about/contributors.qmd similarity index 100% rename from docs/contributors.qmd rename to about/contributors.qmd diff --git a/docs/supported_formats.qmd b/about/supported_formats.qmd similarity index 100% rename from docs/supported_formats.qmd rename to about/supported_formats.qmd diff --git a/docs/_static/diataxis.png b/assets/diataxis.png similarity index 100% rename from docs/_static/diataxis.png rename to assets/diataxis.png diff --git a/docs/_static/logo.png b/assets/logo.png similarity index 100% rename from docs/_static/logo.png rename to assets/logo.png diff --git a/docs/_static/logo.svg b/assets/logo.svg similarity index 100% rename from docs/_static/logo.svg rename to assets/logo.svg diff --git a/docs/_static/patch_n_spool.png b/assets/patch_n_spool.png similarity index 100% rename from docs/_static/patch_n_spool.png rename to assets/patch_n_spool.png diff --git a/docs/contributing/adding_test_data.qmd b/contributing/adding_test_data.qmd similarity index 100% rename from docs/contributing/adding_test_data.qmd rename to contributing/adding_test_data.qmd diff --git a/docs/contributing/code_of_conduct.qmd b/contributing/code_of_conduct.qmd similarity index 100% rename from docs/contributing/code_of_conduct.qmd rename to contributing/code_of_conduct.qmd diff --git a/docs/contributing/contributing.qmd b/contributing/contributing.qmd similarity index 100% rename from docs/contributing/contributing.qmd rename to contributing/contributing.qmd diff --git a/docs/contributing/dev_install.qmd b/contributing/dev_install.qmd similarity index 100% rename from docs/contributing/dev_install.qmd rename to contributing/dev_install.qmd diff --git a/docs/contributing/documentation.qmd b/contributing/documentation.qmd similarity index 88% rename from docs/contributing/documentation.qmd rename to contributing/documentation.qmd index 6e83c55ea..d791eaa7b 100644 --- a/docs/contributing/documentation.qmd +++ b/contributing/documentation.qmd @@ -107,31 +107,29 @@ print("cool beans") # Generating Documentation -DASCore's documentation is built with [quarto](https://quarto.org/). In order to build the documentation, you must first [install DASCore in development mode](dev_install.qmd) then [install quarto](https://quarto.org/docs/get-started/). - -Next, the automatic API documents are created with scripts/build_api_docs.py +DASCore's documentation is built with [great-docs](https://posit-dev.github.io/great-docs/), which is based on [quarto](https://quarto.org/). In order to build the documentation, you must first [install DASCore in development mode](dev_install.qmd), [install quarto](https://quarto.org/docs/get-started/), then install great-docs: ```bash -python scripts/build_api_docs.py +pip install great-docs ``` -Finally, the documentation can be built by calling quarto render on the docs folder: +The entire site (API reference included) is then built with a single command run from the repository root: ```bash -quarto render docs +great-docs build ``` -The newly generated html can then be accessed by double-clicking on the html index at docs/_site/index.html. +The newly generated html can then be accessed by double-clicking on the html index at great-docs/_site/index.html. Conversely, you can also preview the documentation so changes are rendered in real time in the browser: ```bash -quarto preview docs +great-docs preview ``` :::{.callout-warning} -If you need to change the structure of the site, like adding a new section/subsection, the file to edit is scripts/_templates/_quarto.yml. -Do not modify docs/_quarto.yml because it will be overwritten. +The site structure, the curated API reference, and everything else about the build are configured in great-docs.yml at the repository root. +The great-docs/ directory is an ephemeral build directory; do not edit or commit it. ::: # Cross references @@ -139,7 +137,7 @@ Do not modify docs/_quarto.yml because it will be overwritten. Cross references provide a means of linking parts of the documentation to the API docs for specific modules, classes, functions, or methods. They work just like normal markdown links except the reference is a dascore object surrounded by backticks like so: ``` -This is a link to DASCore's [Patch](`dascore.core.Patch`). +This is a link to DASCore's [Patch](`dascore.Patch`). ``` To link to qmd files in the documentation folder (eg from a docstring) the path relative to the docs folder can be used: diff --git a/docs/contributing/extending_dascore.qmd b/contributing/extending_dascore.qmd similarity index 100% rename from docs/contributing/extending_dascore.qmd rename to contributing/extending_dascore.qmd diff --git a/docs/contributing/general_guidelines.qmd b/contributing/general_guidelines.qmd similarity index 100% rename from docs/contributing/general_guidelines.qmd rename to contributing/general_guidelines.qmd diff --git a/docs/contributing/new_format.qmd b/contributing/new_format.qmd similarity index 100% rename from docs/contributing/new_format.qmd rename to contributing/new_format.qmd diff --git a/docs/contributing/profiling_benchmarks.qmd b/contributing/profiling_benchmarks.qmd similarity index 100% rename from docs/contributing/profiling_benchmarks.qmd rename to contributing/profiling_benchmarks.qmd diff --git a/docs/contributing/publish_a_new_release.qmd b/contributing/publish_a_new_release.qmd similarity index 100% rename from docs/contributing/publish_a_new_release.qmd rename to contributing/publish_a_new_release.qmd diff --git a/docs/contributing/style_and_linting.qmd b/contributing/style_and_linting.qmd similarity index 100% rename from docs/contributing/style_and_linting.qmd rename to contributing/style_and_linting.qmd diff --git a/docs/contributing/testing.qmd b/contributing/testing.qmd similarity index 100% rename from docs/contributing/testing.qmd rename to contributing/testing.qmd diff --git a/dascore/core/coordmanager.py b/dascore/core/coordmanager.py index c61ccea9f..5ba3a4642 100644 --- a/dascore/core/coordmanager.py +++ b/dascore/core/coordmanager.py @@ -1163,7 +1163,7 @@ def get_coord_manager( Information about coordinates. These can be a mapping of the form: {name, array}, {name: (dim_name, array)}, or {name: ((dim_names,) array). Can also be a - [`CoordManager`](`dascore.core.CoordManager`). + [`CoordManager`](`dascore.CoordManager`). dims Tuple specify dimension names shape diff --git a/dascore/proc/correlate.py b/dascore/proc/correlate.py index f30c33c97..1fd66d83b 100644 --- a/dascore/proc/correlate.py +++ b/dascore/proc/correlate.py @@ -52,7 +52,7 @@ def correlate_shift( undo_weighting If True, also undo the weighting artifact caused by DASCore's dft weighting. This is done by simply dividing by the coordinate step. - See [dft note](`docs/notes/dft_notes.qmd`) for more details. + See [dft note](/notes/dft_notes.qmd) for more details. Examples -------- @@ -103,7 +103,7 @@ def correlate( While a 2D patch is required for input, a 3D patch is returned where the 3rd dimension corresponds to the source rows/columns. For the case of a - single source, the [`Patch.squeeze`](`dascore.Patch.squeeze`) method + single source, the [`Patch.squeeze`](`dascore.proc.squeeze`) method can be helpful to remove length 1 dimensions. Parameters diff --git a/dascore/proc/filter.py b/dascore/proc/filter.py index 74b3f75a2..af3400d8d 100644 --- a/dascore/proc/filter.py +++ b/dascore/proc/filter.py @@ -552,7 +552,7 @@ def slope_filter( >>> filt = np.array([2e3,2.2e3,8e3,2e4]) * dc.get_unit("m/s") >>> patch_filtered = patch.slope_filter(filt=filt) - The [FK recipe](`docs/recipes/fk.qmd`) provides additional examples. + The [FK recipe](/recipes/fk.qmd) provides additional examples. """ def _check_inputs(patch, filt, dims): diff --git a/dascore/proc/hampel.py b/dascore/proc/hampel.py index 8cb203402..949540e47 100644 --- a/dascore/proc/hampel.py +++ b/dascore/proc/hampel.py @@ -150,7 +150,7 @@ def hampel_filter( See Also -------- - - [Despiking recipe](`docs/recipes/despiking.qmd`) + - [Despiking recipe](/recipes/despiking.qmd) Examples -------- diff --git a/dascore/proc/resample.py b/dascore/proc/resample.py index d969744f6..8435a5c03 100644 --- a/dascore/proc/resample.py +++ b/dascore/proc/resample.py @@ -122,7 +122,7 @@ def interpolate(patch: PatchType, kind: str | int = "linear", **kwargs) -> Patch This function just uses scipy's interp1d function under the hood. See scipy.interpolate.interp1d for information. - See also [snap](`dascore.core.Patch.snap_coords`). + See also [snap](`dascore.proc.snap_coords`). Examples -------- diff --git a/dascore/proc/whiten.py b/dascore/proc/whiten.py index 531d9bc52..20be5793f 100644 --- a/dascore/proc/whiten.py +++ b/dascore/proc/whiten.py @@ -90,7 +90,7 @@ def whiten( The whitened signal is returned in the same domain (eq frequency or time domain) as the input signal. See also the - [Whiten Processing Section](`docs/tutorial/processing.qmd`#whiten). + [Whiten Processing Section](/tutorial/processing.qmd#whiten). Parameters ---------- diff --git a/dascore/transform/fourier.py b/dascore/transform/fourier.py index b86402ab9..a1366e37b 100644 --- a/dascore/transform/fourier.py +++ b/dascore/transform/fourier.py @@ -262,7 +262,7 @@ def dft( - Non-dimensional coordinates associated with transformed coordinates will be dropped in the output. - - See the [FFT notes](`docs/notes/dft_notes.qmd`) for more details. + - See the [FFT notes](/notes/dft_notes.qmd) for more details. See Also -------- diff --git a/dascore/transform/integrate.py b/dascore/transform/integrate.py index 17e1e13c0..30140dd4e 100644 --- a/dascore/transform/integrate.py +++ b/dascore/transform/integrate.py @@ -108,7 +108,7 @@ def integrate( ----- The number of dimensions will always remain the same regardless of `definite` value. To remove dimensions with length 1, use - [`Patch.squeeze`](`dascore.Patch.squeeze`). + [`Patch.squeeze`](`dascore.proc.squeeze`). Examples -------- diff --git a/dascore/transform/strain.py b/dascore/transform/strain.py index d5110dcdc..09b0ba05d 100644 --- a/dascore/transform/strain.py +++ b/dascore/transform/strain.py @@ -84,7 +84,7 @@ def velocity_to_strain_rate( gauge_length is more complex with higher order filters. See @yang2022filtering for more info. - See the [`velocity_to_strain_rate` note](docs/notes/velocity_to_strain_rate.qmd) + See the [`velocity_to_strain_rate` note](/notes/velocity_to_strain_rate.qmd) for more details on step_multiple and order effects. The [edgeless](`dascore.Patch.velocity_to_strain_rate_edgeless`) version @@ -166,7 +166,7 @@ def velocity_to_strain_rate_edgeless( the sampling along the distance dimension. See the - [`velocity_to_strain_rate` note](docs/notes/velocity_to_strain_rate.qmd) + [`velocity_to_strain_rate` note](/notes/velocity_to_strain_rate.qmd) for more details on step_multiple and order effects. """ if step_multiple <= 0: diff --git a/dascore/utils/patch.py b/dascore/utils/patch.py index 8955d26bf..84ee08a50 100644 --- a/dascore/utils/patch.py +++ b/dascore/utils/patch.py @@ -301,7 +301,7 @@ def patch_function( machinery multiple times from within another patch function. - If using `PatchType` or `SpoolType` type variables from the - [constants module](`dascore.constants`), make sure dascore is imported + [constants module](/reference/index.qmd), make sure dascore is imported as dc at the top of the file where the patch function is defined so the forward refs can be resolved properly for type checking. """ @@ -1376,7 +1376,7 @@ def concatenate_patches( - [`Spool.chunk`](`dascore.BaseSpool.chunk`) performs a similar operation but accounts for coordinate values. - See also the - [chunk section of the spool tutorial](`docs/tutorial/spool`#concatenate) + [chunk section of the spool tutorial](/tutorial/spool.qmd#concatenate) """ def _get_dim_and_value(kwargs): diff --git a/great-docs.yml b/great-docs.yml new file mode 100644 index 000000000..a150280e8 --- /dev/null +++ b/great-docs.yml @@ -0,0 +1,334 @@ +# Great Docs Configuration for DASCore +# See https://posit-dev.github.io/great-docs/user-guide/configuration.html +# +# This replaces the previous custom doc build (scripts/build_api_docs.py, +# scripts/_index_api.py, scripts/_render_api.py, scripts/_qmd_builder.py, +# scripts/_validate_links.py, and docs/filters/fill_links.py). + +display_name: DASCore + +# Docstring format used throughout the package. +parser: numpy + +# Runtime introspection (needed so @compose_docstring-templated docstrings +# render with their substitutions filled in). +dynamic: true + +site_url: "https://dascore.org" +repo: "https://github.com/DASDAE/dascore" + +logo: + light: assets/logo.png + dark: assets/logo.png + alt: "DASCore logo" + show_title: true + +# Bibliography so citations (e.g. @lindsey2020broadband) in docstrings and +# narrative pages resolve instead of hanging pandoc. +bibliography: docs/references.bib + +authors: + - name: The DASDAE contributors + role: Author + github: DASDAE + +# Narrative documentation. Each section becomes a top-level site directory +# matching the old site layout, so existing relative links keep working. +sections: + - title: Tutorial + dir: tutorial + - title: Recipes + dir: recipes + index: true + - title: Notes + dir: notes + index: true + - title: Contributing + dir: contributing + index: true + - title: About + dir: about + index: true + +# Names picked up by discovery that are implementation details or +# accidental re-exports (dascore modules do not define __all__). +exclude: + - clients + - warnings + - compat.MATERIALIZE_NOW + - compat.random_state + - examples.compose_docstring + - examples.fetch + - examples.iterate + - examples.get_patch_names + - examples.random_state + - examples.register_func + - examples.EXAMPLE_PATCHES + - examples.EXAMPLE_SPOOLS + - examples.UnknownExampleError + - io.HDF5Reader + - io.HDF5Writer + - io.PatchNameSpace + - proc.ArrayLike + - proc.PatchType + - proc.apply_operator + - proc.array + - proc.compose_docstring + - proc.coords_from_df + - proc.get_parent_code_name + - proc.get_dim_axis_value + - proc.iterate + - proc.select_values_description + - proc.CoordError + - proc.ParameterError + - proc.PatchCoordinateError + - proc.PatchError + - units.assert_dtype_compatible_with_units + - units.dtype_time_like + - units.is_array + - units.is_datetime64 + - units.is_timedelta64 + - units.iterate + - units.maybe_convert_percent_to_fraction + - units.numeric + - units.quant_sequence_to_quant_array + - units.str_or_none + - units.unbyte + - units.UnitError + - viz.PatchNameSpace + +# Curated API reference. Grouped by task, mirroring how the tutorial +# introduces the library. +reference: + - title: Getting Data In and Out + desc: Read, scan, and write fiber-optic sensing data files + contents: + - spool + - read + - scan + - scan_to_df + - write + - get_format + + - title: Core Classes + desc: The central data structures of DASCore + contents: + - name: Patch + members: [data, coords, dims, attrs, shape, size, ndim, dtype, seconds, channel_count, coord_shapes, assign_coords, get_patch_name, iresample, iselect, tran, T] + - name: BaseSpool + members: [chunk, concatenate, get_contents, get_patch_names, map, select, sort, split, update, viz] + - clients.dirspool.DirectorySpool + - name: PatchAttrs + members: [coords_from_dims, dim_tuple, drop, drop_private, flat_dump, from_dict, get, items, parse_coord_attributes, rename_dimension, update] + - name: CoordManager + members: [convert_units, coord_range, coord_shapes, coord_size, decimate, dim_to_coord_map, disassociate_coord, drop_coords, drop_disassociated_coords, drop_private_coords, equals, flip, get_array, get_axis, get_coord, get_coord_tuple_map, keys, make_broadcastable_to, max, min, ndim, new, order, rename_coord, select, set_dims, set_units, shape, simplify_units, size, snap, sort, squeeze, step, to_summary_dict, transpose, update, update_from_attrs, validate_data] + - name: proc.BaseCoord + members: [align_to, approx_equal, change_length, convert_units, coord_range, empty, get_attrs_dict, get_next_index, get_sample_count, get_slice_tuple, index, max, min, new, order, reduce_coord, select, set_units, simplify_units, snap, sort, to_summary, update, update_data, update_limits] + - get_coord + - get_coord_manager + + - title: Patch Processing + desc: > + Processing routines. Each of these functions is also attached to + Patch as a method (e.g. patch.pass_filter(...)). + contents: + - proc.abs + - proc.add_distance_to + - proc.align_patch_coords + - proc.align_to_coord + - proc.angle + - proc.append_dims + - proc.bool_patch + - proc.conj + - proc.correlate + - proc.convert_units + - proc.correlate_shift + - proc.decimate + - proc.demean + - proc.detrend + - proc.demedian + - proc.drop_coords + - proc.drop_private_coords + - proc.dropna + - proc.equals + - proc.fillna + - proc.flip + - proc.full + - proc.gaussian_filter + - proc.get_array + - proc.get_axis + - proc.hampel_filter + - proc.imag + - proc.interpolate + - proc.line_mute + - proc.make_broadcastable_to + - proc.median_filter + - proc.normalize + - proc.notch_filter + - proc.order + - proc.pad + - proc.pass_filter + - proc.pipe + - proc.real + - proc.rename_coords + - proc.resample + - proc.rolling + - proc.roll + - proc.savgol_filter + - proc.select + - proc.set_dims + - proc.set_units + - proc.simplify_units + - proc.slope_filter + - proc.slope_mute + - proc.snap_coords + - proc.sobel_filter + - proc.sort_coords + - proc.squeeze + - proc.standardize + - proc.taper + - proc.taper_range + - proc.transpose + - proc.update + - proc.update_attrs + - proc.update_coords + - proc.where + - proc.whiten + - proc.wiener_filter + - patch_function + + - title: Transforms + desc: Transformations that change patch units or domain + contents: + - transform.dft + - transform.idft + - transform.rfft + - transform.stft + - transform.istft + - transform.spectrogram + - transform.envelope + - transform.differentiate + - transform.fbe + - transform.hilbert + - transform.integrate + - transform.kurtosis + - transform.stalta + - transform.dispersion_phase_shift + - transform.phase_weighted_stack + - transform.radians_to_strain + - transform.tau_p + - transform.velocity_to_strain_rate + - transform.velocity_to_strain_rate_edgeless + + - title: Visualization + desc: Matplotlib-based plotting of patches + contents: + - viz.waterfall + - viz.wiggle + - viz.spectrogram + - viz.specplot + - viz.map_fiber + + - title: Example Data + desc: Functions for generating example patches and spools + contents: + - get_example_patch + - get_example_spool + - examples.chirp + - examples.deformation_rate_event_1 + - examples.delta_patch + - examples.dispersion_event + - examples.diverse_spool + - examples.example_event_1 + - examples.example_event_2 + - examples.febus_dss_mine_1 + - examples.febus_dss_mine_2 + - examples.forge_dss + - examples.forge_dts + - examples.nd_patch + - examples.patch_with_null + - examples.random_directory_spool + - examples.random_patch + - examples.random_patch_lat_lon + - examples.random_patch_xyz + - examples.random_spool + - examples.ricker_moveout + - examples.sin_wave_patch + - examples.spool_to_directory + - examples.wacky_dim_coord_patch + + - title: Units and Time + desc: Unit and time conversion utilities + contents: + - get_quantity + - get_unit + - to_datetime64 + - to_timedelta64 + - to_float + - units.convert_units + - units.get_factor_and_unit + - units.get_filter_units + - units.get_inverted_quant + - units.get_quantity_str + - units.get_registry + - units.invert_quantity + - units.is_percent + + - title: IO Interfaces + desc: Interoperability with other libraries and the FiberIO plugin system + contents: + - io.FiberIO + - io.PatchIO + - io.PatchFileSummary + - io.dataframe_to_patch + - io.patch_to_dataframe + - io.obspy_to_patch + - io.patch_to_obspy + - io.xarray_to_patch + - io.patch_to_xarray + - io.BinaryReader + - io.BinaryWriter + - io.PyTablesReader + - io.PyTablesWriter + + - title: Utilities + desc: Assorted helper utilities + contents: + - utils.array.apply_ufunc + - utils.array.apply_array_func + - utils.patch.merge_compatible_coords_attrs + + - title: Exceptions + desc: Exception classes raised by DASCore + contents: + - exceptions.DASCoreError + - exceptions.AttributeMergeError + - exceptions.ChunkError + - exceptions.CoordError + - exceptions.CoordDataError + - exceptions.CoordMergeError + - exceptions.CoordSortError + - exceptions.DASVaderCompatibilityError + - exceptions.DependencyError + - exceptions.FilterValueError + - exceptions.IncompatiblePatchError + - exceptions.InvalidFiberFileError + - exceptions.InvalidFiberIOError + - exceptions.InvalidFileHandlerError + - exceptions.InvalidIndexVersionError + - exceptions.InvalidSpoolError + - exceptions.InvalidTimeRangeError + - exceptions.MissingOptionalDependencyError + - exceptions.ParameterError + - exceptions.PatchAttributeError + - exceptions.PatchBroadcastError + - exceptions.PatchConversionError + - exceptions.PatchCoordinateError + - exceptions.PatchError + - exceptions.TimeError + - exceptions.UnitError + - exceptions.UnknownExampleError + - exceptions.UnknownFiberFormatError + - exceptions.UnsupportedKeywordError + +jupyter: python3 diff --git a/index.qmd b/index.qmd new file mode 100644 index 000000000..921b234a9 --- /dev/null +++ b/index.qmd @@ -0,0 +1,152 @@ +--- +execute: + warning: false +--- + +# DASCore + +A python library for distributed fiber optic sensing. + +[![coverage](https://codecov.io/gh/dasdae/dascore/branch/master/graph/badge.svg)](https://codecov.io/gh/dasdae/dascore) +[![CodSpeed Badge](https://img.shields.io/endpoint?url=https://codspeed.io/badge.json)](https://codspeed.io/DASDAE/dascore) +[![PyPI Version](https://img.shields.io/pypi/v/dascore.svg)](https://pypi.python.org/pypi/dascore) +[![supported versions](https://img.shields.io/pypi/pyversions/dascore.svg?label=python_versions)](https://pypi.python.org/pypi/dascore) +[![PyPI Downloads](https://img.shields.io/pypi/dm/dascore.svg?label=pypi)](https://pypi.org/project/dascore/) +[![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/dascore.svg?label=conda)](https://github.com/conda-forge/dascore-feedstock) +[![DOI](https://zenodo.org/badge/422627477.svg)](https://zenodo.org/badge/latestdoi/422627477) +[![Licence](https://www.gnu.org/graphics/lgplv3-88x31.png)](https://www.gnu.org/licenses/lgpl.html) + +[Code](https://github.com/DASDAE/dascore) + +Documentation [[stable](https://dascore.org), [development](https://dascore.netlify.app/)] + +[Citation](https://seismica.library.mcgill.ca/article/view/1184) + +> Chambers, D., Jin, G., Tourei, A., Issah, A. H. S., Lellouch, A., Martin, E., Zhu, D., Girard, A., Yuan, S., Cullison, T., Snyder, T., Kim, S., Danes, N., Pnithan, N., Boltz, M. S. & Mendoza, M. M. (2024). DASCore: a Python Library for Distributed Fiber Optic Sensing. Seismica, 3(2). + +[![Contributors](https://contrib.rocks/image?repo=DASDAE/dascore)](https://github.com/DASDAE/dascore/graphs/contributors) + + +:::{.callout minimal="true"} +Version-specific documentation builds are attached to the [release pages](https://github.com/DASDAE/dascore/releases). +::: + +# Highlights + +DASCore is a Python library for distributed acoustic sensing (DAS). It provides: + +1. IO support for [many DAS data formats](about/supported_formats.qmd) +2. Common processing routines +3. Basic visualizations + +:::{.callout-note} +DASCore is part of the [DAS Data Analysis Ecosystem (DASDAE)](https://dasdae.org). +::: + +# Introductory usage + +## Read a file + +```{python} +import dascore as dc +# Import fetch to read DASCore example files +from dascore.utils.downloader import fetch + +# Fetch a sample file path from DASCore +file_path = fetch('terra15_das_1_trimmed.hdf5') +# To read DAS data stored locally on your machine, simply replace the above line with: +# file_path = "/path/to/data/directory/data.EXT" + +spool = dc.spool(file_path) +patch = spool[0] +``` + +## Working with a directory of DAS files + +```{python} +#| output: false +import dascore as dc +# Import fetch to read DASCore example files +from dascore.utils.downloader import fetch + +# Fetch a sample file path from DASCore (just to get a usable path for the rest of the cell) +directory_path = fetch('terra15_das_1_trimmed.hdf5').parent +# To read a directory of DAS data stored locally on your machine, +# simply replace the above line with: +# directory_path = "/path/to/data/directory/" + +spool = ( + # Create a spool to interact with directory data + dc.spool(directory_path) + # Index the directory contents + .update() + # Sub-select a specific time range + .select(time_min=('2020-01-01', ...)) + # Specify chunk of the output patches + .chunk(time=60, overlap=10) +) +``` + +## Get patches (array w/ metadata) + +```{python} +import dascore as dc + +spool = dc.get_example_spool('diverse_das') + +# Spools are like lists, you can get patches through iteration +for patch in spool: + ... + +# or through indexing +patch = spool[0] +``` + +## Perform processing + +```{python} +import dascore as dc + +patch = dc.get_example_patch('random_das') + +out = ( + # Decimate along time axis (keep every 8th sample) + patch.decimate(time=8) + # Detrend along the distance dimension + .detrend(dim='distance') + # Apply 10Hz low-pass filter along time dimension + .pass_filter(time=(..., 10)) +) +``` + +## Visualize + +```{python} +import dascore as dc + +patch = dc.get_example_patch('example_event_2') + +patch.viz.waterfall(show=True); +``` + +# Installation + +Use pip or conda to install DASCore: + +```bash +pip install dascore +``` + +```bash +conda install dascore -c conda-forge +``` + +See [this recipe](recipes/docker_basic.qmd) for installation with Docker. + +See the [contributing docs](contributing/contributing.qmd) for development installations. + +# Feedback and Support + +Use the [project discussions](https://github.com/DASDAE/dascore/discussions) to ask a question. + +Use the [project issues](https://github.com/DASDAE/dascore/issues) to report an issue. diff --git a/docs/notes/coordinate_internals.qmd b/notes/coordinate_internals.qmd similarity index 100% rename from docs/notes/coordinate_internals.qmd rename to notes/coordinate_internals.qmd diff --git a/docs/notes/dft_notes.qmd b/notes/dft_notes.qmd similarity index 100% rename from docs/notes/dft_notes.qmd rename to notes/dft_notes.qmd diff --git a/docs/notes/doc_strategy.qmd b/notes/doc_strategy.qmd similarity index 97% rename from docs/notes/doc_strategy.qmd rename to notes/doc_strategy.qmd index aa6d31349..c76ad5f5e 100644 --- a/docs/notes/doc_strategy.qmd +++ b/notes/doc_strategy.qmd @@ -4,7 +4,7 @@ title: DASCore Documentation Strategy DASCore's documentation follows the [Diátaxis](https://diataxis.fr/) approach. In this system, developed by Daniele Procida, there are four types of documentation with different goals: -![](../_static/diataxis.png) +![](../assets/diataxis.png) The sections of DASCore's documentation can be classified as follows: diff --git a/docs/notes/notes.qmd b/notes/notes.qmd similarity index 100% rename from docs/notes/notes.qmd rename to notes/notes.qmd diff --git a/docs/notes/patch_attrs.qmd b/notes/patch_attrs.qmd similarity index 96% rename from docs/notes/patch_attrs.qmd rename to notes/patch_attrs.qmd index 483de5b9b..50e221f51 100644 --- a/docs/notes/patch_attrs.qmd +++ b/notes/patch_attrs.qmd @@ -26,7 +26,7 @@ A stale or misleading `data_type` is much worse than an empty one. | Output is a known derived product with a stable meaning | Set a specific snake_case `data_type`. | | Output changes physical meaning but no stable label is appropriate | Clear `data_type` to `""`. | -DASCore-assigned `data_type` values should be snake_case and listed in `VALID_DATA_TYPES` in [`dascore.constants`](`dascore.constants`). Correctness-critical code should prefer units, coordinates, and explicit validation. +DASCore-assigned `data_type` values should be snake_case and listed in `VALID_DATA_TYPES` in [`dascore.constants`](/reference/index.qmd). Correctness-critical code should prefer units, coordinates, and explicit validation. ### Patch functions diff --git a/docs/notes/spool_chunking.qmd b/notes/spool_chunking.qmd similarity index 100% rename from docs/notes/spool_chunking.qmd rename to notes/spool_chunking.qmd diff --git a/docs/notes/spool_index.qmd b/notes/spool_index.qmd similarity index 100% rename from docs/notes/spool_index.qmd rename to notes/spool_index.qmd diff --git a/docs/notes/spool_selection.qmd b/notes/spool_selection.qmd similarity index 100% rename from docs/notes/spool_selection.qmd rename to notes/spool_selection.qmd diff --git a/docs/notes/velocity_to_strain_rate.qmd b/notes/velocity_to_strain_rate.qmd similarity index 96% rename from docs/notes/velocity_to_strain_rate.qmd rename to notes/velocity_to_strain_rate.qmd index a48f6dcfe..03bd00983 100644 --- a/docs/notes/velocity_to_strain_rate.qmd +++ b/notes/velocity_to_strain_rate.qmd @@ -14,8 +14,8 @@ Although DASCore usually refers to these type of data as "velocity", since the u There are two functions for converting velocity data to strain rate: -1. [Patch.velocity_to_strain_rate](`dascore.Patch.velocity_to_strain_rate`) -2. [Patch.velocity_to_strain_rate_edgeless](`dascore.Patch.velocity_to_strain_rate_edgeless`) +1. [Patch.velocity_to_strain_rate](`dascore.transform.velocity_to_strain_rate`) +2. [Patch.velocity_to_strain_rate_edgeless](`dascore.transform.velocity_to_strain_rate_edgeless`) The first function uses a central difference scheme when possible, but also a forward/backwards difference scheme on the edges. This results in patch that is the same shape as the input patch, but, depending on the parameters, there may be some artefacts on the end channels. It only supports even `step_multiple` values which means the smallest gauge length is twice the distance step. It also supports higher order filters if the [findiff library](https://findiff.readthedocs.io/en/latest/) is installed. diff --git a/docs/recipes/add_spatial_coordinates_to_patch.qmd b/recipes/add_spatial_coordinates_to_patch.qmd similarity index 100% rename from docs/recipes/add_spatial_coordinates_to_patch.qmd rename to recipes/add_spatial_coordinates_to_patch.qmd diff --git a/docs/recipes/contributing_to_documentation.qmd b/recipes/contributing_to_documentation.qmd similarity index 100% rename from docs/recipes/contributing_to_documentation.qmd rename to recipes/contributing_to_documentation.qmd diff --git a/docs/recipes/correlate.qmd b/recipes/correlate.qmd similarity index 100% rename from docs/recipes/correlate.qmd rename to recipes/correlate.qmd diff --git a/docs/recipes/despiking.qmd b/recipes/despiking.qmd similarity index 97% rename from docs/recipes/despiking.qmd rename to recipes/despiking.qmd index 5dd76203b..53eabe03c 100644 --- a/docs/recipes/despiking.qmd +++ b/recipes/despiking.qmd @@ -11,7 +11,7 @@ This recipe demonstrates how to remove spikes from DAS data. The Hampel filter is effective for removing outliers (spikes) in data by identifying values that deviate significantly from the local median in terms of median absolute deviation [(MAD)](https://en.wikipedia.org/wiki/Median_absolute_deviation). This makes it particularly useful for cleaning DAS data that may contain various types of noise spikes. -DASCore provides the [`Patch.hampel_filter`](`dascore.Patch.hampel_filter`). The filter works by: +DASCore provides the [`Patch.hampel_filter`](`dascore.proc.hampel_filter`). The filter works by: 1. Computing the local median within a sliding window (optionally along multiple dimensions) 2. Calculating the median absolute deviation (MAD) within the same window diff --git a/docs/recipes/docker_basic.qmd b/recipes/docker_basic.qmd similarity index 100% rename from docs/recipes/docker_basic.qmd rename to recipes/docker_basic.qmd diff --git a/docs/recipes/edge_effects.qmd b/recipes/edge_effects.qmd similarity index 100% rename from docs/recipes/edge_effects.qmd rename to recipes/edge_effects.qmd diff --git a/docs/recipes/external_conversion.qmd b/recipes/external_conversion.qmd similarity index 100% rename from docs/recipes/external_conversion.qmd rename to recipes/external_conversion.qmd diff --git a/docs/recipes/fk.qmd b/recipes/fk.qmd similarity index 90% rename from docs/recipes/fk.qmd rename to recipes/fk.qmd index 7321b3abb..00f1a19d5 100644 --- a/docs/recipes/fk.qmd +++ b/recipes/fk.qmd @@ -52,7 +52,7 @@ ax.set_ylim(-.2, .2); ## Slope Filtering -One advantage of the F-K transform is the ability to manipulate signals based on their apparent velocities. [`Patch.slope_filter`](`dascore.Patch.slope_filter`) can be used for this purpose. +One advantage of the F-K transform is the ability to manipulate signals based on their apparent velocities. [`Patch.slope_filter`](`dascore.proc.slope_filter`) can be used for this purpose. For example, given the first example event, we can apply a slope filter whose range covers reasonable seismic velocities. The `filt` parameter specifies the slope (apparent velocities). It is a 4 length sequence of the form [va, vb, vc, vd] where velocities between `vb` and `vc` are unchanged (or set to zero if `invert=True`) and values between `va` and `vb`, as well as those between `vc` and `vd`, are tapered. @@ -69,7 +69,7 @@ It's important to remember that *apparent* velocities (>= velocity) are filtered ### Phase Separation -Another application of [`slope_filter`](`dascore.Patch.slope_filter`) is to separate P/S waves. In this case, the P velocity is about 4500 m/s and the S velocity is about 2700 m/s. The following code highlights S waves, but also introduces some artifacts: +Another application of [`slope_filter`](`dascore.proc.slope_filter`) is to separate P/S waves. In this case, the P velocity is about 4500 m/s and the S velocity is about 2700 m/s. The following code highlights S waves, but also introduces some artifacts: ```{python} # velocities in m/s (distance in meters, time in seconds) diff --git a/docs/recipes/how_to_contribute.qmd b/recipes/how_to_contribute.qmd similarity index 100% rename from docs/recipes/how_to_contribute.qmd rename to recipes/how_to_contribute.qmd diff --git a/docs/recipes/low_freq_proc.qmd b/recipes/low_freq_proc.qmd similarity index 100% rename from docs/recipes/low_freq_proc.qmd rename to recipes/low_freq_proc.qmd diff --git a/docs/recipes/overview.qmd b/recipes/overview.qmd similarity index 100% rename from docs/recipes/overview.qmd rename to recipes/overview.qmd diff --git a/docs/recipes/parallelization.qmd b/recipes/parallelization.qmd similarity index 100% rename from docs/recipes/parallelization.qmd rename to recipes/parallelization.qmd diff --git a/docs/recipes/plotting_channel_number.qmd b/recipes/plotting_channel_number.qmd similarity index 100% rename from docs/recipes/plotting_channel_number.qmd rename to recipes/plotting_channel_number.qmd diff --git a/docs/recipes/real_time_proc.qmd b/recipes/real_time_proc.qmd similarity index 100% rename from docs/recipes/real_time_proc.qmd rename to recipes/real_time_proc.qmd diff --git a/docs/recipes/smoothing.qmd b/recipes/smoothing.qmd similarity index 64% rename from docs/recipes/smoothing.qmd rename to recipes/smoothing.qmd index ac62bcdf7..adc3a2655 100644 --- a/docs/recipes/smoothing.qmd +++ b/recipes/smoothing.qmd @@ -8,13 +8,13 @@ This recipe compares several smoothing strategies. A few patch methods useful for smoothing are: -- [`Patch.rolling`](`dascore.Patch.rolling`) -- [`Patch.savgol_filter`](`dascore.Patch.savgol_filter`) -- [`Patch.gaussian_filter`](`dascore.Patch.gaussian_filter`) +- [`Patch.rolling`](`dascore.proc.rolling`) +- [`Patch.savgol_filter`](`dascore.proc.savgol_filter`) +- [`Patch.gaussian_filter`](`dascore.proc.gaussian_filter`) :::{.callout-note} -[`Patch.rolling`](`dascore.Patch.rolling`) is quite flexible and can be used for many different processing tasks. However, as mentioned in the [rolling section of the tutorial](/tutorial/processing.qmd#rolling), [`Patch.rolling`](`dascore.Patch.rolling`) includes `NaN` entries in the output due to edge effects. This can require some additional thought to properly deal with. +[`Patch.rolling`](`dascore.proc.rolling`) is quite flexible and can be used for many different processing tasks. However, as mentioned in the [rolling section of the tutorial](/tutorial/processing.qmd#rolling), [`Patch.rolling`](`dascore.proc.rolling`) includes `NaN` entries in the output due to edge effects. This can require some additional thought to properly deal with. The other methods mentioned above deal with edge effects differently (governed by the `mode` parameter) and by default don't include `NaN` entries. ::: @@ -35,7 +35,7 @@ ax.set_title("un-smoothed patch"); ## Rolling -[`Patch.rolling`](`dascore.Patch.rolling`) can be used for applying aggregation functions to rolling windows along one dimension of the `Patch` instance. For instance, to apply a rolling mean to the time axis: +[`Patch.rolling`](`dascore.proc.rolling`) can be used for applying aggregation functions to rolling windows along one dimension of the `Patch` instance. For instance, to apply a rolling mean to the time axis: ```{python} smoothed_patch = ( @@ -80,12 +80,12 @@ ax = nan_patch.viz.waterfall() ax.set_title("NaNs in Patch"); ``` -Which can be dropped with [Patch.dropna](`dascore.Patch.dropna`). +Which can be dropped with [Patch.dropna](`dascore.proc.dropna`). ## Savgol filter -[`Patch.savgol_filter`](`dascore.Patch.savgol_filter`) uses [SciPy's savgol_filter](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.savgol_filter.html), which is an implementation of the [Savitzky-Golay Filter](https://en.wikipedia.org/wiki/Savitzky%E2%80%93Golay_filter) to apply smoothing along a single dimension. +[`Patch.savgol_filter`](`dascore.proc.savgol_filter`) uses [SciPy's savgol_filter](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.savgol_filter.html), which is an implementation of the [Savitzky-Golay Filter](https://en.wikipedia.org/wiki/Savitzky%E2%80%93Golay_filter) to apply smoothing along a single dimension. ```{python} smoothed_patch = ( @@ -112,7 +112,7 @@ ax.set_title("savgol time and distance"); ## Gaussian filter -[`Patch.gaussian_filter`](`dascore.Patch.gaussian_filter`) uses [SciPy's gaussian_filter](https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.gaussian_filter.html) to apply a gaussian smoothing operator to the patch. Note that the keyword arguments here specify standard deviation, and the `truncate` keyword determines how many standard deviations are included in the smoothing kernel. +[`Patch.gaussian_filter`](`dascore.proc.gaussian_filter`) uses [SciPy's gaussian_filter](https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.gaussian_filter.html) to apply a gaussian smoothing operator to the patch. Note that the keyword arguments here specify standard deviation, and the `truncate` keyword determines how many standard deviations are included in the smoothing kernel. ```{python} smoothed_patch = patch.gaussian_filter( diff --git a/skills/dascore/SKILL.md b/skills/dascore/SKILL.md new file mode 100644 index 000000000..f820a6c43 --- /dev/null +++ b/skills/dascore/SKILL.md @@ -0,0 +1,95 @@ +--- +name: dascore +description: > + Python library for distributed fiber optic sensing (DAS/DTS/DSS). Use when + reading, processing, transforming, or visualizing fiber-optic sensing data + (e.g. HDF5/TDMS/SEGY DAS files from Terra15, Silixa, OptoDAS, Febus, etc.), + or when converting such data between formats or to ObsPy/xarray objects. +license: LGPL-3.0-or-later +compatibility: Requires Python >=3.10. +--- + +# DASCore + +DASCore reads, processes, and visualizes distributed acoustic sensing (DAS) +data. The two central types are: + +- **`Patch`** — an n-D array (usually time × distance) with coordinates and + metadata. Immutable: every method returns a *new* patch. +- **Spool** (`dc.spool(...)`) — a collection of patches, backed by memory, a + single file, or a directory of files. Iterate it to get patches. + +## Install + +```bash +pip install dascore # or: conda install -c conda-forge dascore +``` + +## Core workflow + +```python +import dascore as dc + +spool = dc.spool("path/to/file_or_directory") # lazy; indexes directories +spool = spool.select(time=("2023-01-01", ...)) # filter before loading +spool = spool.chunk(time=60) # re-chunk to 60 s patches +for patch in spool: + out = ( + patch.detrend("time") # most proc funcs are methods + .pass_filter(time=(1, 100)) # units in Hz for time dim + .velocity_to_strain_rate() + ) +``` + +## Decision table + +| Task | Use | Not | +|---|---|---| +| Read data files | `dc.spool(path)[0]` or iterate | `dc.read` (low-level) | +| Discover file metadata cheaply | `dc.scan(path)` / `dc.scan_to_df(path)` | reading whole files | +| Subset by time/distance values | `patch.select(time=(t1, t2))` | index math | +| Subset by sample index | `patch.select(time=(0, 100), samples=True)` | `iselect` shorthand also exists | +| Merge contiguous patches | `spool.chunk(time=None)` | manual `np.concatenate` | +| Fixed-length windows | `spool.chunk(time=30, overlap=5)` | manual slicing | +| Parallel processing | `spool.map(func, client=executor)` | multiprocessing on patches directly | +| Get example data | `dc.get_example_patch("random_das")` | downloading files in tests/docs | +| Save patches | `patch.io.write(path, "dasdae")` or `dc.write(...)` | pickle | +| Convert to ObsPy/xarray/pandas | `patch.io.to_obspy()` etc. | manual conversion | + +## Gotchas + +- **Patches are immutable.** `patch.pass_filter(...)` returns a new patch; + the original is unchanged. Chain calls or reassign. +- **Time is numpy `datetime64`/`timedelta64`.** Use `dc.to_datetime64("2023-01-01")` + and `dc.to_timedelta64(1.5)` to build values; select accepts strings, + datetime64, and floats-as-seconds for relative offsets. +- **`...` (Ellipsis) means "open ended"** in ranges: `time=(start, ...)`. +- **Filter arguments are ranges keyed by dimension**: + `patch.pass_filter(time=(1, 100))` band-passes 1–100 Hz along the time dim; + `None` on one side makes it low/high pass. +- **Units**: many methods accept pint quantities, e.g. + `patch.convert_units(distance="ft")`; `dc.get_quantity("10 m/s")` parses + strings. Do not cache pint quantities across registry resets. +- **Directory spools need an index update** after files change: + `spool.update()`. +- **`spool.select` on non-coordinate attrs** matches exact values or + collections (e.g. `network={"das1", "das2"}`). +- **Processing functions live in `dascore.proc` but are attached to `Patch` + as methods**; transforms live in `dascore.transform`; plots in + `dascore.viz` (e.g. `patch.viz.waterfall()`). + +## Capability boundaries + +- DASCore handles single-experiment array data, not seismic network + workflows — use ObsPy for station/inventory-based seismology. +- Supported formats and their read/scan/write capabilities are listed at + https://dascore.org/supported_formats.html — writing is only supported + for a few formats (DASDAE, and converters via ObsPy/xarray). +- For very large datasets, prefer `spool.select(...).chunk(...)` before + loading; patches load lazily from directory spools. + +## Resources + +- Full documentation: https://dascore.org/ +- LLM index: https://dascore.org/llms.txt (full: /llms-full.txt) +- Tutorials: https://dascore.org/tutorial/concepts.html diff --git a/docs/tutorial/concepts.qmd b/tutorial/concepts.qmd similarity index 98% rename from docs/tutorial/concepts.qmd rename to tutorial/concepts.qmd index 07b50530c..921d7721e 100644 --- a/docs/tutorial/concepts.qmd +++ b/tutorial/concepts.qmd @@ -15,7 +15,7 @@ The `Patch` contains a contiguous block of N dimensional data and metadata. The `Spool` manages a group of `Patch`es. These can be in memory, on disk, or a remote resource. -![Patch (blue) and Spool (red)](../_static/patch_n_spool.png){#fig-patch_n_spool} +![Patch (blue) and Spool (red)](../assets/patch_n_spool.png){#fig-patch_n_spool} You will read more about Patches and Spools later on in the tutorial. diff --git a/docs/tutorial/configuration.qmd b/tutorial/configuration.qmd similarity index 100% rename from docs/tutorial/configuration.qmd rename to tutorial/configuration.qmd diff --git a/docs/tutorial/coords.qmd b/tutorial/coords.qmd similarity index 100% rename from docs/tutorial/coords.qmd rename to tutorial/coords.qmd diff --git a/docs/tutorial/file_io.qmd b/tutorial/file_io.qmd similarity index 100% rename from docs/tutorial/file_io.qmd rename to tutorial/file_io.qmd diff --git a/docs/tutorial/patch.qmd b/tutorial/patch.qmd similarity index 92% rename from docs/tutorial/patch.qmd rename to tutorial/patch.qmd index 9e7b9b33c..b8b82680c 100644 --- a/docs/tutorial/patch.qmd +++ b/tutorial/patch.qmd @@ -339,7 +339,7 @@ The following methods help trim, reshape, and manipulate coordinates. ## Select -Patches are trimmed using the [`Patch.select`](`dascore.Patch.select`) method. Unlike [`Patch.order`](`dascore.Patch.order`), `select` will not change the order of the affected dimensions, it will only remove elements. Most commonly, `select` takes the coordinate name and a tuple of (lower_limit, upper_limit) as the values. Either limit can be `...` or `None`, indicating an open interval, as can an infinite bound pointing away from the data, such as `(lower_limit, np.inf)`. +Patches are trimmed using the [`Patch.select`](`dascore.proc.select`) method. Unlike [`Patch.order`](`dascore.proc.order`), `select` will not change the order of the affected dimensions, it will only remove elements. Most commonly, `select` takes the coordinate name and a tuple of (lower_limit, upper_limit) as the values. Either limit can be `...` or `None`, indicating an open interval, as can an infinite bound pointing away from the data, such as `(lower_limit, np.inf)`. ```{python} import numpy as np @@ -465,7 +465,7 @@ assert outside.get_coord("distance").step is None That is why [`Spool.unselect`](`dascore.core.spool.Spool.unselect`) refuses the patches' own coordinates. A patch can have samples removed from its middle; at spool level the complement of a range would be a hole in every patch rather than a choice between patches. The coordinates an attached DASDAE inventory defines along the fiber are a separate case, and are accepted: removing one of those chooses which channels a patch holds. When several coordinates are named, each is complemented on its own — the true complement of a block is a frame around it, which no array can hold. ## Order - Order is similar to [`Patch.select`](`dascore.Patch.select`), but will re-arrange data to the order specified by a value array. This may also cause parts of the patch to be duplicated. + Order is similar to [`Patch.select`](`dascore.proc.select`), but will re-arrange data to the order specified by a value array. This may also cause parts of the patch to be duplicated. ```{python} import numpy as np @@ -488,7 +488,7 @@ assert np.all(dist_order2 == patch_dist2.get_array("distance")) ## New dimensions Sometimes it can be useful to add new (empty) dimensions to a Patch. -[`Patch.append_dims`](`dascore.Patch.append_dims`) does this. +[`Patch.append_dims`](`dascore.proc.append_dims`) does this. ```python import dascore as dc @@ -529,11 +529,11 @@ out = ( .pass_filter(time=(..., 10)) ) ``` -The processing methods are located in the [dascore.proc](`dascore.proc`) module. The [patch processing tutorial](processing.qmd) provides more information about processing routines. +The processing methods are located in the [dascore.proc](/reference/index.qmd#patch-processing) module. The [patch processing tutorial](processing.qmd) provides more information about processing routines. # Visualization -DASCore provides some visualization functions in the [dascore.viz](`dascore.viz`) module or using the `Patch.viz` namespace. DASCore generally only implements simple, matplotlib based visualizations but other DASDAE packages will likely do more interesting visualizations. +DASCore provides some visualization functions in the [dascore.viz](/reference/index.qmd#visualization) module or using the `Patch.viz` namespace. DASCore generally only implements simple, matplotlib based visualizations but other DASDAE packages will likely do more interesting visualizations. ```{python} import dascore as dc @@ -553,7 +553,7 @@ Because patches should be treated as immutable objects, they can't be modified w ## Update -[`Patch.update`](`dascore.core.patch.Patch.update`) uses the `Patch` instances as a template and returns a new `Patch` instances with one or more aspects modified. +[`Patch.update`](`dascore.proc.update`) uses the `Patch` instances as a template and returns a new `Patch` instances with one or more aspects modified. ```{python} import dascore as dc @@ -568,7 +568,7 @@ new_attrs_patch = pa.update(attrs=dict(tag="TMU")) ## Update attrs -[`Patch.update_attrs`](`dascore.core.patch.Patch.update_attrs`) is for making changes to the attrs (metadata) while keeping the unaffected metadata (`Patch.update` would completely replace the old attrs). +[`Patch.update_attrs`](`dascore.proc.update_attrs`) is for making changes to the attrs (metadata) while keeping the unaffected metadata (`Patch.update` would completely replace the old attrs). ```{python} import dascore as dc @@ -587,7 +587,7 @@ assert pa1.attrs.new_attr == 42 ## Update coords -[`Patch.update_coords`](`dascore.core.patch.Patch.update_coords`) returns a new patch with the coordinates changed in some way. These changes can include: +[`Patch.update_coords`](`dascore.proc.update_coords`) returns a new patch with the coordinates changed in some way. These changes can include: - Modifying (updating) existing coordinates - Adding new coordinates - Changing coordinate dimensional association @@ -733,9 +733,9 @@ As mentioned in the [units section of the concept page](concepts.qmd#units), DAS There are two methods for configuring the units associated with a `Patch`. -[`Patch.set_units`](`dascore.Patch.set_units`) sets the units on a patch or its coordinates. Old units are simply overwritten without performing any conversions. The first argument sets the data units and the keywords set the coordinate units. +[`Patch.set_units`](`dascore.proc.set_units`) sets the units on a patch or its coordinates. Old units are simply overwritten without performing any conversions. The first argument sets the data units and the keywords set the coordinate units. -[`Patch.convert_units`](`dascore.Patch.convert_units`) converts data or coordinates units by appropriately transforming the data or coordinates arrays. If no units exist they will simply be set. +[`Patch.convert_units`](`dascore.proc.convert_units`) converts data or coordinates units by appropriately transforming the data or coordinates arrays. If no units exist they will simply be set. ```{python} import dascore as dc @@ -777,7 +777,7 @@ sub_selected = pa.select(distance=(10*ft, 10*m)) dist_filtered = pa.pass_filter(distance=(10*m, 100*m)) ``` -See the documentation on [`Patch.select`](`dascore.Patch.select`) and [`Patch.pass_filter`](`dascore.Patch.pass_filter`) for more details. +See the documentation on [`Patch.select`](`dascore.proc.select`) and [`Patch.pass_filter`](`dascore.proc.pass_filter`) for more details. # Patch operations diff --git a/docs/tutorial/processing.qmd b/tutorial/processing.qmd similarity index 82% rename from docs/tutorial/processing.qmd rename to tutorial/processing.qmd index eaadfd64d..ab503ac4e 100644 --- a/docs/tutorial/processing.qmd +++ b/tutorial/processing.qmd @@ -4,14 +4,14 @@ execute: warning: false --- The following shows some simple examples of patch processing. See the -[proc module](`dascore.proc`) for a list of all processing functions. +[proc module](/reference/index.qmd#patch-processing) for a list of all processing functions. # Basic There are several "basic" processing functions which manipulate the patch metadata, shape, etc. Many of these are covered in the [patch tutorial](patch.qmd), but here are a few that aren't: ## Transpose -The [`transpose` patch function](`dascore.Patch.transpose`) patch function simply transposes the dimensions of the patch, either by rotating the dimensions or to a new specified dimension. +The [`transpose` patch function](`dascore.proc.transpose`) patch function simply transposes the dimensions of the patch, either by rotating the dimensions or to a new specified dimension. ```{python} import dascore as dc @@ -27,7 +27,7 @@ transposed = patch.transpose("time", "distance") ``` ## Squeeze -[`squeeze`](`dascore.Patch.squeeze`) removes dimensions which have a single value (see also `numpy.squeeze`). +[`squeeze`](`dascore.proc.squeeze`) removes dimensions which have a single value (see also `numpy.squeeze`). ```{python} import dascore as dc @@ -44,7 +44,7 @@ print(f"Post-squeeze shape: {squeezed.shape}") ## Dropna -The [`dropna` patch function](`dascore.Patch.dropna`) patch function drops "nullish" values from a given label. +The [`dropna` patch function](`dascore.proc.dropna`) patch function drops "nullish" values from a given label. ```{python} import numpy as np @@ -68,7 +68,7 @@ assert not np.any(np.isnan(no_na_patch.data)) # Decimate -[decimate](`dascore.Patch.decimate`) decimates a `Patch` along a given axis while by default performing low-pass filtering to avoid [aliasing](https://en.wikipedia.org/wiki/Aliasing). +[decimate](`dascore.proc.decimate`) decimates a `Patch` along a given axis while by default performing low-pass filtering to avoid [aliasing](https://en.wikipedia.org/wiki/Aliasing). ## Data creation @@ -119,7 +119,7 @@ decimated_no_filt.viz.wiggle(show=True); # Taper -[taper](`dascore.Patch.taper`) is used to taper the edges of a patch dimension to zero. To see this, let's create a patch of all 1s and apply the taper function +[taper](`dascore.proc.taper`) is used to taper the edges of a patch dimension to zero. To see this, let's create a patch of all 1s and apply the taper function ```{python} import numpy as np @@ -153,7 +153,7 @@ patch_ones.taper(distance=(None, 0.1)).viz.waterfall(); See also the [edge effects recipe](../recipes/edge_effects.qmd) for using tapering to help filtering. # Rolling -The [rolling patch function](`dascore.Patch.rolling`) implements moving window operators similar to [pandas rolling](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.rolling.html). It is useful for smoothing, calculating aggregated statistics, etc. +The [rolling patch function](`dascore.proc.rolling`) implements moving window operators similar to [pandas rolling](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.rolling.html). It is useful for smoothing, calculating aggregated statistics, etc. Here is an example of using a rolling mean to smooth along the time axis: @@ -168,12 +168,12 @@ smoothed = patch.rolling(time=50*dt).mean() smoothed.viz.waterfall(); ``` -Notice the nan values at the start of the time axis. These can be trimmed with [`Patch.dropna`](`dascore.Patch.dropna`). +Notice the nan values at the start of the time axis. These can be trimmed with [`Patch.dropna`](`dascore.proc.dropna`). # Whiten -The [`Patch.whiten`](`dascore.Patch.whiten`) function performs spectral whitening by balancing the amplitude spectra of the patch while leaving the phase (largely) unchanged. Spectral whitening is often a pre-processing step in ambient noise correlation workflows. +The [`Patch.whiten`](`dascore.proc.whiten`) function performs spectral whitening by balancing the amplitude spectra of the patch while leaving the phase (largely) unchanged. Spectral whitening is often a pre-processing step in ambient noise correlation workflows. To demonstrate, we create some plotting code and an example patch. diff --git a/docs/tutorial/remote_patches.qmd b/tutorial/remote_patches.qmd similarity index 100% rename from docs/tutorial/remote_patches.qmd rename to tutorial/remote_patches.qmd diff --git a/docs/tutorial/spool.qmd b/tutorial/spool.qmd similarity index 100% rename from docs/tutorial/spool.qmd rename to tutorial/spool.qmd diff --git a/docs/tutorial/transformations.qmd b/tutorial/transformations.qmd similarity index 100% rename from docs/tutorial/transformations.qmd rename to tutorial/transformations.qmd diff --git a/docs/tutorial/visualization.qmd b/tutorial/visualization.qmd similarity index 94% rename from docs/tutorial/visualization.qmd rename to tutorial/visualization.qmd index d320ea6b9..011784ecc 100644 --- a/docs/tutorial/visualization.qmd +++ b/tutorial/visualization.qmd @@ -6,7 +6,7 @@ execute: # Viz The following provides some examples of patch visualization. -See the [viz module documentation](`dascore.viz`) for a list of visualization functions +See the [viz module documentation](/reference/index.qmd#visualization) for a list of visualization functions ## Waterfall The [`waterfall patch function`](`dascore.viz.waterfall`) creates a waterfall plot of the patch data. From c76566629a9adce7596c96f368d556950f172014 Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Sat, 4 Jul 2026 05:46:10 +0200 Subject: [PATCH 02/22] Set explicit title on landing page --- index.qmd | 1 + 1 file changed, 1 insertion(+) diff --git a/index.qmd b/index.qmd index 921b234a9..a02eae962 100644 --- a/index.qmd +++ b/index.qmd @@ -1,4 +1,5 @@ --- +title: DASCore execute: warning: false --- From 9cd076f389ff418e0eae780b0c65e87945a0265c Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Sat, 4 Jul 2026 20:35:29 +0200 Subject: [PATCH 03/22] Add link-inventory aliases so all cross-reference styles resolve Add scripts/greatdocs_alias_inventory.py, run as a quarto pre-render hook (great-docs.yml pre_render key). After great-docs generates objects.json, the script imports dascore and appends inventory entries for: - every public access path to a documented object (Patch.pass_filter and the other dynamically attached methods, re-export paths like dascore.core.Patch, and canonical module.qualname paths) - module references (dascore.proc, dascore.viz, ...), which link to the matching section of the API index With this, docstrings and narrative pages can link to any public alias path or documentation page and the built site has zero unresolved cross references. Also document coords_from_df, get_summary_df, H5Reader and H5Writer, drop a stale see-also link to the removed iter_fs_contents, avoid an interlink in a docstring summary line, and update the contributing docs to describe the linking rules. --- contributing/documentation.qmd | 10 +- contributing/new_format.qmd | 2 +- dascore/examples.py | 2 +- great-docs.yml | 13 +- notes/dft_notes.qmd | 2 +- scripts/greatdocs_alias_inventory.py | 189 +++++++++++++++++++++++++++ tutorial/file_io.qmd | 2 +- 7 files changed, 210 insertions(+), 10 deletions(-) create mode 100644 scripts/greatdocs_alias_inventory.py diff --git a/contributing/documentation.qmd b/contributing/documentation.qmd index d791eaa7b..aa0c78117 100644 --- a/contributing/documentation.qmd +++ b/contributing/documentation.qmd @@ -140,10 +140,16 @@ Cross references provide a means of linking parts of the documentation to the AP This is a link to DASCore's [Patch](`dascore.Patch`). ``` -To link to qmd files in the documentation folder (eg from a docstring) the path relative to the docs folder can be used: +Any public access path to a documented object works, including method aliases +and re-export paths (e.g. `` `dascore.Patch.pass_filter` `` or +`` `dascore.proc.pass_filter` ``); scripts/greatdocs_alias_inventory.py adds +these aliases to the link inventory during the build. Module references such +as `` `dascore.proc` `` link to the matching section of the API index. + +To link to a documentation page (eg from a docstring), use its site-root path: ``` -This is a link to [this qmd file](`docs/contributing/documentation.qmd`). +See the [patch tutorial](/tutorial/patch.qmd) for examples. ``` Cross references can be used in both docstrings and the qmd documentation pages. diff --git a/contributing/new_format.qmd b/contributing/new_format.qmd index c95a7a490..12085e4f2 100644 --- a/contributing/new_format.qmd +++ b/contributing/new_format.qmd @@ -392,7 +392,7 @@ The name and version of the format are separated by a double underscore. ## Directories as Inputs -Some `FiberIO` formats may not be self-contained files, but rather must be understood in the context of an entire directory. In these cases, the `input_type` parameter on the `FiberIO` subclass should be set to "directory". See the [xml_binary](`dascore.io.xml_binary`) module for an example of a directory based `FiberIO` implementation. +Some `FiberIO` formats may not be self-contained files, but rather must be understood in the context of an entire directory. In these cases, the `input_type` parameter on the `FiberIO` subclass should be set to "directory". See the [xml_binary](https://github.com/DASDAE/dascore/tree/master/dascore/io/xml_binary) module for an example of a directory based `FiberIO` implementation. :::{.callout-warning} DASCore assumes a directory-based `FiberIO` does not have any sub patch files of a different format. Once a valid `FiberIO` directory is found, contents of the directory are no longer searched for Patch files. diff --git a/dascore/examples.py b/dascore/examples.py index 20bff10af..50c9e7a2a 100644 --- a/dascore/examples.py +++ b/dascore/examples.py @@ -308,7 +308,7 @@ def example_event_1(): @register_func(EXAMPLE_PATCHES, key="example_event_2") def example_event_2(): """ - [`example_event_1`](`dascore.examples.example_event_1`) with pre-processing. + Same as `example_event_1` but with pre-processing applied. """ path = fetch("example_dasdae_event_1.h5") patch = _load_example_patch_from_file(path).update_attrs(data_type="strain_rate") diff --git a/great-docs.yml b/great-docs.yml index a150280e8..0ba674bdb 100644 --- a/great-docs.yml +++ b/great-docs.yml @@ -23,6 +23,11 @@ logo: alt: "DASCore logo" show_title: true +# Pre-render hook: add alias entries (Patch methods, re-export paths, +# module links) to the interlink inventory so alias-style cross references +# keep resolving. +pre_render: scripts/greatdocs_alias_inventory.py + # Bibliography so citations (e.g. @lindsey2020broadband) in docstrings and # narrative pages resolve instead of hanging pandoc. bibliography: docs/references.bib @@ -66,15 +71,12 @@ exclude: - examples.EXAMPLE_PATCHES - examples.EXAMPLE_SPOOLS - examples.UnknownExampleError - - io.HDF5Reader - - io.HDF5Writer - io.PatchNameSpace - proc.ArrayLike - proc.PatchType - proc.apply_operator - proc.array - proc.compose_docstring - - proc.coords_from_df - proc.get_parent_code_name - proc.get_dim_axis_value - proc.iterate @@ -119,7 +121,7 @@ reference: members: [chunk, concatenate, get_contents, get_patch_names, map, select, sort, split, update, viz] - clients.dirspool.DirectorySpool - name: PatchAttrs - members: [coords_from_dims, dim_tuple, drop, drop_private, flat_dump, from_dict, get, items, parse_coord_attributes, rename_dimension, update] + members: [coords_from_dims, dim_tuple, drop, drop_private, flat_dump, from_dict, get, get_summary_df, items, parse_coord_attributes, rename_dimension, update] - name: CoordManager members: [convert_units, coord_range, coord_shapes, coord_size, decimate, dim_to_coord_map, disassociate_coord, drop_coords, drop_disassociated_coords, drop_private_coords, equals, flip, get_array, get_axis, get_coord, get_coord_tuple_map, keys, make_broadcastable_to, max, min, ndim, new, order, rename_coord, select, set_dims, set_units, shape, simplify_units, size, snap, sort, squeeze, step, to_summary_dict, transpose, update, update_from_attrs, validate_data] - name: proc.BaseCoord @@ -140,6 +142,7 @@ reference: - proc.append_dims - proc.bool_patch - proc.conj + - proc.coords_from_df - proc.correlate - proc.convert_units - proc.correlate_shift @@ -288,6 +291,8 @@ reference: - io.patch_to_xarray - io.BinaryReader - io.BinaryWriter + - io.H5Reader + - io.H5Writer - io.PyTablesReader - io.PyTablesWriter diff --git a/notes/dft_notes.qmd b/notes/dft_notes.qmd index f202f8bf5..8d5860eeb 100644 --- a/notes/dft_notes.qmd +++ b/notes/dft_notes.qmd @@ -1,6 +1,6 @@ # Fourier Transforms in DASCore -These notes provide the reasoning for DASCore's [fourier](`dascore.transform.fourier`) module implementation. +These notes provide the reasoning for DASCore's [fourier](/reference/index.qmd#transforms) module implementation. ## Summary {#sec-summary} diff --git a/scripts/greatdocs_alias_inventory.py b/scripts/greatdocs_alias_inventory.py new file mode 100644 index 000000000..cc4865042 --- /dev/null +++ b/scripts/greatdocs_alias_inventory.py @@ -0,0 +1,189 @@ +""" +Quarto pre-render hook: add alias entries to the great-docs link inventory. + +DASCore exposes most functionality through aliases: processing functions are +attached to Patch as methods (``Patch.taper = dascore.proc.taper``), objects +are re-exported at several import paths, and narrative docs link to modules. +great-docs only indexes the canonical location of each documented object, so +links written against an alias path (e.g. ``[taper](`dascore.Patch.taper`)``) +would not resolve. + +This script runs inside the great-docs build directory (wired via the +``pre_render`` key of great-docs.yml) after the API reference and +``objects.json`` are generated but before Quarto renders the site. It imports +dascore, resolves every inventory entry to its runtime object, and then adds +an inventory alias for every public access path that reaches a documented +object. Module links are pointed at their section of the API index page. + +The heavy lifting (link resolution in rendered HTML) stays in great-docs; +this only feeds it a richer inventory. +""" + +from __future__ import annotations + +import json +import os +import sys +from pathlib import Path + +OBJECTS_JSON = Path("objects.json") + +# Modules whose links should land on a section of the API index. +MODULE_SECTIONS = { + "dascore.core": "reference/index.html#core-classes", + "dascore.examples": "reference/index.html#example-data", + "dascore.exceptions": "reference/index.html#exceptions", + "dascore.io": "reference/index.html#io-interfaces", + "dascore.proc": "reference/index.html#patch-processing", + "dascore.transform": "reference/index.html#transforms", + "dascore.units": "reference/index.html#units-and-time", + "dascore.utils": "reference/index.html#utilities", + "dascore.viz": "reference/index.html#visualization", + "dascore.constants": "reference/index.html", +} + + +def _ensure_dascore(): + """Import dascore, re-execing with the project venv python if needed. + + Quarto runs pre-render scripts with whatever python it finds first, which + is not necessarily the environment dascore is installed in. + """ + try: + import dascore # noqa: F401 + + return + except ImportError: + pass + project_dir = Path(os.environ.get("QUARTO_PROJECT_DIR", ".")) + for candidate in ( + project_dir.parent / ".venv" / "bin" / "python", + project_dir.parent / ".venv" / "Scripts" / "python.exe", + ): + if candidate.is_file() and str(candidate) != sys.executable: + os.execv(str(candidate), [str(candidate), *sys.argv]) + raise SystemExit( + "greatdocs_alias_inventory: could not import dascore; install it in " + "the python environment quarto uses for pre-render scripts." + ) + + +def _unwrap(obj): + seen = set() + while getattr(obj, "__wrapped__", None) is not None and id(obj) not in seen: + seen.add(id(obj)) + obj = obj.__wrapped__ + return obj + + +def _resolve(name: str): + """Resolve a dotted inventory name to a runtime object, or None.""" + import dascore + + parts = name.split(".") + if parts[0] != "dascore": + return None + obj = dascore + for part in parts[1:]: + try: + obj = getattr(obj, part) + except AttributeError: + return None + return obj + + +def main() -> None: + _ensure_dascore() + import dascore as dc + + data = json.loads(OBJECTS_JSON.read_text()) + items = data["items"] + known = {it["name"] for it in items} + + # Map runtime object id -> best inventory item (prefer non-module roles, + # e.g. proc.taper the function page over proc.taper the module). + by_id: dict[int, dict] = {} + for it in items: + obj = _resolve(it["name"]) + if obj is None: + continue + current = by_id.get(id(_unwrap(obj))) + if current is None or (current["role"] == "module" and it["role"] != "module"): + by_id[id(_unwrap(obj))] = it + + new_items = [] + + def add_alias(name: str, target: dict) -> None: + if name in known: + return + known.add(name) + new_items.append( + { + "name": name, + "domain": "py", + "role": target["role"], + "priority": "2", + "uri": target["uri"], + "dispname": target.get("dispname", "-"), + } + ) + + # 1. Canonical module.qualname alias for every documented object (e.g. + # dascore.utils.patch.get_patch_names for BaseSpool.get_patch_names). + for target in by_id.values(): + obj = _resolve(target["name"]) + module = getattr(obj, "__module__", None) + qualname = getattr(obj, "__qualname__", None) + if module and qualname and "<" not in qualname: + add_alias(f"{module}.{qualname}", target) + + # 2. Aliases for public attributes of the documented core classes + # (covers the dynamically attached Patch/Spool methods). + from dascore.core.coords import BaseCoord + + for cls in (dc.Patch, dc.BaseSpool, dc.PatchAttrs, dc.CoordManager, BaseCoord): + prefixes = [f"dascore.{cls.__name__}", f"{cls.__module__}.{cls.__qualname__}"] + import dascore.core + + if getattr(dascore.core, cls.__name__, None) is cls: + prefixes.append(f"dascore.core.{cls.__name__}") + for attr in dir(cls): + if attr.startswith("_"): + continue + try: + target = by_id.get(id(_unwrap(getattr(cls, attr)))) + except Exception: + continue + if target is None: + continue + for prefix in prefixes: + add_alias(f"{prefix}.{attr}", target) + + # 3. Aliases for public re-exports one level below dascore and + # dascore.core (e.g. dascore.core.Patch, dascore.io.write). + import dascore.core + + for module in (dc, dc.core): + for attr in dir(module): + if attr.startswith("_"): + continue + try: + target = by_id.get(id(_unwrap(getattr(module, attr)))) + except Exception: + continue + if target is not None: + add_alias(f"{module.__name__}.{attr}", target) + + # 4. Module links -> API index sections. + for name, uri in MODULE_SECTIONS.items(): + add_alias(name, {"role": "module", "uri": uri, "dispname": "-"}) + + if new_items: + data["items"] = items + new_items + data["count"] = len(data["items"]) + OBJECTS_JSON.write_text(json.dumps(data, indent=1)) + print(f"greatdocs_alias_inventory: added {len(new_items)} alias entries") + + +if __name__ == "__main__": + main() diff --git a/tutorial/file_io.qmd b/tutorial/file_io.qmd index 28d558e98..da238781e 100644 --- a/tutorial/file_io.qmd +++ b/tutorial/file_io.qmd @@ -36,7 +36,7 @@ print(loaded.dims) ## Writing Patches to Disk -Patches can be written to disk using the `io` namespace. The following shows how to write a Patch to disk in the [DASDAE format](`dascore.io.dasdae`) +Patches can be written to disk using the `io` namespace. The following shows how to write a Patch to disk in the [DASDAE format](https://github.com/DASDAE/dascore/tree/master/dascore/io/dasdae) ```{python} from pathlib import Path From 234591a20998f0e2081788f4a10f935b56c262f5 Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Sat, 4 Jul 2026 21:27:26 +0200 Subject: [PATCH 04/22] Style docs with DASCore branding - Navy navbar with gold keyline and logo-derived accent colors (light/dark variants), APCA-picked navbar text - Lucide icons on top navigation entries - Navy headings, bordered h2s, softened code blocks via a small include_in_header stylesheet - Rewrite the landing page: hero carries the branding; drop the readme badge wall; installation first, then executable examples, citation, and support links - Hide the duplicate landing-page title and stop the navbar wordmark from truncating --- great-docs.yml | 47 ++++++++++++++++++++++++++++++ index.qmd | 79 +++++++++++++++++++------------------------------- 2 files changed, 77 insertions(+), 49 deletions(-) diff --git a/great-docs.yml b/great-docs.yml index 0ba674bdb..766d84f8c 100644 --- a/great-docs.yml +++ b/great-docs.yml @@ -28,6 +28,53 @@ logo: # keep resolving. pre_render: scripts/greatdocs_alias_inventory.py +# Branding: colors derived from the DASCore logo (navy #002868, +# red #D0002A, gold #FFC934). +accent_color: + light: "#00306E" + dark: "#8FB4F2" + +# Solid navy navbar (text color is auto-picked for contrast). +navbar_color: + light: "#002868" + dark: "#0B1730" + +# Lucide icons for the top navigation. +nav_icons: + navbar: + Tutorial: graduation-cap + Recipes: chef-hat + Notes: notebook-pen + Contributing: git-pull-request + About: info + Reference: library + Changelog: history + +# Small brand stylesheet: gold keyline under the navbar, navy headings, +# slightly softened code blocks. +include_in_header: + - text: | + + # Bibliography so citations (e.g. @lindsey2020broadband) in docstrings and # narrative pages resolve instead of hanging pandoc. bibliography: docs/references.bib diff --git a/index.qmd b/index.qmd index a02eae962..7b5a89af1 100644 --- a/index.qmd +++ b/index.qmd @@ -4,36 +4,6 @@ execute: warning: false --- -# DASCore - -A python library for distributed fiber optic sensing. - -[![coverage](https://codecov.io/gh/dasdae/dascore/branch/master/graph/badge.svg)](https://codecov.io/gh/dasdae/dascore) -[![CodSpeed Badge](https://img.shields.io/endpoint?url=https://codspeed.io/badge.json)](https://codspeed.io/DASDAE/dascore) -[![PyPI Version](https://img.shields.io/pypi/v/dascore.svg)](https://pypi.python.org/pypi/dascore) -[![supported versions](https://img.shields.io/pypi/pyversions/dascore.svg?label=python_versions)](https://pypi.python.org/pypi/dascore) -[![PyPI Downloads](https://img.shields.io/pypi/dm/dascore.svg?label=pypi)](https://pypi.org/project/dascore/) -[![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/dascore.svg?label=conda)](https://github.com/conda-forge/dascore-feedstock) -[![DOI](https://zenodo.org/badge/422627477.svg)](https://zenodo.org/badge/latestdoi/422627477) -[![Licence](https://www.gnu.org/graphics/lgplv3-88x31.png)](https://www.gnu.org/licenses/lgpl.html) - -[Code](https://github.com/DASDAE/dascore) - -Documentation [[stable](https://dascore.org), [development](https://dascore.netlify.app/)] - -[Citation](https://seismica.library.mcgill.ca/article/view/1184) - -> Chambers, D., Jin, G., Tourei, A., Issah, A. H. S., Lellouch, A., Martin, E., Zhu, D., Girard, A., Yuan, S., Cullison, T., Snyder, T., Kim, S., Danes, N., Pnithan, N., Boltz, M. S. & Mendoza, M. M. (2024). DASCore: a Python Library for Distributed Fiber Optic Sensing. Seismica, 3(2). - -[![Contributors](https://contrib.rocks/image?repo=DASDAE/dascore)](https://github.com/DASDAE/dascore/graphs/contributors) - - -:::{.callout minimal="true"} -Version-specific documentation builds are attached to the [release pages](https://github.com/DASDAE/dascore/releases). -::: - -# Highlights - DASCore is a Python library for distributed acoustic sensing (DAS). It provides: 1. IO support for [many DAS data formats](about/supported_formats.qmd) @@ -41,17 +11,35 @@ DASCore is a Python library for distributed acoustic sensing (DAS). It provides: 3. Basic visualizations :::{.callout-note} -DASCore is part of the [DAS Data Analysis Ecosystem (DASDAE)](https://dasdae.org). +DASCore is part of the [DAS Data Analysis Ecosystem (DASDAE)](https://dasdae.org). +Version-specific documentation builds are attached to the +[release pages](https://github.com/DASDAE/dascore/releases). ::: +# Installation + +Use pip or conda to install DASCore: + +```bash +pip install dascore +``` + +```bash +conda install dascore -c conda-forge +``` + +See [this recipe](recipes/docker_basic.qmd) for installation with Docker, and +the [contributing docs](contributing/contributing.qmd) for development +installations. + # Introductory usage ## Read a file ```{python} import dascore as dc -# Import fetch to read DASCore example files -from dascore.utils.downloader import fetch +# Import fetch to read DASCore example files +from dascore.utils.downloader import fetch # Fetch a sample file path from DASCore file_path = fetch('terra15_das_1_trimmed.hdf5') @@ -67,12 +55,12 @@ patch = spool[0] ```{python} #| output: false import dascore as dc -# Import fetch to read DASCore example files +# Import fetch to read DASCore example files from dascore.utils.downloader import fetch # Fetch a sample file path from DASCore (just to get a usable path for the rest of the cell) directory_path = fetch('terra15_das_1_trimmed.hdf5').parent -# To read a directory of DAS data stored locally on your machine, +# To read a directory of DAS data stored locally on your machine, # simply replace the above line with: # directory_path = "/path/to/data/directory/" @@ -114,7 +102,7 @@ out = ( # Decimate along time axis (keep every 8th sample) patch.decimate(time=8) # Detrend along the distance dimension - .detrend(dim='distance') + .detrend(dim='distance') # Apply 10Hz low-pass filter along time dimension .pass_filter(time=(..., 10)) ) @@ -130,24 +118,17 @@ patch = dc.get_example_patch('example_event_2') patch.viz.waterfall(show=True); ``` -# Installation +# Citation -Use pip or conda to install DASCore: +If you use DASCore in your work, please cite the +[Seismica article](https://seismica.library.mcgill.ca/article/view/1184): -```bash -pip install dascore -``` - -```bash -conda install dascore -c conda-forge -``` - -See [this recipe](recipes/docker_basic.qmd) for installation with Docker. - -See the [contributing docs](contributing/contributing.qmd) for development installations. +> Chambers, D., Jin, G., Tourei, A., Issah, A. H. S., Lellouch, A., Martin, E., Zhu, D., Girard, A., Yuan, S., Cullison, T., Snyder, T., Kim, S., Danes, N., Pnithan, N., Boltz, M. S. & Mendoza, M. M. (2024). DASCore: a Python Library for Distributed Fiber Optic Sensing. Seismica, 3(2). # Feedback and Support Use the [project discussions](https://github.com/DASDAE/dascore/discussions) to ask a question. Use the [project issues](https://github.com/DASDAE/dascore/issues) to report an issue. + +[![Contributors](https://contrib.rocks/image?repo=DASDAE/dascore)](https://github.com/DASDAE/dascore/graphs/contributors) From 9bbbd78482460481bd94575727930112c0283585 Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Mon, 20 Jul 2026 07:06:36 +0200 Subject: [PATCH 05/22] Reconcile great-docs build with current dev and fix rough edges Update the great-docs prototype to build cleanly against dev's current API and address several rendering issues surfaced by rebasing onto dev. great-docs.yml (API reference): - Drop members/objects removed on dev: Patch.assign_coords/iresample/ iselect/tran, PatchAttrs.coords_from_dims/dim_tuple/parse_coord_ attributes/rename_dimension, CoordManager.update_from_attrs, proc.BaseCoord.get_attrs_dict, transform.rfft/spectrogram, io.PyTables*. - Replace clients.dirspool.DirectorySpool with the unified Spool. - Restrict io.H5Reader/H5Writer to get_handle so griffe's dynamic introspection no longer recurses into the h5py.File constructor and fails; this keeps the whole API reference in dynamic mode, which resolves module-shadowing functions (proc.correlate, viz.waterfall, transform.hilbert, ...) to the function rather than framing them as modules. Build hooks and styling: - Add scripts/greatdocs_build_fixups.py (quarto pre_render) to undo the heading bump great-docs applies to code-cell comments in index.qmd, and to dedent/de-duplicate GitHub release bodies in changelog.qmd so their headings render instead of appearing as literal markdown. - Fix the homepage directory-spool example, which errored under dev's stricter spool selection, by making it an illustrative (non-executed) snippet. - CSS: wrap long sidebar entries at word boundaries and restore the "Notes" docstring callout box on API pages (shift-heading-level-by promotes it to h1, which great-docs' h2/h3 rule missed). CI: build_docs_greatdocs.yaml installs the docs/test/extras deps that the example pages import (pytest, findiff, xarray, obspy, ...). --- .github/workflows/build_docs_greatdocs.yaml | 5 +- great-docs.yml | 71 ++++++-- index.qmd | 11 +- scripts/greatdocs_build_fixups.py | 181 ++++++++++++++++++++ 4 files changed, 244 insertions(+), 24 deletions(-) create mode 100644 scripts/greatdocs_build_fixups.py diff --git a/.github/workflows/build_docs_greatdocs.yaml b/.github/workflows/build_docs_greatdocs.yaml index 2e83cadbb..0b8f5c4be 100644 --- a/.github/workflows/build_docs_greatdocs.yaml +++ b/.github/workflows/build_docs_greatdocs.yaml @@ -31,7 +31,10 @@ jobs: - name: Install dascore and great-docs run: | - python -m pip install -e ".[docs]" great-docs + # docs: doc-build helpers; test: pytest (used by some notes pages); + # extras: optional format/processing deps imported by example cells + # (findiff, xarray, obspy, ...). + python -m pip install -e ".[docs,test,extras]" great-docs - name: Prepare test data run: | diff --git a/great-docs.yml b/great-docs.yml index 766d84f8c..7571817f8 100644 --- a/great-docs.yml +++ b/great-docs.yml @@ -23,10 +23,15 @@ logo: alt: "DASCore logo" show_title: true -# Pre-render hook: add alias entries (Patch methods, re-export paths, -# module links) to the interlink inventory so alias-style cross references -# keep resolving. -pre_render: scripts/greatdocs_alias_inventory.py +# Pre-render hooks: +# - greatdocs_build_fixups.py patches generated index.qmd/changelog.qmd +# (undo code-comment heading bump, drop duplicate changelog version headings). +# - greatdocs_alias_inventory.py adds alias entries (Patch methods, re-export +# paths, module links) to the interlink inventory so alias-style cross +# references keep resolving. +pre_render: + - scripts/greatdocs_build_fixups.py + - scripts/greatdocs_alias_inventory.py # Branding: colors derived from the DASCore logo (navy #002868, # red #D0002A, gold #FFC934). @@ -73,6 +78,38 @@ include_in_header: .navbar .navbar-brand-container { flex-shrink: 0; } body:has(.gd-hero) main > header#title-block-header h1.title { display: none; } .sidebar nav[role="doc-toc"] a.active { font-weight: 600; } + /* Wrap long sidebar entries at word boundaries, not mid-word. */ + #quarto-sidebar .sidebar-item-text, + #quarto-sidebar .sidebar-item .menu-text { + overflow-wrap: break-word; + word-break: normal; + hyphens: none; + } + /* great-docs styles Notes docstring sections as a blue box for + h2/h3, but shift-heading-level-by promotes them to h1 on API + pages, dropping the box. Restore it for the h1 case. */ + section:has(> h1.doc-notes) { + border-left: 4px solid #3B82F6; + background-color: #EFF6FF; + padding: 0.75rem 1rem; + border-radius: 4px; + margin: 1rem 0; + color: #1f2937; + } + section:has(> h1.doc-notes) > h1.doc-notes { + font-size: 0.9rem; + font-weight: 600; + color: #1f2937; + margin: 0 0 0.25rem 0; + } + section:has(> h1.doc-notes) > h1.doc-notes::before { content: "\2139\FE0F\00a0"; } + section:has(> h1.doc-notes) > p { margin-bottom: 0; color: #1f2937; } + .quarto-dark section:has(> h1.doc-notes) { + background-color: rgba(59, 130, 246, 0.12); + color: #dbe4f0; + } + .quarto-dark section:has(> h1.doc-notes) > h1.doc-notes, + .quarto-dark section:has(> h1.doc-notes) > p { color: #dbe4f0; } # Bibliography so citations (e.g. @lindsey2020broadband) in docstrings and @@ -163,16 +200,17 @@ reference: desc: The central data structures of DASCore contents: - name: Patch - members: [data, coords, dims, attrs, shape, size, ndim, dtype, seconds, channel_count, coord_shapes, assign_coords, get_patch_name, iresample, iselect, tran, T] + members: [data, coords, dims, attrs, shape, size, ndim, dtype, seconds, channel_count, coord_shapes, get_patch_name, T] - name: BaseSpool members: [chunk, concatenate, get_contents, get_patch_names, map, select, sort, split, update, viz] - - clients.dirspool.DirectorySpool + - name: Spool + members: [from_directory, from_file, chunk_plan, stack, spool_path, indexer, has_live_patches] - name: PatchAttrs - members: [coords_from_dims, dim_tuple, drop, drop_private, flat_dump, from_dict, get, get_summary_df, items, parse_coord_attributes, rename_dimension, update] + members: [drop, drop_private, flat_dump, from_dict, get, get_summary_df, items, update] - name: CoordManager - members: [convert_units, coord_range, coord_shapes, coord_size, decimate, dim_to_coord_map, disassociate_coord, drop_coords, drop_disassociated_coords, drop_private_coords, equals, flip, get_array, get_axis, get_coord, get_coord_tuple_map, keys, make_broadcastable_to, max, min, ndim, new, order, rename_coord, select, set_dims, set_units, shape, simplify_units, size, snap, sort, squeeze, step, to_summary_dict, transpose, update, update_from_attrs, validate_data] + members: [convert_units, coord_range, coord_shapes, coord_size, decimate, dim_to_coord_map, disassociate_coord, drop_coords, drop_disassociated_coords, drop_private_coords, equals, flip, get_array, get_axis, get_coord, get_coord_tuple_map, keys, make_broadcastable_to, max, min, ndim, new, order, rename_coord, select, set_dims, set_units, shape, simplify_units, size, snap, sort, squeeze, step, to_summary_dict, transpose, update, validate_data] - name: proc.BaseCoord - members: [align_to, approx_equal, change_length, convert_units, coord_range, empty, get_attrs_dict, get_next_index, get_sample_count, get_slice_tuple, index, max, min, new, order, reduce_coord, select, set_units, simplify_units, snap, sort, to_summary, update, update_data, update_limits] + members: [align_to, approx_equal, change_length, convert_units, coord_range, empty, get_next_index, get_sample_count, get_slice_tuple, index, max, min, new, order, reduce_coord, select, set_units, simplify_units, snap, sort, to_summary, update, update_data, update_limits] - get_coord - get_coord_manager @@ -252,10 +290,8 @@ reference: contents: - transform.dft - transform.idft - - transform.rfft - transform.stft - transform.istft - - transform.spectrogram - transform.envelope - transform.differentiate - transform.fbe @@ -338,10 +374,15 @@ reference: - io.patch_to_xarray - io.BinaryReader - io.BinaryWriter - - io.H5Reader - - io.H5Writer - - io.PyTablesReader - - io.PyTablesWriter + # Restrict to the public method: documenting the `constructor` class + # attribute (h5py.File) makes griffe's dynamic introspection fail while + # resolving h5py internals, which would drop the whole API reference to + # static analysis (mis-framing module-shadowing functions like + # proc.correlate as modules). + - name: io.H5Reader + members: [get_handle] + - name: io.H5Writer + members: [get_handle] - title: Utilities desc: Assorted helper utilities diff --git a/index.qmd b/index.qmd index 7b5a89af1..b43de19e9 100644 --- a/index.qmd +++ b/index.qmd @@ -53,16 +53,11 @@ patch = spool[0] ## Working with a directory of DAS files ```{python} -#| output: false +#| eval: false import dascore as dc -# Import fetch to read DASCore example files -from dascore.utils.downloader import fetch -# Fetch a sample file path from DASCore (just to get a usable path for the rest of the cell) -directory_path = fetch('terra15_das_1_trimmed.hdf5').parent -# To read a directory of DAS data stored locally on your machine, -# simply replace the above line with: -# directory_path = "/path/to/data/directory/" +# Point this at a directory of DAS files on your machine. +directory_path = "/path/to/data/directory/" spool = ( # Create a spool to interact with directory data diff --git a/scripts/greatdocs_build_fixups.py b/scripts/greatdocs_build_fixups.py new file mode 100644 index 000000000..12883616d --- /dev/null +++ b/scripts/greatdocs_build_fixups.py @@ -0,0 +1,181 @@ +""" +Quarto pre-render hook: patch great-docs-generated pages before rendering. + +great-docs generates two pages whose content needs small post-processing that +the tool does not (yet) do itself. This script runs inside the great-docs build +directory (wired via the ``pre_render`` key of great-docs.yml), after the pages +are generated but before Quarto renders them. + +1. ``index.qmd`` — great-docs builds the landing page from the repo readme and + bumps every ``#`` heading one level (``#`` -> ``##``) so the page nests under + its title. That regex also rewrites ``#`` comment lines *inside* fenced code + cells, so ``# import ...`` renders as ``## import ...``. We undo the bump for + ``##``-or-deeper lines that sit inside code fences. + +2. ``changelog.qmd`` — each release section already gets a + ``## {version} {.changelog-version}`` heading from great-docs, but the GitHub + release body usually *also* starts with a ``# {version}`` heading. That + duplicate renders as a stray paragraph or a repeated heading. We drop the + leading body heading when its text matches the section's version. + +Both fixes are written to be safe to run anywhere: the index fix only touches +``##``-or-deeper lines (repo-source comments are single ``#`` and are left +alone), and missing files are skipped. +""" + +from __future__ import annotations + +import re +from pathlib import Path + +FENCE_RE = re.compile(r"^\s*(`{3,}|~{3,})") +# A code-comment line that great-docs over-bumped (two or more leading #). +BUMPED_COMMENT_RE = re.compile(r"^(#{2,})(\s)") +HEADING_RE = re.compile(r"^\s*(#{1,6})\s+(.*?)\s*$") +CHANGELOG_VERSION_RE = re.compile(r"^#{1,6}\s+(.*?)\s*\{\.changelog-version\}\s*$") +DATE_LINE_RE = re.compile(r"^\s*\*.*\[GitHub\]") + + +def fix_index(path: Path) -> int: + """De-bump ``#`` comment lines that great-docs doubled inside code fences.""" + if not path.exists(): + return 0 + lines = path.read_text(encoding="utf-8").split("\n") + in_fence = False + marker = "" + changed = 0 + for i, line in enumerate(lines): + m = FENCE_RE.match(line) + if m: + mk = m.group(1)[0] + if not in_fence: + in_fence, marker = True, mk + elif mk == marker: + in_fence, marker = False, "" + continue + if in_fence: + bm = BUMPED_COMMENT_RE.match(line) + if bm: + lines[i] = line[1:] # drop one leading '#' + changed += 1 + if changed: + path.write_text("\n".join(lines), encoding="utf-8") + return changed + + +def _fix_release_body(version: str, body: list[str]) -> tuple[list[str], int, int]: + """Clean one release body: drop a duplicate version heading and dedent. + + Some GitHub release bodies are uniformly indented (~2 spaces). great-docs' + ``.strip()`` un-indents only the *first* line of the body, so the rest stay + indented and pandoc renders their ``### ...`` headings as literal text. We + split off the date line, drop a leading heading that repeats the version, + then strip the body's base indent from every line. The base indent is taken + from the note lines *after* the anomalous first line, and we remove at most + that many leading spaces per line so relative nesting (e.g. list-item + continuations) is preserved. + """ + dropped = deindented = 0 + # Keep the leading date line (and blanks before it) outside the dedent. + head: list[str] = [] + idx = 0 + while idx < len(body): + head.append(body[idx]) + if DATE_LINE_RE.match(body[idx]): + idx += 1 + break + idx += 1 + note = body[idx:] + + # Drop a leading heading that just repeats the version. + j = 0 + while j < len(note) and note[j].strip() == "": + j += 1 + if j < len(note): + hm = HEADING_RE.match(note[j]) + if hm and hm.group(2).strip() == version: + note = note[:j] + note[j + 1 :] + dropped = 1 + + # Base indent = the most common leading indent among non-blank lines. Using + # the mode (not the min) is robust to the anomalous 0-indent lines these + # bodies contain: the generator un-indents the first line, and GitHub's + # auto-generated "**Full Changelog**" footer also sits at column 0. + indents = [len(ln) - len(ln.lstrip(" ")) for ln in note if ln.strip()] + base = 0 + if indents: + counts: dict[int, int] = {} + for ind in indents: + counts[ind] = counts.get(ind, 0) + 1 + # Highest count wins; ties resolve to the smaller indent. + base = min(counts, key=lambda k: (-counts[k], k)) + if base: + strip_re = re.compile(r"^ {1,%d}" % base) + new_note = [strip_re.sub("", ln) for ln in note] + if new_note != note: + note = new_note + deindented = 1 + return head + note, dropped, deindented + + +def fix_changelog(path: Path) -> int: + """Drop duplicate version headings and dedent indented release bodies.""" + if not path.exists(): + return 0 + lines = path.read_text(encoding="utf-8").split("\n") + + # Find the frontmatter/preamble, then split into per-release blocks at each + # `{.changelog-version}` heading. + out: list[str] = [] + i = 0 + version: str | None = None + block: list[str] = [] + dropped = deindented = 0 + + def flush() -> None: + nonlocal dropped, deindented + if version is None: + out.extend(block) + return + fixed, d, di = _fix_release_body(version, block) + dropped += d + deindented += di + out.extend(fixed) + + for line in lines: + vm = CHANGELOG_VERSION_RE.match(line) + if vm: + flush() + out.append(line) + version = vm.group(1).strip() + block = [] + elif version is None: + out.append(line) + else: + block.append(line) + flush() + + if dropped or deindented: + # Collapse runs of blank lines left behind to a single blank line. + collapsed: list[str] = [] + for ln in out: + if ln.strip() == "" and collapsed and collapsed[-1].strip() == "": + continue + collapsed.append(ln) + path.write_text("\n".join(collapsed), encoding="utf-8") + return dropped + deindented + + +def main() -> int: + cwd = Path.cwd() + n_index = fix_index(cwd / "index.qmd") + n_changelog = fix_changelog(cwd / "changelog.qmd") + print( + f"greatdocs_build_fixups: de-bumped {n_index} code-comment line(s) in " + f"index.qmd, dropped {n_changelog} duplicate changelog heading(s)." + ) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From 05ae07b81edfd0a39c690868dafb7cf2f0d45dc2 Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Mon, 20 Jul 2026 07:06:52 +0200 Subject: [PATCH 06/22] Polish great-docs narrative pages: headings and card descriptions Fix heading levels and enrich section-index cards across the tutorial, recipes, notes, contributing, and about sections. - Demote headings by one level in pages that used `#` for their top sections. Under great-docs' `shift-heading-level-by: -1` those `#` headings rendered as plain paragraphs and were missing from the page TOC; they now render as real headings. Code-cell comments are left untouched. Pages that already used `##` sections are unchanged. - Give the few pages that relied on a bare `#` title (or an empty frontmatter block) an explicit frontmatter `title:` so the title renders correctly. - Add a `description:` to every card-index page so the recipes/notes/ contributing/about landing pages show informative cards instead of bare titles. --- about/acknowledgements.qmd | 4 +- about/contributors.qmd | 5 +- about/supported_formats.qmd | 1 + contributing/adding_test_data.qmd | 5 +- contributing/code_of_conduct.qmd | 6 +- contributing/contributing.qmd | 9 +-- contributing/dev_install.qmd | 13 ++-- contributing/documentation.qmd | 19 ++--- contributing/extending_dascore.qmd | 1 + contributing/general_guidelines.qmd | 9 +-- contributing/new_format.qmd | 1 + contributing/profiling_benchmarks.qmd | 5 +- contributing/publish_a_new_release.qmd | 1 + contributing/style_and_linting.qmd | 5 +- contributing/testing.qmd | 5 +- notes/coordinate_internals.qmd | 1 + notes/dft_notes.qmd | 5 +- notes/doc_strategy.qmd | 1 + notes/notes.qmd | 1 + notes/patch_attrs.qmd | 1 + notes/spool_chunking.qmd | 1 + notes/spool_index.qmd | 1 + notes/spool_selection.qmd | 1 + notes/velocity_to_strain_rate.qmd | 1 + recipes/add_spatial_coordinates_to_patch.qmd | 1 + recipes/contributing_to_documentation.qmd | 1 + recipes/correlate.qmd | 1 + recipes/despiking.qmd | 1 + recipes/docker_basic.qmd | 1 + recipes/edge_effects.qmd | 1 + recipes/external_conversion.qmd | 1 + recipes/fk.qmd | 1 + recipes/how_to_contribute.qmd | 21 +++--- recipes/low_freq_proc.qmd | 1 + recipes/overview.qmd | 1 + recipes/parallelization.qmd | 19 ++--- recipes/plotting_channel_number.qmd | 1 + recipes/real_time_proc.qmd | 1 + recipes/smoothing.qmd | 1 + tutorial/concepts.qmd | 8 +-- tutorial/coords.qmd | 40 +++++------ tutorial/patch.qmd | 76 ++++++++++---------- tutorial/processing.qmd | 24 +++---- tutorial/spool.qmd | 24 +++---- tutorial/transformations.qmd | 4 +- tutorial/visualization.qmd | 8 +-- 46 files changed, 191 insertions(+), 148 deletions(-) diff --git a/about/acknowledgements.qmd b/about/acknowledgements.qmd index 102c5a840..d8dee05ea 100644 --- a/about/acknowledgements.qmd +++ b/about/acknowledgements.qmd @@ -1,10 +1,10 @@ --- +title: Acknowledgments +description: "Funding sources and acknowledgments." --- -# Acknowledgments - - DASDAE is supported in part by the NSF Geoinformatics Program, under grant [#2148614](https://nsf.gov/awardsearch/showAward?AWD_ID=2148614) diff --git a/about/contributors.qmd b/about/contributors.qmd index 9f117d85c..1e8e29e8b 100644 --- a/about/contributors.qmd +++ b/about/contributors.qmd @@ -1,3 +1,6 @@ -# Contributors +--- +title: Contributors +description: "Thanks to everyone who has contributed to DASCore." +--- A huge thanks to [all the DASCore contributors](https://github.com/DASDAE/dascore/graphs/contributors)! diff --git a/about/supported_formats.qmd b/about/supported_formats.qmd index 22e8fa462..8b80f1857 100644 --- a/about/supported_formats.qmd +++ b/about/supported_formats.qmd @@ -1,5 +1,6 @@ --- title: Supported File Formats +description: "File formats DASCore can read and write." execute: warning: false --- diff --git a/contributing/adding_test_data.qmd b/contributing/adding_test_data.qmd index deb19438b..bf87ff1e0 100644 --- a/contributing/adding_test_data.qmd +++ b/contributing/adding_test_data.qmd @@ -1,10 +1,11 @@ --- title: Adding Test Data +description: "How to add small test files and generated patches to DASCore." --- There are a few different way to add test data to dascore. The key, however, is to ensure test files and generated patches are small (a few mb at most) so the documentation and test suite still run quickly. -# Adding functions which create example data +## Adding functions which create example data The [examples module](`dascore.examples`) contains several functions for creating example `Patch` and `Spool` instances. You can add a new function in that module which creates a new patch or spool, then just register the function so it can be called from `dc.get_example_patch` or `dc.get_example_spool`. These should be simple objects which can be generated within python. If you need to download a file see [adding a data file](#adding_a_data_file). @@ -41,7 +42,7 @@ spool_example = dc.get_example_spool("new_das_spool") If, in the test code, the example patch or spool is used only once, just call the get_example function in the test. If it is needed multiple times, consider putting it in a fixture. See [testing](./testing.qmd) for more on fixtures. -# Adding a data file +## Adding a data file Of course, not all data can easily be generated in python. For example, testing [support for new file formats](./new_format.qmd) typically requires a test file. diff --git a/contributing/code_of_conduct.qmd b/contributing/code_of_conduct.qmd index da65e7a57..ccb5c6445 100644 --- a/contributing/code_of_conduct.qmd +++ b/contributing/code_of_conduct.qmd @@ -1,5 +1,7 @@ - -# Contributor Covenant Code of Conduct +--- +title: Contributor Covenant Code of Conduct +description: "The Contributor Covenant standards for our community." +--- ## Our Pledge diff --git a/contributing/contributing.qmd b/contributing/contributing.qmd index 3d074698e..020673820 100644 --- a/contributing/contributing.qmd +++ b/contributing/contributing.qmd @@ -1,11 +1,12 @@ --- title: Contributing +description: "How to get involved and contribute to DASCore." --- Contributions to DASCore are welcomed and appreciated. Before contributing please be aware of our [code of conduct](code_of_conduct.qmd). -# Prerequisites +## Prerequisites To start, clone DASCore and [install it in development mode](dev_install.qmd). If you are new to contributing to open-source projects, this [recipe](../recipes/how_to_contribute.qmd) provides step-by-step instructions. @@ -14,17 +15,17 @@ Review how [DASCore's testing](testing.qmd) works, [how DASCore is documented](d -# Planning +## Planning Development planning and prioritization takes place [here](https://github.com/orgs/DASDAE/projects/2). -# DASCore or other DASDAE packages +## DASCore or other DASDAE packages You may wonder whether a new feature you'd like to add belongs in DASCore, or if it should be part of another [DASDAE](https://github.com/DASDAE) package. The guiding principle is that if it does not require additional dependencies and is not particularly specialized to one sub-area of applied seismology, then it can be part of DASCore. What if the feature you're interested in adding is generally applicable for many kinds of DAS data analysis, but requires some additional package dependency? If this is the case, open a discussion describing the feature, the additional dependency, and (optional but encouraged) other future features that may also share this dependency. Typically we'll try to come to a clear consensus, then you can move ahead with development. If the proposed DASCore dependency addition appears to be controversial, then you will deliver a short presentation at one of the bi-weekly DASDAE developer team check-ins that should describe the feature, the additional dependency (including the approximate size of the additional software to be installed), and ideas for other features this dependency could enable. Then the developer community in attendance will discuss the proposed change and take a vote (majority approval required). If you are interested in creating a new [DASDAE](https://github.com/DASDAE) package which uses DASCore as a dependency, you are not required to hold it to the same style and testing guidelines as DASCore, but you are encouraged to do so, and can use DASCore's setup as an example. Following a common set of style and contributor workflows will make it easier for us to develop a community of DASDAE developers who can easily move between using and developing any of the DASDAE packages. -# Leadership +## Leadership Currently DASCore operates in BDFL mode during its initial construction phase, with Derrick Chambers leading the oversight of the master branch, but this is not intended to be the mode of operation in the future. At a DASDAE developer team check-in (currently biweekly), the team reviews contributions and nominates a leadership team for the next cycle based on contribution history. diff --git a/contributing/dev_install.qmd b/contributing/dev_install.qmd index b4d86ee90..c74e0d042 100644 --- a/contributing/dev_install.qmd +++ b/contributing/dev_install.qmd @@ -1,17 +1,18 @@ --- title: DASCore Development Installation +description: "Set up DASCore for local development." --- The following steps are needed to set up `DASCore` for development: -## 1. Clone DASCore +### 1. Clone DASCore ```bash git clone https://github.com/dasdae/dascore cd dascore ``` -## 2. Pull tags +### 2. Pull tags Make sure to pull all of the latest git tags. @@ -20,7 +21,7 @@ Make sure to pull all of the latest git tags. git pull origin master --tags ``` -## 3. Create a virtual environment (optional) +### 3. Create a virtual environment (optional) Create and activate a virtual environment so DASCore will not mess with the base (or system) python installation. @@ -38,7 +39,7 @@ conda env create -f environment.yml conda activate dascore ``` -## 4. Install DASCore in development mode +### 4. Install DASCore in development mode ```bash pip install -e ".[dev]" @@ -50,7 +51,7 @@ If you created the environment with `uv venv`, use `uv pip` instead. A uv virtua uv pip install -e ".[dev]" ``` -## 5. Setup pre-commit hooks +### 5. Setup pre-commit hooks dascore uses several [pre-commit](https://pre-commit.com/) hooks to ensure the code stays tidy. Please install and use them! @@ -58,7 +59,7 @@ dascore uses several [pre-commit](https://pre-commit.com/) hooks to ensure the c pre-commit install -f ``` -# Refresh +## Refresh If you have already installed dascore but it has been a while, please do the following before creating a new branch: diff --git a/contributing/documentation.qmd b/contributing/documentation.qmd index aa0c78117..37fc3d1b7 100644 --- a/contributing/documentation.qmd +++ b/contributing/documentation.qmd @@ -1,15 +1,16 @@ --- title: Documentation +description: "The levels of DASCore documentation and how they fit together." --- There are several levels of documentation in DASCore. These include: code comments (which are primarily for developers), docstrings (which are used to generate the API docs), and markdown documentation pages like this one which have a .qmd extension. -# Code comments +## Code comments Code comments are primarily for developers. They should describe useful information and not just restate obvious parts of the code. Consider refactoring with better named variables or smaller, well named functions if you find yourself making lots of these types of comments. Don't be afraid to make multi-line comments if needed. -# Doc-Strings +## Doc-Strings Use [numpy style docstrings](https://numpydoc.readthedocs.io/en/latest/format.html). All public code (doesn't start with a `_`) should have a "full" docstring but private code (starts with a `_`) can have an abbreviated docstring. @@ -69,7 +70,7 @@ def _recombobulate(df, arg1, arg2): ``` -## Examples in docstrings +### Examples in docstrings Examples in docstrings can be done using the standard [doctest](https://docs.python.org/3/library/doctest.html) syntax as above, or [quarto code blocks](https://quarto.org/docs/output-formats/html-code.html) can be used directly. The latter gives more control over outputs and display options. @@ -95,7 +96,7 @@ would produce the following code in the examples section: ````raw ```{{python}} #| code-fold: true -# This is a base example +## This is a base example print(1 + 2) ``` ### This is a sub-section @@ -105,7 +106,7 @@ print("cool beans") ``` ```` -# Generating Documentation +## Generating Documentation DASCore's documentation is built with [great-docs](https://posit-dev.github.io/great-docs/), which is based on [quarto](https://quarto.org/). In order to build the documentation, you must first [install DASCore in development mode](dev_install.qmd), [install quarto](https://quarto.org/docs/get-started/), then install great-docs: @@ -132,7 +133,7 @@ The site structure, the curated API reference, and everything else about the bui The great-docs/ directory is an ephemeral build directory; do not edit or commit it. ::: -# Cross references +## Cross references Cross references provide a means of linking parts of the documentation to the API docs for specific modules, classes, functions, or methods. They work just like normal markdown links except the reference is a dascore object surrounded by backticks like so: @@ -154,7 +155,7 @@ See the [patch tutorial](/tutorial/patch.qmd) for examples. Cross references can be used in both docstrings and the qmd documentation pages. -# Referencing publications +## Referencing publications New references should be added to the references.bib file in the docs folder. @@ -169,7 +170,7 @@ Citing @lindsey2021fiber or [@lindsey2021fiber] References then show up at the bottom of the page, or if the mouse pointer hovers over the link. -# Equations +## Equations Equations use standard LaTeX. Inline equations ($E=mc^2$) are surrounded by a single dollar sign (`$`) like this: `$E=mc^2$`. Multiline equations start and end with double dollar signs (`$$`) and can be given a referenceable label. For example: @@ -195,6 +196,6 @@ $${#eq-rotations} and @eq-rotations is referenced by `@eq-rotations`. -# Additional Tips +## Additional Tips For more information about figure alignment, code blocks, formatting, etc. checkout the excellent [quarto docs](https://quarto.org/). diff --git a/contributing/extending_dascore.qmd b/contributing/extending_dascore.qmd index 1d7d82a6b..d71708964 100644 --- a/contributing/extending_dascore.qmd +++ b/contributing/extending_dascore.qmd @@ -1,5 +1,6 @@ --- title: Extending DASCore +description: "Add custom Patch and Spool namespaces via plugins." --- This page explains how to extend DASCore with `Patch` and `Spool` namespaces. Use it when you want users to write code like `patch.my_plugin.some_method()` or `spool.my_plugin.some_method()` from a separate package. diff --git a/contributing/general_guidelines.qmd b/contributing/general_guidelines.qmd index 741b3b041..5990538f6 100644 --- a/contributing/general_guidelines.qmd +++ b/contributing/general_guidelines.qmd @@ -1,9 +1,10 @@ --- title: Guidelines +description: "A few guidelines to follow when developing DASCore." --- This page highlights a few guidelines for DASCore development. -# Branching and versioning +## Branching and versioning We create new features or bug fixes in their own branches and merge them into `dev` via pull requests. `dev` is the integration branch; it is merged into `master` at release time. We may switch to a more complex branching model if @@ -15,7 +16,7 @@ follow [semantic versioning](https://semver.org/), meaning we will not bump the is more stable. -# Changelog entries +## Changelog entries DASCore keeps no changelog file; the [release notes](https://github.com/DASDAE/dascore/releases) are assembled from merged pull requests. Every pull request therefore needs a `## Changelog` section, which CI checks. Write one bullet @@ -32,12 +33,12 @@ Write the text after the colon as a complete sentence, with a subject and a verb `none` may be written bare or as the section's only bullet (`- none`); both pass. -# Paths +## Paths Prefer `pathlib.Path` to strings when working with paths. However, when dealing with many many files (e.g., indexers) strings may be preferred for efficiency. -# Working with dataframes +## Working with dataframes Column names should be snake_cased whenever possible. diff --git a/contributing/new_format.qmd b/contributing/new_format.qmd index 12085e4f2..824b0f8bd 100644 --- a/contributing/new_format.qmd +++ b/contributing/new_format.qmd @@ -1,5 +1,6 @@ --- title: Adding a New Format +description: "Add IO support for a new file format." --- This page details how to add IO support for a new format to DASCore. The steps are: diff --git a/contributing/profiling_benchmarks.qmd b/contributing/profiling_benchmarks.qmd index bd4b23b88..fe3724f87 100644 --- a/contributing/profiling_benchmarks.qmd +++ b/contributing/profiling_benchmarks.qmd @@ -1,7 +1,8 @@ --- title: Profiling and Benchmarks +description: "Run and write DASCore's CodSpeed benchmark suite." --- -# Benchmarks +## Benchmarks DASCore uses [codspeed](https://codspeed.io/) to create and run a simple benchmark suite. The benchmarks are found in the benchmarks folder at the top level of the repository. @@ -14,7 +15,7 @@ However, when you create a pull request, the benchmarks will be run in the CI/CD If you add significant new functionality, you should probably add a benchmark. -# Profiling +## Profiling If you find a significant issue, you can profile the problematic benchmark(s) to see *why* their performance degraded. This can be done with the [pytest profile plugin](https://pypi.org/project/pytest-profiling/). diff --git a/contributing/publish_a_new_release.qmd b/contributing/publish_a_new_release.qmd index 3ce102298..ef55f357b 100644 --- a/contributing/publish_a_new_release.qmd +++ b/contributing/publish_a_new_release.qmd @@ -1,5 +1,6 @@ --- title: "Publish a new release" +description: "The maintainer workflow for publishing a DASCore release." --- This page describes the maintainer workflow for publishing a DASCore release. DASCore's package version is derived from git tags, so the release tag is the source of truth and no version file needs to be edited by hand. diff --git a/contributing/style_and_linting.qmd b/contributing/style_and_linting.qmd index 8c34281d2..d76730983 100644 --- a/contributing/style_and_linting.qmd +++ b/contributing/style_and_linting.qmd @@ -1,8 +1,9 @@ --- title: "Style and Linting" +description: "Code style and linting conventions (Black, flake8)." --- -# Linting +## Linting DASCore uses [Black](https://github.com/ambv/black) and [flake8](http://flake8.pycqa.org/en/latest/) for code linting. If you have [properly installed DASCore's pre-commit hooks](dev_install.qmd#setup-pre-commit-hooks) they will be @@ -17,7 +18,7 @@ pre-commit run --all It is often useful to run this command twice before making changes because many of the hooks will automatically fix the issue they raise on the first run. -# Type Hints +## Type Hints DASCore makes extensive use of Python 3's [type hints](https://docs.python.org/3/library/typing.html). Use them to annotate any public functions/methods. See the docstring section of the [documentation page](documentation.qmd) diff --git a/contributing/testing.qmd b/contributing/testing.qmd index 5fab6207c..cb036aee5 100644 --- a/contributing/testing.qmd +++ b/contributing/testing.qmd @@ -1,8 +1,9 @@ --- title: "Testing" +description: "Run and write DASCore's pytest test suite." --- -# Testing +## Testing DASCore's test suite is run with [pytest](https://docs.pytest.org/en/stable/). While in the base dascore repo (and after [installing DASCore for development](dev_install.qmd)) invoke pytest from the command line: @@ -59,7 +60,7 @@ pytest tests/test_autogenerated_doccode The `tests/test_autogenerated_doccode` directory is intentionally gitignored and should be regenerated locally rather than committed. -## Writing Tests +### Writing Tests Tests should go into the `tests/` folder, which mirrors the structure of the main package. For example, if you are writing tests for `dascore.Patch`, whose class definition is diff --git a/notes/coordinate_internals.qmd b/notes/coordinate_internals.qmd index 267c0bba7..526fb5391 100644 --- a/notes/coordinate_internals.qmd +++ b/notes/coordinate_internals.qmd @@ -1,5 +1,6 @@ --- title: Coordinate Internals +description: "The internal coordinate model, including string-coordinate handling." --- This note explains the current internal coordinate model in DASCore, with particular attention to exact values, segmented coordinates, summaries, and scan payloads. diff --git a/notes/dft_notes.qmd b/notes/dft_notes.qmd index 8d5860eeb..aa818762e 100644 --- a/notes/dft_notes.qmd +++ b/notes/dft_notes.qmd @@ -1,4 +1,7 @@ -# Fourier Transforms in DASCore +--- +title: Fourier Transforms in DASCore +description: "The reasoning behind DASCore's Fourier transform implementation." +--- These notes provide the reasoning for DASCore's [fourier](/reference/index.qmd#transforms) module implementation. diff --git a/notes/doc_strategy.qmd b/notes/doc_strategy.qmd index c76ad5f5e..f1a4b706d 100644 --- a/notes/doc_strategy.qmd +++ b/notes/doc_strategy.qmd @@ -1,5 +1,6 @@ --- title: DASCore Documentation Strategy +description: "How DASCore's documentation follows the Diataxis framework." --- DASCore's documentation follows the [Diátaxis](https://diataxis.fr/) approach. In this system, developed by Daniele Procida, there are four types of documentation with different goals: diff --git a/notes/notes.qmd b/notes/notes.qmd index 0c60a8997..a635f226b 100644 --- a/notes/notes.qmd +++ b/notes/notes.qmd @@ -1,5 +1,6 @@ --- title: Notes +description: "Understanding-oriented explanations of DASCore's design and implementation." --- This section provides understanding-oriented explanations of DASCore implementation and design decisions. diff --git a/notes/patch_attrs.qmd b/notes/patch_attrs.qmd index 50e221f51..136b30efc 100644 --- a/notes/patch_attrs.qmd +++ b/notes/patch_attrs.qmd @@ -1,5 +1,6 @@ --- title: PatchAttrs +description: "How PatchAttrs stores identity, coordinate, and data metadata for a patch." --- [`PatchAttrs`](`dascore.core.attrs.PatchAttrs`) stores non-coordinate metadata about a [`Patch`](`dascore.Patch`), including measurement labels, instrument identity, data units, processing history, and format-specific fields. Coordinate values and summaries are deliberately owned elsewhere. diff --git a/notes/spool_chunking.qmd b/notes/spool_chunking.qmd index a2da0cd34..c450acd51 100644 --- a/notes/spool_chunking.qmd +++ b/notes/spool_chunking.qmd @@ -1,5 +1,6 @@ --- title: Spool Chunking +description: "How Spool.chunk plans and assembles chunked patch data." --- `Spool.chunk` runs in two stages: a **planner** decides everything from metadata alone, and **assembly** loads, trims, and combines patch data only when a patch is requested. The code cells below execute against the real machinery, so this note fails the doc build if it drifts from the implementation. diff --git a/notes/spool_index.qmd b/notes/spool_index.qmd index 240cb891f..626792b24 100644 --- a/notes/spool_index.qmd +++ b/notes/spool_index.qmd @@ -1,5 +1,6 @@ --- title: Spool Index +description: "The shared metadata model and SQLite directory index behind spools." --- Directory and in-memory spools use the same metadata model. The persisted directory index is one SQLite file named `.dascore_index.sqlite3`; in-memory spools use the same schema in an in-memory SQLite database. The index stores summaries and source identities, not patch data. diff --git a/notes/spool_selection.qmd b/notes/spool_selection.qmd index 51a66d027..51c968d0c 100644 --- a/notes/spool_selection.qmd +++ b/notes/spool_selection.qmd @@ -1,5 +1,6 @@ --- title: Spool Selection +description: "How Spool.select filters memory and directory spools." --- `Spool.select` uses one selector model for memory and directory spools. Patch-list and directory spools compose selections in a `PatchCatalog`; ordinary metadata predicates are pushed into SQLite and remain lazy until contents, length, indexing, or iteration requires rows. diff --git a/notes/velocity_to_strain_rate.qmd b/notes/velocity_to_strain_rate.qmd index 03bd00983..a91c915d9 100644 --- a/notes/velocity_to_strain_rate.qmd +++ b/notes/velocity_to_strain_rate.qmd @@ -1,5 +1,6 @@ --- title: "Velocity to Strain Rate" +description: "Subtleties of converting velocity-format patches to strain rate." execute: warn: false --- diff --git a/recipes/add_spatial_coordinates_to_patch.qmd b/recipes/add_spatial_coordinates_to_patch.qmd index 6d00dfde3..9bc368f84 100644 --- a/recipes/add_spatial_coordinates_to_patch.qmd +++ b/recipes/add_spatial_coordinates_to_patch.qmd @@ -1,5 +1,6 @@ --- title: Add Spatial Coordinates +description: "Attach tabulated spatial coordinates (e.g. from a tap test) to a patch dimension." execute: warning: false --- diff --git a/recipes/contributing_to_documentation.qmd b/recipes/contributing_to_documentation.qmd index 034d45784..d7195d26a 100644 --- a/recipes/contributing_to_documentation.qmd +++ b/recipes/contributing_to_documentation.qmd @@ -1,5 +1,6 @@ --- title: Contributing to Documentation +description: "Build the docs locally and make changes to DASCore's documentation." --- Here, we elaborate on how you can build new documentation or make changes to existing DASCore documentation. diff --git a/recipes/correlate.qmd b/recipes/correlate.qmd index 21182d8be..24c752107 100644 --- a/recipes/correlate.qmd +++ b/recipes/correlate.qmd @@ -1,5 +1,6 @@ --- title: Correlate +description: "Cross-correlate a channel/time sample against all others with the correlate module." execute: warning: false --- diff --git a/recipes/despiking.qmd b/recipes/despiking.qmd index 53eabe03c..c949934c0 100644 --- a/recipes/despiking.qmd +++ b/recipes/despiking.qmd @@ -1,5 +1,6 @@ --- title: "Despiking" +description: "Remove spikes from DAS data." execute: warning: false --- diff --git a/recipes/docker_basic.qmd b/recipes/docker_basic.qmd index ee43fe3f6..2ca6c53be 100644 --- a/recipes/docker_basic.qmd +++ b/recipes/docker_basic.qmd @@ -1,5 +1,6 @@ --- title: Using DASCore with Docker +description: "Run DASCore inside a Docker container." execute: warning: false --- diff --git a/recipes/edge_effects.qmd b/recipes/edge_effects.qmd index 4c5f72349..f4dd5e8db 100644 --- a/recipes/edge_effects.qmd +++ b/recipes/edge_effects.qmd @@ -1,5 +1,6 @@ --- title: Taper Edge Effects +description: "Use tapering to manage edge effects from filtering and other processing." execute: warning: false --- diff --git a/recipes/external_conversion.qmd b/recipes/external_conversion.qmd index 804f0f6de..806a78652 100644 --- a/recipes/external_conversion.qmd +++ b/recipes/external_conversion.qmd @@ -1,5 +1,6 @@ --- title: Patch Conversions +description: "Convert patches to and from other libraries' data structures." execute: warning: false --- diff --git a/recipes/fk.qmd b/recipes/fk.qmd index 00f1a19d5..d29c3da30 100644 --- a/recipes/fk.qmd +++ b/recipes/fk.qmd @@ -1,5 +1,6 @@ --- title: F-K Transform and Filtering +description: "Apply frequency-wavenumber (F-K) transforms and filtering." execute: warning: False --- diff --git a/recipes/how_to_contribute.qmd b/recipes/how_to_contribute.qmd index 1e1e7ddf1..ff22d27a8 100644 --- a/recipes/how_to_contribute.qmd +++ b/recipes/how_to_contribute.qmd @@ -1,12 +1,13 @@ --- title: "How to Contribute?" +description: "A step-by-step guide to making your first contribution to DASCore." --- On this page, we provide a step-by-step procedure on how you can start contributing to DASCore. -# DASDAE developers +## DASDAE developers -## Step 1: Install DASCore in development mode +### Step 1: Install DASCore in development mode For the first time using DASCore in development mode, or if a new release is out, you need to install DASCore as it is mentioned [here](https://dascore.org/contributing/dev_install.html). Otherwise, you just need to activate the environment: @@ -33,7 +34,7 @@ pytest ``` -## Step 2: Create a new branch to work on +### Step 2: Create a new branch to work on To create a new branch: @@ -75,25 +76,25 @@ git commit -m "your commit" git push origin branch_name ``` -## Step 3: Create a Pull Request +### Step 3: Create a Pull Request Navigate to the DASCore repository on GitHub, and you should see a notification about your recent push. Click the "Compare & pull request" button to create a new pull request. -# DASDAE users +## DASDAE users If you'd like to contribute to DASCore as a user, you should first fork the DASCore repository. Forking a repository allows you to freely experiment with changes without affecting the original project. Below is a detailed guide on how to do this. [This GitHub documentation](https://docs.github.com/en/get-started/quickstart/contributing-to-projects) might be beneficial to review as well. -## Step 1: Fork the repository +### Step 1: Fork the repository Go to the [DASCore repository](https://github.com/DASDAE/dascore) and click on "Fork". -## Step 2: Clone your fork +### Step 2: Clone your fork Once you have forked the repository, you need to clone it to your local machine to start making changes. Then navigate to your local repository: ```bash cd dascore ``` -## Step 3: Set Upstream Repository +### Step 3: Set Upstream Repository Add the original DASCore repository as an upstream repository, which will be useful for keeping your fork up to date with the original project: ```bash @@ -110,7 +111,7 @@ You should see the original repository as `upstream` and your fork as `origin`. Then, create a new branch and start making changes to the repository. -## Step 4: Create a new branch to work on +### Step 4: Create a new branch to work on To create a new branch: @@ -152,6 +153,6 @@ git commit -m "your commit" git push origin branch_name ``` -## Step 5: Create a Pull Request +### Step 5: Create a Pull Request Navigate to your project's GitHub repository, for instance, https://github.com//dascore, and click "Contribute" and then "Open a pull request". Then, create a pull request and provide a detailed title and description for your changes, explaining the rationale behind your pull request. diff --git a/recipes/low_freq_proc.qmd b/recipes/low_freq_proc.qmd index 38eacd007..7afc546c1 100644 --- a/recipes/low_freq_proc.qmd +++ b/recipes/low_freq_proc.qmd @@ -1,5 +1,6 @@ --- title: "Low-Frequency Processing" +description: "Apply efficient low-frequency (LF) processing to a spool of DAS data." --- This recipe demonstrates how DASCore can be used to apply low-frequency (LF) processing to a spool of DAS data. LF processing helps efficiently downsample the entire spool. diff --git a/recipes/overview.qmd b/recipes/overview.qmd index e43a6f0f4..30e56fe0f 100644 --- a/recipes/overview.qmd +++ b/recipes/overview.qmd @@ -1,5 +1,6 @@ --- title: "Overview" +description: "Start here: a cookbook of task-focused DASCore examples." --- Welcome to DASCore's cookbook! This is a collection of examples (recipes) to demonstrate how to perform various tasks with DASCore. Use the collapsible menu in the sidebar to browse the recipes and consider [contributing](../contributing/contributing.qmd) some examples of your own. diff --git a/recipes/parallelization.qmd b/recipes/parallelization.qmd index 67fc92352..343be6401 100644 --- a/recipes/parallelization.qmd +++ b/recipes/parallelization.qmd @@ -1,12 +1,13 @@ --- title: "Parallel Processing" +description: "Strategies for parallelizing embarrassingly parallel spool workflows." execute: eval: false --- This recipe shows a few strategies to parallelize "embarrassingly parallel" spool processing workflows. -# Processes and Threads +## Processes and Threads [`Spool.map`](`dascore.core.spool.BaseSpool.map`) is the easiest way to process patches in a spool in parallel. Here is an example using the Python standard library module [concurrent.futures](https://docs.python.org/3/library/concurrent.futures.html): ```{python} @@ -29,11 +30,11 @@ The `ThreadPoolExecutor` from the same module also works. On a free-threaded (no There are two downsides to this approach. First, if the patches aren't chunked adequately it may exhaust the available memory. Second, it will only work on a single machine. The next section presents a more scalable option. -# Thread Safety +## Thread Safety DASCore's core test suite — no optional dependencies, no network tests — runs on a free-threaded CPython build with the GIL disabled. The guarantees below are what that supports; they apply equally to threads on a standard build. -## What threads may share +### What threads may share Patches are immutable, so any number of threads may read the same patch. Spools may also be read concurrently: iterating, selecting, chunking, indexing and taking their length are safe from several threads at once, because the underlying metadata caches are synchronized internally. @@ -43,7 +44,7 @@ The process-wide registries take care of themselves. The file-format (`FiberIO`) Remote files are cached per resource. Threads asking for the same remote file take turns, so it downloads once and the rest use the result; different files download at the same time. -## What threads may not share +### What threads may not share State-changing calls follow a single-writer model. Updating a directory spool, adding patches to an in-memory spool and [`clear_remote_file_cache`](`dascore.utils.remote_io.clear_remote_file_cache`) should each run from one thread, with no other thread reading the same object meanwhile. DASCore keeps its own structures consistent through such a change, but it does not make a reader see a coherent before-or-after snapshot of it. @@ -51,17 +52,17 @@ An open file handle belongs to one IO operation. DASCore opens each resource onc Third-party `FiberIO` plugins are responsible for their own thread safety. DASCore synchronizes the registry that holds them and serializes their import, but a plugin which keeps mutable state of its own must guard it. -## Configuration in threads +### Configuration in threads Configuration has two tiers, described in [runtime configuration](../tutorial/configuration.qmd). `set_config` changes the process-wide base and is visible from every thread. `config_context` overrides the config for the current context only, and a newly started thread begins with a fresh context, so a scoped override does not automatically reach threads started inside it. [`Spool.map`](`dascore.core.spool.BaseSpool.map`) handles this for you: it binds the configuration active when `map` is called and re-applies it inside each worker, for thread pools and process pools alike. When starting threads yourself, either set the configuration permanently before starting them or re-apply the scoped override inside each thread. -# MPI4Py +## MPI4Py This section shows how to use the "mpi4py" library to parallelize dascore code. -## Installation +### Installation First, make sure you have installed DASCore on your machine. See [DASCore Installation](https://dascore.org/#:~:text=0.2%29%3B-,Installation). Secondly, you need to properly install the mpi4py library. After installing and loading the [Open MPI](https://docs.open-mpi.org/en/v5.0.x/installing-open-mpi/quickstart.html) module on your machine (e.g., on Linux: `load module to/mpi/openmpi/gcc/compiler/path`), install [mpi4py](https://pypi.org/project/mpi4py/). It might be easier to install using conda-forge as below: @@ -72,7 +73,7 @@ conda install -c conda-forge mpi4py openmpi Please note that this procedure is tested for Python 3.11 and Open MPI GCC 3.1.3 -## Parallel script +### Parallel script Here is an example for parallelization of Patches over processors: @@ -110,7 +111,7 @@ comm.barrier() sys.exit(0) ``` -## Run the script +### Run the script If you like to run the `mpi_spool.py` script using `n = 4` processors (which means each processor will run the script separately), you can use: diff --git a/recipes/plotting_channel_number.qmd b/recipes/plotting_channel_number.qmd index d2a193cbc..32c9ad89b 100644 --- a/recipes/plotting_channel_number.qmd +++ b/recipes/plotting_channel_number.qmd @@ -1,5 +1,6 @@ --- title: Plot Channel Number +description: "Plot channel number instead of distance or depth." execute: warning: false --- diff --git a/recipes/real_time_proc.qmd b/recipes/real_time_proc.qmd index f3fb72b4a..db2dfd7cd 100644 --- a/recipes/real_time_proc.qmd +++ b/recipes/real_time_proc.qmd @@ -1,5 +1,6 @@ --- title: "Real-Time Processing" +description: "Process streaming DAS data in near real time." execute: eval: false --- diff --git a/recipes/smoothing.qmd b/recipes/smoothing.qmd index adc3a2655..2d857631e 100644 --- a/recipes/smoothing.qmd +++ b/recipes/smoothing.qmd @@ -1,5 +1,6 @@ --- title: "Patch Smoothing" +description: "Compare several patch smoothing strategies." execute: warning: false --- diff --git a/tutorial/concepts.qmd b/tutorial/concepts.qmd index 921d7721e..22cf3e493 100644 --- a/tutorial/concepts.qmd +++ b/tutorial/concepts.qmd @@ -6,7 +6,7 @@ execute: This page highlights some concepts helpful for working with DASCore. -# Data structures +## Data structures For most uses of DASCore, only two data structures are directly involved. These are the [Patch](patch.qmd) and the [Spool](spool.qmd). @@ -19,7 +19,7 @@ disk, or a remote resource. You will read more about Patches and Spools later on in the tutorial. -# Time +## Time Any expression of time should use [numpy](https://numpy.org/doc/stable/reference/arrays.datetime.html) time constructs, which include [datetime64](https://numpy.org/doc/stable/reference/arrays.scalars.html#numpy.datetime64) and [timedelta64](https://numpy.org/doc/stable/reference/arrays.scalars.html#numpy.timedelta64). @@ -56,7 +56,7 @@ time_2 = dc.to_datetime64(610243200) ``` -# Dimension Selection +## Dimension Selection Most of DASCore's processing methods can be applied along any dimension. Typically, the dimension is selected with keyword, and the method specific data are passed as values. For example, applying [pass_filter](`dascore.proc.filter.pass_filter`) to a patch with `distance` and `time` dimensions works like this: @@ -108,7 +108,7 @@ assert np.allclose( When in doubt, be explicit with units and read the docs for the function in question! -# Units +## Units DASCore provides first class support for units through the [`units`](`dascore.units`) module. Units (or rather quantities) can be imported directly or can be created with the [get_quantity](`dascore.units.get_quantity`) function. diff --git a/tutorial/coords.qmd b/tutorial/coords.qmd index b04f7c667..9c37a9e98 100644 --- a/tutorial/coords.qmd +++ b/tutorial/coords.qmd @@ -10,7 +10,7 @@ This page covers advanced DASCore features. Most users will be fine with only th In order to manage coordinate labels and array manipulations, DASCore implements two classes, [`BaseCoord`](`dascore.core.coords.BaseCoord`), which has several associated subclasses corresponding to different types of coordinates, and [CoordManager](`dascore.core.coordmanager.CoordManager`) which manages a group of coordinates. Much like the [`Patch`](`dascore.core.patch.Patch`), instances of both of these classes are immutable (to the extent possible), so they cannot be modified in place but have methods which return new instances. -# Coordinates +## Coordinates Coordinates usually keep track of labels along an associated dimension of an array, but they can also be independent of array data. They provide methods for slicing, re-ordering, filtering etc. and are used internally by DASCore for such operations. @@ -21,9 +21,9 @@ Much like DASCore's [`Spool`](`dascore.core.spool.BaseSpool`), Coordinates are a Coordinates are very similar (in concept) to Pandas' indices, with some significant differences in implementation. ::: -## Coordinate Creation +### Coordinate Creation -### Get Coord +#### Get Coord [`get_coord`](`dascore.core.coords.get_coord`) returns an instance of a subclass of [`BaseCoord`](`dascore.core.coords.BaseCoord`) appropriate for the input values. Here are a few examples: @@ -62,7 +62,7 @@ print(type(coord).__name__) print(coord.values) ``` -### Segmented Coordinates +#### Segmented Coordinates [`CoordSegmented`](`dascore.core.coords.CoordSegmented`) preserves monotonic coordinate blocks and the discontinuities between them. It is useful when a logical coordinate contains dropped samples, acquisition gaps, or a sampling-rate change but the corresponding data should remain in one in-memory patch. @@ -95,7 +95,7 @@ assert len(exact_coord.get_discontinuities("gaps")) == 1 Segmented coordinates have `step=None` because one step cannot describe the entire coordinate. `coord.simplify(tolerance=...)` may replace segments with a simpler fit while bounding how far values move; `coord.snap()` always forces one evenly sampled range and can move interior values without a bound. Use `patch.split_gaps()` to turn a patch with segmented dimensional coordinates into contiguous patches before writing it to a format that cannot store gaps. -### Update +#### Update Update uses the existing coordinate as a template and returns a coordinate with some part modified. @@ -122,7 +122,7 @@ coord_new_max = coord.update(max=stop + 10 * step) ``` -## Coordinate Attributes +### Coordinate Attributes The following tables shows some of the commonly used coordinate attributes: @@ -140,11 +140,11 @@ The following tables shows some of the commonly used coordinate attributes: : Coordinate attributes {.striped .hover} -## Coordinate Methods +### Coordinate Methods This section highlights some of the coordinate methods. The methods which would cause changes to a data array return a new coordinate and an object that can be used for indexing an array. This can either be a `slice` instance or another array which uses numpy's advanced indexing features for sorting or selection. -### Sort +#### Sort [`sort`](`dascore.core.coords.BaseCoord.sort`) sorts the values of the coordinate. ```{python} @@ -164,7 +164,7 @@ data = np.random.rand(10, 20) sorted_data = data[indexer, :] ``` -### Snap +#### Snap [`snap`](`dascore.core.coords.BaseCoord.snap`) replaces coordinate values with an evenly sampled range spanning the same minimum and maximum. This intentionally loses interior precision and should be used only when that idealization is acceptable. Unlike [`sort`](`dascore.core.coords.BaseCoord.sort`), it returns only a new coordinate and no indexer, because it replaces the values rather than permuting them, so for an unsorted coordinate the snapped values no longer label the samples they used to. When data alignment matters, use [`CoordManager.snap`](`dascore.core.coordmanager.CoordManager.snap`), which sorts the coordinate and its associated array together before snapping, or [`Patch.snap_coords(...)`](`dascore.Patch.snap_coords`), which does the same across the selected dimensions of a patch. @@ -185,7 +185,7 @@ assert snapped_coord.max() == irregular_coord.max() Use `simplify(tolerance=...)` instead when the maximum allowed coordinate movement must be explicit. Most coordinate types are already in their simplest form; this distinction is most useful for segmented coordinates. -### Select +#### Select [`select`](`dascore.core.coords.BaseCoord.select`) is used for slicing/sub-selecting. ```{python} @@ -215,7 +215,7 @@ new_coord, indexer = coord.select((14*ft, 50 * ft)) print(new_coord) ``` -## String Coordinates +### String Coordinates String coordinates support exact matching, wildcard matching with `*` and `?`, compiled regular expressions, boolean-mask selection, and sorting. They are @@ -260,7 +260,7 @@ compiled regular expressions, or boolean masks. Strings containing `*` or `?` are treated as wildcard patterns, so avoid those characters in labels you intend to select literally. -### Units +#### Units [`convert_units`](`dascore.core.coords.BaseCoord.convert_units`) and [`set_units`](`dascore.core.coords.BaseCoord.set_units`) are used to change/set the units associated with a coordinate. @@ -288,7 +288,7 @@ print(f"Simplified units are: {simple_coord.units}") print(f"New coord lims are: {simple_coord.limits}") ``` -### Get Next Index +#### Get Next Index [`get_next_index`](`dascore.core.coords.BaseCoord.get_next_index`) returns the index value (an integer) for where a value would be inserted into the coordinate. It can only be used on a sorted coordinate. ```{python} @@ -300,12 +300,12 @@ assert coord.get_next_index(1) == 1 assert coord.get_next_index(2.000001) == 3 ``` -# CoordManager +## CoordManager The [`CoordManager`](`dascore.core.coordmanager.CoordManager`) handles a group of coordinates and provides methods for updating managed data arrays. -## Coordinate Manager Creation +### Coordinate Manager Creation [`CoordManager`](`dascore.core.coordmanager.CoordManager`) instances can be created from a dictionary of coordinates via the [`get_coord_manager`](`dascore.core.coordmanager.get_coord_manager`) function. ```{python} @@ -349,7 +349,7 @@ cm_many_coords = get_coord_manager(coords=coord_dict, dims=("dim1", "dim2")) print(cm_many_coords) ``` -### Update +#### Update [`update`](`dascore.core.coordmanager.CoordManager.update`) uses an existing `CoordinateManager` as a template and updates some aspect in the returned coordinate. @@ -400,11 +400,11 @@ new_cm_5 = cm.update(time=None) assert "time" not in new_cm_5.dims ``` -## Coordinate Manager Methods +### Coordinate Manager Methods Much like `BaseCoord`, the `CoordinateManager` class implements a variety of methods for filtering, sorting, modifying units, etc. However, there are some difference. Unlike coordinates, when an operation would change the data array associated with the coordinates, the `CoordManager` method accepts the array as an argument and returns a new array. Like the `Patch` methods, `CoordManager` methods use keyword arguments to specify coordinates by name. -### Select +#### Select [select](`dascore.core.coordmanager.CoordManager.select`) trims the coordinate manager and, optionally, an associated array. @@ -418,7 +418,7 @@ new_cm, new_data = cm.select(data=data, distance=(..., 100)) ``` -### Sort +#### Sort [sort](`dascore.core.coordmanager.CoordManager.sort`) sorts along one or more axes. @@ -432,7 +432,7 @@ cm, data = patch.coords, patch.data new_cm, new_data = cm.sort("time", "distance", reverse=True) ``` -### Rename Coord +#### Rename Coord [rename_coord](`dascore.core.coordmanager.CoordManager.rename_coord`) renames a coordinate or dimension. diff --git a/tutorial/patch.qmd b/tutorial/patch.qmd index b8b82680c..3720302eb 100644 --- a/tutorial/patch.qmd +++ b/tutorial/patch.qmd @@ -10,11 +10,11 @@ A [`Patch`](`dascore.core.patch.Patch`) manages an array and its associated coor The `Patch` design was inspired by [Xarray's `DataArray`](https://docs.xarray.dev/en/stable/generated/xarray.DataArray.html) ::: -# Patch creation +## Patch creation Patches can be created in several different ways. -## Load an example patch +### Load an example patch DASCore includes several example datasets. They are mostly used for simple demonstrations and testing. @@ -28,7 +28,7 @@ pa2 = dc.get_example_patch("example_event_1") See [`get_example_patch`](`dascore.examples.get_example_patch`) for supported patches. -## Load a file +### Load a file A single file can be loaded like this: @@ -59,7 +59,7 @@ pa = dc.spool(path)[0] Spools are covered in more detail in the [next section](spool.qmd). -## Manually create a patch +### Manually create a patch Patches can be created from: @@ -100,9 +100,9 @@ dims = ('distance', 'time') pa = dc.Patch(data=array, coords=coords, attrs=attrs, dims=dims) ``` -# Patch anatomy +## Patch anatomy -## Data +### Data The data is simply an n-dimensional array which is accessed with the `data` attribute. @@ -130,7 +130,7 @@ array[:10] = 12 # then this works ::: -## Coords +### Coords DASCore implements a class called [CoordManager](`dascore.core.coordmanager.CoordManager`) which manages dimension names, coordinate labels, selecting, sorting, etc. `CoordManager` has several convenience methods for accessing contained information: @@ -216,7 +216,7 @@ compiled regular expressions, boolean-mask selection, and sorting, but they do not support units or numeric range selection. Avoid using `*` or `?` in labels you intend to select literally. -## Attrs +### Attrs The metadata stored in `Patch.attrs` is a [pydantic model](https://docs.pydantic.dev/usage/models/) which enforces a schema and provides validation. [`PatchAttrs.get_summary_df`](`dascore.models.base.DascoreBaseModel.get_summary_df`) generates a table of the attribute descriptions: @@ -238,7 +238,7 @@ Markdown(df_str) Specific data formats may also add attributes (e.g. "gauge_length", "pulse_width"), but this depends on the parser. -### Patch History +#### Patch History Patch-processing methods append entries to `Patch.attrs.history` by default so downstream steps remain traceable. @@ -267,7 +267,7 @@ assert out.attrs.history == old_history `Patch.attrs` only stores non-coordinate metadata. This includes things like the acquisition key, data units, and observing-system fields such as `gauge_length` or `pulse_width`. -## Summary +### Summary `Patch.summary` provides a read-only combined view of: @@ -296,7 +296,7 @@ print(row["distance_max"]) The `data_type` attribute is an optional label for the kind of data in the patch. It is useful for display defaults and quick inspection, but physical interpretation should come from `data_units`, coordinate units, and `history`. See the [PatchAttrs note](../notes/patch_attrs.qmd) for more detail. -## String representation +### String representation DASCore Patches have a useful string representation: @@ -307,7 +307,7 @@ patch = dc.get_example_patch() print(patch) ``` -## Shortcuts +### Shortcuts DASCore Patches offer a few shortcuts for quickly accessing commonly used information: @@ -333,11 +333,11 @@ patch_name = patch.get_patch_name() patch_names = spool.get_patch_names() ``` -# Trim and Reshape +## Trim and Reshape The following methods help trim, reshape, and manipulate coordinates. -## Select +### Select Patches are trimmed using the [`Patch.select`](`dascore.proc.select`) method. Unlike [`Patch.order`](`dascore.proc.order`), `select` will not change the order of the affected dimensions, it will only remove elements. Most commonly, `select` takes the coordinate name and a tuple of (lower_limit, upper_limit) as the values. Either limit can be `...` or `None`, indicating an open interval, as can an infinite bound pointing away from the data, such as `(lower_limit, np.inf)`. @@ -438,7 +438,7 @@ sub_patch = patch.select(distance=np.array([0, 12, 10, 9]), samples=True) assert len(sub_patch.get_array('distance')) == 4 ``` -## Unselect +### Unselect [`Patch.unselect`](`dascore.Patch.unselect`) is the complement of `select`: it takes the same selectors and removes the samples `select` would have kept. Naming one coordinate gives exactly the complement; naming several complements each on its own, as below. @@ -464,7 +464,7 @@ assert outside.get_coord("distance").step is None That is why [`Spool.unselect`](`dascore.core.spool.Spool.unselect`) refuses the patches' own coordinates. A patch can have samples removed from its middle; at spool level the complement of a range would be a hole in every patch rather than a choice between patches. The coordinates an attached DASDAE inventory defines along the fiber are a separate case, and are accepted: removing one of those chooses which channels a patch holds. When several coordinates are named, each is complemented on its own — the true complement of a block is a frame around it, which no array can hold. -## Order +### Order Order is similar to [`Patch.select`](`dascore.proc.select`), but will re-arrange data to the order specified by a value array. This may also cause parts of the patch to be duplicated. ```{python} @@ -485,7 +485,7 @@ patch_dist2 = patch.order(distance=dist_order2) assert np.all(dist_order2 == patch_dist2.get_array("distance")) ``` -## New dimensions +### New dimensions Sometimes it can be useful to add new (empty) dimensions to a Patch. [`Patch.append_dims`](`dascore.proc.append_dims`) does this. @@ -512,7 +512,7 @@ patch_extended_coord = patch_extended.update_coords(money=[10, 30]) Although these examples are quite contrived, these functions are very useful for transforms which create high dimensional patches. -# Processing +## Processing The patch has several methods which are intended to be chained together via a [fluent interface](https://en.wikipedia.org/wiki/Fluent_interface), meaning each method returns a new `Patch` instance. @@ -531,7 +531,7 @@ out = ( ``` The processing methods are located in the [dascore.proc](/reference/index.qmd#patch-processing) module. The [patch processing tutorial](processing.qmd) provides more information about processing routines. -# Visualization +## Visualization DASCore provides some visualization functions in the [dascore.viz](/reference/index.qmd#visualization) module or using the `Patch.viz` namespace. DASCore generally only implements simple, matplotlib based visualizations but other DASDAE packages will likely do more interesting visualizations. @@ -547,11 +547,11 @@ patch = ( patch.viz.waterfall(show=True); ``` -# Modifying patches +## Modifying patches Because patches should be treated as immutable objects, they can't be modified with normal attribute assignment. However, DASCore provides several methods that return new patches with modifications. -## Update +### Update [`Patch.update`](`dascore.proc.update`) uses the `Patch` instances as a template and returns a new `Patch` instances with one or more aspects modified. @@ -566,7 +566,7 @@ new_data_patch = pa.update(data=pa.data * 10) new_attrs_patch = pa.update(attrs=dict(tag="TMU")) ``` -## Update attrs +### Update attrs [`Patch.update_attrs`](`dascore.proc.update_attrs`) is for making changes to the attrs (metadata) while keeping the unaffected metadata (`Patch.update` would completely replace the old attrs). @@ -585,7 +585,7 @@ assert pa1.attrs.new_attr == 42 ``` -## Update coords +### Update coords [`Patch.update_coords`](`dascore.proc.update_coords`) returns a new patch with the coordinates changed in some way. These changes can include: - Modifying (updating) existing coordinates @@ -593,7 +593,7 @@ assert pa1.attrs.new_attr == 42 - Changing coordinate dimensional association -### Modifying coordinates +#### Modifying coordinates Coordinates can be updated by specifying a new array which should take the place of the old one: @@ -621,7 +621,7 @@ new_time = pa.coords.min('time') + one_second new = pa.update_coords(time_min=new_time) ``` -### Adding coordinates +#### Adding coordinates Commonly, additional coordinates, such as latitude/longitude, are attached to a particular dimension such as distance. It is also possible to include coordinates that are not associated with any dimensions. @@ -658,7 +658,7 @@ out_3 = pa.update_coords( no_dim_coord = pa.update_coords(non_dim=(None, np.arange(10))) ``` -### Changing coordinate dimensional association +#### Changing coordinate dimensional association The dimensions each coordinate is associated with can be changed. For example, to remove a coordinate's dimension association: @@ -673,7 +673,7 @@ lat = patch.coords.get_array('latitude') patch_detached_lat = patch.update_coords(latitude=(None, lat)) ``` -## Dropping coordinates +### Dropping coordinates Non-dimensional coordinates can be dropped using [`Patch.drop_coords`](`dascore.proc.coords.drop_coords`). Dimensional coordinates, however, cannot be dropped since doing so would force the patch data to become degenerate. @@ -688,7 +688,7 @@ patch_dropped_lat = patch.drop_coords("latitude") print(patch_dropped_lat.coords) ``` -### Coords in patch initialization +#### Coords in patch initialization Any number of coordinates can also be assigned when the patch is initiated. For coordinates other than those of the patch dimensions, the associated dimensions must be specified. For example: @@ -725,11 +725,11 @@ out = dc.Patch(data=array, coords=coords, attrs=attrs, dims=dims) ``` -# Units +## Units As mentioned in the [units section of the concept page](concepts.qmd#units), DASCore provides first-class support for units. -## Patch units +### Patch units There are two methods for configuring the units associated with a `Patch`. @@ -762,7 +762,7 @@ print(type(patch.attrs.data_units)) print(get_quantity_str(patch.attrs.data_units)) ``` -## Units in processing functions +### Units in processing functions ```{python} import dascore as dc @@ -779,7 +779,7 @@ dist_filtered = pa.pass_filter(distance=(10*m, 100*m)) See the documentation on [`Patch.select`](`dascore.proc.select`) and [`Patch.pass_filter`](`dascore.proc.pass_filter`) for more details. -# Patch operations +## Patch operations Patches implement many numpy-like functions which are applied directly to a patch using built-in python operators. @@ -789,7 +789,7 @@ In the case of scalars and numpy arrays, the operations are broadcast over the p See [`merge_compatible_coords_attrs`](`dascore.utils.patch.merge_compatible_coords_attrs`) for more details on how attributes and coordinates are handled when performing operations on two patches. ::: -## Patch operations with scalars +### Patch operations with scalars ```{python} import numpy as np @@ -823,7 +823,7 @@ print(f"units before operation {patch.attrs.data_units}") print(f"units after operation {new.attrs.data_units}") ``` -## Patch operations with numpy arrays +### Patch operations with numpy arrays `Patch` implements the numpy array protocol, meaning you can use numpy functions on patches @@ -855,9 +855,9 @@ print(f"units before operation {patch.attrs.data_units}") print(f"units after operation {out1.attrs.data_units}") ``` -## Patch operations with other patches +### Patch operations with other patches -### Identically shaped patches +#### Identically shaped patches When patches are shaped the same, the operations can simply be applied on the data arrays, then coords and attrs merged. @@ -876,7 +876,7 @@ out = patch + patch assert np.allclose(patch.data * 2, out.data) ``` -### Broadcastable patches +#### Broadcastable patches If the arrays are not shaped the same, but they can be broadcasted to compatible shapes, these operations work as well. @@ -895,7 +895,7 @@ sum_patch = patch + sub_patch print(sum_patch.shape) ``` -### Numpy Functions +#### Numpy Functions DASCore uses [apply_array_ufunc](`dascore.utils.array.apply_ufunc`) and [array_function](`dascore.utils.array.apply_array_func`) for applying numpy functions to `Patch` instances. diff --git a/tutorial/processing.qmd b/tutorial/processing.qmd index ab503ac4e..4d4964da8 100644 --- a/tutorial/processing.qmd +++ b/tutorial/processing.qmd @@ -6,11 +6,11 @@ execute: The following shows some simple examples of patch processing. See the [proc module](/reference/index.qmd#patch-processing) for a list of all processing functions. -# Basic +## Basic There are several "basic" processing functions which manipulate the patch metadata, shape, etc. Many of these are covered in the [patch tutorial](patch.qmd), but here are a few that aren't: -## Transpose +### Transpose The [`transpose` patch function](`dascore.proc.transpose`) patch function simply transposes the dimensions of the patch, either by rotating the dimensions or to a new specified dimension. ```{python} @@ -26,7 +26,7 @@ print(f"dims after transpose: {transposed.dims}") transposed = patch.transpose("time", "distance") ``` -## Squeeze +### Squeeze [`squeeze`](`dascore.proc.squeeze`) removes dimensions which have a single value (see also `numpy.squeeze`). ```{python} @@ -42,7 +42,7 @@ squeezed = flat_patch.squeeze() print(f"Post-squeeze shape: {squeezed.shape}") ``` -## Dropna +### Dropna The [`dropna` patch function](`dascore.proc.dropna`) patch function drops "nullish" values from a given label. @@ -66,11 +66,11 @@ assert not np.any(np.isnan(no_na_patch.data)) ``` -# Decimate +## Decimate [decimate](`dascore.proc.decimate`) decimates a `Patch` along a given axis while by default performing low-pass filtering to avoid [aliasing](https://en.wikipedia.org/wiki/Aliasing). -## Data creation +### Data creation First, we create a patch composed of two sine waves; one above the new decimation frequency and one below. @@ -87,7 +87,7 @@ patch = dc.examples.get_example_patch( patch.viz.wiggle(show=True); ``` -## IIR filter +### IIR filter Next we decimate by 10x using IIR filter @@ -99,7 +99,7 @@ decimated_iir.viz.wiggle(show=True); Notice the lowpass filter removed the 200 Hz signal and only the 10Hz wave remains. -## FIR filter +### FIR filter Next we decimate by 10x using FIR filter. @@ -108,7 +108,7 @@ decimated_fir = patch.decimate(time=10, filter_type='fir') decimated_fir.viz.wiggle(show=True); ``` -## No Filter +### No Filter Next, we decimate without a filter to purposely induce aliasing. @@ -117,7 +117,7 @@ decimated_no_filt = patch.decimate(time=10, filter_type=None) decimated_no_filt.viz.wiggle(show=True); ``` -# Taper +## Taper [taper](`dascore.proc.taper`) is used to taper the edges of a patch dimension to zero. To see this, let's create a patch of all 1s and apply the taper function @@ -152,7 +152,7 @@ patch_ones.taper(distance=(None, 0.1)).viz.waterfall(); See also the [edge effects recipe](../recipes/edge_effects.qmd) for using tapering to help filtering. -# Rolling +## Rolling The [rolling patch function](`dascore.proc.rolling`) implements moving window operators similar to [pandas rolling](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.rolling.html). It is useful for smoothing, calculating aggregated statistics, etc. Here is an example of using a rolling mean to smooth along the time axis: @@ -171,7 +171,7 @@ smoothed.viz.waterfall(); Notice the nan values at the start of the time axis. These can be trimmed with [`Patch.dropna`](`dascore.proc.dropna`). -# Whiten +## Whiten The [`Patch.whiten`](`dascore.proc.whiten`) function performs spectral whitening by balancing the amplitude spectra of the patch while leaving the phase (largely) unchanged. Spectral whitening is often a pre-processing step in ambient noise correlation workflows. diff --git a/tutorial/spool.qmd b/tutorial/spool.qmd index f52ec0984..3f210d065 100644 --- a/tutorial/spool.qmd +++ b/tutorial/spool.qmd @@ -8,11 +8,11 @@ Spools are containers/managers of [patches](patch.qmd). The spool interface is d For file-backed spools, DASCore first scans metadata and coordinate summaries, then loads patch data only when you access a patch from the spool. This means methods like `get_contents()` work from patch summary metadata, while `spool[0]` or iteration materializes loaded patches. -# Data Sources +## Data Sources The simplest way to get the appropriate spool for a specified input is to use the [`spool`](`dascore.spool`) function, which knows about many different input types and returns an appropriate [`BaseSpool`](`dascore.core.spool.BaseSpool`) subclass instance. -## Patches (in-memory) +### Patches (in-memory) ```{python} import dascore as dc @@ -22,7 +22,7 @@ patch_list = [dc.get_example_patch()] spool1 = dc.spool(patch_list) ``` -## A Single file +### A Single file ```{python} import dascore as dc @@ -42,7 +42,7 @@ dc.write(dc.get_example_patch(), remote_file, "DASDAE") spool2_remote = dc.spool(remote_file) ``` -## A directory of DAS files +### A directory of DAS files ```{python} import dascore as dc @@ -86,7 +86,7 @@ spool.update() It is best not to delete files once added to a directory managed by DASCore. ::: -### Path attributes (hive-style directories) +#### Path attributes (hive-style directories) Directory spools parse `key=value` pairs out of the paths inside the spool, in the style of [Hive partitioning](https://hive.apache.org/). Each directory segment can hold one pair (`acquisition_key=XX.R2D1..RAW/`), and any segment — including the file name, whose extension is ignored — can hold several separated by `__` (the same separator DASCore's default patch names use). The parsed values become string attributes: they show up in `get_contents()`, work with `select`, and are set on loaded patches. When a path attribute and an attribute stored inside the file share a name, the path wins — renaming a directory (or file) is how you attach or correct metadata without rewriting data. @@ -139,7 +139,7 @@ from full reads. See the [Working with Remote Patches](remote_patches.qmd) tutorial for the remote-cache policy, spool implications, and examples. ::: -# Accessing patches +## Accessing patches Patches are extracted from the spool via simple iteration or indexing. New spools are returned via slicing. @@ -193,7 +193,7 @@ index_array = np.array([2, 0]) new = spool[index_array] ``` -# get_contents +## get_contents The [`get_contents`](`dascore.core.spool.BaseSpool.get_contents`) method returns a dataframe listing the spool contents. This method may not be supported on all spools, especially those interfacing with large remote resources. @@ -215,7 +215,7 @@ display(contents.drop(columns=[c for c in contents.columns if c.startswith('_')] The columns returned by `get_contents()` come from the same patch summary metadata exposed by `Patch.summary`, so fields such as `time_min`, `time_max`, and `distance_step` are available without loading the underlying patch data. Source metadata such as `source_path`, `source_format`, and `source_patch_id` are also available for file-backed spools. -# select +## select The [select](`dascore.core.spool.BaseSpool.select`) method selects a subset of a spool and returns a new spool. [`get_contents`](`dascore.core.spool.BaseSpool.get_contents`) will now reflect a subset of the original data requested by the select operation. @@ -242,7 +242,7 @@ subspool = spool.select(acquisition_key={'DAS2.R2D1..RAW', 'DAS3.R2D1..RAW'}) subspool = spool.select(tag='some*') ``` -# unselect +## unselect [`unselect`](`dascore.core.spool.BaseSpool.unselect`) is the complement of `select`: it returns the patches the same selection would have removed. Each keyword means what it means in `select`, so this is how to name what a spool does *not* want without spelling out the rest of the archive. @@ -257,7 +257,7 @@ assert len(subspool) + len(spool.select(tag='some_tag')) == len(spool) Coordinates are not accepted yet. Selecting on a coordinate trims each patch to the range as well as dropping the patches which miss it entirely, so the complement of `time=(t1, t2)` is the part of every patch *before* `t1` together with the part *after* `t2` — one patch becoming two. That is subdivision rather than filtering, and `unselect` does not do it yet; select the ranges to keep instead. -# chunk +## chunk The [`chunk`](`dascore.core.spool.BaseSpool.chunk`) method controls how data are grouped together in patches within the spool. It can be used to merge contiguous patches together, specify the size of patches for processing, specify overlap with previous patches, etc. @@ -287,7 +287,7 @@ size_chunked = spool.chunk(time=1 * megabytes) A data size measures the data array only; coordinates, attrs, and any copies made later during processing are extra, so the patch as a whole is somewhat larger. The sample count is rounded down, so the patch's data never exceeds the requested size, and `MB` is 10^6^ bytes while `MiB` is 2^20^. `overlap` accepts the same forms. -# concatenate +## concatenate Similar to `chunk`, [`Spool.concatenate`](`dascore.BaseSpool.concatenate`) is used to combine patches together. However, `concatenate` doesn't account for coordinate values along the concatenation axis, and can even be used to create new patch dimensions. Like `chunk`, it is available on every spool and produces a lazy, plan-backed result. ```python @@ -306,7 +306,7 @@ merged = spool.concatenate(time=None) print(merged[0].coords) ``` -# map +## map The [`map`](`dascore.core.spool.BaseSpool.map`) method applies a function to all patches in the spool. It provides an efficient way to process large datasets, especially when combined with clients (aka executors). diff --git a/tutorial/transformations.qmd b/tutorial/transformations.qmd index d81202c88..0955646e7 100644 --- a/tutorial/transformations.qmd +++ b/tutorial/transformations.qmd @@ -6,7 +6,7 @@ execute: In DASCore, transformations are operations which change the domain of a patch, and usually its units and dimension names along with it. Transforms can be found in the [transform module](`dascore.transform`) or accessed as `Patch` methods. -# Discrete Fourier Transforms +## Discrete Fourier Transforms The [Discrete Fourier Transform](https://en.wikipedia.org/wiki/Discrete_Fourier_transform) (dft) is commonly used in many signal processing workflows. DASCore implements this as the [dft](`dascore.transform.fourier.dft`) patch method. @@ -52,7 +52,7 @@ print(f"dims after round trip: {round_trip.dims}") assert np.allclose(round_trip.data.real, patch.data) ``` -# Short Time Fourier Transform +## Short Time Fourier Transform Related to the Discrete Fourier Transform, the [Short Term Fourier Transform](https://en.wikipedia.org/wiki/Short-time_Fourier_transform) is useful for analyzing the time-dependent frequency content. DASCore implements this as [stft](`dascore.transform.fourier.stft`) and the corresponding [istft](`dascore.transform.fourier.istft`). diff --git a/tutorial/visualization.qmd b/tutorial/visualization.qmd index 011784ecc..0b5dcc7be 100644 --- a/tutorial/visualization.qmd +++ b/tutorial/visualization.qmd @@ -4,11 +4,11 @@ execute: warning: false --- -# Viz +## Viz The following provides some examples of patch visualization. See the [viz module documentation](/reference/index.qmd#visualization) for a list of visualization functions -## Waterfall +### Waterfall The [`waterfall patch function`](`dascore.viz.waterfall`) creates a waterfall plot of the patch data. ```{python} @@ -20,7 +20,7 @@ patch = dc.get_example_patch('example_event_2') patch.viz.waterfall(show=True); ``` -### Controlling color scaling +#### Controlling color scaling The `scale` parameter controls the colorbar saturation. By default, waterfall uses a statistical fence (1.5×IQR) to exclude outliers and show the majority of the data clearly. @@ -44,7 +44,7 @@ plt.tight_layout() plt.show() ``` -## Wiggle +### Wiggle The [`wiggle patch function`](`dascore.viz.wiggle`) creates a wiggle plot of the patch data. We'll use the same patch as above to model this function. ```{python} From f8b09ccc89312366c23c60be23d1a4a21431bd5b Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Mon, 20 Jul 2026 12:07:07 +0200 Subject: [PATCH 07/22] Match the old doc site's theme instead of hand-styling great-docs The prototype styled the site with a + light: "#eeeeee" + dark: "#222222" # Bibliography so citations (e.g. @lindsey2020broadband) in docstrings and # narrative pages resolve instead of hanging pandoc. From f4cece256732bc394facf36dfb13550b77da681e Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Tue, 11 Aug 2026 10:48:27 +0200 Subject: [PATCH 08/22] Reconcile the great-docs build with the current dev API Rebasing onto dev picked up API changes that break or skew the doc build: - BaseSpool.viz and io.PatchFileSummary were removed by dev; leaving them in the reference config fails the API-reference step outright. - Spool.stack moved up to BaseSpool, so document it there. - Drop exclude entries for names that no longer exist. - Point the new coordinate-internals docstring links at the site path used by the rest of the package. --- dascore/core/coords.py | 6 +++--- dascore/core/summary.py | 2 +- dascore/io/dasdae/utils.py | 2 +- great-docs.yml | 8 ++------ 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/dascore/core/coords.py b/dascore/core/coords.py index a0cf22c17..52d09f4de 100644 --- a/dascore/core/coords.py +++ b/dascore/core/coords.py @@ -1,6 +1,6 @@ """Machinery for coordinates. -See ['Coordinate Internals'](`docs/notes/coordinate_internals.qmd`) for the +See [Coordinate Internals](/notes/coordinate_internals.qmd) for the current coord-family and string-coordinate design notes. """ @@ -2739,7 +2739,7 @@ def _raise_string_coord_error(operation: str) -> None: class CoordString(BaseCoord): """A coordinate implementation for string/categorical values. - See ['Coordinate Internals'](`docs/notes/coordinate_internals.qmd`) for the + See [Coordinate Internals](/notes/coordinate_internals.qmd) for the constraints that make string coords differ from numeric and time-like coords. Plain string selectors use exact matching unless they contain `*` or `?`, in which case they are treated as unix-style wildcard patterns. @@ -2943,7 +2943,7 @@ def get_coord( Notes ----- - See ['Coordinate Internals'](`docs/notes/coordinate_internals.qmd`) for + See [Coordinate Internals](/notes/coordinate_internals.qmd) for dispatch and coord-family design notes. The following combinations of input parameters are typical: diff --git a/dascore/core/summary.py b/dascore/core/summary.py index a49c62cbe..799dec55b 100644 --- a/dascore/core/summary.py +++ b/dascore/core/summary.py @@ -1,6 +1,6 @@ """Summary models for patch workflows. -See ['Coordinate Internals'](`docs/notes/coordinate_internals.qmd`) for the +See [Coordinate Internals](/notes/coordinate_internals.qmd) for the relationship between full coords, exact coord summaries, and flattened index metadata. """ diff --git a/dascore/io/dasdae/utils.py b/dascore/io/dasdae/utils.py index c6aea96b1..e3248b1f5 100644 --- a/dascore/io/dasdae/utils.py +++ b/dascore/io/dasdae/utils.py @@ -1,6 +1,6 @@ """DASDAE format utilities. -See ['Coordinate Internals'](`docs/notes/coordinate_internals.qmd`) for the +See [Coordinate Internals](/notes/coordinate_internals.qmd) for the coord serialization and string-serialization design notes used here. """ diff --git a/great-docs.yml b/great-docs.yml index bc01a3ccd..a9b52a54c 100644 --- a/great-docs.yml +++ b/great-docs.yml @@ -87,7 +87,6 @@ exclude: - warnings - compat.MATERIALIZE_NOW - compat.random_state - - examples.compose_docstring - examples.fetch - examples.iterate - examples.get_patch_names @@ -117,9 +116,7 @@ exclude: - units.is_timedelta64 - units.iterate - units.maybe_convert_percent_to_fraction - - units.numeric - units.quant_sequence_to_quant_array - - units.str_or_none - units.unbyte - units.UnitError - viz.PatchNameSpace @@ -143,9 +140,9 @@ reference: - name: Patch members: [data, coords, dims, attrs, shape, size, ndim, dtype, seconds, channel_count, coord_shapes, get_patch_name, T] - name: BaseSpool - members: [chunk, concatenate, get_contents, get_patch_names, map, select, sort, split, update, viz] + members: [chunk, concatenate, get_contents, get_patch_names, map, select, sort, split, stack, update] - name: Spool - members: [from_directory, from_file, chunk_plan, stack, spool_path, indexer, has_live_patches] + members: [from_directory, from_file, chunk_plan, spool_path, indexer, has_live_patches] - name: PatchAttrs members: [drop, drop_private, flat_dump, from_dict, get, get_summary_df, items, update] - name: CoordManager @@ -306,7 +303,6 @@ reference: contents: - io.FiberIO - io.PatchIO - - io.PatchFileSummary - io.dataframe_to_patch - io.patch_to_dataframe - io.obspy_to_patch From f6a861702c71ca6a3dbdf73d05a8a79ecbe762d5 Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Tue, 11 Aug 2026 11:19:33 +0200 Subject: [PATCH 09/22] Build with great-docs 0.16 and cover dev's newer API great-docs 0.16 renders class signatures with their parameters and points See Also links at the pages the reference actually generates (0.14 emitted 404s for every one of them), so require it in the doc workflow. Document the API dev added since the prototype was written, which was turning up as unresolved cross references: scan_payloads/ScanPayload, PatchSummary, the segmented-coordinate types, ChunkPlan, clear_remote_file_cache and the new exceptions. Also document the aggregate functions (patch.mean, patch.std, ...), which the reference had never covered. Reference entries have to be reachable by attribute traversal from the dascore package: adding io.utils.get_exact_coord, where io.utils is only a submodule, makes griffe's dynamic introspection fail and silently drops the whole reference to static analysis, leaving compose_docstring templates unrendered. Pin the prototype workflow's actions to hashes so it passes the zizmor policy dev now enforces. --- .github/workflows/build_docs_greatdocs.yaml | 17 +++++++---- .gitignore | 2 ++ contributing/new_format.qmd | 2 +- dascore/transform/fourier.py | 5 ++-- great-docs.yml | 33 +++++++++++++++++++-- scripts/greatdocs_alias_inventory.py | 1 + skills/dascore/SKILL.md | 4 +-- 7 files changed, 51 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build_docs_greatdocs.yaml b/.github/workflows/build_docs_greatdocs.yaml index 0b8f5c4be..3c184ff37 100644 --- a/.github/workflows/build_docs_greatdocs.yaml +++ b/.github/workflows/build_docs_greatdocs.yaml @@ -12,20 +12,24 @@ name: BuildDocsGreatDocs on: workflow_dispatch: +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: + persist-credentials: false fetch-tags: "true" fetch-depth: "0" - - uses: quarto-dev/quarto-actions/setup@v2 + - uses: quarto-dev/quarto-actions/setup@8a96df13519ee81fd526f2dfca5962811136661b # v2.2.0 with: version: 1.8.27 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.12" @@ -34,7 +38,10 @@ jobs: # docs: doc-build helpers; test: pytest (used by some notes pages); # extras: optional format/processing deps imported by example cells # (findiff, xarray, obspy, ...). - python -m pip install -e ".[docs,test,extras]" great-docs + # great-docs >=0.16 renders class signatures with their parameters + # and points See Also links at the pages the reference actually + # generates; earlier versions emit broken links. + python -m pip install -e ".[docs,test,extras]" "great-docs>=0.16" - name: Prepare test data run: | @@ -44,7 +51,7 @@ jobs: run: | great-docs build - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: documentation path: ./great-docs/_site diff --git a/.gitignore b/.gitignore index 759de9549..1a80f187b 100644 --- a/.gitignore +++ b/.gitignore @@ -115,3 +115,5 @@ prof/ #JetBrains .idea/ great-docs/ +# Quarto freeze cache written by great-docs builds. +_freeze/ diff --git a/contributing/new_format.qmd b/contributing/new_format.qmd index 824b0f8bd..138fcd6c3 100644 --- a/contributing/new_format.qmd +++ b/contributing/new_format.qmd @@ -143,7 +143,7 @@ Every `FiberIO.scan` implementation must accept `snap: bool = True`, either expl - `snap=True` (the default) preserves existing behavior. Formats may represent stored sample times as an idealized uniform range. - `snap=False` means returned coords must represent stored coordinate values exactly. For header-defined formats whose coordinates are already specified by start, step, and sample count, this is a documented no-op. -Formats that read stored per-sample coordinate arrays must not use bare `get_coord(array)` for the exact path because its tolerant uniformity inference can snap small jitter. Use the shared [`get_exact_coord`](`dascore.io.utils.get_exact_coord`) helper, which builds a value-preserving coordinate via `CoordSegmented.from_array(values, tolerance=0, units=...)`: a truly uniform array becomes a `CoordRange`, a piecewise-uniform array exposes its internal sampling changes through `CoordSegmented`, and a non-monotonic array falls back to a plain array coordinate. The helper also guards against pathological input: an array whose sub-step jitter would produce roughly one segment per sample is returned as a plain monotonic coordinate rather than an over-segmented one, keeping every value exact without the memory and construction cost of per-sample seams. +Formats that read stored per-sample coordinate arrays must not use bare `get_coord(array)` for the exact path because its tolerant uniformity inference can snap small jitter. Use the shared `get_exact_coord` helper (in `dascore.io.utils`), which builds a value-preserving coordinate via `CoordSegmented.from_array(values, tolerance=0, units=...)`: a truly uniform array becomes a `CoordRange`, a piecewise-uniform array exposes its internal sampling changes through `CoordSegmented`, and a non-monotonic array falls back to a plain array coordinate. The helper also guards against pathological input: an array whose sub-step jitter would produce roughly one segment per sample is returned as a plain monotonic coordinate rather than an over-segmented one, keeping every value exact without the memory and construction cost of per-sample seams. `snap=False` describes the coordinate values *stored* by the format, which are not necessarily what `read(...)` returns. A format whose `read` reconstructs coordinates from header start/step/count metadata (e.g. ProdML) will still return that idealized range from `read`, while `scan_payloads(..., snap=False)` reports the exact stored per-sample array. The common IO conformance test only compares scan and read coordinates for formats whose `read` also accepts `snap`/`snap_dims`. diff --git a/dascore/transform/fourier.py b/dascore/transform/fourier.py index a1366e37b..36d8a94df 100644 --- a/dascore/transform/fourier.py +++ b/dascore/transform/fourier.py @@ -418,7 +418,7 @@ def idft(patch: PatchType, dim: str | Sequence[str] | None = None) -> PatchType: Currently, only patches that have been transformed with [dft](`dascore.transform.fourier.dft`) can be used with this function. After transformation with dft, the transformed coordinates cannot change - (e.g., with [select]('dascore.proc.basic.select`) otherwise idft won't + (e.g., with [select](`dascore.proc.select`)) otherwise idft won't work. Parameters @@ -436,8 +436,7 @@ def idft(patch: PatchType, dim: str | Sequence[str] | None = None) -> PatchType: - Real transforms are determined by transformed coordinates which have no negative values. - - See the [FFT note](dascore.org/notes/fft_notes.html) in Notes section - of DASCore's documentation. + - See the [FFT note](/notes/dft_notes.qmd) for more details. See Also -------- diff --git a/great-docs.yml b/great-docs.yml index a9b52a54c..f561cebf6 100644 --- a/great-docs.yml +++ b/great-docs.yml @@ -131,6 +131,7 @@ reference: - read - scan - scan_to_df + - scan_payloads - write - get_format @@ -138,17 +139,25 @@ reference: desc: The central data structures of DASCore contents: - name: Patch - members: [data, coords, dims, attrs, shape, size, ndim, dtype, seconds, channel_count, coord_shapes, get_patch_name, T] + members: [data, coords, dims, attrs, shape, size, ndim, dtype, seconds, channel_count, coord_shapes, get_coord, get_patch_name, T] - name: BaseSpool members: [chunk, concatenate, get_contents, get_patch_names, map, select, sort, split, stack, update] - name: Spool members: [from_directory, from_file, chunk_plan, spool_path, indexer, has_live_patches] - name: PatchAttrs members: [drop, drop_private, flat_dump, from_dict, get, get_summary_df, items, update] + - name: PatchSummary + members: [dim_tuple, dump_structured, flat_dump, from_patch, get_coord_summary, get_summary_df] - name: CoordManager members: [convert_units, coord_range, coord_shapes, coord_size, decimate, dim_to_coord_map, disassociate_coord, drop_coords, drop_disassociated_coords, drop_private_coords, equals, flip, get_array, get_axis, get_coord, get_coord_tuple_map, keys, make_broadcastable_to, max, min, ndim, new, order, rename_coord, select, set_dims, set_units, shape, simplify_units, size, snap, sort, squeeze, step, to_summary_dict, transpose, update, validate_data] - name: proc.BaseCoord - members: [align_to, approx_equal, change_length, convert_units, coord_range, empty, get_next_index, get_sample_count, get_slice_tuple, index, max, min, new, order, reduce_coord, select, set_units, simplify_units, snap, sort, to_summary, update, update_data, update_limits] + members: [align_to, approx_equal, change_length, convert_units, coord_range, empty, get_discontinuities, get_next_index, get_sample_count, get_slice_tuple, index, max, min, new, order, reduce_coord, select, set_units, simplify, simplify_units, snap, sort, to_summary, update, update_data, update_limits] + - name: proc.CoordSegmented + members: [from_array, get_discontinuities, simplify] + - core.coords.CoordRange + - core.coords.CoordMonotonicArray + - core.coords.CoordSummary + - core.coords.concat_coords - get_coord - get_coord_manager @@ -159,6 +168,17 @@ reference: contents: - proc.abs - proc.add_distance_to + - proc.aggregate.aggregate + - proc.aggregate.all + - proc.aggregate.any + - proc.aggregate.first + - proc.aggregate.last + - proc.aggregate.max + - proc.aggregate.mean + - proc.aggregate.median + - proc.aggregate.min + - proc.aggregate.std + - proc.aggregate.sum - proc.align_patch_coords - proc.align_to_coord - proc.angle @@ -303,6 +323,7 @@ reference: contents: - io.FiberIO - io.PatchIO + - io.ScanPayload - io.dataframe_to_patch - io.patch_to_dataframe - io.obspy_to_patch @@ -326,7 +347,9 @@ reference: contents: - utils.array.apply_ufunc - utils.array.apply_array_func + - utils.chunk_plan.ChunkPlan - utils.patch.merge_compatible_coords_attrs + - utils.remote_io.clear_remote_file_cache - title: Exceptions desc: Exception classes raised by DASCore @@ -338,6 +361,7 @@ reference: - exceptions.CoordDataError - exceptions.CoordMergeError - exceptions.CoordSortError + - exceptions.DASCorePluginError - exceptions.DASVaderCompatibilityError - exceptions.DependencyError - exceptions.FilterValueError @@ -345,16 +369,21 @@ reference: - exceptions.InvalidFiberFileError - exceptions.InvalidFiberIOError - exceptions.InvalidFileHandlerError + - exceptions.InvalidIndexError - exceptions.InvalidIndexVersionError + - exceptions.InvalidInventoryError - exceptions.InvalidSpoolError + - exceptions.InvalidSpoolQueryError - exceptions.InvalidTimeRangeError - exceptions.MissingOptionalDependencyError + - exceptions.MissingPatchError - exceptions.ParameterError - exceptions.PatchAttributeError - exceptions.PatchBroadcastError - exceptions.PatchConversionError - exceptions.PatchCoordinateError - exceptions.PatchError + - exceptions.RemoteCacheError - exceptions.TimeError - exceptions.UnitError - exceptions.UnknownExampleError diff --git a/scripts/greatdocs_alias_inventory.py b/scripts/greatdocs_alias_inventory.py index cc4865042..db07cb4d8 100644 --- a/scripts/greatdocs_alias_inventory.py +++ b/scripts/greatdocs_alias_inventory.py @@ -35,6 +35,7 @@ "dascore.exceptions": "reference/index.html#exceptions", "dascore.io": "reference/index.html#io-interfaces", "dascore.proc": "reference/index.html#patch-processing", + "dascore.proc.aggregate": "reference/index.html#patch-processing", "dascore.transform": "reference/index.html#transforms", "dascore.units": "reference/index.html#units-and-time", "dascore.utils": "reference/index.html#utilities", diff --git a/skills/dascore/SKILL.md b/skills/dascore/SKILL.md index f820a6c43..b66af2e34 100644 --- a/skills/dascore/SKILL.md +++ b/skills/dascore/SKILL.md @@ -48,7 +48,7 @@ for patch in spool: | Read data files | `dc.spool(path)[0]` or iterate | `dc.read` (low-level) | | Discover file metadata cheaply | `dc.scan(path)` / `dc.scan_to_df(path)` | reading whole files | | Subset by time/distance values | `patch.select(time=(t1, t2))` | index math | -| Subset by sample index | `patch.select(time=(0, 100), samples=True)` | `iselect` shorthand also exists | +| Subset by sample index | `patch.select(time=(0, 100), samples=True)` | index math on `patch.data` | | Merge contiguous patches | `spool.chunk(time=None)` | manual `np.concatenate` | | Fixed-length windows | `spool.chunk(time=30, overlap=5)` | manual slicing | | Parallel processing | `spool.map(func, client=executor)` | multiprocessing on patches directly | @@ -83,7 +83,7 @@ for patch in spool: - DASCore handles single-experiment array data, not seismic network workflows — use ObsPy for station/inventory-based seismology. - Supported formats and their read/scan/write capabilities are listed at - https://dascore.org/supported_formats.html — writing is only supported + https://dascore.org/about/supported_formats.html — writing is only supported for a few formats (DASDAE, and converters via ObsPy/xarray). - For very large datasets, prefer `spool.select(...).chunk(...)` before loading; patches load lazily from directory spools. From f9af07a35fe41aff6365ce5668de197ba01ded43 Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Tue, 11 Aug 2026 12:07:16 +0200 Subject: [PATCH 10/22] Retire the old documentation build great-docs now renders the whole site, so the custom pipeline it replaced comes out: the api-doc scripts and their templates, the link-filling pandoc filter, the old landing page and stylesheet, and the prep_doc_build action. The three doc workflows share one build-docs action that installs great-docs and runs it; master deploys great-docs/_site to netlify with the netlify CLI, since `quarto publish` has no project to publish now that the site id in docs/_publish.yml is gone. Two pages from docs/ survive the move: the hand-maintained list of unreleased API changes (the generated changelog only covers published releases) and the third-party plugin table, both now in about/. generate_doc_code_tests.py walks the section directories rather than docs/, which is otherwise nearly empty; without this it would silently stop mirroring every narrative page into the test suite. Drop the section landing pages that only listed their own section's pages: great-docs generates a card index for each, so they showed up as a card inside themselves. contributing.qmd has content of its own and keeps its url, so only its title changes. The generated cards are laid out one per row with banner-sized padding; style them as a compact responsive grid. --- .agents/agents.md | 10 +- .github/actions/build-docs/action.yml | 28 +- .github/actions/prep_doc_build/action.yml | 23 - .../workflows/build_deploy_master_docs.yaml | 11 +- .../workflows/build_deploy_stable_docs.yaml | 4 +- .github/workflows/build_docs_greatdocs.yaml | 65 -- .github/workflows/test_doc_build.yml | 4 +- .gitignore | 11 +- .pre-commit-config.yaml | 1 - {docs => about}/supported_plugins.qmd | 1 + assets/dascore.scss | 54 ++ contributing/contributing.qmd | 2 +- dascore/proc/aggregate.py | 8 +- dascore/proc/hampel.py | 5 +- dascore/proc/mute.py | 12 +- dascore/transform/fourier.py | 8 +- dascore/utils/patch.py | 4 +- docs/.gitignore | 6 - docs/_publish.yml | 4 - docs/changelog.qmd | 5 - docs/filters/fill_links.py | 113 ---- docs/filters/filter_test_data/test.json | 1 - .../filters/filter_test_data/test_data_2.json | 1 - .../filters/filter_test_data/test_data_3.json | 1 - .../filters/filter_test_data/test_data_4.json | 1 - docs/index.css | 233 ------- docs/index.qmd | 129 ---- docs/styles.css | 78 --- great-docs.yml | 8 +- notes/notes.qmd | 15 - pyproject.toml | 4 +- recipes/contributing_to_documentation.qmd | 28 +- recipes/overview.qmd | 6 - scripts/_index_api.py | 267 -------- scripts/_qmd_builder.py | 103 --- scripts/_render_api.py | 639 ------------------ scripts/_templates/_quarto.yml | 240 ------- scripts/_templates/notes.md | 4 - scripts/_templates/parent_source_block.html | 6 - scripts/_templates/signature.html | 19 - scripts/_templates/table.html | 24 - scripts/_validate_links.py | 72 -- scripts/build_api_docs.py | 31 - scripts/generate_doc_code_tests.py | 31 +- scripts/greatdocs_alias_inventory.py | 1 + scripts/greatdocs_build_fixups.py | 4 +- scripts/test_generate_doc_code_tests.py | 14 +- scripts/test_index_api.py | 35 - scripts/test_qmd_builder.py | 32 - scripts/test_render_api.py | 134 ---- 50 files changed, 167 insertions(+), 2373 deletions(-) delete mode 100644 .github/actions/prep_doc_build/action.yml delete mode 100644 .github/workflows/build_docs_greatdocs.yaml rename {docs => about}/supported_plugins.qmd (86%) delete mode 100644 docs/.gitignore delete mode 100644 docs/_publish.yml delete mode 100644 docs/changelog.qmd delete mode 100644 docs/filters/fill_links.py delete mode 100644 docs/filters/filter_test_data/test.json delete mode 100644 docs/filters/filter_test_data/test_data_2.json delete mode 100644 docs/filters/filter_test_data/test_data_3.json delete mode 100644 docs/filters/filter_test_data/test_data_4.json delete mode 100644 docs/index.css delete mode 100644 docs/index.qmd delete mode 100644 docs/styles.css delete mode 100644 notes/notes.qmd delete mode 100644 recipes/overview.qmd delete mode 100644 scripts/_index_api.py delete mode 100644 scripts/_qmd_builder.py delete mode 100644 scripts/_render_api.py delete mode 100644 scripts/_templates/_quarto.yml delete mode 100644 scripts/_templates/notes.md delete mode 100644 scripts/_templates/parent_source_block.html delete mode 100644 scripts/_templates/signature.html delete mode 100644 scripts/_templates/table.html delete mode 100644 scripts/_validate_links.py delete mode 100644 scripts/build_api_docs.py delete mode 100644 scripts/test_index_api.py delete mode 100644 scripts/test_qmd_builder.py delete mode 100644 scripts/test_render_api.py diff --git a/.agents/agents.md b/.agents/agents.md index 854ddb09d..840170715 100644 --- a/.agents/agents.md +++ b/.agents/agents.md @@ -42,16 +42,18 @@ pytest dascore --doctest-modules ## Docs -- `.qmd` under `docs/`; API docs come from docstrings. Update with any behavior or API change. Do not hard-wrap prose. -- Edit `scripts/_templates/_quarto.yml` for site structure; `docs/_quarto.yml` is generated. +- `.qmd` in the top-level section directories (`tutorial/`, `recipes/`, `notes/`, `contributing/`, `about/`), with `index.qmd` as the landing page. API docs come from docstrings. Update with any behavior or API change. Do not hard-wrap prose. +- Site structure, styling and the curated API reference are configured in `great-docs.yml`; the `great-docs/` directory is generated. New public API needs a reference entry, and `tests/test_doc_coverage.py` fails when it has none. ```bash -python scripts/build_api_docs.py && quarto render docs +pip install "great-docs>=0.16" +great-docs build # writes great-docs/_site +great-docs preview # serves the built site ``` ### Changelog -No changelog file, and do not add one — no `CHANGELOG.md`, `changelog.d/`, or "unreleased" sections. `docs/changelog.qmd` is a stub pinned by `tests/test_changelog.py`. Put the summary in the PR's required `## Changelog` section, formatted per "Changelog entries" in `docs/contributing/general_guidelines.qmd`; `.github/scripts/check_pr_changelog.py` is the parser CI runs. +No changelog file, and do not add one — no `CHANGELOG.md`, `changelog.d/`, or "unreleased" sections; the site's changelog page is generated from the GitHub releases at build time, and `tests/test_changelog.py` fails if a source page appears. Put the summary in the PR's required `## Changelog` section, formatted per "Changelog entries" in `contributing/general_guidelines.qmd`; `.github/scripts/check_pr_changelog.py` is the parser CI runs. ## Before handing off diff --git a/.github/actions/build-docs/action.yml b/.github/actions/build-docs/action.yml index ae83a258c..e8b76825b 100644 --- a/.github/actions/build-docs/action.yml +++ b/.github/actions/build-docs/action.yml @@ -1,13 +1,31 @@ name: "Build DASCore Docs" -description: "Builds DASCore's Documentation." +description: "Builds DASCore's Documentation with great-docs." runs: using: "composite" steps: - - uses: ./.github/actions/prep_doc_build + - name: Install quarto + uses: quarto-dev/quarto-actions/setup@8a96df13519ee81fd526f2dfca5962811136661b # v2.2.0 + with: + # 1.3.x dies with "RangeError: Invalid string length" once the + # generated API sidebar gets large enough; see + # quarto-dev/quarto-cli#10504. + version: 1.8.27 - - name: build quarto project - shell: bash + - name: print quarto version + shell: bash -l {0} run: | - quarto render docs + quarto --version + + - name: install great-docs + shell: bash -l {0} + run: | + # >=0.16 renders class signatures with their parameters and points + # See Also links at the pages the reference actually generates. + python -m pip install "great-docs>=0.16" + + - name: build documentation + shell: bash -l {0} + run: | + great-docs build diff --git a/.github/actions/prep_doc_build/action.yml b/.github/actions/prep_doc_build/action.yml deleted file mode 100644 index cd350c166..000000000 --- a/.github/actions/prep_doc_build/action.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: "prepare for doc build" -description: "Installs quarto, renders api docs, prints quarto version" - -runs: - using: "composite" - steps: - - name: Install quarto - uses: quarto-dev/quarto-actions/setup@8a96df13519ee81fd526f2dfca5962811136661b # v2.2.0 - with: - # 1.3.x dies with "RangeError: Invalid string length" once the - # generated _quarto.yml API sidebar gets large enough; see - # quarto-dev/quarto-cli#10504. - version: 1.8.27 - - - name: print quarto version - shell: bash - run: | - quarto --version - - - name: render API docs - shell: bash - run: | - python scripts/build_api_docs.py diff --git a/.github/workflows/build_deploy_master_docs.yaml b/.github/workflows/build_deploy_master_docs.yaml index 034b73633..5698a39ee 100644 --- a/.github/workflows/build_deploy_master_docs.yaml +++ b/.github/workflows/build_deploy_master_docs.yaml @@ -49,12 +49,17 @@ jobs: python-version: ${{ steps.shared-vars.outputs.python-default }} prepare-test-data: "true" - - uses: ./.github/actions/prep_doc_build + - uses: ./.github/actions/build-docs - name: publish docs to netlify shell: bash env: - QUARTO_PRINT_STACK: true NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} run: | - quarto publish docs --no-prompt --no-browser + # The site id previously lived in docs/_publish.yml, which + # `quarto publish` read; great-docs emits a plain directory, so + # deploy it with netlify's own CLI instead. + npx --yes netlify-cli@23 deploy \ + --prod --no-build \ + --dir great-docs/_site \ + --site da79b12f-cb25-4fcc-aeb6-f19705848130 diff --git a/.github/workflows/build_deploy_stable_docs.yaml b/.github/workflows/build_deploy_stable_docs.yaml index abe6f3ca5..e89685111 100644 --- a/.github/workflows/build_deploy_stable_docs.yaml +++ b/.github/workflows/build_deploy_stable_docs.yaml @@ -81,11 +81,11 @@ jobs: - name: Upload artifact uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: - path: 'docs/_site' + path: 'great-docs/_site' - name: Zip doc build if: startsWith(github.ref, 'refs/tags/') - run: zip docs.zip docs/_site -r + run: zip docs.zip great-docs/_site -r - name: Upload release docs if: startsWith(github.ref, 'refs/tags/') diff --git a/.github/workflows/build_docs_greatdocs.yaml b/.github/workflows/build_docs_greatdocs.yaml deleted file mode 100644 index 3c184ff37..000000000 --- a/.github/workflows/build_docs_greatdocs.yaml +++ /dev/null @@ -1,65 +0,0 @@ -# Proposed replacement for the doc-build workflows using great-docs. -# One command (great-docs build) replaces scripts/build_api_docs.py + -# quarto render, and the output additionally contains llms.txt, -# llms-full.txt, per-page markdown, SKILL.md and .well-known/agent-skills. -# -# NOTE (prototype): kept alongside the old workflows for comparison; a real -# migration would fold this into build_deploy_master_docs.yaml, -# build_deploy_stable_docs.yaml and test_doc_build.yml. - -name: BuildDocsGreatDocs - -on: - workflow_dispatch: - -permissions: - contents: read - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - fetch-tags: "true" - fetch-depth: "0" - - - uses: quarto-dev/quarto-actions/setup@8a96df13519ee81fd526f2dfca5962811136661b # v2.2.0 - with: - version: 1.8.27 - - - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 - with: - python-version: "3.12" - - - name: Install dascore and great-docs - run: | - # docs: doc-build helpers; test: pytest (used by some notes pages); - # extras: optional format/processing deps imported by example cells - # (findiff, xarray, obspy, ...). - # great-docs >=0.16 renders class signatures with their parameters - # and points See Also links at the pages the reference actually - # generates; earlier versions emit broken links. - python -m pip install -e ".[docs,test,extras]" "great-docs>=0.16" - - - name: Prepare test data - run: | - python scripts/modify_h5_file.py || true - - - name: Build documentation - run: | - great-docs build - - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: documentation - path: ./great-docs/_site - # .well-known/agent-skills must survive packaging - include-hidden-files: true - retention-days: 7 - - # Deployment: `quarto publish` no longer applies; push great-docs/_site - # with the netlify CLI instead, e.g.: - # npx netlify-cli deploy --prod --dir great-docs/_site - # or use great-docs setup-github-pages for a Pages deployment. diff --git a/.github/workflows/test_doc_build.yml b/.github/workflows/test_doc_build.yml index a79086184..869e2b1b1 100644 --- a/.github/workflows/test_doc_build.yml +++ b/.github/workflows/test_doc_build.yml @@ -49,7 +49,9 @@ jobs: - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: documentation_build_test - path: ./docs/_site + path: ./great-docs/_site + # .well-known/agent-skills must survive packaging + include-hidden-files: true retention-days: 1 - name: Generate documentation URL diff --git a/.gitignore b/.gitignore index 1a80f187b..54bd86513 100644 --- a/.gitignore +++ b/.gitignore @@ -52,9 +52,6 @@ coverage.xml # logs: *.log -# Sphinx documentation -docs/_build/ - # PyBuilder target/ @@ -70,12 +67,9 @@ target/ .DS_store* # docs -docs/api/* _autosummary .quarto/ -docs/site_libs -docs/_quarto.yml -docs/**/*.ipynb +**/*.quarto_ipynb .cross_ref.json # profile stuff from asv @@ -88,8 +82,7 @@ scratch/** uv.lock tests/test_autogenerated_doccode/ -docs/index_files -docs/index.quarto_ipynb +index_files/ # Agent stuff .codex diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 10ef6d235..eb3914ed2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,3 @@ -exclude: scripts/_templates repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.3.0 diff --git a/docs/supported_plugins.qmd b/about/supported_plugins.qmd similarity index 86% rename from docs/supported_plugins.qmd rename to about/supported_plugins.qmd index c4b68e204..3c05dd4cb 100644 --- a/docs/supported_plugins.qmd +++ b/about/supported_plugins.qmd @@ -1,5 +1,6 @@ --- title: Supported Third-Party Plugins +description: "Packages that add namespaces to DASCore's Patch and Spool." execute: warning: false --- diff --git a/assets/dascore.scss b/assets/dascore.scss index 9cee7a8ad..5cc400247 100644 --- a/assets/dascore.scss +++ b/assets/dascore.scss @@ -213,3 +213,57 @@ body:has(.gd-hero) { display: none; } } + +// Section index cards (the generated Recipes/Notes/Contributing/About +// landing pages). great-docs lays out description-only entries as a +// single-column grid of tall, generously padded boxes, which reads as a stack +// of banners; this makes them a responsive multi-column grid of smaller cards. +// +// The generated markup carries these rules as inline styles, so the overrides +// have to be `!important` to win. Everything great-docs does not set inline +// (hover, dark mode) is left as a normal rule. +.section-cards.section-cards-list { + grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)) !important; + gap: 0.75rem !important; + + .section-card { + padding: 0.75rem 0.9rem !important; + border-color: $border-color !important; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + + &:hover { + border-color: rgba($primary, 0.6) !important; + box-shadow: 0 0.125rem 0.35rem rgba(0, 0, 0, 0.08); + } + } + + .section-card-title { + font-size: 1rem !important; + margin-bottom: 0.2rem !important; + color: $primary !important; + } + + .section-card-desc { + font-size: 0.85rem !important; + line-height: 1.4 !important; + } +} + +body.quarto-dark .section-cards.section-cards-list { + .section-card { + border-color: rgba(255, 255, 255, 0.15) !important; + + &:hover { + border-color: rgba(tint-color($primary, 45%), 0.6) !important; + box-shadow: none; + } + } + + .section-card-title { + color: tint-color($primary, 45%) !important; + } + + .section-card-desc { + color: rgba(255, 255, 255, 0.65) !important; + } +} diff --git a/contributing/contributing.qmd b/contributing/contributing.qmd index 020673820..40163452e 100644 --- a/contributing/contributing.qmd +++ b/contributing/contributing.qmd @@ -1,5 +1,5 @@ --- -title: Contributing +title: Contributing Overview description: "How to get involved and contribute to DASCore." --- diff --git a/dascore/proc/aggregate.py b/dascore/proc/aggregate.py index 0b0ad6e6a..31caf762a 100644 --- a/dascore/proc/aggregate.py +++ b/dascore/proc/aggregate.py @@ -47,10 +47,10 @@ def aggregate( The aggregation to apply along dimension. Options are: {options} - See Also - -------- - - See also the aggregation shortcut methods in the - [aggregate module](`dascore.proc.aggregate`). + Notes + ----- + The aggregation shortcut methods (`patch.mean`, `patch.std`, ...) live in + the [aggregate module](`dascore.proc.aggregate`) and call this function. Examples -------- diff --git a/dascore/proc/hampel.py b/dascore/proc/hampel.py index 949540e47..ac8f38e2d 100644 --- a/dascore/proc/hampel.py +++ b/dascore/proc/hampel.py @@ -148,9 +148,8 @@ def hampel_filter( - Installing `bottleneck` package can further improve approximate-mode performance. - See Also - -------- - - [Despiking recipe](/recipes/despiking.qmd) + The [despiking recipe](/recipes/despiking.qmd) shows this filter used on + an example dataset. Examples -------- diff --git a/dascore/proc/mute.py b/dascore/proc/mute.py index 9d9d4d9c8..4e58c7181 100644 --- a/dascore/proc/mute.py +++ b/dascore/proc/mute.py @@ -525,10 +525,10 @@ def line_mute( See Also -------- - - [`Patch.select`](`dascore.Patch.select`) - - [`Patch.taper_range`](`dascore.Patch.taper_range`) - - [`Patch.gaussian_filter`](`dascore.proc.filter.gaussian_filter`) - - [`Patch.slope_mute`](`dascore.Patch.slope_mute`) + dascore.proc.coords.select + dascore.proc.taper.taper_range + dascore.proc.filter.gaussian_filter + dascore.proc.mute.slope_mute """ # Get geometry object to set up the problem. geo = _get_mute_geometry(patch, kwargs, relative) @@ -610,8 +610,8 @@ def slope_mute( See Also -------- - - [`Patch.slope_filter`](`dascore.proc.filter.slope_filter`) - - [`Patch.line_mute`](`dascore.proc.mute.line_mute`) + dascore.proc.filter.slope_filter + dascore.proc.mute.line_mute """ # Convert slopes to array and validate slopes_array = np.asarray(slopes) diff --git a/dascore/transform/fourier.py b/dascore/transform/fourier.py index 36d8a94df..400b5c6da 100644 --- a/dascore/transform/fourier.py +++ b/dascore/transform/fourier.py @@ -266,8 +266,8 @@ def dft( See Also -------- - - [idft](`dascore.transform.fourier.idft`) - - [stft](`dascore.transform.fourier.stft`) + dascore.transform.fourier.idft + dascore.transform.fourier.stft Examples -------- @@ -440,8 +440,8 @@ def idft(patch: PatchType, dim: str | Sequence[str] | None = None) -> PatchType: See Also -------- - - [dft](`dascore.transform.fourier.dft`) - - [istft](`dascore.transform.fourier.istft`) + dascore.transform.fourier.dft + dascore.transform.fourier.istft Examples -------- diff --git a/dascore/utils/patch.py b/dascore/utils/patch.py index 84ee08a50..4c4a1bd0c 100644 --- a/dascore/utils/patch.py +++ b/dascore/utils/patch.py @@ -602,8 +602,8 @@ def get_patch_names( See Also -------- - - [`Patch.get_patch_name`](`dascore.Patch.get_patch_name`) - - [`Spool.get_patch_names`](`dascore.BaseSpool.get_patch_names`) + dascore.core.patch.Patch.get_patch_name + dascore.core.spool.BaseSpool.get_patch_names Examples -------- diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 8088b9c47..000000000 --- a/docs/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.quarto/ -_site/* - -/.quarto/ - -**/*.quarto_ipynb diff --git a/docs/_publish.yml b/docs/_publish.yml deleted file mode 100644 index 9ffd03714..000000000 --- a/docs/_publish.yml +++ /dev/null @@ -1,4 +0,0 @@ -- source: project - netlify: - - id: da79b12f-cb25-4fcc-aeb6-f19705848130 - url: 'https://dascore.netlify.app' diff --git a/docs/changelog.qmd b/docs/changelog.qmd deleted file mode 100644 index 3b246252d..000000000 --- a/docs/changelog.qmd +++ /dev/null @@ -1,5 +0,0 @@ -# Changelog - -DASCore's changelog is the [releases page](https://github.com/DASDAE/dascore/releases), which tracks changes from one version to another. - -This page remains only so that existing links to it keep working; it is not part of the site navigation and is never updated per pull request. Each pull request describes its own user-facing and breaking changes, and those descriptions are collected into the release notes when a version is tagged. See [publish a new release](contributing/publish_a_new_release.qmd) for that workflow. diff --git a/docs/filters/fill_links.py b/docs/filters/fill_links.py deleted file mode 100644 index ad819cb41..000000000 --- a/docs/filters/fill_links.py +++ /dev/null @@ -1,113 +0,0 @@ -""" -Custom filter that makes dynamic (sphinx-esc) cross links work. - -Replaces markdown such as [Patch](`dascore.Patch`) with the path to the markdown -file created from dascore/scripts/build_api_docs.py. -""" - -from __future__ import annotations - -import io -import json -import re -import sys -from functools import cache -from pathlib import Path - - -@cache -def get_cross_ref_dict() -> dict[str, str]: - """Load cross-reference dictionaries.""" - out = {} - path = Path(__file__).absolute() - count = 0 - while path.name != "docs" or str(path).count("docs") != 1: - path = path.parent - count += 1 - if count > 100: - raise ValueError("failed to find cross-ref file") - for cross_ref_path in path.rglob(".cross_ref.json"): - out.update(json.loads(cross_ref_path.read_text())) - assert out, "didn't find cross ref dict" - return out - - -def load_stdin(input_stream=None): - """Load input from stdin (json string).""" - if input_stream is None: - input_stream = io.TextIOWrapper(sys.stdin.buffer, encoding="utf-8") - return input_stream.read() - - -def dump_stdout(output_str, out_stream=None): - """Dump modified json string to std out.""" - if out_stream is None: - out_stream = sys.stdout - out_stream.write(output_str) - - -def replace_links(json_data, raw_string): - """Replace the aliases (links) with the cross-references.""" - - def _yield_links(element): - """Yield all link elements.""" - if isinstance(element, list): - for sub_element in element: - yield from _yield_links(sub_element) - elif isinstance(element, dict): - if element.get("t") == "Link": - yield element - else: - for item, value in element.items(): - yield from _yield_links(value) - # yield from _yield_links(element.get("c", [])) - - # reg_pattern = r'(?<="\%60)(.*?)(?=\%60")' - reg_pattern = r"(?<=\%60)(.*?)(?=\%60)" - replace_dict = {} - for link in _yield_links(json_data): - str_to_scan = json.dumps(link, separators=(",", ":"), ensure_ascii=False) - matches = re.finditer(reg_pattern, str_to_scan) - for match in matches: - start, stop = match.span() - cross_refs = get_cross_ref_dict() - key = str_to_scan[start:stop].replace("`", "") - if (new_value := cross_refs.get(key, key)) != key: - # new_sub_str = str_to_scan.replace(f'"%60{key}%60"', f'"{new_value}"') - new_sub_str = str_to_scan.replace(f"%60{key}%60", f"{new_value}") - if str_to_scan in replace_dict: - assert replace_dict[str_to_scan] == new_sub_str - replace_dict[str_to_scan] = new_sub_str - for i, v in replace_dict.items(): - raw_string = raw_string.replace(i, v) - return raw_string - - -def test(): - """Function to test filter.""" - here = Path(__file__).parent - data_path = here / "filter_test_data" / "test_data_4.json" - with data_path.open("r") as fi: - data = fi.read() - input_stream = io.StringIO(data) - main(input_stream) - - -def main(raw_data=None): - """Run filter.""" - raw_str = load_stdin(raw_data) - json_data = json.loads(raw_str) - output_data = replace_links(json_data, raw_str) - dump_stdout(output_data) - - -if __name__ == "__main__": - main() - # test() - - -# This is useful for debugging, but need to first install remote_pdb -# from remote_pdb import RemotePdb -# RemotePdb('127.0.0.1', 4444).set_trace() -# Then telnet into the debugger -# telnet 127.0.0.1 4444 diff --git a/docs/filters/filter_test_data/test.json b/docs/filters/filter_test_data/test.json deleted file mode 100644 index af852cac2..000000000 --- a/docs/filters/filter_test_data/test.json +++ /dev/null @@ -1 +0,0 @@ -{"pandoc-api-version":[1,22,2,1],"meta":{"biblio-config":{"t":"MetaBool","c":true},"bibliography":{"t":"MetaList","c":[{"t":"MetaInlines","c":[{"t":"Str","c":"references.bib"}]}]},"code-copy":{"t":"MetaBool","c":true},"date-format":{"t":"MetaInlines","c":[{"t":"Str","c":"long"}]},"document-css":{"t":"MetaBool","c":false},"fig-responsive":{"t":"MetaBool","c":true},"header-includes":{"t":"MetaList","c":[{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html",""]}]}]},"include-after":{"t":"MetaList","c":[{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html"," \n"]}]},{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html","\n"]}]},{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html"," \n"]}]}]},"include-before":{"t":"MetaList","c":[{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html","
\n
\n \n
\n\n
\n\n\n
\n
\n
\n\n
\n"]}]}]},"labels":{"t":"MetaMap","c":{"abstract":{"t":"MetaInlines","c":[{"t":"Str","c":"Abstract"}]},"affiliations":{"t":"MetaInlines","c":[{"t":"Str","c":"Affiliations"}]},"authors":{"t":"MetaInlines","c":[{"t":"Str","c":"Authors"}]},"description":{"t":"MetaInlines","c":[{"t":"Str","c":"Description"}]},"doi":{"t":"MetaInlines","c":[{"t":"Str","c":"Doi"}]},"modified":{"t":"MetaInlines","c":[{"t":"Str","c":"Modified"}]},"published":{"t":"MetaInlines","c":[{"t":"Str","c":"Published"}]}}},"lang":{"t":"MetaInlines","c":[{"t":"Str","c":"en"}]},"link-citations":{"t":"MetaBool","c":true},"quarto-template-params":{"t":"MetaMap","c":{"title-block-categories":{"t":"MetaInlines","c":[{"t":"Str","c":"true"}]}}},"quarto-version":{"t":"MetaInlines","c":[{"t":"Str","c":"1.3.119"}]},"theme":{"t":"MetaMap","c":{"light":{"t":"MetaInlines","c":[{"t":"Str","c":"yeti"}]}}},"title":{"t":"MetaInlines","c":[{"t":"Str","c":"Quickstart"}]},"toc-title":{"t":"MetaInlines","c":[{"t":"Str","c":"On"},{"t":"Space"},{"t":"Str","c":"this"},{"t":"Space"},{"t":"Str","c":"page"}]}},"blocks":[{"t":"Para","c":[{"t":"Str","c":"dascore"},{"t":"Space"},{"t":"Str","c":"can"},{"t":"Space"},{"t":"Link","c":[["",[],[]],[{"t":"Str","c":"link"}],["%60dascore.Patch%60",""]]}]},{"t":"Header","c":[2,["read-a-single-file",[],[]],[{"t":"Str","c":"Read"},{"t":"Space"},{"t":"Str","c":"a"},{"t":"Space"},{"t":"Str","c":"single"},{"t":"Space"},{"t":"Str","c":"file"}]]},{"t":"Div","c":[["",["cell"],[["execution_count","1"]]],[{"t":"CodeBlock","c":[["",["python","cell-code"],[]],"import dascore as dc\nfrom dascore.utils.downloader import fetch\n# get a path to an example file, replace with your path\nfile_path = fetch('terra15_das_1_trimmed.hdf5')\nspool = dc.spool(file_path)"]}]]},{"t":"Header","c":[2,["read-data-from-a-directory-of-fiber-optic-data-files",[],[]],[{"t":"Str","c":"Read"},{"t":"Space"},{"t":"Str","c":"data"},{"t":"Space"},{"t":"Str","c":"from"},{"t":"Space"},{"t":"Str","c":"a"},{"t":"Space"},{"t":"Str","c":"directory"},{"t":"Space"},{"t":"Str","c":"of"},{"t":"Space"},{"t":"Str","c":"fiber"},{"t":"Space"},{"t":"Str","c":"optic"},{"t":"Space"},{"t":"Str","c":"data"},{"t":"Space"},{"t":"Str","c":"files"}]]},{"t":"Div","c":[["",["cell"],[["execution_count","2"]]],[{"t":"CodeBlock","c":[["",["python","cell-code"],[]],"import dascore as dc\nfrom dascore.utils.downloader import fetch\n# get a path to a directory of das files, replace with your path\ndirectory_path = fetch('terra15_das_1_trimmed.hdf5').parent\nspool = dc.spool(directory_path).update()"]}]]},{"t":"Header","c":[2,["get-patches-2d-array",[],[]],[{"t":"Str","c":"Get"},{"t":"Space"},{"t":"Str","c":"patches"},{"t":"Space"},{"t":"Str","c":"(2D"},{"t":"Space"},{"t":"Str","c":"array)"}]]},{"t":"Div","c":[["",["cell"],[["execution_count","3"]]],[{"t":"CodeBlock","c":[["",["python","cell-code"],[]],"import dascore as dc\nspool = dc.get_example_spool('diverse_das')\n# get patches through iteration\nfor patch in spool:\n ...\n# Or through indexing\npatch = spool[0]"]}]]},{"t":"Header","c":[2,["perform-processing",[],[]],[{"t":"Str","c":"Perform"},{"t":"Space"},{"t":"Str","c":"processing"}]]},{"t":"Div","c":[["",["cell"],[["execution_count","4"]]],[{"t":"CodeBlock","c":[["",["python","cell-code"],[]],"import dascore as dc\npatch = dc.get_example_patch('random_das')\nout = (\n patch.decimate(time=8) # decimate along time axis\n .detrend(dim='distance') # detrend in distance axis\n .pass_filter(time=(None, 10)) # apply bandpass filter\n)"]}]]},{"t":"Header","c":[2,["visualize",[],[]],[{"t":"Str","c":"Visualize"}]]},{"t":"Div","c":[["",["cell"],[["execution_count","5"]]],[{"t":"CodeBlock","c":[["",["python","cell-code"],[]],"import dascore as dc\npatch = dc.get_example_patch('random_das')\npatch.viz.waterfall(show=True, scale=0.02);"]},{"t":"Div","c":[["",["cell-output","cell-output-display"],[]],[{"t":"Para","c":[{"t":"Image","c":[["",[],[["width","592"],["height","419"]]],[],["quickstart_files/figure-html/cell-6-output-1.png",""]]}]}]]}]]},{"t":"Div","c":[["quarto-navigation-envelope",["hidden"],[]],[{"t":"Para","c":[{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar-title"]]],[{"t":"Str","c":"DASCore"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar-title"]]],[{"t":"Str","c":"DASCore"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Introduction"]]],[{"t":"Str","c":"Introduction"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Tutorial"]]],[{"t":"Str","c":"Tutorial"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Recipes"]]],[{"t":"Str","c":"Recipes"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Contributing"]]],[{"t":"Str","c":"Contributing"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:API"]]],[{"t":"Str","c":"API"}]]}]}]]},{"t":"Div","c":[["quarto-meta-markdown",["hidden"],[]],[{"t":"Para","c":[{"t":"Span","c":[["",["hidden"],[["render-id","quarto-metatitle"]]],[{"t":"Str","c":"DASCore"},{"t":"Space"},{"t":"Str","c":"-"},{"t":"Space"},{"t":"Str","c":"Quickstart"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-twittercardtitle"]]],[{"t":"Str","c":"DASCore"},{"t":"Space"},{"t":"Str","c":"-"},{"t":"Space"},{"t":"Str","c":"Quickstart"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-ogcardtitle"]]],[{"t":"Str","c":"DASCore"},{"t":"Space"},{"t":"Str","c":"-"},{"t":"Space"},{"t":"Str","c":"Quickstart"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-metasitename"]]],[{"t":"Str","c":"DASCore"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-twittercarddesc"]]],[]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-ogcardddesc"]]],[]]}]}]]}]} diff --git a/docs/filters/filter_test_data/test_data_2.json b/docs/filters/filter_test_data/test_data_2.json deleted file mode 100644 index 5964df327..000000000 --- a/docs/filters/filter_test_data/test_data_2.json +++ /dev/null @@ -1 +0,0 @@ -{"pandoc-api-version":[1,22,2,1],"meta":{"biblio-config":{"t":"MetaBool","c":true},"bibliography":{"t":"MetaList","c":[{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../references.bib"}]}]},"code-copy":{"t":"MetaBool","c":true},"date-format":{"t":"MetaInlines","c":[{"t":"Str","c":"long"}]},"document-css":{"t":"MetaBool","c":false},"fig-responsive":{"t":"MetaBool","c":true},"header-includes":{"t":"MetaList","c":[{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html",""]}]}]},"include-after":{"t":"MetaList","c":[{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html","
\n"]}]},{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html","\n"]}]},{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html","\n
\n"]}]}]},"include-before":{"t":"MetaList","c":[{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html","
\n
\n \n \n
\n\n
\n\n \n\n
\n
\n
\n\n
\n"]}]}]},"labels":{"t":"MetaMap","c":{"abstract":{"t":"MetaInlines","c":[{"t":"Str","c":"Abstract"}]},"affiliations":{"t":"MetaInlines","c":[{"t":"Str","c":"Affiliations"}]},"authors":{"t":"MetaInlines","c":[{"t":"Str","c":"Authors"}]},"description":{"t":"MetaInlines","c":[{"t":"Str","c":"Description"}]},"doi":{"t":"MetaInlines","c":[{"t":"Str","c":"Doi"}]},"modified":{"t":"MetaInlines","c":[{"t":"Str","c":"Modified"}]},"published":{"t":"MetaInlines","c":[{"t":"Str","c":"Published"}]}}},"lang":{"t":"MetaInlines","c":[{"t":"Str","c":"en"}]},"link-citations":{"t":"MetaBool","c":true},"pagetitle":{"t":"MetaString","c":"get_contents"},"quarto-template-params":{"t":"MetaMap","c":{"title-block-categories":{"t":"MetaInlines","c":[{"t":"Str","c":"true"}]}}},"quarto-version":{"t":"MetaInlines","c":[{"t":"Str","c":"1.2.313"}]},"theme":{"t":"MetaMap","c":{"light":{"t":"MetaInlines","c":[{"t":"Str","c":"yeti"}]}}},"toc-title":{"t":"MetaInlines","c":[{"t":"Str","c":"On"},{"t":"Space"},{"t":"Str","c":"this"},{"t":"Space"},{"t":"Str","c":"page"}]},"website":{"t":"MetaMap","c":{"favicon":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../_static/logo.png"}]},"image":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../_static/logo.png"}]},"navbar":{"t":"MetaMap","c":{"background":{"t":"MetaInlines","c":[{"t":"Str","c":"light"}]},"left":{"t":"MetaList","c":[{"t":"MetaMap","c":{"file":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../index.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Introduction"}]}}},{"t":"MetaMap","c":{"file":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../tutorial/concepts.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Tutorial"}]}}},{"t":"MetaMap","c":{"file":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../recipes/overview.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Recipes"}]}}},{"t":"MetaMap","c":{"file":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../contributing/contributing.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Contributing"}]}}},{"t":"MetaMap","c":{"file":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../api/dascore.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"API"}]}}}]},"logo":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../_static/logo.png"}]},"logo-alt":{"t":"MetaInlines","c":[{"t":"Str","c":"DASCore"},{"t":"Space"},{"t":"Str","c":"logo."}]},"right":{"t":"MetaList","c":[{"t":"MetaMap","c":{"aria-label":{"t":"MetaInlines","c":[{"t":"Str","c":"DASDAE"},{"t":"Space"},{"t":"Str","c":"Twitter"}]},"href":{"t":"MetaInlines","c":[{"t":"Str","c":"https://twitter.com/dasdae_org"}]},"icon":{"t":"MetaInlines","c":[{"t":"Str","c":"twitter"}]}}},{"t":"MetaMap","c":{"aria-label":{"t":"MetaInlines","c":[{"t":"Str","c":"DASCore"},{"t":"Space"},{"t":"Str","c":"GitHub"}]},"href":{"t":"MetaInlines","c":[{"t":"Str","c":"https://github.com/dasdae/dascore"}]},"icon":{"t":"MetaInlines","c":[{"t":"Str","c":"github"}]}}}]},"search":{"t":"MetaBool","c":true}}},"page-navigation":{"t":"MetaBool","c":true},"repo-actions":{"t":"MetaList","c":[{"t":"MetaInlines","c":[{"t":"Str","c":"edit"}]}]},"repo-branch":{"t":"MetaInlines","c":[{"t":"Str","c":"master"}]},"repo-subdir":{"t":"MetaInlines","c":[{"t":"Str","c":"docs"}]},"repo-url":{"t":"MetaInlines","c":[{"t":"Str","c":"https://github.com/dasdae/dascore"}]},"sidebar":{"t":"MetaList","c":[{"t":"MetaMap","c":{"collapse-level":{"t":"MetaInlines","c":[{"t":"Str","c":"2"}]},"contents":{"t":"MetaList","c":[{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../index.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Introduction"}]}}},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../changelog.md"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Changelog"}]}}},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../contributors.md"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Contributors"}]}}},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../acknowledgements.md"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Acknowledgements"}]}}}]},"logo":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../_static/logo.png"}]},"search":{"t":"MetaBool","c":true},"style":{"t":"MetaInlines","c":[{"t":"Str","c":"floating"}]},"title":{"t":"MetaInlines","c":[{"t":"Str","c":"About"}]},"tools":{"t":"MetaList","c":[]}}},{"t":"MetaMap","c":{"collapse-level":{"t":"MetaInlines","c":[{"t":"Str","c":"2"}]},"contents":{"t":"MetaList","c":[{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../tutorial/concepts.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"DASCore"},{"t":"Space"},{"t":"Str","c":"Concepts"}]}}},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../tutorial/patch.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Patch"}]}}},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../tutorial/spool.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Spool"}]}}},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../tutorial/processing.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Processing"}]}}},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../tutorial/visualization.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Visualization"}]}}},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../tutorial/file_io.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"File"},{"t":"Space"},{"t":"Str","c":"IO"}]}}}]},"logo":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../_static/logo.png"}]},"search":{"t":"MetaBool","c":true},"style":{"t":"MetaInlines","c":[{"t":"Str","c":"floating"}]},"title":{"t":"MetaInlines","c":[{"t":"Str","c":"Tutorial"}]},"tools":{"t":"MetaList","c":[]}}},{"t":"MetaMap","c":{"collapse-level":{"t":"MetaInlines","c":[{"t":"Str","c":"2"}]},"contents":{"t":"MetaList","c":[{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../recipes/overview.qmd"}]},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../recipes/how_to_contribute.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"How"},{"t":"Space"},{"t":"Str","c":"to"},{"t":"Space"},{"t":"Str","c":"Contribute?"}]}}},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../recipes/contributing_to_documentation.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Contributing"},{"t":"Space"},{"t":"Str","c":"to"},{"t":"Space"},{"t":"Str","c":"Documentation"}]}}}]},"logo":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../_static/logo.png"}]},"search":{"t":"MetaBool","c":true},"style":{"t":"MetaInlines","c":[{"t":"Str","c":"floating"}]},"title":{"t":"MetaInlines","c":[{"t":"Str","c":"Recipes"}]},"tools":{"t":"MetaList","c":[]}}},{"t":"MetaMap","c":{"collapse-level":{"t":"MetaInlines","c":[{"t":"Str","c":"2"}]},"contents":{"t":"MetaList","c":[{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../contributing/contributing.qmd"}]},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../contributing/dev_install.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Dev"},{"t":"Space"},{"t":"Str","c":"Install"}]}}},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../contributing/style_and_linting.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Style"}]}}},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../contributing/testing.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Testing"}]}}},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../contributing/adding_test_data.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Adding"},{"t":"Space"},{"t":"Str","c":"Test"},{"t":"Space"},{"t":"Str","c":"Data"}]}}},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../contributing/documentation.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Documentation"}]}}},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../contributing/general_guidelines.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"General"},{"t":"Space"},{"t":"Str","c":"Guidelines"}]}}},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../contributing/new_format.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Adding"},{"t":"Space"},{"t":"Str","c":"a"},{"t":"Space"},{"t":"Str","c":"new"},{"t":"Space"},{"t":"Str","c":"format"}]}}},{"t":"MetaMap","c":{"href":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../contributing/code_of_conduct.qmd"}]},"text":{"t":"MetaInlines","c":[{"t":"Str","c":"Code"},{"t":"Space"},{"t":"Str","c":"of"},{"t":"Space"},{"t":"Str","c":"Conduct"}]}}}]},"logo":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../_static/logo.png"}]},"search":{"t":"MetaBool","c":true},"style":{"t":"MetaInlines","c":[{"t":"Str","c":"floating"}]},"title":{"t":"MetaInlines","c":[{"t":"Str","c":"Contributing"}]},"tools":{"t":"MetaList","c":[]}}},{"t":"MetaMap","c":{"collapse-level":{"t":"MetaInlines","c":[{"t":"Str","c":"2"}]},"contents":{"t":"MetaList","c":[{"t":"MetaMap","c":{"auto":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../api"}]}}}]},"logo":{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../../_static/logo.png"}]},"search":{"t":"MetaBool","c":true},"style":{"t":"MetaInlines","c":[{"t":"Str","c":"floating"}]},"title":{"t":"MetaInlines","c":[{"t":"Str","c":"API"}]},"tools":{"t":"MetaList","c":[]}}}]},"site-path":{"t":"MetaInlines","c":[{"t":"Str","c":"/docs"}]},"title":{"t":"MetaInlines","c":[{"t":"Str","c":"DASCore"}]},"twitter-card":{"t":"MetaBool","c":true}}}},"blocks":[{"t":"Header","c":[1,["get_contents",[],[]],[{"t":"Str","c":"get_contents"}]]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html","
"]},{"t":"Plain","c":[{"t":"Emph","c":[{"t":"Str","c":"method"}]},{"t":"Space"},{"t":"Str","c":"of"},{"t":"Space"},{"t":"Link","c":[["",[],[]],[{"t":"Str","c":"dascore.core.spool.BaseSpool"}],["%60dascore.core.spool.BaseSpool%60",""]]}]},{"t":"RawBlock","c":["html",""]},{"t":"Plain","c":[{"t":"Link","c":[["",[],[]],[{"t":"Str","c":"source"}],["https://github.com/DASDAE/dascore/blob/master/dascore/core/spool.py#L85-L89",""]]}]},{"t":"RawBlock","c":["html","
"]},{"t":"Div","c":[["",["padded_bottom_10pt"],[]],[{"t":"Div","c":[["",["def_block"],[]],[{"t":"Para","c":[{"t":"RawInline","c":["html",""]},{"t":"Str","c":"get_contents"},{"t":"RawInline","c":["html",""]},{"t":"Str","c":"("},{"t":"RawInline","c":["html","
"]},{"t":"SoftBreak"},{"t":"Str","c":"    self:"},{"t":"Space"},{"t":"Link","c":[["",[],[]],[{"t":"Str","c":"Spool"}],["%60dascore.Spool%60",""]]},{"t":"SoftBreak"},{"t":"Str","c":","},{"t":"RawInline","c":["html","
"]},{"t":"SoftBreak"},{"t":"Str","c":")->"},{"t":"Space"},{"t":"Str","c":"DataFrame"}]}]]}]]},{"t":"Para","c":[{"t":"Str","c":"Get"},{"t":"Space"},{"t":"Str","c":"a"},{"t":"Space"},{"t":"Str","c":"dataframe"},{"t":"Space"},{"t":"Str","c":"of"},{"t":"Space"},{"t":"Str","c":"the"},{"t":"Space"},{"t":"Str","c":"patches"},{"t":"Space"},{"t":"Str","c":"that"},{"t":"Space"},{"t":"Str","c":"will"},{"t":"Space"},{"t":"Str","c":"be"},{"t":"Space"},{"t":"Str","c":"returned"},{"t":"Space"},{"t":"Str","c":"by"},{"t":"Space"},{"t":"Str","c":"the"},{"t":"Space"},{"t":"Str","c":"spool."}]},{"t":"Div","c":[["quarto-navigation-envelope",["hidden"],[]],[{"t":"Para","c":[{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar-title"]]],[{"t":"Str","c":"API"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar-title"]]],[{"t":"Str","c":"DASCore"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-next"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-prev"]]],[{"t":"Str","c":"chunk"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-1"]]],[{"t":"Str","c":"Api"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore.html"]]],[{"t":"Str","c":"dascore"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-2"]]],[{"t":"Str","c":"Dascore"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients.html"]]],[{"t":"Str","c":"clients"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/compat.html"]]],[{"t":"Str","c":"compat"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/constants.html"]]],[{"t":"Str","c":"constants"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core.html"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples.html"]]],[{"t":"Str","c":"examples"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions.html"]]],[{"t":"Str","c":"exceptions"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io.html"]]],[{"t":"Str","c":"io"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc.html"]]],[{"t":"Str","c":"proc"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform.html"]]],[{"t":"Str","c":"transform"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/version.html"]]],[{"t":"Str","c":"version"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/viz.html"]]],[{"t":"Str","c":"viz"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-3"]]],[{"t":"Str","c":"Clients"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/dirspool.html"]]],[{"t":"Str","c":"dirspool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/filespool.html"]]],[{"t":"Str","c":"filespool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-4"]]],[{"t":"Str","c":"Dirspool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/dirspool/AbstractIndexer.html"]]],[{"t":"Str","c":"AbstractIndexer"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/dirspool/DirectoryIndexer.html"]]],[{"t":"Str","c":"DirectoryIndexer"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/dirspool/DirectorySpool.html"]]],[{"t":"Str","c":"DirectorySpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-5"]]],[{"t":"Str","c":"AbstractIndexer"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/dirspool/AbstractIndexer/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-6"]]],[{"t":"Str","c":"DirectoryIndexer"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/dirspool/DirectoryIndexer/clear_cache.html"]]],[{"t":"Str","c":"clear_cache"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/dirspool/DirectoryIndexer/ensure_path_exists.html"]]],[{"t":"Str","c":"ensure_path_exists"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/dirspool/DirectoryIndexer/get_contents.html"]]],[{"t":"Str","c":"get_contents"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/dirspool/DirectoryIndexer/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-7"]]],[{"t":"Str","c":"DirectorySpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/dirspool/DirectorySpool/get_contents.html"]]],[{"t":"Str","c":"get_contents"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/dirspool/DirectorySpool/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/dirspool/DirectorySpool/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-8"]]],[{"t":"Str","c":"Filespool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/filespool/DataFrameSpool.html"]]],[{"t":"Str","c":"DataFrameSpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/filespool/FiberIO.html"]]],[{"t":"Str","c":"FiberIO"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/filespool/FileSpool.html"]]],[{"t":"Str","c":"FileSpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-9"]]],[{"t":"Str","c":"DataFrameSpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/filespool/DataFrameSpool/chunk.html"]]],[{"t":"Str","c":"chunk"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/filespool/DataFrameSpool/get_contents.html"]]],[{"t":"Str","c":"get_contents"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/filespool/DataFrameSpool/new_from_df.html"]]],[{"t":"Str","c":"new_from_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/filespool/DataFrameSpool/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/filespool/DataFrameSpool/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-10"]]],[{"t":"Str","c":"FiberIO"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/filespool/FiberIO/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/filespool/FiberIO/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/filespool/FiberIO/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/filespool/FiberIO/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-11"]]],[{"t":"Str","c":"FileSpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/filespool/FileSpool/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-12"]]],[{"t":"Str","c":"Core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/patch.html"]]],[{"t":"Str","c":"patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/schema.html"]]],[{"t":"Str","c":"schema"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool.html"]]],[{"t":"Str","c":"spool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-13"]]],[{"t":"Str","c":"Patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/patch/Patch.html"]]],[{"t":"Str","c":"Patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/patch/PatchIO.html"]]],[{"t":"Str","c":"PatchIO"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/patch/TransformPatchNameSpace.html"]]],[{"t":"Str","c":"TransformPatchNameSpace"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/patch/VizPatchNameSpace.html"]]],[{"t":"Str","c":"VizPatchNameSpace"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-14"]]],[{"t":"Str","c":"Patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/patch/Patch/equals.html"]]],[{"t":"Str","c":"equals"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/patch/Patch/new.html"]]],[{"t":"Str","c":"new"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/patch/Patch/pipe.html"]]],[{"t":"Str","c":"pipe"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/patch/Patch/to_xarray.html"]]],[{"t":"Str","c":"to_xarray"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/patch/Patch/update_attrs.html"]]],[{"t":"Str","c":"update_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-15"]]],[{"t":"Str","c":"Schema"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/schema/DateTime64.html"]]],[{"t":"Str","c":"DateTime64"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/schema/SimpleValidator.html"]]],[{"t":"Str","c":"SimpleValidator"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/schema/TimeDelta64.html"]]],[{"t":"Str","c":"TimeDelta64"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-16"]]],[{"t":"Str","c":"DateTime64"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/schema/DateTime64/validate.html"]]],[{"t":"Str","c":"validate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-17"]]],[{"t":"Str","c":"SimpleValidator"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/schema/SimpleValidator/func.html"]]],[{"t":"Str","c":"func"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/schema/SimpleValidator/validate.html"]]],[{"t":"Str","c":"validate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-18"]]],[{"t":"Str","c":"TimeDelta64"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/schema/TimeDelta64/validate.html"]]],[{"t":"Str","c":"validate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-19"]]],[{"t":"Str","c":"Spool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool.html"]]],[{"t":"Str","c":"BaseSpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/MemorySpool.html"]]],[{"t":"Str","c":"MemorySpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/spool.html"]]],[{"t":"Str","c":"spool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/spool_from_patch.html"]]],[{"t":"Str","c":"spool_from_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/spool_from_patch_list.html"]]],[{"t":"Str","c":"spool_from_patch_list"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/spool_from_spool.html"]]],[{"t":"Str","c":"spool_from_spool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/spool_from_str.html"]]],[{"t":"Str","c":"spool_from_str"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-20"]]],[{"t":"Str","c":"BaseSpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/chunk.html"]]],[{"t":"Str","c":"chunk"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/get_contents.html"]]],[{"t":"Str","c":"get_contents"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-21"]]],[{"t":"Str","c":"Examples"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/get_example_patch.html"]]],[{"t":"Str","c":"get_example_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/get_example_spool.html"]]],[{"t":"Str","c":"get_example_spool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/sin_wave_patch.html"]]],[{"t":"Str","c":"sin_wave_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/spool_to_directory.html"]]],[{"t":"Str","c":"spool_to_directory"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-22"]]],[{"t":"Str","c":"Exceptions"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/DASCoreError.html"]]],[{"t":"Str","c":"DASCoreError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/FilterValueError.html"]]],[{"t":"Str","c":"FilterValueError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/InvalidFiberFile.html"]]],[{"t":"Str","c":"InvalidFiberFile"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/InvalidFileFormatter.html"]]],[{"t":"Str","c":"InvalidFileFormatter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/InvalidTimeRange.html"]]],[{"t":"Str","c":"InvalidTimeRange"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/PatchCoordError.html"]]],[{"t":"Str","c":"PatchCoordError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/PatchError.html"]]],[{"t":"Str","c":"PatchError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/UnknownFiberFormat.html"]]],[{"t":"Str","c":"UnknownFiberFormat"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/UnsupportedKeyword.html"]]],[{"t":"Str","c":"UnsupportedKeyword"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-23"]]],[{"t":"Str","c":"Io"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core.html"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae.html"]]],[{"t":"Str","c":"dasdae"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/indexer.html"]]],[{"t":"Str","c":"indexer"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/pickle.html"]]],[{"t":"Str","c":"pickle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/plugin.html"]]],[{"t":"Str","c":"plugin"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms.html"]]],[{"t":"Str","c":"tdms"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15.html"]]],[{"t":"Str","c":"terra15"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/wav.html"]]],[{"t":"Str","c":"wav"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-24"]]],[{"t":"Str","c":"Core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/scan_to_df.html"]]],[{"t":"Str","c":"scan_to_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-25"]]],[{"t":"Str","c":"Dasdae"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/core.html"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-26"]]],[{"t":"Str","c":"Core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/core/DASDAEV1.html"]]],[{"t":"Str","c":"DASDAEV1"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-27"]]],[{"t":"Str","c":"index"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/core/DASDAEV1/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/core/DASDAEV1/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/core/DASDAEV1/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/core/DASDAEV1/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-28"]]],[{"t":"Str","c":"Pickle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/pickle/core.html"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-29"]]],[{"t":"Str","c":"Core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/pickle/core/PickleIO.html"]]],[{"t":"Str","c":"PickleIO"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-30"]]],[{"t":"Str","c":"PickleIO"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/pickle/core/PickleIO/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/pickle/core/PickleIO/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/pickle/core/PickleIO/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-31"]]],[{"t":"Str","c":"Tdms"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/core.html"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-32"]]],[{"t":"Str","c":"Core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/core/TDMSFormatterV4713.html"]]],[{"t":"Str","c":"TDMSFormatterV4713"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-33"]]],[{"t":"Str","c":"TDMSFormatterV4713"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/core/TDMSFormatterV4713/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/core/TDMSFormatterV4713/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/core/TDMSFormatterV4713/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-34"]]],[{"t":"Str","c":"Utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/utils/parse_time_stamp.html"]]],[{"t":"Str","c":"parse_time_stamp"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/utils/type_not_supported.html"]]],[{"t":"Str","c":"type_not_supported"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-35"]]],[{"t":"Str","c":"Terra15"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/core.html"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-36"]]],[{"t":"Str","c":"Core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/core/Terra15FormatterV4.html"]]],[{"t":"Str","c":"Terra15FormatterV4"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/core/Terra15FormatterV5.html"]]],[{"t":"Str","c":"Terra15FormatterV5"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-37"]]],[{"t":"Str","c":"Terra15FormatterV4"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/core/Terra15FormatterV4/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/core/Terra15FormatterV4/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/core/Terra15FormatterV4/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-38"]]],[{"t":"Str","c":"Wav"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/wav/core.html"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-39"]]],[{"t":"Str","c":"Core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/wav/core/WavIO.html"]]],[{"t":"Str","c":"WavIO"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-40"]]],[{"t":"Str","c":"WavIO"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/wav/core/WavIO/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-41"]]],[{"t":"Str","c":"Proc"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/aggregate.html"]]],[{"t":"Str","c":"aggregate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic.html"]]],[{"t":"Str","c":"basic"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/detrend.html"]]],[{"t":"Str","c":"detrend"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/filter.html"]]],[{"t":"Str","c":"filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/resample.html"]]],[{"t":"Str","c":"resample"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-42"]]],[{"t":"Str","c":"Aggregate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/aggregate/aggregate.html"]]],[{"t":"Str","c":"aggregate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-43"]]],[{"t":"Str","c":"Basic"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/abs.html"]]],[{"t":"Str","c":"abs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/normalize.html"]]],[{"t":"Str","c":"normalize"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/rename.html"]]],[{"t":"Str","c":"rename"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/squeeze.html"]]],[{"t":"Str","c":"squeeze"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/standardize.html"]]],[{"t":"Str","c":"standardize"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/transpose.html"]]],[{"t":"Str","c":"transpose"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-44"]]],[{"t":"Str","c":"Detrend"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/detrend/detrend.html"]]],[{"t":"Str","c":"detrend"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-45"]]],[{"t":"Str","c":"Filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/filter/median_filter.html"]]],[{"t":"Str","c":"median_filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/filter/pass_filter.html"]]],[{"t":"Str","c":"pass_filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/filter/sobel_filter.html"]]],[{"t":"Str","c":"sobel_filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-46"]]],[{"t":"Str","c":"Resample"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/resample/decimate.html"]]],[{"t":"Str","c":"decimate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/resample/interpolate.html"]]],[{"t":"Str","c":"interpolate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/resample/iresample.html"]]],[{"t":"Str","c":"iresample"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/resample/resample.html"]]],[{"t":"Str","c":"resample"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-47"]]],[{"t":"Str","c":"Select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/select/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-48"]]],[{"t":"Str","c":"Transform"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/fft.html"]]],[{"t":"Str","c":"fft"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/spectro.html"]]],[{"t":"Str","c":"spectro"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/strain.html"]]],[{"t":"Str","c":"strain"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-49"]]],[{"t":"Str","c":"Fft"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/fft/rfft.html"]]],[{"t":"Str","c":"rfft"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-50"]]],[{"t":"Str","c":"Spectro"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/spectro/spectrogram.html"]]],[{"t":"Str","c":"spectrogram"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-51"]]],[{"t":"Str","c":"Strain"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/strain/velocity_to_strain_rate.html"]]],[{"t":"Str","c":"velocity_to_strain_rate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-52"]]],[{"t":"Str","c":"Utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/chunk.html"]]],[{"t":"Str","c":"chunk"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/coords.html"]]],[{"t":"Str","c":"coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/docs.html"]]],[{"t":"Str","c":"docs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/downloader.html"]]],[{"t":"Str","c":"downloader"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5.html"]]],[{"t":"Str","c":"hdf5"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/mapping.html"]]],[{"t":"Str","c":"mapping"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc.html"]]],[{"t":"Str","c":"misc"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch.html"]]],[{"t":"Str","c":"patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd.html"]]],[{"t":"Str","c":"pd"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/plotting.html"]]],[{"t":"Str","c":"plotting"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/progress.html"]]],[{"t":"Str","c":"progress"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time.html"]]],[{"t":"Str","c":"time"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-53"]]],[{"t":"Str","c":"Chunk"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/chunk/ChunkManager.html"]]],[{"t":"Str","c":"ChunkManager"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/chunk/get_intervals.html"]]],[{"t":"Str","c":"get_intervals"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-54"]]],[{"t":"Str","c":"ChunkManager"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/chunk/ChunkManager/chunk.html"]]],[{"t":"Str","c":"chunk"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/chunk/ChunkManager/get_instruction_df.html"]]],[{"t":"Str","c":"get_instruction_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-55"]]],[{"t":"Str","c":"Coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/coords/assign_coords.html"]]],[{"t":"Str","c":"assign_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-56"]]],[{"t":"Str","c":"Downloader"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/downloader/fetch.html"]]],[{"t":"Str","c":"fetch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-57"]]],[{"t":"Str","c":"Hdf5"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/fill_defaults_from_pydantic.html"]]],[{"t":"Str","c":"fill_defaults_from_pydantic"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/get_max_min_times.html"]]],[{"t":"Str","c":"get_max_min_times"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDFPatchIndexManager.html"]]],[{"t":"Str","c":"HDFPatchIndexManager"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/InvalidFileHandler.html"]]],[{"t":"Str","c":"InvalidFileHandler"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/InvalidIndexVersionError.html"]]],[{"t":"Str","c":"InvalidIndexVersionError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/list_ser_to_str.html"]]],[{"t":"Str","c":"list_ser_to_str"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/open_hdf5_file.html"]]],[{"t":"Str","c":"open_hdf5_file"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/suppress_warnings.html"]]],[{"t":"Str","c":"suppress_warnings"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/to_number.html"]]],[{"t":"Str","c":"to_number"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-58"]]],[{"t":"Str","c":"HDFPatchIndexManager"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDFPatchIndexManager/decode_table.html"]]],[{"t":"Str","c":"decode_table"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDFPatchIndexManager/encode_table.html"]]],[{"t":"Str","c":"encode_table"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDFPatchIndexManager/get_index.html"]]],[{"t":"Str","c":"get_index"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDFPatchIndexManager/validate_version.html"]]],[{"t":"Str","c":"validate_version"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDFPatchIndexManager/write_update.html"]]],[{"t":"Str","c":"write_update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-59"]]],[{"t":"Str","c":"Mapping"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/mapping/FrozenDict.html"]]],[{"t":"Str","c":"FrozenDict"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-60"]]],[{"t":"Str","c":"FrozenDict"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/mapping/FrozenDict/copy.html"]]],[{"t":"Str","c":"copy"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-61"]]],[{"t":"Str","c":"Misc"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/all_close.html"]]],[{"t":"Str","c":"all_close"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/CacheDescriptor.html"]]],[{"t":"Str","c":"CacheDescriptor"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/check_evenly_sampled.html"]]],[{"t":"Str","c":"check_evenly_sampled"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/get_slice.html"]]],[{"t":"Str","c":"get_slice"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/iter_files.html"]]],[{"t":"Str","c":"iter_files"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/iterate.html"]]],[{"t":"Str","c":"iterate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/MethodNameSpace.html"]]],[{"t":"Str","c":"MethodNameSpace"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/MissingOptionalDependency.html"]]],[{"t":"Str","c":"MissingOptionalDependency"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/optional_import.html"]]],[{"t":"Str","c":"optional_import"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/ParameterError.html"]]],[{"t":"Str","c":"ParameterError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/register_func.html"]]],[{"t":"Str","c":"register_func"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-62"]]],[{"t":"Str","c":"Patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/append_func.html"]]],[{"t":"Str","c":"append_func"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/check_patch_attrs.html"]]],[{"t":"Str","c":"check_patch_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/check_patch_dims.html"]]],[{"t":"Str","c":"check_patch_dims"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/compose_docstring.html"]]],[{"t":"Str","c":"compose_docstring"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/Coords.html"]]],[{"t":"Str","c":"Coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/copy_attrs.html"]]],[{"t":"Str","c":"copy_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/format_dtypes.html"]]],[{"t":"Str","c":"format_dtypes"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/get_default_patch_name.html"]]],[{"t":"Str","c":"get_default_patch_name"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/get_dim_value_from_kwargs.html"]]],[{"t":"Str","c":"get_dim_value_from_kwargs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/get_start_stop_step.html"]]],[{"t":"Str","c":"get_start_stop_step"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/merge_patches.html"]]],[{"t":"Str","c":"merge_patches"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/patch_function.html"]]],[{"t":"Str","c":"patch_function"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/PatchAttributeError.html"]]],[{"t":"Str","c":"PatchAttributeError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/PatchAttrs.html"]]],[{"t":"Str","c":"PatchAttrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/PatchDimError.html"]]],[{"t":"Str","c":"PatchDimError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/patches_to_df.html"]]],[{"t":"Str","c":"patches_to_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/PatchFileSummary.html"]]],[{"t":"Str","c":"PatchFileSummary"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/scan_patches.html"]]],[{"t":"Str","c":"scan_patches"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/to_datetime64.html"]]],[{"t":"Str","c":"to_datetime64"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/to_timedelta64.html"]]],[{"t":"Str","c":"to_timedelta64"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-63"]]],[{"t":"Str","c":"Coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/Coords/get.html"]]],[{"t":"Str","c":"get"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/Coords/to_nested_dict.html"]]],[{"t":"Str","c":"to_nested_dict"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/Coords/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-64"]]],[{"t":"Str","c":"PatchAttrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/PatchAttrs/Config.html"]]],[{"t":"Str","c":"Config"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/PatchAttrs/get.html"]]],[{"t":"Str","c":"get"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/PatchAttrs/get_defaults.html"]]],[{"t":"Str","c":"get_defaults"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/PatchAttrs/items.html"]]],[{"t":"Str","c":"items"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-65"]]],[{"t":"Str","c":"PatchFileSummary"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/PatchFileSummary/get_defaults.html"]]],[{"t":"Str","c":"get_defaults"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/PatchFileSummary/get_index_columns.html"]]],[{"t":"Str","c":"get_index_columns"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-66"]]],[{"t":"Str","c":"Pd"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/adjust_segments.html"]]],[{"t":"Str","c":"adjust_segments"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/filter_df.html"]]],[{"t":"Str","c":"filter_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/get_column_names_from_dim.html"]]],[{"t":"Str","c":"get_column_names_from_dim"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/get_dim_names_from_columns.html"]]],[{"t":"Str","c":"get_dim_names_from_columns"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/get_interval_columns.html"]]],[{"t":"Str","c":"get_interval_columns"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/get_regex.html"]]],[{"t":"Str","c":"get_regex"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/yield_slice_from_kwargs.html"]]],[{"t":"Str","c":"yield_slice_from_kwargs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-67"]]],[{"t":"Str","c":"Progress"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/progress/track.html"]]],[{"t":"Str","c":"track"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-68"]]],[{"t":"Str","c":"Time"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/datetime_to_float.html"]]],[{"t":"Str","c":"datetime_to_float"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/get_select_time.html"]]],[{"t":"Str","c":"get_select_time"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/is_datetime64.html"]]],[{"t":"Str","c":"is_datetime64"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/TimeError.html"]]],[{"t":"Str","c":"TimeError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-69"]]],[{"t":"Str","c":"Viz"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/viz/core.html"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/viz/spectrogram.html"]]],[{"t":"Str","c":"spectrogram"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/viz/waterfall.html"]]],[{"t":"Str","c":"waterfall"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-70"]]],[{"t":"Str","c":"Spectrogram"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/viz/spectrogram/spectrogram.html"]]],[{"t":"Str","c":"spectrogram"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-71"]]],[{"t":"Str","c":"Waterfall"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/viz/waterfall/waterfall.html"]]],[{"t":"Str","c":"waterfall"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Introduction"]]],[{"t":"Str","c":"Introduction"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Tutorial"]]],[{"t":"Str","c":"Tutorial"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Recipes"]]],[{"t":"Str","c":"Recipes"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Contributing"]]],[{"t":"Str","c":"Contributing"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:API"]]],[{"t":"Str","c":"API"}]]}]}]]},{"t":"Div","c":[["quarto-meta-markdown",["hidden"],[]],[{"t":"Para","c":[{"t":"Span","c":[["",["hidden"],[["render-id","quarto-twittercardtitle"]]],[]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-ogcardtitle"]]],[]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-metasitename"]]],[{"t":"Str","c":"DASCore"}]]}]}]]}]} diff --git a/docs/filters/filter_test_data/test_data_3.json b/docs/filters/filter_test_data/test_data_3.json deleted file mode 100644 index ebdfa51ae..000000000 --- a/docs/filters/filter_test_data/test_data_3.json +++ /dev/null @@ -1 +0,0 @@ -{"pandoc-api-version":[1,23],"meta":{"biblio-config":{"t":"MetaBool","c":true},"bibliography":{"t":"MetaList","c":[{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../references.bib"}]}]},"code-copy":{"t":"MetaBool","c":true},"date-format":{"t":"MetaInlines","c":[{"t":"Str","c":"long"}]},"document-css":{"t":"MetaBool","c":false},"fig-responsive":{"t":"MetaBool","c":true},"header-includes":{"t":"MetaList","c":[{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html",""]}]}]},"include-after":{"t":"MetaList","c":[{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html","
\n"]}]},{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html","\n"]}]},{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html","\n
\n"]}]}]},"include-before":{"t":"MetaList","c":[{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html","
\n
\n \n \n
\n\n
\n\n \n
\n\n
\n
\n
\n\n
\n"]}]}]},"labels":{"t":"MetaMap","c":{"abstract":{"t":"MetaInlines","c":[{"t":"Str","c":"Abstract"}]},"affiliations":{"t":"MetaInlines","c":[{"t":"Str","c":"Affiliations"}]},"authors":{"t":"MetaInlines","c":[{"t":"Str","c":"Authors"}]},"description":{"t":"MetaInlines","c":[{"t":"Str","c":"Description"}]},"doi":{"t":"MetaInlines","c":[{"t":"Str","c":"Doi"}]},"modified":{"t":"MetaInlines","c":[{"t":"Str","c":"Modified"}]},"published":{"t":"MetaInlines","c":[{"t":"Str","c":"Published"}]}}},"lang":{"t":"MetaInlines","c":[{"t":"Str","c":"en"}]},"link-citations":{"t":"MetaBool","c":true},"pagetitle":{"t":"MetaString","c":"integrate"},"quarto-custom-nodes":{"t":"MetaList","c":[{"t":"MetaMap","c":{"id":{"t":"MetaString","c":"Callout 1 Block"},"kind":{"t":"MetaString","c":"Block"},"t":{"t":"MetaString","c":"Callout"},"tbl":{"t":"MetaMap","c":{"attr":{"t":"MetaMap","c":{"attributes":{"t":"MetaMap","c":{}},"classes":{"t":"MetaList","c":[]},"identifier":{"t":"MetaString","c":""}}},"content":{"t":"MetaBlocks","c":[{"t":"Para","c":[{"t":"Str","c":"The"},{"t":"Space"},{"t":"Str","c":"number"},{"t":"Space"},{"t":"Str","c":"of"},{"t":"Space"},{"t":"Str","c":"dimensions"},{"t":"Space"},{"t":"Str","c":"will"},{"t":"Space"},{"t":"Str","c":"always"},{"t":"Space"},{"t":"Str","c":"remain"},{"t":"Space"},{"t":"Str","c":"the"},{"t":"Space"},{"t":"Str","c":"same"},{"t":"Space"},{"t":"Str","c":"regardless"},{"t":"Space"},{"t":"Str","c":"of"},{"t":"Space"},{"t":"Code","c":[["",[],[]],"definite"]},{"t":"SoftBreak"},{"t":"Str","c":"value."},{"t":"Space"},{"t":"Str","c":"To"},{"t":"Space"},{"t":"Str","c":"remove"},{"t":"Space"},{"t":"Str","c":"dimensions"},{"t":"Space"},{"t":"Str","c":"with"},{"t":"Space"},{"t":"Str","c":"length"},{"t":"Space"},{"t":"Str","c":"1,"},{"t":"SoftBreak"},{"t":"Str","c":"see"},{"t":"Space"},{"t":"Link","c":[["",[],[]],[{"t":"Str","c":"squeeze"}],["%60dascore.proc.basic.squeeze%60",""]]},{"t":"Str","c":"."}]}]}}}}}]},"quarto-template-params":{"t":"MetaMap","c":{"title-block-categories":{"t":"MetaInlines","c":[{"t":"Str","c":"true"}]}}},"quarto-version":{"t":"MetaInlines","c":[{"t":"Str","c":"1.3.450"}]},"theme":{"t":"MetaMap","c":{"dark":{"t":"MetaInlines","c":[{"t":"Str","c":"darkly"}]},"light":{"t":"MetaInlines","c":[{"t":"Str","c":"yeti"}]}}},"title":{"t":"MetaInlines","c":[{"t":"Str","c":"integrate"}]},"toc-title":{"t":"MetaInlines","c":[{"t":"Str","c":"On"},{"t":"Space"},{"t":"Str","c":"this"},{"t":"Space"},{"t":"Str","c":"page"}]}},"blocks":[{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html","
"]},{"t":"Plain","c":[{"t":"Emph","c":[{"t":"Str","c":"function"}]},{"t":"Space"},{"t":"Str","c":"of"},{"t":"Space"},{"t":"Link","c":[["",[],[]],[{"t":"Str","c":"dascore.transform.integrate"}],["%60dascore.transform.integrate%60",""]]}]},{"t":"RawBlock","c":["html",""]},{"t":"Plain","c":[{"t":"Link","c":[["",[],[]],[{"t":"Str","c":"source"}],["https://github.com/DASDAE/dascore/blob/master/dascore/transform/integrate.py#L79-L128",""]]}]},{"t":"RawBlock","c":["html","
"]},{"t":"Div","c":[["",["padded_bottom_10pt"],[]],[{"t":"Div","c":[["",["def_block"],[]],[{"t":"Para","c":[{"t":"RawInline","c":["html",""]},{"t":"Str","c":"integrate"},{"t":"RawInline","c":["html",""]},{"t":"Str","c":"("},{"t":"RawInline","c":["html","
"]},{"t":"SoftBreak"},{"t":"Str","c":"    patch:"},{"t":"Space"},{"t":"Link","c":[["",[],[]],[{"t":"Str","c":"Patch"}],["%60dascore.Patch%60",""]]},{"t":"SoftBreak"},{"t":"Str","c":","},{"t":"RawInline","c":["html","
"]},{"t":"SoftBreak"},{"t":"Str","c":"    dim:"},{"t":"Space"},{"t":"Str","c":"collections.abc.Sequence[collections.abc.Sequence[str],"},{"t":"Space"},{"t":"Str","c":"str,"},{"t":"Space"},{"t":"Str","c":"None]"},{"t":"SoftBreak"},{"t":"Str","c":","},{"t":"RawInline","c":["html","
"]},{"t":"SoftBreak"},{"t":"Str","c":"    definite:"},{"t":"Space"},{"t":"Str","c":"bool"},{"t":"SoftBreak"},{"t":"Str","c":"="},{"t":"Space"},{"t":"Str","c":"False,"},{"t":"RawInline","c":["html","
"]},{"t":"SoftBreak"},{"t":"Str","c":")->"},{"t":"Space"},{"t":"Quoted","c":[{"t":"SingleQuote"},[{"t":"Str","c":"PatchType"}]]}]}]]}]]},{"t":"Para","c":[{"t":"Str","c":"Integrate"},{"t":"Space"},{"t":"Str","c":"along"},{"t":"Space"},{"t":"Str","c":"a"},{"t":"Space"},{"t":"Str","c":"specified"},{"t":"Space"},{"t":"Str","c":"dimension"},{"t":"Space"},{"t":"Str","c":"using"},{"t":"Space"},{"t":"Str","c":"composite"},{"t":"Space"},{"t":"Str","c":"trapezoidal"},{"t":"Space"},{"t":"Str","c":"rule."}]},{"t":"Header","c":[2,["parameters",[],[]],[{"t":"Str","c":"Parameters"}]]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html",""]},{"t":"RawBlock","c":["html","
"]},{"t":"Plain","c":[{"t":"Str","c":"Parameter"}]},{"t":"RawBlock","c":["html",""]},{"t":"Plain","c":[{"t":"Str","c":"Description"}]},{"t":"RawBlock","c":["html","
"]},{"t":"Plain","c":[{"t":"Str","c":"patch"}]},{"t":"RawBlock","c":["html",""]},{"t":"Plain","c":[{"t":"Str","c":"Patch"},{"t":"Space"},{"t":"Str","c":"object"},{"t":"Space"},{"t":"Str","c":"for"},{"t":"Space"},{"t":"Str","c":"integration."}]},{"t":"RawBlock","c":["html","
"]},{"t":"Plain","c":[{"t":"Str","c":"dim"}]},{"t":"RawBlock","c":["html",""]},{"t":"Plain","c":[{"t":"Str","c":"The"},{"t":"Space"},{"t":"Str","c":"dimension(s)"},{"t":"Space"},{"t":"Str","c":"along"},{"t":"Space"},{"t":"Str","c":"which"},{"t":"Space"},{"t":"Str","c":"to"},{"t":"Space"},{"t":"Str","c":"integrate."},{"t":"Space"},{"t":"Str","c":"If"},{"t":"Space"},{"t":"Str","c":"None,"},{"t":"Space"},{"t":"Str","c":"integrate"},{"t":"Space"},{"t":"Str","c":"along"},{"t":"RawInline","c":["html","
"]},{"t":"Str","c":"all"},{"t":"Space"},{"t":"Str","c":"dimensions."}]},{"t":"RawBlock","c":["html","
"]},{"t":"Plain","c":[{"t":"Str","c":"definite"}]},{"t":"RawBlock","c":["html",""]},{"t":"Plain","c":[{"t":"Str","c":"If"},{"t":"Space"},{"t":"Str","c":"True,"},{"t":"Space"},{"t":"Str","c":"consider"},{"t":"Space"},{"t":"Str","c":"the"},{"t":"Space"},{"t":"Str","c":"integration"},{"t":"Space"},{"t":"Str","c":"to"},{"t":"Space"},{"t":"Str","c":"be"},{"t":"Space"},{"t":"Str","c":"defined"},{"t":"Space"},{"t":"Str","c":"from"},{"t":"Space"},{"t":"Str","c":"the"},{"t":"Space"},{"t":"Str","c":"minimum"},{"t":"Space"},{"t":"Str","c":"to"},{"t":"RawInline","c":["html","
"]},{"t":"Str","c":"the"},{"t":"Space"},{"t":"Str","c":"maximum"},{"t":"Space"},{"t":"Str","c":"value"},{"t":"Space"},{"t":"Str","c":"along"},{"t":"Space"},{"t":"Str","c":"specified"},{"t":"Space"},{"t":"Str","c":"dimension(s)."},{"t":"Space"},{"t":"Str","c":"In"},{"t":"Space"},{"t":"Str","c":"essense,"},{"t":"Space"},{"t":"Str","c":"this"},{"t":"RawInline","c":["html","
"]},{"t":"Str","c":"collapses"},{"t":"Space"},{"t":"Str","c":"the"},{"t":"Space"},{"t":"Str","c":"integrated"},{"t":"Space"},{"t":"Str","c":"dimensions"},{"t":"Space"},{"t":"Str","c":"to"},{"t":"Space"},{"t":"Str","c":"a"},{"t":"Space"},{"t":"Str","c":"lenght"},{"t":"Space"},{"t":"Str","c":"of"},{"t":"Space"},{"t":"Str","c":"1."},{"t":"RawInline","c":["html","
"]},{"t":"Str","c":"If"},{"t":"Space"},{"t":"Str","c":"define"},{"t":"Space"},{"t":"Str","c":"is"},{"t":"Space"},{"t":"Str","c":"False,"},{"t":"Space"},{"t":"Str","c":"the"},{"t":"Space"},{"t":"Str","c":"shape"},{"t":"Space"},{"t":"Str","c":"of"},{"t":"Space"},{"t":"Str","c":"the"},{"t":"Space"},{"t":"Str","c":"patch"},{"t":"Space"},{"t":"Str","c":"is"},{"t":"Space"},{"t":"Str","c":"preserved"},{"t":"Space"},{"t":"Str","c":"and"},{"t":"Space"},{"t":"Str","c":"a"},{"t":"RawInline","c":["html","
"]},{"t":"Quoted","c":[{"t":"DoubleQuote"},[{"t":"Str","c":"cumulative"}]]},{"t":"Space"},{"t":"Str","c":"type"},{"t":"Space"},{"t":"Str","c":"integration"},{"t":"Space"},{"t":"Str","c":"in"},{"t":"Space"},{"t":"Str","c":"performed."}]},{"t":"RawBlock","c":["html","
"]},{"t":"Plain","c":[{"t":"RawInline","c":["QUARTO_custom","Callout 1 Block"]}]},{"t":"Header","c":[2,["examples",[],[]],[{"t":"Str","c":"Examples"}]]},{"t":"Div","c":[["",["cell"],[["execution_count","1"]]],[{"t":"CodeBlock","c":[["",["python","cell-code"],[]],"import dascore as dc\npatch = dc.get_example_patch()\n# integrate along time axis, preserve patch shape with indefinite integral\ntime_integrated = patch.integrate(dim=\"time\", definite=False)\n# integrate along distance axis, collapse distance coordinate\ndist_integrated = patch.integrate(dim=\"distance\", definite=True)\n# integrate along all dimensions.\nall_integrated = patch.integrate(dim=None, definite=False)"]}]]},{"t":"Div","c":[["quarto-navigation-envelope",["hidden"],[]],[{"t":"Para","c":[{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar-title"]]],[{"t":"Str","c":"API"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar-title"]]],[{"t":"Str","c":"DASCore"},{"t":"Space"},{"t":"Str","c":"(0.1.1.dev2)"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-next"]]],[{"t":"Str","c":"spectro"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-prev"]]],[{"t":"Str","c":"integrate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-1"]]],[{"t":"Str","c":"dascore"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/version.html"]]],[{"t":"Str","c":"version"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-2"]]],[{"t":"Str","c":"clients"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-3"]]],[{"t":"Str","c":"dirspool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-4"]]],[{"t":"Str","c":"DirectorySpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/dirspool/DirectorySpool/get_contents.html"]]],[{"t":"Str","c":"get_contents"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/dirspool/DirectorySpool/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-5"]]],[{"t":"Str","c":"filespool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-6"]]],[{"t":"Str","c":"FileSpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/filespool/FileSpool/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-7"]]],[{"t":"Str","c":"compat"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/compat/array.html"]]],[{"t":"Str","c":"array"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-8"]]],[{"t":"Str","c":"constants"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-9"]]],[{"t":"Str","c":"ExecutorType"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/constants/ExecutorType/map.html"]]],[{"t":"Str","c":"map"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-10"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/schema.html"]]],[{"t":"Str","c":"schema"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-11"]]],[{"t":"Str","c":"attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/check_coords.html"]]],[{"t":"Str","c":"check_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/check_dims.html"]]],[{"t":"Str","c":"check_dims"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/combine_patch_attrs.html"]]],[{"t":"Str","c":"combine_patch_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/decompose_attrs.html"]]],[{"t":"Str","c":"decompose_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/merge_compatible_coords_attrs.html"]]],[{"t":"Str","c":"merge_compatible_coords_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-12"]]],[{"t":"Str","c":"PatchAttrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/coords_from_dims.html"]]],[{"t":"Str","c":"coords_from_dims"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/drop_private.html"]]],[{"t":"Str","c":"drop_private"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/flat_dump.html"]]],[{"t":"Str","c":"flat_dump"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/from_dict.html"]]],[{"t":"Str","c":"from_dict"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/get.html"]]],[{"t":"Str","c":"get"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/items.html"]]],[{"t":"Str","c":"items"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/parse_coord_attributes.html"]]],[{"t":"Str","c":"parse_coord_attributes"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/rename_dimension.html"]]],[{"t":"Str","c":"rename_dimension"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-13"]]],[{"t":"Str","c":"coordmanager"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/get_coord_manager.html"]]],[{"t":"Str","c":"get_coord_manager"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/merge_coord_managers.html"]]],[{"t":"Str","c":"merge_coord_managers"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-14"]]],[{"t":"Str","c":"CoordManager"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/convert_units.html"]]],[{"t":"Str","c":"convert_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/coord_range.html"]]],[{"t":"Str","c":"coord_range"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/coord_size.html"]]],[{"t":"Str","c":"coord_size"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/decimate.html"]]],[{"t":"Str","c":"decimate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/disassociate_coord.html"]]],[{"t":"Str","c":"disassociate_coord"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/drop_coords.html"]]],[{"t":"Str","c":"drop_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/drop_disassociated_coords.html"]]],[{"t":"Str","c":"drop_disassociated_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/equals.html"]]],[{"t":"Str","c":"equals"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/get_array.html"]]],[{"t":"Str","c":"get_array"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/get_coord.html"]]],[{"t":"Str","c":"get_coord"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/get_coord_tuple_map.html"]]],[{"t":"Str","c":"get_coord_tuple_map"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/keys.html"]]],[{"t":"Str","c":"keys"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/max.html"]]],[{"t":"Str","c":"max"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/min.html"]]],[{"t":"Str","c":"min"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/new.html"]]],[{"t":"Str","c":"new"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/rename_coord.html"]]],[{"t":"Str","c":"rename_coord"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/set_dims.html"]]],[{"t":"Str","c":"set_dims"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/set_units.html"]]],[{"t":"Str","c":"set_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/simplify_units.html"]]],[{"t":"Str","c":"simplify_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/snap.html"]]],[{"t":"Str","c":"snap"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/sort.html"]]],[{"t":"Str","c":"sort"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/squeeze.html"]]],[{"t":"Str","c":"squeeze"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/step.html"]]],[{"t":"Str","c":"step"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/to_summary_dict.html"]]],[{"t":"Str","c":"to_summary_dict"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/transpose.html"]]],[{"t":"Str","c":"transpose"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/update_from_attrs.html"]]],[{"t":"Str","c":"update_from_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/validate_data.html"]]],[{"t":"Str","c":"validate_data"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-15"]]],[{"t":"Str","c":"coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/ensure_consistent_dtype.html"]]],[{"t":"Str","c":"ensure_consistent_dtype"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/get_compatible_values.html"]]],[{"t":"Str","c":"get_compatible_values"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/get_coord.html"]]],[{"t":"Str","c":"get_coord"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-16"]]],[{"t":"Str","c":"BaseCoord"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/check_time_units.html"]]],[{"t":"Str","c":"check_time_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/convert_units.html"]]],[{"t":"Str","c":"convert_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/coord_range.html"]]],[{"t":"Str","c":"coord_range"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/empty.html"]]],[{"t":"Str","c":"empty"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/get_attrs_dict.html"]]],[{"t":"Str","c":"get_attrs_dict"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/get_next_index.html"]]],[{"t":"Str","c":"get_next_index"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/get_sample_count.html"]]],[{"t":"Str","c":"get_sample_count"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/get_slice_tuple.html"]]],[{"t":"Str","c":"get_slice_tuple"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/index.html"]]],[{"t":"Str","c":"index"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/max.html"]]],[{"t":"Str","c":"max"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/min.html"]]],[{"t":"Str","c":"min"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/set_units.html"]]],[{"t":"Str","c":"set_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/simplify_units.html"]]],[{"t":"Str","c":"simplify_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/snap.html"]]],[{"t":"Str","c":"snap"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/sort.html"]]],[{"t":"Str","c":"sort"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/to_summary.html"]]],[{"t":"Str","c":"to_summary"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/update_data.html"]]],[{"t":"Str","c":"update_data"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/update_limits.html"]]],[{"t":"Str","c":"update_limits"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-17"]]],[{"t":"Str","c":"CoordArray"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordArray/check_time_units.html"]]],[{"t":"Str","c":"check_time_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordArray/convert_units.html"]]],[{"t":"Str","c":"convert_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordArray/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordArray/snap.html"]]],[{"t":"Str","c":"snap"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordArray/sort.html"]]],[{"t":"Str","c":"sort"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordArray/update_limits.html"]]],[{"t":"Str","c":"update_limits"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-18"]]],[{"t":"Str","c":"CoordDegenerate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordDegenerate/check_time_units.html"]]],[{"t":"Str","c":"check_time_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordDegenerate/empty.html"]]],[{"t":"Str","c":"empty"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordDegenerate/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordDegenerate/snap.html"]]],[{"t":"Str","c":"snap"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-19"]]],[{"t":"Str","c":"CoordMonotonicArray"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordMonotonicArray/check_time_units.html"]]],[{"t":"Str","c":"check_time_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordMonotonicArray/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-20"]]],[{"t":"Str","c":"CoordRange"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordRange/change_length.html"]]],[{"t":"Str","c":"change_length"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordRange/check_time_units.html"]]],[{"t":"Str","c":"check_time_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordRange/convert_units.html"]]],[{"t":"Str","c":"convert_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordRange/ensure_all_attrs_set.html"]]],[{"t":"Str","c":"ensure_all_attrs_set"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordRange/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordRange/sort.html"]]],[{"t":"Str","c":"sort"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordRange/update_limits.html"]]],[{"t":"Str","c":"update_limits"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-21"]]],[{"t":"Str","c":"CoordSummary"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordSummary/get_correct_dtype_cast_values.html"]]],[{"t":"Str","c":"get_correct_dtype_cast_values"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordSummary/ser_model.html"]]],[{"t":"Str","c":"ser_model"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordSummary/to_coord.html"]]],[{"t":"Str","c":"to_coord"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-22"]]],[{"t":"Str","c":"patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-23"]]],[{"t":"Str","c":"Patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/patch/Patch/assign_coords.html"]]],[{"t":"Str","c":"assign_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/patch/Patch/iresample.html"]]],[{"t":"Str","c":"iresample"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/patch/Patch/iselect.html"]]],[{"t":"Str","c":"iselect"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-24"]]],[{"t":"Str","c":"spool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/MemorySpool.html"]]],[{"t":"Str","c":"MemorySpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/spool.html"]]],[{"t":"Str","c":"spool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-25"]]],[{"t":"Str","c":"BaseSpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/chunk.html"]]],[{"t":"Str","c":"chunk"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/get_contents.html"]]],[{"t":"Str","c":"get_contents"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/map.html"]]],[{"t":"Str","c":"map"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/sort.html"]]],[{"t":"Str","c":"sort"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/split.html"]]],[{"t":"Str","c":"split"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/stack.html"]]],[{"t":"Str","c":"stack"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-26"]]],[{"t":"Str","c":"DataFrameSpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/DataFrameSpool/chunk.html"]]],[{"t":"Str","c":"chunk"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/DataFrameSpool/get_contents.html"]]],[{"t":"Str","c":"get_contents"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/DataFrameSpool/new_from_df.html"]]],[{"t":"Str","c":"new_from_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/DataFrameSpool/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/DataFrameSpool/sort.html"]]],[{"t":"Str","c":"sort"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/DataFrameSpool/split.html"]]],[{"t":"Str","c":"split"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-27"]]],[{"t":"Str","c":"examples"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/dispersion_event.html"]]],[{"t":"Str","c":"dispersion_event"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/diverse_spool.html"]]],[{"t":"Str","c":"diverse_spool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/example_event_1.html"]]],[{"t":"Str","c":"example_event_1"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/example_event_2.html"]]],[{"t":"Str","c":"example_event_2"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/get_example_patch.html"]]],[{"t":"Str","c":"get_example_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/get_example_spool.html"]]],[{"t":"Str","c":"get_example_spool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/patch_with_null.html"]]],[{"t":"Str","c":"patch_with_null"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/random_patch.html"]]],[{"t":"Str","c":"random_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/random_patch_lat_lon.html"]]],[{"t":"Str","c":"random_patch_lat_lon"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/random_spool.html"]]],[{"t":"Str","c":"random_spool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/ricker_moveout.html"]]],[{"t":"Str","c":"ricker_moveout"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/sin_wave_patch.html"]]],[{"t":"Str","c":"sin_wave_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/spool_to_directory.html"]]],[{"t":"Str","c":"spool_to_directory"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/wacky_dim_coord_patch.html"]]],[{"t":"Str","c":"wacky_dim_coord_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-28"]]],[{"t":"Str","c":"exceptions"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/AttributeMergeError.html"]]],[{"t":"Str","c":"AttributeMergeError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/ChunkError.html"]]],[{"t":"Str","c":"ChunkError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/CoordDataError.html"]]],[{"t":"Str","c":"CoordDataError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/CoordError.html"]]],[{"t":"Str","c":"CoordError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/CoordMergeError.html"]]],[{"t":"Str","c":"CoordMergeError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/CoordSortError.html"]]],[{"t":"Str","c":"CoordSortError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/DASCoreError.html"]]],[{"t":"Str","c":"DASCoreError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/FilterValueError.html"]]],[{"t":"Str","c":"FilterValueError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/IncompatiblePatchError.html"]]],[{"t":"Str","c":"IncompatiblePatchError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/InvalidFiberFileError.html"]]],[{"t":"Str","c":"InvalidFiberFileError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/InvalidFiberIOError.html"]]],[{"t":"Str","c":"InvalidFiberIOError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/InvalidFileHandlerError.html"]]],[{"t":"Str","c":"InvalidFileHandlerError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/InvalidIndexVersionError.html"]]],[{"t":"Str","c":"InvalidIndexVersionError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/InvalidSpoolError.html"]]],[{"t":"Str","c":"InvalidSpoolError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/InvalidTimeRangeError.html"]]],[{"t":"Str","c":"InvalidTimeRangeError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/MissingOptionalDependencyError.html"]]],[{"t":"Str","c":"MissingOptionalDependencyError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/ParameterError.html"]]],[{"t":"Str","c":"ParameterError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/PatchAttributeError.html"]]],[{"t":"Str","c":"PatchAttributeError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/PatchConversionError.html"]]],[{"t":"Str","c":"PatchConversionError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/PatchDimError.html"]]],[{"t":"Str","c":"PatchDimError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/PatchError.html"]]],[{"t":"Str","c":"PatchError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/TimeError.html"]]],[{"t":"Str","c":"TimeError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/UnitError.html"]]],[{"t":"Str","c":"UnitError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/UnknownExampleError.html"]]],[{"t":"Str","c":"UnknownExampleError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/UnknownFiberFormatError.html"]]],[{"t":"Str","c":"UnknownFiberFormatError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/UnsupportedKeywordError.html"]]],[{"t":"Str","c":"UnsupportedKeywordError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-29"]]],[{"t":"Str","c":"io"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/PatchIO.html"]]],[{"t":"Str","c":"PatchIO"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-30"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/scan_to_df.html"]]],[{"t":"Str","c":"scan_to_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-31"]]],[{"t":"Str","c":"FiberIO"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/FiberIO/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/FiberIO/get_supported_io_table.html"]]],[{"t":"Str","c":"get_supported_io_table"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/FiberIO/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/FiberIO/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/FiberIO/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-32"]]],[{"t":"Str","c":"PatchFileSummary"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/PatchFileSummary/flat_dump.html"]]],[{"t":"Str","c":"flat_dump"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/PatchFileSummary/translate_d_to_step.html"]]],[{"t":"Str","c":"translate_d_to_step"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-33"]]],[{"t":"Str","c":"dasdae"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-34"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-35"]]],[{"t":"Str","c":"DASDAEV1"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/core/DASDAEV1/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/core/DASDAEV1/index.html"]]],[{"t":"Str","c":"index"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/core/DASDAEV1/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/core/DASDAEV1/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/core/DASDAEV1/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-36"]]],[{"t":"Str","c":"dashdf5"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dashdf5/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-37"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dashdf5/core/ProdMLPatchAttrs.html"]]],[{"t":"Str","c":"ProdMLPatchAttrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-38"]]],[{"t":"Str","c":"DASHDF5"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dashdf5/core/DASHDF5/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dashdf5/core/DASHDF5/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dashdf5/core/DASHDF5/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-39"]]],[{"t":"Str","c":"febus"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/febus/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-40"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/febus/core/Febus2.html"]]],[{"t":"Str","c":"Febus2"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/febus/core/FebusPatchAttrs.html"]]],[{"t":"Str","c":"FebusPatchAttrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-41"]]],[{"t":"Str","c":"Febus1"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/febus/core/Febus1/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/febus/core/Febus1/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/febus/core/Febus1/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-42"]]],[{"t":"Str","c":"h5simple"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/h5simple/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-43"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-44"]]],[{"t":"Str","c":"H5Simple"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/h5simple/core/H5Simple/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/h5simple/core/H5Simple/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/h5simple/core/H5Simple/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-45"]]],[{"t":"Str","c":"indexer"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-46"]]],[{"t":"Str","c":"AbstractIndexer"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/indexer/AbstractIndexer/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-47"]]],[{"t":"Str","c":"DirectoryIndexer"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/indexer/DirectoryIndexer/clear_cache.html"]]],[{"t":"Str","c":"clear_cache"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/indexer/DirectoryIndexer/get_contents.html"]]],[{"t":"Str","c":"get_contents"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/indexer/DirectoryIndexer/get_index_metadata.html"]]],[{"t":"Str","c":"get_index_metadata"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/indexer/DirectoryIndexer/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-48"]]],[{"t":"Str","c":"optodas"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/optodas/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-49"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/optodas/core/OptoDASPatchAttrs.html"]]],[{"t":"Str","c":"OptoDASPatchAttrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-50"]]],[{"t":"Str","c":"OptoDASV8"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/optodas/core/OptoDASV8/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/optodas/core/OptoDASV8/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/optodas/core/OptoDASV8/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-51"]]],[{"t":"Str","c":"pickle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-52"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-53"]]],[{"t":"Str","c":"PickleIO"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/pickle/core/PickleIO/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/pickle/core/PickleIO/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/pickle/core/PickleIO/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-54"]]],[{"t":"Str","c":"prodml"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/prodml/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-55"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/prodml/core/ProdMLPatchAttrs.html"]]],[{"t":"Str","c":"ProdMLPatchAttrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/prodml/core/ProdMLV2_1.html"]]],[{"t":"Str","c":"ProdMLV2_1"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-56"]]],[{"t":"Str","c":"ProdMLV2_0"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/prodml/core/ProdMLV2_0/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/prodml/core/ProdMLV2_0/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/prodml/core/ProdMLV2_0/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-57"]]],[{"t":"Str","c":"rsf"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-58"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-59"]]],[{"t":"Str","c":"RSFV1"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/rsf/core/RSFV1/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-60"]]],[{"t":"Str","c":"segy"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/segy/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-61"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-62"]]],[{"t":"Str","c":"SegyV2"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/segy/core/SegyV2/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/segy/core/SegyV2/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/segy/core/SegyV2/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-63"]]],[{"t":"Str","c":"sentek"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/sentek/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-64"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-65"]]],[{"t":"Str","c":"SentekV5"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/sentek/core/SentekV5/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/sentek/core/SentekV5/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/sentek/core/SentekV5/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-66"]]],[{"t":"Str","c":"tdms"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-67"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-68"]]],[{"t":"Str","c":"TDMSFormatterV4713"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/core/TDMSFormatterV4713/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/core/TDMSFormatterV4713/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/core/TDMSFormatterV4713/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-69"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/utils/parse_time_stamp.html"]]],[{"t":"Str","c":"parse_time_stamp"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/utils/type_not_supported.html"]]],[{"t":"Str","c":"type_not_supported"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-70"]]],[{"t":"Str","c":"terra15"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-71"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/core/Terra15FormatterV5.html"]]],[{"t":"Str","c":"Terra15FormatterV5"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/core/Terra15FormatterV6.html"]]],[{"t":"Str","c":"Terra15FormatterV6"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-72"]]],[{"t":"Str","c":"Terra15FormatterV4"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/core/Terra15FormatterV4/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/core/Terra15FormatterV4/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/core/Terra15FormatterV4/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-73"]]],[{"t":"Str","c":"wav"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-74"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-75"]]],[{"t":"Str","c":"WavIO"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/wav/core/WavIO/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-76"]]],[{"t":"Str","c":"proc"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-77"]]],[{"t":"Str","c":"aggregate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/aggregate/aggregate.html"]]],[{"t":"Str","c":"aggregate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-78"]]],[{"t":"Str","c":"basic"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/abs.html"]]],[{"t":"Str","c":"abs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/angle.html"]]],[{"t":"Str","c":"angle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/apply_operator.html"]]],[{"t":"Str","c":"apply_operator"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/dropna.html"]]],[{"t":"Str","c":"dropna"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/equals.html"]]],[{"t":"Str","c":"equals"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/imag.html"]]],[{"t":"Str","c":"imag"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/normalize.html"]]],[{"t":"Str","c":"normalize"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/pad.html"]]],[{"t":"Str","c":"pad"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/pipe.html"]]],[{"t":"Str","c":"pipe"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/real.html"]]],[{"t":"Str","c":"real"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/set_dims.html"]]],[{"t":"Str","c":"set_dims"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/squeeze.html"]]],[{"t":"Str","c":"squeeze"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/standardize.html"]]],[{"t":"Str","c":"standardize"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/transpose.html"]]],[{"t":"Str","c":"transpose"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/update_attrs.html"]]],[{"t":"Str","c":"update_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-79"]]],[{"t":"Str","c":"coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/coords/assert_has_coords.html"]]],[{"t":"Str","c":"assert_has_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/coords/coords_from_df.html"]]],[{"t":"Str","c":"coords_from_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/coords/drop_coords.html"]]],[{"t":"Str","c":"drop_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/coords/get_coord.html"]]],[{"t":"Str","c":"get_coord"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/coords/rename_coords.html"]]],[{"t":"Str","c":"rename_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/coords/snap_coords.html"]]],[{"t":"Str","c":"snap_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/coords/sort_coords.html"]]],[{"t":"Str","c":"sort_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/coords/update_coords.html"]]],[{"t":"Str","c":"update_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-80"]]],[{"t":"Str","c":"correlate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/correlate/correlate.html"]]],[{"t":"Str","c":"correlate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-81"]]],[{"t":"Str","c":"detrend"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/detrend/detrend.html"]]],[{"t":"Str","c":"detrend"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-82"]]],[{"t":"Str","c":"filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/filter/gaussian_filter.html"]]],[{"t":"Str","c":"gaussian_filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/filter/median_filter.html"]]],[{"t":"Str","c":"median_filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/filter/pass_filter.html"]]],[{"t":"Str","c":"pass_filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/filter/savgol_filter.html"]]],[{"t":"Str","c":"savgol_filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/filter/sobel_filter.html"]]],[{"t":"Str","c":"sobel_filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-83"]]],[{"t":"Str","c":"resample"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/resample/decimate.html"]]],[{"t":"Str","c":"decimate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/resample/interpolate.html"]]],[{"t":"Str","c":"interpolate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/resample/resample.html"]]],[{"t":"Str","c":"resample"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-84"]]],[{"t":"Str","c":"rolling"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/rolling/rolling.html"]]],[{"t":"Str","c":"rolling"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-85"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/select/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-86"]]],[{"t":"Str","c":"taper"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/taper/taper.html"]]],[{"t":"Str","c":"taper"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-87"]]],[{"t":"Str","c":"units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/units/convert_units.html"]]],[{"t":"Str","c":"convert_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/units/set_units.html"]]],[{"t":"Str","c":"set_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/units/simplify_units.html"]]],[{"t":"Str","c":"simplify_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-88"]]],[{"t":"Str","c":"whiten"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/whiten/whiten.html"]]],[{"t":"Str","c":"whiten"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-89"]]],[{"t":"Str","c":"transform"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-90"]]],[{"t":"Str","c":"differentiate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/differentiate/differentiate.html"]]],[{"t":"Str","c":"differentiate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-91"]]],[{"t":"Str","c":"dispersion"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/dispersion/dispersion_phase_shift.html"]]],[{"t":"Str","c":"dispersion_phase_shift"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-92"]]],[{"t":"Str","c":"fft"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/fft/rfft.html"]]],[{"t":"Str","c":"rfft"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-93"]]],[{"t":"Str","c":"fourier"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/fourier/dft.html"]]],[{"t":"Str","c":"dft"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/fourier/idft.html"]]],[{"t":"Str","c":"idft"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-94"]]],[{"t":"Str","c":"integrate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/integrate/integrate.html"]]],[{"t":"Str","c":"integrate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-95"]]],[{"t":"Str","c":"spectro"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/spectro/spectrogram.html"]]],[{"t":"Str","c":"spectrogram"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-96"]]],[{"t":"Str","c":"strain"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/strain/velocity_to_strain_rate.html"]]],[{"t":"Str","c":"velocity_to_strain_rate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-97"]]],[{"t":"Str","c":"units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/assert_dtype_compatible_with_units.html"]]],[{"t":"Str","c":"assert_dtype_compatible_with_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/convert_units.html"]]],[{"t":"Str","c":"convert_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/get_factor_and_unit.html"]]],[{"t":"Str","c":"get_factor_and_unit"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/get_filter_units.html"]]],[{"t":"Str","c":"get_filter_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/get_quantity.html"]]],[{"t":"Str","c":"get_quantity"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/get_quantity_str.html"]]],[{"t":"Str","c":"get_quantity_str"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/get_registry.html"]]],[{"t":"Str","c":"get_registry"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/get_unit.html"]]],[{"t":"Str","c":"get_unit"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/invert_quantity.html"]]],[{"t":"Str","c":"invert_quantity"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-98"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/plotting.html"]]],[{"t":"Str","c":"plotting"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-99"]]],[{"t":"Str","c":"chunk"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/chunk/get_intervals.html"]]],[{"t":"Str","c":"get_intervals"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-100"]]],[{"t":"Str","c":"ChunkManager"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/chunk/ChunkManager/chunk.html"]]],[{"t":"Str","c":"chunk"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/chunk/ChunkManager/get_instruction_df.html"]]],[{"t":"Str","c":"get_instruction_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-101"]]],[{"t":"Str","c":"display"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/display/array_to_text.html"]]],[{"t":"Str","c":"array_to_text"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/display/attrs_to_text.html"]]],[{"t":"Str","c":"attrs_to_text"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/display/get_dascore_text.html"]]],[{"t":"Str","c":"get_dascore_text"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/display/get_nice_text.html"]]],[{"t":"Str","c":"get_nice_text"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-102"]]],[{"t":"Str","c":"docs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/docs/compose_docstring.html"]]],[{"t":"Str","c":"compose_docstring"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/docs/format_dtypes.html"]]],[{"t":"Str","c":"format_dtypes"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/docs/objs_to_doc_df.html"]]],[{"t":"Str","c":"objs_to_doc_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-103"]]],[{"t":"Str","c":"downloader"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/downloader/fetch.html"]]],[{"t":"Str","c":"fetch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/downloader/get_registry_df.html"]]],[{"t":"Str","c":"get_registry_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-104"]]],[{"t":"Str","c":"hdf5"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/open_hdf5_file.html"]]],[{"t":"Str","c":"open_hdf5_file"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/unpack_scalar_h5_dataset.html"]]],[{"t":"Str","c":"unpack_scalar_h5_dataset"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-105"]]],[{"t":"Str","c":"H5Reader"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/H5Reader/get_handle.html"]]],[{"t":"Str","c":"get_handle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-106"]]],[{"t":"Str","c":"H5Writer"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/H5Writer/get_handle.html"]]],[{"t":"Str","c":"get_handle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-107"]]],[{"t":"Str","c":"HDF5Reader"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDF5Reader/get_handle.html"]]],[{"t":"Str","c":"get_handle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-108"]]],[{"t":"Str","c":"HDF5Writer"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDF5Writer/get_handle.html"]]],[{"t":"Str","c":"get_handle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-109"]]],[{"t":"Str","c":"HDFPatchIndexManager"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDFPatchIndexManager/decode_table.html"]]],[{"t":"Str","c":"decode_table"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDFPatchIndexManager/encode_table.html"]]],[{"t":"Str","c":"encode_table"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDFPatchIndexManager/get_index.html"]]],[{"t":"Str","c":"get_index"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDFPatchIndexManager/validate_version.html"]]],[{"t":"Str","c":"validate_version"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDFPatchIndexManager/write_update.html"]]],[{"t":"Str","c":"write_update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-110"]]],[{"t":"Str","c":"io"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/get_handle_from_resource.html"]]],[{"t":"Str","c":"get_handle_from_resource"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/obspy_to_patch.html"]]],[{"t":"Str","c":"obspy_to_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/patch_to_obspy.html"]]],[{"t":"Str","c":"patch_to_obspy"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/patch_to_xarray.html"]]],[{"t":"Str","c":"patch_to_xarray"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/xarray_to_patch.html"]]],[{"t":"Str","c":"xarray_to_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-111"]]],[{"t":"Str","c":"BinaryReader"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/BinaryReader/get_handle.html"]]],[{"t":"Str","c":"get_handle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-112"]]],[{"t":"Str","c":"BinaryWriter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/BinaryWriter/get_handle.html"]]],[{"t":"Str","c":"get_handle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-113"]]],[{"t":"Str","c":"IOResourceManager"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/IOResourceManager/close_all.html"]]],[{"t":"Str","c":"close_all"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/IOResourceManager/get_resource.html"]]],[{"t":"Str","c":"get_resource"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-114"]]],[{"t":"Str","c":"mapping"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-115"]]],[{"t":"Str","c":"FrozenDict"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/mapping/FrozenDict/copy.html"]]],[{"t":"Str","c":"copy"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-116"]]],[{"t":"Str","c":"misc"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/CacheDescriptor.html"]]],[{"t":"Str","c":"CacheDescriptor"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/MethodNameSpace.html"]]],[{"t":"Str","c":"MethodNameSpace"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/all_close.html"]]],[{"t":"Str","c":"all_close"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/all_diffs_close_enough.html"]]],[{"t":"Str","c":"all_diffs_close_enough"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/broadcast_for_index.html"]]],[{"t":"Str","c":"broadcast_for_index"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/cached_method.html"]]],[{"t":"Str","c":"cached_method"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/check_filter_kwargs.html"]]],[{"t":"Str","c":"check_filter_kwargs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/check_filter_range.html"]]],[{"t":"Str","c":"check_filter_range"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/get_middle_value.html"]]],[{"t":"Str","c":"get_middle_value"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/get_parent_code_name.html"]]],[{"t":"Str","c":"get_parent_code_name"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/get_stencil_coefs.html"]]],[{"t":"Str","c":"get_stencil_coefs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/is_valid_coord_str.html"]]],[{"t":"Str","c":"is_valid_coord_str"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/iter_files.html"]]],[{"t":"Str","c":"iter_files"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/iterate.html"]]],[{"t":"Str","c":"iterate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/maybe_get_attrs.html"]]],[{"t":"Str","c":"maybe_get_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/maybe_get_items.html"]]],[{"t":"Str","c":"maybe_get_items"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/optional_import.html"]]],[{"t":"Str","c":"optional_import"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/register_func.html"]]],[{"t":"Str","c":"register_func"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/sanitize_range_param.html"]]],[{"t":"Str","c":"sanitize_range_param"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/separate_coord_info.html"]]],[{"t":"Str","c":"separate_coord_info"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/suppress_warnings.html"]]],[{"t":"Str","c":"suppress_warnings"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/to_str.html"]]],[{"t":"Str","c":"to_str"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/unbyte.html"]]],[{"t":"Str","c":"unbyte"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/warn_or_raise.html"]]],[{"t":"Str","c":"warn_or_raise"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-117"]]],[{"t":"Str","c":"models"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/models/sensible_model_equals.html"]]],[{"t":"Str","c":"sensible_model_equals"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-118"]]],[{"t":"Str","c":"DascoreBaseModel"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/models/DascoreBaseModel/get_summary_df.html"]]],[{"t":"Str","c":"get_summary_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/models/DascoreBaseModel/new.html"]]],[{"t":"Str","c":"new"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-119"]]],[{"t":"Str","c":"patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/check_patch_attrs.html"]]],[{"t":"Str","c":"check_patch_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/check_patch_dims.html"]]],[{"t":"Str","c":"check_patch_dims"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/get_default_patch_name.html"]]],[{"t":"Str","c":"get_default_patch_name"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/get_dim_sampling_rate.html"]]],[{"t":"Str","c":"get_dim_sampling_rate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/get_dim_value_from_kwargs.html"]]],[{"t":"Str","c":"get_dim_value_from_kwargs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/get_multiple_dim_value_from_kwargs.html"]]],[{"t":"Str","c":"get_multiple_dim_value_from_kwargs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/get_start_stop_step.html"]]],[{"t":"Str","c":"get_start_stop_step"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/merge_patches.html"]]],[{"t":"Str","c":"merge_patches"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/patch_function.html"]]],[{"t":"Str","c":"patch_function"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/patches_to_df.html"]]],[{"t":"Str","c":"patches_to_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/scan_patches.html"]]],[{"t":"Str","c":"scan_patches"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-120"]]],[{"t":"Str","c":"pd"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/adjust_segments.html"]]],[{"t":"Str","c":"adjust_segments"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/dataframe_to_patch.html"]]],[{"t":"Str","c":"dataframe_to_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/fill_defaults_from_pydantic.html"]]],[{"t":"Str","c":"fill_defaults_from_pydantic"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/filter_df.html"]]],[{"t":"Str","c":"filter_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/get_column_names_from_dim.html"]]],[{"t":"Str","c":"get_column_names_from_dim"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/get_dim_names_from_columns.html"]]],[{"t":"Str","c":"get_dim_names_from_columns"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/get_interval_columns.html"]]],[{"t":"Str","c":"get_interval_columns"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/get_regex.html"]]],[{"t":"Str","c":"get_regex"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/list_ser_to_str.html"]]],[{"t":"Str","c":"list_ser_to_str"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/patch_to_dataframe.html"]]],[{"t":"Str","c":"patch_to_dataframe"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/split_df_query.html"]]],[{"t":"Str","c":"split_df_query"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/yield_range_tuple_from_kwargs.html"]]],[{"t":"Str","c":"yield_range_tuple_from_kwargs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-121"]]],[{"t":"Str","c":"progress"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/progress/get_progress_instance.html"]]],[{"t":"Str","c":"get_progress_instance"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/progress/track.html"]]],[{"t":"Str","c":"track"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-122"]]],[{"t":"Str","c":"time"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/dtype_time_like.html"]]],[{"t":"Str","c":"dtype_time_like"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/get_max_min_times.html"]]],[{"t":"Str","c":"get_max_min_times"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/is_datetime64.html"]]],[{"t":"Str","c":"is_datetime64"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/is_timedelta64.html"]]],[{"t":"Str","c":"is_timedelta64"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/to_datetime64.html"]]],[{"t":"Str","c":"to_datetime64"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/to_float.html"]]],[{"t":"Str","c":"to_float"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/to_int.html"]]],[{"t":"Str","c":"to_int"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/to_timedelta64.html"]]],[{"t":"Str","c":"to_timedelta64"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-123"]]],[{"t":"Str","c":"transformatter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/transformatter/FourierTransformatter.html"]]],[{"t":"Str","c":"FourierTransformatter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-124"]]],[{"t":"Str","c":"BaseTransformatter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/transformatter/BaseTransformatter/rename_dims.html"]]],[{"t":"Str","c":"rename_dims"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-125"]]],[{"t":"Str","c":"viz"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/viz/VizPatchNameSpace.html"]]],[{"t":"Str","c":"VizPatchNameSpace"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-126"]]],[{"t":"Str","c":"spectrogram"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/viz/spectrogram/spectrogram.html"]]],[{"t":"Str","c":"spectrogram"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-127"]]],[{"t":"Str","c":"waterfall"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/viz/waterfall/waterfall.html"]]],[{"t":"Str","c":"waterfall"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-128"]]],[{"t":"Str","c":"wiggle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/viz/wiggle/wiggle.html"]]],[{"t":"Str","c":"wiggle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Introduction"]]],[{"t":"Str","c":"Introduction"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:/index.html"]]],[{"t":"Str","c":"/index.html"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Tutorial"]]],[{"t":"Str","c":"Tutorial"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:/tutorial/concepts.html"]]],[{"t":"Str","c":"/tutorial/concepts.html"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Recipes"]]],[{"t":"Str","c":"Recipes"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:/recipes/overview.html"]]],[{"t":"Str","c":"/recipes/overview.html"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Notes"]]],[{"t":"Str","c":"Notes"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:/notes/notes.html"]]],[{"t":"Str","c":"/notes/notes.html"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Contributing"]]],[{"t":"Str","c":"Contributing"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:/contributing/contributing.html"]]],[{"t":"Str","c":"/contributing/contributing.html"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:API"]]],[{"t":"Str","c":"API"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:/api/dascore.html"]]],[{"t":"Str","c":"/api/dascore.html"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:https://github.com/dasdae/dascore"]]],[{"t":"Str","c":"https://github.com/dasdae/dascore"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-breadcrumbs-ca7f8cd10a5c633b30bcc55700c7d9a8"]]],[{"t":"Str","c":"dascore"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-breadcrumbs-d825c53d89d9cacb3e034bcb138f3d37"]]],[{"t":"Str","c":"transform"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-breadcrumbs-4e4aaf3fee165531347b772f66b4f30c"]]],[{"t":"Str","c":"integrate"}]]}]}]]},{"t":"Div","c":[["quarto-meta-markdown",["hidden"],[]],[{"t":"Para","c":[{"t":"Span","c":[["",["hidden"],[["render-id","quarto-twittercardtitle"]]],[]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-ogcardtitle"]]],[]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-metasitename"]]],[{"t":"Str","c":"DASCore"},{"t":"Space"},{"t":"Str","c":"(0.1.1.dev2)"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-twittercarddesc"]]],[]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-ogcardddesc"]]],[]]}]}]]}]} diff --git a/docs/filters/filter_test_data/test_data_4.json b/docs/filters/filter_test_data/test_data_4.json deleted file mode 100644 index bd4169a4d..000000000 --- a/docs/filters/filter_test_data/test_data_4.json +++ /dev/null @@ -1 +0,0 @@ -{"pandoc-api-version":[1,23],"meta":{"biblio-config":{"t":"MetaBool","c":true},"bibliography":{"t":"MetaList","c":[{"t":"MetaInlines","c":[{"t":"Str","c":"../../../../references.bib"}]}]},"code-copy":{"t":"MetaBool","c":true},"date-format":{"t":"MetaInlines","c":[{"t":"Str","c":"long"}]},"document-css":{"t":"MetaBool","c":false},"fig-responsive":{"t":"MetaBool","c":true},"header-includes":{"t":"MetaList","c":[{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html",""]}]}]},"include-after":{"t":"MetaList","c":[{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html","
\n"]}]},{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html","\n"]}]},{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html","\n
\n"]}]}]},"include-before":{"t":"MetaList","c":[{"t":"MetaBlocks","c":[{"t":"RawBlock","c":["html","
\n
\n \n \n
\n\n
\n\n \n
\n\n
\n
\n
\n\n
\n"]}]}]},"labels":{"t":"MetaMap","c":{"abstract":{"t":"MetaInlines","c":[{"t":"Str","c":"Abstract"}]},"affiliations":{"t":"MetaInlines","c":[{"t":"Str","c":"Affiliations"}]},"authors":{"t":"MetaInlines","c":[{"t":"Str","c":"Authors"}]},"description":{"t":"MetaInlines","c":[{"t":"Str","c":"Description"}]},"doi":{"t":"MetaInlines","c":[{"t":"Str","c":"Doi"}]},"modified":{"t":"MetaInlines","c":[{"t":"Str","c":"Modified"}]},"published":{"t":"MetaInlines","c":[{"t":"Str","c":"Published"}]}}},"lang":{"t":"MetaInlines","c":[{"t":"Str","c":"en"}]},"link-citations":{"t":"MetaBool","c":true},"pagetitle":{"t":"MetaString","c":"integrate"},"quarto-custom-nodes":{"t":"MetaList","c":[{"t":"MetaMap","c":{"id":{"t":"MetaString","c":"Callout 1 Block"},"kind":{"t":"MetaString","c":"Block"},"t":{"t":"MetaString","c":"Callout"},"tbl":{"t":"MetaMap","c":{"attr":{"t":"MetaMap","c":{"attributes":{"t":"MetaMap","c":{}},"classes":{"t":"MetaList","c":[]},"identifier":{"t":"MetaString","c":""}}},"content":{"t":"MetaBlocks","c":[{"t":"Para","c":[{"t":"Str","c":"To"},{"t":"Space"},{"t":"Str","c":"remove"},{"t":"Space"},{"t":"Str","c":"dimensions"},{"t":"Space"},{"t":"Str","c":"with"},{"t":"Space"},{"t":"Str","c":"length"},{"t":"Space"},{"t":"Str","c":"1,"},{"t":"SoftBreak"},{"t":"Str","c":"see"},{"t":"Space"},{"t":"Link","c":[["",[],[]],[{"t":"Str","c":"squeeze"}],["%60dascore.proc.basic.squeeze%60",""]]},{"t":"Str","c":"."}]}]}}}}}]},"quarto-template-params":{"t":"MetaMap","c":{"title-block-categories":{"t":"MetaInlines","c":[{"t":"Str","c":"true"}]}}},"quarto-version":{"t":"MetaInlines","c":[{"t":"Str","c":"1.3.450"}]},"theme":{"t":"MetaMap","c":{"dark":{"t":"MetaInlines","c":[{"t":"Str","c":"darkly"}]},"light":{"t":"MetaInlines","c":[{"t":"Str","c":"yeti"}]}}},"toc-title":{"t":"MetaInlines","c":[{"t":"Str","c":"On"},{"t":"Space"},{"t":"Str","c":"this"},{"t":"Space"},{"t":"Str","c":"page"}]}},"blocks":[{"t":"Header","c":[1,["integrate",[],[]],[{"t":"Str","c":"integrate"}]]},{"t":"Plain","c":[{"t":"RawInline","c":["QUARTO_custom","Callout 1 Block"]}]},{"t":"Div","c":[["quarto-navigation-envelope",["hidden"],[]],[{"t":"Para","c":[{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar-title"]]],[{"t":"Str","c":"API"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar-title"]]],[{"t":"Str","c":"DASCore"},{"t":"Space"},{"t":"Str","c":"(0.1.1.dev2)"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-next"]]],[{"t":"Str","c":"spectro"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-prev"]]],[{"t":"Str","c":"integrate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-1"]]],[{"t":"Str","c":"dascore"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/version.html"]]],[{"t":"Str","c":"version"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-2"]]],[{"t":"Str","c":"clients"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-3"]]],[{"t":"Str","c":"dirspool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-4"]]],[{"t":"Str","c":"DirectorySpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/dirspool/DirectorySpool/get_contents.html"]]],[{"t":"Str","c":"get_contents"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/dirspool/DirectorySpool/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-5"]]],[{"t":"Str","c":"filespool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-6"]]],[{"t":"Str","c":"FileSpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/clients/filespool/FileSpool/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-7"]]],[{"t":"Str","c":"compat"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/compat/array.html"]]],[{"t":"Str","c":"array"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-8"]]],[{"t":"Str","c":"constants"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-9"]]],[{"t":"Str","c":"ExecutorType"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/constants/ExecutorType/map.html"]]],[{"t":"Str","c":"map"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-10"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/schema.html"]]],[{"t":"Str","c":"schema"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-11"]]],[{"t":"Str","c":"attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/check_coords.html"]]],[{"t":"Str","c":"check_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/check_dims.html"]]],[{"t":"Str","c":"check_dims"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/combine_patch_attrs.html"]]],[{"t":"Str","c":"combine_patch_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/decompose_attrs.html"]]],[{"t":"Str","c":"decompose_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/merge_compatible_coords_attrs.html"]]],[{"t":"Str","c":"merge_compatible_coords_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-12"]]],[{"t":"Str","c":"PatchAttrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/coords_from_dims.html"]]],[{"t":"Str","c":"coords_from_dims"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/drop_private.html"]]],[{"t":"Str","c":"drop_private"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/flat_dump.html"]]],[{"t":"Str","c":"flat_dump"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/from_dict.html"]]],[{"t":"Str","c":"from_dict"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/get.html"]]],[{"t":"Str","c":"get"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/items.html"]]],[{"t":"Str","c":"items"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/parse_coord_attributes.html"]]],[{"t":"Str","c":"parse_coord_attributes"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/rename_dimension.html"]]],[{"t":"Str","c":"rename_dimension"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/attrs/PatchAttrs/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-13"]]],[{"t":"Str","c":"coordmanager"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/get_coord_manager.html"]]],[{"t":"Str","c":"get_coord_manager"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/merge_coord_managers.html"]]],[{"t":"Str","c":"merge_coord_managers"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-14"]]],[{"t":"Str","c":"CoordManager"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/convert_units.html"]]],[{"t":"Str","c":"convert_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/coord_range.html"]]],[{"t":"Str","c":"coord_range"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/coord_size.html"]]],[{"t":"Str","c":"coord_size"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/decimate.html"]]],[{"t":"Str","c":"decimate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/disassociate_coord.html"]]],[{"t":"Str","c":"disassociate_coord"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/drop_coords.html"]]],[{"t":"Str","c":"drop_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/drop_disassociated_coords.html"]]],[{"t":"Str","c":"drop_disassociated_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/equals.html"]]],[{"t":"Str","c":"equals"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/get_array.html"]]],[{"t":"Str","c":"get_array"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/get_coord.html"]]],[{"t":"Str","c":"get_coord"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/get_coord_tuple_map.html"]]],[{"t":"Str","c":"get_coord_tuple_map"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/keys.html"]]],[{"t":"Str","c":"keys"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/max.html"]]],[{"t":"Str","c":"max"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/min.html"]]],[{"t":"Str","c":"min"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/new.html"]]],[{"t":"Str","c":"new"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/rename_coord.html"]]],[{"t":"Str","c":"rename_coord"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/set_dims.html"]]],[{"t":"Str","c":"set_dims"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/set_units.html"]]],[{"t":"Str","c":"set_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/simplify_units.html"]]],[{"t":"Str","c":"simplify_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/snap.html"]]],[{"t":"Str","c":"snap"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/sort.html"]]],[{"t":"Str","c":"sort"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/squeeze.html"]]],[{"t":"Str","c":"squeeze"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/step.html"]]],[{"t":"Str","c":"step"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/to_summary_dict.html"]]],[{"t":"Str","c":"to_summary_dict"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/transpose.html"]]],[{"t":"Str","c":"transpose"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/update_from_attrs.html"]]],[{"t":"Str","c":"update_from_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coordmanager/CoordManager/validate_data.html"]]],[{"t":"Str","c":"validate_data"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-15"]]],[{"t":"Str","c":"coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/ensure_consistent_dtype.html"]]],[{"t":"Str","c":"ensure_consistent_dtype"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/get_compatible_values.html"]]],[{"t":"Str","c":"get_compatible_values"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/get_coord.html"]]],[{"t":"Str","c":"get_coord"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-16"]]],[{"t":"Str","c":"BaseCoord"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/check_time_units.html"]]],[{"t":"Str","c":"check_time_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/convert_units.html"]]],[{"t":"Str","c":"convert_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/coord_range.html"]]],[{"t":"Str","c":"coord_range"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/empty.html"]]],[{"t":"Str","c":"empty"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/get_attrs_dict.html"]]],[{"t":"Str","c":"get_attrs_dict"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/get_next_index.html"]]],[{"t":"Str","c":"get_next_index"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/get_sample_count.html"]]],[{"t":"Str","c":"get_sample_count"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/get_slice_tuple.html"]]],[{"t":"Str","c":"get_slice_tuple"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/index.html"]]],[{"t":"Str","c":"index"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/max.html"]]],[{"t":"Str","c":"max"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/min.html"]]],[{"t":"Str","c":"min"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/set_units.html"]]],[{"t":"Str","c":"set_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/simplify_units.html"]]],[{"t":"Str","c":"simplify_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/snap.html"]]],[{"t":"Str","c":"snap"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/sort.html"]]],[{"t":"Str","c":"sort"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/to_summary.html"]]],[{"t":"Str","c":"to_summary"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/update_data.html"]]],[{"t":"Str","c":"update_data"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/BaseCoord/update_limits.html"]]],[{"t":"Str","c":"update_limits"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-17"]]],[{"t":"Str","c":"CoordArray"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordArray/check_time_units.html"]]],[{"t":"Str","c":"check_time_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordArray/convert_units.html"]]],[{"t":"Str","c":"convert_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordArray/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordArray/snap.html"]]],[{"t":"Str","c":"snap"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordArray/sort.html"]]],[{"t":"Str","c":"sort"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordArray/update_limits.html"]]],[{"t":"Str","c":"update_limits"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-18"]]],[{"t":"Str","c":"CoordDegenerate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordDegenerate/check_time_units.html"]]],[{"t":"Str","c":"check_time_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordDegenerate/empty.html"]]],[{"t":"Str","c":"empty"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordDegenerate/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordDegenerate/snap.html"]]],[{"t":"Str","c":"snap"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-19"]]],[{"t":"Str","c":"CoordMonotonicArray"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordMonotonicArray/check_time_units.html"]]],[{"t":"Str","c":"check_time_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordMonotonicArray/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-20"]]],[{"t":"Str","c":"CoordRange"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordRange/change_length.html"]]],[{"t":"Str","c":"change_length"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordRange/check_time_units.html"]]],[{"t":"Str","c":"check_time_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordRange/convert_units.html"]]],[{"t":"Str","c":"convert_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordRange/ensure_all_attrs_set.html"]]],[{"t":"Str","c":"ensure_all_attrs_set"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordRange/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordRange/sort.html"]]],[{"t":"Str","c":"sort"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordRange/update_limits.html"]]],[{"t":"Str","c":"update_limits"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-21"]]],[{"t":"Str","c":"CoordSummary"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordSummary/get_correct_dtype_cast_values.html"]]],[{"t":"Str","c":"get_correct_dtype_cast_values"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordSummary/ser_model.html"]]],[{"t":"Str","c":"ser_model"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/coords/CoordSummary/to_coord.html"]]],[{"t":"Str","c":"to_coord"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-22"]]],[{"t":"Str","c":"patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-23"]]],[{"t":"Str","c":"Patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/patch/Patch/assign_coords.html"]]],[{"t":"Str","c":"assign_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/patch/Patch/iresample.html"]]],[{"t":"Str","c":"iresample"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/patch/Patch/iselect.html"]]],[{"t":"Str","c":"iselect"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-24"]]],[{"t":"Str","c":"spool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/MemorySpool.html"]]],[{"t":"Str","c":"MemorySpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/spool.html"]]],[{"t":"Str","c":"spool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-25"]]],[{"t":"Str","c":"BaseSpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/chunk.html"]]],[{"t":"Str","c":"chunk"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/get_contents.html"]]],[{"t":"Str","c":"get_contents"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/map.html"]]],[{"t":"Str","c":"map"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/sort.html"]]],[{"t":"Str","c":"sort"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/split.html"]]],[{"t":"Str","c":"split"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/stack.html"]]],[{"t":"Str","c":"stack"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/BaseSpool/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-26"]]],[{"t":"Str","c":"DataFrameSpool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/DataFrameSpool/chunk.html"]]],[{"t":"Str","c":"chunk"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/DataFrameSpool/get_contents.html"]]],[{"t":"Str","c":"get_contents"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/DataFrameSpool/new_from_df.html"]]],[{"t":"Str","c":"new_from_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/DataFrameSpool/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/DataFrameSpool/sort.html"]]],[{"t":"Str","c":"sort"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/core/spool/DataFrameSpool/split.html"]]],[{"t":"Str","c":"split"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-27"]]],[{"t":"Str","c":"examples"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/dispersion_event.html"]]],[{"t":"Str","c":"dispersion_event"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/diverse_spool.html"]]],[{"t":"Str","c":"diverse_spool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/example_event_1.html"]]],[{"t":"Str","c":"example_event_1"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/example_event_2.html"]]],[{"t":"Str","c":"example_event_2"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/get_example_patch.html"]]],[{"t":"Str","c":"get_example_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/get_example_spool.html"]]],[{"t":"Str","c":"get_example_spool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/patch_with_null.html"]]],[{"t":"Str","c":"patch_with_null"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/random_patch.html"]]],[{"t":"Str","c":"random_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/random_patch_lat_lon.html"]]],[{"t":"Str","c":"random_patch_lat_lon"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/random_spool.html"]]],[{"t":"Str","c":"random_spool"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/ricker_moveout.html"]]],[{"t":"Str","c":"ricker_moveout"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/sin_wave_patch.html"]]],[{"t":"Str","c":"sin_wave_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/spool_to_directory.html"]]],[{"t":"Str","c":"spool_to_directory"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/examples/wacky_dim_coord_patch.html"]]],[{"t":"Str","c":"wacky_dim_coord_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-28"]]],[{"t":"Str","c":"exceptions"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/AttributeMergeError.html"]]],[{"t":"Str","c":"AttributeMergeError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/ChunkError.html"]]],[{"t":"Str","c":"ChunkError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/CoordDataError.html"]]],[{"t":"Str","c":"CoordDataError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/CoordError.html"]]],[{"t":"Str","c":"CoordError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/CoordMergeError.html"]]],[{"t":"Str","c":"CoordMergeError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/CoordSortError.html"]]],[{"t":"Str","c":"CoordSortError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/DASCoreError.html"]]],[{"t":"Str","c":"DASCoreError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/FilterValueError.html"]]],[{"t":"Str","c":"FilterValueError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/IncompatiblePatchError.html"]]],[{"t":"Str","c":"IncompatiblePatchError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/InvalidFiberFileError.html"]]],[{"t":"Str","c":"InvalidFiberFileError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/InvalidFiberIOError.html"]]],[{"t":"Str","c":"InvalidFiberIOError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/InvalidFileHandlerError.html"]]],[{"t":"Str","c":"InvalidFileHandlerError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/InvalidIndexVersionError.html"]]],[{"t":"Str","c":"InvalidIndexVersionError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/InvalidSpoolError.html"]]],[{"t":"Str","c":"InvalidSpoolError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/InvalidTimeRangeError.html"]]],[{"t":"Str","c":"InvalidTimeRangeError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/MissingOptionalDependencyError.html"]]],[{"t":"Str","c":"MissingOptionalDependencyError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/ParameterError.html"]]],[{"t":"Str","c":"ParameterError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/PatchAttributeError.html"]]],[{"t":"Str","c":"PatchAttributeError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/PatchConversionError.html"]]],[{"t":"Str","c":"PatchConversionError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/PatchDimError.html"]]],[{"t":"Str","c":"PatchDimError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/PatchError.html"]]],[{"t":"Str","c":"PatchError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/TimeError.html"]]],[{"t":"Str","c":"TimeError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/UnitError.html"]]],[{"t":"Str","c":"UnitError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/UnknownExampleError.html"]]],[{"t":"Str","c":"UnknownExampleError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/UnknownFiberFormatError.html"]]],[{"t":"Str","c":"UnknownFiberFormatError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/exceptions/UnsupportedKeywordError.html"]]],[{"t":"Str","c":"UnsupportedKeywordError"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-29"]]],[{"t":"Str","c":"io"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/PatchIO.html"]]],[{"t":"Str","c":"PatchIO"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-30"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/scan_to_df.html"]]],[{"t":"Str","c":"scan_to_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-31"]]],[{"t":"Str","c":"FiberIO"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/FiberIO/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/FiberIO/get_supported_io_table.html"]]],[{"t":"Str","c":"get_supported_io_table"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/FiberIO/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/FiberIO/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/FiberIO/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-32"]]],[{"t":"Str","c":"PatchFileSummary"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/PatchFileSummary/flat_dump.html"]]],[{"t":"Str","c":"flat_dump"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/core/PatchFileSummary/translate_d_to_step.html"]]],[{"t":"Str","c":"translate_d_to_step"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-33"]]],[{"t":"Str","c":"dasdae"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-34"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-35"]]],[{"t":"Str","c":"DASDAEV1"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/core/DASDAEV1/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/core/DASDAEV1/index.html"]]],[{"t":"Str","c":"index"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/core/DASDAEV1/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/core/DASDAEV1/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dasdae/core/DASDAEV1/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-36"]]],[{"t":"Str","c":"dashdf5"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dashdf5/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-37"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dashdf5/core/ProdMLPatchAttrs.html"]]],[{"t":"Str","c":"ProdMLPatchAttrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-38"]]],[{"t":"Str","c":"DASHDF5"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dashdf5/core/DASHDF5/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dashdf5/core/DASHDF5/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/dashdf5/core/DASHDF5/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-39"]]],[{"t":"Str","c":"febus"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/febus/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-40"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/febus/core/Febus2.html"]]],[{"t":"Str","c":"Febus2"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/febus/core/FebusPatchAttrs.html"]]],[{"t":"Str","c":"FebusPatchAttrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-41"]]],[{"t":"Str","c":"Febus1"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/febus/core/Febus1/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/febus/core/Febus1/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/febus/core/Febus1/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-42"]]],[{"t":"Str","c":"h5simple"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/h5simple/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-43"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-44"]]],[{"t":"Str","c":"H5Simple"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/h5simple/core/H5Simple/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/h5simple/core/H5Simple/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/h5simple/core/H5Simple/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-45"]]],[{"t":"Str","c":"indexer"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-46"]]],[{"t":"Str","c":"AbstractIndexer"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/indexer/AbstractIndexer/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-47"]]],[{"t":"Str","c":"DirectoryIndexer"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/indexer/DirectoryIndexer/clear_cache.html"]]],[{"t":"Str","c":"clear_cache"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/indexer/DirectoryIndexer/get_contents.html"]]],[{"t":"Str","c":"get_contents"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/indexer/DirectoryIndexer/get_index_metadata.html"]]],[{"t":"Str","c":"get_index_metadata"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/indexer/DirectoryIndexer/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-48"]]],[{"t":"Str","c":"optodas"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/optodas/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-49"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/optodas/core/OptoDASPatchAttrs.html"]]],[{"t":"Str","c":"OptoDASPatchAttrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-50"]]],[{"t":"Str","c":"OptoDASV8"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/optodas/core/OptoDASV8/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/optodas/core/OptoDASV8/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/optodas/core/OptoDASV8/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-51"]]],[{"t":"Str","c":"pickle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-52"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-53"]]],[{"t":"Str","c":"PickleIO"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/pickle/core/PickleIO/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/pickle/core/PickleIO/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/pickle/core/PickleIO/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-54"]]],[{"t":"Str","c":"prodml"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/prodml/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-55"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/prodml/core/ProdMLPatchAttrs.html"]]],[{"t":"Str","c":"ProdMLPatchAttrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/prodml/core/ProdMLV2_1.html"]]],[{"t":"Str","c":"ProdMLV2_1"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-56"]]],[{"t":"Str","c":"ProdMLV2_0"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/prodml/core/ProdMLV2_0/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/prodml/core/ProdMLV2_0/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/prodml/core/ProdMLV2_0/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-57"]]],[{"t":"Str","c":"rsf"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-58"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-59"]]],[{"t":"Str","c":"RSFV1"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/rsf/core/RSFV1/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-60"]]],[{"t":"Str","c":"segy"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/segy/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-61"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-62"]]],[{"t":"Str","c":"SegyV2"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/segy/core/SegyV2/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/segy/core/SegyV2/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/segy/core/SegyV2/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-63"]]],[{"t":"Str","c":"sentek"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/sentek/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-64"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-65"]]],[{"t":"Str","c":"SentekV5"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/sentek/core/SentekV5/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/sentek/core/SentekV5/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/sentek/core/SentekV5/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-66"]]],[{"t":"Str","c":"tdms"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-67"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-68"]]],[{"t":"Str","c":"TDMSFormatterV4713"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/core/TDMSFormatterV4713/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/core/TDMSFormatterV4713/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/core/TDMSFormatterV4713/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-69"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/utils/parse_time_stamp.html"]]],[{"t":"Str","c":"parse_time_stamp"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/tdms/utils/type_not_supported.html"]]],[{"t":"Str","c":"type_not_supported"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-70"]]],[{"t":"Str","c":"terra15"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/utils.html"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-71"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/core/Terra15FormatterV5.html"]]],[{"t":"Str","c":"Terra15FormatterV5"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/core/Terra15FormatterV6.html"]]],[{"t":"Str","c":"Terra15FormatterV6"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-72"]]],[{"t":"Str","c":"Terra15FormatterV4"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/core/Terra15FormatterV4/get_format.html"]]],[{"t":"Str","c":"get_format"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/core/Terra15FormatterV4/read.html"]]],[{"t":"Str","c":"read"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/terra15/core/Terra15FormatterV4/scan.html"]]],[{"t":"Str","c":"scan"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-73"]]],[{"t":"Str","c":"wav"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-74"]]],[{"t":"Str","c":"core"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-75"]]],[{"t":"Str","c":"WavIO"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/io/wav/core/WavIO/write.html"]]],[{"t":"Str","c":"write"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-76"]]],[{"t":"Str","c":"proc"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-77"]]],[{"t":"Str","c":"aggregate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/aggregate/aggregate.html"]]],[{"t":"Str","c":"aggregate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-78"]]],[{"t":"Str","c":"basic"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/abs.html"]]],[{"t":"Str","c":"abs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/angle.html"]]],[{"t":"Str","c":"angle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/apply_operator.html"]]],[{"t":"Str","c":"apply_operator"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/dropna.html"]]],[{"t":"Str","c":"dropna"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/equals.html"]]],[{"t":"Str","c":"equals"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/imag.html"]]],[{"t":"Str","c":"imag"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/normalize.html"]]],[{"t":"Str","c":"normalize"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/pad.html"]]],[{"t":"Str","c":"pad"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/pipe.html"]]],[{"t":"Str","c":"pipe"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/real.html"]]],[{"t":"Str","c":"real"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/set_dims.html"]]],[{"t":"Str","c":"set_dims"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/squeeze.html"]]],[{"t":"Str","c":"squeeze"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/standardize.html"]]],[{"t":"Str","c":"standardize"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/transpose.html"]]],[{"t":"Str","c":"transpose"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/update.html"]]],[{"t":"Str","c":"update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/basic/update_attrs.html"]]],[{"t":"Str","c":"update_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-79"]]],[{"t":"Str","c":"coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/coords/assert_has_coords.html"]]],[{"t":"Str","c":"assert_has_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/coords/coords_from_df.html"]]],[{"t":"Str","c":"coords_from_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/coords/drop_coords.html"]]],[{"t":"Str","c":"drop_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/coords/get_coord.html"]]],[{"t":"Str","c":"get_coord"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/coords/rename_coords.html"]]],[{"t":"Str","c":"rename_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/coords/snap_coords.html"]]],[{"t":"Str","c":"snap_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/coords/sort_coords.html"]]],[{"t":"Str","c":"sort_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/coords/update_coords.html"]]],[{"t":"Str","c":"update_coords"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-80"]]],[{"t":"Str","c":"correlate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/correlate/correlate.html"]]],[{"t":"Str","c":"correlate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-81"]]],[{"t":"Str","c":"detrend"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/detrend/detrend.html"]]],[{"t":"Str","c":"detrend"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-82"]]],[{"t":"Str","c":"filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/filter/gaussian_filter.html"]]],[{"t":"Str","c":"gaussian_filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/filter/median_filter.html"]]],[{"t":"Str","c":"median_filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/filter/pass_filter.html"]]],[{"t":"Str","c":"pass_filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/filter/savgol_filter.html"]]],[{"t":"Str","c":"savgol_filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/filter/sobel_filter.html"]]],[{"t":"Str","c":"sobel_filter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-83"]]],[{"t":"Str","c":"resample"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/resample/decimate.html"]]],[{"t":"Str","c":"decimate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/resample/interpolate.html"]]],[{"t":"Str","c":"interpolate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/resample/resample.html"]]],[{"t":"Str","c":"resample"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-84"]]],[{"t":"Str","c":"rolling"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/rolling/rolling.html"]]],[{"t":"Str","c":"rolling"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-85"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/select/select.html"]]],[{"t":"Str","c":"select"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-86"]]],[{"t":"Str","c":"taper"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/taper/taper.html"]]],[{"t":"Str","c":"taper"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-87"]]],[{"t":"Str","c":"units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/units/convert_units.html"]]],[{"t":"Str","c":"convert_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/units/set_units.html"]]],[{"t":"Str","c":"set_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/units/simplify_units.html"]]],[{"t":"Str","c":"simplify_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-88"]]],[{"t":"Str","c":"whiten"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/proc/whiten/whiten.html"]]],[{"t":"Str","c":"whiten"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-89"]]],[{"t":"Str","c":"transform"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-90"]]],[{"t":"Str","c":"differentiate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/differentiate/differentiate.html"]]],[{"t":"Str","c":"differentiate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-91"]]],[{"t":"Str","c":"dispersion"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/dispersion/dispersion_phase_shift.html"]]],[{"t":"Str","c":"dispersion_phase_shift"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-92"]]],[{"t":"Str","c":"fft"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/fft/rfft.html"]]],[{"t":"Str","c":"rfft"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-93"]]],[{"t":"Str","c":"fourier"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/fourier/dft.html"]]],[{"t":"Str","c":"dft"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/fourier/idft.html"]]],[{"t":"Str","c":"idft"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-94"]]],[{"t":"Str","c":"integrate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/integrate/integrate.html"]]],[{"t":"Str","c":"integrate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-95"]]],[{"t":"Str","c":"spectro"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/spectro/spectrogram.html"]]],[{"t":"Str","c":"spectrogram"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-96"]]],[{"t":"Str","c":"strain"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/transform/strain/velocity_to_strain_rate.html"]]],[{"t":"Str","c":"velocity_to_strain_rate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-97"]]],[{"t":"Str","c":"units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/assert_dtype_compatible_with_units.html"]]],[{"t":"Str","c":"assert_dtype_compatible_with_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/convert_units.html"]]],[{"t":"Str","c":"convert_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/get_factor_and_unit.html"]]],[{"t":"Str","c":"get_factor_and_unit"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/get_filter_units.html"]]],[{"t":"Str","c":"get_filter_units"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/get_quantity.html"]]],[{"t":"Str","c":"get_quantity"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/get_quantity_str.html"]]],[{"t":"Str","c":"get_quantity_str"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/get_registry.html"]]],[{"t":"Str","c":"get_registry"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/get_unit.html"]]],[{"t":"Str","c":"get_unit"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/units/invert_quantity.html"]]],[{"t":"Str","c":"invert_quantity"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-98"]]],[{"t":"Str","c":"utils"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/plotting.html"]]],[{"t":"Str","c":"plotting"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-99"]]],[{"t":"Str","c":"chunk"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/chunk/get_intervals.html"]]],[{"t":"Str","c":"get_intervals"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-100"]]],[{"t":"Str","c":"ChunkManager"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/chunk/ChunkManager/chunk.html"]]],[{"t":"Str","c":"chunk"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/chunk/ChunkManager/get_instruction_df.html"]]],[{"t":"Str","c":"get_instruction_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-101"]]],[{"t":"Str","c":"display"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/display/array_to_text.html"]]],[{"t":"Str","c":"array_to_text"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/display/attrs_to_text.html"]]],[{"t":"Str","c":"attrs_to_text"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/display/get_dascore_text.html"]]],[{"t":"Str","c":"get_dascore_text"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/display/get_nice_text.html"]]],[{"t":"Str","c":"get_nice_text"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-102"]]],[{"t":"Str","c":"docs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/docs/compose_docstring.html"]]],[{"t":"Str","c":"compose_docstring"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/docs/format_dtypes.html"]]],[{"t":"Str","c":"format_dtypes"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/docs/objs_to_doc_df.html"]]],[{"t":"Str","c":"objs_to_doc_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-103"]]],[{"t":"Str","c":"downloader"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/downloader/fetch.html"]]],[{"t":"Str","c":"fetch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/downloader/get_registry_df.html"]]],[{"t":"Str","c":"get_registry_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-104"]]],[{"t":"Str","c":"hdf5"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/open_hdf5_file.html"]]],[{"t":"Str","c":"open_hdf5_file"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/unpack_scalar_h5_dataset.html"]]],[{"t":"Str","c":"unpack_scalar_h5_dataset"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-105"]]],[{"t":"Str","c":"H5Reader"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/H5Reader/get_handle.html"]]],[{"t":"Str","c":"get_handle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-106"]]],[{"t":"Str","c":"H5Writer"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/H5Writer/get_handle.html"]]],[{"t":"Str","c":"get_handle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-107"]]],[{"t":"Str","c":"HDF5Reader"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDF5Reader/get_handle.html"]]],[{"t":"Str","c":"get_handle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-108"]]],[{"t":"Str","c":"HDF5Writer"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDF5Writer/get_handle.html"]]],[{"t":"Str","c":"get_handle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-109"]]],[{"t":"Str","c":"HDFPatchIndexManager"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDFPatchIndexManager/decode_table.html"]]],[{"t":"Str","c":"decode_table"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDFPatchIndexManager/encode_table.html"]]],[{"t":"Str","c":"encode_table"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDFPatchIndexManager/get_index.html"]]],[{"t":"Str","c":"get_index"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDFPatchIndexManager/validate_version.html"]]],[{"t":"Str","c":"validate_version"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/hdf5/HDFPatchIndexManager/write_update.html"]]],[{"t":"Str","c":"write_update"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-110"]]],[{"t":"Str","c":"io"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/get_handle_from_resource.html"]]],[{"t":"Str","c":"get_handle_from_resource"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/obspy_to_patch.html"]]],[{"t":"Str","c":"obspy_to_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/patch_to_obspy.html"]]],[{"t":"Str","c":"patch_to_obspy"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/patch_to_xarray.html"]]],[{"t":"Str","c":"patch_to_xarray"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/xarray_to_patch.html"]]],[{"t":"Str","c":"xarray_to_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-111"]]],[{"t":"Str","c":"BinaryReader"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/BinaryReader/get_handle.html"]]],[{"t":"Str","c":"get_handle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-112"]]],[{"t":"Str","c":"BinaryWriter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/BinaryWriter/get_handle.html"]]],[{"t":"Str","c":"get_handle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-113"]]],[{"t":"Str","c":"IOResourceManager"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/IOResourceManager/close_all.html"]]],[{"t":"Str","c":"close_all"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/io/IOResourceManager/get_resource.html"]]],[{"t":"Str","c":"get_resource"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-114"]]],[{"t":"Str","c":"mapping"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-115"]]],[{"t":"Str","c":"FrozenDict"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/mapping/FrozenDict/copy.html"]]],[{"t":"Str","c":"copy"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-116"]]],[{"t":"Str","c":"misc"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/CacheDescriptor.html"]]],[{"t":"Str","c":"CacheDescriptor"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/MethodNameSpace.html"]]],[{"t":"Str","c":"MethodNameSpace"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/all_close.html"]]],[{"t":"Str","c":"all_close"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/all_diffs_close_enough.html"]]],[{"t":"Str","c":"all_diffs_close_enough"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/broadcast_for_index.html"]]],[{"t":"Str","c":"broadcast_for_index"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/cached_method.html"]]],[{"t":"Str","c":"cached_method"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/check_filter_kwargs.html"]]],[{"t":"Str","c":"check_filter_kwargs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/check_filter_range.html"]]],[{"t":"Str","c":"check_filter_range"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/get_middle_value.html"]]],[{"t":"Str","c":"get_middle_value"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/get_parent_code_name.html"]]],[{"t":"Str","c":"get_parent_code_name"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/get_stencil_coefs.html"]]],[{"t":"Str","c":"get_stencil_coefs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/is_valid_coord_str.html"]]],[{"t":"Str","c":"is_valid_coord_str"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/iter_files.html"]]],[{"t":"Str","c":"iter_files"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/iterate.html"]]],[{"t":"Str","c":"iterate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/maybe_get_attrs.html"]]],[{"t":"Str","c":"maybe_get_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/maybe_get_items.html"]]],[{"t":"Str","c":"maybe_get_items"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/optional_import.html"]]],[{"t":"Str","c":"optional_import"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/register_func.html"]]],[{"t":"Str","c":"register_func"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/sanitize_range_param.html"]]],[{"t":"Str","c":"sanitize_range_param"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/separate_coord_info.html"]]],[{"t":"Str","c":"separate_coord_info"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/suppress_warnings.html"]]],[{"t":"Str","c":"suppress_warnings"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/to_str.html"]]],[{"t":"Str","c":"to_str"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/unbyte.html"]]],[{"t":"Str","c":"unbyte"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/misc/warn_or_raise.html"]]],[{"t":"Str","c":"warn_or_raise"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-117"]]],[{"t":"Str","c":"models"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/models/sensible_model_equals.html"]]],[{"t":"Str","c":"sensible_model_equals"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-118"]]],[{"t":"Str","c":"DascoreBaseModel"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/models/DascoreBaseModel/get_summary_df.html"]]],[{"t":"Str","c":"get_summary_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/models/DascoreBaseModel/new.html"]]],[{"t":"Str","c":"new"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-119"]]],[{"t":"Str","c":"patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/check_patch_attrs.html"]]],[{"t":"Str","c":"check_patch_attrs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/check_patch_dims.html"]]],[{"t":"Str","c":"check_patch_dims"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/get_default_patch_name.html"]]],[{"t":"Str","c":"get_default_patch_name"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/get_dim_sampling_rate.html"]]],[{"t":"Str","c":"get_dim_sampling_rate"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/get_dim_value_from_kwargs.html"]]],[{"t":"Str","c":"get_dim_value_from_kwargs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/get_multiple_dim_value_from_kwargs.html"]]],[{"t":"Str","c":"get_multiple_dim_value_from_kwargs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/get_start_stop_step.html"]]],[{"t":"Str","c":"get_start_stop_step"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/merge_patches.html"]]],[{"t":"Str","c":"merge_patches"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/patch_function.html"]]],[{"t":"Str","c":"patch_function"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/patches_to_df.html"]]],[{"t":"Str","c":"patches_to_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/patch/scan_patches.html"]]],[{"t":"Str","c":"scan_patches"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-120"]]],[{"t":"Str","c":"pd"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/adjust_segments.html"]]],[{"t":"Str","c":"adjust_segments"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/dataframe_to_patch.html"]]],[{"t":"Str","c":"dataframe_to_patch"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/fill_defaults_from_pydantic.html"]]],[{"t":"Str","c":"fill_defaults_from_pydantic"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/filter_df.html"]]],[{"t":"Str","c":"filter_df"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/get_column_names_from_dim.html"]]],[{"t":"Str","c":"get_column_names_from_dim"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/get_dim_names_from_columns.html"]]],[{"t":"Str","c":"get_dim_names_from_columns"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/get_interval_columns.html"]]],[{"t":"Str","c":"get_interval_columns"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/get_regex.html"]]],[{"t":"Str","c":"get_regex"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/list_ser_to_str.html"]]],[{"t":"Str","c":"list_ser_to_str"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/patch_to_dataframe.html"]]],[{"t":"Str","c":"patch_to_dataframe"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/split_df_query.html"]]],[{"t":"Str","c":"split_df_query"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/pd/yield_range_tuple_from_kwargs.html"]]],[{"t":"Str","c":"yield_range_tuple_from_kwargs"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-121"]]],[{"t":"Str","c":"progress"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/progress/get_progress_instance.html"]]],[{"t":"Str","c":"get_progress_instance"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/progress/track.html"]]],[{"t":"Str","c":"track"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-122"]]],[{"t":"Str","c":"time"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/dtype_time_like.html"]]],[{"t":"Str","c":"dtype_time_like"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/get_max_min_times.html"]]],[{"t":"Str","c":"get_max_min_times"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/is_datetime64.html"]]],[{"t":"Str","c":"is_datetime64"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/is_timedelta64.html"]]],[{"t":"Str","c":"is_timedelta64"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/to_datetime64.html"]]],[{"t":"Str","c":"to_datetime64"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/to_float.html"]]],[{"t":"Str","c":"to_float"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/to_int.html"]]],[{"t":"Str","c":"to_int"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/time/to_timedelta64.html"]]],[{"t":"Str","c":"to_timedelta64"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-123"]]],[{"t":"Str","c":"transformatter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/transformatter/FourierTransformatter.html"]]],[{"t":"Str","c":"FourierTransformatter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-124"]]],[{"t":"Str","c":"BaseTransformatter"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/utils/transformatter/BaseTransformatter/rename_dims.html"]]],[{"t":"Str","c":"rename_dims"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-125"]]],[{"t":"Str","c":"viz"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/viz/VizPatchNameSpace.html"]]],[{"t":"Str","c":"VizPatchNameSpace"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-126"]]],[{"t":"Str","c":"spectrogram"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/viz/spectrogram/spectrogram.html"]]],[{"t":"Str","c":"spectrogram"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-127"]]],[{"t":"Str","c":"waterfall"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/viz/waterfall/waterfall.html"]]],[{"t":"Str","c":"waterfall"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:quarto-sidebar-section-128"]]],[{"t":"Str","c":"wiggle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-sidebar:/api/dascore/viz/wiggle/wiggle.html"]]],[{"t":"Str","c":"wiggle"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Introduction"]]],[{"t":"Str","c":"Introduction"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:/index.html"]]],[{"t":"Str","c":"/index.html"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Tutorial"]]],[{"t":"Str","c":"Tutorial"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:/tutorial/concepts.html"]]],[{"t":"Str","c":"/tutorial/concepts.html"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Recipes"]]],[{"t":"Str","c":"Recipes"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:/recipes/overview.html"]]],[{"t":"Str","c":"/recipes/overview.html"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Notes"]]],[{"t":"Str","c":"Notes"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:/notes/notes.html"]]],[{"t":"Str","c":"/notes/notes.html"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:Contributing"]]],[{"t":"Str","c":"Contributing"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:/contributing/contributing.html"]]],[{"t":"Str","c":"/contributing/contributing.html"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:API"]]],[{"t":"Str","c":"API"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:/api/dascore.html"]]],[{"t":"Str","c":"/api/dascore.html"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-int-navbar:https://github.com/dasdae/dascore"]]],[{"t":"Str","c":"https://github.com/dasdae/dascore"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-breadcrumbs-ca7f8cd10a5c633b30bcc55700c7d9a8"]]],[{"t":"Str","c":"dascore"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-breadcrumbs-d825c53d89d9cacb3e034bcb138f3d37"]]],[{"t":"Str","c":"transform"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-breadcrumbs-4e4aaf3fee165531347b772f66b4f30c"]]],[{"t":"Str","c":"integrate"}]]}]}]]},{"t":"Div","c":[["quarto-meta-markdown",["hidden"],[]],[{"t":"Para","c":[{"t":"Span","c":[["",["hidden"],[["render-id","quarto-twittercardtitle"]]],[]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-ogcardtitle"]]],[]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-metasitename"]]],[{"t":"Str","c":"DASCore"},{"t":"Space"},{"t":"Str","c":"(0.1.1.dev2)"}]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-twittercarddesc"]]],[]]},{"t":"SoftBreak"},{"t":"Span","c":[["",["hidden"],[["render-id","quarto-ogcardddesc"]]],[]]}]}]]}]} diff --git a/docs/index.css b/docs/index.css deleted file mode 100644 index a1ae93c41..000000000 --- a/docs/index.css +++ /dev/null @@ -1,233 +0,0 @@ - -.content-block { - padding-top: 20px; - padding-bottom: 10px; - margin-left: 30px; - margin-right: 30px; - } - - - @media(min-width: 900px) { - .content-block { - margin-left: 50px; - margin-right: 50px; - } - } - - @media (min-width: 1200px) { - .content-block { - max-width: 1100px; - margin-left: auto; - margin-right: auto; - } - } - - .hero-banner { - position: relative; - background-color: rgb(237,243,249); - display: flex; - justify-content: center; - } - - .hero-banner h1 { - color: #39729E; - font-size: 2.5rem; - } - - - .hero-banner .hero-image { - position: absolute; - display: none; - height: auto; - } - - @media (min-width: 1000px) { - .hero-banner .hero-image { - display: initial; - width: 270px; - } - } - - @media (min-width: 1200px) { - .hero-banner .hero-image { - width: 340px; - } - } - - @media (min-width: 1400px) { - .hero-banner .hero-image { - width: 440px; - } - } - - .hero-banner .hero-image p { - margin-bottom: 0; - } - - .hero-banner .hero-image-left { - left: 0; - bottom: 0; - } - - .hero-banner .hero-image-right { - right: 0; - bottom: 0; - } - - - .hero-banner .content-block { - max-width: 600px; - z-index: 2; - } - - .hero-banner a { - text-decoration: none; - } - - .hero-banner h3 { - margin-top: 1.3rem; - margin-bottom: 1.3rem; - } - - .hero-banner h4 { - margin-top: 0; - } - - .hero-banner a[role="button"] { - margin-right: 17px; - margin-top: 0.6rem; - margin-bottom: 1.6rem; - } - - - .hero-banner #btn-guide { - background-color: #959595 !important; - border: none; - } - - - - - .hero-banner ul { - padding-inline-start: 21px; - font-size: 1.1rem; - } - - .hero-banner ul li { - padding-bottom: 0.4rem; - } - - - .alt-background { - background-color: rgb(247,249,251); - border-top: 1px solid #dee2e6; - border-bottom: 1px solid #dee2e6; - } - - .hello-quarto { - padding-bottom: 1rem; - } - - @media (min-width: 600px) { - .hello-quarto-banner { - display: inline-flex; - align-content: center; - justify-content: center; - } - - .hello-quarto-banner h1 { - margin-right: 40px; - } - - .hello-quarto-banner ul { - - } - } - - .hello-quarto-banner .nav-pills .nav-link.active, .nav-pills .show>.nav-link { - border: none; - border-bottom: 2px solid #39729E !important; - color: #39729E; - background-color: transparent; - - } - - .hello-quarto-banner .nav-pills button { - width: 125px; - } - - .hello-quarto .tab-content { - border: none; - padding: 0; - color: rgb(84, 85, 85); - } - - .hello-quarto .tab-content p { - font-size: 1.1em; - margin-bottom: 1.5em; - } - - .hello-quarto div.sourceCode { - background-color: white; - border: 1px solid #dee2e6; - } - - .hello-output { - background-color: white; - border: 1px solid #dee2e6; - max-height: 660px; - } - - .features { - padding-bottom: 2em; - } - - .feature { - margin-top: 20px; - } - - @media (min-width: 800px) { - .features { - display: flex; - flex-direction: row; - flex-wrap: wrap; - margin: 0 0 0 -30px; - width: calc(100% + 30px); - } - .feature { - width: calc(33% - 30px); - margin: 20px 0 0 30px; - } - } - - .feature h3 { - margin-top: 0; - } - - .feature p:first-of-type { - margin-bottom: 0.2rem; - color: rgb(84, 85, 85); - } - - .get-started { - text-align: center; - padding-bottom: 2rem; - } - - .get-started h3 { - margin-top: 1rem; - margin-bottom: 2rem; - } - - nav.page-navigation { - display: none; - } - - .nav-footer { - border-top: none !important; - } - - .nav-pills .nav-link.active, .nav-pills .show>.nav-link { - color: #fff; - background-color: #ff7518; - } diff --git a/docs/index.qmd b/docs/index.qmd deleted file mode 100644 index bc6dea07c..000000000 --- a/docs/index.qmd +++ /dev/null @@ -1,129 +0,0 @@ ---- -execute: - warning: false ---- - -{{< include ../readme.md >}} - -:::{.callout minimal="true"} -Version-specific documentation builds are attached to the [release pages](https://github.com/DASDAE/dascore/releases). -::: - -# Highlights - -DASCore is a Python library for distributed acoustic sensing (DAS). It provides: - -1. IO support for [many DAS data formats](supported_formats.qmd) -2. Common processing routines -3. Basic visualizations -4. Plugin support for [known third-party namespaces](supported_plugins.qmd) - -:::{.callout-note} -DASCore is part of the [DAS Data Analysis Ecosystem (DASDAE)](https://dasdae.org). -::: - -# Introductory usage - -## Read a file - -```{python} -import dascore as dc -# Import fetch to read DASCore example files -from dascore.utils.downloader import fetch - -# Fetch a sample file path from DASCore -file_path = fetch('terra15_das_1_trimmed.hdf5') -# To read DAS data stored locally on your machine, simply replace the above line with: -# file_path = "/path/to/data/directory/data.EXT" - -spool = dc.spool(file_path) -patch = spool[0] -``` - -## Working with a directory of DAS files - -```{python} -#| output: false -import dascore as dc - -# Write example DAS files to a local directory just to get a usable path. -# To read a directory of DAS data stored on your machine, -# simply replace the line below with: -# directory_path = "/path/to/data/directory/" -directory_path = dc.examples.spool_to_directory(dc.get_example_spool()) - -spool = ( - # Create a spool to interact with directory data - dc.spool(directory_path) - # Index the directory contents - .update() - # Sub-select a specific time range - .select(time=('2020-01-01', ...)) - # Specify chunk of the output patches - .chunk(time=2, overlap=0.5) -) -``` - -## Get patches (array w/ metadata) - -```{python} -import dascore as dc - -spool = dc.get_example_spool('diverse_das') - -# Spools are like lists, you can get patches through iteration -for patch in spool: - ... - -# or through indexing -patch = spool[0] -``` - -## Perform processing - -```{python} -import dascore as dc - -patch = dc.get_example_patch('random_das') - -out = ( - # Decimate along time axis (keep every 8th sample) - patch.decimate(time=8) - # Detrend along the distance dimension - .detrend(dim='distance') - # Apply 10Hz low-pass filter along time dimension - .pass_filter(time=(..., 10)) -) -``` - -## Visualize - -```{python} -import dascore as dc - -patch = dc.get_example_patch('example_event_2') - -patch.viz.waterfall(show=True); -``` - -# Installation - -Use pip or conda to install DASCore: - -```bash -pip install dascore -``` - -```bash -conda install dascore -c conda-forge -``` - -See [this recipe](recipes/docker_basic.qmd) for installation with Docker. - -See the [contributing docs](contributing/contributing.qmd) for development installations. - -# Feedback and Support - -Use the [project discussions](https://github.com/DASDAE/dascore/discussions) to ask a question. - -Use the [project issues](https://github.com/DASDAE/dascore/issues) to report an issue. diff --git a/docs/styles.css b/docs/styles.css deleted file mode 100644 index a26f8cde8..000000000 --- a/docs/styles.css +++ /dev/null @@ -1,78 +0,0 @@ -/* css styles */ - -body { - font-size: 18px; -} - -table { - border-collapse: collapse; - border: 2px solid rgb(200, 200, 200); - letter-spacing: 1px; - font-size: 0.8rem; - display: table; - width: 100%; - padding-bottom: 4px; -} - -caption { - padding: 10px; - caption-side: top; - color: #666; - text-align: center; - letter-spacing: 1px; - font-size: small; -} - -td { - border: 0.5px solid rgb(190, 190, 190); - padding: 10px 20px; - text-align: left; - vertical-align: middle; - /*white-space: pre;*/ -} - -/*Try not to let first column wrap.*/ -td:first-child { - white-space: nowrap; -} - -th { - border: 0.5px solid rgb(190, 190, 190); - padding: 10px 20px; - text-align: center; -} - - -/*This makes every other row striped. */ -tbody tr:nth-child(odd) { - background-color: rgba(210, 209, 209, 0.35); -} - - -/* Custom classes */ - -.padded_bottom_10pt { - padding-bottom: 10pt; -} - -.def_block { - background-color: rgba(210, 209, 209, 0.3); - margin: 1em; - box-sizing: content-box; - padding-left: 10px; - padding-right: 10px; - border-radius: 25px; - padding-bottom: 0px; - padding-top: 2px; -} - -.origin_table { - border: 0em; - width: 100%; - margin: 0; - font-size: 1em; - border-style: hidden !important; - font-family: 'Bree Serif', serif; - display: block; - margin-bottom: 10px; -} diff --git a/great-docs.yml b/great-docs.yml index f561cebf6..9d4bce86e 100644 --- a/great-docs.yml +++ b/great-docs.yml @@ -1,9 +1,9 @@ # Great Docs Configuration for DASCore # See https://posit-dev.github.io/great-docs/user-guide/configuration.html # -# This replaces the previous custom doc build (scripts/build_api_docs.py, -# scripts/_index_api.py, scripts/_render_api.py, scripts/_qmd_builder.py, -# scripts/_validate_links.py, and docs/filters/fill_links.py). +# `great-docs build` renders the whole site: the narrative sections below, +# the API reference generated from docstrings, and the agent-facing outputs +# (llms.txt, per-page markdown, .well-known/agent-skills). display_name: DASCore @@ -36,7 +36,7 @@ pre_render: # Site styling. `yeti` is the Bootswatch theme the previous doc build used, so # fonts, colors and spacing carry over unchanged; great-docs.scss is listed # explicitly (great-docs appends it otherwise) so assets/dascore.scss can layer -# on top of it. That last file replaces docs/styles.css. +# on top of it. That file carries the old site's custom CSS. site: theme: - yeti diff --git a/notes/notes.qmd b/notes/notes.qmd deleted file mode 100644 index a635f226b..000000000 --- a/notes/notes.qmd +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Notes -description: "Understanding-oriented explanations of DASCore's design and implementation." ---- - -This section provides understanding-oriented explanations of DASCore implementation and design decisions. - -- [Coordinate Internals](coordinate_internals.qmd) explains coordinate families, segmented coordinates, summary envelopes, and exact scan payloads. -- [PatchAttrs](patch_attrs.qmd) explains non-coordinate metadata boundaries and `data_type` policy. -- [Documentation Strategy](doc_strategy.qmd) -- [Fourier Transforms](dft_notes.qmd) -- [Velocity to Strain Rate](velocity_to_strain_rate.qmd) -- [Spool Index](spool_index.qmd) -- [Spool Selection](spool_selection.qmd) -- [Spool Chunking](spool_chunking.qmd) diff --git a/pyproject.toml b/pyproject.toml index e9ce5a14d..751039f0b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,7 +73,6 @@ extras = [ ] docs = [ - "jinja2", "ipywidgets", "tabulate", # Quarto executes the {python} cells in docs/**.qmd through jupyter, so @@ -247,6 +246,9 @@ convention = "numpy" # F401: a notebook often imports a name only used inside an IPython magic, # which ruff cannot see, and its autofix would delete the import. "*.ipynb" = ["D103", "F401"] +# The doc-build hooks report progress on stdout (T201), and import dascore +# only after re-execing with the environment it is installed in (PLC0415). +"scripts/greatdocs_*.py" = ["T201", "PLC0415"] [tool.pytest.ini_options] norecursedirs = [ diff --git a/recipes/contributing_to_documentation.qmd b/recipes/contributing_to_documentation.qmd index d7195d26a..df7de1127 100644 --- a/recipes/contributing_to_documentation.qmd +++ b/recipes/contributing_to_documentation.qmd @@ -7,9 +7,9 @@ Here, we elaborate on how you can build new documentation or make changes to exi ## Building/Editing documentation -First, install the [Quarto](https://quarto.org/docs/get-started/) +The site is built by [great-docs](https://posit-dev.github.io/great-docs/), which renders the narrative pages and the API reference with [Quarto](https://quarto.org/docs/get-started/). -To ensure Quarto is installed properly and to get the installation version: +First, install Quarto. To ensure it is installed properly and to get the installation version: ```bash quarto --version @@ -21,25 +21,27 @@ If you have not already installed jupyter in your environment, install it using conda install jupyter ``` -Go to the DASCore directory on your machine: +Then install great-docs: ```bash -cd dascore +pip install "great-docs>=0.16" ``` -Then generate DASCore's API markdown files by running the following script: +Go to the DASCore directory on your machine and build the site: ```bash -python scripts/build_api_docs.py -``` - -```bash -quarto preview docs +cd dascore +great-docs build ``` :::{.note} -This will take a few minutes the first time you run it. After that, the results are cached and only the changed files are re-rendered. +This will take several minutes the first time you run it. After that, the results are cached and only the changed files are re-rendered. ::: -Now, you can make new documentation or make changes to the "index.qmd" file on the /dascore/docs/ directory and so on. -However, if you make changes to any of DASCore's docstring, you need to re-run the build_api_docs.py script for the changes to appear. +The built site lands in `great-docs/_site`. To read it in a browser: + +```bash +great-docs preview +``` + +Narrative pages live in the top-level section directories (`tutorial/`, `recipes/`, `notes/`, `contributing/`, `about/`), and `index.qmd` is the landing page. Adding a `.qmd` file to one of those directories adds a page to that section. The API reference is generated from DASCore's docstrings, so changing a docstring is enough to change the reference; which objects appear there, along with the site's structure and styling, is configured in `great-docs.yml`. diff --git a/recipes/overview.qmd b/recipes/overview.qmd deleted file mode 100644 index 30e56fe0f..000000000 --- a/recipes/overview.qmd +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "Overview" -description: "Start here: a cookbook of task-focused DASCore examples." ---- - -Welcome to DASCore's cookbook! This is a collection of examples (recipes) to demonstrate how to perform various tasks with DASCore. Use the collapsible menu in the sidebar to browse the recipes and consider [contributing](../contributing/contributing.qmd) some examples of your own. diff --git a/scripts/_index_api.py b/scripts/_index_api.py deleted file mode 100644 index 5e872db2b..000000000 --- a/scripts/_index_api.py +++ /dev/null @@ -1,267 +0,0 @@ -"""A script to create an index of the structure of the DASCore package.""" - -from __future__ import annotations - -import inspect -import os -from collections import defaultdict -from importlib import import_module -from pathlib import Path -from types import FunctionType, MethodType, ModuleType -from typing import Literal - - -def _unwrap_obj(obj): - """Unwrap a decorated object.""" - while getattr(obj, "__wrapped__", None) is not None: - obj = obj.__wrapped__ - return obj - - -def _get_file_path(obj): - """Try to get the file of a python object.""" - obj = _unwrap_obj(obj) - try: - path = inspect.getfile(obj) - except TypeError: - path = "" - return Path(path) - - -def _is_environment_path(path) -> bool: - """ - Return True if the path belongs to an environment nested in the project. - - Virtual environments (e.g. .venv) created inside the repository would - otherwise be traversed as if their contents were part of the project. - """ - excluded = {"site-packages", ".venv", "venv", ".pixi", ".tox", ".nox"} - return bool(excluded.intersection(Path(path).parts)) - - -def _get_base_address(path, base_path): - """ - Get the base address inherent in the path. - - For example, dascore/core/patch.py should return - - dascore.core.patch - """ - if _is_environment_path(path): - return "" - try: - out = Path(path).relative_to(Path(base_path)) - except ValueError: - return "" - new = str(out).replace("/__init__.py", "").replace(".py", "") - return new.replace("/", ".") - - -def _get_address(obj, rel_path): - """Get the address for an object.""" - base_list = ( - str(rel_path) - .replace(f"{os.sep}__init__.py", "") - .replace(".py", "") - .split(os.sep) - ) - if not isinstance(obj, ModuleType) and hasattr(obj, "__name__"): - name_list = [obj.__name__] - else: - name_list = [] - return ".".join(base_list + name_list) - - -def _yield_get_submodules(obj, base_path): - """Dynamically load submodules that may not have been imported.""" - path = Path(inspect.getfile(obj)) - if not isinstance(obj, ModuleType) or path.name != "__init__.py": - return - submodules = path.parent.glob("*") - for submod_path in submodules: - is_dir = submod_path.is_dir() - is_init = submod_path.name.endswith("__init__.py") - # this is a directory, look for corresponding __init__.py - if is_dir and (submod_path / "__init__.py").exists(): - mod_name = str(submod_path.relative_to(base_path)).replace(os.sep, ".") - mod = import_module(mod_name) - yield mod_name, mod - elif submod_path.name.endswith(".py") and not is_init: - mod_name = ( - str(submod_path.relative_to(base_path)) - .replace(".py", "") - .replace(os.sep, ".") - ) - mod = import_module(mod_name) - yield mod_name, mod - - -def parse_project(obj, key=None): - """Parse the project create dict of data and data_type.""" - - def get_type( - obj, parent_is_class=False - ) -> Literal["module", "function", "method", "class"] | None: - """Return a string of the type of object.""" - obj = _unwrap_obj(obj) - if isinstance(obj, ModuleType): - return "module" - elif isinstance(obj, MethodType): - return "method" - elif isinstance(obj, FunctionType): - # since this is a class not instance we need this check. - if parent_is_class: - return "method" - else: - return "function" - elif isinstance(obj, type): - return "class" - return None - - def extract_data(obj, parent_is_class): - """ - Make lists of attributes, methods, etc. - - These can be feed to render templates. - """ - try: - sig = inspect.signature(obj) - except (TypeError, ValueError): - sig = None - - docstr = inspect.getdoc(obj) or "" - dtype = get_type(obj, parent_is_class) - data = defaultdict(list) - data["docstring"] = docstr - data["signature"] = sig - data["data_type"] = dtype - data["short_description"] = docstr.split("\n")[0] - data["object"] = obj - # get sub-modules, methods, functions, etc. (just one level deep) - - subs = list(inspect.getmembers(obj)) + list( - _yield_get_submodules(obj, base_path) - ) - for name, sub_obj in subs: - if name.startswith("_"): - continue - sub_obj = _unwrap_obj(sub_obj) - sub_dtype = get_type(sub_obj, dtype == "class") - # for modules, skip entities that aren't children - if dtype == "module": - path, sub_path = _get_file_path(obj), _get_file_path(sub_obj) - if str(path).replace("/__init__.py", "") not in str(sub_path): - continue - data[sub_dtype].append(str(id(sub_obj))) - - return data - - def get_data(obj, key, base_path, parent_is_class): - """Get data from object.""" - path = inspect.getfile(obj) - base_address = _get_base_address(path, base_path) - data = extract_data(obj, parent_is_class) - data["base_path"] = Path(base_path) - data["path"] = Path(path) - data["key"] = key - data["name"] = key.split(".")[-1] - data["base_address"] = base_address - return data - - def traverse(obj, data_dict, base_path, key=None, parent_is_class=False): - """Traverse tree, populate data_dict.""" - obj = _unwrap_obj(obj) - obj_id = str(id(obj)) - path = _get_file_path(obj) - - # this is something outside of dascore or we have already seen it. - if str(base_path) not in str(path) or obj_id in data_dict: - return - # skip contents of environments (e.g. .venv) nested in the project. - if _is_environment_path(path): - return - # load all the modules first - if isinstance(obj, ModuleType): - key = _get_address(obj, path.relative_to(base_path)) - data_dict[obj_id] = get_data(obj, key, base_path, parent_is_class) - for _, mod in _yield_get_submodules(obj, base_path): - traverse(mod, data_dict, base_path) - for name, obj in inspect.getmembers(obj): - # skip private members; we don't document them. - if name.startswith("_"): - continue - # recurse non-private methods - traverse(obj, data_dict, base_path, f"{key}.{name}", False) - # then handle non-modules - else: - path = inspect.getfile(obj) - base_address = _get_base_address(path, base_path) - - # this is referenced outside of its base address, skip this one. - # A prefix test rather than a substring one: the address of - # dascore/core/inventory.py is a substring of every key under - # dascore/core/inventory_loader.py, so a module named after - # another would claim as its own everything it merely imports. - if key != base_address and not key.startswith(f"{base_address}."): - return - - data_dict[str(id(obj))] = get_data(obj, key, base_path, parent_is_class) - # recurse attributes and methods of classes - if inspect.isclass(obj): - for sub_name, sub_obj in inspect.getmembers(obj): - if sub_name.startswith("_") or not callable(sub_obj): - continue - sub_path = _get_file_path(sub_obj) - if str(base_path) not in str(sub_path): - continue - if _is_environment_path(sub_path): - continue - sub_key = f"{key}.{sub_name}" - # make sure this is where the method is defined else skip - if str(sub_path) != str(path): - continue - traverse(sub_obj, data_dict, base_path, sub_key, True) - - base_path = Path(_get_file_path(obj)).parent.parent - data_dict = {} - traverse(obj, data_dict, base_path) - - return data_dict - - -def get_alias_mapping(module, key=None): - """Return a dict of {object_path: id} to construct cross refs.""" - - def traverse_simple(obj, key, data_dict, base_path, allow_base=False): - """Traverse the tree and write out markdown.""" - obj = _unwrap_obj(obj) - obj_id = str(id(obj)) - path = _get_file_path(obj) - # don't let base module be re-indexed - if obj is base_mod and not allow_base: - return - # skip things outside of this module - if not _get_base_address(path, base_path): - return - # need to ensure all sub-modules are loaded. - if isinstance(obj, ModuleType): - for _, mod in _yield_get_submodules(obj, base_path): - attach_name = f"{mod.__name__.split('.')[-1]}" - setattr(obj, attach_name, mod) - - data_dict[key] = obj_id - for member_name, member in inspect.getmembers(obj): - if member_name.startswith("_"): - continue - new_key = ".".join([key, member_name]) - if f".{new_key.split('.')[-1]}" in key: - continue - traverse_simple(member, new_key, data_dict, base_path) - - data_dict = {} - key = key or getattr(module, "__name__", None) - base_path = Path(_get_file_path(module)).parent.parent - # define base module and base key to not allow recursion through them. - base_mod = module - traverse_simple(module, key, data_dict, base_path, allow_base=True) - return data_dict diff --git a/scripts/_qmd_builder.py b/scripts/_qmd_builder.py deleted file mode 100644 index 6695dfbf6..000000000 --- a/scripts/_qmd_builder.py +++ /dev/null @@ -1,103 +0,0 @@ -"""A script to build quartos main config file.""" - -from __future__ import annotations - -import os -from pathlib import Path - -from _render_api import get_template - -import dascore as dc - -API_PATH = Path(__file__).absolute().parent.parent / "docs" / "api" - -# separation for each level of toc tree -LEVEL_SEP = " " - - -def _build_content_string(path, api_path): - """Build a content string.""" - out = [ - f"- text: {path.with_suffix('').name}", - f" href: {path.relative_to(api_path)}", - ] - return out - - -def _build_section_string(path, api_path): - """Build a string for entire sections.""" - out = [ - f"- section: {path.with_suffix('').name}", - f" href: {path.relative_to(api_path)}", - " contents:", - ] - return out - - -def _get_level(path, base_path): - """Get the level of directory nested for path from base_path.""" - level = len(str(path.relative_to(base_path)).split(os.sep)) - 1 - return level - - -def build_amp_toc_tree(api_path=API_PATH): - """Build the toc tree for the API.""" - # get all sub directories - base_path = api_path.parent - sub_dirs = sorted(x for x in api_path.rglob("*") if x.is_dir()) - sub_dir_set = set(sub_dirs) - out = [] - # iterate and make contents - for dir_path in sub_dirs: - # this is an un-cleaned up quarto dir from rendering - bad_endings = ["execute-results", "_files"] - bad_ending = any(dir_path.name.endswith(x) for x in bad_endings) - bad_p_ending = any(dir_path.parent.name.endswith(x) for x in bad_endings) - # the expected path of the qmd file related to this directory. - section_qmd = dir_path.with_suffix(".qmd") - if (bad_ending or bad_p_ending) and not section_qmd.exists(): - continue - assert section_qmd.exists() - level = _get_level(section_qmd, api_path) - # see how deep we are in toc tree for determine spaces needed - section_list = _build_section_string(section_qmd, base_path) - for val in section_list: - out.append(LEVEL_SEP * (level) + val) - # now go through contents - contents = sorted( - x for x in dir_path.glob("*.qmd") if x.with_suffix("") not in sub_dir_set - ) - for content in contents: - content_list = _build_content_string(content, base_path) - for val in content_list: - out.append(LEVEL_SEP * (level + 1) + val) - return out - - -def _get_dascore_title(): - """Get the DASCore title with the docs version.""" - doc_version = os.environ.get("DASCORE_DOC_VERSION") - if doc_version is not None: - vstr = doc_version - else: - version_str = str(dc.__version__) - if "dev" not in version_str: - vstr = version_str - else: - vstr = version_str.split("+")[0] - return f"DASCore ({vstr})" - - -def create_quarto_qmd(): - """Create the _quarto.yml file.""" - temp = get_template("_quarto.yml") - version_str = _get_dascore_title() - api_toc_tree = build_amp_toc_tree() - out = temp.render(dascore_version_str=version_str, api_toc_tree=api_toc_tree) - path = Path(__file__).parent.parent / "docs" / "_quarto.yml" - with path.open("w") as fi: - fi.write(out) - - -if __name__ == "__main__": - create_quarto_qmd() diff --git a/scripts/_render_api.py b/scripts/_render_api.py deleted file mode 100644 index 3f7b9a246..000000000 --- a/scripts/_render_api.py +++ /dev/null @@ -1,639 +0,0 @@ -"""Create the html tables for parameters and such from dataframes.""" - -from __future__ import annotations - -import hashlib -import inspect -import json -import os -import typing -from collections import defaultdict -from functools import cache -from itertools import pairwise -from pathlib import Path - -import pandas as pd -from jinja2 import Environment, FileSystemLoader - -RENDER_FUNCS = {} -DOC_PATH = Path(__file__).absolute().parent.parent / "docs" -API_DOC_PATH = DOC_PATH / "api" -API_DOC_PATH.mkdir(exist_ok=True, parents=True) -TEMPLATE_PATH = DOC_PATH / "_templates" -GITHUB_PATH = "https://github.com" -GITHUB_REPOSITORY = "DASDAE/dascore" -GITHUB_REF = "/master" - - -@cache -def get_env(): - """Get the template environment.""" - template_path = Path(__file__).absolute().parent / "_templates" - env = Environment(loader=FileSystemLoader(template_path)) - return env - - -@cache -def get_template(name): - """Get the template for rendering tables.""" - env = get_env() - template = env.get_template(name) - return template - - -def _simple_plural(text): - """Return plural form of string.""" - if text.endswith("s"): - return text + "es" - return text + "s" - - -def sha_256(path_or_str: Path | str) -> str: - """Get the Sha256 hash of a file or a string.""" - if isinstance(path_or_str, Path) and Path(path_or_str).exists(): - with open(path_or_str) as fi: - path_or_str = fi.read() - return hashlib.sha256(str(path_or_str).encode("utf-8")).hexdigest() - - -def build_table(df: pd.DataFrame, caption=None): - """An opinionated function to make a dataframe into html table.""" - df = df.drop_duplicates() - template = get_template("table.html") - columns = [x.capitalize() for x in df.columns] - rows = df.to_records(index=False).tolist() - out = template.render(columns=columns, rows=rows, caption=caption) - return out - - -def is_it_subclass(obj, cls): - """A more intelligent issubclass that doesn't through TypeErrors.""" - try: - return issubclass(obj, cls) - except TypeError: - return False - - -def _deduplicate_list(seq): - """Return a list with duplicate removed, preserves order.""" - seen = set() - return [x for x in seq if not (x in seen or seen.add(x))] - - -def unpact_annotation(obj, data_dict, address_dict) -> str: - """Convert an annotation to string with linking.""" - str_id = str(id(obj)) - str_rep = str(obj) - # this is a basic type, just get its name. - if is_it_subclass(obj, (str, int, float)): - out = str_rep.replace("", "").replace("'", "") - # this is a forward ref, strip out name and hope for the best ;) - elif isinstance(obj, typing.ForwardRef): - # todo: this needs to be more generic, but forward refs are hard! - # just assume the bound string is resolvable - key = str(obj).split("('")[-1].replace("')", "") - name = key.split(".")[-1] - # dc. is the same as dascore. - if key.startswith("dc."): - key = f"dascore.{key[3:]}" - return f"[{name}](`{key}`)" - # Array-like thing from numpy #TODO improve this - elif "numpy.typing" in str_rep: - return "ArrayLike" - # this is a union, unpack it - elif str_rep.startswith("typing.Union") or str_rep.startswith("typing.Optional"): - annos = [unpact_annotation(x, data_dict, address_dict) for x in obj.__args__] - out = " | ".join(_deduplicate_list(annos)) - # This is a Dict, List, Tuple, etc. Just unpack. - elif hasattr(obj, "__args__"): - name = str_rep.replace("typing.", "").split("[")[0] - sub = [unpact_annotation(x, data_dict, address_dict) for x in obj.__args__] - out = f"{name}[{', '.join(sub)}]" - # this is a typevar - elif hasattr(obj, "__bound__"): - out = unpact_annotation(obj.__bound__, data_dict, address_dict) - # this is a class in dascore - elif str_id in data_dict: - data = data_dict[str_id] - out = f"[{data['name']}](`{data['key']}`)" - # this is a typing type, like Any - elif str_rep.startswith("typing."): - out = str_rep.split("typing.")[-1] - # NoneType should just be None - elif is_it_subclass(obj, type(None)): - out = "None" - # ... - elif obj is Ellipsis: - out = "..." - # generic class from another library - elif str_rep.startswith("", "") - # return a self type. - elif str_rep.endswith(".Self"): - out = "Self" - # probably a literal, just give up here - else: - if isinstance(obj, str): # make str look like str - out = f"'{obj!s}'" - else: - out = str(obj) - return out.strip() - - -def get_type_hints(obj) -> dict: - """ - Get an object's type hints, tolerating names missing at runtime. - - Annotations only imported under `TYPE_CHECKING` cannot be resolved when - the docs are built, so fall back to the unevaluated annotations rather - than failing the entire build. - - The fallback is all-or-nothing because `get_type_hints` resolves an - object's annotations together. Today only class-level annotations hit - it, and those are never matched against the parameters a signature is - built from, so nothing renders differently. - """ - try: - return typing.get_type_hints(obj) - except NameError: - return dict(inspect.get_annotations(obj)) - - -def build_signature(data, data_dict, address_dict): - """Return html of signature block.""" - sentinel = object() # to know missing values - - def get_annotation_str(param): - """Get string of annotation.""" - if not param: - return "" - annotation_str = unpact_annotation(param, data_dict, address_dict) - return f": {annotation_str}" - - def get_param_prefix(kind): - """Get the prefix for a parameter (eg ** in **kwargs).""" - if kind == inspect.Parameter.VAR_POSITIONAL: - return "*" - elif kind == inspect.Parameter.VAR_KEYWORD: - return "**" - return "" - - def get_default_value(param, sig): - """Get the default value for a parameter.""" - default = sig.parameters[param].default - if default is inspect._empty: - return sentinel - if default == "": - default = '""' - return str(default) - - def get_params(sig, annotations): - out = [] - for param, value in sig.parameters.items(): - prefix = get_param_prefix(value.kind) - annotation_str = get_annotation_str(annotations.get(param)) - return_str = get_default_value(param, sig) - param_str = f"{prefix + param}{annotation_str}\n" - if return_str is not sentinel: - param_str += f" = {return_str}" - out.append(param_str) - return out - - def get_return_line(sig): - annotation = sig.return_annotation - if annotation is inspect._empty: - return_str = ")" - else: - return_str = unpact_annotation(annotation, data_dict, address_dict) - return_str = f")-> {return_str}" - return return_str - - def get_sig_dict(data): - """Create a dict of render-able signature stuff.""" - sig = data["signature"] - annotations = get_type_hints(data["object"]) - out = dict( - params=get_params(sig, annotations), - return_line=get_return_line(sig), - name=data["name"], - ) - return out - - # no need to do anything if entity is not callable. - if not data["signature"]: - return "" - - template = get_template("signature.html") - sig_dict = get_sig_dict(data) - out = template.render(**sig_dict) - return out - - -class NumpyDocStrParser: - """Class which parses/process docstrings written in numpy style.""" - - heading_char = "##" - - def __init__(self, data): - self._data = data - - def parse_sections(self, docstr): - """Parse the sections of the docstring.""" - out = {} - doc_lines = docstr.split("\n") - dividers = ( - [0] - + [ - num - for num, x in enumerate(doc_lines) - if (set(x).issubset({" ", "-", "\t"}) and ("-" in x)) - ] - + [len(doc_lines) + 2] - ) - for start, stop in pairwise(dividers): - # determine header or just use 'pre' for txt before headings - header = "pre" if start == 0 else doc_lines[start - 1].strip() - # skips the ----- line where applicable - lstart = start if header == "pre" else start + 1 - out[header] = "\n".join(doc_lines[lstart : stop - 2]).strip() - return out - - def style_parameters(self, param_str): - """ - Style the parameters block. - """ - lines = param_str.split("\n") - # parameters don't have spaces at the start - param_start = [num for num, x in enumerate(lines) if not x.startswith(" ")] - param_start.append(len(lines)) - # parse parameters into (parameter): txt - param_desc = [] - for ind_num, ind in enumerate(param_start[:-1]): - key = lines[ind].strip() - # get the number of indents (usually 4) - in_char = (len(lines[1]) - len(lines[1].lstrip())) * " " - desc_lines = lines[ind + 1 : param_start[ind_num + 1]] - vals = [ - # strip out the first indentation line - (x[len(in_char) :] if x.startswith(in_char) and in_char else x) - for x in desc_lines - ] - # breakpoint() - param_desc.append((key, "
".join(vals))) - table = pd.DataFrame(param_desc, columns=["Parameter", "Description"]) - return build_table(table) - - def style_examples(self, example_str): - """ - Styles example blocks. - - Example blocks can be written in standard doc-test or quarto styles. - """ - return to_quarto_code(example_str) - - def style_notes(self, notes_str): - """Styles notes section of str.""" - template = get_template("notes.md") - return template.render(note_text=notes_str) - - def style_sections(self, raw_sections): - """Apply styling to sections.""" - out = dict(raw_sections) - lower2upper = {x.lower(): x for x in out} - overlap = set(lower2upper) & set(self.stylers) - for name in overlap: - upper_name = lower2upper[name] - out[upper_name] = self.stylers[name](self, out[upper_name]) - return out - - def __call__(self): - """Process the docstring.""" - sections_raw = self.parse_sections(self._data["docstring"]) - sections_styled = self.style_sections(sections_raw) - out = [] - for name, content in sections_styled.items(): - if name == "pre" or "note" in name.lower(): - out.append(content) - else: - out.append(f"\n{self.heading_char} {name}\n{content}") - return "\n".join(out) - - # stylers are used to decide which style function to apply for various - # sections. - stylers = { # noqa - "parameter": style_parameters, - "parameters": style_parameters, - # Numpydoc's section for arguments a function holds and forwards - # rather than reads; they are parameters and render as one. - "other parameters": style_parameters, - "attributes": style_parameters, - "examples": style_examples, - "example": style_examples, - "notes": style_notes, - "note": style_notes, - } - - -def to_quarto_code(code_lines): - """Class for parsing code (eg examples in docstrings) to quarto output.""" - option_chars = "#|" - - def _get_blocks(code_lines): - """Get code blocks. Code blocks are divided by titles "###".""" - code_blocks = defaultdict(list) - current_key = "" - for line in code_lines: - if line.startswith("###"): - current_key = line.replace("###", "").lstrip() - else: - code_blocks[current_key].append(line) - return code_blocks - - def _is_doctest_line(line): - strip = line.lstrip() - doc_str_line = strip.startswith(">>>") or strip.startswith("...") - return doc_str_line - - def _strip_code(code_str): - """Strip off spaces and the doctest stuff (..., >>>, etc).""" - out = [] - code_lines = code_str.splitlines() - # first determine if this is a docstring or not - is_docstring = False - for line in code_lines: - strip = line.lstrip() - if strip.startswith(">>>"): - is_docstring = True - # first determine how much to strip from each line. - start_index = 999 - for line in code_lines: - striped = line.lstrip().lstrip(">").lstrip(".").lstrip() - if not len(striped): - continue - if is_docstring and not _is_doctest_line(line): - continue - strip_len = len(line) - len(striped) - start_index = min([start_index, strip_len]) - # then do the stripping - for line in code_lines: - if (is_docstring and _is_doctest_line(line)) or not is_docstring: - out.append(line[start_index:]) - return out - - def _get_options(code_lines): - """Get all quarto options used.""" - options = [] - code_segments = [] - # first get min space to strip. - for line in code_lines: - if line.startswith(option_chars): - options.append(line) - # Strip out the python code specifier. - elif line.startswith("```{"): - continue - else: - code_segments.append(line) - return code_segments, options - - def _strip_blocks(code_blocks): - """Strip empty lines from start and end of list of codes.""" - while len(code_blocks) and not code_blocks[0].strip(): - code_blocks = code_blocks[1:] - while len(code_blocks) and not code_blocks[-1].strip(): - code_blocks = code_blocks[:-1] - return code_blocks - - def _to_quarto(options, blocks): - """Convert output to quarto string.""" - out = [] - for section_name, code_blocks in blocks.items(): - title = [] if not section_name else [f"### {section_name}"] - stripped_block = _strip_blocks(code_blocks) - if not stripped_block: - continue - new_code = [*title, "```{python}", *options, *stripped_block, "```"] - out.append("\n".join(new_code).lstrip()) - return "\n".join(out) - - code_lines_stripped = _strip_code(code_lines) - code_lines_no_options, options = _get_options(code_lines_stripped) - blocks = _get_blocks(code_lines_no_options) - out = _to_quarto(options, blocks) - return out - - -class Render: - """A class to render API docs for each entity.""" - - # The order in which to render the tables. - _table_order = ("parameter", "method", "attribute", "function", "class", "module") - - def __init__(self, data_dict, object_id, address_dict): - self._data_dict = data_dict - self._data = data_dict[object_id] - self._address_dict = address_dict - - def has_subsection(self, name): - """Return True if a module has a subsection.""" - possible_children = self._data.get(name, {}) - children = self.get_children_object_ids(possible_children) - return bool(children) - - def render_linked_table(self, name): - """Render a table for a specific name.""" - out = [] - for oid in self._data[name]: - if oid not in self._data_dict: - continue - sub_data = self._data_dict[oid] - linked_name = f"[{sub_data['name']}](`{sub_data['key']}`)" - desc = sub_data["short_description"] - out.append((linked_name, desc)) - df = pd.DataFrame(out, columns=["name", "description"]) - return build_table(df) - - def get_children_object_ids(self, ids): - """Of an object id list, return the children of the current object.""" - key = self._data["key"] - out = { - x for x in ids if x in self._data_dict and key in self._data_dict[x]["key"] - } - return out - - def _get_github_source(self, data): - """Get the github source url.""" - obj = data["object"] - source_code, line_start = inspect.getsourcelines(obj) - line_end = line_start + len(source_code) - rel_path = data["path"].relative_to(data["base_path"]) - # grab repo stuff from environment (on GH actions) or defaults - github_url = os.environ.get("GITHUB_SERVER_URL", GITHUB_PATH) - owner_repo = os.environ.get("GITHUB_REPOSITORY", GITHUB_REPOSITORY) - branch = os.environ.get("GITHUB_REF", GITHUB_REF).split("/")[-1] - source_url = ( - f"{github_url}/{owner_repo}/blob/{branch}/{rel_path!s}" - f"#L{line_start + 1}-L{line_end}" - ) - return source_url - - def _get_class_parent_string(self, data): - """Get the class parent string.""" - obj = data["object"] - parents = [x for x in obj.__mro__[1:-1]] - # this class only inherits from object (or type if metaclass) - if not len(parents): - return "" - parent_list = [] - for parent in parents: - name = parent.__name__ - key = str(id(parent)) - if parent_data := self._data_dict.get(key): - parent_str = f"[{name}](`{parent_data['key']}`)" - else: - parent_str = ( - str(parent).replace("", "").replace("'", "") - ) - parent_list.append(parent_str) - out = f"
inherits from: {', '.join(parent_list)} \n" - return out - - def _get_parent_source_block(self, data): - """Create a parent block with a link.""" - parent = data["key"].removesuffix(f".{data['name']}") - if parent: - parent_str = f" of [{parent}](`{parent}`)" - else: - parent_str = "" - origin_txt = f"*{self._data['data_type']}* {parent_str}" - source_url = self._get_github_source(data) - - if inspect.isclass(data["object"]): - # add class's ancestor(s) - origin_txt += self._get_class_parent_string(data) - - template = get_template("parent_source_block.html") - out = template.render(origin_txt=origin_txt, source_url=source_url) - return out - - def render_markdown(self, heading="##"): - """Convert numpy docstrings to markdown with some html styling.""" - data = self._data - docstr = NumpyDocStrParser(data) - - tables = [ - f"\n{heading} {_simple_plural(x).capitalize()}\n" - f"{self.render_linked_table(x)}\n" - for x in self._table_order - if self.has_subsection(x) - ] - signature = build_signature(data, self._data_dict, self._address_dict) - out = ( - f"# {self._data['name']}\n\n" - f"{self._get_parent_source_block(data)}\n\n" - f"{signature}\n" - f"{docstr()}\n" - f"{''.join(tables)}\n" - ) - return out - - -def create_json_mapping(data_dict, obj_dict, api_path): - """Create the mapping which links address to file path.""" - out = {} - - # add code paths - for obj_id, data in data_dict.items(): - sub_dir = api_path / "/".join(data["key"].split(".")[:-1]) - path = api_path / sub_dir / f"{data['name']}.qmd" - out[data["key"]] = f"/{path.relative_to(DOC_PATH)}" - - # add alias (eg import shortcuts/imports from other modules) - for alias in set(obj_dict) - set(out): - obj_id = obj_dict[alias] - if obj_id not in data_dict: - continue - main_key = data_dict[obj_id]["key"] - out[alias] = out[main_key] - return out - - -def write_api_markdown(data_dict, api_path, address_dict, debug=False): - """Write all the markdown to disk.""" - files_to_delete = set(Path(api_path).rglob("*.qmd")) - for obj_id, data in data_dict.items(): - # get path and ensure parents exist - sub_dir = api_path / "/".join(data["key"].split(".")[:-1]) - path = api_path / sub_dir / f"{data['name']}.qmd" - - path.parent.mkdir(exist_ok=True, parents=True) - # remove path from files to delete - if path in files_to_delete: - files_to_delete.remove(path) - # don't render non-target file if debugging - if debug and data["name"] != "read": - continue - # render and write - render = Render(data_dict, obj_id, address_dict) - markdown = render.render_markdown() - # check if file has changed, if not don't write - if path.exists() and sha_256(path) == sha_256(markdown): - continue - path.write_text(markdown) - # remove files that are no longer written. This can happen when the code is - # refactored or objects are deleted. - for path in files_to_delete: - path.unlink() - - -def _clear_empty_directories(parent_path): - """Recursively delete empty directories.""" - - def _dir_empty(path): - """Return True if directory is empty.""" - contents = ( - x - for x in path.rglob("*") - if not (x.name.startswith(".") and len(x.name) < 3) - ) - if any(contents): - return False - return True - - for path in parent_path.rglob("*"): - if not path.is_dir(): - continue - if _dir_empty(path): - os.rmdir(path) - - -def _map_other_qmd_files(doc_path=DOC_PATH, api_path=API_DOC_PATH): - """Add all other qmd files, excluding API.""" - out = {} - parent_doc = doc_path.parent - api_relative = str(api_path.relative_to(doc_path)) - for path in DOC_PATH.rglob("*.qmd"): - path_relative = str(path.relative_to(parent_doc)) - # Skip API docs - if path_relative.startswith(api_relative): - continue - value = "/" + str(path.relative_to(doc_path)) - out[path_relative] = value - # also add key with no qmd extension. - out[path_relative.split(".")[0]] = value - return out - - -def render_project(data_dict, address_dict, api_path=API_DOC_PATH, debug=False): - """Render the markdown files.""" - # Create and write the qmd files for each function/class/module - write_api_markdown(data_dict, api_path, address_dict, debug=debug) - # put the parts together; alias; path to docs - path_mapping = create_json_mapping(data_dict, address_dict, api_path) - # Add the other parts of the documentation. - path_mapping.update(_map_other_qmd_files()) - # dump the json mapping to disk in doc folder - cross_ref_path = Path(DOC_PATH) / ".cross_ref.json" - with open(cross_ref_path, "w") as fi: - json.dump(path_mapping, fi, indent=2) - # Clear out empty directories - _clear_empty_directories(api_path) diff --git a/scripts/_templates/_quarto.yml b/scripts/_templates/_quarto.yml deleted file mode 100644 index fdf8ca1ef..000000000 --- a/scripts/_templates/_quarto.yml +++ /dev/null @@ -1,240 +0,0 @@ -# NOTE: This file is auto generated by a template in the scripts directory -# dascore/scripts/templates/_quarto.yml, be sure to change that file. - -project: - type: website - output-dir: _site - -filters: - - quarto - - filters/fill_links.py - -execute: - warning: false - -format: - html: - toc: true - theme: - light: yeti - dark: darkly - code-copy: true - code-overflow: wrap - css: styles.css - -website: - title: {{ dascore_version_str }} - repo-url: https://github.com/dasdae/dascore - site-path: /docs - site-url: https://www.dascore.org - - image: "_static/logo.png" - favicon: "_static/logo.png" - repo-subdir: docs - repo-branch: master - repo-actions: [edit] - page-navigation: true - - navbar: - logo: _static/logo.png - logo-alt: "DASCore logo." - background: light - search: true - left: - - text: Introduction - file: index.qmd - - - text: Tutorial - file: tutorial/concepts.qmd - - - text: Recipes - file: recipes/overview.qmd - - - text: Notes - file: notes/notes.qmd - - - text: Contributing - file: contributing/contributing.qmd - - - text: API - file: api/dascore.qmd - - right: - - - icon: github - href: https://github.com/dasdae/dascore - aria-label: DASCore GitHub - - sidebar: - - id: about - title: "About" - style: "floating" - collapse-level: 2 - logo: "_static/logo.png" - search: true - contents: - - text: Introduction - href: index.qmd - - - text: Formats - href: supported_formats.qmd - - - text: Plugins - href: supported_plugins.qmd - - - text: Changelog - href: https://github.com/DASDAE/dascore/releases - - - text: Contributors - href: contributors.qmd - - - text: Acknowledgements - href: acknowledgements.qmd - - - id: tutorial - title: "Tutorial" - contents: - - text: DASCore Concepts - href: tutorial/concepts.qmd - - - text: Patch - href: tutorial/patch.qmd - - - text: Spool - href: tutorial/spool.qmd - - - text: Processing - href: tutorial/processing.qmd - - - text: Transformations - href: tutorial/transformations.qmd - - - text: Visualization - href: tutorial/visualization.qmd - - - text: File IO - href: tutorial/file_io.qmd - - - text: Working with Remote Patches - href: tutorial/remote_patches.qmd - - - text: Configuration - href: tutorial/configuration.qmd - - - text: Coordinates - href: tutorial/coords.qmd - - - id: Recipes - title: 'Recipes' - collapse-level: 1 - contents: - - recipes/overview.qmd - - - section: "Contributing" - contents: - - - recipes/how_to_contribute.qmd - - recipes/contributing_to_documentation.qmd - - - section: "Coordinates" - contents: - - - recipes/add_spatial_coordinates_to_patch.qmd - - recipes/plotting_channel_number.qmd - - - section: "Processing" - contents: - - - recipes/despiking.qmd - - recipes/smoothing.qmd - - recipes/correlate.qmd - - recipes/edge_effects.qmd - - recipes/fk.qmd - - recipes/real_time_proc.qmd - - recipes/parallelization.qmd - - recipes/low_freq_proc.qmd - - - section: "IO" - contents: - - - recipes/external_conversion.qmd - - - section: "Misc" - contents: - - - recipes/docker_basic.qmd - - - id: contributing - title: "Contributing" - contents: - - contributing/contributing.qmd - - - text: Dev Install - href: contributing/dev_install.qmd - - - text: Style - href: contributing/style_and_linting.qmd - - - text: "Testing" - href: contributing/testing.qmd - - - text: "Adding Test Data" - href: contributing/adding_test_data.qmd - - - text: Documentation - href: contributing/documentation.qmd - - - text: Profiling and Benchmarks - href: contributing/profiling_benchmarks.qmd - - - text: General Guidelines - href: contributing/general_guidelines.qmd - - - text: "Adding a new format" - href: contributing/new_format.qmd - - - text: "Extending DASCore" - href: contributing/extending_dascore.qmd - - - text: "Publish a new release" - href: contributing/publish_a_new_release.qmd - - - text: "Code of Conduct" - href: contributing/code_of_conduct.qmd - - - id: Notes - title: 'Notes' - href: notes/notes.qmd - contents: - - notes/notes.qmd - - - text: Documentation Strategy - href: notes/doc_strategy.qmd - - - text: Coordinate Internals - href: notes/coordinate_internals.qmd - - - text: PatchAttrs - href: notes/patch_attrs.qmd - - - text: Fourier Transforms - href: notes/dft_notes.qmd - - - text: Velocity to Strain Rate - href: notes/velocity_to_strain_rate.qmd - - - text: Spool Index - href: notes/spool_index.qmd - - - text: Spool Selection - href: notes/spool_selection.qmd - - - id: API - title: "API" - href: api/dascore.qmd - contents: - {% for item in api_toc_tree -%} - {{ item }} - {% endfor %} - -bibliography: references.bib diff --git a/scripts/_templates/notes.md b/scripts/_templates/notes.md deleted file mode 100644 index 6737be8a8..000000000 --- a/scripts/_templates/notes.md +++ /dev/null @@ -1,4 +0,0 @@ - -:::{.callout-note} -{{ note_text }} -::: diff --git a/scripts/_templates/parent_source_block.html b/scripts/_templates/parent_source_block.html deleted file mode 100644 index 5e5da1ee1..000000000 --- a/scripts/_templates/parent_source_block.html +++ /dev/null @@ -1,6 +0,0 @@ - - - - - -
{{ origin_txt }}[source]({{ source_url }})
diff --git a/scripts/_templates/signature.html b/scripts/_templates/signature.html deleted file mode 100644 index cc672ef29..000000000 --- a/scripts/_templates/signature.html +++ /dev/null @@ -1,19 +0,0 @@ -:::{.padded_bottom_10pt} - -:::{.def_block} -{% if params %} - -{{ name }}(
-{%- for param in params %} -     {{ param }},
-{%- endfor %} -{{ return_line }} - -{% else %} - -{{ name }}({{ return_line }} - -{% endif %} -::: - -::: diff --git a/scripts/_templates/table.html b/scripts/_templates/table.html deleted file mode 100644 index 555a3a3e6..000000000 --- a/scripts/_templates/table.html +++ /dev/null @@ -1,24 +0,0 @@ -{# A template for making tables. #} - - {%- if caption %} - - {%- endif %} - - - {%- for col in columns %} - - {%- endfor %} - - - - {%- for row in rows %} - - {%- for val in row %} - - {%- endfor %} - - {%- endfor %} - -
- {{ caption }} -
{{ col }}
{{ val }}
diff --git a/scripts/_validate_links.py b/scripts/_validate_links.py deleted file mode 100644 index dc2309444..000000000 --- a/scripts/_validate_links.py +++ /dev/null @@ -1,72 +0,0 @@ -"""Script to validate links in qmd files.""" - -from __future__ import annotations - -import json -import re -from functools import cache -from pathlib import Path - - -def _get_docs_path(): - """Find the documentation path.""" - path = Path(__file__).parent.parent / "docs" - return path - - -def get_qmd_files( - path=None, -): - """Yield all QMD files.""" - path = _get_docs_path() if path is None else path - yield from path.rglob("*qmd") - - -def yield_links(text, pattern=r"(?<=\]\(`).*?(?=`\))"): - """Yield links found in documentation.""" - matches = re.findall(pattern, text) - yield from matches - - -@cache -def load_index(path=None): - """Load the index with the linked locations.""" - if path is None: - path = _get_docs_path() / ".cross_ref.json" - with open(path) as fi: - out = json.load(fi) - return out - - -def validate_all_links(): - """Scan all documentation files and ensure the links are valid.""" - index = load_index() - good_links, bad_links, file_count = 0, 0, 0 - bad = [] - for path in get_qmd_files(): - file_count += 1 - text = path.read_text() - for link in yield_links(text): - if link not in index: - bad.append((str(path), link)) - bad_links += 1 - else: - good_links += 1 - print( # noqa - f"Validated links in documentation. Scanned {file_count} files, " - f"found {good_links} good links and {bad_links} bad links" - ) - if bad_links: - msg = "Please fix the following (path/link)\n" - max_len = max(len(x[0]) for x in bad) - out = [] - for path, link in bad: - path_str = path.ljust(max_len + 3) - out.append(f"{path_str} {link}") - new_str = msg + "\n".join(out) - raise ValueError(new_str) - - -if __name__ == "__main__": - validate_all_links() - pass diff --git a/scripts/build_api_docs.py b/scripts/build_api_docs.py deleted file mode 100644 index 0c84811f3..000000000 --- a/scripts/build_api_docs.py +++ /dev/null @@ -1,31 +0,0 @@ -"""Script to build the API docs for dascore.""" - -from __future__ import annotations - -import sys -from contextlib import suppress - -from _index_api import get_alias_mapping, parse_project -from _qmd_builder import create_quarto_qmd -from _render_api import render_project -from _validate_links import validate_all_links - -import dascore as dc - -with suppress(AttributeError): - sys.stdout.encoding = "utf-8" - - -if __name__ == "__main__": - print("Building documentation") # noqa - print(f"Parsing project {dc.__name__}") # noqa - data_dict = parse_project(dc) - obj_dict = get_alias_mapping(dc) - print("Generating qmd files") # noqa - render_project(data_dict, obj_dict, debug=False) - # create the quarto info file (needs templating) - print("creating quarto config") # noqa - create_quarto_qmd() - # validate links - print("Validating links") # noqa - validate_all_links() diff --git a/scripts/generate_doc_code_tests.py b/scripts/generate_doc_code_tests.py index 665b8e674..1f3021558 100644 --- a/scripts/generate_doc_code_tests.py +++ b/scripts/generate_doc_code_tests.py @@ -6,8 +6,8 @@ How it works: -1. Discover every source ``.qmd`` file under ``docs/``, excluding generated API - docs under ``docs/api/``. +1. Discover every source ``.qmd`` file in the narrative doc sections + (``tutorial/``, ``recipes/``, ...) plus the landing page. 2. Parse each qmd file and keep only executable Quarto ``{python ...}`` fences. 3. Respect document-level ``execute.eval: false`` and chunk-level ``#| eval: false`` / ``#| execute: false`` switches. @@ -38,12 +38,15 @@ # The generator always runs from the repository checkout. REPO_ROOT = Path(__file__).resolve().parent.parent -# Source qmd files live under docs/. -DOCS_PATH = REPO_ROOT / "docs" +# Narrative doc sources sit at the top of the repo, one directory per +# great-docs section, so paths mirror the site layout. +DOCS_PATH = REPO_ROOT +# Keep in sync with the `sections:` entries in great-docs.yml. +DOC_SECTIONS = ("tutorial", "recipes", "notes", "contributing", "about") +# The landing page is the one doc source outside a section directory. +ROOT_DOCS = ("index.qmd",) # Generated pytest files are mirrored into a dedicated test tree. TESTS_PATH = REPO_ROOT / "tests" / "test_autogenerated_doccode" -# API docs are generated elsewhere and should not be mirrored again here. -API_DOCS_PATH = DOCS_PATH / "api" # Force stable cross-platform text IO for both reads and writes. TEXT_ENCODING = "utf-8" @@ -307,12 +310,12 @@ def extract_qmd_file(path: Path) -> QmdFile: def iter_source_qmd_files(base_path: Path = DOCS_PATH) -> list[Path]: """Return source qmd files to mirror into tests.""" - # Mirror every qmd under docs/, except generated API docs. - return [ - path - for path in sorted(base_path.rglob("*.qmd")) - if API_DOCS_PATH not in path.parents and path != API_DOCS_PATH - ] + # Only the narrative sections are walked; everything else at the repo root + # (generated sites, test fixtures, ...) is not documentation source. + paths = [base_path / name for name in ROOT_DOCS if (base_path / name).exists()] + for section in DOC_SECTIONS: + paths.extend((base_path / section).rglob("*.qmd")) + return sorted(paths) def get_output_path( @@ -321,8 +324,8 @@ def get_output_path( docs_path: Path = DOCS_PATH, ) -> Path: """Map a qmd file to its generated pytest module.""" - # Keep the generated tree shaped like docs/, but swap the filename to - # `test_.py` so pytest discovers it naturally. + # Keep the generated tree shaped like the doc sections, but swap the + # filename to `test_.py` so pytest discovers it naturally. relative = source_path.relative_to(docs_path) filename = f"test_{source_path.stem}.py" if len(relative.parts) == 1: diff --git a/scripts/greatdocs_alias_inventory.py b/scripts/greatdocs_alias_inventory.py index db07cb4d8..44ce7693c 100644 --- a/scripts/greatdocs_alias_inventory.py +++ b/scripts/greatdocs_alias_inventory.py @@ -94,6 +94,7 @@ def _resolve(name: str): def main() -> None: + """Append alias entries to the interlink inventory.""" _ensure_dascore() import dascore as dc diff --git a/scripts/greatdocs_build_fixups.py b/scripts/greatdocs_build_fixups.py index 12883616d..306d392fe 100644 --- a/scripts/greatdocs_build_fixups.py +++ b/scripts/greatdocs_build_fixups.py @@ -110,7 +110,7 @@ def _fix_release_body(version: str, body: list[str]) -> tuple[list[str], int, in # Highest count wins; ties resolve to the smaller indent. base = min(counts, key=lambda k: (-counts[k], k)) if base: - strip_re = re.compile(r"^ {1,%d}" % base) + strip_re = re.compile(rf"^ {{1,{base}}}") new_note = [strip_re.sub("", ln) for ln in note] if new_note != note: note = new_note @@ -127,7 +127,6 @@ def fix_changelog(path: Path) -> int: # Find the frontmatter/preamble, then split into per-release blocks at each # `{.changelog-version}` heading. out: list[str] = [] - i = 0 version: str | None = None block: list[str] = [] dropped = deindented = 0 @@ -167,6 +166,7 @@ def flush() -> None: def main() -> int: + """Patch the generated index and changelog pages in place.""" cwd = Path.cwd() n_index = fix_index(cwd / "index.qmd") n_changelog = fix_changelog(cwd / "changelog.qmd") diff --git a/scripts/test_generate_doc_code_tests.py b/scripts/test_generate_doc_code_tests.py index c7a772d53..a68c2e989 100644 --- a/scripts/test_generate_doc_code_tests.py +++ b/scripts/test_generate_doc_code_tests.py @@ -191,7 +191,7 @@ class TestOutputPaths: def test_root_doc_maps_to_root_test(self): """Top-level docs should stay at the top of generated tests.""" - # docs/index.qmd becomes tests/test_autogenerated_doccode/test_index.py + # index.qmd becomes tests/test_autogenerated_doccode/test_index.py source = DOCS_PATH / "index.qmd" tests = Path("/repo/tests/test_autogenerated_doccode") assert get_output_path(source, tests_path=tests) == tests / "test_index.py" @@ -221,14 +221,14 @@ class TestRenderAndWrite: def test_render_includes_source_and_chunk_payload(self): """Generated modules should inline source code with source comments.""" # The generated file should contain enough literal data to run by itself. - source = REPO_ROOT / "docs" / "tutorial" / "example.qmd" + source = REPO_ROOT / "tutorial" / "example.qmd" module = render_test_module(source, (Chunk(start_line=12, source="x = 1\n"),)) - assert "Autogenerated from docs/tutorial/example.qmd" in module + assert "Autogenerated from tutorial/example.qmd" in module assert "@pytest.mark.docs_examples" in module assert "def test_main()" in module - assert "source_qmd = 'docs/tutorial/example.qmd'" in module + assert "source_qmd = 'tutorial/example.qmd'" in module assert "with qmd_test_context(source_qmd):" in module - assert "### docs/tutorial/example.qmd:12" in module + assert "### tutorial/example.qmd:12" in module assert "x = 1" in module assert "CHUNKS =" not in module assert "SOURCE_QMD =" not in module @@ -236,7 +236,7 @@ def test_render_includes_source_and_chunk_payload(self): def test_render_hoists_future_imports(self): """Future imports should move to module scope.""" - source = REPO_ROOT / "docs" / "tutorial" / "example.qmd" + source = REPO_ROOT / "tutorial" / "example.qmd" module = render_test_module( source, ( @@ -247,7 +247,7 @@ def test_render_hoists_future_imports(self): ), ) assert "from __future__ import annotations\n\nimport pytest" in module - assert "# docs/tutorial/example.qmd:12" in module + assert "# tutorial/example.qmd:12" in module assert " x = 1" in module assert " from __future__ import annotations" not in module diff --git a/scripts/test_index_api.py b/scripts/test_index_api.py deleted file mode 100644 index 05d3eb986..000000000 --- a/scripts/test_index_api.py +++ /dev/null @@ -1,35 +0,0 @@ -"""Tests for the api indexing helpers.""" - -from __future__ import annotations - -from _index_api import _get_base_address, _is_environment_path - - -class TestIsEnvironmentPath: - """Tests for detecting environment paths nested in the project.""" - - def test_venv_path(self): - """A .venv created in the repo should be excluded.""" - assert _is_environment_path("/repo/.venv/lib/python3.12/foo.py") - - def test_site_packages_path(self): - """Any site-packages path should be excluded.""" - assert _is_environment_path("/repo/env/lib/site-packages/scipy/x.py") - - def test_project_path(self): - """Regular project paths should not be excluded.""" - assert not _is_environment_path("/repo/dascore/core/patch.py") - - -class TestGetBaseAddress: - """Tests for converting paths to addresses.""" - - def test_environment_path_returns_empty(self): - """Environment paths should not get a base address.""" - path = "/repo/.venv/lib/python3.12/site-packages/scipy/signal.py" - assert _get_base_address(path, "/repo") == "" - - def test_project_path_returns_address(self): - """Project paths should convert to dotted addresses.""" - path = "/repo/dascore/core/patch.py" - assert _get_base_address(path, "/repo") == "dascore.core.patch" diff --git a/scripts/test_qmd_builder.py b/scripts/test_qmd_builder.py deleted file mode 100644 index d22933b6e..000000000 --- a/scripts/test_qmd_builder.py +++ /dev/null @@ -1,32 +0,0 @@ -"""Tests for building Quarto config values.""" - -from __future__ import annotations - -import pytest - -_qmd_builder = pytest.importorskip("_qmd_builder") - - -class TestGetDascoreTitle: - """Tests for DASCore title version formatting.""" - - def test_release_version(self, monkeypatch): - """Release versions are shown as-is.""" - monkeypatch.delenv("DASCORE_DOC_VERSION", raising=False) - monkeypatch.setattr(_qmd_builder.dc, "__version__", "0.1.16") - - assert _qmd_builder._get_dascore_title() == "DASCore (0.1.16)" - - def test_dev_version(self, monkeypatch): - """Dev versions strip local version metadata.""" - monkeypatch.delenv("DASCORE_DOC_VERSION", raising=False) - monkeypatch.setattr(_qmd_builder.dc, "__version__", "0.1.16.dev19+gabc123") - - assert _qmd_builder._get_dascore_title() == "DASCore (0.1.16.dev19)" - - def test_doc_version_override(self, monkeypatch): - """The docs version override controls the rendered site title.""" - monkeypatch.setenv("DASCORE_DOC_VERSION", "0.1.16") - monkeypatch.setattr(_qmd_builder.dc, "__version__", "0.1.16.dev19+gabc123") - - assert _qmd_builder._get_dascore_title() == "DASCore (0.1.16)" diff --git a/scripts/test_render_api.py b/scripts/test_render_api.py deleted file mode 100644 index 29f7156d5..000000000 --- a/scripts/test_render_api.py +++ /dev/null @@ -1,134 +0,0 @@ -"""Tests for rendering api stuff.""" - -from __future__ import annotations - -import inspect -import typing - -import pytest - -from dascore.core.spool import Spool - -# These tests only work if doc deps are installed. -pytest.importorskip("jinja2") - -from _render_api import build_signature, get_type_hints, to_quarto_code - - -class TestGetTypeHints: - """Tests for resolving the type hints of documented objects.""" - - def test_resolvable_hints(self): - """Annotations which resolve should still return their objects.""" - - def func(a: int) -> str: - """A documented function.""" - - hints = get_type_hints(func) - assert hints["a"] is int - assert hints["return"] is str - - def test_type_checking_only_annotation(self): - """ - Annotations imported only under TYPE_CHECKING can't be resolved when - the docs are built, but they shouldn't break the build. - """ - - class Klass: - """A class annotated with a name missing at runtime.""" - - attr: OnlyImportedWhileTypeChecking # noqa: F821 - - # The un-guarded call is what used to kill the doc build. - with pytest.raises(NameError): - typing.get_type_hints(Klass) - assert get_type_hints(Klass) == {"attr": "OnlyImportedWhileTypeChecking"} - - def test_signature_of_type_checking_annotated_class(self): - """Spool annotates a TYPE_CHECKING-only import; it must still render.""" - data = { - "signature": inspect.signature(Spool), - "object": Spool, - "name": "Spool", - } - out = build_signature(data, {}, {}) - assert "Spool" in out - assert "data" in out - - -class TestToQuartoCode: - """Tests for code parsing to quarto-style code strings.""" - - def test_basic(self): - """Ensure a simple example works.""" - code = """ - print("hey") - """ - out = to_quarto_code(code) - assert '```{python}\nprint("hey")\n```' == out - - def test_docstring(self): - """Ensure docstring works.""" - code = """ - >>> print("bob") - >>> for a in range(10): - ... print(a) - """ - out = to_quarto_code(code) - assert " print(a)" in out.splitlines() - - def test_output_handled(self): - """Docstrings can have outputs in them, we need to strip them out.""" - code = """ - >>> print("bob") - bob - """ - out = to_quarto_code(code) - assert '```{python}\nprint("bob")\n```' == out - - def test_titles(self): - """Ensure titles are carried forward.""" - code1 = """ - >>> ### Simple example - >>> print("a") - >>> - >>> ### More complex example - >>> print(1 + 2) - """ - out1 = to_quarto_code(code1) - code2 = """ - - ### Simple example - print("a") - ### More complex example - print(1 + 2) - - """ - out2 = to_quarto_code(code2) - assert out1 == out2 - - def test_options(self): - """Ensure quarto options carry forward.""" - code1 = """ - >>> #| fold: true - >>> print("bob") - >>> - >>> ### Another example - >>> print("bill") - """ - out = to_quarto_code(code1) - expected_str = "#| fold: true" - assert expected_str in out - assert out.count(expected_str) == 2 - - def test_combination(self): - """A combination of stuff.""" - code1 = """ - >>> #| code-fold: true - >>> # This is a base example - >>> print(1 + 2) - >>> ### This is a sub-section - >>> print("cool beans") - """ - out = to_quarto_code(code1) - assert out From d0890c9220393222b054d957685b28d511dde40a Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Thu, 13 Aug 2026 09:25:07 +0200 Subject: [PATCH 11/22] Document every dascore.utils helper on one page The curated API reference covers the patch, spool and processing surface, which left the 169 public helpers in dascore.utils undocumented: the old build walked the package and rendered them all, a page each. A page per helper triples the site for objects that are supporting cast, so render them onto a single page instead. render_package_api walks the package and renders each module as a section and each object as an entry: signature and summary in the open, and the parameter table, returns and examples inside a collapsed callout, so the page reads as an index but carries the full docs. Parameter types come from the annotations, since DASCore documents them there rather than in the docstring. The page table of contents lists the 28 modules while every object keeps an explicit anchor. Those anchors are what cross references resolve to: the inventory hook now registers each helper at its anchor on the page, so existing links like `dascore.utils.chunk_plan.ChunkPlan` keep working and the five utils entries the reference used to carry are no longer needed. --- dascore/utils/docs.py | 200 +++++++++++++++++++++++++++ great-docs.yml | 13 +- pyproject.toml | 10 +- scripts/greatdocs_alias_inventory.py | 36 +++++ tests/test_utils/test_doc_utils.py | 39 ++++++ utilities/index.qmd | 16 +++ 6 files changed, 304 insertions(+), 10 deletions(-) create mode 100644 utilities/index.qmd diff --git a/dascore/utils/docs.py b/dascore/utils/docs.py index 9802ab7cc..9259a0632 100644 --- a/dascore/utils/docs.py +++ b/dascore/utils/docs.py @@ -2,8 +2,11 @@ from __future__ import annotations +import importlib import inspect +import logging import os +import pkgutil import textwrap from collections.abc import Sequence from pathlib import Path @@ -165,3 +168,200 @@ def objs_to_doc_df(doc_dict, cross_reference=True): df = pd.Series(out).to_frame().reset_index() df.columns = ["Name", "Description"] return df + + +# --------------------------------------------------------------------------- +# Rendering a module's public API onto a single documentation page. +# +# Modules of small helpers get one page each rather than a page per function: +# the summary and signature stay visible while the parameter table, examples +# and notes sit in a collapsed callout. Every entry keeps an explicit anchor so +# cross references can link straight to it. +# --------------------------------------------------------------------------- + + +def get_doc_anchor(dotted: str) -> str: + """Return the html anchor used for a dotted path on a rendered API page.""" + return dotted.replace(".", "-").replace("_", "-").lower() + + +def _fmt_annotation(anno) -> str: + """Render an annotation the way it was written in the source.""" + if isinstance(anno, str): + return anno + return getattr(anno, "__name__", None) or str(anno).replace("typing.", "") + + +def _fmt_default(value) -> str: + """Render a default value compactly (classes by name, not repr).""" + if inspect.isclass(value) or inspect.isfunction(value): + return value.__name__ + return repr(value) + + +def _signature(obj) -> str: + """Render a signature without the quoting artifacts of string annotations.""" + try: + sig = inspect.signature(obj) + except (TypeError, ValueError): + return getattr(obj, "__name__", "?") + "(...)" + parts, seen_kw_only = [], False + for p in sig.parameters.values(): + if p.kind is p.KEYWORD_ONLY and not seen_kw_only: + parts.append("*") + seen_kw_only = True + text = p.name + if p.kind is p.VAR_POSITIONAL: + text = f"*{text}" + elif p.kind is p.VAR_KEYWORD: + text = f"**{text}" + if p.annotation is not p.empty: + text += f": {_fmt_annotation(p.annotation)}" + if p.default is not p.empty: + text += f" = {_fmt_default(p.default)}" + parts.append(text) + ret = "" + if sig.return_annotation is not sig.empty: + ret = f" -> {_fmt_annotation(sig.return_annotation)}" + return f"{obj.__name__}({', '.join(parts)}){ret}" + + +def _param_types(obj) -> dict[str, str]: + """Map parameter name to its annotation, for the parameter table.""" + try: + sig = inspect.signature(obj) + except (TypeError, ValueError): + return {} + return { + p.name: _fmt_annotation(p.annotation) + for p in sig.parameters.values() + if p.annotation is not p.empty + } + + +def _parse(doc: str): + """Parse a numpydoc docstring into griffe sections.""" + from griffe import Docstring # noqa: PLC0415 + + # Griffe logs a warning for every parameter documented without a type, + # which is DASCore's house style (types come from the annotations). + logging.getLogger("griffe").setLevel(logging.ERROR) + return Docstring(doc, parser="numpy").parse("numpy") + + +def _render_sections(sections, types: dict[str, str]) -> tuple[str, list[str]]: + """Return the summary line and the collapsible body blocks.""" + summary, blocks = "", [] + for sec in sections: + kind = sec.kind.value + if kind == "text": + text = str(sec.value).strip() + if not summary: + first, _, rest = text.partition("\n\n") + summary = " ".join(first.split()) + if rest.strip(): + blocks.append(rest.strip()) + else: + blocks.append(text) + elif kind == "parameters": + rows = ["| Parameter | Type | Description |", "|---|---|---|"] + for p in sec.value: + anno = types.get(p.name) or ( + "" if p.annotation is None else str(p.annotation) + ) + anno = f"`{anno}`" if anno else "" + desc = " ".join(str(p.description).split()) + rows.append(f"| `{p.name}` | {anno} | {desc} |") + blocks.append("\n".join(rows)) + elif kind in {"returns", "yields"}: + items = [] + for r in sec.value: + anno = "" if r.annotation is None else f"`{r.annotation}` — " + items.append(f"{anno}{' '.join(str(r.description).split())}") + blocks.append(f"**{kind.title()}:** " + "; ".join(items)) + elif kind == "raises": + items = [ + f"`{r.annotation}` — {' '.join(str(r.description).split())}" + for r in sec.value + ] + blocks.append("**Raises:** " + "; ".join(items)) + elif kind == "examples": + for _, text in sec.value: + blocks.append("```python\n" + str(text).strip() + "\n```") + elif kind == "admonition": + body = getattr(sec.value, "description", sec.value) + blocks.append(f"**{sec.title or 'Note'}:** {str(body).strip()}") + else: + blocks.append(str(sec.value).strip()) + return summary, blocks + + +def iter_public(module_name: str): + """Yield (name, object) for public objects defined in the module.""" + mod = importlib.import_module(module_name) + for name in sorted(dir(mod)): + if name.startswith("_"): + continue + obj = getattr(mod, name) + if not (inspect.isfunction(obj) or inspect.isclass(obj)): + continue + if getattr(obj, "__module__", "") != module_name: + continue + yield name, obj + + +def render_module_api(module_name: str) -> str: + """Render every public object defined in a module as markdown.""" + out: list[str] = [] + for name, obj in iter_public(module_name): + dotted = f"{module_name}.{name}" + doc = inspect.getdoc(obj) or "" + summary, blocks = ( + _render_sections(_parse(doc), _param_types(obj)) if doc else ("", []) + ) + out.append(f"#### {name} {{#{get_doc_anchor(dotted)}}}\n") + out.append(f"```python\n{_signature(obj)}\n```\n") + if summary: + out.append(f"{summary}\n") + if blocks: + out.append( + '::: {.callout-note collapse="true" appearance="simple" ' + 'title="Details"}\n' + ) + out.extend(b + "\n" for b in blocks) + out.append(":::\n") + return "\n".join(out) + + +def render_package_api(package_name: str, skip_empty: bool = True) -> str: + """ + Render the public API of every module in a package as markdown. + + Each module becomes a level-two heading and each object a level-three + heading below it, so the page table of contents lists modules while every + object still has an anchor to link to. + + Parameters + ---------- + package_name + The importable name of the package, e.g. "dascore.utils". + skip_empty + If True, omit modules which define no public objects. + """ + package = importlib.import_module(package_name) + out = [] + for info in pkgutil.walk_packages(package.__path__, prefix=f"{package_name}."): + if any(part.startswith("_") for part in info.name.split(".")): + continue + try: + body = render_module_api(info.name) + except ImportError: # an optional dependency the doc env lacks + continue + if skip_empty and not body.strip(): + continue + out.append(f"### {info.name} {{#{get_doc_anchor(info.name)}}}\n") + module_doc = inspect.getdoc(importlib.import_module(info.name)) or "" + if module_doc: + out.append(" ".join(module_doc.split("\n\n")[0].split()) + "\n") + out.append(body) + return "\n".join(out) diff --git a/great-docs.yml b/great-docs.yml index 9d4bce86e..48a88c5af 100644 --- a/great-docs.yml +++ b/great-docs.yml @@ -79,6 +79,10 @@ sections: - title: About dir: about index: true + # One page for the whole utils package: a page per helper would triple the + # site for objects that are supporting cast rather than the main interface. + - title: Utilities + dir: utilities # Names picked up by discovery that are implementation details or # accidental re-exports (dascore modules do not define __all__). @@ -342,15 +346,6 @@ reference: - name: io.H5Writer members: [get_handle] - - title: Utilities - desc: Assorted helper utilities - contents: - - utils.array.apply_ufunc - - utils.array.apply_array_func - - utils.chunk_plan.ChunkPlan - - utils.patch.merge_compatible_coords_attrs - - utils.remote_io.clear_remote_file_cache - - title: Exceptions desc: Exception classes raised by DASCore contents: diff --git a/pyproject.toml b/pyproject.toml index 751039f0b..c608bc42e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,6 +73,8 @@ extras = [ ] docs = [ + # renders utils docstrings onto the utilities page + "griffe", "ipywidgets", "tabulate", # Quarto executes the {python} cells in docs/**.qmd through jupyter, so @@ -302,7 +304,13 @@ include = ["dascore"] # These files lazily import optional or untyped modules (xarray, numba, # h5py.h5r) that are not installed in the pre-commit hook's environment. [[tool.ty.overrides]] -include = ["dascore/compat.py", "dascore/utils/jit.py", "dascore/io/dasvader/utils.py"] +# griffe (docs extra) is imported only while rendering the utilities page. +include = [ + "dascore/compat.py", + "dascore/utils/docs.py", + "dascore/utils/jit.py", + "dascore/io/dasvader/utils.py", +] [tool.ty.overrides.rules] unresolved-import = "ignore" diff --git a/scripts/greatdocs_alias_inventory.py b/scripts/greatdocs_alias_inventory.py index 44ce7693c..ed27e50bd 100644 --- a/scripts/greatdocs_alias_inventory.py +++ b/scripts/greatdocs_alias_inventory.py @@ -21,6 +21,8 @@ from __future__ import annotations +import importlib +import inspect import json import os import sys @@ -28,6 +30,15 @@ OBJECTS_JSON = Path("objects.json") +# Where the single-page utils reference lands in the built site. +# +# great-docs resolves inventory uris in two ways: with the linking page's path +# (a relative path is computed, which normalizes the `..`) and, on reference +# pages, by simply stripping a leading `reference/` -- that branch assumes +# every documented object lives under `reference/`. Spelling the path this way +# lands on `../utilities/index.html` either way. Worth reporting upstream. +UTILITIES_PAGE = "reference/../utilities/index.html" + # Modules whose links should land on a section of the API index. MODULE_SECTIONS = { "dascore.core": "reference/index.html#core-classes", @@ -180,6 +191,31 @@ def add_alias(name: str, target: dict) -> None: for name, uri in MODULE_SECTIONS.items(): add_alias(name, {"role": "module", "uri": uri, "dispname": "-"}) + # 5. The utilities page documents every helper in dascore.utils on one + # page, so point cross references at the anchor of each entry rather + # than a page that does not exist. + import pkgutil + + from dascore.utils.docs import get_doc_anchor, iter_public + + utils = importlib.import_module("dascore.utils") + for info in pkgutil.walk_packages(utils.__path__, prefix="dascore.utils."): + if any(part.startswith("_") for part in info.name.split(".")): + continue + try: + members = list(iter_public(info.name)) + except ImportError: + continue + if not members: + continue + page = f"{UTILITIES_PAGE}#{get_doc_anchor(info.name)}" + add_alias(info.name, {"role": "module", "uri": page, "dispname": "-"}) + for name, obj in members: + dotted = f"{info.name}.{name}" + uri = f"{UTILITIES_PAGE}#{get_doc_anchor(dotted)}" + role = "class" if inspect.isclass(obj) else "function" + add_alias(dotted, {"role": role, "uri": uri, "dispname": "-"}) + if new_items: data["items"] = items + new_items data["count"] = len(data["items"]) diff --git a/tests/test_utils/test_doc_utils.py b/tests/test_utils/test_doc_utils.py index 53527fd28..02d379d34 100644 --- a/tests/test_utils/test_doc_utils.py +++ b/tests/test_utils/test_doc_utils.py @@ -13,9 +13,12 @@ from dascore.utils.docs import ( compose_docstring, format_dtypes, + get_doc_anchor, get_docstring, get_plugin_table, objs_to_doc_df, + render_module_api, + render_package_api, ) @@ -153,3 +156,39 @@ def test_example_no_cross_ref(self): df = objs_to_doc_df(EXAMPLE_PATCHES, cross_reference=False) assert "(`dascore.examples" not in df["Name"].iloc[0] assert isinstance(df, pd.DataFrame) + + +class TestRenderApi: + """Tests for rendering a module's API onto one documentation page.""" + + @pytest.fixture(scope="class") + def misc_markdown(self): + """Rendered markdown for a module with a mix of documented objects.""" + return render_module_api("dascore.utils.misc") + + def test_anchor_is_stable_and_html_safe(self): + """Anchors must be reproducible so the inventory can point at them.""" + anchor = get_doc_anchor("dascore.utils.misc.iterate") + assert anchor == "dascore-utils-misc-iterate" + assert anchor == get_doc_anchor("dascore.utils.misc.iterate") + + def test_entry_has_anchor_signature_and_summary(self, misc_markdown): + """Each entry needs the pieces a reader and the inventory rely on.""" + assert "#### iterate {#dascore-utils-misc-iterate}" in misc_markdown + assert "iterate(" in misc_markdown + + def test_details_are_collapsed(self, misc_markdown): + """Parameters and examples sit in a collapsed callout, not inline.""" + assert 'collapse="true"' in misc_markdown + assert "| Parameter | Type | Description |" in misc_markdown + + def test_only_objects_defined_in_the_module(self, misc_markdown): + """Imported names belong to the module which defines them.""" + # misc imports numpy as np; it should not document numpy. + assert "#### np " not in misc_markdown + + def test_package_render_covers_every_module(self): + """Every non-private module with public objects gets a section.""" + markdown = render_package_api("dascore.utils") + assert "### dascore.utils.misc {#dascore-utils-misc}" in markdown + assert "### dascore.utils.patch {#dascore-utils-patch}" in markdown diff --git a/utilities/index.qmd b/utilities/index.qmd new file mode 100644 index 000000000..8dc218c57 --- /dev/null +++ b/utilities/index.qmd @@ -0,0 +1,16 @@ +--- +title: Utilities +description: "Every public helper in dascore.utils, with details on demand." +--- + +DASCore's `utils` package holds the helpers the rest of the library is built from. They are public, but they are supporting cast rather than the main interface — the [API reference](/reference/index.qmd) covers the patch, spool and processing functions most users need. + +Everything defined in `dascore.utils` is listed below, one section per module. Each entry shows its signature and summary; open **Details** for parameters, returns and examples. + +```{python} +#| echo: false +#| output: asis +from dascore.utils.docs import render_package_api + +print(render_package_api("dascore.utils")) +``` From f1e52f1bb7c235011e75b49e8c534ac0fb99ee8a Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Thu, 13 Aug 2026 12:29:58 +0200 Subject: [PATCH 12/22] Render every kind of docstring section on the utilities page Two gaps showed up once the whole of dascore.utils was rendered onto one page. Sections griffe parses into models rather than strings (Attributes, Other Parameters) fell to the catch-all branch and printed an object repr into the page; they now render as a table like Parameters does. And decorated helpers such as functools.cache wrappers are callables rather than functions, so the public-object walk skipped them, dropping both their docs and the anchor cross references resolve to. --- dascore/utils/docs.py | 33 +++++++++++++++++++++++++----- tests/test_utils/test_doc_utils.py | 13 ++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/dascore/utils/docs.py b/dascore/utils/docs.py index 9259a0632..102caddbd 100644 --- a/dascore/utils/docs.py +++ b/dascore/utils/docs.py @@ -288,24 +288,47 @@ def _render_sections(sections, types: dict[str, str]) -> tuple[str, list[str]]: elif kind == "examples": for _, text in sec.value: blocks.append("```python\n" + str(text).strip() + "\n```") + elif kind in {"attributes", "other parameters"}: + label = "Attribute" if kind == "attributes" else "Parameter" + rows = [f"| {label} | Type | Description |", "|---|---|---|"] + for a in sec.value: + anno = types.get(a.name) or ( + "" if a.annotation is None else str(a.annotation) + ) + anno = f"`{anno}`" if anno else "" + desc = " ".join(str(a.description).split()) + rows.append(f"| `{a.name}` | {anno} | {desc} |") + blocks.append("\n".join(rows)) elif kind == "admonition": body = getattr(sec.value, "description", sec.value) blocks.append(f"**{sec.title or 'Note'}:** {str(body).strip()}") - else: - blocks.append(str(sec.value).strip()) + elif isinstance(sec.value, str): + blocks.append(sec.value.strip()) return summary, blocks def iter_public(module_name: str): - """Yield (name, object) for public objects defined in the module.""" + """ + Yield (name, object) for public objects defined in the module. + + Decorated helpers (e.g. functools.cache) are callables rather than plain + functions, so unwrap before deciding what a name is and where it was + defined; skipping them would drop both their docs and their anchor. + """ mod = importlib.import_module(module_name) for name in sorted(dir(mod)): if name.startswith("_"): continue obj = getattr(mod, name) - if not (inspect.isfunction(obj) or inspect.isclass(obj)): + unwrapped = inspect.unwrap(obj) + is_documentable = ( + inspect.isfunction(unwrapped) + or inspect.isclass(unwrapped) + or (callable(obj) and inspect.isroutine(unwrapped)) + ) + if not is_documentable or inspect.ismodule(obj): continue - if getattr(obj, "__module__", "") != module_name: + if getattr(unwrapped, "__module__", "") != module_name: continue yield name, obj diff --git a/tests/test_utils/test_doc_utils.py b/tests/test_utils/test_doc_utils.py index 02d379d34..bcf504fc5 100644 --- a/tests/test_utils/test_doc_utils.py +++ b/tests/test_utils/test_doc_utils.py @@ -16,6 +16,7 @@ get_doc_anchor, get_docstring, get_plugin_table, + iter_public, objs_to_doc_df, render_module_api, render_package_api, @@ -192,3 +193,15 @@ def test_package_render_covers_every_module(self): markdown = render_package_api("dascore.utils") assert "### dascore.utils.misc {#dascore-utils-misc}" in markdown assert "### dascore.utils.patch {#dascore-utils-patch}" in markdown + + def test_decorated_helpers_are_documented(self): + """Cached helpers are callables, not functions, and must not vanish.""" + names = {name for name, _ in iter_public("dascore.utils.downloader")} + assert "get_registry_df" in names + + def test_griffe_models_never_reach_the_page(self): + """Unhandled docstring sections must not render object reprs.""" + # ChunkPlan documents an Attributes section, which has its own model. + markdown = render_module_api("dascore.utils.chunk_plan") + assert "object at 0x" not in markdown + assert "| Attribute | Type | Description |" in markdown From 030654ae265e37f9667c318039184ca9d2e430ac Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Thu, 13 Aug 2026 12:30:02 +0200 Subject: [PATCH 13/22] Point cross references at the anchors reference pages emit great-docs records a member's uri with its fully qualified name as the fragment (Patch.html#dascore.Patch.data) while quarto gives that member's section the short id (#data), so every member cross reference landed at the top of the page instead of the member. Nothing warns: the file exists, only the fragment is absent. Repoint the inventory uris before the aliases are derived from them, and drop the fragment entirely for an object which owns its whole page. --- scripts/greatdocs_alias_inventory.py | 30 +++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/scripts/greatdocs_alias_inventory.py b/scripts/greatdocs_alias_inventory.py index ed27e50bd..52023fdc1 100644 --- a/scripts/greatdocs_alias_inventory.py +++ b/scripts/greatdocs_alias_inventory.py @@ -49,7 +49,6 @@ "dascore.proc.aggregate": "reference/index.html#patch-processing", "dascore.transform": "reference/index.html#transforms", "dascore.units": "reference/index.html#units-and-time", - "dascore.utils": "reference/index.html#utilities", "dascore.viz": "reference/index.html#visualization", "dascore.constants": "reference/index.html", } @@ -113,6 +112,27 @@ def main() -> None: items = data["items"] known = {it["name"] for it in items} + # 0. Point uris at anchors the rendered pages actually emit. great-docs + # records `Patch.html#dascore.Patch.data`, but quarto gives the member + # section the short id `#data`; an object which owns its whole page + # (write.html) has no anchor for itself and needs none. This runs first + # so the aliases added below copy the corrected uris. + rewritten = 0 + for item in items: + uri = item.get("uri", "") + page, sep, fragment = uri.partition("#") + if not sep or not page.startswith("reference/") or "." not in fragment: + continue + page_object = page[len("reference/") : -len(".html")] + qualname = fragment.removeprefix("dascore.") + if qualname == page_object: # the object owns the page + new_uri = page + else: + new_uri = f"{page}#{qualname.split('.')[-1]}" + if new_uri != uri: + item["uri"] = new_uri + rewritten += 1 + # Map runtime object id -> best inventory item (prefer non-module roles, # e.g. proc.taper the function page over proc.taper the module). by_id: dict[int, dict] = {} @@ -199,6 +219,7 @@ def add_alias(name: str, target: dict) -> None: from dascore.utils.docs import get_doc_anchor, iter_public utils = importlib.import_module("dascore.utils") + add_alias("dascore.utils", {"role": "module", "uri": UTILITIES_PAGE}) for info in pkgutil.walk_packages(utils.__path__, prefix="dascore.utils."): if any(part.startswith("_") for part in info.name.split(".")): continue @@ -216,11 +237,14 @@ def add_alias(name: str, target: dict) -> None: role = "class" if inspect.isclass(obj) else "function" add_alias(dotted, {"role": role, "uri": uri, "dispname": "-"}) - if new_items: + if new_items or rewritten: data["items"] = items + new_items data["count"] = len(data["items"]) OBJECTS_JSON.write_text(json.dumps(data, indent=1)) - print(f"greatdocs_alias_inventory: added {len(new_items)} alias entries") + print( + f"greatdocs_alias_inventory: added {len(new_items)} alias entries, " + f"repointed {rewritten} anchors" + ) if __name__ == "__main__": From b1bd24cf308d9338bfa15f71b4ab7c02383ddc0d Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Thu, 13 Aug 2026 12:30:09 +0200 Subject: [PATCH 14/22] Fail the tests when public API is missing from the docs The API reference is curated, which reads better than a generated dump but means new public API is invisible until someone lists it, and nothing about adding a function makes that omission noticeable: dev had grown PatchSummary, the config API, CoordSegmented and eleven aggregate functions with no signal. Compare the public surface against everything the docs cover and fail when an object appears nowhere, counting the reference, the utilities page, the supported formats table, and an explicit list of deliberate omissions. The same test checks the reference does not rot in the other direction: that entries still resolve by attribute access, which is what keeps one stale entry from silently dropping the whole reference to static analysis, that listed members exist, and that a documented class has no undocumented public members. Doing so found the config and inventory APIs, twenty-one properties and a handful of functions missing, along with an exclude entry for a package removed in #751; all are now covered. --- great-docs.yml | 63 +++- pyproject.toml | 1 + recipes/contributing_to_documentation.qmd | 20 ++ tests/test_doc_coverage.py | 394 ++++++++++++++++++++++ 4 files changed, 470 insertions(+), 8 deletions(-) create mode 100644 tests/test_doc_coverage.py diff --git a/great-docs.yml b/great-docs.yml index 48a88c5af..9ef396498 100644 --- a/great-docs.yml +++ b/great-docs.yml @@ -87,7 +87,6 @@ sections: # Names picked up by discovery that are implementation details or # accidental re-exports (dascore modules do not define __all__). exclude: - - clients - warnings - compat.MATERIALIZE_NOW - compat.random_state @@ -124,6 +123,7 @@ exclude: - units.unbyte - units.UnitError - viz.PatchNameSpace + - viz.VizPatchNameSpace # Curated API reference. Grouped by task, mirroring how the tutorial # introduces the library. @@ -143,23 +143,26 @@ reference: desc: The central data structures of DASCore contents: - name: Patch - members: [data, coords, dims, attrs, shape, size, ndim, dtype, seconds, channel_count, coord_shapes, get_coord, get_patch_name, T] + members: [data, coords, dims, attrs, shape, size, ndim, dtype, seconds, channel_count, coord_shapes, flat_dump, get_coord, get_patch_name, get_registered_namespaces, summary, T] - name: BaseSpool - members: [chunk, concatenate, get_contents, get_patch_names, map, select, sort, split, stack, update] + members: [chunk, concatenate, get_contents, get_patch_names, get_registered_namespaces, map, select, sort, split, stack, update] - name: Spool members: [from_directory, from_file, chunk_plan, spool_path, indexer, has_live_patches] - name: PatchAttrs - members: [drop, drop_private, flat_dump, from_dict, get, get_summary_df, items, update] + members: [drop, drop_private, flat_dump, from_dict, get, get_summary_df, items, new, update] - name: PatchSummary - members: [dim_tuple, dump_structured, flat_dump, from_patch, get_coord_summary, get_summary_df] + members: [dim_tuple, dump_structured, flat_dump, from_patch, get_coord_summary, get_summary_df, new, summary] - name: CoordManager - members: [convert_units, coord_range, coord_shapes, coord_size, decimate, dim_to_coord_map, disassociate_coord, drop_coords, drop_disassociated_coords, drop_private_coords, equals, flip, get_array, get_axis, get_coord, get_coord_tuple_map, keys, make_broadcastable_to, max, min, ndim, new, order, rename_coord, select, set_dims, set_units, shape, simplify_units, size, snap, sort, squeeze, step, to_summary_dict, transpose, update, validate_data] + members: [convert_units, coord_range, coord_shapes, coord_size, decimate, dim_to_coord_map, disassociate_coord, drop_coords, drop_disassociated_coords, drop_private_coords, equals, flip, get_array, get_axis, get_coord, get_coord_tuple_map, get_summary_df, keys, make_broadcastable_to, max, min, ndim, new, order, rename_coord, select, set_dims, set_units, shape, simplify_units, size, snap, sort, squeeze, step, to_summary_dict, transpose, update, validate_data] - name: proc.BaseCoord - members: [align_to, approx_equal, change_length, convert_units, coord_range, empty, get_discontinuities, get_next_index, get_sample_count, get_slice_tuple, index, max, min, new, order, reduce_coord, select, set_units, simplify, simplify_units, snap, sort, to_summary, update, update_data, update_limits] + members: [align_to, approx_equal, change_length, convert_units, coord_range, data, degenerate, empty, evenly_sampled, fingerprint, get_discontinuities, get_next_index, get_sample_count, get_slice_tuple, get_summary_df, index, limits, max, min, ndim, new, order, reduce_coord, reverse_sorted, select, set_units, simplify, simplify_units, size, snap, sort, sorted, to_summary, unit_str, update, update_data, update_limits] - name: proc.CoordSegmented - members: [from_array, get_discontinuities, simplify] + members: [from_array, get_discontinuities, segment_count, simplify, values] - core.coords.CoordRange - core.coords.CoordMonotonicArray + - core.coords.CoordArray + - core.coords.CoordPartial + - core.coords.CoordString - core.coords.CoordSummary - core.coords.concat_coords - get_coord @@ -234,6 +237,7 @@ reference: - proc.snap_coords - proc.sobel_filter - proc.sort_coords + - proc.split_gaps - proc.squeeze - proc.standardize - proc.taper @@ -314,12 +318,14 @@ reference: - to_timedelta64 - to_float - units.convert_units + - units.get_byte_count - units.get_factor_and_unit - units.get_filter_units - units.get_inverted_quant - units.get_quantity_str - units.get_registry - units.invert_quantity + - units.is_data_size - units.is_percent - title: IO Interfaces @@ -346,6 +352,47 @@ reference: - name: io.H5Writer members: [get_handle] + - title: Configuration + desc: Reading and setting DASCore's runtime configuration + contents: + - config.get_config + - config.set_config + - config.config_context + - config.config_attr + - config.reset_config + - config.DascoreConfig + + - title: Inventory + desc: > + The DASDAE inventory model, describing the cables, interrogators and + channels a dataset was recorded with. + contents: + - Inventory + - inventory + - core.inventory.Network + - core.inventory.Station + - core.inventory.Channel + - core.inventory.Cable + - core.inventory.FiberArray + - core.inventory.FiberSegment + - core.inventory.Interrogator + - core.inventory.OpticalPath + - core.inventory.OpticalPathAnnotation + - core.inventory.OpticalMeasurement + - core.inventory.Acquisition + - core.inventory.Connector + - core.inventory.Splice + - core.inventory.Terminator + - core.inventory.Enclosure + - core.inventory.CouplingCondition + - core.inventory.Geometry + - core.inventory.DistanceMap + - core.inventory.CoordinateReferenceSystem + - core.inventory.Response + - core.inventory.CreationInfo + - core.inventory.ExternalResource + - core.inventory.ResolvedContext + - title: Exceptions desc: Exception classes raised by DASCore contents: diff --git a/pyproject.toml b/pyproject.toml index c608bc42e..abb3f5a62 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,6 +94,7 @@ test = [ "pytest-cov>=4", "pre-commit", "pytest", + "pyyaml", # test_doc_coverage.py reads great-docs.yml "pytest-timeout", "pytest-codeblocks", "s3fs", diff --git a/recipes/contributing_to_documentation.qmd b/recipes/contributing_to_documentation.qmd index df7de1127..0a9b58a3e 100644 --- a/recipes/contributing_to_documentation.qmd +++ b/recipes/contributing_to_documentation.qmd @@ -38,10 +38,30 @@ great-docs build This will take several minutes the first time you run it. After that, the results are cached and only the changed files are re-rendered. ::: +:::{.callout-warning} +The cache is keyed on the `.qmd` source, not on the DASCore code a page imports. A page which builds its content by calling DASCore — the utilities page, the supported formats and plugins tables, the example listings — will keep showing its previous output after you change the underlying function. Delete the page's cache entry to force it to run again: + +```bash +rm -rf _freeze/utilities +``` + +A fresh checkout has no cache, so CI never sees stale output; this only bites while developing locally. +::: + The built site lands in `great-docs/_site`. To read it in a browser: ```bash great-docs preview ``` +## Documenting new public API + +The API reference is curated rather than generated: `great-docs.yml` lists the objects it documents, grouped by task. That means adding a public function does not add it to the docs, so `tests/test_doc_coverage.py` walks the public functions and classes DASCore defines and fails when one is represented nowhere. Its failure message names the missing objects and your options, which are to add a `reference:` entry, let it be rendered on the utilities page by putting it in `dascore.utils`, or record it as deliberately undocumented in that test file with a reason. + +The same test checks that reference entries still resolve, that class `members:` lists name real methods, and that every public method and property of a documented class is covered. Run it on its own while editing docs: + +```bash +pytest tests/test_doc_coverage.py +``` + Narrative pages live in the top-level section directories (`tutorial/`, `recipes/`, `notes/`, `contributing/`, `about/`), and `index.qmd` is the landing page. Adding a `.qmd` file to one of those directories adds a page to that section. The API reference is generated from DASCore's docstrings, so changing a docstring is enough to change the reference; which objects appear there, along with the site's structure and styling, is configured in `great-docs.yml`. diff --git a/tests/test_doc_coverage.py b/tests/test_doc_coverage.py new file mode 100644 index 000000000..91448245d --- /dev/null +++ b/tests/test_doc_coverage.py @@ -0,0 +1,394 @@ +""" +Tests that every public object in DASCore is represented in the documentation. + +The API reference in great-docs.yml is curated: entries are grouped by task +rather than mirroring the package layout. Curation reads better than a generated +dump, but it means new public API is invisible in the docs until someone lists +it, and nothing about adding a function makes that omission noticeable. These +tests compare DASCore's public surface against everything the docs cover and +fail when an object is represented nowhere. + +An object counts as covered when it is listed in the reference, rendered on the +utilities page, shown in the supported formats table, or named below as +deliberately undocumented. + +Scope: the functions and classes a module defines or re-exports, and the public +methods and properties of documented classes. Constants and type aliases are +not checked, since they are rendered inline in signatures rather than given +pages of their own. +""" + +from __future__ import annotations + +import importlib +import inspect +import pkgutil +from pathlib import Path + +import pytest + +import dascore as dc +from dascore.io.core import FiberIO +from dascore.utils.docs import iter_public + +# Not every job that collects this suite installs the docs/test extras; the +# free-threaded and WASM workflows install pytest alone. +yaml = pytest.importorskip("yaml") + +CONFIG_PATH = Path(dc.__file__).parents[1] / "great-docs.yml" + +# The package whose public objects are rendered onto a single page rather than +# given a reference entry each. Must match utilities/index.qmd. +SINGLE_PAGE_PACKAGE = "dascore.utils" + +# Modules whose contents are deliberately absent from the API reference. A +# trailing ".*" exempts the submodules but not the module itself, so public API +# added to dascore/io/__init__.py is still checked while reader internals +# several levels down are not. +UNREFERENCED_MODULES = { + "dascore.compat": "Shims over numpy/scipy, not DASCore's own API.", + "dascore.constants": "Type aliases and constants, rendered inline in signatures.", + "dascore.io.*": ( + "Format reader internals. IO meant for users is re-exported at " + "dascore.io and listed in the reference; the readers themselves appear " + "in the supported formats table on about/supported_formats.qmd." + ), +} + +# Individual objects deliberately absent, where the module they live in is +# otherwise documented. +UNREFERENCED_OBJECTS = { + "dascore.core.coords.ensure_consistent_dtype": "Coord construction helper.", + "dascore.core.coords.get_compatible_values": "Coord construction helper.", + "dascore.core.summary.normalize_source_patch_id": "Summary internal.", +} + +# Class members which are mechanism rather than API: pydantic validators run +# during model construction and are never called by hand. Keyed by the class's +# path in great-docs.yml, and inherited by subclasses. +UNREFERENCED_MEMBERS = { + "PatchAttrs.reject_coordinate_attributes": "Pydantic validator.", + "proc.BaseCoord.check_time_units": "Pydantic validator.", +} + +MISSING_MSG = """ +{count} public object(s) appear nowhere in the documentation: + +{listing} + +Every public object needs one of: + * an entry in the `reference:` section of great-docs.yml (the usual fix), + * an entry in that file's `exclude:` list, if discovery should skip it, + * a home in {package}, whose public objects are all rendered + automatically onto the utilities page, + * an entry in UNREFERENCED_MODULES or UNREFERENCED_OBJECTS in this file, + with a short reason, if it is public but intentionally undocumented. +""" + + +def _load_config() -> dict: + """Return the parsed great-docs configuration.""" + return yaml.safe_load(CONFIG_PATH.read_text()) + + +def _walk_modules(package) -> list[str]: + """Return importable module names in a package, skipping private paths.""" + out = [package.__name__] + prefix = f"{package.__name__}." + for info in pkgutil.walk_packages(package.__path__, prefix=prefix): + if not any(part.startswith("_") for part in info.name.split(".")): + out.append(info.name) + return out + + +def _resolve(dotted: str): + """ + Getattr-walk a dascore-relative dotted path, returning None if unreachable. + + Reference entries must be reachable this way, not merely importable: griffe + resolves them with getattr, and one unreachable entry drops the whole + reference to static analysis. + """ + obj = dc + for part in dotted.split("."): + obj = getattr(obj, part, None) + if obj is None: + return None + return obj + + +def _key(obj): + """Return a hashable identity for an object, or None if it has none.""" + obj = inspect.unwrap(obj) + try: + hash(obj) + except TypeError: + return None + return obj + + +def _iter_public_safe(module_name: str) -> list: + """ + Return a module's public objects, tolerating a missing optional dependency. + + Only the absence of a third-party package is tolerated. An ImportError + naming a dascore module is a broken import, and swallowing it would drop + every object in that module from the comparison and quietly weaken the test. + """ + try: + return list(iter_public(module_name)) + except ImportError as e: + if (e.name or "").startswith("dascore"): + raise + return [] + + +def _reexports(module_name: str) -> list: + """ + Return public objects a package exposes but does not define. + + Re-exporting is how a package states what it considers public, so these are + checked even when the module the object is defined in is exempt. + """ + module = importlib.import_module(module_name) + out = [] + for name in dir(module): + if name.startswith("_"): + continue + obj = getattr(module, name) + unwrapped = inspect.unwrap(obj) + if not (inspect.isfunction(unwrapped) or inspect.isclass(unwrapped)): + continue + if getattr(unwrapped, "__module__", "") != module_name: + out.append((name, obj)) + return out + + +def _public_surface() -> dict: + """Map each public object to the dotted path of the module defining it.""" + out = {} + for module_name in _walk_modules(dc): + for name, obj in _iter_public_safe(module_name): + out.setdefault(inspect.unwrap(obj), f"{module_name}.{name}") + # Anything a package with an exempt subtree re-exports is public by + # intent, so record it under the package rather than where it is defined. + for prefix in UNREFERENCED_MODULES: + if not prefix.endswith(".*"): + continue + root = prefix[:-2] + for name, obj in _reexports(root): + out[inspect.unwrap(obj)] = f"{root}.{name}" + return out + + +def _reference_entries(config) -> list[tuple[str, list[str]]]: + """Return (dotted path, member names) for every reference entry.""" + out = [] + for group in config.get("reference", []): + for item in group.get("contents", []): + if isinstance(item, str): + out.append((item, [])) + else: + out.append((item["name"], item.get("members", []))) + return out + + +def _documented(config) -> set: + """Return every object the documentation covers.""" + out = set() + for dotted, members in _reference_entries(config): + obj = _resolve(dotted) + if obj is None: + continue + out.add(_key(obj)) + for member in members: + sub = getattr(obj, member, None) + if sub is not None: + out.add(_key(sub)) + package = importlib.import_module(SINGLE_PAGE_PACKAGE) + for module_name in _walk_modules(package): + try: + objects = list(iter_public(module_name)) + except ImportError: + continue + out.update(_key(obj) for _, obj in objects) + for dotted in config.get("exclude", []): + out.add(_key(_resolve(dotted))) + out.discard(None) + return out + + +def _accounted_members(config) -> dict: + """Map each documented class to the member names accounted for on it.""" + out: dict = {} + for dotted, members in _reference_entries(config): + obj = _resolve(dotted) + if not inspect.isclass(obj): + continue + exempt = { + name.rsplit(".", 1)[1] + for name in UNREFERENCED_MEMBERS + if name.rsplit(".", 1)[0] == dotted + } + out.setdefault(obj, set()).update(members, exempt) + return out + + +def _formats_table_entries() -> set: + """Return the (name, version) pairs listed on the supported formats page.""" + table = FiberIO.get_supported_io_table() + return set(zip(table["name"], table["version"], strict=True)) + + +def _in_formats_table(obj, entries: set) -> bool: + """ + Return True for a reader the supported formats page actually lists. + + Subclassing FiberIO is not enough: a reader only reaches the table once it + is registered, so an unregistered one is documented nowhere. + """ + if not (inspect.isclass(obj) and issubclass(obj, FiberIO)): + return False + return (getattr(obj, "name", None), getattr(obj, "version", None)) in entries + + +def _member_origin(attr) -> str: + """ + Return the module a class member comes from. + + A property has no __module__ of its own, so ask the getter it wraps; + without this every new property would look like inherited third-party + machinery and be skipped. + """ + if isinstance(attr, property): + attr = attr.fget + return getattr(attr, "__module__", "") or "" + + +def _is_exempt(dotted: str) -> bool: + """Return True if policy says this object need not be documented.""" + if dotted in UNREFERENCED_OBJECTS: + return True + module = dotted.rsplit(".", 1)[0] + for prefix in UNREFERENCED_MODULES: + if prefix.endswith(".*"): + if module.startswith(prefix[:-1]): + return True + elif module == prefix or module.startswith(f"{prefix}."): + return True + return False + + +@pytest.fixture(scope="module") +def config(): + """The parsed great-docs configuration.""" + if not CONFIG_PATH.exists(): + pytest.skip("great-docs.yml is only present in a source checkout") + return _load_config() + + +@pytest.fixture(scope="module") +def documented(config): + """Every object covered by the documentation.""" + return _documented(config) + + +@pytest.fixture(scope="module") +def surface(): + """Every public object in DASCore, mapped to where it is defined.""" + return _public_surface() + + +class TestDocCoverage: + """Ensure the curated documentation keeps pace with the public API.""" + + def test_every_public_object_is_documented(self, documented, surface): + """Public objects must be represented somewhere in the docs.""" + table = _formats_table_entries() + missing = { + dotted + for obj, dotted in surface.items() + if obj not in documented + and not _in_formats_table(obj, table) + and not _is_exempt(dotted) + } + if missing: + listing = "\n".join(f" {name}" for name in sorted(missing)) + msg = MISSING_MSG.format( + count=len(missing), listing=listing, package=SINGLE_PAGE_PACKAGE + ) + pytest.fail(msg) + + def test_reference_entries_resolve(self, config): + """ + Every reference entry must be reachable by getattr from dascore. + + The doc build fails on a deleted object, but slowly and with a less + direct message; an entry that is importable yet not attribute-reachable + does something worse, silently degrading the whole reference to static + analysis so templated docstrings render as literal placeholders. + """ + unresolved = [ + dotted + for dotted, _ in _reference_entries(config) + if _resolve(dotted) is None + ] + assert not unresolved, ( + f"great-docs.yml lists objects which no longer exist or are not " + f"reachable as attributes of dascore: {sorted(unresolved)}" + ) + + def test_listed_members_exist(self, config): + """Members named in the reference must exist on their class.""" + missing = [] + for dotted, members in _reference_entries(config): + obj = _resolve(dotted) + if obj is None: + continue + missing += [ + f"{dotted}.{m}" for m in members if getattr(obj, m, None) is None + ] + assert not missing, ( + f"great-docs.yml names members which no longer exist: {sorted(missing)}" + ) + + def test_public_members_are_documented(self, config, documented): + """ + Public members of documented classes must themselves be covered. + + A class listed with an explicit `members` list shows only those members, + so a new method is invisible unless it is added there. A member is also + covered when it is documented in its own right (patch functions are + attached to Patch as methods), when an ancestor's entry already accounts + for the name (Spool.chunk overrides the documented BaseSpool.chunk), or + when its type is documented, which is how the generated arithmetic + methods on Patch are covered: they are all instances of PatchUFunc, + whose page describes what every one of them does. + """ + accounted = _accounted_members(config) + missing = [] + for dotted, members in _reference_entries(config): + obj = _resolve(dotted) + if not inspect.isclass(obj) or not members: + continue + names = set().union(*(accounted.get(a, set()) for a in obj.__mro__)) + for name in dir(obj): + if name.startswith("_") or name in names: + continue + attr = inspect.unwrap(inspect.getattr_static(obj, name, None)) + if not _member_origin(attr).startswith("dascore"): + continue # inherited from pydantic, etc. + if _key(attr) in documented or type(attr) in documented: + continue + missing.append(f"{dotted}.{name}") + assert not missing, ( + f"Public members are missing from the `members` lists in " + f"great-docs.yml: {sorted(missing)}" + ) + + def test_exclude_list_is_current(self, config): + """Excluded names must still exist, so the list does not go stale.""" + stale = [d for d in config.get("exclude", []) if _resolve(d) is None] + assert not stale, ( + f"great-docs.yml excludes objects which no longer exist: {sorted(stale)}" + ) From 1bc68b8d0d689e91a27f4ff59d53cc4dc99892bd Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Thu, 13 Aug 2026 12:35:11 +0200 Subject: [PATCH 15/22] Document the API added since the last rebase The coverage test caught what it exists to catch: dev has since grown Patch.enrich, Spool.unselect, the inventory attach/remove/enrich methods, an inventory example pair, make_scan_payload and UnresolvedPatchError, none of which the curated reference listed. The inventory resolution helpers stay undocumented and are recorded as such; they are plumbing behind enrich rather than API, and are not re-exported. --- great-docs.yml | 8 ++++++-- tests/test_doc_coverage.py | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/great-docs.yml b/great-docs.yml index 9ef396498..50892cace 100644 --- a/great-docs.yml +++ b/great-docs.yml @@ -145,9 +145,9 @@ reference: - name: Patch members: [data, coords, dims, attrs, shape, size, ndim, dtype, seconds, channel_count, coord_shapes, flat_dump, get_coord, get_patch_name, get_registered_namespaces, summary, T] - name: BaseSpool - members: [chunk, concatenate, get_contents, get_patch_names, get_registered_namespaces, map, select, sort, split, stack, update] + members: [chunk, concatenate, get_contents, get_patch_names, get_registered_namespaces, map, select, sort, split, stack, unselect, update] - name: Spool - members: [from_directory, from_file, chunk_plan, spool_path, indexer, has_live_patches] + members: [from_directory, from_file, attach_inventory, chunk_plan, enrich, remove_inventory, spool_path, indexer, has_live_patches] - name: PatchAttrs members: [drop, drop_private, flat_dump, from_dict, get, get_summary_df, items, new, update] - name: PatchSummary @@ -203,6 +203,7 @@ reference: - proc.drop_coords - proc.drop_private_coords - proc.dropna + - proc.enrich - proc.equals - proc.fillna - proc.flip @@ -297,6 +298,7 @@ reference: - examples.febus_dss_mine_2 - examples.forge_dss - examples.forge_dts + - examples.inventory_patch_pair - examples.nd_patch - examples.patch_with_null - examples.random_directory_spool @@ -334,6 +336,7 @@ reference: - io.FiberIO - io.PatchIO - io.ScanPayload + - io.make_scan_payload - io.dataframe_to_patch - io.patch_to_dataframe - io.obspy_to_patch @@ -428,6 +431,7 @@ reference: - exceptions.RemoteCacheError - exceptions.TimeError - exceptions.UnitError + - exceptions.UnresolvedPatchError - exceptions.UnknownExampleError - exceptions.UnknownFiberFormatError - exceptions.UnsupportedKeywordError diff --git a/tests/test_doc_coverage.py b/tests/test_doc_coverage.py index 91448245d..29cf13ad7 100644 --- a/tests/test_doc_coverage.py +++ b/tests/test_doc_coverage.py @@ -61,6 +61,10 @@ "dascore.core.coords.ensure_consistent_dtype": "Coord construction helper.", "dascore.core.coords.get_compatible_values": "Coord construction helper.", "dascore.core.summary.normalize_source_patch_id": "Summary internal.", + "dascore.core.inventory.InventoryNames": "Names the inventory machinery fills in.", + "dascore.core.inventory.interval_masks": "Coverage helper for inventory resolution.", + "dascore.proc.inventory.get_attr_values": "Enrichment internal, not re-exported.", + "dascore.proc.inventory.resolve_contexts": "Enrichment internal, not re-exported.", } # Class members which are mechanism rather than API: pydantic validators run From f1d7ce9323f25637f7ac85fb64154426e4cc0fcd Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Thu, 13 Aug 2026 12:35:11 +0200 Subject: [PATCH 16/22] Keep the changelog policy test working in the new layout The test pinned the contents of docs/changelog.qmd and keyed its skip on docs/index.qmd, so on this branch it silently skipped rather than failed: the docs no longer live under docs/, and great-docs generates the changelog page from the GitHub releases, which is what preserves the published URL. Assert the policy that survives the move -- that no changelog source exists and the config still names the repository the releases come from. --- tests/test_changelog.py | 76 +++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/tests/test_changelog.py b/tests/test_changelog.py index dd4d30509..b7e5c2ad4 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -2,61 +2,77 @@ Test which enforces that DASCore keeps no changelog. Release notes are assembled from the pull requests merged since the last tag, -each of which describes its own user-facing and breaking changes. The changelog -page survives only as a stub preserving its published URL, so this test pins its -contents exactly and fails if anything is added to it. +each of which describes its own user-facing and breaking changes. The site's +changelog page is generated at build time from the GitHub releases, so no +changelog source belongs in the repository and this test fails if one appears. """ from __future__ import annotations -# E501: the expected text below is a byte-for-byte copy of a markdown page whose -# prose is deliberately not hard-wrapped; rewrapping it would break the match. -# ruff: noqa: E501 import importlib.util from pathlib import Path import pytest _REPO_ROOT = Path(__file__).resolve().parents[1] -_DOC_PATH = _REPO_ROOT / "docs" -_CHANGELOG_PATH = _DOC_PATH / "changelog.qmd" _CHECKER_PATH = _REPO_ROOT / ".github" / "scripts" / "check_pr_changelog.py" +_CONFIG_PATH = _REPO_ROOT / "great-docs.yml" -# Run wherever the docs are, skip where they are not. The sdist grafts tests but -# ships only docs/LICENSE, so the directory existing is not enough to tell the -# two apart; index.qmd is present iff the real docs tree is. Deliberately not -# keyed on changelog.qmd, or deleting the page would skip rather than fail. -_DOCS_PRESENT = (_DOC_PATH / "index.qmd").is_file() - -_EXPECTED = """# Changelog - -DASCore's changelog is the [releases page](https://github.com/DASDAE/dascore/releases), which tracks changes from one version to another. +# Directories the docs are written in, plus the repository root, which is where +# a hand-written changelog would most likely land. +_DOC_DIRS = ("about", "contributing", "docs", "notes", "recipes", "tutorial") -This page remains only so that existing links to it keep working; it is not part of the site navigation and is never updated per pull request. Each pull request describes its own user-facing and breaking changes, and those descriptions are collected into the release notes when a version is tagged. See [publish a new release](contributing/publish_a_new_release.qmd) for that workflow. -""" +# Run wherever the docs are, skip where they are not. The sdist grafts tests but +# ships only docs/LICENSE, so a directory existing is not enough to tell the two +# apart; the landing page is present iff the real docs tree is. +_DOCS_PRESENT = (_REPO_ROOT / "index.qmd").is_file() _POLICY = ( "DASCore does not keep a changelog. Describe user-facing and breaking " "changes in the pull request that makes them, under the headings in " ".github/pull_request_template.md; they are collected into the release " - "notes when a version is tagged. See .agents/agents.md. The page itself " - "must stay exactly as pinned here, since it is published as " - "dascore.org/changelog.html." + "notes when a version is tagged. See .agents/agents.md. The published " + "dascore.org/changelog.html page is generated from those releases by " + "great-docs, so writing one here would collide with it." ) +def _changelog_sources() -> list[Path]: + """Return any file in the repository which is a changelog of its own.""" + out = [] + for name in (_REPO_ROOT.name, *_DOC_DIRS): + directory = _REPO_ROOT if name == _REPO_ROOT.name else _REPO_ROOT / name + for path in sorted(directory.glob("*")): + stem = path.name.lower() + if stem.startswith("changelog") or stem.startswith("change_log"): + out.append(path) + return out + + @pytest.mark.skipif( not _DOCS_PRESENT, reason="the docs are not present (e.g. running from an sdist)", ) -class TestChangelogIsAStub: - """The changelog page must stay a pointer to the releases page.""" - - def test_contents_are_unchanged(self): - """The page must match the expected stub exactly.""" - assert _CHANGELOG_PATH.exists(), f"{_CHANGELOG_PATH} is missing. {_POLICY}" - contents = _CHANGELOG_PATH.read_text(encoding="utf-8") - assert contents.strip() == _EXPECTED.strip(), _POLICY +class TestNoChangelogSource: + """The changelog must come from the releases, not from a file.""" + + def test_no_changelog_page(self): + """No changelog source file may exist in the docs or repo root.""" + found = _changelog_sources() + assert not found, f"{[str(p) for p in found]} should not exist. {_POLICY}" + + def test_release_notes_are_configured(self): + """ + The generated page needs the repository it draws releases from. + + Dropping `repo` from the configuration would silently take the + changelog page with it, leaving dascore.org/changelog.html a 404. + """ + text = _CONFIG_PATH.read_text(encoding="utf-8") + assert "\nrepo:" in text, ( + f"great-docs.yml must set `repo:` so the changelog page is " + f"generated from the GitHub releases. {_POLICY}" + ) def _load_checker(): From 1003ea952954651ffd4323e7ac38a36338424b9e Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Thu, 13 Aug 2026 12:53:47 +0200 Subject: [PATCH 17/22] Keep a fenced docstring example inside its own block A docstring may hold a code block of its own, and compose_docstring's does. Wrapping it in a fence of the same length ended the block at the example's opening fence: the example body rendered as prose and the rest of the page, including the next entry's anchor, was swallowed by the next fence pandoc met. Pass an already-fenced example through, demoting an executable `{python}` cell to a plain block so the page shows it rather than running it, and size the wrapper fences around whatever the content contains. The anchor repointing learns the same lesson from the other direction: the id pandoc derives from a heading is lowercased, so `Patch.T` lands at `#t`, and a member the page does not render (a dunder) has no anchor at all. --- dascore/utils/docs.py | 29 +++++++++++++++++++++++--- scripts/greatdocs_alias_inventory.py | 15 ++++++++------ tests/test_utils/test_doc_utils.py | 31 ++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 9 deletions(-) diff --git a/dascore/utils/docs.py b/dascore/utils/docs.py index 102caddbd..cc1fb05b9 100644 --- a/dascore/utils/docs.py +++ b/dascore/utils/docs.py @@ -7,6 +7,7 @@ import logging import os import pkgutil +import re import textwrap from collections.abc import Sequence from pathlib import Path @@ -249,6 +250,18 @@ def _parse(doc: str): return Docstring(doc, parser="numpy").parse("numpy") +def _fence(text: str, char: str = "`") -> str: + """ + Return a fence long enough to enclose text carrying fences of its own. + + Docstrings are markdown, so one may hold a code block or a callout; a + fence of the usual three would be closed by the first one inside and the + rest of the page would render as its contents. + """ + longest = max((len(m) for m in re.findall(f"{char}+", text)), default=0) + return char * max(3, longest + 1) + + def _render_sections(sections, types: dict[str, str]) -> tuple[str, list[str]]: """Return the summary line and the collapsible body blocks.""" summary, blocks = "", [] @@ -287,7 +300,16 @@ def _render_sections(sections, types: dict[str, str]) -> tuple[str, list[str]]: blocks.append("**Raises:** " + "; ".join(items)) elif kind == "examples": for _, text in sec.value: - blocks.append("```python\n" + str(text).strip() + "\n```") + body = str(text).strip() + # An example which is already a code block keeps its own + # fence; wrapping it would show the fence as content. A + # `{python}` cell is demoted to a plain block, since the page + # displays examples rather than running them. + if body.startswith("```"): + blocks.append(re.sub(r"^(`{3,})\{python\}", r"\1python", body)) + else: + fence = _fence(body) + blocks.append(f"{fence}python\n{body}\n{fence}") elif kind in {"attributes", "other parameters"}: label = "Attribute" if kind == "attributes" else "Parameter" rows = [f"| {label} | Type | Description |", "|---|---|---|"] @@ -347,12 +369,13 @@ def render_module_api(module_name: str) -> str: if summary: out.append(f"{summary}\n") if blocks: + fence = _fence("\n".join(blocks), ":") out.append( - '::: {.callout-note collapse="true" appearance="simple" ' + f'{fence} {{.callout-note collapse="true" appearance="simple" ' 'title="Details"}\n' ) out.extend(b + "\n" for b in blocks) - out.append(":::\n") + out.append(f"{fence}\n") return "\n".join(out) diff --git a/scripts/greatdocs_alias_inventory.py b/scripts/greatdocs_alias_inventory.py index 52023fdc1..a4087fb54 100644 --- a/scripts/greatdocs_alias_inventory.py +++ b/scripts/greatdocs_alias_inventory.py @@ -114,21 +114,24 @@ def main() -> None: # 0. Point uris at anchors the rendered pages actually emit. great-docs # records `Patch.html#dascore.Patch.data`, but quarto gives the member - # section the short id `#data`; an object which owns its whole page - # (write.html) has no anchor for itself and needs none. This runs first - # so the aliases added below copy the corrected uris. + # section the id pandoc derives from its heading: the short name, + # lowercased (`Patch.T` lands at `#t`). An object which owns its whole + # page (write.html), and a private member the page does not render at + # all, are honestly linked at the top of the page instead. This runs + # first so the aliases added below copy the corrected uris. rewritten = 0 for item in items: uri = item.get("uri", "") page, sep, fragment = uri.partition("#") - if not sep or not page.startswith("reference/") or "." not in fragment: + if not sep or not page.startswith("reference/"): continue page_object = page[len("reference/") : -len(".html")] qualname = fragment.removeprefix("dascore.") - if qualname == page_object: # the object owns the page + member = qualname.split(".")[-1] + if qualname == page_object or member.startswith("_"): new_uri = page else: - new_uri = f"{page}#{qualname.split('.')[-1]}" + new_uri = f"{page}#{member.lower()}" if new_uri != uri: item["uri"] = new_uri rewritten += 1 diff --git a/tests/test_utils/test_doc_utils.py b/tests/test_utils/test_doc_utils.py index bcf504fc5..b6b149ad7 100644 --- a/tests/test_utils/test_doc_utils.py +++ b/tests/test_utils/test_doc_utils.py @@ -204,4 +204,35 @@ def test_griffe_models_never_reach_the_page(self): # ChunkPlan documents an Attributes section, which has its own model. markdown = render_module_api("dascore.utils.chunk_plan") assert "object at 0x" not in markdown + + def test_an_example_which_is_a_code_block_stays_one_block(self): + """A fenced example must not close the fence the page wraps it in.""" + # compose_docstring's example is itself a fenced block. Wrapping it in + # a fence of the same length ends the block at the example's own + # opening fence, so the example body lands outside any block and the + # rest of the page is swallowed by the next fence it meets. + markdown = render_module_api("dascore.utils.docs") + inside, fence = set(), "" + for line in markdown.splitlines(): + if line.startswith("```") and not fence: + fence = line[: len(line) - len(line.lstrip("`"))] + elif fence and line.strip() == fence: + fence = "" + elif fence: + inside.add(line) + assert not fence, "a code block was left open" + assert "from dascore.utils.docs import compose_docstring" in inside + + def test_examples_are_shown_rather_than_executed(self): + """A `{python}` cell would run when the page is rendered.""" + markdown = render_package_api("dascore.utils") + assert "```{python}" not in markdown + + def test_every_callout_is_closed(self): + """An unclosed callout swallows the entries which follow it.""" + markdown = render_package_api("dascore.utils") + lines = markdown.splitlines() + opened = sum(1 for line in lines if line.startswith(":::") and "{" in line) + closed = sum(1 for line in lines if set(line.strip()) == {":"}) + assert opened == closed assert "| Attribute | Type | Description |" in markdown From bfb494a555e604591e7804a55ab540c400ce9d3a Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Thu, 13 Aug 2026 13:16:45 +0200 Subject: [PATCH 18/22] Close the gaps a review found in the doc coverage tests Each of these let a real omission pass. A helper defined in dascore/utils/__init__.py counted as covered while the utilities page, which walked only the submodules, rendered neither it nor its anchor; the page and the test now walk the package the same way. A class listed with an explicit empty `members` list was skipped rather than checked, so emptying one would silently undocument every member. An ImportError naming an installed package -- a misspelled `from numpy import ...` -- was swallowed as a missing optional dependency, dropping every object in that module from the comparison. The changelog scan hard-coded its directories, missing both the utilities section and anything nested, and accepted `repo:` with no value even though an empty one takes the generated changelog page with it. A reader was counted as listed on the formats page when it merely shared a registered reader's name and version, rather than being the registered one. --- dascore/utils/docs.py | 26 ++++++--- scripts/greatdocs_alias_inventory.py | 18 +++---- tests/test_changelog.py | 40 +++++++++----- tests/test_doc_coverage.py | 79 +++++++++++++++++----------- 4 files changed, 101 insertions(+), 62 deletions(-) diff --git a/dascore/utils/docs.py b/dascore/utils/docs.py index cc1fb05b9..54c07e5bc 100644 --- a/dascore/utils/docs.py +++ b/dascore/utils/docs.py @@ -379,6 +379,21 @@ def render_module_api(module_name: str) -> str: return "\n".join(out) +def iter_package_modules(package_name: str): + """ + Yield the importable name of a package and each public module in it. + + The package itself is included: a helper defined in its ``__init__`` is + as public as one in a submodule, and leaving it out would document + neither it nor an anchor to link to it. + """ + package = importlib.import_module(package_name) + yield package_name + for info in pkgutil.walk_packages(package.__path__, prefix=f"{package_name}."): + if not any(part.startswith("_") for part in info.name.split(".")): + yield info.name + + def render_package_api(package_name: str, skip_empty: bool = True) -> str: """ Render the public API of every module in a package as markdown. @@ -394,19 +409,16 @@ def render_package_api(package_name: str, skip_empty: bool = True) -> str: skip_empty If True, omit modules which define no public objects. """ - package = importlib.import_module(package_name) out = [] - for info in pkgutil.walk_packages(package.__path__, prefix=f"{package_name}."): - if any(part.startswith("_") for part in info.name.split(".")): - continue + for name in iter_package_modules(package_name): try: - body = render_module_api(info.name) + body = render_module_api(name) except ImportError: # an optional dependency the doc env lacks continue if skip_empty and not body.strip(): continue - out.append(f"### {info.name} {{#{get_doc_anchor(info.name)}}}\n") - module_doc = inspect.getdoc(importlib.import_module(info.name)) or "" + out.append(f"### {name} {{#{get_doc_anchor(name)}}}\n") + module_doc = inspect.getdoc(importlib.import_module(name)) or "" if module_doc: out.append(" ".join(module_doc.split("\n\n")[0].split()) + "\n") out.append(body) diff --git a/scripts/greatdocs_alias_inventory.py b/scripts/greatdocs_alias_inventory.py index a4087fb54..3d32ad20f 100644 --- a/scripts/greatdocs_alias_inventory.py +++ b/scripts/greatdocs_alias_inventory.py @@ -21,7 +21,6 @@ from __future__ import annotations -import importlib import inspect import json import os @@ -217,25 +216,20 @@ def add_alias(name: str, target: dict) -> None: # 5. The utilities page documents every helper in dascore.utils on one # page, so point cross references at the anchor of each entry rather # than a page that does not exist. - import pkgutil + from dascore.utils.docs import get_doc_anchor, iter_package_modules, iter_public - from dascore.utils.docs import get_doc_anchor, iter_public - - utils = importlib.import_module("dascore.utils") add_alias("dascore.utils", {"role": "module", "uri": UTILITIES_PAGE}) - for info in pkgutil.walk_packages(utils.__path__, prefix="dascore.utils."): - if any(part.startswith("_") for part in info.name.split(".")): - continue + for module_name in iter_package_modules("dascore.utils"): try: - members = list(iter_public(info.name)) + members = list(iter_public(module_name)) except ImportError: continue if not members: continue - page = f"{UTILITIES_PAGE}#{get_doc_anchor(info.name)}" - add_alias(info.name, {"role": "module", "uri": page, "dispname": "-"}) + page = f"{UTILITIES_PAGE}#{get_doc_anchor(module_name)}" + add_alias(module_name, {"role": "module", "uri": page, "dispname": "-"}) for name, obj in members: - dotted = f"{info.name}.{name}" + dotted = f"{module_name}.{name}" uri = f"{UTILITIES_PAGE}#{get_doc_anchor(dotted)}" role = "class" if inspect.isclass(obj) else "function" add_alias(dotted, {"role": role, "uri": uri, "dispname": "-"}) diff --git a/tests/test_changelog.py b/tests/test_changelog.py index b7e5c2ad4..9d905f693 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -10,6 +10,7 @@ from __future__ import annotations import importlib.util +import re from pathlib import Path import pytest @@ -18,9 +19,11 @@ _CHECKER_PATH = _REPO_ROOT / ".github" / "scripts" / "check_pr_changelog.py" _CONFIG_PATH = _REPO_ROOT / "great-docs.yml" -# Directories the docs are written in, plus the repository root, which is where -# a hand-written changelog would most likely land. -_DOC_DIRS = ("about", "contributing", "docs", "notes", "recipes", "tutorial") +# The directories the docs are written in, read from the configuration so a new +# section is searched too, plus `docs` (assets the sections draw on) and the +# repository root, which is where a hand-written changelog would most likely +# land. +_SECTION_RE = re.compile(r"^\s+dir:\s*(\S+)\s*$", re.MULTILINE) # Run wherever the docs are, skip where they are not. The sdist grafts tests but # ships only docs/LICENSE, so a directory existing is not enough to tell the two @@ -37,16 +40,25 @@ ) +def _doc_directories() -> list[Path]: + """Return the repository root and every directory a section is built from.""" + config = _CONFIG_PATH.read_text(encoding="utf-8") + dirs = {"docs", *_SECTION_RE.findall(config)} + return [_REPO_ROOT, *(_REPO_ROOT / name for name in sorted(dirs))] + + def _changelog_sources() -> list[Path]: - """Return any file in the repository which is a changelog of its own.""" + """Return any file in the docs which is a changelog of its own.""" out = [] - for name in (_REPO_ROOT.name, *_DOC_DIRS): - directory = _REPO_ROOT if name == _REPO_ROOT.name else _REPO_ROOT / name - for path in sorted(directory.glob("*")): - stem = path.name.lower() - if stem.startswith("changelog") or stem.startswith("change_log"): + for directory in _doc_directories(): + # The root is searched shallowly (its subdirectories are the sections, + # searched in their own right); a section, all the way down. + paths = directory.glob("*") if directory == _REPO_ROOT else directory.rglob("*") + for path in paths: + name = path.name.lower() + if name.startswith(("changelog", "change_log")): out.append(path) - return out + return sorted(out) @pytest.mark.skipif( @@ -69,9 +81,11 @@ def test_release_notes_are_configured(self): changelog page with it, leaving dascore.org/changelog.html a 404. """ text = _CONFIG_PATH.read_text(encoding="utf-8") - assert "\nrepo:" in text, ( - f"great-docs.yml must set `repo:` so the changelog page is " - f"generated from the GitHub releases. {_POLICY}" + match = re.search(r'^repo:\s*"?(\S+?)"?\s*$', text, re.MULTILINE) + repo = match.group(1) if match else "" + assert "github.com" in repo, ( + f"great-docs.yml must set `repo:` to the GitHub repository the " + f"changelog page is generated from, not {repo!r}. {_POLICY}" ) diff --git a/tests/test_doc_coverage.py b/tests/test_doc_coverage.py index 29cf13ad7..7b93a31cf 100644 --- a/tests/test_doc_coverage.py +++ b/tests/test_doc_coverage.py @@ -21,6 +21,7 @@ from __future__ import annotations import importlib +import importlib.util import inspect import pkgutil from pathlib import Path @@ -29,7 +30,7 @@ import dascore as dc from dascore.io.core import FiberIO -from dascore.utils.docs import iter_public +from dascore.utils.docs import iter_package_modules, iter_public # Not every job that collects this suite installs the docs/test extras; the # free-threaded and WASM workflows install pytest alone. @@ -62,7 +63,7 @@ "dascore.core.coords.get_compatible_values": "Coord construction helper.", "dascore.core.summary.normalize_source_patch_id": "Summary internal.", "dascore.core.inventory.InventoryNames": "Names the inventory machinery fills in.", - "dascore.core.inventory.interval_masks": "Coverage helper for inventory resolution.", + "dascore.core.inventory.interval_masks": "Inventory coverage helper.", "dascore.proc.inventory.get_attr_values": "Enrichment internal, not re-exported.", "dascore.proc.inventory.resolve_contexts": "Enrichment internal, not re-exported.", } @@ -135,18 +136,30 @@ def _iter_public_safe(module_name: str) -> list: """ Return a module's public objects, tolerating a missing optional dependency. - Only the absence of a third-party package is tolerated. An ImportError - naming a dascore module is a broken import, and swallowing it would drop - every object in that module from the comparison and quietly weaken the test. + Only a package which is not installed at all is tolerated. An ImportError + naming a dascore module, or naming an installed one (a misspelled `from + numpy import ...`), is a broken import; swallowing it would drop every + object in that module from the comparison and quietly weaken the test. """ try: return list(iter_public(module_name)) except ImportError as e: - if (e.name or "").startswith("dascore"): + name = e.name or "" + if name.startswith("dascore") or _is_installed(name): raise return [] +def _is_installed(module_name: str) -> bool: + """Return True if the named package can be found in the environment.""" + if not module_name: + return True + try: + return importlib.util.find_spec(module_name.split(".")[0]) is not None + except (ImportError, ValueError): + return True + + def _reexports(module_name: str) -> list: """ Return public objects a package exposes but does not define. @@ -185,15 +198,21 @@ def _public_surface() -> dict: return out -def _reference_entries(config) -> list[tuple[str, list[str]]]: - """Return (dotted path, member names) for every reference entry.""" +def _reference_entries(config) -> list[tuple[str, list[str] | None]]: + """ + Return (dotted path, member names) for every reference entry. + + Members are None for an entry which does not name them, which is how + great-docs is told to document them all; an entry naming an empty list + documents none of them, and is checked like any other explicit list. + """ out = [] for group in config.get("reference", []): for item in group.get("contents", []): if isinstance(item, str): - out.append((item, [])) + out.append((item, None)) else: - out.append((item["name"], item.get("members", []))) + out.append((item["name"], item.get("members"))) return out @@ -205,17 +224,14 @@ def _documented(config) -> set: if obj is None: continue out.add(_key(obj)) - for member in members: + for member in members or []: sub = getattr(obj, member, None) if sub is not None: out.add(_key(sub)) - package = importlib.import_module(SINGLE_PAGE_PACKAGE) - for module_name in _walk_modules(package): - try: - objects = list(iter_public(module_name)) - except ImportError: - continue - out.update(_key(obj) for _, obj in objects) + # Walked the way the page renders it, so the two cannot disagree about + # which modules are covered. + for module_name in iter_package_modules(SINGLE_PAGE_PACKAGE): + out.update(_key(obj) for _, obj in _iter_public_safe(module_name)) for dotted in config.get("exclude", []): out.add(_key(_resolve(dotted))) out.discard(None) @@ -234,26 +250,29 @@ def _accounted_members(config) -> dict: for name in UNREFERENCED_MEMBERS if name.rsplit(".", 1)[0] == dotted } - out.setdefault(obj, set()).update(members, exempt) + out.setdefault(obj, set()).update(members or [], exempt) return out def _formats_table_entries() -> set: - """Return the (name, version) pairs listed on the supported formats page.""" - table = FiberIO.get_supported_io_table() - return set(zip(table["name"], table["version"], strict=True)) + """Return the reader classes the supported formats page lists.""" + FiberIO.get_supported_io_table() # loads the plugins the table is built from + return { + type(fiberio) + for versions in FiberIO.manager._format_version.values() + for fiberio in versions.values() + } -def _in_formats_table(obj, entries: set) -> bool: +def _in_formats_table(obj, readers: set) -> bool: """ Return True for a reader the supported formats page actually lists. - Subclassing FiberIO is not enough: a reader only reaches the table once it - is registered, so an unregistered one is documented nowhere. + Subclassing FiberIO is not enough, and neither is sharing a registered + reader's name and version: the table lists the reader the registry holds, + so an unregistered one is documented nowhere. """ - if not (inspect.isclass(obj) and issubclass(obj, FiberIO)): - return False - return (getattr(obj, "name", None), getattr(obj, "version", None)) in entries + return obj in readers def _member_origin(attr) -> str: @@ -350,7 +369,7 @@ def test_listed_members_exist(self, config): if obj is None: continue missing += [ - f"{dotted}.{m}" for m in members if getattr(obj, m, None) is None + f"{dotted}.{m}" for m in members or [] if getattr(obj, m, None) is None ] assert not missing, ( f"great-docs.yml names members which no longer exist: {sorted(missing)}" @@ -373,7 +392,7 @@ def test_public_members_are_documented(self, config, documented): missing = [] for dotted, members in _reference_entries(config): obj = _resolve(dotted) - if not inspect.isclass(obj) or not members: + if not inspect.isclass(obj) or members is None: continue names = set().union(*(accounted.get(a, set()) for a in obj.__mro__)) for name in dir(obj): From 2bdfa7a5fc6e498ca1f8df8bf26b0ff0f18149bb Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Thu, 13 Aug 2026 13:34:54 +0200 Subject: [PATCH 19/22] Document the spool inventory and fiber-selection API Rebasing picked up Patch.unselect, Spool.conform_to_inventory and Spool.split_by, none of which the curated reference listed. The placement helpers behind them, and the directory loader dc.inventory() reaches, stay undocumented and are recorded as such. --- great-docs.yml | 3 ++- tests/test_doc_coverage.py | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/great-docs.yml b/great-docs.yml index 50892cace..d20cbdbda 100644 --- a/great-docs.yml +++ b/great-docs.yml @@ -147,7 +147,7 @@ reference: - name: BaseSpool members: [chunk, concatenate, get_contents, get_patch_names, get_registered_namespaces, map, select, sort, split, stack, unselect, update] - name: Spool - members: [from_directory, from_file, attach_inventory, chunk_plan, enrich, remove_inventory, spool_path, indexer, has_live_patches] + members: [from_directory, from_file, attach_inventory, chunk_plan, conform_to_inventory, enrich, remove_inventory, split_by, spool_path, indexer, has_live_patches] - name: PatchAttrs members: [drop, drop_private, flat_dump, from_dict, get, get_summary_df, items, new, update] - name: PatchSummary @@ -244,6 +244,7 @@ reference: - proc.taper - proc.taper_range - proc.transpose + - proc.unselect - proc.update - proc.update_attrs - proc.update_coords diff --git a/tests/test_doc_coverage.py b/tests/test_doc_coverage.py index 7b93a31cf..be77d4216 100644 --- a/tests/test_doc_coverage.py +++ b/tests/test_doc_coverage.py @@ -66,6 +66,13 @@ "dascore.core.inventory.interval_masks": "Inventory coverage helper.", "dascore.proc.inventory.get_attr_values": "Enrichment internal, not re-exported.", "dascore.proc.inventory.resolve_contexts": "Enrichment internal, not re-exported.", + "dascore.proc.inventory.PlacedRow": "Inventory placement internal.", + "dascore.proc.inventory.RowEpochs": "Inventory placement internal.", + "dascore.proc.inventory.channel_placements": "Inventory placement internal.", + "dascore.proc.inventory.resolve_channel_pieces": "Inventory placement internal.", + "dascore.proc.inventory.resolve_row_epochs": "Inventory placement internal.", + "dascore.proc.inventory.resolve_split_pieces": "Inventory placement internal.", + "dascore.core.inventory_loader.load_directory": "Reached through dc.inventory().", } # Class members which are mechanism rather than API: pydantic validators run From dfcc9ed526727ff8c5430bc23246c6645cbe94e0 Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Thu, 13 Aug 2026 13:49:35 +0200 Subject: [PATCH 20/22] Say so when the docstring renderer's parser is missing griffe parses the docstrings the utilities page is built from, and it arrives with the doc build rather than with dascore, so the minimal dependency, free-threaded and WASM jobs do not have it. Two things went wrong there: the render tests errored instead of skipping, and render_package_api swallowed the ImportError as a module with a missing optional dependency, so the whole page came back empty without a word. Import griffe through optional_import, guard the module import alone, and skip the render tests where griffe is absent. --- dascore/utils/docs.py | 15 +++++++++++---- tests/test_utils/test_doc_utils.py | 8 ++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/dascore/utils/docs.py b/dascore/utils/docs.py index 54c07e5bc..c3d219e32 100644 --- a/dascore/utils/docs.py +++ b/dascore/utils/docs.py @@ -242,12 +242,15 @@ def _param_types(obj) -> dict[str, str]: def _parse(doc: str): """Parse a numpydoc docstring into griffe sections.""" - from griffe import Docstring # noqa: PLC0415 + from dascore.utils.misc import optional_import # noqa: PLC0415 + + # griffe ships with the doc build rather than with dascore. + griffe = optional_import("griffe", required_for="rendering the API docs") # Griffe logs a warning for every parameter documented without a type, # which is DASCore's house style (types come from the annotations). logging.getLogger("griffe").setLevel(logging.ERROR) - return Docstring(doc, parser="numpy").parse("numpy") + return griffe.Docstring(doc, parser="numpy").parse("numpy") def _fence(text: str, char: str = "`") -> str: @@ -412,13 +415,17 @@ def render_package_api(package_name: str, skip_empty: bool = True) -> str: out = [] for name in iter_package_modules(package_name): try: - body = render_module_api(name) + module = importlib.import_module(name) except ImportError: # an optional dependency the doc env lacks continue + # Rendering is deliberately outside the guard: a module which cannot + # be imported is skipped, but a renderer which cannot run would + # otherwise empty the page without saying so. + body = render_module_api(name) if skip_empty and not body.strip(): continue out.append(f"### {name} {{#{get_doc_anchor(name)}}}\n") - module_doc = inspect.getdoc(importlib.import_module(name)) or "" + module_doc = inspect.getdoc(module) or "" if module_doc: out.append(" ".join(module_doc.split("\n\n")[0].split()) + "\n") out.append(body) diff --git a/tests/test_utils/test_doc_utils.py b/tests/test_utils/test_doc_utils.py index b6b149ad7..aecfe961e 100644 --- a/tests/test_utils/test_doc_utils.py +++ b/tests/test_utils/test_doc_utils.py @@ -2,6 +2,7 @@ from __future__ import annotations +import importlib.util import textwrap import pandas as pd @@ -162,6 +163,13 @@ def test_example_no_cross_ref(self): class TestRenderApi: """Tests for rendering a module's API onto one documentation page.""" + # griffe parses the docstrings and ships with the doc build, not with + # dascore; the minimal-dependency, free-threaded and WASM jobs lack it. + pytestmark = pytest.mark.skipif( + importlib.util.find_spec("griffe") is None, + reason="griffe is only installed with the doc build", + ) + @pytest.fixture(scope="class") def misc_markdown(self): """Rendered markdown for a module with a mix of documented objects.""" From 7218e922624c4b3a2c9f8290112bda495e38a20b Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Thu, 13 Aug 2026 14:20:37 +0200 Subject: [PATCH 21/22] Render docstrings without the branches nothing reaches The renderer carried three guards no docstring in the package reaches: a fallback for a signature inspect cannot read, which every function and class it documents has, and a text branch and a string branch for section shapes griffe's numpy parser does not produce. Fold the two text cases into one, let an unreadable signature fail the build rather than half-render, and drop unhandled sections outright, which is what the model-valued ones already do. The one guard that does earn its place, skipping a module whose optional dependency is missing, now has a test. --- dascore/utils/docs.py | 22 ++++++++-------------- tests/test_utils/test_doc_utils.py | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/dascore/utils/docs.py b/dascore/utils/docs.py index c3d219e32..abbe5bcd2 100644 --- a/dascore/utils/docs.py +++ b/dascore/utils/docs.py @@ -202,10 +202,7 @@ def _fmt_default(value) -> str: def _signature(obj) -> str: """Render a signature without the quoting artifacts of string annotations.""" - try: - sig = inspect.signature(obj) - except (TypeError, ValueError): - return getattr(obj, "__name__", "?") + "(...)" + sig = inspect.signature(obj) parts, seen_kw_only = [], False for p in sig.parameters.values(): if p.kind is p.KEYWORD_ONLY and not seen_kw_only: @@ -229,10 +226,7 @@ def _signature(obj) -> str: def _param_types(obj) -> dict[str, str]: """Map parameter name to its annotation, for the parameter table.""" - try: - sig = inspect.signature(obj) - except (TypeError, ValueError): - return {} + sig = inspect.signature(obj) return { p.name: _fmt_annotation(p.annotation) for p in sig.parameters.values() @@ -272,12 +266,11 @@ def _render_sections(sections, types: dict[str, str]) -> tuple[str, list[str]]: kind = sec.kind.value if kind == "text": text = str(sec.value).strip() - if not summary: + if not summary: # the first line of the first block is the summary first, _, rest = text.partition("\n\n") summary = " ".join(first.split()) - if rest.strip(): - blocks.append(rest.strip()) - else: + text = rest.strip() + if text: blocks.append(text) elif kind == "parameters": rows = ["| Parameter | Type | Description |", "|---|---|---|"] @@ -327,8 +320,9 @@ def _render_sections(sections, types: dict[str, str]) -> tuple[str, list[str]]: elif kind == "admonition": body = getattr(sec.value, "description", sec.value) blocks.append(f"**{sec.title or 'Note'}:** {str(body).strip()}") - elif isinstance(sec.value, str): - blocks.append(sec.value.strip()) + # Any other section is dropped rather than rendered: griffe parses + # several into models of their own, whose repr on the page would be + # worse than their absence. return summary, blocks diff --git a/tests/test_utils/test_doc_utils.py b/tests/test_utils/test_doc_utils.py index aecfe961e..c3124cce1 100644 --- a/tests/test_utils/test_doc_utils.py +++ b/tests/test_utils/test_doc_utils.py @@ -2,12 +2,14 @@ from __future__ import annotations +import importlib import importlib.util import textwrap import pandas as pd import pytest +import dascore.utils.docs as docs_module import dascore.utils.namespace as ns_module from dascore.core.attrs import PatchAttrs from dascore.examples import EXAMPLE_PATCHES @@ -236,6 +238,20 @@ def test_examples_are_shown_rather_than_executed(self): markdown = render_package_api("dascore.utils") assert "```{python}" not in markdown + def test_a_module_needing_a_missing_dependency_is_skipped(self, monkeypatch): + """One unimportable module must not take the rest of the page with it.""" + real = importlib.import_module + + def fake(name, *args, **kwargs): + if name == "dascore.utils.misc": + raise ImportError("no optional dependency here") + return real(name, *args, **kwargs) + + monkeypatch.setattr(docs_module.importlib, "import_module", fake) + markdown = render_package_api("dascore.utils") + assert "### dascore.utils.misc" not in markdown + assert "### dascore.utils.patch {#dascore-utils-patch}" in markdown + def test_every_callout_is_closed(self): """An unclosed callout swallows the entries which follow it.""" markdown = render_package_api("dascore.utils") From 63ce41251aa5e5d2c8e89e5d8841341b0877a187 Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Thu, 13 Aug 2026 14:33:05 +0200 Subject: [PATCH 22/22] Document the model layer split out of utils #891 moved the pydantic base classes and their annotated types out of dascore.utils.models into a dascore.models package, which took them off the utilities page that had been documenting them. Give them a reference section of their own, along with the two registry calls a package registering its own model would use; the rest of the tagging machinery stays internal. The package docstring links to DascoreBaseModel, so the link now resolves too. --- great-docs.yml | 15 +++++++++++++++ tests/test_doc_coverage.py | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/great-docs.yml b/great-docs.yml index d20cbdbda..08d2e3bac 100644 --- a/great-docs.yml +++ b/great-docs.yml @@ -397,6 +397,20 @@ reference: - core.inventory.ExternalResource - core.inventory.ResolvedContext + - title: Models + desc: > + The base classes DASCore's documents are built from, and the registry + which lets a serialized document name the class it holds. + contents: + - models.DascoreBaseModel + - models.InventoryModel + - models.TimeRangedModel + - models.sensible_model_equals + - models.sensible_model_hash + - models.values_equal + - models.registry.register_model + - models.registry.registered_models + - title: Exceptions desc: Exception classes raised by DASCore contents: @@ -418,6 +432,7 @@ reference: - exceptions.InvalidIndexError - exceptions.InvalidIndexVersionError - exceptions.InvalidInventoryError + - exceptions.InvalidModelTagError - exceptions.InvalidSpoolError - exceptions.InvalidSpoolQueryError - exceptions.InvalidTimeRangeError diff --git a/tests/test_doc_coverage.py b/tests/test_doc_coverage.py index be77d4216..ddfa982fa 100644 --- a/tests/test_doc_coverage.py +++ b/tests/test_doc_coverage.py @@ -73,6 +73,10 @@ "dascore.proc.inventory.resolve_row_epochs": "Inventory placement internal.", "dascore.proc.inventory.resolve_split_pieces": "Inventory placement internal.", "dascore.core.inventory_loader.load_directory": "Reached through dc.inventory().", + "dascore.models.registry.check_tag_matches": "Model tagging internal.", + "dascore.models.registry.get_model_tag": "Model tagging internal.", + "dascore.models.registry.resolve_model_tag": "Model tagging internal.", + "dascore.models.registry.resolve_tagged_model": "Model tagging internal.", } # Class members which are mechanism rather than API: pydantic validators run