{ "cells": [ { "cell_type": "markdown", "id": "e9dfe0df-9f1a-4e5d-99d3-81f01a76d3c8", "metadata": { "tags": [] }, "source": [ "# Awesome HRRR \n", "\n", "**Rich Signell (USGS) with Martin Durant (Anaconda), Eskild Eriksen (Quansight)**\n", "\n", "NOAA's High-Resolution Rapid Refresh (HRRR) model is a 3km model of CONUS updated every hour, assimilating Radar data every 15 minutes. \n", "\n", "\n", "\n", "**Data**: \n", "* [AWS Public Data](https://registry.opendata.aws/noaa-hrrr-pds/): Available on the Cloud, YAY! Thousands of GRIB2 files each day -- not awesome yet!\n", "\n", "**Goal**:\n", "Make it easy and cloud-performant to access this collection of data. We use Kerchunk/Fsspec to extract all the metadata, create a virtual Zarrset which just pokes into the files to only extract the compressed data chunks from the pile of files. \n", "\n", "**Tech Stack**:\n", "* [Nebari](https://www.nebari.dev/) (formerly Qhub) for deploying JupyterHub on Kubernetes with [Dask Gateway](https://gateway.dask.org/)\n", "* [fsspec](https://filesystem-spec.readthedocs.io/en/latest/) for representing scientific data format files as a Zarr dataset (ReferenceFileSystem)\n", "* [Kerchunk](https://github.com/fsspec/kerchunk) for creating the ReferenceFileSystem JSON\n", "* [kbatch](https://github.com/kbatch-dev/kbatch) for running notebooks as batch jobs on Kubernetes (includes new `cronjob` feature for running on a schedule)\n", "* Jupyter, Dask, Xarray, Zarr, Holoviz\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "9ac4c885-3e20-473b-aca5-63e611c181f9", "metadata": {}, "outputs": [], "source": [ "import xarray as xr\n", "import hvplot.xarray\n", "import panel as pn\n", "import fsspec\n", "import datetime as dt" ] }, { "cell_type": "markdown", "id": "eac4889f-9979-4016-b492-ac54b3b1289d", "metadata": {}, "source": [ "#### Create Dask Cluster \n", "Here we use Dask Gateway, but could use any Dask Cluster" ] }, { "cell_type": "code", "execution_count": null, "id": "f0d7312e-ccbf-4962-8320-12a31fbabe16", "metadata": {}, "outputs": [], "source": [ "from dask_gateway import Gateway\n", "# instantiate dask gateway\n", "gateway = Gateway()\n", "\n", "# setup a cluster\n", "options = gateway.cluster_options(use_local_defaults=False)\n", "\n", "options.conda_environment='users/pangeo'\n", "options.profile = 'Medium Worker'\n", "\n", "cluster = gateway.new_cluster(options)\n", "\n", "cluster.scale(30)\n", "\n", "# get the client for the cluster\n", "client = cluster.get_client()" ] }, { "cell_type": "code", "execution_count": 21, "id": "55e2b4d0-2753-4a6e-b14e-43aa3c932a0f", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "8d537adc78c14d4db0a9b3a88389a1a3", "version_major": 2, "version_minor": 0 }, "text/plain": [ "VBox(children=(HTML(value='
<xarray.Dataset>\n",
"Dimensions: (valid_time: 90, y: 1059, x: 1799)\n",
"Coordinates:\n",
" heightAboveGround float64 ...\n",
" latitude (y, x) float64 dask.array<chunksize=(1059, 1799), meta=np.ndarray>\n",
" longitude (y, x) float64 dask.array<chunksize=(1059, 1799), meta=np.ndarray>\n",
" step timedelta64[ns] ...\n",
" time (valid_time) datetime64[ns] dask.array<chunksize=(1,), meta=np.ndarray>\n",
" * valid_time (valid_time) datetime64[ns] 2022-07-10T17:00:00 ... 20...\n",
"Dimensions without coordinates: y, x\n",
"Data variables:\n",
" d2m (valid_time, y, x) float32 dask.array<chunksize=(1, 1059, 1799), meta=np.ndarray>\n",
" pt (valid_time, y, x) float32 dask.array<chunksize=(1, 1059, 1799), meta=np.ndarray>\n",
" r2 (valid_time, y, x) float32 dask.array<chunksize=(1, 1059, 1799), meta=np.ndarray>\n",
" sh2 (valid_time, y, x) float32 dask.array<chunksize=(1, 1059, 1799), meta=np.ndarray>\n",
" si10 (valid_time, y, x) float32 dask.array<chunksize=(1, 1059, 1799), meta=np.ndarray>\n",
" t2m (valid_time, y, x) float32 dask.array<chunksize=(1, 1059, 1799), meta=np.ndarray>\n",
" u10 (valid_time, y, x) float32 dask.array<chunksize=(1, 1059, 1799), meta=np.ndarray>\n",
" unknown (valid_time, y, x) float32 dask.array<chunksize=(1, 1059, 1799), meta=np.ndarray>\n",
" v10 (valid_time, y, x) float32 dask.array<chunksize=(1, 1059, 1799), meta=np.ndarray>\n",
"Attributes:\n",
" Conventions: CF-1.7\n",
" GRIB_centre: kwbc\n",
" GRIB_centreDescription: US National Weather Service - NCEP\n",
" GRIB_edition: 2\n",
" GRIB_subCentre: 0\n",
" history: 2022-07-13T18:55 GRIB to CDM+CF via cfgrib-0.9.1...\n",
" institution: US National Weather Service - NCEP| Workers | 30 |
|---|---|
| Threads | 60 |
| Memory | 240.00 GiB |
Dashboard: https://jupyter.qhub.esipfed.org/gateway/clusters/dev.af59dda21ced4ffba572390fe11a4780/status
\n" } }, "5b64058914174fedb653bed7cf6af5f6": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "6456d941dc8344c7ab9195230062a321": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntTextModel", "state": { "description": "Maximum", "layout": "IPY_MODEL_6a6fb9398bfe4fb9ba54b3efa99fa8ee", "step": 1, "style": "IPY_MODEL_abbaa29df02b40a2b59fbcffc43cd303" } }, "6a6fb9398bfe4fb9ba54b3efa99fa8ee": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "150px" } }, "8d537adc78c14d4db0a9b3a88389a1a3": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "children": [ "IPY_MODEL_e493111b36fc474d94c2b19f7f41fe53", "IPY_MODEL_2e59ba6c5888411e90a27a4cd84d6b09", "IPY_MODEL_f94143594e094e8294f5cbdc6f590b8a", "IPY_MODEL_55af4f69e0f34a008e369ad7f8406374" ], "layout": "IPY_MODEL_3f1983ed4754497fa2d26ff371fcdcdf" } }, "abbaa29df02b40a2b59fbcffc43cd303": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "ad5bf6e47d52444fa552fbb1936ddf1d": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "add02d8fbcb048c2b5a308656443a7e4": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "ButtonStyleModel", "state": {} }, "ba49ce3fecc644d190ac054103004326": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "be3e7455fb824a39a4165c3436c39424": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "c06c9ed068c446d7afcd6c5b9463f70f": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "c3befad4fd754b2ea0c0c546f26ddf7b": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "min_width": "150px" } }, "c68ef040e684402a8e1c6cc692205bf3": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "min_width": "500px" } }, "c9016a30b7894e929c8b7d4288d8babb": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntTextModel", "state": { "description": "Workers", "layout": "IPY_MODEL_6a6fb9398bfe4fb9ba54b3efa99fa8ee", "step": 1, "style": "IPY_MODEL_201fac89f02349b6b2acbe72998b42f9" } }, "dcc23361e2784464be49d97bb3ee806b": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "children": [ "IPY_MODEL_41c7ad774d874e70b37f06501d27dd38", "IPY_MODEL_6456d941dc8344c7ab9195230062a321", "IPY_MODEL_e4192dcb139a46119d7fdcdda161667e" ], "layout": "IPY_MODEL_f033b5c20e3f4a6e938b3af9e208c808" } }, "e4192dcb139a46119d7fdcdda161667e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "ButtonModel", "state": { "description": "Adapt", "layout": "IPY_MODEL_6a6fb9398bfe4fb9ba54b3efa99fa8ee", "style": "IPY_MODEL_add02d8fbcb048c2b5a308656443a7e4" } }, "e493111b36fc474d94c2b19f7f41fe53": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "layout": "IPY_MODEL_31df01b8363343cd91505b11db0d70b5", "style": "IPY_MODEL_0be288d2ef3e4737ad6a0922bef57946", "value": "Name: dev.af59dda21ced4ffba572390fe11a4780
" } }, "fcbb071b5217439b864323987d4fd483": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } } }, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }