diff --git a/tutorials/Earthdata_Subset_and_Plot-LIVE.ipynb b/tutorials/Earthdata_Subset_and_Plot-LIVE.ipynb
new file mode 100644
index 0000000..0a8ef5d
--- /dev/null
+++ b/tutorials/Earthdata_Subset_and_Plot-LIVE.ipynb
@@ -0,0 +1,2091 @@
+{
+ "cells": [
+ {
+ "cell_type": "raw",
+ "id": "bcf23fc8-ae63-4efe-84bb-c67acdffb973",
+ "metadata": {},
+ "source": [
+ "---\n",
+ "title: \"Part 2 of the In-cloud Science Workflow: Data subsetting and plotting with earthaccess, xarray, and harmony\"\n",
+ "---"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a28d9430-1a3e-480c-bf15-c35f938b4210",
+ "metadata": {},
+ "source": [
+ "## Summary\n",
+ "\n",
+ "Welcome to Part 2 of the In-cloud Science Workflow workshop.\n",
+ "\n",
+ "In these examples we will use the [xarray](https://xarray.dev/), [earthaccess](https://nsidc.github.io/earthaccess/), and [harmony-py](https://github.com/nasa/harmony-py) libraries to subset data and make figures using `cartopy`, `matplotlib`, and `geoviews`.\n",
+ "\n",
+ "We will go through **two examples of subsetting and plotting data in the Earthdata Cloud:** \n",
+ "\n",
+ "1. Example 1 - `earthaccess` and `xarray` for precipitation estimates from [IMERG, Daily Level 3 data](https://doi.org/10.5067/GPM/IMERGDF/DAY/07)\n",
+ "2. Example 2 - `harmony-py` for direct cloud subsetting of precipitable water data from the [DSCOVR EPIC Composite](https://doi.org/10.5067/EPIC/DSCOVR/L2_COMPOSITE_01).\n",
+ "3. Appendix 1 - Snow cover data from [MODIS/Terra, Daily Level 3 data](https://doi.org/10.5067/MODIS/MOD10C1.061) with `rioxarray`\n",
+ "4. Appendix 2 - Snow mass data from [SMAP, 3-hourly Level 4 data](https://doi.org/10.5067/EVKPQZ4AFC4D)\n",
+ " \n",
+ "In the first example, we will be accessing data directly from Amazon Web Services (AWS), specifically in the us-west-2 region, which is where all cloud-hosted NASA Earthdata reside. This shared compute environment (JupyterHub) is also running in the same location. We will then load the data into Python as an `xarray` dataset and use `xarray` to subset.\n",
+ "\n",
+ "In the second example, we will demonstrate an example of pulling data via the cloud from an existing on-premise data server. In this example, the data are subsetted using one of the data transformation services provided in the NASA Earthdata system. Both `xarray` and `harmony-py` can be run outside of AWS as well.\n",
+ "\n",
+ "See the bottom of the notebook for additional resources, including several tutorials that that served as a foundation for this clinic. Includes: https://github.com/rupesh2/atmospheric_rivers/tree/main\n",
+ "\n",
+ "Note: \"direct cloud access\" is also called \"direct S3 access\" or simply \"direct access\".\n",
+ "\n",
+ "## Learning Objectives\n",
+ "\n",
+ "1. Extract variables, temporal slices, and spatial slices from an `xarray` dataset \n",
+ "2. Plot data and exclude data points via boolean conditions, using `xarray`, `cartopy`, `matplotlib`, and `rasterio`\n",
+ "3. Plot a polygon geojson file with a basemap using `geoviews` \n",
+ "4. Conceptualize data subsetting services provided by NASA Earthdata, including Harmony\n",
+ "5. Utilize the `harmony-py` library to request data over the Bay of San Francisco"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "66d78efc-2d62-428a-a813-e58f949ee1bf",
+ "metadata": {},
+ "source": [
+ "### Import Required Packages"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "f04a653d-b9e5-4cfe-a198-b5b612389742",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [
+ {
+ "data": {
+ "application/javascript": [
+ "(function(root) {\n",
+ " function now() {\n",
+ " return new Date();\n",
+ " }\n",
+ "\n",
+ " var force = true;\n",
+ " var py_version = '3.2.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n",
+ " var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n",
+ " var reloading = false;\n",
+ " var Bokeh = root.Bokeh;\n",
+ " var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n",
+ "\n",
+ " if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n",
+ " root._bokeh_timeout = Date.now() + 5000;\n",
+ " root._bokeh_failed_load = false;\n",
+ " }\n",
+ "\n",
+ " function run_callbacks() {\n",
+ " try {\n",
+ " root._bokeh_onload_callbacks.forEach(function(callback) {\n",
+ " if (callback != null)\n",
+ " callback();\n",
+ " });\n",
+ " } finally {\n",
+ " delete root._bokeh_onload_callbacks;\n",
+ " }\n",
+ " console.debug(\"Bokeh: all callbacks have finished\");\n",
+ " }\n",
+ "\n",
+ " function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n",
+ " if (css_urls == null) css_urls = [];\n",
+ " if (js_urls == null) js_urls = [];\n",
+ " if (js_modules == null) js_modules = [];\n",
+ " if (js_exports == null) js_exports = {};\n",
+ "\n",
+ " root._bokeh_onload_callbacks.push(callback);\n",
+ "\n",
+ " if (root._bokeh_is_loading > 0) {\n",
+ " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
+ " return null;\n",
+ " }\n",
+ " if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n",
+ " run_callbacks();\n",
+ " return null;\n",
+ " }\n",
+ " if (!reloading) {\n",
+ " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
+ " }\n",
+ "\n",
+ " function on_load() {\n",
+ " root._bokeh_is_loading--;\n",
+ " if (root._bokeh_is_loading === 0) {\n",
+ " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n",
+ " run_callbacks()\n",
+ " }\n",
+ " }\n",
+ " window._bokeh_on_load = on_load\n",
+ "\n",
+ " function on_error() {\n",
+ " console.error(\"failed to load \" + url);\n",
+ " }\n",
+ "\n",
+ " var skip = [];\n",
+ " if (window.requirejs) {\n",
+ " window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n",
+ " require([\"jspanel\"], function(jsPanel) {\n",
+ "\twindow.jsPanel = jsPanel\n",
+ "\ton_load()\n",
+ " })\n",
+ " require([\"jspanel-modal\"], function() {\n",
+ "\ton_load()\n",
+ " })\n",
+ " require([\"jspanel-tooltip\"], function() {\n",
+ "\ton_load()\n",
+ " })\n",
+ " require([\"jspanel-hint\"], function() {\n",
+ "\ton_load()\n",
+ " })\n",
+ " require([\"jspanel-layout\"], function() {\n",
+ "\ton_load()\n",
+ " })\n",
+ " require([\"jspanel-contextmenu\"], function() {\n",
+ "\ton_load()\n",
+ " })\n",
+ " require([\"jspanel-dock\"], function() {\n",
+ "\ton_load()\n",
+ " })\n",
+ " require([\"gridstack\"], function(GridStack) {\n",
+ "\twindow.GridStack = GridStack\n",
+ "\ton_load()\n",
+ " })\n",
+ " require([\"notyf\"], function() {\n",
+ "\ton_load()\n",
+ " })\n",
+ " root._bokeh_is_loading = css_urls.length + 9;\n",
+ " } else {\n",
+ " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n",
+ " }\n",
+ "\n",
+ " var existing_stylesheets = []\n",
+ " var links = document.getElementsByTagName('link')\n",
+ " for (var i = 0; i < links.length; i++) {\n",
+ " var link = links[i]\n",
+ " if (link.href != null) {\n",
+ "\texisting_stylesheets.push(link.href)\n",
+ " }\n",
+ " }\n",
+ " for (var i = 0; i < css_urls.length; i++) {\n",
+ " var url = css_urls[i];\n",
+ " if (existing_stylesheets.indexOf(url) !== -1) {\n",
+ "\ton_load()\n",
+ "\tcontinue;\n",
+ " }\n",
+ " const element = document.createElement(\"link\");\n",
+ " element.onload = on_load;\n",
+ " element.onerror = on_error;\n",
+ " element.rel = \"stylesheet\";\n",
+ " element.type = \"text/css\";\n",
+ " element.href = url;\n",
+ " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n",
+ " document.body.appendChild(element);\n",
+ " } if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n",
+ " var urls = ['https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n",
+ " for (var i = 0; i < urls.length; i++) {\n",
+ " skip.push(urls[i])\n",
+ " }\n",
+ " } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n",
+ " var urls = ['https://cdn.holoviz.org/panel/1.2.3/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n",
+ " for (var i = 0; i < urls.length; i++) {\n",
+ " skip.push(urls[i])\n",
+ " }\n",
+ " } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n",
+ " var urls = ['https://cdn.holoviz.org/panel/1.2.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n",
+ " for (var i = 0; i < urls.length; i++) {\n",
+ " skip.push(urls[i])\n",
+ " }\n",
+ " } var existing_scripts = []\n",
+ " var scripts = document.getElementsByTagName('script')\n",
+ " for (var i = 0; i < scripts.length; i++) {\n",
+ " var script = scripts[i]\n",
+ " if (script.src != null) {\n",
+ "\texisting_scripts.push(script.src)\n",
+ " }\n",
+ " }\n",
+ " for (var i = 0; i < js_urls.length; i++) {\n",
+ " var url = js_urls[i];\n",
+ " if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n",
+ "\tif (!window.requirejs) {\n",
+ "\t on_load();\n",
+ "\t}\n",
+ "\tcontinue;\n",
+ " }\n",
+ " var element = document.createElement('script');\n",
+ " element.onload = on_load;\n",
+ " element.onerror = on_error;\n",
+ " element.async = false;\n",
+ " element.src = url;\n",
+ " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+ " document.head.appendChild(element);\n",
+ " }\n",
+ " for (var i = 0; i < js_modules.length; i++) {\n",
+ " var url = js_modules[i];\n",
+ " if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n",
+ "\tif (!window.requirejs) {\n",
+ "\t on_load();\n",
+ "\t}\n",
+ "\tcontinue;\n",
+ " }\n",
+ " var element = document.createElement('script');\n",
+ " element.onload = on_load;\n",
+ " element.onerror = on_error;\n",
+ " element.async = false;\n",
+ " element.src = url;\n",
+ " element.type = \"module\";\n",
+ " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+ " document.head.appendChild(element);\n",
+ " }\n",
+ " for (const name in js_exports) {\n",
+ " var url = js_exports[name];\n",
+ " if (skip.indexOf(url) >= 0 || root[name] != null) {\n",
+ "\tif (!window.requirejs) {\n",
+ "\t on_load();\n",
+ "\t}\n",
+ "\tcontinue;\n",
+ " }\n",
+ " var element = document.createElement('script');\n",
+ " element.onerror = on_error;\n",
+ " element.async = false;\n",
+ " element.type = \"module\";\n",
+ " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
+ " element.textContent = `\n",
+ " import ${name} from \"${url}\"\n",
+ " window.${name} = ${name}\n",
+ " window._bokeh_on_load()\n",
+ " `\n",
+ " document.head.appendChild(element);\n",
+ " }\n",
+ " if (!js_urls.length && !js_modules.length) {\n",
+ " on_load()\n",
+ " }\n",
+ " };\n",
+ "\n",
+ " function inject_raw_css(css) {\n",
+ " const element = document.createElement(\"style\");\n",
+ " element.appendChild(document.createTextNode(css));\n",
+ " document.body.appendChild(element);\n",
+ " }\n",
+ "\n",
+ " var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.2.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.2.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.2.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.2.2.min.js\", \"https://cdn.holoviz.org/panel/1.2.3/dist/panel.min.js\", \"https://cdn.jsdelivr.net/npm/@holoviz/geoviews@1.10.1/dist/geoviews.min.js\"];\n",
+ " var js_modules = [];\n",
+ " var js_exports = {};\n",
+ " var css_urls = [];\n",
+ " var inline_js = [ function(Bokeh) {\n",
+ " Bokeh.set_log_level(\"info\");\n",
+ " },\n",
+ "function(Bokeh) {} // ensure no trailing comma for IE\n",
+ " ];\n",
+ "\n",
+ " function run_inline_js() {\n",
+ " if ((root.Bokeh !== undefined) || (force === true)) {\n",
+ " for (var i = 0; i < inline_js.length; i++) {\n",
+ " inline_js[i].call(root, root.Bokeh);\n",
+ " }\n",
+ " // Cache old bokeh versions\n",
+ " if (Bokeh != undefined && !reloading) {\n",
+ "\tvar NewBokeh = root.Bokeh;\n",
+ "\tif (Bokeh.versions === undefined) {\n",
+ "\t Bokeh.versions = new Map();\n",
+ "\t}\n",
+ "\tif (NewBokeh.version !== Bokeh.version) {\n",
+ "\t Bokeh.versions.set(NewBokeh.version, NewBokeh)\n",
+ "\t}\n",
+ "\troot.Bokeh = Bokeh;\n",
+ " }} else if (Date.now() < root._bokeh_timeout) {\n",
+ " setTimeout(run_inline_js, 100);\n",
+ " } else if (!root._bokeh_failed_load) {\n",
+ " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
+ " root._bokeh_failed_load = true;\n",
+ " }\n",
+ " root._bokeh_is_initializing = false\n",
+ " }\n",
+ "\n",
+ " function load_or_wait() {\n",
+ " // Implement a backoff loop that tries to ensure we do not load multiple\n",
+ " // versions of Bokeh and its dependencies at the same time.\n",
+ " // In recent versions we use the root._bokeh_is_initializing flag\n",
+ " // to determine whether there is an ongoing attempt to initialize\n",
+ " // bokeh, however for backward compatibility we also try to ensure\n",
+ " // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n",
+ " // before older versions are fully initialized.\n",
+ " if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n",
+ " root._bokeh_is_initializing = false;\n",
+ " root._bokeh_onload_callbacks = undefined;\n",
+ " console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n",
+ " load_or_wait();\n",
+ " } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n",
+ " setTimeout(load_or_wait, 100);\n",
+ " } else {\n",
+ " Bokeh = root.Bokeh;\n",
+ " bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n",
+ " root._bokeh_is_initializing = true\n",
+ " root._bokeh_onload_callbacks = []\n",
+ " if (!reloading && (!bokeh_loaded || is_dev)) {\n",
+ "\troot.Bokeh = undefined;\n",
+ " }\n",
+ " load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n",
+ "\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n",
+ "\trun_inline_js();\n",
+ " });\n",
+ " }\n",
+ " }\n",
+ " // Give older versions of the autoload script a head-start to ensure\n",
+ " // they initialize before we start loading newer version.\n",
+ " setTimeout(load_or_wait, 100)\n",
+ "}(window));"
+ ],
+ "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n var py_version = '3.2.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n var reloading = false;\n var Bokeh = root.Bokeh;\n var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n run_callbacks();\n return null;\n }\n if (!reloading) {\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"jspanel\"], function(jsPanel) {\n\twindow.jsPanel = jsPanel\n\ton_load()\n })\n require([\"jspanel-modal\"], function() {\n\ton_load()\n })\n require([\"jspanel-tooltip\"], function() {\n\ton_load()\n })\n require([\"jspanel-hint\"], function() {\n\ton_load()\n })\n require([\"jspanel-layout\"], function() {\n\ton_load()\n })\n require([\"jspanel-contextmenu\"], function() {\n\ton_load()\n })\n require([\"jspanel-dock\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 9;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n var existing_stylesheets = []\n var links = document.getElementsByTagName('link')\n for (var i = 0; i < links.length; i++) {\n var link = links[i]\n if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n }\n }\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.2.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.2.3/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.2.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } var existing_scripts = []\n var scripts = document.getElementsByTagName('script')\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n\texisting_scripts.push(script.src)\n }\n }\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n var url = js_exports[name];\n if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.2.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.2.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.2.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.2.2.min.js\", \"https://cdn.holoviz.org/panel/1.2.3/dist/panel.min.js\", \"https://cdn.jsdelivr.net/npm/@holoviz/geoviews@1.10.1/dist/geoviews.min.js\"];\n var js_modules = [];\n var js_exports = {};\n var css_urls = [];\n var inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n Bokeh = root.Bokeh;\n bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n if (!reloading && (!bokeh_loaded || is_dev)) {\n\troot.Bokeh = undefined;\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));"
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/javascript": [
+ "\n",
+ "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n",
+ " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n",
+ "}\n",
+ "\n",
+ "\n",
+ " function JupyterCommManager() {\n",
+ " }\n",
+ "\n",
+ " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n",
+ " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n",
+ " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n",
+ " comm_manager.register_target(comm_id, function(comm) {\n",
+ " comm.on_msg(msg_handler);\n",
+ " });\n",
+ " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n",
+ " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n",
+ " comm.onMsg = msg_handler;\n",
+ " });\n",
+ " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n",
+ " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n",
+ " var messages = comm.messages[Symbol.asyncIterator]();\n",
+ " function processIteratorResult(result) {\n",
+ " var message = result.value;\n",
+ " console.log(message)\n",
+ " var content = {data: message.data, comm_id};\n",
+ " var buffers = []\n",
+ " for (var buffer of message.buffers || []) {\n",
+ " buffers.push(new DataView(buffer))\n",
+ " }\n",
+ " var metadata = message.metadata || {};\n",
+ " var msg = {content, buffers, metadata}\n",
+ " msg_handler(msg);\n",
+ " return messages.next().then(processIteratorResult);\n",
+ " }\n",
+ " return messages.next().then(processIteratorResult);\n",
+ " })\n",
+ " }\n",
+ " }\n",
+ "\n",
+ " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n",
+ " if (comm_id in window.PyViz.comms) {\n",
+ " return window.PyViz.comms[comm_id];\n",
+ " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n",
+ " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n",
+ " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n",
+ " if (msg_handler) {\n",
+ " comm.on_msg(msg_handler);\n",
+ " }\n",
+ " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n",
+ " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n",
+ " comm.open();\n",
+ " if (msg_handler) {\n",
+ " comm.onMsg = msg_handler;\n",
+ " }\n",
+ " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n",
+ " var comm_promise = google.colab.kernel.comms.open(comm_id)\n",
+ " comm_promise.then((comm) => {\n",
+ " window.PyViz.comms[comm_id] = comm;\n",
+ " if (msg_handler) {\n",
+ " var messages = comm.messages[Symbol.asyncIterator]();\n",
+ " function processIteratorResult(result) {\n",
+ " var message = result.value;\n",
+ " var content = {data: message.data};\n",
+ " var metadata = message.metadata || {comm_id};\n",
+ " var msg = {content, metadata}\n",
+ " msg_handler(msg);\n",
+ " return messages.next().then(processIteratorResult);\n",
+ " }\n",
+ " return messages.next().then(processIteratorResult);\n",
+ " }\n",
+ " }) \n",
+ " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n",
+ " return comm_promise.then((comm) => {\n",
+ " comm.send(data, metadata, buffers, disposeOnDone);\n",
+ " });\n",
+ " };\n",
+ " var comm = {\n",
+ " send: sendClosure\n",
+ " };\n",
+ " }\n",
+ " window.PyViz.comms[comm_id] = comm;\n",
+ " return comm;\n",
+ " }\n",
+ " window.PyViz.comm_manager = new JupyterCommManager();\n",
+ " \n",
+ "\n",
+ "\n",
+ "var JS_MIME_TYPE = 'application/javascript';\n",
+ "var HTML_MIME_TYPE = 'text/html';\n",
+ "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n",
+ "var CLASS_NAME = 'output';\n",
+ "\n",
+ "/**\n",
+ " * Render data to the DOM node\n",
+ " */\n",
+ "function render(props, node) {\n",
+ " var div = document.createElement(\"div\");\n",
+ " var script = document.createElement(\"script\");\n",
+ " node.appendChild(div);\n",
+ " node.appendChild(script);\n",
+ "}\n",
+ "\n",
+ "/**\n",
+ " * Handle when a new output is added\n",
+ " */\n",
+ "function handle_add_output(event, handle) {\n",
+ " var output_area = handle.output_area;\n",
+ " var output = handle.output;\n",
+ " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n",
+ " return\n",
+ " }\n",
+ " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n",
+ " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n",
+ " if (id !== undefined) {\n",
+ " var nchildren = toinsert.length;\n",
+ " var html_node = toinsert[nchildren-1].children[0];\n",
+ " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n",
+ " var scripts = [];\n",
+ " var nodelist = html_node.querySelectorAll(\"script\");\n",
+ " for (var i in nodelist) {\n",
+ " if (nodelist.hasOwnProperty(i)) {\n",
+ " scripts.push(nodelist[i])\n",
+ " }\n",
+ " }\n",
+ "\n",
+ " scripts.forEach( function (oldScript) {\n",
+ " var newScript = document.createElement(\"script\");\n",
+ " var attrs = [];\n",
+ " var nodemap = oldScript.attributes;\n",
+ " for (var j in nodemap) {\n",
+ " if (nodemap.hasOwnProperty(j)) {\n",
+ " attrs.push(nodemap[j])\n",
+ " }\n",
+ " }\n",
+ " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n",
+ " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n",
+ " oldScript.parentNode.replaceChild(newScript, oldScript);\n",
+ " });\n",
+ " if (JS_MIME_TYPE in output.data) {\n",
+ " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n",
+ " }\n",
+ " output_area._hv_plot_id = id;\n",
+ " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n",
+ " window.PyViz.plot_index[id] = Bokeh.index[id];\n",
+ " } else {\n",
+ " window.PyViz.plot_index[id] = null;\n",
+ " }\n",
+ " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n",
+ " var bk_div = document.createElement(\"div\");\n",
+ " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n",
+ " var script_attrs = bk_div.children[0].attributes;\n",
+ " for (var i = 0; i < script_attrs.length; i++) {\n",
+ " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n",
+ " }\n",
+ " // store reference to server id on output_area\n",
+ " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "/**\n",
+ " * Handle when an output is cleared or removed\n",
+ " */\n",
+ "function handle_clear_output(event, handle) {\n",
+ " var id = handle.cell.output_area._hv_plot_id;\n",
+ " var server_id = handle.cell.output_area._bokeh_server_id;\n",
+ " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n",
+ " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n",
+ " if (server_id !== null) {\n",
+ " comm.send({event_type: 'server_delete', 'id': server_id});\n",
+ " return;\n",
+ " } else if (comm !== null) {\n",
+ " comm.send({event_type: 'delete', 'id': id});\n",
+ " }\n",
+ " delete PyViz.plot_index[id];\n",
+ " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n",
+ " var doc = window.Bokeh.index[id].model.document\n",
+ " doc.clear();\n",
+ " const i = window.Bokeh.documents.indexOf(doc);\n",
+ " if (i > -1) {\n",
+ " window.Bokeh.documents.splice(i, 1);\n",
+ " }\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "/**\n",
+ " * Handle kernel restart event\n",
+ " */\n",
+ "function handle_kernel_cleanup(event, handle) {\n",
+ " delete PyViz.comms[\"hv-extension-comm\"];\n",
+ " window.PyViz.plot_index = {}\n",
+ "}\n",
+ "\n",
+ "/**\n",
+ " * Handle update_display_data messages\n",
+ " */\n",
+ "function handle_update_output(event, handle) {\n",
+ " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n",
+ " handle_add_output(event, handle)\n",
+ "}\n",
+ "\n",
+ "function register_renderer(events, OutputArea) {\n",
+ " function append_mime(data, metadata, element) {\n",
+ " // create a DOM node to render to\n",
+ " var toinsert = this.create_output_subarea(\n",
+ " metadata,\n",
+ " CLASS_NAME,\n",
+ " EXEC_MIME_TYPE\n",
+ " );\n",
+ " this.keyboard_manager.register_events(toinsert);\n",
+ " // Render to node\n",
+ " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n",
+ " render(props, toinsert[0]);\n",
+ " element.append(toinsert);\n",
+ " return toinsert\n",
+ " }\n",
+ "\n",
+ " events.on('output_added.OutputArea', handle_add_output);\n",
+ " events.on('output_updated.OutputArea', handle_update_output);\n",
+ " events.on('clear_output.CodeCell', handle_clear_output);\n",
+ " events.on('delete.Cell', handle_clear_output);\n",
+ " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n",
+ "\n",
+ " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n",
+ " safe: true,\n",
+ " index: 0\n",
+ " });\n",
+ "}\n",
+ "\n",
+ "if (window.Jupyter !== undefined) {\n",
+ " try {\n",
+ " var events = require('base/js/events');\n",
+ " var OutputArea = require('notebook/js/outputarea').OutputArea;\n",
+ " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n",
+ " register_renderer(events, OutputArea);\n",
+ " }\n",
+ " } catch(err) {\n",
+ " }\n",
+ "}\n"
+ ],
+ "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n"
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "# Suppress warnings\n",
+ "import warnings\n",
+ "warnings.simplefilter('ignore')\n",
+ "warnings.filterwarnings('ignore')\n",
+ "from pprint import pprint\n",
+ "\n",
+ "# Example 1 imports\n",
+ "import earthaccess\n",
+ "import xarray as xr\n",
+ "xr.set_options(display_expand_attrs=False)\n",
+ "import matplotlib.pyplot as plt\n",
+ "import cartopy.crs as ccrs\n",
+ "import cartopy.feature as cfeature\n",
+ "\n",
+ "# Example 2 imports (Example 1 imports plus these...)\n",
+ "import datetime as dt\n",
+ "import json\n",
+ "from cartopy.mpl.ticker import LatitudeFormatter, LongitudeFormatter\n",
+ "import geopandas as gpd\n",
+ "import geoviews as gv\n",
+ "gv.extension('bokeh', 'matplotlib', logo=False)\n",
+ "from harmony import Client, Collection, Request, CapabilitiesRequest\n",
+ "\n",
+ "# Appendix 1 imports\n",
+ "from pathlib import Path\n",
+ "import rioxarray as rxr\n",
+ "\n",
+ "%matplotlib inline"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "442bd92a-8f2d-4448-a59e-da4567710730",
+ "metadata": {},
+ "source": [
+ "## Picking up where we left off\n",
+ "\n",
+ "We will authenticate our Earthaccess session, and then open the results like we did in the Search & Discovery section."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "0fe0002f-c759-4611-8dd7-861b8bd38971",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "EARTHDATA_USERNAME and EARTHDATA_PASSWORD are not set in the current environment, try setting them or use a different strategy (netrc, interactive)\n",
+ "You're now authenticated with NASA Earthdata Login\n",
+ "Using token with expiration date: 01/26/2024\n",
+ "Using .netrc file for EDL\n"
+ ]
+ }
+ ],
+ "source": [
+ "auth = earthaccess.login()\n",
+ "# are we authenticated?\n",
+ "if not auth.authenticated:\n",
+ " # ask for credentials and persist them in a .netrc file\n",
+ " auth.login(strategy=\"interactive\", persist=True)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a6a3cb10-6988-401e-a618-59e2f5ac3228",
+ "metadata": {},
+ "source": [
+ "## Example 1 - Xarray Subsetting - Precipitation estimates from IMERG, Daily Level 3"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b5b794c8-a100-46f0-8020-e2341ff2b201",
+ "metadata": {
+ "tags": []
+ },
+ "source": [
+ "### Dataset\n",
+ "We will use the GPM IMERG Final Precipitation L3 Daily dataset for this tutorial. The IMERG Precipitation Rate provides the rain and snow rates in millimeters per hour (mm/hr). It is estimated by the Integrated Multi-satellitE Retrievals for Global Precipitation Measurement (GPM) (IMERG) algorithm. The IMERG algorithm uses passive-microwave data from the GPM constellation of satellites and infrared data from geosynchronous satellites. IMERG “morphs” observations to earlier or later times using wind from weather-model analyses. The daily IMERG dataset is derived from the half-hourly GPM_3IMERGHH. The derived result represents the final estimate of the daily mean precipitation rate in mm/day.\n",
+ "\n",
+ "The IMERG data has 0.1 x 0.1 degree latitude-longitude resolution (approximately 11 by 11 km at the Equator). The grid covers the globe, although precipitation cannot always be estimated near the Poles. The dataset and algorithm are described in the [data user guide](https://gpm1.gesdisc.eosdis.nasa.gov/data/GPM_L3/doc/README.GPM.pdf) and the [Algorithm Theoretical Basis Document (ATBD)](https://arthurhou.pps.eosdis.nasa.gov/Documents/IMERG_V07_ATBD_final.pdf). \n",
+ "\n",
+ "Please cite the dataset as:\n",
+ "> Huffman, G.J., E.F. Stocker, D.T. Bolvin, E.J. Nelkin, Jackson Tan (2023), GPM IMERG Final Precipitation L3 1 day 0.1 degree x 0.1 degree V07, Edited by Andrey Savtchenko, Greenbelt, MD, Goddard Earth Sciences Data and Information Services Center (GES DISC), https://doi.org/10.5067/GPM/IMERGDF/DAY/07"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "3dbe9828-37e9-4949-846f-297057e5b0d5",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Granules found: 3\n",
+ " Opening 3 granules, approx size: 0.08 GB\n"
+ ]
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "fd179bfbc37043628d1382e7274a4e3b",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "QUEUEING TASKS | : 0it [00:00, ?it/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "0364418fcc1345d5b23f8f2eee4e716e",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "PROCESSING TASKS | : 0%| | 0/3 [00:00, ?it/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "4c7161e8136d4a5ca98e622563769647",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "COLLECTING RESULTS | : 0%| | 0/3 [00:00, ?it/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "collection_id = 'C2723754864-GES_DISC' # GPM IMERG Final Precipitation L3 1 day 0.1 degree x 0.1 degree V07 (GPM_3IMERGDF)\n",
+ "\n",
+ "# Bounds within which we search for data granules\n",
+ "# min lon, min lat, max lon, max lat\n",
+ "\n",
+ "# For reference (e.g., to visualize in https://geojson.io/), here is a GeoJSON representing the above bounding box:\n",
+ "# {\"type\": \"FeatureCollection\", \"features\": [{\"type\": \"Feature\", \"properties\": {}, \"geometry\": {\"type\": \"LineString\", \"bbox\": [-127.0761, 31.6444, -113.9039, 42.631], \"coordinates\": [[-113.9039, 42.631], [-127.0761,42.631], [-127.0761, 31.6444], [-113.9039, 31.6444], [-113.9039, 42.631]]}}]}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7de0326f-8c8e-4ae1-b8b2-ae0a73f594cb",
+ "metadata": {},
+ "source": [
+ "Note that `xarray` works with \"lazy\" computation whenever possible. In this case, the metadata are loaded into JupyterHub memory, but the data arrays and their values are not — until there is a need for them."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f72eb32d-8421-4f54-a2bd-7b8bc3dc531a",
+ "metadata": {
+ "tags": []
+ },
+ "source": [
+ "Let's print out all the variable names."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "0f8beea9-bc30-4d02-9401-5b8605ad6847",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "383e376f-149f-4d5f-aa2e-f292e951170f",
+ "metadata": {},
+ "source": [
+ "Of the variables listed above, we are interested in three variables: `precipitation`, `precipitation_cnt_cond`, and `probabilityLiquidPrecipitation`. Let's print their attributes."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "f0241c11-ac86-418a-92e4-bb289468cc16",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "91434dd4-8aad-4b95-9ee4-b5dce04c60a0",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "635f9e55-aa5e-4c4a-a571-2f29917e360e",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f480119f-777f-42b6-ae2c-d9a5de1cb8a0",
+ "metadata": {},
+ "source": [
+ "### Subsetting\n",
+ "\n",
+ "In addition to directly accessing the files archived and distributed by each of the NASA DAACs, many datasets also support services that allow us to customize the data via subsetting, reformatting, reprojection/regridding, and file aggregation. What does subsetting mean? To **subset** means to extract only the portions of a dataset that are needed for a given purpose. Here's a generalized graphic of what we mean. \n",
+ "\n",
+ "![](https://github.com/NASA-Openscapes/earthdata-cloud-cookbook/blob/main/examples/images/subsetting_diagram.png?raw=true){fig-alt=\"Three maps of the United States are present, with a red bounding box over the state of Colorado. Filtering and subsetting are demonstrated by overlaying SMAP L2 data, with data overlapping and cropping the rectangle, respectively.\" width=60%}\n",
+ "\n",
+ "There are three primary types of subsetting that we will walk through: \n",
+ "1. Temporal\n",
+ "2. Spatial\n",
+ "3. Variable\n",
+ "\n",
+ "In each case, we will be excluding parts of the dataset that are not wanted using `xarray`. Note that \"subsetting\" is also called a data \"transformation\"."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "a228b00d-9659-4766-b25b-d9ba82506006",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "23fc1e31-656b-4a02-a80f-b6ea11712068",
+ "metadata": {},
+ "source": [
+ "We start with a subset that represents the U.S. state of California. Notice the dimensions of the Dataset and each variable — time, lon, lat, and 'nv' (number of vertices) for the bounds variable."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "29355579-79f2-4ebf-b7d7-5a5c60a59d2e",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "# Display the full dataset's metadata\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "8641b5ae-043e-4233-bdfe-dada8370dfd5",
+ "metadata": {},
+ "source": [
+ "Now we will prepare a subset. We're using essentially the same spatial bounds as above; however, as opposed to the `earthaccess` inputs above, here we must provide inputs in the formats expected by `xarray`. Instead of a single, four-element, bounding box, we use Python `slice` objects, which are defined by starting and ending numbers."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "e3b5b217-246c-4549-8e7d-773dec50bf40",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "af9214c2-ef33-4d27-acca-511380b565db",
+ "metadata": {},
+ "source": [
+ "Notice the differences?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "210377ad-4dd0-401d-aad8-0d1760941daf",
+ "metadata": {},
+ "source": [
+ "### Plotting\n",
+ "\n",
+ "We will first plot using the methods built-in to the `xarray` package.\n",
+ "\n",
+ "Note that, as opposed to the \"lazy\" loading of metadata previously, this will now perform \"eager\" computation, pulling the required data chunks."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "d97b5757-eb9e-4816-b2c8-5516823080ae",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "566d6593-7d61-4a8a-8873-e313b2474b5a",
+ "metadata": {},
+ "source": [
+ "Now let's utilize the \"Probability of liquid precipitation phase\" (`probabilityLiquidPrecipitation`) variable to split apart the snow precipitation from everything else. From the variable's description attribute, we can see that \"0=missing values; 1=likely solid; 100=likely liquid or no precipitation\".\n",
+ "\n",
+ "Moreover, we'll utilize `precipitation_cnt_cond` to filter out data points that had less than 0.01 mm/hr preciptation amounts."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5c8222e6-df93-496b-ac47-0dcff427fb33",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d0834c9e-653e-4d3d-9114-bf927d6c984b",
+ "metadata": {},
+ "source": [
+ "In the following plotting commands, we utilize `cartopy` and `matplotlib` to generate a more customized figure. \n",
+ "\n",
+ "`cartopy` is used to set the map projection (to PlateCarree) and to add U.S. state boundary lines to the figure. `matplotlib`'s pcolormesh is used to generate the color plot, with colors determined by the third argument's value."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "62e9dcc1-c311-4bef-8a65-08beb54f0453",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "# create the plot\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5ff73775-de33-4033-af1d-1c999e5f5faa",
+ "metadata": {},
+ "source": [
+ "Notice the enhancements?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "49fc0a27-2fbe-4cca-a3d1-095fa6a2b60c",
+ "metadata": {},
+ "source": [
+ "## Example 2 - Harmony-py Subsetting - Precipitable Water from DSCOVR-EPIC Composite"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a1d10aeb-a770-4988-bd1e-0d8b02f818c5",
+ "metadata": {},
+ "source": [
+ "### Dataset\n",
+ "The NASA Earth Polychromatic Imaging Camera (EPIC)-view Multi-Sensor Global Cloud and Radiance Composites are generated by optimally merging together multiple imagers on low Earth orbit (LEO) satellites (including MODIS, VIIRS, and AVHRR) and geostationary (GEO) satellites (including GOES-13 and -15, METEOSAT-7 and -10, MTSAT-2, and Himawari-8). These provide a seamless global composite product at 5-km resolution by using an aggregated rating that considers five parameters (nominal satellite resolution, pixel time relative to the Earth Polychromatic Imaging Camera (EPIC) observation time, viewing zenith angle, distance from day/night terminator, and sun glint factor) and selects the best observation at the time nearest to the EPIC measurements. The global composite data are then remapped into the EPIC Field of View (FOV) by convolving the high-resolution cloud properties with the EPIC point spread function (PSF) defined with a half-pixel accuracy to produce the EPIC composite. PSF-weighted radiances and cloud properties averages are computed separately for each cloud phase. Ancillary data (i.e., surface type, snow and ice map, skin temperature, precipitable water, etc.) needed for anisotropic factor selections are also included in the composite. These composite images are produced for each observation time of the EPIC instrument (typically 300 to 600 composites per month, or every 1 to 3 hours).\n",
+ "\n",
+ "\n",
+ "The dataset and development of the composite product is described in the [Khlopenkov et al., 2017](https://doi.org/10.1117/12.2278645) and the [Product Description page](http://doi.org/10.5067/EPIC/DSCOVR/L2_COMPOSITE_01). This dataset can also be viewed in [Earthdata Search](https://cmr.earthdata.nasa.gov/search/concepts/C1576365803-LARC_ASDC.html). \n",
+ "\n",
+ "Please cite the dataset as:\n",
+ "> NASA/LARC/SD/ASDC. (2017). EPIC-view satellite composites for DSCOVR, Version 1 [Data set]. NASA Langley Atmospheric Science Data Center DAAC. Retrieved from https://doi.org/10.5067/EPIC/DSCOVR/L2_COMPOSITE_01."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a0df8ec4-6c65-4746-8c06-c6b8e42eaadb",
+ "metadata": {},
+ "source": [
+ "### Harmony\n",
+ "\n",
+ "[Harmony](https://www.earthdata.nasa.gov/learn/articles/harmony-in-the-cloud) is the behind-the-scenes orchestrator for much of the cloud-based transformations happening on NASA's [Earthdata Search](https://search.earthdata.nasa.gov/search) interface. However, requests can also be sent directly to Harmony in a programmatic fashion, either through use of the `harmony-py` Python library or through transmitting underlying HTTP requests. In this example, we demonstrate the use of `harmony-py`, which was created as an alternative to Harmony's RESTful Application Programming Interface (API) and to make it more convenient to invoke Harmony directly from a Python environment, such as Jupyter notebooks or larger Python applications.\n",
+ "\n",
+ "Note that additional examples can be found on the `harmony-py` GitHub page [here](https://github.com/nasa/harmony-py/tree/main)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b88e0741-db91-4d6a-95bf-82554eeb8a96",
+ "metadata": {},
+ "source": [
+ "First we need to instantiate a `Client` object, with which we will be able to interact with Harmony."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "583e324b-88c9-4726-af33-ff07367dcf28",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "28bb3263-7a60-4e17-b2d0-2f9189badceb",
+ "metadata": {},
+ "source": [
+ "#### Inspecting a data collection for its capabilities and variables\n",
+ "\n",
+ "With harmony-py, you can request a report of the capabilities that are configured for a given collection. We use that function here to inspect the DSCOVR EPIC-view Composite collection."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "db162b89-de86-4bb0-b620-4257d9af6b92",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "844bdc84-4eeb-4cba-bb66-41ff8cc9ba51",
+ "metadata": {},
+ "source": [
+ "This data collection has one \"service\" associated with it, which provides several subsetting capabilities."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4b59af1b-7338-40f9-8965-80339436f6a1",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "958edbe7-d4ab-4df7-aefa-ecf717ccb9d1",
+ "metadata": {},
+ "source": [
+ "We can also see the list of variables associated with this data collection."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "3fbe4b39-df2c-4189-9eb9-aadeb1b492c0",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ef12d0b6-0fac-4f9c-bbb0-0c199cf53e70",
+ "metadata": {},
+ "source": [
+ "The subsetter service capabilities told us what the service is capable of \"in general\". How about the capabilities reported for this data collection in particular?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "90865d24-6bbc-46ff-97a4-05f7d8fb4f3b",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4184b164-2ba1-4180-a338-263302bc29a6",
+ "metadata": {},
+ "source": [
+ "Notice the `True`s and the `False`s?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "60f65119-5436-4701-ac48-bf64d6d163cc",
+ "metadata": {},
+ "source": [
+ "### Subsetting"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "03b8f6a3-5278-4ca7-87e5-75f10deec65c",
+ "metadata": {},
+ "source": [
+ "#### Define an area of interest\n",
+ "\n",
+ "For this example, we will use a GeoJSON to specify a non-rectangular region instead of a simpler, rectangular bounding box. We will use the GeoJSON that defines a region around San Francisco."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "33249e74-603d-4030-a2df-1b19df50fce1",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "# Read the GeoJSON into a GeoDataFrame\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b7e72238-dea5-400a-b09e-74a75ecf46ad",
+ "metadata": {},
+ "source": [
+ "Here we illustrate the use of GeoViews, which is another open source data visualization library, like `matplotlib`. GeoViews is designed to work well with netCDF data, as well as Geopandas dataframes. The syntax for Geoviews is different in several ways — e.g., the dataset is often specified as the first argument and different components are combined using the `*` symbol."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "58c13872-3ca2-436e-ae53-3c22ce07e60c",
+ "metadata": {
+ "collapsed": true,
+ "jupyter": {
+ "outputs_hidden": true
+ },
+ "tags": []
+ },
+ "outputs": [
+ {
+ "ename": "NameError",
+ "evalue": "name 'gv' is not defined",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[0;32mIn[4], line 5\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# We define a Geoview Point so we can visualize the area of interest in relation to San Francisco\u001b[39;00m\n\u001b[1;32m 2\u001b[0m \n\u001b[1;32m 3\u001b[0m \n\u001b[1;32m 4\u001b[0m \u001b[38;5;66;03m# Generate an image\u001b[39;00m\n\u001b[0;32m----> 5\u001b[0m base \u001b[38;5;241m=\u001b[39m \u001b[43mgv\u001b[49m\u001b[38;5;241m.\u001b[39mtile_sources\u001b[38;5;241m.\u001b[39mEsriImagery\u001b[38;5;241m.\u001b[39mopts(width\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m650\u001b[39m, height\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m500\u001b[39m)\n\u001b[1;32m 6\u001b[0m ocean_map \u001b[38;5;241m=\u001b[39m gv\u001b[38;5;241m.\u001b[39mPolygons(gdf)\u001b[38;5;241m.\u001b[39mopts(line_color\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124myellow\u001b[39m\u001b[38;5;124m'\u001b[39m, line_width\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m5\u001b[39m, color\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m)\n\u001b[1;32m 8\u001b[0m base \u001b[38;5;241m*\u001b[39m ocean_map \u001b[38;5;241m*\u001b[39m cities_lonlat\u001b[38;5;241m.\u001b[39moptions(size\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m20\u001b[39m, color\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mred\u001b[39m\u001b[38;5;124m'\u001b[39m, marker\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mx\u001b[39m\u001b[38;5;124m'\u001b[39m)\n",
+ "\u001b[0;31mNameError\u001b[0m: name 'gv' is not defined"
+ ]
+ }
+ ],
+ "source": [
+ "# We define a Geoview Point so we can visualize the area of interest in relation to San Francisco\n",
+ "\n",
+ "\n",
+ "# Generate an image\n",
+ "base = gv.tile_sources.EsriImagery.opts(width=650, height=500)\n",
+ "ocean_map = gv.Polygons(gdf).opts(line_color='yellow', line_width=5, color=None)\n",
+ "\n",
+ "base * ocean_map * cities_lonlat.options(size=20, color='red', marker='x')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9e01ba7d-e499-4869-a835-6e2349303e21",
+ "metadata": {},
+ "source": [
+ "#### Build a Harmony subsetting request\n",
+ "\n",
+ "A Harmony request can include spatial, temporal, and variable subsetting all in the same request. Here we will request all three types of subsetting to be performed on the EPIC-view Composite dataset."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "f02d190d-81f3-4fd2-b92e-5345769b85ca",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2ca89302-42f0-4017-ba0f-a6e348b8dc1d",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "044b95c6-4312-4d99-acfc-6eea0e28056d",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2abe3ac3-5172-4218-ba44-0b063abdbac1",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "da982b31-5fad-4202-8b86-09d98e83859b",
+ "metadata": {},
+ "source": [
+ "While this processes, we can discuss the harmony job in some more detail. First, note that this request is identical to what can be achieved through NASA's Earthdata Search interface, such as this URL: [https://search.earthdata.nasa.gov/search/granules?p=C1576365803-LARC_ASDC!C1576365803-LARC_ASDC&pg[1][a]=1576368528!1576368575!LARC_ASDC&pg[1][v]=t&pg[1][gsk]=-start_date&pg[1][m]=harmony0&pg[1][of]=application/x-netcdf4&pg[1][ets]=t&pg[1][ess]=t&q=C1576365803-LARC_ASDC&sb[0]=-123.99609%2C37.19991%2C-120.44531%2C38.78263&qt=2016-02-24T12%3A00%3A00.000Z%2C2016-02-24T23%3A00%3A00.000Z&tl=1702228562!3!!&lat=37.8270894268111&long=-130.67578125&zoom=4](https://search.earthdata.nasa.gov/search/granules?p=C1576365803-LARC_ASDC!C1576365803-LARC_ASDC&pg[1][a]=1576368528!1576368575!LARC_ASDC&pg[1][v]=t&pg[1][gsk]=-start_date&pg[1][m]=harmony0&pg[1][of]=application/x-netcdf4&pg[1][ets]=t&pg[1][ess]=t&q=C1576365803-LARC_ASDC&sb[0]=-123.99609%2C37.19991%2C-120.44531%2C38.78263&qt=2016-02-24T12%3A00%3A00.000Z%2C2016-02-24T23%3A00%3A00.000Z&tl=1702228562!3!!&lat=37.8270894268111&long=-130.67578125&zoom=4)\n",
+ "\n",
+ "(Futher information and examples can be found in the `harmony-py` repository, such as [this introductory notebook](https://github.com/nasa/harmony-py/blob/main/examples/intro_tutorial.ipynb).)\n",
+ "\n",
+ "#### Request Parameters\n",
+ "\n",
+ "In addition to the above request parameters, other advanced parameters may be of interest. Note that many reformatting or advanced projection options may not be available for your requested dataset. See the documentation for details on how to construct these parameters.\n",
+ "\n",
+ "- `crs`: Reproject the output coverage to the given CRS. Recognizes CRS types that can be inferred by gdal, including EPSG codes, Proj4 strings, and OGC URLs (http://www.opengis.net/def/crs/%E2%80%A6)\n",
+ "- `interpolation`: specify the interpolation method used during reprojection and scaling\n",
+ "- `scale_extent`: scale the resulting coverage either among one axis to a given extent\n",
+ "- `scale_size`: scale the resulting coverage either among one axis to a given size\n",
+ "- `granule_id`: The CMR Granule ID for the granule (file) which should be retrieved\n",
+ "- `width`: number of columns to return in the output coverage\n",
+ "- `height`: number of rows to return in the output coverage\n",
+ "- `format`: the output mime type to return\n",
+ "- `max_results`: limits the number of input files processed in the request\n",
+ "\n",
+ "#### Harmony Client\n",
+ "\n",
+ "There are four options for providing your Earthdata Login token or username and password when creating a Harmony Client:\n",
+ "\n",
+ "1. Provide EDL token using environment variable, e.g.:\n",
+ "\n",
+ "> `$ export EDL_TOKEN='my_eld_token'`\n",
+ "\n",
+ "2. Provide your username and password directly when creating the client:\n",
+ "\n",
+ "> `harmony_client = Client(auth=('captainmarvel', 'marve10u5'))`\n",
+ "\n",
+ "3. Set your credentials using environment variables:\n",
+ "\n",
+ "You can either export these directly:\n",
+ "\n",
+ "> `$ export EDL_USERNAME='captainmarvel'`\n",
+ "\n",
+ "> `$ export EDL_PASSWORD='marve10u5'`\n",
+ "\n",
+ "Or by storing them in a .env file, which operates in a similar fashion to .netrc. You will need to store the file in your current working directory and it must be named .env with the following format:\n",
+ "\n",
+ "> `EDL_USERNAME=myusername`\n",
+ "\n",
+ "> `EDL_PASSWORD=mypass`\n",
+ "\n",
+ "4. Use a .netrc file:\n",
+ "\n",
+ "> ```\n",
+ "machine urs.earthdata.nasa.gov\n",
+ "login captainmarvel\n",
+ "password marve10u5\n",
+ "```"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "dcdf99d8-74c1-49cf-b65d-38ea1ef0e5e4",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4d996a53-6cf4-40c3-a5c5-06d932956609",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "80f432ab-17aa-4fe8-b99a-831dd59725ed",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ef2b5dea-e0ba-4574-90b7-f087c94605b7",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c6fc0c90-8a6d-4248-ab94-4b8e6afdedc2",
+ "metadata": {},
+ "source": [
+ "### Plotting"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "629911d9-8b17-44b0-8e3d-2e630a521495",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "id": "1c01834c-1ce1-4993-8b43-9a8bc9a862b9",
+ "metadata": {
+ "collapsed": true,
+ "jupyter": {
+ "outputs_hidden": true
+ },
+ "tags": []
+ },
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ "