{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "042dbd67-e9fb-41bd-a465-c3a11f8ae20f",
   "metadata": {},
   "source": [
    "# Calculating global annual methane increases from satellite data using an ensemble dynamic linear model approach\n",
    "This notebook contains example code to calculate and plot global annual methane increases derived from Sentinel-5P TROPOMI WFDM XCH$_4$ data.\n",
    "\n",
    "**Version** : 1.0.0b1\n",
    "\n",
    "**DOI**: /\n",
    "\n",
    "**Requirements** :\n",
    "- The gridded WFMDv1.8 data can be downloaded from [10.5281/zenodo.8185672](https://doi.org/10.5281/zenodo.8185672)\n",
    "- The following python packages need to be installed\n",
    "    - xarray\n",
    "    - netcdf4\n",
    "    - numpy\n",
    "    - matplotlib\n",
    "    - tabulate\n",
    "    - statsmodels\n",
    "    - cartopy (optional)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "507a0e4c-919b-4657-9968-84f8b25f913f",
   "metadata": {},
   "source": [
    "## Import packages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ee5b7401-4018-4739-b5cb-ed38d940bee2",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import datetime\n",
    "\n",
    "import xarray as xr\n",
    "import numpy as np \n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.dates\n",
    "\n",
    "# Uncomment if you have installed cartopy\n",
    "# import cartopy.crs as ccrs\n",
    "# import cartopy.feature as cf\n",
    "\n",
    "\n",
    "import dlmhelper.tools\n",
    "import dlmhelper.data\n",
    "#from dlmhelper.spatio_temporal import inhomogeneity_spatial, inhomogeneity_temporal\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a765babd-cdf9-4bb5-af07-0d0455fbdc96",
   "metadata": {
    "tags": []
   },
   "source": [
    "## Function definitons\n",
    "These functions handle the reading, gridding and saving of .nc files"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3d92618a-b2b2-4c64-8615-5ebcd2f81d75",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "def load_grid_from_netcdf(d1,m1,y1,d2,m2,y2,path,grid_dim=None):\n",
    "    \"\"\"\n",
    "    Loads gridded data from NetCDF file for further processing. Sorts the data and adds missing\n",
    "    days.\n",
    "    \n",
    "    Parameters:\n",
    "        d1 (int): Day of the month for the start date (1-31).\n",
    "        m1 (int): Month of the start date (1-12).\n",
    "        y1 (int): Year of the start date.\n",
    "        d2 (int): Day of the month for the end date (1-31).\n",
    "        m2 (int): Month of the end date (1-12).\n",
    "        y2 (int): Year of the end date.\n",
    "        path (str): Path to NetCDF file\n",
    "        grid_dim (array-like, optional): Area to be read formatted as\n",
    "            [lat_low, lat_high, lon_low, lon_high]\n",
    "            \n",
    "    Returns:\n",
    "        np.array: Average XCH4 for each grid cell with shape (LAT,LON,TIME)\n",
    "        np.array: XCH4 uncertainty for each grid cell with shape (LAT,LON,TIME)\n",
    "        np.array: Number of datapoints used for each grid cell with shape (LAT,LON,TIME)\n",
    "        np.array: Latitudes for the lower boundary of the grid cells with shape (LAT)\n",
    "        np.array: Longitudes for the lower boundary of the grid cells with shape (LON)\n",
    "        np.array: Time as days since 1970-1-1 with shape (TIME)\n",
    "        np.array: Information about the grid formatted as\n",
    "                [lat_low, lat_high, lon_low, lon_high, lat_step, lon_step]\n",
    "        str: String containing the name of the product\n",
    "    \n",
    "\n",
    "    \"\"\"\n",
    "    \n",
    "    date_min=(datetime.datetime(y1,m1,d1)-datetime.datetime(1970,1,1)).days\n",
    "    date_max=(datetime.datetime(y2,m2,d2)-datetime.datetime(1970,1,1)).days\n",
    "\n",
    "    ds = xr.load_dataset(path)\n",
    "    \n",
    "    product_type = ds.attrs['product_type']\n",
    "    LAT_LOW = ds.attrs['lat_low']\n",
    "    LAT_HIGH = ds.attrs['lat_high']\n",
    "    LON_LOW = ds.attrs['lon_low']\n",
    "    LON_HIGH = ds.attrs['lon_high']\n",
    "    LAT_STEP = ds.attrs['lat_res']\n",
    "    LON_STEP = ds.attrs['lon_res']\n",
    "    latd=int((LAT_HIGH-LAT_LOW)/LAT_STEP)\n",
    "    lond=int((LON_HIGH-LON_LOW)/LON_STEP)\n",
    "    sdev=np.zeros((latd,lond))\n",
    "    xch4 = np.zeros((latd,lond))\n",
    "    \n",
    "    x = ds.variables['lon']\n",
    "    y = ds.variables['lat']\n",
    "    d = ds.variables['day']\n",
    "    \n",
    "    ref_time = ds.attrs['reference_time']\n",
    "    \n",
    "    \n",
    "    if grid_dim is not None:\n",
    "        lat_min, lat_max, lon_min, lon_max = grid_dim\n",
    "    else:\n",
    "        lat_min,lat_max,lon_min,lon_max = LAT_LOW, LAT_HIGH, LON_LOW, LON_HIGH\n",
    "    \n",
    "    a = (y>=lat_min) & (y<lat_max)\n",
    "    b = (x>=lon_min) & (x<lon_max)\n",
    "    xch4 = ds.variables['xch4'][a,b,(d>=date_min) & (d<=date_max)]\n",
    "    sdev = ds.variables['xch4_err'][a,b,(d>=date_min) & (d<=date_max)]\n",
    "    N = ds.variables['N'][a,b,(d>=date_min) & (d<=date_max)]\n",
    "    \n",
    "    d=d[(d>=date_min) & (d<=date_max)]\n",
    "    \n",
    "    x = x[b]\n",
    "    y = y[a]\n",
    "\n",
    "    ds.close()\n",
    "    \n",
    "    grid_dim = {\n",
    "        'LAT_LOW': lat_min,\n",
    "        'LAT_HIGH': lat_max, \n",
    "        'LON_LOW': lon_min,\n",
    "        'LON_HIGH': lon_max,\n",
    "        'LAT_STEP': LAT_STEP,\n",
    "        'LON_STEP': LON_STEP\n",
    "    }\n",
    "    return xch4, sdev, N, x.values, y.values, d, grid_dim, product_type , ref_time"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c046ab89-dbd7-4f6f-a858-e022b2e73793",
   "metadata": {
    "tags": []
   },
   "source": [
    "## Settings"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b9af7324-66ba-433b-b5da-848fff3f2cae",
   "metadata": {},
   "source": [
    "First the area and time ranges to be read from the NetCDF file are defined\n",
    "- <b> grid </b> <i>(LAT_LOW, LAT_HIGH, LON_LOW, LON_HIGH)</i>: Defines the subgrid to be read from the file\n",
    "- <b> d1, m1, y1, d2, m2, y2 </b>: Define the start and end date for the time series\n",
    "- <b> dd1, md1, yd1, dd2, md2, yd2 </b>: Define the start and end date for which the data will be loaded\n",
    "\n",
    "We define a time series from 2018-01 to 2023-03 only using data from 2018-05 to 2023-03. While data is theoretically available from 2017-11, the commisioning phase of the S5P mission ended with 2018-05, thus we only use data starting from this point."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "058bd03c-c6b3-41fa-9b95-a765d9c334bf",
   "metadata": {},
   "outputs": [],
   "source": [
    "#Area to be loaded from the NetCDF file\n",
    "grid=[-90,90,-180,180]\n",
    "\n",
    "#These dates define the start and end date for the time series\n",
    "d1, m1, y1 = (1,1,2018)\n",
    "d2, m2, y2 = (1,3,2023)\n",
    "\n",
    "#These dates the start and end date for which data form the NetCDF file shall be used\n",
    "dd1, md1, yd1 = (1,5,2018)\n",
    "dd2, md2, yd2 = (1,3,2023)\n",
    "\n",
    "path_in = \"/path/to/global_2x2_64_xch4_trend_LAT_-90.00_90.00_LON_-180.00_180.00.nc\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "79aa2dea-0402-4e7b-ba92-ed96e438711b",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "name = \"global\" # Name used when saving DLM fit resuts\n",
    "FOLDS = 5       # Number of folds to use for cross validation\n",
    "ZONAL_AVG = True # If true, average over longitudes first and latitudes second. This helps to reduce sampling related biases.\n",
    "\n",
    "path_out = \"./\" # Path to save DLMResults and final plot"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7a3d1d13-cc30-4767-928a-c0564981018e",
   "metadata": {
    "tags": []
   },
   "source": [
    "## Load data\n",
    "The gridded data is loaded from the NetCDF file using the determined date range and area."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2a663053-fd89-4d19-b7ce-c00a61f28aa1",
   "metadata": {},
   "outputs": [],
   "source": [
    "date_min = (datetime.datetime(y1,m1,d1)-datetime.datetime(1970,1,1)).days\n",
    "date_max = (datetime.datetime(y2,m2,d2)-datetime.datetime(1970,1,1)).days\n",
    "\n",
    "vmr, sdev, N, lons, lats, d, grid_dim, product_type, ref_time = load_grid_from_netcdf(d1,m1,y1,d2,m2,y2,path_in,grid_dim=grid)\n",
    "\n",
    "data_min = (datetime.datetime(yd1,md1,dd1)-datetime.datetime(1970,1,1)).days\n",
    "data_max = (datetime.datetime(yd2,md2,dd2)-datetime.datetime(1970,1,1)).days\n",
    "    \n",
    "_idx = (d<data_min) | (d>data_max)\n",
    "vmr[:,:,_idx] = np.nan\n",
    "sdev[:,:,_idx] = np.nan"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6b210140-54d0-405c-866c-4432e7cdff26",
   "metadata": {},
   "outputs": [],
   "source": [
    "grid_data = dlmhelper.data.Grid(vmr, lats, lons, time= d,time_unit = \"day\",error=sdev, N = N, reference_time = ref_time, grid_dim = grid_dim, product_type=\"WFMDv1.8\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "604c1f46-8303-48b7-90cf-c3a280421c59",
   "metadata": {},
   "source": [
    "## Pre-processing of data\n",
    "Here the gridded data is filtered using the spatial and temporal homogeneity measure from [Sofieva et al. (2014)](https://www.doi.org/10.5194/amt-7-1891-2014).\n",
    "This removes grid cells with inhomogeneous temporal coverage and days with inhomogeneous spatial coverage from the analysis."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e2641d06-8eb3-4709-b4bd-b8f1a0baf755",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "HT_LIM = 0.5 \n",
    "Ht = grid_data.inhomogeneity_temporal()\n",
    "grid_data.filter_inhomogeneity_temporal(ht_lim=HT_LIM)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ca2b7ad9-39de-4f1e-89b1-1053be8a0101",
   "metadata": {},
   "source": [
    "_To visualize the temporal inhomogeneity nicely the cartopy package is needed_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a0d3563e-fe6b-4b62-a342-318f0e2aba4d",
   "metadata": {},
   "outputs": [],
   "source": [
    "LAT_LOW = grid_dim[\"LAT_LOW\"]\n",
    "LAT_HIGH = grid_dim[\"LAT_HIGH\"]\n",
    "LON_LOW = grid_dim[\"LON_LOW\"]\n",
    "LON_HIGH = grid_dim[\"LON_HIGH\"]\n",
    "LAT_STEP = grid_dim[\"LAT_STEP\"]\n",
    "LON_STEP = grid_dim[\"LON_STEP\"]\n",
    "\n",
    "import sys\n",
    "\n",
    "cmap = \"BrBG\"\n",
    "\n",
    "if 'cartopy' in sys.modules:\n",
    "    \n",
    "    fig = plt.figure()\n",
    "    proj=ccrs.PlateCarree()\n",
    "    proj._threshold /= 100.\n",
    "    ax = fig.add_subplot(111,projection=proj)\n",
    "    ax.add_feature(cf.COASTLINE)\n",
    "    ax.gridlines(draw_labels=True)\n",
    "    ax.set_extent([LON_LOW,LON_HIGH,LAT_LOW,LAT_HIGH],ccrs.PlateCarree())\n",
    "\n",
    "    X2=list(lats)\n",
    "    X2.append(X2[-1]+LON_STEP)\n",
    "    Y2=list(lons)\n",
    "    Y2.append(Y2[-1]+LAT_STEP)\n",
    "    X2=np.asarray(X2)\n",
    "    Y2=np.asarray(Y2)\n",
    "\n",
    "    X=lons\n",
    "    Y=lats\n",
    "    XX,YY=np.meshgrid(Y2,X2)\n",
    "    ht_masked = np.ma.masked_equal(Ht[...,0],0)\n",
    "\n",
    "    plt.title(f'Temporal inhomogeneity ({product_type})') \n",
    "    vmin = 0\n",
    "    vmax = 1\n",
    "    cm=plt.pcolormesh(XX,YY,ht_masked,shading='auto',cmap=cmap,transform=ccrs.PlateCarree(),vmin=vmin,vmax = vmax)\n",
    "\n",
    "    cb=fig.colorbar(cm,fraction=0.046,pad=0.1,orientation='horizontal')\n",
    "    cb.set_label(r'inhomogeneity')\n",
    "\n",
    "else:\n",
    "    \n",
    "    fig = plt.figure()\n",
    "    ax = fig.add_subplot(111)\n",
    "\n",
    "    X2=list(lats)\n",
    "    X2.append(X2[-1]+LON_STEP)\n",
    "    Y2=list(lons)\n",
    "    Y2.append(Y2[-1]+LAT_STEP)\n",
    "    X2=np.asarray(X2)\n",
    "    Y2=np.asarray(Y2)\n",
    "\n",
    "    X=lons\n",
    "    Y=lats\n",
    "    XX,YY=np.meshgrid(Y2,X2)\n",
    "    ht_masked = np.ma.masked_equal(Ht[...,0],0)\n",
    "\n",
    "    plt.title(f'Temporal inhomogeneity ({product_type})') \n",
    "    vmin = 0\n",
    "    vmax = 1\n",
    "    cm=plt.pcolormesh(XX,YY,ht_masked,shading='auto',cmap=cmap,vmin=vmin,vmax = vmax)\n",
    "\n",
    "    cb=fig.colorbar(cm,fraction=0.046,pad=0.1,orientation='horizontal')\n",
    "    cb.set_label(r'inhomogeneity')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "478ce56e-4012-403e-8803-843c1ba6e003",
   "metadata": {},
   "source": [
    "Calculate & plot spatial homogeneity"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ef8cd549-da0b-4907-9377-c9b4c4ccf33e",
   "metadata": {},
   "outputs": [],
   "source": [
    "Hs = grid_data.inhomogeneity_spatial()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e5cedb53-b96d-47bb-a970-8d0af50f30dd",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure()\n",
    "ax = fig.add_subplot(111)\n",
    "ax.set_title(\"Spatial inhomogeneity\")\n",
    "ax.scatter(grid_data.time,Hs[:,0],s=3)\n",
    "#ax.axhline(0.2639240547142875,color='black')\n",
    "ax.xaxis_date()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3497f3f5-19eb-46a1-95bf-f318ed1ad346",
   "metadata": {},
   "source": [
    "Filter the grid_data object using spatial homogeneity and the standard limit $H_s^{lim} = $ median + 2 x $\\sigma$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "87fe0f03-14e1-478f-bd44-b1e773c0ac1f",
   "metadata": {},
   "outputs": [],
   "source": [
    "grid_data.filter_inhomogeneity_spatial()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b29b9cde-9174-4269-a39c-9e363a9d621e",
   "metadata": {},
   "source": [
    "Filter data with low spatial homogeneity"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1559e15a-326e-464b-8030-ea5b3354fcf8",
   "metadata": {},
   "source": [
    "Calculate the time series as the area-weighted average from the processed gridded data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cf1980d2-2d04-4b88-a0a0-bda5d5c196a7",
   "metadata": {},
   "outputs": [],
   "source": [
    "time_series = grid_data.to_timeseries(zonal_avg=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cbc78bc1-2e8d-4202-ae3e-5f2b6f2a0aa3",
   "metadata": {},
   "outputs": [],
   "source": [
    "product_type = time_series.product_type\n",
    "vmr_whmean, sdev_whmean = time_series.data, time_series.error\n",
    "d = time_series.time\n",
    "\n",
    "vmr_min = np.nanmin(vmr_whmean)-5; vmr_max=np.nanmax(vmr_whmean)+5\n",
    "\n",
    "fig = plt.figure()\n",
    "ax = fig.add_subplot(111)\n",
    "ax.errorbar(d,vmr_whmean,yerr=sdev_whmean,color='black',ecolor='gray',ls='',marker='.')\n",
    "ax.set_title(f\"Daily area-weighted XCH$_4$\")\n",
    "ax.set_xlabel(\"Date\")\n",
    "ax.set_ylabel(f\"XCH$_4$ [pbb]\")\n",
    "ax.set_ylim(1800,1900)\n",
    "ax.xaxis_date()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "70a349ed-1570-4442-8b17-d5479e08c87b",
   "metadata": {},
   "outputs": [],
   "source": [
    "time_series.save('./',\"WFMD_TimeSeries.dat\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "00152bb0-ef5f-4db2-b5ab-24c5a641f777",
   "metadata": {},
   "outputs": [],
   "source": [
    "time_series = dlmhelper.data.TimeSeries.load('./WFMD_TimeSeries.dat')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "397bb7ea-5cb5-4f31-a70d-0f4bebdda538",
   "metadata": {
    "tags": []
   },
   "source": [
    "## Dynamic linear model fit\n",
    "The daily area-weighted XCH4 data is fitted using a dynamic linear model approach. \n",
    "For this an ensemble of different DLMs is fitted to the data. Additonally, cross validation is performed from which an average mean squared error (AMSE) is determined for each model.\n",
    "\n",
    "The AMSE is used together with the variance of the level and seasonal component of the DLM fits to create an aggregated measure (agg) for model selection.\n",
    "The final model is used to calculate the global annual methane increases.\n",
    "### Create Folds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "539d48e8-1352-48c5-8b04-7f35356e1312",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "scores = dlmhelper.tools.cv_dlm_ensemble(time_series,\n",
    "                        level = [True], variable_level= [False],\n",
    "                        trend = [True], variable_trend= [True],\n",
    "                        seasonal = [True],\n",
    "                        seasonal_period=[[365.2]],\n",
    "                        seasonal_harmonics=[\n",
    "                            [[1,2,3,4]]\n",
    "                        ],\n",
    "                        variable_seasonal= [\n",
    "                                [[True, False]]\n",
    "                            ],\n",
    "                        irregular=[True,False],\n",
    "                        autoregressive = [1],\n",
    "                        folds = 5\n",
    "                        )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "44ab01c1-f293-4f72-a2ce-3fea2033dc7d",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "dlm_results =  dlmhelper.tools.dlm_ensemble(time_series, name=\"wfmd_global_ensemble\",\n",
    "                                            seasonal_period=[[365.2]],\n",
    "                                            seasonal_harmonics=[\n",
    "                                                [[1,2,3,4]]\n",
    "                                            ],\n",
    "                                            variable_seasonal= [\n",
    "                                                    [[True, False]]\n",
    "                                                ],\n",
    "                                            irregular=[True,False], scores=scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f384fd06-4ece-4372-b7e2-df0e538fd0e9",
   "metadata": {},
   "outputs": [],
   "source": [
    "dlm_results.summary(converged=True, sort='agg')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "513d10ef-a742-48ac-abd4-99c67f8dadee",
   "metadata": {},
   "source": [
    "The best fits can also be quickly plotted"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5dfb7fe7-4acc-4c14-93cb-5afa2603d2d6",
   "metadata": {},
   "outputs": [],
   "source": [
    "dlm_results.plot_summary(num=8, converged=True, sort='agg',figsize=(16,8))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "baf23078-c292-4a63-95f9-3605ec3342dd",
   "metadata": {},
   "source": [
    "The DLM Results can be easily saved as a .tar for later use"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dfa1bf81-8cc0-4b07-b409-e867d2a7dfe8",
   "metadata": {},
   "outputs": [],
   "source": [
    "dlm_results.save_archive(path_out+f'{name}.tar')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "30e96e1c-a259-4341-838e-563935c27aac",
   "metadata": {},
   "outputs": [],
   "source": [
    "dlm_results = dlmhelper.data.DLMResultList.load_archive(path_out+\"global.tar\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8f83b5b0-2eff-4c84-912d-2e3afc769897",
   "metadata": {},
   "source": [
    "# Plot global annual methane increases"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1523b83f-ca25-491e-8a10-5d09617b2254",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Definition of colors used\n",
    "c1 = \"#0072B2\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cd5ef96a-2714-43cb-89a5-aed1d77f8e11",
   "metadata": {},
   "outputs": [],
   "source": [
    "# The sampling error is not calculated in this notebook to keep things simple\n",
    "sampling_error = [2.95916842, 0.24635348, 0.19208639, 0.25882388, 0.2505219 ]\n",
    "\n",
    "model_error = dlmhelper.tools.model_selection_bias_ALI(dlm_results, percentile=100,years=[2018,2019,2020,2021,2022])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c6a73d79-f9c2-45ca-a7ce-7450c241a467",
   "metadata": {},
   "source": [
    "The best model is selected using the \"agg\" measure as a selection criterion"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1c780992-6225-4ef6-878a-5261c5c4086f",
   "metadata": {},
   "outputs": [],
   "source": [
    "wfmd_global = dlm_results.get_best_result(sort='agg')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "913b52a8-0b86-46a7-a371-1008bfa0da1a",
   "metadata": {},
   "outputs": [],
   "source": [
    "SIGMA = 1\n",
    "\n",
    "\n",
    "years = np.asarray([2018,2019,2020,2021,2022])\n",
    "ami = np.zeros(years.shape)\n",
    "ami_std = np.zeros(years.shape)\n",
    "total_error = np.zeros(years.shape)\n",
    "\n",
    "for i, y in enumerate(years):\n",
    "    ami[i], ami_std[i] = dlmhelper.tools.annual_level_increase(wfmd_global, y)\n",
    "    total_error[i] = np.sqrt(ami_std[i]**2+model_error[i]**2+sampling_error[i]**2)\n",
    "\n",
    "fig = plt.figure() \n",
    "ax = fig.add_subplot(111)\n",
    "ax.set_ylim([0,20])\n",
    "ax.set_ylabel(\"XCH$_4$ increase [ppb]\",fontsize=\"x-large\")\n",
    "ax.set_xticks(years)\n",
    "ax.xaxis.set_tick_params(labelsize=\"x-large\")\n",
    "ax.set_title(\"Global annual methane increases (DLM@WFMDv1.8(daily))\")\n",
    "ax.bar(years, ami, yerr=SIGMA*(total_error), align ='center', edgecolor='black',color=c1,hatch=[\"//\",\"\",\"\",\"\",\"\"], width=1)\n",
    "\n",
    "for i, y in enumerate(years):\n",
    "    ax.text(y-0.45,0.7,f\"{ami[i]:.2f}\\n({total_error[i]:.2f})\",fontsize=12,color=\"white\",fontweight=\"heavy\")\n",
    "    \n",
    "#ax.set_title(\"Global annual methane increases\")\n",
    "ax.text(2017.5,19,\"Note: AMI for 2018 only includes data from 01.05.2018\",backgroundcolor='white',fontsize=\"small\")\n",
    "#plt.savefig(path_out+\"fig04.png\",dpi=300)\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
