Ejemplo n.º 1
0
def run(input_nc, 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 watools.General.raster_conversions as RC
    import watools.Functions.Start.Area_converter as Area

    Runoff = RC.Open_nc_array(input_nc, Var='Runoff_M')

    # Open information and open the Runoff array
    geo_out, epsg, size_X, size_Y, size_Z, Time = RC.Open_nc_info(input_nc)

    # 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]
        Lat_coord = Coord[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[time_step_array, lat_pix,
                       lon_pix] = Runoff[time_step_array, lat_pix,
                                         lon_pix] + value_mm
    return (Runoff)
Ejemplo n.º 2
0
def Degrees_to_m2(Reference_data):
    """
    This functions calculated the area of each pixel in squared meter.

    Parameters
    ----------
    Reference_data: str
        Path to a tiff file or nc file or memory file of which the pixel area must be defined

    Returns
    -------
    area_in_m2: array
        Array containing the area of each pixel in squared meters

    """
    try:
        # Get the extension of the example data
        filename, file_extension = os.path.splitext(Reference_data)

        # Get raster information
        if str(file_extension) == '.tif':
            geo_out, proj, size_X, size_Y = RC.Open_array_info(Reference_data)
        elif str(file_extension) == '.nc':
            geo_out, epsg, size_X, size_Y, size_Z, Time = RC.Open_nc_info(
                Reference_data)

    except:
        geo_out = Reference_data.GetGeoTransform()
        size_X = Reference_data.RasterXSize()
        size_Y = Reference_data.RasterYSize()

    # Calculate the difference in latitude and longitude in meters
    dlat, dlon = Calc_dlat_dlon(geo_out, size_X, size_Y)

    # Calculate the area in squared meters
    area_in_m2 = dlat * dlon

    return (area_in_m2)
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
def Find_Area_Volume_Relation(region, input_JRC, input_nc):

    # Find relation between V and A

    import numpy as np
    import watools.General.raster_conversions as RC
    import watools.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
    DEM_Array = RC.Open_nc_array(input_nc, "dem")
    Geo_out_dem, proj_dem, size_X_dem, size_Y_dem, size_Z_dem, time = RC.Open_nc_info(
        input_nc)

    # Save Example as memory file
    dest_example = DC.Save_as_MEM(Water_array, Geo_out, projection='WGS84')
    dest_dem = DC.Save_as_MEM(DEM_Array, Geo_out_dem, projection='WGS84')

    # reproject DEM by using example
    dest_out = RC.reproject_dataset_example(dest_dem, 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 watools.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)