Ejemplo n.º 1
0
    def downscalePrecipitation(self,
                               currTimeStep,
                               useFactor=True,
                               minCorrelationCriteria=0.85):

        preSlope = 0.001 * vos.netcdf2PCRobjClone(\
                           self.precipLapseRateNC, 'precipitation',\
                           currTimeStep.month, useDoy = "Yes",\
                           cloneMapFileName=self.cloneMap,\
                           LatitudeLongitude = True)
        preSlope = pcr.cover(preSlope, 0.0)
        preSlope = pcr.max(0., preSlope)

        preCriteria = vos.netcdf2PCRobjClone(\
                     self.precipitCorrelNC, 'precipitation',\
                     currTimeStep.month, useDoy = "Yes",\
                     cloneMapFileName=self.cloneMap,\
                     LatitudeLongitude = True)
        preSlope = pcr.ifthenelse(preCriteria > minCorrelationCriteria,\
                   preSlope, 0.0)
        preSlope = pcr.cover(preSlope, 0.0)

        if useFactor == True:
            factor = pcr.max(0.,
                             self.precipitation + preSlope * self.anomalyDEM)
            factor = factor / \
                     pcr.areaaverage(factor, self.meteoDownscaleIds)
            factor = pcr.cover(factor, 1.0)
            self.precipitation = factor * self.precipitation
        else:
            self.precipitation = self.precipitation + preSlope * self.anomalyDEM

        self.precipitation = pcr.max(0.0, self.precipitation)
Ejemplo n.º 2
0
    def downscaleTemperature(self,
                             currTimeStep,
                             useFactor=False,
                             maxCorrelationCriteria=-0.75,
                             zeroCelciusInKelvin=273.15):

        tmpSlope = 1.000 * vos.netcdf2PCRobjClone(\
                           self.temperLapseRateNC, 'temperature',\
                           currTimeStep.month, useDoy = "Yes",\
                           cloneMapFileName=self.cloneMap,\
                           LatitudeLongitude = True)
        tmpSlope = pcr.min(0., tmpSlope)  # must be negative
        tmpCriteria = vos.netcdf2PCRobjClone(\
                      self.temperatCorrelNC, 'temperature',\
                      currTimeStep.month, useDoy = "Yes",\
                      cloneMapFileName=self.cloneMap,\
                      LatitudeLongitude = True)
        tmpSlope = pcr.ifthenelse(tmpCriteria < maxCorrelationCriteria,\
                   tmpSlope, 0.0)
        tmpSlope = pcr.cover(tmpSlope, 0.0)

        if useFactor == True:
            temperatureInKelvin = self.temperature + zeroCelciusInKelvin
            factor = pcr.max(0.0,
                             temperatureInKelvin + tmpSlope * self.anomalyDEM)
            factor = factor / \
                     pcr.areaaverage(factor, self.meteoDownscaleIds)
            factor = pcr.cover(factor, 1.0)
            self.temperature = factor * temperatureInKelvin - zeroCelciusInKelvin
        else:
            self.temperature = self.temperature + tmpSlope * self.anomalyDEM
    def dynamic(self):
        
        # re-calculate model time using current pcraster timestep value
        self.modelTime.update(self.currentTimeStep())

        # at the end of every month:
        # - aggregate/average the value at basin scale:
        # - then report it to the netcdf file:
        if self.modelTime.endMonth == True:

            # values from grace:
            grace_value = pcr.cover(vos.netcdf2PCRobjClone(\
                          self.output_files['one_degree_tws_month_anomaly']['grace'],\
                          "lwe_thickness",\
                          str(self.modelTime.fulldate), "mid-month",\
                          self.input_files["basin30minmap"]), 0.0)
            #
            basin_grace = pcr.areatotal(self.cell_area * grace_value, self.catchment)/\
                          pcr.areatotal(self.cell_area, self.catchment)

            # values from pcr-globwb simulation:
            model_value = pcr.cover(vos.netcdf2PCRobjClone(\
                          self.output_files['one_degree_tws_month_anomaly']['model'],\
                          "pcrglobwb_tws",\
                          str(self.modelTime.fulldate), "end-month",\
                          self.input_files["basin30minmap"]), 0.0)
            #
            basin_model = pcr.areatotal(self.cell_area * model_value, self.catchment)/\
                          pcr.areatotal(self.cell_area, self.catchment)

            # reporting
            timeStamp = datetime.datetime(self.modelTime.year,\
                                          self.modelTime.month,\
                                          self.modelTime.day,0)
            # write grace 
            self.output.data2NetCDF(self.output_files["basinscale_tws_month_anomaly"]['grace'],\
                                    "lwe_thickness",\
                                    pcr.pcr2numpy(basin_grace,vos.MV),\
                                    timeStamp)
            # write model
            self.output.data2NetCDF(self.output_files["basinscale_tws_month_anomaly"]['model'],\
                                    "pcrglobwb_tws",\
                                    pcr.pcr2numpy(basin_model,vos.MV),\
                                    timeStamp)

        # at the last dynamic time step 
        # - prepare annual anomaly time series
        # - evaluate the pcr-globwb model results to grace time series (monthly and annual)
        if self.modelTime.currTime == self.modelTime.endTime:

            # prepare annual anomaly time series
            self.prepare_annual_anomaly()

            # evaluate the pcr-globwb model results to grace time series 
            # (monthly & annual resolution - basin & one degree scale)
            self.evaluate_to_grace_data()
    def dynamic(self):
        
        # re-calculate current model time using current pcraster timestep value
        self.modelTime.update(self.currentTimeStep())

        # open input data 
        referencePotET = vos.netcdf2PCRobjClone(\
                             self.input_files['referencePotET']['file_name'], \
                             self.input_files['referencePotET']['variable_name'], \
                             str(self.modelTime.fulldate), \
                             useDoy = None, \
                             cloneMapFileName = self.cloneMapFileName)
        cropKC = {}
        for lc_type in ["forest", "grassland", "irrPaddy", "irrNonPaddy"]:
            cropKC[lc_type] = vos.netcdf2PCRobjClone(\
                                  self.input_files['cropKC'][lc_type], \
                                  self.input_files['cropKC']['variable_name'], \
                                  str(self.modelTime.fulldate), 
                                  useDoy = None,
                                  cloneMapFileName = self.cloneMapFileName)
               
        # calculate
        potential_evaporation = {}
        for lc_type in ["forest", "grassland", "irrPaddy", "irrNonPaddy"]:
            potential_evaporation[lc_type] = referencePotET * cropKC[lc_type]
        
        # reporting for daily values
        timeStamp = datetime.datetime(self.modelTime.year,\
                                      self.modelTime.month,\
                                      self.modelTime.day,0)
        for lc_type in ["forest", "grassland", "irrPaddy", "irrNonPaddy"]:
            file_name = self.output['folder'] + "/daily_potential_evaporation_" + self.variable_unit + "_" + lc_type + ".nc"
            self.netcdf_report.data2NetCDF(file_name,\
                                           self.variable_name,\
                                           pcr.pcr2numpy(potential_evaporation[lc_type], vos.MV),\
                                           timeStamp)

        # reporting for monthly values
        # - reset at the beginning of the month:
        if self.modelTime.isFirstDayOfMonth:
            for lc_type in ["forest", "grassland", "irrPaddy", "irrNonPaddy"]:
                self.monthly_accumulator[lc_type] = pcr.scalar(0.0)
        # - accumulate until the last day of the month:
        for lc_type in ["forest", "grassland", "irrPaddy", "irrNonPaddy"]:
            self.monthly_accumulator[lc_type] = self.monthly_accumulator[lc_type] + potential_evaporation[lc_type]
        if self.modelTime.endMonth:
            for lc_type in ["forest", "grassland", "irrPaddy", "irrNonPaddy"]:
                file_name = self.output['folder'] + "/monthly_potential_evaporation_" + self.variable_unit + "_" + lc_type + ".nc"
                
                print file_name
                
                self.netcdf_report.data2NetCDF(file_name,\
                                               self.variable_name,\
                                               pcr.pcr2numpy(self.monthly_accumulator[lc_type]/calendar.monthrange(self.modelTime.year, self.modelTime.month)[1], vos.MV),\
                                               timeStamp)
Ejemplo n.º 5
0
    def dynamic(self):

        # re-calculate current model time using current pcraster timestep value
        self.modelTime.update(self.currentTimeStep())

        # processing done only at the last day of the month
        if self.modelTime.isLastDayOfYear():

            logger.info("Reading runoff for time %s", self.modelTime.currTime)
            annual_input_file = self.input_file %(str(self.modelTime.currTime.year), \
                                                  str(self.modelTime.currTime.year))
            self.cell_value = vos.netcdf2PCRobjClone(annual_input_file, "automatic", \
                                                     str(self.modelTime.fulldate), \
                                                     useDoy = None, \
                                                     cloneMapFileName = self.clonemap_file_name, \
                                                     LatitudeLongitude = True)
            self.cell_value = pcr.cover(self.total_runoff, 0.0)

            logger.info("Calculating basin value for time %s",
                        self.modelTime.currTime)
            self.basin_value = pcr.catchmenttotal(
                self.total_runoff * self.cell_area,
                self.ldd_network) / self.basin_area

            # reporting
            # - time stamp for reporting
            timeStamp = datetime.datetime(self.modelTime.year,\
                                          self.modelTime.month,\
                                          self.modelTime.day,\
                                          0)
            logger.info("Reporting for time %s", self.modelTime.currTime)
            self.netcdf_report.data2NetCDF(self.output_file, \
                                           "total_flow", \
                                           pcr.pcr2numpy(self.total_flow, vos.MV), \
                                           timeStamp)
Ejemplo n.º 6
0
    def dynamic(self):

        # re-calculate current model time using current pcraster timestep value
        self.modelTime.update(self.currentTimeStep())

        # perform the operation only at the last day of the month (as the input netcdf file has a monthly resolution with the last date of the month as its time stamp)
        if self.modelTime.isLastDayOfMonth():

            self.i_month = self.i_month + 1

            # reading a netcdf file (global extent, 5 arcmin resolution):
            pcr.setclone(self.globeCloneMapFileName)
            global_pcraster_map = vos.netcdf2PCRobjClone(ncFile    = self.netcdf_input['file_name'], \
                                                         varName   = self.netcdf_input['variable_name'], \
                                                         dateInput = self.modelTime.fulldate)
            # save it to pcraster maps (still at a global extent and 5 arcmin resolution);
            # there will be two files as follows:
            # - Format 1: example file names: htop0000.001 (for the 1st time step), htop0000.002, htop0000.003, etc. ...
            pcraster_file_name = self.pcraster_output[
                'output_folder'] + "/global/" + self.pcraster_output[
                    'file_name']
            pcraster_file_name = pcr.framework.frameworkBase.generateNameT(
                pcraster_file_name, self.i_month)
            pcr.report(global_pcraster_map, pcraster_file_name)
            # - Format 2: example file names: htop_2000_01.map, htop_2000_02.map, etc.
            pcraster_file_name = self.pcraster_output[
                'output_folder'] + "/global/" + self.pcraster_output[
                    'file_name'] + "_" + self.modelTime.fulldate[0:7].replace(
                        "-", "_") + ".map"
            pcr.report(global_pcraster_map, pcraster_file_name)

            # reproject and resample it to a local coordinate system
            pcr.setclone(self.localCloneMapFileName)
            local_pcraster_map = vos.readPCRmapClone(v = pcraster_file_name, \
                                                     cloneMapFileName = self.localCloneMapFileName, \
                                                     tmpDir = self.pcraster_output['output_folder'] + "/tmp/", \
                                                     absolutePath = None,\
                                                     isLddMap = False, \
                                                     cover = None, \
                                                     isNomMap = False, \
                                                     inputEPSG  = self.inputEPSG,
                                                     outputEPSG = self.outputEPSG,
                                                     method = "near")
            # save it to pcraster maps (now already at the extent, the resolution and the coordinate system of the local model)
            # there will be two files as follows:
            # - Format 1: example file names: htop0000.001 (for the 1st time step), htop0000.002, htop0000.003, etc. ...
            pcraster_file_name = self.pcraster_output[
                'output_folder'] + "/regional/" + self.pcraster_output[
                    'file_name']
            pcraster_file_name = pcr.framework.frameworkBase.generateNameT(
                pcraster_file_name, self.i_month)
            pcr.report(local_pcraster_map, pcraster_file_name)
            # - Format 2: example file names: htop_2000_01.map, htop_2000_02.map, etc.
            pcraster_file_name = self.pcraster_output[
                'output_folder'] + "/regional/" + self.pcraster_output[
                    'file_name'] + "_" + self.modelTime.fulldate[0:7].replace(
                        "-", "_") + ".map"
            pcr.report(local_pcraster_map, pcraster_file_name)
    def dynamic(self):
        
        # update model time using the current pcraster timestep value
        self.modelTime.update(self.currentTimeStep())

        # reading gross and netto values:
        if self.modelTime.isLastDayOfMonth():

            gross_value = vos.netcdf2PCRobjClone(ncFile  = self.input_netcdf['gross_file_name'],
                                                 varName = self.input_netcdf['gross_variable_name'],
                                                 dateInput = str(self.modelTime.fulldate))

            netto_value = vos.netcdf2PCRobjClone(ncFile  = self.input_netcdf['netto_file_name'],
                                                 varName = self.input_netcdf['netto_variable_name'],
                                                 dateInput = str(self.modelTime.fulldate))
            
            # covering with zero and convert the unit to 
            gross_value = pcr.cover(gross_value, 0.0)/self.cell_area                                     
            netto_value = pcr.cover(netto_value, 0.0)/self.cell_area                                     

        # reporting
        if self.modelTime.isLastDayOfMonth():

            # put the output in a dictionary
            output = {}
            output[self.output_netcdf['gross_variable_name']] = pcr.pcr2numpy(gross_value, vos.MV)
            output[self.output_netcdf['netto_variable_name']] = pcr.pcr2numpy(netto_value, vos.MV)
            
            # time stamp 
            timeStamp = datetime.datetime(self.modelTime.year,\
                                          self.modelTime.month,\
                                          self.modelTime.day,0)
            # to netcdf 
            self.output.dataList2NetCDF(self.output_netcdf['file_name'],\
                                       [self.output_netcdf['gross_variable_name'], self.output_netcdf['netto_variable_name']],\
                                        output,\
                                        timeStamp)

        # closing the file at the end of
        if self.modelTime.isLastTimeStep(): self.output.close(self.output_netcdf['file_name'])
    def dynamic(self):
        
        # update model time using the current pcraster timestep value
        self.modelTime.update(self.currentTimeStep())

        # reading
        data_available = True
        if data_available:
            input_value = vos.netcdf2PCRobjClone(ncFile  = self.input_netcdf['file_name'],
                                                 varName = self.input_netcdf['variable_name'],
                                                 dateInput = str(self.modelTime.fulldate),
                                                 useDoy = None,
                                                 cloneMapFileName = self.clone_map_file)
            data_available = True  
        
        else:
            print "No values are available for this date: "+str(self.modelTime)
            data_available = False 
        
        if data_available: output_value = input_value

        # upscaling
        if data_available and self.resample_factor > 1.0:
        
            # upscaling using cell area
            cell_area = pcr.ifthen(pcr.defined(output_value), self.cell_area)
            output_value_in_pcraster = \
                            vos.getValDivZero(\
                            pcr.areatotal(output_value*self.cell_area, self.unique_ids),\
                            pcr.areatotal(self.cell_area, self.unique_ids), vos.smallNumber)
            
            # resample to the output clone resolution 
            output_value = vos.regridToCoarse(pcr.pcr2numpy(output_value_in_pcraster, vos.MV),
                                              self.resample_factor, "max", vos.MV)

        # reporting
        if data_available:

            # time stamp 
            timestepPCR = self.modelTime.timeStepPCR
            timeStamp = datetime.datetime(self.modelTime.year,\
                                          self.modelTime.month,\
                                          self.modelTime.day,0)
            # write to netcdf 
            self.output.data2NetCDF(self.output_netcdf['file_name'],\
                                    self.output_netcdf['variable_name'],\
                                    output_value,\
                                    timeStamp)

        # closing the file at the end of
        if self.modelTime.isLastTimeStep(): self.output.close(self.output_netcdf['file_name'])
Ejemplo n.º 9
0
    def dynamic(self):

        # re-calculate current model time using current pcraster timestep value
        self.modelTime.update(self.currentTimeStep())

        # processing done only at the last day of the month
        if self.modelTime.isLastDayOfMonth():
            
            logger.info("Reading runoff for time %s", self.modelTime.currTime)
            self.total_runoff = vos.netcdf2PCRobjClone(self.totat_runoff_input_file, "total_runoff",\
                                                       str(self.modelTime.fulldate), 
                                                       useDoy = None,
                                                       cloneMapFileName = self.clonemap_file_name,\
                                                       LatitudeLongitude = True)
            self.total_runoff = pcr.cover(self.total_runoff, 0.0)
            
            logger.info("Calculating total inflow and internal inflow for time %s", self.modelTime.currTime)
            self.total_flow    = pcr.catchmenttotal(self.total_runoff * self.cell_area, self.ldd_network)
            self.internal_flow = pcr.areatotal(self.total_runoff  * self.cell_area, self.sub_catchment)
            # - convert values to m3/s
            number_of_days_in_a_month = self.modelTime.day
            self.total_flow         = self.total_flow    / (number_of_days_in_a_month * 24. * 3600.)
            self.internal_flow      = self.internal_flow / (number_of_days_in_a_month * 24. * 3600.)
            # - limit the values to the landmask only
            self.total_flow         = pcr.ifthen(self.landmask, self.total_flow)
            self.internal_flow      = pcr.ifthen(self.landmask, self.internal_flow)
            
            logger.info("Extrapolating or time %s", self.modelTime.currTime)
            # Purpose: To avoid missing value data while being extracted by cdo command
            self.total_flow         = pcr.cover(self.total_flow,    pcr.windowmaximum(self.total_flow,    0.125)) 
            self.internal_flow      = pcr.cover(self.internal_flow, pcr.windowaverage(self.internal_flow, 0.125)) 

            # reporting 
            # - time stamp for reporting
            timeStamp = datetime.datetime(self.modelTime.year,\
                                          self.modelTime.month,\
                                          self.modelTime.day,\
                                          0)
            logger.info("Reporting for time %s", self.modelTime.currTime)
            self.netcdf_report.data2NetCDF(self.total_flow_output_file, \
                                           "total_flow", \
                                           pcr.pcr2numpy(self.total_flow, vos.MV), \
                                           timeStamp)
            self.netcdf_report.data2NetCDF(self.internal_flow_output_file, \
                                           "internal_flow", \
                                           pcr.pcr2numpy(self.internal_flow, vos.MV), \
                                           timeStamp)
Ejemplo n.º 10
0
    def dynamic(self):
        
        # re-calculate model time using current pcraster timestep value
        self.modelTime.update(self.currentTimeStep())

        # processing / calculating only at the last day of the month:
        if self.modelTime.endMonth == True:
        
            #~ # open totalWaterStorageThickness (unit: m, monthly average values) 
            #~ value_at_5min = vos.netcdf2PCRobjClone(\
                            #~ self.input_files["model_total_water_storage"],\
                            #~ "total_thickness_of_water_storage",\
                            #~ str(self.modelTime.fulldate), useDoy = "end-month")
            
            # open totalWaterStorageThickness (unit: m, monthly average values) 
            value_at_5min = vos.netcdf2PCRobjClone(\
                            self.input_files["model_total_water_storage"],\
                            self.input_files["model_total_water_storage_variable_name"],\
                            str(self.modelTime.fulldate), useDoy = "end-month")

            # upscale to one degree resolution
            value_at_1deg_but_5min_cell = \
                            vos.getValDivZero(\
                            pcr.areatotal(self.cell_area*value_at_5min,\
                                                         self.one_degree_id),\
                            pcr.areatotal(self.cell_area,self.one_degree_id),
                            vos.smallNumber)
            
            # resample from 5 arc minute cells to one degree cells
            value_at_1deg = vos.regridToCoarse(\
                            pcr.pcr2numpy(value_at_1deg_but_5min_cell,vos.MV),self.resample_factor,"max",vos.MV)
            #
            # reporting
            timestepPCR = self.modelTime.timeStepPCR
            timeStamp = datetime.datetime(self.modelTime.year,\
                                          self.modelTime.month,\
                                          self.modelTime.day,0)
            # write it to netcdf 
            self.output.data2NetCDF(self.output_files['one_degree_tws']['model'],\
                                    "pcrglobwb_tws",\
                                    value_at_1deg,\
                                    timeStamp)
    
    for iYear in range(staYear,endYear+1):

        # time stamp
        timeStamp = datetime.datetime(int(iYear),int(1),int(1),int(0))
        fulldate = '%4i-%02i-%02i' %(int(iYear),int(1),int(1))
        print fulldate

        # index for time object in the netcdf file:
        index = index + 1

        # reading values from the input netcdf files (30min)
        abstraction_volume_30min = pcr.roundup(
                                   vos.netcdf2PCRobjClone(inputDirectory+inputFiles,\
                                                          inputVarNames,
                                                          fulldate,
                                                          None,
                                                          cloneMapFileName)) * 0.001   # unit: bcm/year
        
        abstraction = pcr.cover(abstraction_volume_30min, 0.0)
        
        # use window maximum to be in the conservative side:
        window_size = 1.0
        abstraction = pcr.windowmaximum(abstraction, 1.0) 
        
        # covering the map with zero
        pcrValue = pcr.cover(abstraction, 0.0)  # unit: m/day                       

        # the value should be higher than the previous year value
        if iYear > staYear: pcrValue = pcr.max(preValue, pcrValue)
        preValue = pcrValue
Ejemplo n.º 12
0
    def read_forcings(self, currTimeStep):

        #-----------------------------------------------------------------------
        # NOTE: RvB 13/07/2016 hard-coded reference to the variable names
        # preciptiation, temperature and evapotranspiration have been replaced
        # by the variable names used in the netCDF and passed from the ini file
        #-----------------------------------------------------------------------

        # method for finding time indexes in the precipitation netdf file:
        # - the default one
        method_for_time_index = None
        # - based on the ini/configuration file (if given)
        if 'time_index_method_for_precipitation_netcdf' in list(self.iniItems.meteoOptions.keys()) and\
                                                           self.iniItems.meteoOptions['time_index_method_for_precipitation_netcdf'] != "None":
            method_for_time_index = self.iniItems.meteoOptions[
                'time_index_method_for_precipitation_netcdf']

        # reading precipitation:
        if self.precipitation_set_per_year:
            #~ print currTimeStep.year
            nc_file_per_year = self.preFileNC % (float(
                currTimeStep.year), float(currTimeStep.year))
            self.precipitation = vos.netcdf2PCRobjClone(\
                                      nc_file_per_year, self.preVarName,\
                                      str(currTimeStep.fulldate),
                                      useDoy = method_for_time_index,
                                      cloneMapFileName = self.cloneMap,\
                                      LatitudeLongitude = True)
        else:
            self.precipitation = vos.netcdf2PCRobjClone(\
                                      self.preFileNC, self.preVarName,\
                                      str(currTimeStep.fulldate),
                                      useDoy = method_for_time_index,
                                      cloneMapFileName = self.cloneMap,\
                                      LatitudeLongitude = True)

        #-----------------------------------------------------------------------
        # NOTE: RvB 13/07/2016 added to automatically update precipitation
        self.precipitation = self.preConst + self.preFactor * pcr.ifthen(
            self.landmask, self.precipitation)
        #-----------------------------------------------------------------------

        # make sure that precipitation is always positive
        self.precipitation = pcr.max(0., self.precipitation)
        self.precipitation = pcr.cover(self.precipitation, 0.0)

        # ignore very small values of precipitation (less than 0.00001 m/day or less than 0.01 kg.m-2.day-1 )
        if self.usingDailyTimeStepForcingData:
            self.precipitation = pcr.rounddown(
                self.precipitation * 100000.) / 100000.

        # method for finding time index in the temperature netdf file:
        # - the default one
        method_for_time_index = None
        # - based on the ini/configuration file (if given)
        if 'time_index_method_for_temperature_netcdf' in list(self.iniItems.meteoOptions.keys()) and\
                                                         self.iniItems.meteoOptions['time_index_method_for_temperature_netcdf'] != "None":
            method_for_time_index = self.iniItems.meteoOptions[
                'time_index_method_for_temperature_netcdf']

        # reading temperature
        if self.temperature_set_per_year:
            nc_file_per_year = self.tmpFileNC % (int(
                currTimeStep.year), int(currTimeStep.year))
            self.temperature = vos.netcdf2PCRobjClone(\
                                      nc_file_per_year, self.tmpVarName,\
                                      str(currTimeStep.fulldate),
                                      useDoy = method_for_time_index,
                                      cloneMapFileName = self.cloneMap,\
                                      LatitudeLongitude = True)
        else:
            self.temperature = vos.netcdf2PCRobjClone(\
                                 self.tmpFileNC,self.tmpVarName,\
                                 str(currTimeStep.fulldate),
                                 useDoy = method_for_time_index,
                                 cloneMapFileName=self.cloneMap,\
                                 LatitudeLongitude = True)

        #-----------------------------------------------------------------------
        # NOTE: RvB 13/07/2016 added to automatically update temperature
        self.temperature = self.tmpConst + self.tmpFactor * pcr.ifthen(
            self.landmask, self.temperature)
        #-----------------------------------------------------------------------

        # Downscaling precipitation and temperature
        if self.downscalePrecipitationOption:
            self.downscalePrecipitation(currTimeStep)
        if self.downscaleTemperatureOption:
            self.downscaleTemperature(currTimeStep)

        # calculate or obtain referencePotET
        if self.refETPotMethod == 'Hamon':            self.referencePotET = \
   refPotET.HamonPotET(self.temperature,\
                       currTimeStep.doy,\
                       self.latitudes)
        if self.refETPotMethod == 'Input':

            # method for finding time indexes in the precipitation netdf file:
            # - the default one
            method_for_time_index = None
            # - based on the ini/configuration file (if given)
            if 'time_index_method_for_ref_pot_et_netcdf' in list(self.iniItems.meteoOptions.keys()) and\
                                                            self.iniItems.meteoOptions['time_index_method_for_ref_pot_et_netcdf'] != "None":
                method_for_time_index = self.iniItems.meteoOptions[
                    'time_index_method_for_ref_pot_et_netcdf']

            if self.refETPotFileNC_set_per_year:
                nc_file_per_year = self.etpFileNC % (int(
                    currTimeStep.year), int(currTimeStep.year))
                self.referencePotET = vos.netcdf2PCRobjClone(\
                                      nc_file_per_year, self.refETPotVarName,\
                                      str(currTimeStep.fulldate),
                                      useDoy = method_for_time_index,
                                      cloneMapFileName = self.cloneMap,\
                                      LatitudeLongitude = True)
            else:
                self.referencePotET = vos.netcdf2PCRobjClone(\
                                      self.etpFileNC,self.refETPotVarName,\
                                      str(currTimeStep.fulldate),
                                      useDoy = method_for_time_index,
                                      cloneMapFileName=self.cloneMap,\
                                      LatitudeLongitude = True)
            #-----------------------------------------------------------------------
            # NOTE: RvB 13/07/2016 added to automatically update reference potential evapotranspiration
            self.referencePotET = self.refETPotConst + self.refETPotFactor * pcr.ifthen(
                self.landmask, self.referencePotET)
            #-----------------------------------------------------------------------

        # Downscaling referenceETPot (based on temperature)
        if self.downscaleReferenceETPotOption: self.downscaleReferenceETPot()

        # smoothing:
        if self.forcingSmoothing == True:
            logger.debug("Forcing data are smoothed.")
            self.precipitation = pcr.windowaverage(self.precipitation,
                                                   self.smoothingWindowsLength)
            self.temperature = pcr.windowaverage(self.temperature,
                                                 self.smoothingWindowsLength)
            self.referencePotET = pcr.windowaverage(
                self.referencePotET, self.smoothingWindowsLength)

        # rounding temperature values to minimize numerical errors (note only to minimize, not remove)
        self.temperature = pcr.roundoff(self.temperature * 1000.) / 1000.

        # ignore snow by setting temperature to 25 deg C
        if self.ignore_snow: self.temperature = pcr.spatial(pcr.scalar(25.))

        # define precipitation, temperature and referencePotET ONLY at landmask area (for reporting):
        self.precipitation = pcr.ifthen(self.landmask, self.precipitation)
        self.temperature = pcr.ifthen(self.landmask, self.temperature)
        self.referencePotET = pcr.ifthen(self.landmask, self.referencePotET)

        # make sure precipitation and referencePotET are always positive:
        self.precipitation = pcr.max(0.0, self.precipitation)
        self.referencePotET = pcr.max(0.0, self.referencePotET)

        if self.report == True:
            timeStamp = datetime.datetime(currTimeStep.year,\
                                          currTimeStep.month,\
                                          currTimeStep.day,\
                                          0)
            # writing daily output to netcdf files
            timestepPCR = currTimeStep.timeStepPCR
            if self.outDailyTotNC[0] != "None":
                for var in self.outDailyTotNC:
                    self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_dailyTot.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var),vos.MV),\
                                         timeStamp,timestepPCR-1)

            # writing monthly output to netcdf files
            # -cummulative
            if self.outMonthTotNC[0] != "None":
                for var in self.outMonthTotNC:

                    # introduce variables at the beginning of simulation or
                    #     reset variables at the beginning of the month
                    if currTimeStep.timeStepPCR == 1 or \
                       currTimeStep.day == 1:                        \
                                               vars(self)[var+'MonthTot'] = pcr.scalar(0.0)

                    # accumulating
                    vars(self)[var + 'MonthTot'] += vars(self)[var]

                    # reporting at the end of the month:
                    if currTimeStep.endMonth == True:
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_monthTot.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var+'MonthTot'),\
                           vos.MV),timeStamp,currTimeStep.monthIdx-1)
            # -average
            if self.outMonthAvgNC[0] != "None":
                for var in self.outMonthAvgNC:
                    # only if a accumulator variable has not been defined:
                    if var not in self.outMonthTotNC:

                        # introduce accumulator at the beginning of simulation or
                        #     reset accumulator at the beginning of the month
                        if currTimeStep.timeStepPCR == 1 or \
                           currTimeStep.day == 1:                            \
                                                       vars(self)[var+'MonthTot'] = pcr.scalar(0.0)
                        # accumulating
                        vars(self)[var + 'MonthTot'] += vars(self)[var]

                    # calculating average & reporting at the end of the month:
                    if currTimeStep.endMonth == True:
                        vars(self)[var+'MonthAvg'] = vars(self)[var+'MonthTot']/\
                                                     currTimeStep.day
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_monthAvg.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var+'MonthAvg'),\
                           vos.MV),timeStamp,currTimeStep.monthIdx-1)
            #
            # -last day of the month
            if self.outMonthEndNC[0] != "None":
                for var in self.outMonthEndNC:
                    # reporting at the end of the month:
                    if currTimeStep.endMonth == True:
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_monthEnd.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var),vos.MV),\
                                         timeStamp,currTimeStep.monthIdx-1)

            # writing yearly output to netcdf files
            # -cummulative
            if self.outAnnuaTotNC[0] != "None":
                for var in self.outAnnuaTotNC:

                    # introduce variables at the beginning of simulation or
                    #     reset variables at the beginning of the month
                    if currTimeStep.timeStepPCR == 1 or \
                       currTimeStep.doy == 1:                        \
                                               vars(self)[var+'AnnuaTot'] = pcr.scalar(0.0)

                    # accumulating
                    vars(self)[var + 'AnnuaTot'] += vars(self)[var]

                    # reporting at the end of the year:
                    if currTimeStep.endYear == True:
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_annuaTot.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var+'AnnuaTot'),\
                           vos.MV),timeStamp,currTimeStep.annuaIdx-1)
            # -average
            if self.outAnnuaAvgNC[0] != "None":
                for var in self.outAnnuaAvgNC:
                    # only if a accumulator variable has not been defined:
                    if var not in self.outAnnuaTotNC:
                        # introduce accumulator at the beginning of simulation or
                        #     reset accumulator at the beginning of the year
                        if currTimeStep.timeStepPCR == 1 or \
                           currTimeStep.doy == 1:                            \
                                                       vars(self)[var+'AnnuaTot'] = pcr.scalar(0.0)
                        # accumulating
                        vars(self)[var + 'AnnuaTot'] += vars(self)[var]
                    #
                    # calculating average & reporting at the end of the year:
                    if currTimeStep.endYear == True:
                        vars(self)[var+'AnnuaAvg'] = vars(self)[var+'AnnuaTot']/\
                                                     currTimeStep.doy
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_annuaAvg.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var+'AnnuaAvg'),\
                           vos.MV),timeStamp,currTimeStep.annuaIdx-1)
            #
            # -last day of the year
            if self.outAnnuaEndNC[0] != "None":
                for var in self.outAnnuaEndNC:
                    # reporting at the end of the year:
                    if currTimeStep.endYear == True:
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_annuaEnd.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var),vos.MV),\
                                         timeStamp,currTimeStep.annuaIdx-1)
Ejemplo n.º 13
0
    def read_forcings(self, currTimeStep):

        # reading precipitation:
        if self.precipitation_set_per_year:
            #~ print currTimeStep.year
            nc_file_per_year = self.preFileNC % (float(
                currTimeStep.year), float(currTimeStep.year))
            self.precipitation = vos.netcdf2PCRobjClone(\
                                      nc_file_per_year, 'precipitation',\
                                      str(currTimeStep.fulldate),
                                      useDoy = None,
                                      cloneMapFileName = self.cloneMap,\
                                      LatitudeLongitude = True)
        else:
            #self.precipitation = vos.netcdf2PCRobjClone(\
            #                          self.preFileNC, 'precipitation',\
            #                          str(currTimeStep.fulldate),
            #                          useDoy = None,
            #                          cloneMapFileName = self.cloneMap,\
            #                          LatitudeLongitude = True)

            # reading precip when ISI-MIP is used
            precipitation = vos.netcdf2PCRobjClone(\
                                      self.preFileNC, 'pr',\
                                      str(currTimeStep.fulldate),
                                      useDoy = None,
                                      cloneMapFileName = self.cloneMap,\
                                      LatitudeLongitude = True)
            # unit original km m-2 s-1 to m d-1
            # soortelijk gewicht water = 998 km/m3
        self.precipitation = (precipitation / 998.0) * (60. * 60. * 24)

        precipitationCorrectionFactor = pcr.scalar(
            1.0
        )  # Since 19 Feb 2014, Edwin removed the support for correcting precipitation.
        self.precipitation = pcr.max(0.,self.precipitation*\
                precipitationCorrectionFactor)
        self.precipitation = pcr.cover(self.precipitation, 0.0)

        # ignore very small values of precipitation (less than 0.00001 m/day or less than 0.01 kg.m-2.day-1 )
        if self.usingDailyTimeStepForcingData:
            self.precipitation = pcr.rounddown(
                self.precipitation * 100000.) / 100000.

        # reading temperature
        if self.temperature_set_per_year:
            nc_file_per_year = self.tmpFileNC % (int(
                currTimeStep.year), int(currTimeStep.year))
            self.temperature = vos.netcdf2PCRobjClone(\
                                      nc_file_per_year, 'temperature',\
                                      str(currTimeStep.fulldate),
                                      useDoy = None,
                                      cloneMapFileName = self.cloneMap,\
                                      LatitudeLongitude = True)
        else:
            # updated to temp when using ISI-MIP projection
            temperature = vos.netcdf2PCRobjClone(\
                                 self.tmpFileNC,'tas',\
                                 str(currTimeStep.fulldate),
                                 useDoy = None,
                                 cloneMapFileName=self.cloneMap,\
                                 LatitudeLongitude = True)
# unit K to C
        self.temperature = temperature - 273.15

        # Downscaling precipitation and temperature
        if self.downscalePrecipitationOption:
            self.downscalePrecipitation(currTimeStep)
        if self.downscaleTemperatureOption:
            self.downscaleTemperature(currTimeStep)

        # calculate or obtain referencePotET
        if self.refETPotMethod == 'Hamon':            self.referencePotET = \
   refPotET.HamonPotET(self.temperature,\
                       currTimeStep.doy,\
                       self.latitudes)
        if self.refETPotMethod == 'Input':
            if self.refETPotFileNC_set_per_year:
                nc_file_per_year = self.etpFileNC % (int(
                    currTimeStep.year), int(currTimeStep.year))
                self.referencePotET = vos.netcdf2PCRobjClone(\
                                      nc_file_per_year, 'evapotranspiration',\
                                      str(currTimeStep.fulldate),
                                      useDoy = None,
                                      cloneMapFileName = self.cloneMap,\
                                      LatitudeLongitude = True)
            else:
                self.referencePotET = vos.netcdf2PCRobjClone(\
                                      self.etpFileNC,'evapotranspiration',\
                                      str(currTimeStep.fulldate),
                                      useDoy = None,
                                      cloneMapFileName=self.cloneMap,\
                                      LatitudeLongitude = True)

        # Downscaling referenceETPot (based on temperature)
        if self.downscaleReferenceETPotOption: self.downscaleReferenceETPot()

        # smoothing:
        if self.forcingSmoothing == True:
            logger.debug("Forcing data are smoothed.")
            self.precipitation = pcr.windowaverage(self.precipitation,
                                                   self.smoothingWindowsLength)
            self.temperature = pcr.windowaverage(self.temperature,
                                                 self.smoothingWindowsLength)
            self.referencePotET = pcr.windowaverage(
                self.referencePotET, self.smoothingWindowsLength)

        # make sure precipitation is always positive:
        self.precipitation = pcr.max(0.0, self.precipitation)

        # rounding temperature values to minimize numerical errors (note only to minimize, not remove)
        self.temperature = pcr.roundoff(self.temperature * 1000.) / 1000.

        # ignore snow by setting temperature to 25 deg C
        if self.ignore_snow: self.temperature = pcr.spatial(pcr.scalar(25.))

        # define precipitation, temperature and referencePotET ONLY at landmask area (for reporting):
        self.precipitation = pcr.ifthen(self.landmask, self.precipitation)
        self.temperature = pcr.ifthen(self.landmask, self.temperature)
        self.referencePotET = pcr.ifthen(self.landmask, self.referencePotET)

        if self.report == True:
            timeStamp = datetime.datetime(currTimeStep.year,\
                                          currTimeStep.month,\
                                          currTimeStep.day,\
                                          0)
            # writing daily output to netcdf files
            timestepPCR = currTimeStep.timeStepPCR
            if self.outDailyTotNC[0] != "None":
                for var in self.outDailyTotNC:
                    self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_dailyTot.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var),vos.MV),\
                                         timeStamp,timestepPCR-1)

            # writing monthly output to netcdf files
            # -cummulative
            if self.outMonthTotNC[0] != "None":
                for var in self.outMonthTotNC:

                    # introduce variables at the beginning of simulation or
                    #     reset variables at the beginning of the month
                    if currTimeStep.timeStepPCR == 1 or \
                       currTimeStep.day == 1:                        \
                                               vars(self)[var+'MonthTot'] = pcr.scalar(0.0)

                    # accumulating
                    vars(self)[var + 'MonthTot'] += vars(self)[var]

                    # reporting at the end of the month:
                    if currTimeStep.endMonth == True:
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_monthTot.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var+'MonthTot'),\
                           vos.MV),timeStamp,currTimeStep.monthIdx-1)
            # -average
            if self.outMonthAvgNC[0] != "None":
                for var in self.outMonthAvgNC:
                    # only if a accumulator variable has not been defined:
                    if var not in self.outMonthTotNC:

                        # introduce accumulator at the beginning of simulation or
                        #     reset accumulator at the beginning of the month
                        if currTimeStep.timeStepPCR == 1 or \
                           currTimeStep.day == 1:                            \
                                                       vars(self)[var+'MonthTot'] = pcr.scalar(0.0)
                        # accumulating
                        vars(self)[var + 'MonthTot'] += vars(self)[var]

                    # calculating average & reporting at the end of the month:
                    if currTimeStep.endMonth == True:
                        vars(self)[var+'MonthAvg'] = vars(self)[var+'MonthTot']/\
                                                     currTimeStep.day
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_monthAvg.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var+'MonthAvg'),\
                           vos.MV),timeStamp,currTimeStep.monthIdx-1)
            #
            # -last day of the month
            if self.outMonthEndNC[0] != "None":
                for var in self.outMonthEndNC:
                    # reporting at the end of the month:
                    if currTimeStep.endMonth == True:
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_monthEnd.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var),vos.MV),\
                                         timeStamp,currTimeStep.monthIdx-1)

            # writing yearly output to netcdf files
            # -cummulative
            if self.outAnnuaTotNC[0] != "None":
                for var in self.outAnnuaTotNC:

                    # introduce variables at the beginning of simulation or
                    #     reset variables at the beginning of the month
                    if currTimeStep.timeStepPCR == 1 or \
                       currTimeStep.doy == 1:                        \
                                               vars(self)[var+'AnnuaTot'] = pcr.scalar(0.0)

                    # accumulating
                    vars(self)[var + 'AnnuaTot'] += vars(self)[var]

                    # reporting at the end of the year:
                    if currTimeStep.endYear == True:
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_annuaTot.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var+'AnnuaTot'),\
                           vos.MV),timeStamp,currTimeStep.annuaIdx-1)
            # -average
            if self.outAnnuaAvgNC[0] != "None":
                for var in self.outAnnuaAvgNC:
                    # only if a accumulator variable has not been defined:
                    if var not in self.outAnnuaTotNC:
                        # introduce accumulator at the beginning of simulation or
                        #     reset accumulator at the beginning of the year
                        if currTimeStep.timeStepPCR == 1 or \
                           currTimeStep.doy == 1:                            \
                                                       vars(self)[var+'AnnuaTot'] = pcr.scalar(0.0)
                        # accumulating
                        vars(self)[var + 'AnnuaTot'] += vars(self)[var]
                    #
                    # calculating average & reporting at the end of the year:
                    if currTimeStep.endYear == True:
                        vars(self)[var+'AnnuaAvg'] = vars(self)[var+'AnnuaTot']/\
                                                     currTimeStep.doy
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_annuaAvg.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var+'AnnuaAvg'),\
                           vos.MV),timeStamp,currTimeStep.annuaIdx-1)
            #
            # -last day of the year
            if self.outAnnuaEndNC[0] != "None":
                for var in self.outAnnuaEndNC:
                    # reporting at the end of the year:
                    if currTimeStep.endYear == True:
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_annuaEnd.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var),vos.MV),\
                                         timeStamp,currTimeStep.annuaIdx-1)
fraction_reserved_recharge = pcr.cover(fraction_reserved_recharge, 0.1)
# - set minimum value to 0.10
fraction_reserved_recharge = pcr.max(0.10, fraction_reserved_recharge)
# - set maximum value to 0.75
fraction_reserved_recharge = pcr.min(0.75, fraction_reserved_recharge)

# areal_groundwater_abstraction (unit: m/year)
#~ groundwater_abstraction = pcr.cover(pcr.readmap("/nfsarchive/edwin-emergency-backup-DO-NOT-DELETE/rapid/edwin/05min_runs_results/2015_04_27/non_natural_2015_04_27/global/analysis/avg_values_1990_to_2010/totalGroundwaterAbstraction_annuaTot_output_1990to2010.map"), 0.0)
groundwater_abstraction = pcr.scalar(0.0)
for year in range(start_year, end_year + 1, 1):
    date_input_in_string = str(year) + "-12-31"
    netcdf_file   = "/nfsarchive/edwin-emergency-backup-DO-NOT-DELETE/rapid/edwin/05min_runs_results/2015_04_27/non_natural_2015_04_27/global/netcdf/totalGroundwaterAbstraction_annuaTot_output_1981to2010.nc"
    variable_name = "total_groundwater_abstraction"
    groundwater_abstraction += vos.netcdf2PCRobjClone(ncFile = netcdf_file, varName = variable_name, dateInput = date_input_in_string,\
                                                      useDoy = None,
                                                      cloneMapFileName  = None,\
                                                      LatitudeLongitude = True,\
                                                      specificFillValue = None)
areal_groundwater_abstraction = pcr.cover(pcr.areatotal(groundwater_abstraction * cell_area, class_map)/pcr.areatotal(cell_area, class_map), 0.0)

# areal groundwater recharge (unit: m/year)
# cdo command: cdo setunit,m.year-1 -timavg -yearsum -selyear,1990/2010 ../../netcdf/gwRecharge_monthTot_output.nc gwRecharge_annuaTot_output_1990to2010.nc
#~ groundwater_recharge = pcr.cover(pcr.readmap("/nfsarchive/edwin-emergency-backup-DO-NOT-DELETE/rapid/edwin/05min_runs_results/2015_04_27/non_natural_2015_04_27/global/analysis/avg_values_1990_to_2010/gwRecharge_annuaTot_output_1990to2010.map"), 0.0) 
groundwater_recharge = pcr.scalar(0.0)
for year in range(start_year, end_year + 1, 1):
    date_input_in_string = str(year) + "-12-31"
    netcdf_file   = "/nfsarchive/edwin-emergency-backup-DO-NOT-DELETE/rapid/edwin/05min_runs_results/2015_04_27/non_natural_2015_04_27/global/netcdf/gwRecharge_annuaTot_output_1981to2010.nc"
    variable_name = "groundwater_recharge"
    groundwater_recharge += vos.netcdf2PCRobjClone(ncFile = netcdf_file, varName = variable_name, dateInput = date_input_in_string,\
                                                   useDoy = None,
                                                   cloneMapFileName  = None,\
basin_map  = pcr.ifthen(landmask, basin_map)
pcr.report(basin_map , "basin_map.map")
#~ pcr.aguila(basin_map)
# - calculate the basin area
basin_area = pcr.areatotal(cell_area, basin_map)
pcr.report(basin_area, "basin_area.map")
#~ pcr.aguila(basin_area)


# finding the month that give the maximum discharge (from the climatology time series)
msg = "Identifying the month with peak discharge (from climatology time series):"
logger.info(msg)	
# - read the maximum monthly discharge for every basin
maximum_discharge = vos.netcdf2PCRobjClone(input_files['maximumClimatologyDischargeMonthAvg'], \
                                           "discharge", 1,\
                                           useDoy = "Yes",
                                           cloneMapFileName  = clone_map_file,\
                                           LatitudeLongitude = True,\
                                           specificFillValue = None)
maximum_discharge = pcr.areamaximum(\
                  pcr.cover(maximum_discharge, 0.0), basin_map)
# - find the month with maximum discharge
maximum_month = pcr.spatial(pcr.scalar(1.0))
for i_month in range(1, 12 + 1):
    # read the climatology discharge time series
    discharge_for_this_month = vos.netcdf2PCRobjClone(input_files['climatologyDischargeMonthAvg'], \
                                                      "discharge", i_month,\
                                                      useDoy = "Yes",
                                                      cloneMapFileName  = clone_map_file,\
                                                      LatitudeLongitude = True,\
                                                      specificFillValue = None)
    # upscale it to the basin scale
Ejemplo n.º 16
0
    def read_forcings(self, currTimeStep):
        # reading precipitation:
        self.precipitation = vos.netcdf2PCRobjClone(\
                                  self.preFileNC,'precipitation',\
                                  str(currTimeStep.fulldate),
                                  useDoy = None,
                                  cloneMapFileName=self.cloneMap,\
                                  LatitudeLongitude = True)

        precipitationCorrectionFactor = pcr.scalar(
            1.0
        )  # Since 19 Feb 2014, Edwin removed the support for correcting precipitation.
        self.precipitation = pcr.max(0.,self.precipitation*\
                precipitationCorrectionFactor)
        self.precipitation = pcr.cover(self.precipitation, 0.0)

        # ignore very small values of precipitation (less than 0.00001 m/day or less than 0.01 kg.m-2.day-1 )
        if self.usingDailyTimeStepForcingData:
            self.precipitation = pcr.rounddown(
                self.precipitation * 100000.) / 100000.

        # reading temperature
        self.temperature = vos.netcdf2PCRobjClone(\
                                 self.tmpFileNC,'temperature',\
                                 str(currTimeStep.fulldate),
                                 useDoy = None,
                                  cloneMapFileName=self.cloneMap,\
                                  LatitudeLongitude = True)

        # Downscaling precipitation and temperature
        if self.downscalePrecipitationOption:
            self.downscalePrecipitation(currTimeStep)
        if self.downscaleTemperatureOption:
            self.downscaleTemperature(currTimeStep)

        # calculate or obtain referencePotET
        if self.refETPotMethod == 'Hamon':            self.referencePotET = \
   refPotET.HamonPotET(self.temperature,\
                       currTimeStep.doy,\
                       self.latitudes)
        if self.refETPotMethod == 'Input':
            self.referencePotET = vos.netcdf2PCRobjClone(\
                                     self.etpFileNC,'evapotranspiration',\
                                     str(currTimeStep.fulldate),
                                     useDoy = None,
                                      cloneMapFileName=self.cloneMap,\
                                      LatitudeLongitude = True)

        # Downscaling referenceETPot (based on temperature)
        if self.downscaleReferenceETPotOption: self.downscaleReferenceETPot()

        # smoothing:
        if self.forcingSmoothing == True:
            logger.info("Forcing data are smoothed.")
            self.precipitation = pcr.windowaverage(self.precipitation,
                                                   self.smoothingWindowsLength)
            self.temperature = pcr.windowaverage(self.temperature,
                                                 self.smoothingWindowsLength)
            self.referencePotET = pcr.windowaverage(
                self.referencePotET, self.smoothingWindowsLength)

        # define precipitation, temperature and referencePotET ONLY at landmask area (for reporting):
        self.precipitation = pcr.ifthen(self.landmask, self.precipitation)
        self.temperature = pcr.ifthen(self.landmask, self.temperature)
        self.referencePotET = pcr.ifthen(self.landmask, self.referencePotET)

        if self.report == True:
            timeStamp = datetime.datetime(currTimeStep.year,\
                                          currTimeStep.month,\
                                          currTimeStep.day,\
                                          0)
            # writing daily output to netcdf files
            timestepPCR = currTimeStep.timeStepPCR
            if self.outDailyTotNC[0] != "None":
                for var in self.outDailyTotNC:
                    self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_dailyTot.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var),vos.MV),\
                                         timeStamp,timestepPCR-1)

            # writing monthly output to netcdf files
            # -cummulative
            if self.outMonthTotNC[0] != "None":
                for var in self.outMonthTotNC:

                    # introduce variables at the beginning of simulation or
                    #     reset variables at the beginning of the month
                    if currTimeStep.timeStepPCR == 1 or \
                       currTimeStep.day == 1:                        \
                                               vars(self)[var+'MonthTot'] = pcr.scalar(0.0)

                    # accumulating
                    vars(self)[var + 'MonthTot'] += vars(self)[var]

                    # reporting at the end of the month:
                    if currTimeStep.endMonth == True:
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_monthTot.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var+'MonthTot'),\
                           vos.MV),timeStamp,currTimeStep.monthIdx-1)
            # -average
            if self.outMonthAvgNC[0] != "None":
                for var in self.outMonthAvgNC:
                    # only if a accumulator variable has not been defined:
                    if var not in self.outMonthTotNC:

                        # introduce accumulator at the beginning of simulation or
                        #     reset accumulator at the beginning of the month
                        if currTimeStep.timeStepPCR == 1 or \
                           currTimeStep.day == 1:                            \
                                                       vars(self)[var+'MonthTot'] = pcr.scalar(0.0)
                        # accumulating
                        vars(self)[var + 'MonthTot'] += vars(self)[var]

                    # calculating average & reporting at the end of the month:
                    if currTimeStep.endMonth == True:
                        vars(self)[var+'MonthAvg'] = vars(self)[var+'MonthTot']/\
                                                     currTimeStep.day
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_monthAvg.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var+'MonthAvg'),\
                           vos.MV),timeStamp,currTimeStep.monthIdx-1)
            #
            # -last day of the month
            if self.outMonthEndNC[0] != "None":
                for var in self.outMonthEndNC:
                    # reporting at the end of the month:
                    if currTimeStep.endMonth == True:
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_monthEnd.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var),vos.MV),\
                                         timeStamp,currTimeStep.monthIdx-1)

            # writing yearly output to netcdf files
            # -cummulative
            if self.outAnnuaTotNC[0] != "None":
                for var in self.outAnnuaTotNC:

                    # introduce variables at the beginning of simulation or
                    #     reset variables at the beginning of the month
                    if currTimeStep.timeStepPCR == 1 or \
                       currTimeStep.doy == 1:                        \
                                               vars(self)[var+'AnnuaTot'] = pcr.scalar(0.0)

                    # accumulating
                    vars(self)[var + 'AnnuaTot'] += vars(self)[var]

                    # reporting at the end of the year:
                    if currTimeStep.endYear == True:
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_annuaTot.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var+'AnnuaTot'),\
                           vos.MV),timeStamp,currTimeStep.annuaIdx-1)
            # -average
            if self.outAnnuaAvgNC[0] != "None":
                for var in self.outAnnuaAvgNC:
                    # only if a accumulator variable has not been defined:
                    if var not in self.outAnnuaTotNC:
                        # introduce accumulator at the beginning of simulation or
                        #     reset accumulator at the beginning of the year
                        if currTimeStep.timeStepPCR == 1 or \
                           currTimeStep.doy == 1:                            \
                                                       vars(self)[var+'AnnuaTot'] = pcr.scalar(0.0)
                        # accumulating
                        vars(self)[var + 'AnnuaTot'] += vars(self)[var]
                    #
                    # calculating average & reporting at the end of the year:
                    if currTimeStep.endYear == True:
                        vars(self)[var+'AnnuaAvg'] = vars(self)[var+'AnnuaTot']/\
                                                     currTimeStep.doy
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_annuaAvg.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var+'AnnuaAvg'),\
                           vos.MV),timeStamp,currTimeStep.annuaIdx-1)
            #
            # -last day of the year
            if self.outAnnuaEndNC[0] != "None":
                for var in self.outAnnuaEndNC:
                    # reporting at the end of the year:
                    if currTimeStep.endYear == True:
                        self.netcdfObj.data2NetCDF(str(self.outNCDir)+"/"+ \
                                         str(var)+"_annuaEnd.nc",\
                                         var,\
                          pcr2numpy(self.__getattribute__(var),vos.MV),\
                                         timeStamp,currTimeStep.annuaIdx-1)
Ejemplo n.º 17
0
    def modflow_simulation(self,\
                           simulation_type,\
                           initial_head,\
                           currTimeStep = None,\
                           PERLEN = 1.0, 
                           NSTP   = 1, \
                           HCLOSE = 1.0,\
                           RCLOSE = 10.* 400.*400.,\
                           MXITER = 50,\
                           ITERI = 30,\
                           NPCOND = 1,\
                           RELAX = 1.00,\
                           NBPOL = 2,\
                           DAMP = 1,\
                           ITMUNI = 4, LENUNI = 2, TSMULT = 1.0):
        
        # initiate pcraster modflow object if modflow is not called yet:
        if self.modflow_has_been_called == False or self.modflow_converged == False:
            self.initiate_modflow()
            self.modflow_has_been_called = True

        if simulation_type == "transient":
            logger.info("Preparing MODFLOW input for a transient simulation.")
            SSTR = 0
        if simulation_type == "steady-state":
            logger.info("Preparing MODFLOW input for a steady-state simulation.")
            SSTR = 1

        # waterBody class to define the extent of lakes and reservoirs
        #
        if simulation_type == "steady-state":
            self.WaterBodies = waterBodies.WaterBodies(self.iniItems,\
                                                       self.landmask,\
                                                       self.onlyNaturalWaterBodies)
            self.WaterBodies.getParameterFiles(date_given = self.iniItems.globalOptions['startTime'],\
                                               cellArea = self.cellAreaMap, \
                                               ldd = self.lddMap)        
        #
        if simulation_type == "transient":
            if currTimeStep.timeStepPCR == 1:
               self.WaterBodies = waterBodies.WaterBodies(self.iniItems,\
                                                          self.landmask,\
                                                          self.onlyNaturalWaterBodies)
            if currTimeStep.timeStepPCR == 1 or currTimeStep.doy == 1:
               self.WaterBodies.getParameterFiles(date_given = str(currTimeStep.fulldate),\
                                                  cellArea = self.cellAreaMap, \
                                                  ldd = self.lddMap)        

        print "here"

        # using dem_average as the initial groundwater head value 
        self.pcr_modflow.setInitialHead(initial_head, 1)
        
        # set parameter values for the DIS package and PCG solver
        self.pcr_modflow.setDISParameter(ITMUNI, LENUNI, PERLEN, NSTP, TSMULT, SSTR)
        self.pcr_modflow.setPCG(MXITER, ITERI, NPCOND, HCLOSE, RCLOSE, RELAX, NBPOL, DAMP)
        #
        # Some notes about the values  
        #
        # ITMUNI = 4     # indicates the time unit (0: undefined, 1: seconds, 2: minutes, 3: hours, 4: days, 5: years)
        # LENUNI = 2     # indicates the length unit (0: undefined, 1: feet, 2: meters, 3: centimeters)
        # PERLEN = 1.0   # duration of a stress period
        # NSTP   = 1     # number of time steps in a stress period
        # TSMULT = 1.0   # multiplier for the length of the successive iterations
        # SSTR   = 1     # 0 - transient, 1 - steady state
        #
        # MXITER = 50                 # maximum number of outer iterations           # Deltares use 50
        # ITERI  = 30                 # number of inner iterations                   # Deltares use 30
        # NPCOND = 1                  # 1 - Modified Incomplete Cholesky, 2 - Polynomial matrix conditioning method;
        # HCLOSE = 0.01               # HCLOSE (unit: m) 
        # RCLOSE = 10.* 400.*400.     # RCLOSE (unit: m3)
        # RELAX  = 1.00               # relaxation parameter used with NPCOND = 1
        # NBPOL  = 2                  # indicates whether the estimate of the upper bound on the maximum eigenvalue is 2.0 (but we don ot use it, since NPCOND = 1) 
        # DAMP   = 1                  # no damping (DAMP introduced in MODFLOW 2000)
        
        # read input files (for the steady-state condition, we use pcraster maps):
        if simulation_type == "steady-state":
            # - discharge (m3/s) from PCR-GLOBWB
            discharge = vos.readPCRmapClone(self.iniItems.modflowSteadyStateInputOptions['avgDischargeInputMap'],\
                                                self.cloneMap, self.tmpDir, self.inputDir)
            # - recharge/capillary rise (unit: m/day) from PCR-GLOBWB 
            gwRecharge = vos.readPCRmapClone(self.iniItems.modflowSteadyStateInputOptions['avgGroundwaterRechargeInputMap'],\
                                                self.cloneMap, self.tmpDir, self.inputDir)
            if self.ignoreCapRise: gwRecharge = pcr.max(0.0, gwRecharge) 
            gwAbstraction = pcr.spatial(pcr.scalar(0.0))

        # read input files (for the transient, input files are given in netcdf files):
        if simulation_type == "transient":
            # - discharge (m3/s) from PCR-GLOBWB
            discharge = vos.netcdf2PCRobjClone(self.iniItems.modflowTransientInputOptions['dischargeInputNC'],
                                               "discharge",str(currTimeStep.fulldate),None,self.cloneMap)
            # - recharge/capillary rise (unit: m/day) from PCR-GLOBWB 
            gwRecharge = vos.netcdf2PCRobjClone(self.iniItems.modflowTransientInputOptions['groundwaterRechargeInputNC'],\
                                               "groundwater_recharge",str(currTimeStep.fulldate),None,self.cloneMap)
            if self.ignoreCapRise: gwRecharge = pcr.max(0.0, gwRecharge) 
            # - groundwater abstraction (unit: m/day) from PCR-GLOBWB 
            gwAbstraction = vos.netcdf2PCRobjClone(self.iniItems.modflowTransientInputOptions['groundwaterAbstractionInputNC'],\
                                               "total_groundwater_abstraction",str(currTimeStep.fulldate),None,self.cloneMap)

        # set recharge, river, well and drain packages
        self.set_river_package(discharge, currTimeStep)
        self.set_recharge_package(gwRecharge)
        self.set_well_package(gwAbstraction)
        self.set_drain_package()
        
        # execute MODFLOW 
        logger.info("Executing MODFLOW.")
        self.pcr_modflow.run()
        
        logger.info("Check if the model whether a run has converged or not")
        self.modflow_converged = self.check_modflow_convergence()
        if self.modflow_converged == False:

            msg = "MODFLOW FAILED TO CONVERGE with HCLOSE = "+str(HCLOSE)+" and RCLOSE = "+str(RCLOSE)
            logger.info(msg)
            
            # iteration index for the RCLOSE
            self.iteration_RCLOSE += 1 
            # reset if the index has reached the length of available criteria
            if self.iteration_RCLOSE > (len(self.criteria_RCLOSE)-1): self.iteration_RCLOSE = 0     

            # iteration index for the HCLOSE
            if self.iteration_RCLOSE == 0: self.iteration_HCLOSE += 1 
            
            # we have to reset modflow as we want to change the PCG setup
            self.modflow_has_been_called = False
            
            # for the steady state simulation, we still save the calculated head as the initial estimate for the next iteration
            if simulation_type == "steady-state": self.groundwaterHead = self.pcr_modflow.getHeads(1)
            # NOTE: We cannot implement this principle for transient simulation 
            
        else:

            msg = "HURRAY!!! MODFLOW CONVERGED with HCLOSE = "+str(HCLOSE)+" and RCLOSE = "+str(RCLOSE)
            logger.info(msg)

            # reset the iteration because modflow has converged
            self.iteration_HCLOSE = 0
            self.iteration_RCLOSE = 0
            
            self.modflow_has_been_called = True
            
            # obtaining the results from modflow simulation
            self.groundwaterHead = None
            self.groundwaterHead = self.pcr_modflow.getHeads(1)  
            
            # calculate groundwater depth only in the landmask region
            self.groundwaterDepth = pcr.ifthen(self.landmask, self.dem_average - self.groundwaterHead)
    def dynamic(self):

        # re-calculate current model time using current pcraster timestep value
        self.modelTime.update(self.currentTimeStep())
        msg = "\n\n\n Processing the date " + self.modelTime.fulldate + "\n\n\n"
        logger.info(msg)

        # read netcdf file
        logger.info("Reading netcdf file.")
        # - set the clone to the necdf file extent
        pcr.setclone(self.inputClone)
        # - read netcdf file
        input_pcr = vos.netcdf2PCRobjClone(ncFile = self.netcdf_input_file, \
                                           varName = "automatic", \
                                           dateInput = self.modelTime.fulldate, \
                                           useDoy = None, \
                                           cloneMapFileName  = self.inputClone, \
                                           LatitudeLongitude = True, \
                                           specificFillValue = None)

        # reprojection
        logger.info("Reprojection.")
        #
        # - save it to a pcraster file in the temporary folder
        tmp_input_pcr_file = self.tmpDir + "/" + "tmp_input_pcr.map"
        pcr.report(input_pcr, tmp_input_pcr_file)
        # - convert it to tif
        tmp_input_tif_file = self.tmpDir + "/" + "tmp_input_pcr.tif"
        cmd = 'gdal_translate ' + tmp_input_pcr_file + " " + tmp_input_tif_file
        logger.debug(cmd)
        os.system(cmd)
        # - re-projection to the outputProjection
        tmp_reprj_tif_file = self.tmpDir + "/" + "tmp_reprj_tif.tif"
        bound_box = self.x_min_output + " " + self.y_min_output + " " + self.x_max_output + " " + self.y_max_output
        cell_size = self.cell_length + " " + self.cell_length
        cmd = 'gdalwarp '+\
              '-s_srs ' + '"' + self.inputProjection  +'" '+\
              '-t_srs ' + '"' + self.outputProjection +'" '+\
              '-te ' + bound_box + " " +\
              '-tr ' + cell_size + " " +\
              '-r '+ self.resample_method + " " +\
              '-srcnodata -3.4028234663852886e+38 -dstnodata -3.4028234663852886e+38 '+\
              tmp_input_tif_file + " "+\
              tmp_reprj_tif_file
        logger.debug(cmd)
        os.system(cmd)
        # - convert it back to pcraster map
        tmp_reprj_map_file = self.tmpDir + "/" + "tmp_reprj_map.map"
        cmd = 'gdal_translate -of PCRaster ' + tmp_reprj_tif_file + " " + tmp_reprj_map_file
        logger.debug(cmd)
        os.system(cmd)
        # - make sure that it has a valid mapattr
        cmd = 'mapattr -c ' + self.outputClone + " " + tmp_reprj_map_file
        logger.debug(cmd)
        os.system(cmd)

        # read the re-projected file
        logger.info(
            "Read the re-projected file, including unit conversion/correction."
        )
        # - set the clone to the output clone
        pcr.setclone(self.outputClone)
        output_pcr = pcr.readmap(tmp_reprj_map_file)
        # - unit conversion
        output_pcr = output_pcr * self.unit_conversion_factor + self.unit_conversion_offset
        #~ pcr.aguila(output_pcr)
        #~ raw_input("Press Enter to continue...")

        # perform area operation
        logger.info("Performing area operation.")
        output_area_pcr = pcr.areaaverage(output_pcr, self.area_class)
        #~ pcr.aguila(output_area_pcr)
        #~ raw_input("Press Enter to continue...")

        # save it to a daily tss file
        logger.info("Saving daily value to a tss file.")
        self.tss_daily_reporting.sample(output_area_pcr)

        # calculate 10 day average
        # - initiate/reset counter and accumulator
        if self.modelTime.day == 1 or self.modelTime.day == 11 or self.modelTime.day == 21:
            self.day_counter = pcr.scalar(0.0)
            self.cummulative_per_ten_days = pcr.scalar(0.0)
            self.average_per_ten_days = pcr.scalar(0.0)
        # - accumulating
        self.day_counter = self.day_counter + 1.0
        self.cummulative_per_ten_days = self.cummulative_per_ten_days + output_area_pcr
        # - calculate 10 day average and reporting
        if self.modelTime.day == 10 or self.modelTime.day == 20 or self.modelTime.isLastDayOfMonth(
        ):
            logger.info(
                'Calculating/saving 10 day average value to a tss file.')
            average_per_ten_days = self.cummulative_per_ten_days / pcr.ifthen(
                self.landmask, self.day_counter)
            #~ pcr.aguila(average_per_ten_days)
            #~ raw_input("Press Enter to continue...")
            if self.report_10day_pcr_files:
                logger.info('Saving 10 day average value to pcraster file.')
                cwd = os.getcwd()
                os.chdir(self.mapDir)
                self.report(average_per_ten_days, "dcd")
                os.chdir(cwd)
        else:
            average_per_ten_days = pcr.scalar(-9999.99)
        self.tss_10day_reporting.sample(average_per_ten_days)

        # clean the temporary folder
        cmd = 'rm -r ' + self.tmpDir + "/*"
        print cmd
        os.system(cmd)

        # change directory to the output folder so that the tss file will be stored there
        os.chdir(self.output_folder)
Ejemplo n.º 19
0
    def modflow_simulation(self,\
                           simulation_type,\
                           initial_head_layer_1, initial_head_layer_2,\
                           currTimeStep = None,\
                           NSTP   = 1, \
                           HCLOSE = 0.5,\
                           RCLOSE = 100.* 400.*400.,\
                           MXITER = 300,\
                           ITERI = 100,\
                           NPCOND = 1,\
                           RELAX = 1.00,\
                           NBPOL = 2,\
                           DAMP = 1,\
                           ITMUNI = 4, LENUNI = 2, PERLEN = 1.0, TSMULT = 1.0):
        # initiate pcraster modflow object
        self.initiate_modflow()

        if simulation_type == "transient":
            logger.info("Preparing MODFLOW input for a transient simulation.")
            SSTR = 0
        if simulation_type == "steady-state":
            logger.info(
                "Preparing MODFLOW input for a steady-state simulation.")
            SSTR = 1

        # waterBody class to define the extent of lakes and reservoirs
        #
        if simulation_type == "steady-state":
            self.WaterBodies = waterBodies.WaterBodies(self.iniItems,\
                                                       self.landmask,\
                                                       self.onlyNaturalWaterBodies)
            self.WaterBodies.getParameterFiles(date_given = self.iniItems.globalOptions['startTime'],\
                                               cellArea = self.cellAreaMap, \
                                               ldd = self.lddMap)
        #
        if simulation_type == "transient":
            if currTimeStep.timeStepPCR == 1:
                self.WaterBodies = waterBodies.WaterBodies(self.iniItems,\
                                                           self.landmask,\
                                                           self.onlyNaturalWaterBodies)
            if currTimeStep.timeStepPCR == 1 or currTimeStep.doy == 1:
                self.WaterBodies.getParameterFiles(date_given = str(currTimeStep.fulldate),\
                                                   cellArea = self.cellAreaMap, \
                                                   ldd = self.lddMap)

        # using dem_average as the initial groundwater head value
        self.pcr_modflow.setInitialHead(initial_head_layer_1, 1)
        self.pcr_modflow.setInitialHead(initial_head_layer_2, 2)

        # set parameter values for the DIS package and PCG solver
        self.pcr_modflow.setDISParameter(ITMUNI, LENUNI, PERLEN, NSTP, TSMULT,
                                         SSTR)
        self.pcr_modflow.setPCG(MXITER, ITERI, NPCOND, HCLOSE, RCLOSE, RELAX,
                                NBPOL, DAMP)
        #
        # Some notes about the values
        #
        # ITMUNI = 4     # indicates the time unit (0: undefined, 1: seconds, 2: minutes, 3: hours, 4: days, 5: years)
        # LENUNI = 2     # indicates the length unit (0: undefined, 1: feet, 2: meters, 3: centimeters)
        # PERLEN = 1.0   # duration of a stress period
        # NSTP   = 1     # number of time steps in a stress period
        # TSMULT = 1.0   # multiplier for the length of the successive iterations
        # SSTR   = 1     # 0 - transient, 1 - steady state
        #
        # MXITER = 100                # maximum number of outer iterations
        # ITERI  = 30                 # number of inner iterations
        # NPCOND = 1                  # 1 - Modified Incomplete Cholesky, 2 - Polynomial matrix conditioning method;
        # HCLOSE = 0.01               # HCLOSE (unit: m) # 0.05 is working
        # RCLOSE = 10.* 400.*400.     # RCLOSE (unit: m3) ; Deltares people uses 100 m3 for their 25 m resolution modflow model
        # RELAX  = 1.00               # relaxation parameter used with NPCOND = 1
        # NBPOL  = 2                  # indicates whether the estimate of the upper bound on the maximum eigenvalue is 2.0 (but we don ot use it, since NPCOND = 1)
        # DAMP   = 1                  # no damping (DAMP introduced in MODFLOW 2000)

        # read input files (for the steady-state condition, we use pcraster maps):
        if simulation_type == "steady-state":
            # - discharge (m3/s) from PCR-GLOBWB
            discharge = vos.readPCRmapClone(self.iniItems.modflowSteadyStateInputOptions['avgDischargeInputMap'],\
                                                self.cloneMap, self.tmpDir, self.inputDir)
            # - recharge/capillary rise (unit: m/day) from PCR-GLOBWB
            gwRecharge = vos.readPCRmapClone(self.iniItems.modflowSteadyStateInputOptions['avgGroundwaterRechargeInputMap'],\
                                                self.cloneMap, self.tmpDir, self.inputDir)
            if self.ignoreCapRise: gwRecharge = pcr.max(0.0, gwRecharge)
            gwAbstraction = pcr.spatial(pcr.scalar(0.0))

        # read input files (for the transient, input files are given in netcdf files):
        if simulation_type == "transient":
            # - discharge (m3/s) from PCR-GLOBWB
            discharge = vos.netcdf2PCRobjClone(
                self.iniItems.modflowTransientInputOptions['dischargeInputNC'],
                "discharge", str(currTimeStep.fulldate), None, self.cloneMap)
            # - recharge/capillary rise (unit: m/day) from PCR-GLOBWB
            gwRecharge = vos.netcdf2PCRobjClone(self.iniItems.modflowTransientInputOptions['groundwaterRechargeInputNC'],\
                                               "groundwater_recharge",str(currTimeStep.fulldate),None,self.cloneMap)
            if self.ignoreCapRise: gwRecharge = pcr.max(0.0, gwRecharge)
            # - groundwater abstraction (unit: m/day) from PCR-GLOBWB
            gwAbstraction = vos.netcdf2PCRobjClone(self.iniItems.modflowTransientInputOptions['groundwaterAbstractionInputNC'],\
                                               "total_groundwater_abstraction",str(currTimeStep.fulldate),None,self.cloneMap)

        # set recharge and river packages
        self.set_river_package(discharge)
        self.set_recharge_package(gwRecharge)
        self.set_well_package(gwAbstraction)

        # execute MODFLOW
        logger.info("Executing MODFLOW.")
        self.pcr_modflow.run()

        # TODO: Add the mechanism to check whether a run has converged or not.

        # obtaining the results from modflow simulation
        self.groundwaterHeadLayer2 = None
        self.groundwaterHeadLayer2 = self.pcr_modflow.getHeads(2)
        self.groundwaterHeadLayer1 = None
        self.groundwaterHeadLayer1 = self.pcr_modflow.getHeads(1)

        # calculate groundwater depth only in the landmask region
        self.groundwaterDepth = pcr.ifthen(
            self.landmask, self.dem_average - self.groundwaterHeadLayer2)
logger.info(msg)
#
for i_year in range(str_year, end_year + 1):

    for var in variable_names:

        msg = "Merging for the variable " + str(var) + " for the year " + str(
            i_year)
        logger.info(msg)

        # time index for this year
        time_index_in_netcdf_file = i_year - str_year + 1

        value_from_the_hydrological_year_1 = vos.netcdf2PCRobjClone(input_files['file_name']["hydrological_year_1"][var], \
                                                                    varDict.netcdf_short_name[var], time_index_in_netcdf_file,\
                                                                    useDoy = "Yes",
                                                                    cloneMapFileName  = clone_map_file,\
                                                                    LatitudeLongitude = True,\
                                                                    specificFillValue = None)

        value_from_the_hydrological_year_2 = vos.netcdf2PCRobjClone(input_files['file_name']["hydrological_year_2"][var], \
                                                                    varDict.netcdf_short_name[var], time_index_in_netcdf_file,\
                                                                    useDoy = "Yes",
                                                                    cloneMapFileName  = clone_map_file,\
                                                                    LatitudeLongitude = True,\
                                                                    specificFillValue = None)

        # merging two hydrological years
        value_for_this_year = pcr.ifthenelse(pcr.scalar(hydro_year_type) == 1, value_from_the_hydrological_year_1, \
                                                                               value_from_the_hydrological_year_2)
        value_for_this_year = pcr.cover(value_for_this_year, 0.0)
Ejemplo n.º 21
0
    for iYear in range(staYear,endYear+1):
        
        # time stamp and index for netcdf files:
        index = index + 1
        timeStamp = datetime.datetime(int(iYear), int(12), int(31), int(0))
        fulldate = '%4i-%02i-%02i'  %(int(iYear), int(12), int(31))
        print fulldate

        # reading pcraster files:
        for var in inputFiles.keys():        
            print inputFiles[var]
            if var != "area_equipped_with_irrigation":
                output[var]['pcr_value'] = vos.netcdf2PCRobjClone(ncFile = inputFiles[var],\
                                                                  varName = "Automatic",\
                                                                  dateInput = fulldate,
                                                                  useDoy = None,
                                                                  cloneMapFileName  = cloneMapFileName,
                                                                  LatitudeLongitude = True,
                                                                  specificFillValue = None)
            else:
                output[var]['pcr_value'] = vos.netcdf2PCRobjClone(ncFile = inputFiles[var],\
                                                                  varName = "Automatic",\
                                                                  dateInput = fulldate,
                                                                  useDoy = "yearly",
                                                                  cloneMapFileName  = cloneMapFileName,
                                                                  LatitudeLongitude = True,
                                                                  specificFillValue = None)

        # calculating irrigation water consumption
        output['irrigation_water_consumption']['pcr_value'] = output['evaporation_from_irrigation']['pcr_value'] * \
                                                              vos.getValDivZero(output['irrigation_water_withdrawal']['pcr_value'], \
for var_name in ['channelStorage', 'floodVolume']: 
    
    msg  = "Applying gumbel parameters from the climate run: " + str(input_files["future"]['file_name'][var_name])
    msg += "    that are bias corrected to the baseline run: " + str(input_files["baseline"]['file_name'][var_name])
    msg += "                         and the historical run: " + str(input_files["historical"]['file_name'][var_name])
    logger.info(msg)

    # read gumbel parameters from : ['p_zero', 'location_parameter', 'scale_parameter']
    for run_type in ["future", "historical", "baseline"]:

        netcdf_input_file = input_files[run_type]['file_name'][var_name]
        #
        variable_name = str('p_zero') + "_of_" + varDict.netcdf_short_name[var_name]
        p_zero[run_type]   = vos.netcdf2PCRobjClone(netcdf_input_file,\
                                          variable_name,\
                                          1,\
                                          "Yes",\
                                          input_files['clone_map_05min'])
        #
        variable_name = str('location_parameter') + "_of_" + varDict.netcdf_short_name[var_name]
        location[run_type] = vos.netcdf2PCRobjClone(netcdf_input_file,\
                                          variable_name,\
                                          1,\
                                          "Yes",\
                                          input_files['clone_map_05min'])
        #
        variable_name = str('scale_parameter') + "_of_" + varDict.netcdf_short_name[var_name]
        scale[run_type]    = vos.netcdf2PCRobjClone(netcdf_input_file,\
                                          variable_name,\
                                          1,\
                                          "Yes",\
Ejemplo n.º 23
0
    def getParameterFiles(self, date_given, cellArea, ldd):

        # parameters for Water Bodies: fracWat
        #                              waterBodyIds
        #                              waterBodyOut
        #                              waterBodyArea
        #                              waterBodyTyp
        #                              waterBodyCap

        # cell surface area (m2) and ldd
        self.cellArea = cellArea
        ldd = pcr.ifthen(self.landmask, ldd)

        # date and year used for accessing/extracting water body information
        date_used = date_given
        if self.onlyNaturalWaterBodies == True:
            date_used = self.dateForNaturalCondition
        year_used = date_used[0:4]

        # fracWat = fraction of surface water bodies (dimensionless)
        self.fracWat = pcr.scalar(0.0)

        if self.useNetCDF:
            self.fracWat = vos.netcdf2PCRobjClone(self.ncFileInp,'fracWaterInp', \
                           date_used, useDoy = 'yearly',\
                           cloneMapFileName = self.cloneMap)
        self.fracWat = pcr.cover(self.fracWat, 0.0)
        self.fracWat = pcr.max(0.0, self.fracWat)
        self.fracWat = pcr.min(1.0, self.fracWat)

        self.waterBodyIds = pcr.nominal(0)  # waterBody ids
        self.waterBodyOut = pcr.boolean(0)  # waterBody outlets
        self.waterBodyArea = pcr.scalar(0.)  # waterBody surface areas

        # water body ids
        if self.useNetCDF:
            self.waterBodyIds = vos.netcdf2PCRobjClone(self.ncFileInp,'waterBodyIds', \
                                date_used, useDoy = 'yearly',\
                                cloneMapFileName = self.cloneMap)
        self.waterBodyIds = pcr.ifthen(\
                            pcr.scalar(self.waterBodyIds) > 0.,\
                            pcr.nominal(self.waterBodyIds))

        # water body outlets (correcting outlet positions)
        wbCatchment = pcr.catchmenttotal(pcr.scalar(1), ldd)
        self.waterBodyOut = pcr.ifthen(wbCatchment ==\
                            pcr.areamaximum(wbCatchment, \
                            self.waterBodyIds),\
                            self.waterBodyIds)     # = outlet ids
        self.waterBodyOut = pcr.ifthen(\
                            pcr.scalar(self.waterBodyIds) > 0.,\
                            self.waterBodyOut)
        # TODO: Please also consider endorheic lakes!

        # correcting water body ids
        self.waterBodyIds = pcr.ifthen(\
                            pcr.scalar(self.waterBodyIds) > 0.,\
                            pcr.subcatchment(ldd,self.waterBodyOut))

        # boolean map for water body outlets:
        self.waterBodyOut = pcr.ifthen(\
                            pcr.scalar(self.waterBodyOut) > 0.,\
                            pcr.boolean(1))

        # reservoir surface area (m2):
        if self.useNetCDF:
            resSfArea = 1000. * 1000. * \
                        vos.netcdf2PCRobjClone(self.ncFileInp,'resSfAreaInp', \
                        date_used, useDoy = 'yearly',\
                        cloneMapFileName = self.cloneMap)
        resSfArea = pcr.areaaverage(resSfArea, self.waterBodyIds)
        resSfArea = pcr.cover(resSfArea, 0.)

        # water body surface area (m2): (lakes and reservoirs)
        self.waterBodyArea = pcr.max(pcr.areatotal(\
                             pcr.cover(\
                             self.fracWat*self.cellArea, 0.0), self.waterBodyIds),
                             pcr.areaaverage(\
                             pcr.cover(resSfArea, 0.0) ,       self.waterBodyIds))
        self.waterBodyArea = pcr.ifthen(self.waterBodyArea > 0.,\
                             self.waterBodyArea)

        # correcting water body ids and outlets (exclude all water bodies with surfaceArea = 0)
        self.waterBodyIds = pcr.ifthen(self.waterBodyArea > 0.,
                                       self.waterBodyIds)
        self.waterBodyOut = pcr.ifthen(pcr.boolean(self.waterBodyIds),
                                       self.waterBodyOut)

        # water body types:
        # - 2 = reservoirs (regulated discharge)
        # - 1 = lakes (weirFormula)
        # - 0 = non lakes or reservoirs (e.g. wetland)
        self.waterBodyTyp = pcr.nominal(0)

        if self.useNetCDF:
            self.waterBodyTyp = vos.netcdf2PCRobjClone(self.ncFileInp,'waterBodyTyp', \
                                date_used, useDoy = 'yearly',\
                                cloneMapFileName = self.cloneMap)

        # excluding wetlands (waterBodyTyp = 0) in all functions related to lakes/reservoirs
        #
        self.waterBodyTyp = pcr.ifthen(\
                            pcr.scalar(self.waterBodyTyp) > 0,\
                            pcr.nominal(self.waterBodyTyp))
        self.waterBodyTyp = pcr.ifthen(\
                            pcr.scalar(self.waterBodyIds) > 0,\
                            pcr.nominal(self.waterBodyTyp))
        self.waterBodyTyp = pcr.areamajority(self.waterBodyTyp,\
                                             self.waterBodyIds)     # choose only one type: either lake or reservoir
        self.waterBodyTyp = pcr.ifthen(\
                            pcr.scalar(self.waterBodyTyp) > 0,\
                            pcr.nominal(self.waterBodyTyp))
        self.waterBodyTyp = pcr.ifthen(pcr.boolean(self.waterBodyIds),
                                       self.waterBodyTyp)

        # correcting lakes and reservoirs ids and outlets
        self.waterBodyIds = pcr.ifthen(
            pcr.scalar(self.waterBodyTyp) > 0, self.waterBodyIds)
        self.waterBodyOut = pcr.ifthen(
            pcr.scalar(self.waterBodyIds) > 0, self.waterBodyOut)

        # reservoir maximum capacity (m3):
        self.resMaxCap = pcr.scalar(0.0)
        self.waterBodyCap = pcr.scalar(0.0)

        if self.useNetCDF:
            self.resMaxCap = 1000. * 1000. * \
                             vos.netcdf2PCRobjClone(self.ncFileInp,'resMaxCapInp', \
                             date_used, useDoy = 'yearly',\
                             cloneMapFileName = self.cloneMap)
        self.resMaxCap = pcr.ifthen(self.resMaxCap > 0,\
                                    self.resMaxCap)
        self.resMaxCap = pcr.areaaverage(self.resMaxCap,\
                                         self.waterBodyIds)

        # water body capacity (m3): (lakes and reservoirs)
        self.waterBodyCap = pcr.cover(
            self.resMaxCap, 0.0)  # Note: Most of lakes have capacities > 0.
        self.waterBodyCap = pcr.ifthen(pcr.boolean(self.waterBodyIds),
                                       self.waterBodyCap)

        # correcting water body types:                                  # Reservoirs that have zero capacities will be assumed as lakes.
        self.waterBodyTyp = \
                 pcr.ifthen(pcr.scalar(self.waterBodyTyp) > 0.,\
                                       self.waterBodyTyp)
        self.waterBodyTyp = pcr.ifthenelse(self.waterBodyCap > 0.,\
                                           self.waterBodyTyp,\
                 pcr.ifthenelse(pcr.scalar(self.waterBodyTyp) == 2,\
                                           pcr.nominal(1),\
                                           self.waterBodyTyp))

        # final corrections:
        self.waterBodyTyp = pcr.ifthen(self.waterBodyArea > 0.,\
                                       self.waterBodyTyp)                     # make sure that all lakes and/or reservoirs have surface areas
        self.waterBodyTyp = \
                 pcr.ifthen(pcr.scalar(self.waterBodyTyp) > 0.,\
                                       self.waterBodyTyp)                     # make sure that only types 1 and 2 will be considered in lake/reservoir functions
        self.waterBodyIds = pcr.ifthen(pcr.scalar(self.waterBodyTyp) > 0.,\
                            self.waterBodyIds)                                # make sure that all lakes and/or reservoirs have ids
        self.waterBodyOut = pcr.ifthen(pcr.scalar(self.waterBodyIds) > 0.,\
                                                  self.waterBodyOut)          # make sure that all lakes and/or reservoirs have outlets

        # for a natural run (self.onlyNaturalWaterBodies == True)
        # which uses only the year 1900, assume all reservoirs are lakes
        if self.onlyNaturalWaterBodies == True and date_used == self.dateForNaturalCondition:
            logger.info(
                "Using only natural water bodies identified in the year 1900. All reservoirs in 1900 are assumed as lakes."
            )
            self.waterBodyTyp = \
             pcr.ifthen(pcr.scalar(self.waterBodyTyp) > 0.,\
                        pcr.nominal(1))

        # check that all lakes and/or reservoirs have types, ids, surface areas and outlets:
        test = pcr.defined(self.waterBodyTyp) & pcr.defined(self.waterBodyArea) &\
               pcr.defined(self.waterBodyIds) & pcr.boolean(pcr.areamaximum(pcr.scalar(self.waterBodyOut), self.waterBodyIds))
        a, b, c = vos.getMinMaxMean(
            pcr.cover(pcr.scalar(test), 1.0) - pcr.scalar(1.0))
        threshold = 1e-3
        if abs(a) > threshold or abs(b) > threshold:
            logger.warning(
                "Missing information in some lakes and/or reservoirs.")

        # cropping only in the landmask region:
        self.fracWat = pcr.ifthen(self.landmask, self.fracWat)
        self.waterBodyIds = pcr.ifthen(self.landmask, self.waterBodyIds)
        self.waterBodyOut = pcr.ifthen(self.landmask, self.waterBodyOut)
        self.waterBodyArea = pcr.ifthen(self.landmask, self.waterBodyArea)
        self.waterBodyTyp = pcr.ifthen(self.landmask, self.waterBodyTyp)
        self.waterBodyCap = pcr.ifthen(self.landmask, self.waterBodyCap)
Ejemplo n.º 24
0
# return periods (must be increasing)
return_periods = ["2-year", "5-year", "10-year", "25-year", "50-year", "100-year", "250-year", "500-year", "1000-year"]
#
for var_name in variable_name_list: 
    
    msg = "Applying gumbel parameters from the file: " + str(input_files['file_name'][var_name])
    logger.info(msg)

    netcdf_input_file = input_files['file_name'][var_name]
    
    # read gumbel parameters: ['p_zero', 'location_parameter', 'scale_parameter']
    #
    variable_name = str('p_zero') + "_of_" + varDict.netcdf_short_name[var_name]
    p_zero   = vos.netcdf2PCRobjClone(netcdf_input_file,\
                                      variable_name,\
                                      1,\
                                      "Yes",\
                                      input_files['clone_map_05min'])
    #
    variable_name = str('location_parameter') + "_of_" + varDict.netcdf_short_name[var_name]
    location = vos.netcdf2PCRobjClone(netcdf_input_file,\
                                      variable_name,\
                                      1,\
                                      "Yes",\
                                      input_files['clone_map_05min'])
    #
    variable_name = str('scale_parameter') + "_of_" + varDict.netcdf_short_name[var_name]
    scale    = vos.netcdf2PCRobjClone(netcdf_input_file,\
                                      variable_name,\
                                      1,\
                                      "Yes",\
# assumption for minimum surface water level
minimum_fraction_of_surface_water = 0.005
msg = "Using the assumption for minimum_fraction_of_surface_water: " + str(minimum_fraction_of_surface_water)
#
for i_year in range(str_year, end_year + 1):
    
    msg = "Calculate surface water level at 5 arc-min resolution for the year: " + str(i_year)
    logger.info(msg)
    
    # time index for this year (for reading netcdf file
    time_index_in_netcdf_file = i_year - str_year + 1

    # read channel storage  (unit: m3)
    channel_storage = vos.netcdf2PCRobjClone(input_files['file_name']['channelStorage'], \
                                             "channel_storage", time_index_in_netcdf_file,\
                                             useDoy = "Yes", \
                                             cloneMapFileName  = clone_map_file,\
                                             LatitudeLongitude = True,\
                                             specificFillValue = None)
    channel_storage = pcr.ifthen(landmask, pcr.cover(channel_storage, 0.0))
    
    # read fraction_of_surface_water (dimensionless)
    fraction_of_surface_water = vos.netcdf2PCRobjClone(input_files['file_name']['dynamicFracWat'], \
                                                       "fraction_of_surface_water", time_index_in_netcdf_file,\
                                                       useDoy = "Yes", \
                                                       cloneMapFileName  = clone_map_file,\
                                                       LatitudeLongitude = True,\
                                                       specificFillValue = None)
    fraction_of_surface_water = pcr.ifthen(landmask, pcr.cover(fraction_of_surface_water, 0.0))
    
    # calculate surface water level
    surface_water_level = channel_storage / (pcr.max(fraction_of_surface_water, minimum_fraction_of_surface_water) * cell_area)
Ejemplo n.º 26
0
basin_map = pcr.clump(basin_map)
basin_map = pcr.ifthen(landmask, basin_map)
pcr.report(basin_map, "basin_map.map")
#~ pcr.aguila(basin_map)
# - calculate the basin area
basin_area = pcr.areatotal(cell_area, basin_map)
pcr.report(basin_area, "basin_area.map")
#~ pcr.aguila(basin_area)

# finding the month that give the maximum discharge (from the climatology time series)
msg = "Identifying the month with peak discharge (from climatology time series):"
logger.info(msg)
# - read the maximum monthly discharge for every basin
maximum_discharge = vos.netcdf2PCRobjClone(input_files['maximumClimatologyDischargeMonthAvg'], \
                                           "discharge", 1,\
                                           useDoy = "Yes",
                                           cloneMapFileName  = clone_map_file,\
                                           LatitudeLongitude = True,\
                                           specificFillValue = None)
maximum_discharge = pcr.areamaximum(\
                  pcr.cover(maximum_discharge, 0.0), basin_map)
# - find the month with maximum discharge
maximum_month = pcr.spatial(pcr.scalar(1.0))
for i_month in range(1, 12 + 1):
    # read the climatology discharge time series
    discharge_for_this_month = vos.netcdf2PCRobjClone(input_files['climatologyDischargeMonthAvg'], \
                                                      "discharge", i_month,\
                                                      useDoy = "Yes",
                                                      cloneMapFileName  = clone_map_file,\
                                                      LatitudeLongitude = True,\
                                                      specificFillValue = None)
    # upscale it to the basin scale
    # ignoring some variable names
    variable_names.pop('lat','')
    variable_names.pop('lon','')
    variable_names.pop('latiudes','')
    variable_names.pop('longitudes','')
    variable_names.pop('latiude','')
    variable_names.pop('longitude','')
    variable_names.pop('time','')
    # use the first variable
    variable_name = str(variable_names[0])
msg = 'Converting '+variable_name+' from the file:'+input_netcdf_filename+' to '+output_pcraster_filename
print msg    

# set date_yyyy_mm_dd
date_yyyy_mm_dd = None
if len(sys.argv) > 5: date_yyyy_mm_dd = sys.argv[5]

# read netcdf file
if date_yyyy_mm_dd == None:
    map_value = vos.netcdf2PCRobjCloneWithoutTime(input_netcdf_filename,\
                                                  variable_name,\
                                                  clone_map_filename)
else:                                                  
    map_value = vos.netcdf2PCRobjClone(input_netcdf_filename,\
                                       variable_name,\
                                       date_yyyy_mm_dd,\
                                       clone_map_filename)
    
# save the map as pcraster map
pcr.report(map_value, output_pcraster_filename)
        for iMonth in range(1,12+1):
            timeStamp = datetime.datetime(int(iYear),int(iMonth),int(1),int(0))

            fulldate = '%4i-%02i-%02i' %(int(iYear),int(iMonth),int(1))
            print fulldate

            monthRange = float(calendar.monthrange(int(iYear), int(iMonth))[1])
            print(monthRange)
            
            index = index + 1
            for iVar in range(0,len(varNames)):      
                
                # reading values from the input netcdf files (30min)
                demand_volume_30min = vos.netcdf2PCRobjClone(inputDirectory+inputFiles[iVar],\
                                                             inputVarNames[iVar],
                                                             fulldate,
                                                             None,
                                                             cloneMapFileName) * 1000.*1000./ monthRange   # unit: m3/day
                demand_volume_30min = pcr.ifthen(landmask, demand_volume_30min)
                
                # demand in m/day
                demand = demand_volume_30min /\
                         pcr.areatotal(cellArea, uniqueIDs30min)
                
                # covering the map with zero
                pcrValue = pcr.cover(demand, 0.0)  # unit: m/day                       

                # convert values to pcraster object
                varField = pcr.pcr2numpy(pcrValue, vos.MV)

                # write values to netcdf files
msg = "Using the assumption for minimum_fraction_of_surface_water: " + str(
    minimum_fraction_of_surface_water)
#
for i_year in range(str_year, end_year + 1):

    msg = "Calculate surface water level at half-arc degree resolution for the year: " + str(
        i_year)
    logger.info(msg)

    # time index for this year (for reading netcdf file
    time_index_in_netcdf_file = i_year - str_year + 1

    # read channel storage and upscale it to 30 arc-min (unit: m3)
    channel_storage = vos.netcdf2PCRobjClone(input_files['file_name']['channelStorage'], \
                                             "channel_storage", time_index_in_netcdf_file,\
                                             useDoy = "Yes", \
                                             cloneMapFileName  = clone_map_file,\
                                             LatitudeLongitude = True,\
                                             specificFillValue = None)
    channel_storage = pcr.ifthen(landmask, pcr.cover(channel_storage, 0.0))
    # - upscale it to 30 arc-min (unit: m3)
    channel_storage_30min = pcr.areatotal(channel_storage, cell_ids_30min)

    # read fraction_of_surface_water and upscale it to 30 arc-min (dimensionless)
    fraction_of_surface_water = vos.netcdf2PCRobjClone(input_files['file_name']['dynamicFracWat'], \
                                                       "fraction_of_surface_water", time_index_in_netcdf_file,\
                                                       useDoy = "Yes", \
                                                       cloneMapFileName  = clone_map_file,\
                                                       LatitudeLongitude = True,\
                                                       specificFillValue = None)
    fraction_of_surface_water = pcr.ifthen(
        landmask, pcr.cover(fraction_of_surface_water, 0.0))
Ejemplo n.º 30
0
    def getParameterFiles(self,currTimeStep,cellArea,ldd,\
                               initial_condition_dictionary = None,\
                               currTimeStepInDateTimeFormat = False):

        # parameters for Water Bodies: fracWat
        #                              waterBodyIds
        #                              waterBodyOut
        #                              waterBodyArea
        #                              waterBodyTyp
        #                              waterBodyCap

        # cell surface area (m2) and ldd
        self.cellArea = cellArea
        ldd = pcr.ifthen(self.landmask, ldd)

        # date used for accessing/extracting water body information
        if currTimeStepInDateTimeFormat:
            date_used = currTimeStep
            year_used = currTimeStep.year
        else:
            date_used = currTimeStep.fulldate
            year_used = currTimeStep.year
        if self.onlyNaturalWaterBodies == True:
            date_used = self.dateForNaturalCondition
            year_used = self.dateForNaturalCondition[0:4]

        # fracWat = fraction of surface water bodies (dimensionless)
        self.fracWat = pcr.scalar(0.0)

        if self.useNetCDF:
            self.fracWat = vos.netcdf2PCRobjClone(self.ncFileInp,'fracWaterInp', \
                           date_used, useDoy = 'yearly',\
                           cloneMapFileName = self.cloneMap)
        else:
            self.fracWat = vos.readPCRmapClone(\
                           self.fracWaterInp+str(year_used)+".map",
                           self.cloneMap,self.tmpDir,self.inputDir)

        self.fracWat = pcr.cover(self.fracWat, 0.0)
        self.fracWat = pcr.max(0.0, self.fracWat)
        self.fracWat = pcr.min(1.0, self.fracWat)

        self.waterBodyIds = pcr.nominal(0)  # waterBody ids
        self.waterBodyOut = pcr.boolean(0)  # waterBody outlets
        self.waterBodyArea = pcr.scalar(0.)  # waterBody surface areas

        # water body ids
        if self.useNetCDF:
            self.waterBodyIds = vos.netcdf2PCRobjClone(self.ncFileInp,'waterBodyIds', \
                                date_used, useDoy = 'yearly',\
                                cloneMapFileName = self.cloneMap)
        else:
            self.waterBodyIds = vos.readPCRmapClone(\
                self.waterBodyIdsInp+str(year_used)+".map",\
                self.cloneMap,self.tmpDir,self.inputDir,False,None,True)
        #
        self.waterBodyIds = pcr.ifthen(\
                            pcr.scalar(self.waterBodyIds) > 0.,\
                            pcr.nominal(self.waterBodyIds))

        # water body outlets (correcting outlet positions)
        wbCatchment = pcr.catchmenttotal(pcr.scalar(1), ldd)
        self.waterBodyOut = pcr.ifthen(wbCatchment ==\
                            pcr.areamaximum(wbCatchment, \
                            self.waterBodyIds),\
                            self.waterBodyIds) # = outlet ids           # This may give more than two outlets, particularly if there are more than one cells that have largest upstream areas
        # - make sure that there is only one outlet for each water body
        self.waterBodyOut = pcr.ifthen(\
                            pcr.areaorder(pcr.scalar(self.waterBodyOut), \
                            self.waterBodyOut) == 1., self.waterBodyOut)
        self.waterBodyOut = pcr.ifthen(\
                            pcr.scalar(self.waterBodyIds) > 0.,\
                            self.waterBodyOut)

        # TODO: Please also consider endorheic lakes!

        # correcting water body ids
        self.waterBodyIds = pcr.ifthen(\
                            pcr.scalar(self.waterBodyIds) > 0.,\
                            pcr.subcatchment(ldd,self.waterBodyOut))

        # boolean map for water body outlets:
        self.waterBodyOut = pcr.ifthen(\
                            pcr.scalar(self.waterBodyOut) > 0.,\
                            pcr.boolean(1))

        # reservoir surface area (m2):
        if self.useNetCDF:
            resSfArea = 1000. * 1000. * \
                        vos.netcdf2PCRobjClone(self.ncFileInp,'resSfAreaInp', \
                        date_used, useDoy = 'yearly',\
                        cloneMapFileName = self.cloneMap)
        else:
            resSfArea = 1000. * 1000. * vos.readPCRmapClone(
                   self.resSfAreaInp+str(year_used)+".map",\
                   self.cloneMap,self.tmpDir,self.inputDir)
        resSfArea = pcr.areaaverage(resSfArea, self.waterBodyIds)
        resSfArea = pcr.cover(resSfArea, 0.)

        # water body surface area (m2): (lakes and reservoirs)
        self.waterBodyArea = pcr.max(pcr.areatotal(\
                             pcr.cover(\
                             self.fracWat*self.cellArea, 0.0), self.waterBodyIds),
                             pcr.areaaverage(\
                             pcr.cover(resSfArea, 0.0) ,       self.waterBodyIds))
        self.waterBodyArea = pcr.ifthen(self.waterBodyArea > 0.,\
                             self.waterBodyArea)

        # correcting water body ids and outlets (exclude all water bodies with surfaceArea = 0)
        self.waterBodyIds = pcr.ifthen(self.waterBodyArea > 0.,
                                       self.waterBodyIds)
        self.waterBodyOut = pcr.ifthen(pcr.boolean(self.waterBodyIds),
                                       self.waterBodyOut)

        # water body types:
        # - 2 = reservoirs (regulated discharge)
        # - 1 = lakes (weirFormula)
        # - 0 = non lakes or reservoirs (e.g. wetland)
        self.waterBodyTyp = pcr.nominal(0)

        if self.useNetCDF:
            self.waterBodyTyp = vos.netcdf2PCRobjClone(self.ncFileInp,'waterBodyTyp', \
                                date_used, useDoy = 'yearly',\
                                cloneMapFileName = self.cloneMap)
        else:
            self.waterBodyTyp = vos.readPCRmapClone(
                self.waterBodyTypInp+str(year_used)+".map",\
                self.cloneMap,self.tmpDir,self.inputDir,False,None,True)

        # excluding wetlands (waterBodyTyp = 0) in all functions related to lakes/reservoirs
        #
        self.waterBodyTyp = pcr.ifthen(\
                            pcr.scalar(self.waterBodyTyp) > 0,\
                            pcr.nominal(self.waterBodyTyp))
        self.waterBodyTyp = pcr.ifthen(\
                            pcr.scalar(self.waterBodyIds) > 0,\
                            pcr.nominal(self.waterBodyTyp))
        self.waterBodyTyp = pcr.areamajority(self.waterBodyTyp,\
                                             self.waterBodyIds)     # choose only one type: either lake or reservoir
        self.waterBodyTyp = pcr.ifthen(\
                            pcr.scalar(self.waterBodyTyp) > 0,\
                            pcr.nominal(self.waterBodyTyp))
        self.waterBodyTyp = pcr.ifthen(pcr.boolean(self.waterBodyIds),
                                       self.waterBodyTyp)

        # correcting lakes and reservoirs ids and outlets
        self.waterBodyIds = pcr.ifthen(
            pcr.scalar(self.waterBodyTyp) > 0, self.waterBodyIds)
        self.waterBodyOut = pcr.ifthen(
            pcr.scalar(self.waterBodyIds) > 0, self.waterBodyOut)

        # reservoir maximum capacity (m3):
        self.resMaxCap = pcr.scalar(0.0)
        self.waterBodyCap = pcr.scalar(0.0)

        if self.useNetCDF:
            self.resMaxCap = 1000. * 1000. * \
                             vos.netcdf2PCRobjClone(self.ncFileInp,'resMaxCapInp', \
                             date_used, useDoy = 'yearly',\
                             cloneMapFileName = self.cloneMap)
        else:
            self.resMaxCap = 1000. * 1000. * vos.readPCRmapClone(\
                self.resMaxCapInp+str(year_used)+".map", \
                self.cloneMap,self.tmpDir,self.inputDir)

        self.resMaxCap = pcr.ifthen(self.resMaxCap > 0,\
                                    self.resMaxCap)
        self.resMaxCap = pcr.areaaverage(self.resMaxCap,\
                                         self.waterBodyIds)

        # water body capacity (m3): (lakes and reservoirs)
        self.waterBodyCap = pcr.cover(
            self.resMaxCap, 0.0)  # Note: Most of lakes have capacities > 0.
        self.waterBodyCap = pcr.ifthen(pcr.boolean(self.waterBodyIds),
                                       self.waterBodyCap)

        # correcting water body types:                                  # Reservoirs that have zero capacities will be assumed as lakes.
        self.waterBodyTyp = \
                 pcr.ifthen(pcr.scalar(self.waterBodyTyp) > 0.,\
                                       self.waterBodyTyp)
        self.waterBodyTyp = pcr.ifthenelse(self.waterBodyCap > 0.,\
                                           self.waterBodyTyp,\
                 pcr.ifthenelse(pcr.scalar(self.waterBodyTyp) == 2,\
                                           pcr.nominal(1),\
                                           self.waterBodyTyp))

        # final corrections:
        self.waterBodyTyp = pcr.ifthen(self.waterBodyArea > 0.,\
                                       self.waterBodyTyp)                     # make sure that all lakes and/or reservoirs have surface areas
        self.waterBodyTyp = \
                 pcr.ifthen(pcr.scalar(self.waterBodyTyp) > 0.,\
                                       self.waterBodyTyp)                     # make sure that only types 1 and 2 will be considered in lake/reservoir functions
        self.waterBodyIds = pcr.ifthen(pcr.scalar(self.waterBodyTyp) > 0.,\
                            self.waterBodyIds)                                # make sure that all lakes and/or reservoirs have ids
        self.waterBodyOut = pcr.ifthen(pcr.scalar(self.waterBodyIds) > 0.,\
                                                  self.waterBodyOut)          # make sure that all lakes and/or reservoirs have outlets

        # for a natural run (self.onlyNaturalWaterBodies == True)
        # which uses only the year 1900, assume all reservoirs are lakes
        if self.onlyNaturalWaterBodies == True and date_used == self.dateForNaturalCondition:
            logger.info(
                "Using only natural water bodies identified in the year 1900. All reservoirs in 1900 are assumed as lakes."
            )
            self.waterBodyTyp = \
             pcr.ifthen(pcr.scalar(self.waterBodyTyp) > 0.,\
                        pcr.nominal(1))

        # check that all lakes and/or reservoirs have types, ids, surface areas and outlets:
        test = pcr.defined(self.waterBodyTyp) & pcr.defined(self.waterBodyArea) &\
               pcr.defined(self.waterBodyIds) & pcr.boolean(pcr.areamaximum(pcr.scalar(self.waterBodyOut), self.waterBodyIds))
        a, b, c = vos.getMinMaxMean(
            pcr.cover(pcr.scalar(test), 1.0) - pcr.scalar(1.0))
        threshold = 1e-3
        if abs(a) > threshold or abs(b) > threshold:
            logger.warning(
                "Missing information in some lakes and/or reservoirs.")

        # at the beginning of simulation period (timeStepPCR = 1)
        # - we have to define/get the initial conditions
        #
        if initial_condition_dictionary != None and currTimeStep.timeStepPCR == 1:
            self.getICs(initial_condition_dictionary)

        # For each new reservoir (introduced at the beginning of the year)
        # initiating storage, average inflow and outflow
        # PS: THIS IS NOT NEEDED FOR OFFLINE MODFLOW RUN!
        #
        try:
            self.waterBodyStorage = pcr.cover(self.waterBodyStorage, 0.0)
            self.avgInflow = pcr.cover(self.avgInflow, 0.0)
            self.avgOutflow = pcr.cover(self.avgOutflow, 0.0)
            self.waterBodyStorage = pcr.ifthen(self.landmask,
                                               self.waterBodyStorage)
            self.avgInflow = pcr.ifthen(self.landmask, self.avgInflow)
            self.avgOutflow = pcr.ifthen(self.landmask, self.avgOutflow)
        except:
            # PS: FOR OFFLINE MODFLOW RUN!
            pass
        # TODO: Remove try and except

        # cropping only in the landmask region:
        self.fracWat = pcr.ifthen(self.landmask, self.fracWat)
        self.waterBodyIds = pcr.ifthen(self.landmask, self.waterBodyIds)
        self.waterBodyOut = pcr.ifthen(self.landmask, self.waterBodyOut)
        self.waterBodyArea = pcr.ifthen(self.landmask, self.waterBodyArea)
        self.waterBodyTyp = pcr.ifthen(self.landmask, self.waterBodyTyp)
        self.waterBodyCap = pcr.ifthen(self.landmask, self.waterBodyCap)
    msg += "    that are bias corrected to the baseline run: " + str(
        input_files["baseline"]['file_name'][var_name])
    msg += "                         and the historical run: " + str(
        input_files["historical"]['file_name'][var_name])
    logger.info(msg)

    # read gumbel parameters from : ['p_zero', 'location_parameter', 'scale_parameter']
    for run_type in ["future", "historical", "baseline"]:

        netcdf_input_file = input_files[run_type]['file_name'][var_name]
        #
        variable_name = str(
            'p_zero') + "_of_" + varDict.netcdf_short_name[var_name]
        p_zero[run_type]   = vos.netcdf2PCRobjClone(netcdf_input_file,\
                                          variable_name,\
                                          1,\
                                          "Yes",\
                                          input_files['clone_map_30min'])
        #
        variable_name = str('location_parameter'
                            ) + "_of_" + varDict.netcdf_short_name[var_name]
        location[run_type] = vos.netcdf2PCRobjClone(netcdf_input_file,\
                                          variable_name,\
                                          1,\
                                          "Yes",\
                                          input_files['clone_map_30min'])
        #
        variable_name = str(
            'scale_parameter') + "_of_" + varDict.netcdf_short_name[var_name]
        scale[run_type]    = vos.netcdf2PCRobjClone(netcdf_input_file,\
                                          variable_name,\
msg = "Merging two hydrologyical years for the following variables:"
logger.info(msg)
#
for i_year in range(str_year, end_year + 1):
    
    for var in variable_names:
        
        msg = "Merging for the variable " + str(var) + " for the year " + str(i_year)
        logger.info(msg)
        
        # time index for this year
        time_index_in_netcdf_file = i_year - str_year + 1
        
        value_from_the_hydrological_year_1 = vos.netcdf2PCRobjClone(input_files['file_name']["hydrological_year_1"][var], \
                                                                    varDict.netcdf_short_name[var], time_index_in_netcdf_file,\
                                                                    useDoy = "Yes",
                                                                    cloneMapFileName  = clone_map_file,\
                                                                    LatitudeLongitude = True,\
                                                                    specificFillValue = None)
        
        value_from_the_hydrological_year_2 = vos.netcdf2PCRobjClone(input_files['file_name']["hydrological_year_2"][var], \
                                                                    varDict.netcdf_short_name[var], time_index_in_netcdf_file,\
                                                                    useDoy = "Yes",
                                                                    cloneMapFileName  = clone_map_file,\
                                                                    LatitudeLongitude = True,\
                                                                    specificFillValue = None)
        
        # merging two hydrological years 
        value_for_this_year = pcr.ifthenelse(pcr.scalar(hydro_year_type) == 1, value_from_the_hydrological_year_1, \
                                                                               value_from_the_hydrological_year_2)
        value_for_this_year = pcr.cover(value_for_this_year, 0.0)
        
# return periods
return_periods = ["2-year", "5-year", "10-year", "25-year", "50-year", "100-year", "250-year", "500-year", "1000-year"]
#
for var_name in ['surfaceWaterLevel']: 
    
    msg = "Applying gumbel parameters from the file: " + str(input_files['file_name'][var_name])
    logger.info(msg)

    netcdf_input_file = input_files['file_name'][var_name]
    
    # read gumbel parameters: ['p_zero', 'location_parameter', 'scale_parameter']
    #
    variable_name = str('p_zero') + "_of_" + varDict.netcdf_short_name[var_name]
    p_zero   = vos.netcdf2PCRobjClone(netcdf_input_file,\
                                      variable_name,\
                                      1,\
                                      "Yes",\
                                      input_files['clone_map_30min'])
    #
    variable_name = str('location_parameter') + "_of_" + varDict.netcdf_short_name[var_name]
    location = vos.netcdf2PCRobjClone(netcdf_input_file,\
                                      variable_name,\
                                      1,\
                                      "Yes",\
                                      input_files['clone_map_30min'])
    #
    variable_name = str('scale_parameter') + "_of_" + varDict.netcdf_short_name[var_name]
    scale    = vos.netcdf2PCRobjClone(netcdf_input_file,\
                                      variable_name,\
                                      1,\
                                      "Yes",\