diff --git a/.gitignore b/.gitignore index d32ae4e..647a13a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,9 @@ __pycache__/ # C extensions *.so +# Notebook example datasets downloaded locally +example_data/*/ + # Distribution / packaging .Python build/ diff --git a/conda/environment-ep-main.yml b/conda/environment-ep-main.yml index ff8889a..63902aa 100644 --- a/conda/environment-ep-main.yml +++ b/conda/environment-ep-main.yml @@ -12,6 +12,7 @@ dependencies: - numba # Helps ensure a recent version is installed - numpy<2 - pip + - pooch # -- holoviz -- - jupyter_bokeh - datashader diff --git a/conda/environment.yml b/conda/environment.yml index 7d86500..6bd6644 100644 --- a/conda/environment.yml +++ b/conda/environment.yml @@ -10,6 +10,7 @@ dependencies: - cartopy - scipy - numba # Helps ensure a recent version is installed + - pooch # -- holoviz -- - jupyter_bokeh - datashader diff --git a/notebooks/_toc.yml b/notebooks/_toc.yml index d5e7237..7cfb901 100644 --- a/notebooks/_toc.yml +++ b/notebooks/_toc.yml @@ -15,3 +15,4 @@ parts: - file: glider_AZFP - file: seafloor_detection - file: transient_noise + - file: resample_to_geometry diff --git a/notebooks/gallery.yml b/notebooks/gallery.yml index 03012c9..c5369e0 100644 --- a/notebooks/gallery.yml +++ b/notebooks/gallery.yml @@ -52,4 +52,11 @@ repository: https://github.com/OSOceanAcoustics/echopype-examples/blob/main/notebooks/transient_noise.ipynb notebook: transient_noise.ipynb summary: Transient noise removal with echopype (two algorithms) and exploring the effects on Sv profiles. - image: images/gallery/08_transient_noise.png \ No newline at end of file + image: images/gallery/08_transient_noise.png + +- name: Regridding using a predetermined Grid + website: https://echopype-examples.readthedocs.io/en/latest/resample_to_geometry.html + repository: https://github.com/OSOceanAcoustics/echopype-examples/blob/main/notebooks/resample_to_geometry.ipynb + notebook: resample_to_geometry.ipynb + summary: Regridding using a predetermined Grid + image: images/gallery/10_resample_to_geometry.png \ No newline at end of file diff --git a/notebooks/images/gallery/10_resample_to_geometry.png b/notebooks/images/gallery/10_resample_to_geometry.png new file mode 100644 index 0000000..0ca3552 Binary files /dev/null and b/notebooks/images/gallery/10_resample_to_geometry.png differ diff --git a/notebooks/resample_to_geometry.ipynb b/notebooks/resample_to_geometry.ipynb new file mode 100644 index 0000000..7ee4a65 --- /dev/null +++ b/notebooks/resample_to_geometry.ipynb @@ -0,0 +1,4186 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1755b086", + "metadata": {}, + "source": [ + "## Resample channels to a common range geometry" + ] + }, + { + "cell_type": "markdown", + "id": "193fcd24", + "metadata": {}, + "source": [ + "```{important}\n", + "This notebook uses development-version functionality that is not yet available in the latest released version of `echopype`.\n", + "\n", + "Users need to install `echopype` from source to reproduce the examples shown here.\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "4bf4663c", + "metadata": {}, + "source": [ + "### Introduction\n", + "\n", + "Different frequencies may not share the same vertical sampling resolution or the same maximum range.\n", + "\n", + "When comparing channels directly, it is often useful to express them on a common range geometry.\n", + "\n", + "This notebook demonstrates two approaches:\n", + "\n", + "1. Resample to the exact geometry of the 200 kHz channel.\n", + "2. Resample to a custom grid using the 200 kHz spacing while extending the range support.\n", + "\n", + "The examples below also illustrate how these choices affect the final data geometry." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "6ec7b13c-3310-4f22-82b6-8c636441cf19", + "metadata": {}, + "outputs": [], + "source": [ + "import echopype as ep\n", + "import numpy as np\n", + "import pandas as pd\n", + "import xarray as xr\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from echopype.commongrid import resample_to_geometry" + ] + }, + { + "cell_type": "markdown", + "id": "2dd1f5b5-7d8b-43d5-bc86-0455ca36c512", + "metadata": {}, + "source": [ + "#### Load an EK80 dataset\n", + "\n", + "We first load a multi-frequency EK80 dataset and compute calibrated volume backscattering strength (`Sv`).\n", + "\n", + "Depth is then added to the dataset to simplify comparisons between channels with different acquisition geometries." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "2d0b2ac9-4fba-4337-8f41-6e4edef56676", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
<xarray.Dataset> Size: 926MB\n", + "Dimensions: (channel: 5, ping_time: 213,\n", + " range_sample: 36198, filenames: 1)\n", + "Coordinates:\n", + " * channel (channel) object 40B 'WBT 400140-15 ES120-...\n", + " * ping_time (ping_time) datetime64[ns] 2kB 2023-08-11T...\n", + " * range_sample (range_sample) int64 290kB 0 1 ... 36197\n", + " * filenames (filenames) int64 8B 0\n", + "Data variables: (12/26)\n", + " Sv (channel, ping_time, range_sample) float64 308MB ...\n", + " echo_range (channel, ping_time, range_sample) float64 308MB ...\n", + " tau_effective (channel) float64 40B 0.0009239 ... 0.0009306\n", + " frequency_nominal (channel) float64 40B 1.2e+05 ... 2e+05\n", + " sound_speed float64 8B 1.48e+03\n", + " sound_absorption (channel) float64 40B 0.03281 ... 0.0463\n", + " ... ...\n", + " impedance_transducer (channel) float64 40B 75.0 75.0 ... 75.0 75.0\n", + " impedance_transceiver (channel) int64 40B 5400 5400 5400 5400 5400\n", + " receiver_sampling_frequency (channel) float64 40B 1.5e+06 ... 1.5e+06\n", + " source_filenames (filenames) <U82 328B 's3://noaa-wcsd-pds/...\n", + " water_level float64 8B 0.0\n", + " depth (channel, ping_time, range_sample) float64 308MB ...\n", + "Attributes:\n", + " processing_software_name: echopype\n", + " processing_software_version: 0.11.2.dev22+gc1a2a5660\n", + " processing_time: 2026-06-11T02:14:04+00:00\n", + " processing_function: calibrate.compute_Sv
<xarray.Dataset> Size: 926MB\n", + "Dimensions: (ping_time: 213, range_sample: 36198, channel: 5)\n", + "Coordinates:\n", + " * ping_time (ping_time) datetime64[ns] 2kB 2023-08-11T16:57:27.277...\n", + " * range_sample (range_sample) int64 290kB 0 1 2 3 ... 36195 36196 36197\n", + " * channel (channel) <U25 500B 'WBT 400140-15 ES120-7C_ES' ... 'W...\n", + "Data variables:\n", + " Sv (channel, ping_time, range_sample) float64 308MB dask.array<chunksize=(1, 213, 36198), meta=np.ndarray>\n", + " echo_range (channel, ping_time, range_sample) float64 308MB dask.array<chunksize=(5, 213, 36198), meta=np.ndarray>\n", + " frequency_nominal (channel) float64 40B dask.array<chunksize=(1,), meta=np.ndarray>\n", + " water_level float64 8B 0.0\n", + " depth (channel, ping_time, range_sample) float64 308MB dask.array<chunksize=(5, 213, 36198), meta=np.ndarray>\n", + "Attributes:\n", + " processing_software_name: echopype\n", + " processing_software_version: 0.11.2.dev22+gc1a2a5660\n", + " processing_time: 2026-06-11T02:14:52+00:00\n", + " processing_function: commongrid.resample_to_geometry
<xarray.DataArray 'echo_range' (ping_time: 213, range_sample: 36198)> Size: 62MB\n", + "array([[0. , 0.02367923, 0.04735847, ..., nan, nan,\n", + " nan],\n", + " [0. , 0.02367923, 0.04735847, ..., nan, nan,\n", + " nan],\n", + " [0. , 0.02367923, 0.04735847, ..., nan, nan,\n", + " nan],\n", + " ...,\n", + " [0. , 0.02367923, 0.04735847, ..., nan, nan,\n", + " nan],\n", + " [0. , 0.02367923, 0.04735847, ..., nan, nan,\n", + " nan],\n", + " [0. , 0.02367923, 0.04735847, ..., nan, nan,\n", + " nan]], shape=(213, 36198))\n", + "Coordinates:\n", + " * ping_time (ping_time) datetime64[ns] 2kB 2023-08-11T16:57:27.277163 ....\n", + " * range_sample (range_sample) int64 290kB 0 1 2 3 ... 36194 36195 36196 36197
<xarray.Dataset> Size: 926MB\n", + "Dimensions: (ping_time: 213, range_sample: 36198, channel: 5)\n", + "Coordinates:\n", + " * ping_time (ping_time) datetime64[ns] 2kB 2023-08-11T16:57:27.277...\n", + " * range_sample (range_sample) int64 290kB 0 1 2 3 ... 36195 36196 36197\n", + " * channel (channel) <U25 500B 'WBT 400140-15 ES120-7C_ES' ... 'W...\n", + "Data variables:\n", + " Sv (channel, ping_time, range_sample) float64 308MB dask.array<chunksize=(1, 213, 36198), meta=np.ndarray>\n", + " echo_range (channel, ping_time, range_sample) float64 308MB 0.0 ....\n", + " frequency_nominal (channel) float64 40B dask.array<chunksize=(1,), meta=np.ndarray>\n", + " water_level float64 8B 0.0\n", + " depth (channel, ping_time, range_sample) float64 308MB 0.0 ....\n", + "Attributes:\n", + " processing_software_name: echopype\n", + " processing_software_version: 0.11.2.dev22+gc1a2a5660\n", + " processing_time: 2026-06-11T02:15:35+00:00\n", + " processing_function: commongrid.resample_to_geometry
| \n", + " | frequency_kHz | \n", + "original_grid_max_m | \n", + "strict_200_grid_max_m | \n", + "custom_grid_max_m | \n", + "original_last_finite_Sv_m | \n", + "strict_last_finite_Sv_m | \n", + "custom_last_finite_Sv_m | \n", + "
|---|---|---|---|---|---|---|---|
| 0 | \n", + "120.0 | \n", + "749.980496 | \n", + "299.968519 | \n", + "749.992335 | \n", + "749.980496 | \n", + "299.968519 | \n", + "749.992335 | \n", + "
| 1 | \n", + "18.0 | \n", + "749.977536 | \n", + "299.968519 | \n", + "749.992335 | \n", + "749.977536 | \n", + "299.968519 | \n", + "749.992335 | \n", + "
| 2 | \n", + "70.0 | \n", + "749.980496 | \n", + "299.968519 | \n", + "749.992335 | \n", + "749.980496 | \n", + "299.968519 | \n", + "749.992335 | \n", + "
| 3 | \n", + "38.0 | \n", + "749.980496 | \n", + "299.968519 | \n", + "749.992335 | \n", + "749.980496 | \n", + "299.968519 | \n", + "749.992335 | \n", + "
| 4 | \n", + "200.0 | \n", + "299.968519 | \n", + "299.968519 | \n", + "749.992335 | \n", + "299.968519 | \n", + "299.968519 | \n", + "299.992198 | \n", + "
| \n", + " | frequency_kHz | \n", + "sample_interval_s | \n", + "expected_spacing_m | \n", + "original_spacing_m | \n", + "resampled_spacing_m | \n", + "original_max_range_m | \n", + "resampled_max_range_m | \n", + "
|---|---|---|---|---|---|---|---|
| 0 | \n", + "120.0 | \n", + "0.000040 | \n", + "0.029599 | \n", + "0.029599 | \n", + "0.023679 | \n", + "749.980496 | \n", + "299.968519 | \n", + "
| 1 | \n", + "18.0 | \n", + "0.000028 | \n", + "0.020719 | \n", + "0.020719 | \n", + "0.023679 | \n", + "749.977536 | \n", + "299.968519 | \n", + "
| 2 | \n", + "70.0 | \n", + "0.000048 | \n", + "0.035519 | \n", + "0.035519 | \n", + "0.023679 | \n", + "749.980496 | \n", + "299.968519 | \n", + "
| 3 | \n", + "38.0 | \n", + "0.000040 | \n", + "0.029599 | \n", + "0.029599 | \n", + "0.023679 | \n", + "749.980496 | \n", + "299.968519 | \n", + "
| 4 | \n", + "200.0 | \n", + "0.000032 | \n", + "0.023679 | \n", + "0.023679 | \n", + "0.023679 | \n", + "299.968519 | \n", + "299.968519 | \n", + "