{ "cells": [ { "cell_type": "markdown", "id": "8f1994c5-bb2a-4c52-8405-fd240cf965ba", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "## GRIB: create fieldlist from array and metadata" ] }, { "cell_type": "raw", "id": "a8eca176-b7fc-41d8-a1ac-e243c5f8070b", "metadata": { "editable": true, "raw_mimetype": "text/restructuredtext", "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "In this notebook we will show how to do some computations with GRIB data and generate a array fieldlist from the results.\n", "\n", "First we :ref:`read ` some GRIB data containing pressure level fields." ] }, { "cell_type": "code", "execution_count": 1, "id": "348564d3-1e60-455f-9081-499ce083d27c", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "import earthkit.data as ekd\n", "from earthkit.data import FieldList\n", "import numpy as np\n", "\n", "ekd.download_example_file(\"tuv_pl.grib\")\n", "ds = ekd.from_source(\"file\", \"tuv_pl.grib\")" ] }, { "cell_type": "markdown", "id": "9e6a80f5-77fc-40f8-a0be-86b80275c390", "metadata": {}, "source": [ "We will use the following method to compute the potential temperature:" ] }, { "cell_type": "code", "execution_count": 2, "id": "bce2d006-4c44-4726-82fe-2b70f7d81df2", "metadata": {}, "outputs": [], "source": [ "def potential_temperature(t, p):\n", " # t: temperature in K\n", " # p: pressure in Pa\n", " return t*(100000./p)**0.285611" ] }, { "cell_type": "markdown", "id": "03513bab-1a94-430c-b740-695f3f6c7d07", "metadata": {}, "source": [ "#### Working with a single field" ] }, { "cell_type": "markdown", "id": "ea335181-87a5-4bee-8a2e-8bd93084e75b", "metadata": {}, "source": [ "In this example we compute the potential temperature for the 850 hPa level using the 4th field from the fieldlist." ] }, { "cell_type": "code", "execution_count": 3, "id": "7586daef-1098-483b-9747-4aac9386e45b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(GribField(t,850,20180801,1200,0,0), 'K')" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f = ds[3]\n", "f, f.metadata(\"units\")" ] }, { "cell_type": "markdown", "id": "78801efa-c8da-4e35-abe0-33aa7d7974c0", "metadata": {}, "source": [ "The computations are done with numpy arrays:" ] }, { "cell_type": "code", "execution_count": 4, "id": "60db0219-044d-4977-abf5-e30065400a8f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "typeOfLevel= isobaricInhPa\n" ] }, { "data": { "text/plain": [ "array([285.48786915, 285.48786915, 285.48786915, 285.48786915,\n", " 285.48786915, 285.48786915, 285.48786915, 285.48786915,\n", " 285.48786915, 285.48786915])" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t = f.values\n", "print(\"typeOfLevel=\", f.metadata(\"typeOfLevel\"))\n", "p = f.metadata(\"level\")*100. #hPa -> Pa\n", "t_new = potential_temperature(t, p)\n", "t_new[:10]" ] }, { "cell_type": "raw", "id": "07e29bb2-1410-4d4d-8feb-e6aa1af0215a", "metadata": { "editable": true, "raw_mimetype": "text/restructuredtext", "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "We create a new :py:class:`~data.readers.grib.metadata.GribMetadata` object from the source field's :py:meth:`~data.readers.grib.codes.GribField.metadata` using :py:meth:`~data.readers.grib.metadata.GribMetadata.override`. The original metadata remains the same." ] }, { "cell_type": "code", "execution_count": 5, "id": "f8dcc33c-6818-415d-8088-6a01666ca87f", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "pt\n", "t\n" ] } ], "source": [ "md_new = f.metadata().override(shortName=\"pt\")\n", "print(md_new[\"shortName\"])\n", "print(f.metadata(\"shortName\"))" ] }, { "cell_type": "raw", "id": "058c2fd8-569b-4ddb-b8bb-217854e9ff73", "metadata": { "editable": true, "raw_mimetype": "text/restructuredtext", "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "A new FieldList (type of :py:class:`~data.indexing.fieldlist.SimpleFieldList`) can be created from the resulting ndarray and the modified metadata. It will store a list of :py:class:`~data.sources.array_list.ArrayField` fields each containing a values array and a metadata object entirely in memory. This fieldlist behaves as if it were a :py:class:`~data.readers.grib.index.GribFieldList`." ] }, { "cell_type": "code", "execution_count": 6, "id": "5a2557a6-091c-4345-a792-d3bfa7876c77", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
centreshortNametypeOfLevelleveldataDatedataTimestepRangedataTypenumbergridType
0ecmfptisobaricInhPa8502018080112000an0regular_ll
\n", "
" ], "text/plain": [ " centre shortName typeOfLevel level dataDate dataTime stepRange \\\n", "0 ecmf pt isobaricInhPa 850 20180801 1200 0 \n", "\n", " dataType number gridType \n", "0 an 0 regular_ll " ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ds_new = FieldList.from_array(t_new, md_new)\n", "ds_new.ls()" ] }, { "cell_type": "code", "execution_count": 7, "id": "2ccde1fc-f8c4-4d4d-abda-3ca3feebd02e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "ArrayField(pt,850,20180801,1200,0,0)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ds_new[0]" ] }, { "cell_type": "raw", "id": "c7733bdd-1a47-4dba-aac4-b6ed43e15337", "metadata": { "editable": true, "raw_mimetype": "text/restructuredtext", "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "The new fieldlist can be saved into a GRIB file:" ] }, { "cell_type": "code", "execution_count": 8, "id": "c22a23fc-fccd-45ef-887e-95ab61b0dee1", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
centreshortNametypeOfLevelleveldataDatedataTimestepRangedataTypenumbergridType
0ecmfptisobaricInhPa8502018080112000an0regular_ll
\n", "
" ], "text/plain": [ " centre shortName typeOfLevel level dataDate dataTime stepRange \\\n", "0 ecmf pt isobaricInhPa 850 20180801 1200 0 \n", "\n", " dataType number gridType \n", "0 an 0 regular_ll " ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "path = \"_pt_single.grib\"\n", "ds_new.to_target(\"file\", path)\n", "\n", "# read file back and check content\n", "ds1 = ekd.from_source(\"file\",path)\n", "ds1.ls()" ] }, { "cell_type": "markdown", "id": "b717b7f9-dd46-43cc-81d7-570164954a0d", "metadata": {}, "source": [ "#### Working with multiple fields" ] }, { "cell_type": "markdown", "id": "671716f8-19cf-47e9-bb8f-45c9651bf76e", "metadata": {}, "source": [ "In this example we compute the potential temperature for 3 pressure levels." ] }, { "cell_type": "code", "execution_count": 9, "id": "bedb28e0-dc98-4145-8559-da96cadca828", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
centreshortNametypeOfLevelleveldataDatedataTimestepRangedataTypenumbergridTypeunits
0ecmftisobaricInhPa8502018080112000an0regular_llK
1ecmftisobaricInhPa7002018080112000an0regular_llK
2ecmftisobaricInhPa5002018080112000an0regular_llK
\n", "
" ], "text/plain": [ " centre shortName typeOfLevel level dataDate dataTime stepRange \\\n", "0 ecmf t isobaricInhPa 850 20180801 1200 0 \n", "1 ecmf t isobaricInhPa 700 20180801 1200 0 \n", "2 ecmf t isobaricInhPa 500 20180801 1200 0 \n", "\n", " dataType number gridType units \n", "0 an 0 regular_ll K \n", "1 an 0 regular_ll K \n", "2 an 0 regular_ll K " ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fs = ds.sel(shortName=\"t\", level=[850, 700, 500])\n", "fs.ls(extra_keys=[\"units\"])" ] }, { "cell_type": "code", "execution_count": 10, "id": "74881517-ce58-4692-b1f1-cf281c5c1df2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(3, 84)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p = np.asarray(fs.metadata(\"level\")).reshape(-1, 1)*100. # hPa -> Pa\n", "t_new = potential_temperature(fs.values, p)\n", "t_new.shape" ] }, { "cell_type": "raw", "id": "8f2f7612-3ff9-4982-9cb0-a91a426f1b0f", "metadata": { "editable": true, "raw_mimetype": "text/restructuredtext", "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "We create an array fieldlist from the resulting ndarray and the modified metadata." ] }, { "cell_type": "code", "execution_count": 11, "id": "ab0c805e-9e33-40f1-a816-501c2cff64a1", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
centreshortNametypeOfLevelleveldataDatedataTimestepRangedataTypenumbergridType
0ecmfptisobaricInhPa8502018080112000an0regular_ll
1ecmfptisobaricInhPa7002018080112000an0regular_ll
2ecmfptisobaricInhPa5002018080112000an0regular_ll
\n", "
" ], "text/plain": [ " centre shortName typeOfLevel level dataDate dataTime stepRange \\\n", "0 ecmf pt isobaricInhPa 850 20180801 1200 0 \n", "1 ecmf pt isobaricInhPa 700 20180801 1200 0 \n", "2 ecmf pt isobaricInhPa 500 20180801 1200 0 \n", "\n", " dataType number gridType \n", "0 an 0 regular_ll \n", "1 an 0 regular_ll \n", "2 an 0 regular_ll " ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "md_new = [f.metadata().override(shortName=\"pt\") for f in fs]\n", "ds_new = FieldList.from_array(t_new, md_new)\n", "ds_new.ls()" ] }, { "cell_type": "raw", "id": "ca785b7b-d7a8-424b-99c5-19056a0b23b0", "metadata": { "editable": true, "raw_mimetype": "text/restructuredtext", "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "The new fieldlist can be saved into a GRIB file:" ] }, { "cell_type": "code", "execution_count": 12, "id": "e8e1c8a2-87aa-4ec2-895e-8ea7bd83e101", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
centreshortNametypeOfLevelleveldataDatedataTimestepRangedataTypenumbergridType
0ecmfptisobaricInhPa8502018080112000an0regular_ll
1ecmfptisobaricInhPa7002018080112000an0regular_ll
2ecmfptisobaricInhPa5002018080112000an0regular_ll
\n", "
" ], "text/plain": [ " centre shortName typeOfLevel level dataDate dataTime stepRange \\\n", "0 ecmf pt isobaricInhPa 850 20180801 1200 0 \n", "1 ecmf pt isobaricInhPa 700 20180801 1200 0 \n", "2 ecmf pt isobaricInhPa 500 20180801 1200 0 \n", "\n", " dataType number gridType \n", "0 an 0 regular_ll \n", "1 an 0 regular_ll \n", "2 an 0 regular_ll " ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "path = \"_pt_multi.grib\"\n", "ds_new.to_target(\"file\", path)\n", "\n", "# read file back and check content\n", "ds1 = ekd.from_source(\"file\", path)\n", "ds1.ls()" ] }, { "cell_type": "markdown", "id": "3f4d3b46-e905-4ac6-88c2-bd514101d61b", "metadata": {}, "source": [ "#### Performing the computations in a loop" ] }, { "cell_type": "raw", "id": "4fc8aa2f-c5ea-4310-841a-98c863a4acd7", "metadata": { "editable": true, "raw_mimetype": "text/restructuredtext", "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "In this example we create an **empty** :py:class:`~data.core.fieldlist.FieldList` and add the results of the computations to it in a loop." ] }, { "cell_type": "code", "execution_count": 13, "id": "6c6e8651-f5a3-4534-9227-812e8e69407d", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "fs = ds.sel(shortName=\"t\", level=[850, 700, 500])\n", "\n", "# create an empty fieldlist\n", "ds_r = FieldList()\n", "\n", "for f in fs:\n", " p = f.metadata(\"level\")*100. # hPa -> Pa\n", " t_new = potential_temperature(f.values, p)\n", " md_new = f.metadata().override(shortName=\"pt\")\n", " \n", " # create new numpy fieldlist with a single field\n", " ds_new = FieldList.from_array(t_new, md_new)\n", "\n", " # add it to the resulting fieldlist\n", " ds_r += ds_new" ] }, { "cell_type": "code", "execution_count": 14, "id": "32c53494-e8f4-4a22-aa93-e16b5188483a", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
centreshortNametypeOfLevelleveldataDatedataTimestepRangedataTypenumbergridType
0ecmfptisobaricInhPa8502018080112000an0regular_ll
1ecmfptisobaricInhPa7002018080112000an0regular_ll
2ecmfptisobaricInhPa5002018080112000an0regular_ll
\n", "
" ], "text/plain": [ " centre shortName typeOfLevel level dataDate dataTime stepRange \\\n", "0 ecmf pt isobaricInhPa 850 20180801 1200 0 \n", "1 ecmf pt isobaricInhPa 700 20180801 1200 0 \n", "2 ecmf pt isobaricInhPa 500 20180801 1200 0 \n", "\n", " dataType number gridType \n", "0 an 0 regular_ll \n", "1 an 0 regular_ll \n", "2 an 0 regular_ll " ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ds_r.ls()" ] }, { "cell_type": "raw", "id": "b7635ff3-9610-415b-861d-de934591c960", "metadata": { "editable": true, "raw_mimetype": "text/restructuredtext", "slideshow": { "slide_type": "" }, "tags": [], "vscode": { "languageId": "raw" } }, "source": [ "The new fieldlist can be saved into a GRIB file:" ] }, { "cell_type": "code", "execution_count": 15, "id": "a149caa0-b1ba-4b8e-b2d0-6aad7ee224a6", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
centreshortNametypeOfLevelleveldataDatedataTimestepRangedataTypenumbergridType
0ecmfptisobaricInhPa8502018080112000an0regular_ll
1ecmfptisobaricInhPa7002018080112000an0regular_ll
2ecmfptisobaricInhPa5002018080112000an0regular_ll
\n", "
" ], "text/plain": [ " centre shortName typeOfLevel level dataDate dataTime stepRange \\\n", "0 ecmf pt isobaricInhPa 850 20180801 1200 0 \n", "1 ecmf pt isobaricInhPa 700 20180801 1200 0 \n", "2 ecmf pt isobaricInhPa 500 20180801 1200 0 \n", "\n", " dataType number gridType \n", "0 an 0 regular_ll \n", "1 an 0 regular_ll \n", "2 an 0 regular_ll " ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "path = \"_pt_from_loop.grib\"\n", "ds_r.to_target(\"file\", path)\n", "\n", "# read file back and check content\n", "ds1 = ekd.from_source(\"file\", path)\n", "ds1.ls()" ] }, { "cell_type": "code", "execution_count": null, "id": "8ce30259-bb20-492e-b90b-244636822dea", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "dev_ecc", "language": "python", "name": "dev_ecc" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.13" } }, "nbformat": 4, "nbformat_minor": 5 }