{ "cells": [ { "cell_type": "markdown", "id": "d2583da9-3f1e-40e6-b81d-700f26e89daa", "metadata": { "tags": [] }, "source": [ "## Accessing NOAA U.S. NClimGrid with the Planetary Computer STAC API\n", "\n", "The [NOAA U.S. Climate Gridded Dataset (NClimGrid)](https://www.ncei.noaa.gov/access/metadata/landing-page/bin/iso?id=gov.noaa.ncdc:C00332) consists of four climate variables derived from the Global Historical Climatology Network Daily dataset (GHCNd): \n", "- maximum temperature, \n", "- minimum temperature, \n", "- average temperature, \n", "- and precipitation. \n", "\n", "Values in a 1/24 degree lat/lon (nominal 5x5 kilometer) grid are provided for the contiguous United States (CONUS). Daily data are available from 1951 to the present; monthly data span from 1895 to present. Images are stored in cloud-optimized GeoTIFF (COG) format.\n", "\n", "\n", "In this notebook, we'll demonstrate how to access and work with NClimGrid Monthly data through the Planetary Computer API. Documentation for this dataset is available at the [Planetary Computer Data Catalog](https://planetarycomputer.microsoft.com/dataset/group/noaa-nclimgrid).\n", "\n" ] }, { "cell_type": "markdown", "id": "6c7da081-b792-45f2-a428-ea8f9ecbda08", "metadata": {}, "source": [ "### Environment setup\n", "\n", "This notebook works with or without an API key, but you will be given more permissive access to the data with an API key.\n", "The [Planetary Computer Hub](https://planetarycomputer.microsoft.com/compute) is pre-configured to the user account API key." ] }, { "cell_type": "code", "execution_count": 1, "id": "f3f030fa-8639-4b4e-b0a1-f3226375c28e", "metadata": {}, "outputs": [], "source": [ "import odc.stac\n", "import planetary_computer\n", "import pystac_client\n", "import rich.table" ] }, { "cell_type": "markdown", "id": "527d242e-32b4-49fb-a513-a74ee38495da", "metadata": { "tags": [] }, "source": [ "### Query for available data\n", "\n", "The datasets hosted by the Planetary Computer are available from [Azure Blob Storage](https://docs.microsoft.com/en-us/azure/storage/blobs/). We'll use [pystac-client](https://pystac-client.readthedocs.io/) to search the Planetary Computer's [STAC API](https://planetarycomputer.microsoft.com/api/stac/v1/docs) for the subset of the data that we care about, and then we'll load the data directly from Azure Blob Storage. We'll specify a `modifier` so that we can access the data stored in the Planetary Computer's private Blob Storage Containers. See [Reading from the STAC API](https://planetarycomputer.microsoft.com/docs/quickstarts/reading-stac/) and [Using tokens for data access](https://planetarycomputer.microsoft.com/docs/concepts/sas/) for more.\n", "\n", "In this notebook, we'll demonstrate how to access and work with NClimGrid Monthly data. We select times within the monthly data temporal extent (1951 to the present). The STAC API locates the available STAC items within the specified parameter." ] }, { "cell_type": "code", "execution_count": null, "id": "914344e5", "metadata": {}, "outputs": [], "source": [ "# Open the Planetary Computer STAC API\n", "catalog = pystac_client.Client.open(\n", " \"https://planetarycomputer.microsoft.com/api/stac/v1/\",\n", " modifier=planetary_computer.sign_inplace,\n", ")" ] }, { "cell_type": "code", "execution_count": 3, "id": "63ddd01e-2ae3-4b5d-af8f-cdcbb56f0423", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Fetching 2020-01-01\n", "Fetching 2020-04-01\n", "Fetching 2020-07-01\n", "Fetching 2020-10-01\n" ] } ], "source": [ "# Select time of interest\n", "datetimes = [\n", " \"2020-01-01\",\n", " \"2020-04-01\",\n", " \"2020-07-01\",\n", " \"2020-10-01\",\n", "]\n", "\n", "items = dict()\n", "\n", "# Fetch the collection of interest and print available items\n", "for datetime in datetimes:\n", " print(f\"Fetching {datetime}\")\n", " search = catalog.search(\n", " collections=[\"noaa-nclimgrid-monthly\"],\n", " datetime=datetime,\n", " )\n", " items[datetime] = next(search.items())" ] }, { "cell_type": "markdown", "id": "69f3564c-bd52-452d-875d-34d9309a64c9", "metadata": {}, "source": [ "### Available Assets" ] }, { "cell_type": "markdown", "id": "cfd0f626-55bb-4bcf-a2b6-d276df55a0d4", "metadata": {}, "source": [ "Let's display the available assets and metadata for the NClimGrid Monthly items. " ] }, { "cell_type": "code", "execution_count": 4, "id": "2cc1ebf2-1188-42db-90b5-17026d7770b7", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n", "┃ Key ┃ Value ┃\n", "┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n", "│ prcp │ Monthly Precipitation (mm) │\n", "│ tavg │ Monthly Average Temperature (degree Celsius) │\n", "│ tmax │ Monthly Maximmum Temperature (degree Celsius) │\n", "│ tmin │ Monthly Minimum Temperature (degree Celsius) │\n", "│ prcp_source │ Monthly Precipitation Source Data │\n", "│ tavg_source │ Monthly Average Temperature Source Data │\n", "│ tmax_source │ Monthly Maximmum Temperature Source Data │\n", "│ tmin_source │ Monthly Minimum Temperature Source Data │\n", "│ tilejson │ TileJSON with default rendering │\n", "│ rendered_preview │ Rendered preview │\n", "└──────────────────┴───────────────────────────────────────────────┘\n", "\n" ], "text/plain": [ "┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n", "┃\u001b[1m \u001b[0m\u001b[1mKey \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mValue \u001b[0m\u001b[1m \u001b[0m┃\n", "┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n", "│ prcp │ Monthly Precipitation (mm) │\n", "│ tavg │ Monthly Average Temperature (degree Celsius) │\n", "│ tmax │ Monthly Maximmum Temperature (degree Celsius) │\n", "│ tmin │ Monthly Minimum Temperature (degree Celsius) │\n", "│ prcp_source │ Monthly Precipitation Source Data │\n", "│ tavg_source │ Monthly Average Temperature Source Data │\n", "│ tmax_source │ Monthly Maximmum Temperature Source Data │\n", "│ tmin_source │ Monthly Minimum Temperature Source Data │\n", "│ tilejson │ TileJSON with default rendering │\n", "│ rendered_preview │ Rendered preview │\n", "└──────────────────┴───────────────────────────────────────────────┘\n" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Assets\n", "t = rich.table.Table(\"Key\", \"Value\")\n", "for key, asset in items[\"2020-01-01\"].assets.items():\n", " t.add_row(key, asset.title)\n", "t" ] }, { "cell_type": "code", "execution_count": 5, "id": "1c6ae738-7e4d-4718-9c67-22783557bff6", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n", "┃ Key ┃ Value ┃\n", "┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n", "│ created │ 2022-09-07T19:48:28.906953Z │\n", "│ datetime │ None │\n", "│ end_datetime │ 2020-01-31T23:59:59Z │\n", "│ proj:epsg │ 4326 │\n", "│ proj:shape │ [596, 1385] │\n", "│ proj:transform │ [0.04166667, 0.0, -124.70833333, 0.0, -0.04166667, 49.37500127] │\n", "│ start_datetime │ 2020-01-01T00:00:00Z │\n", "└────────────────┴─────────────────────────────────────────────────────────────────┘\n", "\n" ], "text/plain": [ "┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n", "┃\u001b[1m \u001b[0m\u001b[1mKey \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mValue \u001b[0m\u001b[1m \u001b[0m┃\n", "┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n", "│ created │ 2022-09-07T19:48:28.906953Z │\n", "│ datetime │ None │\n", "│ end_datetime │ 2020-01-31T23:59:59Z │\n", "│ proj:epsg │ 4326 │\n", "│ proj:shape │ [596, 1385] │\n", "│ proj:transform │ [0.04166667, 0.0, -124.70833333, 0.0, -0.04166667, 49.37500127] │\n", "│ start_datetime │ 2020-01-01T00:00:00Z │\n", "└────────────────┴─────────────────────────────────────────────────────────────────┘\n" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Metadata\n", "t = rich.table.Table(\"Key\", \"Value\")\n", "for k, v in sorted(items[\"2020-01-01\"].properties.items()):\n", " t.add_row(k, str(v))\n", "t" ] }, { "cell_type": "markdown", "id": "fcd49bc9-32ac-4b10-83f8-e9fbd2a870ac", "metadata": {}, "source": [ "### Loading the land cover data\n", "Now let's load STAC items into an xarray dataset using [odc-stac](https://github.com/opendatacube/odc-stac). Location coordinates are centered to CONUS (39.50°N, 98.35°W). " ] }, { "cell_type": "code", "execution_count": 6, "id": "a47797be-4fd0-4e4a-aed1-212642d05043", "metadata": {}, "outputs": [], "source": [ "item = list(items.values())[0]\n", "stac_cfg = {item.collection_id: {\"assets\": {k: {\"nodata\": 0} for k in item.assets}}}" ] }, { "cell_type": "code", "execution_count": 7, "id": "a8fc2966-2787-4f20-bb2d-e47d4829cec5", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
<xarray.Dataset>\n", "Dimensions: (latitude: 1683, longitude: 1684, time: 4)\n", "Coordinates:\n", " * latitude (latitude) float64 74.48 74.44 74.4 74.36 ... 4.597 4.555 4.514\n", " * longitude (longitude) float64 -133.3 -133.3 -133.3 ... -63.38 -63.34\n", " spatial_ref int32 4326\n", " * time (time) datetime64[ns] 2020-01-01 2020-04-01 ... 2020-10-01\n", "Data variables:\n", " prcp (time, latitude, longitude) float32 nan nan nan ... nan nan nan\n", " tavg (time, latitude, longitude) float32 nan nan nan ... nan nan nan\n", " tmax (time, latitude, longitude) float32 nan nan nan ... nan nan nan\n", " tmin (time, latitude, longitude) float32 nan nan nan ... nan nan nan