Skip to content

Instantly share code, notes, and snippets.

@barronh
Last active March 8, 2022 20:35
Show Gist options
  • Save barronh/a25bb894d0882c643948354434e77a25 to your computer and use it in GitHub Desktop.
Save barronh/a25bb894d0882c643948354434e77a25 to your computer and use it in GitHub Desktop.
CSV2CAMxEMIS.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "CSV2CAMxEMIS.ipynb",
"provenance": [],
"authorship_tag": "ABX9TyOezZllLuDmKRPjjQcJ8aME",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/barronh/a25bb894d0882c643948354434e77a25/csv2camxemis.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "boQZJlVphA90",
"colab_type": "text"
},
"source": [
"# CAMx Emissions From CSV\n",
"\n",
"* Create an emissions file from a CSV file.\n",
"* CSV file must have columns\n",
" * lat, lon in decimal degrees,\n",
" * hour in utc (0-23), and\n",
" * and emission variables with units appropriate for CAMx\n",
"* Runs completely in the cloud\n",
" * To completely run with synthetic emissions, choose `Runtime` menu and then `Run all`\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "nmwwKJ1fh0_l",
"colab_type": "text"
},
"source": [
"# Install System Libraries\n",
"\n",
"* Requries libgeos-dev for projections\n",
"* Requries netcdf-bin for ncgen\n",
"* Takes a minute or so"
]
},
{
"cell_type": "code",
"metadata": {
"id": "9YWytCaU-dqk",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 221
},
"outputId": "4156ba71-9712-4b33-ae52-99b07c113207"
},
"source": [
"!apt-get -qq install libgeos-dev\n",
"!apt-get -qq install netcdf-bin"
],
"execution_count": 1,
"outputs": [
{
"output_type": "stream",
"text": [
"Selecting previously unselected package libgeos-dev.\n",
"(Reading database ... 144467 files and directories currently installed.)\n",
"Preparing to unpack .../libgeos-dev_3.6.2-1build2_amd64.deb ...\n",
"Unpacking libgeos-dev (3.6.2-1build2) ...\n",
"Setting up libgeos-dev (3.6.2-1build2) ...\n",
"Processing triggers for man-db (2.8.3-2ubuntu0.1) ...\n",
"Selecting previously unselected package netcdf-bin.\n",
"(Reading database ... 144483 files and directories currently installed.)\n",
"Preparing to unpack .../netcdf-bin_1%3a4.6.0-2build1_amd64.deb ...\n",
"Unpacking netcdf-bin (1:4.6.0-2build1) ...\n",
"Setting up netcdf-bin (1:4.6.0-2build1) ...\n",
"Processing triggers for man-db (2.8.3-2ubuntu0.1) ...\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "P1WY68ae2cAi",
"colab_type": "text"
},
"source": [
"# Install Python Libraries\n",
"\n",
"* `basemap` is used for mapping and projection support, which is installed to support it.\n",
"* `PseudoNetCDF` is installed for IOAPI-like support.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "l8iJqlot_7VQ",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 170
},
"outputId": "9068279b-d3ab-470d-c608-316f565a4dc2"
},
"source": [
"!pip install -q https://github.com/matplotlib/basemap/archive/master.zip\n",
"!pip install -q https://github.com/barronh/pseudonetcdf/archive/master.zip"
],
"execution_count": 2,
"outputs": [
{
"output_type": "stream",
"text": [
"\u001b[K |████████████████████████████████| 133.1MB 70kB/s \n",
"\u001b[K |████████████████████████████████| 10.9MB 7.5MB/s \n",
"\u001b[K |████████████████████████████████| 225kB 47.5MB/s \n",
"\u001b[?25h Building wheel for basemap (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
" Building wheel for pyshp (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
"\u001b[K \\ 2.5MB 1.2MB/s\n",
"\u001b[K |████████████████████████████████| 4.1MB 4.7MB/s \n",
"\u001b[K |████████████████████████████████| 327kB 45.1MB/s \n",
"\u001b[?25h Building wheel for PseudoNetCDF (setup.py) ... \u001b[?25l\u001b[?25hdone\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YwWQoliQ0Rky",
"colab_type": "text"
},
"source": [
"# Import Libraries Used Later\n",
"\n",
"* `google.colab.files` used to download\n",
"* `IPython.display.clear_output` used to animate\n",
"* `time` used to set animation speed\n",
"* `numpy` used for math\n",
"* `pandas` used for csv\n",
"* `PseudoNetCDF` used for ioapi-like support"
]
},
{
"cell_type": "code",
"metadata": {
"id": "0rOHhK3bg76q",
"colab_type": "code",
"colab": {}
},
"source": [
"from google.colab import files\n",
"from IPython.display import clear_output\n",
"import time\n",
"from datetime import datetime\n",
"import numpy as np\n",
"import pandas as pd\n",
"import PseudoNetCDF as pnc"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "qjoDkFY5iYIy",
"colab_type": "text"
},
"source": [
"# Synthetic Data\n",
"\n",
"* Optionally, updload your own data and replace this code with\n",
" * drag file to browser on left\n",
" * set inpath to your file name (e.g., inpath = 'yourfile.csv')\n",
"* If you do not change inpath, this code invents a CSV file\n",
" * It will be a sin wave of NO and NO2 that evovles over time.\n",
" * 90/10 split between NO and No2\n",
"\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "X_BSRATBBybP",
"colab_type": "code",
"colab": {}
},
"source": [
"inpath = None\n",
"if inpath is not None:\n",
" data = pd.read_csv(inpath)\n",
"else:\n",
" lat = (np.sin(np.linspace(0, 2*np.pi, 100)) * 7 + 40).round(2)\n",
" lon = np.linspace(-120, -80, 100)\n",
" hour = np.floor(np.linspace(0, 23.99, 100)).astype('i')\n",
" NO = np.random.lognormal(0.09, sigma=0.1, size=100)\n",
" NO2 = np.random.lognormal(0.01, sigma=0.01, size=100)\n",
" data = pd.DataFrame.from_dict(dict(lat=lat, lon=lon, hour=hour, NO=NO, NO2=NO2))"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "YKtjcPuToSji",
"colab_type": "text"
},
"source": [
"# Separate Meta from Variables\n",
"\n",
"* Make a list of meta variables\n",
"* The emission keys should be all the rest"
]
},
{
"cell_type": "code",
"metadata": {
"id": "UWZX2O6KixPE",
"colab_type": "code",
"colab": {}
},
"source": [
"metakeys = ('lat', 'lon', 'hour')\n",
"emiskeys = [k for k in data.columns if k not in metakeys]"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "rPvWbrwUixyr",
"colab_type": "text"
},
"source": [
"# Create Global Option Dictionary\n",
"\n",
"* I copied meta data from default 36km emissions\n",
"* You can update these however you want\n",
"* SDATE/STIME control the starting time\n",
"* CDATE/WDATE note when it was written\n",
"* NAME, NOTE, FILEDESC are meta variables\n",
"* Other variables define the grid and vertical structure\n",
" * The meanings of parameters are described by IOAPI (link below)\n",
" * grid params: P_ALP, P_BET, P_GAM, XCENT, YCENT, XCELL, YCELL\n",
"\n",
"\n",
"https://www.cmascenter.org/ioapi/documentation/all_versions/html/GRIDS.html"
]
},
{
"cell_type": "code",
"metadata": {
"id": "smspkmOf_jbI",
"colab_type": "code",
"colab": {}
},
"source": [
"wYYYYJJJ = int(datetime.today().strftime('%Y%j'))\n",
"wHHMMSS = int(datetime.today().strftime('%H%M%S'))\n",
"globalprops = {\n",
" 'SDATE': 2020001, 'STIME': 0, 'TSTEP': 10000, 'NSTEPS': 25,\n",
" 'NLAYS': 1, 'NROWS': 91, 'NCOLS': 158, 'NTHIK': 1,\n",
" 'P_ALP': 45., 'P_BET': 33., 'P_GAM': -97.,\n",
" 'XCENT': -97., 'YCENT': 40., 'XCELL': 36000., 'YCELL': 36000.,\n",
" 'XORIG': -2556000., 'YORIG': -1872000.,\n",
" 'VGTYP': 6, 'VGTOP': np.float32(10000.),\n",
" 'VGLVLS': np.float32([0]),\n",
" 'CPROJ': 2, 'GDTYP': 2, 'IUTM': 0,\n",
" 'ISTAG': 0, 'ITZON': 0,\n",
" 'NAME': \"EMISSIONS\", 'NOTE': \"EMISSIONS\", 'FILEDESC': \"EMISSIONS\",\n",
" 'FTYPE': 1, 'GDNAM': \"CAMx v6.50\", 'UPNAM': \"CAMx v6.50\",\n",
" 'CDATE': wYYYYJJJ, 'CTIME': wHHMMSS, 'WDATE': wYYYYJJJ, 'WTIME': wHHMMSS,\n",
" 'NVARS': len(emiskeys),\n",
" 'VAR-LIST': ''.join([k.ljust(16) for k in emiskeys]),\n",
"}"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "ORZt6eGxv4Cc",
"colab_type": "text"
},
"source": [
"# Create File\n",
"\n",
"* Make an ioapi-like file.\n",
"* Add dimensions\n",
"* Add properties"
]
},
{
"cell_type": "code",
"metadata": {
"id": "tbPKeVvTvD2J",
"colab_type": "code",
"colab": {}
},
"source": [
"emisncf = pnc.cmaqfiles.ioapi_base()\n",
"emisncf.createDimension('TSTEP', globalprops['NSTEPS']).setunlimited(True)\n",
"emisncf.createDimension('VAR', globalprops['NVARS'])\n",
"emisncf.createDimension('DATE-TIME', 2)\n",
"emisncf.createDimension('LAY', globalprops['NLAYS'])\n",
"emisncf.createDimension('ROW', globalprops['NROWS'])\n",
"emisncf.createDimension('COL', globalprops['NCOLS'])\n",
"emisncf.setncatts(globalprops)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "9ZCzVoyTwAbA",
"colab_type": "text"
},
"source": [
"# Add meta-variables\n",
"\n",
"* TFLAG is derived from SDATE, STIME and TSTEP\n",
"* X,Y,longitude,latitude are coordinates derived from projection"
]
},
{
"cell_type": "code",
"metadata": {
"id": "YZvqMCLQvGiE",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 51
},
"outputId": "31a433f9-1283-45bb-ad56-a73b3ac6d3e9"
},
"source": [
"# Add TFLAG\n",
"emisncf.updatetflag()\n",
"# Add x/y\n",
"xvar = emisncf.createVariable('X', 'f', ('COL',))\n",
"xvar.units = 'km'\n",
"xvar.long_name = 'X coordinate'\n",
"xvar.var_desc = 'X cartesian distance from projection origin'\n",
"xvar[:] = eval('XORIG + XCELL / 2 + np.arange(NCOLS) * XCELL', None, globalprops) / 1000\n",
"yvar = emisncf.createVariable('Y', 'f', ('ROW',))\n",
"yvar.units = 'km'\n",
"yvar.long_name = 'X coordinate'\n",
"yvar.var_desc = 'X cartesian distance from projection origin'\n",
"yvar[:] = eval('YORIG + YCELL / 2 + np.arange(NROWS) * YCELL', None, globalprops) / 1000\n",
"# Add lon/lat\n",
"I, J = eval('np.meshgrid(np.arange(NCOLS), np.arange(NROWS))', None, globalprops)\n",
"glon, glat = emisncf.ij2ll(I, J)\n",
"lonvar = emisncf.createVariable('longitude', 'f', ('ROW', 'COL'))\n",
"lonvar.units = 'Degrees east'\n",
"lonvar.long_name = 'Longitude'\n",
"lonvar.var_desc = 'Longitude degrees east'\n",
"lonvar.coordinates = 'latitude longitude'\n",
"lonvar[:] = glon\n",
"latvar = emisncf.createVariable('latitude', 'f', ('ROW', 'COL'))\n",
"latvar.units = 'Degrees north'\n",
"latvar.long_name = 'Latitude'\n",
"latvar.var_desc = 'Latitude degrees north'\n",
"latvar.coordinates = 'latitude longitude'\n",
"latvar[:] = glat"
],
"execution_count": 8,
"outputs": [
{
"output_type": "stream",
"text": [
"**PNC:/usr/local/lib/python3.6/dist-packages/PseudoNetCDF/pncwarn.py:24:UserWarning:\n",
" IOAPI_ISPH is assumed to be 6370000.; consistent with WRF\n"
],
"name": "stderr"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "_E-CyZpqwNr2",
"colab_type": "text"
},
"source": [
"# Add Emission Variables\n",
"\n",
"* For each emission key\n",
"* Add those variables with "
]
},
{
"cell_type": "code",
"metadata": {
"id": "pG60py8JvLYL",
"colab_type": "code",
"colab": {}
},
"source": [
"# Create emission variables\n",
"for emiskey in emiskeys:\n",
" var = emisncf.createVariable(emiskey, 'f', ('TSTEP', 'LAY', 'ROW', 'COL'))\n",
" var.long_name = emiskey.ljust(16)[:16]\n",
" var.var_desc='{} emissions'.format(emiskey).ljust(80)[:80]\n",
" var.units='mol hr-1'.ljust(16)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "268gMazypTtv",
"colab_type": "text"
},
"source": [
"# Use file to map lon/lat to Grid I,J\n",
"\n",
"* Python i,j are 0-based indices\n",
"* PseudoNetCDFFile has an ll2ij\n",
"* Using pandas to group and sum\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "-4dZRh2SDBKk",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 51
},
"outputId": "120e2d8c-43f6-4fbd-9f89-0af4f1bb0a00"
},
"source": [
"data['I'], data['J'] = emisncf.ll2ij(data.lon.values, data.lat.values)"
],
"execution_count": 10,
"outputs": [
{
"output_type": "stream",
"text": [
"**PNC:/usr/local/lib/python3.6/dist-packages/PseudoNetCDF/pncwarn.py:24:UserWarning:\n",
" IOAPI_ISPH is assumed to be 6370000.; consistent with WRF\n"
],
"name": "stderr"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "lzmecpmXD2Qx",
"colab_type": "code",
"colab": {}
},
"source": [
"grouped = data.groupby(['I', 'J', 'hour'], as_index=False).sum()"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "jRbvffxrwyBz",
"colab_type": "text"
},
"source": [
"# Add Emissions Variables\n",
"\n",
"* Use hour, I, and J as indices\n",
"* Create a zeros array\n",
"* Write values into zeros array\n",
"* Add array to file variable"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Aai7nJ3aEbUe",
"colab_type": "code",
"colab": {}
},
"source": [
"h = grouped.hour.values\n",
"i = grouped.I.values\n",
"j = grouped.J.values\n",
"nt = emisncf.NSTEPS\n",
"nl = len(emisncf.dimensions['LAY'])\n",
"nr = len(emisncf.dimensions['ROW'])\n",
"nc = len(emisncf.dimensions['COL'])\n",
"for key in emiskeys:\n",
" var = emisncf.variables[key]\n",
" vals = np.zeros((nt, nl, nr, nc), dtype='f')\n",
" vals[h, h*0, j, i] = grouped[key].values\n",
" var[:] = vals\n"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "uO0Gv-m5w9UR",
"colab_type": "text"
},
"source": [
"# Save the File Out\n",
"\n",
"* Start by removing the file (in case you are running again)\n",
"* Save the file\n",
" * Save returns a reference to the output file\n",
" * Closing the output file\n",
"* Note that NAME is not passed through. Name is now a special attribute...\n",
" * Does camx work without NAME?"
]
},
{
"cell_type": "code",
"metadata": {
"id": "FS-4zir_x9ck",
"colab_type": "code",
"colab": {}
},
"source": [
"outpath = 'emis_from_csv.nc'"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "zvmNXcx6mua2",
"colab_type": "code",
"colab": {}
},
"source": [
"!rm -f {outpath}"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "pH6v9ybgo2Jf",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 51
},
"outputId": "dcbd4f06-88f9-4475-eae2-cfdf072a750b"
},
"source": [
"outf = emisncf.save(outpath, verbose=0, format='NETCDF3_64BIT_OFFSET')\n",
"outf.close()"
],
"execution_count": 15,
"outputs": [
{
"output_type": "stream",
"text": [
"/usr/local/lib/python3.6/dist-packages/PseudoNetCDF/pncgen.py:91: UserWarning: Could not add NAME to file; <class 'AttributeError'>: NetCDF: String match to name in use\n",
" warn(\"Could not add %s to file; %s: %s\" % (k, type(e), e))\n"
],
"name": "stderr"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "TcvH62QBxJ_4",
"colab_type": "text"
},
"source": [
"# Visualize Results\n",
"\n",
"* Open the written out file\n",
"* Plot cumulative sums in three hours increments\n",
"* The plot the sum of all hours"
]
},
{
"cell_type": "code",
"metadata": {
"id": "PXtUJDKyUV4S",
"colab_type": "code",
"colab": {}
},
"source": [
"emisncf2 = pnc.pncopen(outpath, format='ioapi', mode='rs')"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "46mGsFWxGNm0",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 360
},
"outputId": "408fb092-2bb2-4723-a12a-55fdd8b04a85"
},
"source": [
"for i in range(1, nt + 3, 3):\n",
" ax = emisncf2.sliceDimensions(TSTEP=slice(0, i)).plot(\n",
" 'NO', dimreduction='sum',\n",
" plot_kw=dict(vmin=0, vmax=1),\n",
" )\n",
" display(ax.figure)\n",
" time.sleep(0.5)\n",
" clear_output(wait=True)\n",
" ax.figure.clf()\n",
"\n",
"ax = emisncf2.plot(\n",
" 'NO',\n",
" plot_kw=dict(vmin=0, vmax=1),\n",
" dimreduction='sum'\n",
")"
],
"execution_count": 17,
"outputs": [
{
"output_type": "stream",
"text": [
"**PNC:/usr/local/lib/python3.6/dist-packages/PseudoNetCDF/pncwarn.py:24:UserWarning:\n",
" IOAPI_ISPH is assumed to be 6370000.; consistent with WRF\n",
"**PNC:/usr/local/lib/python3.6/dist-packages/PseudoNetCDF/pncwarn.py:24:UserWarning:\n",
" IOAPI_ISPH is assumed to be 6370000.; consistent with WRF\n",
"**PNC:/usr/local/lib/python3.6/dist-packages/PseudoNetCDF/pncwarn.py:24:UserWarning:\n",
" IOAPI_ISPH is assumed to be 6370000.; consistent with WRF\n"
],
"name": "stderr"
},
{
"output_type": "display_data",
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 2 Axes>"
]
},
"metadata": {
"tags": [],
"needs_background": "light"
}
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "VaoWdDu-oNKO",
"colab_type": "text"
},
"source": [
"# Now Download Output\n",
"\n",
"* You can browse on the left and right-click and download\n",
"* Or you can run the code cell below"
]
},
{
"cell_type": "code",
"metadata": {
"id": "LPOnKG4AoPqs",
"colab_type": "code",
"colab": {}
},
"source": [
"files.download(outpath)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "w-OW1eIU05ZH",
"colab_type": "code",
"colab": {}
},
"source": [
""
],
"execution_count": 0,
"outputs": []
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment