def Run(input_nc, output_nc, input_JRC): # Define names #Name_py_Discharge_dict_CR2 = os.path.join(Dir_Basin, 'Simulations', 'Simulation_%d' %Simulation, 'Sheet_5', 'Discharge_dict_CR2_simulation%d.npy' %(Simulation)) #Name_py_River_dict_CR2 = os.path.join(Dir_Basin, 'Simulations', 'Simulation_%d' %Simulation, 'Sheet_5', 'River_dict_CR2_simulation%d.npy' %(Simulation)) #Name_py_DEM_dict_CR2 = os.path.join(Dir_Basin, 'Simulations', 'Simulation_%d' %Simulation, 'Sheet_5', 'DEM_dict_CR2_simulation%d.npy' %(Simulation)) #Name_py_Distance_dict_CR2 = os.path.join(Dir_Basin, 'Simulations', 'Simulation_%d' %Simulation, 'Sheet_5', 'Distance_dict_CR2_simulation%d.npy' %(Simulation)) #if not (os.path.exists(Name_py_Discharge_dict_CR2) and os.path.exists(Name_py_River_dict_CR2) and os.path.exists(Name_py_DEM_dict_CR2) and os.path.exists(Name_py_Distance_dict_CR2)): # Copy dicts as starting adding reservoir import watools.General.raster_conversions as RC import numpy as np from datetime import date Discharge_dict_CR2 = RC.Open_nc_dict(output_nc, "dischargedict_dynamic") DEM_dataset = RC.Open_nc_array(input_nc, "dem") time = RC.Open_nc_array(output_nc, "time") Startdate = date.fromordinal(time[0]) Enddate = date.fromordinal(time[-1]) # Define names for reservoirs calculations #Name_py_Diff_Water_Volume = os.path.join(Dir_Basin,'Simulations','Simulation_%d' %Simulation, 'Sheet_5','Diff_Water_Volume_CR2_simulation%d.npy' %(Simulation)) #Name_py_Regions = os.path.join(Dir_Basin,'Simulations','Simulation_%d' %Simulation, 'Sheet_5','Regions_simulation%d.npy' %(Simulation)) geo_out, proj, size_X, size_Y = RC.Open_array_info(input_JRC) Boundaries = dict() Boundaries['Lonmin'] = geo_out[0] Boundaries['Lonmax'] = geo_out[0] + size_X * geo_out[1] Boundaries['Latmin'] = geo_out[3] + size_Y * geo_out[5] Boundaries['Latmax'] = geo_out[3] Regions = Calc_Regions(input_nc, output_nc, input_JRC, Boundaries) Amount_months = len(Discharge_dict_CR2[0]) Diff_Water_Volume = np.zeros([len(Regions), Amount_months, 3]) reservoir = 0 for region in Regions: popt = Find_Area_Volume_Relation(region, input_JRC, input_nc) Area_Reservoir_Values = GEE_calc_reservoir_area( region, Startdate, Enddate) Diff_Water_Volume[reservoir, :, :] = Calc_Diff_Storage( Area_Reservoir_Values, popt) reservoir += 1 ################# 7.3 Add storage reservoirs and change outflows ################## Discharge_dict_CR2, River_dict_CR2, DEM_dict_CR2, Distance_dict_CR2 = Add_Reservoirs( output_nc, Diff_Water_Volume, Regions) return (Discharge_dict_CR2, River_dict_CR2, DEM_dict_CR2, Distance_dict_CR2)
def Run(input_nc, output_nc): # Open discharge dict Discharge_dict = RC.Open_nc_dict(output_nc, 'dischargedict_dynamic') # Open River dict River_dict = RC.Open_nc_dict(output_nc, 'riverdict_static') # Open River Array Rivers = RC.Open_nc_array(output_nc, Var='rivers') # Open Supply Array DataCube_surface_withdrawal_mm = RC.Open_nc_array(input_nc, Var='Extraction_M') Areas_in_m2 = RC.Open_nc_array(input_nc, Var='area') DataCube_surface_withdrawal_m3 = ((DataCube_surface_withdrawal_mm / 1000) * Areas_in_m2) # Open Basin Array Basin = RC.Open_nc_array(input_nc, Var='basin') # Copy dicts as starting adding reservoir Discharge_dict_new = copy.deepcopy(Discharge_dict) # Open data array info based on example data geo_out_example, epsg_example, size_X_example, size_Y_example, size_Z_example, Time_example = RC.Open_nc_info( input_nc) # 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)) + 1 del x, y # Find IDs ID_Rivers = Rivers * ID_Matrix # find IDs drainage for only the basin ID_Rivers_flow = RC.gap_filling(ID_Rivers, NoDataValue=0.) * Basin Water_Error = 0 Count = 0 for i in np.unique(ID_Rivers_flow)[1:]: Count += 1 if np.nansum(DataCube_surface_withdrawal_m3[:, ID_Rivers_flow == i]) > 0: sys.stdout.write( "\r%s Procent of adding irrigation completed with %.2f x 10^9 m3 Water Error " % (np.int( np.ceil((np.float(Count) / len(np.unique(ID_Rivers_flow)) * 100))), Water_Error / 1e9)) sys.stdout.flush() #print('%s Procent of adding irrigation completed' %np.int(i/np.unique(ID_Rivers_flow)[-1]*100)) total_surface_withdrawal = np.nansum( DataCube_surface_withdrawal_m3[:, ID_Rivers_flow == i], 1) # Find exact area in river directory for River_part in iter(River_dict.items()): if len(np.argwhere(River_part[1] == i)) > 0: # Find the river part in the dictionery row_discharge = np.argwhere(River_part[1] == i)[0][0] # Subtract the withdrawal from that specific riverpart Real_Surface_Withdrawal = np.minimum( Discharge_dict_new[ River_part[0]][:, row_discharge].flatten(), total_surface_withdrawal[:, None].flatten()) Water_Error += np.maximum( np.nansum(total_surface_withdrawal[:, None].flatten() - Real_Surface_Withdrawal), 0) Discharge_dict_new[River_part[ 0]][:, 0:row_discharge] = Discharge_dict_new[River_part[ 0]][:, 0: row_discharge] - Real_Surface_Withdrawal[:, None] # Subtract the withdrawal from the part downstream of the riverpart within the same dictionary Discharge_dict_new[River_part[0]][np.logical_and( Discharge_dict_new[River_part[0]] <= 0, Discharge_dict[River_part[0]] >= 0)] = 0 End_river = River_dict[River_part[0]][0] times = 0 # Subtract the withdrawal from all the other downstream dictionaries while len(River_dict) > times: for River_part_downstream in iter(River_dict.items()): if River_part_downstream[1][-1] == End_river: Discharge_dict_new[River_part_downstream[ 0]][:, :] = Discharge_dict_new[ River_part_downstream[ 0]][:, :] - Real_Surface_Withdrawal[:, None] #Discharge_dict_new[River_part_downstream[0]][:,1:] = Discharge_dict_new[River_part_downstream[0]][:,1:] - total_surface_withdrawal[:,None] Discharge_dict_new[River_part_downstream[0]][ np.logical_and( Discharge_dict_new[ River_part_downstream[0]] <= 0, Discharge_dict[ River_part_downstream[0]] >= 0)] = 0 End_river = River_dict[ River_part_downstream[0]][0] times = 0 times += 1 return (Discharge_dict_new)
def main(input_nc, output_nc, input_JRC, Inflow_Text_Files, include_reservoirs=1): import time import watools.General.raster_conversions as RC import watools.General.data_conversions as DC import numpy as np import netCDF4 ####################### add inflow text files ################################# if len(Inflow_Text_Files) > 0: import watools.Models.SurfWAT.Part0_Add_Inlets as Part0_Add_Inlets # Calculate the runoff that will be routed by including the inlets Runoff = Part0_Add_Inlets(input_nc, Inflow_Text_Files) else: # Extract runoff data from NetCDF file Runoff = RC.Open_nc_array(input_nc, Var='Runoff_M') ############################################################################### # Extract flow direction data from NetCDF file flow_directions = RC.Open_nc_array(input_nc, Var='demdir') # Extract basin data from NetCDF file Basin = RC.Open_nc_array(input_nc, Var='basin') Areas_in_m2 = RC.Open_nc_array(input_nc, Var='area') Runoff_in_m3_month = ((Runoff / 1000) * Areas_in_m2) ############################################################################### ############################### Run Part 1 #################################### ############################################################################### import watools.Models.SurfWAT.Part1_Channel_Routing as Part1_Channel_Routing Routed_Array, Accumulated_Pixels, Rivers = Part1_Channel_Routing.Run( Runoff_in_m3_month, flow_directions, Basin) ############################################################################### ################## Create NetCDF Part 1 results ############################### ############################################################################### ################### Get Example parameters for NetCDF ######################### # Create NetCDF 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) time_or = RC.Open_nc_array(input_nc, Var='time') # Latitude and longitude lon_ls = np.arange(size_X_example) * geo_out_example[1] + geo_out_example[ 0] + 0.5 * geo_out_example[1] lat_ls = np.arange(size_Y_example) * geo_out_example[5] + geo_out_example[ 3] - 0.5 * geo_out_example[5] lat_n = len(lat_ls) lon_n = len(lon_ls) ################################ Save NetCDF ################################## # Create NetCDF file nc_file = netCDF4.Dataset(output_nc, 'w') nc_file.set_fill_on() # Create dimensions lat_dim = nc_file.createDimension('latitude', lat_n) lon_dim = nc_file.createDimension('longitude', lon_n) # Create NetCDF variables crso = nc_file.createVariable('crs', 'i4') crso.long_name = 'Lon/Lat Coords in WGS84' crso.standard_name = 'crs' crso.grid_mapping_name = 'latitude_longitude' crso.projection = epsg_example crso.longitude_of_prime_meridian = 0.0 crso.semi_major_axis = 6378137.0 crso.inverse_flattening = 298.257223563 crso.geo_reference = geo_out_example ######################### Save Rasters in NetCDF ############################## lat_var = nc_file.createVariable('latitude', 'f8', ('latitude', )) lat_var.units = 'degrees_north' lat_var.standard_name = 'latitude' lat_var.pixel_size = geo_out_example[5] lon_var = nc_file.createVariable('longitude', 'f8', ('longitude', )) lon_var.units = 'degrees_east' lon_var.standard_name = 'longitude' lon_var.pixel_size = geo_out_example[1] nc_file.createDimension('time', None) timeo = nc_file.createVariable('time', 'f4', ('time', )) timeo.units = 'Monthly' timeo.standard_name = 'time' # Variables rivers_var = nc_file.createVariable('rivers', 'i', ('latitude', 'longitude'), fill_value=-9999) rivers_var.long_name = 'Rivers' rivers_var.grid_mapping = 'crs' accpix_var = nc_file.createVariable('accpix', 'f8', ('latitude', 'longitude'), fill_value=-9999) accpix_var.long_name = 'Accumulated Pixels' accpix_var.units = 'AmountPixels' accpix_var.grid_mapping = 'crs' discharge_nat_var = nc_file.createVariable( 'discharge_natural', 'f8', ('time', 'latitude', 'longitude'), fill_value=-9999) discharge_nat_var.long_name = 'Natural Discharge' discharge_nat_var.units = 'm3/month' discharge_nat_var.grid_mapping = 'crs' # Load data lat_var[:] = lat_ls lon_var[:] = lon_ls timeo[:] = time_or # Static variables rivers_var[:, :] = Rivers[:, :] accpix_var[:, :] = Accumulated_Pixels[:, :] for i in range(len(time_or)): discharge_nat_var[i, :, :] = Routed_Array[i, :, :] time.sleep(1) nc_file.close() del Routed_Array, Accumulated_Pixels ############################################################################### ############################### Run Part 2 #################################### ############################################################################### import watools.Models.SurfWAT.Part2_Create_Dictionaries as Part2_Create_Dictionaries DEM_dict, River_dict, Distance_dict, Discharge_dict = Part2_Create_Dictionaries.Run( input_nc, output_nc) ############################################################################### ################## Create NetCDF Part 2 results ############################### ############################################################################### # Create NetCDF file nc_file = netCDF4.Dataset(output_nc, 'r+') nc_file.set_fill_on() ###################### Save Dictionaries in NetCDF ############################ parmsdem = nc_file.createGroup('demdict_static') for k, v in list(DEM_dict.items()): setattr(parmsdem, str(k), str(v.tolist())) parmsriver = nc_file.createGroup('riverdict_static') for k, v in list(River_dict.items()): setattr(parmsriver, str(k), str(v.tolist())) parmsdist = nc_file.createGroup('distancedict_static') for k, v in list(Distance_dict.items()): setattr(parmsdist, str(k), str(v.tolist())) parmsdis = nc_file.createGroup('dischargedict_dynamic') for k, v in list(Discharge_dict.items()): setattr(parmsdis, str(k), str(v.tolist())) # Close file time.sleep(1) nc_file.close() ############################################################################### ############################### Run Part 3 #################################### ############################################################################### if include_reservoirs == 1: import watools.Models.SurfWAT.Part3_Reservoirs as Part3_Reservoirs Discharge_dict_2, River_dict_2, DEM_dict_2, Distance_dict_2 = Part3_Reservoirs.Run( input_nc, output_nc, input_JRC) else: import copy Discharge_dict_2 = copy.deepcopy(Discharge_dict) River_dict_2 = copy.deepcopy(River_dict) DEM_dict_2 = copy.deepcopy(DEM_dict) Distance_dict_2 = copy.deepcopy(Distance_dict) ############################################################################### ################## Create NetCDF Part 3 results ############################### ############################################################################### # Create NetCDF file nc_file = netCDF4.Dataset(output_nc, 'r+') nc_file.set_fill_on() ###################### Save Dictionaries in NetCDF ############################ parmsdisres = nc_file.createGroup('dischargedictreservoirs_dynamic') for k, v in list(Discharge_dict_2.items()): setattr(parmsdisres, str(k), str(v.tolist())) parmsrivresend = nc_file.createGroup('riverdictres_static') for k, v in list(River_dict_2.items()): setattr(parmsrivresend, str(k), str(v.tolist())) parmsdemres = nc_file.createGroup('demdictres_static') for k, v in list(DEM_dict_2.items()): setattr(parmsdemres, str(k), str(v.tolist())) parmsdistres = nc_file.createGroup('distancedictres_static') for k, v in list(Distance_dict_2.items()): setattr(parmsdistres, str(k), str(v.tolist())) # Close file time.sleep(1) nc_file.close() del DEM_dict, River_dict, Distance_dict, Discharge_dict ############################################################################### ############################### Run Part 4 #################################### ############################################################################### import watools.Models.SurfWAT.Part4_Withdrawals as Part4_Withdrawals Discharge_dict_end, Error_map = Part4_Withdrawals.Run(input_nc, output_nc) ############################################################################### ################## Create NetCDF Part 4 results ############################### ############################################################################### # Create NetCDF file nc_file = netCDF4.Dataset(output_nc, 'r+') nc_file.set_fill_on() ######################### Save Rasters in NetCDF ############################## error_map_var = nc_file.createVariable('error_map_mm', 'f8', ('time', 'latitude', 'longitude'), fill_value=-9999) error_map_var.long_name = 'Error Map' error_map_var.units = 'mm/month' error_map_var.grid_mapping = 'crs' for i in range(len(time_or)): error_map_var[i, :, :] = Error_map[i, :, :] ###################### Save Dictionaries in NetCDF ############################ parmsdisend = nc_file.createGroup('dischargedictend_dynamic') for k, v in list(Discharge_dict_end.items()): setattr(parmsdisend, str(k), str(v.tolist())) # Close file time.sleep(1) nc_file.close() del Discharge_dict_end ############################################################################### ############### Part 5 Convert dictionaries to rasters ######################## ############################################################################### River_dict = RC.Open_nc_dict(output_nc, 'riverdict_static') # End discharge dictionary to raster Discharge_dict_end = RC.Open_nc_dict(output_nc, 'dischargedictend_dynamic') DataCube_Discharge_end = DC.Convert_dict_to_array(River_dict, Discharge_dict_end, input_nc) ###################### Save Dictionaries in NetCDF ############################ # Create NetCDF file nc_file = netCDF4.Dataset(output_nc, 'r+') nc_file.set_fill_on() discharge_end_var = nc_file.createVariable( 'discharge_end', 'f8', ('time', 'latitude', 'longitude'), fill_value=-9999) discharge_end_var.long_name = 'End Discharge' discharge_end_var.units = 'm3/month' discharge_end_var.grid_mapping = 'crs' for i in range(len(time_or)): discharge_end_var[i, :, :] = DataCube_Discharge_end[i, :, :] # Close file nc_file.close() del DataCube_Discharge_end
def Add_Reservoirs(output_nc, Diff_Water_Volume, Regions): import numpy as np import watools.General.raster_conversions as RC import watools.General.data_conversions as DC # Extract data from NetCDF file Discharge_dict = RC.Open_nc_dict(output_nc, "dischargedict_dynamic") River_dict = RC.Open_nc_dict(output_nc, "riverdict_static") DEM_dict = RC.Open_nc_dict(output_nc, "demdict_static") Distance_dict = RC.Open_nc_dict(output_nc, "distancedict_static") Rivers = RC.Open_nc_array(output_nc, "rivers") acc_pixels = RC.Open_nc_array(output_nc, "accpix") # Open data array info based on example data geo_out, epsg, size_X, size_Y, size_Z, time = RC.Open_nc_info(output_nc) # 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)) + 1 del x, y Acc_Pixels_Rivers = Rivers * acc_pixels ID_Rivers = Rivers * ID_Matrix Amount_of_Reservoirs = len(Regions) Reservoir_is_in_River = np.ones([len(Regions), 3]) * -9999 for reservoir in range(0, Amount_of_Reservoirs): region = Regions[reservoir, :] dest = DC.Save_as_MEM(Acc_Pixels_Rivers, geo_out, projection='WGS84') Rivers_Acc_Pixels_reservoir, Geo_out = RC.clip_data( dest, latlim=[region[2], region[3]], lonlim=[region[0], region[1]]) dest = DC.Save_as_MEM(ID_Rivers, geo_out, projection='WGS84') Rivers_ID_reservoir, Geo_out = RC.clip_data( dest, latlim=[region[2], region[3]], lonlim=[region[0], region[1]]) size_Y_reservoir, size_X_reservoir = np.shape( Rivers_Acc_Pixels_reservoir) IDs_Edges = [] IDs_Edges = np.append(IDs_Edges, Rivers_Acc_Pixels_reservoir[0, :]) IDs_Edges = np.append(IDs_Edges, Rivers_Acc_Pixels_reservoir[:, 0]) IDs_Edges = np.append( IDs_Edges, Rivers_Acc_Pixels_reservoir[int(size_Y_reservoir) - 1, :]) IDs_Edges = np.append( IDs_Edges, Rivers_Acc_Pixels_reservoir[:, int(size_X_reservoir) - 1]) Value_Reservoir = np.max(np.unique(IDs_Edges)) y_pix_res, x_pix_res = np.argwhere( Rivers_Acc_Pixels_reservoir == Value_Reservoir)[0] ID_reservoir = Rivers_ID_reservoir[y_pix_res, x_pix_res] # Find exact reservoir area in river directory for River_part in River_dict.items(): if len(np.argwhere(River_part[1] == ID_reservoir)) > 0: Reservoir_is_in_River[reservoir, 0] = np.argwhere( River_part[1] == ID_reservoir) #River_part_good Reservoir_is_in_River[reservoir, 1] = River_part[0] #River_Add_Reservoir Reservoir_is_in_River[reservoir, 2] = 1 #Reservoir_is_in_River numbers = abs(Reservoir_is_in_River[:, 1].argsort() - len(Reservoir_is_in_River) + 1) for number in range(0, len(Reservoir_is_in_River)): row_reservoir = np.argwhere(numbers == number)[0][0] if not Reservoir_is_in_River[row_reservoir, 2] == -9999: # Get discharge into the reservoir: Flow_in_res_m3 = Discharge_dict[int(Reservoir_is_in_River[ row_reservoir, 1])][:, int(Reservoir_is_in_River[row_reservoir, 0])] # Get difference reservoir Change_Reservoir_m3 = Diff_Water_Volume[row_reservoir, :, 2] # Total Change outflow Change_outflow_m3 = np.minimum(Flow_in_res_m3, Change_Reservoir_m3) Difference = Change_outflow_m3 - Change_Reservoir_m3 if abs(np.sum(Difference)) > 10000 and np.sum( Change_Reservoir_m3[Change_outflow_m3 > 0]) > 0: Change_outflow_m3[Change_outflow_m3 < 0] = Change_outflow_m3[ Change_outflow_m3 < 0] * np.sum( Change_outflow_m3[Change_outflow_m3 > 0]) / np.sum( Change_Reservoir_m3[Change_outflow_m3 > 0]) # Find key name (which is also the lenght of the river dictionary) i = len(River_dict) #River_with_reservoirs_dict[i]=list((River_dict[River_Add_Reservoir][River_part_good[0][0]:]).flat) < MAAK DIRECTORIES ARRAYS OP DEZE MANIER DAN IS DE ARRAY 1D River_dict[i] = River_dict[int(Reservoir_is_in_River[ row_reservoir, 1])][int(Reservoir_is_in_River[row_reservoir, 0]):] River_dict[int( Reservoir_is_in_River[row_reservoir, 1])] = River_dict[int( Reservoir_is_in_River[ row_reservoir, 1])][:int(Reservoir_is_in_River[row_reservoir, 0]) + 1] DEM_dict[i] = DEM_dict[int(Reservoir_is_in_River[ row_reservoir, 1])][int(Reservoir_is_in_River[row_reservoir, 0]):] DEM_dict[int( Reservoir_is_in_River[row_reservoir, 1])] = DEM_dict[int( Reservoir_is_in_River[ row_reservoir, 1])][:int(Reservoir_is_in_River[row_reservoir, 0]) + 1] Distance_dict[i] = Distance_dict[int(Reservoir_is_in_River[ row_reservoir, 1])][int(Reservoir_is_in_River[row_reservoir, 0]):] Distance_dict[int( Reservoir_is_in_River[row_reservoir, 1])] = Distance_dict[int( Reservoir_is_in_River[ row_reservoir, 1])][:int(Reservoir_is_in_River[row_reservoir, 0]) + 1] Discharge_dict[i] = Discharge_dict[int(Reservoir_is_in_River[ row_reservoir, 1])][:, int(Reservoir_is_in_River[row_reservoir, 0]):] Discharge_dict[int( Reservoir_is_in_River[row_reservoir, 1])] = Discharge_dict[int( Reservoir_is_in_River[ row_reservoir, 1])][:, :int(Reservoir_is_in_River[row_reservoir, 0]) + 1] Discharge_dict[int(Reservoir_is_in_River[ row_reservoir, 1])][:, 1:int(Reservoir_is_in_River[row_reservoir, 0]) + 1] = Discharge_dict[int( Reservoir_is_in_River[row_reservoir, 1] )][:, 1:int(Reservoir_is_in_River[row_reservoir, 0]) + 1] - Change_outflow_m3[:, None] Next_ID = River_dict[int(Reservoir_is_in_River[row_reservoir, 1])][0] times = 0 while len(River_dict) > times: for River_part in River_dict.items(): if River_part[-1][-1] == Next_ID: Next_ID = River_part[-1][0] item = River_part[0] #Always 10 procent of the incoming discharge will pass the dam Change_outflow_m3[:, None] = np.minimum( 0.9 * Discharge_dict[item][:, -1:], Change_outflow_m3[:, None]) Discharge_dict[item][:, 1:] = Discharge_dict[ item][:, 1:] - Change_outflow_m3[:, None] print(item) times = 0 times += 1 return (Discharge_dict, River_dict, DEM_dict, Distance_dict)