{ "cells": [ { "cell_type": "markdown", "id": "eecd1d2c-6b93-428e-8a60-5800274da618", "metadata": {}, "source": [ "## Using the ESA CCI Toolbox with the xcube Viewer\n", "\n", "The xcube viewer is an easy way to display gridded data. In this notebook, we show how the viewer can be started from a notebook and how cci datasets can be added to it.\n", "\n", "To run this Notebook, make sure the ESA CCI Toolbox is setup correctly." ] }, { "cell_type": "markdown", "id": "cb14d9ac-8491-410d-a836-c554dae785c7", "metadata": {}, "source": [ "The viewer requires datasets. For this notebook, we will access them from the Zarr store and the regular store." ] }, { "cell_type": "code", "execution_count": 1, "id": "c8835695-30f4-49aa-9a83-bd83f66db59e", "metadata": { "tags": [] }, "outputs": [], "source": [ "from xcube.core.store import new_data_store\n", "\n", "zarr_store = new_data_store('esa-cci-zarr')\n", "cci_store = new_data_store('esa-cci')" ] }, { "cell_type": "markdown", "id": "e2b51cb0-ebf9-4579-b4ab-83ea6141bd9b", "metadata": {}, "source": [ "If you want, you can execute the following lines to see which datasets are available. For now, this part is in a comment as we do not want to print all the datasets for reasons of readability." ] }, { "cell_type": "code", "execution_count": 2, "id": "db8b5afb-3f1f-4e3d-b02d-66f23fb15b1a", "metadata": {}, "outputs": [], "source": [ "# zarr_store.list_data_ids()" ] }, { "cell_type": "code", "execution_count": 3, "id": "9452e767-c40c-4081-a05d-051daf84f93a", "metadata": {}, "outputs": [], "source": [ "# cci_store.list_data_ids()" ] }, { "cell_type": "markdown", "id": "83cf99d0-98df-4550-aed2-a32d9bcda85c", "metadata": {}, "source": [ "From the Zarr store, we pick a snow dataset." ] }, { "cell_type": "code", "execution_count": 4, "id": "5185b930-ec04-4a63-abb6-592345663b8f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset> Size: 823GB\n",
       "Dimensions:   (lat: 1800, nv: 2, lon: 3600, time: 7934)\n",
       "Coordinates:\n",
       "  * lat       (lat) float64 14kB -89.95 -89.85 -89.75 ... 89.75 89.85 89.95\n",
       "    lat_bnds  (lat, nv) float64 29kB dask.array<chunksize=(900, 2), meta=np.ndarray>\n",
       "  * lon       (lon) float64 29kB -179.9 -179.8 -179.8 ... 179.7 179.8 179.9\n",
       "    lon_bnds  (lon, nv) float64 58kB dask.array<chunksize=(900, 2), meta=np.ndarray>\n",
       "  * time      (time) datetime64[ns] 63kB 1979-01-02 1979-01-04 ... 2020-05-24\n",
       "Dimensions without coordinates: nv\n",
       "Data variables:\n",
       "    swe       (time, lat, lon) float64 411GB dask.array<chunksize=(10, 900, 900), meta=np.ndarray>\n",
       "    swe_std   (time, lat, lon) float64 411GB dask.array<chunksize=(10, 900, 900), meta=np.ndarray>\n",
       "Attributes: (12/43)\n",
       "    Conventions:                CF-1.9\n",
       "    cdm_data_type:              grid\n",
       "    comment:                    The following auxiliary datasets are used for...\n",
       "    creator_email:              kari.luojus@fmi.fi (Scientific and Production...\n",
       "    creator_name:               Finnish Meteorological Institute\n",
       "    creator_url:                www.fmi.fi\n",
       "    ...                         ...\n",
       "    time_coverage_duration:     P1D\n",
       "    time_coverage_end:          20200524T000000Z\n",
       "    time_coverage_resolution:   P1D\n",
       "    time_coverage_start:        19790102T000000Z\n",
       "    title:                      ESA CCI snow SWE product level L3C daily, Dyn...\n",
       "    tracking_id:                25063fb5-47ad-424a-8f26-29bdf35efb78
" ], "text/plain": [ " Size: 823GB\n", "Dimensions: (lat: 1800, nv: 2, lon: 3600, time: 7934)\n", "Coordinates:\n", " * lat (lat) float64 14kB -89.95 -89.85 -89.75 ... 89.75 89.85 89.95\n", " lat_bnds (lat, nv) float64 29kB dask.array\n", " * lon (lon) float64 29kB -179.9 -179.8 -179.8 ... 179.7 179.8 179.9\n", " lon_bnds (lon, nv) float64 58kB dask.array\n", " * time (time) datetime64[ns] 63kB 1979-01-02 1979-01-04 ... 2020-05-24\n", "Dimensions without coordinates: nv\n", "Data variables:\n", " swe (time, lat, lon) float64 411GB dask.array\n", " swe_std (time, lat, lon) float64 411GB dask.array\n", "Attributes: (12/43)\n", " Conventions: CF-1.9\n", " cdm_data_type: grid\n", " comment: The following auxiliary datasets are used for...\n", " creator_email: kari.luojus@fmi.fi (Scientific and Production...\n", " creator_name: Finnish Meteorological Institute\n", " creator_url: www.fmi.fi\n", " ... ...\n", " time_coverage_duration: P1D\n", " time_coverage_end: 20200524T000000Z\n", " time_coverage_resolution: P1D\n", " time_coverage_start: 19790102T000000Z\n", " title: ESA CCI snow SWE product level L3C daily, Dyn...\n", " tracking_id: 25063fb5-47ad-424a-8f26-29bdf35efb78" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "snow_ds = zarr_store.open_data('ESACCI-L3C_SNOW-SWE-1979-2020-fv2.0.zarr')\n", "snow_ds" ] }, { "cell_type": "markdown", "id": "a7890833-ee3a-4c48-94db-9c482bc74b6a", "metadata": {}, "source": [ "From the cci store, we pick an aerosol dataset. However, let's just use a subset here, to see how it will look in the viewer." ] }, { "cell_type": "code", "execution_count": 5, "id": "043170ab-5066-4e51-93bd-af922afe4236", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset> Size: 308kB\n",
       "Dimensions:                  (time: 12, lat: 80, lon: 80, bnds: 2)\n",
       "Coordinates:\n",
       "  * lat                      (lat) float32 320B -39.5 -38.5 -37.5 ... 38.5 39.5\n",
       "  * lon                      (lon) float32 320B -22.5 -21.5 -20.5 ... 55.5 56.5\n",
       "  * time                     (time) datetime64[ns] 96B 2005-01-16T12:00:00 .....\n",
       "    time_bnds                (time, bnds) datetime64[ns] 192B dask.array<chunksize=(12, 2), meta=np.ndarray>\n",
       "Dimensions without coordinates: bnds\n",
       "Data variables:\n",
       "    absorbing_aerosol_index  (time, lat, lon) float32 307kB dask.array<chunksize=(1, 80, 80), meta=np.ndarray>\n",
       "Attributes:\n",
       "    Conventions:             CF-1.7\n",
       "    title:                   esacci.AEROSOL.mon.L3.AAI.multi-sensor.multi-pla...\n",
       "    date_created:            2025-12-04T11:52:18.378325\n",
       "    processing_level:        L3\n",
       "    time_coverage_start:     2005-01-01T00:00:00\n",
       "    time_coverage_end:       2006-01-01T00:00:00\n",
       "    time_coverage_duration:  P365DT0H0M0S\n",
       "    history:                 [{'program': 'xcube_cci.chunkstore.CciChunkStore...
" ], "text/plain": [ " Size: 308kB\n", "Dimensions: (time: 12, lat: 80, lon: 80, bnds: 2)\n", "Coordinates:\n", " * lat (lat) float32 320B -39.5 -38.5 -37.5 ... 38.5 39.5\n", " * lon (lon) float32 320B -22.5 -21.5 -20.5 ... 55.5 56.5\n", " * time (time) datetime64[ns] 96B 2005-01-16T12:00:00 .....\n", " time_bnds (time, bnds) datetime64[ns] 192B dask.array\n", "Dimensions without coordinates: bnds\n", "Data variables:\n", " absorbing_aerosol_index (time, lat, lon) float32 307kB dask.array\n", "Attributes:\n", " Conventions: CF-1.7\n", " title: esacci.AEROSOL.mon.L3.AAI.multi-sensor.multi-pla...\n", " date_created: 2025-12-04T11:52:18.378325\n", " processing_level: L3\n", " time_coverage_start: 2005-01-01T00:00:00\n", " time_coverage_end: 2006-01-01T00:00:00\n", " time_coverage_duration: P365DT0H0M0S\n", " history: [{'program': 'xcube_cci.chunkstore.CciChunkStore..." ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x1 = -23.40 # degree\n", "y1 = -40.40 # degree\n", "x2 = 57.40 # degree\n", "y2 = 40.40 # degree\n", "bbox = (x1, y1, x2, y2)\n", "\n", "aerosol_ds = cci_store.open_data(\n", " 'esacci.AEROSOL.mon.L3.AAI.multi-sensor.multi-platform.MSAAI.1-7.r1',\n", " variable_names=['absorbing_aerosol_index'],\n", " bbox=bbox,\n", " time_range=['2005-01-01', '2005-12-31']\n", ")\n", "aerosol_ds" ] }, { "cell_type": "markdown", "id": "b60043ab-dd61-4672-afc0-0f3a4eafc52c", "metadata": {}, "source": [ "Now that we have the datasets assembled, we can start the viewer. We import it from xcube like this:" ] }, { "cell_type": "code", "execution_count": 6, "id": "c979a8d3-f5b0-4ec5-87ec-7314efdf0d66", "metadata": {}, "outputs": [], "source": [ "from xcube.webapi.viewer import Viewer" ] }, { "cell_type": "code", "execution_count": 7, "id": "bb6a212d-5cbe-42c7-a2cc-b9ca349e6171", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "404 GET /viewer/config/config.json (127.0.0.1): xcube viewer has not been been configured\n", "404 GET /viewer/config/config.json (127.0.0.1) 11.21ms\n", "501 GET /viewer/state?key=sentinel (127.0.0.1) 0.27ms\n", "404 GET /viewer/ext/contributions (127.0.0.1) 0.32ms\n" ] } ], "source": [ "viewer = Viewer()" ] }, { "cell_type": "markdown", "id": "8f10e24b-c1bb-4e9b-8cdd-6edf790b1134", "metadata": {}, "source": [ "Next, we add the datasets." ] }, { "cell_type": "code", "execution_count": 8, "id": "5ad7df08-b848-44d0-b347-9dc9b6a1d927", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'63622925-cb47-4e27-9346-0d0acc930130'" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "viewer.add_dataset(snow_ds)" ] }, { "cell_type": "code", "execution_count": 9, "id": "5572d300-5ffe-4c97-9f7b-484c30068d61", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'5c042aa5-b2de-47db-b7af-2051191afb16'" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "viewer.add_dataset(aerosol_ds)" ] }, { "cell_type": "markdown", "id": "0085b7c5-bf67-4d08-b61b-c39a5fbc8446", "metadata": {}, "source": [ "Now that the viewer is set up, we can ask for information about it. With the following command, we get the links for the server and the viewer. The server is responsible for serving the datasets. You may take the link and use it with any running viewer. However, it is directly plugged into the viewer instance which you can open from its link." ] }, { "cell_type": "code", "execution_count": 10, "id": "7224ebec-a8bc-4f1b-901b-e15a65f7e173", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Server: http://localhost:8000\n", "Viewer: http://localhost:8000/viewer/?serverUrl=http://localhost:8000\n" ] } ], "source": [ "viewer.info()" ] }, { "cell_type": "markdown", "id": "50f9dd64-758d-4c2e-8793-d34b7e2e3bb2", "metadata": {}, "source": [ "Alternatively, you can open the viewer in a notebook cell:" ] }, { "cell_type": "code", "execution_count": 11, "id": "6bf05c54-437f-4d3c-88a7-b56d303071ff", "metadata": {}, "outputs": [ { "data": { "text/html": [ "