{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "b8fe8bda",
   "metadata": {},
   "source": [
    "# readDiag\n",
    "\n",
    "The `readDiag` package was designed to be a tool that enables easy access to diagnostic files generated by the [Gridpoint Statistical Interpolation (GSI) system](https://github.com/NOAA-EMC/GSI). The package is mainly composed of 2 classes, the first one for reading data (`read_diag`) and the other for creating different types of figures with selected data (`plot_diag`).\n",
    "\n",
    "## The `read_diag` Class\n",
    "\n",
    "The `read_diag` class consists of 5 functions:\n",
    "\n",
    "1. `__init__(self, diagFile, diagFileAnl=None, isisList=None, zlevs=None)`: where `diagFile` is the diagnostic file of the first outer loop with OmF information, and `diagFileAnl` is the diagnostic file of the last outer loop with OmA information. Note that it is not necessary to inform both files; `diagFileAnl` is optional. In this case, the read information (Omf or OmA) will depend on the outer loop (diagnostic file) provided.\n",
    "2. `overview(self)`: this function creates and returns a dictionary with the information in the file.\n",
    "3. `pfileinfo(self)`: this function elegantly prints a list with the information in the file.\n",
    "4. `close(self)`: this function closes the last opened file.\n",
    "5. `tocsv(self, varName=None, varType=None, dateIni=None, dateFin=None, nHour=\"06\", Level=None, Lay=None, SingleL=None)`: this function generates a CSV file of the OmF and OmA parameters with the following information: date, mean, standard deviation, and total data for the chosen variable and type.\n",
    "\n",
    "The input data for the function and functionalities are identical to those of the `time_series` function presented in the next section in the `plot_diag` class (item 7 - see also details of functionalities [here](#time_series)). What distinguishes the two functions is that this one writes a CSV file, and the other generates time series figures.\n",
    "\n",
    "## The `plot_diag` Class\n",
    "\n",
    "The `plot_diag` class consists of 7 functions:\n",
    "\n",
    "1. `plot(self, varName, varType, param, mask=None, **kwargs)`: the `plot` function generates a figure for the variable `varName` (e.g., `uv`), `varType` (e.g., `220` (dropssonda)), and `param`, which can be various options such as `param=\"obs\"` for the observation value, `param=\"omf\"` for observation minus background, or `param=\"oma\"` for observation minus analysis. It is also possible to mask the data with the `iuse` variable, which indicates whether the data was (`iuse=1`) or was not (`iuse=-1` - monitored data) used in assimilation. Below is an example executed for `varName=\"uv\"`, `varType=220`, `param=\"obs\"`, and mask `iuse==1\"`:\n",
    "\n",
    "<img src=notefigs/uv_obs_plot.png style=\"width: 800px;\">\n",
    "<br>\n",
    "    \n",
    "2. `ptmap(self, varName, varType=None, mask=None, **kwargs)`: the `ptmap` function generates a figure with the location of all observations defined by `varName` (e.g., `uv`) and `varType` (can be a single type or a list, e.g., `[200]` or `[220,221,257]`). If `varType` is not informed, then all types will be included in the figure. It is also possible to mask the data with the `iuse` variable, which indicates whether the data was (`iuse=1`) or was not (`iuse=-1` - monitored data) used in assimilation. Below is an example executed for `varName=\"uv\"`, `varType=[254,242,221,220,257,258,281,280]`, and `mask=None`;\n",
    "\n",
    "<img src=notefigs/uv_254_242_221_220_257_258_281_280_ptmap.png style=\"width: 800px;\">\n",
    "<br>\n",
    "\n",
    "3. `pvmap(self, varName=None, mask=None, **kwargs)`: the `pvmap` function is similar to the `ptmap` function, with the difference of not specifying the type (`varType`), so you can choose a list of variables, e.g., `[\"uv\",\"ps\",\"t\"]`. Below is an example executed for `varName=['uv','ps','t']`, and `mask=None`; \n",
    "\n",
    "<img src=notefigs/uv_ps_t_pvmap.png style=\"width: 800px;\">\n",
    "<br>\n",
    "\n",
    "4. `pcount(self,varName,**kwargs)`: the `pcount` function generates a histogram of the data quantity for a specific variable `varName` (e.g., `uv`) and all available types (`varType`);\n",
    "\n",
    "<img src=notefigs/uv_pcount.png style=\"width: 800px;\">\n",
    "<br>\n",
    "\n",
    "5. `kxcount(self,**kwargs)`: the `kxcount` function is similar to `pcount` but does not specify the variable (`varName`). This function generates a histogram with the total data (all variables summed) for all available types (`varType`);\n",
    "\n",
    "<img src=notefigs/kxcount.png style=\"width: 800px;\">\n",
    "<br>\n",
    "\n",
    "6. `vcount(self,**kwargs)`: the `vcount` function generates a histogram with the total quantity of data for each variable (`ps`, `t`, `q`, `uv`);\n",
    "\n",
    "<img src=notefigs/vcount.png style=\"width: 800px;\">\n",
    "<br>\n",
    "\n",
    "7. `time_series(self, varName=None, varType=None, dateIni=None, dateFin=None, nHour=\"06\", vminOMA=None, vmaxOMA=None, vminSTD=0.0, vmaxSTD=14.0, Level=None, Lay=None, SingleL=None, Clean=None)`: the `time_series` function can generate 6 different types of figures, depending on the configuration specified in its call. The common feature among the 6 types is the time variation, while the difference between the 6 types is the way to treat the vertical levels. Basically, these ways are distributed between varying vertically (different values for different levels/layers) and fixed vertically (specific level, layer mean, or the entire atmosphere).\n",
    "\n",
    "The input parameters for the function and each of the figure options will be explained in more detail below.\n",
    "\n",
    "| Parameter       | Example                                  | Description\n",
    "| :---            | :---:                                    | :---\n",
    "| `self`          | `['/home/user/diag_conv_01.2019121000']` | List with all full paths (`path/file_name`) of each time in the time series.\n",
    "| `varName`       | `uv`                                     | Variable name\n",
    "| `varType`       | `220`                                    | Variable type\n",
    "| `dateIni`       | `2019121000`                             | Initial date of the time series\n",
    "| `dateFin`       | `2019121118`                             | Final date of the time series\n",
    "| `nHour`         | `6`                                      | Time interval in hours between each file in the `self` list\n",
    "| `vminOMA`       | `-2.0`                                   | Minimum value of the y-scale (ordinate) for OmF and OmA\n",
    "| `vmaxOMA`       | `2.0`                                    | Maximum value of the y-scale (ordinate) for OmF and OmA\n",
    "| `vminSTD`       | `0.0`                                    | Minimum value of the y-scale (ordinate) for the standard deviation\n",
    "| `vmaxSTD`       | `14.0`                                   | Maximum value of the y-scale (ordinate) for the standard deviation\n",
    "| `Level`         | `Zlevs`                                  | Value of the level to make the time series; options: numerical value corresponding to the level, e.g., 1000 for 1000 hPa; `Zlevs` to plot by layers (around the standard levels); `None` to plot all levels.\n",
    "| `Lay`           | 25                                       | Half of the layer size (if `Level=\"Zlevs\"`) in hPa if opting for layer sampling. If `Lay=None`, `Lay` will be internally calculated to fill the entire atmosphere containing the standard levels.\n",
    "| `SingleL`       | `All`                                    | When `Level` is fixed, e.g., 1000 hPa, it will be considered exactly that level (using the option `SingleL=None`) or at all levels as a single layer (using `SingleL=\"All\"`) or in a layer defined around the `Level` value ranging between `Level-Lay` and `Level+Lay`. If `Lay` is not informed, a default value of 50 hPa will be used.\n",
    "| `Clean`         | `True` or `False`                        | If `True`, after generating and saving the figure, the figure window is restarted (`plt.clf()`) or closed (`plt.close()`); if `False`, this procedure is eliminated, and the figure remains available for viewing with `plt.show()`.\n",
    "\n",
    "All figures generated with the option `Level` equal to `None` or `Zlevs` will contain the term `all_levels` in the name; otherwise, it will be `level` or `layer`, depending on the `SingleL` option.\n",
    "\n",
    "Throughout this notebook, examples with code snippets are shown to illustrate the use of the functions listed above."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1fc906bd-2955-4e39-9a90-ff65a123e82a",
   "metadata": {},
   "source": [
    "## Using the `read_diag` Class\n",
    "\n",
    "### Required Libraries\n",
    "\n",
    "To start using `readDiag`, first load the necessary libraries for its usage:\n",
    "\n",
    "* `gsidiag`: it is the library that contains the `read_diag` and `plot_diag` classes;\n",
    "* `pandas`: it is the library that provides tabulated data structures used by `readDiag`;\n",
    "* `matplotlib`: it is the library from which figures are created;\n",
    "* `datetime`: it is the library used for date manipulation.\n",
    "\n",
    "The `%matplotlib inline` instruction is a Jupyter magic command and only adjusts the environment so that the `plt.show()` command is not needed whenever figures are displayed within the notebook. If you are using `readDiag` within a Python script, this directive can be omitted, and the `plt.show()` command should be used as needed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ec5cd34c-a7d6-498c-85bf-879b2265b64a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Uncomment next line to use in Google Colab\n",
    "#!pip install readDiag"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7bd343fb",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import gsidiag as gd\n",
    "\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "from datetime import datetime, timedelta\n",
    "\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "62634f50",
   "metadata": {},
   "source": [
    "### Main Variables\n",
    "\n",
    "In the table below, the default values of the variables used throughout this tutorial are listed. Note that the variables have different types, and some can be declared as `None`.\n",
    "\n",
    "| Variables |     | Values          | Type              |\n",
    "| :---:     |:---:| :---             | :---              |\n",
    "| `DIRdiag` | =   | `/pesq/share/das/dist/joao.gerd/EXP18/GSI/dataout` | string |\n",
    "|`varName`  | =   | `uv`             | string            |\n",
    "|`varType`  | =   | `220`            | integer           |\n",
    "|`dateIni`  | =   | `2019121000`     | string            |\n",
    "|`dateFin`  | =   | `2019121118`     | string            |\n",
    "|`nHour`    | =   | `6`              | string            |\n",
    "|`vminOMA`  | =   | `-2.0`           | float             |\n",
    "|`vmaxOMA`  | =   | `2.0`            | float             |\n",
    "|`vminSTD`  | =   | `0.0`            | float             |\n",
    "|`vmaxSTD`  | =   | `14.0`           | float             |\n",
    "|`Level`    | =   | `1000`           | integer or `None` |\n",
    "|`Lay`      | =   | `15`             | integer or `None` |\n",
    "|`SingleL`  | =   | `OneL`           | string            |\n",
    "\n",
    "Thus, in the following cell, the variables are adjusted according to the values in the table above. Additionally, the date values are also adjusted to compose the path and names of the GSI diagnostic files:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c524c794",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "# For use in Egeon\n",
    "#DIRdiag = \"/pesq/share/das/dist/joao.gerd/EXP18/GSI/dataout\"\n",
    "\n",
    "# For use in Itapemirim (Colorado, Ilopolis, and other virtual machines)\n",
    "#DIRdiag = \"/share/das/dist/joao.gerd/EXP18/GSI/dataout\"\n",
    "\n",
    "# For use on a local machine (in this case, the remote directory should be mounted locally with the sshfs command)\n",
    "# Example:\n",
    "# $ sshfs username@egeon.cptec.inpe.br:/pesq/share/das/dist/joao.gerd/EXP18/GSI/dataout /extra2/EGEON_EXP18_GSI_dataout\n",
    "# or\n",
    "# $ sshfs username@itapemirim.cptec.inpe.br:/share/das/dist/joao.gerd/EXP18/GSI/dataout /extra2/EGEON_EXP18_GSI_dataout\n",
    "DIRdiag = '/extra2/EGEON_EXP18_GSI_dataout'\n",
    "\n",
    "varName = 'uv'\n",
    "varType = 220\n",
    "dateIni = '2019121000' \n",
    "dateFin = '2019121118' \n",
    "nHour = '6'          \n",
    "vminOMA = -2.0       \n",
    "vmaxOMA = 2.0        \n",
    "vminSTD = 0.0        \n",
    "vmaxSTD = 14.0       \n",
    "Level = 1000\n",
    "Lay = 15           \n",
    "SingleL = 'OneL' \n",
    "\n",
    "datei = datetime.strptime(str(dateIni), '%Y%m%d%H')\n",
    "datef = datetime.strptime(str(dateFin), '%Y%m%d%H')\n",
    "dates = [dates.strftime('%Y%m%d%H') for dates in pd.date_range(datei, datef,freq='6H').tolist()]\n",
    "\n",
    "print(dates)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8d3337a9",
   "metadata": {},
   "source": [
    "Generating the `path` and `pathc` variables where the complete paths (including the file name) of the diagnostic files for the first (OmF) and last (OmA) outer loops will be:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5322fbbf",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "paths, pathsc = [], []\n",
    "\n",
    "OuterL = '01'        \n",
    "[paths.append(DIRdiag + '/' + dt + '/diag_conv_' + OuterL + '.' + dt) for dt in dates]\n",
    "\n",
    "OuterLc = '03'\n",
    "[pathsc.append(DIRdiag + '/' + dt + '/diag_conv_' + OuterLc + '.' + dt) for dt in dates]\n",
    "\n",
    "print(paths)\n",
    "print('')\n",
    "print(pathsc)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cb3223cc",
   "metadata": {},
   "source": [
    "### Reading Diagnostic Files\n",
    "\n",
    "**Note:** Reading diagnostic files using the values adjusted for the parameters above requires at least 8GB of RAM. If necessary, adjust the parameters to consider a smaller interval.\n",
    "\n",
    "Reading diagnostic files with the `read_diag()` function from the `readDiag` package. In the following code snippet, note that the `read_diag()` function is used within a loop that iterates over all the files in the `paths` and `pathsc` lists defined in the previous step. At the end of the loop, the `gdf_list` list is generated, which will contain all the files read by `readDiag`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5d8035ca",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "read = True\n",
    "\n",
    "if read:        \n",
    "    gdf_list = []\n",
    "    print('')\n",
    "    \n",
    "    print('Please wait; the estimated total time for reading the files is ' +\n",
    "          str(int((float(len(paths))*20)/60)) + ' minutes and ' +\n",
    "          str(int((float(len(paths))*20)%60)) + ' seconds.')\n",
    "    \n",
    "    print('')\n",
    "    \n",
    "    for path, pathc in zip(paths, pathsc):\n",
    "        print('Reading ' + path)\n",
    "        \n",
    "        gdf = gd.read_diag(path, pathc)\n",
    "        \n",
    "        gdf_list.append(gdf)\n",
    "        \n",
    "    print('Done!')    "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2a1a2bfd",
   "metadata": {},
   "source": [
    "The `gdf_list` variable is a list of dataframes containing the data from each diagnostic file. To work with a single time, simply refer to the list with a fixed index, for example: `gdf_list[0]`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "655590bb",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "gdf_list"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "28e3569a-1b5d-451d-9e15-720a9153e6b7",
   "metadata": {},
   "source": [
    "Setting `tidx = 0` retrieves the first object from the `gdf_list`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "88d8af81",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "tidx = 0\n",
    "gdf_list[tidx]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f4ad8170-bffd-4c93-a51a-5747b88478b1",
   "metadata": {
    "tags": []
   },
   "source": [
    "### Obtaining File Information\n",
    "\n",
    "Use the `pfileinfo()` function to get a list of observations and their respective types (`kx`) contained within the file:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "83af7ed8",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "gdf_list[tidx].pfileinfo()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7e1f38c4-1212-410f-9148-1982a7bbf5cb",
   "metadata": {},
   "source": [
    "In addition to the `pfileinfo()` method, other methods and functions can also be used to access information about the opened files. To get a list of available methods and functions, type `gdf_list[tidx].` and press the `<TAB>` key twice on the keyboard:\n",
    "\n",
    "```python\n",
    ">>> gdf_list[tidx].\n",
    "gdf_list[tidx].close(      gdf_list[tidx].obsInfo     gdf_list[tidx].pfileinfo(  gdf_list[tidx].zlevs\n",
    "gdf_list[tidx].tocsv(      gdf_list[tidx].overview(   gdf_list[tidx].varNames\n",
    "gdf_list[tidx].obs\n",
    "```\n",
    "\n",
    "The built-in methods and functions have documentation, which can be accessed as follows:\n",
    "\n",
    "```python\n",
    "print(object.function_name.__doc__)\n",
    "```\n",
    "\n",
    "or\n",
    "\n",
    "```python\n",
    "help(object.function_name)\n",
    "```\n",
    "\n",
    "For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ec440584-05c6-4ca5-a150-f32b3df367f8",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "print(gdf_list[tidx].pfileinfo.__doc__)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8fb93454-49f9-4f25-899e-d89344d8c5a8",
   "metadata": {},
   "source": [
    "or alternatively:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9be857b1-4371-4528-ac22-477878108426",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "help(gdf_list[tidx].pfileinfo)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "17224ffc-c96d-42a9-beda-7e7a6d72c8f1",
   "metadata": {},
   "source": [
    "To get a dictionary with all the information about the variables and types contained in the file, use the `obsInfo` method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c8c368b1",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "gdf_list[tidx].obsInfo"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2da780bf",
   "metadata": {},
   "source": [
    "To access a specific variable (e.g., `uv`), do the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "75438415",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "print('Variable: ', varName)\n",
    "\n",
    "gdf_list[tidx].obsInfo[varName]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "769f7e52",
   "metadata": {},
   "source": [
    "To access specific variable and type (e.g., `uv` of type `220`), do:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8265a96d",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "print('Variable: ', varName, ' and Type: ', varType)\n",
    "\n",
    "gdf_list[tidx].obsInfo[varName].loc[varType]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "da23137b",
   "metadata": {},
   "source": [
    "The `varType` parameter can also be a list, for example: `varType=[220, 221]`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fc0be327",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "varTypes = [220,221]\n",
    "\n",
    "print('Variable: ', varName, ' e Types: ', varTypes)\n",
    "\n",
    "gdf_list[tidx].obsInfo[varName].loc[varTypes]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "936ea5b0",
   "metadata": {},
   "source": [
    "To access the observation value, use the `obs` method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8d7f6cea",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "print('Variable: ', varName, ' e Type: ', varType)\n",
    "\n",
    "gdf_list[tidx].obsInfo[varName].loc[varType].obs"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "baaf3d6a",
   "metadata": {},
   "source": [
    "## Using the `plot_diag` Class\n",
    "\n",
    "### Spatial Distribution\n",
    "\n",
    "The usage of the `plot_diag` class functions is presented below, along with commands to generate various types of figures.\n",
    "\n",
    "Generating a figure with observation values (`param='obs'`) for the selected variable and type:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6c16f7d1",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "param = 'obs'\n",
    "\n",
    "gd.plot_diag.plot(gdf_list[tidx], \n",
    "                  varName=varName, \n",
    "                  varType=varType, \n",
    "                  param=param, \n",
    "                  mask='iuse == 1', \n",
    "                  legend='true')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f82df541",
   "metadata": {},
   "source": [
    "To save the figure, define its name (`figname`) and execute the following commands:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "84169c19",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "figname = varName + '_' + param + '_' + 'plot.png'\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.savefig(figname)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2a240e9d-3d2a-48e3-a76a-f09fc6331a1d",
   "metadata": {},
   "source": [
    "Generating the same figure, but considering various different types (`kx`) of the selected observation:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0be7a398",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "varTypes = [254,242,221,220,257,258,281,280]\n",
    "idschar = '_'.join([str(item) for item in varTypes])\n",
    "\n",
    "gd.plot_diag.ptmap(gdf_list[tidx], varName=varName, varType=varTypes)\n",
    "\n",
    "figname = varName + '_' + idschar + '_' + 'ptmap.png'\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.savefig(figname)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fb0eaa77-fca0-4be6-8d82-1ef7794bab0b",
   "metadata": {},
   "source": [
    "Generating a figure with different variables, considering the mask `iuse==1`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8bdc6d6a",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "varNames = ['uv','ps','t']\n",
    "idschar = '_'.join([str(item) for item in varNames])\n",
    "\n",
    "gd.plot_diag.pvmap(gdf_list[tidx], varName=varNames, mask='iuse==1')\n",
    "\n",
    "figname = idschar + '_pvmap.png'\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.savefig(figname)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a48cf904-ad49-4d2e-9415-6bec88ab48cc",
   "metadata": {},
   "source": [
    "### Histogram\n",
    "\n",
    "Use the `pcount()` function from the `plot_diag` class to obtain a histogram with the count of the number of observations for a specific variable:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "078f84a8",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "gd.plot_diag.pcount(gdf_list[tidx], varName)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "368a57ec-9e04-4394-a9d7-4cb4bba1b0a3",
   "metadata": {},
   "source": [
    "Use the `vcount()` function from the `plot_diag` class to obtain a histogram with the count of the number of observations for all types of variables:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b1d44398",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "gd.plot_diag.vcount(gdf_list[tidx])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f50747e4-44c9-48d3-a150-ec640573cb18",
   "metadata": {},
   "source": [
    "Similarly, use the `kxcount()` function from the `plot_diag` class to obtain a histogram with the count of the number of observations per type:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "46deda00",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "gd.plot_diag.kxcount(gdf_list[tidx])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "deb35f54",
   "metadata": {},
   "source": [
    "### Time Series\n",
    "\n",
    "<a id='time_series'></a>\n",
    "Below are the options for figures using the `time_series()` function, included in the `plot_diag` class. Initially, a figure is generated with the parameters already set in this section. Figures are then presented by changing the `Level`, `Lay`, and `SingleL` parameters.\n",
    "\n",
    "Plotting a time series for OmA and OmF:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "241bc9fc",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "gd.plot_diag.time_series(gdf_list,\n",
    "                         varName=varName, \n",
    "                         varType=varType, \n",
    "                         dateIni=dateIni, \n",
    "                         dateFin=dateFin, \n",
    "                         nHour=nHour, \n",
    "                         vminOMA=vminOMA, \n",
    "                         vmaxOMA=vmaxOMA, \n",
    "                         vminSTD=vminSTD, \n",
    "                         vmaxSTD=vmaxSTD, \n",
    "                         Level=Level, \n",
    "                         Lay=Lay, \n",
    "                         SingleL=SingleL,\n",
    "                         Clean=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "905097b2",
   "metadata": {},
   "source": [
    "In the previous case, the `Level` parameter was fixed at 1000 hPa with `SingleL` equal to `All`, meaning that the entire atmosphere was considered as a single layer, and the value 1000 hPa serves as a flag to indicate that there is no variation in height. Even with `Level=1000`, you can use `SingleL='OneL'` for a single layer around the `Level` value, in this case, 1000 hPa, varying between `Level-Lay` and `Level+Lay` (in the variable definition, `Lay` was fixed at 15 hPa; in case it is `None`, the default value of 50 hPa is used)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "565623bd",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "SingleL = 'OneL'\n",
    "Lay = 15\n",
    "\n",
    "gd.plot_diag.time_series(gdf_list,\n",
    "                         varName=varName, \n",
    "                         varType=varType, \n",
    "                         dateIni=dateIni, \n",
    "                         dateFin=dateFin, \n",
    "                         nHour=nHour, \n",
    "                         vminOMA=vminOMA, \n",
    "                         vmaxOMA=vmaxOMA, \n",
    "                         vminSTD=vminSTD, \n",
    "                         vmaxSTD=vmaxSTD, \n",
    "                         Level=Level, \n",
    "                         Lay=Lay, \n",
    "                         SingleL=SingleL,\n",
    "                         Clean=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8771f5b9",
   "metadata": {},
   "source": [
    "Notice how in the example above, the amount of data decreases since now a layer between 1015 and 985 hPa is being used.\n",
    "\n",
    "Now, let's change it to not fix it at a single level or layer, i.e., change the `Level` variable to `None` or `Zlevs`. The `None` option looks for data at each level existing in the files and creates the plot for all these levels, but the values on the y-axis (ordinate) are only for the standard levels. It's important to clarify that the so-called standard levels are defined in the `read_diag` class and can be accessed using the `zlevs` method as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "269a1812",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "gdf_list[tidx].zlevs"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "29f63a5f-8d2c-4e8d-a292-89a484740c06",
   "metadata": {},
   "source": [
    "This way, you can use the `Level='Zlevs'` parameter to produce a time series by levels:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7b8695b3",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "Level = 'Zlevs'\n",
    "Lay = 15\n",
    "\n",
    "gd.plot_diag.time_series(gdf_list,\n",
    "                         varName=varName, \n",
    "                         varType=varType, \n",
    "                         dateIni=dateIni, \n",
    "                         dateFin=dateFin, \n",
    "                         nHour=nHour, \n",
    "                         vminOMA=vminOMA, \n",
    "                         vmaxOMA=vmaxOMA, \n",
    "                         vminSTD=vminSTD, \n",
    "                         vmaxSTD=vmaxSTD, \n",
    "                         Level=Level, \n",
    "                         Lay=Lay, \n",
    "                         SingleL=SingleL,\n",
    "                         Clean=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "168e33f3",
   "metadata": {},
   "source": [
    "If `Lay=None`, then the layers are filled, varying between the mean value considering the lower and upper layers. For example, for the 700 hPa level, a layer is constructed between 750 and 650 hPa, since the lower and upper levels are 800 and 600 hPa, respectively. For the 1000 hPa level, the layer varies between 1050 and 950 hPa.\n",
    "\n",
    "The same previous example, but considering `Level='Zlevs'`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "369095b9",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "Level = 'Zlevs'\n",
    "Lay = None\n",
    "\n",
    "gd.plot_diag.time_series(gdf_list,\n",
    "                         varName=varName, \n",
    "                         varType=varType, \n",
    "                         dateIni=dateIni, \n",
    "                         dateFin=dateFin, \n",
    "                         nHour=nHour, \n",
    "                         vminOMA=vminOMA, \n",
    "                         vmaxOMA=vmaxOMA, \n",
    "                         vminSTD=vminSTD, \n",
    "                         vmaxSTD=vmaxSTD, \n",
    "                         Level=Level, \n",
    "                         Lay=Lay, \n",
    "                         SingleL=SingleL,\n",
    "                         Clean=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f65d75eb",
   "metadata": {},
   "source": [
    "Finally, there is the option to consider all levels, i.e., `Level=None`. This option brings some difficulty in visualizing the information in the figure due to the large number of levels and distribution of data across all levels:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c4a84f15",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "Level = None\n",
    "\n",
    "gd.plot_diag.time_series(gdf_list,\n",
    "                         varName=varName, \n",
    "                         varType=varType, \n",
    "                         dateIni=dateIni, \n",
    "                         dateFin=dateFin, \n",
    "                         nHour=nHour, \n",
    "                         vminOMA=vminOMA, \n",
    "                         vmaxOMA=vmaxOMA, \n",
    "                         vminSTD=vminSTD, \n",
    "                         vmaxSTD=vmaxSTD, \n",
    "                         Level=Level, \n",
    "                         Lay=Lay, \n",
    "                         SingleL=SingleL,\n",
    "                         Clean=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "529b6856-e35f-461c-b56f-db7c2fee7521",
   "metadata": {},
   "source": [
    "After finishing the use of the files, close them to release the used memory:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c19c6b4d-1272-4476-b311-7c51b67546ca",
   "metadata": {},
   "outputs": [],
   "source": [
    "for file in gdf_list:\n",
    "    file.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ab17d898",
   "metadata": {},
   "source": [
    "The `readDiag` is an actively developing package with continuous updates. New features will be added and demonstrated through this notebook."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eefbad7e-cccf-4a99-be5f-aa4d5c2dd642",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "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.9.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
