{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# readDiag\n",
    "\n",
    "O pacote `readDiag` foi concebido para ser uma ferramenta que possibilita o fácil acesso aos arquivos diagnósticos gerados pelo [Gridpoint Statistical Interpolation (GSI) system](https://github.com/NOAA-EMC/GSI). O pacote é composto principalmente por 2 classes, a primeira para ler os dados (`read_diag`) e outra para fazer diferentes tipos de figuras com dados selecionados (`plot_diag`).\n",
    "\n",
    "## A Classe `read_diag`\n",
    "\n",
    "A classe read_diag é composta por 5 funções:\n",
    "\n",
    "1. `__init__(self, diagFile, diagFileAnl=None, isisList=None, zlevs=None)`: sendo `diagFile` o arquivo de diagnóstico do primeiro outer loop com informação do OmF e `diagFileAnl` do último outer loop com informação do OmA. Note que não é necessário informar os dois arquivos, o `diagFileAnl` é opcional. Neste caso, a informação lida (Omf ou OmA) dependerá do outer loop (arquivo diagnóstico) fornecido;\n",
    "2. `overview(self)`: esta função cria e retorna um dicionário com as informações existentes no arquivo;\n",
    "3. `pfileinfo(self)`: esta função imprime de forma elegante uma lista com as informações existentes no arquivo;\n",
    "4. `close(self)`: esta função fecha o último arquivo aberto;\n",
    "5. `tocsv(self, varName=None, varType=None, dateIni=None, dateFin=None, nHour=\"06\", Level=None, Lay=None, SingleL=None)`: esta função gera um arquivo CSV dos parâmetros OmF e OmA com as seguintes informações: data, média, desvio-padrão e total de dados para a variável e tipo escolhidos.\n",
    "    \n",
    "Os dados de entrada da função e funcionalidades são idênticas àquelas da função `time_series` que é apresentada na próxima seção na classe `plot_diag` (item 7 - ver também detalhes das funcionalidades [aqui](#time_series)). O que distingue as duas funções é que esta escreve um arquivo CSV e a outra gera figuras de séries temporais.\n",
    "\n",
    "## A Classe `plot_diag`\n",
    "    \n",
    "A classe plot_diag é composta por 7 funções:\n",
    "\n",
    "1. `plot(self, varName, varType, param, mask=None, **kwargs)`: a função `plot` gera uma figura para a variável `varName` (ex: `uv`), `varType` (ex: `220` (dropssonda)) e `param`, que pode ser várias opções como: `param=\"obs\"` para o valor da observação, `param=\"omf\"` para observação menos background ou `param=\"oma\"` para observação menos análise. Também é possível mascarar os dados com a variável `iuse`, que indica se o dado foi (`iuse=1`) ou não (`iuse=-1` - dado monitorado) utilizado na assimilação. Abaixo há um exemplo executado para `varName=\"uv\"`, `varType=220`, `param=\"obs\"` e 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)`: a função `ptmap` gera uma figura com a localização de todas as observações definidas por `varName` (ex: `uv`) e `varType` (pode ser um único tipo ou uma lista, ex: `[200]` ou `[220,221,257]`. Se `varType` não for informado, então todos os tipos serão incluídos na figura. Também é possível mascarar os dados com a variável `iuse`, que indica se o dado foi (`iuse=1`) ou não (`iuse=-1` - dado monitorado) utilizado na assimilação. Abaixo há um exemplo executado para `varName=\"uv\"`, `varType=[254,242,221,220,257,258,281,280]` e `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)`: a função `pvmap` é similar à função `ptmap`, com a diferença de não especificar o tipo (`varType`), podendo então escolher uma lista de variáveis, ex: `[\"uv\",\"ps\",\"t\"]`. Abaixo há um exemplo executado para `varName=['uv','ps','t']`, e `mask=None`; \n",
    "\n",
    "<img src=notefigs/uv_ps_t_pvmap.png style=\"width: 800px;\">\n",
    "<br>\n",
    "\n",
    "4. `pcount(self,varName,**kwargs)`: a função `pcount` gera um histograma da quantidade de dados para uma determinada variável `varName` (ex: `uv`) e todos os tipos disponíveis (`varType`);\n",
    "\n",
    "<img src=notefigs/uv_pcount.png style=\"width: 800px;\">\n",
    "<br>\n",
    "\n",
    "5. `kxcount(self,**kwargs)`: a função `kxcount` é similar à `pcount`, porém não especifica a variável (`varName`). Esta função gera um histograma com o total de dados (todas as variáveis somadas) para todos os tipos disponíveis (`varType`);\n",
    "\n",
    "<img src=notefigs/kxcount.png style=\"width: 800px;\">\n",
    "<br>\n",
    "\n",
    "6. `vcount(self,**kwargs)`: a função `vcount` gera um histograma com a quantidade total de dados para cada variável (`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)`: a função `time_series` pode gerar 6 tipos distintos de figuras, dependendo da configuração especificada na sua chamada. A característica comum entre os 6 tipos é a variação no tempo, enquanto que a diferença entre os 6 tipos é a forma de tratar os níveis verticais. Basicamente estas formas são distribuídas entre variar na vertical (diferentes valores para diferentes níveis/camadas) e fixo na vertical (nível específico, média na camada ou toda a atmosfera). \n",
    "\n",
    "No decorrer deste notebook são mostrados exemplos com recortes de código para exemplificar o uso das funções acima elencadas.\n",
    "\n",
    "**Nota:** esta é uma versão simplificada do notebook `readDiag_tutorial_completo-pt_br.ipynb`.\n",
    "\n",
    "## Utilização da classe `read_diag`\n",
    "\n",
    "### Bibliotecas necessárias\n",
    "\n",
    "Para iniciar a utilização do `readDiag`, carregue primeiro as bibliotecas necessárias para a sua utilização:\n",
    "\n",
    "* `gsidiag`: é a biblioteca que contém as classes `read_diag` e `plot_diag`;\n",
    "* `pandas`: é a biblioteca que fornece as estruturas de dados tabulados utilizadas pelo `readDiag`;\n",
    "* `matplotlib`: é a biblioteca a partir da qual são confeccionadas as figuras.\n",
    "\n",
    "A instrução `%matplotlib inline` é um comando mágico do Jupyter e apenas ajusta o ambiente para que não seja necessário utilizar o comando `plt.show()` sempre que figuras forem mostradas dentro do notebook. Se você estiver utilizando o `readDiag` dentro de um script Python, esta diretiva pode ser suprimida e o comando `plt.show()` deve ser utilizado, a depender da situação."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Descomente a linha a seguir para utilizar este notebook no Google Colab\n",
    "#!pip install readDiag"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import gsidiag as gd\n",
    "\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Com a biblioteca principal carregada, abra o arquivo `diag_conv_01.2020031112` (~64 MB). Este arquivo está contido no diretório `data` deste repositório e é fornecido para testar as funcionalidades do `readDiag`. Este é um arquivo contém as informações de diagnósticos das observações convencionais do GSI, provenientes da minimização da função custo 3DVar, válido para a data 2020031112.\n",
    "\n",
    "Para abrir o arquivo, será criado o objeto `file`, a partir do qual serão utilizados as funções e os métodos embutidos do `readDiag`.\n",
    "\n",
    "**Nota:** o parâmetro `%%time` é um comando mágico do Jupyter para contabilizar o tempo de execução das células do notebook e não é necessário para a utilização do `readDiag`.\n",
    "\n",
    "Para carregar o arquivo indicado, faça:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%time\n",
    "\n",
    "file = gd.read_diag('../data/diag_conv_01.2020031112')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "### Obtendo informações dos arquivos\n",
    "\n",
    "Utilize a função `pfileinfo()` para obter uma lista das observações e seus respectivos tipos (`kx`) que estão contidos dentro do arquivo:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "file.pfileinfo()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Além do método `pfileinfo()`, outros métodos e funções também podem ser utilizados para acessar as informações sobre os arquivos abertos. Para obter uma lista dos métodos e funções disponíveis, digite `gdf_list[tidx].` e pressione a tecla `<TAB>` duas vezes no teclado:\n",
    "\n",
    "```python\n",
    ">>> file.\n",
    "file.close(      file.obsInfo     file.pfileinfo(  file.zlevs       \n",
    "file.tocsv(      file.overview(   file.varNames    \n",
    "file.obs\n",
    "```\n",
    "\n",
    "Os métodos e funções embutidas possuem documentação, as quais podem ser acessadas da seguinte forma:\n",
    "\n",
    "```python\n",
    "print(object.function_name.__doc__)\n",
    "```\n",
    "\n",
    "ou\n",
    "\n",
    "```python\n",
    "help(object.function_name)\n",
    "```\n",
    "\n",
    "Por exemplo:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "print(file.pfileinfo.__doc__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "ou ainda:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "help(file.pfileinfo)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Para obter um dicionário com todas as informações sobre as variáveis e tipos contidos no arquivo, utilize o método `obsInfo`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "file.obsInfo"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Para acessar uma variável específica (ex: `uv`), faça:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "varName = 'uv'\n",
    "print('Variável: ', varName)\n",
    "\n",
    "file.obsInfo[varName]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "Para acessar variável e tipo específicos (ex: `uv` do tipo `220`), faça:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "varType = 220\n",
    "print('Variável: ', varName, ' e Tipo: ', varType)\n",
    "\n",
    "file.obsInfo[varName].loc[varType]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "O parâmetro `varType` pode ser também uma lista, ex: `varType=[220,221]`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "varTypes = [220,221]\n",
    "\n",
    "print('Variável: ', varName, ' e Tipos: ', varTypes)\n",
    "\n",
    "file.obsInfo[varName].loc[varTypes]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Para acessar o valor da observação, utilize o método `obs`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "print('Variável: ', varName, ' e Tipo: ', varType)\n",
    "\n",
    "file.obsInfo[varName].loc[varType].obs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Utilização da classe `plot_diag`\n",
    "\n",
    "### Distribuição espacial\n",
    "\n",
    "A utilização das funções da classe `plot_diag` é apresentada abaixo, junto com os comandos para gerar diversos tipos de figuras.\n",
    "\n",
    "Gerando uma figura com os valores das observações (`param='obs'`) para a variável e tipo selecionados:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "param = 'obs'\n",
    "\n",
    "gd.plot_diag.plot(file, \n",
    "                  varName=varName, \n",
    "                  varType=varType, \n",
    "                  param=param, \n",
    "                  mask='iuse == 1', \n",
    "                  legend='true')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Para salvar a figura, defina o seu nome (`figname`) e execute os comandos a seguir:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "figname = varName + '_' + param + '_' + 'plot.png'\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.savefig(figname)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Gerando a mesma figura, mas considerando vários tipos diferentes (`kx`) da observação selecionada:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "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(file, varName=varName, varType=varTypes)\n",
    "\n",
    "figname = varName + '_' + idschar + '_' + 'ptmap.png'\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.savefig(figname)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Gerando uma figura com diferentes variáveis, considerando a máscara `iuse==1`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "varNames = ['uv','ps','t']\n",
    "idschar = '_'.join([str(item) for item in varNames])\n",
    "\n",
    "gd.plot_diag.pvmap(file, varName=varNames, mask='iuse==1')\n",
    "\n",
    "figname = idschar + '_pvmap.png'\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.savefig(figname)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Histograma\n",
    "\n",
    "Utilize a função `pcount()` da classe `plot_diag` para obter um histograma com a contagem do número de observações para uma determinada variável:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "gd.plot_diag.pcount(file, varName)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Utilize a função `vcount()` da classe `plot_diag` para obter um histograma com a contagem do número de observações para todos os tipos de variáveis:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "gd.plot_diag.vcount(file)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "De forma semelhante, utilize a função `kxcount()` da classe `plot_diag` para obter um histograma com a contagem do número de observações por tipo:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "gd.plot_diag.kxcount(file)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Como estamos lidando apenas com um arquivo (i.e., com apenas uma única data), não podemos criar uma série temporal dos valores de OmA e OmF. Para isso, com alguns arquivos em mão, utilize os exemplos contidos no notebook `readDiag_tutorial_simples-pt_br.ipynb`.\n",
    "\n",
    "Finalizado o uso do arquivo, feche-o para liberar a memória utilizada:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "file.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "O `readDiag` é um pacote em desenvolvimento e em constante atualização. Novas funcionalidades serão adicionadas e demonstradas por meio deste notebook."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "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": 4
}
