Example #1
0
def main(inputs):

    # Set Variables
    Start_year_analyses = inputs["Start_year"]
    End_year_analyses = inputs["End_year"]
    output_folder = inputs["Output_folder"]  
    WAPOR_LVL = inputs["WAPOR_LEVEL"]  
    Phenology_Threshold = inputs["Phenology_Threshold"]  
    Phenology_Slope = inputs["Phenology_Slope"]  
    METEO_timestep = inputs["METEO_timestep"]             
    try:
        Radiation_Data = inputs["Radiation_Source"]   
    except:
        Radiation_Data = "KNMI"   
    try:
        Albedo_Data = inputs["Albedo_Source"]   
    except:
        Albedo_Data = "MODIS"    
        
    import WaporTranslator.LEVEL_1.Input_Data as Inputs
    import WaporTranslator.LEVEL_1.DataCube as DataCube
    import WaporTranslator.LEVEL_2 as L2
    import WaporTranslator.LEVEL_2.Functions as Functions
    
    # Do not show non relevant warnings
    warnings.filterwarnings("ignore")
    warnings.filterwarnings("ignore", category=FutureWarning)
    warnings.filterwarnings("ignore", category=RuntimeWarning)
    
    # Create output folder for LEVEL 2 data
    output_folder_L2 = os.path.join(output_folder, "LEVEL_2")
    if not os.path.exists(output_folder_L2):
        os.makedirs(output_folder_L2)
    
    # Define dates
    Dates = Functions.Get_Dekads(Start_year_analyses, End_year_analyses)
    Dates_yearly = list(pd.date_range("%s-01-01" %str(Start_year_analyses), "%s-12-31" %End_year_analyses, freq = "AS")) 

    # Get path and formats
    Paths = Inputs.Input_Paths()
    Formats = Inputs.Input_Formats()
    Conversions = Inputs.Input_Conversions()
    
    # Set example file
    example_file = os.path.join(output_folder, "LEVEL_1", "MASK", "MASK.tif")
    
    # Open Mask
    dest_mask = gdal.Open(example_file)
    MASK = dest_mask.GetRasterBand(1).ReadAsArray()
    
    # Load inputs for LEVEL 2
    T = DataCube.Rasterdata_tiffs(os.path.join(output_folder, str(Paths.T) %WAPOR_LVL), str(Formats.T) %WAPOR_LVL, Dates, Conversion = Conversions.T, Example_Data = example_file, Mask_Data = example_file, gap_filling = 1, reprojection_type = 2, Variable = 'T', Product = 'WAPOR', Unit = 'mm/day')
    ET0 = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.ET0), Formats.ET0, Dates, Conversion = Conversions.ET0, Example_Data = example_file, Mask_Data = example_file, gap_filling = 1, reprojection_type = 2, Variable = 'ET0', Product = 'WAPOR', Unit = 'mm/day')
    LU = DataCube.Rasterdata_tiffs(os.path.join(output_folder, str(Paths.LU) %WAPOR_LVL), str(Formats.LU) %WAPOR_LVL, Dates_yearly, Conversion = Conversions.LU, Example_Data = example_file, Mask_Data = example_file, Variable = 'LU', Product = 'WAPOR', Unit = 'LU')
    LUdek = DataCube.Rasterdata_tiffs(os.path.join(output_folder,str(Paths.LU) %WAPOR_LVL), str(Formats.LU) %WAPOR_LVL, Dates, Conversion = Conversions.LU, Example_Data = example_file, Mask_Data = example_file, Variable = 'LU', Product = 'WAPOR', Unit = 'LU')

    ################################## Calculate LU map ##########################################
    
    Phenology_pixels_year, Grassland_pixels_year = Create_LU_MAP(output_folder, Dates_yearly, LU, LUdek, Paths.LU_ESA, Formats.LU_ESA, example_file)
    LU_END = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.LU_END), Formats.LU_END, list(Dates_yearly), Conversion = Conversions.LU_END, Variable = 'LU_END', Product = '', Unit = '-')

    del LU
       
    ################################## Get ALBEDO data ############################################

    if Radiation_Data == "LANDSAF":
        Start_Rad = 2016
    if Radiation_Data == "KNMI":    
        Start_Rad = 2017
    if METEO_timestep == "Monthly":    
        Start_Rad = Start_year_analyses
        
    Dates_Net_Radiation = Functions.Get_Dekads(str(np.maximum(int(Start_year_analyses), Start_Rad)), End_year_analyses)   

    if Albedo_Data == "MODIS":
        Albedo = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.Albedo), Formats.Albedo, Dates_Net_Radiation, Conversion = Conversions.Albedo, Example_Data = example_file, Mask_Data = example_file, gap_filling = 1, reprojection_type = 2, Variable = 'Albedo', Product = 'MODIS', Unit = '-')
    else:
    
        Albedo_Array = np.ones([len(Dates_Net_Radiation), T.Size[1], T.Size[2]])* 0.17
        
        for Dates_albedo in Dates_Net_Radiation:
            Year_now = Dates_albedo.year
            LU_Now = LU_END.Data[Year_now-Start_year_analyses,:,:]
            Albedo_Array_now = np.ones([T.Size[1], T.Size[2]])* 0.17
            Albedo_Array_now = np.where(LU_Now==1, 0.20, Albedo_Array_now)
            Albedo_Array_now= np.where(LU_Now==3, 0.23, Albedo_Array_now)             
            Albedo_Array[Year_now-Start_year_analyses,:,:] = Albedo_Array_now
  
        Albedo = DataCube.Rasterdata_Empty()
        Albedo.Data = Albedo_Array * MASK
        Albedo.Projection = T.Projection
        Albedo.GeoTransform = T.GeoTransform
        Albedo.Ordinal_time = np.array(list(map(lambda i : i.toordinal(), Dates_Net_Radiation)))
        Albedo.Size = Albedo_Array.shape
        Albedo.Variable = "Albedo"
        Albedo.Unit = "-"

    if METEO_timestep == "Monthly":
        Dates_monthly = list(pd.date_range("%s-01-01" %str(Start_year_analyses), "%s-12-31" %End_year_analyses, freq = "MS"))    
     
        Temp_monthly = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.Temp_monthly), Formats.Temp_monthly, Dates_monthly, Conversion = Conversions.Temp_monthly, Example_Data = example_file, Mask_Data = example_file, reprojection_type = 2, Variable = 'Temperature', Product = 'GLDAS', Unit = 'Celcius')
        Hum_monthly = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.Hum_monthly), Formats.Hum_monthly, Dates_monthly, Conversion = Conversions.Hum_monthly, Example_Data = example_file, Mask_Data = example_file, reprojection_type = 2, Variable = 'Humidity', Product = 'GLDAS', Unit = 'Percentage')
        DSSF_monthly = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.DSSF_monthly), Formats.DSSF_monthly, Dates_monthly, Conversion = Conversions.DSSF_monthly,  Example_Data = example_file, Mask_Data = example_file, reprojection_type = 2, Variable = 'DSSF', Product = 'GLDAS', Unit = 'W/m2')
        
    if METEO_timestep == "Daily":
        Dates_Daily = list(pd.date_range("%s-01-01" %str(Start_year_analyses), "%s-12-31" %End_year_analyses))
        
        Dates_Net_Radiation_Daily = list(pd.date_range("%s-01-01" %str(np.maximum(int(Start_year_analyses), Start_Rad)), "%s-12-31" %End_year_analyses))

        # Open daily
        if Radiation_Data == "LANDSAF":
            DSLF_daily = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.DSLF), Formats.DSLF, Dates_Net_Radiation_Daily, Conversion = Conversions.DSLF, Example_Data = example_file, Mask_Data = example_file, reprojection_type = 2, Variable = 'DSLF', Product = 'LANDSAF', Unit = 'W/m2')
            DSSF_daily = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.DSSF), Formats.DSSF, Dates_Net_Radiation_Daily, Conversion = Conversions.DSSF, Example_Data = example_file, Mask_Data = example_file, reprojection_type = 2, Variable = 'DSSF', Product = 'LANDSAF', Unit = 'W/m2')
        if Radiation_Data == "KNMI":
            DSSF_daily = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.KNMI), Formats.KNMI, Dates_Net_Radiation_Daily, Conversion = Conversions.KNMI, Example_Data = example_file, Mask_Data = example_file, reprojection_type = 2, Variable = 'SDS', Product = 'KNMI', Unit = 'W/m2')
            
        Temp_daily = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.Temp), Formats.Temp, Dates_Daily, Conversion = Conversions.Temp, Example_Data = example_file, Mask_Data = example_file, reprojection_type = 2, Variable = 'Temperature', Product = 'GLDAS', Unit = 'Celcius')
        Hum_daily = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.Hum), Formats.Hum, Dates_Daily, Conversion = Conversions.Hum, Example_Data = example_file, Mask_Data = example_file, reprojection_type = 2, Variable = 'Humidity', Product = 'GLDAS', Unit = 'Percentage')
     
        #################### Convert into daily datasets ############################################
        Albedo_Daily = Functions.Calc_Daily_from_Dekads(Albedo)

    ################################### Calculate LAI ############################################
    LAI_Data = np.log((1-np.minimum(T.Data/ET0.Data, 0.99)))/(-0.55)
    LAI_Data[LUdek.Data==80] = 0.0
    LAI_Data = LAI_Data.clip(0.0, 7.0)
    
    # Write in DataCube
    LAI = DataCube.Rasterdata_Empty()
    LAI.Data = LAI_Data * MASK
    LAI.Projection = T.Projection
    LAI.GeoTransform = T.GeoTransform
    LAI.Ordinal_time = T.Ordinal_time
    LAI.Size = LAI_Data.shape
    LAI.Variable = "Leaf Area Index"
    LAI.Unit = "m2-m-2"
    
    del LAI_Data, LUdek
    
    LAI.Save_As_Tiff(os.path.join(output_folder_L2, "LAI"))
    
    if METEO_timestep == "Monthly":       
    
        DEM =  DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.DEM), Formats.DEM, Dates = None, Conversion = Conversions.DEM, Example_Data = example_file, Mask_Data = example_file, reprojection_type = 2, Variable = 'DEM', Product = 'SRTM', Unit = 'm')
  
        DSSF = Functions.Calc_Dekads_from_Monthly(DSSF_monthly)
        Temp = Functions.Calc_Dekads_from_Monthly(Temp_monthly)
        Hum = Functions.Calc_Dekads_from_Monthly(Hum_monthly)
        
        ###################### Calculate Net Radiation (daily) #####################################
        DOY = np.array(list(map(lambda i : int(datetime.datetime.fromordinal(i).strftime('%j')), LAI.Ordinal_time[np.isin(LAI.Ordinal_time, DSSF.Ordinal_time)])))
        Latitude = Albedo.GeoTransform[3] + Albedo.GeoTransform[5] * np.float_(list(range(0,Albedo.Size[1]))) - 0.5 * Albedo.GeoTransform[5]
        Inverse_Relative_Distance_Earth_Sun = 1 + 0.033* np.cos(2 * np.pi * DOY/365)
        Solar_Declanation = 0.409 * np.sin(2 * np.pi * DOY/365 - 1.39) 
        Sunset_Hour_Angle = np.squeeze(np.arccos(-np.tan(Latitude[None, :, None]/180 * np.pi)*np.tan(Solar_Declanation[:, None, None])))
        Extra_Terrestrial_Radiation = np.squeeze(435.2 * Inverse_Relative_Distance_Earth_Sun[:, None, None] * (Sunset_Hour_Angle[:, :, None] * np.sin((Latitude[None, :, None]/180) * np.pi) * np.sin(Solar_Declanation[:, None, None]) + np.cos((Latitude[None, :, None]/180) * np.pi) * np.cos(Solar_Declanation[:, None, None]) * np.sin(Sunset_Hour_Angle[:, :, None])))
        Saturated_Vapor_Pressure = 0.611 * np.exp((17.27 * Temp.Data)/(237.3 + Temp.Data))
        Actual_Vapor_Pressure = Hum.Data * 0.01 * Saturated_Vapor_Pressure     
        Slope_Saturated_Vapor_Pressure = 4098 * Saturated_Vapor_Pressure/(Temp.Data+237.3)**2
        Psy_Constant = 0.665 * 0.001 * 101.3 * ((293 - 0.0065 * DEM.Data)/293)**(5.26)
        Net_Longwave_FAO = (0.34 - 0.14 * (Actual_Vapor_Pressure[np.isin(Temp.Ordinal_time, DSSF.Ordinal_time), :, :])**(0.5)) * (1.35 * DSSF.Data/(0.8 * Extra_Terrestrial_Radiation[:, :, None]) - 0.35) * 0.0000000567 * (273.15+Temp.Data[np.isin(Temp.Ordinal_time, DSSF.Ordinal_time), :, :])**4
        Net_Longwave_Slob = 110 * (DSSF.Data/Extra_Terrestrial_Radiation[:, :, None])
        Net_Longwave = np.where(Net_Longwave_FAO>Net_Longwave_Slob, Net_Longwave_FAO, Net_Longwave_Slob) 
        Net_Radiation_Data =(1 - Albedo.Data[np.isin(Albedo.Ordinal_time, DSSF.Ordinal_time), :, :])*DSSF.Data - Net_Longwave
  
        Days_in_Dekads = np.append(Albedo.Ordinal_time[1:] - Albedo.Ordinal_time[:-1], 11)
       
        ###################### Calculate ET0 de Bruin Daily #####################################
        ET0_deBruin_Data = ((Slope_Saturated_Vapor_Pressure[np.isin(Temp.Ordinal_time, DSSF.Ordinal_time), :, :]/(Slope_Saturated_Vapor_Pressure[np.isin(Temp.Ordinal_time, DSSF.Ordinal_time), :, :] + Psy_Constant[None, :, :])) * ((1 - 0.23) * DSSF.Data - Net_Longwave_Slob) + 20)/28.4 * Days_in_Dekads[:, None, None]

        # Write in DataCube
        ET0_deBruin = DataCube.Rasterdata_Empty()
        ET0_deBruin.Data = ET0_deBruin_Data * MASK
        ET0_deBruin.Projection = Albedo.Projection
        ET0_deBruin.GeoTransform = Albedo.GeoTransform
        ET0_deBruin.Ordinal_time = Albedo.Ordinal_time
        ET0_deBruin.Size = ET0_deBruin_Data.shape
        ET0_deBruin.Variable = "ET0 de Bruin"
        ET0_deBruin.Unit = "mm-dekad-1"
        
        ET0_deBruin.Save_As_Tiff(os.path.join(output_folder_L2, "ET0_deBruin"))  
        
         # Write in DataCube
        Net_Radiation = DataCube.Rasterdata_Empty()
        Net_Radiation.Data = Net_Radiation_Data * MASK
        Net_Radiation.Projection = Albedo.Projection
        Net_Radiation.GeoTransform = Albedo.GeoTransform
        Net_Radiation.Ordinal_time = Albedo.Ordinal_time
        Net_Radiation.Size = Net_Radiation_Data.shape
        Net_Radiation.Variable = "Net Radiation"
        Net_Radiation.Unit = "W-m-2"      
            
    if METEO_timestep == "Daily":    
    
        #################### Calculate Net Radiation LANDSAF method ###################################    
        if Radiation_Data == "LANDSAF":
            
            ################# Calculate Land Surface Emissivity ###########################################
            Land_Surface_Emissivity_Data = np.minimum(1, 0.9 + 0.017 * LAI.Data[np.isin(LAI.Ordinal_time, Albedo.Ordinal_time), :, :])
            Land_Surface_Emissivity_Data = Land_Surface_Emissivity_Data.clip(0, 1.0)
            
            # Write in DataCube
            Land_Surface_Emissivity = DataCube.Rasterdata_Empty()
            Land_Surface_Emissivity.Data = Land_Surface_Emissivity_Data * MASK
            Land_Surface_Emissivity.Projection = Albedo.Projection
            Land_Surface_Emissivity.GeoTransform = Albedo.GeoTransform
            Land_Surface_Emissivity.Ordinal_time = Albedo.Ordinal_time
            Land_Surface_Emissivity.Size = Land_Surface_Emissivity_Data.shape
            Land_Surface_Emissivity.Variable = "Land Surface Emissivity"
            Land_Surface_Emissivity.Unit = "-"
            
            del Land_Surface_Emissivity_Data
            
            Land_Surface_Emissivity.Save_As_Tiff(os.path.join(output_folder_L2, "Land_Surface_Emissivity"))
            
            #################### Convert into daily datasets ############################################
            Land_Surface_Emissivity_Daily = Functions.Calc_Daily_from_Dekads(Land_Surface_Emissivity)   
    
            ###################### Calculate Net Radiation (daily) #####################################
            Net_Radiation_Data_Daily = (1 - Albedo_Daily.Data) * DSSF_daily.Data + DSLF_daily.Data * 1.15 - Land_Surface_Emissivity_Daily.Data * 0.0000000567 * (273.15 + Temp_daily.Data[np.isin(Temp_daily.Ordinal_time, DSLF_daily.Ordinal_time)] - 4)**4
            Net_Radiation_Data_Daily  = Net_Radiation_Data_Daily.clip(0, 500)
            Net_Radiation_Data_Daily[Net_Radiation_Data_Daily == 0] = np.nan
            
            del Land_Surface_Emissivity_Daily, DSSF_daily, DSLF_daily
            
        #################### Calculate Net Radiation KNMI method ###################################  
        if Radiation_Data == "KNMI":
            
            DEM =  DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.DEM), Formats.DEM, Dates = None, Conversion = Conversions.DEM, Example_Data = example_file, Mask_Data = example_file, reprojection_type = 2, Variable = 'DEM', Product = 'SRTM', Unit = 'm')
    
            ###################### Calculate Net Radiation (daily) #####################################
            DOY = np.array(list(map(lambda i : int(datetime.datetime.fromordinal(i).strftime('%j')), Albedo_Daily.Ordinal_time[np.isin(Albedo_Daily.Ordinal_time, DSSF_daily.Ordinal_time)])))
            Latitude = Albedo.GeoTransform[3] + Albedo.GeoTransform[5] * np.float_(list(range(0,Albedo.Size[1]))) - 0.5 * Albedo.GeoTransform[5]
            Inverse_Relative_Distance_Earth_Sun = 1 + 0.033* np.cos(2 * np.pi * DOY/365)
            Solar_Declanation = 0.409 * np.sin(2 * np.pi * DOY/365 - 1.39) 
            Sunset_Hour_Angle = np.squeeze(np.arccos(-np.tan(Latitude[None, :, None]/180 * np.pi)*np.tan(Solar_Declanation[:, None, None])))
            Extra_Terrestrial_Radiation = np.squeeze(435.2 * Inverse_Relative_Distance_Earth_Sun[:, None, None] * (Sunset_Hour_Angle[:, :, None] * np.sin((Latitude[None, :, None]/180) * np.pi) * np.sin(Solar_Declanation[:, None, None]) + np.cos((Latitude[None, :, None]/180) * np.pi) * np.cos(Solar_Declanation[:, None, None]) * np.sin(Sunset_Hour_Angle[:, :, None])))
            Saturated_Vapor_Pressure = 0.611 * np.exp((17.27 * Temp_daily.Data)/(237.3 + Temp_daily.Data))
            Actual_Vapor_Pressure = Hum_daily.Data * 0.01 * Saturated_Vapor_Pressure     
            Slope_Saturated_Vapor_Pressure = 4098 * Saturated_Vapor_Pressure/(Temp_daily.Data+237.3)**2
            Psy_Constant = 0.665 * 0.001 * 101.3 * ((293 - 0.0065 * DEM.Data)/293)**(5.26)
            Net_Longwave_FAO = (0.34 - 0.14 * (Actual_Vapor_Pressure[np.isin(Temp_daily.Ordinal_time, DSSF_daily.Ordinal_time), :, :])**(0.5)) * (1.35 * DSSF_daily.Data/(0.8 * Extra_Terrestrial_Radiation[:, :, None]) - 0.35) * 0.0000000567 * (273.15+Temp_daily.Data[np.isin(Temp_daily.Ordinal_time, DSSF_daily.Ordinal_time), :, :])**4
            Net_Longwave_Slob = 110 * (DSSF_daily.Data/Extra_Terrestrial_Radiation[:, :, None])
            Net_Longwave = np.where(Net_Longwave_FAO>Net_Longwave_Slob, Net_Longwave_FAO, Net_Longwave_Slob) 
            Net_Radiation_Data_Daily =(1 - Albedo_Daily.Data[np.isin(Albedo_Daily.Ordinal_time, DSSF_daily.Ordinal_time), :, :])*DSSF_daily.Data - Net_Longwave
    
            del Hum_daily, Latitude, Inverse_Relative_Distance_Earth_Sun, Solar_Declanation, Sunset_Hour_Angle, Saturated_Vapor_Pressure, Actual_Vapor_Pressure, Net_Longwave_FAO, Net_Longwave
     
            ###################### Calculate ET0 de Bruin Daily #####################################
            ET0_deBruin_Daily_Data = ((Slope_Saturated_Vapor_Pressure[np.isin(Temp_daily.Ordinal_time, DSSF_daily.Ordinal_time), :, :]/(Slope_Saturated_Vapor_Pressure[np.isin(Temp_daily.Ordinal_time, DSSF_daily.Ordinal_time), :, :] + Psy_Constant[None, :, :])) * ((1 - 0.23) * DSSF_daily.Data - Net_Longwave_Slob) + 20)/28.4
    
            # Write in DataCube
            ET0_deBruin_Daily = DataCube.Rasterdata_Empty()
            ET0_deBruin_Daily.Data = ET0_deBruin_Daily_Data * MASK
            ET0_deBruin_Daily.Projection = Albedo.Projection
            ET0_deBruin_Daily.GeoTransform = Albedo.GeoTransform
            ET0_deBruin_Daily.Ordinal_time = Albedo_Daily.Ordinal_time
            ET0_deBruin_Daily.Size = ET0_deBruin_Daily_Data.shape
            ET0_deBruin_Daily.Variable = "ET0 de Bruin"
            ET0_deBruin_Daily.Unit = "mm-d-1"
            
            # change from daily to decads
            ET0_deBruin = Functions.Calc_Dekads_from_Daily(ET0_deBruin_Daily, flux_state = "flux")
            ET0_deBruin.Unit = "mm-dekad-1"
            
            del ET0_deBruin_Daily_Data, Net_Longwave_Slob, KNMI_daily, Psy_Constant
            
            ET0_deBruin.Save_As_Tiff(os.path.join(output_folder_L2, "ET0_deBruin"))
    
        # Write in DataCube
        Net_Radiation_Daily = DataCube.Rasterdata_Empty()
        Net_Radiation_Daily.Data = Net_Radiation_Data_Daily * MASK
        Net_Radiation_Daily.Projection = Albedo.Projection
        Net_Radiation_Daily.GeoTransform = Albedo.GeoTransform
        Net_Radiation_Daily.Ordinal_time = Albedo_Daily.Ordinal_time
        Net_Radiation_Daily.Size = Net_Radiation_Data_Daily.shape
        Net_Radiation_Daily.Variable = "Net Radiation"
        Net_Radiation_Daily.Unit = "W-m-2"
        
        del Net_Radiation_Data_Daily, Albedo_Daily, ET0_deBruin_Daily, Albedo
        
        ############### convert Net Radiation to dekadal ############################################
        Net_Radiation = Functions.Calc_Dekads_from_Daily(Net_Radiation_Daily, flux_state = "state")
        Temp = Functions.Calc_Dekads_from_Daily(Temp_daily, flux_state = "state")
        
        del Net_Radiation_Daily, Temp_daily

    # Calc net Radiation of before 2016 if required
    if (int(Start_year_analyses) < Start_Rad and METEO_timestep != "Monthly"):
        
        Total_years = int(np.ceil(Net_Radiation.Size[0]/36))
        Net_Radiation_Per_Dekad = np.ones([36, Net_Radiation.Size[1], Net_Radiation.Size[2]]) * np.nan
        ET0_Per_Dekad = np.ones([36, Net_Radiation.Size[1], Net_Radiation.Size[2]]) * np.nan
        
        IDs_diff = ET0.Size[0] - Net_Radiation.Size[0]
        for dekad in range(0,36):
            IDs_rad = np.array(range(0, Total_years)) * 36 + dekad  
            IDs_rad_good = IDs_rad[IDs_rad<=Net_Radiation.Size[0]]
            IDs_et0 = np.array(range(0, Total_years)) * 36 + dekad + IDs_diff 
            IDs_et0_good = IDs_et0[IDs_et0<=ET0.Size[0]]
            Net_Radiation_Per_Dekad[dekad, :, :] = np.nanmean(Net_Radiation.Data[IDs_rad_good,:,:], axis = 0)
            ET0_Per_Dekad[dekad, :, :] = np.nanmean(ET0.Data[IDs_et0_good,:,:], axis = 0)

        Ratio_per_dekad = Net_Radiation_Per_Dekad/ET0_Per_Dekad
        
        Ratios = Ratio_per_dekad 
        for i in range(0, Start_Rad - int(Start_year_analyses)-1):
            Ratios = np.vstack([Ratios, Ratio_per_dekad])
        
        Net_Radiation_Before_Start_Rad = Ratios * ET0.Data[0:Ratios.shape[0],:,:]
        Net_Radiation_Data = np.vstack([Net_Radiation_Before_Start_Rad, Net_Radiation.Data])
        
        Net_Radiation.Data = Net_Radiation_Data
        Net_Radiation.Size = Net_Radiation_Data.shape
        Net_Radiation.Ordinal_time = T.Ordinal_time    

        del Net_Radiation_Data
        
    Net_Radiation.Unit = "W-m-2"     
    Net_Radiation.Save_As_Tiff(os.path.join(output_folder_L2, "Net_Radiation"))

    ############################ Calculate Root Depth ##########################################    

    # Load inputs for LEVEL 2    
    ET = DataCube.Rasterdata_tiffs(os.path.join(output_folder, str(Paths.ET) %WAPOR_LVL), str(Formats.ET) %WAPOR_LVL, Dates, Conversion = Conversions.ET, Example_Data = example_file, Mask_Data = example_file, gap_filling = 1, reprojection_type = 2, Variable = 'ET', Product = 'WAPOR', Unit = 'mm/day')
    P = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.P), Formats.P, Dates, Conversion = Conversions.P, Example_Data = example_file, Mask_Data = example_file, gap_filling = 1, reprojection_type = 2, Variable = 'P', Product = 'WAPOR', Unit = 'mm/day')
    NPP = DataCube.Rasterdata_tiffs(os.path.join(output_folder, str(Paths.NPP) %WAPOR_LVL), str(Formats.NPP) %WAPOR_LVL, Dates, Conversion = Conversions.NPP, Example_Data = example_file, Mask_Data = example_file, Variable = 'NPP', Product = 'WAPOR', Unit = 'kg/ha/day')
 
    ############################ Calculate Root Depth ##########################################
    Root_Depth_Data = 0.85 * 100 * np.maximum(0, -0.0326 * LAI.Data**2 + 0.4755 * LAI.Data - 0.0411)
    Root_Depth_Data = Root_Depth_Data.clip(0, 500)
    
    # Write in DataCube
    Root_Depth = DataCube.Rasterdata_Empty()
    Root_Depth.Data = Root_Depth_Data * MASK
    Root_Depth.Projection = ET.Projection
    Root_Depth.GeoTransform = ET.GeoTransform
    Root_Depth.Ordinal_time = ET.Ordinal_time
    Root_Depth.Size = Root_Depth_Data.shape
    Root_Depth.Variable = "Root Depth"
    Root_Depth.Unit = "cm"
    
    del Root_Depth_Data
    
    Root_Depth.Save_As_Tiff(os.path.join(output_folder_L2, "Root_Depth"))
    
    ################# Calculate Fractional Vegetation Cover #######################################
    Fract_vegt_Data = 1-np.exp(-0.65 * LAI.Data)
    Fract_vegt_Data = Fract_vegt_Data.clip(0, 1.0)
    
    # Write in DataCube
    Fract_vegt = DataCube.Rasterdata_Empty()
    Fract_vegt.Data = Fract_vegt_Data * MASK
    Fract_vegt.Projection = ET.Projection
    Fract_vegt.GeoTransform = ET.GeoTransform
    Fract_vegt.Ordinal_time = ET.Ordinal_time
    Fract_vegt.Size = Fract_vegt_Data.shape
    Fract_vegt.Variable = "Fractional Vegetation"
    Fract_vegt.Unit = "-"
    
    del Fract_vegt_Data
    
    Fract_vegt.Save_As_Tiff(os.path.join(output_folder_L2, "Fractional_Vegetation_Cover"))
    
    ########################## Calculate maximum Kc ####################################
    Kc_MAX_Data = np.minimum(1.4 ,0.95 * Fract_vegt.Data + 0.2)
    Kc_MAX_Data = Kc_MAX_Data.clip(0, 500)
    
    # Write in DataCube
    Kc_MAX = DataCube.Rasterdata_Empty()
    Kc_MAX.Data = Kc_MAX_Data * MASK
    Kc_MAX.Projection = ET.Projection
    Kc_MAX.GeoTransform = ET.GeoTransform
    Kc_MAX.Ordinal_time = ET.Ordinal_time
    Kc_MAX.Size = Kc_MAX_Data.shape
    Kc_MAX.Variable = "Kc MAX"
    Kc_MAX.Unit = "-"
    
    del Kc_MAX_Data, Fract_vegt
    
    Kc_MAX.Save_As_Tiff(os.path.join(output_folder_L2, "Kc_MAX"))
 
    ################# Calculate Evaporative Fraction ############################################
    Evaporative_Fraction_Data = ET.Data *28.4/Net_Radiation.Data
    Evaporative_Fraction_Data = Evaporative_Fraction_Data.clip(0, 1.5)
    
    # Write in DataCube
    Evaporative_Fraction = DataCube.Rasterdata_Empty()
    Evaporative_Fraction.Data = Evaporative_Fraction_Data * MASK
    Evaporative_Fraction.Projection = ET.Projection
    Evaporative_Fraction.GeoTransform = ET.GeoTransform
    Evaporative_Fraction.Ordinal_time = ET.Ordinal_time
    Evaporative_Fraction.Size = Evaporative_Fraction_Data.shape
    Evaporative_Fraction.Variable = "Evaporative Fraction"
    Evaporative_Fraction.Unit = "-"
    
    del Evaporative_Fraction_Data
    
    Evaporative_Fraction.Save_As_Tiff(os.path.join(output_folder_L2, "Evaporative_Fraction"))

    ############## Calculate Land Theta Saturated Subsoil ##################################
    
    # Open Constant
    Bulk =  DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.Bulk), Formats.Bulk.format(level=6), Dates = None, Conversion = Conversions.Bulk, Example_Data = example_file, Mask_Data = example_file, reprojection_type = 2, Variable = 'Bulk', Product = 'SoilGrids', Unit = 'kg/m3')
    Sand =  DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.Sand), Formats.Sand.format(level=6), Dates = None, Conversion = Conversions.Sand, Example_Data = example_file, Mask_Data = example_file, reprojection_type = 2, Variable = 'Sand', Product = 'SoilGrids', Unit = 'Percentage')
    Clay =  DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.Clay), Formats.Clay.format(level=6), Dates = None, Conversion = Conversions.Clay, Example_Data = example_file, Mask_Data = example_file, reprojection_type = 2, Variable = 'Clay', Product = 'SoilGrids', Unit = 'Percentage')
       
    Theta_Sat_Subsoil_Data = 0.85 * (1 - Bulk.Data/2650) + 0.13 * Clay.Data * 0.01
    
    # Write in DataCube
    Theta_Sat_Subsoil = DataCube.Rasterdata_Empty()
    Theta_Sat_Subsoil.Data = Theta_Sat_Subsoil_Data * MASK
    Theta_Sat_Subsoil.Projection = ET.Projection
    Theta_Sat_Subsoil.GeoTransform = ET.GeoTransform
    Theta_Sat_Subsoil.Ordinal_time = None
    Theta_Sat_Subsoil.Size = Theta_Sat_Subsoil_Data.shape
    Theta_Sat_Subsoil.Variable = "Saturated Theta Subsoil"
    Theta_Sat_Subsoil.Unit = "cm3-cm-3"
    
    del Theta_Sat_Subsoil_Data
    
    Theta_Sat_Subsoil.Save_As_Tiff(os.path.join(output_folder_L2, "Theta_Sat_Subsoil"))
    
    ################### Calculate Theta Field Capacity Subsoil #############################
    Theta_FC_Subsoil_Data = -2.95 * Theta_Sat_Subsoil.Data**2 + 3.96 * Theta_Sat_Subsoil.Data - 0.871
    
    # Write in DataCube
    Theta_FC_Subsoil = DataCube.Rasterdata_Empty()
    Theta_FC_Subsoil.Data = Theta_FC_Subsoil_Data * MASK
    Theta_FC_Subsoil.Projection = ET.Projection
    Theta_FC_Subsoil.GeoTransform = ET.GeoTransform
    Theta_FC_Subsoil.Ordinal_time = None
    Theta_FC_Subsoil.Size = Theta_FC_Subsoil_Data.shape
    Theta_FC_Subsoil.Variable = "Field Capacity Subsoil"
    Theta_FC_Subsoil.Unit = "cm3-cm-3"
    
    del Theta_FC_Subsoil_Data
    
    Theta_FC_Subsoil.Save_As_Tiff(os.path.join(output_folder_L2, "Theta_FC_Subsoil"))
    
    ################### Calculate Theta Wilting Point Subsoil ##############################
    Theta_WP_Subsoil_Data = 3.0575 * Theta_FC_Subsoil.Data**4.5227
    
    # Write in DataCube
    Theta_WP_Subsoil = DataCube.Rasterdata_Empty()
    Theta_WP_Subsoil.Data = Theta_WP_Subsoil_Data * MASK
    Theta_WP_Subsoil.Projection = ET.Projection
    Theta_WP_Subsoil.GeoTransform = ET.GeoTransform
    Theta_WP_Subsoil.Ordinal_time = None
    Theta_WP_Subsoil.Size = Theta_WP_Subsoil_Data.shape
    Theta_WP_Subsoil.Variable = "Wilting Point Subsoil"
    Theta_WP_Subsoil.Unit = "cm3-cm-3"
    
    del Theta_WP_Subsoil_Data
    
    Theta_WP_Subsoil.Save_As_Tiff(os.path.join(output_folder_L2, "Theta_WP_Subsoil"))
    
    ################### Calculate Theta Wilting Point Subsoil ##############################
    Soil_Water_Holding_Capacity_Data = (Theta_FC_Subsoil.Data - Theta_WP_Subsoil.Data ) * 1000
    
    # Write in DataCube
    Soil_Water_Holding_Capacity = DataCube.Rasterdata_Empty()
    Soil_Water_Holding_Capacity.Data = Soil_Water_Holding_Capacity_Data * MASK
    Soil_Water_Holding_Capacity.Projection = ET.Projection
    Soil_Water_Holding_Capacity.GeoTransform = ET.GeoTransform
    Soil_Water_Holding_Capacity.Ordinal_time = None
    Soil_Water_Holding_Capacity.Size = Soil_Water_Holding_Capacity_Data.shape
    Soil_Water_Holding_Capacity.Variable = "Soil Water Holding Capacity"
    Soil_Water_Holding_Capacity.Unit = "mm-m-1"
    
    del Soil_Water_Holding_Capacity_Data
    
    Soil_Water_Holding_Capacity.Save_As_Tiff(os.path.join(output_folder_L2, "Soil_Water_Holding_Capacity"))
    
    ################### Calculate Soil Moisture ############################################
    Soil_Moisture_Data = Theta_Sat_Subsoil.Data * np.exp((Evaporative_Fraction.Data.clip(0, 0.9) - 1)/0.421)
    
    # Write in DataCube
    Soil_Moisture = DataCube.Rasterdata_Empty()
    Soil_Moisture.Data = Soil_Moisture_Data * MASK
    Soil_Moisture.Projection = ET.Projection
    Soil_Moisture.GeoTransform = ET.GeoTransform
    Soil_Moisture.Ordinal_time = ET.Ordinal_time
    Soil_Moisture.Size = Soil_Moisture_Data.shape
    Soil_Moisture.Variable = "Soil Moisture"
    Soil_Moisture.Unit = "cm3-cm-3"
    
    del Soil_Moisture_Data
    
    Soil_Moisture.Save_As_Tiff(os.path.join(output_folder_L2, "Soil_Moisture"))
    
    ######################## Calculate days in each dekads #################################
    
    Days_in_Dekads = np.append(ET.Ordinal_time[1:] - ET.Ordinal_time[:-1], 11)
    
    ######################## Calculate Crop Water Requirement ########################
    
    Crop_Water_Requirement_Data = np.squeeze(np.maximum(Days_in_Dekads[:, None, None] * ET.Data, Kc_MAX.Data[None, :, :] * ET0.Data * Days_in_Dekads[:, None, None]), axis = 0)
    
    # Write in DataCube
    Crop_Water_Requirement = DataCube.Rasterdata_Empty()
    Crop_Water_Requirement.Data = Crop_Water_Requirement_Data * MASK
    Crop_Water_Requirement.Projection = ET.Projection
    Crop_Water_Requirement.GeoTransform = ET.GeoTransform
    Crop_Water_Requirement.Ordinal_time = ET.Ordinal_time
    Crop_Water_Requirement.Size = Crop_Water_Requirement_Data.shape
    Crop_Water_Requirement.Variable = "Crop Water Requirement"
    Crop_Water_Requirement.Unit = "mm-dekad-1"
    
    del Crop_Water_Requirement_Data, Kc_MAX
    
    Crop_Water_Requirement.Save_As_Tiff(os.path.join(output_folder_L2, "Crop_Water_Requirement"))
    
    ######################## Calculate Critical Soil Moisture ########################
    
    # Calculate Critical Soil Moisture
    Critical_Soil_Moisture_Data = Theta_WP_Subsoil.Data[None,:,:] + (Theta_FC_Subsoil.Data[None,:,:] - Theta_WP_Subsoil.Data[None,:,:]) * (0.47+0.04*(5 - Crop_Water_Requirement.Data/Days_in_Dekads[:, None, None]))
    
    # Write in DataCube
    Critical_Soil_Moisture = DataCube.Rasterdata_Empty()
    Critical_Soil_Moisture.Data = Critical_Soil_Moisture_Data * MASK
    Critical_Soil_Moisture.Projection = ET.Projection
    Critical_Soil_Moisture.GeoTransform = ET.GeoTransform
    Critical_Soil_Moisture.Ordinal_time = ET.Ordinal_time
    Critical_Soil_Moisture.Size = Critical_Soil_Moisture_Data.shape
    Critical_Soil_Moisture.Variable = "Critical Soil Moisture"
    Critical_Soil_Moisture.Unit = "cm3-cm-3"
    
    del Critical_Soil_Moisture_Data
    
    Critical_Soil_Moisture.Save_As_Tiff(os.path.join(output_folder_L2, "Critical_Soil_Moisture"))
    
    del Critical_Soil_Moisture
    
    ################## Calculate Soil Moisture Start and End ########################
    
    Soil_Moisture_Start_Data = np.concatenate((Soil_Moisture.Data[0,:,:][None, :, :],(Soil_Moisture.Data[:-1,:,:]+Soil_Moisture.Data[1:,:,:])/2), axis=0)
    Soil_Moisture_End_Data = np.concatenate(((Soil_Moisture.Data[1:,:,:]+Soil_Moisture.Data[:-1,:,:])/2, Soil_Moisture.Data[-1,:,:][None, :, :]), axis=0)  
    
    # Write in DataCube
    Soil_Moisture_Start = DataCube.Rasterdata_Empty()
    Soil_Moisture_Start.Data = Soil_Moisture_Start_Data * MASK
    Soil_Moisture_Start.Projection = Soil_Moisture.Projection
    Soil_Moisture_Start.GeoTransform = Soil_Moisture.GeoTransform
    Soil_Moisture_Start.Ordinal_time = Soil_Moisture.Ordinal_time
    Soil_Moisture_Start.Size = Soil_Moisture_Start_Data.shape
    Soil_Moisture_Start.Variable = "Soil Moisture Start"
    Soil_Moisture_Start.Unit = "cm3-cm-3"
    
    # Write in DataCube
    Soil_Moisture_End = DataCube.Rasterdata_Empty()
    Soil_Moisture_End.Data = Soil_Moisture_End_Data * MASK
    Soil_Moisture_End.Projection = Soil_Moisture.Projection
    Soil_Moisture_End.GeoTransform = Soil_Moisture.GeoTransform
    Soil_Moisture_End.Ordinal_time = Soil_Moisture.Ordinal_time
    Soil_Moisture_End.Size = Soil_Moisture_End_Data.shape
    Soil_Moisture_End.Variable = "Soil Moisture End"
    Soil_Moisture_End.Unit = "cm3-cm-3"
    
    del Soil_Moisture_End_Data, Soil_Moisture_Start_Data
    
    Soil_Moisture_Start.Save_As_Tiff(os.path.join(output_folder_L2, "Temp", "Soil_Moisture_Start"))
    Soil_Moisture_End.Save_As_Tiff(os.path.join(output_folder_L2, "Temp", "Soil_Moisture_End"))
    
    ################## Calculate Soil Moisture Change ##################################  
    
    Soil_Moisture_Change_Data = 10 * Root_Depth.Data * Days_in_Dekads[:, None, None] * (Soil_Moisture_End.Data - Soil_Moisture_Start.Data)
    
    # Write in DataCube
    Soil_Moisture_Change = DataCube.Rasterdata_Empty()
    Soil_Moisture_Change.Data = Soil_Moisture_Change_Data * MASK
    Soil_Moisture_Change.Projection = Soil_Moisture.Projection
    Soil_Moisture_Change.GeoTransform = Soil_Moisture.GeoTransform
    Soil_Moisture_Change.Ordinal_time = Soil_Moisture.Ordinal_time
    Soil_Moisture_Change.Size = Soil_Moisture_Change_Data.shape
    Soil_Moisture_Change.Variable = "Change Soil Moisture"
    Soil_Moisture_Change.Unit = "mm-dekad-1"
    
    del Soil_Moisture_Change_Data, Soil_Moisture_Start, Soil_Moisture_End
    
    Soil_Moisture_Change.Save_As_Tiff(os.path.join(output_folder_L2, "Soil_Moisture_Change"))
    
    ################## Calculate Net Supply / Net Drainage ##############################
    
    Net_Supply_Drainage_Data = (ET.Data - P.Data) * Days_in_Dekads[:, None, None] + Soil_Moisture_Change.Data
    
    # Write in DataCube
    Net_Supply_Drainage = DataCube.Rasterdata_Empty()
    Net_Supply_Drainage.Data = Net_Supply_Drainage_Data * MASK
    Net_Supply_Drainage.Projection = Soil_Moisture.Projection
    Net_Supply_Drainage.GeoTransform = Soil_Moisture.GeoTransform
    Net_Supply_Drainage.Ordinal_time = Soil_Moisture.Ordinal_time
    Net_Supply_Drainage.Size = Net_Supply_Drainage_Data.shape
    Net_Supply_Drainage.Variable = "Net Supply Drainage"
    Net_Supply_Drainage.Unit = "mm-dekad-1"
    
    del Net_Supply_Drainage_Data, Soil_Moisture_Change
    
    Net_Supply_Drainage.Save_As_Tiff(os.path.join(output_folder_L2, "Temp", "Net_Supply_Drainage"))
    
    del Net_Supply_Drainage
    
    #################### Calculate Deep Percolation ###################################    
    
    Deep_Percolation_Data = np.maximum(0, (Soil_Moisture.Data - Theta_FC_Subsoil.Data[None, :, :]) * Root_Depth.Data * Days_in_Dekads[:, None, None])
    
    # Write in DataCube
    Deep_Percolation = DataCube.Rasterdata_Empty()
    Deep_Percolation.Data = Deep_Percolation_Data * MASK
    Deep_Percolation.Projection = Soil_Moisture.Projection
    Deep_Percolation.GeoTransform = Soil_Moisture.GeoTransform
    Deep_Percolation.Ordinal_time = Soil_Moisture.Ordinal_time
    Deep_Percolation.Size = Deep_Percolation_Data.shape
    Deep_Percolation.Variable = "Deep Percolation"
    Deep_Percolation.Unit = "mm-dekad-1"
    
    del Deep_Percolation_Data
    
    Deep_Percolation.Save_As_Tiff(os.path.join(output_folder_L2, "Deep_Percolation"))
    
    del Deep_Percolation
    
    ############### Calculate Storage coefficient for surface runoff #################   
    
    Storage_Coeff_Surface_Runoff_Data = 4 * (Sand.Data[None, :, :] * LAI.Data) * (Theta_Sat_Subsoil.Data[None, :, :] - Soil_Moisture.Data)
    
    # Write in DataCube
    Storage_Coeff_Surface_Runoff = DataCube.Rasterdata_Empty()
    Storage_Coeff_Surface_Runoff.Data = Storage_Coeff_Surface_Runoff_Data * MASK
    Storage_Coeff_Surface_Runoff.Projection = Soil_Moisture.Projection
    Storage_Coeff_Surface_Runoff.GeoTransform = Soil_Moisture.GeoTransform
    Storage_Coeff_Surface_Runoff.Ordinal_time = Soil_Moisture.Ordinal_time
    Storage_Coeff_Surface_Runoff.Size = Storage_Coeff_Surface_Runoff_Data.shape
    Storage_Coeff_Surface_Runoff.Variable = "Storage Coefficient Surface Runoff"
    Storage_Coeff_Surface_Runoff.Unit = "mm-dekad-1"
    
    del Storage_Coeff_Surface_Runoff_Data
    
    Storage_Coeff_Surface_Runoff.Save_As_Tiff(os.path.join(output_folder_L2, "Storage_Coeff_Surface_Runoff"))
    
    ######################## Calculate Surface Runoff P  #############################
    I = DataCube.Rasterdata_tiffs(os.path.join(output_folder, str(Paths.I) %WAPOR_LVL), str(Formats.I) %WAPOR_LVL, Dates, Conversion = Conversions.I, Example_Data = example_file, Mask_Data = example_file, gap_filling = 1, reprojection_type = 2, Variable = 'I', Product = 'WAPOR', Unit = 'mm/day')
    
    Surface_Runoff_P_Data = (Days_in_Dekads[:, None, None] * (P.Data - I.Data))**2/(Days_in_Dekads[:, None, None] * (P.Data- I.Data) + Storage_Coeff_Surface_Runoff.Data)
    Surface_Runoff_P_Data[np.isnan(Surface_Runoff_P_Data)] = 0.0
    
    # Write in DataCube
    Surface_Runoff_P = DataCube.Rasterdata_Empty()
    Surface_Runoff_P.Data = Surface_Runoff_P_Data * MASK
    Surface_Runoff_P.Projection = Soil_Moisture.Projection
    Surface_Runoff_P.GeoTransform = Soil_Moisture.GeoTransform
    Surface_Runoff_P.Ordinal_time = Soil_Moisture.Ordinal_time
    Surface_Runoff_P.Size = Surface_Runoff_P_Data.shape
    Surface_Runoff_P.Variable = "Surface Runoff Precipitation"
    Surface_Runoff_P.Unit = "mm-dekad-1"
    
    del Surface_Runoff_P_Data, I, Storage_Coeff_Surface_Runoff
    
    Surface_Runoff_P.Save_As_Tiff(os.path.join(output_folder_L2, "Surface_Runoff_P"))
    
    ######################## Calculate Surface Runoff P ##############################  
    
    Surface_Runoff_Coefficient_Data = np.maximum(0.1, Surface_Runoff_P.Data/(P.Data * Days_in_Dekads[:, None, None]))
    Surface_Runoff_Coefficient_Data[np.isnan(Surface_Runoff_Coefficient_Data)] = 0.1
     
    # Write in DataCube
    Surface_Runoff_Coefficient = DataCube.Rasterdata_Empty()
    Surface_Runoff_Coefficient.Data = Surface_Runoff_Coefficient_Data * MASK
    Surface_Runoff_Coefficient.Projection = Soil_Moisture.Projection
    Surface_Runoff_Coefficient.GeoTransform = Soil_Moisture.GeoTransform
    Surface_Runoff_Coefficient.Ordinal_time = Soil_Moisture.Ordinal_time
    Surface_Runoff_Coefficient.Size = Surface_Runoff_Coefficient_Data.shape
    Surface_Runoff_Coefficient.Variable = "Surface Runoff Coefficient"
    Surface_Runoff_Coefficient.Unit = "-"
    
    del Surface_Runoff_Coefficient_Data
    
    Surface_Runoff_Coefficient.Save_As_Tiff(os.path.join(output_folder_L2, "Surface_Runoff_Coefficient"))
    
    del Surface_Runoff_P, Surface_Runoff_Coefficient
    
    ######################## Calculate updated maximum kc ######################
    
    Kc_MAX_update_Data = Crop_Water_Requirement.Data/(Days_in_Dekads[:, None, None] * ET0.Data)
    
    # Write in DataCube
    Kc_MAX_update = DataCube.Rasterdata_Empty()
    Kc_MAX_update.Data = Kc_MAX_update_Data * MASK
    Kc_MAX_update.Projection = LAI.Projection
    Kc_MAX_update.GeoTransform = LAI.GeoTransform
    Kc_MAX_update.Ordinal_time = LAI.Ordinal_time
    Kc_MAX_update.Size = Kc_MAX_update_Data.shape
    Kc_MAX_update.Variable = "Kc MAX update"
    Kc_MAX_update.Unit = "-"
    
    del Kc_MAX_update_Data
    
    Kc_MAX_update.Save_As_Tiff(os.path.join(output_folder_L2, "Kc_MAX_update"))
    
    del Kc_MAX_update
    
    ################# Calculate 10 year Mean Net Radiation, per Pixel ########################
    
    Total_years = int(np.ceil(Net_Radiation.Size[0]/36))
    Net_Radiation_Long_Term_Data = np.ones([36, Net_Radiation.Size[1], Net_Radiation.Size[2]]) * np.nan
    
    for dekad in range(0,36):
        IDs = np.array(range(0, Total_years)) * 36 + dekad  
        IDs_good = IDs[IDs<=Net_Radiation.Size[0]]
        Net_Radiation_Long_Term_Data[dekad, :, :] = np.nanmean(Net_Radiation.Data[IDs_good,:,:], axis = 0)
    
    # Write in DataCube
    Net_Radiation_Long_Term = DataCube.Rasterdata_Empty()
    Net_Radiation_Long_Term.Data = Net_Radiation_Long_Term_Data * MASK
    Net_Radiation_Long_Term.Projection = Soil_Moisture.Projection
    Net_Radiation_Long_Term.GeoTransform = Soil_Moisture.GeoTransform
    Net_Radiation_Long_Term.Ordinal_time = "Long_Term_Decade"
    Net_Radiation_Long_Term.Size = Net_Radiation_Long_Term_Data.shape
    Net_Radiation_Long_Term.Variable = "Long Term Net Radiation"
    Net_Radiation_Long_Term.Unit = "W-m-2"
    
    del Net_Radiation_Long_Term_Data
    
    Net_Radiation_Long_Term.Save_As_Tiff(os.path.join(output_folder_L2, "Net_Radiation_Long_Term"))
    
    del Net_Radiation_Long_Term
    
    ##################### Calculate 10 year mean evaporative fraction ###########################
    
    Total_years = int(np.ceil(Evaporative_Fraction.Size[0]/36))
    Evaporative_Fraction_Long_Term_Data = np.ones([36, Evaporative_Fraction.Size[1], Evaporative_Fraction.Size[2]]) * np.nan
    
    for dekad in range(0,36):
        IDs = np.array(range(0, Total_years)) * 36 + dekad  
        IDs_good = IDs[IDs<=Evaporative_Fraction.Size[0]]
        Evaporative_Fraction_Long_Term_Data[dekad, :, :] = np.nanmean(Evaporative_Fraction.Data[IDs_good,:,:], axis = 0)
    
    # Write in DataCube
    Evaporative_Fraction_Long_Term = DataCube.Rasterdata_Empty()
    Evaporative_Fraction_Long_Term.Data = Evaporative_Fraction_Long_Term_Data * MASK
    Evaporative_Fraction_Long_Term.Projection = Soil_Moisture.Projection
    Evaporative_Fraction_Long_Term.GeoTransform = Soil_Moisture.GeoTransform
    Evaporative_Fraction_Long_Term.Ordinal_time = "Long_Term_Decade"
    Evaporative_Fraction_Long_Term.Size = Evaporative_Fraction_Long_Term_Data.shape
    Evaporative_Fraction_Long_Term.Variable = "Long Term Evaporative Fraction"
    Evaporative_Fraction_Long_Term.Unit = "-"
    
    del Evaporative_Fraction_Long_Term_Data
    
    Evaporative_Fraction_Long_Term.Save_As_Tiff(os.path.join(output_folder_L2, "Evaporative_Fraction_Long_Term"))
    
    del Evaporative_Fraction_Long_Term
    
    ######################### Calculate 10 yr mean soil moisture ###########################
    
    Total_years = int(np.ceil(Evaporative_Fraction.Size[0]/36))
    Soil_Moisture_Long_Term_Data = np.ones([36, Soil_Moisture.Size[1], Soil_Moisture.Size[2]]) * np.nan
    
    for dekad in range(0,36):
        IDs = np.array(range(0, Total_years)) * 36 + dekad  
        IDs_good = IDs[IDs<=Soil_Moisture.Size[0]]
        Soil_Moisture_Long_Term_Data[dekad, :, :] = np.nanmean(Soil_Moisture.Data[IDs_good,:,:], axis = 0)
    
    # Write in DataCube
    Soil_Moisture_Long_Term = DataCube.Rasterdata_Empty()
    Soil_Moisture_Long_Term.Data = Soil_Moisture_Long_Term_Data * MASK
    Soil_Moisture_Long_Term.Projection = Soil_Moisture.Projection
    Soil_Moisture_Long_Term.GeoTransform = Soil_Moisture.GeoTransform
    Soil_Moisture_Long_Term.Ordinal_time = "Long_Term_Decade"
    Soil_Moisture_Long_Term.Size = Soil_Moisture_Long_Term_Data.shape
    Soil_Moisture_Long_Term.Variable = "Long Term Soil Moisture"
    Soil_Moisture_Long_Term.Unit = "cm3-cm-3"
    
    del Soil_Moisture_Long_Term_Data
    
    Soil_Moisture_Long_Term.Save_As_Tiff(os.path.join(output_folder_L2, "Soil_Moisture_Long_Term"))
    
    del Soil_Moisture_Long_Term
    
    ################## Calculate Available Water Before Depletion ##########################
    
    Available_Before_Depletion_Data = 0.8 * (Theta_FC_Subsoil.Data[None, :, :] - 0.12) * 10 * Root_Depth.Data
    
    # Write in DataCube
    Available_Before_Depletion = DataCube.Rasterdata_Empty()
    Available_Before_Depletion.Data = Available_Before_Depletion_Data * MASK
    Available_Before_Depletion.Projection = Root_Depth.Projection
    Available_Before_Depletion.GeoTransform = Root_Depth.GeoTransform
    Available_Before_Depletion.Ordinal_time = Root_Depth.Ordinal_time
    Available_Before_Depletion.Size = Available_Before_Depletion_Data.shape
    Available_Before_Depletion.Variable = "Available Before Depletion"
    Available_Before_Depletion.Unit = "mm"
    
    del Theta_WP_Subsoil, Root_Depth
    
    Available_Before_Depletion.Save_As_Tiff(os.path.join(output_folder_L2, "Available_Before_Depletion"))
    
    del Available_Before_Depletion
    
    ############################### Calculate Phenelogy ####################################
    
    L2.Phenology.Calc_Phenology(output_folder, Start_year_analyses, End_year_analyses, T, ET, NPP, P, Temp, ET0, LU_END, Phenology_pixels_year, Grassland_pixels_year, example_file, Days_in_Dekads, Phenology_Threshold, Phenology_Slope)

    return()    
Example #2
0
def Calc_Dekads_from_Monthly(DataCube_in):

    import WaporTranslator.LEVEL_1.DataCube as DataCube

    # Get the timesteps of the dekads and the monthly
    Time_monthly = DataCube_in.Ordinal_time
    Time = Get_Dekads(
        datetime.datetime.fromordinal(Time_monthly[0]).year,
        datetime.datetime.fromordinal(Time_monthly[-1]).year)
    Time = np.array(list(map(lambda i: i.toordinal(), Time)))

    # Create empty array
    Data_out = np.ones([
        len(Time_monthly) * 3, DataCube_in.Size[1], DataCube_in.Size[2]
    ]) * np.nan

    Counter = 1

    for i in range(0, DataCube_in.Size[1]):
        for j in range(0, DataCube_in.Size[2]):

            sys.stdout.write(
                "\rCreate Dekads %s %i/%i (%f %%)" %
                (DataCube_in.Variable, Counter,
                 (DataCube_in.Size[1] * DataCube_in.Size[2]), Counter /
                 (DataCube_in.Size[1] * DataCube_in.Size[2]) * 100))
            sys.stdout.flush()

            x = np.append(Time_monthly, Time[-1])
            y = np.append(DataCube_in.Data[:, i, j], DataCube_in.Data[-1, i,
                                                                      j])
            try:
                f2 = interp1d(x, y, kind='linear')
                inter = f2(Time)
            except:
                inter = np.ones(len(Time)) * np.nan

            Data_out[:, i, j] = inter
            Counter += 1

    DataCube_out = DataCube.Rasterdata_Empty()
    DataCube_out.Data = Data_out
    DataCube_out.Projection = DataCube_in.Projection
    DataCube_out.Size = [len(Time), DataCube_in.Size[1], DataCube_in.Size[2]]
    DataCube_out.GeoTransform = DataCube_in.GeoTransform
    DataCube_out.NoData = np.nan
    DataCube_out.Ordinal_time = Time

    # Origin Of Data
    DataCube_out.Directory = ''
    DataCube_out.Format = ''

    # Describtion of dataset
    DataCube_out.Variable = DataCube_in.Variable
    DataCube_out.Product = DataCube_in.Product
    DataCube_out.Description = DataCube_in.Description
    DataCube_out.Unit = DataCube_in.Unit
    DataCube_out.Dimension_description = DataCube_in.Dimension_description

    # Time Series
    DataCube_out.Startdate = '%d-%02d-%02d' % (datetime.datetime.fromordinal(
        Time[0]).year, datetime.datetime.fromordinal(
            Time[0]).month, datetime.datetime.fromordinal(Time[0]).day)
    DataCube_out.Enddate = '%d-%02d-%02d' % (datetime.datetime.fromordinal(
        Time[-1]).year, datetime.datetime.fromordinal(
            Time[-1]).month, datetime.datetime.fromordinal(Time[-1]).day)
    DataCube_out.Timestep = ''

    print(
        "                                                                                                                      "
    )

    return (DataCube_out)
Example #3
0
def Calc_Dekads_from_Daily(DataCube_in, flux_state="flux"):

    import WaporTranslator.LEVEL_1.DataCube as DataCube

    # Get the timesteps of the dekads and the daily
    Time = DataCube_in.Ordinal_time

    # Open data
    Data_array = DataCube_in.Data

    # Find dekades dates
    Dates_dek = Get_Dekads(str(datetime.datetime.fromordinal(Time[0]).year),
                           str(datetime.datetime.fromordinal(Time[-1]).year))

    # Define the output array
    Data_out = np.ones(
        [len(Dates_dek), DataCube_in.Size[1], DataCube_in.Size[2]]) * np.nan

    Counter = 1
    for Date_dek in Dates_dek:

        sys.stdout.write(
            "\rCreate Daily %s %i/%i (%f %%)" %
            (DataCube_in.Variable, Counter, len(Dates_dek), Counter /
             (len(Dates_dek)) * 100))
        sys.stdout.flush()

        # date in dekad
        day_dekad = int(
            "%d" % int(np.minimum(int(
                ("%02d" % int(str(Date_dek.day)))[0]), 2)))
        year = Date_dek.year
        month = Date_dek.month

        # Get end date day of dekad
        if day_dekad == 2:
            End_day_dekad = calendar.monthrange(year, month)[1]
        else:
            End_day_dekad = int(str(int(day_dekad)) + "1") + 9

        Startdate_or = Date_dek.toordinal()
        Enddate_or = datetime.datetime(year, month, End_day_dekad).toordinal()

        Time_good = np.where(
            np.logical_and(Time >= Startdate_or, Time <= Enddate_or), True,
            False)

        Array_dek = Data_array[Time_good, :, :]

        if flux_state == "flux":
            Data_out[int(Counter - 1), :, :] = np.nansum(Array_dek, axis=0)
        if flux_state == "state":
            Data_out[int(Counter - 1), :, :] = np.nanmean(Array_dek, axis=0)

        Counter += 1

    DataCube_out = DataCube.Rasterdata_Empty()
    DataCube_out.Data = Data_out
    DataCube_out.GeoTransform = DataCube_in.GeoTransform
    DataCube_out.Projection = DataCube_in.Projection
    DataCube_out.Size = [
        len(Dates_dek), DataCube_in.Size[1], DataCube_in.Size[2]
    ]
    DataCube_out.GeoTransform = DataCube_in.GeoTransform
    DataCube_out.NoData = np.nan
    DataCube_out.Ordinal_time = np.array(
        list(map(lambda i: i.toordinal(), Dates_dek)))
    DataCube_out.Variable = DataCube_in.Variable

    print(
        "                                                                                                                      "
    )

    return (DataCube_out)
def main(inputs):

    # Set Variables
    Start_year_analyses = inputs["Start_year"]
    End_year_analyses = inputs["End_year"]
    output_folder = inputs["Output_folder"]
    WAPOR_LVL = inputs["WAPOR_LEVEL"]
    threshold_irrigated = inputs["Irrigation_Dekads_Threshold"]
    Champion_per = inputs["Champion_Percentage"]

    # Do not show non relevant warnings
    warnings.filterwarnings("ignore")
    warnings.filterwarnings("ignore", category=FutureWarning)
    warnings.filterwarnings("ignore", category=RuntimeWarning)

    Startdate = "%s-01-01" % Start_year_analyses
    Enddate = "%s-12-31" % End_year_analyses

    # Define dates
    Dates = Functions.Get_Dekads(Start_year_analyses, End_year_analyses)
    Dates_Years = pd.date_range(Startdate, Enddate, freq="AS")

    # Get path and formats
    Paths = Inputs.Input_Paths()
    Formats = Inputs.Input_Formats()
    Conversions = Inputs.Input_Conversions()

    # Set example file
    example_file = os.path.join(output_folder, "LEVEL_1", "MASK", "MASK.tif")

    # Open Mask
    dest_mask = gdal.Open(example_file)
    MASK = dest_mask.GetRasterBand(1).ReadAsArray()

    # Define output folder LEVEL 3
    output_folder_L3 = os.path.join(output_folder, "LEVEL_3", "Irrigation")
    if not os.path.exists(output_folder_L3):
        os.makedirs(output_folder_L3)

    ################################# Dynamic maps #################################
    Crop_Water_Requirement = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.Crop_Water_Requirement),
        Formats.Crop_Water_Requirement,
        Dates,
        Conversion=Conversions.Crop_Water_Requirement,
        Example_Data=example_file,
        Mask_Data=example_file,
        gap_filling=1,
        reprojection_type=2,
        Variable='Crop Water Requirement',
        Product='',
        Unit='mm/decade')
    ET = DataCube.Rasterdata_tiffs(os.path.join(output_folder,
                                                str(Paths.ET) % WAPOR_LVL),
                                   str(Formats.ET) % WAPOR_LVL,
                                   Dates,
                                   Conversion=Conversions.ET,
                                   Example_Data=example_file,
                                   Mask_Data=example_file,
                                   gap_filling=1,
                                   reprojection_type=2,
                                   Variable='ET',
                                   Product='WAPOR',
                                   Unit='mm/day')
    E = DataCube.Rasterdata_tiffs(os.path.join(output_folder,
                                               str(Paths.E) % WAPOR_LVL),
                                  str(Formats.E) % WAPOR_LVL,
                                  Dates,
                                  Conversion=Conversions.E,
                                  Example_Data=example_file,
                                  Mask_Data=example_file,
                                  gap_filling=1,
                                  reprojection_type=2,
                                  Variable='E',
                                  Product='WAPOR',
                                  Unit='mm/day')
    I = DataCube.Rasterdata_tiffs(os.path.join(output_folder,
                                               str(Paths.I) % WAPOR_LVL),
                                  str(Formats.I) % WAPOR_LVL,
                                  Dates,
                                  Conversion=Conversions.I,
                                  Example_Data=example_file,
                                  Mask_Data=example_file,
                                  gap_filling=1,
                                  reprojection_type=2,
                                  Variable='I',
                                  Product='WAPOR',
                                  Unit='mm/day')
    P = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.P),
                                  Formats.P,
                                  Dates,
                                  Conversion=Conversions.P,
                                  Example_Data=example_file,
                                  Mask_Data=example_file,
                                  gap_filling=1,
                                  reprojection_type=2,
                                  Variable='P',
                                  Product='WAPOR',
                                  Unit='mm/day')
    Critical_Soil_Moisture = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.Critical_Soil_Moisture),
        Formats.Critical_Soil_Moisture,
        Dates,
        Conversion=Conversions.Critical_Soil_Moisture,
        Variable='Critical Soil Moisture',
        Product='SoilGrids',
        Unit='cm3/cm3')
    Soil_Moisture = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.Soil_Moisture),
        Formats.Soil_Moisture,
        Dates,
        Conversion=Conversions.Soil_Moisture,
        Variable='Soil Moisture',
        Product='',
        Unit='cm3/cm3')
    Net_Supply_Drainage = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.Net_Supply_Drainage),
        Formats.Net_Supply_Drainage,
        Dates,
        Conversion=Conversions.Net_Supply_Drainage,
        Variable='Net Supply Drainage',
        Product='',
        Unit='mm/decade')
    Deep_Percolation = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.Deep_Percolation),
        Formats.Deep_Percolation,
        Dates,
        Conversion=Conversions.Deep_Percolation,
        Variable='Deep Percolation',
        Product='',
        Unit='mm/decade')
    Surface_Runoff_Coefficient = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.Surface_Runoff_Coefficient),
        Formats.Surface_Runoff_Coefficient,
        Dates,
        Conversion=Conversions.Surface_Runoff_Coefficient,
        Variable='Surface Runoff Coefficient',
        Product='',
        Unit='-')
    Surface_Runoff_P = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.Surface_Runoff_P),
        Formats.Surface_Runoff_P,
        Dates,
        Conversion=Conversions.Surface_Runoff_P,
        Variable='Surface Runoff Precipitation',
        Product='',
        Unit='mm/decade')
    AEZ = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.AEZ),
                                    Formats.AEZ,
                                    Dates,
                                    Conversion=Conversions.AEZ,
                                    Variable='Surface Runoff Coefficient',
                                    Product='',
                                    Unit='-')
    ETcum = DataCube.Rasterdata_tiffs(os.path.join(output_folder,
                                                   Paths.Cumulative_ET),
                                      Formats.Cumulative_ET,
                                      Dates,
                                      Conversion=Conversions.Cumulative_ET,
                                      Variable='Cumulated Evapotranspiration',
                                      Product='',
                                      Unit='mm/decade')
    Irrigation = DataCube.Rasterdata_tiffs(os.path.join(
        output_folder, Paths.Irrigation),
                                           Formats.Irrigation,
                                           Dates,
                                           Conversion=Conversions.Irrigation,
                                           Variable='Irrigation',
                                           Product='',
                                           Unit='-')

    ################################# Static maps #################################
    Theta_FC_Subsoil = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.Theta_FC_Subsoil),
        Formats.Theta_FC_Subsoil,
        Dates=None,
        Conversion=Conversions.Theta_FC_Subsoil,
        Example_Data=example_file,
        Mask_Data=example_file,
        reprojection_type=2,
        Variable='Theta Field Capacity Subsoil',
        Product='SoilGrids',
        Unit='cm3/cm3')

    ######################## Calculate days in each dekads #################################
    Days_in_Dekads = np.append(ET.Ordinal_time[1:] - ET.Ordinal_time[:-1], 11)

    ######################## Calculate Irrigation Water Requirement ########################
    Irrigation_Water_Requirement_Data = (
        Crop_Water_Requirement.Data -
        0.7 * P.Data * Days_in_Dekads[:, None, None]) / (0.65)

    # Write in DataCube
    Irrigation_Water_Requirement = DataCube.Rasterdata_Empty()
    Irrigation_Water_Requirement.Data = Irrigation_Water_Requirement_Data * MASK
    Irrigation_Water_Requirement.Projection = ET.Projection
    Irrigation_Water_Requirement.GeoTransform = ET.GeoTransform
    Irrigation_Water_Requirement.Ordinal_time = ET.Ordinal_time
    Irrigation_Water_Requirement.Size = Irrigation_Water_Requirement_Data.shape
    Irrigation_Water_Requirement.Variable = "Irrigation Water Requirement"
    Irrigation_Water_Requirement.Unit = "mm-dekad-1"

    del Irrigation_Water_Requirement_Data

    Irrigation_Water_Requirement.Save_As_Tiff(
        os.path.join(output_folder_L3, "Irrigation_Water_Requirement"))

    ######################## Calculate ETblue ########################
    ETblue_Data = np.where(
        ET.Data > 0.7 * P.Data,
        Days_in_Dekads[:, None, None] * (ET.Data - 0.7 * P.Data), 0)

    # Write in DataCube
    ETblue = DataCube.Rasterdata_Empty()
    ETblue.Data = ETblue_Data * MASK
    ETblue.Projection = ET.Projection
    ETblue.GeoTransform = ET.GeoTransform
    ETblue.Ordinal_time = ET.Ordinal_time
    ETblue.Size = ETblue_Data.shape
    ETblue.Variable = "Blue Evapotranspiration"
    ETblue.Unit = "mm-dekad-1"

    del ETblue_Data

    ETblue.Save_As_Tiff(os.path.join(output_folder_L3, "ETblue"))

    ######################## Calculate Gross Irrigation Water Supply ########################
    Gross_Irrigation_Water_Supply_Data = np.maximum(
        0, (Net_Supply_Drainage.Data + Deep_Percolation.Data +
            Surface_Runoff_P.Data) * (1 + Surface_Runoff_Coefficient.Data))
    Gross_Irrigation_Water_Supply_Data = np.maximum(
        1 / 0.95 * ETblue.Data, Gross_Irrigation_Water_Supply_Data)

    # Write in DataCube
    Gross_Irrigation_Water_Supply = DataCube.Rasterdata_Empty()
    Gross_Irrigation_Water_Supply.Data = Gross_Irrigation_Water_Supply_Data * MASK
    Gross_Irrigation_Water_Supply.Projection = ET.Projection
    Gross_Irrigation_Water_Supply.GeoTransform = ET.GeoTransform
    Gross_Irrigation_Water_Supply.Ordinal_time = ET.Ordinal_time
    Gross_Irrigation_Water_Supply.Size = Gross_Irrigation_Water_Supply_Data.shape
    Gross_Irrigation_Water_Supply.Variable = "Gross Irrigation Water Supply"
    Gross_Irrigation_Water_Supply.Unit = "mm-dekad-1"

    del Gross_Irrigation_Water_Supply_Data

    Gross_Irrigation_Water_Supply.Save_As_Tiff(
        os.path.join(output_folder_L3, "Gross_Irrigation_Water_Supply"))

    ######################## Calculate Adequacy Relative Water Supply ########################
    Adequacy_Relative_Water_Supply_Data = (
        Gross_Irrigation_Water_Supply.Data +
        P.Data * Days_in_Dekads[:, None, None]) / Crop_Water_Requirement.Data

    # Write in DataCube
    Adequacy_Relative_Water_Supply = DataCube.Rasterdata_Empty()
    Adequacy_Relative_Water_Supply.Data = Adequacy_Relative_Water_Supply_Data * MASK
    Adequacy_Relative_Water_Supply.Projection = ET.Projection
    Adequacy_Relative_Water_Supply.GeoTransform = ET.GeoTransform
    Adequacy_Relative_Water_Supply.Ordinal_time = ET.Ordinal_time
    Adequacy_Relative_Water_Supply.Size = Adequacy_Relative_Water_Supply_Data.shape
    Adequacy_Relative_Water_Supply.Variable = "Adequacy Relative Water Supply"
    Adequacy_Relative_Water_Supply.Unit = "-"

    del Adequacy_Relative_Water_Supply_Data

    Adequacy_Relative_Water_Supply.Save_As_Tiff(
        os.path.join(output_folder_L3, "Adequacy_Relative_Water_Supply"))

    ######################## Calculate Adequacy Relative Irrigation Water Supply ########################
    Adequacy_Relative_Irrigation_Water_Supply_Data = Gross_Irrigation_Water_Supply.Data / Irrigation_Water_Requirement.Data

    # Write in DataCube
    Adequacy_Relative_Irrigation_Water_Supply = DataCube.Rasterdata_Empty()
    Adequacy_Relative_Irrigation_Water_Supply.Data = Adequacy_Relative_Irrigation_Water_Supply_Data * MASK
    Adequacy_Relative_Irrigation_Water_Supply.Projection = ET.Projection
    Adequacy_Relative_Irrigation_Water_Supply.GeoTransform = ET.GeoTransform
    Adequacy_Relative_Irrigation_Water_Supply.Ordinal_time = ET.Ordinal_time
    Adequacy_Relative_Irrigation_Water_Supply.Size = Adequacy_Relative_Irrigation_Water_Supply_Data.shape
    Adequacy_Relative_Irrigation_Water_Supply.Variable = "Adequacy Relative Irrigation Water Supply"
    Adequacy_Relative_Irrigation_Water_Supply.Unit = "-"

    del Adequacy_Relative_Irrigation_Water_Supply_Data

    Adequacy_Relative_Irrigation_Water_Supply.Save_As_Tiff(
        os.path.join(output_folder_L3,
                     "Adequacy_Relative_Irrigation_Water_Supply"))

    ######################## Calculate Non Consumptive Use Due To Irrigation ########################
    Non_Consumptive_Use_Due_To_Irrigation_Data = np.maximum(
        0, Gross_Irrigation_Water_Supply.Data - ETblue.Data)

    # Write in DataCube
    Non_Consumptive_Use_Due_To_Irrigation = DataCube.Rasterdata_Empty()
    Non_Consumptive_Use_Due_To_Irrigation.Data = Non_Consumptive_Use_Due_To_Irrigation_Data.clip(
        0, 100) * MASK
    Non_Consumptive_Use_Due_To_Irrigation.Projection = ET.Projection
    Non_Consumptive_Use_Due_To_Irrigation.GeoTransform = ET.GeoTransform
    Non_Consumptive_Use_Due_To_Irrigation.Ordinal_time = ET.Ordinal_time
    Non_Consumptive_Use_Due_To_Irrigation.Size = Non_Consumptive_Use_Due_To_Irrigation_Data.shape
    Non_Consumptive_Use_Due_To_Irrigation.Variable = "Non Consumptive Use Due To Irrigation"
    Non_Consumptive_Use_Due_To_Irrigation.Unit = "mm-dekad-1"

    del Non_Consumptive_Use_Due_To_Irrigation_Data

    Non_Consumptive_Use_Due_To_Irrigation.Save_As_Tiff(
        os.path.join(output_folder_L3,
                     "Non_Consumptive_Use_Due_To_Irrigation"))

    ######################### Calculate Onfarm Irrigation Efficiency ########################
    Gross_Irrigation_Water_Supply.Data[Gross_Irrigation_Water_Supply.Data ==
                                       0] = 0.001
    Onfarm_Irrigation_Efficiency_Data = ETblue.Data / Gross_Irrigation_Water_Supply.Data * 100
    Onfarm_Irrigation_Efficiency_Data = Onfarm_Irrigation_Efficiency_Data.astype(
        np.float64)

    # Write in DataCube
    Onfarm_Irrigation_Efficiency = DataCube.Rasterdata_Empty()
    Onfarm_Irrigation_Efficiency.Data = Onfarm_Irrigation_Efficiency_Data.clip(
        0, 100) * MASK
    Onfarm_Irrigation_Efficiency.Projection = ET.Projection
    Onfarm_Irrigation_Efficiency.GeoTransform = ET.GeoTransform
    Onfarm_Irrigation_Efficiency.Ordinal_time = ET.Ordinal_time
    Onfarm_Irrigation_Efficiency.Size = Onfarm_Irrigation_Efficiency_Data.shape
    Onfarm_Irrigation_Efficiency.Variable = "Onfarm Irrigation Efficiency"
    Onfarm_Irrigation_Efficiency.Unit = "Percentage"

    del Onfarm_Irrigation_Efficiency_Data

    Onfarm_Irrigation_Efficiency.Save_As_Tiff(
        os.path.join(output_folder_L3, "Onfarm_Irrigation_Efficiency"))

    ########################## Calculate Degree Of Over Irrigation #########################
    Degree_Of_Over_Irrigation_Data = np.maximum(
        Theta_FC_Subsoil.Data[None, :, :] / Soil_Moisture.Data, 1) * 100

    # Write in DataCube
    Degree_Of_Over_Irrigation = DataCube.Rasterdata_Empty()
    Degree_Of_Over_Irrigation.Data = Degree_Of_Over_Irrigation_Data * MASK
    Degree_Of_Over_Irrigation.Projection = ET.Projection
    Degree_Of_Over_Irrigation.GeoTransform = ET.GeoTransform
    Degree_Of_Over_Irrigation.Ordinal_time = ET.Ordinal_time
    Degree_Of_Over_Irrigation.Size = Degree_Of_Over_Irrigation_Data.shape
    Degree_Of_Over_Irrigation.Variable = "Degree Of Over Irrigation"
    Degree_Of_Over_Irrigation.Unit = "-"

    del Degree_Of_Over_Irrigation_Data

    Degree_Of_Over_Irrigation.Save_As_Tiff(
        os.path.join(output_folder_L3, "Degree_Of_Over_Irrigation"))

    ########################### Calculate Adequacy Degree Of Under Irrigation ##########################
    Degree_Of_Under_Irrigation_Data = np.minimum(
        Critical_Soil_Moisture.Data / Soil_Moisture.Data, 1) * 100

    # Write in DataCube
    Degree_Of_Under_Irrigation = DataCube.Rasterdata_Empty()
    Degree_Of_Under_Irrigation.Data = Degree_Of_Under_Irrigation_Data * MASK
    Degree_Of_Under_Irrigation.Projection = ET.Projection
    Degree_Of_Under_Irrigation.GeoTransform = ET.GeoTransform
    Degree_Of_Under_Irrigation.Ordinal_time = ET.Ordinal_time
    Degree_Of_Under_Irrigation.Size = Degree_Of_Under_Irrigation_Data.shape
    Degree_Of_Under_Irrigation.Variable = "Adequacy Degree Of Under Irrigation"
    Degree_Of_Under_Irrigation.Unit = "-"

    del Degree_Of_Under_Irrigation_Data

    Degree_Of_Under_Irrigation.Save_As_Tiff(
        os.path.join(output_folder_L3, "Degree_Of_Under_Irrigation"))

    ############################ Calculate Adequacy Crop Water Deficit ###########################
    Adequacy_Crop_Water_Deficit_Data = Crop_Water_Requirement.Data - ET.Data * Days_in_Dekads[:,
                                                                                              None,
                                                                                              None]

    # Write in DataCube
    Adequacy_Crop_Water_Deficit = DataCube.Rasterdata_Empty()
    Adequacy_Crop_Water_Deficit.Data = Adequacy_Crop_Water_Deficit_Data * MASK
    Adequacy_Crop_Water_Deficit.Projection = ET.Projection
    Adequacy_Crop_Water_Deficit.GeoTransform = ET.GeoTransform
    Adequacy_Crop_Water_Deficit.Ordinal_time = ET.Ordinal_time
    Adequacy_Crop_Water_Deficit.Size = Adequacy_Crop_Water_Deficit_Data.shape
    Adequacy_Crop_Water_Deficit.Variable = "Adequacy Crop Water Deficit"
    Adequacy_Crop_Water_Deficit.Unit = "mm-dekad-1"

    del Adequacy_Crop_Water_Deficit_Data

    Adequacy_Crop_Water_Deficit.Save_As_Tiff(
        os.path.join(output_folder_L3, "Adequacy_Crop_Water_Deficit"))

    ################################# Calculate Spatial Target Evapotranspiration #################################
    L3_AEZ_ET = dict()
    AEZ.Data = AEZ.Data.astype(np.int)
    for AEZ_ID in np.unique(AEZ.Data[~np.isnan(AEZ.Data)]):
        L3_AEZ_ET[int(AEZ_ID)] = np.nanpercentile(np.where(
            AEZ.Data == AEZ_ID, ET.Data, np.nan),
                                                  Champion_per,
                                                  axis=(1, 2))

    ################################# Create spatial target maps #################################
    ET_Target_Spatial_Data = np.ones(Adequacy_Crop_Water_Deficit.Size) * np.nan
    for AEZ_ID in np.unique(AEZ.Data[~np.isnan(AEZ.Data)]):
        ET_Target_Spatial_Data = np.where(
            AEZ.Data == AEZ_ID, L3_AEZ_ET[int(AEZ_ID)][:, None, None],
            ET_Target_Spatial_Data)

    ############################# Calculate Target Evapotranspiration ############################

    ET_Target_Spatial_Data = ET_Target_Spatial_Data

    # Write in DataCube
    ET_Target_Spatial = DataCube.Rasterdata_Empty()
    ET_Target_Spatial.Data = ET_Target_Spatial_Data * MASK
    ET_Target_Spatial.Projection = ET.Projection
    ET_Target_Spatial.GeoTransform = ET.GeoTransform
    ET_Target_Spatial.Ordinal_time = ET.Ordinal_time
    ET_Target_Spatial.Size = ET_Target_Spatial_Data.shape
    ET_Target_Spatial.Variable = "Target Evapotranspiration Spatial"
    ET_Target_Spatial.Unit = "mm-dekad-1"

    del ET_Target_Spatial_Data

    ET_Target_Spatial.Save_As_Tiff(
        os.path.join(output_folder_L3, "ET_Target_Spatial"))

    ############################## Calculate Evapotranspiration Savings #############################
    ET_Savings_Spatial_Data = np.minimum(
        0, ET_Target_Spatial.Data - ET.Data * Days_in_Dekads[:, None, None])

    # Write in DataCube
    ET_Savings_Spatial = DataCube.Rasterdata_Empty()
    ET_Savings_Spatial.Data = ET_Savings_Spatial_Data * MASK
    ET_Savings_Spatial.Projection = ET.Projection
    ET_Savings_Spatial.GeoTransform = ET.GeoTransform
    ET_Savings_Spatial.Ordinal_time = ET.Ordinal_time
    ET_Savings_Spatial.Size = ET_Savings_Spatial_Data.shape
    ET_Savings_Spatial.Variable = "Evapotranspiration Savings Spatial"
    ET_Savings_Spatial.Unit = "mm-dekad-1"

    del ET_Savings_Spatial_Data

    ET_Savings_Spatial.Save_As_Tiff(
        os.path.join(output_folder_L3, "ET_Savings_Spatial"))

    ################################# Calculate 10 year mean Evapotranspiration #################################

    Total_years = int(np.ceil(ET.Size[0] / 36))
    Mean_Long_Term_ET_Data = np.ones([36, ET.Size[1], ET.Size[2]]) * np.nan

    for dekad in range(0, 36):
        IDs = np.array(range(0, Total_years)) * 36 + dekad
        IDs_good = IDs[IDs <= ET.Size[0]]
        Mean_Long_Term_ET_Data[dekad, :, :] = np.nanmean(
            ET.Data[IDs_good, :, :] * Days_in_Dekads[IDs_good, None, None],
            axis=0)

    # Write in DataCube
    Mean_Long_Term_ET = DataCube.Rasterdata_Empty()
    Mean_Long_Term_ET.Data = Mean_Long_Term_ET_Data * MASK
    Mean_Long_Term_ET.Projection = ET.Projection
    Mean_Long_Term_ET.GeoTransform = ET.GeoTransform
    Mean_Long_Term_ET.Ordinal_time = "Long_Term_Decade"
    Mean_Long_Term_ET.Size = Mean_Long_Term_ET_Data.shape
    Mean_Long_Term_ET.Variable = "Mean Long Term Evapotranspiration"
    Mean_Long_Term_ET.Unit = "mm-dekad-1"

    del Mean_Long_Term_ET_Data

    Mean_Long_Term_ET.Save_As_Tiff(
        os.path.join(output_folder_L3, "Mean_Long_Term_Evapotranspiration"))
    '''    
    ################################## Calculate Gap in Evapotranspiration #################################
    ET_Gap_Temporal_Data = np.minimum(0, np.tile(Mean_Long_Term_ET.Data, (Total_years, 1, 1)) - ET.Data * Days_in_Dekads[:, None, None])

    # Write in DataCube    
    ET_Gap_Temporal = DataCube.Rasterdata_Empty()
    ET_Gap_Temporal.Data = ET_Gap_Temporal_Data * MASK
    ET_Gap_Temporal.Projection = ET.Projection
    ET_Gap_Temporal.GeoTransform = ET.GeoTransform
    ET_Gap_Temporal.Ordinal_time = ET.Ordinal_time
    ET_Gap_Temporal.Size = ET_Gap_Temporal_Data.shape
    ET_Gap_Temporal.Variable = "Evapotranspiration Gap Temporal"
    ET_Gap_Temporal.Unit = "mm-dekad-1"       

    del ET_Gap_Temporal_Data
    
    ET_Gap_Temporal.Save_As_Tiff(os.path.join(output_folder_L3, "ETgap"))


    ################################### Calculate Feasible Water Conservation ##################################
    Feasible_Water_Conservation_Data =(ET_Savings_Spatial.Data + ET_Gap_Temporal.Data)/2

    # Write in DataCube
    Feasible_Water_Conservation = DataCube.Rasterdata_Empty()
    Feasible_Water_Conservation.Data = Feasible_Water_Conservation_Data * MASK
    Feasible_Water_Conservation.Projection = ET.Projection
    Feasible_Water_Conservation.GeoTransform = ET.GeoTransform
    Feasible_Water_Conservation.Ordinal_time = ET.Ordinal_time
    Feasible_Water_Conservation.Size = Feasible_Water_Conservation_Data.shape
    Feasible_Water_Conservation.Variable = "Feasible Water Conservation"
    Feasible_Water_Conservation.Unit = "mm-dekad-1"       

    del Feasible_Water_Conservation_Data
    
    Feasible_Water_Conservation.Save_As_Tiff(os.path.join(output_folder_L3, "Feasible_Water_Conservation"))
    '''
    #################################### Calculate Non Beneficial Water Losses ###################################
    Non_Beneficial_Water_Losses_Data = (E.Data +
                                        I.Data) * Days_in_Dekads[:, None, None]

    # Write in DataCube
    Non_Beneficial_Water_Losses = DataCube.Rasterdata_Empty()
    Non_Beneficial_Water_Losses.Data = Non_Beneficial_Water_Losses_Data * MASK
    Non_Beneficial_Water_Losses.Projection = ET.Projection
    Non_Beneficial_Water_Losses.GeoTransform = ET.GeoTransform
    Non_Beneficial_Water_Losses.Ordinal_time = ET.Ordinal_time
    Non_Beneficial_Water_Losses.Size = Non_Beneficial_Water_Losses_Data.shape
    Non_Beneficial_Water_Losses.Variable = "Non Beneficial Water Losses"
    Non_Beneficial_Water_Losses.Unit = "mm-dekad-1"

    del Non_Beneficial_Water_Losses_Data

    Non_Beneficial_Water_Losses.Save_As_Tiff(
        os.path.join(output_folder_L3, "Non_Beneficial_Water_Losses"))

    ##################################### Calculate Equity ####################################

    Irrigation_MASK_Data = np.where(Irrigation.Data > threshold_irrigated, 1,
                                    np.nan)

    Soil_Moisture_Irrigated = Soil_Moisture.Data * Irrigation_MASK_Data
    Equity_Soil_Moisture_Data = np.nanstd(Soil_Moisture_Irrigated, axis=(
        1, 2)) / np.nanmean(Soil_Moisture_Irrigated, axis=(1, 2))
    Equity_Soil_Moisture_Data_Map = np.where(
        Irrigation_MASK_Data == 1, Equity_Soil_Moisture_Data[:, None, None],
        np.nan)

    # Write in DataCube
    Equity_Soil_Moisture = DataCube.Rasterdata_Empty()
    Equity_Soil_Moisture.Data = Equity_Soil_Moisture_Data_Map * MASK
    Equity_Soil_Moisture.Projection = ET.Projection
    Equity_Soil_Moisture.GeoTransform = ET.GeoTransform
    Equity_Soil_Moisture.Ordinal_time = ET.Ordinal_time
    Equity_Soil_Moisture.Size = Equity_Soil_Moisture_Data_Map.shape
    Equity_Soil_Moisture.Variable = "Equity Soil Moisture"
    Equity_Soil_Moisture.Unit = "-"

    del Equity_Soil_Moisture_Data_Map

    Equity_Soil_Moisture.Save_As_Tiff(
        os.path.join(output_folder_L3, "Equity_Soil_Moisture"))

    ##################################### Calculate Reliability #####################################
    Soil_Moisture_Season = np.where(np.isnan(ETcum.Data), np.nan,
                                    Soil_Moisture.Data)
    Reliability_Soil_Moisture_Data = np.ones(
        [Total_years, ET.Size[1], ET.Size[2]]) * np.nan
    for i in range(0, Total_years):
        Start = int(i * 36)
        End = int(Start + 36)
        Reliability_Soil_Moisture_Data[i, :, :] = np.nanstd(
            Soil_Moisture_Season[Start:End, :, :], axis=0) / np.nanmean(
                Soil_Moisture_Season[Start:End, :, :], axis=0)

    # Write in DataCube
    Reliability_Soil_Moisture = DataCube.Rasterdata_Empty()
    Reliability_Soil_Moisture.Data = Reliability_Soil_Moisture_Data * MASK
    Reliability_Soil_Moisture.Projection = ET.Projection
    Reliability_Soil_Moisture.GeoTransform = ET.GeoTransform
    Reliability_Soil_Moisture.Ordinal_time = np.array(
        list(map(lambda i: i.toordinal(), Dates_Years)))
    Reliability_Soil_Moisture.Size = Reliability_Soil_Moisture_Data.shape
    Reliability_Soil_Moisture.Variable = "Reliability Soil Moisture"
    Reliability_Soil_Moisture.Unit = "-"

    del Reliability_Soil_Moisture_Data

    Reliability_Soil_Moisture.Save_As_Tiff(
        os.path.join(output_folder_L3, "Reliability_Soil_Moisture"))

    return ()
Example #5
0
def main(inputs):

    # Set Variables
    Start_year_analyses = inputs["Start_year"]
    End_year_analyses = inputs["End_year"]
    output_folder = inputs["Output_folder"]
    WAPOR_LVL = inputs["WAPOR_LEVEL"]
    METEO_timestep = inputs["METEO_timestep"]

    import WaporTranslator.LEVEL_1.Input_Data as Inputs
    import WaporTranslator.LEVEL_1.DataCube as DataCube
    import WaporTranslator.LEVEL_2.Functions as Functions
    import WaporTranslator.LEVEL_3.Food_Security.LEVEL_3_Calc_Food_Security as L3_Food

    # Do not show non relevant warnings
    warnings.filterwarnings("ignore")
    warnings.filterwarnings("ignore", category=FutureWarning)
    warnings.filterwarnings("ignore", category=RuntimeWarning)

    # Define dates
    Dates = Functions.Get_Dekads(Start_year_analyses, End_year_analyses)

    # Get path and formats
    Paths = Inputs.Input_Paths()
    Formats = Inputs.Input_Formats()
    Conversions = Inputs.Input_Conversions()

    # Set example file
    example_file = os.path.join(output_folder, "LEVEL_1", "MASK", "MASK.tif")

    # Open Mask
    dest_mask = gdal.Open(example_file)
    MASK = dest_mask.GetRasterBand(1).ReadAsArray()

    # Define output folder LEVEL 3
    output_folder_L3 = os.path.join(output_folder, "LEVEL_3", "Climate_Smart")
    if not os.path.exists(output_folder_L3):
        os.makedirs(output_folder_L3)

    ################################# Dynamic maps #################################
    ET = DataCube.Rasterdata_tiffs(os.path.join(output_folder,
                                                str(Paths.ET) % WAPOR_LVL),
                                   str(Formats.ET) % WAPOR_LVL,
                                   Dates,
                                   Conversion=Conversions.ET,
                                   Example_Data=example_file,
                                   Mask_Data=example_file,
                                   gap_filling=1,
                                   reprojection_type=2,
                                   Variable='ET',
                                   Product='WAPOR',
                                   Unit='mm/day')
    NPP = DataCube.Rasterdata_tiffs(os.path.join(output_folder,
                                                 str(Paths.NPP) % WAPOR_LVL),
                                    str(Formats.NPP) % WAPOR_LVL,
                                    Dates,
                                    Conversion=Conversions.NPP,
                                    Example_Data=example_file,
                                    Mask_Data=example_file,
                                    gap_filling=1,
                                    reprojection_type=2,
                                    Variable='NPP',
                                    Product='WAPOR',
                                    Unit='g/m2/d')
    CropType = DataCube.Rasterdata_tiffs(os.path.join(output_folder,
                                                      Paths.LU_END),
                                         Formats.LU_END,
                                         Dates,
                                         Conversion=Conversions.LU_END,
                                         Variable='LU_END',
                                         Product='',
                                         Unit='-')
    CropSeason = DataCube.Rasterdata_tiffs(os.path.join(
        output_folder, Paths.CropSeason),
                                           Formats.CropSeason,
                                           Dates,
                                           Conversion=Conversions.CropSeason,
                                           Variable='CropSeason',
                                           Product='',
                                           Unit='-')
    Fractional_Vegetation_Cover = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.Fractional_Vegetation_Cover),
        Formats.Fractional_Vegetation_Cover,
        Dates,
        Conversion=Conversions.Fractional_Vegetation_Cover,
        Variable='Fractional Vegetation Cover',
        Product='',
        Unit='-')
    Deep_Percolation = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.Deep_Percolation),
        Formats.Deep_Percolation,
        Dates,
        Conversion=Conversions.Deep_Percolation,
        Variable='Deep Percolation',
        Product='',
        Unit='mm/decade')
    Surface_Runoff_P = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.Surface_Runoff_P),
        Formats.Surface_Runoff_P,
        Dates,
        Conversion=Conversions.Surface_Runoff_P,
        Variable='Surface Runoff Precipitation',
        Product='',
        Unit='mm/decade')
    Net_Radiation = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.Net_Radiation),
        Formats.Net_Radiation,
        Dates,
        Conversion=Conversions.Net_Radiation,
        Variable='Net Radiation',
        Product='',
        Unit='W/m2')
    Evaporative_Fraction = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.EF),
        Formats.EF,
        Dates,
        Conversion=Conversions.EF,
        Variable='Evaporative Fraction',
        Product='',
        Unit='-')
    if METEO_timestep == "Daily":
        Dates_D = list(
            pd.date_range("%s-01-01" % Start_year_analyses,
                          "%s-12-31" % End_year_analyses,
                          freq="D"))
        Wind_daily = DataCube.Rasterdata_tiffs(os.path.join(
            output_folder, Paths.Wind),
                                               Formats.Wind,
                                               Dates_D,
                                               Conversion=Conversions.Wind,
                                               Example_Data=example_file,
                                               Mask_Data=example_file,
                                               gap_filling=1,
                                               reprojection_type=2,
                                               Variable='Wind Speed',
                                               Product='',
                                               Unit='m/s')
        Wind = Functions.Calc_Dekads_from_Daily(Wind_daily, flux_state="state")

    if METEO_timestep == "Monthly":
        Dates_MS = list(
            pd.date_range("%s-01-01" % Start_year_analyses,
                          "%s-12-31" % End_year_analyses,
                          freq="MS"))
        Wind_monthly = DataCube.Rasterdata_tiffs(
            os.path.join(output_folder, Paths.Wind_monthly),
            Formats.Wind_monthly,
            Dates_MS,
            Conversion=Conversions.Wind_monthly,
            Example_Data=example_file,
            Mask_Data=example_file,
            gap_filling=1,
            reprojection_type=2,
            Variable='Wind Speed',
            Product='',
            Unit='m/s')
        Wind = Functions.Calc_Dekads_from_Monthly(Wind_monthly)

    ################################# Static maps #################################
    Soil_Organic_Carbon_Stock2 = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.SOCS),
        Formats.SOCS.format(level=2),
        Dates=None,
        Conversion=Conversions.SOCS,
        Example_Data=example_file,
        Mask_Data=example_file,
        gap_filling=1,
        reprojection_type=2,
        Variable='Soil Organic Carbon Stock level 2',
        Product='',
        Unit='ton/ha')
    Soil_Organic_Carbon_Stock3 = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.SOCS),
        Formats.SOCS.format(level=3),
        Dates=None,
        Conversion=Conversions.SOCS,
        Example_Data=example_file,
        Mask_Data=example_file,
        gap_filling=1,
        reprojection_type=2,
        Variable='Soil Organic Carbon Stock level 2',
        Product='',
        Unit='ton/ha')
    Soil_Organic_Carbon_Stock4 = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.SOCS),
        Formats.SOCS.format(level=4),
        Dates=None,
        Conversion=Conversions.SOCS,
        Example_Data=example_file,
        Mask_Data=example_file,
        gap_filling=1,
        reprojection_type=2,
        Variable='Soil Organic Carbon Stock level 2',
        Product='',
        Unit='ton/ha')
    Soil_Organic_Carbon_Content1 = DataCube.Rasterdata_tiffs(
        os.path.join(output_folder, Paths.SOCC),
        Formats.SOCC.format(level=1),
        Dates=None,
        Conversion=Conversions.SOCC,
        Example_Data=example_file,
        Mask_Data=example_file,
        gap_filling=1,
        reprojection_type=2,
        Variable='Soil Organic Carbon Content level 1',
        Product='',
        Unit='gr/kg')
    PH10 = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.PH10),
                                     Formats.PH10.format(level=1),
                                     Dates=None,
                                     Conversion=Conversions.PH10,
                                     Example_Data=example_file,
                                     Mask_Data=example_file,
                                     gap_filling=1,
                                     reprojection_type=2,
                                     Variable='PH10 for level 1',
                                     Product='',
                                     Unit='ton/ha')
    Clay = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.Clay),
                                     Formats.Clay.format(level=6),
                                     Dates=None,
                                     Conversion=Conversions.Clay,
                                     Example_Data=example_file,
                                     Mask_Data=example_file,
                                     reprojection_type=2,
                                     Variable='Clay',
                                     Product='SoilGrids',
                                     Unit='Percentage')
    Silt = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.Silt),
                                     Formats.Silt.format(level=6),
                                     Dates=None,
                                     Conversion=Conversions.Silt,
                                     Example_Data=example_file,
                                     Mask_Data=example_file,
                                     reprojection_type=2,
                                     Variable='Silt',
                                     Product='SoilGrids',
                                     Unit='Percentage')
    Sand = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.Sand),
                                     Formats.Sand.format(level=6),
                                     Dates=None,
                                     Conversion=Conversions.Sand,
                                     Example_Data=example_file,
                                     Mask_Data=example_file,
                                     reprojection_type=2,
                                     Variable='Sand',
                                     Product='SoilGrids',
                                     Unit='Percentage')
    DEM = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.DEM),
                                    Formats.DEM,
                                    Dates=None,
                                    Conversion=Conversions.DEM,
                                    Example_Data=example_file,
                                    Mask_Data=example_file,
                                    reprojection_type=2,
                                    Variable='DEM',
                                    Product='SRTM',
                                    Unit='m')

    ######################## Calculate days in each dekads #################################
    Days_in_Dekads = np.append(ET.Ordinal_time[1:] - ET.Ordinal_time[:-1], 11)

    ################################# Calculate Crop Season and LU #################################
    Season_Type = L3_Food.Calc_Crops(CropType, CropSeason, MASK)

    ################################# Calculate Carbon Root Zone  #################################
    # Calculate Carbon Root Zone Cropland
    Carbon_Root_Zone_Cropland = (Soil_Organic_Carbon_Stock2.Data +
                                 Soil_Organic_Carbon_Stock3.Data +
                                 Soil_Organic_Carbon_Stock4.Data) * 1000

    # Calculate Carbon Root Zone Pasture
    Carbon_Root_Zone_Pasture = (Soil_Organic_Carbon_Stock2.Data +
                                Soil_Organic_Carbon_Stock3.Data) * 1000

    # Carbon Root Zone
    Carbon_Root_Zone_Data = np.where(Season_Type.Data == 5,
                                     Carbon_Root_Zone_Pasture[None, :, :],
                                     Carbon_Root_Zone_Cropland[None, :, :])

    # Write in DataCube
    Carbon_Root_Zone = DataCube.Rasterdata_Empty()
    Carbon_Root_Zone.Data = Carbon_Root_Zone_Data * MASK
    Carbon_Root_Zone.Projection = ET.Projection
    Carbon_Root_Zone.GeoTransform = ET.GeoTransform
    Carbon_Root_Zone.Ordinal_time = ET.Ordinal_time
    Carbon_Root_Zone.Size = Carbon_Root_Zone_Data.shape
    Carbon_Root_Zone.Variable = "Carbon Root Zone"
    Carbon_Root_Zone.Unit = "kg-ha-1"

    del Carbon_Root_Zone_Data

    Carbon_Root_Zone.Save_As_Tiff(
        os.path.join(output_folder_L3, "Carbon_Root_Zone"))

    ################################# Calculate Carbon Sequestration #################################
    # Calculate Sequestration Cropland
    Carbon_Sequestration_Cropland = 10 * NPP.Data * (
        1 - 4 / (4 + 1)) * Days_in_Dekads[:, None, None] * 0.3

    # Calculate Sequestration Pasture
    Carbon_Sequestration_Pasture = 10 * NPP.Data * (
        1 - 1.5 / (1.5 + 1)) * Days_in_Dekads[:, None, None] * 0.7

    # Carbon Root Zone
    Carbon_Sequestration_Data = np.where(Season_Type.Data == 5,
                                         Carbon_Sequestration_Pasture,
                                         Carbon_Sequestration_Cropland)

    # Write in DataCube
    Carbon_Sequestration = DataCube.Rasterdata_Empty()
    Carbon_Sequestration.Data = Carbon_Sequestration_Data * MASK
    Carbon_Sequestration.Projection = ET.Projection
    Carbon_Sequestration.GeoTransform = ET.GeoTransform
    Carbon_Sequestration.Ordinal_time = ET.Ordinal_time
    Carbon_Sequestration.Size = Carbon_Sequestration_Data.shape
    Carbon_Sequestration.Variable = "Carbon Sequestration"
    Carbon_Sequestration.Unit = "kg-ha-1-dekad-1"

    del Carbon_Sequestration_Data

    Carbon_Sequestration.Save_As_Tiff(
        os.path.join(output_folder_L3, "Carbon_Sequestration"))

    ################################# Calculate Climatic Cooling #################################
    Climatic_Cooling_Data = (
        (0.7 * Net_Radiation.Data -
         (1 - Evaporative_Fraction.Data) * Net_Radiation.Data) *
        (208 / Wind.Data)) / (1.15 * 1004)

    # Write in DataCube
    Climatic_Cooling = DataCube.Rasterdata_Empty()
    Climatic_Cooling.Data = Climatic_Cooling_Data * MASK
    Climatic_Cooling.Projection = ET.Projection
    Climatic_Cooling.GeoTransform = ET.GeoTransform
    Climatic_Cooling.Ordinal_time = ET.Ordinal_time
    Climatic_Cooling.Size = Climatic_Cooling_Data.shape
    Climatic_Cooling.Variable = "Climatic Cooling"
    Climatic_Cooling.Unit = "Celcius-dekad-1"

    del Climatic_Cooling_Data

    Climatic_Cooling.Save_As_Tiff(
        os.path.join(output_folder_L3, "Climatic_Cooling"))

    ################################# Calculate Water Generation #################################
    Water_Generation_Data = (Surface_Runoff_P.Data +
                             Deep_Percolation.Data) * 10

    # Write in DataCube
    Water_Generation = DataCube.Rasterdata_Empty()
    Water_Generation.Data = Water_Generation_Data * MASK
    Water_Generation.Projection = ET.Projection
    Water_Generation.GeoTransform = ET.GeoTransform
    Water_Generation.Ordinal_time = ET.Ordinal_time
    Water_Generation.Size = Water_Generation_Data.shape
    Water_Generation.Variable = "Water Generation"
    Water_Generation.Unit = "m3-ha-1-dekad-1"

    del Water_Generation_Data

    Water_Generation.Save_As_Tiff(
        os.path.join(output_folder_L3, "Water_Generation"))

    ################################# Calculate Soil Erodibility #################################
    Soil_Erodibility_Data = (0.043 * PH10.Data + 0.062 /
                             (Soil_Organic_Carbon_Content1.Data * 10) +
                             0.0082 * Sand.Data -
                             0.0062 * Clay.Data) * Silt.Data / 10

    # Write in DataCube
    Soil_Erodibility = DataCube.Rasterdata_Empty()
    Soil_Erodibility.Data = Soil_Erodibility_Data * MASK
    Soil_Erodibility.Projection = ET.Projection
    Soil_Erodibility.GeoTransform = ET.GeoTransform
    Soil_Erodibility.Ordinal_time = None
    Soil_Erodibility.Size = Soil_Erodibility_Data.shape
    Soil_Erodibility.Variable = "Soil Erodibility"
    Soil_Erodibility.Unit = "-"

    del Soil_Erodibility_Data

    Soil_Erodibility.Save_As_Tiff(
        os.path.join(output_folder_L3, "Soil_Erodibility"))

    ################################# Calculate Combating Soil Erosion #################################
    Combating_Soil_Erosion_Data = 50 * Water_Generation.Data * Soil_Erodibility.Data * 1 * DEM.Data[
        None, :, :] * Fractional_Vegetation_Cover.Data * 0.5

    # Write in DataCube
    Combating_Soil_Erosion = DataCube.Rasterdata_Empty()
    Combating_Soil_Erosion.Data = Combating_Soil_Erosion_Data * MASK
    Combating_Soil_Erosion.Projection = ET.Projection
    Combating_Soil_Erosion.GeoTransform = ET.GeoTransform
    Combating_Soil_Erosion.Ordinal_time = ET.Ordinal_time
    Combating_Soil_Erosion.Size = Combating_Soil_Erosion_Data.shape
    Combating_Soil_Erosion.Variable = "Combating Soil Erosion"
    Combating_Soil_Erosion.Unit = "kg-ha-1-dekad-1"

    del Combating_Soil_Erosion_Data

    Combating_Soil_Erosion.Save_As_Tiff(
        os.path.join(output_folder_L3, "Combating_Soil_Erosion"))

    ################################# Calculate Sustaining Rainfall #################################
    Sustaining_Rainfall_Data = 0.2 * ET.Data * Days_in_Dekads[:, None, None]

    # Write in DataCube
    Sustaining_Rainfall = DataCube.Rasterdata_Empty()
    Sustaining_Rainfall.Data = Sustaining_Rainfall_Data * MASK
    Sustaining_Rainfall.Projection = ET.Projection
    Sustaining_Rainfall.GeoTransform = ET.GeoTransform
    Sustaining_Rainfall.Ordinal_time = ET.Ordinal_time
    Sustaining_Rainfall.Size = Sustaining_Rainfall_Data.shape
    Sustaining_Rainfall.Variable = "Sustaining Rainfall"
    Sustaining_Rainfall.Unit = "m3-ha-1-dekad-1"

    del Sustaining_Rainfall_Data

    Sustaining_Rainfall.Save_As_Tiff(
        os.path.join(output_folder_L3, "Sustaining_Rainfall"))

    ################################# Calculate NPP Change In Time #################################

    # Set time
    T = np.arange(len(Dates))

    # Calculate trend
    trend_dekad = (
        (np.sum(np.where(np.isnan(NPP.Data), 0, 1), axis=0) *
         np.nansum(NPP.Data * T[:, None, None], axis=0)) -
        (np.nansum(NPP.Data, axis=0) * np.nansum(T[:, None, None], axis=0))
    ) / ((np.sum(np.where(np.isnan(NPP.Data), 0, 1), axis=0) *
          np.nansum(T[:, None, None] * T[:, None, None], axis=0)) -
         (np.nansum(T[:, None, None], axis=0) *
          np.nansum(T[:, None, None], axis=0)))
    trend_year = trend_dekad * 36
    NPP_Change_In_Time_Data = trend_year / np.nanmean(NPP.Data, axis=0) * 100

    # Write in DataCube
    NPP_Change_In_Time = DataCube.Rasterdata_Empty()
    NPP_Change_In_Time.Data = NPP_Change_In_Time_Data * MASK
    NPP_Change_In_Time.Projection = ET.Projection
    NPP_Change_In_Time.GeoTransform = ET.GeoTransform
    NPP_Change_In_Time.Ordinal_time = None
    NPP_Change_In_Time.Size = NPP_Change_In_Time_Data.shape
    NPP_Change_In_Time.Variable = "NPP Change In Time Data"
    NPP_Change_In_Time.Unit = "Percentage-year-1"

    del NPP_Change_In_Time_Data

    NPP_Change_In_Time.Save_As_Tiff(
        os.path.join(output_folder_L3, "NPP_Change_In_Time"))

    return ()
def main(inputs):  

    # Set Variables
    Start_year_analyses = inputs["Start_year"]
    End_year_analyses = inputs["End_year"]
    output_folder = inputs["Output_folder"]  
    WAPOR_LVL = inputs["WAPOR_LEVEL"]   

    # Do not show non relevant warnings
    warnings.filterwarnings("ignore")
    warnings.filterwarnings("ignore", category=FutureWarning)
    warnings.filterwarnings("ignore", category=RuntimeWarning)
    
    # Define dates
    Dates = Functions.Get_Dekads(Start_year_analyses, End_year_analyses)
    
    # Get path and formats
    Paths = Inputs.Input_Paths()
    Formats = Inputs.Input_Formats()
    Conversions = Inputs.Input_Conversions()
    
    # Set example file
    example_file = os.path.join(output_folder, "LEVEL_1", "MASK", "MASK.tif")
    
    # Open Mask
    dest_mask = gdal.Open(example_file)
    MASK = dest_mask.GetRasterBand(1).ReadAsArray()
    
    # Define output folder LEVEL 3
    output_folder_L3 = os.path.join(output_folder, "LEVEL_3", "Drought")
    if not os.path.exists(output_folder_L3):
        os.makedirs(output_folder_L3)
    
    ################################# Dynamic maps #################################
    ET = DataCube.Rasterdata_tiffs(os.path.join(output_folder, str(Paths.ET) %WAPOR_LVL), str(Formats.ET) %WAPOR_LVL, Dates, Conversion = Conversions.ET, Example_Data = example_file, Mask_Data = example_file, gap_filling = 1, reprojection_type = 2, Variable = 'ET', Product = 'WAPOR', Unit = 'mm/day')
    Pcum = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.Cumulative_P), Formats.Cumulative_P, Dates, Conversion = Conversions.Cumulative_P, Variable = 'Pcum', Product = '', Unit = 'mm')
    ETcum = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.Cumulative_ET), Formats.Cumulative_ET, Dates, Conversion = Conversions.Cumulative_ET, Variable = 'ETcum', Product = '', Unit = 'mm')
    Soil_Moisture = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.Soil_Moisture), Formats.Soil_Moisture, Dates, Conversion = Conversions.Soil_Moisture, Variable = 'Soil Moisture', Product = '', Unit = 'cm3/cm3')
    Crop_Water_Requirement = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.Crop_Water_Requirement), Formats.Crop_Water_Requirement, Dates, Conversion = Conversions.Crop_Water_Requirement, Example_Data = example_file, Mask_Data = example_file, gap_filling = 1, reprojection_type = 2, Variable = 'Crop Water Requirement', Product = '', Unit = 'mm/decade')
    Soil_Moisture_Long_Term = DataCube.Rasterdata_tiffs(os.path.join(output_folder, Paths.Soil_Moisture_Long_Term), Formats.Soil_Moisture_Long_Term, Dates, Conversion = Conversions.Soil_Moisture_Long_Term, Example_Data = example_file, Mask_Data = example_file, gap_filling = 1, reprojection_type = 2, Variable = 'Long Term Soil Moisture', Product = '', Unit = 'cm3/cm3')
   
    ######################## Calculate days in each dekads #################################
    Days_in_Dekads = np.append(ET.Ordinal_time[1:] - ET.Ordinal_time[:-1], 11)    

    ######################## Calculate Evapotranspiration deficit ########################
    ET_Deficit_Data = Crop_Water_Requirement.Data - ET.Data * Days_in_Dekads[:, None, None]

    # Write in DataCube
    ET_Deficit = DataCube.Rasterdata_Empty()
    ET_Deficit.Data = ET_Deficit_Data * MASK
    ET_Deficit.Projection = ET.Projection
    ET_Deficit.GeoTransform = ET.GeoTransform
    ET_Deficit.Ordinal_time = ET.Ordinal_time
    ET_Deficit.Size = ET_Deficit_Data.shape
    ET_Deficit.Variable = "Evapotranspiration Deficit"
    ET_Deficit.Unit = "mm-dekad-1"       

    del ET_Deficit_Data
    
    ET_Deficit.Save_As_Tiff(os.path.join(output_folder_L3, "ET_Deficit"))     
    
    ######################## Calculate Accumulated Rainfall Deficit over Season ########################
    Accumulated_Rainfall_Deficit_Data = Pcum.Data - ETcum.Data

    # Write in DataCube
    Accumulated_Rainfall_Deficit = DataCube.Rasterdata_Empty()
    Accumulated_Rainfall_Deficit.Data = Accumulated_Rainfall_Deficit_Data * MASK
    Accumulated_Rainfall_Deficit.Projection = ET.Projection
    Accumulated_Rainfall_Deficit.GeoTransform = ET.GeoTransform
    Accumulated_Rainfall_Deficit.Ordinal_time = ET.Ordinal_time
    Accumulated_Rainfall_Deficit.Size = Accumulated_Rainfall_Deficit_Data.shape
    Accumulated_Rainfall_Deficit.Variable = "Accumulated Rainfall Deficit"
    Accumulated_Rainfall_Deficit.Unit = "mm"       

    del Accumulated_Rainfall_Deficit_Data
    
    Accumulated_Rainfall_Deficit.Save_As_Tiff(os.path.join(output_folder_L3, "Accumulated_Rainfall_Deficit"))     
    
    ######################## Calculate Soil Moisture Anomaly ########################
    Soil_Moisture_Anomaly_Data = (Soil_Moisture.Data - Soil_Moisture_Long_Term.Data)/Soil_Moisture_Long_Term.Data * 100 
 
    # Write in DataCube
    Soil_Moisture_Anomaly = DataCube.Rasterdata_Empty()
    Soil_Moisture_Anomaly.Data = Soil_Moisture_Anomaly_Data * MASK
    Soil_Moisture_Anomaly.Projection = ET.Projection
    Soil_Moisture_Anomaly.GeoTransform = ET.GeoTransform
    Soil_Moisture_Anomaly.Ordinal_time = ET.Ordinal_time
    Soil_Moisture_Anomaly.Size = Soil_Moisture_Anomaly_Data.shape
    Soil_Moisture_Anomaly.Variable = "Soil Moisture Anomaly"
    Soil_Moisture_Anomaly.Unit = "Percentage"       

    del Soil_Moisture_Anomaly_Data
    
    Soil_Moisture_Anomaly.Save_As_Tiff(os.path.join(output_folder_L3, "Soil_Moisture_Anomaly"))     
        
    ######################## Calculate Lake Reservoir Level Anomaly ########################
    #Lake_Reservoir_Level_Anomaly = 
    
    ######################## Calculate Open Water Anomaly ########################
    #Open_Water_Anomaly = 
    
    ######################## Calculate Integrated Drought Alert Level ########################
    Alert_limits = Alert_dict()
    
    Integrated_Drought_Alert_Level_ET_Deficit = np.ones(ET.Size) * np.nan
    Integrated_Drought_Alert_Level_P_Deficit = np.ones(ET.Size) * np.nan    
    Integrated_Drought_Alert_Level_Soil_Anomalies = np.ones(ET.Size) * np.nan
        
    for values in Alert_limits['et_deficit'].items():
        Integrated_Drought_Alert_Level_ET_Deficit = np.where(np.logical_and(ET_Deficit.Data > values[1][0], ET_Deficit.Data <= values[1][1]), values[0], Integrated_Drought_Alert_Level_ET_Deficit)
    for values in Alert_limits['p_deficit'].items():
        Integrated_Drought_Alert_Level_P_Deficit = np.where(np.logical_and(Accumulated_Rainfall_Deficit.Data > values[1][0], Accumulated_Rainfall_Deficit.Data <= values[1][1]), values[0], Integrated_Drought_Alert_Level_P_Deficit)
    for values in Alert_limits['soil_anomalies'].items():
        Integrated_Drought_Alert_Level_Soil_Anomalies = np.where(np.logical_and(Soil_Moisture_Anomaly.Data < values[1][0], Soil_Moisture_Anomaly.Data >= values[1][1]), values[0], Integrated_Drought_Alert_Level_Soil_Anomalies)

    Integrated_Drought_Alert_Level_Data = np.nanmax(np.stack((Integrated_Drought_Alert_Level_ET_Deficit, Integrated_Drought_Alert_Level_P_Deficit, Integrated_Drought_Alert_Level_Soil_Anomalies)),axis = 0)    

    # Write in DataCube
    Integrated_Drought_Alert_Level = DataCube.Rasterdata_Empty()
    Integrated_Drought_Alert_Level.Data = Integrated_Drought_Alert_Level_Data * MASK
    Integrated_Drought_Alert_Level.Projection = ET.Projection
    Integrated_Drought_Alert_Level.GeoTransform = ET.GeoTransform
    Integrated_Drought_Alert_Level.Ordinal_time = ET.Ordinal_time
    Integrated_Drought_Alert_Level.Size = Integrated_Drought_Alert_Level_Data.shape
    Integrated_Drought_Alert_Level.Variable = "Integrated Drought Alert Level"
    Integrated_Drought_Alert_Level.Unit = "Percentage"       

    del Integrated_Drought_Alert_Level_Data
    
    Integrated_Drought_Alert_Level.Save_As_Tiff(os.path.join(output_folder_L3, "Integrated_Drought_Alert_Level"))   
     
    return()