示例#1
0
def find_outlet(ldd):
    """
    Tries to find the outlet of the largest catchment in the Ldd

    Input:
        - Ldd

    Output:
        - outlet map (single point in the map)
    """
    largest = pcr.mapmaximum(pcr.catchmenttotal(pcr.spatial(pcr.scalar(1.0)), ldd))
    outlet = pcr.ifthen(
        pcr.catchmenttotal(1.0, ldd) == largest, pcr.spatial(pcr.scalar(1.0))
    )

    return outlet
示例#2
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)
示例#3
0
def find_outlet(ldd):
    """
    Tries to find the outlet of the largest catchment in the Ldd

    Input:
        - Ldd

    Output:
        - outlet map (single point in the map)
    """
    largest = pcr.mapmaximum(pcr.catchmenttotal(pcr.spatial(pcr.scalar(1.0)), ldd))
    outlet = pcr.ifthen(
        pcr.catchmenttotal(1.0, ldd) == largest, pcr.spatial(pcr.scalar(1.0))
    )

    return outlet
示例#4
0
 def initial(self):
     #####################
     # * initial section #
     #####################
     #-constants
     # betaQ [-]: constant of kinematic wave momentum equation
     self.betaQ = 0.6
     #-channel LDD
     self.channelLDD= pcr.ifthenelse(self.waterBodies.distribution != 0,\
      pcr.ldd(5),self.LDD)
     #-channel area and storage
     self.channelArea = self.channelWidth * self.channelLength
     self.channelStorageCapacity= pcr.ifthenelse(self.waterBodies.distribution == 0,\
      self.channelArea*self.channelDepth,pcr.scalar(0.))
     #-basin outlets
     self.basinOutlet = pcr.pit(self.LDD) != 0
     #-read initial conditions
     self.Q = clippedRead.get(self.QIniMap)
     self.actualStorage = clippedRead.get(self.actualStorageIniMap)
     self.actualStorage= pcr.ifthenelse(self.waterBodies.distribution != 0,\
      pcr.ifthenelse(self.waterBodies.location != 0,\
       pcr.areatotal(self.actualStorage,self.waterBodies.distribution),0),\
        self.actualStorage)
     self.waterBodies.actualStorage = self.waterBodies.retrieveMapValue(
         self.actualStorage)
     #-update targets of average and bankful discharge
     self.waterBodies.averageQ = self.waterBodies.retrieveMapValue(
         self.averageQ)
     self.waterBodies.bankfulQ = self.waterBodies.retrieveMapValue(
         self.bankfulQ)
     #-return the parameters for the kinematic wave,
     # including alpha, wetted area, flood fraction, flood volume and depth
     # and the corresponding land area
     floodedFraction,floodedDepth,\
      self.wettedArea,self.alphaQ= self.kinAlphaComposite(self.actualStorage,self.floodplainMask)
     self.wettedArea= self.waterBodies.returnMapValue(self.wettedArea,\
      self.waterBodies.channelWidth+2.*self.waterBodies.updateWaterHeight())
     self.waterFraction= pcr.ifthenelse(self.waterBodies.distribution == 0,\
      pcr.max(self.waterFractionMask,floodedFraction),self.waterFractionMask)
     self.landFraction = pcr.max(0., 1. - self.waterFraction)
     #-update on velocity and check on Q - NOTE: does not work in case of reservoirs!
     self.flowVelocity = pcr.ifthenelse(self.wettedArea > 0,
                                        self.Q / self.wettedArea, 0.)
     pcr.report(
         self.flowVelocity,
         pcrm.generateNameT(flowVelocityFileName,
                            0).replace('.000', '.ini'))
     #-setting initial values for specific runoff and surface water extraction
     self.landSurfaceQ = pcr.scalar(0.)
     self.potWaterSurfaceQ = pcr.scalar(0.)
     self.surfaceWaterExtraction = pcr.scalar(0.)
     #-budget check: setting initial values for cumulative discharge and
     # net cumulative input, including initial storage [m3]
     self.totalDischarge = pcr.scalar(0.)
     self.cumulativeDeltaStorage = pcr.catchmenttotal(
         self.actualStorage, self.LDD)
示例#5
0
    def additional_post_processing(self):
        # In this method/function, users can add their own post-processing.

        # consumption for and return flow from non irrigation water demand (unit: m/day)
        ## TODO self.nonIrrWaterConsumption = self._model.routing.nonIrrWaterConsumption
        ## TODO self.nonIrrReturnFlow       = self._model.routing.nonIrrReturnFlow

        # accumulated runoff (m3/s) along the drainage network - not including local changes in water bodies
        if "accuRunoff" in self.variables_for_report:
            self.accuRunoff = pcr.catchmenttotal(
                self.runoff * self._model.routing.cellArea,
                self._model.routing.lddMap) / vos.secondsPerDay()

        # accumulated baseflow (m3) along the drainage network
        if "accuBaseflow" in self.variables_for_report:
            self.accuBaseflow = pcr.catchmenttotal(
                self.baseflow * self._model.routing.cellArea,
                self._model.routing.lddMap)

        # local changes in water bodies (i.e. abstraction, return flow, evaporation, bed exchange), excluding runoff
        self.local_water_body_flux = self._model.routing.local_input_to_surface_water / self._model.routing.cellArea - self.runoff

        # total runoff (m) from local land surface runoff and local changes in water bodies
        self.totalRunoff = self.runoff + self.local_water_body_flux  # actually this is equal to self._model.routing.local_input_to_surface_water / self._model.routing.cellArea

        # accumulated total runoff (m3) along the drainage network - not including local changes in water bodies
        if "accuTotalRunoff" in self.variables_for_report:
            self.accuTotalRunoff = pcr.catchmenttotal(
                self.totalRunoff * self._model.routing.cellArea,
                self._model.routing.lddMap) / vos.secondsPerDay()

        # surfaceWaterStorage (unit: m) - negative values may be reported
        self.surfaceWaterStorage = self._model.routing.channelStorage / self._model.routing.cellArea

        # Stefanie's post processing: reporting lake and reservoir storage (unit: m3)
        self.waterBodyStorage = pcr.ifthen(self._model.routing.landmask, \
                                pcr.ifthen(\
                                pcr.scalar(self._model.routing.WaterBodies.waterBodyIds) > 0.,\
                                           self._model.routing.WaterBodies.waterBodyStorage))     # Note: This value is after lake/reservoir outflow.
示例#6
0
def getCatchmentMap(config, modLon, modLat, option="Reference options"):
    catchmentAreaMap = str(config.get(option, 'catchmentAreaMap'))
    cellAreaMap = str(config.get(option, 'cellAreaMap'))
    cellAreaConstant = str(config.get(option, 'cellAreaConstant'))
    routingMap = str(config.get(option, 'routingMap'))
    if os.path.exists(catchmentAreaMap):
        f = gdal.Open(catchmentAreaMap)
        catchmentArea = matchMaps(f, modLon, modLat)
        return catchmentArea
    elif os.path.exists(cellAreaMap) and os.path.exists(routingMap):
        pcr.setclone(routingMap)
        catchmentAcc = pcr.catchmenttotal(cellAreaMap, routingMap)
        catchmentArea = pcr.pcr2numpy(catchmentAcc, -9999.)
        return catchmentArea
    elif os.path.exists(cellAreaMap) and os.path.exists(routingMap):
        pcr.setclone(routingMap)
        catchmentAcc = pcr.catchmenttotal(pcr.scalar(cellAreaConstant),
                                          routingMap)
        catchmentArea = pcr.pcr2numpy(catchmentAcc, -9999.)
        return catchmentArea
    else:
        print "No valid catchment size and or routing map provided"
        return False
def getCatchmentMap(config, option="otherReference"):
    catchmentAreaMap = str(config.get(option, 'catchmentAreaMap'))
    cellAreaMap = str(config.get(option, 'cellAreaMap'))
    cellAreaConstant = str(config.get(option, 'cellAreaConstant'))
    routingMap = str(config.get(option, 'routingMap'))
    if os.path.exists(catchmentAreaMap):
        f = gdal.Open(catchmentAreaMap)
        catchmentArea = f.GetRasterBand(1).ReadAsArray()
        return catchmentArea
    elif os.path.exists(cellAreaMap) and os.path.exists(routingMap):
        pcr.setclone(routingMap)
        catchmentAcc = pcr.catchmenttotal(cellAreaMap, routingMap)
        catchmentArea = pcr.pcr2numpy(catchmentAcc, -9999.)
        return catchmentArea
    elif os.path.exists(cellAreaMap) and os.path.exists(routingMap):
        pcr.setclone(routingMap)
        catchmentAcc = pcr.catchmenttotal(pcr.scalar(cellAreaConstant),
                                          routingMap)
        catchmentArea = pcr.pcr2numpy(catchmentAcc, -9999.)
        return catchmentArea
    else:
        print "No valid catchment size and or routing map provided"
        return False
 def budgetCheck(self, sample, timestep):
     # NOTE this is only valid if addition,subtraction and lateral flow are invoked EACH TIME STEP
     # NOTE this does not include amountOfMoistureThickNetAdded in case of regolith thickness change
     self.actualAdditionCum = self.actualAdditionCum + self.actualAdditionFlux * self.timeStepDuration
     self.actualAbstractionCum = self.actualAbstractionCum + self.actualAbstractionFlux * self.timeStepDuration
     self.upwardSeepageCum = self.upwardSeepageCum + self.upwardSeepageFlux * self.timeStepDuration
     self.lateralFlowFluxAmountCum = self.lateralFlowFluxAmountCum + self.lateralFlowFluxAmount
     self.increaseInSubsurfaceStorage = self.soilMoistureThick - self.initialSoilMoistureThick
     budget = pcr.catchmenttotal(self.actualAdditionCum - self.increaseInSubsurfaceStorage - self.actualAbstractionCum
            - self.upwardSeepageCum, self.ldd) \
            - self.lateralFlowFluxAmountCum
     pcr.report(budget, pcrfw.generateNameST('B-sub', sample, timestep))
     pcr.report(budget / self.lateralFlowFluxAmountCum,
                pcrfw.generateNameST('BR-sub', sample, timestep))
     return self.increaseInSubsurfaceStorage, self.lateralFlowFluxAmountCum, self.actualAbstractionCum
	def initial(self):
		#####################
		# * initial section #
		#####################
		#-constants
		# betaQ [-]: constant of kinematic wave momentum equation
		self.betaQ= 0.6
		#-channel LDD
		self.channelLDD= pcr.ifthenelse(self.waterBodies.distribution != 0,\
			pcr.ldd(5),self.LDD)
		#-channel area and storage
		self.channelArea= self.channelWidth*self.channelLength
		self.channelStorageCapacity= pcr.ifthenelse(self.waterBodies.distribution == 0,\
			self.channelArea*self.channelDepth,pcr.scalar(0.))
		#-basin outlets
		self.basinOutlet= pcr.pit(self.LDD) != 0
		#-read initial conditions
		self.Q= clippedRead.get(self.QIniMap)
		self.actualStorage= clippedRead.get(self.actualStorageIniMap)
		self.actualStorage= pcr.ifthenelse(self.waterBodies.distribution != 0,\
			pcr.ifthenelse(self.waterBodies.location != 0,\
				pcr.areatotal(self.actualStorage,self.waterBodies.distribution),0),\
					self.actualStorage)   
		self.waterBodies.actualStorage= self.waterBodies.retrieveMapValue(self.actualStorage)
		#-update targets of average and bankful discharge
		self.waterBodies.averageQ= self.waterBodies.retrieveMapValue(self.averageQ)
		self.waterBodies.bankfulQ= self.waterBodies.retrieveMapValue(self.bankfulQ)
		#-return the parameters for the kinematic wave,
		# including alpha, wetted area, flood fraction, flood volume and depth
		# and the corresponding land area
		floodedFraction,floodedDepth,\
			self.wettedArea,self.alphaQ= self.kinAlphaComposite(self.actualStorage,self.floodplainMask)
		self.wettedArea= self.waterBodies.returnMapValue(self.wettedArea,\
			self.waterBodies.channelWidth+2.*self.waterBodies.updateWaterHeight())
		self.waterFraction= pcr.ifthenelse(self.waterBodies.distribution == 0,\
			pcr.max(self.waterFractionMask,floodedFraction),self.waterFractionMask)
		self.landFraction= pcr.max(0.,1.-self.waterFraction)
		#-update on velocity and check on Q - NOTE: does not work in case of reservoirs!
		self.flowVelocity= pcr.ifthenelse(self.wettedArea > 0,self.Q/self.wettedArea,0.)
		pcr.report(self.flowVelocity,pcrm.generateNameT(flowVelocityFileName,0).replace('.000','.ini'))
		#-setting initial values for specific runoff and surface water extraction
		self.landSurfaceQ= pcr.scalar(0.)
		self.potWaterSurfaceQ= pcr.scalar(0.)
		self.surfaceWaterExtraction= pcr.scalar(0.)
		#-budget check: setting initial values for cumulative discharge and 
		# net cumulative input, including initial storage [m3]   
		self.totalDischarge= pcr.scalar(0.)
		self.cumulativeDeltaStorage= pcr.catchmenttotal(self.actualStorage,self.LDD)
示例#10
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)
示例#11
0
def riverlength(ldd, order):
    """
    Determines the length of a river using the ldd.
    only determined for order and higher.

    Input:
        - ldd, order (streamorder)

    Returns:
        - totallength,lengthpercell, streamorder
    """
    strorder = pcr.streamorder(ldd)
    strorder = pcr.ifthen(strorder >= pcr.ordinal(order), strorder)
    dist = pcr.max(pcr.celllength(),
                   pcr.ifthen(pcr.boolean(strorder), pcr.downstreamdist(ldd)))

    return pcr.catchmenttotal(pcr.cover(dist, 0), ldd), dist, strorder
示例#12
0
def riverlength(ldd, order):
    """
    Determines the length of a river using the ldd.
    only determined for order and higher.

    Input:
        - ldd, order (streamorder)

    Returns:
        - totallength,lengthpercell, streamorder
    """
    strorder = pcr.streamorder(ldd)
    strorder = pcr.ifthen(strorder >= pcr.ordinal(order), strorder)
    dist = pcr.max(
        pcr.celllength(), pcr.ifthen(pcr.boolean(strorder), pcr.downstreamdist(ldd))
    )

    return pcr.catchmenttotal(pcr.cover(dist, 0), ldd), dist, strorder
示例#13
0
                                output_files['tmp_folder'],
                                None, False, None, True))
#~ pcr.aguila(basin_map)
# - extend/extrapolate the basin
basin_map = pcr.cover(basin_map, pcr.windowmajority(basin_map, 0.5))
basin_map = pcr.cover(basin_map, pcr.windowmajority(basin_map, 0.5))
basin_map = pcr.cover(basin_map, pcr.windowmajority(basin_map, 0.5))
basin_map = pcr.cover(basin_map, pcr.windowmajority(basin_map, 1.0))
basin_map = pcr.cover(basin_map, pcr.windowmajority(basin_map, 1.5))
basin_map = pcr.ifthen(landmask, basin_map)
#~ pcr.aguila(basin_map)

msg = "Redefining the basin map (so that it is consistent with the ldd map used in PCR-GLOBWB):"
logger.info(msg)
# - calculate the upstream area of every pixel:
upstream_area = pcr.catchmenttotal(cell_area, ldd)
# - calculate the catchment area of every basin:
upstream_area_maximum = pcr.areamaximum(upstream_area, basin_map)
# - identify the outlet of every basin (in order to rederive the basin so that it is consistent with the ldd)
outlet = pcr.nominal(
    pcr.uniqueid(
        pcr.ifthen(upstream_area == upstream_area_maximum, pcr.boolean(1.0))))
# - ignoring outlets with small upstream areas
threshold = 50. * 1000. * 1000.  # unit: m2
outlet = pcr.ifthen(upstream_area_maximum > threshold, outlet)
#~ pcr.aguila(outlet)
outlet = pcr.cover(outlet, pcr.nominal(0.0))
# - recalculate the basin
basin_map = pcr.nominal(pcr.subcatchment(ldd, outlet))
basin_map = pcr.clump(basin_map)
basin_map = pcr.ifthen(landmask, basin_map)
示例#14
0
    def dynamic(self):
        self.counter += 1
        print(
            str(self.curdate.day) + '-' + str(self.curdate.month) + '-' +
            str(self.curdate.year) + '  t = ' + str(self.counter))

        #-Snow and rain fraction settings for non-glacier part of model cell
        SnowFrac = pcr.ifthenelse(self.SnowStore > 0,
                                  pcr.scalar(1 - self.GlacFrac), 0)
        RainFrac = pcr.ifthenelse(self.SnowStore == 0,
                                  pcr.scalar(1 - self.GlacFrac), 0)

        #-Read the precipitation time-series
        if self.precNetcdfFLAG == 1:
            #-read forcing by netcdf input
            Precip = self.netcdf2PCraster.netcdf2pcrDynamic(self, pcr, 'Prec')
        else:
            #-read forcing by map input
            Precip = pcr.readmap(pcrm.generateNameT(self.Prec, self.counter))
        PrecipTot = Precip
        #-Report Precip
        self.reporting.reporting(self, pcr, 'TotPrec', Precip)
        self.reporting.reporting(self, pcr, 'TotPrecF',
                                 Precip * (1 - self.GlacFrac))

        #-Temperature and determine reference evapotranspiration
        if self.tempNetcdfFLAG == 1:
            #-read forcing by netcdf input
            Temp = self.netcdf2PCraster.netcdf2pcrDynamic(self, pcr, 'Temp')
        else:
            #-read forcing by map input
            Temp = pcr.readmap(pcrm.generateNameT(self.Tair, self.counter))

        if self.ETREF_FLAG == 0:
            if self.TminNetcdfFLAG == 1:
                #-read forcing by netcdf input
                TempMin = self.netcdf2PCraster.netcdf2pcrDynamic(
                    self, pcr, 'Tmin')
            else:
                #-read forcing by map input
                TempMin = pcr.readmap(
                    pcrm.generateNameT(self.Tmin, self.counter))
            if self.TmaxNetcdfFLAG == 1:
                #-read forcing by netcdf input
                TempMax = self.netcdf2PCraster.netcdf2pcrDynamic(
                    self, pcr, 'Tmax')
            else:
                #-read forcing by map input
                TempMax = pcr.readmap(
                    pcrm.generateNameT(self.Tmax, self.counter))
            ETref = self.Hargreaves.Hargreaves(
                pcr, self.Hargreaves.extrarad(self, pcr), Temp, TempMax,
                TempMin)
        else:
            ETref = pcr.readmap(pcrm.generateNameT(self.ETref, self.counter))
        self.reporting.reporting(self, pcr, 'TotETref', ETref)
        self.reporting.reporting(self, pcr, 'TotETrefF',
                                 ETref * (1 - self.GlacFrac))

        #-Interception and effective precipitation
        if self.DynVegFLAG == 1:
            #-read dynamic processes dynamic vegetation
            Precip = self.dynamic_veg.dynamic(self, pcr, pcrm, np, Precip,
                                              ETref)

        elif self.KcStatFLAG == 0:
            #-Try to read the KC map series
            try:
                self.Kc = pcr.readmap(
                    pcrm.generateNameT(self.Kcmaps, self.counter))
                self.KcOld = self.Kc
            except:
                self.Kc = self.KcOld
        #-report mm effective precipitation for sub-basin averages
        if self.mm_rep_FLAG == 1 and self.Prec_mm_FLAG == 1 and (
                self.RoutFLAG == 1 or self.ResFLAG == 1 or self.LakeFLAG == 1):
            self.PrecSubBasinTSS.sample(
                pcr.catchmenttotal(Precip *
                                   (1 - self.GlacFrac), self.FlowDir) /
                pcr.catchmenttotal(1, self.FlowDir))

        #-Snow, rain, and glacier calculations for glacier fraction of cell
        if self.GlacFLAG:
            #-read dynamic processes glacier
            Rain_GLAC, Snow_GLAC, ActSnowMelt_GLAC, SnowR_GLAC, GlacMelt, GlacPerc, self.GlacR = self.glacier.dynamic(
                self, pcr, pd, Temp, Precip)
        #-If glacier module is not used, then
        else:
            Rain_GLAC = 0
            Snow_GLAC = 0
            ActSnowMelt_GLAC = 0
            self.TotalSnowStore_GLAC = 0
            SnowR_GLAC = 0
            self.GlacR = 0
            GlacMelt = 0
            GlacPerc = 0

        # Calculate snow and rain for non-glacier part of cell
        if self.SnowFLAG == 1:
            #-read dynamic processes snow
            Rain, self.SnowR, OldTotalSnowStore = self.snow.dynamic(
                self, pcr, Temp, Precip, Snow_GLAC, ActSnowMelt_GLAC, SnowFrac,
                RainFrac, SnowR_GLAC)
        else:
            Rain = Precip
            self.SnowR = 0
            OldTotalSnowStore = 0
            self.TotalSnowStore = 0
        #-Report Rain
        self.reporting.reporting(self, pcr, 'TotRain', Rain)
        self.reporting.reporting(self, pcr, 'TotRainF',
                                 Rain * (1 - self.GlacFrac) +
                                 Rain_GLAC)  # for entire cell

        #-Potential evapotranspiration
        ETpot = self.ET.ETpot(ETref, self.Kc)
        if self.ETOpenWaterFLAG == 1:
            self.ETOpenWater = self.ET.ETpot(ETref, self.kcOpenWater)
        #-Report ETpot
        self.reporting.reporting(self, pcr, 'TotETpot', ETpot)
        self.reporting.reporting(self, pcr, 'TotETpotF', ETpot * RainFrac)

        #-Rootzone calculations
        self.RootWater = self.RootWater + self.CapRise
        #-Calculate rootzone runoff
        tempvar = self.rootzone.RootRunoff(self, pcr, RainFrac, Rain)
        #-Rootzone runoff
        RootRunoff = tempvar[0]
        #-Infiltration
        Infil = tempvar[1]
        #-Report infiltration
        self.reporting.reporting(self, pcr, 'Infil', Infil)
        #-Updated rootwater content
        self.RootWater = pcr.ifthenelse(RainFrac > 0, self.RootWater + Infil,
                                        self.RootWater)

        #-Actual evapotranspiration
        if self.PlantWaterStressFLAG == 1:
            etreddry = self.ET.ks(self, pcr, ETpot)
        else:
            etreddry = pcr.max(
                pcr.min((self.RootWater - self.RootDry) /
                        (self.RootWilt - self.RootDry), 1), 0)
        self.reporting.reporting(self, pcr, 'PlantStress', 1 - etreddry)
        ETact = self.ET.ETact(pcr, ETpot, self.RootWater, self.RootSat,
                              etreddry, RainFrac)
        #-Report the actual evapotranspiration
        self.reporting.reporting(
            self, pcr, 'TotETact',
            ETact * (1 - self.openWaterFrac) +
            self.ETOpenWater * self.openWaterFrac)
        #-Actual evapotranspiration, corrected for rain fraction
        ActETact = ETact * RainFrac
        #-Report the actual evapotranspiration, corrected for rain fraction
        self.reporting.reporting(self, pcr, 'TotETactF', ActETact)
        if self.mm_rep_FLAG == 1 and self.ETa_mm_FLAG == 1 and (
                self.RoutFLAG == 1 or self.ResFLAG == 1 or self.LakeFLAG == 1):
            self.ETaSubBasinTSS.sample(
                pcr.catchmenttotal(ActETact, self.FlowDir) /
                pcr.catchmenttotal(1, self.FlowDir))
        #-Update rootwater content
        self.RootWater = pcr.max(self.RootWater - ETact, 0)

        #-Calculate drainage
        temp_RootDrain = self.rootzone.RootDrainage(
            pcr, self.RootWater, self.RootDrain, self.RootField, self.RootSat,
            self.RootDrainVel, self.RootTT)
        #-Calculate percolation
        temp_rootperc = self.rootzone.RootPercolation(pcr, self.RootWater,
                                                      self.SubWater,
                                                      self.RootField,
                                                      self.RootTT, self.SubSat)
        #-Total sum of water able to leave the soil
        RootOut = temp_RootDrain + temp_rootperc
        #-Calculate new values for drainage and percolation (to be used when RootOut > RootExcess)
        newdrain, newperc = self.rootzone.CalcFrac(pcr, self.RootWater,
                                                   self.RootField,
                                                   temp_RootDrain,
                                                   temp_rootperc)
        #-Determine whether the new values need to be used
        rootexcess = pcr.max(self.RootWater - self.RootField, 0)
        self.RootDrain = pcr.ifthenelse(RootOut > rootexcess, newdrain,
                                        temp_RootDrain)
        rootperc = pcr.ifthenelse(RootOut > rootexcess, newperc, temp_rootperc)
        #-Update the RootWater content
        # Roottemp = self.RootWater
        self.RootWater = self.RootWater - (self.RootDrain + rootperc)

        #-Report rootzone percolation, corrected for fraction
        self.reporting.reporting(self, pcr, 'TotRootPF',
                                 rootperc * (1 - self.GlacFrac))
        #-Report rootwater content
        self.reporting.reporting(self, pcr, 'StorRootW',
                                 self.RootWater * (1 - self.openWaterFrac))

        #-Sub soil calculations
        self.SubWater = self.SubWater + rootperc
        if self.GroundFLAG == 0:
            if self.SeepStatFLAG == 0:
                try:
                    self.SeePage = pcr.readmap(
                        pcrm.generateNameT(self.Seepmaps, self.counter))
                    self.SeepOld = self.SeePage
                except:
                    self.SeePage = self.SeepOld

            #-Report seepage
            self.reporting.reporting(self, pcr, 'TotSeepF',
                                     pcr.scalar(self.SeePage))
            self.SubWater = pcr.min(pcr.max(self.SubWater - self.SeePage, 0),
                                    self.SubSat)
            if self.mm_rep_FLAG == 1 and self.Seep_mm_FLAG == 1 and (
                    self.RoutFLAG == 1 or self.ResFLAG == 1
                    or self.LakeFLAG == 1):
                self.SeepSubBasinTSS.sample(
                    pcr.catchmenttotal(self.SeePage, self.FlowDir) /
                    pcr.catchmenttotal(1, self.FlowDir))
        #-Capillary rise
        self.CapRise = self.subzone.CapilRise(pcr, self.SubField,
                                              self.SubWater, self.CapRiseMax,
                                              self.RootWater, self.RootSat,
                                              self.RootField)
        #-Report capillary rise, corrected for fraction
        self.reporting.reporting(self, pcr, 'TotCapRF',
                                 self.CapRise * (1 - self.GlacFrac))
        #-Update sub soil water content
        self.SubWater = self.SubWater - self.CapRise
        if self.GroundFLAG == 1:  # sub percolation will be calculated instead of subdrainage
            subperc = self.subzone.SubPercolation(pcr, self.SubWater,
                                                  self.SubField, self.SubTT,
                                                  self.Gw, self.GwSat)
            ActSubPerc = subperc * (1 - self.GlacFrac)
            #-Report the subzone percolation, corrected for the fraction
            self.reporting.reporting(self, pcr, 'TotSubPF', ActSubPerc)
            #-Update sub soil water content
            self.SubWater = self.SubWater - subperc
        else:  # sub drainage will be calculated instead of sub percolation
            self.SubDrain = self.subzone.SubDrainage(pcr, self.SubWater,
                                                     self.SubField,
                                                     self.SubSat,
                                                     self.SubDrainVel,
                                                     self.SubDrain, self.SubTT)
            #-Report drainage from subzone
            self.reporting.reporting(self, pcr, 'TotSubDF', self.SubDrain)
            #-Update sub soil water content
            self.SubWater = self.SubWater - self.SubDrain
        #-Report rootwater content
        self.reporting.reporting(self, pcr, 'StorSubW',
                                 self.SubWater * (1 - self.openWaterFrac))

        #-Changes in soil water storage
        OldSoilWater = self.SoilWater
        self.SoilWater = (self.RootWater + self.SubWater) * (1 - self.GlacFrac)

        #-Rootzone runoff
        self.RootRR = RootRunoff * RainFrac * (1 - self.openWaterFrac)
        #-Report rootzone runoff, corrected for fraction
        self.reporting.reporting(self, pcr, 'TotRootRF', self.RootRR)
        #-Rootzone drainage
        self.RootDR = self.RootDrain * (1 - self.GlacFrac) * (
            1 - self.openWaterFrac)
        #-Report rootzone drainage, corrected for fraction
        self.reporting.reporting(self, pcr, 'TotRootDF', self.RootDR)
        #-Rain runoff
        self.RainR = self.RootRR + self.RootDR
        #-Report rain runoff
        self.reporting.reporting(self, pcr, 'TotRainRF', self.RainR)

        #-Groundwater calculations
        if self.GroundFLAG == 1:
            #-read dynamic processes groundwater
            self.groundwater.dynamic(self, pcr, ActSubPerc, GlacPerc)
        else:
            #-Use drainage from subsoil as baseflow
            self.BaseR = self.SubDrain
            #-Groundwater level as scaled between min and max measured gwl
            SoilAct = self.RootWater + self.SubWater
            SoilRel = (SoilAct - self.SoilMin) / (
                self.SoilMax - self.SoilMin
            )  # scale between 0 (dry) and 1 (wet)
            GWL = self.GWL_base - (SoilRel - 0.5) * self.GWL_base
            #-Report groundwater
            self.reporting.reporting(self, pcr, 'GWL', GWL)

        #-Report Total runoff
        TotR = self.BaseR + self.RainR + self.SnowR + self.GlacR
        self.reporting.reporting(self, pcr, 'TotRF', TotR)

        #-Routing for lake and/or reservoir modules
        if self.LakeFLAG == 1 or self.ResFLAG == 1:
            #-read dynamic processes advanced routing
            Q = self.advanced_routing.dynamic(self, pcr, pcrm, config, TotR,
                                              self.ETOpenWater, PrecipTot)

        #-Normal routing module
        elif self.RoutFLAG == 1:
            self.routing.dynamic(self, pcr, TotR)

            if self.GlacFLAG:
                #-read dynamic reporting processes glacier
                self.glacier.dynamic_reporting(self, pcr, pd, np)

        #-Water balance
        if self.GlacFLAG and self.GlacRetreat == 1:
            GlacTable_MODid = self.GlacTable.loc[:, ['FRAC_GLAC', 'ICE_DEPTH']]
            GlacTable_MODid['ICE_DEPTH'] = GlacTable_MODid[
                'ICE_DEPTH'] * GlacTable_MODid['FRAC_GLAC']
            GlacTable_MODid = GlacTable_MODid.groupby(
                GlacTable_MODid.index).sum()
            GlacTable_MODid.fillna(0., inplace=True)
            #-Report pcraster map of glacier depth
            iceDepth = pcr.numpy.zeros(self.ModelID_1d.shape)
            iceDepth[self.GlacierKeys] = GlacTable_MODid['ICE_DEPTH']
            iceDepth = iceDepth.reshape(self.ModelID.shape)
            iceDepth = pcr.numpy2pcr(pcr.Scalar, iceDepth, self.MV)
            iceDepth = pcr.ifthen(
                self.clone, iceDepth)  #-only use values where clone is True
            iceDepth = iceDepth * 1000  # in mm
            #-change in storage
            dS = ((self.RootWater - self.oldRootWater) + (self.SubWater - self.oldSubWater)) * (1-self.GlacFrac) + (self.Gw - self.oldGw) + \
             (self.TotalSnowStore-OldTotalSnowStore) + (iceDepth - self.oldIceDepth)
            #-set old state variables for glacier
            self.oldIceDepth = iceDepth
            iceDepth = None
            del iceDepth
            GlacTable_MODid = None
            del GlacTable_MODid
        elif self.GroundFLAG:
            #-change in storage
            dS = ((self.RootWater - self.oldRootWater) + (self.SubWater - self.oldSubWater)) * (1-self.GlacFrac) + (self.Gw - self.oldGw) + \
             (self.TotalSnowStore-OldTotalSnowStore)
            # set old state variables for groundwater
            self.oldGw = self.Gw
        else:
            #-change in storage
            dS = ((self.RootWater - self.oldRootWater) +
                  (self.SubWater - self.oldSubWater)) * (1 - self.GlacFrac) + (
                      self.TotalSnowStore - OldTotalSnowStore)

        #-water balance per time step
        if self.GroundFLAG:
            waterbalance = Precip - ActETact - self.BaseR - self.RainR - self.SnowR - self.GlacR - dS
        else:
            waterbalance = Precip - ActETact - self.BaseR - self.RainR - self.SnowR - dS - self.SeePage
        self.reporting.reporting(self, pcr, 'wbal', waterbalance)

        #-total water balance
        self.waterbalanceTot = self.waterbalanceTot + waterbalance
        #-report water balance and accumulated water balance
        if self.wbal_TSS_FLAG and (self.RoutFLAG == 1 or self.ResFLAG == 1
                                   or self.LakeFLAG == 1):
            self.wbalTSS.sample(
                pcr.catchmenttotal(waterbalance, self.FlowDir) /
                pcr.catchmenttotal(1., self.FlowDir))
            self.wbalTotTSS.sample(
                pcr.catchmenttotal(self.waterbalanceTot, self.FlowDir) /
                pcr.catchmenttotal(1., self.FlowDir))
        # set old state variables
        self.oldRootWater = self.RootWater
        self.oldSubWater = self.SubWater
        waterbalance = None
        del waterbalance
        dS = None
        del dS
        #-End of water balance calculations

        #-Sediment yield
        if self.SedFLAG == 1:
            #-determine runoff in mm per day
            if self.RoutFLAG == 1 or self.ResFLAG == 1 or self.LakeFLAG == 1:
                Runoff = (Q * 3600 * 24) / pcr.cellarea() * 1000
            else:
                Runoff = TotR

            #-MUSLE
            if self.SedModel == 1:
                #-read dynamic processes musle
                self.musle.dynamic(self, pcr, Runoff)

                #-sediment transport
                if self.SedTransFLAG == 1:
                    #-read dynamic sediment transport processes musle
                    self.sediment_transport.dynamic_musle(self, pcr)

            #-Modified Morgan-Morgan-Finney model
            if self.SedModel == 2:
                #-determine soil erosion in transport (G)
                G = self.mmf.dynamic(self, pcr, Precip, Runoff)

                #-sediment transport
                if self.SedTransFLAG == 1:
                    #-read dynamic sediment transport processes mmf
                    self.sediment_transport.dynamic_mmf(
                        self, pcr, Runoff, np, G)

        #-update current date
        self.curdate = self.curdate + self.datetime.timedelta(days=1)
示例#15
0
    def checkBudgets(self, currentSampleNumber, currentTimeStep):

        increaseInPrecipitationStore = 0.0 - self.d_exchangevariables.cumulativePrecipitation
        pcr.report(
            increaseInPrecipitationStore,
            pcrfw.generateNameST('incP', currentSampleNumber, currentTimeStep))

        increaseInInterceptionStore = self.d_interceptionuptomaxstore.budgetCheck(
            currentSampleNumber, currentTimeStep)
        pcr.report(
            increaseInInterceptionStore,
            pcrfw.generateNameST('incI', currentSampleNumber, currentTimeStep))

        increaseInSurfaceStore = self.d_surfaceStore.budgetCheck(
            currentSampleNumber, currentTimeStep)
        pcr.report(
            increaseInSurfaceStore,
            pcrfw.generateNameST('incS', currentSampleNumber, currentTimeStep))
        increaseInSurfaceStoreQM = pcr.catchmenttotal(
            increaseInSurfaceStore, self.ldd) * pcr.cellarea()
        pcr.report(
            increaseInSurfaceStoreQM,
            pcrfw.generateNameST('testb', currentSampleNumber,
                                 currentTimeStep))

        # let op: infiltration store is directly passed to subsurface store, thus is not a real store
        increaseInInfiltrationStore = self.d_infiltrationgreenandampt.budgetCheck(
            currentSampleNumber, currentTimeStep)

        increaseInSubSurfaceWaterStore, lateralFlowInSubsurfaceStore, abstractionFromSubSurfaceWaterStore = \
                                 self.d_subsurfaceWaterOneLayer.budgetCheck(currentSampleNumber, currentTimeStep)
        increaseInSubSurfaceStoreQM = pcr.catchmenttotal(
            increaseInSubSurfaceWaterStore, self.ldd) * pcr.cellarea()

        increaseInRunoffStoreCubicMetresInUpstreamArea = self.d_runoffAccuthreshold.budgetCheck(
        )

        totalIncreaseInStoresCubicMetresInUpstreamArea = 0.0
        stores = [
            increaseInPrecipitationStore, increaseInInterceptionStore,
            increaseInSurfaceStore, increaseInSubSurfaceWaterStore
        ]
        for store in stores:
            increaseInStoreCubicMetresInUpstreamArea = pcr.catchmenttotal(
                store, self.ldd) * pcr.cellarea()
            totalIncreaseInStoresCubicMetresInUpstreamArea = totalIncreaseInStoresCubicMetresInUpstreamArea + \
                                                           increaseInStoreCubicMetresInUpstreamArea

        pcr.report(
            totalIncreaseInStoresCubicMetresInUpstreamArea,
            pcrfw.generateNameST('inSt', currentSampleNumber, currentTimeStep))
        pcr.report(
            increaseInRunoffStoreCubicMetresInUpstreamArea,
            pcrfw.generateNameST('inRu', currentSampleNumber, currentTimeStep))
        pcr.report(
            pcr.catchmenttotal(self.d_exchangevariables.upwardSeepageFlux,
                               self.ldd) * pcr.cellarea(),
            pcrfw.generateNameST('inSe', currentSampleNumber, currentTimeStep))
        # total budget is total increase in stores plus the upward seepage flux for each ts that is passed to the next
        # timestep and thus not taken into account in the current timestep budgets
        budget = totalIncreaseInStoresCubicMetresInUpstreamArea + increaseInRunoffStoreCubicMetresInUpstreamArea + \
               lateralFlowInSubsurfaceStore * pcr.cellarea() + pcr.catchmenttotal(abstractionFromSubSurfaceWaterStore, self.ldd) * pcr.cellarea() + \
               pcr.catchmenttotal(self.d_exchangevariables.upwardSeepageFlux, self.ldd) * pcr.cellarea()
        pcr.report(
            budget,
            pcrfw.generateNameST('B-tot', currentSampleNumber,
                                 currentTimeStep))
        budgetRel = budget / increaseInRunoffStoreCubicMetresInUpstreamArea
        pcr.report(
            budgetRel,
            pcrfw.generateNameST('B-rel', currentSampleNumber,
                                 currentTimeStep))
示例#16
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)
示例#17
0
    def additional_post_processing(self):
        # In this method/function, users can add their own post-processing.

        # consumption for and return flow from non irrigation water demand (unit: m/day)
        self.nonIrrWaterConsumption = self._model.routing.nonIrrWaterConsumption
        self.nonIrrReturnFlow = self._model.routing.nonIrrReturnFlow

        # accumulated runoff (m3/s) along the drainage network - not including local changes in water bodies
        if "accuRunoff" in self.variables_for_report:
            self.accuRunoff = pcr.catchmenttotal(
                self.runoff * self._model.routing.cellArea,
                self._model.routing.lddMap) / vos.secondsPerDay()

        # accumulated baseflow (m3) along the drainage network
        if "accuBaseflow" in self.variables_for_report:
            self.accuBaseflow = pcr.catchmenttotal(
                self.baseflow * self._model.routing.cellArea,
                self._model.routing.lddMap)

        # local changes in water bodies (i.e. abstraction, return flow, evaporation, bed exchange), excluding runoff
        self.local_water_body_flux = self._model.routing.local_input_to_surface_water / \
            self._model.routing.cellArea - self.runoff

        # total runoff (m) from local land surface runoff and local changes in water bodies
        # actually this is equal to self._model.routing.local_input_to_surface_water / self._model.routing.cellArea
        self.totalRunoff = self.runoff + self.local_water_body_flux

        # accumulated total runoff (m3) along the drainage network - not including local changes in water bodies
        if "accuTotalRunoff" in self.variables_for_report:
            self.accuTotalRunoff = pcr.catchmenttotal(
                self.totalRunoff * self._model.routing.cellArea,
                self._model.routing.lddMap) / vos.secondsPerDay()

        # fossil groundwater storage
        self.storGroundwaterFossil = self._model.groundwater.storGroundwaterFossil

        # total groundwater storage: (non fossil and fossil)
        self.storGroundwaterTotal = self._model.groundwater.storGroundwater + \
            self._model.groundwater.storGroundwaterFossil

        # total active storage thickness (m) for the entire water column - not including fossil groundwater (unmetDemand)
        # - including: interception, snow, soil and non fossil groundwater
        self.totalActiveStorageThickness = pcr.ifthen(
            self._model.routing.landmask,
            self._model.routing.channelStorage / self._model.routing.cellArea +
            self._model.landSurface.totalSto +
            self._model.groundwater.storGroundwater)

        # total water storage thickness (m) for the entire water column:
        # - including: interception, snow, soil, non fossil groundwater and fossil groundwater (unmetDemand)
        # - this is usually used for GRACE comparison
        self.totalWaterStorageThickness = self.totalActiveStorageThickness + \
            self._model.groundwater.storGroundwaterFossil

        # surfaceWaterStorage (unit: m) - negative values may be reported
        self.surfaceWaterStorage = self._model.routing.channelStorage / \
            self._model.routing.cellArea

        # Menno's post proccessing: fractions of water sources (allocated for) satisfying water demand in each cell
        self.fracSurfaceWaterAllocation = pcr.ifthen(
            self._model.routing.landmask,
            vos.getValDivZero(
                self._model.landSurface.allocSurfaceWaterAbstract,
                self.totalGrossDemand, vos.smallNumber))
        self.fracSurfaceWaterAllocation = pcr.ifthenelse(
            self.totalGrossDemand < vos.smallNumber, 1.0,
            self.fracSurfaceWaterAllocation)
        #
        self.fracNonFossilGroundwaterAllocation = pcr.ifthen(
            self._model.routing.landmask,
            vos.getValDivZero(
                self._model.groundwater.allocNonFossilGroundwater,
                self.totalGrossDemand, vos.smallNumber))
        self.fracNonFossilGroundwaterAllocation = pcr.ifthenelse(
            self.totalGrossDemand < vos.smallNumber, 0.0,
            self.fracNonFossilGroundwaterAllocation)
        #
        self.fracOtherWaterSourceAllocation = pcr.ifthen(
            self._model.routing.landmask,
            vos.getValDivZero(self._model.groundwater.unmetDemand,
                              self.totalGrossDemand, vos.smallNumber))
        self.totalFracWaterSourceAllocation = self.fracSurfaceWaterAllocation + \
            self.fracNonFossilGroundwaterAllocation + \
            self.fracOtherWaterSourceAllocation

        # Stefanie's post processing: reporting lake and reservoir storage (unit: m3)
        self.waterBodyStorage = pcr.ifthen(
            self._model.routing.landmask,
            pcr.ifthen(
                pcr.scalar(self._model.routing.WaterBodies.waterBodyIds) > 0.,
                self._model.routing.WaterBodies.waterBodyStorage)
        )  # Note: This value is after lake/reservoir outflow.
        #
        # snowMelt (m/day)
        self.snowMelt = self._model.landSurface.snowMelt

        # soil moisture state from (approximately) the first 5 cm soil
        if self._model.landSurface.numberOfSoilLayers == 3:
            self.storUppSurface = self._model.landSurface.storUpp000005  # unit: m
            self.satDegUppSurface = self._model.landSurface.satDegUpp000005  # unit: percentage

        # reporting water balance from the land surface part (excluding surface water bodies)
        self.land_surface_water_balance = self._model.waterBalance

        # evaporation from irrigation areas (m/day) - values are average over the entire cell area
        if self._model.landSurface.includeIrrigation:
            self.evaporation_from_irrigation = self._model.landSurface.landCoverObj['irrPaddy'].actualET * \
                self._model.landSurface.landCoverObj['irrPaddy'].fracVegCover + \
                self._model.landSurface.landCoverObj['irrNonPaddy'].actualET * \
                self._model.landSurface.landCoverObj['irrNonPaddy'].fracVegCover
示例#18
0
 def dynamic(self):
     #####################
     # * dynamic section #
     #####################
     #-evaluation of the current date: return current month and the time step used
     #-reading in fluxes over land and water area for current time step [m/d]
     # and read in reservoir demand and surface water extraction [m3]
     try:
         self.landSurfaceQ = clippedRead.get(
             pcrm.generateNameT(landSurfaceQFileName,
                                self.currentTimeStep()))
     except:
         pass
     try:
         self.potWaterSurfaceQ = clippedRead.get(
             pcrm.generateNameT(waterSurfaceQFileName,
                                self.currentTimeStep()))
     except:
         pass
     #-surface water extraction and reservoir demand currently set to zero, should
     # be computed automatically and updated to reservoirs
     self.potSurfaceWaterExtraction = pcr.spatial(pcr.scalar(0.))
     #self.waterBodies.demand=  #self.reservoirDemandTSS.assignID(self.waterBodies.ID,self.currentTimeStep(),0.)*self.timeSec
     #-initialization of cumulative values of actual water extractions
     self.actWaterSurfaceQ = pcr.spatial(pcr.scalar(0.))
     self.actSurfaceWaterExtraction = pcr.spatial(pcr.scalar(0.))
     #-definition of sub-loop for routing scheme - explicit scheme has to satisfy Courant condition
     timeLimit= pcr.cellvalue(pcr.mapminimum((pcr.cover(pcr.ifthen(self.waterBodies.distribution == 0,\
      self.channelLength/self.flowVelocity),\
       self.timeSec/self.nrIterDefault)*self.timeSec/self.nrIterDefault)**0.5),1)[0]
     nrIter = int(self.timeSec / timeLimit)
     nrIter = min(nrIter, int(self.timeSec / 300.))
     while float(self.timeSec / nrIter) % 1 <> 0:
         nrIter += 1
     deltaTime = self.timeSec / nrIter
     #-sub-loop for current time step
     if self.currentDate.day == 1 or nrIter >= 24:
         print '\n*\tprocessing %s, currently using %d substeps of %d seconds\n' % \
          (self.currentDate.date(),nrIter,deltaTime)
     #-update discharge and storage
     for nrICur in range(nrIter):
         #-initializing discharge for the current sub-timestep and fill in values
         # for channels and at outlets of waterbodies
         # * channels *
         estQ= pcr.ifthenelse((self.actualStorage > 0.) & (self.waterBodies.distribution == 0) ,\
          (self.wettedArea/self.alphaQ)**(1./self.betaQ),0.)
         #estQ= pcr.ifthenelse((self.actualStorage > 0.) & (self.waterBodies.distribution == 0) ,\
         #0.5*(self.Q+(self.wettedArea/self.alphaQ)**(1./self.betaQ)),0.)
         #estQ= pcr.min(estQ,self.actualStorage/deltaTime)
         self.report(estQ, 'results/qest')
         self.Q = pcr.spatial(pcr.scalar(0.))
         self.Q= pcr.ifthenelse(self.waterBodies.distribution == 0,\
          pcr.kinematic(self.channelLDD,estQ,0.,self.alphaQ,\
           self.betaQ,1,deltaTime,self.channelLength),self.Q)
         # * water bodies *
         self.waterBodies.dischargeUpdate()
         self.Q = self.waterBodies.returnMapValue(self.Q,
                                                  self.waterBodies.actualQ)
         #-fluxes and resulting change in storage: first the local fluxes are evaluated
         # and aggregated over the water bodies where applicable; this includes the specific runoff [m/day/m2]
         # from input and the estimated extraction from surface water as volume per day [m3/day];
         # specific runoff from the land surface is always positive whereas the fluxes over the water surface
         # are potential, including discharge, and are adjusted to match the availabe storage; to this end,
         # surface water storage and fluxes over water bodies are totalized and assigned to the outlet;
         # discharge is updated in a separate step, after vertical fluxes are compared to the actual storage
         deltaActualStorage= ((self.landFraction*self.landSurfaceQ+\
          self.waterFraction*self.potWaterSurfaceQ)*self.cellArea-\
          self.potSurfaceWaterExtraction)*float(self.duration)/nrIter
         deltaActualStorage= pcr.ifthenelse(self.waterBodies.distribution != 0,\
          pcr.ifthenelse(self.waterBodies.location != 0,\
           pcr.areatotal(deltaActualStorage,self.waterBodies.distribution),0),\
            deltaActualStorage)
         adjustmentRatio= pcr.ifthenelse(deltaActualStorage < 0.,\
          pcr.min(1.,-self.actualStorage/deltaActualStorage),1.)
         self.actWaterSurfaceQ += adjustmentRatio * self.potWaterSurfaceQ
         self.actSurfaceWaterExtraction += adjustmentRatio * self.actSurfaceWaterExtraction
         deltaActualStorage *= adjustmentRatio
         #-local water balance check
         if testLocalWaterBalance:
             differenceActualStorage = self.actualStorage
             differenceActualStorage += deltaActualStorage
         #-overall water balance check: net input
         self.cumulativeDeltaStorage += pcr.catchmenttotal(
             deltaActualStorage, self.LDD)
         #-update storage first with local changes, then balance discharge with storage and update storage
         # with lateral flow and return value to water bodies
         self.actualStorage += deltaActualStorage
         self.actualStorage = pcr.max(0., self.actualStorage)
         self.Q = pcr.min(self.Q, self.actualStorage / deltaTime)
         deltaActualStorage = (-self.Q +
                               pcr.upstream(self.LDD, self.Q)) * deltaTime
         deltaActualStorage= pcr.ifthenelse(self.waterBodies.distribution != 0,\
          pcr.ifthenelse(self.waterBodies.location != 0,\
           pcr.areatotal(deltaActualStorage,self.waterBodies.distribution),0),\
            deltaActualStorage)
         self.actualStorage += deltaActualStorage
         self.actualStorage = pcr.max(0., self.actualStorage)
         self.waterBodies.actualStorage = self.waterBodies.retrieveMapValue(
             self.actualStorage)
         #-flooded fraction returned
         floodedFraction,floodedDepth,\
           self.wettedArea,self.alphaQ= self.kinAlphaComposite(self.actualStorage,self.floodplainMask)
         self.wettedArea= self.waterBodies.returnMapValue(self.wettedArea,\
          self.waterBodies.channelWidth+2.*self.waterBodies.updateWaterHeight())
         self.waterFraction= pcr.ifthenelse(self.waterBodies.distribution == 0,\
          pcr.max(self.waterFractionMask,floodedFraction),self.waterFractionMask)
         self.landFraction = pcr.max(0., 1. - self.waterFraction)
         self.flowVelocity = pcr.ifthenelse(self.wettedArea > 0,
                                            self.Q / self.wettedArea, 0.)
         #-local water balance check
         if testLocalWaterBalance:
             differenceActualStorage += deltaActualStorage
             differenceActualStorage -= self.actualStorage
             totalDifference = pcr.cellvalue(
                 pcr.maptotal(differenceActualStorage), 1)[0]
             minimumDifference = pcr.cellvalue(
                 pcr.mapminimum(differenceActualStorage), 1)[0]
             maximumDifference = pcr.cellvalue(
                 pcr.mapmaximum(differenceActualStorage), 1)[0]
             if abs(totalDifference) > 1.e-3:
                 print 'water balance error: total %e; min %e; max %e' %\
                  (totalDifference,minimumDifference,maximumDifference)
                 if reportLocalWaterBalance:
                     pcr.report(differenceActualStorage,
                                'mbe_%s.map' % self.currentDate.date())
         #-overall water balance check: updating cumulative discharge and total storage [m3]
         self.totalDischarge += self.Q * deltaTime
         self.totalStorage = pcr.catchmenttotal(self.actualStorage,
                                                self.LDD)
     #-check on occurrence of last day and report mass balance
     if self.currentDate == self.endDate:
         #-report initial maps
         pcr.report(self.Q, self.QIniMap)
         pcr.report(self.actualStorage, self.actualStorageIniMap)
         #-return relative and absolute water balance error per cell and
         # as total at basin outlets
         self.totalDischarge= pcr.ifthen((self.waterBodies.distribution == 0) | \
          (self.waterBodies.location != 0),self.totalDischarge)
         self.cumulativeDeltaStorage= pcr.ifthen((self.waterBodies.distribution == 0) | \
          (self.waterBodies.location != 0),self.cumulativeDeltaStorage)
         massBalanceError= self.totalStorage+self.totalDischarge-\
          self.cumulativeDeltaStorage
         relMassBalanceError = 1. + pcr.ifthenelse(
             self.cumulativeDeltaStorage <> 0.,
             massBalanceError / self.cumulativeDeltaStorage, 0.)
         totalMassBalanceError= pcr.cellvalue(pcr.maptotal(pcr.ifthen(self.basinOutlet,\
          massBalanceError)),1)[0]
         totalCumulativeDeltaStorage= pcr.cellvalue(pcr.maptotal(pcr.ifthen(self.basinOutlet,\
          self.cumulativeDeltaStorage)),1)[0]
         if totalCumulativeDeltaStorage > 0:
             totalRelativeMassBalanceError = 1. + totalMassBalanceError / totalCumulativeDeltaStorage
         else:
             totalRelativeMassBalanceError = 1.
         #-report maps and echo value
         pcr.report(massBalanceError, mbeFileName)
         pcr.report(relMassBalanceError, mbrFileName)
         print '\n*\ttotal global mass balance error [m3]: %8.3g' % totalMassBalanceError
         print '\n*\trelative global mass balance error [-]: %5.3f' % totalRelativeMassBalanceError
         #-echo to screen: total mass balance error and completion of run
         print '\trun completed'
     #-end of day: return states and fluxes
     #-get surface water attributes?
     if getSurfaceWaterAttributes:
         #-compute the following secondary variables:
         # surface water area [m2]: area given dynamic surface water fraction
         # residence time [days]: volume over discharge, assigned -1 in case discharge is zero
         # surface water depth [m], weighed by channel and floodplain volume
         surfaceWaterArea = self.waterFraction * self.cellArea
         surfaceWaterArea= pcr.ifthenelse(self.waterBodies.distribution != 0,\
           pcr.ifthenelse(self.waterBodies.location != 0,\
            pcr.areatotal(surfaceWaterArea,self.waterBodies.distribution),0),\
             surfaceWaterArea)
         surfaceWaterResidenceTime = pcr.ifthenelse(
             self.Q > 0., self.actualStorage / (self.Q * self.timeSec), -1)
         surfaceWaterDepth= pcr.ifthenelse(self.actualStorage > 0.,\
          pcr.max(0.,self.actualStorage-self.channelStorageCapacity)**2/\
           (self.actualStorage*surfaceWaterArea),0.)
         surfaceWaterDepth+= pcr.ifthenelse(self.actualStorage > 0.,\
          pcr.min(self.channelStorageCapacity,self.actualStorage)**2/(self.waterFractionMask*\
          self.cellArea*self.actualStorage),0.)
         #-reports: values at outlet of lakes or reservoirs are assigned to their full extent
         self.report(pcr.ifthenelse(self.waterBodies.distribution != 0,\
          pcr.areamaximum(surfaceWaterArea,self.waterBodies.distribution),surfaceWaterArea),\
           surfaceWaterAreaFileName)
         self.report(pcr.ifthenelse(self.waterBodies.distribution != 0,\
          pcr.areamaximum(surfaceWaterResidenceTime,self.waterBodies.distribution),surfaceWaterResidenceTime),\
           surfaceWaterResidenceTimeFileName)
         self.report(pcr.ifthenelse(self.waterBodies.distribution != 0,\
          pcr.areamaximum(surfaceWaterDepth,self.waterBodies.distribution),surfaceWaterDepth),\
           surfaceWaterDepthFileName)
     #-reports on standard output: values at outlet of lakes or reservoirs are assigned to their full extent
     self.report(
         pcr.ifthenelse(
             self.waterBodies.distribution != 0,
             pcr.areamaximum(self.flowVelocity,
                             self.waterBodies.distribution),
             self.flowVelocity), flowVelocityFileName)
     self.report(
         pcr.ifthenelse(
             self.waterBodies.distribution != 0,
             pcr.areamaximum(self.Q, self.waterBodies.distribution),
             self.Q), QFileName)
     self.report(pcr.ifthenelse(self.waterBodies.distribution == 0,\
      floodedFraction,0.),floodedFractionFileName)
     self.report(pcr.ifthenelse(self.waterBodies.distribution == 0,\
      floodedDepth,0.),floodedDepthFileName)
     self.report(self.actualStorage, actualStorageFileName)
     #-update date for time step and report relevant daily output
     self.currentDate = self.currentDate + datetime.timedelta(self.duration)
示例#19
0
def subcatch_order_b(
    ldd, oorder, sizelimit=0, fill=False, fillcomplete=False, stoporder=0
):
    """
    Determines subcatchments using the catchment order

    This version tries to keep the number op upstream/downstream catchment the
    small by first dederivingatchment connected to the major river(the order) given, and fill
    up from there.

    Input:
        - ldd
        - oorder - order to use
        - sizelimit - smallest catchments to include, default is all (sizelimit=0) in number of cells
        - if fill is set to True the higer order catchment are filled also
        - if fillcomplete is set to True the whole ldd is filled with catchments.


    :returns sc, dif, nldd; Subcatchment, Points, subcatchldd
    """
    # outl = find_outlet(ldd)
    # large = pcr.subcatchment(ldd,pcr.boolean(outl))

    if stoporder == 0:
        stoporder = oorder

    stt = pcr.streamorder(ldd)
    sttd = pcr.downstream(ldd, stt)
    pts = pcr.ifthen((pcr.scalar(sttd) - pcr.scalar(stt)) > 0.0, sttd)
    maxorder = pcraster.framework.getCellValue(pcr.mapmaximum(stt), 1, 1)
    dif = pcr.uniqueid(pcr.boolean(pcr.ifthen(stt == pcr.ordinal(oorder), pts)))

    if fill:
        for order in range(oorder, maxorder):
            m_pts = pcr.ifthen((pcr.scalar(sttd) - pcr.scalar(order)) > 0.0, sttd)
            m_dif = pcr.uniqueid(
                pcr.boolean(pcr.ifthen(stt == pcr.ordinal(order), m_pts))
            )
            dif = pcr.uniqueid(pcr.boolean(pcr.cover(m_dif, dif)))

        for myorder in range(oorder - 1, stoporder, -1):
            sc = pcr.subcatchment(ldd, pcr.nominal(dif))
            m_pts = pcr.ifthen((pcr.scalar(sttd) - pcr.scalar(stt)) > 0.0, sttd)
            m_dif = pcr.uniqueid(
                pcr.boolean(pcr.ifthen(stt == pcr.ordinal(myorder - 1), m_pts))
            )
            dif = pcr.uniqueid(
                pcr.boolean(pcr.cover(pcr.ifthen(pcr.scalar(sc) == 0, m_dif), dif))
            )

        if fillcomplete:
            sc = pcr.subcatchment(ldd, pcr.nominal(dif))
            cs, m_dif, stt = subcatch_order_a(ldd, stoporder)
            dif = pcr.uniqueid(
                pcr.boolean(
                    pcr.cover(
                        pcr.ifthen(pcr.scalar(sc) == 0, pcr.ordinal(m_dif)),
                        pcr.ordinal(dif),
                    )
                )
            )

    scsize = pcr.catchmenttotal(1, ldd)
    dif = pcr.ordinal(pcr.uniqueid(pcr.boolean(pcr.ifthen(scsize >= sizelimit, dif))))
    sc = pcr.subcatchment(ldd, dif)

    # Make pit ldd
    nldd = pcr.lddrepair(pcr.ifthenelse(pcr.cover(dif, 0) > 0, 5, ldd))

    return sc, dif, nldd
示例#20
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)
示例#21
0
    def evaluateAllModelResults(self,globalCloneMapFileName,\
                                catchmentClassFileName,\
                                lddMapFileName,\
                                cellAreaMapFileName,\
                                pcrglobwb_output,\
                                analysisOutputDir="",\
                                tmpDir = "/dev/shm/edwin_grdc_"):     

        # output directory for all analyses for all stations
        analysisOutputDir   = str(analysisOutputDir)
        self.chartOutputDir = analysisOutputDir+"/chart/"
        self.tableOutputDir = analysisOutputDir+"/table/"
        #
        if analysisOutputDir == "": self.chartOutputDir = "chart/"
        if analysisOutputDir == "": self.tableOutputDir = "table/"
        #
        # make the chart and table directories:
        os.system('rm -r '+self.chartOutputDir+"*")
        os.system('rm -r '+self.tableOutputDir+"*")
        os.makedirs(self.chartOutputDir)
        os.makedirs(self.tableOutputDir)
        
        # cloneMap for all pcraster operations
        pcr.setclone(globalCloneMapFileName)
        cloneMap = pcr.boolean(1)
        self.cell_size_in_arc_degree = vos.getMapAttributesALL(globalCloneMapFileName)['cellsize']
        
        lddMap = pcr.lddrepair(pcr.readmap(lddMapFileName))
        cellArea = pcr.scalar(pcr.readmap(cellAreaMapFileName))
        
        # The landMaskClass map contains the nominal classes for all landmask regions. 
        landMaskClass = pcr.nominal(cloneMap)  # default: if catchmentClassFileName is not given
        if catchmentClassFileName != None:
            landMaskClass = pcr.nominal(pcr.readmap(catchmentClassFileName))

        # model catchment areas and cordinates
        catchmentAreaAll = pcr.catchmenttotal(cellArea, lddMap) / (1000*1000)  # unit: km2
        xCoordinate = pcr.xcoordinate(cloneMap)
        yCoordinate = pcr.ycoordinate(cloneMap)

	print "Jaaaaaa"
        
        for id in self.list_of_grdc_ids: 

            logger.info("Evaluating simulated discharge to the grdc observation at "+str(self.attributeGRDC["id_from_grdc"][str(id)])+".")
            
            # identify model pixel
            self.identifyModelPixel(tmpDir,catchmentAreaAll,landMaskClass,xCoordinate,yCoordinate,str(id))

            # evaluate model results to GRDC data
            self.evaluateModelResultsToGRDC(str(id),pcrglobwb_output,catchmentClassFileName,tmpDir)
            
        # write the summary to a table 
        summary_file = analysisOutputDir+"summary.txt"
        #
        logger.info("Writing the summary for all stations to the file: "+str(summary_file)+".")
        #
        # prepare the file:
        summary_file_handle = open(summary_file,"w")
        #
        # write the header
        summary_file_handle.write( ";".join(self.grdc_dict_keys)+"\n")
        #
        # write the content
        for id in self.list_of_grdc_ids:
            rowLine  = ""
            for key in self.grdc_dict_keys: rowLine += str(self.attributeGRDC[key][str(id)]) + ";"   
            rowLine = rowLine[0:-1] + "\n"
            summary_file_handle.write(rowLine)
        summary_file_handle.close()           
def main():
	#-initialization
	# MVs
	MV= -999.
	# minimum catchment size to process
	catchmentSizeLimit= 0.0
	# period of interest, start and end year
	startYear= 1961
	endYear= 2010
	# maps
	cloneMapFileName= '/data/hydroworld/PCRGLOBWB20/input30min/global/Global_CloneMap_30min.map'
	lddFileName= '/data/hydroworld/PCRGLOBWB20/input30min/routing/lddsound_30min.map'
	cellAreaFileName= '/data/hydroworld/PCRGLOBWB20/input30min/routing/cellarea30min.map'
	# set clone 
	pcr.setclone(cloneMapFileName)
	# output
	outputPath= '/scratch/rens/reservedrecharge'
	percentileMapFileName= os.path.join(outputPath,'q%03d_cumsec.map')
	textFileName= os.path.join(outputPath,'groundwater_environmentalflow_%d.txt')
	fractionReservedRechargeMapFileName= os.path.join(outputPath,'fraction_reserved_recharge%d.map')
	fractionMinimumReservedRechargeMapFileName= os.path.join(outputPath,'minimum_fraction_reserved_recharge%d.map')
	# input
	inputPath= '/nfsarchive/edwin-emergency-backup-DO-NOT-DELETE/rapid/edwin/05min_runs_results/2015_04_27/non_natural_2015_04_27/global/netcdf/'
	# define data to be read from netCDF files
	ncData= {}
	variableName= 'totalRunoff'
	ncData[variableName]= {}
	ncData[variableName]['fileName']= os.path.join(inputPath,'totalRunoff_monthTot_output.nc')
	ncData[variableName]['fileRoot']= os.path.join(outputPath,'qloc')
	ncData[variableName]['annualAverage']= pcr.scalar(0)	
	variableName= 'gwRecharge'
	ncData[variableName]= {}
	ncData[variableName]['fileName']= os.path.join(inputPath,'gwRecharge_monthTot_output.nc')
	ncData[variableName]['fileRoot']= os.path.join(outputPath,'gwrec')
	ncData[variableName]['annualAverage']= pcr.scalar(0)
	variableName= 'discharge'
	ncData[variableName]= {}
	ncData[variableName]['fileName']= os.path.join(inputPath,'totalRunoff_monthTot_output.nc')
	ncData[variableName]['fileRoot']= os.path.join(outputPath,'qc')
	ncData[variableName]['annualAverage']= pcr.scalar(0)
	ncData[variableName]['mapStack']= np.array([])
	# percents and environmental flow condition set as percentile
	percents= range(10,110,10)
	environmentalFlowPercent= 10
	if environmentalFlowPercent not in percents:
		percents.append(environmentalFlowPercent)
		percents.sort()

	#-start
	# obtain attributes
	pcr.setclone(cloneMapFileName)
	cloneSpatialAttributes= spatialAttributes(cloneMapFileName)
	years= range(startYear,endYear+1)
	# output path
	if not os.path.isdir(outputPath):
		os.makedirs(outputPath)
	os.chdir(outputPath)
	# compute catchments
	ldd= pcr.readmap(lddFileName)
	cellArea= pcr.readmap(cellAreaFileName)
	catchments= pcr.catchment(ldd,pcr.pit(ldd))
	fractionWater= pcr.scalar(0.0) # temporary!
	lakeMask= pcr.boolean(0) # temporary!
	pcr.report(catchments,os.path.join(outputPath,'catchments.map'))
	maximumCatchmentID= int(pcr.cellvalue(pcr.mapmaximum(pcr.scalar(catchments)),1)[0])
	# iterate over years
	weight= float(len(years))**-1
	for year in years:
		#-echo year
		print ' - processing year %d' % year
		#-process data
		startDate= datetime.datetime(year,1,1)
		endDate= datetime.datetime(year,12,31)
		timeSteps= endDate.toordinal()-startDate.toordinal()+1
		dynamicIncrement= 1
		for variableName in ncData.keys():
			print '   extracting %s' % variableName,
			ncFileIn= ncData[variableName]['fileName']
			#-process data
			pcrDataSet= pcrObject(variableName, ncData[variableName]['fileRoot'],\
				ncFileIn,cloneSpatialAttributes, pcrVALUESCALE= pcr.Scalar, resamplingAllowed= True,\
				dynamic= True, dynamicStart= startDate, dynamicEnd= endDate, dynamicIncrement= dynamicIncrement, ncDynamicDimension= 'time')
			pcrDataSet.initializeFileInfo()
			pcrDataSet.processFileInfo()
			for fileInfo in pcrDataSet.fileProcessInfo.values()[0]:
				tempFileName= fileInfo[1]
				variableField= pcr.readmap(tempFileName)
				variableField= pcr.ifthen(pcr.defined(ldd),pcr.cover(variableField,0))
				if variableName == 'discharge':
					dayNumber= int(os.path.splitext(tempFileName)[1].strip('.'))
					date= datetime.date(year,1,1)+datetime.timedelta(dayNumber-1)
					numberDays= calendar.monthrange(year,date.month)[1]
					variableField= pcr.max(0,pcr.catchmenttotal(variableField*cellArea,ldd)/(numberDays*24*3600))
				ncData[variableName]['annualAverage']+= weight*variableField
				if 'mapStack' in ncData[variableName].keys():
					tempArray= pcr2numpy(variableField,MV)
					mask= tempArray != MV
					if ncData[variableName]['mapStack'].size != 0:
						ncData[variableName]['mapStack']= np.vstack((ncData[variableName]['mapStack'],tempArray[mask]))
					else:
						ncData[variableName]['mapStack']= tempArray[mask]
						coordinates= np.zeros((ncData[variableName]['mapStack'].size,2))
						pcr.setglobaloption('unitcell')
						tempArray= pcr2numpy(pcr.ycoordinate(pcr.boolean(1))+0.5,MV)
						coordinates[:,0]= tempArray[mask]
						tempArray= pcr2numpy(pcr.xcoordinate(pcr.boolean(1))+0.5,MV)
						coordinates[:,1]= tempArray[mask]      
				os.remove(tempFileName)				
			# delete object
			pcrDataSet= None
			del pcrDataSet
			# close line on screen
			print
	# report annual averages
	key= 'annualAverage'
	ncData['discharge'][key]/= 12
	for variableName in ncData.keys():
		ncData[variableName][key]= pcr.max(0,ncData[variableName][key])
		pcr.report(ncData[variableName][key],\
			os.path.join(outputPath,'%s_%s.map' % (variableName,key)))
	# remove aux.xml
	for tempFileName in os.listdir(outputPath):
		if 'aux.xml' in tempFileName:
			os.remove(tempFileName)
	# sort data
	print 'sorting discharge data'
	variableName= 'discharge'
	key= 'mapStack'
	indices= np.zeros((ncData[variableName][key].shape),np.uint)
	for iCnt in xrange(ncData[variableName][key].shape[1]):
		indices[:,iCnt]= ncData[variableName][key][:,iCnt].argsort(kind= 'mergesort')
		ncData[variableName][key][:,iCnt]= ncData[variableName][key][:,iCnt][indices[:,iCnt]]
	# extract values for percentiles
	print 'returning maps'
	for percent in percents:
		percentile= 0.01*percent
		index0= min(ncData[variableName][key].shape[0]-1,int(percentile*ncData[variableName][key].shape[0]))
		index1= min(ncData[variableName][key].shape[0]-1,int(percentile*ncData[variableName][key].shape[0])+1)
		x0= float(index0)/ncData[variableName][key].shape[0]
		x1= float(index1)/ncData[variableName][key].shape[0]
		if x0 <> x1:
			y= ncData[variableName][key][index0,:]+(percentile-x0)*\
				 (ncData[variableName][key][index1,:]-ncData[variableName][key][index0,:])/(x1-x0)
		else:
			y= ncData[variableName][key][index0,:]
		# convert a slice of the stack into an array
		tempArray= np.ones((cloneSpatialAttributes.numberRows,cloneSpatialAttributes.numberCols))*MV
		for iCnt in xrange(coordinates.shape[0]):
			row= coordinates[iCnt,0]-1
			col= coordinates[iCnt,1]-1
			tempArray[row,col]= y[iCnt]
		variableField= numpy2pcr(pcr.Scalar,tempArray,MV)
		pcr.report(variableField,percentileMapFileName % percent)
		if percent == environmentalFlowPercent:
			ncData[variableName]['environmentalFlow']= variableField
		tempArray= None; variableField= None
		del tempArray, variableField
	# process environmental flow
	# initialize map of reserved recharge fraction
	fractionReservedRechargeMap= pcr.ifthen(ncData[variableName]['environmentalFlow'] < 0,pcr.scalar(0))
	fractionMinimumReservedRechargeMap= pcr.ifthen(ncData[variableName]['environmentalFlow'] < 0,pcr.scalar(0))
	textFile= open(textFileName % environmentalFlowPercent,'w')
	hStr= 'Environmental flow analysis per basin, resulting in a map of renewable, exploitable recharge, for the %d%s quantile of discharge\n' % (environmentalFlowPercent,'%')
	hStr+= 'Returns Q_%d/R, the fraction of reserved recharge needed to sustain fully the environental flow requirement defined as the %d percentile,\n' % (environmentalFlowPercent, environmentalFlowPercent)
	hStr+= 'and Q*_%d/R, a reduced fraction that takes the availability of surface water into account\n' % environmentalFlowPercent
	textFile.write(hStr)
	print hStr
	# create header to display on screen and write to file
	# reported are: 1: ID, 2: Area, 3: average discharge, 4: environmental flow, 5: average recharge,
	# 6: Q_%d/Q, 7: Q_%d/R_Avg, 8: R_Avg/Q_Avg, 9: Q*_%d/R_Avg
	hStr= '%6s,%15s,%15s,%15s,%15s,%15s,%15s,%15s,%15s\n' % \
		('ID','Area [km2]','Q_Avg [m3]','Q_%d [m3]' % environmentalFlowPercent ,'R_Avg [m3]','Q_%d/Q_Avg [-]' % environmentalFlowPercent,\
			'Q_%d/Q_Avg [-]' % environmentalFlowPercent,'R_Avg/Q_Avg [-]','Q*_%d/Q_Avg [-]' % environmentalFlowPercent)
	textFile.write(hStr)
	print hStr
	for catchment in xrange(1,maximumCatchmentID+1):
		# create catchment mask and check whether it does not coincide with a lake
		catchmentMask= catchments == catchment
		catchmentSize= pcr.cellvalue(pcr.maptotal(pcr.ifthen(catchmentMask,cellArea*1.e-6)),1)[0]
		#~ ##~ if pcr.cellvalue(pcr.maptotal(pcr.ifthen(catchmentMask,pcr.scalar(lakeMask))),1) <> \
				#~ ##~ pcr.cellvalue(pcr.maptotal(pcr.ifthen(catchmentMask,pcr.scalar(catchmentMask))),1)[0] and \
				#~ ##~ catchmentSize > catchmentSizeLimit:
		key= 'annualAverage'
		variableName= 'discharge'			
		if bool(pcr.cellvalue(pcr.maptotal(pcr.ifthen((ldd == 5) & catchmentMask,\
				pcr.scalar(ncData[variableName][key] > 0))),1)[0]) and catchmentSize >= catchmentSizeLimit:
			# valid catchment, process
			# all volumes are in m3 per year
			key= 'annualAverage'
			catchmentAverageDischarge= pcr.cellvalue(pcr.mapmaximum(pcr.ifthen(catchmentMask & (ldd == 5),\
				ncData[variableName][key])),1)[0]*365.25*3600*24
			variableName= 'gwRecharge'
			catchmentRecharge= pcr.cellvalue(pcr.maptotal(pcr.ifthen(catchmentMask,ncData[variableName][key]*\
				(1.-fractionWater)*cellArea)),1)[0]
			variableName= 'totalRunoff'
			catchmentRunoff= pcr.cellvalue(pcr.maptotal(pcr.ifthen(catchmentMask,ncData[variableName][key]*\
				cellArea)),1)[0]
			key= 'environmentalFlow'
			variableName= 'discharge'			
			catchmentEnvironmentalFlow= pcr.cellvalue(pcr.mapmaximum(pcr.ifthen(catchmentMask & (ldd == 5),\
				ncData[variableName][key])),1)[0]*365.25*3600*24
			catchmentRunoff= max(catchmentRunoff,catchmentEnvironmentalFlow)
			if catchmentAverageDischarge > 0.:
				fractionEnvironmentalFlow= catchmentEnvironmentalFlow/catchmentAverageDischarge
				fractionGroundWaterContribution= catchmentRecharge/catchmentAverageDischarge
			else:
				fractionEnvironmentalFlow= 0.
				fractionGroundWaterContribution= 0.
			if catchmentRecharge > 0:
				fractionReservedRecharge= min(1,catchmentEnvironmentalFlow/catchmentRecharge)
			else:
				fractionReservedRecharge= 1.0
			fractionMinimumReservedRecharge= (fractionReservedRecharge+fractionGroundWaterContribution-\
				fractionReservedRecharge*fractionGroundWaterContribution)*fractionReservedRecharge
			#~ # echo to screen, and write to file and map
			wStr= '%6s,%15.1f,%15.6g,%15.6g,%15.6g,%15.6f,%15.6f,%15.6f,%15.6f\n' % \
				(catchment,catchmentSize,catchmentAverageDischarge,catchmentEnvironmentalFlow,catchmentRecharge,\
					fractionEnvironmentalFlow,fractionReservedRecharge,fractionGroundWaterContribution,fractionMinimumReservedRecharge)
			print wStr
			textFile.write(wStr)
			# update maps
			fractionReservedRechargeMap= pcr.ifthenelse(catchmentMask,\
				pcr.scalar(fractionReservedRecharge),fractionReservedRechargeMap)
			fractionMinimumReservedRechargeMap= pcr.ifthenelse(catchmentMask,\
				pcr.scalar(fractionMinimumReservedRecharge),fractionMinimumReservedRechargeMap)
	#-report map and close text file
	pcr.report(fractionReservedRechargeMap,fractionReservedRechargeMapFileName % environmentalFlowPercent)
	pcr.report(fractionMinimumReservedRechargeMap,fractionMinimumReservedRechargeMapFileName % environmentalFlowPercent)
	# close text file
	textFile.close()
	# finished
	print 'all done!'
示例#23
0
    def additional_post_processing(self):
        # In this method/function, users can add their own post-processing.

        # accumulated baseflow (m3/s) along the drainage network
        if "accuBaseflow" in self.variables_for_report:
            self.accuBaseflow = pcr.catchmenttotal(
                self.baseflow * self._model.routing.cellArea,
                self._model.routing.lddMap) / vos.secondsPerDay()

        # local changes in water bodies (i.e. abstraction, return flow, evaporation, bed exchange), excluding runoff
        self.local_water_body_flux = self._model.routing.local_input_to_surface_water / self._model.routing.cellArea - self.runoff

        # total runoff (m) from local land surface runoff and local changes in water bodies
        self.totalRunoff = self.runoff + self.local_water_body_flux  # actually this is equal to self._model.routing.local_input_to_surface_water / self._model.routing.cellArea

        # water body evaporation (m) - from surface water fractions only
        self.waterBodyActEvaporation = self._model.routing.waterBodyEvaporation
        self.waterBodyPotEvaporation = self._model.routing.waterBodyPotEvap
        #
        self.fractionWaterBodyEvaporation = vos.getValDivZero(self.waterBodyActEvaporation,\
                                                              self.waterBodyPotEvaporation,\
                                                              vos.smallNumber)

        # land surface evaporation (m)
        self.actualET = self._model.landSurface.actualET

        # fossil groundwater storage
        self.storGroundwaterFossil = self._model.groundwater.storGroundwaterFossil

        # total groundwater storage: (non fossil and fossil)
        self.storGroundwaterTotal  = self._model.groundwater.storGroundwater + \
                                     self._model.groundwater.storGroundwaterFossil

        # total active storage thickness (m) for the entire water column - not including fossil groundwater
        # - including: interception, snow, soil and non fossil groundwater
        self.totalActiveStorageThickness = pcr.ifthen(\
                                           self._model.routing.landmask, \
                                           self._model.routing.channelStorage / self._model.routing.cellArea + \
                                           self._model.landSurface.totalSto + \
                                           self._model.groundwater.storGroundwater)

        # total water storage thickness (m) for the entire water column:
        # - including: interception, snow, soil, non fossil groundwater and fossil groundwater
        # - this is usually used for GRACE comparison
        self.totalWaterStorageThickness  = self.totalActiveStorageThickness + \
                                           self._model.groundwater.storGroundwaterFossil

        # surfaceWaterStorage (unit: m) - negative values may be reported
        self.surfaceWaterStorage = self._model.routing.channelStorage / self._model.routing.cellArea

        # Menno's post proccessing: fractions of water sources (allocated for) satisfying water demand in each cell
        self.fracSurfaceWaterAllocation = pcr.ifthen(self._model.routing.landmask, \
                                          vos.getValDivZero(\
                                          self._model.landSurface.allocSurfaceWaterAbstract, self.totalGrossDemand, vos.smallNumber))
        self.fracSurfaceWaterAllocation = pcr.ifthenelse(
            self.totalGrossDemand < vos.smallNumber, 1.0,
            self.fracSurfaceWaterAllocation)
        #
        self.fracNonFossilGroundwaterAllocation = pcr.ifthen(self._model.routing.landmask, \
                                                  vos.getValDivZero(\
                                                  self._model.groundwater.allocNonFossilGroundwater, self.totalGrossDemand, vos.smallNumber))
        #
        self.fracOtherWaterSourceAllocation = pcr.ifthen(self._model.routing.landmask, \
                                              vos.getValDivZero(\
                                              self._model.groundwater.unmetDemand, self.totalGrossDemand, vos.smallNumber))
        #
        self.fracDesalinatedWaterAllocation = pcr.ifthen(self._model.routing.landmask, \
                                              vos.getValDivZero(\
                                              self._model.landSurface.desalinationAllocation, self.totalGrossDemand, vos.smallNumber))
        #
        self.totalFracWaterSourceAllocation = self.fracSurfaceWaterAllocation + \
                                              self.fracNonFossilGroundwaterAllocation + \
                                              self.fracOtherWaterSourceAllocation + \
                                              self.fracDesalinatedWaterAllocation

        # Stefanie's post processing:
        # -  reporting lake and reservoir storage (unit: m3)
        self.waterBodyStorage = pcr.ifthen(self._model.routing.landmask, \
                                pcr.ifthen(\
                                pcr.scalar(self._model.routing.WaterBodies.waterBodyIds) > 0.,\
                                           self._model.routing.WaterBodies.waterBodyStorage))     # Note: This value is after lake/reservoir outflow.
        # - snowMelt (m)
        self.snowMelt = self._model.landSurface.snowMelt

        # An example to report variables from certain land cover types
        # - evaporation from irrigation areas (m/day) - values are average over the entire cell area
        if self._model.landSurface.includeIrrigation:            \
                       self.evaporation_from_irrigation = self._model.landSurface.landCoverObj['irrPaddy'].actualET * \
                                                          self._model.landSurface.landCoverObj['irrPaddy'].fracVegCover + \
                                                          self._model.landSurface.landCoverObj['irrNonPaddy'].actualET * \
                                                          self._model.landSurface.landCoverObj['irrNonPaddy'].fracVegCover

        # Total groundwater abstraction (m) (assuming otherWaterSourceAbstraction as fossil groundwater abstraction
        self.totalGroundwaterAbstraction = self.nonFossilGroundwaterAbstraction +\
                                           self.fossilGroundwaterAbstraction

        # net liquid water passing to the soil
        self.net_liquid_water_to_soil = self._model.landSurface.netLqWaterToSoil

        # consumptive water use and return flow from non irrigation water demand (unit: m/day)
        self.nonIrrWaterConsumption = self._model.routing.nonIrrWaterConsumption
        self.nonIrrReturnFlow = self._model.routing.nonIrrReturnFlow

        # total potential water demand - not considering water availability
        self.totalPotentialMaximumGrossDemand = self._model.landSurface.totalPotentialMaximumGrossDemand
	def dynamic(self):
		#####################
		# * dynamic section #
		#####################
		#-evaluation of the current date: return current month and the time step used
		#-reading in fluxes over land and water area for current time step [m/d]
		# and read in reservoir demand and surface water extraction [m3]
		try:
			self.landSurfaceQ= clippedRead.get(pcrm.generateNameT(landSurfaceQFileName,self.currentTimeStep()))
		except:
			pass
		try:
			self.potWaterSurfaceQ= clippedRead.get(pcrm.generateNameT(waterSurfaceQFileName,self.currentTimeStep()))
		except:
			pass
		#-surface water extraction and reservoir demand currently set to zero, should
		# be computed automatically and updated to reservoirs
		self.potSurfaceWaterExtraction= pcr.spatial(pcr.scalar(0.))
		#self.waterBodies.demand=  #self.reservoirDemandTSS.assignID(self.waterBodies.ID,self.currentTimeStep(),0.)*self.timeSec
		#-initialization of cumulative values of actual water extractions
		self.actWaterSurfaceQ= pcr.spatial(pcr.scalar(0.))
		self.actSurfaceWaterExtraction= pcr.spatial(pcr.scalar(0.))    
		#-definition of sub-loop for routing scheme - explicit scheme has to satisfy Courant condition
		timeLimit= pcr.cellvalue(pcr.mapminimum((pcr.cover(pcr.ifthen(self.waterBodies.distribution == 0,\
			self.channelLength/self.flowVelocity),\
				self.timeSec/self.nrIterDefault)*self.timeSec/self.nrIterDefault)**0.5),1)[0]
		nrIter= int(self.timeSec/timeLimit)
		nrIter= min(nrIter,int(self.timeSec/300.))
		while float(self.timeSec/nrIter) % 1 <> 0:
			nrIter+= 1
		deltaTime= self.timeSec/nrIter
		#-sub-loop for current time step
		if self.currentDate.day == 1 or nrIter >= 24:
			print '\n*\tprocessing %s, currently using %d substeps of %d seconds\n' % \
				(self.currentDate.date(),nrIter,deltaTime)
		#-update discharge and storage
		for nrICur in range(nrIter):
			#-initializing discharge for the current sub-timestep and fill in values
			# for channels and at outlets of waterbodies
			# * channels *
			estQ= pcr.ifthenelse((self.actualStorage > 0.) & (self.waterBodies.distribution == 0) ,\
				(self.wettedArea/self.alphaQ)**(1./self.betaQ),0.)
			#estQ= pcr.ifthenelse((self.actualStorage > 0.) & (self.waterBodies.distribution == 0) ,\
				#0.5*(self.Q+(self.wettedArea/self.alphaQ)**(1./self.betaQ)),0.)
			#estQ= pcr.min(estQ,self.actualStorage/deltaTime)
			self.report(estQ,'results/qest')
			self.Q= pcr.spatial(pcr.scalar(0.))
			self.Q= pcr.ifthenelse(self.waterBodies.distribution == 0,\
				pcr.kinematic(self.channelLDD,estQ,0.,self.alphaQ,\
					self.betaQ,1,deltaTime,self.channelLength),self.Q)
			# * water bodies *
			self.waterBodies.dischargeUpdate()
			self.Q= self.waterBodies.returnMapValue(self.Q,self.waterBodies.actualQ)
			#-fluxes and resulting change in storage: first the local fluxes are evaluated
			# and aggregated over the water bodies where applicable; this includes the specific runoff [m/day/m2]
			# from input and the estimated extraction from surface water as volume per day [m3/day];
			# specific runoff from the land surface is always positive whereas the fluxes over the water surface
			# are potential, including discharge, and are adjusted to match the availabe storage; to this end,
			# surface water storage and fluxes over water bodies are totalized and assigned to the outlet;
			# discharge is updated in a separate step, after vertical fluxes are compared to the actual storage
			deltaActualStorage= ((self.landFraction*self.landSurfaceQ+\
				self.waterFraction*self.potWaterSurfaceQ)*self.cellArea-\
				self.potSurfaceWaterExtraction)*float(self.duration)/nrIter
			deltaActualStorage= pcr.ifthenelse(self.waterBodies.distribution != 0,\
				pcr.ifthenelse(self.waterBodies.location != 0,\
					pcr.areatotal(deltaActualStorage,self.waterBodies.distribution),0),\
						deltaActualStorage)   
			adjustmentRatio= pcr.ifthenelse(deltaActualStorage < 0.,\
				pcr.min(1.,-self.actualStorage/deltaActualStorage),1.)
			self.actWaterSurfaceQ+= adjustmentRatio*self.potWaterSurfaceQ
			self.actSurfaceWaterExtraction+= adjustmentRatio*self.actSurfaceWaterExtraction
			deltaActualStorage*= adjustmentRatio
			#-local water balance check
			if testLocalWaterBalance:
				differenceActualStorage= self.actualStorage
				differenceActualStorage+= deltaActualStorage
			#-overall water balance check: net input
			self.cumulativeDeltaStorage+= pcr.catchmenttotal(deltaActualStorage,self.LDD)
			#-update storage first with local changes, then balance discharge with storage and update storage
			# with lateral flow and return value to water bodies
			self.actualStorage+= deltaActualStorage
			self.actualStorage= pcr.max(0.,self.actualStorage)
			self.Q= pcr.min(self.Q,self.actualStorage/deltaTime)
			deltaActualStorage= (-self.Q+pcr.upstream(self.LDD,self.Q))*deltaTime
			deltaActualStorage= pcr.ifthenelse(self.waterBodies.distribution != 0,\
				pcr.ifthenelse(self.waterBodies.location != 0,\
					pcr.areatotal(deltaActualStorage,self.waterBodies.distribution),0),\
						deltaActualStorage)
			self.actualStorage+= deltaActualStorage
			self.actualStorage= pcr.max(0.,self.actualStorage)
			self.waterBodies.actualStorage= self.waterBodies.retrieveMapValue(self.actualStorage)
			#-flooded fraction returned
			floodedFraction,floodedDepth,\
					self.wettedArea,self.alphaQ= self.kinAlphaComposite(self.actualStorage,self.floodplainMask)
			self.wettedArea= self.waterBodies.returnMapValue(self.wettedArea,\
				self.waterBodies.channelWidth+2.*self.waterBodies.updateWaterHeight())
			self.waterFraction= pcr.ifthenelse(self.waterBodies.distribution == 0,\
				pcr.max(self.waterFractionMask,floodedFraction),self.waterFractionMask)
			self.landFraction= pcr.max(0.,1.-self.waterFraction)
			self.flowVelocity= pcr.ifthenelse(self.wettedArea > 0,self.Q/self.wettedArea,0.)
			#-local water balance check
			if testLocalWaterBalance:
				differenceActualStorage+= deltaActualStorage
				differenceActualStorage-= self.actualStorage
				totalDifference= pcr.cellvalue(pcr.maptotal(differenceActualStorage),1)[0]
				minimumDifference= pcr.cellvalue(pcr.mapminimum(differenceActualStorage),1)[0]
				maximumDifference= pcr.cellvalue(pcr.mapmaximum(differenceActualStorage),1)[0]
				if abs(totalDifference) > 1.e-3:
					print 'water balance error: total %e; min %e; max %e' %\
						(totalDifference,minimumDifference,maximumDifference)
					if  reportLocalWaterBalance:           
						pcr.report(differenceActualStorage,'mbe_%s.map' % self.currentDate.date())
			#-overall water balance check: updating cumulative discharge and total storage [m3]
			self.totalDischarge+= self.Q*deltaTime
			self.totalStorage= pcr.catchmenttotal(self.actualStorage,self.LDD)
		#-check on occurrence of last day and report mass balance
		if self.currentDate == self.endDate:
			#-report initial maps
			pcr.report(self.Q,self.QIniMap)
			pcr.report(self.actualStorage,self.actualStorageIniMap)
			#-return relative and absolute water balance error per cell and
			# as total at basin outlets
			self.totalDischarge= pcr.ifthen((self.waterBodies.distribution == 0) | \
				(self.waterBodies.location != 0),self.totalDischarge)
			self.cumulativeDeltaStorage= pcr.ifthen((self.waterBodies.distribution == 0) | \
				(self.waterBodies.location != 0),self.cumulativeDeltaStorage)
			massBalanceError= self.totalStorage+self.totalDischarge-\
				self.cumulativeDeltaStorage
			relMassBalanceError= 1.+pcr.ifthenelse(self.cumulativeDeltaStorage <> 0.,
				massBalanceError/self.cumulativeDeltaStorage,0.)
			totalMassBalanceError= pcr.cellvalue(pcr.maptotal(pcr.ifthen(self.basinOutlet,\
				massBalanceError)),1)[0]
			totalCumulativeDeltaStorage= pcr.cellvalue(pcr.maptotal(pcr.ifthen(self.basinOutlet,\
				self.cumulativeDeltaStorage)),1)[0]
			if totalCumulativeDeltaStorage > 0:
				totalRelativeMassBalanceError= 1.+totalMassBalanceError/totalCumulativeDeltaStorage
			else:
				totalRelativeMassBalanceError= 1.
			#-report maps and echo value
			pcr.report(massBalanceError,mbeFileName)
			pcr.report(relMassBalanceError,mbrFileName)
			print '\n*\ttotal global mass balance error [m3]: %8.3g' % totalMassBalanceError
			print '\n*\trelative global mass balance error [-]: %5.3f' % totalRelativeMassBalanceError     
			#-echo to screen: total mass balance error and completion of run
			print '\trun completed'
		#-end of day: return states and fluxes
		#-get surface water attributes?
		if getSurfaceWaterAttributes:
			#-compute the following secondary variables:
			# surface water area [m2]: area given dynamic surface water fraction
			# residence time [days]: volume over discharge, assigned -1 in case discharge is zero
			# surface water depth [m], weighed by channel and floodplain volume
			surfaceWaterArea= self.waterFraction*self.cellArea
			surfaceWaterArea= pcr.ifthenelse(self.waterBodies.distribution != 0,\
					pcr.ifthenelse(self.waterBodies.location != 0,\
						pcr.areatotal(surfaceWaterArea,self.waterBodies.distribution),0),\
							surfaceWaterArea)     
			surfaceWaterResidenceTime= pcr.ifthenelse(self.Q > 0.,self.actualStorage/(self.Q*self.timeSec),-1)
			surfaceWaterDepth= pcr.ifthenelse(self.actualStorage > 0.,\
				pcr.max(0.,self.actualStorage-self.channelStorageCapacity)**2/\
					(self.actualStorage*surfaceWaterArea),0.)
			surfaceWaterDepth+= pcr.ifthenelse(self.actualStorage > 0.,\
				pcr.min(self.channelStorageCapacity,self.actualStorage)**2/(self.waterFractionMask*\
				self.cellArea*self.actualStorage),0.)
			#-reports: values at outlet of lakes or reservoirs are assigned to their full extent
			self.report(pcr.ifthenelse(self.waterBodies.distribution != 0,\
				pcr.areamaximum(surfaceWaterArea,self.waterBodies.distribution),surfaceWaterArea),\
					surfaceWaterAreaFileName)   
			self.report(pcr.ifthenelse(self.waterBodies.distribution != 0,\
				pcr.areamaximum(surfaceWaterResidenceTime,self.waterBodies.distribution),surfaceWaterResidenceTime),\
					surfaceWaterResidenceTimeFileName)
			self.report(pcr.ifthenelse(self.waterBodies.distribution != 0,\
				pcr.areamaximum(surfaceWaterDepth,self.waterBodies.distribution),surfaceWaterDepth),\
					surfaceWaterDepthFileName)
		#-reports on standard output: values at outlet of lakes or reservoirs are assigned to their full extent
		self.report(pcr.ifthenelse(self.waterBodies.distribution != 0,
			pcr.areamaximum(self.flowVelocity,self.waterBodies.distribution),self.flowVelocity),flowVelocityFileName)
		self.report(pcr.ifthenelse(self.waterBodies.distribution != 0,
			pcr.areamaximum(self.Q,self.waterBodies.distribution),self.Q),QFileName)
		self.report(pcr.ifthenelse(self.waterBodies.distribution == 0,\
			floodedFraction,0.),floodedFractionFileName)
		self.report(pcr.ifthenelse(self.waterBodies.distribution == 0,\
			floodedDepth,0.),floodedDepthFileName)
		self.report(self.actualStorage,actualStorageFileName)
		#-update date for time step and report relevant daily output 
		self.currentDate= self.currentDate+datetime.timedelta(self.duration)
示例#25
0
    def dynamic(self):
        """ dynamic part of the output module
        """

        # ************************************************************
        # ***** WRITING RESULTS: TIME SERIES *************************
        # ************************************************************

        # xxx=catchmenttotal(self.var.SurfaceRunForest * self.var.PixelArea, self.var.Ldd) * self.var.InvUpArea
        # self.var.Tss['DisTS'].sample(xxx)
        # self.report(self.Precipitation,binding['TaMaps'])

        # if fast init than without time series
        settings = LisSettings.instance()
        option = settings.options
        binding = settings.binding
        flags = settings.flags
        report_time_serie_act = settings.report_timeseries
        report_maps_end = settings.report_maps_end
        report_maps_steps = settings.report_maps_steps
        report_maps_all = settings.report_maps_all

        if not (option['InitLisfloodwithoutSplit']):

            if flags['loud']:
                # print the discharge of the first output map loc
                try:
                    print(" %10.2f" % self.var.Tss["DisTS"].firstout(
                        decompress(self.var.ChanQAvg)))
                except:
                    pass

            for tss in report_time_serie_act:
                # report time series
                what = 'self.var.' + report_time_serie_act[tss].output_var
                how = report_time_serie_act[tss].operation[0] if len(
                    report_time_serie_act[tss].operation) else ''
                if how == 'mapmaximum':
                    changed = compressArray(mapmaximum(decompress(eval(what))))
                    what = 'changed'
                if how == 'total':
                    changed = compressArray(
                        catchmenttotal(
                            decompress(eval(what)) * self.var.PixelAreaPcr,
                            self.var.Ldd) * self.var.InvUpArea)
                    what = 'changed'
                self.var.Tss[tss].sample(decompress(eval(what)))

        # ************************************************************
        # ***** WRITING RESULTS: MAPS   ******************************
        # ************************************************************

        # started nicely but now it becomes way to complicated, I am not happy about the next part -> has to be chaged

        checkifdouble = []  # list to check if map is reported more than once
        monthly = False
        yearly = False

        # Report END maps

        for maps in report_maps_end.keys():
            # report end map filename
            if settings.mc_set:
                # MonteCarlo model
                where = os.path.join(str(self.var.currentSampleNumber()),
                                     binding[maps].split("/")[-1])
            else:
                where = binding.get(maps)
            if not where:
                continue
            what = 'self.var.' + report_maps_end[maps].output_var
            if where not in checkifdouble:
                checkifdouble.append(where)
                # checks if saved at same place, if no: add to list

                if self.var.currentTimeStep() == self.var.nrTimeSteps():
                    # final step: Write end maps
                    # Get start date for reporting start step
                    # (last step indeed)
                    reportStartDate = inttodate(self.var.currentTimeStep() - 1,
                                                self.var.CalendarDayStart)

                    # if suffix with '.' is part of the filename report with
                    # suffix
                    head, tail = os.path.split(where)
                    if '.' in tail:
                        if option['writeNetcdf']:
                            # CM mod: write end map to netCDF file (single)
                            # CM ##########################

                            try:
                                writenet(0, eval(what), where, self.var.DtDay,
                                         maps,
                                         report_maps_end[maps].output_var,
                                         report_maps_end[maps].unit, 'f4',
                                         reportStartDate,
                                         self.var.currentTimeStep(),
                                         self.var.currentTimeStep())
                            except Exception as e:
                                print(str(e), 'END', what, where,
                                      self.var.DtDay, maps,
                                      report_maps_end[maps].output_var,
                                      report_maps_end[maps].unit, 'f4',
                                      reportStartDate,
                                      self.var.currentTimeStep(),
                                      self.var.currentTimeStep())
                            ################################

                        else:
                            report(decompress(eval(what)), str(where))
                    else:
                        if option['writeNetcdfStack']:

                            try:
                                writenet(0, eval(what), where, self.var.DtDay,
                                         maps,
                                         report_maps_end[maps].output_var,
                                         report_maps_end[maps].unit, 'f4',
                                         reportStartDate,
                                         self.var.currentTimeStep(),
                                         self.var.currentTimeStep())
                            except Exception as e:
                                print(str(e), 'END', what, where,
                                      self.var.DtDay, maps,
                                      report_maps_end[maps].output_var,
                                      report_maps_end[maps].unit, 'f4',
                                      reportStartDate,
                                      self.var.currentTimeStep(),
                                      self.var.currentTimeStep())
                            ###########################
                        else:
                            self.var.report(decompress(eval(what)), str(where))

        # Report REPORTSTEPS maps
        for maps in report_maps_steps.keys():
            # report reportsteps maps
            if settings.mc_set:
                # MonteCarlo model
                where = os.path.join(str(self.var.currentSampleNumber()),
                                     binding[maps].split("/")[-1])
            else:
                where = binding.get(maps)
            if not where:
                continue
            what = 'self.var.' + report_maps_steps[maps].output_var
            if not (where in checkifdouble):
                checkifdouble.append(where)
                # checks if saved at same place, if no: add to list
                if self.var.currentTimeStep() in self.var.ReportSteps:
                    flagcdf = 1  # index flag for writing nedcdf = 1 (=steps) -> indicated if a netcdf is created or maps are appended
                    frequency = "all"
                    try:
                        if report_maps_steps[maps].monthly:
                            monthly = True
                            flagcdf = 3  # set to monthly (step) flag
                            frequency = "monthly"
                    except:
                        monthly = False
                    try:
                        if report_maps_steps[maps].yearly:
                            yearly = True
                            flagcdf = 4  # set to yearly (step) flag
                            frequency = "annual"
                    except:
                        yearly = False

                    if (monthly and self.var.monthend) or (
                            yearly
                            and self.var.yearend) or not (monthly or yearly):
                        # checks if a flag monthly or yearly exists
                        if option['writeNetcdfStack']:
                            # Get start date for reporting start step
                            reportStartDate = inttodate(
                                self.var.ReportSteps[0] - 1,
                                self.var.CalendarDayStart)
                            # get step number for first reporting step
                            reportStepStart = 1
                            # get step number for last reporting step
                            reportStepEnd = self.var.ReportSteps[
                                -1] - self.var.ReportSteps[0] + 1
                            cdfflags = CDFFlags.instance()
                            try:
                                writenet(cdfflags[flagcdf], eval(what), where,
                                         self.var.DtDay, maps,
                                         report_maps_steps[maps].output_var,
                                         report_maps_steps[maps].unit, 'f4',
                                         reportStartDate, reportStepStart,
                                         reportStepEnd, frequency)
                            except Exception as e:
                                print(" +----> ERR: {}".format(str(e)))
                                print(
                                    "REP flag:{} - {} {} {} {} {} {} {} {} {} {}"
                                    .format(cdfflags[flagcdf], what, where,
                                            self.var.DtDay, maps,
                                            report_maps_steps[maps].output_var,
                                            report_maps_steps[maps].unit, 'f4',
                                            reportStartDate, reportStepStart,
                                            reportStepEnd))

                        else:
                            self.var.report(decompress(eval(what)), str(where))

        # Report ALL maps
        for maps in report_maps_all.keys():
            # report maps for all timesteps
            if settings.mc_set:
                where = os.path.join(str(self.var.currentSampleNumber()),
                                     binding[maps].split("/")[-1])
            else:
                where = binding.get(maps)
            if not where:
                continue
            what = 'self.var.' + report_maps_all[maps].output_var
            if where not in checkifdouble:
                checkifdouble.append(where)
                # checks if saved at same place, if no: add to list

                # index flag for writing nedcdf = 1 (=all) -> indicated if a netcdf is created or maps are appended
                # cannot check only if netcdf exists, because than an old netcdf will be used accidently
                flagcdf = 2
                frequency = "all"
                try:
                    if report_maps_all[maps].monthly:
                        monthly = True
                        flagcdf = 5  # set to monthly flag
                        frequency = "monthly"
                except:
                    monthly = False
                try:
                    if report_maps_all[maps].yearly:
                        yearly = True
                        flagcdf = 6  # set to yearly flag
                        frequency = "annual"
                except:
                    yearly = False

                if (monthly and self.var.monthend) or (
                        yearly
                        and self.var.yearend) or not (monthly or yearly):
                    # checks if a flag monthly or yearly exists]
                    if option['writeNetcdfStack']:
                        #Get start date for reporting start step
                        reportStartDate = inttodate(
                            binding['StepStartInt'] - 1,
                            self.var.CalendarDayStart)
                        # CM: get step number for first reporting step which is always the first simulation step
                        # CM: first simulation step referred to reportStartDate
                        ##reportStepStart = int(binding['StepStart'])
                        reportStepStart = 1
                        #get step number for last reporting step which is always the last simulation step
                        #last simulation step referred to reportStartDate
                        reportStepEnd = binding['StepEndInt'] - binding[
                            'StepStartInt'] + 1

                        try:
                            cdfflags = CDFFlags.instance()
                            writenet(cdfflags[flagcdf], eval(what), where,
                                     self.var.DtDay, maps,
                                     report_maps_all[maps].output_var,
                                     report_maps_all[maps].unit, 'f4',
                                     reportStartDate, reportStepStart,
                                     reportStepEnd, frequency)
                        except Exception as e:
                            warnings.warn(LisfloodWarning(str(e)))
                            print(str(e), "ALL", what, where, self.var.DtDay,
                                  maps, report_maps_all[maps].output_var,
                                  report_maps_all[maps].unit, 'f4',
                                  reportStartDate, reportStepStart,
                                  reportStepEnd)
                    else:
                        self.var.report(decompress(eval(what)),
                                        trimPCRasterOutputPath(where))

        cdfflags = CDFFlags.instance()
        # set the falg to indicate if a netcdffile has to be created or is only appended
        # if reportstep than increase the counter
        if self.var.currentTimeStep() in self.var.ReportSteps:
            # FIXME magic numbers. replace indexes with descriptive keys
            cdfflags.inc(1)
            # globals.cdfFlag[1] += 1
            if self.var.monthend:
                # globals.cdfFlag[3] += 1
                cdfflags.inc(3)
            if self.var.yearend:
                # globals.cdfFlag[4] += 1
                cdfflags.inc(4)

        # increase the counter for report all maps
        cdfflags.inc(2)
        # globals.cdfFlag[2] += 1
        if self.var.monthend:
            # globals.cdfFlag[5] += 1
            cdfflags.inc(5)
        if self.var.yearend:
            # globals.cdfFlag[6] += 1
            cdfflags.inc(6)
示例#26
0
def subcatch_order_b(
    ldd, oorder, sizelimit=0, fill=False, fillcomplete=False, stoporder=0
):
    """
    Determines subcatchments using the catchment order

    This version tries to keep the number op upstream/downstream catchment the
    small by first dederivingatchment connected to the major river(the order) given, and fill
    up from there.

    Input:
        - ldd
        - oorder - order to use
        - sizelimit - smallest catchments to include, default is all (sizelimit=0) in number of cells
        - if fill is set to True the higer order catchment are filled also
        - if fillcomplete is set to True the whole ldd is filled with catchments.


    :returns sc, dif, nldd; Subcatchment, Points, subcatchldd
    """
    # outl = find_outlet(ldd)
    # large = pcr.subcatchment(ldd,pcr.boolean(outl))

    if stoporder == 0:
        stoporder = oorder

    stt = pcr.streamorder(ldd)
    sttd = pcr.downstream(ldd, stt)
    pts = pcr.ifthen((pcr.scalar(sttd) - pcr.scalar(stt)) > 0.0, sttd)
    maxorder = pcraster.framework.getCellValue(pcr.mapmaximum(stt), 1, 1)
    dif = pcr.uniqueid(pcr.boolean(pcr.ifthen(stt == pcr.ordinal(oorder), pts)))

    if fill:
        for order in range(oorder, maxorder):
            m_pts = pcr.ifthen((pcr.scalar(sttd) - pcr.scalar(order)) > 0.0, sttd)
            m_dif = pcr.uniqueid(
                pcr.boolean(pcr.ifthen(stt == pcr.ordinal(order), m_pts))
            )
            dif = pcr.uniqueid(pcr.boolean(pcr.cover(m_dif, dif)))

        for myorder in range(oorder - 1, stoporder, -1):
            sc = pcr.subcatchment(ldd, pcr.nominal(dif))
            m_pts = pcr.ifthen((pcr.scalar(sttd) - pcr.scalar(stt)) > 0.0, sttd)
            m_dif = pcr.uniqueid(
                pcr.boolean(pcr.ifthen(stt == pcr.ordinal(myorder - 1), m_pts))
            )
            dif = pcr.uniqueid(
                pcr.boolean(pcr.cover(pcr.ifthen(pcr.scalar(sc) == 0, m_dif), dif))
            )

        if fillcomplete:
            sc = pcr.subcatchment(ldd, pcr.nominal(dif))
            cs, m_dif, stt = subcatch_order_a(ldd, stoporder)
            dif = pcr.uniqueid(
                pcr.boolean(
                    pcr.cover(
                        pcr.ifthen(pcr.scalar(sc) == 0, pcr.ordinal(m_dif)),
                        pcr.ordinal(dif),
                    )
                )
            )

    scsize = pcr.catchmenttotal(1, ldd)
    dif = pcr.ordinal(pcr.uniqueid(pcr.boolean(pcr.ifthen(scsize >= sizelimit, dif))))
    sc = pcr.subcatchment(ldd, dif)

    # Make pit ldd
    nldd = pcr.lddrepair(pcr.ifthenelse(pcr.cover(dif, 0) > 0, 5, ldd))

    return sc, dif, nldd
        reservoir_capacity = pcr.ifthen(landmask, \
                             pcr.cover(\
                             vos.readPCRmapClone(reservoir_capacity_file, \
                                                 clone_map_file, \
                                                 tmp_folder, \
                                                 None, False, None, False), 0.0)) * 1000. * 1000.
        water_body_id      = vos.readPCRmapClone(water_body_id_file, \
                                                 clone_map_file, \
                                                 tmp_folder, \
                                                 None, False, None, True )
        water_body_id = pcr.ifthen(
            pcr.scalar(water_body_id) > 0.00, water_body_id)
        water_body_id = pcr.ifthen(landmask, water_body_id)
        #
        # water body outlet
        wbCatchment = pcr.catchmenttotal(pcr.scalar(1), ldd_map_low_resolution)
        water_body_outlet  = pcr.ifthen(wbCatchment ==\
                             pcr.areamaximum(wbCatchment, \
                             water_body_id),\
                             water_body_id) # = 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
        water_body_outlet  = pcr.ifthen(\
                             pcr.areaorder(pcr.scalar( water_body_outlet), \
                             water_body_outlet) == 1., water_body_outlet)
        water_body_outlet  = pcr.ifthen(\
                             pcr.scalar(water_body_outlet) > 0., water_body_outlet)

        # calculate overbank volume from reservoirs (and lakes)
        lake_reservoir_volume = pcr.areatotal(extreme_value_map, water_body_id)
        lake_reservoir_overbank_volume = pcr.cover(
            pcr.max(0.0, lake_reservoir_volume - reservoir_capacity), 0.0)
示例#28
0
    def __init__(self, modelTime, input_file, output_file, variable_name,
                 variable_unit):
        DynamicModel.__init__(self)

        self.modelTime = modelTime

        # netcdf input file - based on PCR-GLOBWB output
        self.input_file = "/projects/0/dfguu/users/edwin/pcr-globwb-aqueduct/historical/1951-2005/gfdl-esm2m/temperature_annuaAvg_output_%s-12-31_to_%s-12-31.nc"
        self.input_file = input_file

        # output file - in netcdf format
        self.output_file = output_folder + "/mekong/basin_temperature_annuaAvg_output.nc"
        self.output_file = output_file

        # output variable name and unit
        self.variable_name = variable_name
        self.variable_unit = variable_unit

        # preparing temporary directory
        self.temporary_directory = output_folder + "/tmp/"
        os.makedirs(self.temporary_directory)

        # clone and landmask maps
        logger.info("Set the clone and landmask maps.")
        self.clonemap_file_name = "/projects/0/dfguu/users/edwinhs/data/mekong_etc_clone/version_2018-10-22/final/clone_mekong.map"
        pcr.setclone(self.clonemap_file_name)
        landmask_file_name = "/projects/0/dfguu/users/edwinhs/data/mekong_etc_clone/version_2018-10-22/final/mask_mekong.map"
        self.landmask = vos.readPCRmapClone(landmask_file_name, \
                                            self.clonemap_file_name, \
                                            self.temporary_directory, \
                                            None, False, None, True)

        # pcraster input files
        # - river network map and sub-catchment map
        ldd_file_name = "/projects/0/dfguu/data/hydroworld/PCRGLOBWB20/input5min/routing/lddsound_05min.map"
        # - cell area (unit: m2)
        cell_area_file_name = "/projects/0/dfguu/data/hydroworld/PCRGLOBWB20/input5min/routing/cellsize05min.correct.map"

        # loading pcraster input maps
        self.ldd_network   = vos.readPCRmapClone(ldd_file_name, \
                                                 self.clonemap_file_name, \
                                                 self.temporary_directory, \
                                                 None, \
                                                 True)
        self.ldd_network = pcr.lddrepair(pcr.ldd(self.ldd_network))
        self.ldd_network = pcr.lddrepair(self.ldd_network)
        self.cell_area     = vos.readPCRmapClone(cell_area_file_name, \
                                                 self.clonemap_file_name, \
                                                 self.temporary_directory, \
                                                 None)

        # set/limit all input maps to the defined landmask
        self.ldd_network = pcr.ifthen(self.landmask, self.ldd_network)
        self.cell_area = pcr.ifthen(self.landmask, self.cell_area)

        # calculate basin/catchment area
        self.basin_area = pcr.catchmenttotal(self.cell_area, self.ldd_network)
        self.basin_area = pcr.ifthen(self.landmask, self.basin_area)

        # preparing an object for reporting netcdf files:
        self.netcdf_report = netcdf_writer.PCR2netCDF(self.clonemap_file_name)

        # preparing netcdf output files:
        self.netcdf_report.createNetCDF(self.output_file, \
                                        self.variable_name, \
                                        self.variable_unit)
示例#29
0
    def getParameterFiles(
        self, currTimeStep, cellArea, ldd, initial_condition_dictionary=None
    ):

        # 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
        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.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.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.0, self.waterBodyOut
        )
        # TODO: Please also consider endorheic lakes!

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

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

        # reservoir surface area (m2):
        if self.useNetCDF:
            resSfArea = (
                1000.0
                * 1000.0
                * vos.netcdf2PCRobjClone(
                    self.ncFileInp,
                    "resSfAreaInp",
                    date_used,
                    useDoy="yearly",
                    cloneMapFileName=self.cloneMap,
                )
            )
        else:
            resSfArea = (
                1000.0
                * 1000.0
                * 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.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.0, self.waterBodyArea)

        # correcting water body ids and outlets (exclude all water bodies with surfaceArea = 0)
        self.waterBodyIds = pcr.ifthen(self.waterBodyArea > 0.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.0
                * 1000.0
                * vos.netcdf2PCRobjClone(
                    self.ncFileInp,
                    "resMaxCapInp",
                    date_used,
                    useDoy="yearly",
                    cloneMapFileName=self.cloneMap,
                )
            )
        else:
            self.resMaxCap = (
                1000.0
                * 1000.0
                * 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.0, self.waterBodyTyp
        )
        self.waterBodyTyp = pcr.ifthenelse(
            self.waterBodyCap > 0.0,
            self.waterBodyTyp,
            pcr.ifthenelse(
                pcr.scalar(self.waterBodyTyp) == 2, pcr.nominal(1), self.waterBodyTyp
            ),
        )

        # final corrections:
        self.waterBodyTyp = pcr.ifthen(
            self.waterBodyArea > 0.0, self.waterBodyTyp
        )  # make sure that all lakes and/or reservoirs have surface areas
        self.waterBodyTyp = pcr.ifthen(
            pcr.scalar(self.waterBodyTyp) > 0.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.0, self.waterBodyIds
        )  # make sure that all lakes and/or reservoirs have ids
        self.waterBodyOut = pcr.ifthen(
            pcr.scalar(self.waterBodyIds) > 0.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.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 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
        #
        self.waterBodyStorage = pcr.cover(self.waterBodyStorage, 0.0)
        self.avgInflow = pcr.cover(self.avgInflow, 0.0)
        self.avgOutflow = pcr.cover(self.avgOutflow, 0.0)

        # 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)
        self.waterBodyStorage = pcr.ifthen(self.landmask, self.waterBodyStorage)
        self.avgInflow = pcr.ifthen(self.landmask, self.avgInflow)
        self.avgOutflow = pcr.ifthen(self.landmask, self.avgOutflow)
                                output_files['tmp_folder'],
                                None, False, None, True))
#~ pcr.aguila(basin_map)
# - extend/extrapolate the basin
basin_map = pcr.cover(basin_map, pcr.windowmajority(basin_map, 0.5))
basin_map = pcr.cover(basin_map, pcr.windowmajority(basin_map, 0.5))
basin_map = pcr.cover(basin_map, pcr.windowmajority(basin_map, 0.5))
basin_map = pcr.cover(basin_map, pcr.windowmajority(basin_map, 1.0))
basin_map = pcr.cover(basin_map, pcr.windowmajority(basin_map, 1.5))
basin_map = pcr.ifthen(landmask, basin_map)
#~ pcr.aguila(basin_map)

msg = "Redefining the basin map (so that it is consistent with the ldd map used in PCR-GLOBWB):"
logger.info(msg)
# - calculate the upstream area of every pixel:
upstream_area = pcr.catchmenttotal(cell_area, ldd)
# - calculate the catchment area of every basin:
upstream_area_maximum = pcr.areamaximum(upstream_area, basin_map)
# - identify the outlet of every basin (in order to rederive the basin so that it is consistent with the ldd)
outlet = pcr.nominal(pcr.uniqueid(pcr.ifthen(upstream_area == upstream_area_maximum, pcr.boolean(1.0))))
# - ignoring outlets with small upstream areas
threshold = 50. * 1000. * 1000.                                                 # unit: m2
outlet    = pcr.ifthen(upstream_area_maximum > threshold, outlet)
#~ pcr.aguila(outlet)
outlet = pcr.cover(outlet, pcr.nominal(0.0))
# - recalculate the basin
basin_map  = pcr.nominal(pcr.subcatchment(ldd, outlet))
basin_map  = pcr.clump(basin_map)
basin_map  = pcr.ifthen(landmask, basin_map)
pcr.report(basin_map , "basin_map.map")
#~ pcr.aguila(basin_map)
                                                 None, False, None, False), 0.0))
        reservoir_capacity = pcr.ifthen(landmask, \
                             pcr.cover(\
                             vos.readPCRmapClone(reservoir_capacity_file, \
                                                 clone_map_file, \
                                                 tmp_folder, \
                                                 None, False, None, False), 0.0)) * 1000. * 1000.
        water_body_id      = vos.readPCRmapClone(water_body_id_file, \
                                                 clone_map_file, \
                                                 tmp_folder, \
                                                 None, False, None, True )
        water_body_id      = pcr.ifthen(pcr.scalar(water_body_id) > 0.00, water_body_id)
        water_body_id      = pcr.ifthen( landmask, water_body_id)                                         
        #
        # water body outlet
        wbCatchment        = pcr.catchmenttotal(pcr.scalar(1), ldd_map_low_resolution)
        water_body_outlet  = pcr.ifthen(wbCatchment ==\
                             pcr.areamaximum(wbCatchment, \
                             water_body_id),\
                             water_body_id) # = 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 
        water_body_outlet  = pcr.ifthen(\
                             pcr.areaorder(pcr.scalar( water_body_outlet), \
                             water_body_outlet) == 1., water_body_outlet)
        water_body_outlet  = pcr.ifthen(\
                             pcr.scalar(water_body_outlet) > 0., water_body_outlet)

        # calculate overbank volume from reservoirs (and lakes)
        lake_reservoir_volume          = pcr.areatotal(extreme_value_map, water_body_id)
        lake_reservoir_overbank_volume = pcr.cover(
                                         pcr.max(0.0, lake_reservoir_volume - reservoir_capacity), 0.0)
    def evaluateAllModelResults(self,globalCloneMapFileName,\
                                catchmentClassFileName,\
                                lddMapFileName,\
                                cellAreaMapFileName,\
                                pcrglobwb_output,\
                                analysisOutputDir="",\
                                tmpDir = None):     

        # temporary directory
        if tmpDir == None: tmpDir = self.tmpDir+"/edwin_grdc_"
        
        # output directory for all analyses for all stations
        analysisOutputDir   = str(analysisOutputDir)
        self.chartOutputDir = analysisOutputDir+"/chart/"
        self.tableOutputDir = analysisOutputDir+"/table/"
        #
        if analysisOutputDir == "": self.chartOutputDir = "chart/"
        if analysisOutputDir == "": self.tableOutputDir = "table/"
        #
        # make the chart and table directories:
        os.system('rm -r '+self.chartOutputDir+"*")
        os.system('rm -r '+self.tableOutputDir+"*")
        os.makedirs(self.chartOutputDir)
        os.makedirs(self.tableOutputDir)
        
        # cloneMap for all pcraster operations
        pcr.setclone(globalCloneMapFileName)
        cloneMap = pcr.boolean(1)
        self.cell_size_in_arc_degree = vos.getMapAttributesALL(globalCloneMapFileName)['cellsize']
        
        lddMap = pcr.lddrepair(pcr.readmap(lddMapFileName))
        cellArea = pcr.scalar(pcr.readmap(cellAreaMapFileName))
        
        # The landMaskClass map contains the nominal classes for all landmask regions. 
        landMaskClass = pcr.nominal(cloneMap)  # default: if catchmentClassFileName is not given
        if catchmentClassFileName != None:
            landMaskClass = pcr.nominal(pcr.readmap(catchmentClassFileName))

        # model catchment areas and cordinates
        catchmentAreaAll = pcr.catchmenttotal(cellArea, lddMap) / (1000*1000)  # unit: km2
        xCoordinate = pcr.xcoordinate(cloneMap)
        yCoordinate = pcr.ycoordinate(cloneMap)
        
        for id in self.list_of_grdc_ids: 

            logger.info("Evaluating simulated discharge to the grdc observation at "+str(self.attributeGRDC["id_from_grdc"][str(id)])+".")
            
            # identify model pixel
            self.identifyModelPixel(tmpDir,catchmentAreaAll,landMaskClass,xCoordinate,yCoordinate,str(id))

            # evaluate model results to GRDC data
            self.evaluateModelResultsToGRDC(str(id),pcrglobwb_output,catchmentClassFileName,tmpDir)
            
        # write the summary to a table 
        summary_file = analysisOutputDir+"summary.txt"
        #
        logger.info("Writing the summary for all stations to the file: "+str(summary_file)+".")
        #
        # prepare the file:
        summary_file_handle = open(summary_file,"w")
        #
        # write the header
        summary_file_handle.write( ";".join(self.grdc_dict_keys)+"\n")
        #
        # write the content
        for id in self.list_of_grdc_ids:
            rowLine  = ""
            for key in self.grdc_dict_keys: rowLine += str(self.attributeGRDC[key][str(id)]) + ";"   
            rowLine = rowLine[0:-1] + "\n"
            summary_file_handle.write(rowLine)
        summary_file_handle.close()           
#~ -rwxr-xr-x 1 sutan101 depfg  36M Nov 11  2019 cellsize05min.correct.map
#~ -rw-r--r-- 1 sutan101 depfg  36M Nov 14  2019 cellsize05min_correct.nc
#~ -rw-r--r-- 1 sutan101 depfg  36M Nov 14  2019 cellsize05min.correct.nc
#~ -rw-r--r-- 1 sutan101 depfg  129 Nov 14  2019 hydroworld_source.txt
#~ -rwxr-xr-x 1 sutan101 depfg 8.9M Nov 11  2019 lddsound_05min.map
#~ -rw-r--r-- 1 sutan101 depfg  36M Nov 14  2019 lddsound_05min.nc
#~ -rw-r--r-- 1 sutan101 depfg  36M Nov 14  2019 lddsound_05min_unmask.nc

# calculate pcrglobwb catchment area
# - reading input files
ldd_file_name = "/scratch/depfg/sutan101/data/pcrglobwb2_input_release/version_2019_11_beta_extended/pcrglobwb2_input/global_05min/routing/ldd_and_cell_area/lddsound_05min.map"
ldd = pcr.readmap(ldd_file_name)
cell_area_file_name = "/scratch/depfg/sutan101/data/pcrglobwb2_input_release/version_2019_11_beta_extended/pcrglobwb2_input/global_05min/routing/ldd_and_cell_area/cellsize05min.correct.map"
cellarea = pcr.readmap(cell_area_file_name)
# - calculate pcrglobwb catchment area (km2)
pcrglobwb_catchment_area_km2 = pcr.catchmenttotal(cellarea, ldd) / 1e6

# loop through the table
for table_line in table_lines[1:len(table_lines) + 1]:
    #~ for table_line in table_lines[0:len(table_lines) + 1]:
    #~ for table_line in table_lines[1:3]:

    # select one line (representing each station) and save it to a tmp file
    tmp_file_name = "one_line.tmp"
    if os.path.exists(tmp_file_name): os.remove(tmp_file_name)
    one_line_txt_file = open(tmp_file_name, "w")
    one_line_txt_file.write(table_line)
    one_line_txt_file.close()

    # edwin_code.map: col2map --clone lddsound_05min.map -N -x 3 -y 2 -v 1 one_line_from_edwin_code_and_usgs_drain_area_km2.txt edwin_code.map
    cmd = "col2map --clone " + ldd_file_name + \