{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Managing Information Loss with xarray operations\n", "\n", "Sometimes, you can lose important information from your dataset when performing operations.\n", "You will likely want to keep track of the attributes, `nodata`, and `CRS`.\n", "\n", "API Reference:\n", "\n", "- [rio.to_raster()](../rioxarray.rst#rioxarray.raster_dataset.RasterDataset.to_raster)\n", "- [rio.write_crs()](../rioxarray.rst#rioxarray.rioxarray.XRasterBase.write_crs)\n", "- [rio.write_transform()](../rioxarray.rst#rioxarray.rioxarray.XRasterBase.write_transform)\n", "- [rio.update_attrs()](../rioxarray.rst#rioxarray.rioxarray.XRasterBase.update_attrs)\n", "- [rio.update_encoding()](../rioxarray.rst#rioxarray.rioxarray.XRasterBase.update_encoding)\n", "- [rio.crs](../rioxarray.rst#rioxarray.rioxarray.XRasterBase.crs)\n", "- [rio.nodata](../rioxarray.rst#rioxarray.raster_array.RasterArray.nodata)\n", "- [rio.encoded_nodata](../rioxarray.rst#rioxarray.raster_array.RasterArray.encoded_nodata)\n", "- [rio.write_nodata](../rioxarray.rst#rioxarray.raster_array.RasterArray.write_nodata)\n", "- [rio.transform()](../rioxarray.rst#rioxarray.rioxarray.XRasterBase.transform)\n", "\n", "Note that `write_transform` is only needed if you are not saving the x,y coordinates. It is for\n", "GDAL to be able to read in the transform without needing the original coordinates and is useful\n", "if you read in the file with `parse_coordinates=False`." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import rioxarray\n", "import xarray" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "See docs for [rioxarray.open_rasterio](../rioxarray.rst#rioxarray-open-rasterio)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "rds = rioxarray.open_rasterio(\n", " \"../../test/test_data/input/PLANET_SCOPE_3D.nc\",\n", " variable=[\"green\"],\n", " mask_and_scale=True,\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice the original data:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "({'nodata': 0, 'units': ('DN', 'DN')},\n", " {'dtype': 'float64',\n", " 'grid_mapping': 'spatial_ref',\n", " 'scale_factor': 1.0,\n", " 'add_offset': 0.0,\n", " '_FillValue': nan,\n", " 'source': 'netcdf:../../test/test_data/input/PLANET_SCOPE_3D.nc:green'},\n", " CRS.from_epsg(32722),\n", " nan)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rds.green.attrs, rds.green.encoding, rds.green.rio.crs, rds.green.rio.nodata" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice how information is lost in the operation:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "({}, {}, CRS.from_epsg(32722), None)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "new_ds = rds.green + rds.green\n", "new_ds.attrs, new_ds.encoding, new_ds.rio.crs, new_ds.rio.nodata" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To preserve attributes, xarray has [set_options](http://xarray.pydata.org/en/stable/generated/xarray.set_options.html#xarray-set-options) with `keep_attrs=True`. However, it does not preserve the encoding." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "({'nodata': 0, 'units': ('DN', 'DN')}, {}, CRS.from_epsg(32722), 0.0)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "with xarray.set_options(keep_attrs=True):\n", " new_ds = rds.green + rds.green\n", "new_ds.attrs, new_ds.encoding, new_ds.rio.crs, new_ds.rio.nodata" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another solution is to save the original attributes and then copy them over\n", "once the operation is complete:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "({'nodata': 0, 'units': ('DN', 'DN')},\n", " {'grid_mapping': 'spatial_ref',\n", " 'dtype': 'float64',\n", " 'scale_factor': 1.0,\n", " 'add_offset': 0.0,\n", " '_FillValue': nan,\n", " 'source': 'netcdf:../../test/test_data/input/PLANET_SCOPE_3D.nc:green'},\n", " CRS.from_epsg(32722),\n", " nan)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "new_ds = rds.green + rds.green\n", "new_ds.rio.write_crs(rds.green.rio.crs, inplace=True)\n", "new_ds.rio.update_attrs(rds.green.attrs, inplace=True)\n", "new_ds.rio.update_encoding(rds.green.encoding, inplace=True)\n", "new_ds.attrs, new_ds.encoding, new_ds.rio.crs, new_ds.rio.nodata" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "new_ds.rio.to_raster(\"combination_keep_attrs.tif\")" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\"bounds\": [466266.0, 8084670.0, 466296.0, 8084700.0], \"colorinterp\": [\"gray\", \"undefined\"], \"count\": 2, \"crs\": \"EPSG:32722\", \"descriptions\": [\"green\", \"green\"], \"driver\": \"GTiff\", \"dtype\": \"float64\", \"height\": 10, \"indexes\": [1, 2], \"interleave\": \"pixel\", \"lnglat\": [-51.31732641226951, -17.322997474192466], \"mask_flags\": [[\"nodata\"], [\"nodata\"]], \"nodata\": NaN, \"res\": [3.0, 3.0], \"shape\": [10, 10], \"tiled\": false, \"transform\": [3.0, 0.0, 466266.0, 0.0, -3.0, 8084700.0, 0.0, 0.0, 1.0], \"units\": [null, null], \"width\": 10}\n" ] } ], "source": [ "!rio info combination_keep_attrs.tif" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.8" } }, "nbformat": 4, "nbformat_minor": 4 }