def prepare_actual_leaf_area_mat_from_dem(dem_ascii_filename, xsize, ysize, zsize, max_tree_ht=50): """ Takes the DEM text file, gets the number of grids in sim from the DEM, then pushes the actual leaf area values up (ground under the trees), so calculate how many cells we need to push the actual leaf area matrix up (each x,y position will be pushed up a different value, which corresponds to the elevation of terrain below this plot relative to the minimum elevation on the simulated grid, NOT relative to sea level). Parameters: dem_ascii_filename -- file name of the Digital Elevation Model to use (.txt) xsize,ysize,zsize -- the x width (E<-->W) of a plot, y length (N<-->S) of a plot, and z (vertical step size along tree for light computation, 1m) max_tree_ht=50 -- max height of tree permitted (light subroutine doesn't check above this) Returns: actual_leaf_area_mat -- contains -1 below ground and 0 above ground for each plot and air space above plot size: nx, ny, vertical space = (max_tree_ht+(max elevation in sim - min elevation in sim)) dem_offset_index_mat -- size: nx (# plots along E<-->W transect), ny (# plots along N<-->S transect), 1 each x,y contains an index, which specifies the height in meters above the minimum elevation in the simulation """ # get the number of cells in the z direction that will hold the plot actual leaf area data (w/o DEM adjustment) zcells = math.ceil(max_tree_ht / zsize) # read in the DEM which we will eventually place under the actual leaf area grid dem_mat = read_in_ascii(filename=dem_ascii_filename) #print 'dem value at x=1, y=3 is %s' %(dem_mat[1,3]) # get the number of grid points from the dem; the actual leaf area grid x,y dimension will be the same size nx, ny = dem_mat.shape # what is the minimum height of the dem terrain within simulated grid of plots dem_min = np.min(dem_mat) # The DEM will push the actual leaf area values up (ground under the trees), so calculate how # many cells we need to push the actual leaf area matrix up (each x,y position will be pushed up # a different value, which corresponds to the elevation of terrain below this plot # relative to the minimum elevation on the simulated grid, NOT relative to sea level). # dtype stored as integer, so as to use these values as indices later on. dem_offset_index_mat = np.array(np.round((dem_mat - dem_min) / zsize), dtype=np.int) additional_zcells = np.max( dem_offset_index_mat) #highest elevation on grid #print 'additonal z offset due to DEM is %s cells' %(additional_zcells) # calculate the total number of cells we need to hold the relativized DEM elevation # and trees that can reach up to the max_tree_ht total_zcells = zcells + additional_zcells # inititally the actual leaf area matrix is all zeros (no trees and no ground) actual_leaf_area_mat = np.zeros((nx, ny, total_zcells)) #print 'actual leaf area matrix shape is :' ,actual_leaf_area_mat.shape # fill in the below ground levels with the special flag (-1) GROUND_FLAG = -1 for x in xrange(nx): for y in xrange(ny): gnd_level = dem_offset_index_mat[x, y] actual_leaf_area_mat[x, y, :gnd_level] = GROUND_FLAG # We should now have an actual leaf area matrix with below ground levels flagged, # and above ground values empty and ready to be filled. To use this, # we need the light routine to be aware of the ground flag, as well # as provide the ground offset level where each tree level begins. return actual_leaf_area_mat, dem_offset_index_mat
def prepare_actual_leaf_area_mat_from_dem(dem_ascii_filename, xsize,ysize,zsize, max_tree_ht=50): """ Takes the DEM text file, gets the number of grids in sim from the DEM, then pushes the actual leaf area values up (ground under the trees), so calculate how many cells we need to push the actual leaf area matrix up (each x,y position will be pushed up a different value, which corresponds to the elevation of terrain below this plot relative to the minimum elevation on the simulated grid, NOT relative to sea level). Parameters: dem_ascii_filename -- file name of the Digital Elevation Model to use (.txt) xsize,ysize,zsize -- the x width (E<-->W) of a plot, y length (N<-->S) of a plot, and z (vertical step size along tree for light computation, 1m) max_tree_ht=50 -- max height of tree permitted (light subroutine doesn't check above this) Returns: actual_leaf_area_mat -- contains -1 below ground and 0 above ground for each plot and air space above plot size: nx, ny, vertical space = (max_tree_ht+(max elevation in sim - min elevation in sim)) dem_offset_index_mat -- size: nx (# plots along E<-->W transect), ny (# plots along N<-->S transect), 1 each x,y contains an index, which specifies the height in meters above the minimum elevation in the simulation """ # get the number of cells in the z direction that will hold the plot actual leaf area data (w/o DEM adjustment) zcells = math.ceil(max_tree_ht / zsize) # read in the DEM which we will eventually place under the actual leaf area grid dem_mat = read_in_ascii(filename=dem_ascii_filename) #print 'dem value at x=1, y=3 is %s' %(dem_mat[1,3]) # get the number of grid points from the dem; the actual leaf area grid x,y dimension will be the same size nx, ny = dem_mat.shape # what is the minimum height of the dem terrain within simulated grid of plots dem_min = np.min(dem_mat) # The DEM will push the actual leaf area values up (ground under the trees), so calculate how # many cells we need to push the actual leaf area matrix up (each x,y position will be pushed up # a different value, which corresponds to the elevation of terrain below this plot # relative to the minimum elevation on the simulated grid, NOT relative to sea level). # dtype stored as integer, so as to use these values as indices later on. dem_offset_index_mat = np.array( np.round((dem_mat - dem_min) / zsize), dtype=np.int) additional_zcells = np.max(dem_offset_index_mat) #highest elevation on grid #print 'additonal z offset due to DEM is %s cells' %(additional_zcells) # calculate the total number of cells we need to hold the relativized DEM elevation # and trees that can reach up to the max_tree_ht total_zcells = zcells + additional_zcells # inititally the actual leaf area matrix is all zeros (no trees and no ground) actual_leaf_area_mat = np.zeros( (nx, ny, total_zcells) ) #print 'actual leaf area matrix shape is :' ,actual_leaf_area_mat.shape # fill in the below ground levels with the special flag (-1) GROUND_FLAG = -1 for x in xrange(nx): for y in xrange(ny): gnd_level = dem_offset_index_mat[x,y] actual_leaf_area_mat[x,y,:gnd_level] = GROUND_FLAG # We should now have an actual leaf area matrix with below ground levels flagged, # and above ground values empty and ready to be filled. To use this, # we need the light routine to be aware of the ground flag, as well # as provide the ground offset level where each tree level begins. return actual_leaf_area_mat, dem_offset_index_mat
def one_time_radiation_readin(monthly_radiation_files_path): """ Activated in year 1 of sim to read-in the radiation files computed in GIS for the simulated terrain; generates a list of matrices to be called during PET and soil moisture and light calculations. Returns: radiation_rasters_lst = a list of 12 matrices containing accumulated radiation for each month on each plot """ radiation_rasters_lst = [] for i in range(12): filename = monthly_radiation_files_path + '/monthlyradiation%d.txt' % ( i + 1 ) #rad1.txt corresponds to january.... rad12.txt corresponds to december's radiation months_rad_mat = read_in_ascii(filename) radiation_rasters_lst.append(months_rad_mat) return radiation_rasters_lst
def one_time_radiation_readin(monthly_radiation_files_path, expected_nx, expected_ny): """ Activated in year 1 of sim to read-in the radiation files computed in GIS for the simulated terrain; generates a list of matrices to be called during PET and soil moisture and light calculations. Parameters: monthly_radiation_files_path -- folder location for the 12 monthly radiation matrices expected_nx, expected_ny -- define the DEM matrix (obtained from DEM.shape) Returns: radiation_rasters_lst = a list of 12 matrices containing accumulated radiation for each month on each plot """ radiation_rasters_lst = [] for i in range(12): filename = monthly_radiation_files_path + '/monthlyradiation%d.txt' % ( i + 1 ) #rad1.txt corresponds to january.... rad12.txt corresponds to december's radiation months_rad_mat = read_in_ascii(filename) if months_rad_mat.shape != (expected_nx, expected_ny): raise Exception("Monthly radiation file wrong shape: %s" % filename) radiation_rasters_lst.append(months_rad_mat) return radiation_rasters_lst
def compute_GDD(): from load_driver import load_driver_json driver_file = 'driver_boreal.json' #for testing, comparing against ZELIG v1.0 from Urban 1990 # load the species specific parameters from the driver file into a dictionary called driver driver = load_driver_json(driver_file) # define the range of years to simulate over start = 0 stop = driver["NYRS"] - 1 nplots = driver["NPLOTS"] GDD_matrix, monthly_temp_mat_lst, total_growing_season_mat = GrowingDegreeDays_calc( ddbase=5.5, monthly_temperature_avgs_lst=driver["XT"], monthly_temperature_stds_lst=driver["VT"], lapse_rate_adj_mat=read_in_ascii('elev_adj_factor.txt')) generate_ERDASimg_grid(metadata_file='elev_adj_factor.txt', matrix_file='GDD_grid.img', numpy_raster=GDD_matrix) radiation_mat_lst = one_time_radiation_readin() monthly_sim_rain_vec = rain_sim(rainfall_monthly_avgs=driver['XR'], rainfall_monthly_stds=driver['VR']) initial_soil_water_mat = np.zeros(GDD_matrix.shape) initial_soil_water_mat = driver[ 'FC'] #start sim with FC as soil water content soil_moisture_mat, drydays_fraction_mat = drydays( total_growing_season_mat=total_growing_season_mat, soil_moisture_mat=initial_soil_water_mat, wilting_point=driver['WP'], monthly_temp_mat_lst=monthly_temp_mat_lst, radiation_mat_lst=radiation_mat_lst, field_capacity=driver['FC'], monthly_sim_rain_vec=monthly_sim_rain_vec, ddbase=5.56) #specify ddbase in driver? generate_ERDASimg_grid(metadata_file='elev_adj_factor.txt', matrix_file='DryDays_grid.img', numpy_raster=drydays_fraction_mat)
zsize=zsize, PHIB=0.45, PHID=0.55) # get the empty actual leaf area matrix that has been adjusted for the DEM actual_leaf_area_mat, dem_offset_index_mat = prepare_actual_leaf_area_mat_from_dem( dem_ascii_filename='elevation10m.txt', xsize=xsize, ysize=ysize, zsize=zsize, max_tree_ht=MAX_TREE_HT) #actual_leaf_area_mat[:,:,:] = 0.0 # Read in the radiation fraction matrix that is used to scale the proportion of radiation # that is available to every location on the DEM at ground-level. This will be used to account for terrain shading. # Same fraction used for top-of-canopy, since found no significant difference b/w the two. radiation_fraction_mat = np.array( read_in_ascii(filename='radiationfraction_ascii.txt'), dtype=np.float) rad_min = np.min(radiation_fraction_mat) rad_max = np.max(radiation_fraction_mat ) # the range is often very small, unless transect N-S? print 'min rad = %s max rad = %s' % (rad_min, rad_max) ## TEST # put in a tree popsicle; to remove tree comment out the two lines below px, py = 10, 10 actual_leaf_area_mat[px, py, dem_offset_index_mat[px, py] + 30:-10] = 1e20 #px, py = 10, 11 #actual_leaf_area_mat[px,py, dem_offset_index_mat[px,py]+30:-10] = 100000.0 #px, py = 11, 10 #actual_leaf_area_mat[px,py, dem_offset_index_mat[px,py]+30:-10] = 100000.0 #px, py = 11, 11 #actual_leaf_area_mat[px,py, dem_offset_index_mat[px,py]+30:-10] = 100000.0
# define the plot size along the x,y, and z dimentions # 10m by 10m by 1m xsize, ysize, zsize = 10., 10., 1. # the maximum height a tree can reach in m MAX_TREE_HT = 50 # pre-compute the "arrows" that will be used to compute the light at every position in the actual leaf area matrix arrows_list = build_arrows_list(xsize=xsize, ysize=ysize, zsize=zsize, PHIB=0.45, PHID=0.55) # get the empty actual leaf area matrix that has been adjusted for the DEM actual_leaf_area_mat, dem_offset_index_mat = prepare_actual_leaf_area_mat_from_dem(dem_ascii_filename='elevation10m.txt', xsize=xsize,ysize=ysize,zsize=zsize, max_tree_ht=MAX_TREE_HT) #actual_leaf_area_mat[:,:,:] = 0.0 # Read in the radiation fraction matrix that is used to scale the proportion of radiation # that is available to every location on the DEM at ground-level. This will be used to account for terrain shading. # Same fraction used for top-of-canopy, since found no significant difference b/w the two. radiation_fraction_mat = np.array(read_in_ascii(filename='radiationfraction_ascii.txt'), dtype=np.float) rad_min = np.min(radiation_fraction_mat) rad_max = np.max(radiation_fraction_mat) # the range is often very small, unless transect N-S? print 'min rad = %s max rad = %s' %(rad_min, rad_max) ## TEST # put in a tree popsicle; to remove tree comment out the two lines below px, py = 10, 10 actual_leaf_area_mat[px,py, dem_offset_index_mat[px,py]+30:-10] = 1e20 #px, py = 10, 11 #actual_leaf_area_mat[px,py, dem_offset_index_mat[px,py]+30:-10] = 100000.0 #px, py = 11, 10 #actual_leaf_area_mat[px,py, dem_offset_index_mat[px,py]+30:-10] = 100000.0 #px, py = 11, 11 #actual_leaf_area_mat[px,py, dem_offset_index_mat[px,py]+30:-10] = 100000.0 ## END TEST