{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Python-AWIPS Tutorial Notebook"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"\n",
"# Objectives\n",
"\n",
"* Use python-awips to connect to an EDEX server\n",
"* Define and filter the data request specifically for new [CIRA GOES16 data products](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html#additional-documentation)\n",
"* Resize the products to their native resolution\n",
"* Write the individual bands (channels) locally\n",
"* Combine and write the RGB product locally\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Table of Contents\n",
"\n",
"[1 Imports](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html#imports)
\n",
"[2 Initial Setup](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html#initial-setup)
\n",
" [2.1 EDEX Connection](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html#edex-connection)
\n",
" [2.2 Parameter Definition](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html#parameter-definition)
\n",
"[3 Function: set_size()](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html#function-set_size)
\n",
"[4 Function: write_img()](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html#function-write-img)
\n",
"[5 Get the Data and Write it Out!](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html#get-the-data-and-write-it-out)
\n",
" [5.1 Filter the Data](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html#filter-the-data)
\n",
" [5.2 Define Output Location](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html#define-output-location)
\n",
" [5.3 Write Out GOES Images](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html#write-out-goes-images)
\n",
"[6 See Also](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html#see-also)
\n",
" [6.1 Related Notebooks](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html#related-notebooks)
\n",
" [6.2 Additional Documentation](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html#additional-documentation)
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## 1 Imports\n",
"\n",
"The imports below are used throughout the notebook. Note the first import is coming directly from python-awips and allows us to connect to an EDEX server. The subsequent imports are for data manipulation and visualization. "
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"from awips.dataaccess import DataAccessLayer\n",
"import cartopy.crs as ccrs\n",
"import cartopy.feature as cfeat\n",
"import matplotlib.pyplot as plt\n",
"from datetime import datetime\n",
"import numpy as np\n",
"import os"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Top](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html)\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2 Initial Setup\n",
"\n",
"### 2.1 EDEX Connection\n",
"\n",
"First we establish a connection to Unidata's public EDEX server. With that connection made, we can create a [new data request object](http://unidata.github.io/python-awips/api/IDataRequest.html) and set the data type to ***satellite***."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"# Create an EDEX data request\n",
"DataAccessLayer.changeEDEXHost(\"edex-cloud.unidata.ucar.edu\")\n",
"request = DataAccessLayer.newDataRequest()\n",
"request.setDatatype(\"satellite\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.2 Parameter Definition\n",
"\n",
"After establishing the python-awips specific objects, we create a few other parameters that will be used for the data query based off of known values: projection, and extent."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"# Create a projection for ECONUS and WCONUS\n",
"# Set up the projection using known parameters (from the netcdf of GOES products)\n",
"globe = ccrs.Globe(semimajor_axis=6378137.0, semiminor_axis=6356752.5, ellipse=None)\n",
"sat_h = 35785830.0\n",
"proj = ccrs.Geostationary(globe=globe, central_longitude=-75.0, satellite_height=sat_h, sweep_axis='x')\n",
"\n",
"# Define the extents for ECONUS and WCONUS in goes native coords\n",
"# (originally taken from netcdf GOES data)\n",
"extent = (-3626751., 1382263.5, 1583666.1, 4588674.)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Top](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html)\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3 Function: set_size()\n",
"\n",
"Here we're defining a function that will allow us to pass in the dimensions of the output file we desire in pixels. Default Python methods require the size to be set in inches, which is confusing in our case, since we know what the size of GOES images are in pixels. Also, default Python functions add a padding when creating figures, and we don't want that. \n",
"\n",
"This function allows the exact final image to be specified based in pixels, with no padding or buffers."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"def set_size(w,h, plt):\n",
" \"\"\" w, h: width, height in pixels \"\"\"\n",
" \n",
" # Convert from pixels to inches\n",
" DPI = plt.figure().get_dpi()\n",
" w = w/float(DPI)\n",
" h = h/float(DPI)\n",
" \n",
" # Get the axes\n",
" ax=plt.gca()\n",
"\n",
" # Remove the padding\n",
" l = ax.figure.subplotpars.left\n",
" r = ax.figure.subplotpars.right\n",
" t = ax.figure.subplotpars.top\n",
" b = ax.figure.subplotpars.bottom\n",
" figw = float(w)/(r-l)\n",
" figh = float(h)/(t-b)\n",
" \n",
" # Set the final size\n",
" ax.figure.set_size_inches(figw, figh)\n",
" \n",
" # Return the DPI, this is used when in the \n",
" # write_image() function\n",
" return DPI"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Top](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html)\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4 Function: write_img()\n",
"\n",
"Next, we're defining another function which takes the image data, file name, projection, extent, reference time, and whether or not to print out a footnote.\n",
"\n",
"This method specifies the size of the output image and creates a plot object to draw all our data into. Then it draws the GOES data, coastlines, state boundaries, and lat/lon lines onto the image. Additionally, if we want, it writes out a short footnote describing what product we're looking at. Finally, it writes out the figure to disk. \n",
"\n",
"By default we're specifying the output dimensions to be 5000x4000 pixels, because that is the native GOES image size, but feel free to modify these values if you wish to print out an image of another size (you may want to keep the w:h ratio the same though)."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"def write_img(data, name, proj, extent, reftime, footnote):\n",
" \n",
" # Specify the desired size, in pixels\n",
" px_width = 5000.0\n",
" px_height = 3000.0\n",
"\n",
" # Create the plot with proper projection, and set the figure size\n",
" fig = plt.figure()\n",
" DPI = set_size(px_width, px_height, plt)\n",
" ax = plt.axes(projection=proj)\n",
" \n",
" # Draw GOES data\n",
" ax.imshow(data, cmap='gray', transform=proj, extent=extent)\n",
"\n",
" # Add Coastlines and States\n",
" ax.coastlines(resolution='50m', color='magenta', linewidth=1.0)\n",
" ax.add_feature(cfeat.STATES, edgecolor='magenta', linewidth=1.0)\n",
" ax.gridlines(color='cyan', linewidth=2.0, xlocs=np.arange(-180, 180, 10), linestyle=(0,(5,10)))\n",
"\n",
" # Create and draw the footnote if needed\n",
" if footnote: \n",
" footnoteStr = ' CIRA-'+name[7:-4]+'-'+str(reftime)\n",
" plt.annotate(str(footnoteStr), (0,0), (0, 0), xycoords='axes fraction', textcoords='offset points', va='top')\n",
" \n",
" # Write out the figure\n",
" plt.savefig(name, dpi=DPI, bbox_inches='tight', pad_inches=0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Top](https://unidata.github.io/python-awips/examples/generated/GOES_CIRA_Product_Writer.html)\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5 Get the Data and Write it Out!\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 5.1 Filter the Data\n",
"\n",
"Define exactly what data we want to be printing out. This notebook is designed to loop through and print out multiple images, so here we can pick which images we're wanting to print out. We're specifying ***ECONUS*** (for East CONUS), ***CLDSNOW***, ***DBRDUST***, and ***GEOCOLR*** (for the new CIRA products) and the ***three channels*** for the RBG composites."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"