{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Light cross sectional flux (LCSF) method\n",
    "This notebook demonstrates how to quantify CO$_2$ and NO$_x$ emissions from point sources using synthetic CO2M observations for a power plant and for a city.\n",
    "The method used to quantify emissions is derived from a cross-sectional flux estimation method illustrated in Zheng et al., 2020 (https://doi.org/10.5194/acp-20-8501-2020) and Chevallier et al., 2020 (https://doi.org/10.1029/2020GL090244)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%load_ext autoreload\n",
    "%autoreload 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "import cartopy.crs as ccrs\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import xarray as xr\n",
    "\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "# import and setup matplotlib\n",
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "plt.rcParams['figure.dpi'] = 100\n",
    "\n",
    "import ddeq"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define coordinate reference systems used by the tool, the SMARTCARB model domain and the path to SMARTCARB data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from ddeq.smartcarb import DOMAIN\n",
    "\n",
    "# Path to test dataset incl in ddeq\n",
    "DATA_PATH = os.path.join(os.path.dirname(ddeq.__file__), '..', '..', 'notebooks', 'data')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Read list of point sources in the SMARTCARB model domain from \"sources.csv\" file."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# list of point sources\n",
    "sources = ddeq.misc.read_point_sources()\n",
    "sources = sources.sel(source=['Janschwalde', 'Boxberg'])\n",
    "sources"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Synthetic satellite observations"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Synthetic satellite observations are available from the SMARTCARB project (https://doi.org/10.5281/zenodo.4048227). The `ddeq` package can read the data files and automatically applies random noise and cloud filters to the observations. The code also fixes some issues with the dataset such as wrong emissions for industry in Berlin in January and July. It is also possible to scale the anthropogenic model tracers: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "filename = os.path.join(DATA_PATH, 'Sentinel_7_CO2_2015042311_o1670_l0483.nc')\n",
    "data = ddeq.smartcarb.read_level2(filename, co2_noise_scenario='low', no2_noise_scenario='high')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Light cross-sectional flux estimation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Parameters of the method\n",
    "The operations of the light cross-sectional method for estimating emissions are defined by several parameters.\n",
    "Complete list can be found in the function ddeq.lcs.estimate_emissions. A shorter list can be provided by the user as the example below"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "lcs_params={}\n",
    "\n",
    "# if float: Altitude at or below (if wind_alti_avg set to True) which effective\n",
    "# winds for emission computation are extracted.\n",
    "# if set to 'GNFR-A': ERA-5 averaged winds depending on profile emissions are used as effective winds\n",
    "lcs_params['alti_ref'] = 'GNFR-A' # Or 'GNFR-A'\n",
    "\n",
    "# if effective winds for emissions computation are averaged between the surface and the reference altitude\n",
    "lcs_params['wind_alti_avg'] = False\n",
    "\n",
    "# Wind product. So far the implementation has been done for SMARTCARB and ERA-5 winds\n",
    "lcs_params['wind_product'] = 'SMARTCARB' # ERA5 || SMARTCARB\n",
    "\n",
    "# Tracer gases used for the emission estimations\n",
    "# If NO2 l2 data are used, NOx emissions are estimated.\n",
    "# If CO2_with_NO2 is prescribed, NOx and CO2 emissions from CO2 data only are also provided\n",
    "lcs_params['tracer_gases'] = ['CO2']  # ['CO2','NO2','CO2_with_NO2']\n",
    "\n",
    "lcs_params['use_prior'] = False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Extracting wind fields\n",
    "Wind files should correspond to the L2 satellite data file and to the chosen wind product."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if lcs_params['wind_product'] == 'ERA5':\n",
    "    pass\n",
    "else:\n",
    "    wind_filename = os.path.join(DATA_PATH, 'SMARTCARB_winds_2015042311.nc')\n",
    "      \n",
    "winds = ddeq.wind.read_field(wind_filename, altitude=lcs_params['alti_ref'], average_below=False, product=lcs_params['wind_product'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Emissions of the sources are estimated by the function ddeq.lcs.estimate_emissions. \n",
    "By default, the function returns for all sources the emission estimates, their precision, and the distances\n",
    "to the source of the points where emissions are estimated. If all_diags set to True, additional information relative\n",
    "to the line densities are also provided for the graphical representation of the results."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "lcs_params = {}\n",
    "lcs_params['verbose'] = False\n",
    "lcs_params['f_NOx_NO2'] = 1.32\n",
    "\n",
    "lcs_params['n_min_fit_pts'] = 10\n",
    "#lcs_params['fit_pt_slice_width'] = 15\n",
    "\n",
    "\n",
    "# Q prior with 0.1-1.9 bounds\n",
    "lcs_params['use_prior'] = False\n",
    "priors = dict(\n",
    "    (name, {'NO2': {'Q': 1.0, 'tau': 4.0}, 'CO2': {'Q': 1000.0, 'tau': 1e10}})\n",
    "    for name in sources.source.values\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "res_no2 = ddeq.lcsf.estimate_emissions(data, winds, sources, priors=priors,\n",
    "                                       lcs_params=lcs_params, gases=['NO2'],\n",
    "                                       fit_backgrounds=[False], all_diags=True)\n",
    "\n",
    "res_co2 = ddeq.lcsf.estimate_emissions(data, winds, sources, priors=priors,\n",
    "                                       lcs_params=lcs_params, gases=['CO2'],\n",
    "                                       fit_backgrounds=[True], all_diags=True)\n",
    "\n",
    "res_both = ddeq.lcsf.estimate_emissions(data, winds, sources,\n",
    "                                  lcs_params=lcs_params, gases=['NO2', 'CO2'], priors=priors,\n",
    "                                  fit_backgrounds=[False, True], all_diags=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Printing of the results (Only works for SMARTCARB dataset)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ddeq.lcsf.make_results_table_for_smartcarb(res_both, sources, ['CO2', 'NO2'], data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Plotting results for a given source"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Chosen Source\n",
    "source_name = 'Janschwalde'\n",
    "emi_time = pd.Timestamp(data.time.values)\n",
    "\n",
    "true_emis = {}\n",
    "for gas in ['CO2', 'NO2']:\n",
    "    true_emis[gas] = ddeq.smartcarb.read_true_emissions(emi_time, gas, source_name,\n",
    "                                                   tmin=10, tmax=11).mean()\n",
    "\n",
    "fig = ddeq.vis.plot_lcsf_results(source_name, res_both, data, sources,\n",
    "                                gases=['CO2', 'NO2'], true_emis=true_emis)\n"
   ]
  },
  {
   "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.10.6"
  },
  "toc-autonumbering": true,
  "toc-showmarkdowntxt": false
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
