def mCH(las_file): norm_file = las_file.replace(".las", "_normalized.las") noise_file = las_file.replace(".las", "_noise.las") mch_file = las_file.replace(".las", "_mCH.bil") epsg = '32611' res = str(0.10) gp_file = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\19_149\\19_149_las_proc\\OUTPUT_FILES\\LAS\\19_149_las_proc_ground_thinned_merged.las" noise_class = str(7) noise_isolation = str(2) noise_step = str(0.25) z_min = str(1) z_max = str(30) # normalize heights lasheight_cmd = [ lastools_dir + "lasheight.exe", '-i', las_file, '-epsg', epsg, '-ground_points', gp_file, '-all_ground_points', '-replace_z', '-o', norm_file ] pcs = subprocess.Popen(lasheight_cmd) # start process pcs.wait() # wait for it to finish # normalize heights lasnoise_cmd = [ lastools_dir + "lasnoise.exe", '-i', norm_file, '-epsg', epsg, '-isolated', noise_isolation, '-step', noise_step, '-classify_as', noise_class, '-o', noise_file ] pcs = subprocess.Popen(lasnoise_cmd) # start process pcs.wait() # wait for it to finish # calculate mean canopy height lasgrid_cmd = [ lastools_dir + "lasgrid.exe", '-i', noise_file, '-epsg', epsg, '-keep_z', z_min, z_max, '-drop_class', noise_class, '-step', res, '-elevation', '-mean', '-o', mch_file ] pcs = subprocess.Popen(lasgrid_cmd) # start process pcs.wait() # wait for it to finish ras = raslib.raster_load(mch_file) ras.data[ras.data == ras.no_data] = 0 raslib.raster_save(ras, mch_file, file_format="EHdr")
parent_filtered = parent_filtered.loc[ parent_filtered.prominence_expected >= prominence_cutoff] parent_filtered = parent_filtered.reset_index(drop=True) # preallocate nearest_map = np.full_like(elev, ras.no_data) distance_map = np.full_like(elev, np.nan) # slow but works (60s?) for ii in range(0, ras.cols): for jj in range(0, ras.rows): cell_coords = ras.T1 * [ii, jj] distances = np.sqrt( (cell_coords[0] - np.array(parent_filtered.UTM11N_x))**2 + (cell_coords[1] - np.array(parent_filtered.UTM11N_y))**2) nearest_id = np.argmin(distances) nearest_map[jj, ii] = parent_filtered.id[nearest_id] distance_map[jj, ii] = distances[nearest_id] # export parent_map to raster file ras_nearest = ras ras_nearest.data = nearest_map raslib.raster_save(ras_nearest, nearest_out, data_format="int") # export distance_map to raster file ras_distance = ras ras_distance.data = distance_map raslib.raster_save(ras_distance, distance_out, data_format="float") # import matplotlib # matplotlib.use('TkAgg') # import matplotlib.pyplot as plt # plt.imshow(record, interpolation='nearest')
from libraries import raslib ras_in = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\19_149\\19_149_las_proc\\OUTPUT_FILES\\RAS\\19_149_ground_point_density_r.10m.bil" ras = raslib.raster_load(ras_in) ras.data[ras.data == ras.no_data] = 0 ras_out = ras_in.replace(".bil", "_nona.tif") raslib.raster_save(ras, ras_out)
# reload peaklist if wishing to skip above calculations # peaklist = pd.read_csv(treetops_out) print("Calculating distance and index maps") # filter to true peaks peaks_filtered = peaklist.loc[peaklist.true_peak == 1, ['UTM11N_x', 'UTM11N_y']] # load raster template for outputs ras_map = raslib.raster_load(ras_template_in) # calculate distance and index maps index_map, distance_map = raslib.raster_nearest_neighbor(peaks_filtered, ras_map) print("Writing index map to file") # export index_map to raster file ras_index = ras_map ras_index.data = index_map raslib.raster_save(ras_index, index_out, data_format="uint32") print("Writing distance map to file") # export distance_map to raster file ras_distance = ras_map ras_distance.data = distance_map raslib.raster_save(ras_distance, distance_out, data_format="float32") # import matplotlib # matplotlib.use('TkAgg') # import matplotlib.pyplot as plt # peace = neighborhoods.copy() # peace[peace == 0] = np.nan # plt.imshow(peace, interpolation='nearest')
def main(): """ Calculates raster distance to canopy edge from canopy height model following Mazzotti et al. 2019 :return: """ import numpy as np from scipy.ndimage import convolve from libraries import raslib import os # config ras_dir = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\19_149\\19_149_las_proc\\OUTPUT_FILES\\CHM\\" # ras_file = "19_149_spike_free_chm_r.10m.tif" ras_file = "19_149_spike_free_chm_r.25m.tif" ras_in = ras_dir + ras_file # canopy height model in # step_size = 0.10 # in m step_size = 0.25 # in m canopy_min_elev = 2 # height of "canopy edge" kernel_dim = 3 # step size = (kernel_dim - 1)/2 max_scan = 100 # max number of steps file_out = ras_in.replace('CHM', 'DCE').replace('.tif', '_dce.tif') # load raster ras = raslib.raster_load(ras_in) # define canopy binary canopy = np.full([ras.rows, ras.cols], 0) canopy[ras.data >= canopy_min_elev] = 1 # preallocate distance to canopy edge (DCE) record record = np.full([ras.rows, ras.cols], np.nan) kernel = np.full([kernel_dim, kernel_dim], 1) binary = canopy.copy() #while scan: for ii in range(1, max_scan): convolved = convolve(binary, kernel) contenders = np.max([binary * (kernel_dim ** 2), convolved], 0) edges = (contenders > 0) & (contenders < kernel_dim ** 2) binary[edges] = 1 record[edges] = ii binary = 1 - canopy for jj in range(1, max_scan): ii = 1 - jj convolved = convolve(binary, kernel) contenders = np.max([binary * (kernel_dim ** 2), convolved], 0) edges = (contenders > 0) & (contenders < kernel_dim ** 2) binary[edges] = 1 record[edges] = ii # correct for step size record = record * step_size record[np.isnan(record)] = ras.no_data # export dir_out = ras_dir.replace('CHM', 'DCE') if not os.path.exists(dir_out): os.makedirs(dir_out) ras_dce = ras ras_dce.data = record raslib.raster_save(ras_dce, file_out, data_format="float32") rec = raslib.raster_load(file_out) rec.data[rec.data != rec.no_data]
def pd_to_ras(df, colname, template_in, file_out): temp = raslib.raster_load(template_in) temp.data[:, :] = temp.no_data temp.data[df.y_index, df.x_index] = df.loc[:, colname] raslib.raster_save(temp, file_out)
for ii in range(0, len(metalog)): temp = tif.imread(batch_dir + metalog.file_name[ii])[:, :, 1] temp[temp == -9999] = np.nan temp = temp * scaling_coef * metalog.weight[ii] lncnw = np.nansum(np.concatenate((lncnw[:, :, np.newaxis], temp[:, :, np.newaxis]), axis=2), axis=2) print(str(ii + 1) + ' of ' + str(len(metalog))) # clean up nans lncnw[np.isnan(template.data)] = np.nan # export to file template.data = lncnw template.band_count = 1 raslib.raster_save(template, batch_dir + 'weighted_cn.tif') import matplotlib matplotlib.use('TkAgg') import matplotlib.pyplot as plt plt.imshow(lncnw, interpolation='nearest') plt.scatter(phi_weight.phi, phi_weight.area_weight_cum) plt.scatter(phi_weight.phi, phi_weight.area_weight) plt.scatter(phi_weight.phi, -phi_weight.covar) plt.scatter(phi_weight.phi, np.sin(2 * phi_weight.phi)/(np.pi * phi_weight.phi ** 2)/10)
def main(): """ Creation of snow products (HS, dHS, SWE, dSWE) from processed lidar DSMs, merged CHM, merged point densities :return: """ from libraries import raslib import numpy as np import pandas as pd import os snow_on = ["19_045", "19_050", "19_052", "19_107", "19_123"] snow_off = ["19_149"] all_dates = snow_on + snow_off # dict of density assumptions (key) with dates for which to be calculated (values) snow_on_ass = {} snow_on_ass["alin"] = ["19_045", "19_050", "19_052", "19_107", "19_123"] snow_on_ass["clin"] = ["19_045", "19_050", "19_052", "19_107", "19_123"] snow_on_ass["fcon"] = ["19_045", "19_050", "19_052", "19_107", "19_123"] snow_on_ass["ccon"] = ["19_045", "19_050", "19_052", "19_107", "19_123"] snow_on_ass["ahpl"] = ["19_045", "19_050", "19_052"] resolution = [".05", ".10", ".25", "1.00"] resamp_resolution = [".10", ".25", "1.00"] # interpolation_lengths = ["0", "1", "2", "3"] interpolation_lengths = ["2", "3"] # dict of density assumption (key) and corresponding parameters (values) swe_dens_ass = {} # coefficients for snow depth [cm], swe [mm] # # all veg, each day, linear depth-density # depth_to_density_intercept = dict(zip(snow_on, [109.1403, 110.2249, 72.5015, 224.6406, 223.5683])) # depth_to_density_slope = dict(zip(snow_on, np.array([1.2717, 1.2212, 1.5346, 1.7833, 1.2072]))) # swe_dens_ass["alin"] = (depth_to_density_intercept, depth_to_density_slope) # # forest only, each day, linear depth-density # depth_to_density_intercept = dict(zip(snow_on, [147.5136, 102.460, 3.303, 249.1015, 293.10207])) # depth_to_density_slope = dict(zip(snow_on, np.array([1.3616, 1.486, 4.054, 0.3966, -0.03987]))) # dens_ass["flin"] = (depth_to_density_intercept, depth_to_density_slope) # # # all, each day, constant density # depth_to_density_intercept = dict(zip(snow_on, np.array([191.534, 189.129, 176.066, 297.336, 298.589]))) # depth_to_density_slope = dict(zip(snow_on, np.array([0, 0, 0, 0, 0]))) # dens_ass["acon"] = (depth_to_density_intercept, depth_to_density_slope) # # forest only, each day, constant density depth_to_density_intercept = dict( zip(snow_on, np.array([165.05, 158.56, 134.48, 263.22, 291.14]))) depth_to_density_slope = dict(zip(snow_on, np.array([0, 0, 0, 0, 0]))) swe_dens_ass["fcon"] = (depth_to_density_intercept, depth_to_density_slope) # # clearing only, each day, constant density # depth_to_density_intercept = dict(zip(snow_on, np.array([189.022, 193.585, 181.896, 304.722, 303.800]))) # depth_to_density_slope = dict(zip(snow_on, np.array([0, 0, 0, 0, 0]))) # swe_dens_ass["ccon"] = (depth_to_density_intercept, depth_to_density_slope) # clearing only, each day, linear depth-density depth_to_density_intercept = dict( zip(snow_on, np.array([109.1403, 118.8462, 76.6577, 263.4744, 254.5358]))) depth_to_density_slope = dict( zip(snow_on, np.array([1.2717, 1.0892, 1.4445, 0.9819, 0.7354]))) swe_dens_ass["clin"] = (depth_to_density_intercept, depth_to_density_slope) # # # # hedstrom pomeroy intercept linear # depth_to_density_intercept = dict(zip(snow_on, np.array([89.26, 85.39, 72.05, None, None]))) # depth_to_density_slope = dict(zip(snow_on, np.array([1.59, 1.6336, 1.5420, None, None]))) # swe_dens_ass["ahpl"] = (depth_to_density_intercept, depth_to_density_slope) dswe_dens_ass = {} # dswe_dens_ass["fnsd"] = [85.08949, 72.235068, None, None] # new snow density from forest SR50 # dswe_dens_ass["cnsd"] = [96.886757, 83.370217, None, None] # new snow density from clearing SR50 dswe_dens_ass["ucgo"] = [196.406605, 91.346775, None, None] # new snow density from clearing SR50 dhs_bias = [0.0136670391, -0.0531575101, None, None] # dhs bias from clearing SR50 for select bias correction # templates for file naming and management dem_in_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\<DATE>\\<DATE>_las_proc\\TEMP_FILES\\12_dem\\res_<RES>\\' dem_merged_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\<DATE>\\<DATE>_las_proc\\OUTPUT_FILES\\DEM\\' dem_merged_file_template = '<DATE>_dem_r<RES>m.tif' dem_int_in_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\<DATE>\\<DATE>_las_proc\\TEMP_FILES\\12_dem\\interpolated_res_<RES>\\' dem_int_merged_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\<DATE>\\<DATE>_las_proc\\OUTPUT_FILES\\DEM\\interpolated\\' dem_int_merged_file_template = '<DATE>_dem_interpolated_r<RES>m.tif' dsm_can_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\<DATE>\\<DATE>_las_proc\\OUTPUT_FILES\\CAN\\<DATE>_spike_free_dsm_can_r<RES>m.bil' chm_dir_template = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\<DATE>\\<DATE>_las_proc\\OUTPUT_FILES\\CHM\\" chm_file_template = "<DATE>_spike_free_chm_r<RES>m.tif" hs_in_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\<DATE>\\<DATE>_las_proc\\TEMP_FILES\\15_hs\\interp_<INTLEN>x\\res_<RES>\\' hs_merged_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\<DATE>\\<DATE>_las_proc\\OUTPUT_FILES\\HS\\interp_<INTLEN>x\\' hs_merged_file_template = '<DATE>_hs_r<RES>m_interp<INTLEN>x.tif' hs_bias_file_in = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\analysis\\validation\\lidar_hs_point_samples_error.csv" hs_bias_file_out = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\analysis\\validation\\lidar_hs_point_samples_error_ceiling.csv" hs_bc_dir_template = hs_merged_dir_template + 'bias_corrected\\' hs_bc_file_template = hs_merged_file_template.replace( '.tif', '_bias_corrected.tif') # hs_clean_dir_template = hs_merged_dir_template + 'clean\\' # bias corrected hs_clean_dir_template = hs_merged_dir_template + 'clean_no_bias\\' hs_clean_file_template = hs_merged_file_template.replace( '.tif', '_clean.tif') hs_resamp_dir_template = hs_merged_dir_template + 'resamp\\' hs_resamp_file_template = hs_clean_file_template.replace( '.tif', '_resamp.tif') # dhs_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\products\\mb_65\\dHS\\interp_<INTLEN>x\\<DDI>-<DDJ>\\' dhs_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\products\\mb_65\\dHS_no_bias\\interp_<INTLEN>x\\<DDI>-<DDJ>\\' dhs_file_template = 'dhs_<DDI>-<DDJ>_r<RES>m_interp<INTLEN>x.tif' # swe_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\<DATE>\\<DATE>_las_proc\\OUTPUT_FILES\\SWE\\<ASS>\\interp_<INTLEN>x\\' swe_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\<DATE>\\<DATE>_las_proc\\OUTPUT_FILES\\SWE_no_bias\\<ASS>\\interp_<INTLEN>x\\' swe_file_template = 'swe_<ASS>_<DATE>_r<RES>m_interp<INTLEN>x.tif' # swe_masked_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\<DATE>\\<DATE>_las_proc\\OUTPUT_FILES\\SWE\\<ASS>\\interp_<INTLEN>x\\masked\\' swe_masked_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\<DATE>\\<DATE>_las_proc\\OUTPUT_FILES\\SWE_no_bias\\<ASS>\\interp_<INTLEN>x\\masked\\' swe_masked_file_template = 'swe_<ASS>_<DATE>_r<RES>m_interp<INTLEN>x_masked.tif' # dswe_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\products\\mb_65\\dSWE\\<ASS>\\interp_<INTLEN>x\\<DDI>-<DDJ>\\' dswe_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\products\\mb_65\\dSWE_no_bias\\<ASS>\\interp_<INTLEN>x\\<DDI>-<DDJ>\\' dswe_file_template = 'dswe_<ASS>_<DDI>-<DDJ>_r<RES>m_interp<INTLEN>x.tif' # dswe_masked_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\products\\mb_65\\dSWE\\<ASS>\\interp_<INTLEN>x\\<DDI>-<DDJ>\\masked\\' dswe_masked_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\products\\mb_65\\dSWE_no_bias\\<ASS>\\interp_<INTLEN>x\\<DDI>-<DDJ>\\masked\\' dswe_masked_file_template = 'dswe_<ASS>_<DDI>-<DDJ>_r<RES>m_interp<INTLEN>x_masked.tif' point_dens_dir_template = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\<DATE>\\<DATE>_las_proc\\OUTPUT_FILES\\RAS\\' point_dens_file_template = '<DATE>_ground_point_density_r<RES>m.bil' initial_pts_file = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\surveys\\all_ground_points_UTM11N_uid_flagged_cover.csv" hs_uncorrected_pts_path_out = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\analysis\\validation\\lidar_hs_point_samples_uncorrected.csv" hs_uncorrected_pts_path_out_sst = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\analysis\\validation\\lidar_hs_point_samples_uncorrected_sst.csv" hs_clean_pts_path_out = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\analysis\\validation\\lidar_hs_point_samples_clean.csv" hs_resamp_pts_path_out = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\analysis\\validation\\lidar_hs_point_samples_resamp.csv" swe_pts_path_out = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\analysis\\validation\\lidar_swe_point_samples.csv" point_dens_pts_path_out = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\analysis\\validation\\lidar_point_density_point_samples.csv" dem_pts_path_out = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\analysis\\validation\\lidar_dem_point_samples.csv" # mask polygons snow_mask = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\site_library\\snow_depth_mask.shp" trail_mask = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\site_library\\trampled_snow_mask_dissolved.shp" def path_sub(path, dd=None, rr=None, qq=None, ddi=None, ddj=None, itn=None, ass=None, intlen=None): # function for file name parsing if isinstance(path, str): # nest pure strings in list path = [path] for ii in range(0, len(path)): if dd is not None: path[ii] = path[ii].replace('<DATE>', dd) if rr is not None: path[ii] = path[ii].replace('<RES>', rr) if qq is not None: path[ii] = path[ii].replace('<QUANT>', str(qq)) if ddi is not None: path[ii] = path[ii].replace('<DDI>', str(ddi)) if ddj is not None: path[ii] = path[ii].replace('<DDJ>', str(ddj)) if itn is not None: path[ii] = path[ii].replace('<ITN>', str(itn)) if ass is not None: path[ii] = path[ii].replace('<ASS>', str(ass)) if intlen is not None: path[ii] = path[ii].replace('<INTLEN>', str(intlen)) return ''.join(path) # merge all dems into single outputs (culled and interpolated) for dd in (snow_on + snow_off): # update file paths with date dem_out_dir = path_sub(dem_merged_dir_template, dd=dd) dem_int_out_dir = path_sub(dem_int_merged_dir_template, dd=dd) # create DEM directory if does not exist if not os.path.exists(dem_out_dir): os.makedirs(dem_out_dir) if not os.path.exists(dem_int_out_dir): os.makedirs(dem_int_out_dir) for rr in resolution: # standard dem_in_dir = path_sub(dem_in_dir_template, dd=dd, rr=rr) dem_out_file = path_sub(dem_merged_file_template, dd=dd, rr=rr) raslib.raster_merge(dem_in_dir, '.bil', dem_out_dir + dem_out_file, no_data="-9999") # interpolated dem_int_in_dir = path_sub(dem_int_in_dir_template, dd=dd, rr=rr) dem_int_out_file = path_sub(dem_int_merged_file_template, dd=dd, rr=rr) raslib.raster_merge(dem_int_in_dir, '.bil', dem_int_out_dir + dem_int_out_file, no_data="-9999") # create snow off CHM products for dd in snow_off: chm_out_dir = path_sub(chm_dir_template, dd=dd) # create directory if does not exist if not os.path.exists(chm_out_dir): os.makedirs(chm_out_dir) for rr in resolution: dem_int_in = path_sub( [dem_int_merged_dir_template, dem_int_merged_file_template], dd=dd, rr=rr) dsm_can_in = path_sub(dsm_can_template, dd=dd, rr=rr) chm_out = path_sub([chm_dir_template, chm_file_template], dd=dd, rr=rr) hs = raslib.raster_dif_gdal(dsm_can_in, dem_int_in, inherit_from=2, dif_out=chm_out) # merge snow on snow depths into single output (PST) for dd in snow_on: for intlen in interpolation_lengths: # update file paths with date hs_out_dir = path_sub(hs_merged_dir_template, dd=dd, intlen=intlen) # create DEM directory if does not exist if not os.path.exists(hs_out_dir): os.makedirs(hs_out_dir) for rr in resolution: hs_in_dir = path_sub(hs_in_dir_template, dd=dd, rr=rr, intlen=intlen) hs_out_file = path_sub(hs_merged_file_template, dd=dd, rr=rr, intlen=intlen) # calculate hs raslib.raster_merge(hs_in_dir, '.bil', hs_out_dir + hs_out_file, no_data="-9999") # point hs samples pts_file_in = initial_pts_file for dd in snow_on: for intlen in interpolation_lengths: for rr in resolution: hs_in_path = path_sub(hs_merged_dir_template + hs_merged_file_template, dd=dd, rr=rr, intlen=intlen) colname = str(dd) + '_' + str(rr) + '_' + str(intlen) raslib.csv_sample_raster(hs_in_path, pts_file_in, hs_uncorrected_pts_path_out, "xcoordUTM11", "ycoordUTM11", colname, sample_no_data_value='') pts_file_in = hs_uncorrected_pts_path_out # run r script "snow_depth_bias_correction.r" # # bias-correct snow depths # hs_bias = pd.read_csv(hs_bias_file_in).loc[:, ["day", "lidar_res", "interp_len", "hs_mb"]] # hs_bias.loc[:, "q_999"] = np.nan # hs_bias_cor_res = 0.05 # hs_bias_cor_intlen = 2 # for dd in snow_on: # for intlen in interpolation_lengths: # # update file paths with date # hs_in_dir = path_sub(hs_merged_dir_template, dd=dd, intlen=intlen) # hs_bc_dir = path_sub(hs_bc_dir_template, dd=dd, intlen=intlen) # # # create DEM directory if does not exist # if not os.path.exists(hs_bc_dir): # os.makedirs(hs_bc_dir) # # # read mean bias value # mb = hs_bias.hs_mb[(hs_bias.day == dd) & # (hs_bias.lidar_res == hs_bias_cor_res) & # (hs_bias.interp_len == hs_bias_cor_intlen)] # if len(mb) != 1: # raise Exception("More than one (or no) match for snow depth bias, bias correction aborted.") # # mb = mb.values[0] # mb = 0 # no bias correction! # # for rr in resolution: # hs_in_file = path_sub(hs_merged_file_template, dd=dd, rr=rr, intlen=intlen) # # # load file # hs_bc_file = path_sub(hs_bc_file_template, dd=dd, rr=rr, intlen=intlen) # # # bias correct valid hs values # ras = raslib.raster_load(hs_in_dir + hs_in_file) # ras.data[ras.data != ras.no_data] += -mb # # # save # raslib.raster_save(ras, hs_bc_dir + hs_bc_file) hs_clean_ceiling_res = '.05' hs_clean_ceiling_intlen = '2' # avoid intlen 1 with res .05 hs_clean_ceiling_quantile = 0.999 # determined visually... hs_bias = pd.read_csv( hs_bias_file_in).loc[:, ["day", "lidar_res", "interp_len", "hs_mb"]] hs_bias.loc[:, "ceiling_quantile"] = hs_clean_ceiling_quantile hs_bias.loc[:, "ceiling_res"] = hs_clean_ceiling_res hs_bias.loc[:, "ceiling_value"] = np.nan # clean snow depths (restrict to specified range) for dd in snow_on: for intlen in interpolation_lengths: # update file paths with date # hs_in_dir = path_sub(hs_bc_dir_template, dd=dd, intlen=intlen) # uses bias corrected hs_in_dir = path_sub(hs_merged_dir_template, dd=dd, intlen=intlen) # not bias corrected hs_clean_dir = path_sub(hs_clean_dir_template, dd=dd, intlen=intlen) # create DEM directory if does not exist if not os.path.exists(hs_clean_dir): os.makedirs(hs_clean_dir) # load file # hs_ceil_path = path_sub(hs_bc_dir_template + hs_bc_file_template, dd=dd, rr=hs_clean_ceiling_res, intlen=hs_clean_ceiling_intlen) hs_ceil_path = path_sub( hs_merged_dir_template + hs_merged_file_template, dd=dd, rr=hs_clean_ceiling_res, intlen=hs_clean_ceiling_intlen) # not bias corr ras = raslib.raster_load(hs_ceil_path) # record quantiles cv = np.quantile(ras.data[ras.data != ras.no_data], hs_clean_ceiling_quantile) hs_bias.loc[hs_bias.day == dd, "ceiling_value"] = cv for rr in resolution: # hs_in_file = path_sub(hs_bc_file_template, dd=dd, rr=rr, intlen=intlen) hs_in_file = path_sub(hs_merged_file_template, dd=dd, rr=rr, intlen=intlen) # not bias corrected # load file hs_clean_file = path_sub(hs_clean_file_template, dd=dd, rr=rr, intlen=intlen) # send negative values to zero ras = raslib.raster_load(hs_in_dir + hs_in_file) ras.data[(ras.data < 0) & (ras.data != ras.no_data)] = 0 # send values beyond ceiling to no_data ras.data[ras.data > cv] = ras.no_data # save raslib.raster_save(ras, hs_clean_dir + hs_clean_file) hs_bias.to_csv(hs_bias_file_out, index=False) # # resample points # for dd in snow_on: # for intlen in interpolation_lengths: # # update file paths with date # hs_resamp_dir = path_sub(hs_resamp_dir_template, dd=dd, intlen=intlen) # # # create DEM directory if does not exist # if not os.path.exists(hs_resamp_dir): # os.makedirs(hs_resamp_dir) # # hs_data_file = path_sub(hs_clean_dir_template + hs_clean_file_template, dd=dd, rr=".05", intlen=intlen) # # for rr in resamp_resolution: # hs_format_in = path_sub(hs_clean_dir_template + hs_clean_file_template, dd=dd, rr=rr, intlen=intlen) # # out file # hs_resamp_out = path_sub(hs_resamp_dir_template + hs_resamp_file_template, dd=dd, rr=rr, intlen=intlen) # # raslib.ras_reproject(hs_data_file, hs_format_in, hs_resamp_out, mode="median") # differential snow depth (dHS) for ii in range(0, len(snow_on) - 1): ddi = snow_on[ii] ddj = snow_on[ii + 1] for intlen in interpolation_lengths: # update file paths with dates dhs_dir = path_sub(dhs_dir_template, ddi=ddi, ddj=ddj, intlen=intlen) # create sHD directory if does not exist if not os.path.exists(dhs_dir): os.makedirs(dhs_dir) for rr in resolution: ddi_in = path_sub( [hs_clean_dir_template, hs_clean_file_template], dd=ddi, rr=rr, intlen=intlen) ddj_in = path_sub( [hs_clean_dir_template, hs_clean_file_template], dd=ddj, rr=rr, intlen=intlen) dhs_out = path_sub([dhs_dir_template, dhs_file_template], ddi=ddi, ddj=ddj, rr=rr, intlen=intlen) hs = raslib.raster_dif_gdal(ddj_in, ddi_in, inherit_from=2, dif_out=dhs_out) # Select bias correction of dHS for ii in range(0, len(snow_on) - 1): if dhs_bias[ii] is not None: ddi = snow_on[ii] ddj = snow_on[ii + 1] for intlen in interpolation_lengths: # update file paths with dates dhs_dir = path_sub(dhs_dir_template, ddi=ddi, ddj=ddj, intlen=intlen) dhs_bc_dir = dhs_dir.replace("dHS_no_bias", "dHS_bias_corrected") # create sHD directory if does not exist if not os.path.exists(dhs_bc_dir): os.makedirs(dhs_bc_dir) for rr in resolution: dhs_in = dhs_dir + path_sub(dhs_file_template, ddi=ddi, ddj=ddj, rr=rr, intlen=intlen) dhs_bc_out = dhs_bc_dir + path_sub(dhs_file_template, ddi=ddi, ddj=ddj, rr=rr, intlen=intlen) # load dhs ras = raslib.raster_load(dhs_in) # correct for bias ras.data[(ras.data != ras.no_data)] = ras.data[ (ras.data != ras.no_data)] - dhs_bias[ii] # save raslib.raster_save(ras, dhs_bc_out) # run density analysis in r # calculate SWE products for ass in swe_dens_ass.keys(): print(ass) for intlen in interpolation_lengths: for dd in snow_on_ass[ass]: # update file paths with date swe_dir = path_sub(swe_dir_template, dd=dd, ass=ass, intlen=intlen) swe_masked_dir = path_sub(swe_masked_dir_template, dd=dd, ass=ass, intlen=intlen) # create SWE directory if does not exist if not os.path.exists(swe_dir): os.makedirs(swe_dir) if not os.path.exists(swe_masked_dir): os.makedirs(swe_masked_dir) for rr in resolution: # update file paths with resolution hs_file = path_sub( [hs_clean_dir_template, hs_clean_file_template], dd=dd, rr=rr, intlen=intlen) swe_file = path_sub([swe_dir_template, swe_file_template], dd=dd, rr=rr, ass=ass, intlen=intlen) swe_masked_file = path_sub( [swe_masked_dir_template, swe_masked_file_template], dd=dd, rr=rr, ass=ass, intlen=intlen) # calculate swe ras = raslib.raster_load(hs_file) valid_cells = np.where(ras.data != ras.no_data) depth = ras.data[valid_cells] # calculate swe from depth density regression mm = swe_dens_ass[ass][1][dd] bb = swe_dens_ass[ass][0][dd] swe = depth * (mm * depth * 100 + bb) ras.data[valid_cells] = swe raslib.raster_save(ras, swe_file) # mask ras = raslib.raster_load(swe_file) # load copy raslib.raster_save(ras, swe_masked_file) # save copy raslib.raster_burn(swe_masked_file, snow_mask, ras.no_data) # burn end of season snow raslib.raster_burn(swe_masked_file, trail_mask, ras.no_data) # burn trampled snow # dSWE from dHS for ass in dswe_dens_ass.keys(): print(ass) for ii in range(0, len(snow_on) - 1): if dswe_dens_ass[ass][ii] is not None: ddi = snow_on[ii] ddj = snow_on[ii + 1] for intlen in interpolation_lengths: # update file paths with dates dswe_dir = path_sub(dswe_dir_template, ddi=ddi, ddj=ddj, intlen=intlen, ass=ass) dswe_masked_dir = path_sub(dswe_masked_dir_template, ddi=ddi, ddj=ddj, ass=ass, intlen=intlen) if not os.path.exists(dswe_dir): os.makedirs(dswe_dir) if not os.path.exists(dswe_masked_dir): os.makedirs(dswe_masked_dir) if not os.path.exists( dswe_dir.replace("dSWE_no_bias", "dSWE_bias_corrected")): os.makedirs( dswe_dir.replace("dSWE_no_bias", "dSWE_bias_corrected")) if not os.path.exists( dswe_masked_dir.replace("dSWE_no_bias", "dSWE_bias_corrected")): os.makedirs( dswe_masked_dir.replace("dSWE_no_bias", "dSWE_bias_corrected")) for rr in resolution: # no bias dhs_in = path_sub( [dhs_dir_template, dhs_file_template], ddi=ddi, ddj=ddj, rr=rr, intlen=intlen) dswe_out = path_sub( [dswe_dir_template, dswe_file_template], ddi=ddi, ddj=ddj, rr=rr, intlen=intlen, ass=ass) dswe_masked_file = path_sub([ dswe_masked_dir_template, dswe_masked_file_template ], ddi=ddi, ddj=ddj, rr=rr, intlen=intlen, ass=ass) # load data ras = raslib.raster_load(dhs_in) # multiply differential depth by new snow density ras.data[ras.data != ras.no_data] = ras.data[ ras.data != ras.no_data] * dswe_dens_ass[ass][ii] # save dswe raslib.raster_save(ras, dswe_out) # mask ras = raslib.raster_load(dswe_out) # load copy raslib.raster_save(ras, dswe_masked_file) # save copy raslib.raster_burn(dswe_masked_file, trail_mask, ras.no_data) # burn trampled snow # bias_corrected dhs_in = path_sub( [dhs_dir_template, dhs_file_template], ddi=ddi, ddj=ddj, rr=rr, intlen=intlen) dhs_in = dhs_in.replace("dHS_no_bias", "dHS_bias_corrected") dswe_out = path_sub( [dswe_dir_template, dswe_file_template], ddi=ddi, ddj=ddj, rr=rr, intlen=intlen, ass=ass) dswe_out = dswe_out.replace("dSWE_no_bias", "dSWE_bias_corrected") dswe_masked_file = path_sub([ dswe_masked_dir_template, dswe_masked_file_template ], ddi=ddi, ddj=ddj, rr=rr, intlen=intlen, ass=ass) dswe_masked_file = dswe_masked_file.replace( "dSWE_no_bias", "dSWE_bias_corrected") # load data ras = raslib.raster_load(dhs_in) # multiply differential depth by new snow density ras.data[ras.data != ras.no_data] = ras.data[ ras.data != ras.no_data] * dswe_dens_ass[ass][ii] # save dswe raslib.raster_save(ras, dswe_out) # mask ras = raslib.raster_load(dswe_out) # load copy raslib.raster_save(ras, dswe_masked_file) # save copy raslib.raster_burn(dswe_masked_file, trail_mask, ras.no_data) # burn trampled snow # # differential SWE products # for ass in swe_dens_ass.keys(): # print(ass) # for intlen in interpolation_lengths: # for ii in range(0, len(snow_on_ass[ass]) - 1): # ddi = snow_on[ii] # ddj = snow_on[ii + 1] # # # update file paths with dates # dswe_dir = path_sub(dswe_dir_template, ddi=ddi, ddj=ddj, ass=ass, intlen=intlen) # dswe_masked_dir = path_sub(dswe_masked_dir_template, ddi=ddi, ddj=ddj, ass=ass, intlen=intlen) # # # create SWE directory if does not exist # if not os.path.exists(dswe_dir): # os.makedirs(dswe_dir) # if not os.path.exists(dswe_masked_dir): # os.makedirs(dswe_masked_dir) # # for rr in resolution: # ddi_in = path_sub([swe_dir_template, swe_file_template], dd=ddi, rr=rr, ass=ass, intlen=intlen) # ddj_in = path_sub([swe_dir_template, swe_file_template], dd=ddj, rr=rr, ass=ass, intlen=intlen) # dswe_file = path_sub([dswe_dir_template, dswe_file_template], ddi=ddi, ddj=ddj, rr=rr, ass=ass, intlen=intlen) # dswe_masked_file = path_sub([dswe_masked_dir_template, dswe_masked_file_template], ddi=ddi, ddj=ddj, rr=rr, ass=ass, intlen=intlen) # # dswe_ras = rastools.raster_dif_gdal(ddj_in, ddi_in, inherit_from=2, dif_out=dswe_file) # # # mask # ras = rastools.raster_load(dswe_file) # rastools.raster_save(ras, dswe_masked_file) # # rastools.raster_burn(dswe_masked_file, snow_mask, ras.no_data) # rastools.raster_burn(dswe_masked_file, trail_mask, ras.no_data) # point samples of hs pts_file_in = initial_pts_file for dd in snow_on: for intlen in interpolation_lengths: for rr in resolution: try: hs_clean_path = path_sub(hs_clean_dir_template + hs_clean_file_template, dd=dd, rr=rr, intlen=intlen) colname = str(dd) + '_' + str(rr) + '_' + str(intlen) raslib.csv_sample_raster(hs_clean_path, pts_file_in, hs_clean_pts_path_out, "xcoordUTM11", "ycoordUTM11", colname, sample_no_data_value='') pts_file_in = hs_clean_pts_path_out except AttributeError: print('File does not exist') # # # resampled points # pts_file_in = initial_pts_file # for dd in snow_on: # for intlen in interpolation_lengths: # for rr in resamp_resolution: # try: # hs_resamp_path = path_sub(hs_resamp_dir_template + hs_resamp_file_template, dd=dd, rr=rr, intlen=intlen) # colname = str(dd) + '_' + str(rr) + '_' + str(intlen) # rastools.csv_sample_raster(hs_resamp_path, pts_file_in, hs_resamp_pts_path_out, "xcoordUTM11", # "ycoordUTM11", colname, sample_no_data_value='') # pts_file_in = hs_resamp_pts_path_out # # except AttributeError: # print('File does not exist') # point samples of swe pts_file_in = initial_pts_file for ass in swe_dens_ass.keys(): for dd in snow_on_ass[ass]: for intlen in interpolation_lengths: for rr in resolution: try: swe_path = path_sub(swe_dir_template + swe_file_template, dd=dd, rr=rr, ass=ass, intlen=intlen) colname = str(dd) + '_' + str(rr) + '_' + str( ass) + '_' + str(intlen) raslib.csv_sample_raster(swe_path, pts_file_in, swe_pts_path_out, "xcoordUTM11", "ycoordUTM11", colname, sample_no_data_value='') pts_file_in = swe_pts_path_out except AttributeError: print('File does not exist') # point samples of point density pts_file_in = initial_pts_file for dd in snow_on + snow_off: for rr in [".10", ".25"]: point_dens_path = path_sub(point_dens_dir_template + point_dens_file_template, dd=dd, rr=rr) colname = str(dd) + '_' + str(rr) raslib.csv_sample_raster(point_dens_path, pts_file_in, point_dens_pts_path_out, "xcoordUTM11", "ycoordUTM11", colname, sample_no_data_value='') pts_file_in = point_dens_pts_path_out print(rr) # point samples of interpolated dem pts_file_in = initial_pts_file for dd in (snow_on + snow_off): for rr in resolution: for intlen in interpolation_lengths: dem_path = path_sub(dem_merged_dir_template + dem_merged_file_template, dd=dd, rr=rr) colname = str(dd) + '_' + str(rr) raslib.csv_sample_raster(dem_path, pts_file_in, dem_pts_path_out, "xcoordUTM11", "ycoordUTM11", colname, sample_no_data_value='') pts_file_in = dem_pts_path_out print(rr)
def main(): """ Build grid of points with consistent indexing at various resolutions :return: """ import pandas as pd import numpy as np from libraries import raslib import os batch_dir = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\site_library\\hemi_grid_points\\mb_65_r.25m_snow_on_offset0\\' # build point list from DEM dem_in = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\19_052\\19_052_las_proc\\OUTPUT_FILES\\DEM\\interpolated\\19_052_dem_interpolated_r.25m.tif' # snow-on # dem_in = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\19_149\\19_149_las_proc\\OUTPUT_FILES\\DEM\\interpolated\\19_149_dem_interpolated_r.25m.tif' # snow-off vertical_offset = 0 mb_65_poly = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\site_library\\mb_65_poly.shp' mb_15_poly = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\site_library\\mb_15_poly.shp' uf_poly = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\site_library\\upper_forest_poly_UTM11N.shp' uc_poly = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\site_library\\upper_clearing_poly_UTM11N.shp' # for plot mappings resolution = ['.05', '.10', '.25', '1.00'] template_scheme = 'C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\19_149\\19_149_las_proc\\OUTPUT_FILES\\TEMPLATES\\19_149_all_point_density_r<RES>m.bil' # dem_in = 'C:\\Users\\jas600\\workzone\\data\\hemigen\\hemi_lookups\\19_149_dem_r1.00m_q0.25_interpolated_min1.tif' # site_poly = 'C:\\Users\\jas600\\workzone\\data\\hemigen\\hemi_lookups\\upper_forest_poly_UTM11N.shp' # batch_dir = 'C:\\Users\\jas600\\workzone\\data\\hemigen\\uf_1m_pr_0_os_0.5\\' # create batch dir if does not exist if not os.path.exists(batch_dir): os.makedirs(batch_dir) pts = raslib.raster_to_pd(dem_in, 'z_m', include_nans=True) pts.z_m = pts.z_m + vertical_offset # shift z_m by vertical offset # add point id pts = pts.reset_index() pts.columns = ['id', 'x_utm11n', 'y_utm11n', 'x_index', 'y_index', 'z_m'] # # add flag for mb_65 # load dem as template site_plot = raslib.raster_load(dem_in) # fill data with zeros site_plot.data = np.full((site_plot.rows, site_plot.cols), 0) # save to file mb_65_plot_dir = batch_dir + 'mb_65_plot_over_dem.tiff' raslib.raster_save(site_plot, mb_65_plot_dir, data_format='byte') # burn site polygon into plot data as ones raslib.raster_burn(mb_65_plot_dir, mb_65_poly, 1) # load plot data mb_65_plot = raslib.raster_load(mb_65_plot_dir) # # add flag for mb_15 # load template site_plot = raslib.raster_load(dem_in) # fill data with zeros site_plot.data = np.full((site_plot.rows, site_plot.cols), 0) # save to file mb_15_plot_dir = batch_dir + 'mb_15_plot_over_dem.tiff' raslib.raster_save(site_plot, mb_15_plot_dir, data_format='byte') # burn site polygon into plot data as ones raslib.raster_burn(mb_15_plot_dir, mb_15_poly, 1) # load plot data mb_15_plot = raslib.raster_load(mb_15_plot_dir) # # add flag for (UF) # load template site_plot = raslib.raster_load(dem_in) # fill data with zeros site_plot.data = np.full((site_plot.rows, site_plot.cols), 0) # save to file uf_plot_dir = batch_dir + 'uf_plot_over_dem.tiff' raslib.raster_save(site_plot, uf_plot_dir, data_format='byte') # burn site polygon into plot data as ones raslib.raster_burn(uf_plot_dir, uf_poly, 1) # load plot data uf_plot = raslib.raster_load(uf_plot_dir) # merge plot data with points pts_index = (pts.y_index.values, pts.x_index.values) pts = pts.assign(mb_65=mb_65_plot.data[pts_index].astype(bool), mb_15=mb_15_plot.data[pts_index].astype(bool), uf=uf_plot.data[pts_index].astype(bool)) # export point lookup as csv pts_dir = batch_dir + 'dem_r.25_points.csv' pts.to_csv(pts_dir, index=False) # format point ids as raster id_raster = raslib.raster_load(dem_in) id_raster.data = np.full([id_raster.rows, id_raster.cols], id_raster.no_data).astype(int) id_raster.data[pts_index] = pts.id # save id raster to file id_raster_out = batch_dir + 'dem_r.25_point_ids.tif' raslib.raster_save(id_raster, id_raster_out, data_format="int32") # point subsets pts_mb_65 = pts[pts.mb_65] pts_dir = batch_dir + 'dem_r.25_points_mb_65.csv' pts_mb_65.to_csv(pts_dir, index=False) pts_mb_15 = pts[pts.mb_15] pts_dir = batch_dir + 'dem_r.25_points_mb_15.csv' pts_mb_15.to_csv(pts_dir, index=False) pts_uf = pts[pts.uf] pts_dir = batch_dir + 'dem_r.25_points_uf.csv' pts_uf.to_csv(pts_dir, index=False) # create cookie cutters of sites for each resolution for rr in resolution: file_out = 'uf_plot_r' + rr + 'm.tif' site_poly = uf_poly template_in = template_scheme.replace('<RES>', rr) ras = raslib.raster_load(template_in) ras.data = np.full((ras.rows, ras.cols), 0) ras.no_data = 0 ras_out = batch_dir + file_out raslib.raster_save(ras, ras_out, data_format='byte') raslib.raster_burn(ras_out, site_poly, 1) for rr in resolution: file_out = 'uc_plot_r' + rr + 'm.tif' site_poly = uc_poly template_in = template_scheme.replace('<RES>', rr) ras = raslib.raster_load(template_in) ras.data = np.full((ras.rows, ras.cols), 0) ras.no_data = 0 ras_out = batch_dir + file_out raslib.raster_save(ras, ras_out, data_format='byte') raslib.raster_burn(ras_out, site_poly, 1) for rr in resolution: file_out = 'site_plots_r' + rr + 'm.tif' template_in = template_scheme.replace('<RES>', rr) ras = raslib.raster_load(template_in) ras.data = np.full((ras.rows, ras.cols), 0) ras.no_data = 0 ras_out = batch_dir + file_out raslib.raster_save(ras, ras_out, data_format='uint16') raslib.raster_burn(ras_out, uf_poly, 1) raslib.raster_burn(ras_out, uc_poly, 2) for rr in resolution: file_out = 'mb_15_plot_r' + rr + 'm.tif' site_poly = mb_15_poly template_in = template_scheme.replace('<RES>', rr) ras = raslib.raster_load(template_in) ras.data = np.full((ras.rows, ras.cols), 0) ras.no_data = 0 ras_out = batch_dir + file_out raslib.raster_save(ras, ras_out, data_format='byte') raslib.raster_burn(ras_out, site_poly, 1) for rr in resolution: file_out = 'mb_65_plot_r' + rr + 'm.tif' site_poly = mb_65_poly template_in = template_scheme.replace('<RES>', rr) ras = raslib.raster_load(template_in) ras.data = np.full((ras.rows, ras.cols), 0) ras.no_data = 0 ras_out = batch_dir + file_out raslib.raster_save(ras, ras_out, data_format='byte') raslib.raster_burn(ras_out, site_poly, 1)
lpmf.data = num / denom lpml = raslib.raster_load(dir_in + FG_in) num = (LG.data + FG.data) denom = (LG.data + FG.data + FC.data) denom[denom == 0] = np.nan lpml.data = num / denom lpmc = raslib.raster_load(dir_in + FG_in) num = LG.data denom = (LG.data + FC.data) denom[denom == 0] = np.nan lpmc.data = num / denom fcov = raslib.raster_load(dir_in + FG_in) fcov.data = 1 - lpmf.data lpmf.data[np.isnan(lpmf.data)] = no_data lpml.data[np.isnan(lpml.data)] = no_data lpmc.data[np.isnan(lpmc.data)] = no_data fcov.data[np.isnan(fcov.data)] = no_data # export if not os.path.exists(dir_out): os.makedirs(dir_out) raslib.raster_save(lpmf, dir_out + lpmf_out) raslib.raster_save(lpml, dir_out + lpml_out) raslib.raster_save(lpmc, dir_out + lpmc_out) raslib.raster_save(fcov, dir_out + fcov_out)
def las_quantile_dem(las_in, ras_template, q, q_out=None, n_out=None, las_ground_class=2): """ Produces a raster DEM from classified point cloud by calculating a pixel-wise quantile :param las_in: path to LAS point cloud file :param ras_template: path to a geotif image from which pixel binning will be inherited :param q: quantile in range [0, 1] quich will be calculated for each pixel :param q_out: path of resultant quantile product (optional) :param n_out: path of resultant cell point count product (optional) :param las_ground_class: class of points representing ground :return: quantile product, count product """ from libraries import raslib import scipy.stats import numpy as np # load las ground points las = las_xyz_load(las_in, keep_class=las_ground_class) # load template raster for pixel geometry ras = raslib.raster_load(ras_template) # calculate bins x_bins = (ras.T0 * (np.linspace(0, ras.cols, ras.cols + 1), 0))[0] y_bins = (ras.T0 * (0, np.linspace(0, ras.rows, ras.rows + 1)))[1] ras_bins = [y_bins, x_bins] # rectify bins rectified = [False, False] for ii in [0, 1]: if ras_bins[ii][0] > ras_bins[ii][-1]: ras_bins[ii] = np.flip(ras_bins[ii]) rectified[ii] = True print('Computing counts... ', end='') stat_n, xEdges, yEdges, binnumber = scipy.stats.binned_statistic_2d( las[:, 1], las[:, 0], las[:, 2], statistic='count', bins=ras_bins) print('done') print('Computing quantile... ') def quantile_q(x): return np.quantile(x, q) # preallocate stat_q stat_q = np.full((ras.rows, ras.cols), np.nan) # for each column for ii in range(0, ras.cols): # select all points in column stripe_points = (las[:, 0] > ras_bins[1][ii]) & ( las[:, 0] < ras_bins[1][ii + 1] ) # all y values, within x value range las_sub = las[stripe_points, :] if las_sub.size > 0: # calculate quantile stat_q_col, yEdges, binnumber = scipy.stats.binned_statistic( las_sub[:, 1], las_sub[:, 2], statistic=quantile_q, bins=ras_bins[0]) # save to composite output stat_q[:, ii] = stat_q_col # advance start bound print('column ' + str(ii + 1) + ' of ' + str(ras.cols)) # undo rectification for ii in [0, 1]: if rectified[ii]: stat_n = np.flip(stat_n, ii) stat_q = np.flip(stat_q, ii) # save outputs to file if q_out is not None: # output quantile q_ras = raslib.raster_load(ras_template) q_ras.data = stat_q q_ras.data[np.isnan(q_ras.data)] = q_ras.no_data raslib.raster_save(q_ras, q_out, data_format='float32') if n_out is not None: # output count n_ras = raslib.raster_load(ras_template) n_ras.data = stat_n n_ras.data[np.isnan(n_ras.data)] = n_ras.no_data raslib.raster_save(n_ras, n_out, data_format='float32') return stat_q, stat_n
hs = raslib.raster_load(hs_in) # dft = rastools.raster_load(dft_in) # send hs to hdf5 raslib.raster_to_hdf5(hs_in, hs_hdf5, "hs_04m") # sample site # create raster of false values site_shp_path = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\site_library\\sub_plot_library\\forest_upper.shp" site_raster_path = "C:\\Users\\Cob\\index\\educational\\usask\\research\\masters\\data\\lidar\\site_library\\upper_forest_poly_UTM11N.tif" template = raslib.raster_load(hs_in) template.data = np.full([template.rows, template.cols], 0) template.no_data = 0 raslib.raster_save(template, site_raster_path, data_format="int16") # burn in upper forest site as true values raslib.raster_burn(site_raster_path, site_shp_path, 1) # sample rasters raslib.hdf5_sample_raster(hs_hdf5, hs_dft_hdf5, [dft_in, site_raster_path, hs_10_in], sample_col_name=["dft", "uf", "hs_01m"]) ##### Plotting ##### df = vaex.open(hs_dft_hdf5, 'r') df.get_column_names() no_data = -9999 df_uf = df[df.uf == 1]