From 858f04e42260ab21fd9e0d8b2ea79006f7eec882 Mon Sep 17 00:00:00 2001 From: alfredhub Date: Mon, 13 Mar 2017 14:13:47 -0400 Subject: [PATCH 01/20] Week 5 lecture uploaded --- Lectures/week_5.ipynb | 458 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 458 insertions(+) create mode 100644 Lectures/week_5.ipynb diff --git a/Lectures/week_5.ipynb b/Lectures/week_5.ipynb new file mode 100644 index 0000000..3b84f88 --- /dev/null +++ b/Lectures/week_5.ipynb @@ -0,0 +1,458 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "![NASA](http://www.nasa.gov/sites/all/themes/custom/nasatwo/images/nasa-logo.svg)\n", + "![DEVELOP](../../../DEVELOP_logo.png)\n", + "\n", + "---\n", + "\n", + "# GDAL\n", + "\n", + "### Goddard Space Flight Center\n", + "\n", + "#### March 13, 2017\n", + "\n", + "---\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# What is GDAL?\n", + "\n", + "---\n", + "\n", + "* __Geospatial Data Abstraction Library__ - A programmatic way to do geoprocessing, providing similar capabilities to those available in ArcGIS\n", + "* Useful for building automated systems, performing repetitive analysis, etc.\n", + "* Developed by Frank Warmerdam, Sean Gilles, et al.\n", + "* Both ArcGIS and QGIS use GDAL \"under the hood\"\n", + "* When people say GDAL, they really mean the GDAL sub-library of the OSGeo (Open Source Geospatial Foundation) package. OSGeo has two sub-libraries:\n", + " * gdal - reading, processing, writing raster data\n", + " * ogr - reading, processing, writing vector data\n", + " * This lecture will only cover gdal, but note that you will need ogr to do anything significant with vector data\n", + "* GDAL has been built to work with several different languages, including Python, R, C, and C++, but some of its most useful capabilities exist as standalone command line tools - essentially, these are their own little programs that can only be started through the command line\n", + " * We will look at both the GDAL Python functions and some of the most useful command line tools\n", + "* [OSGeo site](http://osgeo.org)\n", + "* [GDAL Python reference](http://gdal.org/python/)\n", + "* [GDAL Python tips](https://trac.osgeo.org/gdal/wiki/PythonGotchas)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# GDAL vs. ArcPy - Pros and Cons\n", + "\n", + "---\n", + "\n", + "* GDAL is faster and more accurate\n", + "* GDAL typically provides more flexibility and control\n", + "* Some things can be done in GDAL that simply aren't possible (to my knowledge) in ArcGIS, such as reprojecting between certain coordinate systems\n", + "* GDAL is free and open source\n", + "* However, GDAL is significantly less user-friendly, because:\n", + " * There is no GUI version of the software, like ArcMap for ArcGIS\n", + " * The documentation is primarily written for programmers, and is generally light on explanation\n", + "* To summarize, you can expect a steep learning curve with GDAL, but you will ultimately be able to do some cool stuff" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# Example Project: More fun with MODIS\n", + "\n", + "---\n", + "\n", + "To explore GDAL and allow comparisons between GDAL and ArcPy, we will examine some of the same steps we took in our project last week, namely:\n", + "* Extracting a single subdataset from a MODIS HDF file\n", + "* Opening this data with Python and doing some math\n", + "* Writing the modified data back to disk\n", + "\n", + "We will also perform a new step, which is not possible with ArcGIS: reprojecting the data from its native sinusoidal coordinate system to WGS 1984.\n", + "\n", + "__Important:__ Before beginning this lecture, you should have followed the GDAL installation instructions, available from the root directory of the DEVELOP Python GitHub." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Download data\n", + "\n", + "---\n", + "\n", + "Download this MODIS image: ftp://ladsweb.nascom.nasa.gov/allData/6/MOD11A2/2016/201/MOD11A2.A2016201.h11v05.006.2016242234243.hdf \n", + "\n", + "Copy it to the directory where you want to store your data. You may already have this image from last week's ArcPy lecture.\n", + "\n", + "### Get metadata\n", + "\n", + "---\n", + "\n", + "We want to extract a subdataset from this HDF file, but suppose we don't know what that subdataset is called? Navigate to your working directory, and type the following in the command line:\n", + "\n", + "```> gdalinfo MOD11A2.A2016201.h11v05.006.2016242234243.hdf```\n", + "\n", + "This is a lot of information, but it should look familiar from the HDF/netCDF lecture. If you look closely, you will seen the names and descriptions of each subdataset. For example, the full name of the daytime LST subdataset is ```HDF4_EOS:EOS_GRID:\"MOD11A2.A2016201.h11v05.006.2016242234243.hdf\":MODIS_Grid_8Day_1km_LST:LST_Day_1km```\n", + "\n", + "### Extract subdataset\n", + "\n", + "---\n", + "\n", + "To extract the daytime LST subdataset, we will use one of the most useful GDAL command line tools: ```gdal_translate```. This tool is most commonly used for converting data from one file format to another. If you don't have experience running command line tools, the general format is:\n", + "* Name of tool first\n", + "* Optional parameters specified as ```-OptParam ArgumentForOptParam```\n", + "* Required arguments\n", + "\n", + "In the case of ```gdal_translate```, there are two required arguments: the names of the input and output files. There are also numerous optional arguments that can be used to pack in additional functionality, such as altering the output bit depth and resampling the data. To extract the subdataset, go to your command line and type:\n", + "\n", + "```> gdal_translate HDF4_EOS:EOS_GRID:\"MOD11A2.A2016201.h11v05.006.2016242234243.hdf\":MODIS_Grid_8Day_1km_LST:LST_Day_1km MOD11A2.A2016201.h11v05.006.2016242234243_dayLST.tif```\n", + "\n", + "In this case, we are not using any optional arguments, merely providing the name of the subdataset we care about and an output file name. Now, even with copy/pasting, tab-filling, etc., it would be tedious to do this for numerous images. Let's take a look at how we might call this command from Python, using the ```subprocess``` module." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('Input file size is 1200, 1200\\r\\n0...10...20...30...40...50...60...70...80...90...100 - done.\\r\\n', '')\n" + ] + } + ], + "source": [ + "import subprocess\n", + "import os\n", + "\n", + "#Change system to working directory\n", + "workdir = \"C:\\\\Users\\\\abhubba1\\\\Documents\\\\Python Scripts\\\\DEVELOP_class\"\n", + "os.chdir(workdir)\n", + "\n", + "MODIS_file = \"MOD11A2.A2016201.h11v05.006.2016242234243.hdf\"\n", + "\n", + "#Send gdal_translate command to system shell, capture result, and print it\n", + "dayLST_fname = MODIS_file.rstrip('.hdf')+'_GDAL_dayLST.tif'\n", + "trans_day_cmd = ['gdal_translate', 'HDF4_EOS:EOS_GRID:\"'+MODIS_file+\\\n", + " '\":MODIS_Grid_8Day_1km_LST:LST_Day_1km', dayLST_fname]\n", + "p_trans_day = subprocess.Popen(trans_day_cmd, stdout=subprocess.PIPE, \n", + " stderr=subprocess.PIPE)\n", + "print(p_trans_day.communicate())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ```subprocess.Popen``` takes a list of string arguments that comprise your command. Every separate element of a command should be its own element in this list. Note that this includes the name of an optional parameter and the argument for that parameter.\n", + "\n", + "Optionally, ```subprocess.Popen``` also allows us to capture the ```stdout``` and ```stderr``` streams. These are the output and error streams for programs run in the command line, and contain output messages and errors, respectively. It is common to save these to a text file to view later, but in this case we are just printing them using the ```communicate()``` method.\n", + "\n", + "### Opening raster data in Python\n", + "\n", + "---\n", + "\n", + "We have just covered an example of using GDAL command line tools, and calling those tools from Python. As mentioned above, many of GDAL's most useful capabilities are command line tools such as this, but GDAL also has a Python-specific library that allows us to perform some operations entirely in Python, without sending any commands to the system. In some cases, this Python library duplicates the capabilities of the command line tools, and in that case, it is generally better to use the command line tool, as they tend to be better supported. However, the Python library allows us to do some uniquely cool things, such as opening a raster as a NumPy array." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import os\n", + "\n", + "from osgeo import gdal\n", + "import numpy as np\n", + "\n", + "gdal.UseExceptions()\n", + "\n", + "#Change system to working directory\n", + "workdir = \"C:\\\\Users\\\\abhubba1\\\\Documents\\\\Python Scripts\\\\DEVELOP_class\"\n", + "os.chdir(workdir)\n", + "\n", + "MODIS_file = \"MOD11A2.A2016201.h11v05.006.2016242234243.hdf\"\n", + "dayLST_fname = MODIS_file.rstrip('.hdf')+'_GDAL_dayLST.tif'\n", + "\n", + "#Register driver for this file type\n", + "driver = gdal.GetDriverByName(\"GTiff\")\n", + "driver.Register()\n", + "#Open raster as GDAL dataset\n", + "dayLST_dataset = gdal.Open(dayLST_fname)\n", + "#Get geotransform and projection from GDAL dataset. These contain \n", + "#the geospatial information of the data, and we will need them \n", + "#later to write the array back to a raster file.\n", + "geotrans = dayLST_dataset.GetGeoTransform()\n", + "proj = dayLST_dataset.GetProjection()\n", + "#Open the only band in the dataset. Note that band numbering \n", + "#starts from 1 as far as GDAL is concerned.\n", + "dayLST_band = dayLST_dataset.GetRasterBand(1)\n", + "#Pull data from band into a NumPy array\n", + "dayLST_array = dayLST_band.ReadAsArray()\n", + "#Get the NoData value for this band\n", + "fillval = dayLST_band.GetNoDataValue()\n", + "#Create a new masked array, where all areas of NoData are masked \n", + "#out\n", + "dayLST_ma_array = np.ma.masked_equal(dayLST_array, fillval)\n", + "#Empty band and dataset objects to avoid lock issues later. Be \n", + "#sure to empty the band object first, as there can be problems \n", + "#otherwise.\n", + "dayLST_band = None\n", + "dayLST_dataset = None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There's a lot going on here, so let's unpack it:\n", + "```Python\n", + "#Register driver for this file type\n", + "driver = gdal.GetDriverByName(\"GTiff\")\n", + "driver.Register()\n", + "```\n", + "GDAL has a separate driver for each supported raster format, and it is necessary to register this driver so that GDAL knows how to open a given file. It is also possible to register all drivers at once, but we will need our driver later to write the data to disk, so we want to use ```GetDriverByName```.\n", + "```Python\n", + "#Open raster as GDAL dataset\n", + "dayLST_dataset = gdal.Open(dayLST_fname)\n", + "#Get geotransform and projection from GDAL dataset. These contain \n", + "#the geospatial information of the data, and we will need them \n", + "#later to write the array back to a raster file.\n", + "geotrans = dayLST_dataset.GetGeoTransform()\n", + "proj = dayLST_dataset.GetProjection()\n", + "```\n", + "This first line opens the raster as a GDAL dataset object, which you can think of as the umbrella which encompasses all aspects of a raster, including both metadata and data. After that, we need to retrieve two pieces of metadata, the geotransform and the projection. Opening raster data in a NumPy array is powerful, but NumPy can't store the geospatial information, so we need to keep track of that ourselves.\n", + "```Python\n", + "#Open the only band in the dataset. Note that band numbering \n", + "#starts from 1 as far as GDAL is concerned.\n", + "dayLST_band = dayLST_dataset.GetRasterBand(1)\n", + "#Pull data from band into a NumPy array\n", + "dayLST_array = dayLST_band.ReadAsArray()\n", + "```\n", + "The dataset object contains all of the bands in the dataset, which in this case is only one band. We are retrieving that band and using ```ReadAsArray``` to load it into a NumPy array.\n", + "```Python\n", + "#Get the NoData value for this band\n", + "fillval = dayLST_band.GetNoDataValue()\n", + "#Create a new masked array, where all areas of NoData are masked \n", + "#out\n", + "dayLST_ma_array = np.ma.masked_equal(dayLST_array, fillval)\n", + "```\n", + "Another important piece of metadata is the NoData value. As with the geotransform and projection, we need to keep track of this for writing the data later. However, we also need it now, because we are going to create a NumPy masked array.\n", + "\n", + "A masked array is the same as a normal NumPy array, except it contains a second Boolean array that is used for masking. Any cell that is ```True``` in this Boolean array will be masked in the data, and these masked cells will not be included in any NumPy operations. In this case, we are using ```masked_equal``` to create an array that is masked everywhere the NoData value is present. Now we can do math with this array and not worry about NoData values throwing things off.\n", + "```Python\n", + "#Empty band and dataset objects to avoid lock issues later. Be \n", + "#sure to empty the band object first, as there can be problems \n", + "#otherwise.\n", + "dayLST_band = None\n", + "dayLST_dataset = None\n", + "```\n", + "As was the case when working with ArcPy, leaving the GDAL objects lying around can lead to issues later, as these objects point to the files on disk.\n", + "\n", + "### Raster math\n", + "\n", + "---\n", + "\n", + "Or, more properly, NumPy math. While opening this data as a NumPy array was, let's be honest, a pain in the butt, now we have a NumPy array of our data, and we can do just about anything we want with it. NumPy has an expansive library of mathematical operations - it is called Numerical Python for a reason. For even more possibilities, check out the SciPy library, which is built on top of NumPy.\n", + "\n", + "In the interests of time and continuity with the ArcPy lecture, we will simply rescale the data. As with ArcPy objects, NumPy will automatically apply simple mathematical operations elementwise to the array." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "scale = 0.02\n", + "dayLST_array_sc = dayLST_ma_array * scale" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Writing the array back to a raster\n", + "\n", + "---\n", + "\n", + "After we have manipulated the data to our heart's content, we need to write it back to a raster format. In many ways, this is just the reverse of what we did above to read it into an array." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "gdal.UseExceptions()\n", + "\n", + "#Create new dataset to contain output\n", + "scale_fname = MODIS_file.rstrip('.hdf')+'_GDAL_scale.tif'\n", + "out_dataset = driver.Create(scale_fname, dayLST_array_sc.shape[1], \n", + " dayLST_array_sc.shape[0], eType = gdal.GDT_UInt16)\n", + "#Set geotransform and projection of output dataset\n", + "out_dataset.SetGeoTransform(geotrans)\n", + "out_dataset.SetProjection(proj)\n", + "#Create a band for our data\n", + "out_band = out_dataset.GetRasterBand(1)\n", + "#Write our data to the band\n", + "out_band.WriteArray(dayLST_array_sc)\n", + "#Tell the raster which value signifies NoData\n", + "out_band.SetNoDataValue(fillval)\n", + "#Write the data from memory to disk. Not strictly necessary, as \n", + "#this should occur anyway at some point, but it is good practice.\n", + "out_band.FlushCache()\n", + "#Clear band and dataset to avoid lock problems\n", + "out_band = None\n", + "out_dataset = None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's unpack this one as well:\n", + "```Python\n", + "#Create new dataset to contain output\n", + "scale_fname = MODIS_file.rstrip('.hdf')+'_GDAL_scale.tif'\n", + "out_dataset = driver.Create(scale_fname, dayLST_array_sc.shape[1], \n", + " dayLST_array_sc.shape[0], eType = gdal.GDT_UInt16)\n", + "```\n", + "Here we use our driver object to create a new dataset with the file name, dimensions, and data type of our choosing. Note the data type has to be specified as a ```GDALDataType``` object, the reference for which can be found [here](http://www.gdal.org/gdal_8h.html#a22e22ce0a55036a96f652765793fb7a4).\n", + "```Python\n", + "#Set geotransform and projection of output dataset\n", + "out_dataset.SetGeoTransform(geotrans)\n", + "out_dataset.SetProjection(proj)\n", + "```\n", + "As mentioned above, the NumPy array isn't storing our geospatial metadata, so here we give that information to our new dataset object.\n", + "```Python\n", + "#Create a band for our data\n", + "out_band = out_dataset.GetRasterBand(1)\n", + "#Write our data to the band\n", + "out_band.WriteArray(dayLST_array_sc)\n", + "```\n", + "These lines create a band for the output data, and assign the data to that band. We could create more bands in the same way if we were working with multiband rasters.\n", + "```Python\n", + "#Tell the raster which value signifies NoData\n", + "out_band.SetNoDataValue(fillval)\n", + "```\n", + "A NoData value is just a number unless the raster knows which number signifies NoData. This line provides that information.\n", + "```Python\n", + "#Write the data from memory to disk. Not strictly necessary, as \n", + "#this should occur anyway at some point, but it is good practice.\n", + "out_band.FlushCache()\n", + "```\n", + "Even though we \"wrote\" the array above, this is line that actually writes the data to disk. This should happen anyway when we \"close\" the dataset below, but it is good practice.\n", + "```Python\n", + "#Clear band and dataset to avoid lock problems\n", + "out_band = None\n", + "out_dataset = None\n", + "```\n", + "Clearing out these objects is helpful to avoid lock problems, as mentioned above. You can think of this as \"closing\" the file, from GDAL's perspective.\n", + "\n", + "### Reprojecting raster data\n", + "\n", + "---\n", + "\n", + "Up until this point, we have been duplicating the capabilities of ArcGIS in GDAL. This can be handy because GDAL generally performs things more quickly, more accurately, and provides more control over the process. It is also free, which is nice if you don't have an ArcGIS license. However, you have probably noticed that doing these things in GDAL is, on the surface at least, more complex than doing them with ArcPy. We haven't covered anything where you strictly _need_ GDAL. So, in this last section, we will go over something that strictly requires GDAL: reprojecting data from MODIS sinusoidal to WGS 1984.\n", + "\n", + "To do this, we will be using the extremely powerful ```gdalwarp``` command line tool. In addition to reprojecting, this tool can be used for clipping, masking, resampling, etc., but it is designed around reprojection. To do this from the command line, type:\n", + "```\n", + "> gdalwarp -t_srs \"EPSG:4326\" in_file out_file\n", + "```\n", + "Replace ```in_file``` with the name of our MODIS raster, and replace ```out_file``` with an output file name of your choosing. To call this tool from Python, you would use ```subprocess```, as above:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('0...10...20...30...40...50...60...70...80...90...100 - done.\\r\\n', '')\n" + ] + } + ], + "source": [ + "import subprocess\n", + "import os\n", + "\n", + "#Change system to working directory\n", + "workdir = \"C:\\\\Users\\\\abhubba1\\\\Documents\\\\Python Scripts\\\\DEVELOP_class\"\n", + "os.chdir(workdir)\n", + "\n", + "MODIS_file = \"MOD11A2.A2016201.h11v05.006.2016242234243.hdf\"\n", + "scale_fname = MODIS_file.rstrip('.hdf')+'_GDAL_scale.tif'\n", + "\n", + "#Send gdalwarp command to system shell, capture result, and print it\n", + "reproj_fname = MODIS_file.rstrip('.hdf')+'_GDAL_reproj.tif'\n", + "reproj_cmd = ['gdalwarp', '-t_srs', 'EPSG:4326', scale_fname, reproj_fname]\n", + "p_reproj = subprocess.Popen(reproj_cmd, stdout=subprocess.PIPE, \n", + " stderr=subprocess.PIPE)\n", + "print(p_reproj.communicate())" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} From 1a751e8ecd22b013415cddbe4b84c7d54a5da34a Mon Sep 17 00:00:00 2001 From: Brent Smith Date: Mon, 13 Mar 2017 14:52:01 -0400 Subject: [PATCH 02/20] updated --- Lectures/{ => Week_05}/week_5.ipynb | 30 +++++++---------------------- 1 file changed, 7 insertions(+), 23 deletions(-) rename Lectures/{ => Week_05}/week_5.ipynb (97%) diff --git a/Lectures/week_5.ipynb b/Lectures/Week_05/week_5.ipynb similarity index 97% rename from Lectures/week_5.ipynb rename to Lectures/Week_05/week_5.ipynb index 3b84f88..776cf10 100644 --- a/Lectures/week_5.ipynb +++ b/Lectures/Week_05/week_5.ipynb @@ -135,19 +135,11 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "('Input file size is 1200, 1200\\r\\n0...10...20...30...40...50...60...70...80...90...100 - done.\\r\\n', '')\n" - ] - } - ], + "outputs": [], "source": [ "import subprocess\n", "import os\n", @@ -184,7 +176,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { "collapsed": true }, @@ -290,7 +282,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": { "collapsed": false }, @@ -313,7 +305,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": { "collapsed": false }, @@ -400,19 +392,11 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "('0...10...20...30...40...50...60...70...80...90...100 - done.\\r\\n', '')\n" - ] - } - ], + "outputs": [], "source": [ "import subprocess\n", "import os\n", From bd4ed8a826e67f721369568de04336fa477dccc9 Mon Sep 17 00:00:00 2001 From: alfredhub Date: Mon, 13 Mar 2017 15:28:45 -0400 Subject: [PATCH 03/20] Update week_5.ipynb --- Lectures/Week_05/week_5.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lectures/Week_05/week_5.ipynb b/Lectures/Week_05/week_5.ipynb index 776cf10..1ec5ecb 100644 --- a/Lectures/Week_05/week_5.ipynb +++ b/Lectures/Week_05/week_5.ipynb @@ -9,7 +9,7 @@ }, "source": [ "![NASA](http://www.nasa.gov/sites/all/themes/custom/nasatwo/images/nasa-logo.svg)\n", - "![DEVELOP](../../../DEVELOP_logo.png)\n", + "![DEVELOP](../../DEVELOP_logo.png)\n", "\n", "---\n", "\n", From 4016ec635143e4d3865cc5eb73a25facb045906b Mon Sep 17 00:00:00 2001 From: Brent Smith Date: Mon, 13 Mar 2017 15:39:16 -0400 Subject: [PATCH 04/20] spaces --- Lectures/Week_05/week_5.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lectures/Week_05/week_5.ipynb b/Lectures/Week_05/week_5.ipynb index 776cf10..320e6cb 100644 --- a/Lectures/Week_05/week_5.ipynb +++ b/Lectures/Week_05/week_5.ipynb @@ -103,7 +103,7 @@ "\n", "---\n", "\n", - "Download this MODIS image: ftp://ladsweb.nascom.nasa.gov/allData/6/MOD11A2/2016/201/MOD11A2.A2016201.h11v05.006.2016242234243.hdf \n", + "Download this MODIS image: ftp://ladsweb.nascom.nasa.gov/allData/6/MOD11A2/2016/201/MOD11A2.A2016201.h11v05.006.2016242234243.hdf \n", "\n", "Copy it to the directory where you want to store your data. You may already have this image from last week's ArcPy lecture.\n", "\n", From ed6fdadc71d3fdc9aef81d5ca6eaa30c47319150 Mon Sep 17 00:00:00 2001 From: Brent Smith Date: Mon, 13 Mar 2017 15:42:32 -0400 Subject: [PATCH 05/20] fix --- Lectures/Week_05/week_5.ipynb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lectures/Week_05/week_5.ipynb b/Lectures/Week_05/week_5.ipynb index c04325e..9bd478a 100644 --- a/Lectures/Week_05/week_5.ipynb +++ b/Lectures/Week_05/week_5.ipynb @@ -103,7 +103,8 @@ "\n", "---\n", "\n", - "Download this MODIS image: ftp://ladsweb.nascom.nasa.gov/allData/6/MOD11A2/2016/201/MOD11A2.A2016201.h11v05.006.2016242234243.hdf \n", + "Download this MODIS image: \n", + "ftp://ladsweb.nascom.nasa.gov/allData/6/MOD11A2/2016/201/MOD11A2.A2016201.h11v05.006.2016242234243.hdf \n", "\n", "Copy it to the directory where you want to store your data. You may already have this image from last week's ArcPy lecture.\n", "\n", From c471ebc580870daf03acbb017aba42b4aabdd51b Mon Sep 17 00:00:00 2001 From: alfredhub Date: Thu, 30 Mar 2017 16:21:48 -0400 Subject: [PATCH 06/20] Add files via upload --- Lectures/Week_04/arcpy_demo.py | 61 ++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 Lectures/Week_04/arcpy_demo.py diff --git a/Lectures/Week_04/arcpy_demo.py b/Lectures/Week_04/arcpy_demo.py new file mode 100644 index 0000000..3849aee --- /dev/null +++ b/Lectures/Week_04/arcpy_demo.py @@ -0,0 +1,61 @@ +""" +Author: Alfred Hubbard +Version: 1.0 +Start Date: 3/5/17 +Description: This script demonstrates basic concepts of ArcPy. +""" + +import arcpy + +workdir = "C:\\Users\\abhubba1\\Documents\\Python Scripts\\DEVELOP_class" +arcpy.env.workspace = workdir +arcpy.env.mask = "Virginia.shp" +arcpy.env.overwriteOutput = True + +arcpy.CheckOutExtension("spatial") + +scale = 0.02 +thres = 15 +out_cellsize = 231.6563583 +MODIS_files = ["MOD11A2.A2016017.h11v05.006.2016234002041.hdf", + "MOD11A2.A2016105.h11v05.006.2016242152502.hdf", + "MOD11A2.A2016201.h11v05.006.2016242234243.hdf", + "MOD11A2.A2016289.h11v05.006.2016302010943.hdf"] + +for f in MODIS_files: + + #Extract from HDF + day_LST = f.rstrip(".hdf") + "_dayLST.tif" + arcpy.ExtractSubDataset_management(f, day_LST, subdataset_index=0) + night_LST = f.rstrip(".hdf") + "_nightLST.tif" + arcpy.ExtractSubDataset_management(f, night_LST, subdataset_index=4) + + #Scale + day_LST_sc = arcpy.Raster(day_LST) * scale + night_LST_sc = arcpy.Raster(night_LST) * scale + + #Perform subtraction + diff = day_LST_sc - night_LST_sc + diff.save(f.rstrip(".hdf")+"_diff.tif") + + #Apply conditional + diff_thres = arcpy.sa.Con(diff > thres, 1, 0) + diff_thres.save(f.rstrip(".hdf")+"_thres.tif") + + #Resample + res = f.rstrip(".hdf") + "_res.tif" + arcpy.Resample_management(diff_thres, res, cell_size=out_cellsize) + + #Clear variables to avoid locks + day_LST_sc = None + night_LST_sc = None + diff = None + diff_thres = None + +arcpy.CheckInExtension("spatial") + +#Empty environment settings to prevent them operating on subsequent +#runs in the same Python session +arcpy.env.workspace = None +arcpy.env.overwriteOutput = None +arcpy.env.mask = None \ No newline at end of file From 573ef8026b0f29ac2ba0d411e1dea456d2f04973 Mon Sep 17 00:00:00 2001 From: alfredhub Date: Thu, 30 Mar 2017 16:22:07 -0400 Subject: [PATCH 07/20] Add files via upload --- Lectures/Week_05/gdal_demo.py | 120 ++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 Lectures/Week_05/gdal_demo.py diff --git a/Lectures/Week_05/gdal_demo.py b/Lectures/Week_05/gdal_demo.py new file mode 100644 index 0000000..f785251 --- /dev/null +++ b/Lectures/Week_05/gdal_demo.py @@ -0,0 +1,120 @@ +""" +Author: Alfred Hubbard +Version: 1.0 +Start Date: 3/7/17 +Description: This script demonstrates basic applications of GDAL. +""" + +import subprocess +import os + +import numpy as np +from osgeo import gdal + +workdir = "C:\\Users\\abhubba1\\Documents\\Python Scripts\\DEVELOP_class" +os.chdir(workdir) + +#By default the GDAL Python API does not return errors to the Python +#console; this reverses that setting +gdal.UseExceptions() + +scale = 0.02 +thres = 15 +out_cellsize = '231.6563583' +MODIS_files = ["MOD11A2.A2016017.h11v05.006.2016234002041.hdf", + "MOD11A2.A2016105.h11v05.006.2016242152502.hdf", + "MOD11A2.A2016201.h11v05.006.2016242234243.hdf", + "MOD11A2.A2016289.h11v05.006.2016302010943.hdf"] + +for f in MODIS_files: + + #Extract single subdataset from HDF and save as GeoTIFF + dayLST_fname = f.rstrip('.hdf')+'_GDAL_dayLST.tif' + trans_day_cmd = ['gdal_translate', 'HDF4_EOS:EOS_GRID:"'+f+\ + '":MODIS_Grid_8Day_1km_LST:LST_Day_1km', dayLST_fname] + p_trans_day = subprocess.Popen(trans_day_cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + for line in p_trans_day.communicate(): + print(line) + nightLST_fname = f.rstrip('.hdf')+'_GDAL_nightLST.tif' + trans_night_cmd = ['gdal_translate', 'HDF4_EOS:EOS_GRID:"'+f+\ + '":MODIS_Grid_8Day_1km_LST:LST_Night_1km', + nightLST_fname] + p_trans_night = subprocess.Popen(trans_night_cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + for line in p_trans_night.communicate(): + print(line) + + #Register driver for this file type + driver = gdal.GetDriverByName("GTiff") + driver.Register() + #Open raster as GDAL dataset + dayLST_dataset = gdal.Open(dayLST_fname) + #Get geotransform and projection from GDAL dataset. These contain + #the geospatial information of the data, and we will need them + #later to write the array back to a raster file. + geotrans = dayLST_dataset.GetGeoTransform() + proj = dayLST_dataset.GetProjection() + #Open the only band in the dataset. Note that band numbering + #starts from 1 as far as GDAL is concerned. + dayLST_band = dayLST_dataset.GetRasterBand(1) + #Pull data from band into a NumPy array + dayLST_array = dayLST_band.ReadAsArray() + #Get the NoData value for this band + fillval = dayLST_band.GetNoDataValue() + #Create a new masked array, where all areas of NoData are masked + #out + dayLST_ma_array = np.ma.masked_equal(dayLST_array, fillval) + #Empty band and dataset objects to avoid lock issues later. Be + #sure to empty the band object first, as there can be problems + #otherwise. + dayLST_band = None + dayLST_dataset = None + + nightLST_dataset = gdal.Open(nightLST_fname) + nightLST_band = nightLST_dataset.GetRasterBand(1) + nightLST_array = nightLST_band.ReadAsArray() + nightLST_ma_array = np.ma.masked_equal(nightLST_array, fillval) + nightLST_band = None + nightLST_dataset = None + + #Apply scale factor + dayLST_array_sc = dayLST_ma_array * scale + nightLST_array_sc = nightLST_ma_array * scale + + #Compute difference + diff = dayLST_array_sc - nightLST_array_sc + + #Apply conditional + diff_thres = np.ma.where(diff>thres, 1, 0) + new_fillval = 7 + diff_thres[diff_thres.mask] = new_fillval + + #Create new dataset to contain output + thres_fname = f.rstrip('.hdf')+'_GDAL_thres.tif' + out_dataset = driver.Create(thres_fname, diff_thres.shape[1], + diff_thres.shape[0]) + #Set geotransform and projection of output dataset + out_dataset.SetGeoTransform(geotrans) + out_dataset.SetProjection(proj) + #Create a band for our data + out_band = out_dataset.GetRasterBand(1) + #Write our data to the band + out_band.WriteArray(diff_thres) + #Tell the raster which value signifies NoData + out_band.SetNoDataValue(new_fillval) + #Write the data from memory to disk. Not strictly necessary, as + #this should occur anyway at some point, but it is good practice. + out_band.FlushCache() + #Clear band and dataset to avoid lock problems + out_band = None + out_dataset = None + + #Resample + res_fname = f.rstrip('.hdf')+'_GDAL_res.tif' + res_cmd = ['gdal_translate', '-tr', out_cellsize, out_cellsize, + thres_fname, res_fname] + p_res = subprocess.Popen(res_cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + for line in p_res.communicate(): + print(line) \ No newline at end of file From c5f794f4947f5011add07af41f2bfb38f5e2463a Mon Sep 17 00:00:00 2001 From: Brent Smith Date: Mon, 5 Jun 2017 09:10:55 -0400 Subject: [PATCH 08/20] cleaning --- .../20170215_conda.txt | 0 Archive/Agenda_F2016.md | 25 + err.png => Archive/err.png | Bin .../gdal_instructions_MacLinux.txt | 0 .../gdal_instructions_Win7.txt | 0 Lectures/Week_01/01_intro.ipynb | 2 +- Lectures/Week_02/sample.ipynb | 6 +- Lectures/Week_03/week_3.ipynb | 505 +++++++++++++++--- Lectures/Week_04/Basemap.ipynb | 6 +- Lectures/Week_05/week_5.ipynb | 2 + README.md | 8 +- 11 files changed, 483 insertions(+), 71 deletions(-) rename 20170215_conda.txt => Archive/20170215_conda.txt (100%) create mode 100644 Archive/Agenda_F2016.md rename err.png => Archive/err.png (100%) rename gdal_instructions_MacLinux.txt => Archive/gdal_instructions_MacLinux.txt (100%) rename gdal_instructions_Win7.txt => Archive/gdal_instructions_Win7.txt (100%) diff --git a/20170215_conda.txt b/Archive/20170215_conda.txt similarity index 100% rename from 20170215_conda.txt rename to Archive/20170215_conda.txt diff --git a/Archive/Agenda_F2016.md b/Archive/Agenda_F2016.md new file mode 100644 index 0000000..79960f9 --- /dev/null +++ b/Archive/Agenda_F2016.md @@ -0,0 +1,25 @@ +### Lectures + +* __September 21 (2-5pm)__ - Python Intro + * [Introduction - Python code & the Interpreter (1 hr)](http://github.com/edmondb/developython/blob/master/Lectures/Week_01/01_intro.ipynb) + * [Data Structures (30 min)](http://github.com/edmondb/developython/blob/master/Lectures/Week_01/02_data_structures.ipynb) + +* __September 28 (2-5pm)__ - Python Intro (Part 2) + * [File I/O (30 min)](http://github.com/edmondb/developython/blob/master/Lectures/Week_02/03_FileIO.ipynb) + * [Loops and Conditionals (30 min)](http://github.com/edmondb/developython/blob/master/Lectures/Week_02/04_conditionals_loops.ipynb) + * [numpy (30 min)](http://github.com/edmondb/developython/blob/master/Lectures/Week_02/05_numpy.ipynb) + +* __October 12 (2-3:30pm)__ - Scientific Programming with GDAL + * [matplotlib (30 min)](http://github.com/edmondb/developython/blob/master/Lectures/Week_03/01_matplotlib.ipynb) + * [GDAL (1 hr)](http://github.com/edmondb/developython/blob/master/Lectures/Week_03/gdal/gdal.ipynb) + +* __October 27 (2:30-4pm)__ - Earth Science Data + * [netCDF3/4 (30 min)]() + * [HDF-5 and h5py (30 min)]() + * [Basemap (30 min)]() + +* __Extras__ - Advanced Topics + * arcPy + * Automation + * Multiprocessing + * OOP diff --git a/err.png b/Archive/err.png similarity index 100% rename from err.png rename to Archive/err.png diff --git a/gdal_instructions_MacLinux.txt b/Archive/gdal_instructions_MacLinux.txt similarity index 100% rename from gdal_instructions_MacLinux.txt rename to Archive/gdal_instructions_MacLinux.txt diff --git a/gdal_instructions_Win7.txt b/Archive/gdal_instructions_Win7.txt similarity index 100% rename from gdal_instructions_Win7.txt rename to Archive/gdal_instructions_Win7.txt diff --git a/Lectures/Week_01/01_intro.ipynb b/Lectures/Week_01/01_intro.ipynb index a7a5d4c..e1788a8 100644 --- a/Lectures/Week_01/01_intro.ipynb +++ b/Lectures/Week_01/01_intro.ipynb @@ -563,7 +563,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.11" + "version": "2.7.13" } }, "nbformat": 4, diff --git a/Lectures/Week_02/sample.ipynb b/Lectures/Week_02/sample.ipynb index 70bab38..ce24501 100644 --- a/Lectures/Week_02/sample.ipynb +++ b/Lectures/Week_02/sample.ipynb @@ -931,9 +931,9 @@ "metadata": { "anaconda-cloud": {}, "kernelspec": { - "display_name": "Python [Root]", + "display_name": "Python 2", "language": "python", - "name": "Python [Root]" + "name": "python2" }, "language_info": { "codemirror_mode": { @@ -945,7 +945,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.12" + "version": "2.7.13" } }, "nbformat": 4, diff --git a/Lectures/Week_03/week_3.ipynb b/Lectures/Week_03/week_3.ipynb index 75bd457..badcde9 100644 --- a/Lectures/Week_03/week_3.ipynb +++ b/Lectures/Week_03/week_3.ipynb @@ -45,17 +45,38 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": { "collapsed": false }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAD8CAYAAACMwORRAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAADNNJREFUeJzt3V+MpfVdx/H3x12QWkto3OmfMNCxsQ2lDVQcsZEmIsaE\nAoFWSSRKN6k1G4xWemGo9KKJ8cbL1Yt2syFGGzSbJkLTrLRN7Ra5AKqzZbt0u9ggbv+Qmh2wFqm0\n7Ha/XswhTIczzDkzZ+bsfHm/kpOc8zy/mfP77TP7nmfOnDMnVYUkqZefmvYEJEmTZ9wlqSHjLkkN\nGXdJasi4S1JDxl2SGjLuktSQcZekhoy7JDW0c1p3vGvXrpqbm5vW3UvStnT48OGnqmpmrXFTi/vc\n3BwLCwvTuntJ2paSfHOUcT4sI0kNGXdJasi4S1JDxl2SGjLuktSQcZekhoy7JDU0ctyT7EjySJKD\nQ/bdlORokiNJFpK8e7LTlCSNY5wXMd0OHAfOH7Lvi8BnqqqSXAZ8CrhkAvOTJK3DSGfuSWaB64G7\nhu2vqmfrxXfafjXgu25L0hSN+rDMXuAO4MxqA5K8L8ljwD8Bvz+BuUmS1mnNuCe5AThZVYdfblxV\n3VtVlwDvBf5ilc+1Z/CY/MLi4uK6JixJWtsoZ+5XATcmOQEcAK5Jcvdqg6vqAeDNSXYN2be/quar\nan5mZs0/aiZJWqc1415Vd1bVbFXNAbcAh6rq1uVjkvxCkgyuXwH8NPD0JsxXkjSCdf/J3yS3AVTV\nPuC3gd1JTgHPAb+z7BeskqQtlmk1eH5+vvx77pI0niSHq2p+rXG+QlWSGjLuktSQcZekhoy7JDVk\n3CWpIeMuSQ0Zd0lqyLhLUkPGXZIaMu6S1JBxl6SGjLskNWTcJakh4y5JDRl3SWrIuEtSQ8Zdkhoy\n7pLUkHGXpIaMuyQ1ZNwlqSHjLkkNGXdJasi4S1JDxl2SGjLuktSQcZekhoy7JDVk3CWpIeMuSQ0Z\nd0lqyLhLUkPGXZIaMu6S1JBxl6SGjLskNWTcJakh4y5JDRl3SWpo5Lgn2ZHkkSQHh+z7vSRHkzya\n5MEkl092mpKkcewcY+ztwHHg/CH7/hP4tar6XpL3APuBX5nA/CRJ6zDSmXuSWeB64K5h+6vqwar6\n3uDmw8DsZKYnSVqPUR+W2QvcAZwZYewHgc+ue0aSpA1bM+5JbgBOVtXhEcb+Oktx/8gq+/ckWUiy\nsLi4OPZkJUmjGeXM/SrgxiQngAPANUnuXjkoyWUsPWxzU1U9PewTVdX+qpqvqvmZmZkNTFuS9HLW\njHtV3VlVs1U1B9wCHKqqW5ePSXIxcA/w/qr6xqbMVJI0snGeLfMTktwGUFX7gI8BPwd8PAnA6aqa\nn8gMJUljS1VN5Y7n5+drYWFhKvctSdtVksOjnDz7ClVJasi4S1JDxl2SGjLuktSQcZekhoy7JDVk\n3CWpIeMuSQ0Zd0lqyLhLUkPGXZIaMu6S1JBxl6SGjLskNWTcJakh4y5JDRl3SWrIuEtSQ8Zdkhoy\n7pLUkHGXpIaMuyQ1ZNwlqSHjLkkNGXdJasi4S1JDxl2SGjLuktSQcZekhoy7JDVk3CWpIeMuSQ0Z\nd0lqyLhLUkPGXZIaMu6S1JBxl6SGjLskNWTcJamhkeOeZEeSR5IcHLLvkiQPJflRkj+d7BQlSePa\nOcbY24HjwPlD9v038CfAeycxKWlanucUP+Q0RRHCeezkXM6Z9rSksY105p5kFrgeuGvY/qo6WVX/\nBpya4NykLfU8p3iOUxQFQFE8xyme98ta29CoD8vsBe4AzmziXKSp+iGnx9ounc3WjHuSG4CTVXV4\no3eWZE+ShSQLi4uLG/100kS9cMY+6nbpbDbKmftVwI1JTgAHgGuS3L2eO6uq/VU1X1XzMzMz6/kU\n0qYJGWu7dDZbM+5VdWdVzVbVHHALcKiqbt30mUlb7LxVnl+w2nbpbLbur9oktwFU1b4kbwAWWHom\nzZkkHwYurapnJjNNafO98KwYny2jDsaKe1XdD9w/uL5v2fb/AmYnOTFpGs7lHGOuFnyFqiQ1ZNwl\nqSHjLkkNGXdJasi4S1JDxl2SGjLuktSQcZekhoy7JDVk3CWpIeMuSQ0Zd0lqyLhLUkPGXZIaMu6S\n1JBxl6SGjLskNWTcJakh4y5JDRl3SWrIuEtSQ8Zdkhoy7pLUkHGXpIaMuyQ1ZNwlqSHjLkkNGXdJ\nasi4S1JDxl2SGjLuktSQcZekhoy7JDVk3CWpIeMuSQ0Zd0lqyLhLUkPGXZIaMu6S1JBxl6SGRo57\nkh1JHklycMi+JPnrJI8nOZrkislOU5I0jnHO3G8Hjq+y7z3AWwaXPcAnNjgvSdIGjBT3JLPA9cBd\nqwy5CfhkLXkYuCDJGyc0R0nSmEY9c98L3AGcWWX/hcC3l93+zmDbT0iyJ8lCkoXFxcWxJipJGt2a\ncU9yA3Cyqg5v9M6qan9VzVfV/MzMzEY/nSRpFaOcuV8F3JjkBHAAuCbJ3SvGPAlctOz27GCbJGkK\n1ox7Vd1ZVbNVNQfcAhyqqltXDPsMsHvwrJl3Ad+vqu9OfrqSpFHsXO8HJrkNoKr2AfcB1wGPA/8H\nfGAis5MkrctYca+q+4H7B9f3LdtewB9NcmKSpPXzFaqS1JBxl6SGjLskNWTcJakh4y5JDRl3SWrI\nuEtSQ8Zdkhoy7pLUkHGXpIaMuyQ1ZNwlqSHjLkkNGXdJasi4S1JDxl2SGjLuktSQcZekhoy7JDVk\n3CWpIeMuSQ0Zd0lqyLhLUkPGXZIaMu6S1JBxl6SGjLskNWTcJakh4y5JDRl3SWrIuEtSQ8Zdkhoy\n7pLUkHGXpIaMuyQ1ZNwlqSHjLkkNGXdJasi4S1JDa8Y9yXlJ/jXJV5McS/LnQ8a8Nsm9SY4Oxr5j\nc6YrSRrFKGfuPwKuqarLgXcC1yZ514oxHwWOVNVlwG7gryY7TUnSONaMey15dnDznMGlVgy7FDg0\nGP8YMJfk9ZOcqCRpdCM95p5kR5IjwEngC1X15RVDvgr81mDslcCbgNlJTlSSNLqR4l5VP66qd7IU\n7CuHPKb+l8AFg28AHwIeAX688vMk2ZNkIcnC4uLiBqcuSVrNWM+Wqar/Ab4EXLti+zNV9YHBN4Dd\nwAzwxJCP319V81U1PzMzs4FpS5JezijPlplJcsHg+quA3wQeWzHmgiTnDm7+AfBAVT0z6clKkkaz\nc4QxbwT+LskOlr4ZfKqqDia5DaCq9gFvG4wp4Bjwwc2asCRpbWvGvaqOAr84ZPu+ZdcfAt462alJ\nktbLV6hKUkPGXZIaMu6S1JBxl6SGjLskNWTcJakh4y5JDaVq5R943KI7ThaBb07lzjdmF/DUtCex\nxVxzf6+09cL2XfObqmrNv98ytbhvV0kWqmp+2vPYSq65v1faeqH/mn1YRpIaMu6S1JBxH9/+aU9g\nClxzf6+09ULzNfuYuyQ15Jm7JDVk3IEkFyX5UpKvJzmW5PaXGfvLSU4nuXnZtmuT/HuSx5P82dbM\nemMmsOYTSR5NciTJwtbMemNGWXOSq5N8f7CuI0k+tmxfy+O8xppbHufBuKsH6zqW5F+Wbd92x3mo\nqnrFX1h6Q5IrBtdfA3wDuHTIuB3AIeA+4OZl2/4DeDNwLktvFv6Sjz3bLhtZ82D7CWDXtNcx6TUD\nVwMHV/l3aHmcV1tz8+N8AfB14OLB7ddt5+M87OKZO1BV362qrwyu/y9wHLhwyNAPAf8InFy27Urg\n8ap6oqqeBw4AN23ylDdsg2velsZY8zDdj3MbI675d4F7qupbg3EvfH1vy+M8jHFfIckcS+889eUV\n2y8E3gd8YsWHXAh8e9nt77DN/vOsY80ABfxzksNJ9mz2HCdttTUP/GqSo0k+m+Ttg21tj/PAsDVD\n3+P8VuC1Se4frG33YPu2P84vGOU9VF8xkvwsS2epH66XvsH3XuAjVXUmydZPbpNsYM3vrqonk7wO\n+EKSx6rqgS2Y8oatseavsPSj+rNJrgM+Dbxlq+c4aRtYc9fjvBP4JeA3gFcBDyV5eIunuKmM+0CS\nc1j6Qvj7qrpnyJB54MAgcruA65KcBp4ELlo2bnaw7ay33jVX1aer6klY+nE2yb0s/Th71v+nX2vN\nyyNQVfcl+XiSXTQ+zqutuaqe6nqcWTojf7qqfgD8IMkDwOWD7dvyOL/EtB/0PxsuQIBPAntHHP+3\nvPgL1Z3AE8DP8+IvYN4+7TVt8ppfDbxm2fUHgWunvaZJrBl4Ay++/uNK4FuDj2t7nF9mzZ2P89uA\nLw6O688AXwPesV2P87CLZ+5LrgLeDzya5Mhg20eBiwGqat9qH1hVp5P8MfB5ln7T/jdVdWyT5zsJ\n614z8Hrg3sEZ/U7gH6rqc5s410kZZc03A384+KnsOeCWWqpB5+M8dM1J2h7nqjqe5HPAUeAMcFdV\nfQ1gmx7nl/AVqpLUkM+WkaSGjLskNWTcJakh4y5JDRl3SWrIuEtSQ8Zdkhoy7pLU0P8DlDxC9Prf\nuLQAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", "\n", "#plt.plot(x, y, 'red-circle')\n", - "plt.plot(2.5, 4.1, 'ro')" + "plt.plot(2.5, 4.1, 'o', color='#F0FFF5')" ] }, { @@ -79,15 +100,36 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": { "collapsed": false }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "x = [0,1,2,3,4,5]\n", "y = [1,2,3,4,5,6]\n", - "plt.plot(x, y)" + "plt.plot(x, y, '--')" ] }, { @@ -99,15 +141,36 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "metadata": { "collapsed": false }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\nRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# plot with legend\n", "plt.plot(x, y, label='a line')\n", - "plt.legend(loc=0)" + "plt.legend(loc='upper right')" ] }, { @@ -119,11 +182,32 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "metadata": { "collapsed": false }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\nARzauCD6Tu+nAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "import numpy as np\n", "\n", @@ -135,6 +219,69 @@ "plt.legend()" ] }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-3.14159265 -3.11695271 -3.09231277 -3.06767283 -3.04303288 -3.01839294\n", + " -2.993753 -2.96911306 -2.94447311 -2.91983317 -2.89519323 -2.87055329\n", + " -2.84591335 -2.8212734 -2.79663346 -2.77199352 -2.74735358 -2.72271363\n", + " -2.69807369 -2.67343375 -2.64879381 -2.62415386 -2.59951392 -2.57487398\n", + " -2.55023404 -2.52559409 -2.50095415 -2.47631421 -2.45167427 -2.42703432\n", + " -2.40239438 -2.37775444 -2.3531145 -2.32847456 -2.30383461 -2.27919467\n", + " -2.25455473 -2.22991479 -2.20527484 -2.1806349 -2.15599496 -2.13135502\n", + " -2.10671507 -2.08207513 -2.05743519 -2.03279525 -2.0081553 -1.98351536\n", + " -1.95887542 -1.93423548 -1.90959553 -1.88495559 -1.86031565 -1.83567571\n", + " -1.81103577 -1.78639582 -1.76175588 -1.73711594 -1.712476 -1.68783605\n", + " -1.66319611 -1.63855617 -1.61391623 -1.58927628 -1.56463634 -1.5399964\n", + " -1.51535646 -1.49071651 -1.46607657 -1.44143663 -1.41679669 -1.39215674\n", + " -1.3675168 -1.34287686 -1.31823692 -1.29359698 -1.26895703 -1.24431709\n", + " -1.21967715 -1.19503721 -1.17039726 -1.14575732 -1.12111738 -1.09647744\n", + " -1.07183749 -1.04719755 -1.02255761 -0.99791767 -0.97327772 -0.94863778\n", + " -0.92399784 -0.8993579 -0.87471795 -0.85007801 -0.82543807 -0.80079813\n", + " -0.77615819 -0.75151824 -0.7268783 -0.70223836 -0.67759842 -0.65295847\n", + " -0.62831853 -0.60367859 -0.57903865 -0.5543987 -0.52975876 -0.50511882\n", + " -0.48047888 -0.45583893 -0.43119899 -0.40655905 -0.38191911 -0.35727916\n", + " -0.33263922 -0.30799928 -0.28335934 -0.2587194 -0.23407945 -0.20943951\n", + " -0.18479957 -0.16015963 -0.13551968 -0.11087974 -0.0862398 -0.06159986\n", + " -0.03695991 -0.01231997 0.01231997 0.03695991 0.06159986 0.0862398\n", + " 0.11087974 0.13551968 0.16015963 0.18479957 0.20943951 0.23407945\n", + " 0.2587194 0.28335934 0.30799928 0.33263922 0.35727916 0.38191911\n", + " 0.40655905 0.43119899 0.45583893 0.48047888 0.50511882 0.52975876\n", + " 0.5543987 0.57903865 0.60367859 0.62831853 0.65295847 0.67759842\n", + " 0.70223836 0.7268783 0.75151824 0.77615819 0.80079813 0.82543807\n", + " 0.85007801 0.87471795 0.8993579 0.92399784 0.94863778 0.97327772\n", + " 0.99791767 1.02255761 1.04719755 1.07183749 1.09647744 1.12111738\n", + " 1.14575732 1.17039726 1.19503721 1.21967715 1.24431709 1.26895703\n", + " 1.29359698 1.31823692 1.34287686 1.3675168 1.39215674 1.41679669\n", + " 1.44143663 1.46607657 1.49071651 1.51535646 1.5399964 1.56463634\n", + " 1.58927628 1.61391623 1.63855617 1.66319611 1.68783605 1.712476\n", + " 1.73711594 1.76175588 1.78639582 1.81103577 1.83567571 1.86031565\n", + " 1.88495559 1.90959553 1.93423548 1.95887542 1.98351536 2.0081553\n", + " 2.03279525 2.05743519 2.08207513 2.10671507 2.13135502 2.15599496\n", + " 2.1806349 2.20527484 2.22991479 2.25455473 2.27919467 2.30383461\n", + " 2.32847456 2.3531145 2.37775444 2.40239438 2.42703432 2.45167427\n", + " 2.47631421 2.50095415 2.52559409 2.55023404 2.57487398 2.59951392\n", + " 2.62415386 2.64879381 2.67343375 2.69807369 2.72271363 2.74735358\n", + " 2.77199352 2.79663346 2.8212734 2.84591335 2.87055329 2.89519323\n", + " 2.91983317 2.94447311 2.96911306 2.993753 3.01839294 3.04303288\n", + " 3.06767283 3.09231277 3.11695271 3.14159265]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "x = np.linspace(-np.pi, np.pi, 256, endpoint=True)\n", + "print(x)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -144,40 +291,132 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 46, "metadata": { "collapsed": false }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\ngg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "plt.figure(1)\n", "plt.subplot(211)\n", - "plt.plot(x, cos, color='C0') # notice the color name\n", + "plt.plot(x, cos) # notice the color name\n", + "plt.plot(x, sin)\n", "\n", "plt.subplot(212)\n", - "plt.plot(x, sin, color='C1')" + "plt.plot(x, sin)" ] }, { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---\n", - "\n", - "---\n", - "\n", - "# NOTICE\n", - "\n", - "---\n", - "\n", - "__Run this line from your Anaconda Prompt (March 1, 2017)__\n", - "```bash\n", - "conda update hdf4\n", - "```\n", - "\n", - "---\n", - "\n", - "---" + "cell_type": "code", + "execution_count": 47, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Help on function subplot in module matplotlib.pyplot:\n", + "\n", + "subplot(*args, **kwargs)\n", + " Return a subplot axes positioned by the given grid definition.\n", + " \n", + " Typical call signature::\n", + " \n", + " subplot(nrows, ncols, plot_number)\n", + " \n", + " Where *nrows* and *ncols* are used to notionally split the figure\n", + " into ``nrows * ncols`` sub-axes, and *plot_number* is used to identify\n", + " the particular subplot that this function is to create within the notional\n", + " grid. *plot_number* starts at 1, increments across rows first and has a\n", + " maximum of ``nrows * ncols``.\n", + " \n", + " In the case when *nrows*, *ncols* and *plot_number* are all less than 10,\n", + " a convenience exists, such that the a 3 digit number can be given instead,\n", + " where the hundreds represent *nrows*, the tens represent *ncols* and the\n", + " units represent *plot_number*. For instance::\n", + " \n", + " subplot(211)\n", + " \n", + " produces a subaxes in a figure which represents the top plot (i.e. the\n", + " first) in a 2 row by 1 column notional grid (no grid actually exists,\n", + " but conceptually this is how the returned subplot has been positioned).\n", + " \n", + " .. note::\n", + " \n", + " Creating a new subplot with a position which is entirely inside a\n", + " pre-existing axes will trigger the larger axes to be deleted::\n", + " \n", + " import matplotlib.pyplot as plt\n", + " # plot a line, implicitly creating a subplot(111)\n", + " plt.plot([1,2,3])\n", + " # now create a subplot which represents the top plot of a grid\n", + " # with 2 rows and 1 column. Since this subplot will overlap the\n", + " # first, the plot (and its axes) previously created, will be removed\n", + " plt.subplot(211)\n", + " plt.plot(range(12))\n", + " plt.subplot(212, facecolor='y') # creates 2nd subplot with yellow background\n", + " \n", + " If you do not want this behavior, use the\n", + " :meth:`~matplotlib.figure.Figure.add_subplot` method or the\n", + " :func:`~matplotlib.pyplot.axes` function instead.\n", + " \n", + " Keyword arguments:\n", + " \n", + " *facecolor*:\n", + " The background color of the subplot, which can be any valid\n", + " color specifier. See :mod:`matplotlib.colors` for more\n", + " information.\n", + " \n", + " *polar*:\n", + " A boolean flag indicating whether the subplot plot should be\n", + " a polar projection. Defaults to *False*.\n", + " \n", + " *projection*:\n", + " A string giving the name of a custom projection to be used\n", + " for the subplot. This projection must have been previously\n", + " registered. See :mod:`matplotlib.projections`.\n", + " \n", + " .. seealso::\n", + " \n", + " :func:`~matplotlib.pyplot.axes`\n", + " For additional information on :func:`axes` and\n", + " :func:`subplot` keyword arguments.\n", + " \n", + " :file:`examples/pie_and_polar_charts/polar_scatter_demo.py`\n", + " For an example\n", + " \n", + " **Example:**\n", + " \n", + " .. plot:: mpl_examples/subplots_axes_and_figures/subplot_demo.py\n", + "\n" + ] + } + ], + "source": [ + "help(plt.subplot)" ] }, { @@ -202,7 +441,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 48, "metadata": { "collapsed": false }, @@ -210,13 +449,13 @@ "source": [ "import netCDF4 as nc\n", "\n", - "f = nc.Dataset('test.nc', 'w')\n", + "f = nc.Dataset('test.nc4', 'w')\n", "f.close()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 49, "metadata": { "collapsed": true }, @@ -268,14 +507,14 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 51, "metadata": { - "collapsed": true + "collapsed": false }, "outputs": [], "source": [ "# netCDF\n", - "rootgrp = nc.Dataset('test.nc', 'a')\n", + "rootgrp = nc.Dataset('test.nc4', 'a')\n", "fcstgrp = rootgrp.createGroup('forecasts')\n", "anlgrp = rootgrp.createGroup('analyses')\n", "\n", @@ -288,7 +527,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 52, "metadata": { "collapsed": true }, @@ -308,24 +547,54 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 55, "metadata": { "collapsed": false }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "root group (NETCDF4 data model, file format HDF5):\n", + " dimensions(sizes): \n", + " variables(dimensions): \n", + " groups: forecasts, analyses\n", + "\n", + "\n", + "\n", + "OrderedDict([(u'forecasts', \n", + "group /forecasts:\n", + " dimensions(sizes): \n", + " variables(dimensions): \n", + " groups: model1, model2\n", + "), (u'analyses', \n", + "group /analyses:\n", + " dimensions(sizes): \n", + " variables(dimensions): \n", + " groups: \n", + ")])\n", + "\n", + "\n", + "\n", + "[u'analyses', u'forecasts']\n" + ] + } + ], "source": [ "# let's look inside these:\n", - "f = nc.Dataset('test.nc', 'r')\n", + "f = nc.Dataset('test.nc4', 'r')\n", "print(f)\n", - "#print('\\n')\n", - "#print(f.groups)\n", + "print('\\n')\n", + "print(f.groups)\n", "f.close()\n", "\n", "print('\\n')\n", "\n", "f = h5.File('test.h5', 'r')\n", "print(f)\n", - "#print(f.keys())\n", + "print(f.keys())\n", "f.close()" ] }, @@ -338,14 +607,14 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 57, "metadata": { - "collapsed": true + "collapsed": false }, "outputs": [], "source": [ "# netCDF (netCDF3 can only have 1 unlimmited dimension)\n", - "rootgrp = nc.Dataset('test.nc', 'a')\n", + "rootgrp = nc.Dataset('test.nc4', 'a')\n", "level = rootgrp.createDimension('level', None) # or 0\n", "time = rootgrp.createDimension('time', None) # or 0\n", "lat = rootgrp.createDimension('lat', 73)\n", @@ -366,14 +635,26 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 59, "metadata": { "collapsed": false }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "OrderedDict([(u'level', (unlimited): name = 'level', size = 0\n", + "), (u'time', (unlimited): name = 'time', size = 0\n", + "), (u'lat', : name = 'lat', size = 73\n", + "), (u'lon', : name = 'lon', size = 144\n", + ")])\n" + ] + } + ], "source": [ "# let's look inside these:\n", - "f = nc.Dataset('test.nc', 'r')\n", + "f = nc.Dataset('test.nc4', 'r')\n", "print(f.dimensions)\n", "f.close()" ] @@ -387,7 +668,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 60, "metadata": { "collapsed": true }, @@ -399,14 +680,14 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 61, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# netCDF\n", - "rootgrp = nc.Dataset('test.nc', 'a')\n", + "rootgrp = nc.Dataset('test.nc4', 'a')\n", "times = rootgrp.createVariable('time', 'f8', ('time',))\n", "levels = rootgrp.createVariable('level', 'i4', ('level',))\n", "latitudes = rootgrp.createVariable('latitude', 'f4', ('lat',))\n", @@ -424,7 +705,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 62, "metadata": { "collapsed": true }, @@ -441,14 +722,31 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 64, "metadata": { "collapsed": false }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[u'time', u'level', u'latitude', u'longitude', u'temp']\n", + "[[ 0.41015527 0.40631986 0.10267066 0.93808627]\n", + " [ 0.47038493 0.55063295 0.91086882 0.52334672]\n", + " [ 0.27892506 0.48110983 0.4794006 0.95779741]\n", + " [ 0.72449797 0.19362372 0.81611872 0.01212891]]\n", + "\n", + "[[ 0.49607593 0.88358039 0.81215775 0.99389112]\n", + " [ 0.51340181 0.61961353 0.93530029 0.74421412]\n", + " [ 0.53950232 0.62176359 0.27123785 0.41296488]\n", + " [ 0.17852955 0.70025551 0.62833965 0.86961234]]\n" + ] + } + ], "source": [ "# let's look inside these:\n", - "rootgrp = nc.Dataset('test.nc', 'a')\n", + "rootgrp = nc.Dataset('test.nc4', 'a')\n", "print(rootgrp.variables.keys())\n", "print(rootgrp.variables['temp'][0,0,[0,1,2,3],[0,1,2,3]])\n", "rootgrp.close()\n", @@ -469,6 +767,93 @@ "\n", "This is just the metadata for the variables/groups." ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "f = nc.Dataset('/Users/ebsmith2/Downloads/GEOS.fp.fcst.inst1_2d_hwl_Nx.20170301_12+20170301_1000.V01.nc4', 'r')" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "root group (NETCDF4 data model, file format HDF5):\n", + " Title: 2d,1-Hourly,Instantaneous,Single-Level,Forecast,Hyperwall\n", + " History: File written by MAPL_CFIO\n", + " Source: GEOSadas-5_16_5_OPS\n", + " Contact: http://gmao.gsfc.nasa.gov\n", + " Conventions: CF\n", + " Institution: NASA Global Modeling and Assimilation Office\n", + " References: see MAPL documentation\n", + " Filename: GEOS.fp.fcst.inst1_2d_hwl_Nx.20170301_12+20170301_1000.V01.nc4\n", + " Comment: NetCDF-4\n", + " dimensions(sizes): lon(1152), lat(721), time(1)\n", + " variables(dimensions): float64 \u001b[4mlon\u001b[0m(lon), float64 \u001b[4mlat\u001b[0m(lat), int32 \u001b[4mtime\u001b[0m(time), float32 \u001b[4mBCCMASS\u001b[0m(time,lat,lon), float32 \u001b[4mBCEXTTAU\u001b[0m(time,lat,lon), float32 \u001b[4mBCFLUXU\u001b[0m(time,lat,lon), float32 \u001b[4mBCFLUXV\u001b[0m(time,lat,lon), float32 \u001b[4mBCSMASS\u001b[0m(time,lat,lon), float32 \u001b[4mCFC12strat\u001b[0m(time,lat,lon), float32 \u001b[4mCFC12trop\u001b[0m(time,lat,lon), float32 \u001b[4mCO2CL\u001b[0m(time,lat,lon), float32 \u001b[4mCOCL\u001b[0m(time,lat,lon), float32 \u001b[4mCOCLbbae\u001b[0m(time,lat,lon), float32 \u001b[4mCOCLbbaf\u001b[0m(time,lat,lon), float32 \u001b[4mCOCLbbgl\u001b[0m(time,lat,lon), float32 \u001b[4mCOCLbbla\u001b[0m(time,lat,lon), float32 \u001b[4mCOCLbbna\u001b[0m(time,lat,lon), float32 \u001b[4mCOCLnbas\u001b[0m(time,lat,lon), float32 \u001b[4mCOCLnbeu\u001b[0m(time,lat,lon), float32 \u001b[4mCOCLnbgl\u001b[0m(time,lat,lon), float32 \u001b[4mCOCLnbna\u001b[0m(time,lat,lon), float32 \u001b[4mCOSC\u001b[0m(time,lat,lon), float32 \u001b[4mDUCMASS\u001b[0m(time,lat,lon), float32 \u001b[4mDUEXTTAU\u001b[0m(time,lat,lon), float32 \u001b[4mDUFLUXU\u001b[0m(time,lat,lon), float32 \u001b[4mDUFLUXV\u001b[0m(time,lat,lon), float32 \u001b[4mDUSMASS\u001b[0m(time,lat,lon), float32 \u001b[4mDUSMASS25\u001b[0m(time,lat,lon), float32 \u001b[4mNISMASS\u001b[0m(time,lat,lon), float32 \u001b[4mNISMASS25\u001b[0m(time,lat,lon), float32 \u001b[4mOCCMASS\u001b[0m(time,lat,lon), float32 \u001b[4mOCEXTTAU\u001b[0m(time,lat,lon), float32 \u001b[4mOCFLUXU\u001b[0m(time,lat,lon), float32 \u001b[4mOCFLUXV\u001b[0m(time,lat,lon), float32 \u001b[4mOCSMASS\u001b[0m(time,lat,lon), float32 \u001b[4mSLP\u001b[0m(time,lat,lon), float32 \u001b[4mSO2CMASS\u001b[0m(time,lat,lon), float32 \u001b[4mSO2SMASS\u001b[0m(time,lat,lon), float32 \u001b[4mSO4CMASS\u001b[0m(time,lat,lon), float32 \u001b[4mSO4SMASS\u001b[0m(time,lat,lon), float32 \u001b[4mSSCMASS\u001b[0m(time,lat,lon), float32 \u001b[4mSSEXTTAU\u001b[0m(time,lat,lon), float32 \u001b[4mSSFLUXU\u001b[0m(time,lat,lon), float32 \u001b[4mSSFLUXV\u001b[0m(time,lat,lon), float32 \u001b[4mSSSMASS\u001b[0m(time,lat,lon), float32 \u001b[4mSSSMASS25\u001b[0m(time,lat,lon), float32 \u001b[4mSUEXTTAU\u001b[0m(time,lat,lon), float32 \u001b[4mSUFLUXU\u001b[0m(time,lat,lon), float32 \u001b[4mSUFLUXV\u001b[0m(time,lat,lon), float32 \u001b[4mTO3\u001b[0m(time,lat,lon), float32 \u001b[4mTOTANGSTR\u001b[0m(time,lat,lon), float32 \u001b[4mTOTEXTTAU\u001b[0m(time,lat,lon), float32 \u001b[4mTOTSCATAU\u001b[0m(time,lat,lon)\n", + " groups: " + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "f" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.imshow(f.variables['SLP'][0][::-1], cmap='jet')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/Lectures/Week_04/Basemap.ipynb b/Lectures/Week_04/Basemap.ipynb index 25445ce..b005c62 100644 --- a/Lectures/Week_04/Basemap.ipynb +++ b/Lectures/Week_04/Basemap.ipynb @@ -134,9 +134,9 @@ "metadata": { "anaconda-cloud": {}, "kernelspec": { - "display_name": "Python [conda root]", + "display_name": "Python 2", "language": "python", - "name": "conda-root-py" + "name": "python2" }, "language_info": { "codemirror_mode": { @@ -148,7 +148,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.12" + "version": "2.7.13" } }, "nbformat": 4, diff --git a/Lectures/Week_05/week_5.ipynb b/Lectures/Week_05/week_5.ipynb index 9bd478a..f819e76 100644 --- a/Lectures/Week_05/week_5.ipynb +++ b/Lectures/Week_05/week_5.ipynb @@ -114,6 +114,8 @@ "\n", "We want to extract a subdataset from this HDF file, but suppose we don't know what that subdataset is called? Navigate to your working directory, and type the following in the command line:\n", "\n", + "> gdalinfo MOD11A2.A2016201.h11v05.006.2016242234243.hdf\n", + "\n", "```> gdalinfo MOD11A2.A2016201.h11v05.006.2016242234243.hdf```\n", "\n", "This is a lot of information, but it should look familiar from the HDF/netCDF lecture. If you look closely, you will seen the names and descriptions of each subdataset. For example, the full name of the daytime LST subdataset is ```HDF4_EOS:EOS_GRID:\"MOD11A2.A2016201.h11v05.006.2016242234243.hdf\":MODIS_Grid_8Day_1km_LST:LST_Day_1km```\n", diff --git a/README.md b/README.md index d22c7d9..fb68d8e 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # developython + +![logo](DEVELOP_logo.png) + Python Training for the DEVELOP program. # Setup Instructions 1. [Download](https://www.continuum.io/downloads) and install __Anaconda for Windows 32-Bit (Python 2.7)__ 2. Do not make it your default Python (possible conflicts with other Python versions or if using arcPy). -3. After installing Anaconda, copy `C:\Python27\ArcGIS10.x\Lib\site-packages\Desktop10.x.pth` to `C:\Users\`__username__`\AppData\Local\Continuum\Anaconda2\Lib\site_packages\`. Note that AppData is a hidden folder, so you must either enable Windows Explorer to show hidden folders or type in the path by hand to the navigation bar of Windows Explorer. +3. After installing Anaconda, copy `C:\Python27\ArcGIS10.x\Lib\site-packages\Desktop10.x.pth` to (replace __username__ here) `C:\Users\`__username__`\AppData\Local\Continuum\Anaconda2\Lib\site_packages\`. Note that AppData is a hidden folder, so you must either enable Windows Explorer to show hidden folders or type in the path by hand to the navigation bar of Windows Explorer. 4. Start -> All Programs -> Anaconda 2 (32-Bit) -> Anaconda Prompt -5. `conda update conda` -6. `conda install netCDF4` -7. Follow [GDAL setup instructions](https://github.com/edmondb/developython/blob/master/gdal_instructions_Win7.txt) for Windows. From f8af84d5681e7eba6058c1be6054bfe3f571e86b Mon Sep 17 00:00:00 2001 From: Brent Smith Date: Mon, 5 Jun 2017 09:11:24 -0400 Subject: [PATCH 09/20] fancy --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index fb68d8e..ab6e34c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ -# developython - ![logo](DEVELOP_logo.png) - +--- Python Training for the DEVELOP program. # Setup Instructions From c5099b625938b34ca55c2498a234cc083c6ce1b0 Mon Sep 17 00:00:00 2001 From: Brent Smith Date: Mon, 5 Jun 2017 09:45:34 -0400 Subject: [PATCH 10/20] archive and week 1 start --- .../Lectures_201702}/Week_01/01_intro.ipynb | 0 .../Week_01/02_data_structures.ipynb | 0 .../Lectures_201702}/Week_01/helloworld.py | 0 .../Lectures_201702}/Week_01/readme.md | 0 .../Lectures_201702}/Week_01/week_1.ipynb | 0 .../Lectures_201702}/Week_02/03_FileIO.ipynb | 0 .../Week_02/04_conditionals_loops.ipynb | 0 .../Lectures_201702}/Week_02/05_numpy.ipynb | 0 .../Lectures_201702}/Week_02/sample.csv | 0 .../Lectures_201702}/Week_02/sample.ipynb | 0 .../Lectures_201702}/Week_02/week_2.ipynb | 0 .../Week_03/01_matplotlib.ipynb | 0 .../Week_03/gdal/array2raster.py | 0 .../Lectures_201702}/Week_03/gdal/gdal.ipynb | 0 .../Week_03/gdal/gdal_commands.txt | 0 .../Week_03/gdal/gdal_example.py | 0 .../Lectures_201702}/Week_03/week_3.ipynb | 0 .../Lectures_201702}/Week_04/Basemap.ipynb | 0 .../Lectures_201702}/Week_04/HDF.ipynb | 0 .../Lectures_201702}/Week_04/arcpy_demo.py | 0 .../Lectures_201702}/Week_04/week_4.ipynb | 0 .../Lectures_201702}/Week_05/gdal_demo.py | 0 .../Lectures_201702}/Week_05/week_5.ipynb | 0 .../Lectures_201702}/readme.md | 0 Lectures_201706/Week_01/helloworld.py | 3 + Lectures_201706/Week_01/readme.md | 1 + Lectures_201706/Week_01/setup_intro.ipynb | 313 ++++++++++++++++++ 27 files changed, 317 insertions(+) rename {Lectures => Archive/Lectures_201702}/Week_01/01_intro.ipynb (100%) rename {Lectures => Archive/Lectures_201702}/Week_01/02_data_structures.ipynb (100%) rename {Lectures => Archive/Lectures_201702}/Week_01/helloworld.py (100%) rename {Lectures => Archive/Lectures_201702}/Week_01/readme.md (100%) rename {Lectures => Archive/Lectures_201702}/Week_01/week_1.ipynb (100%) rename {Lectures => Archive/Lectures_201702}/Week_02/03_FileIO.ipynb (100%) rename {Lectures => Archive/Lectures_201702}/Week_02/04_conditionals_loops.ipynb (100%) rename {Lectures => Archive/Lectures_201702}/Week_02/05_numpy.ipynb (100%) rename {Lectures => Archive/Lectures_201702}/Week_02/sample.csv (100%) rename {Lectures => Archive/Lectures_201702}/Week_02/sample.ipynb (100%) rename {Lectures => Archive/Lectures_201702}/Week_02/week_2.ipynb (100%) rename {Lectures => Archive/Lectures_201702}/Week_03/01_matplotlib.ipynb (100%) rename {Lectures => Archive/Lectures_201702}/Week_03/gdal/array2raster.py (100%) rename {Lectures => Archive/Lectures_201702}/Week_03/gdal/gdal.ipynb (100%) rename {Lectures => Archive/Lectures_201702}/Week_03/gdal/gdal_commands.txt (100%) rename {Lectures => Archive/Lectures_201702}/Week_03/gdal/gdal_example.py (100%) rename {Lectures => Archive/Lectures_201702}/Week_03/week_3.ipynb (100%) rename {Lectures => Archive/Lectures_201702}/Week_04/Basemap.ipynb (100%) rename {Lectures => Archive/Lectures_201702}/Week_04/HDF.ipynb (100%) rename {Lectures => Archive/Lectures_201702}/Week_04/arcpy_demo.py (100%) rename {Lectures => Archive/Lectures_201702}/Week_04/week_4.ipynb (100%) rename {Lectures => Archive/Lectures_201702}/Week_05/gdal_demo.py (100%) rename {Lectures => Archive/Lectures_201702}/Week_05/week_5.ipynb (100%) rename {Lectures => Archive/Lectures_201702}/readme.md (100%) create mode 100644 Lectures_201706/Week_01/helloworld.py create mode 100644 Lectures_201706/Week_01/readme.md create mode 100644 Lectures_201706/Week_01/setup_intro.ipynb diff --git a/Lectures/Week_01/01_intro.ipynb b/Archive/Lectures_201702/Week_01/01_intro.ipynb similarity index 100% rename from Lectures/Week_01/01_intro.ipynb rename to Archive/Lectures_201702/Week_01/01_intro.ipynb diff --git a/Lectures/Week_01/02_data_structures.ipynb b/Archive/Lectures_201702/Week_01/02_data_structures.ipynb similarity index 100% rename from Lectures/Week_01/02_data_structures.ipynb rename to Archive/Lectures_201702/Week_01/02_data_structures.ipynb diff --git a/Lectures/Week_01/helloworld.py b/Archive/Lectures_201702/Week_01/helloworld.py similarity index 100% rename from Lectures/Week_01/helloworld.py rename to Archive/Lectures_201702/Week_01/helloworld.py diff --git a/Lectures/Week_01/readme.md b/Archive/Lectures_201702/Week_01/readme.md similarity index 100% rename from Lectures/Week_01/readme.md rename to Archive/Lectures_201702/Week_01/readme.md diff --git a/Lectures/Week_01/week_1.ipynb b/Archive/Lectures_201702/Week_01/week_1.ipynb similarity index 100% rename from Lectures/Week_01/week_1.ipynb rename to Archive/Lectures_201702/Week_01/week_1.ipynb diff --git a/Lectures/Week_02/03_FileIO.ipynb b/Archive/Lectures_201702/Week_02/03_FileIO.ipynb similarity index 100% rename from Lectures/Week_02/03_FileIO.ipynb rename to Archive/Lectures_201702/Week_02/03_FileIO.ipynb diff --git a/Lectures/Week_02/04_conditionals_loops.ipynb b/Archive/Lectures_201702/Week_02/04_conditionals_loops.ipynb similarity index 100% rename from Lectures/Week_02/04_conditionals_loops.ipynb rename to Archive/Lectures_201702/Week_02/04_conditionals_loops.ipynb diff --git a/Lectures/Week_02/05_numpy.ipynb b/Archive/Lectures_201702/Week_02/05_numpy.ipynb similarity index 100% rename from Lectures/Week_02/05_numpy.ipynb rename to Archive/Lectures_201702/Week_02/05_numpy.ipynb diff --git a/Lectures/Week_02/sample.csv b/Archive/Lectures_201702/Week_02/sample.csv similarity index 100% rename from Lectures/Week_02/sample.csv rename to Archive/Lectures_201702/Week_02/sample.csv diff --git a/Lectures/Week_02/sample.ipynb b/Archive/Lectures_201702/Week_02/sample.ipynb similarity index 100% rename from Lectures/Week_02/sample.ipynb rename to Archive/Lectures_201702/Week_02/sample.ipynb diff --git a/Lectures/Week_02/week_2.ipynb b/Archive/Lectures_201702/Week_02/week_2.ipynb similarity index 100% rename from Lectures/Week_02/week_2.ipynb rename to Archive/Lectures_201702/Week_02/week_2.ipynb diff --git a/Lectures/Week_03/01_matplotlib.ipynb b/Archive/Lectures_201702/Week_03/01_matplotlib.ipynb similarity index 100% rename from Lectures/Week_03/01_matplotlib.ipynb rename to Archive/Lectures_201702/Week_03/01_matplotlib.ipynb diff --git a/Lectures/Week_03/gdal/array2raster.py b/Archive/Lectures_201702/Week_03/gdal/array2raster.py similarity index 100% rename from Lectures/Week_03/gdal/array2raster.py rename to Archive/Lectures_201702/Week_03/gdal/array2raster.py diff --git a/Lectures/Week_03/gdal/gdal.ipynb b/Archive/Lectures_201702/Week_03/gdal/gdal.ipynb similarity index 100% rename from Lectures/Week_03/gdal/gdal.ipynb rename to Archive/Lectures_201702/Week_03/gdal/gdal.ipynb diff --git a/Lectures/Week_03/gdal/gdal_commands.txt b/Archive/Lectures_201702/Week_03/gdal/gdal_commands.txt similarity index 100% rename from Lectures/Week_03/gdal/gdal_commands.txt rename to Archive/Lectures_201702/Week_03/gdal/gdal_commands.txt diff --git a/Lectures/Week_03/gdal/gdal_example.py b/Archive/Lectures_201702/Week_03/gdal/gdal_example.py similarity index 100% rename from Lectures/Week_03/gdal/gdal_example.py rename to Archive/Lectures_201702/Week_03/gdal/gdal_example.py diff --git a/Lectures/Week_03/week_3.ipynb b/Archive/Lectures_201702/Week_03/week_3.ipynb similarity index 100% rename from Lectures/Week_03/week_3.ipynb rename to Archive/Lectures_201702/Week_03/week_3.ipynb diff --git a/Lectures/Week_04/Basemap.ipynb b/Archive/Lectures_201702/Week_04/Basemap.ipynb similarity index 100% rename from Lectures/Week_04/Basemap.ipynb rename to Archive/Lectures_201702/Week_04/Basemap.ipynb diff --git a/Lectures/Week_04/HDF.ipynb b/Archive/Lectures_201702/Week_04/HDF.ipynb similarity index 100% rename from Lectures/Week_04/HDF.ipynb rename to Archive/Lectures_201702/Week_04/HDF.ipynb diff --git a/Lectures/Week_04/arcpy_demo.py b/Archive/Lectures_201702/Week_04/arcpy_demo.py similarity index 100% rename from Lectures/Week_04/arcpy_demo.py rename to Archive/Lectures_201702/Week_04/arcpy_demo.py diff --git a/Lectures/Week_04/week_4.ipynb b/Archive/Lectures_201702/Week_04/week_4.ipynb similarity index 100% rename from Lectures/Week_04/week_4.ipynb rename to Archive/Lectures_201702/Week_04/week_4.ipynb diff --git a/Lectures/Week_05/gdal_demo.py b/Archive/Lectures_201702/Week_05/gdal_demo.py similarity index 100% rename from Lectures/Week_05/gdal_demo.py rename to Archive/Lectures_201702/Week_05/gdal_demo.py diff --git a/Lectures/Week_05/week_5.ipynb b/Archive/Lectures_201702/Week_05/week_5.ipynb similarity index 100% rename from Lectures/Week_05/week_5.ipynb rename to Archive/Lectures_201702/Week_05/week_5.ipynb diff --git a/Lectures/readme.md b/Archive/Lectures_201702/readme.md similarity index 100% rename from Lectures/readme.md rename to Archive/Lectures_201702/readme.md diff --git a/Lectures_201706/Week_01/helloworld.py b/Lectures_201706/Week_01/helloworld.py new file mode 100644 index 0000000..db55787 --- /dev/null +++ b/Lectures_201706/Week_01/helloworld.py @@ -0,0 +1,3 @@ +print('Hello world!') + +print('Howdy class!') diff --git a/Lectures_201706/Week_01/readme.md b/Lectures_201706/Week_01/readme.md new file mode 100644 index 0000000..3e2694a --- /dev/null +++ b/Lectures_201706/Week_01/readme.md @@ -0,0 +1 @@ +# Week 1 diff --git a/Lectures_201706/Week_01/setup_intro.ipynb b/Lectures_201706/Week_01/setup_intro.ipynb new file mode 100644 index 0000000..26ac42e --- /dev/null +++ b/Lectures_201706/Week_01/setup_intro.ipynb @@ -0,0 +1,313 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![NASA](http://www.nasa.gov/sites/all/themes/custom/nasatwo/images/nasa-logo.svg)\n", + "![DEVELOP](../../DEVELOP_logo.png)\n", + "\n", + "---\n", + "\n", + "# Setup & Introduction\n", + "\n", + "### Goddard Space Flight Center\n", + "\n", + "#### June 5, 2017\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Our Setup\n", + "\n", + "---\n", + "\n", + "* Anaconda - Virtual environment (don't need to be root/admin), completely free (and easily managed), from Continuum\n", + "* Enthought Canopy - Virtual environment, not free to add packages/libraries, having several versions gets messy, more business oriented (weirdly is part of Continuum)\n", + "\n", + "##### Computer Setup Instructions\n", + "\n", + "[Basic Setup](https://github.com/edmondb/developython/blob/master/README.md)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Who Are We?\n", + "\n", + "---\n", + "\n", + "* Brent Smith - Senior Scientific Programmer/Analyst, Code 610.1 GMAO - Operational developer, background: theoretical space physics\n", + "* Alfred Hubbard - Scientific Programmer/Analyst, Code 618; maps floods, vegetation, and sometimes other stuff with remotely sensed imagery; uses Python regularly to aid GIS analysis; background in biology and environmental science" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### The Python Programming Language - A Synopsis\n", + "\n", + "---\n", + "\n", + "* Interpreted (think language translator between you and the computer)\n", + "* Ways to run Python Code:\n", + " * __As a .py script (plain text document with python code, I use this method most)__\n", + " * In the Python shell (from the command line - not a good option)\n", + " * In the iPython shell (interactive, better - still not a good option)\n", + " * __In a Jupyter notebook (shareable, you are seeing one now, can run as a script or document)__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### As a script\n", + "\n", + "---\n", + "\n", + "1. Open the helloworld.py script in your text editor to see the contents of this Python script.\n", + "2. In a terminal/command prompt/Anaconda prompt, type:\n", + "\n", + " ```bash\n", + " $ python helloworld.py\n", + " ```\n", + "\n", + "3. You should see the output on the screen.\n", + "\n", + "__Caveat:__ Your prompt should be at the directory containg the helloworld.py script. Perform an ```ls``` (Mac/Linux) or ```dir``` (Windows) to see if that file is in your current working directory." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Jupyter notebook\n", + "\n", + "---\n", + "\n", + "1. From terminal/command prompt/Anaconda prompt type:\n", + "\n", + " ```bash\n", + " jupyter notebook\n", + " ```\n", + "\n", + "2. This directs you to a web browser and you can navigate to an already existing notebook or create one (right side menu New -> Python [default]).\n", + "3. This will open up a new Untitled notebook where you can directly input Python code, Markup formatted text, or have raw text.\n", + "4. Type:\n", + "\n", + " ```python\n", + " print('Hello world!')\n", + " ```\n", + "\n", + "5. Press __```Shift-Enter```__, __```Cntrl-Enter```__, or click __Cells -> Run Cells__ or use the Play button near the top of the page.\n", + "6. You will see the output now.\n", + "7. Exit via closing the browser windows and stopping the server running (Cntrl + Enter) in the terminal/command prompt." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Quick Python Intro\n", + "\n", + "---\n", + "\n", + "Based off of: [Learn X in Y](http://learnxinyminutes.com/docs/python/)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Single line comments start with a number symbol.\n", + "\n", + "\"\"\" Multiline strings can be written\n", + " using three \"s or 's, and are often used\n", + " as comments\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-26\n" + ] + } + ], + "source": [ + "# store inside a variable\n", + "result = -2*(4+9)\n", + "print(result)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3.141592653589793" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Imports\n", + "\n", + "import math\n", + "math.pi" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "> Python imports are like libraries/utilities that others have written for you to use. You can import packages (set of scripts) or modules (single scripts).\n", + "\n", + "The Python Style Guide tells you the best way to perform imports, name functions, and overall coding advice. It used to be called PEP8 (Python Enhancement Proposal 8), but in 2016, it was renamed to pycodestyle.\n", + "\n", + "* [PEP8](http://www.python.org/dev/peps/pep-0008/)\n", + "* [pep8.org](http://pep8.org) - a more human friendly approach" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "__Strings__\n", + "\n", + "* Single-quotes: `'a string'`\n", + "* Double-quotes: `\"another string\"`\n", + "* Joining/concatenation: `'FirstName' + 'LastName'`\n", + "* Formatting: [PyFormat](http://pyformat.info)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "__Iterables__\n", + "\n", + "* Lists (think strings as a list of characters; grocery lists):\n", + "\n", + " ```python\n", + " a_list = ['item 1', 'something else', 2, True, 'and so on']\n", + " another = list('hello')\n", + " ```\n", + "* Tuples (like lists, but not changing)\n", + " \n", + " ```python\n", + " numbers = (1,2,3)\n", + " first, second, third = numbers\n", + " another = tuple('one', 'two')\n", + " ```\n", + " \n", + "* Dictionaries (key/value pairing; like a word dictionary)\n", + " \n", + " ```python\n", + " d = {'key1':'value', 'key2':20, 3:['a', 'list'], 'k5':{'a':'nested','dict':'!'}}\n", + " another = dict(key='value', key2='another')\n", + " ```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "__Control flow__\n", + "\n", + "---\n", + "\n", + "__conditionals__\n", + "\n", + "```python\n", + "some_var = 5\n", + "\n", + "if some_var > 10:\n", + " print(\"some_var is totally bigger than 10.\")\n", + "elif some_var < 10: # This elif clause is optional.\n", + " print(\"some_var is smaller than 10.\")\n", + "else: # This is optional too.\n", + " print(\"some_var is indeed 10.\")\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "__loops__\n", + "\n", + "```python\n", + "for i in range(4):\n", + " print(i)\n", + "```\n", + "\n", + "```python\n", + "# conditionally based\n", + "x = 0\n", + "while x < 4:\n", + " print(x)\n", + " x += 1\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Break" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 723c302059c5f4c8898aa1ad7bdcdcfb6cc41596 Mon Sep 17 00:00:00 2001 From: Brent Smith Date: Mon, 5 Jun 2017 09:46:45 -0400 Subject: [PATCH 11/20] touched file --- Lectures_201706/readme.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Lectures_201706/readme.md diff --git a/Lectures_201706/readme.md b/Lectures_201706/readme.md new file mode 100644 index 0000000..e69de29 From 0f4eb4eea1b85e3171e915e1ad6339c784040984 Mon Sep 17 00:00:00 2001 From: Brent Smith Date: Tue, 6 Jun 2017 09:19:19 -0400 Subject: [PATCH 12/20] final --- Lectures_201706/Week_01/setup_intro.ipynb | 43 +++-------------------- 1 file changed, 4 insertions(+), 39 deletions(-) diff --git a/Lectures_201706/Week_01/setup_intro.ipynb b/Lectures_201706/Week_01/setup_intro.ipynb index 26ac42e..a51370d 100644 --- a/Lectures_201706/Week_01/setup_intro.ipynb +++ b/Lectures_201706/Week_01/setup_intro.ipynb @@ -138,17 +138,9 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-26\n" - ] - } - ], + "outputs": [], "source": [ "# store inside a variable\n", "result = -2*(4+9)\n", @@ -157,20 +149,9 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3.141592653589793" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# Imports\n", "\n", @@ -271,22 +252,6 @@ " x += 1\n", "```" ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Break" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] } ], "metadata": { From 0c2111ebb59cd2eaef63fe0eac23364d7d9d3ae3 Mon Sep 17 00:00:00 2001 From: Brent Smith Date: Tue, 13 Jun 2017 12:46:36 -0400 Subject: [PATCH 13/20] week 2 --- Lectures_201706/Week_02/intro_cont.ipynb | 246 +++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 Lectures_201706/Week_02/intro_cont.ipynb diff --git a/Lectures_201706/Week_02/intro_cont.ipynb b/Lectures_201706/Week_02/intro_cont.ipynb new file mode 100644 index 0000000..bb52a75 --- /dev/null +++ b/Lectures_201706/Week_02/intro_cont.ipynb @@ -0,0 +1,246 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![NASA](http://www.nasa.gov/sites/all/themes/custom/nasatwo/images/nasa-logo.svg)\n", + "![DEVELOP](../../DEVELOP_logo.png)\n", + "\n", + "---\n", + "\n", + "# Introduction Continued\n", + "\n", + "### Goddard Space Flight Center\n", + "\n", + "#### June 13, 2017\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Recap\n", + "\n", + "---\n", + "\n", + "* Anaconda installation - virtual environment - using the Jupyter notebook (not the only way to execute Python code)\n", + "* Python as a calculator (simple math)\n", + "* Imports and the power they possess\n", + "* Strings, formatting, and printing\n", + "* Data types\n", + "* Conditionals\n", + "* Loops" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Getting this lecture...\n", + "\n", + "---\n", + "\n", + "You can download this lecture here by copying all the text and then saving it in an ASCII file (using a text editor) with the .ipynb extension. We will be using the code in this notebook interactively and you will probably want to run it yourself.\n", + "\n", + "# Important\n", + "\n", + "Please install the _netCDF4_ Python package first from your Anaconda command prompt via:\n", + "\n", + "```bash\n", + "conda install netCDF4\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### File I/O\n", + "\n", + "---\n", + "\n", + "File types:\n", + "* __ASCII/Binary__ - simple (binary isn't if you don't know the format)\n", + "* __CSV/JSON files__ - need specific format reader/writer package\n", + "* __Earth Science Structured data - HDF, netCDF4, etc.__ - more complex" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### ASCII/Binary\n", + "\n", + "---\n", + "\n", + "Old:\n", + "```python\n", + "f = open('filename.ascii', 'w')\n", + "f.write('Hi there.')\n", + "f.close()\n", + "```\n", + "\n", + "New:\n", + "```python\n", + "with open('filename.ascii', 'w') as f:\n", + " f.write('Hi there.')\n", + "```\n", + "\n", + "__Note:__ Binary read/write is simply just adding a _'b'_ after the mode of opening the file (eg. 'wb' for writing binary). \n", + "> __File modes:__ r, w, a, + versions, b versions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Although I'm not going to cover them, CSV and JSON file content types are very useful in applications today. Most web applications (GET/POST requests) use JSON for data transactions. The __[csv](http://docs.python.org/2/library/csv.html)__ and __[json](http://docs.python.org/2/library/json.html)__ packages are very useful for dealing with these data." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "> _pickles..._ Python has this thing called pickles where you \"temporarily\" store data. It's a binary file, but is only for small storage that is needed for a short time." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Earth Science Structured Data\n", + "\n", + "---\n", + "\n", + "The __[h5py]()__ and __[netCDF4]()__ Python packages are very useful for reading structured data (multidimensional, multivariate, time-series, etc.). Here, we are going to look at reading and visualizing some structured data." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### ISS RapidScat Data - netCDF4\n", + "\n", + "---\n", + "\n", + "- Make sure you have installed the _netCDF4_ Python package.\n", + "- Retrieve the data via FTP:\n", + "\n", + "[Link for manual download via FTP](ftp://podaac-ftp.jpl.nasa.gov/allData/rapidscat/L2B12/v1.3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import ftplib\n", + "\n", + "ftp = ftplib.FTP('podaac-ftp.jpl.nasa.gov')\n", + "ftp.login()\n", + "ftp.cwd('allData/rapidscat/L2B12/v1.3/2016/232')\n", + "ftp.retrbinary('RETR rs_l2b_v1.3_10827_201609290531.nc.gz', open('ISS.nc.gz', 'wb').write)\n", + "ftp.quit()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "- Manually unzip/uncompress this file.\n", + "- Let's read the data now..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import netCDF4 as nc\n", + "\n", + "f = nc.Dataset('ISS.nc', 'r')\n", + "print(f.variables.keys())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "z = f.variables['retrieved_wind_speed']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "z.dimensions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Visualizing\n", + "\n", + "---\n", + "\n", + "Matplotlib is basically Python's replacement for Matlab. Here is an example of plotting data from our file." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig = plt.figure(figsize = (20,20))\n", + "ax = fig.add_subplot(111)\n", + "img = ax.imshow(f.variables['retrieved_wind_speed'][:].transpose(), interpolation=None)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We could extend this to actually visualize the data plotted on a map (using the Basemap package) and manipulate the NumPy array to give us statistics or further insight into what the data shows us and how it is characterized." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 27b898383a74d14b529918b2fd11d09b0fa7baf2 Mon Sep 17 00:00:00 2001 From: alfredhub Date: Thu, 15 Jun 2017 14:54:33 -0400 Subject: [PATCH 14/20] Empty --- Lectures_201706/Week_03/empty | 1 + 1 file changed, 1 insertion(+) create mode 100644 Lectures_201706/Week_03/empty diff --git a/Lectures_201706/Week_03/empty b/Lectures_201706/Week_03/empty new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Lectures_201706/Week_03/empty @@ -0,0 +1 @@ + From 16bc825593b683ec2d3a998efd7a6c13eb871458 Mon Sep 17 00:00:00 2001 From: alfredhub Date: Thu, 15 Jun 2017 14:58:18 -0400 Subject: [PATCH 15/20] Uploaded lecture --- Lectures_201706/Week_03/Week_03.ipynb | 533 ++++++++++++++++++++++++++ 1 file changed, 533 insertions(+) create mode 100644 Lectures_201706/Week_03/Week_03.ipynb diff --git a/Lectures_201706/Week_03/Week_03.ipynb b/Lectures_201706/Week_03/Week_03.ipynb new file mode 100644 index 0000000..aa6e43f --- /dev/null +++ b/Lectures_201706/Week_03/Week_03.ipynb @@ -0,0 +1,533 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![NASA](http://www.nasa.gov/sites/all/themes/custom/nasatwo/images/nasa-logo.svg)\n", + "![DEVELOP](../../DEVELOP_logo.png)\n", + "\n", + "---\n", + "\n", + "# GIS Automation through ArcPy\n", + "\n", + "### Goddard Space Flight Center\n", + "\n", + "#### March 6, 2017\n", + "\n", + "---\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ArcPy\n", + "\n", + "---\n", + "\n", + "* Python package created by Esri to allow ArcGIS tools to be called from Python\n", + "* This enables all manner of geoprocessing to be done in an automated fashion, as ArcPy can replicate most of the functionality of ArcGIS for Desktop\n", + "* While ArcGIS comes with its own version of Python, ArcPy can be used with other Python installations, as we will do in this course\n", + "* For reference, see the documentation for your version of ArcGIS. The help page for each tool has a description of the Python syntax and (usually) short example scripts.\n", + " * For instance: http://desktop.arcgis.com/en/arcmap/10.4/tools/data-management-toolbox/clip.htm (scroll down)\n", + "* Another resource: [Penn State online course](https://www.e-education.psu.edu/geog485/node/91) covering the same subject matter as this lecture, GIS automation with Python.\n", + "* Possibly the best resource of all: Google\n", + " * While not as well supported as the really popular Python packages (i.e. NumPy, matplotlib, etc.), enough people use ArcPy that you will find decent support on forums like Stack Overflow" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Example Project: Fun with MODIS LST Data\n", + "\n", + "---\n", + "\n", + "* To get a feel for automating typical GIS tasks, we will work through a short project where we:\n", + " * download some MODIS land surface temperature (LST) data\n", + " * extract the bands we want to GeoTIFF\n", + " * perform some analysis, including raster math and conditionals\n", + " * resample the output\n", + " * ... and repeat\n", + "\n", + "### Test ArcPy" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import arcpy" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Download data\n", + "\n", + "---\n", + "\n", + "Download this MODIS image: ftp://ladsweb.nascom.nasa.gov/allData/6/MOD11A2/2016/201/MOD11A2.A2016201.h11v05.006.2016242234243.hdf \n", + "\n", + "Copy it to the directory where you want to store your data.\n", + "\n", + "### Set working directory\n", + "\n", + "---\n", + "\n", + "ArcPy needs to know where to look for inputs and save outputs on your computer. You can specify an absolute path for every file, meaning a path including not only the file name but all the parent directories, including the drive name (i.e. C:\\\\Users\\\\abhubba1\\\\Documents\\\\Python Scripts\\\\DEVELOP_class\\\\thatwasalotoftyping.tif). However, this can grow tedious, so it is usually easier to set the workspace environment (more on these later) to a location of your choosing:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "arcpy.env.workspace = \"C:\\\\Users\\\\abhubba1\\\\Documents\\\\Python Scripts\\\\DEVELOP_class\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Change this path to the directory where you saved the MODIS data in the above step. Now, all you need to provide is a file name, and ArcPy will automatically go to this folder.\n", + "\n", + "Another consideration is that, by default, ArcPy will not permit you to overwrite files that already exist. When you are developing a script, this is usually not what you want (but not always - be careful!). Allow ArcPy to overwrite output as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "arcpy.env.overwriteOutput = True" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Extract from HDF to GeoTIFF\n", + "\n", + "---\n", + "\n", + "With many data types, we would be ready to jump straight in to geoprocessing. However, with MODIS data we have an immediate hurdle: HDF. Fully-featured handling of HDF files requires special Python packages, like h5py, as covered in the previous lecture. For our project, however, this would be overkill. Instead, we can use ArcPy's Extract SubDataset to pull out the data we want into a GeoTIFF.\n", + "\n", + "Let's extract the daytime LST data, which is subdataset 0:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "MODIS_file = \"MOD11A2.A2016201.h11v05.006.2016242234243.hdf\"\n", + "day_LST = MODIS_file.rstrip(\".hdf\") + \"_dayLST.tif\"\n", + "arcpy.ExtractSubDataset_management(MODIS_file, day_LST, subdataset_index=0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "_Note:_ `rstrip` is a string method that removes the string given in the parentheses from the end (right side) of the input string.\n", + "\n", + "To inspect the output, open ArcMap and load this file. Add an imagery basemap as well and compare the two, noting areas of high and low temperature values. Do you see anything strange?\n", + "\n", + "### Perform analysis\n", + "\n", + "---\n", + "\n", + "#### Raster Math\n", + "\n", + "The above data has been scaled to allow it to be stored in an integer format, but this makes it difficult to interpret. To convert it back to Kelvin, we must apply the scale factor, which in this case is 0.02. To do this, we will perform some raster math." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "arcpy.CheckOutExtension(\"spatial\")\n", + "\n", + "scale = 0.02\n", + "day_LST_sc = arcpy.Raster(day_LST) * scale\n", + "\n", + "arcpy.CheckInExtension(\"spatial\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "ArcPy allows basic math operations to be applied on a pixel-by-pixel basis with Python syntax, but it is necessary to create an ArcPy Raster object from your raster file on disk. The math operation returns another ArcPy Raster object, which we have assigned to `day_LST_sc`. Think of these Raster objects in an analogous manner to the data types we covered before, like string, float, int, etc. They can be used in other math operations and passed to some (but not all) ArcGIS tools that take raster input.\n", + "\n", + "Notice the lines before and after the middle block. Raster math requires the Spatial Analyst extension, so it is necessary to check out a license for this extension first. Checking the license back in at the end is not necessary for the code to function, but it is good practice, because your organization may have a license server with limited keys.\n", + "\n", + "At the moment, our scaled daytime LST raster only exists in memory - we have not saved it to disk. To do so:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "path = MODIS_file.rstrip(\".hdf\") + \"_scale.tif\"\n", + "day_LST_sc.save(path)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Math with multiple rasters\n", + "\n", + "In a similar manner, two or more rasters can be used in a formula using simple Python syntax. But first, we need two rasters! Let's repeat the above steps with the nighttime LST band (subdataset 4), from the same MODIS file:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "arcpy.CheckOutExtension(\"spatial\")\n", + "\n", + "MODIS_file = \"MOD11A2.A2016201.h11v05.006.2016242234243.hdf\"\n", + "night_LST = MODIS_file.rstrip(\".hdf\") + \"_nightLST.tif\"\n", + "arcpy.ExtractSubDataset_management(MODIS_file, night_LST, subdataset_index=4)\n", + "\n", + "scale = 0.02\n", + "night_LST_sc = arcpy.Raster(night_LST) * scale\n", + "\n", + "arcpy.CheckInExtension(\"spatial\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "_Note:_ In this case, we did not save the scaled raster to disk. This is not actually necessary to use it in later operations, and not saving intermediates is a good way to conserve disk space.\n", + "\n", + "_Another Note:_ In these examples, we are checking the spatial analyst extension in and out each time, but, if you are writing a long script, it is only necessary to do this once, at the beginning and end.\n", + "\n", + "Now, let's compute the difference between the daytime and nighttime LST:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "arcpy.CheckOutExtension(\"spatial\")\n", + "\n", + "diff = day_LST_sc - night_LST_sc\n", + "diff_path = MODIS_file.rstrip(\".hdf\")+\"_diff.tif\"\n", + "diff.save(diff_path)\n", + "\n", + "arcpy.CheckInExtension(\"spatial\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This will create a new Raster object where each pixel corresponds to the difference between the two old rasters. Open this new raster in ArcMap and compare it to a basemap.\n", + "\n", + "#### Conditionals\n", + "\n", + "Suppose we want to know where the above difference exceeds a certain threshold. We can answer this question using the Con tool, available with the Spatial Analyst extension." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "arcpy.CheckOutExtension(\"spatial\")\n", + "\n", + "thres = 15\n", + "diff_thres = arcpy.sa.Con(diff > thres, 1, 0)\n", + "diff_thres_path = MODIS_file.rstrip(\".hdf\")+\"_thres.tif\"\n", + "diff_thres.save(diff_thres_path)\n", + "\n", + "arcpy.CheckInExtension(\"spatial\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The middle block of code will create and save a raster that contains a 1 wherever the day-night difference exceeds 15, and a 0 wherever it does not.\n", + "\n", + "### Resample\n", + "\n", + "---\n", + "\n", + "We now have a nice Boolean raster that we could use as a mask in some larger project. However, what if the other members of our project are working with the MODIS red and NIR bands, which are 250 m resolution? We can be helpful, and resample our raster to this resolution." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "out_cellsize = 231.6563583\n", + "res = MODIS_file.rstrip(\".hdf\") + \"_res.tif\"\n", + "arcpy.Resample_management(diff_thres, res, cell_size=out_cellsize)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We could have performed this resampling at any point in our processing chain, but we chose to do so at the end. Why might this be best?\n", + "\n", + "### Repeat as necessary\n", + "\n", + "---\n", + "\n", + "We have output (hopefully), but only for one raster file, and when has a project ever involved only one raster file?? The efficiency of scripting ArcGIS in Python becomes apparent when one must do the same thing many times, which should sound like something you have already learned... loops!\n", + "\n", + "First, we'll need some more data. Since we already have a summer image, let's download files from:\n", + "* winter: ftp://ladsweb.nascom.nasa.gov/allData/6/MOD11A2/2016/017/MOD11A2.A2016017.h11v05.006.2016234002041.hdf\n", + "* spring: ftp://ladsweb.nascom.nasa.gov/allData/6/MOD11A2/2016/105/MOD11A2.A2016105.h11v05.006.2016242152502.hdf\n", + "* and fall: ftp://ladsweb.nascom.nasa.gov/allData/6/MOD11A2/2016/289/MOD11A2.A2016289.h11v05.006.2016302010943.hdf\n", + "\n", + "Move these to the same folder you have been using.\n", + "\n", + "Now, let's put everything we did above in a loop:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "u'CheckedIn'" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import arcpy\n", + "\n", + "arcpy.env.workspace = \"C:\\\\Users\\\\abhubba1\\\\Documents\\\\Python Scripts\\\\DEVELOP_class\"\n", + "arcpy.env.overwriteOutput = True\n", + "arcpy.CheckOutExtension(\"spatial\")\n", + "\n", + "scale = 0.02\n", + "thres = 15\n", + "out_cellsize = 231.6563583\n", + "MODIS_files = [\"MOD11A2.A2016017.h11v05.006.2016234002041.hdf\", \n", + " \"MOD11A2.A2016105.h11v05.006.2016242152502.hdf\", \n", + " \"MOD11A2.A2016201.h11v05.006.2016242234243.hdf\", \n", + " \"MOD11A2.A2016289.h11v05.006.2016302010943.hdf\"]\n", + "\n", + "for f in MODIS_files:\n", + " \n", + " #Extract from HDF\n", + " day_LST = f.rstrip(\".hdf\") + \"_dayLST.tif\"\n", + " arcpy.ExtractSubDataset_management(f, day_LST, subdataset_index=0)\n", + " night_LST = f.rstrip(\".hdf\") + \"_nightLST.tif\"\n", + " arcpy.ExtractSubDataset_management(f, night_LST, subdataset_index=4)\n", + " \n", + " #Scale\n", + " day_LST_sc = arcpy.Raster(day_LST) * scale\n", + " night_LST_sc = arcpy.Raster(night_LST) * scale\n", + " \n", + " #Perform subtraction\n", + " diff = day_LST_sc - night_LST_sc\n", + " diff_path = f.rstrip(\".hdf\")+\"_diff.tif\"\n", + " diff.save(diff_path)\n", + " \n", + " #Apply conditional\n", + " diff_thres = arcpy.sa.Con(diff > thres, 1, 0)\n", + " diff_thres_path = f.rstrip(\".hdf\")+\"_thres.tif\"\n", + " diff_thres.save(diff_thres_path)\n", + " \n", + " #Resample\n", + " res = f.rstrip(\".hdf\") + \"_res.tif\"\n", + " arcpy.Resample_management(diff_thres, res, cell_size=out_cellsize)\n", + " \n", + "arcpy.CheckInExtension(\"spatial\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "_Tip:_ If you need to get the names of many files in a folder and don't want to do a lot of tedious typing, check out the [glob](https://docs.python.org/2/library/glob.html) package.\n", + "\n", + "\n", + "\n", + "# Other Considerations\n", + "\n", + "---\n", + "\n", + "### Environments\n", + "\n", + "---\n", + "\n", + "ArcGIS uses environment settings to control the specific characteristics of your current geoprocessing environment. In the above script, we are using two already: workspace and overwrite output. Environments are a powerful way to control the exact way in which your script executes. As another example, let's say that within our MODIS tile, we only really care about Virginia (because it is objectively better than all of these other states), and we want to limit output to this state.\n", + "\n", + "One approach might be to clip each input raster with a shapefile, but we have to do this for each input. In this case, we only have two per iteration, but in other projects we might have a lot more. A more elegant approach is to use the mask environment setting.\n", + "\n", + "Download [this](https://drive.google.com/file/d/0B8toI67HoVSrVzV3aUcwc3FBcG8/view?usp=sharing) shapefile of Virginia, and extract it to your work directory. Then, rerun our script with the mask environment set at the top:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import arcpy\n", + "\n", + "arcpy.env.workspace = \"C:\\\\Users\\\\abhubba1\\\\Documents\\\\Python Scripts\\\\DEVELOP_class\"\n", + "arcpy.env.overwriteOutput = True\n", + "arcpy.env.mask = \"Virginia.shp\"\n", + "arcpy.CheckOutExtension(\"spatial\")\n", + "\n", + "scale = 0.02\n", + "thres = 15\n", + "out_cellsize = 231.6563583\n", + "MODIS_files = [\"MOD11A2.A2016017.h11v05.006.2016234002041.hdf\", \n", + " \"MOD11A2.A2016105.h11v05.006.2016242152502.hdf\", \n", + " \"MOD11A2.A2016201.h11v05.006.2016242234243.hdf\", \n", + " \"MOD11A2.A2016289.h11v05.006.2016302010943.hdf\"]\n", + "\n", + "for f in MODIS_files:\n", + " \n", + " #Extract from HDF\n", + " day_LST = f.rstrip(\".hdf\") + \"_dayLST.tif\"\n", + " arcpy.ExtractSubDataset_management(f, day_LST, subdataset_index=0)\n", + " night_LST = f.rstrip(\".hdf\") + \"_nightLST.tif\"\n", + " arcpy.ExtractSubDataset_management(f, night_LST, subdataset_index=4)\n", + " \n", + " #Scale\n", + " day_LST_sc = arcpy.Raster(day_LST) * scale\n", + " night_LST_sc = arcpy.Raster(night_LST) * scale\n", + " \n", + " #Perform subtraction\n", + " diff = day_LST_sc - night_LST_sc\n", + " diff.save(f.rstrip(\".hdf\")+\"_diff.tif\")\n", + " \n", + " #Apply conditional\n", + " diff_thres = arcpy.sa.Con(diff > thres, 1, 0)\n", + " diff_thres.save(f.rstrip(\".hdf\")+\"_thres.tif\")\n", + " \n", + " #Resample\n", + " res = f.rstrip(\".hdf\") + \"_res.tif\"\n", + " arcpy.Resample_management(diff_thres, res, cell_size=out_cellsize)\n", + " \n", + "arcpy.CheckInExtension(\"spatial\")\n", + "\n", + "arcpy.env.workspace = None\n", + "arcpy.env.overwriteOutput = None\n", + "arcpy.env.mask = None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Inspect the output. If everything worked properly, you should only see data over the scenic Commonwealth of Virginia\n", + "\n", + "__Very important note:__ The nature of environment settings is that they apply to your _entire processing environment_, which means they will stick around for future processes you run in the same session of Python. Old environment settings can lead to mysterious errors, confusion, and general gnashing of teeth. I highly recommend that you clear out your environment settings at the end of your script by setting them to `None`, as I have done above. Even better, clear them immediately after they are no longer needed, in case your script crashes before it completes.\n", + "\n", + "### Editing locks\n", + "\n", + "---\n", + "\n", + "Whenever a program is using a file, it creates a lock that prevents other programs from editing the same file. Python is no different. In general, these should disappear after a script is finished executing. For reasons that are not entirely clear to me, ArcPy often retains locks on ArcPy objects created by a script even said script has completed. This will create problems if you then try to edit the file that object is pointing to in a different program. Therefore, it is also good practice to clear variables that point to ArcPy objects after they are no longer necessary. To accomplish that in our script, add the following to the end:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "day_LST_sc = None\n", + "night_LST_sc = None\n", + "diff = None\n", + "diff_thres = None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "On the other side of the same coin, Python will not be able to edit a file that is locked by another application. In the context of geoprocessing, this can happen because you ran your code, viewed the output in ArcMap, and tried to rerun your code without removing said output from ArcMap. Some of you may have already experienced this phenomenon during this lesson. If you're me, this happens _all the time_..." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 43425d70f47d8ab36c845a937407398fed27de49 Mon Sep 17 00:00:00 2001 From: alfredhub Date: Thu, 15 Jun 2017 14:58:36 -0400 Subject: [PATCH 16/20] Delete empty --- Lectures_201706/Week_03/empty | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Lectures_201706/Week_03/empty diff --git a/Lectures_201706/Week_03/empty b/Lectures_201706/Week_03/empty deleted file mode 100644 index 8b13789..0000000 --- a/Lectures_201706/Week_03/empty +++ /dev/null @@ -1 +0,0 @@ - From 54d700d4104157cb30e6f3ff6a1705309ce0736b Mon Sep 17 00:00:00 2001 From: alfredhub Date: Sun, 24 Sep 2017 13:24:37 -0400 Subject: [PATCH 17/20] Archived summer lectures; created new copies for fall --- .../Lectures_201706}/Week_01/helloworld.py | 0 .../Lectures_201706}/Week_01/readme.md | 0 .../Week_01/setup_intro.ipynb | 0 .../Lectures_201706}/Week_02/intro_cont.ipynb | 0 .../Lectures_201706}/Week_03/Week_03.ipynb | 0 .../Lectures_201706}/readme.md | 0 Lectures_201709/Week_01/helloworld.py | 3 + Lectures_201709/Week_01/readme.md | 1 + Lectures_201709/Week_01/setup_intro.ipynb | 278 +++++++++ Lectures_201709/Week_02/intro_cont.ipynb | 246 ++++++++ Lectures_201709/Week_03/GIS_programming.ipynb | 533 ++++++++++++++++++ Lectures_201709/readme.md | 0 12 files changed, 1061 insertions(+) rename {Lectures_201706 => Archive/Lectures_201706}/Week_01/helloworld.py (100%) rename {Lectures_201706 => Archive/Lectures_201706}/Week_01/readme.md (100%) rename {Lectures_201706 => Archive/Lectures_201706}/Week_01/setup_intro.ipynb (100%) rename {Lectures_201706 => Archive/Lectures_201706}/Week_02/intro_cont.ipynb (100%) rename {Lectures_201706 => Archive/Lectures_201706}/Week_03/Week_03.ipynb (100%) rename {Lectures_201706 => Archive/Lectures_201706}/readme.md (100%) create mode 100644 Lectures_201709/Week_01/helloworld.py create mode 100644 Lectures_201709/Week_01/readme.md create mode 100644 Lectures_201709/Week_01/setup_intro.ipynb create mode 100644 Lectures_201709/Week_02/intro_cont.ipynb create mode 100644 Lectures_201709/Week_03/GIS_programming.ipynb create mode 100644 Lectures_201709/readme.md diff --git a/Lectures_201706/Week_01/helloworld.py b/Archive/Lectures_201706/Week_01/helloworld.py similarity index 100% rename from Lectures_201706/Week_01/helloworld.py rename to Archive/Lectures_201706/Week_01/helloworld.py diff --git a/Lectures_201706/Week_01/readme.md b/Archive/Lectures_201706/Week_01/readme.md similarity index 100% rename from Lectures_201706/Week_01/readme.md rename to Archive/Lectures_201706/Week_01/readme.md diff --git a/Lectures_201706/Week_01/setup_intro.ipynb b/Archive/Lectures_201706/Week_01/setup_intro.ipynb similarity index 100% rename from Lectures_201706/Week_01/setup_intro.ipynb rename to Archive/Lectures_201706/Week_01/setup_intro.ipynb diff --git a/Lectures_201706/Week_02/intro_cont.ipynb b/Archive/Lectures_201706/Week_02/intro_cont.ipynb similarity index 100% rename from Lectures_201706/Week_02/intro_cont.ipynb rename to Archive/Lectures_201706/Week_02/intro_cont.ipynb diff --git a/Lectures_201706/Week_03/Week_03.ipynb b/Archive/Lectures_201706/Week_03/Week_03.ipynb similarity index 100% rename from Lectures_201706/Week_03/Week_03.ipynb rename to Archive/Lectures_201706/Week_03/Week_03.ipynb diff --git a/Lectures_201706/readme.md b/Archive/Lectures_201706/readme.md similarity index 100% rename from Lectures_201706/readme.md rename to Archive/Lectures_201706/readme.md diff --git a/Lectures_201709/Week_01/helloworld.py b/Lectures_201709/Week_01/helloworld.py new file mode 100644 index 0000000..db55787 --- /dev/null +++ b/Lectures_201709/Week_01/helloworld.py @@ -0,0 +1,3 @@ +print('Hello world!') + +print('Howdy class!') diff --git a/Lectures_201709/Week_01/readme.md b/Lectures_201709/Week_01/readme.md new file mode 100644 index 0000000..3e2694a --- /dev/null +++ b/Lectures_201709/Week_01/readme.md @@ -0,0 +1 @@ +# Week 1 diff --git a/Lectures_201709/Week_01/setup_intro.ipynb b/Lectures_201709/Week_01/setup_intro.ipynb new file mode 100644 index 0000000..a51370d --- /dev/null +++ b/Lectures_201709/Week_01/setup_intro.ipynb @@ -0,0 +1,278 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![NASA](http://www.nasa.gov/sites/all/themes/custom/nasatwo/images/nasa-logo.svg)\n", + "![DEVELOP](../../DEVELOP_logo.png)\n", + "\n", + "---\n", + "\n", + "# Setup & Introduction\n", + "\n", + "### Goddard Space Flight Center\n", + "\n", + "#### June 5, 2017\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Our Setup\n", + "\n", + "---\n", + "\n", + "* Anaconda - Virtual environment (don't need to be root/admin), completely free (and easily managed), from Continuum\n", + "* Enthought Canopy - Virtual environment, not free to add packages/libraries, having several versions gets messy, more business oriented (weirdly is part of Continuum)\n", + "\n", + "##### Computer Setup Instructions\n", + "\n", + "[Basic Setup](https://github.com/edmondb/developython/blob/master/README.md)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Who Are We?\n", + "\n", + "---\n", + "\n", + "* Brent Smith - Senior Scientific Programmer/Analyst, Code 610.1 GMAO - Operational developer, background: theoretical space physics\n", + "* Alfred Hubbard - Scientific Programmer/Analyst, Code 618; maps floods, vegetation, and sometimes other stuff with remotely sensed imagery; uses Python regularly to aid GIS analysis; background in biology and environmental science" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### The Python Programming Language - A Synopsis\n", + "\n", + "---\n", + "\n", + "* Interpreted (think language translator between you and the computer)\n", + "* Ways to run Python Code:\n", + " * __As a .py script (plain text document with python code, I use this method most)__\n", + " * In the Python shell (from the command line - not a good option)\n", + " * In the iPython shell (interactive, better - still not a good option)\n", + " * __In a Jupyter notebook (shareable, you are seeing one now, can run as a script or document)__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### As a script\n", + "\n", + "---\n", + "\n", + "1. Open the helloworld.py script in your text editor to see the contents of this Python script.\n", + "2. In a terminal/command prompt/Anaconda prompt, type:\n", + "\n", + " ```bash\n", + " $ python helloworld.py\n", + " ```\n", + "\n", + "3. You should see the output on the screen.\n", + "\n", + "__Caveat:__ Your prompt should be at the directory containg the helloworld.py script. Perform an ```ls``` (Mac/Linux) or ```dir``` (Windows) to see if that file is in your current working directory." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Jupyter notebook\n", + "\n", + "---\n", + "\n", + "1. From terminal/command prompt/Anaconda prompt type:\n", + "\n", + " ```bash\n", + " jupyter notebook\n", + " ```\n", + "\n", + "2. This directs you to a web browser and you can navigate to an already existing notebook or create one (right side menu New -> Python [default]).\n", + "3. This will open up a new Untitled notebook where you can directly input Python code, Markup formatted text, or have raw text.\n", + "4. Type:\n", + "\n", + " ```python\n", + " print('Hello world!')\n", + " ```\n", + "\n", + "5. Press __```Shift-Enter```__, __```Cntrl-Enter```__, or click __Cells -> Run Cells__ or use the Play button near the top of the page.\n", + "6. You will see the output now.\n", + "7. Exit via closing the browser windows and stopping the server running (Cntrl + Enter) in the terminal/command prompt." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Quick Python Intro\n", + "\n", + "---\n", + "\n", + "Based off of: [Learn X in Y](http://learnxinyminutes.com/docs/python/)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Single line comments start with a number symbol.\n", + "\n", + "\"\"\" Multiline strings can be written\n", + " using three \"s or 's, and are often used\n", + " as comments\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# store inside a variable\n", + "result = -2*(4+9)\n", + "print(result)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Imports\n", + "\n", + "import math\n", + "math.pi" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "> Python imports are like libraries/utilities that others have written for you to use. You can import packages (set of scripts) or modules (single scripts).\n", + "\n", + "The Python Style Guide tells you the best way to perform imports, name functions, and overall coding advice. It used to be called PEP8 (Python Enhancement Proposal 8), but in 2016, it was renamed to pycodestyle.\n", + "\n", + "* [PEP8](http://www.python.org/dev/peps/pep-0008/)\n", + "* [pep8.org](http://pep8.org) - a more human friendly approach" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "__Strings__\n", + "\n", + "* Single-quotes: `'a string'`\n", + "* Double-quotes: `\"another string\"`\n", + "* Joining/concatenation: `'FirstName' + 'LastName'`\n", + "* Formatting: [PyFormat](http://pyformat.info)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "__Iterables__\n", + "\n", + "* Lists (think strings as a list of characters; grocery lists):\n", + "\n", + " ```python\n", + " a_list = ['item 1', 'something else', 2, True, 'and so on']\n", + " another = list('hello')\n", + " ```\n", + "* Tuples (like lists, but not changing)\n", + " \n", + " ```python\n", + " numbers = (1,2,3)\n", + " first, second, third = numbers\n", + " another = tuple('one', 'two')\n", + " ```\n", + " \n", + "* Dictionaries (key/value pairing; like a word dictionary)\n", + " \n", + " ```python\n", + " d = {'key1':'value', 'key2':20, 3:['a', 'list'], 'k5':{'a':'nested','dict':'!'}}\n", + " another = dict(key='value', key2='another')\n", + " ```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "__Control flow__\n", + "\n", + "---\n", + "\n", + "__conditionals__\n", + "\n", + "```python\n", + "some_var = 5\n", + "\n", + "if some_var > 10:\n", + " print(\"some_var is totally bigger than 10.\")\n", + "elif some_var < 10: # This elif clause is optional.\n", + " print(\"some_var is smaller than 10.\")\n", + "else: # This is optional too.\n", + " print(\"some_var is indeed 10.\")\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "__loops__\n", + "\n", + "```python\n", + "for i in range(4):\n", + " print(i)\n", + "```\n", + "\n", + "```python\n", + "# conditionally based\n", + "x = 0\n", + "while x < 4:\n", + " print(x)\n", + " x += 1\n", + "```" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Lectures_201709/Week_02/intro_cont.ipynb b/Lectures_201709/Week_02/intro_cont.ipynb new file mode 100644 index 0000000..bb52a75 --- /dev/null +++ b/Lectures_201709/Week_02/intro_cont.ipynb @@ -0,0 +1,246 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![NASA](http://www.nasa.gov/sites/all/themes/custom/nasatwo/images/nasa-logo.svg)\n", + "![DEVELOP](../../DEVELOP_logo.png)\n", + "\n", + "---\n", + "\n", + "# Introduction Continued\n", + "\n", + "### Goddard Space Flight Center\n", + "\n", + "#### June 13, 2017\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Recap\n", + "\n", + "---\n", + "\n", + "* Anaconda installation - virtual environment - using the Jupyter notebook (not the only way to execute Python code)\n", + "* Python as a calculator (simple math)\n", + "* Imports and the power they possess\n", + "* Strings, formatting, and printing\n", + "* Data types\n", + "* Conditionals\n", + "* Loops" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Getting this lecture...\n", + "\n", + "---\n", + "\n", + "You can download this lecture here by copying all the text and then saving it in an ASCII file (using a text editor) with the .ipynb extension. We will be using the code in this notebook interactively and you will probably want to run it yourself.\n", + "\n", + "# Important\n", + "\n", + "Please install the _netCDF4_ Python package first from your Anaconda command prompt via:\n", + "\n", + "```bash\n", + "conda install netCDF4\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### File I/O\n", + "\n", + "---\n", + "\n", + "File types:\n", + "* __ASCII/Binary__ - simple (binary isn't if you don't know the format)\n", + "* __CSV/JSON files__ - need specific format reader/writer package\n", + "* __Earth Science Structured data - HDF, netCDF4, etc.__ - more complex" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### ASCII/Binary\n", + "\n", + "---\n", + "\n", + "Old:\n", + "```python\n", + "f = open('filename.ascii', 'w')\n", + "f.write('Hi there.')\n", + "f.close()\n", + "```\n", + "\n", + "New:\n", + "```python\n", + "with open('filename.ascii', 'w') as f:\n", + " f.write('Hi there.')\n", + "```\n", + "\n", + "__Note:__ Binary read/write is simply just adding a _'b'_ after the mode of opening the file (eg. 'wb' for writing binary). \n", + "> __File modes:__ r, w, a, + versions, b versions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Although I'm not going to cover them, CSV and JSON file content types are very useful in applications today. Most web applications (GET/POST requests) use JSON for data transactions. The __[csv](http://docs.python.org/2/library/csv.html)__ and __[json](http://docs.python.org/2/library/json.html)__ packages are very useful for dealing with these data." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "> _pickles..._ Python has this thing called pickles where you \"temporarily\" store data. It's a binary file, but is only for small storage that is needed for a short time." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Earth Science Structured Data\n", + "\n", + "---\n", + "\n", + "The __[h5py]()__ and __[netCDF4]()__ Python packages are very useful for reading structured data (multidimensional, multivariate, time-series, etc.). Here, we are going to look at reading and visualizing some structured data." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### ISS RapidScat Data - netCDF4\n", + "\n", + "---\n", + "\n", + "- Make sure you have installed the _netCDF4_ Python package.\n", + "- Retrieve the data via FTP:\n", + "\n", + "[Link for manual download via FTP](ftp://podaac-ftp.jpl.nasa.gov/allData/rapidscat/L2B12/v1.3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import ftplib\n", + "\n", + "ftp = ftplib.FTP('podaac-ftp.jpl.nasa.gov')\n", + "ftp.login()\n", + "ftp.cwd('allData/rapidscat/L2B12/v1.3/2016/232')\n", + "ftp.retrbinary('RETR rs_l2b_v1.3_10827_201609290531.nc.gz', open('ISS.nc.gz', 'wb').write)\n", + "ftp.quit()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "- Manually unzip/uncompress this file.\n", + "- Let's read the data now..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import netCDF4 as nc\n", + "\n", + "f = nc.Dataset('ISS.nc', 'r')\n", + "print(f.variables.keys())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "z = f.variables['retrieved_wind_speed']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "z.dimensions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Visualizing\n", + "\n", + "---\n", + "\n", + "Matplotlib is basically Python's replacement for Matlab. Here is an example of plotting data from our file." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig = plt.figure(figsize = (20,20))\n", + "ax = fig.add_subplot(111)\n", + "img = ax.imshow(f.variables['retrieved_wind_speed'][:].transpose(), interpolation=None)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We could extend this to actually visualize the data plotted on a map (using the Basemap package) and manipulate the NumPy array to give us statistics or further insight into what the data shows us and how it is characterized." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Lectures_201709/Week_03/GIS_programming.ipynb b/Lectures_201709/Week_03/GIS_programming.ipynb new file mode 100644 index 0000000..aa6e43f --- /dev/null +++ b/Lectures_201709/Week_03/GIS_programming.ipynb @@ -0,0 +1,533 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![NASA](http://www.nasa.gov/sites/all/themes/custom/nasatwo/images/nasa-logo.svg)\n", + "![DEVELOP](../../DEVELOP_logo.png)\n", + "\n", + "---\n", + "\n", + "# GIS Automation through ArcPy\n", + "\n", + "### Goddard Space Flight Center\n", + "\n", + "#### March 6, 2017\n", + "\n", + "---\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ArcPy\n", + "\n", + "---\n", + "\n", + "* Python package created by Esri to allow ArcGIS tools to be called from Python\n", + "* This enables all manner of geoprocessing to be done in an automated fashion, as ArcPy can replicate most of the functionality of ArcGIS for Desktop\n", + "* While ArcGIS comes with its own version of Python, ArcPy can be used with other Python installations, as we will do in this course\n", + "* For reference, see the documentation for your version of ArcGIS. The help page for each tool has a description of the Python syntax and (usually) short example scripts.\n", + " * For instance: http://desktop.arcgis.com/en/arcmap/10.4/tools/data-management-toolbox/clip.htm (scroll down)\n", + "* Another resource: [Penn State online course](https://www.e-education.psu.edu/geog485/node/91) covering the same subject matter as this lecture, GIS automation with Python.\n", + "* Possibly the best resource of all: Google\n", + " * While not as well supported as the really popular Python packages (i.e. NumPy, matplotlib, etc.), enough people use ArcPy that you will find decent support on forums like Stack Overflow" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Example Project: Fun with MODIS LST Data\n", + "\n", + "---\n", + "\n", + "* To get a feel for automating typical GIS tasks, we will work through a short project where we:\n", + " * download some MODIS land surface temperature (LST) data\n", + " * extract the bands we want to GeoTIFF\n", + " * perform some analysis, including raster math and conditionals\n", + " * resample the output\n", + " * ... and repeat\n", + "\n", + "### Test ArcPy" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import arcpy" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Download data\n", + "\n", + "---\n", + "\n", + "Download this MODIS image: ftp://ladsweb.nascom.nasa.gov/allData/6/MOD11A2/2016/201/MOD11A2.A2016201.h11v05.006.2016242234243.hdf \n", + "\n", + "Copy it to the directory where you want to store your data.\n", + "\n", + "### Set working directory\n", + "\n", + "---\n", + "\n", + "ArcPy needs to know where to look for inputs and save outputs on your computer. You can specify an absolute path for every file, meaning a path including not only the file name but all the parent directories, including the drive name (i.e. C:\\\\Users\\\\abhubba1\\\\Documents\\\\Python Scripts\\\\DEVELOP_class\\\\thatwasalotoftyping.tif). However, this can grow tedious, so it is usually easier to set the workspace environment (more on these later) to a location of your choosing:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "arcpy.env.workspace = \"C:\\\\Users\\\\abhubba1\\\\Documents\\\\Python Scripts\\\\DEVELOP_class\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Change this path to the directory where you saved the MODIS data in the above step. Now, all you need to provide is a file name, and ArcPy will automatically go to this folder.\n", + "\n", + "Another consideration is that, by default, ArcPy will not permit you to overwrite files that already exist. When you are developing a script, this is usually not what you want (but not always - be careful!). Allow ArcPy to overwrite output as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "arcpy.env.overwriteOutput = True" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Extract from HDF to GeoTIFF\n", + "\n", + "---\n", + "\n", + "With many data types, we would be ready to jump straight in to geoprocessing. However, with MODIS data we have an immediate hurdle: HDF. Fully-featured handling of HDF files requires special Python packages, like h5py, as covered in the previous lecture. For our project, however, this would be overkill. Instead, we can use ArcPy's Extract SubDataset to pull out the data we want into a GeoTIFF.\n", + "\n", + "Let's extract the daytime LST data, which is subdataset 0:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "MODIS_file = \"MOD11A2.A2016201.h11v05.006.2016242234243.hdf\"\n", + "day_LST = MODIS_file.rstrip(\".hdf\") + \"_dayLST.tif\"\n", + "arcpy.ExtractSubDataset_management(MODIS_file, day_LST, subdataset_index=0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "_Note:_ `rstrip` is a string method that removes the string given in the parentheses from the end (right side) of the input string.\n", + "\n", + "To inspect the output, open ArcMap and load this file. Add an imagery basemap as well and compare the two, noting areas of high and low temperature values. Do you see anything strange?\n", + "\n", + "### Perform analysis\n", + "\n", + "---\n", + "\n", + "#### Raster Math\n", + "\n", + "The above data has been scaled to allow it to be stored in an integer format, but this makes it difficult to interpret. To convert it back to Kelvin, we must apply the scale factor, which in this case is 0.02. To do this, we will perform some raster math." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "arcpy.CheckOutExtension(\"spatial\")\n", + "\n", + "scale = 0.02\n", + "day_LST_sc = arcpy.Raster(day_LST) * scale\n", + "\n", + "arcpy.CheckInExtension(\"spatial\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "ArcPy allows basic math operations to be applied on a pixel-by-pixel basis with Python syntax, but it is necessary to create an ArcPy Raster object from your raster file on disk. The math operation returns another ArcPy Raster object, which we have assigned to `day_LST_sc`. Think of these Raster objects in an analogous manner to the data types we covered before, like string, float, int, etc. They can be used in other math operations and passed to some (but not all) ArcGIS tools that take raster input.\n", + "\n", + "Notice the lines before and after the middle block. Raster math requires the Spatial Analyst extension, so it is necessary to check out a license for this extension first. Checking the license back in at the end is not necessary for the code to function, but it is good practice, because your organization may have a license server with limited keys.\n", + "\n", + "At the moment, our scaled daytime LST raster only exists in memory - we have not saved it to disk. To do so:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "path = MODIS_file.rstrip(\".hdf\") + \"_scale.tif\"\n", + "day_LST_sc.save(path)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Math with multiple rasters\n", + "\n", + "In a similar manner, two or more rasters can be used in a formula using simple Python syntax. But first, we need two rasters! Let's repeat the above steps with the nighttime LST band (subdataset 4), from the same MODIS file:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "arcpy.CheckOutExtension(\"spatial\")\n", + "\n", + "MODIS_file = \"MOD11A2.A2016201.h11v05.006.2016242234243.hdf\"\n", + "night_LST = MODIS_file.rstrip(\".hdf\") + \"_nightLST.tif\"\n", + "arcpy.ExtractSubDataset_management(MODIS_file, night_LST, subdataset_index=4)\n", + "\n", + "scale = 0.02\n", + "night_LST_sc = arcpy.Raster(night_LST) * scale\n", + "\n", + "arcpy.CheckInExtension(\"spatial\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "_Note:_ In this case, we did not save the scaled raster to disk. This is not actually necessary to use it in later operations, and not saving intermediates is a good way to conserve disk space.\n", + "\n", + "_Another Note:_ In these examples, we are checking the spatial analyst extension in and out each time, but, if you are writing a long script, it is only necessary to do this once, at the beginning and end.\n", + "\n", + "Now, let's compute the difference between the daytime and nighttime LST:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "arcpy.CheckOutExtension(\"spatial\")\n", + "\n", + "diff = day_LST_sc - night_LST_sc\n", + "diff_path = MODIS_file.rstrip(\".hdf\")+\"_diff.tif\"\n", + "diff.save(diff_path)\n", + "\n", + "arcpy.CheckInExtension(\"spatial\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This will create a new Raster object where each pixel corresponds to the difference between the two old rasters. Open this new raster in ArcMap and compare it to a basemap.\n", + "\n", + "#### Conditionals\n", + "\n", + "Suppose we want to know where the above difference exceeds a certain threshold. We can answer this question using the Con tool, available with the Spatial Analyst extension." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "arcpy.CheckOutExtension(\"spatial\")\n", + "\n", + "thres = 15\n", + "diff_thres = arcpy.sa.Con(diff > thres, 1, 0)\n", + "diff_thres_path = MODIS_file.rstrip(\".hdf\")+\"_thres.tif\"\n", + "diff_thres.save(diff_thres_path)\n", + "\n", + "arcpy.CheckInExtension(\"spatial\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The middle block of code will create and save a raster that contains a 1 wherever the day-night difference exceeds 15, and a 0 wherever it does not.\n", + "\n", + "### Resample\n", + "\n", + "---\n", + "\n", + "We now have a nice Boolean raster that we could use as a mask in some larger project. However, what if the other members of our project are working with the MODIS red and NIR bands, which are 250 m resolution? We can be helpful, and resample our raster to this resolution." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "out_cellsize = 231.6563583\n", + "res = MODIS_file.rstrip(\".hdf\") + \"_res.tif\"\n", + "arcpy.Resample_management(diff_thres, res, cell_size=out_cellsize)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We could have performed this resampling at any point in our processing chain, but we chose to do so at the end. Why might this be best?\n", + "\n", + "### Repeat as necessary\n", + "\n", + "---\n", + "\n", + "We have output (hopefully), but only for one raster file, and when has a project ever involved only one raster file?? The efficiency of scripting ArcGIS in Python becomes apparent when one must do the same thing many times, which should sound like something you have already learned... loops!\n", + "\n", + "First, we'll need some more data. Since we already have a summer image, let's download files from:\n", + "* winter: ftp://ladsweb.nascom.nasa.gov/allData/6/MOD11A2/2016/017/MOD11A2.A2016017.h11v05.006.2016234002041.hdf\n", + "* spring: ftp://ladsweb.nascom.nasa.gov/allData/6/MOD11A2/2016/105/MOD11A2.A2016105.h11v05.006.2016242152502.hdf\n", + "* and fall: ftp://ladsweb.nascom.nasa.gov/allData/6/MOD11A2/2016/289/MOD11A2.A2016289.h11v05.006.2016302010943.hdf\n", + "\n", + "Move these to the same folder you have been using.\n", + "\n", + "Now, let's put everything we did above in a loop:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "u'CheckedIn'" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import arcpy\n", + "\n", + "arcpy.env.workspace = \"C:\\\\Users\\\\abhubba1\\\\Documents\\\\Python Scripts\\\\DEVELOP_class\"\n", + "arcpy.env.overwriteOutput = True\n", + "arcpy.CheckOutExtension(\"spatial\")\n", + "\n", + "scale = 0.02\n", + "thres = 15\n", + "out_cellsize = 231.6563583\n", + "MODIS_files = [\"MOD11A2.A2016017.h11v05.006.2016234002041.hdf\", \n", + " \"MOD11A2.A2016105.h11v05.006.2016242152502.hdf\", \n", + " \"MOD11A2.A2016201.h11v05.006.2016242234243.hdf\", \n", + " \"MOD11A2.A2016289.h11v05.006.2016302010943.hdf\"]\n", + "\n", + "for f in MODIS_files:\n", + " \n", + " #Extract from HDF\n", + " day_LST = f.rstrip(\".hdf\") + \"_dayLST.tif\"\n", + " arcpy.ExtractSubDataset_management(f, day_LST, subdataset_index=0)\n", + " night_LST = f.rstrip(\".hdf\") + \"_nightLST.tif\"\n", + " arcpy.ExtractSubDataset_management(f, night_LST, subdataset_index=4)\n", + " \n", + " #Scale\n", + " day_LST_sc = arcpy.Raster(day_LST) * scale\n", + " night_LST_sc = arcpy.Raster(night_LST) * scale\n", + " \n", + " #Perform subtraction\n", + " diff = day_LST_sc - night_LST_sc\n", + " diff_path = f.rstrip(\".hdf\")+\"_diff.tif\"\n", + " diff.save(diff_path)\n", + " \n", + " #Apply conditional\n", + " diff_thres = arcpy.sa.Con(diff > thres, 1, 0)\n", + " diff_thres_path = f.rstrip(\".hdf\")+\"_thres.tif\"\n", + " diff_thres.save(diff_thres_path)\n", + " \n", + " #Resample\n", + " res = f.rstrip(\".hdf\") + \"_res.tif\"\n", + " arcpy.Resample_management(diff_thres, res, cell_size=out_cellsize)\n", + " \n", + "arcpy.CheckInExtension(\"spatial\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "_Tip:_ If you need to get the names of many files in a folder and don't want to do a lot of tedious typing, check out the [glob](https://docs.python.org/2/library/glob.html) package.\n", + "\n", + "\n", + "\n", + "# Other Considerations\n", + "\n", + "---\n", + "\n", + "### Environments\n", + "\n", + "---\n", + "\n", + "ArcGIS uses environment settings to control the specific characteristics of your current geoprocessing environment. In the above script, we are using two already: workspace and overwrite output. Environments are a powerful way to control the exact way in which your script executes. As another example, let's say that within our MODIS tile, we only really care about Virginia (because it is objectively better than all of these other states), and we want to limit output to this state.\n", + "\n", + "One approach might be to clip each input raster with a shapefile, but we have to do this for each input. In this case, we only have two per iteration, but in other projects we might have a lot more. A more elegant approach is to use the mask environment setting.\n", + "\n", + "Download [this](https://drive.google.com/file/d/0B8toI67HoVSrVzV3aUcwc3FBcG8/view?usp=sharing) shapefile of Virginia, and extract it to your work directory. Then, rerun our script with the mask environment set at the top:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import arcpy\n", + "\n", + "arcpy.env.workspace = \"C:\\\\Users\\\\abhubba1\\\\Documents\\\\Python Scripts\\\\DEVELOP_class\"\n", + "arcpy.env.overwriteOutput = True\n", + "arcpy.env.mask = \"Virginia.shp\"\n", + "arcpy.CheckOutExtension(\"spatial\")\n", + "\n", + "scale = 0.02\n", + "thres = 15\n", + "out_cellsize = 231.6563583\n", + "MODIS_files = [\"MOD11A2.A2016017.h11v05.006.2016234002041.hdf\", \n", + " \"MOD11A2.A2016105.h11v05.006.2016242152502.hdf\", \n", + " \"MOD11A2.A2016201.h11v05.006.2016242234243.hdf\", \n", + " \"MOD11A2.A2016289.h11v05.006.2016302010943.hdf\"]\n", + "\n", + "for f in MODIS_files:\n", + " \n", + " #Extract from HDF\n", + " day_LST = f.rstrip(\".hdf\") + \"_dayLST.tif\"\n", + " arcpy.ExtractSubDataset_management(f, day_LST, subdataset_index=0)\n", + " night_LST = f.rstrip(\".hdf\") + \"_nightLST.tif\"\n", + " arcpy.ExtractSubDataset_management(f, night_LST, subdataset_index=4)\n", + " \n", + " #Scale\n", + " day_LST_sc = arcpy.Raster(day_LST) * scale\n", + " night_LST_sc = arcpy.Raster(night_LST) * scale\n", + " \n", + " #Perform subtraction\n", + " diff = day_LST_sc - night_LST_sc\n", + " diff.save(f.rstrip(\".hdf\")+\"_diff.tif\")\n", + " \n", + " #Apply conditional\n", + " diff_thres = arcpy.sa.Con(diff > thres, 1, 0)\n", + " diff_thres.save(f.rstrip(\".hdf\")+\"_thres.tif\")\n", + " \n", + " #Resample\n", + " res = f.rstrip(\".hdf\") + \"_res.tif\"\n", + " arcpy.Resample_management(diff_thres, res, cell_size=out_cellsize)\n", + " \n", + "arcpy.CheckInExtension(\"spatial\")\n", + "\n", + "arcpy.env.workspace = None\n", + "arcpy.env.overwriteOutput = None\n", + "arcpy.env.mask = None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Inspect the output. If everything worked properly, you should only see data over the scenic Commonwealth of Virginia\n", + "\n", + "__Very important note:__ The nature of environment settings is that they apply to your _entire processing environment_, which means they will stick around for future processes you run in the same session of Python. Old environment settings can lead to mysterious errors, confusion, and general gnashing of teeth. I highly recommend that you clear out your environment settings at the end of your script by setting them to `None`, as I have done above. Even better, clear them immediately after they are no longer needed, in case your script crashes before it completes.\n", + "\n", + "### Editing locks\n", + "\n", + "---\n", + "\n", + "Whenever a program is using a file, it creates a lock that prevents other programs from editing the same file. Python is no different. In general, these should disappear after a script is finished executing. For reasons that are not entirely clear to me, ArcPy often retains locks on ArcPy objects created by a script even said script has completed. This will create problems if you then try to edit the file that object is pointing to in a different program. Therefore, it is also good practice to clear variables that point to ArcPy objects after they are no longer necessary. To accomplish that in our script, add the following to the end:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "day_LST_sc = None\n", + "night_LST_sc = None\n", + "diff = None\n", + "diff_thres = None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "On the other side of the same coin, Python will not be able to edit a file that is locked by another application. In the context of geoprocessing, this can happen because you ran your code, viewed the output in ArcMap, and tried to rerun your code without removing said output from ArcMap. Some of you may have already experienced this phenomenon during this lesson. If you're me, this happens _all the time_..." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Lectures_201709/readme.md b/Lectures_201709/readme.md new file mode 100644 index 0000000..e69de29 From db06eae058dd93f1431b24908218521a76cbaac3 Mon Sep 17 00:00:00 2001 From: alfredhub Date: Sun, 24 Sep 2017 15:16:13 -0400 Subject: [PATCH 18/20] Date correction, small clarifications, etc. --- Lectures_201709/Week_01/setup_intro.ipynb | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Lectures_201709/Week_01/setup_intro.ipynb b/Lectures_201709/Week_01/setup_intro.ipynb index a51370d..054cd50 100644 --- a/Lectures_201709/Week_01/setup_intro.ipynb +++ b/Lectures_201709/Week_01/setup_intro.ipynb @@ -9,11 +9,11 @@ "\n", "---\n", "\n", - "# Setup & Introduction\n", + "# Setup & Introduction to Python\n", "\n", "### Goddard Space Flight Center\n", "\n", - "#### June 5, 2017\n", + "#### September 20, 2017\n", "\n", "---" ] @@ -79,7 +79,9 @@ "\n", "3. You should see the output on the screen.\n", "\n", - "__Caveat:__ Your prompt should be at the directory containg the helloworld.py script. Perform an ```ls``` (Mac/Linux) or ```dir``` (Windows) to see if that file is in your current working directory." + "__Caveat:__ Your prompt should be at the directory containg the helloworld.py script. Perform an ```ls``` (Mac/Linux) or ```dir``` (Windows) to see if that file is in your current working directory.\n", + "\n", + "To access a more feature-rich Python code editor, search for and open the __Spyder__ application, which should have been installed with Anaconda. This program features a code editor on the left, a Python console on the lower right, some contextual help on the upper right, and an assortment of helpful tools across the top of the screen." ] }, { @@ -106,7 +108,9 @@ "\n", "5. Press __```Shift-Enter```__, __```Cntrl-Enter```__, or click __Cells -> Run Cells__ or use the Play button near the top of the page.\n", "6. You will see the output now.\n", - "7. Exit via closing the browser windows and stopping the server running (Cntrl + Enter) in the terminal/command prompt." + "7. Exit via closing the browser windows and stopping the server running (Cntrl + Enter) in the terminal/command prompt.\n", + "\n", + "_Note:_ The lectures for this course (i.e. what you are looking at RIGHT NOW) are Jupyter notebooks, and can be opened and run using the above instructions." ] }, { @@ -139,7 +143,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# store inside a variable\n", @@ -150,7 +156,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# Imports\n", From b296b3cfb4419f7ec54d5f5738263008017f8936 Mon Sep 17 00:00:00 2001 From: alfredhub Date: Sun, 24 Sep 2017 15:17:11 -0400 Subject: [PATCH 19/20] Added section on NumPy --- Lectures_201709/Week_02/intro_cont.ipynb | 191 ++++++++++++++++++++++- 1 file changed, 183 insertions(+), 8 deletions(-) diff --git a/Lectures_201709/Week_02/intro_cont.ipynb b/Lectures_201709/Week_02/intro_cont.ipynb index bb52a75..2196911 100644 --- a/Lectures_201709/Week_02/intro_cont.ipynb +++ b/Lectures_201709/Week_02/intro_cont.ipynb @@ -9,11 +9,11 @@ "\n", "---\n", "\n", - "# Introduction Continued\n", + "# Basic Python Continued\n", "\n", "### Goddard Space Flight Center\n", "\n", - "#### June 13, 2017\n", + "#### September 25, 2017\n", "\n", "---" ] @@ -107,6 +107,173 @@ "> _pickles..._ Python has this thing called pickles where you \"temporarily\" store data. It's a binary file, but is only for small storage that is needed for a short time." ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### NumPy: Multidimensional Arrays in Python\n", + "\n", + "---\n", + "\n", + "__[numpy](https://docs.scipy.org/doc/numpy-1.13.0/reference/)__ is short for numerical Python, and is a very powerful and well-supported package that adds multidimensional arrays and numerous mathematical and statistical operations to Python. An even more feature-rich and powerful option is __[scipy](https://docs.scipy.org/doc/scipy/reference/)__, which expands on __```numpy```__.\n", + "\n", + "The core element of __```numpy```__ is the n-dimensional array, or ndarray. To create an array, one has multiple options, including entering numbers directly:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1 5 8]\n", + " [5 7 2]]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "a = np.array([[1,5,8],[5,7,2]])\n", + "print(a)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "...converting from a list or other iterable:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[5 6 8 3 8 4]\n" + ] + } + ], + "source": [ + "l = [5,6,8,3,8,4]\n", + "a = np.array(l)\n", + "print(a)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "...or using one of the specialized constructor functions to make arrays full of ones, random values, or, in this case, zeros:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 0. 0. 0.]\n", + " [ 0. 0. 0.]\n", + " [ 0. 0. 0.]]\n" + ] + } + ], + "source": [ + "a = np.zeros((3,3))\n", + "print(a)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are also ways to read text files directly into NumPy arrays (```loadtxt``` or ```genfromtext```).\n", + "\n", + "Once you have an array, there are numerous operations available to you, both element-wise (i.e. performed on each value of the array):" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 6 8 17]\n", + " [ 5 10 9]]\n", + "[[15 9 27]\n", + " [ 0 9 21]]\n" + ] + } + ], + "source": [ + "a = np.array([[1,5,8],[5,7,2]])\n", + "b = np.array([[5,3,9],[0,3,7]])\n", + "c = a + b\n", + "print(c)\n", + "d = b * 3\n", + "print(d)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "...and across an entire array:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "28\n", + "4.5\n" + ] + } + ], + "source": [ + "total = np.sum(a)\n", + "print(total)\n", + "avg = np.mean(b)\n", + "print(avg)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "NumPy has many other cool abilities, like performing math along specific axes of an array (e.g. summing all of the columns of a 2D array) and using masks. Finally, particularly enthusiastic geospatial analysts can apply NumPy's extensive capabilities to raster images by reading said rasters into NumPy and then manipulating to their heart's content. Two ways to perform this conversion are 1) __[GDAL](https://github.com/edmondb/developython/blob/master/Archive/Lectures_201702/Week_05/week_5.ipynb)__, a powerful raster analysis program covered in a lecture from a previous term (see link) or 2) ```arcpy.RasterToNumPyArray```, a simpler but more constrained option.\n", + "\n", + "However, for analysis problems where NumPy or SciPy's mathematical and statistical capabilities are not necessary, processing rasters directly in ArcPy (to be covered in the next lecture), will be most straightforward." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -115,7 +282,7 @@ "\n", "---\n", "\n", - "The __[h5py]()__ and __[netCDF4]()__ Python packages are very useful for reading structured data (multidimensional, multivariate, time-series, etc.). Here, we are going to look at reading and visualizing some structured data." + "The __[h5py](http://docs.h5py.org/en/latest/)__ and __[netcdf4](http://unidata.github.io/netcdf4-python/)__ Python packages are very useful for reading structured data (multidimensional, multivariate, time-series, etc.). Here, we are going to look at reading and visualizing some structured data." ] }, { @@ -162,7 +329,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "%matplotlib inline\n", @@ -177,7 +346,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "z = f.variables['retrieved_wind_speed']" @@ -186,7 +357,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "z.dimensions" @@ -200,13 +373,15 @@ "\n", "---\n", "\n", - "Matplotlib is basically Python's replacement for Matlab. Here is an example of plotting data from our file." + "Matplotlib is basically Python's replacement for Matlab's plotting capabilities. Here is an example of plotting data from our file." ] }, { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "fig = plt.figure(figsize = (20,20))\n", From 7973b9bb1557feb1a96075266bb1fb0260dcb95e Mon Sep 17 00:00:00 2001 From: alfredhub Date: Mon, 16 Oct 2017 09:28:12 -0400 Subject: [PATCH 20/20] Corrected date --- Lectures_201709/Week_03/GIS_programming.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lectures_201709/Week_03/GIS_programming.ipynb b/Lectures_201709/Week_03/GIS_programming.ipynb index aa6e43f..2b0b696 100644 --- a/Lectures_201709/Week_03/GIS_programming.ipynb +++ b/Lectures_201709/Week_03/GIS_programming.ipynb @@ -13,7 +13,7 @@ "\n", "### Goddard Space Flight Center\n", "\n", - "#### March 6, 2017\n", + "#### October 16, 2017\n", "\n", "---\n", "\n",