diff --git a/ci/requirements/notebooks.yml b/ci/requirements/notebooks.yml index 3fe964a5..6d63de8b 100644 --- a/ci/requirements/notebooks.yml +++ b/ci/requirements/notebooks.yml @@ -15,6 +15,8 @@ dependencies: - h5py - h5netcdf - lat_lon_parser + - libgdal-hdf5 + - libgdal-netcdf - nbconvert - nc-time-axis - netCDF4 diff --git a/notebooks/classify/clutter_cloud.ipynb b/notebooks/classify/clutter_cloud.ipynb index 0aa69a33..eaf697a1 100644 --- a/notebooks/classify/clutter_cloud.ipynb +++ b/notebooks/classify/clutter_cloud.ipynb @@ -39,13 +39,6 @@ " plt.ion()" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "markdown", "metadata": {}, @@ -79,10 +72,11 @@ "metadata": {}, "outputs": [], "source": [ - "pvol = pvol.filter(lambda x: \"sweep\" in x.name)\n", + "pvol1 = pvol.match(\"sweep*\")\n", + "display(pvol1)\n", "vol = []\n", - "for sweep in pvol.values():\n", - " vol.append(sweep.ds.pipe(wrl.georef.georeference))\n", + "for sweep in pvol1.values():\n", + " vol.append(sweep.to_dataset().pipe(wrl.georef.georeference))\n", "vol = xr.concat(vol, dim=\"tilt\")\n", "vol = vol.assign_coords(sweep_mode=vol.sweep_mode)\n", "display(vol)" @@ -232,18 +226,20 @@ "\n", "ax = fig.add_subplot(131)\n", "pm = vol.DBZH[tilt].wrl.vis.plot(ax=ax)\n", - "plt.colorbar(pm, shrink=0.5)\n", + "# plt.colorbar(pm, shrink=0.5)\n", "plt.title(\"Radar reflectivity\")\n", "\n", "ax = fig.add_subplot(132)\n", "pm = vol.sat[tilt].wrl.vis.plot(ax=ax)\n", - "plt.colorbar(pm, shrink=0.5)\n", + "# plt.colorbar(pm, shrink=0.5)\n", "plt.title(\"Satellite cloud classification\")\n", "\n", "ax = fig.add_subplot(133)\n", "pm = vol.clutter[tilt].wrl.vis.plot(ax=ax)\n", - "plt.colorbar(pm, shrink=0.5)\n", - "plt.title(\"Detected clutter\")" + "# plt.colorbar(pm, shrink=0.5)\n", + "plt.title(\"Detected clutter\")\n", + "\n", + "fig.tight_layout()" ] } ], @@ -258,7 +254,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.0" + "version": "3.12.4" }, "toc": { "colors": { diff --git a/notebooks/fileio/backends/cfradial1_backend.ipynb b/notebooks/fileio/backends/cfradial1_backend.ipynb index d69dbba0..f4ede5d8 100644 --- a/notebooks/fileio/backends/cfradial1_backend.ipynb +++ b/notebooks/fileio/backends/cfradial1_backend.ipynb @@ -36,7 +36,6 @@ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import xradar as xd\n", - "import datatree as xt\n", "import xarray as xr\n", "\n", "try:\n", @@ -225,7 +224,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.0" + "version": "3.12.4" } }, "nbformat": 4, diff --git a/notebooks/fileio/backends/cfradial2_backend.ipynb b/notebooks/fileio/backends/cfradial2_backend.ipynb index 1b26713d..7e4f0895 100644 --- a/notebooks/fileio/backends/cfradial2_backend.ipynb +++ b/notebooks/fileio/backends/cfradial2_backend.ipynb @@ -34,7 +34,6 @@ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import xradar as xd\n", - "import datatree as xt\n", "import xarray as xr\n", "\n", "try:\n", @@ -58,7 +57,7 @@ "source": [ "fpath = \"netcdf/cfrad.20080604_002217_000_SPOL_v36_SUR_cfradial2.nc\"\n", "f = wrl.util.get_wradlib_data_file(fpath)\n", - "vol = xt.open_datatree(f)" + "vol = xr.open_datatree(f)" ] }, { @@ -207,7 +206,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.0" + "version": "3.12.4" } }, "nbformat": 4, diff --git a/notebooks/fileio/backends/furuno_backend.ipynb b/notebooks/fileio/backends/furuno_backend.ipynb index 411afbdf..2d2ca571 100644 --- a/notebooks/fileio/backends/furuno_backend.ipynb +++ b/notebooks/fileio/backends/furuno_backend.ipynb @@ -37,7 +37,6 @@ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import xradar as xd\n", - "import datatree as xt\n", "import xarray as xr\n", "\n", "try:\n", @@ -367,7 +366,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.0" + "version": "3.12.4" } }, "nbformat": 4, diff --git a/notebooks/fileio/backends/gamic_backend.ipynb b/notebooks/fileio/backends/gamic_backend.ipynb index 94a77f0c..6347fe74 100644 --- a/notebooks/fileio/backends/gamic_backend.ipynb +++ b/notebooks/fileio/backends/gamic_backend.ipynb @@ -35,7 +35,6 @@ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import xradar as xd\n", - "import datatree as xt\n", "import xarray as xr\n", "\n", "try:\n", @@ -220,7 +219,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.0" + "version": "3.12.4" } }, "nbformat": 4, diff --git a/notebooks/fileio/backends/iris_backend.ipynb b/notebooks/fileio/backends/iris_backend.ipynb index 4e2b2687..ac6cdc8b 100644 --- a/notebooks/fileio/backends/iris_backend.ipynb +++ b/notebooks/fileio/backends/iris_backend.ipynb @@ -37,7 +37,6 @@ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import xradar as xd\n", - "import datatree as xt\n", "import xarray as xr\n", "\n", "try:\n", @@ -213,7 +212,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.0" + "version": "3.12.4" } }, "nbformat": 4, diff --git a/notebooks/fileio/backends/odim_backend.ipynb b/notebooks/fileio/backends/odim_backend.ipynb index 21f317a4..01b70114 100644 --- a/notebooks/fileio/backends/odim_backend.ipynb +++ b/notebooks/fileio/backends/odim_backend.ipynb @@ -36,7 +36,6 @@ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import xradar as xd\n", - "import datatree as xt\n", "import xarray as xr\n", "\n", "try:\n", @@ -220,13 +219,6 @@ ")\n", "display(ts)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -240,7 +232,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.0" + "version": "3.12.4" } }, "nbformat": 4, diff --git a/notebooks/fileio/backends/rainbow_backend.ipynb b/notebooks/fileio/backends/rainbow_backend.ipynb index fbde89ec..1216e79b 100644 --- a/notebooks/fileio/backends/rainbow_backend.ipynb +++ b/notebooks/fileio/backends/rainbow_backend.ipynb @@ -37,7 +37,6 @@ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import xradar as xd\n", - "import datatree as xt\n", "import xarray as xr\n", "\n", "try:\n", @@ -213,7 +212,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.0" + "version": "3.12.4" } }, "nbformat": 4, diff --git a/notebooks/workflow/recipe4.ipynb b/notebooks/workflow/recipe4.ipynb index 08796246..a6672417 100644 --- a/notebooks/workflow/recipe4.ipynb +++ b/notebooks/workflow/recipe4.ipynb @@ -28,7 +28,7 @@ "\n", "**Note**
\n", "\n", - "The following code is based on [xarray](https://docs.xarray.dev), [xarray-datatree](https://xarray-datatree.readthedocs.io) and [xradar](https://docs.openradarscience.org/projects/xradar). It claims multiple data files and presents them in a ``DataTree``.\n", + "The following code is based on [xarray](https://docs.xarray.dev) and [xradar](https://docs.openradarscience.org/projects/xradar). It claims multiple data files and presents them in a ``DataTree``.\n", "\n", "" ] @@ -46,8 +46,7 @@ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import xarray as xr\n", - "import xradar\n", - "from datatree import DataTree, open_datatree\n", + "import xradar as xd\n", "\n", "try:\n", " get_ipython().run_line_magic(\"matplotlib inline\")\n", @@ -243,25 +242,68 @@ "reindex_angle = dict(\n", " tolerance=1.0, start_angle=0, stop_angle=360, angle_res=1.0, direction=1\n", ")\n", - "for r, v in zip(volume_reflectivity, volume_velocity):\n", + "for i, (r, v) in enumerate(zip(volume_reflectivity, volume_velocity)):\n", " ds0 = [\n", - " xr.open_dataset(r0, engine=\"odim\", group=\"sweep_0\", reindex_angle=reindex_angle)\n", + " xr.open_dataset(\n", + " r0,\n", + " engine=\"odim\",\n", + " group=\"sweep_0\",\n", + " reindex_angle=reindex_angle,\n", + " fix_second_angle=True,\n", + " )\n", " for r0 in r\n", " ]\n", + " ds0 = [r0.assign_coords(sweep_mode=r0.sweep_mode.min()) for r0 in ds0]\n", " ds1 = [\n", - " xr.open_dataset(v0, engine=\"odim\", group=\"sweep_0\", reindex_angle=reindex_angle)\n", + " xr.open_dataset(\n", + " v0,\n", + " engine=\"odim\",\n", + " group=\"sweep_0\",\n", + " reindex_angle=reindex_angle,\n", + " fix_second_angle=True,\n", + " )\n", " for v0 in v\n", " ]\n", - " ds = xr.concat(\n", - " [\n", - " xr.merge([r0, v0], compat=\"override\").assign(volume_time=r0.time.min())\n", - " for r0, v0 in zip(ds0, ds1)\n", - " ],\n", - " \"volume_time\",\n", - " )\n", - " dsl.append(ds)\n", - "\n", - "dsl.insert(0, xr.open_dataset(volume_reflectivity[0][0], group=\"/\"))" + " ds1 = [r1.assign_coords(sweep_mode=r1.sweep_mode.min()) for r1 in ds1]\n", + " ds2 = [\n", + " xr.merge([r0, v0], compat=\"no_conflicts\").assign(\n", + " volume_time=r0.time.min().dt.floor(\"5min\")\n", + " )\n", + " for r0, v0 in zip(ds0, ds1)\n", + " ]\n", + " ds2 = [r2.wrl.georef.georeference() for r2 in ds2]\n", + " ds = xr.concat(ds2, \"volume_time\")\n", + " dsl.append(ds)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dsl[0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dtree = {\"/\": xd.io.backends.common._get_required_root_dataset(dsl, optional=False)}\n", + "for i, swp in enumerate(dsl):\n", + " dsl[i][\"sweep_number\"] = i\n", + "dtree = xd.io.backends.common._attach_sweep_groups(dtree, dsl)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "vol = xr.DataTree.from_dict(dtree)" ] }, { @@ -270,12 +312,7 @@ "metadata": {}, "outputs": [], "source": [ - "tree = DataTree(data=xradar.io.backends.common._assign_root(dsl), name=\"root\")\n", - "vol = xradar.io.backends.common._attach_sweep_groups(tree, dsl[1:])\n", - "for i, swp in enumerate(vol.groups[1:]):\n", - " vol[swp][\"sweep_number\"] = i\n", - "# sets arbitrary volume_time in root group to enable isel over groups\n", - "vol = vol.assign_coords(volume_time=vol[\"sweep_0\"].volume_time)" + "display(vol)" ] }, { @@ -328,6 +365,25 @@ "vol[\"sweep_0\"].isel(volume_time=0)" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "vol.match(\"sweep*\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "swp = vol[\"sweep_0\"].isel(volume_time=0).ds\n", + "swp.sweep_fixed_angle.values" + ] + }, { "cell_type": "code", "execution_count": null, @@ -338,11 +394,10 @@ " 4, 3, figsize=(20, 30), sharex=True, sharey=True, constrained_layout=True\n", ")\n", "\n", - "for i, grp in enumerate(vol.groups[1:]):\n", + "for i, grp in enumerate(vol.match(\"sweep_*\")):\n", + " ax = gs.flat[i]\n", " swp = vol[grp].isel(volume_time=0).ds\n", - " swp = swp.assign_coords(sweep_mode=swp.sweep_mode)\n", - " swp.DBZH.wrl.georef.georeference().wrl.vis.plot(ax=gs.flat[i], fig=fig)\n", - " ax = plt.gca()\n", + " swp.DBZH.wrl.vis.plot(ax=ax, fig=fig)\n", " ax.set_title(swp.sweep_fixed_angle.values)\n", "\n", "fig.delaxes(gs.flat[-2])\n", @@ -366,11 +421,10 @@ " 4, 3, figsize=(20, 30), sharex=True, sharey=True, constrained_layout=True\n", ")\n", "\n", - "for i, grp in enumerate(vol.groups[1:]):\n", + "for i, grp in enumerate(vol.match(\"sweep_*\")):\n", + " ax = gs.flat[i]\n", " swp = vol[grp].isel(volume_time=0).ds\n", - " swp = swp.assign_coords(sweep_mode=swp.sweep_mode)\n", - " swp.VRADH.wrl.georef.georeference().wrl.vis.plot(ax=gs.flat[i], fig=fig)\n", - " ax = plt.gca()\n", + " swp.VRADH.wrl.vis.plot(ax=ax, fig=fig)\n", " ax.set_title(swp.sweep_fixed_angle.values)\n", "\n", "fig.delaxes(gs.flat[-2])\n", @@ -391,9 +445,7 @@ "outputs": [], "source": [ "vol0 = vol.isel(volume_time=0)\n", - "swp = vol0[\"sweep_9\"].ds\n", - "# need to assign sweep_mode as coordinate\n", - "swp = swp.assign_coords(sweep_mode=swp.sweep_mode)" + "swp = vol0[\"sweep_9\"].ds" ] }, { @@ -407,8 +459,8 @@ "import cartopy.feature as cfeature\n", "\n", "map_trans = ccrs.AzimuthalEquidistant(\n", - " central_latitude=vol0.root.ds.latitude.values,\n", - " central_longitude=vol0.root.ds.longitude.values,\n", + " central_latitude=swp.latitude.values,\n", + " central_longitude=swp.longitude.values,\n", ")" ] }, @@ -419,8 +471,8 @@ "outputs": [], "source": [ "map_proj = ccrs.AzimuthalEquidistant(\n", - " central_latitude=vol0.root.ds.latitude.values,\n", - " central_longitude=vol0.root.ds.longitude.values,\n", + " central_latitude=swp.latitude.values,\n", + " central_longitude=swp.longitude.values,\n", ")\n", "\n", "pm = swp.DBZH.wrl.georef.georeference().wrl.vis.plot(crs=map_proj)\n", @@ -435,7 +487,7 @@ "metadata": {}, "outputs": [], "source": [ - "map_proj = ccrs.Mercator(central_longitude=vol0.root.ds.longitude.values)\n", + "map_proj = ccrs.Mercator(central_longitude=swp.longitude.values)\n", "fig = plt.figure(figsize=(10, 8))\n", "ax = fig.add_subplot(111, projection=map_proj)\n", "pm = swp.DBZH.wrl.georef.georeference().wrl.vis.plot(ax=ax)\n", @@ -450,8 +502,8 @@ "source": [ "fig = plt.figure(figsize=(10, 8))\n", "proj = ccrs.AzimuthalEquidistant(\n", - " central_latitude=vol0.root.ds.latitude.values,\n", - " central_longitude=vol0.root.ds.longitude.values,\n", + " central_latitude=swp.latitude.values,\n", + " central_longitude=swp.longitude.values,\n", ")\n", "ax = fig.add_subplot(111, projection=proj)\n", "pm = swp.DBZH.wrl.georef.georeference().wrl.vis.plot(ax=ax)\n", @@ -530,7 +582,7 @@ "metadata": {}, "outputs": [], "source": [ - "xradar.io.to_odim(vol0, \"dwd_odim.h5\", source=\"RAD:DWD\")" + "xd.io.to_odim(vol0, \"dwd_odim.h5\", source=\"RAD:DWD\")" ] }, { @@ -548,7 +600,7 @@ "metadata": {}, "outputs": [], "source": [ - "xradar.io.to_cfradial2(vol0, \"dwd_cfradial2.nc\")" + "xd.io.to_cfradial2(vol0, \"dwd_cfradial2.nc\")" ] }, { @@ -564,7 +616,7 @@ "metadata": {}, "outputs": [], "source": [ - "vol1 = xradar.io.open_odim_datatree(\"dwd_odim.h5\")\n", + "vol1 = xd.io.open_odim_datatree(\"dwd_odim.h5\")\n", "display(vol1)" ] }, @@ -574,7 +626,7 @@ "metadata": {}, "outputs": [], "source": [ - "vol2 = open_datatree(\"dwd_cfradial2.nc\")\n", + "vol2 = xr.open_datatree(\"dwd_cfradial2.nc\")\n", "display(vol2)" ] }