{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "1c58cff8",
   "metadata": {},
   "source": [
    "# Walkthrough\n",
    "\n",
    "> *To get it, you first see it, and then let it go*\n",
    "\n",
    "In this tutorial 🧑‍🏫, we'll step through an Earth Observation 🛰️ data pipeline\n",
    "using ``torchdata`` and by the end of this lesson, you should be able to:\n",
    "- Find Cloud-Optimized GeoTIFFs (COGs) from STAC catalogs 🥞\n",
    "- Construct a DataPipe that iteratively reads several COGs in a stream 🌊\n",
    "- Loop through batches of images in a DataPipe with a DataLoader 🏋️\n",
    "\n",
    "## 🎉 **Getting started**\n",
    "\n",
    "These are the tools 🛠️ you'll need."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "237f9ec0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Geospatial libraries\n",
    "import pystac\n",
    "import planetary_computer\n",
    "import rioxarray\n",
    "# Deep Learning libraries\n",
    "import torch\n",
    "import torchdata\n",
    "import zen3geo"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c24c07b",
   "metadata": {},
   "source": [
    "Just to make sure we’re on the same page 📃,\n",
    "let’s check that we’ve got compatible versions installed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "32728b15",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "pystac version: 1.4.0\n",
      "planetary-computer version: 0.4.6\n",
      "torch version: 1.11.0+cu102\n",
      "torchdata version: 0.3.0\n",
      "zen3geo version: 0.1.0+4d1fa95\n",
      "rioxarray (0.11.1) deps:\n",
      "  rasterio: 1.2.10\n",
      "    xarray: 2022.3.0\n",
      "      GDAL: 3.3.2\n",
      "      GEOS: None\n",
      "      PROJ: None\n",
      " PROJ DATA: None\n",
      " GDAL DATA: None\n",
      "\n",
      "Other python deps:\n",
      "     scipy: None\n",
      "    pyproj: 3.3.1\n",
      "\n",
      "System:\n",
      "    python: 3.9.13 (main, Jun  1 2022, 20:52:48)  [GCC 11.2.0]\n",
      "executable: /home/docs/checkouts/readthedocs.org/user_builds/zen3geo/envs/v0.1.0/bin/python\n",
      "   machine: Linux-5.15.0-1004-aws-x86_64-with-glibc2.35\n"
     ]
    }
   ],
   "source": [
    "print(f\"pystac version: {pystac.__version__}\")\n",
    "print(f\"planetary-computer version: {planetary_computer.__version__}\")\n",
    "print(f\"torch version: {torch.__version__}\")\n",
    "\n",
    "print(f\"torchdata version: {torchdata.__version__}\")\n",
    "print(f\"zen3geo version: {zen3geo.__version__}\")\n",
    "rioxarray.show_versions()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "af2436aa",
   "metadata": {},
   "source": [
    "## 0️⃣ Find [Cloud-Optimized GeoTIFFs](https://www.cogeo.org) 🗺️\n",
    "\n",
    "Let's get some optical satellite data using [STAC](https://stacspec.org)!\n",
    "How about Sentinel-2 L2A data over Singapore 🇸🇬?\n",
    "\n",
    "🔗 Links:\n",
    "- [Official Sentinel-2 description page at ESA](https://sentinel.esa.int/web/sentinel/missions/sentinel-2)\n",
    "- [Microsoft Planetary Computer STAC Explorer](https://planetarycomputer.microsoft.com/explore?c=103.8152%2C1.3338&z=10.08&v=2&d=sentinel-2-l2a&s=false%3A%3A100%3A%3Atrue&ae=0&m=cql%3A2ff1401acb50731fa0a6d1e2a46f3064&r=Natural+color)\n",
    "- [AWS Sentinel-2 Cloud-Optimized GeoTIFFs](https://registry.opendata.aws/sentinel-2-l2a-cogs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "f794cc0d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Item id=S2A_MSIL2A_20220115T032101_R118_T48NUG_20220115T170435>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "item_url = \"https://planetarycomputer.microsoft.com/api/stac/v1/collections/sentinel-2-l2a/items/S2A_MSIL2A_20220115T032101_R118_T48NUG_20220115T170435\"\n",
    "\n",
    "# Load the individual item metadata and sign the assets\n",
    "item = pystac.Item.from_file(item_url)\n",
    "signed_item = planetary_computer.sign(item)\n",
    "signed_item"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4dd43b04",
   "metadata": {},
   "source": [
    "### Inspect one of the data assets 🍱\n",
    "\n",
    "The Sentinel-2 STAC item contains several assets.\n",
    "These include different 🌈 bands (e.g. 'B02', 'B03', 'B04').\n",
    "Let's just use the 'visual' product for now which includes the RGB bands."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "9e5906ee",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
       "<defs>\n",
       "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
       "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
       "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
       "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
       "</symbol>\n",
       "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
       "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
       "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
       "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
       "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
       "</symbol>\n",
       "</defs>\n",
       "</svg>\n",
       "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n",
       " *\n",
       " */\n",
       "\n",
       ":root {\n",
       "  --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
       "  --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n",
       "  --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n",
       "  --xr-border-color: var(--jp-border-color2, #e0e0e0);\n",
       "  --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n",
       "  --xr-background-color: var(--jp-layout-color0, white);\n",
       "  --xr-background-color-row-even: var(--jp-layout-color1, white);\n",
       "  --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
       "}\n",
       "\n",
       "html[theme=dark],\n",
       "body.vscode-dark {\n",
       "  --xr-font-color0: rgba(255, 255, 255, 1);\n",
       "  --xr-font-color2: rgba(255, 255, 255, 0.54);\n",
       "  --xr-font-color3: rgba(255, 255, 255, 0.38);\n",
       "  --xr-border-color: #1F1F1F;\n",
       "  --xr-disabled-color: #515151;\n",
       "  --xr-background-color: #111111;\n",
       "  --xr-background-color-row-even: #111111;\n",
       "  --xr-background-color-row-odd: #313131;\n",
       "}\n",
       "\n",
       ".xr-wrap {\n",
       "  display: block !important;\n",
       "  min-width: 300px;\n",
       "  max-width: 700px;\n",
       "}\n",
       "\n",
       ".xr-text-repr-fallback {\n",
       "  /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n",
       "  display: none;\n",
       "}\n",
       "\n",
       ".xr-header {\n",
       "  padding-top: 6px;\n",
       "  padding-bottom: 6px;\n",
       "  margin-bottom: 4px;\n",
       "  border-bottom: solid 1px var(--xr-border-color);\n",
       "}\n",
       "\n",
       ".xr-header > div,\n",
       ".xr-header > ul {\n",
       "  display: inline;\n",
       "  margin-top: 0;\n",
       "  margin-bottom: 0;\n",
       "}\n",
       "\n",
       ".xr-obj-type,\n",
       ".xr-array-name {\n",
       "  margin-left: 2px;\n",
       "  margin-right: 10px;\n",
       "}\n",
       "\n",
       ".xr-obj-type {\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-sections {\n",
       "  padding-left: 0 !important;\n",
       "  display: grid;\n",
       "  grid-template-columns: 150px auto auto 1fr 20px 20px;\n",
       "}\n",
       "\n",
       ".xr-section-item {\n",
       "  display: contents;\n",
       "}\n",
       "\n",
       ".xr-section-item input {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       ".xr-section-item input + label {\n",
       "  color: var(--xr-disabled-color);\n",
       "}\n",
       "\n",
       ".xr-section-item input:enabled + label {\n",
       "  cursor: pointer;\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-section-item input:enabled + label:hover {\n",
       "  color: var(--xr-font-color0);\n",
       "}\n",
       "\n",
       ".xr-section-summary {\n",
       "  grid-column: 1;\n",
       "  color: var(--xr-font-color2);\n",
       "  font-weight: 500;\n",
       "}\n",
       "\n",
       ".xr-section-summary > span {\n",
       "  display: inline-block;\n",
       "  padding-left: 0.5em;\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:disabled + label {\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-section-summary-in + label:before {\n",
       "  display: inline-block;\n",
       "  content: '►';\n",
       "  font-size: 11px;\n",
       "  width: 15px;\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:disabled + label:before {\n",
       "  color: var(--xr-disabled-color);\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:checked + label:before {\n",
       "  content: '▼';\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:checked + label > span {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       ".xr-section-summary,\n",
       ".xr-section-inline-details {\n",
       "  padding-top: 4px;\n",
       "  padding-bottom: 4px;\n",
       "}\n",
       "\n",
       ".xr-section-inline-details {\n",
       "  grid-column: 2 / -1;\n",
       "}\n",
       "\n",
       ".xr-section-details {\n",
       "  display: none;\n",
       "  grid-column: 1 / -1;\n",
       "  margin-bottom: 5px;\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:checked ~ .xr-section-details {\n",
       "  display: contents;\n",
       "}\n",
       "\n",
       ".xr-array-wrap {\n",
       "  grid-column: 1 / -1;\n",
       "  display: grid;\n",
       "  grid-template-columns: 20px auto;\n",
       "}\n",
       "\n",
       ".xr-array-wrap > label {\n",
       "  grid-column: 1;\n",
       "  vertical-align: top;\n",
       "}\n",
       "\n",
       ".xr-preview {\n",
       "  color: var(--xr-font-color3);\n",
       "}\n",
       "\n",
       ".xr-array-preview,\n",
       ".xr-array-data {\n",
       "  padding: 0 5px !important;\n",
       "  grid-column: 2;\n",
       "}\n",
       "\n",
       ".xr-array-data,\n",
       ".xr-array-in:checked ~ .xr-array-preview {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       ".xr-array-in:checked ~ .xr-array-data,\n",
       ".xr-array-preview {\n",
       "  display: inline-block;\n",
       "}\n",
       "\n",
       ".xr-dim-list {\n",
       "  display: inline-block !important;\n",
       "  list-style: none;\n",
       "  padding: 0 !important;\n",
       "  margin: 0;\n",
       "}\n",
       "\n",
       ".xr-dim-list li {\n",
       "  display: inline-block;\n",
       "  padding: 0;\n",
       "  margin: 0;\n",
       "}\n",
       "\n",
       ".xr-dim-list:before {\n",
       "  content: '(';\n",
       "}\n",
       "\n",
       ".xr-dim-list:after {\n",
       "  content: ')';\n",
       "}\n",
       "\n",
       ".xr-dim-list li:not(:last-child):after {\n",
       "  content: ',';\n",
       "  padding-right: 5px;\n",
       "}\n",
       "\n",
       ".xr-has-index {\n",
       "  font-weight: bold;\n",
       "}\n",
       "\n",
       ".xr-var-list,\n",
       ".xr-var-item {\n",
       "  display: contents;\n",
       "}\n",
       "\n",
       ".xr-var-item > div,\n",
       ".xr-var-item label,\n",
       ".xr-var-item > .xr-var-name span {\n",
       "  background-color: var(--xr-background-color-row-even);\n",
       "  margin-bottom: 0;\n",
       "}\n",
       "\n",
       ".xr-var-item > .xr-var-name:hover span {\n",
       "  padding-right: 5px;\n",
       "}\n",
       "\n",
       ".xr-var-list > li:nth-child(odd) > div,\n",
       ".xr-var-list > li:nth-child(odd) > label,\n",
       ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
       "  background-color: var(--xr-background-color-row-odd);\n",
       "}\n",
       "\n",
       ".xr-var-name {\n",
       "  grid-column: 1;\n",
       "}\n",
       "\n",
       ".xr-var-dims {\n",
       "  grid-column: 2;\n",
       "}\n",
       "\n",
       ".xr-var-dtype {\n",
       "  grid-column: 3;\n",
       "  text-align: right;\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-var-preview {\n",
       "  grid-column: 4;\n",
       "}\n",
       "\n",
       ".xr-var-name,\n",
       ".xr-var-dims,\n",
       ".xr-var-dtype,\n",
       ".xr-preview,\n",
       ".xr-attrs dt {\n",
       "  white-space: nowrap;\n",
       "  overflow: hidden;\n",
       "  text-overflow: ellipsis;\n",
       "  padding-right: 10px;\n",
       "}\n",
       "\n",
       ".xr-var-name:hover,\n",
       ".xr-var-dims:hover,\n",
       ".xr-var-dtype:hover,\n",
       ".xr-attrs dt:hover {\n",
       "  overflow: visible;\n",
       "  width: auto;\n",
       "  z-index: 1;\n",
       "}\n",
       "\n",
       ".xr-var-attrs,\n",
       ".xr-var-data {\n",
       "  display: none;\n",
       "  background-color: var(--xr-background-color) !important;\n",
       "  padding-bottom: 5px !important;\n",
       "}\n",
       "\n",
       ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
       ".xr-var-data-in:checked ~ .xr-var-data {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       ".xr-var-data > table {\n",
       "  float: right;\n",
       "}\n",
       "\n",
       ".xr-var-name span,\n",
       ".xr-var-data,\n",
       ".xr-attrs {\n",
       "  padding-left: 25px !important;\n",
       "}\n",
       "\n",
       ".xr-attrs,\n",
       ".xr-var-attrs,\n",
       ".xr-var-data {\n",
       "  grid-column: 1 / -1;\n",
       "}\n",
       "\n",
       "dl.xr-attrs {\n",
       "  padding: 0;\n",
       "  margin: 0;\n",
       "  display: grid;\n",
       "  grid-template-columns: 125px auto;\n",
       "}\n",
       "\n",
       ".xr-attrs dt,\n",
       ".xr-attrs dd {\n",
       "  padding: 0;\n",
       "  margin: 0;\n",
       "  float: left;\n",
       "  padding-right: 10px;\n",
       "  width: auto;\n",
       "}\n",
       "\n",
       ".xr-attrs dt {\n",
       "  font-weight: normal;\n",
       "  grid-column: 1;\n",
       "}\n",
       "\n",
       ".xr-attrs dt:hover span {\n",
       "  display: inline-block;\n",
       "  background: var(--xr-background-color);\n",
       "  padding-right: 10px;\n",
       "}\n",
       "\n",
       ".xr-attrs dd {\n",
       "  grid-column: 2;\n",
       "  white-space: pre-wrap;\n",
       "  word-break: break-all;\n",
       "}\n",
       "\n",
       ".xr-icon-database,\n",
       ".xr-icon-file-text2 {\n",
       "  display: inline-block;\n",
       "  vertical-align: middle;\n",
       "  width: 1em;\n",
       "  height: 1.5em !important;\n",
       "  stroke-width: 0;\n",
       "  stroke: currentColor;\n",
       "  fill: currentColor;\n",
       "}\n",
       "</style><pre class='xr-text-repr-fallback'>&lt;xarray.DataArray (band: 3, y: 10980, x: 10980)&gt;\n",
       "[361681200 values with dtype=uint8]\n",
       "Coordinates:\n",
       "  * band         (band) int64 1 2 3\n",
       "  * x            (x) float64 3e+05 3e+05 3e+05 ... 4.098e+05 4.098e+05 4.098e+05\n",
       "  * y            (y) float64 2e+05 2e+05 2e+05 ... 9.026e+04 9.026e+04 9.024e+04\n",
       "    spatial_ref  int64 0\n",
       "Attributes:\n",
       "    _FillValue:    0.0\n",
       "    scale_factor:  1.0\n",
       "    add_offset:    0.0</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'></div><ul class='xr-dim-list'><li><span class='xr-has-index'>band</span>: 3</li><li><span class='xr-has-index'>y</span>: 10980</li><li><span class='xr-has-index'>x</span>: 10980</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-0e933edf-eb56-4ac3-98e1-71f17f4fe477' class='xr-array-in' type='checkbox' checked><label for='section-0e933edf-eb56-4ac3-98e1-71f17f4fe477' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>...</span></div><div class='xr-array-data'><pre>[361681200 values with dtype=uint8]</pre></div></div></li><li class='xr-section-item'><input id='section-ed841f46-1ecd-4526-99ca-dbcb04651191' class='xr-section-summary-in' type='checkbox'  checked><label for='section-ed841f46-1ecd-4526-99ca-dbcb04651191' class='xr-section-summary' >Coordinates: <span>(4)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>band</span></div><div class='xr-var-dims'>(band)</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>1 2 3</div><input id='attrs-8cb15105-b927-4823-980d-8a63967b0fb8' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-8cb15105-b927-4823-980d-8a63967b0fb8' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-451818de-8308-4dbd-a654-c0a879d1a61e' class='xr-var-data-in' type='checkbox'><label for='data-451818de-8308-4dbd-a654-c0a879d1a61e' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([1, 2, 3])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>x</span></div><div class='xr-var-dims'>(x)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>3e+05 3e+05 ... 4.098e+05 4.098e+05</div><input id='attrs-3ff5f23b-3d98-4c91-b1b0-221d89ca7ac4' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-3ff5f23b-3d98-4c91-b1b0-221d89ca7ac4' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-9d619645-72a8-4191-badd-94d34b928df2' class='xr-var-data-in' type='checkbox'><label for='data-9d619645-72a8-4191-badd-94d34b928df2' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([300005., 300015., 300025., ..., 409775., 409785., 409795.])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>y</span></div><div class='xr-var-dims'>(y)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>2e+05 2e+05 ... 9.026e+04 9.024e+04</div><input id='attrs-2d304593-cc7f-49b6-b199-b04defbbdb36' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-2d304593-cc7f-49b6-b199-b04defbbdb36' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-367ffde9-d0e4-4699-90a2-022ac639fb40' class='xr-var-data-in' type='checkbox'><label for='data-367ffde9-d0e4-4699-90a2-022ac639fb40' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([200035., 200025., 200015., ...,  90265.,  90255.,  90245.])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>spatial_ref</span></div><div class='xr-var-dims'>()</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>0</div><input id='attrs-45d6ee72-a528-4aec-9c14-d1b296982be3' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-45d6ee72-a528-4aec-9c14-d1b296982be3' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-1a44b90f-cb58-47fd-8794-a220a3b8c045' class='xr-var-data-in' type='checkbox'><label for='data-1a44b90f-cb58-47fd-8794-a220a3b8c045' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>crs_wkt :</span></dt><dd>PROJCS[&quot;WGS 84 / UTM zone 48N&quot;,GEOGCS[&quot;WGS 84&quot;,DATUM[&quot;WGS_1984&quot;,SPHEROID[&quot;WGS 84&quot;,6378137,298.257223563,AUTHORITY[&quot;EPSG&quot;,&quot;7030&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;6326&quot;]],PRIMEM[&quot;Greenwich&quot;,0,AUTHORITY[&quot;EPSG&quot;,&quot;8901&quot;]],UNIT[&quot;degree&quot;,0.0174532925199433,AUTHORITY[&quot;EPSG&quot;,&quot;9122&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;4326&quot;]],PROJECTION[&quot;Transverse_Mercator&quot;],PARAMETER[&quot;latitude_of_origin&quot;,0],PARAMETER[&quot;central_meridian&quot;,105],PARAMETER[&quot;scale_factor&quot;,0.9996],PARAMETER[&quot;false_easting&quot;,500000],PARAMETER[&quot;false_northing&quot;,0],UNIT[&quot;metre&quot;,1,AUTHORITY[&quot;EPSG&quot;,&quot;9001&quot;]],AXIS[&quot;Easting&quot;,EAST],AXIS[&quot;Northing&quot;,NORTH],AUTHORITY[&quot;EPSG&quot;,&quot;32648&quot;]]</dd><dt><span>semi_major_axis :</span></dt><dd>6378137.0</dd><dt><span>semi_minor_axis :</span></dt><dd>6356752.314245179</dd><dt><span>inverse_flattening :</span></dt><dd>298.257223563</dd><dt><span>reference_ellipsoid_name :</span></dt><dd>WGS 84</dd><dt><span>longitude_of_prime_meridian :</span></dt><dd>0.0</dd><dt><span>prime_meridian_name :</span></dt><dd>Greenwich</dd><dt><span>geographic_crs_name :</span></dt><dd>WGS 84</dd><dt><span>horizontal_datum_name :</span></dt><dd>World Geodetic System 1984</dd><dt><span>projected_crs_name :</span></dt><dd>WGS 84 / UTM zone 48N</dd><dt><span>grid_mapping_name :</span></dt><dd>transverse_mercator</dd><dt><span>latitude_of_projection_origin :</span></dt><dd>0.0</dd><dt><span>longitude_of_central_meridian :</span></dt><dd>105.0</dd><dt><span>false_easting :</span></dt><dd>500000.0</dd><dt><span>false_northing :</span></dt><dd>0.0</dd><dt><span>scale_factor_at_central_meridian :</span></dt><dd>0.9996</dd><dt><span>spatial_ref :</span></dt><dd>PROJCS[&quot;WGS 84 / UTM zone 48N&quot;,GEOGCS[&quot;WGS 84&quot;,DATUM[&quot;WGS_1984&quot;,SPHEROID[&quot;WGS 84&quot;,6378137,298.257223563,AUTHORITY[&quot;EPSG&quot;,&quot;7030&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;6326&quot;]],PRIMEM[&quot;Greenwich&quot;,0,AUTHORITY[&quot;EPSG&quot;,&quot;8901&quot;]],UNIT[&quot;degree&quot;,0.0174532925199433,AUTHORITY[&quot;EPSG&quot;,&quot;9122&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;4326&quot;]],PROJECTION[&quot;Transverse_Mercator&quot;],PARAMETER[&quot;latitude_of_origin&quot;,0],PARAMETER[&quot;central_meridian&quot;,105],PARAMETER[&quot;scale_factor&quot;,0.9996],PARAMETER[&quot;false_easting&quot;,500000],PARAMETER[&quot;false_northing&quot;,0],UNIT[&quot;metre&quot;,1,AUTHORITY[&quot;EPSG&quot;,&quot;9001&quot;]],AXIS[&quot;Easting&quot;,EAST],AXIS[&quot;Northing&quot;,NORTH],AUTHORITY[&quot;EPSG&quot;,&quot;32648&quot;]]</dd><dt><span>GeoTransform :</span></dt><dd>300000.0 10.0 0.0 200040.0 0.0 -10.0</dd></dl></div><div class='xr-var-data'><pre>array(0)</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-1bf5200c-15d8-4579-8f7b-b48e9d2c5804' class='xr-section-summary-in' type='checkbox'  checked><label for='section-1bf5200c-15d8-4579-8f7b-b48e9d2c5804' class='xr-section-summary' >Attributes: <span>(3)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'><dt><span>_FillValue :</span></dt><dd>0.0</dd><dt><span>scale_factor :</span></dt><dd>1.0</dd><dt><span>add_offset :</span></dt><dd>0.0</dd></dl></div></li></ul></div></div>"
      ],
      "text/plain": [
       "<xarray.DataArray (band: 3, y: 10980, x: 10980)>\n",
       "[361681200 values with dtype=uint8]\n",
       "Coordinates:\n",
       "  * band         (band) int64 1 2 3\n",
       "  * x            (x) float64 3e+05 3e+05 3e+05 ... 4.098e+05 4.098e+05 4.098e+05\n",
       "  * y            (y) float64 2e+05 2e+05 2e+05 ... 9.026e+04 9.026e+04 9.024e+04\n",
       "    spatial_ref  int64 0\n",
       "Attributes:\n",
       "    _FillValue:    0.0\n",
       "    scale_factor:  1.0\n",
       "    add_offset:    0.0"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "url: str = signed_item.assets[\"visual\"].href\n",
    "da = rioxarray.open_rasterio(filename=url)\n",
    "da"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a91cef0",
   "metadata": {},
   "source": [
    "This is how the Sentinel-2 image looks like over Singapore on 15 Jan 2022.\n",
    "\n",
    "![Sentinel-2 image over Singapore on 20220115](https://planetarycomputer.microsoft.com/api/data/v1/item/preview.png?collection=sentinel-2-l2a&item=S2A_MSIL2A_20220115T032101_R118_T48NUG_20220115T170435&assets=visual&asset_bidx=visual%7C1%2C2%2C3&nodata=0)\n",
    "\n",
    "## 1️⃣ Construct [DataPipe](https://github.com/pytorch/data/tree/v0.3.0#what-are-datapipes) 📡\n",
    "\n",
    "A torch `DataPipe` is a way of composing data (rather than inheriting data).\n",
    "Yes, I don't know what it really means either, so here's some extra reading.\n",
    "\n",
    "🔖 References:\n",
    "- https://pytorch.org/blog/pytorch-1.11-released/#introducing-torchdata\n",
    "- https://github.com/pytorch/data/tree/v0.3.0#what-are-datapipes\n",
    "- https://realpython.com/inheritance-composition-python\n",
    "\n",
    "### Create an Iterable 📏\n",
    "\n",
    "Start by wrapping a list of URLs to the Cloud-Optimized GeoTIFF files.\n",
    "We only have 1 item so we'll use ``[url]``, but if you have more, you can do\n",
    "``[url1, url2, url3]``, etc. Pass this iterable list into\n",
    "{py:class}`torchdata.datapipes.iter.IterableWrapper`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "3b9f42e2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<torch.utils.data.datapipes.iter.utils.IterableWrapperIterDataPipe at 0x7fbd90eafdc0>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dp = torchdata.datapipes.iter.IterableWrapper(iterable=[url])\n",
    "dp"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "253daf47",
   "metadata": {},
   "source": [
    "The ``dp`` variable is the DataPipe!\n",
    "Now to apply some more transformations/functions on it.\n",
    "\n",
    "### Read using RioXarrayReader 🌐\n",
    "\n",
    "This is where ☯ ``zen3geo`` comes in. We'll be using the\n",
    "{py:class}`zen3geo.datapipes.rioxarray.RioXarrayReaderIterDataPipe` class, or\n",
    "rather, the short alias {py:class}`zen3geo.datapipes.RioXarrayReader`.\n",
    "\n",
    "Confusingly, there are two ways or forms of applying ``RioXarrayReader``,\n",
    "a class-based method and a functional method."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "14d58eff",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<zen3geo.datapipes.rioxarray.RioXarrayReaderIterDataPipe at 0x7fbd90eaf9d0>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Using class constructors\n",
    "dp_rioxarray = zen3geo.datapipes.RioXarrayReader(source_datapipe=dp)\n",
    "dp_rioxarray"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "f0943f6c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<zen3geo.datapipes.rioxarray.RioXarrayReaderIterDataPipe at 0x7fbd90eaf280>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Using functional form (recommended)\n",
    "dp_rioxarray = dp.read_from_rioxarray()\n",
    "dp_rioxarray"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e985fd1c",
   "metadata": {},
   "source": [
    "Note that both ways are equivalent (they produce the same IterDataPipe output),\n",
    "but the latter (functional) form is preferred, see also\n",
    "https://pytorch.org/data/0.4.0/tutorial.html#registering-datapipes-with-the-functional-api\n",
    "\n",
    "What if you don't want the whole Sentinel-2 scene at the full 10m resolution?\n",
    "Since we're using Cloud-Optimized GeoTIFFs, you could set an ``overview_level``\n",
    "(following https://corteva.github.io/rioxarray/stable/examples/COG.html)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "03a12b23",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<zen3geo.datapipes.rioxarray.RioXarrayReaderIterDataPipe at 0x7fbdc5dfad00>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dp_rioxarray_zoom3 = dp.read_from_rioxarray(overview_level=3)\n",
    "dp_rioxarray_zoom3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eeaa0c8c",
   "metadata": {},
   "source": [
    "Extra keyword arguments will be handled by {py:func}`rioxarray.open_rasterio`\n",
    "or {py:func}`rasterio.open`.\n",
    "\n",
    "```{note}\n",
    "Other DataPipe classes/functions can be stacked or joined to this basic GeoTIFF\n",
    "reader. For example, clipping by bounding box or reprojecting to a certain\n",
    "Coordinate Reference System. If you would like to implement this, check out the\n",
    "[Contributing Guidelines](./CONTRIBUTING) to get started!\n",
    "```\n",
    "\n",
    "## 2️⃣ Loop through DataPipe ⚙️\n",
    "\n",
    "A DataPipe describes a flow of information.\n",
    "Through a series of steps it goes,\n",
    "as one piece comes in, another might follow.\n",
    "\n",
    "### Basic iteration ♻️\n",
    "\n",
    "At the most basic level, you could iterate through the DataPipe like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "6292c4cc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
       "<defs>\n",
       "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
       "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
       "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
       "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
       "</symbol>\n",
       "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
       "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
       "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
       "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
       "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
       "</symbol>\n",
       "</defs>\n",
       "</svg>\n",
       "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n",
       " *\n",
       " */\n",
       "\n",
       ":root {\n",
       "  --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
       "  --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n",
       "  --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n",
       "  --xr-border-color: var(--jp-border-color2, #e0e0e0);\n",
       "  --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n",
       "  --xr-background-color: var(--jp-layout-color0, white);\n",
       "  --xr-background-color-row-even: var(--jp-layout-color1, white);\n",
       "  --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
       "}\n",
       "\n",
       "html[theme=dark],\n",
       "body.vscode-dark {\n",
       "  --xr-font-color0: rgba(255, 255, 255, 1);\n",
       "  --xr-font-color2: rgba(255, 255, 255, 0.54);\n",
       "  --xr-font-color3: rgba(255, 255, 255, 0.38);\n",
       "  --xr-border-color: #1F1F1F;\n",
       "  --xr-disabled-color: #515151;\n",
       "  --xr-background-color: #111111;\n",
       "  --xr-background-color-row-even: #111111;\n",
       "  --xr-background-color-row-odd: #313131;\n",
       "}\n",
       "\n",
       ".xr-wrap {\n",
       "  display: block !important;\n",
       "  min-width: 300px;\n",
       "  max-width: 700px;\n",
       "}\n",
       "\n",
       ".xr-text-repr-fallback {\n",
       "  /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n",
       "  display: none;\n",
       "}\n",
       "\n",
       ".xr-header {\n",
       "  padding-top: 6px;\n",
       "  padding-bottom: 6px;\n",
       "  margin-bottom: 4px;\n",
       "  border-bottom: solid 1px var(--xr-border-color);\n",
       "}\n",
       "\n",
       ".xr-header > div,\n",
       ".xr-header > ul {\n",
       "  display: inline;\n",
       "  margin-top: 0;\n",
       "  margin-bottom: 0;\n",
       "}\n",
       "\n",
       ".xr-obj-type,\n",
       ".xr-array-name {\n",
       "  margin-left: 2px;\n",
       "  margin-right: 10px;\n",
       "}\n",
       "\n",
       ".xr-obj-type {\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-sections {\n",
       "  padding-left: 0 !important;\n",
       "  display: grid;\n",
       "  grid-template-columns: 150px auto auto 1fr 20px 20px;\n",
       "}\n",
       "\n",
       ".xr-section-item {\n",
       "  display: contents;\n",
       "}\n",
       "\n",
       ".xr-section-item input {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       ".xr-section-item input + label {\n",
       "  color: var(--xr-disabled-color);\n",
       "}\n",
       "\n",
       ".xr-section-item input:enabled + label {\n",
       "  cursor: pointer;\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-section-item input:enabled + label:hover {\n",
       "  color: var(--xr-font-color0);\n",
       "}\n",
       "\n",
       ".xr-section-summary {\n",
       "  grid-column: 1;\n",
       "  color: var(--xr-font-color2);\n",
       "  font-weight: 500;\n",
       "}\n",
       "\n",
       ".xr-section-summary > span {\n",
       "  display: inline-block;\n",
       "  padding-left: 0.5em;\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:disabled + label {\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-section-summary-in + label:before {\n",
       "  display: inline-block;\n",
       "  content: '►';\n",
       "  font-size: 11px;\n",
       "  width: 15px;\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:disabled + label:before {\n",
       "  color: var(--xr-disabled-color);\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:checked + label:before {\n",
       "  content: '▼';\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:checked + label > span {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       ".xr-section-summary,\n",
       ".xr-section-inline-details {\n",
       "  padding-top: 4px;\n",
       "  padding-bottom: 4px;\n",
       "}\n",
       "\n",
       ".xr-section-inline-details {\n",
       "  grid-column: 2 / -1;\n",
       "}\n",
       "\n",
       ".xr-section-details {\n",
       "  display: none;\n",
       "  grid-column: 1 / -1;\n",
       "  margin-bottom: 5px;\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:checked ~ .xr-section-details {\n",
       "  display: contents;\n",
       "}\n",
       "\n",
       ".xr-array-wrap {\n",
       "  grid-column: 1 / -1;\n",
       "  display: grid;\n",
       "  grid-template-columns: 20px auto;\n",
       "}\n",
       "\n",
       ".xr-array-wrap > label {\n",
       "  grid-column: 1;\n",
       "  vertical-align: top;\n",
       "}\n",
       "\n",
       ".xr-preview {\n",
       "  color: var(--xr-font-color3);\n",
       "}\n",
       "\n",
       ".xr-array-preview,\n",
       ".xr-array-data {\n",
       "  padding: 0 5px !important;\n",
       "  grid-column: 2;\n",
       "}\n",
       "\n",
       ".xr-array-data,\n",
       ".xr-array-in:checked ~ .xr-array-preview {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       ".xr-array-in:checked ~ .xr-array-data,\n",
       ".xr-array-preview {\n",
       "  display: inline-block;\n",
       "}\n",
       "\n",
       ".xr-dim-list {\n",
       "  display: inline-block !important;\n",
       "  list-style: none;\n",
       "  padding: 0 !important;\n",
       "  margin: 0;\n",
       "}\n",
       "\n",
       ".xr-dim-list li {\n",
       "  display: inline-block;\n",
       "  padding: 0;\n",
       "  margin: 0;\n",
       "}\n",
       "\n",
       ".xr-dim-list:before {\n",
       "  content: '(';\n",
       "}\n",
       "\n",
       ".xr-dim-list:after {\n",
       "  content: ')';\n",
       "}\n",
       "\n",
       ".xr-dim-list li:not(:last-child):after {\n",
       "  content: ',';\n",
       "  padding-right: 5px;\n",
       "}\n",
       "\n",
       ".xr-has-index {\n",
       "  font-weight: bold;\n",
       "}\n",
       "\n",
       ".xr-var-list,\n",
       ".xr-var-item {\n",
       "  display: contents;\n",
       "}\n",
       "\n",
       ".xr-var-item > div,\n",
       ".xr-var-item label,\n",
       ".xr-var-item > .xr-var-name span {\n",
       "  background-color: var(--xr-background-color-row-even);\n",
       "  margin-bottom: 0;\n",
       "}\n",
       "\n",
       ".xr-var-item > .xr-var-name:hover span {\n",
       "  padding-right: 5px;\n",
       "}\n",
       "\n",
       ".xr-var-list > li:nth-child(odd) > div,\n",
       ".xr-var-list > li:nth-child(odd) > label,\n",
       ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
       "  background-color: var(--xr-background-color-row-odd);\n",
       "}\n",
       "\n",
       ".xr-var-name {\n",
       "  grid-column: 1;\n",
       "}\n",
       "\n",
       ".xr-var-dims {\n",
       "  grid-column: 2;\n",
       "}\n",
       "\n",
       ".xr-var-dtype {\n",
       "  grid-column: 3;\n",
       "  text-align: right;\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-var-preview {\n",
       "  grid-column: 4;\n",
       "}\n",
       "\n",
       ".xr-var-name,\n",
       ".xr-var-dims,\n",
       ".xr-var-dtype,\n",
       ".xr-preview,\n",
       ".xr-attrs dt {\n",
       "  white-space: nowrap;\n",
       "  overflow: hidden;\n",
       "  text-overflow: ellipsis;\n",
       "  padding-right: 10px;\n",
       "}\n",
       "\n",
       ".xr-var-name:hover,\n",
       ".xr-var-dims:hover,\n",
       ".xr-var-dtype:hover,\n",
       ".xr-attrs dt:hover {\n",
       "  overflow: visible;\n",
       "  width: auto;\n",
       "  z-index: 1;\n",
       "}\n",
       "\n",
       ".xr-var-attrs,\n",
       ".xr-var-data {\n",
       "  display: none;\n",
       "  background-color: var(--xr-background-color) !important;\n",
       "  padding-bottom: 5px !important;\n",
       "}\n",
       "\n",
       ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
       ".xr-var-data-in:checked ~ .xr-var-data {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       ".xr-var-data > table {\n",
       "  float: right;\n",
       "}\n",
       "\n",
       ".xr-var-name span,\n",
       ".xr-var-data,\n",
       ".xr-attrs {\n",
       "  padding-left: 25px !important;\n",
       "}\n",
       "\n",
       ".xr-attrs,\n",
       ".xr-var-attrs,\n",
       ".xr-var-data {\n",
       "  grid-column: 1 / -1;\n",
       "}\n",
       "\n",
       "dl.xr-attrs {\n",
       "  padding: 0;\n",
       "  margin: 0;\n",
       "  display: grid;\n",
       "  grid-template-columns: 125px auto;\n",
       "}\n",
       "\n",
       ".xr-attrs dt,\n",
       ".xr-attrs dd {\n",
       "  padding: 0;\n",
       "  margin: 0;\n",
       "  float: left;\n",
       "  padding-right: 10px;\n",
       "  width: auto;\n",
       "}\n",
       "\n",
       ".xr-attrs dt {\n",
       "  font-weight: normal;\n",
       "  grid-column: 1;\n",
       "}\n",
       "\n",
       ".xr-attrs dt:hover span {\n",
       "  display: inline-block;\n",
       "  background: var(--xr-background-color);\n",
       "  padding-right: 10px;\n",
       "}\n",
       "\n",
       ".xr-attrs dd {\n",
       "  grid-column: 2;\n",
       "  white-space: pre-wrap;\n",
       "  word-break: break-all;\n",
       "}\n",
       "\n",
       ".xr-icon-database,\n",
       ".xr-icon-file-text2 {\n",
       "  display: inline-block;\n",
       "  vertical-align: middle;\n",
       "  width: 1em;\n",
       "  height: 1.5em !important;\n",
       "  stroke-width: 0;\n",
       "  stroke: currentColor;\n",
       "  fill: currentColor;\n",
       "}\n",
       "</style><pre class='xr-text-repr-fallback'>&lt;xarray.DataArray (band: 3, y: 687, x: 687)&gt;\n",
       "[1415907 values with dtype=uint8]\n",
       "Coordinates:\n",
       "  * band         (band) int64 1 2 3\n",
       "  * x            (x) float64 3.001e+05 3.002e+05 ... 4.096e+05 4.097e+05\n",
       "  * y            (y) float64 2e+05 1.998e+05 1.996e+05 ... 9.048e+04 9.032e+04\n",
       "    spatial_ref  int64 0\n",
       "Attributes:\n",
       "    _FillValue:    0.0\n",
       "    scale_factor:  1.0\n",
       "    add_offset:    0.0</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'></div><ul class='xr-dim-list'><li><span class='xr-has-index'>band</span>: 3</li><li><span class='xr-has-index'>y</span>: 687</li><li><span class='xr-has-index'>x</span>: 687</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-0cec67ee-686d-436a-b97e-4b122aaeb6e3' class='xr-array-in' type='checkbox' checked><label for='section-0cec67ee-686d-436a-b97e-4b122aaeb6e3' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>...</span></div><div class='xr-array-data'><pre>[1415907 values with dtype=uint8]</pre></div></div></li><li class='xr-section-item'><input id='section-dffe453b-0a83-4439-8d45-7897ceac9743' class='xr-section-summary-in' type='checkbox'  checked><label for='section-dffe453b-0a83-4439-8d45-7897ceac9743' class='xr-section-summary' >Coordinates: <span>(4)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>band</span></div><div class='xr-var-dims'>(band)</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>1 2 3</div><input id='attrs-b268c2ca-925b-4599-9fff-9bcca16041d2' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-b268c2ca-925b-4599-9fff-9bcca16041d2' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-f84ffe4b-d3c0-40c2-ae2d-8e9cf76627eb' class='xr-var-data-in' type='checkbox'><label for='data-f84ffe4b-d3c0-40c2-ae2d-8e9cf76627eb' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([1, 2, 3])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>x</span></div><div class='xr-var-dims'>(x)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>3.001e+05 3.002e+05 ... 4.097e+05</div><input id='attrs-64969277-0670-4fa8-ab17-cd6c4e88cf81' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-64969277-0670-4fa8-ab17-cd6c4e88cf81' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-3316bef1-389c-4801-8689-801521bb9249' class='xr-var-data-in' type='checkbox'><label for='data-3316bef1-389c-4801-8689-801521bb9249' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([300079.912664, 300239.737991, 300399.563319, ..., 409400.436681,\n",
       "       409560.262009, 409720.087336])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>y</span></div><div class='xr-var-dims'>(y)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>2e+05 1.998e+05 ... 9.032e+04</div><input id='attrs-e33ea804-d8d5-4fe7-ba37-e3614a8d8eaf' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-e33ea804-d8d5-4fe7-ba37-e3614a8d8eaf' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-2733bf42-3f28-46dc-ba46-b904b367ee14' class='xr-var-data-in' type='checkbox'><label for='data-2733bf42-3f28-46dc-ba46-b904b367ee14' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([199960.087336, 199800.262009, 199640.436681, ...,  90639.563319,\n",
       "        90479.737991,  90319.912664])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>spatial_ref</span></div><div class='xr-var-dims'>()</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>0</div><input id='attrs-f50b6f78-141c-4ac8-8a02-ea5e91d35523' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-f50b6f78-141c-4ac8-8a02-ea5e91d35523' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-59a1415e-c9f5-45b5-a2c8-b783866feaee' class='xr-var-data-in' type='checkbox'><label for='data-59a1415e-c9f5-45b5-a2c8-b783866feaee' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>crs_wkt :</span></dt><dd>PROJCS[&quot;WGS 84 / UTM zone 48N&quot;,GEOGCS[&quot;WGS 84&quot;,DATUM[&quot;WGS_1984&quot;,SPHEROID[&quot;WGS 84&quot;,6378137,298.257223563,AUTHORITY[&quot;EPSG&quot;,&quot;7030&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;6326&quot;]],PRIMEM[&quot;Greenwich&quot;,0,AUTHORITY[&quot;EPSG&quot;,&quot;8901&quot;]],UNIT[&quot;degree&quot;,0.0174532925199433,AUTHORITY[&quot;EPSG&quot;,&quot;9122&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;4326&quot;]],PROJECTION[&quot;Transverse_Mercator&quot;],PARAMETER[&quot;latitude_of_origin&quot;,0],PARAMETER[&quot;central_meridian&quot;,105],PARAMETER[&quot;scale_factor&quot;,0.9996],PARAMETER[&quot;false_easting&quot;,500000],PARAMETER[&quot;false_northing&quot;,0],UNIT[&quot;metre&quot;,1,AUTHORITY[&quot;EPSG&quot;,&quot;9001&quot;]],AXIS[&quot;Easting&quot;,EAST],AXIS[&quot;Northing&quot;,NORTH],AUTHORITY[&quot;EPSG&quot;,&quot;32648&quot;]]</dd><dt><span>semi_major_axis :</span></dt><dd>6378137.0</dd><dt><span>semi_minor_axis :</span></dt><dd>6356752.314245179</dd><dt><span>inverse_flattening :</span></dt><dd>298.257223563</dd><dt><span>reference_ellipsoid_name :</span></dt><dd>WGS 84</dd><dt><span>longitude_of_prime_meridian :</span></dt><dd>0.0</dd><dt><span>prime_meridian_name :</span></dt><dd>Greenwich</dd><dt><span>geographic_crs_name :</span></dt><dd>WGS 84</dd><dt><span>horizontal_datum_name :</span></dt><dd>World Geodetic System 1984</dd><dt><span>projected_crs_name :</span></dt><dd>WGS 84 / UTM zone 48N</dd><dt><span>grid_mapping_name :</span></dt><dd>transverse_mercator</dd><dt><span>latitude_of_projection_origin :</span></dt><dd>0.0</dd><dt><span>longitude_of_central_meridian :</span></dt><dd>105.0</dd><dt><span>false_easting :</span></dt><dd>500000.0</dd><dt><span>false_northing :</span></dt><dd>0.0</dd><dt><span>scale_factor_at_central_meridian :</span></dt><dd>0.9996</dd><dt><span>spatial_ref :</span></dt><dd>PROJCS[&quot;WGS 84 / UTM zone 48N&quot;,GEOGCS[&quot;WGS 84&quot;,DATUM[&quot;WGS_1984&quot;,SPHEROID[&quot;WGS 84&quot;,6378137,298.257223563,AUTHORITY[&quot;EPSG&quot;,&quot;7030&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;6326&quot;]],PRIMEM[&quot;Greenwich&quot;,0,AUTHORITY[&quot;EPSG&quot;,&quot;8901&quot;]],UNIT[&quot;degree&quot;,0.0174532925199433,AUTHORITY[&quot;EPSG&quot;,&quot;9122&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;4326&quot;]],PROJECTION[&quot;Transverse_Mercator&quot;],PARAMETER[&quot;latitude_of_origin&quot;,0],PARAMETER[&quot;central_meridian&quot;,105],PARAMETER[&quot;scale_factor&quot;,0.9996],PARAMETER[&quot;false_easting&quot;,500000],PARAMETER[&quot;false_northing&quot;,0],UNIT[&quot;metre&quot;,1,AUTHORITY[&quot;EPSG&quot;,&quot;9001&quot;]],AXIS[&quot;Easting&quot;,EAST],AXIS[&quot;Northing&quot;,NORTH],AUTHORITY[&quot;EPSG&quot;,&quot;32648&quot;]]</dd><dt><span>GeoTransform :</span></dt><dd>300000.0 159.82532751091702 0.0 200040.0 0.0 -159.82532751091702</dd></dl></div><div class='xr-var-data'><pre>array(0)</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-a373e1cc-8776-4c2d-a371-1d51c6e5f1fb' class='xr-section-summary-in' type='checkbox'  checked><label for='section-a373e1cc-8776-4c2d-a371-1d51c6e5f1fb' class='xr-section-summary' >Attributes: <span>(3)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'><dt><span>_FillValue :</span></dt><dd>0.0</dd><dt><span>scale_factor :</span></dt><dd>1.0</dd><dt><span>add_offset :</span></dt><dd>0.0</dd></dl></div></li></ul></div></div>"
      ],
      "text/plain": [
       "StreamWrapper<<xarray.DataArray (band: 3, y: 687, x: 687)>\n",
       "[1415907 values with dtype=uint8]\n",
       "Coordinates:\n",
       "  * band         (band) int64 1 2 3\n",
       "  * x            (x) float64 3.001e+05 3.002e+05 ... 4.096e+05 4.097e+05\n",
       "  * y            (y) float64 2e+05 1.998e+05 1.996e+05 ... 9.048e+04 9.032e+04\n",
       "    spatial_ref  int64 0\n",
       "Attributes:\n",
       "    _FillValue:    0.0\n",
       "    scale_factor:  1.0\n",
       "    add_offset:    0.0>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "it = iter(dp_rioxarray_zoom3)\n",
    "filename, dataarray = next(it)\n",
    "dataarray"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "055ea47f",
   "metadata": {},
   "source": [
    "Or if you're more familiar with a for-loop, here it is:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "d3ffb02c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "StreamWrapper<<xarray.DataArray (band: 3, y: 687, x: 687)>\n",
      "[1415907 values with dtype=uint8]\n",
      "Coordinates:\n",
      "  * band         (band) int64 1 2 3\n",
      "  * x            (x) float64 3.001e+05 3.002e+05 ... 4.096e+05 4.097e+05\n",
      "  * y            (y) float64 2e+05 1.998e+05 1.996e+05 ... 9.048e+04 9.032e+04\n",
      "    spatial_ref  int64 0\n",
      "Attributes:\n",
      "    _FillValue:    0.0\n",
      "    scale_factor:  1.0\n",
      "    add_offset:    0.0>\n"
     ]
    }
   ],
   "source": [
    "for filename, dataarray in dp_rioxarray_zoom3:\n",
    "    print(dataarray)\n",
    "    # Run model on this data batch"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c92aff91",
   "metadata": {},
   "source": [
    "### Into a DataLoader 🏋️\n",
    "\n",
    "For the deep learning folks, you might need one extra step.\n",
    "The {py:class}``xarray.DataArray`` needs to be converted to a tensor.\n",
    "In the Pytorch world, that can happen via {py:func}``torch.as_tensor``."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "9319e45d",
   "metadata": {},
   "outputs": [],
   "source": [
    "def fn(da):\n",
    "    return torch.as_tensor(da.data)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9e3e5254",
   "metadata": {},
   "source": [
    "Using {py:class}`torchdata.datapipes.iter.Mapper`,\n",
    "we'll apply the tensor conversion function to index 1 of the\n",
    "``(filename, dataarray)`` tuple."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "155c7cb3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<torch.utils.data.datapipes.iter.callable.MapperIterDataPipe at 0x7fbd90e436d0>"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dp_tensor = dp_rioxarray_zoom3.map(fn=fn, input_col=1)\n",
    "dp_tensor"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "35911f28",
   "metadata": {},
   "source": [
    "Finally, let's put our DataPipe into a {py:class}`torch.utils.data.DataLoader`!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "187d85b3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[[[ 46,  29,  34,  ..., 241, 246, 255],\n",
      "          [ 83,  73,  66,  ..., 248, 255, 251],\n",
      "          [ 53,  43,  55,  ..., 246, 247, 243],\n",
      "          ...,\n",
      "          [101, 101, 104,  ...,  78, 179,  83],\n",
      "          [ 99, 103, 105,  ...,  68,  60,  45],\n",
      "          [ 95, 103, 102,  ...,  50,  34,  42]],\n",
      "\n",
      "         [[ 58,  24,  44,  ..., 255, 255, 255],\n",
      "          [ 60,  51,  57,  ..., 255, 255, 254],\n",
      "          [ 47,  22,  47,  ..., 255, 255, 255],\n",
      "          ...,\n",
      "          [110, 111, 114,  ...,  95, 189,  87],\n",
      "          [110, 113, 113,  ...,  85,  62,  48],\n",
      "          [108, 112, 112,  ...,  62,  60,  62]],\n",
      "\n",
      "         [[ 42,  22,  29,  ..., 255, 255, 255],\n",
      "          [ 43,  41,  39,  ..., 255, 255, 254],\n",
      "          [ 35,  30,  37,  ..., 255, 255, 255],\n",
      "          ...,\n",
      "          [ 82,  82,  83,  ...,  74, 174,  57],\n",
      "          [ 82,  84,  84,  ...,  57,  46,  28],\n",
      "          [ 80,  83,  82,  ...,  37,  31,  31]]]], dtype=torch.uint8)\n"
     ]
    }
   ],
   "source": [
    "dataloader = torch.utils.data.DataLoader(dataset=dp_tensor)\n",
    "for batch in dataloader:\n",
    "    filename, tensor = batch\n",
    "    print(tensor)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d2565da",
   "metadata": {},
   "source": [
    "And so it begins 🌄\n",
    "\n",
    "---\n",
    "\n",
    "That’s all 🎉! For more information on how to use DataPipes, check out:\n",
    "\n",
    "- Tutorial at https://pytorch.org/data/0.4.0/tutorial.html\n",
    "- Usage examples at https://pytorch.org/data/0.4.0/examples.html\n",
    "\n",
    "If you have any questions 🙋, feel free to ask us anything at\n",
    "https://github.com/weiji14/zen3geo/discussions or visit the Pytorch forums at\n",
    "https://discuss.pytorch.org/c/data/37.\n",
    "\n",
    "Cheers!"
   ]
  }
 ],
 "metadata": {
  "jupytext": {
   "formats": "md:myst",
   "text_representation": {
    "extension": ".md",
    "format_name": "myst"
   }
  },
  "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.9.13"
  },
  "source_map": [
   11,
   27,
   36,
   41,
   49,
   62,
   69,
   77,
   81,
   104,
   107,
   121,
   127,
   131,
   141,
   144,
   166,
   170,
   174,
   178,
   186,
   189,
   195,
   198,
   202,
   207
  ]
 },
 "nbformat": 4,
 "nbformat_minor": 5
}