Raplee_Kaibab Jobs

Raplee_Kaibab Jobs

Background

Weathering limited hillslopes exhibit topographic asymmetry in both the size and proportion of cliff abundances along opposing aspects, i.e. south and west facing hillslopes versus north and east facing hillslopes. The mechanisms which lead to these formations are thought to be driven by variations in the net energy balance of the landscape. The energy balance is influenced by differences in hillslope angle, aspect of exposure, and location relative to other topographic features (i.e. daily topographic shading) which influence the timing and quantity of solar insolation and the average air and surface temperatures.

GIS algorithms for calculating solar insolation are resource intensive and time consuming. To alleviate the bottleneck in computation time calculations were performed using a distributed computing workflow which uses the Cooperative Computing Lab’s (CCL) Makeflow (Albrect et al. 2012) and Work Queue (Bui et al. 2011) on the San Diego Super Computing (SDSC) Comet.

Hillslopes in the northern hemisphere tend to have the highest vegetation cover on north and east aspects, and the least on south and west aspects. We hypothesized that this pattern is partly a result of potential evapotranspiration being a function of the product of solar insolation and a nonlinear function of temperature. We evaluate this hypothesis by quantifying potential evapotranspiration in a model framework that resolves the diurnal cycles of both solar insolation and temperature. 

Here we propose a modification to the Hamon equation (Hamon 1961, Haith and Shoenaker 1987), 

PET = 2.1Ht2es / Tt+273.2

where

PET is the potential evaporation/transpiration [mm day-1]

Ht is the average number of hours daylight day-1 during the month of day t

e saturated vapor pressure at temperature T [kPa], calculated from the es_min  and es_max

Tt is the mean temperature on day t [C] - which we influence using the solar insolation [Si] ratio against mean monthly temperature. Si is the ratio of total_sun_day / flat_sun_day

In the proposed model we take the ratio Sand modify surface temperature based on the overall proportion of daily solar irradiation relative to a flat unshaded surface at the reference elevation (calculated from GRASS r.sun). we also use the total number of hours of sunlight calculated by r.sun in the H term. 

To normalize the total (global) insolation received at the surface and the EarthEnv MODIS derived monthly cloudiness layer (Wilson and Jetz 2016) to correct for the clear-sky radiation model. 

Global radiation * (1 - Cloudiness/2).

Methods

 

GDAL warping and coarsening. Converted the projection to WGS84 UTM Zone 12N, adjusted the pixel size to 16m and 32m.

gdalwarp -overwrite -s_srs "+proj=lcc +lat_1=25 +lat_2=60 +lat_0=42.5 +lon_0=-100 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs" -t_srs EPSG:32612 -r near -tr 16 16 -multi -of GTiff F:\raplee_kaibab\raplee\hand_run\raplee_annual_pet_trad.tif F:/raplee_kaibab/raplee/PET/annual_pet.tif

 

 

DEM generation

The Raplee Ridge lidar were flown by the National Center for Airborne Laser Mapping (NCALM); those data are hosted by the OpenTopography.org data service. A 2 meter (m) DEM was generated by OpenTopo using Martin Isenberg's triangular irregular network (TIN) tin2dem method.

The Kaibab Plateau DEM data were flown by Watershed Sciences and provided by the United States Forest Service Region 3 office. A two meter DEM was generated by interpolation of the original 1m vendor derived bare earth surface model. 

Solar irradiation

To calculate monthly solar irradiation and average monthly temperatures we used an open-source GIS (GRASS v6.4 2015) solar insolation algorithm called r.sun (Hofierka et al. 2007). R.sun calculates daily global irradiation (direct beam, diffuse, and reflected) for clear sky conditions. R.sun also incorporates topographic shading from nearby features. We summed the daily layers, calculated using the default settings for surface albedo (0.2) and Linke atmospheric turbidity (3.0) with a 15 minute sun angle interval to monthly solar irradiation maps. The integration of daily values across an entire month reduces the angular step-spacing between 15 minute intervals as the day lengths change over the course of the month. 

Example of a single day (Julian day 289, October 16) versus monthly average for the month of October. The 15 minute interval for calculating sun hours per day is obvious in the Julian date, but is less clear in the Global radiation surface (although it is still present)

 Daily (Julian Day 289)Monthly (October)
Sun Hours (hours day)
Global Radiation (w m2)

 

For the climate variable we use the 1km DAYMET data product (Thornton et al. 2014) for monthly temperature (minimum and maximum) averaged for the years 1980-2014. The DAYMET data are interpolated using a bicubic spline to match the resolution of the 2m DEM.

Example of two predominantly facing southwest versus southeast aspect cliffs along the eastern edge of the Kaibab Plateau.

 SW Aspect (Top Left) vs SE Aspect (Bottom Left)
Max Temperature (C)
Effective Precipitation (cm month)
  
PET (mm day-1)

 

We processed the Raplee DEM (38 Mb) on Comet using the effective energy and mass transfer (EEMT) workflow available on GitHub: https://github.com/tyson-swetnam/eemt.

Scripts

After the jobs completed on Comet we wrote two shell scripts to calculate the high resolution temperature models in QGIS.

Import and upscale the rasters:

import_eemt_input_raplee.sh

import_eemt_input_kaibab.sh

Calculate input parameters for EEMT, including topographically modified temperature:

calculate_local_temps.sh

Calculating local temperature using solar irradiation:

rsun_modified_hamon_equation.sh

QGIS Python Code for calculating modified Hamon's Equation:

#######################################
###This script imports the necessary layers for calculating Hamon Equation PET
from osgeo import gdal
from osgeo import osr
from PyQt4.QtCore import QFileInfo, QSettings
from qgis.core import QgsRasterLayer, QgsCoordinateReferenceSystem
from qgis.analysis import QgsRasterCalculator, QgsRasterCalculatorEntry
import processing,math,os,sys

## User must set working directory and the filename of the DEM here before executing run
###Set the working directory for the input data
input_Dir = 'F:/raplee_kaibab/kaibab/'
###Set the output directory for the products
output_Dir = 'F:/raplee_kaibab/kaibab/hand_run/'
os.mkdir(output_Dir, 0755)
dem_filename = 'kaibab_converted.tif'

#########################################
##GDAL import DEM to read the projection
###dem=raster
###e.g. dem = 'dem_10m.tif'
dem = gdal.Open(os.path.join(input_Dir,dem_filename))
gt = dem.GetGeoTransform()
xorigin, xcellsize, xrotation, yorigion, yrotation, ycellsize = gt

##Get and Print Projection Information
projInfo=dem .GetProjection()
print projInfo

###Establish number of days per month (for daily calculations to montly)
month_days = {'jan': 31,'feb': 28, 'mar': 31, 'apr': 30, 'may': 31, 'jun': 30, 'jul':31, 'aug': 31, 'sep': 30, 'oct': 31, 'nov': 30, 'dec': 31}
demLayer  = QgsRasterLayer(os.path.join(input_Dir,dem_filename), "dem")
if not demLayer.isValid(): print "DEM Layer failed to load!"

##Load raster layer into canvas
QgsMapLayerRegistry.instance().addMapLayer(demLayer)
 
###Print Extent of the DEM layer (for use with raster calculator)
print demLayer.extent().xMinimum(), demLayer.extent().xMaximum()
print demLayer.extent().yMinimum(), demLayer.extent().yMaximum()
print demLayer.width(), demLayer.height()
name = demLayer.name()
print name
bands = demLayer.bandCount()
print bands

########Local Topographically Corrected Temperature (modified by using the global solar radiation)
print "Calculating locally corrected min and max temperature (maximum temp modified by solar angle, min temp assumed at night)"
jan_S_i = processing.runalg("saga:rastercalculator",os.path.join(input_Dir,'global/monthly/flat_total_sun_jan_sum.tif'),os.path.join(input_Dir,'global/monthly/total_sun_jan_sum.tif'),"b/a",False,8,os.path.join(output_Dir,'jan_S_i.sdat'))
src_ds = gdal.Open(os.path.join(output_Dir,'jan_S_i.sdat'))
##Open output format driver, see gdal_translate --formats for list
format = "GTiff"
driver = gdal.GetDriverByName( format )

##Output to new format
dst_ds = driver.CreateCopy(os.path.join(output_Dir,'jan_S_i.tif'), src_ds, 0 )

##Properly close the datasets to flush to disk
dst_ds = None
src_ds = None
jan_S_i = os.path.join(output_Dir,'jan_S_i.tif')
jan_S_iLayer  = QgsRasterLayer(jan_S_i, "jan_S_i")
if not jan_S_iLayer.isValid(): print "jan_S_i Layer failed to load!"
####Load raster layer into canvas
QgsMapLayerRegistry.instance().addMapLayer(jan_S_iLayer)
######Topographically modified minimum temperatures are at night - values do not include solar radiation e.g. tmin_local = tmin_topo
######Topographically modified max temperature
jan_tmax_topo = processing.runalg("saga:rastercalculator",os.path.join(output_Dir,'jan_tmax_local.tif'),os.path.join(output_Dir,'jan_S_i.tif'),"a+(b-(1/b))",False,8,os.path.join(output_Dir,'jan_tmax_topo.sdat'))
src_ds = gdal.Open(os.path.join(output_Dir,'jan_tmax_topo.sdat'))
##Open output format driver, see gdal_translate --formats for list
format = "GTiff"
driver = gdal.GetDriverByName( format )

##Output to new format
dst_ds = driver.CreateCopy(os.path.join(output_Dir,'jan_tmax_topo.tif'), src_ds, 0 )
##Properly close the datasets to flush to disk
dst_ds = None
src_ds = None
jan_tmax_topo = os.path.join(output_Dir,'jan_tmax_topo.tif')
jan_tmax_topoLayer  = QgsRasterLayer(jan_tmax_topo, "jan_tmax_topo")
if not jan_tmax_topoLayer.isValid(): print "jan_tmax_topo Layer failed to load!"

####Load raster layer into canvas
QgsMapLayerRegistry.instance().addMapLayer(jan_tmax_topoLayer)

######Topographically modified mean temperature
jan_tmean_topo = processing.runalg("saga:rastercalculator",os.path.join(output_Dir,'jan_tmax_topo.tif'),os.path.join(output_Dir,'jan_tmin_local.tif'),"(a+b)/2",False,8,os.path.join(output_Dir,'jan_tmean_topo.sdat'))
src_ds = gdal.Open(os.path.join(output_Dir,'jan_tmean_topo.sdat'))
##Open output format driver, see gdal_translate --formats for list
format = "GTiff"
driver = gdal.GetDriverByName( format )
##Output to new format
dst_ds = driver.CreateCopy(os.path.join(output_Dir,'jan_tmean_topo.tif'), src_ds, 0 )
##Properly close the datasets to flush to disk
dst_ds = None
src_ds = None
jan_tmean_topo = os.path.join(output_Dir,'jan_tmean_topo.tif')
jan_tmean_topoLayer  = QgsRasterLayer(jan_tmean_topo, "jan_tmean_topo")
if not jan_tmean_topoLayer.isValid(): print "jan_tmean_topo Layer failed to load!"
####Load raster layer into canvas
QgsMapLayerRegistry.instance().addMapLayer(jan_tmean_topoLayer)

########Begin calculating the input parameters for PET
print "Calculating local Potential Evaporation-Transpiration (PET) for EEMT-Trad using Hamon's Equation"
######Calculate es_tmax
jan_es_tmax = processing.runalg("saga:rastercalculator",os.path.join(output_Dir,'jan_tmax_topo.tif'),None,"0.6108*exp((17.27*a)/(a+237.3))",False,8,os.path.join(output_Dir,'jan_es_tmax.sdat'))
src_ds = gdal.Open(os.path.join(output_Dir,'jan_es_tmax.sdat'))
##Open output format driver, see gdal_translate --formats for list
format = "GTiff"
driver = gdal.GetDriverByName( format )
##Output to new format
dst_ds = driver.CreateCopy(os.path.join(output_Dir,'jan_es_tmax.tif'), src_ds, 0 )
##Properly close the datasets to flush to disk
dst_ds = None
src_ds = None
jan_estmax = os.path.join(output_Dir,'jan_es_tmax.tif')
jan_estmaxLayer  = QgsRasterLayer(jan_estmax, "jan_estmax")
if not jan_estmaxLayer.isValid(): print "jan_es_tmax Layer failed to load!"
####Load raster layer into canvas
QgsMapLayerRegistry.instance().addMapLayer(jan_estmaxLayer)
######Calculate es_tmin
jan_es_tmin = processing.runalg("saga:rastercalculator",os.path.join(output_Dir,'jan_tmin_local.tif'),None,"0.6108*exp((17.27*a)/(a+237.3))",False,8,os.path.join(output_Dir,'jan_es_tmin.sdat'))
src_ds = gdal.Open(os.path.join(output_Dir,'jan_es_tmin.sdat'))
##Open output format driver, see gdal_translate --formats for list
format = "GTiff"
driver = gdal.GetDriverByName( format )
##Output to new format
dst_ds = driver.CreateCopy(os.path.join(output_Dir,'jan_es_tmin.tif'), src_ds, 0 )
##Properly close the datasets to flush to disk
dst_ds = None
src_ds = None
jan_estmin = os.path.join(output_Dir,'jan_es_tmin.tif')
jan_estminLayer  = QgsRasterLayer(jan_estmin, "jan_estmin")
if not jan_estminLayer.isValid(): print "jan_es_tmin Layer failed to load!"

####Load raster layer into canvas
QgsMapLayerRegistry.instance().addMapLayer(jan_estminLayer)
######Calculate the mean saturated vapor pressure (kPA)
####Mask pixels with lower than zero mean monthly temperatures for e_s
## When there are more than 2 inputs you need to generate a separate input_params input
input_params =[os.path.join(output_Dir,'jan_es_tmin.sdat'),os.path.join(output_Dir,'jan_es_tmax.sdat')]
jan_e_s = processing.runalg("saga:rastercalculator",os.path.join(output_Dir,'jan_tmean_topo.sdat'),input_params,"ifelse(lt(a,0),0,(b+c)/2)",False,8,os.path.join(output_Dir,'jan_e_s.sdat'))
src_ds = gdal.Open(os.path.join(output_Dir,'jan_e_s.sdat'))
##Open output format driver, see gdal_translate --formats for list
format = "GTiff"
driver = gdal.GetDriverByName( format )
##Output to new format
dst_ds = driver.CreateCopy(os.path.join(output_Dir,'jan_e_s.tif'), src_ds, 0 )
##Properly close the datasets to flush to disk
dst_ds = None
src_ds = None
jan_e_s = os.path.join(output_Dir,'jan_e_s.tif')
jan_esLayer  = QgsRasterLayer(jan_e_s, "jan_e_s")
if not jan_esLayer.isValid(): print "jan_e_s Layer failed to load!"
####Load raster layer into canvas
QgsMapLayerRegistry.instance().addMapLayer(jan_esLayer)

########PET (Traditional) calculation WARNING: Units are in mm^-1 day^-1 
########see https://dl.sciencesocieties.org/publications/vzj/supplements/14/vzj2014.07.0102-supplement.pdf
input_params=[os.path.join(output_Dir,'jan_e_s.tif'),os.path.join(output_Dir,'jan_tmean_topo.tif')]
jan_PET_trad = processing.runalg("saga:rastercalculator",os.path.join(input_Dir,'insol/monthly/hours_sun_jan_average.tif'),input_params,"ifelse(eq(b,0),0,(2.1*(a^2)*b)/(c+273.2))",False,8,os.path.join(output_Dir,'jan_PET_trad.sdat'))
src_ds = gdal.Open(os.path.join(output_Dir,'jan_PET_trad.sdat'))
##Open output format driver, see gdal_translate --formats for list
format = "GTiff"
driver = gdal.GetDriverByName( format )
##Output to new format
dst_ds = driver.CreateCopy(os.path.join(output_Dir,'jan_PET_trad.tif'), src_ds, 0 )
##Properly close the datasets to flush to disk
dst_ds = None
src_ds = None
jan_PET_trad = os.path.join(output_Dir,'jan_PET_trad.tif')
jan_PETtradLayer  = QgsRasterLayer(jan_PET_trad, "jan_PET_trad")
if not jan_PETtradLayer.isValid(): print "jan_PET_trad Layer failed to load!"
####Load raster layer into canvas
QgsMapLayerRegistry.instance().addMapLayer(jan_PETtradLayer)

Results

Comet Jobs

The job ran smoothly, taking ~ 5.27 hours in wall time; we was charged 827 SU.

The solar insolation output of the Raplee EEMT is ~44.5 Gb

Job time results:

real    316m9.945s
user    0m25.089s
sys     1m36.359s

Next, we ran the Kaibab DEM (98 Mb); there were several errors running the job on the Comet login. These are apparently caused by Comet's limit on the number of jobs it can have open at one time. After talking with Mats we ran the jobs on the xd-login (head node) using the Comet resources.

The job ran smoothly and completed. Job time results:

real    665m45.825s
user    0m46.228s
sys     3m15.032s

The solar insolation output of the Kaibab EEMT is 71 Mb. The output of Kaibab is ~96 Gb. 

Acknowledgements 

This work used the Extreme Science and Engineering Discovery Environment (XSEDE), which is supported by National Science Foundation grant number ACI-1053575. We thank Mats Ryge and Yan Liu for their assistance with the EEMT workflow, which was made possible through the XSEDE Extended Collaborative Support Service (ECSS) program.

The Kaibab lidar were funded by the Forest Service Southwestern Region to support landscape restoration and northern Goshawk research on the North Kaibab Plateau.  Lidar QA/QC was by the Southwestern Regional Office Remote Sensing Unit.

The Raplee Ridge lidar data acquisition and processing were completed by the National Center for Airborne Laser Mapping (NCALM - http://www.ncalm.org). NCALM funding provided by NSF's Division of Earth Sciences, Instrumentation and Facilities Program. EAR-1043051.

References

Albrecht, M., P. Donnelly, P. Bui, and D. Thain. 2012.Makeflow: A Portable Abstraction for Data IntensiveComputing on Clusters, Clouds, and Grids. In Workshop onScalable Workflow Enactment Engines and Technologies(SWEET) at ACM SIGMOD.

Bui P., D. Rajan, B. Abdul-Wahid, J. Izaguirre, and D.Thain. 2011. Work Queue + Python: A Framework ForScalable Scientific Ensemble Applications. In Workshop onPython for High Performance and Scientific Computing(PyHPC) at the ACM/IEEE International Conference forHigh Performance Computing, Networking, Storage, andAnalysis (Supercomputing).

GRASS Development Team, 2015. Geographic ResourcesAnalysis Support System (GRASS) Software, Version 6.4. Open Source Geospatial Foundation.http://grass.osgeo.org

Haith, D.A., and L.L. Shoenaker. 1987Generalized watershed loading functions for stream-flow nutrientsWater Resour. Bull. 23:471478doi:10.1111/j.1752-1688.1987.tb00825.x

Hamon W.R. 1961Estimating potential evapotranspirationProc. Am. Soc. Civ. Eng. 87:107120.

Hofierka, J., T. Huld, T. Cebecauer, and M. Šúri, 2007. Opensource solar radiation tools for environmental and renewableenergy applications. Environmental Software Systems, 448.(doi: 10.13140/2.1.3773.6001

Thornton, P.E., M.M. Thornton, B.W. Mayer, N. Wilhelmi,Y.Wei, R. Devarakonda, and R.B. Cook. 2014. Daymet:Daily Surface Weather Data on a 1-km Grid for NorthAmerica, Version 2. Data set. Available on-line[http://daac.ornl.gov] from Oak Ridge National LaboratoryDistributed Active Archive Center, Oak Ridge, Tennessee,USA.

John Towns, Timothy Cockerill, Maytal Dahan, Ian Foster, Kelly Gaither, Andrew Grimshaw, Victor Hazlewood, Scott Lathrop, Dave Lifka, Gregory D. Peterson, Ralph Roskies, J. Ray Scott, Nancy Wilkins-Diehr, "XSEDE: Accelerating Scientific Discovery", Computing in Science & Engineering, vol.16, no. 5, pp. 62-74, Sept.-Oct. 2014, doi:10.1109/MCSE.2014.80

Wilkins-Diehr, N and S Sanielevici, J Alameda, J Cazes, L Crosby, M Pierce, R Roskies. High Performance Computer Applications 6th International Conference, ISUM 2015, Mexico City, Mexico, March 9-13, 2015, Revised Selected Papers Gitler, Isidoro, Klapp, Jaime (Eds.) Springer International Publishing. ISBN 978-3-319-32243-8, 3-13, 2016. 10.1007/978-3-319-32243-8.

Wilson AM, Jetz W (2016) Remotely Sensed High-Resolution Global Cloud Dynamics for Predicting Ecosystem and Biodiversity Distributions. PLoS Biol 14(3): e1002415. doi:10.1371/journal. pbio.1002415