def Add_Inlets(Name_NC_Runoff, Inflow_Text_Files): ''' This functions add inflow to the runoff dataset before the channel routing. The inflow must be a text file with a certain format. The first line of this format are the latitude and longitude. Hereafter for each line the time (ordinal time) and the inflow (m3/month) seperated with one space is defined. See example below: [lat lon] 733042 156225.12 733073 32511321.2 733102 212315.25 733133 2313266.554 ''' # General modules import numpy as np # Water Accounting modules import wa.General.raster_conversions as RC import wa.Functions.Start.Area_converter as Area # Open information and open the Runoff array Runoff_dataCube = RC.Open_nc_array(Name_NC_Runoff) geo_out, epsg, size_X, size_Y, size_Z, Time = RC.Open_nc_info( Name_NC_Runoff) # Calculate the surface area of every pixel dlat, dlon = Area.Calc_dlat_dlon(geo_out, size_X, size_Y) area_in_m2 = dlat * dlon for Inflow_Text_File in Inflow_Text_Files: # Open the inlet text data Inlet = np.genfromtxt(Inflow_Text_File, dtype=None, delimiter=" ") # Read out the coordinates Coord = Inlet[0, :] Lon_coord = Coord[0][1:] Lat_coord = Coord[1][:-1] # Search for the pixel lon_pix = int(np.ceil((float(Lon_coord) - geo_out[0]) / geo_out[1])) lat_pix = int(np.ceil((float(Lat_coord) - geo_out[3]) / geo_out[5])) # Add the value on top of the Runoff array for i in range(1, len(Inlet)): time = float(Inlet[i, 0]) time_step = np.argwhere(np.logical_and(Time >= time, Time <= time)) if len(time_step) > 0: time_step_array = int(time_step[0][0]) value_m3_month = float(Inlet[i, 1]) area_in_m2_pixel = area_in_m2[lat_pix, lon_pix] value_mm = (value_m3_month / area_in_m2_pixel) * 1000 Runoff_dataCube[time_step_array, lat_pix, lon_pix] = Runoff_dataCube[time_step_array, lat_pix, lon_pix] + value_mm return (Runoff_dataCube)
def Run(input_nc, output_nc): # Extract flow direction data from NetCDF file flow_directions = RC.Open_nc_array(input_nc, Var = 'demdir') # Open River Array Rivers = RC.Open_nc_array(output_nc, Var = 'rivers') # Open Accumulated Pixel Array Accumulated_Pixels = RC.Open_nc_array(output_nc, Var = 'accpix') # Open Routed discharge Array Routed_Array = RC.Open_nc_array(output_nc, Var = 'discharge_natural') # Get the raster shape geo_out_example, epsg_example, size_X_example, size_Y_example, size_Z_example, Time_example = RC.Open_nc_info(input_nc) geo_out_example = np.array(geo_out_example) # Create a river array with a boundary of 1 pixel Rivers_bounds = np.zeros([size_Y_example+2, size_X_example+2]) Rivers_bounds[1:-1,1:-1] = Rivers # Create a flow direction array with a boundary of 1 pixel flow_directions[flow_directions==0]=-32768 flow_directions_bound = np.ones([size_Y_example+2, size_X_example+2]) * -32768 flow_directions_bound[1:-1,1:-1] = flow_directions # Create ID Matrix y,x = np.indices((size_Y_example, size_X_example)) ID_Matrix = np.int32(np.ravel_multi_index(np.vstack((y.ravel(),x.ravel())),(size_Y_example,size_X_example),mode='clip').reshape(x.shape)) ID_Matrix_bound = np.ones([size_Y_example+2, size_X_example+2]) * -32768 ID_Matrix_bound[1:-1,1:-1] = ID_Matrix + 1 ID_Matrix_bound[flow_directions_bound==-32768]=-32768 del x, y # Empty total from and to arrays ID_to_total=np.array([]) ID_from_total=np.array([]) # The flow directions parameters of HydroSHED Directions = [1, 2, 4, 8, 16, 32, 64, 128] # Loop over the directions for Direction in Directions: # empty from and to arrays for 1 direction data_flow_to = np.zeros([size_Y_example + 2, size_X_example + 2]) data_flow_from = np.zeros([size_Y_example + 2, size_X_example + 2]) # Get the ID of only the rivers data_flow_to_ID = np.zeros([size_Y_example + 2, size_X_example + 2]) data_flow_in = np.ones([size_Y_example + 2, size_X_example + 2]) * Rivers_bounds # Mask only one direction data_flow_from[flow_directions_bound == Direction] = data_flow_in[flow_directions_bound == Direction] * ID_Matrix_bound[flow_directions_bound == Direction] # Add the data flow to ID if Direction == 4: data_flow_to[1:,:] = data_flow_from[:-1,:] if Direction == 2: data_flow_to[1:,1:] = data_flow_from[:-1,:-1] if Direction == 1: data_flow_to[:,1:] = data_flow_from[:,:-1] if Direction == 128: data_flow_to[:-1,1:] = data_flow_from[1:,:-1] if Direction == 64: data_flow_to[:-1,:] = data_flow_from[1:,:] if Direction == 32: data_flow_to[:-1,:-1] = data_flow_from[1:,1:] if Direction == 16: data_flow_to[:,:-1] = data_flow_from[:,1:] if Direction == 8: data_flow_to[1:,:-1] = data_flow_from[:-1,1:] # mask out the no river pixels data_flow_to_ID[data_flow_to>0] = ID_Matrix_bound[data_flow_to>0] # Collect to and from arrays ID_from_total = np.append(ID_from_total,data_flow_from[data_flow_from!=0].ravel()) ID_to_total = np.append(ID_to_total,data_flow_to_ID[data_flow_to_ID!=0].ravel()) ######################## Define the starting point ############################ # Open Basin area Basin = RC.Open_nc_array(input_nc, Var = 'basin') Basin = -1 * (Basin - 1) Basin_Buffer = RC.Create_Buffer(Basin, 8) Possible_End_Points = np.zeros(Basin.shape) Possible_End_Points[(Basin_Buffer + Rivers) == 2] = 1 End_Points = [[0,0]] rows_col_possible_end_pixels = np.argwhere(Possible_End_Points == 1) # Accumulated_Pixels_possible = ID_Matrix * Possible_End_Points for PosPix in rows_col_possible_end_pixels: Accumulated_Pixels_possible_Area = Accumulated_Pixels[PosPix[0]-1:PosPix[0]+2, PosPix[1]-1:PosPix[1]+2] Max_acc_possible_area = np.max(Accumulated_Pixels_possible_Area) middle_pixel = Accumulated_Pixels_possible_Area[1,1] if Max_acc_possible_area == middle_pixel: if flow_directions[PosPix[0],PosPix[1]] == -32768: acc_aux = np.copy(Accumulated_Pixels_possible_Area) acc_aux[1,1] = 0 off_y = np.where(acc_aux == np.max(acc_aux))[1][0] - 1 off_x = np.where(acc_aux == np.max(acc_aux))[0][0] - 1 PosPix[0] = PosPix[0] + off_x PosPix[1] = PosPix[1] + off_y if End_Points == []: End_Points = PosPix else: End_Points = np.vstack([End_Points, PosPix]) # Create an empty dictionary for the rivers River_dict = dict() # Create empty array for the loop ID_starts_next = [] i = 0 for End_Point in End_Points[1:]: # Define starting point # Max_Acc_Pix = np.nanmax(Accumulated_Pixels[ID_Matrix_bound[1:-1,1:-1]>0]) # ncol, nrow = np.argwhere(Accumulated_Pixels==Max_Acc_Pix)[0] # Add Bounds # col = ncol + 1 # row = nrow + 1 col = End_Point[0] + 1 row = End_Point[1] + 1 ############################ Route the river ################################## # Get the ID of the starting point ID_starts = [ID_Matrix_bound[col,row]] # Keep going on till all the branches are looped while len(ID_starts) > 0: for ID_start in ID_starts: ID_start = int(ID_start) # Empty parameters for new starting point new = 0 IDs = [] # Add starting point Arrays_from = np.argwhere(ID_from_total[:] == ID_start) ID_from = ID_to_total[int(Arrays_from[0])] IDs = np.array([ID_from, ID_start]) ID_start_now = ID_start # Keep going till the branch ends while new == 0: Arrays_to = np.argwhere(ID_to_total[:] == ID_start) # Add IDs to the river dictionary if len(Arrays_to)>1 or len(Arrays_to) == 0: River_dict[i] = IDs i += 1 new = 1 # Define the next loop for the new branches for j in range(0, len(Arrays_to)): ID_starts_next = np.append(ID_starts_next,ID_from_total[int(Arrays_to[j])]) # If it was the last one then empty ID_start_next if ID_start_now == ID_starts[-1]: ID_starts = ID_starts_next ID_starts_next = [] # Add pixel to tree for river dictionary else: ID_start = ID_from_total[Arrays_to[0]] IDs = np.append(IDs, ID_start) ######################## Create dict distance and dict dem #################### # Extract DEM data from NetCDF file DEM = RC.Open_nc_array(input_nc, Var = 'dem') # Get the distance of a horizontal and vertical flow pixel (assuming it flows in a straight line) import wa.Functions.Start.Area_converter as AC vertical, horizontal = AC.Calc_dlat_dlon(geo_out_example,size_X_example, size_Y_example) # Calculate a diagonal flowing pixel (assuming it flos in a straight line) diagonal = np.power((np.square(vertical) + np.square(horizontal)),0.5) # Create empty distance array Distance = np.zeros([size_Y_example, size_X_example]) # Fill in the distance array Distance[np.logical_or(flow_directions == 1,flow_directions == 16)] = horizontal[np.logical_or(flow_directions == 1,flow_directions == 16)] Distance[np.logical_or(flow_directions == 64,flow_directions == 4)] = vertical[np.logical_or(flow_directions == 64,flow_directions == 4)] Distance[np.logical_or(np.logical_or(np.logical_or(flow_directions == 32,flow_directions == 8),flow_directions == 128),flow_directions == 2)] = diagonal[np.logical_or(np.logical_or(np.logical_or(flow_directions == 32,flow_directions == 8),flow_directions == 128),flow_directions == 2)] # Create empty dicionaries for discharge, distance, and DEM Discharge_dict = dict() Distance_dict = dict() DEM_dict = dict() # Create empty arrays needed for the loop River_end = [] River_ends = np.zeros([2,3]) # Loop over the branches for River_number in range(0,len(River_dict)): # Get the pixels associated with the river section River = River_dict[River_number] i=1 # Create empty arrays Distances_river = np.zeros([len(River)]) DEM_river = np.zeros([len(River)]) Discharge_river = np.zeros([len(River)]) # for the first pixel get the previous pixel value from another branche row_start = np.argwhere(River_ends[:,0] == River[0]) if len(row_start) < 1: Distances_river[0] = 0 row, col = np.argwhere(ID_Matrix_bound == River[0])[0][:] DEM_river[0] = DEM[row - 1, col - 1] Discharge_river[0] = -9999 else: Distances_river[0] = River_ends[row_start, 1] DEM_river[0] = River_ends[row_start, 2] row, col = np.argwhere(ID_Matrix_bound == River[0])[0][:] #Discharge_river[0] = Routed_Discharge[timestep, row - 1, col - 1] # For the other pixels get the value of the River ID pixel for River_part in River[1:]: row, col = np.argwhere(ID_Matrix_bound == River_part)[0][:] Distances_river[i] = Distance[row - 1, col - 1] DEM_river[i] = np.max([DEM_river[i-1],DEM[row - 1, col - 1]]) #Discharge_river[i] = Routed_Discharge[timestep, row - 1, col - 1] if River_part == River[1] and Discharge_river[i-1] == -9999: Discharge_river[i - 1] = Discharge_river[i] i += 1 # Write array in dictionary DEM_dict[River_number] = DEM_river Discharge_dict[River_number] = Discharge_river Distance_dict[River_number] = np.cumsum(Distances_river) # Save the last pixel value River_end[:] = [River_part , np.cumsum(Distances_river)[-1], DEM_river[-1]] River_ends = np.vstack((River_ends, River_end)) ########################## Discharge Dictionary ############################### # Create ID Matrix y,x = np.indices((size_Y_example, size_X_example)) ID_Matrix = np.int32(np.ravel_multi_index(np.vstack((y.ravel(),x.ravel())),(size_Y_example,size_X_example),mode='clip').reshape(x.shape)) ID_Matrix_bound = np.ones([size_Y_example+2, size_X_example+2]) * -32768 ID_Matrix_bound[1:-1,1:-1] = ID_Matrix + 1 del x, y # Create empty dicionaries for discharge, distance, and DEM Discharge_dict = dict() Amount_months = len(RC.Open_nc_array(input_nc, Var = 'time')) # Loop over the branches for River_number in range(0,len(River_dict)): # Get the pixels associated with the river section River = River_dict[River_number] i=0 # Create empty arrays Discharge_river = np.zeros([Amount_months, len(River)]) # For the other pixels get the value of the River ID pixel for River_part in River[:]: row, col = np.argwhere(ID_Matrix_bound == River_part)[0][:] Discharge_river[:,i] = Routed_Array[:, row - 1, col - 1] i += 1 # Write array in dictionary Discharge_dict[River_number] = Discharge_river print(River_number) return(DEM_dict, River_dict, Distance_dict, Discharge_dict)
def Find_Area_Volume_Relation(region, input_JRC, DEM_dataset): # Find relation between V and A import numpy as np import wa.General.raster_conversions as RC import wa.General.data_conversions as DC from scipy.optimize import curve_fit import matplotlib.pyplot as plt def func(x, a, b): """ This function is used for finding relation area and volume """ return (a * x**b) def func3(x, a, b, c, d): """ This function is used for finding relation area and volume """ return (a * (x - c)**b + d) #Array, Geo_out = RC.clip_data(input_JRC,latlim=[14.528,14.985],lonlim =[35.810,36.005]) Array, Geo_out = RC.clip_data( input_JRC, latlim=[region[2], region[3]], lonlim=[region[0], region[1] ]) # This reservoir was not filled when SRTM was taken size_Y = int(np.shape([Array])[-2]) size_X = int(np.shape([Array])[-1]) Water_array = np.zeros(np.shape(Array)) buffer_zone = 4 Array[Array > 0] = 1 for i in range(0, size_Y): for j in range(0, size_X): Water_array[i, j] = np.max(Array[ np.maximum(0, i - buffer_zone):np.minimum(size_Y, i + buffer_zone + 1), np.maximum(0, j - buffer_zone):np.minimum(size_X, j + buffer_zone + 1)]) del Array # Open DEM and reproject # Save Example as memory file dest_example = DC.Save_as_MEM(Water_array, Geo_out, projection='WGS84') # reproject DEM by using example dest_out = RC.reproject_dataset_example(DEM_dataset, dest_example, method=2) DEM = dest_out.GetRasterBand(1).ReadAsArray() # find DEM water heights DEM_water = np.zeros(np.shape(Water_array)) DEM_water[Water_array != 1] = np.nan DEM_water[Water_array == 1.] = DEM[Water_array == 1.] # Get array with areas import wa.Functions.Start.Area_converter as Area dlat, dlon = Area.Calc_dlat_dlon(Geo_out, size_X, size_Y) area_in_m2 = dlat * dlon # find volume and Area min_DEM_water = int(np.round(np.nanmin(DEM_water))) max_DEM_water = int(np.round(np.nanmax(DEM_water))) Reservoir_characteristics = np.zeros([1, 5]) i = 0 for height in range(min_DEM_water + 1, max_DEM_water): DEM_water_below_height = np.zeros(np.shape(DEM_water)) DEM_water[np.isnan(DEM_water)] = 1000000 DEM_water_below_height[DEM_water < height] = 1 pixels = np.sum(DEM_water_below_height) area = np.sum(DEM_water_below_height * area_in_m2) if height == min_DEM_water + 1: volume = 0.5 * area histogram = pixels Reservoir_characteristics[:] = [ height, pixels, area, volume, histogram ] else: area_previous = Reservoir_characteristics[i, 2] volume_previous = Reservoir_characteristics[i, 3] volume = volume_previous + 0.5 * ( area - area_previous) + 1 * area_previous histogram_previous = Reservoir_characteristics[i, 1] histogram = pixels - histogram_previous Reservoir_characteristics_one = [ height, pixels, area, volume, histogram ] Reservoir_characteristics = np.append( Reservoir_characteristics, Reservoir_characteristics_one) i += 1 Reservoir_characteristics = np.resize(Reservoir_characteristics, (i + 1, 5)) maxi = int(len(Reservoir_characteristics[:, 3])) # find minimum value for reservoirs height (DEM is same value if reservoir was already filled whe SRTM was created) Historgram = Reservoir_characteristics[:, 4] hist_mean = np.mean(Historgram) hist_std = np.std(Historgram) mini_tresh = hist_std * 5 + hist_mean Check_hist = np.zeros([len(Historgram)]) Check_hist[Historgram > mini_tresh] = Historgram[Historgram > mini_tresh] if np.max(Check_hist) != 0.0: col = np.argwhere(Historgram == np.max(Check_hist))[0][0] mini = col + 1 else: mini = 0 fitted = 0 # find starting point reservoirs V0 = Reservoir_characteristics[mini, 3] A0 = Reservoir_characteristics[mini, 2] # Calculate the best maxi reservoir characteristics, based on the normal V = a*x**b relation while fitted == 0: try: if mini == 0: popt1, pcov1 = curve_fit( func, Reservoir_characteristics[mini:maxi, 2], Reservoir_characteristics[mini:maxi, 3]) else: popt1, pcov1 = curve_fit( func, Reservoir_characteristics[mini:maxi, 2] - A0, Reservoir_characteristics[mini:maxi, 3] - V0) fitted = 1 except: maxi -= 1 if maxi < mini: print 'ERROR: was not able to find optimal fit' fitted = 1 # Remove last couple of pixels of maxi maxi_end = int(np.round(maxi - 0.2 * (maxi - mini))) done = 0 times = 0 while done == 0 and times > 20 and maxi_end < mini: try: if mini == 0: popt, pcov = curve_fit( func, Reservoir_characteristics[mini:maxi_end, 2], Reservoir_characteristics[mini:maxi_end, 3]) else: popt, pcov = curve_fit( func3, Reservoir_characteristics[mini:maxi_end, 2], Reservoir_characteristics[mini:maxi_end, 3]) except: maxi_end = int(maxi) if mini == 0: popt, pcov = curve_fit( func, Reservoir_characteristics[mini:maxi_end, 2], Reservoir_characteristics[mini:maxi_end, 3]) else: popt, pcov = curve_fit( func3, Reservoir_characteristics[mini:maxi_end, 2], Reservoir_characteristics[mini:maxi_end, 3]) if mini == 0: plt.plot(Reservoir_characteristics[mini:maxi_end, 2], Reservoir_characteristics[mini:maxi_end, 3], 'ro') t = np.arange(0., np.max(Reservoir_characteristics[:, 2]), 1000) plt.plot(t, popt[0] * (t)**popt[1], 'g--') plt.axis([ 0, np.max(Reservoir_characteristics[mini:maxi_end, 2]), 0, np.max(Reservoir_characteristics[mini:maxi_end, 3]) ]) plt.show() done = 1 else: plt.plot(Reservoir_characteristics[mini:maxi_end, 2], Reservoir_characteristics[mini:maxi_end, 3], 'ro') t = np.arange(0., np.max(Reservoir_characteristics[:, 2]), 1000) plt.plot(t, popt[0] * (t - popt[2])**popt[1] + popt[3], 'g--') plt.axis([ 0, np.max(Reservoir_characteristics[mini:maxi_end, 2]), 0, np.max(Reservoir_characteristics[mini:maxi_end, 3]) ]) plt.show() Volume_error = popt[3] / V0 * 100 - 100 print 'error Volume = %s percent' % Volume_error print 'error Area = %s percent' % (A0 / popt[2] * 100 - 100) if Volume_error < 30 and Volume_error > -30: done = 1 else: times += 1 maxi_end -= 1 print 'Another run is done in order to improve the result' if done == 0: popt = np.append(popt1, [A0, V0]) if len(popt) == 2: popt = np.append(popt, [0, 0]) return (popt)
def Rivers_General(Name_NC_DEM, Name_NC_DEM_Dir, Name_NC_Acc_Pixels, Name_NC_Rivers, Reference_data): import numpy as np from wa.General import raster_conversions as RC ############################### Open needed dataset ########################### # Extract flow direction data from NetCDF file flow_directions = RC.Open_nc_array(Name_NC_DEM_Dir) # Extract Rivers data from NetCDF file Rivers = RC.Open_nc_array(Name_NC_Rivers) # Extract DEM data from NetCDF file DEM = RC.Open_nc_array(Name_NC_DEM) # Extract Accumulated pixels data from NetCDF file Accumulated_Pixels = RC.Open_nc_array(Name_NC_Acc_Pixels) ############################### Create river tree ############################# # Get the raster shape size_Y, size_X = np.shape(flow_directions) # Create a river array with a boundary of 1 pixel Rivers_bounds = np.zeros([size_Y+2, size_X+2]) Rivers_bounds[1:-1,1:-1] = Rivers # Create a flow direction array with a boundary of 1 pixel flow_directions[flow_directions==0]=-32768 flow_directions_bound = np.ones([size_Y+2, size_X+2]) * -32768 flow_directions_bound[1:-1,1:-1] = flow_directions # Create ID Matrix y,x = np.indices((size_Y, size_X)) ID_Matrix = np.int32(np.ravel_multi_index(np.vstack((y.ravel(),x.ravel())),(size_Y,size_X),mode='clip').reshape(x.shape)) ID_Matrix_bound = np.ones([size_Y+2, size_X+2]) * -32768 ID_Matrix_bound[1:-1,1:-1] = ID_Matrix + 1 ID_Matrix_bound[flow_directions_bound==-32768]=-32768 del x, y # Empty total from and to arrays ID_to_total=np.array([]) ID_from_total=np.array([]) # The flow directions parameters of HydroSHED Directions = [1, 2, 4, 8, 16, 32, 64, 128] # Loop over the directions for Direction in Directions: # empty from and to arrays for 1 direction data_flow_to = np.zeros([size_Y + 2, size_X + 2]) data_flow_from = np.zeros([size_Y + 2, size_X + 2]) # Get the ID of only the rivers data_flow_to_ID = np.zeros([size_Y + 2, size_X + 2]) data_flow_in = np.ones([size_Y + 2, size_X + 2]) * Rivers_bounds # Mask only one direction data_flow_from[flow_directions_bound == Direction] = data_flow_in[flow_directions_bound == Direction] * ID_Matrix_bound[flow_directions_bound == Direction] # Add the data flow to ID if Direction == 4: data_flow_to[1:,:] = data_flow_from[:-1,:] if Direction == 2: data_flow_to[1:,1:] = data_flow_from[:-1,:-1] if Direction == 1: data_flow_to[:,1:] = data_flow_from[:,:-1] if Direction == 128: data_flow_to[:-1,1:] = data_flow_from[1:,:-1] if Direction == 64: data_flow_to[:-1,:] = data_flow_from[1:,:] if Direction == 32: data_flow_to[:-1,:-1] = data_flow_from[1:,1:] if Direction == 16: data_flow_to[:,:-1] = data_flow_from[:,1:] if Direction == 8: data_flow_to[1:,:-1] = data_flow_from[:-1,1:] # mask out the no river pixels data_flow_to_ID[data_flow_to>0] = ID_Matrix_bound[data_flow_to>0] # Collect to and from arrays ID_from_total = np.append(ID_from_total,data_flow_from[data_flow_from!=0].ravel()) ID_to_total = np.append(ID_to_total,data_flow_to_ID[data_flow_to_ID!=0].ravel()) ######################## Define the starting point ############################ # Define starting point Max_Acc_Pix = np.nanmax(Accumulated_Pixels[ID_Matrix_bound[1:-1,1:-1]>0]) ncol, nrow = np.argwhere(Accumulated_Pixels==Max_Acc_Pix)[0] # Add Bounds col = ncol + 1 row = nrow + 1 ############################ Route the river ################################## # Get the ID of the starting point ID_starts = [ID_Matrix_bound[col,row]] # Create an empty dictionary for the rivers River_dict = dict() # Create empty array for the loop ID_starts_next = [] i = 0 # Keep going on till all the branches are looped while len(ID_starts) > 0: for ID_start in ID_starts: ID_start = int(ID_start) # Empty parameters for new starting point new = 0 IDs = [] # Add starting point Arrays_from = np.argwhere(ID_from_total[:] == ID_start) ID_from = ID_to_total[int(Arrays_from[0])] IDs = [ID_from, ID_start] ID_start_now = ID_start # Keep going till the branch ends while new == 0: Arrays_to = np.argwhere(ID_to_total[:] == ID_start) # Add IDs to the river dictionary if len(Arrays_to)>1 or len(Arrays_to) == 0: River_dict[i] = IDs i += 1 new = 1 # Define the next loop for the new branches for j in range(0, len(Arrays_to)): ID_starts_next = np.append(ID_starts_next,ID_from_total[int(Arrays_to[j])]) # If it was the last one then empty ID_start_next if ID_start_now == ID_starts[-1]: ID_starts = ID_starts_next ID_starts_next = [] # Add pixel to tree for river dictionary else: ID_start = ID_from_total[Arrays_to[0]] IDs = np.append(IDs, ID_start) ######################## Create dict distance and dict dem #################### # Get raster information geo_out, proj, size_X, size_Y = RC.Open_array_info(Reference_data) # Get the distance of a horizontal and vertical flow pixel (assuming it flows in a straight line) import wa.Functions.Start.Area_converter as AC vertical, horizontal = AC.Calc_dlat_dlon(geo_out,size_X, size_Y) # Calculate a diagonal flowing pixel (assuming it flos in a straight line) diagonal = np.power((np.square(vertical) + np.square(horizontal)),0.5) # Create empty distance array Distance = np.zeros([size_Y, size_X]) # Fill in the distance array Distance[np.logical_or(flow_directions == 1,flow_directions == 16)] = horizontal[np.logical_or(flow_directions == 1,flow_directions == 16)] Distance[np.logical_or(flow_directions == 64,flow_directions == 4)] = vertical[np.logical_or(flow_directions == 64,flow_directions == 4)] Distance[np.logical_or(np.logical_or(np.logical_or(flow_directions == 32,flow_directions == 8),flow_directions == 128),flow_directions == 2)] = diagonal[np.logical_or(np.logical_or(np.logical_or(flow_directions == 32,flow_directions == 8),flow_directions == 128),flow_directions == 2)] # Create empty dicionaries for discharge, distance, and DEM Discharge_dict = dict() Distance_dict = dict() DEM_dict = dict() # Create empty arrays needed for the loop River_end = [] River_ends = np.zeros([2,3]) # Loop over the branches for River_number in range(0,len(River_dict)): # Get the pixels associated with the river section River = River_dict[River_number] i=1 # Create empty arrays Distances_river = np.zeros([len(River)]) DEM_river = np.zeros([len(River)]) Discharge_river = np.zeros([len(River)]) # for the first pixel get the previous pixel value from another branche row_start = np.argwhere(River_ends[:,0] == River[0]) if len(row_start) < 1: Distances_river[0] = 0 row, col = np.argwhere(ID_Matrix_bound == River[0])[0][:] DEM_river[0] = DEM[row - 1, col - 1] Discharge_river[0] = -9999 else: Distances_river[0] = River_ends[row_start, 1] DEM_river[0] = River_ends[row_start, 2] row, col = np.argwhere(ID_Matrix_bound == River[0])[0][:] #Discharge_river[0] = Routed_Discharge[timestep, row - 1, col - 1] # For the other pixels get the value of the River ID pixel for River_part in River[1:]: row, col = np.argwhere(ID_Matrix_bound == River_part)[0][:] Distances_river[i] = Distance[row - 1, col - 1] DEM_river[i] = np.max([DEM_river[i-1],DEM[row - 1, col - 1]]) #Discharge_river[i] = Routed_Discharge[timestep, row - 1, col - 1] if River_part == River[1] and Discharge_river[i-1] == -9999: Discharge_river[i - 1] = Discharge_river[i] i += 1 # Write array in dictionary DEM_dict[River_number] = DEM_river Discharge_dict[River_number] = Discharge_river Distance_dict[River_number] = np.cumsum(Distances_river) # Save the last pixel value River_end[:] = [River_part , np.cumsum(Distances_river)[-1], DEM_river[-1]] River_ends = np.vstack((River_ends, River_end)) return(River_dict, DEM_dict, Distance_dict)