def make_agg_pairs(pour_points, dom_data, fdr_data, config_dict): """ Group pour points by domain grid outlet cell """ lons = pour_points['lons'] lats = pour_points['lats'] dom_lon = dom_data[config_dict['DOMAIN']['LONGITUDE_VAR']] dom_lat = dom_data[config_dict['DOMAIN']['LATITUDE_VAR']] dom_ids = dom_data['cell_ids'] fdr_lons = fdr_data[config_dict['ROUTING']['LONGITUDE_VAR']] fdr_lats = fdr_data[config_dict['ROUTING']['LATITUDE_VAR']] fdr_srcarea = fdr_data[config_dict['ROUTING']['SOURCE_AREA_VAR']] # ---------------------------------------------------------------- # #Find Destination grid cells log.info('Finding addresses now...') routys, routxs = latlon2yx(plats=lats, plons=lons, glats=fdr_lats, glons=fdr_lons) domys, domxs = latlon2yx(plats=lats, plons=lons, glats=dom_lat, glons=dom_lon) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Do the aggregation outlets = {} for i, (lat, lon) in enumerate(zip(lats, lons)): # Define pour point object (on ) pour_point = Point(lat=lat, lon=lon, domx=domxs[i], domy=domys[i], routx=routxs[i], routy=routys[i], name=None, cell_id=dom_ids[domys[i], domxs[i]]) pour_point.source_area = fdr_srcarea[pour_point.routy, pour_point.routx] cell_id = dom_ids[domys[i], domxs[i]] if cell_id in outlets: outlets[cell_id].pour_points.append(pour_point) outlets[cell_id].upstream_area += pour_point.source_area else: # define outlet grid cell (on domain grid) outlets[cell_id] = Point(domy=domys[i], domx=domxs[i], lat=dom_lat[domys[i], domxs[i]], lon=dom_lon[domys[i], domxs[i]]) outlets[cell_id].pour_points = [pour_point] outlets[cell_id].cell_id = cell_id outlets[cell_id].upstream_area = pour_point.source_area # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Sort based on outlet total source area pour_point.source_area outlets = OrderedDict( sorted(outlets.items(), key=lambda t: t[1].upstream_area, reverse=True)) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Count the pairs pp_count = 0 key_count = 0 num = len(lons) for i, key in enumerate(outlets): key_count += 1 pp_count += len(outlets[key].pour_points) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Print Debug Results log.info('\n------------------ SUMMARY OF MakeAggPairs ------------------') log.info('NUMBER OF POUR POINTS IN INPUT LIST: %i' % num) log.info('NUMBER OF POINTS TO AGGREGATE TO: %i' % key_count) log.info('NUMBER OF POUR POINTS AGGREGATED: %i' % pp_count) log.info('EFFECIENCY OF: %.2f %%' % (100. * pp_count / num)) log.info('UNASSIGNED POUR POINTS: %i' % (num - pp_count)) log.info('-------------------------------------------------------------\n') # ---------------------------------------------------------------- # return outlets
def make_agg_pairs(pour_points, dom_data, fdr_data, config_dict): # def make_agg_pairs(lons, lats, dom_lon, dom_lat, dom_ids, # fdr_lons, fdr_lats, fdr_srcarea, agg_type='agg'): """ Group pour points by domain grid outlet cell """ lons = pour_points['lons'] lats = pour_points['lats'] dom_lon = dom_data[config_dict['DOMAIN']['LONGITUDE_VAR']] dom_lat = dom_data[config_dict['DOMAIN']['LATITUDE_VAR']] dom_ids = dom_data['cell_ids'] fdr_lons = fdr_data[config_dict['ROUTING']['LONGITUDE_VAR']] fdr_lats = fdr_data[config_dict['ROUTING']['LATITUDE_VAR']] fdr_srcarea = fdr_data[config_dict['ROUTING']['SOURCE_AREA_VAR']] routys, routxs = latlon2yx(plats=lats, plons=lons, glats=fdr_lats, glons=fdr_lons) # ---------------------------------------------------------------- # #Find Destination grid cells log.info('Finding addresses now...') if (min(lons) < 0 and dom_lon.min() >= 0): posinds = np.nonzero(dom_lon > 180) dom_lon[posinds] -= 360 log.info('adjusted domain lon minimum') if (min(lons) < 0 and fdr_lons.min() >= 0): posinds = np.nonzero(fdr_lons > 180) fdr_lons[posinds] -= 360 log.info('adjusted fdr lon minimum') combined = np.dstack(([dom_lat.ravel(), dom_lon.ravel()]))[0] points = list(np.vstack((np.array(lats), np.array(lons))).transpose()) mytree = cKDTree(combined) dist, indexes = mytree.query(points, k=1) gridys, gridxs = np.unravel_index(np.array(indexes), dom_lat.shape) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Do the aggregation outlets = {} for i, ind in enumerate(indexes): # Define pour point object (on ) pour_point = Point(lat=lats[i], lon=lons[i], gridx=gridxs[i], gridy=gridys[i], routx=routxs[i], routy=routys[i], name=None, cell_id=dom_ids[gridys[i], gridxs[i]]) pour_point.source_area = fdr_srcarea[pour_point.routy, pour_point.routx] cell_id = dom_ids[gridys[i], gridxs[i]] if cell_id in outlets: outlets[cell_id].pour_points.append(pour_point) outlets[cell_id].upstream_area += pour_point.source_area else: # define outlet grid cell (on domain grid) outlets[cell_id] = Point(gridy=gridys[i], gridx=gridxs[i], lat=combined[ind][0], lon=combined[ind][1]) outlets[cell_id].pour_points = [pour_point] outlets[cell_id].cell_id = cell_id outlets[cell_id].upstream_area = pour_point.source_area # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Sort based on outlet total source area pour_point.source_area outlets = OrderedDict(sorted(outlets.items(), key=lambda t: t[1].upstream_area, reverse=True)) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Count the pairs pp_count = 0 key_count = 0 num = len(lons) for i, key in enumerate(outlets): key_count += 1 pp_count += len(outlets[key].pour_points) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Print Debug Results log.info('\n------------------ SUMMARY OF MakeAggPairs ------------------') log.info('NUMBER OF POUR POINTS IN INPUT LIST: %i' % num) log.info('NUMBER OF POINTS TO AGGREGATE TO: %i' % key_count) log.info('NUMBER OF POUR POINTS AGGREGATED: %i' % pp_count) log.info('EFFECIENCY OF: %.2f %%' % (100.*pp_count / num)) log.info('UNASSIGNED POUR POINTS: %i \n' % (num-pp_count)) log.info('---------------------------------------------------------------\n') # ---------------------------------------------------------------- # return outlets
def rout(pour_point, uh_box, fdr_data, fdr_atts, rout_dict): """ Make the Unit Hydrograph Grid """ log.info("Starting routing program for point: %s", pour_point) # ---------------------------------------------------------------- # # Unpack a few structures uh_t = uh_box['time'] uh_box = uh_box['func'] # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Find Basin Dims and ID basin_id = fdr_data[rout_dict['BASIN_ID_VAR']][pour_point.routy, pour_point.routx] log.info('Input Latitude: %f', pour_point.lat) log.info('Input Longitude: %f', pour_point.lon) log.info('Global Basid ID: %i', basin_id) y_inds, x_inds = np.nonzero(fdr_data[rout_dict['BASIN_ID_VAR']] == basin_id) y = np.arange(len(fdr_data[rout_dict['LATITUDE_VAR']])) x = np.arange(len(fdr_data[rout_dict['LONGITUDE_VAR']])) x_min = min(x[x_inds]) x_max = max(x[x_inds])+1 y_min = min(y[y_inds]) y_max = max(y[y_inds])+1 # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Create the Basin Dictionary, a subset of the fdr_data basin = {} basin['lat'] = fdr_data[rout_dict['LATITUDE_VAR']][y_min:y_max] basin['lon'] = fdr_data[rout_dict['LONGITUDE_VAR']][x_min:x_max] basin['basin_id'] = fdr_data[rout_dict['BASIN_ID_VAR']][y_min:y_max, x_min:x_max] basin['flow_direction'] = fdr_data[rout_dict['FLOW_DIRECTION_VAR']][y_min:y_max, x_min:x_max] basin['flow_distance'] = fdr_data[rout_dict['FLOW_DISTANCE_VAR']][y_min:y_max, x_min:x_max] basin['velocity'] = fdr_data['velocity'][y_min:y_max, x_min:x_max] basin['diffusion'] = fdr_data['diffusion'][y_min:y_max, x_min:x_max] log.debug('Grid cells in subset: %i', basin['velocity'].size) pour_point.basiny, pour_point.basinx = latlon2yx(plats=pour_point.lat, plons=pour_point.lon, glats=basin['lat'], glons=basin['lon']) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Create the rout_data Dictionary rout_data = {'lat': basin['lat'], 'lon': basin['lon'], 'dom_x_min': x_min, 'dom_y_min': y_min, 'dom_x_max': x_max, 'dom_y_max': y_max} log.debug('Clipping indicies:') log.debug('dom_x_min: %s', rout_data['dom_x_min']) log.debug('dom_x_max: %s', rout_data['dom_x_max']) log.debug('dom_y_min: %s', rout_data['dom_y_min']) log.debug('dom_y_max: %s', rout_data['dom_y_max']) # ---------------------------------------------------------------- # # Determine/Set flow direction syntax # Flow directions {north, northeast, east, southeast, # south, southwest, west, northwest} if 'VIC' in fdr_atts[rout_dict['FLOW_DIRECTION_VAR']] or \ fdr_data[rout_dict['FLOW_DIRECTION_VAR']].max() < 10: # VIC Directions: http://www.hydro.washington.edu/Lettenmaier/Models/\ # VIC/Documentation/Routing/FlowDirection.shtml dy = {1: -1, 2: -1, 3: 0, 4: 1, 5: 1, 6: 1, 7: 0, 8: -1} dx = {1: 0, 2: 1, 3: 1, 4: 1, 5: 0, 6: -1, 7: -1, 8: - 1} log.debug('Using VIC flow directions (1-8).') else: # ARCMAP Directions: http://webhelp.esri.com/arcgisdesktop/9.2/\ # index.cfm?TopicName=flow_direction dy = {64: -1, 128: -1, 1: 0, 2: 1, 4: 1, 8: 1, 16: 0, 32: -1} dx = {64: 0, 128: 1, 1: 1, 2: 1, 4: 0, 8: -1, 16: -1, 32: -1} log.debug('Using ARCMAP flow directions (1-128).') # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Find timestep (timestep is determined from uh_BOX input file) input_interval = find_ts(uh_t) rout_data['unit_hydrograph_dt'] = input_interval t_cell = int(rout_dict['CELL_FLOWDAYS']*SECSPERDAY/input_interval) t_uh = int(rout_dict['BASIN_FLOWDAYS']*SECSPERDAY/input_interval) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Read direction grid and find to_col (to_x) and to_row (to_y) to_y, to_x = read_direction(basin['flow_direction'], dy, dx) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Find all grid cells upstream of pour point catchment, rout_data['fraction'] = search_catchment(to_y, to_x, pour_point, basin['basin_id'], basin_id) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Make uh for each grid cell upstream of basin pour point # (linear routing model - Saint-Venant equation) uh = make_uh(input_interval, t_cell, catchment['y_inds'], catchment['x_inds'], basin['velocity'], basin['diffusion'], basin['flow_distance']) # ---------------------------------------------------------------- # # Make uh_river by incrementally moving upstream comining uh functions uh_river = make_grid_uh_river(t_uh, t_cell, uh, to_y, to_x, pour_point, catchment['y_inds'], catchment['x_inds'], catchment['count_ds']) # ---------------------------------------------------------------- # # Make uh_s for each grid cell upstream of basin pour point # (combine IRFs for all grid cells in flow path) uh_s = make_grid_uh(t_uh, t_cell, uh_river, uh_box, to_y, to_x, catchment['y_inds'], catchment['x_inds'], catchment['count_ds']) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Agregate to output timestep rout_data['unit_hydrograph'], \ rout_data['timesteps'] = adjust_uh_timestep(uh_s, t_uh, input_interval, rout_dict['OUTPUT_INTERVAL'], catchment['x_inds'], catchment['y_inds']) # ---------------------------------------------------------------- # return rout_data
def rout(pour_point, uh_box, fdr_data, fdr_atts, rout_dict): """ Make the Unit Hydrograph Grid """ log.info("Starting routing program for point: %s", pour_point) # ---------------------------------------------------------------- # # Unpack a few structures uh_t = uh_box['time'] uh_box = uh_box['func'] # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Find Basin Dims and ID basin_id = fdr_data[rout_dict['BASIN_ID_VAR']][pour_point.routy, pour_point.routx] log.info('Input Latitude: %f', pour_point.lat) log.info('Input Longitude: %f', pour_point.lon) log.info('Global Basid ID: %i', basin_id) y_inds, x_inds = np.nonzero( fdr_data[rout_dict['BASIN_ID_VAR']] == basin_id) y = np.arange(len(fdr_data[rout_dict['LATITUDE_VAR']])) x = np.arange(len(fdr_data[rout_dict['LONGITUDE_VAR']])) x_min = min(x[x_inds]) x_max = max(x[x_inds]) + 1 y_min = min(y[y_inds]) y_max = max(y[y_inds]) + 1 # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Create the Basin Dictionary, a subset of the fdr_data basin = {} basin['lat'] = fdr_data[rout_dict['LATITUDE_VAR']][y_min:y_max] basin['lon'] = fdr_data[rout_dict['LONGITUDE_VAR']][x_min:x_max] basin['basin_id'] = fdr_data[rout_dict['BASIN_ID_VAR']][y_min:y_max, x_min:x_max] basin['flow_direction'] = fdr_data[rout_dict['FLOW_DIRECTION_VAR']][ y_min:y_max, x_min:x_max] basin['flow_distance'] = fdr_data[rout_dict['FLOW_DISTANCE_VAR']][ y_min:y_max, x_min:x_max] basin['velocity'] = fdr_data['velocity'][y_min:y_max, x_min:x_max] basin['diffusion'] = fdr_data['diffusion'][y_min:y_max, x_min:x_max] log.debug('Grid cells in subset: %i', basin['velocity'].size) pour_point.basiny, pour_point.basinx = latlon2yx(plats=pour_point.lat, plons=pour_point.lon, glats=basin['lat'], glons=basin['lon']) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Create the rout_data Dictionary rout_data = { 'lat': basin['lat'], 'lon': basin['lon'], 'dom_x_min': x_min, 'dom_y_min': y_min, 'dom_x_max': x_max, 'dom_y_max': y_max } log.debug('Clipping indicies:') log.debug('dom_x_min: %s', rout_data['dom_x_min']) log.debug('dom_x_max: %s', rout_data['dom_x_max']) log.debug('dom_y_min: %s', rout_data['dom_y_min']) log.debug('dom_y_max: %s', rout_data['dom_y_max']) # ---------------------------------------------------------------- # # Determine/Set flow direction syntax # Flow directions {north, northeast, east, southeast, # south, southwest, west, northwest} if 'VIC' in fdr_atts[rout_dict['FLOW_DIRECTION_VAR']] or \ fdr_data[rout_dict['FLOW_DIRECTION_VAR']].max() < 10: # VIC Directions: http://www.hydro.washington.edu/Lettenmaier/Models/\ # VIC/Documentation/Routing/FlowDirection.shtml dy = {1: -1, 2: -1, 3: 0, 4: 1, 5: 1, 6: 1, 7: 0, 8: -1} dx = {1: 0, 2: 1, 3: 1, 4: 1, 5: 0, 6: -1, 7: -1, 8: -1} log.debug('Using VIC flow directions (1-8).') else: # ARCMAP Directions: http://webhelp.esri.com/arcgisdesktop/9.2/\ # index.cfm?TopicName=flow_direction dy = {64: -1, 128: -1, 1: 0, 2: 1, 4: 1, 8: 1, 16: 0, 32: -1} dx = {64: 0, 128: 1, 1: 1, 2: 1, 4: 0, 8: -1, 16: -1, 32: -1} log.debug('Using ARCMAP flow directions (1-128).') # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Find timestep (timestep is determined from uh_BOX input file) input_interval = find_ts(uh_t) rout_data['unit_hydrograph_dt'] = input_interval t_cell = int(rout_dict['CELL_FLOWDAYS'] * SECSPERDAY / input_interval) t_uh = int(rout_dict['BASIN_FLOWDAYS'] * SECSPERDAY / input_interval) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Read direction grid and find to_col (to_x) and to_row (to_y) to_y, to_x = read_direction(basin['flow_direction'], dy, dx) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Find all grid cells upstream of pour point catchment, rout_data['fraction'] = search_catchment( to_y, to_x, pour_point, basin['basin_id'], basin_id) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Make uh for each grid cell upstream of basin pour point # (linear routing model - Saint-Venant equation) uh = make_uh(input_interval, t_cell, catchment['y_inds'], catchment['x_inds'], basin['velocity'], basin['diffusion'], basin['flow_distance']) # ---------------------------------------------------------------- # # Make uh_river by incrementally moving upstream comining uh functions uh_river = make_grid_uh_river(t_uh, t_cell, uh, to_y, to_x, pour_point, catchment['y_inds'], catchment['x_inds'], catchment['count_ds']) # ---------------------------------------------------------------- # # Make uh_s for each grid cell upstream of basin pour point # (combine IRFs for all grid cells in flow path) uh_s = make_grid_uh(t_uh, t_cell, uh_river, uh_box, to_y, to_x, catchment['y_inds'], catchment['x_inds'], catchment['count_ds']) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Agregate to output timestep rout_data['unit_hydrograph'], \ rout_data['timesteps'] = adjust_uh_timestep(uh_s, t_uh, input_interval, rout_dict['OUTPUT_INTERVAL'], catchment['x_inds'], catchment['y_inds']) # ---------------------------------------------------------------- # return rout_data
def make_agg_pairs(pour_points, dom_data, fdr_data, config_dict): """ Group pour points by domain grid outlet cell """ lons = pour_points["lons"] lats = pour_points["lats"] dom_lon = dom_data[config_dict["DOMAIN"]["LONGITUDE_VAR"]] dom_lat = dom_data[config_dict["DOMAIN"]["LATITUDE_VAR"]] dom_ids = dom_data["cell_ids"] fdr_lons = fdr_data[config_dict["ROUTING"]["LONGITUDE_VAR"]] fdr_lats = fdr_data[config_dict["ROUTING"]["LATITUDE_VAR"]] fdr_srcarea = fdr_data[config_dict["ROUTING"]["SOURCE_AREA_VAR"]] # ---------------------------------------------------------------- # # Find Destination grid cells log.info("Finding addresses now...") routys, routxs = latlon2yx(plats=lats, plons=lons, glats=fdr_lats, glons=fdr_lons) domys, domxs = latlon2yx(plats=lats, plons=lons, glats=dom_lat, glons=dom_lon) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Do the aggregation outlets = {} for i, (lat, lon) in enumerate(zip(lats, lons)): # Define pour point object pour_point = Point( lat=lat, lon=lon, domx=domxs[i], domy=domys[i], routx=routxs[i], routy=routys[i], name=None, cell_id=dom_ids[domys[i], domxs[i]], ) pour_point.source_area = fdr_srcarea[pour_point.routy, pour_point.routx] cell_id = dom_ids[domys[i], domxs[i]] if cell_id in outlets: outlets[cell_id].pour_points.append(pour_point) outlets[cell_id].upstream_area += pour_point.source_area else: # define outlet grid cell (on domain grid) outlets[cell_id] = Point( domy=domys[i], domx=domxs[i], lat=dom_lat[domys[i], domxs[i]], lon=dom_lon[domys[i], domxs[i]] ) outlets[cell_id].pour_points = [pour_point] outlets[cell_id].cell_id = cell_id outlets[cell_id].upstream_area = pour_point.source_area # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Sort based on outlet total source area pour_point.source_area outlets = OrderedDict(sorted(outlets.items(), key=lambda t: t[1].upstream_area, reverse=True)) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Count the pairs pp_count = 0 key_count = 0 num = len(lons) for i, key in enumerate(outlets): key_count += 1 pp_count += len(outlets[key].pour_points) # ---------------------------------------------------------------- # # ---------------------------------------------------------------- # # Print Debug Results log.info("\n------------------ SUMMARY OF MakeAggPairs ------------------") log.info("NUMBER OF POUR POINTS IN INPUT LIST: %i" % num) log.info("NUMBER OF POINTS TO AGGREGATE TO: %i" % key_count) log.info("NUMBER OF POUR POINTS AGGREGATED: %i" % pp_count) log.info("EFFECIENCY OF: %.2f %%" % (100.0 * pp_count / num)) log.info("UNASSIGNED POUR POINTS: %i" % (num - pp_count)) log.info("-------------------------------------------------------------\n") # ---------------------------------------------------------------- # return outlets