def vegetation_fis_validation(top_level_folder, database): """ Validate PyBRAT 4 vegetation FIS with that of pyBRAT 3 :param top_level_folder: Top level folder containing pyBRAT 3 HUC 8 projects :param database: Path to the SQLite database containing pyBRAT configuration :return: None """ hucs = get_hucs_present(top_level_folder, database) for _label, veg_type in {'Existing': 'EX', 'Historic': 'hpe'}.items(): plot_values = [] for _huc, paths in hucs.items(): out_field = 'oVC_{}'.format(veg_type) streamside_field = 'iVeg_30{}'.format(veg_type) riparian_field = 'iVeg100{}'.format(veg_type) # Load the input fields required as well as the pyBRAT3 output fields feature_values = load_attributes( paths['Network'], 'ReachID', [streamside_field, riparian_field]) expected_output = load_attributes(paths['Network'], 'ReachID', [out_field]) calculate_vegegtation_fis(feature_values, streamside_field, riparian_field, out_field) # Merge the results into a master list for reach, feature in feature_values.items(): plot_values.append( (expected_output[reach][out_field], feature[out_field])) validation_chart(plot_values, '{} Vegetation FIS'.format(veg_type)) print('Validation complete')
def hydrology_param_validation(usu_params, database): hucs = {} # Load the USU iHydrology model parameters from CSV file with open(usu_params, 'r') as csvfile: reader = csv.DictReader(csvfile) for row in reader: huc8 = row['HUC8Dir'].split('_')[1] if huc8.startswith('1705'): continue hucs[huc8] = { 'USU': { 'PRECIP': float(row['PRECIP_IN']) * 25.4, 'RR': float(row['BASIN_RELIEF']) * 0.3048, 'ELEV': float(row['ELEV_FT']) * 0.3048, 'MINELEV': float(row['MIN_ELEV_FT']) * 0.3048, 'MEANSLOPE': float(row['SLOPE_PCT']), 'SLOP30_30M': float(row['BASIN_SLOPE']), 'FOREST': float(row['FOREST_PCT']), 'ForestCoverP1': float(row['FOREST_PLUS_PCT']) } } print(len(hucs), 'HUCs loaded from USU model parameters CSV file.') # Calculate the BRAT4 iHydrology mode parameters conn = sqlite3.connect(database) curs = conn.cursor() for huc, values in hucs.items(): curs.execute( 'SELECT Name, Value FROM WatershedHydroParams WHP INNER JOIN HydroParams HP ON WHP.ParamID = HP.ParamID WHERE (WatershedID = ?)', [huc]) values['pyBRAT4'] = {row[0]: row[1] for row in curs.fetchall()} # generate charts for param in [ 'PRECIP', 'RR', 'ELEV', 'MINELEV', 'MEANSLOPE', 'SLOP30_30M', 'FOREST' ]: results = [] for huc, values in hucs.items(): if param in values[ 'USU'] and 'pyBRAT4' in values and param in values[ 'pyBRAT4']: results.append( (values['USU'][param], values['pyBRAT4'][param])) if len(results) > 0: validation_chart(results, 'Hydro Param {}'.format(param)) print('Hydrology Parameter Validation Complete')
def combined_fis_validation(top_level_folder, database): """ Validate PyBRAT 4 combined FIS with that of pyBRAT 3 :param top_level_folder: Top level folder containing pyBRAT 3 HUC 8 projects :param database: Path to the SQLite database containing pyBRAT configuration :return: None """ hucs = get_hucs_present(top_level_folder, database) dathresh = get_drainage_area_thresh(database) for label, veg_type in {'Existing': 'EX', 'Historic': 'HPE'}.items(): capacity_values = [] density_values = [] veg_fis_field = 'oVC_{}'.format(veg_type) com_capacity_field = 'oCC_{}'.format(veg_type) com_density_field = 'oMC_{}'.format(veg_type) for huc, paths in hucs.items(): max_drainage_area = dathresh[huc] # Load the input fields required as well as the pyBRAT3 output fields feature_values = load_attributes(paths['Network'], 'ReachID', [ veg_fis_field, 'iGeo_Slope', 'iGeo_DA', 'iHyd_SP2', 'iHyd_SPLow', 'iGeo_Len' ]) expected_output = load_attributes( paths['Network'], 'ReachID', [com_capacity_field, com_density_field]) # Do the combined FIS calculation calculate_combined_fis(feature_values, veg_fis_field, com_capacity_field, com_density_field, max_drainage_area) # Merge the results into a master list for reach, feature in feature_values.items(): capacity_values.append( (expected_output[reach][com_capacity_field], feature[com_capacity_field])) density_values.append( (expected_output[reach][com_density_field], feature[com_density_field])) # Plot the master list validation_chart(capacity_values, '{} Combined FIS Capacity'.format(label)) validation_chart(density_values, '{} Combined FIS Density'.format(label)) print('Validation complete')
def reach_geometry_validation(top_level_folder, database, buffer_distance): """ Validate PyBRAT 4 vegetation FIS with that of pyBRAT 3 :param top_level_folder: Top level folder containing pyBRAT 3 HUC 8 projects :param database: Path to the SQLite database containing pyBRAT configuration :param buffer_distance: PyBRAT 4 buffer distance for sampling DEM raster elevations :return: None """ hucs = get_hucs_present(top_level_folder, database) fields = ['iGeo_Slope', 'iGeo_ElMin', 'iGeo_ElMax', 'iGeo_Len'] results = {} for _huc, paths in hucs.items(): polylines = load_geometries(paths['Network'], 'ReachID') db_srs = get_db_srs(database) expected = load_attributes(paths['Network'], 'ReachID', fields) results = calculate_reach_geometry(polylines, paths['DEM'], db_srs, buffer_distance) for field in fields: if field not in results: results[field] = [] for reachid, values in results.items(): if reachid in expected: results[field].append((expected[reachid][field], values[field])) [validation_chart(results[field], '{} Reach Geometry'.format(field)) for field in fields] print('Validation complete')
def vegetation_summary_validation(database, veg_raster, top_level_folder): """ Validate PyBRAT 4 vegetation FIS with that of pyBRAT 3 :param top_level_folder: Top level folder containing pyBRAT 3 HUC 8 projects :param database: Path to the SQLite database containing pyBRAT configuration :return: None """ hucs = get_hucs_present(top_level_folder, database) for table, prefix in {'Existing': 'EX', 'Historic': 'Hpe'}.items(): for buffer in [30, 100]: plot_values = [] for huc, paths in hucs.items(): print('Validating', huc) # _rough_convert_metres_to_shapefile_units(paths['Network'], 300) veg_field = 'iVeg_{}{}'.format(buffer, prefix) if buffer == 100: veg_field = veg_field.replace('_', '') # Load the input fields required as well as the pyBRAT3 output fields geometries = load_geometries(paths['Network'], 'ReachID', 5070) expected_output = load_attributes(paths['Network'], 'ReachID', [veg_field]) results = calculate_vegetation_summary(database, geometries, veg_raster, buffer, table, prefix, huc) # Merge the results into a master list for reach, feature in results.items(): plot_values.append((expected_output[reach][veg_field], feature[veg_field])) validation_chart( plot_values, '{0}m {1} Vegetation Summary'.format(buffer, table)) print('Validation complete')
def stream_power_validation(top_level_folder, database, id_field): # Detect which Idaho BRAT HUCs are present on local disk hucs = load_hucs.get_hucs_present(top_level_folder, database) results = {} for huc, paths in hucs.items(): if 'Network' not in paths: print('Skipping {} because no network shapefile'.format(huc)) continue print('Validating stream power for HUC', huc) # Load the pyBRAT3 values inputs = shapefile.load_attributes(paths['Network'], id_field, input_fields) expected = shapefile.load_attributes(paths['Network'], id_field, output_fields) # Calculate the land use attributes calculated = calculate_stream_power.calculate_stream_power(inputs) # Synthesize the results for all the HUCs for field in output_fields: if field not in results: results[field] = [] for reachid, values in calculated.items(): if reachid in expected: results[field].append( (expected[reachid][field], values[field])) # Generate the validation plots [ plotting.validation_chart(results[field], '{} Stream Power'.format(field)) for field in output_fields ] print('Validation complete')
def drainage_area_validation(expected, nhdplushr): log = Logger("BRAT Drainage Area") TIMER_overall = LoopTimer("DA OVERALL") driver = ogr.GetDriverByName("ESRI Shapefile") # Load manually prepared drainage area values into a dictionary of "to nodes" as keys with DA as the values. data_expected = driver.Open(expected, 0) expectedLayer = data_expected.GetLayer() expectedSpatialRef = expectedLayer.GetSpatialRef() # Now load all the NHD Plus HR features and attempt to match up the coordinates chart_values = [] data_source = driver.Open(nhdplushr, 0) layer = data_source.GetLayer() nhdSpatialRef = layer.GetSpatialRef() transform = osr.CoordinateTransformation(nhdSpatialRef, expectedSpatialRef) TIMER_compare = LoopTimer("Compare Expected", useMs=True) matchFound = 0 totalPoints = 0 for feature in layer: geom = feature.GetGeometryRef() geom.Transform(transform) pts = geom.GetPoints() # Slice off the elevation value for simplicity to_point = pts[-1][0:2] totalPoints += 1 # Set a crude rectangle to filter by expectedLayer.SetSpatialFilterRect(to_point[0] - 5, to_point[1] - 5, to_point[0] + 5, to_point[1] + 5) # If you are using an attribute filter ( SetAttributeFilter() ) or spatial filter ( SetSpatialFilter() or SetSpatialFilterRect() ) then you have to use GetNextFeature(). expected_da = {} for expected_feat in expectedLayer: georef = expected_feat.GetGeometryRef() expectedPts = georef.GetPoints() expected_da[expectedPts[-1][0:2]] = expected_feat.GetField( expected_field) # Use the one with the least distance if len(expected_da) > 0: smallest_dist = () for expected_point, da in expected_da.items(): point1 = ogr.Geometry(ogr.wkbPoint) point1.AddPoint(*expected_point) point2 = ogr.Geometry(ogr.wkbPoint) point2.AddPoint(*to_point) dist = point2.Distance(point1) if dist < 0.1 and (len(smallest_dist) == 0 or smallest_dist[1] > dist): smallest_dist = (da, dist) if smallest_dist: matchFound += 1 feat_da = feature.GetField(nhdplushr_filed) if not type(da) is float: log.error("Found invalid expected DA of type {}".format( type(da))) elif not type(feat_da) is float: log.error("Found invalid nhdplus DA of type {}".format( type(feat_da))) else: chart_values.append((da, feat_da, expected_point)) TIMER_compare.progprint() TIMER_compare.tick() feature = None data_source = None TIMER_overall.print("Final") log.info("Points with match: {} / {}".format(matchFound, totalPoints)) title = 'Idaho BRAT drainage area values against NHD Plus HR' plotting.validation_chart([x[0:2] for x in chart_values], title) """