|
2 | 2 | "cells": [ |
3 | 3 | { |
4 | 4 | "cell_type": "markdown", |
5 | | - "id": "cdeef4c6-75b0-44d9-90d4-c850b5d8908a", |
| 5 | + "id": "intro", |
6 | 6 | "metadata": {}, |
7 | 7 | "source": [ |
8 | 8 | "# How to use the Compatibility API\n", |
9 | 9 | "\n", |
10 | | - "The `/compatibility` endpoint displays information about the collection and returns some details about a sample granule. The output is helpful for understanding the structure of the collection and the granules so that you can craft the right set of parameters for visualization or statistics requests.\n", |
| 10 | + "The `/compatibility` endpoint helps you understand how to call TiTiler-CMR for a collection. For hierarchical HDF5 and NetCDF datasets it can return a lightweight list of candidate `group` paths from the root request, then let you inspect variables by making a follow-up request with `group=...`.\n", |
11 | 11 | "\n", |
12 | | - "This notebook demonstrates how to use the compatibility endpoint for th [GHRSST Level 4 MUR Global Foundation Sea Surface Temperature Analysis (v4.1)](https://cmr.earthdata.nasa.gov/search/concepts/C1996881146-POCLOUD) dataset.\n", |
| 12 | + "This notebook demonstrates that workflow for the [NISAR Beta Geocoded Polarimetric Covariance (GCOV)](https://www.earthdata.nasa.gov/data/catalog/asf-nisar-l2-gcov-beta-v1-1) collection, which is a known example of a hierarchical HDF5 dataset that needs a `group` parameter for xarray requests.\n", |
13 | 13 | "\n", |
14 | 14 | "## Setup" |
15 | 15 | ] |
16 | 16 | }, |
17 | 17 | { |
18 | 18 | "cell_type": "code", |
19 | 19 | "execution_count": null, |
20 | | - "id": "7d015182-5347-437a-8b66-d7d62212f0e3", |
| 20 | + "id": "setup", |
21 | 21 | "metadata": {}, |
22 | 22 | "outputs": [], |
23 | 23 | "source": [ |
| 24 | + "import json\n", |
24 | 25 | "import os\n", |
25 | 26 | "\n", |
26 | | - "import json\n", |
27 | 27 | "import earthaccess\n", |
28 | 28 | "import httpx2 as httpx\n", |
29 | 29 | "\n", |
30 | 30 | "titiler_endpoint = os.getenv(\n", |
31 | | - " \"TITILER_CMR_ENDPOINT\", \"https://openveda.cloud/api/titiler-cmr\"\n", |
| 31 | + " \"TITILER_CMR_ENDPOINT\", \"https://staging.openveda.cloud/api/titiler-cmr\"\n", |
32 | 32 | ")" |
33 | 33 | ] |
34 | 34 | }, |
35 | 35 | { |
36 | 36 | "cell_type": "markdown", |
37 | | - "id": "d375b5b7-9322-4f1e-8859-000ef8ac4898", |
| 37 | + "id": "identify-dataset", |
38 | 38 | "metadata": {}, |
39 | 39 | "source": [ |
40 | 40 | "## Identify the dataset\n", |
41 | 41 | "\n", |
42 | | - "You can find the MUR SST dataset using the `earthaccess.search_datasets` function." |
| 42 | + "You can find the collection with `earthaccess.search_datasets`." |
43 | 43 | ] |
44 | 44 | }, |
45 | 45 | { |
46 | 46 | "cell_type": "code", |
47 | 47 | "execution_count": null, |
48 | | - "id": "f3fcc9cd-6105-42fc-98bf-2de40910a79c", |
| 48 | + "id": "search-dataset", |
49 | 49 | "metadata": {}, |
50 | 50 | "outputs": [], |
51 | 51 | "source": [ |
52 | | - "datasets = earthaccess.search_datasets(concept_id=\"C1996881146-POCLOUD\")\n", |
| 52 | + "datasets = earthaccess.search_datasets(concept_id=\"C3622214170-ASF\")\n", |
53 | 53 | "ds = datasets[0]\n", |
54 | 54 | "\n", |
55 | 55 | "collection_concept_id = ds[\"meta\"][\"concept-id\"]\n", |
56 | | - "print(\"CollectionConcept-Id: \", collection_concept_id)\n", |
57 | | - "\n", |
58 | | - "print(\"Abstract: \", ds[\"umm\"][\"Abstract\"])" |
| 56 | + "print(\"CollectionConcept-Id:\", collection_concept_id)\n", |
| 57 | + "print(\"Short name:\", ds[\"umm\"][\"ShortName\"])\n", |
| 58 | + "print(\"Version:\", ds[\"umm\"][\"Version\"])" |
59 | 59 | ] |
60 | 60 | }, |
61 | 61 | { |
62 | 62 | "cell_type": "markdown", |
63 | | - "id": "2a4cffa6-0059-4033-a708-db60d743f0e3", |
| 63 | + "id": "explore-collection", |
64 | 64 | "metadata": {}, |
65 | 65 | "source": [ |
66 | | - "## Explore the collection using the `/compatibility` endpoint" |
| 66 | + "## Explore the collection using `/compatibility`" |
67 | 67 | ] |
68 | 68 | }, |
69 | 69 | { |
70 | 70 | "cell_type": "code", |
71 | 71 | "execution_count": null, |
72 | | - "id": "1bde609a-26df-4f35-b7e1-9e1922e87808", |
| 72 | + "id": "compatibility-request", |
73 | 73 | "metadata": {}, |
74 | 74 | "outputs": [], |
75 | 75 | "source": [ |
|
84 | 84 | }, |
85 | 85 | { |
86 | 86 | "cell_type": "markdown", |
87 | | - "id": "04014a32-9c11-4b75-b40a-e5ad4efd686b", |
| 87 | + "id": "interpret-response", |
| 88 | + "metadata": {}, |
| 89 | + "source": [ |
| 90 | + "## Interpret the response\n", |
| 91 | + "\n", |
| 92 | + "For hierarchical datasets, a root `/compatibility` request stays lightweight. The most important field is:\n", |
| 93 | + "\n", |
| 94 | + "- `compatible_groups`: candidate group paths to try in a follow-up request\n", |
| 95 | + "\n", |
| 96 | + "At this stage the response may not include variable metadata or xarray links yet, because TiTiler-CMR has not inspected a nested group." |
| 97 | + ] |
| 98 | + }, |
| 99 | + { |
| 100 | + "cell_type": "code", |
| 101 | + "execution_count": null, |
| 102 | + "id": "summarize-response", |
| 103 | + "metadata": {}, |
| 104 | + "outputs": [], |
| 105 | + "source": [ |
| 106 | + "compatible_groups = compatibility_response.get(\"compatible_groups\", [])\n", |
| 107 | + "variables = list((compatibility_response.get(\"variables\") or {}).keys())\n", |
| 108 | + "tilejson_link = next(\n", |
| 109 | + " (\n", |
| 110 | + " link[\"href\"]\n", |
| 111 | + " for link in compatibility_response.get(\"links\", [])\n", |
| 112 | + " if link[\"rel\"] == \"tilejson\"\n", |
| 113 | + " ),\n", |
| 114 | + " None,\n", |
| 115 | + ")\n", |
| 116 | + "\n", |
| 117 | + "print(\"compatible_groups:\")\n", |
| 118 | + "for group in compatible_groups:\n", |
| 119 | + " print(\" -\", group)" |
| 120 | + ] |
| 121 | + }, |
| 122 | + { |
| 123 | + "cell_type": "markdown", |
| 124 | + "id": "inspect-explicit-group", |
| 125 | + "metadata": {}, |
| 126 | + "source": [ |
| 127 | + "## Inspect a specific group\n", |
| 128 | + "\n", |
| 129 | + "Once you choose a group from `compatible_groups`, make a follow-up `/compatibility` request with `group=...` to inspect variables and get xarray links." |
| 130 | + ] |
| 131 | + }, |
| 132 | + { |
| 133 | + "cell_type": "code", |
| 134 | + "execution_count": null, |
| 135 | + "id": "compatibility-request-with-group", |
| 136 | + "metadata": {}, |
| 137 | + "outputs": [], |
| 138 | + "source": [ |
| 139 | + "selected_group = compatible_groups[1]\n", |
| 140 | + "\n", |
| 141 | + "grouped_compatibility_response = httpx.get(\n", |
| 142 | + " f\"{titiler_endpoint}/compatibility\",\n", |
| 143 | + " params={\n", |
| 144 | + " \"collection_concept_id\": collection_concept_id,\n", |
| 145 | + " \"group\": selected_group,\n", |
| 146 | + " },\n", |
| 147 | + " timeout=30,\n", |
| 148 | + ").json()\n", |
| 149 | + "\n", |
| 150 | + "print(json.dumps(grouped_compatibility_response, indent=2))" |
| 151 | + ] |
| 152 | + }, |
| 153 | + { |
| 154 | + "cell_type": "code", |
| 155 | + "execution_count": null, |
| 156 | + "id": "summarize-grouped-response", |
| 157 | + "metadata": {}, |
| 158 | + "outputs": [], |
| 159 | + "source": [ |
| 160 | + "group_variables = list((grouped_compatibility_response.get(\"variables\") or {}).keys())\n", |
| 161 | + "group_tilejson_link = next(\n", |
| 162 | + " link[\"href\"]\n", |
| 163 | + " for link in grouped_compatibility_response.get(\"links\", [])\n", |
| 164 | + " if link[\"rel\"] == \"tilejson\"\n", |
| 165 | + ")\n", |
| 166 | + "\n", |
| 167 | + "print(\"selected group:\", selected_group)\n", |
| 168 | + "print(\"variables in selected group (first 10):\", group_variables[:10])\n", |
| 169 | + "print(\"tilejson link for selected group:\", group_tilejson_link)" |
| 170 | + ] |
| 171 | + }, |
| 172 | + { |
| 173 | + "cell_type": "markdown", |
| 174 | + "id": "what-to-do-next", |
88 | 175 | "metadata": {}, |
89 | 176 | "source": [ |
90 | | - "The details from the sample granule show that it is a NetCDF file with four variables (`analysed_sst`, `analysis_error`, `mask`, and `sea_ice_fraction`) and each contains an array with a single time coordinate. The `datetime` key shows the reported temporal range from CMR which indicates that the dataset has granules from `2008-07-23` to present. For each variable several summary statistics are available to help you craft min/max values for the `rescale` parameter.\n", |
| 177 | + "For a grouped dataset like NISAR GCOV, the workflow is:\n", |
| 178 | + "\n", |
| 179 | + "1. Call `/compatibility` without `group` to get candidate `compatible_groups`.\n", |
| 180 | + "2. Choose one of those group paths.\n", |
| 181 | + "3. Call `/compatibility` again with `group=...` to inspect variables and dimensions for that group.\n", |
| 182 | + "4. Pick a variable name from `variables`.\n", |
| 183 | + "5. Reuse the returned xarray links from the grouped response.\n", |
91 | 184 | "\n", |
92 | | - "This information is handy for generating tiles via the tiles API, which you can learn more about in [the Tiles API Documentation](../tiling_api_xarray_backend_example)." |
| 185 | + "That keeps the root compatibility response lightweight while still giving you a practical path to the next xarray request." |
93 | 186 | ] |
94 | 187 | } |
95 | 188 | ], |
|
0 commit comments