def set_input_files(self): # fullPath of CLONE: self.cloneMap = vos.getFullPath(self.globalOptions['cloneMap'], \ self.globalOptions['inputDir']) # Get the fullPaths of the INPUT directories/files mentioned in # a list/dictionary: dirsAndFiles = ['precipitationNC', 'temperatureNC','refETPotFileNC'] for item in dirsAndFiles: if self.meteoOptions[item] != "None": self.meteoOptions[item] = vos.getFullPath(self.meteoOptions[item], self.globalOptions['inputDir'])
def __init__(self, iniItems, landmask, onlyNaturalWaterBodies=False): object.__init__(self) # clone map file names, temporary directory and global/absolute path of input directory self.cloneMap = iniItems.cloneMap self.tmpDir = iniItems.tmpDir self.inputDir = iniItems.globalOptions['inputDir'] self.landmask = landmask # option to perform a run with only natural lakes (without reservoirs) self.onlyNaturalWaterBodies = onlyNaturalWaterBodies if self.onlyNaturalWaterBodies: logger.info( "Using only natural water bodies identified in the year 1900. All reservoirs in 1900 are assumed as lakes." ) self.onlyNaturalWaterBodies = True self.dateForNaturalCondition = "1900-01-01" # The run for a natural condition should access only this date. # netcdf file name for water bodies: self.useNetCDF = True self.ncFileInp = vos.getFullPath( iniItems.modflowParameterOptions['waterBodyInputNC'], self.inputDir) # minimum width (m) used in the weir formula # TODO: define minWeirWidth based on the GLWD, GRanD database and/or bankfull discharge formula self.minWeirWidth = 10.
def __init__(self, cloneMapFileName,\ pcraster_files, \ output, \ modelTime): DynamicModel.__init__(self) # pcr.setclone(cloneMapFileName) self.modelTime = modelTime self.pcraster_files = pcraster_files # move to the input folder os.chdir(self.pcraster_files['directory']) self.output = output self.output['file_name'] = vos.getFullPath(self.output['file_name'], self.output['folder']) # object for reporting self.netcdf_report = OutputNetcdf(cloneMapFileName, self.output['description']) print(self.output['long_name']) # make a netcdf file self.netcdf_report.createNetCDF(self.output['file_name'],\ self.output['variable_name'],\ self.output['unit'],\ self.output['long_name'])
def __init__(self, iniItems, landmask, Dir, cloneMap, tmpDir): object.__init__(self) # clone map file names, temporary directory and global/absolute path of input directory self.cloneMap = cloneMap #iniItems.cloneMap self.tmpDir = tmpDir #iniItems.tmpDir self.inputDir = Dir #iniItems.globalOptions['inputDir'] self.landmask = landmask # local drainage direction: self.lddMap = vos.readPCRmapClone( iniItems.get("routingOptions", "lddMap"), self.cloneMap, self.tmpDir, self.inputDir, True) self.lddMap = pcr.lddrepair(pcr.ldd(self.lddMap)) self.lddMap = pcr.lddrepair(self.lddMap) # option to activate water balance check self.debugWaterBalance = True if configget(iniItems, "routingOptions", "debugWaterBalance", "True") == "False": self.debugWaterBalance = False # option to perform a run with only natural lakes (without reservoirs) self.onlyNaturalWaterBodies = False if "onlyNaturalWaterBodies" in iniItems._sections[ 'routingOptions'] and configget(iniItems, "routingOptions", "onlyNaturalWaterBodies", "False") == "True": logger.info( "Using only natural water bodies identified in the year 1900. All reservoirs in 1900 are assumed as lakes." ) self.onlyNaturalWaterBodies = True self.dateForNaturalCondition = "1900-01-01" # The run for a natural condition should access only this date. # names of files containing water bodies parameters if configget(iniItems, "routingOptions", "waterBodyInputNC", "None") == str(None): self.useNetCDF = False self.fracWaterInp = iniItems.get("routingOptions", "fracWaterInp") self.waterBodyIdsInp = iniItems.get("routingOptions", "waterBodyIds") self.waterBodyTypInp = iniItems.get("routingOptions", "waterBodyTyp") self.resMaxCapInp = iniItems.get("routingOptions", "resMaxCapInp") self.resSfAreaInp = iniItems.get("routingOptions", "resSfAreaInp") else: self.useNetCDF = True self.ncFileInp = vos.getFullPath(\ iniItems.get("routingOptions","waterBodyInputNC"),\ self.inputDir) # minimum width (m) used in the weir formula # TODO: define minWeirWidth based on the GLWD, GRanD database and/or bankfull discharge formula self.minWeirWidth = 10. # lower and upper limits at which reservoir release is terminated and # at which reservoir release is equal to long-term average outflow self.minResvrFrac = 0.10 self.maxResvrFrac = 0.75
def readTopo(self, iniItems): # maps of elevation attributes: topoParams = ['tanslope', 'slopeLength', 'orographyBeta'] if iniItems.landSurfaceOptions['topographyNC'] == str(None): for var in topoParams: input = iniItems.landSurfaceOptions[str(var)] vars(self)[var] = pcr.scalar(0.0) vars(self)[var] = vos.readPCRmapClone(input, self.cloneMap, self.tmpDir, self.inputDir) vars(self)[var] = pcr.cover(vars(self)[var], 0.0) else: topoPropertiesNC = vos.getFullPath(\ iniItems.landSurfaceOptions[\ 'topographyNC'], self.inputDir) for var in topoParams: vars(self)[var] = vos.netcdf2PCRobjCloneWithoutTime(\ topoPropertiesNC,var, \ cloneMapFileName = self.cloneMap) vars(self)[var] = pcr.cover(vars(self)[var], 0.0) self.tanslope = pcr.max(self.tanslope, 0.00001) # maps of relative elevation above flood plains dzRel = [ 'dzRel0001', 'dzRel0005', 'dzRel0010', 'dzRel0020', 'dzRel0030', 'dzRel0040', 'dzRel0050', 'dzRel0060', 'dzRel0070', 'dzRel0080', 'dzRel0090', 'dzRel0100' ] if iniItems.landSurfaceOptions['topographyNC'] == str(None): for i in range(0, len(dzRel)): var = dzRel[i] input = iniItems.landSurfaceOptions[str(var)] vars(self)[var] = vos.readPCRmapClone(input, self.cloneMap, self.tmpDir, self.inputDir) vars(self)[var] = pcr.cover(vars(self)[var], 0.0) if i > 0: vars(self)[var] = pcr.max( vars(self)[var], vars(self)[dzRel[i - 1]]) else: for i in range(0, len(dzRel)): var = dzRel[i] vars(self)[var] = vos.netcdf2PCRobjCloneWithoutTime(\ topoPropertiesNC,var, \ cloneMapFileName = self.cloneMap) vars(self)[var] = pcr.cover(vars(self)[var], 0.0) if i > 0: vars(self)[var] = pcr.max( vars(self)[var], vars(self)[dzRel[i - 1]])
def __init__(self,iniItems,landmask): object.__init__(self) # clone map file names, temporary directory and global/absolute path of input directory self.cloneMap = iniItems.cloneMap self.tmpDir = iniItems.tmpDir self.inputDir = iniItems.globalOptions['inputDir'] self.landmask = landmask # ADDED: variables necessary for 2-way coupling functions # ---------------------------------------------------------------------------------------------------------------- # variable to control activation of 2-way coupling functions (can be changed through BMI) self.ActivateCoupling = iniItems.globalOptions['ActivateCoupling'] # introduce relevant variables for 2-way coupling so they can be changed through BMI when needed self.waterBodyIdsAdjust = pcr.ifthen(self.landmask, pcr.scalar(1.0)) # to control the presence of water bodies # ---------------------------------------------------------------------------------------------------------------- # option to activate water balance check self.debugWaterBalance = True if iniItems.routingOptions['debugWaterBalance'] == "False": self.debugWaterBalance = False # option to perform a run with only natural lakes (without reservoirs) self.onlyNaturalWaterBodies = False if "onlyNaturalWaterBodies" in iniItems.routingOptions.keys() and iniItems.routingOptions['onlyNaturalWaterBodies'] == "True": logger.info("WARNING!! Using only natural water bodies identified in the year 1900. All reservoirs in 1900 are assumed as lakes.") self.onlyNaturalWaterBodies = True self.dateForNaturalCondition = "1900-01-01" # The run for a natural condition should access only this date. # names of files containing water bodies parameters if iniItems.routingOptions['waterBodyInputNC'] == str(None): self.useNetCDF = False self.fracWaterInp = iniItems.routingOptions['fracWaterInp'] self.waterBodyIdsInp = iniItems.routingOptions['waterBodyIds'] self.waterBodyTypInp = iniItems.routingOptions['waterBodyTyp'] self.resMaxCapInp = iniItems.routingOptions['resMaxCapInp'] self.resSfAreaInp = iniItems.routingOptions['resSfAreaInp'] else: self.useNetCDF = True self.ncFileInp = vos.getFullPath(\ iniItems.routingOptions['waterBodyInputNC'],\ self.inputDir) # minimum width (m) used in the weir formula # TODO: define minWeirWidth based on the GLWD, GRanD database and/or bankfull discharge formula self.minWeirWidth = 10. # lower and upper limits at which reservoir release is terminated and # at which reservoir release is equal to long-term average outflow self.minResvrFrac = 0.10 self.maxResvrFrac = 0.75
def __init__(self, cloneMapFileName,\ pcraster_files, \ modelTime, \ output, inputEPSG = None, outputEPSG = None, resample_method = None): DynamicModel.__init__(self) # set the clone map self.cloneMapFileName = cloneMapFileName pcr.setclone(self.cloneMapFileName) # time variable/object self.modelTime = modelTime # output file name, folder name, etc. self.output = output self.output['file_name'] = vos.getFullPath(self.output['file_name'], self.output['folder']) # input and output projection/coordinate systems self.inputEPSG = inputEPSG self.outputEPSG = outputEPSG self.resample_method = resample_method # prepare temporary directory self.tmpDir = output['folder'] + "/tmp/" try: os.makedirs(self.tmpDir) os.system('rm -r ' + tmpDir + "/*") except: pass # pcraster input files self.pcraster_files = pcraster_files # - the begining part of pcraster file names (e.g. "pr" for "pr000000.001") self.pcraster_file_name = self.pcraster_files['directory']+"/"+\ self.pcraster_files['file_name'] # object for reporting self.netcdf_report = OutputNetcdf(mapattr_dict = None,\ cloneMapFileName = cloneMapFileName,\ netcdf_format = "NETCDF3_CLASSIC",\ netcdf_zlib = False,\ netcdf_attribute_dict = None,\ netcdf_attribute_description = self.output['description']) # make a netcdf file self.netcdf_report.createNetCDF(self.output['file_name'],\ self.output['variable_name'],\ self.output['unit'],\ self.output['long_name'])
def __init__(self, cloneMapFileName,\ pcraster_files, \ modelTime, \ output, inputEPSG = None, outputEPSG = None, resample_method = None): DynamicModel.__init__(self) # set the clone map self.cloneMapFileName = cloneMapFileName pcr.setclone(self.cloneMapFileName) # time variable/object self.modelTime = modelTime # output file name, folder name, etc. self.output = output self.output['file_name'] = vos.getFullPath(self.output['file_name'], self.output['folder']) # input and output projection/coordinate systems self.inputEPSG = inputEPSG self.outputEPSG = outputEPSG self.resample_method = resample_method # prepare temporary directory self.tmpDir = output['folder']+"/tmp/" try: os.makedirs(self.tmpDir) os.system('rm -r '+tmpDir+"/*") except: pass # pcraster input files self.pcraster_files = pcraster_files # - the begining part of pcraster file names (e.g. "pr" for "pr000000.001") self.pcraster_file_name = self.pcraster_files['directory']+"/"+\ self.pcraster_files['file_name'] # object for reporting self.netcdf_report = OutputNetcdf(mapattr_dict = None,\ cloneMapFileName = cloneMapFileName,\ netcdf_format = "NETCDF3_CLASSIC",\ netcdf_zlib = False,\ netcdf_attribute_dict = None,\ netcdf_attribute_description = self.output['description']) # make a netcdf file self.netcdf_report.createNetCDF(self.output['file_name'],\ self.output['variable_name'],\ self.output['unit'],\ self.output['long_name'])
def readTopo(self, iniItems, optionDict): # a dictionary/section of options that will be used if optionDict == None: optionDict = iniItems._sections["landSurfaceOptions"] # maps of elevation attributes: topoParams = ['tanslope','slopeLength','orographyBeta'] if optionDict['topographyNC'] == str(None): for var in topoParams: input = configget(iniItems,"landSurfaceOptions",str(var),"None") vars(self)[var] = vos.readPCRmapClone(input,self.cloneMap, self.tmpDir,self.inputDir) if var != "slopeLength": vars(self)[var] = pcr.cover(vars(self)[var], 0.0) else: topoPropertiesNC = vos.getFullPath(\ optionDict['topographyNC'], self.inputDir) for var in topoParams: vars(self)[var] = vos.netcdf2PCRobjCloneWithoutTime(\ topoPropertiesNC,var, \ cloneMapFileName = self.cloneMap) if var != "slopeLength": vars(self)[var] = pcr.cover(vars(self)[var], 0.0) #~ self.tanslope = pcr.max(self.tanslope, 0.00001) # In principle, tanslope can be zero. Zero tanslope will provide zero TCL (no interflow) # covering slopeLength with its maximum value self.slopeLength = pcr.cover(self.slopeLength, pcr.mapmaximum(self.slopeLength)) # maps of relative elevation above flood plains dzRel = ['dzRel0001','dzRel0005', 'dzRel0010','dzRel0020','dzRel0030','dzRel0040','dzRel0050', 'dzRel0060','dzRel0070','dzRel0080','dzRel0090','dzRel0100'] if optionDict['topographyNC'] == str(None): for i in range(0, len(dzRel)): var = dzRel[i] input = optionDict[str(var)] vars(self)[var] = vos.readPCRmapClone(input,self.cloneMap, self.tmpDir,self.inputDir) vars(self)[var] = pcr.cover(vars(self)[var], 0.0) if i > 0: vars(self)[var] = pcr.max(vars(self)[var], vars(self)[dzRel[i-1]]) else: for i in range(0, len(dzRel)): var = dzRel[i] vars(self)[var] = vos.netcdf2PCRobjCloneWithoutTime(\ topoPropertiesNC,var, \ cloneMapFileName = self.cloneMap) vars(self)[var] = pcr.cover(vars(self)[var], 0.0) if i > 0: vars(self)[var] = pcr.max(vars(self)[var], vars(self)[dzRel[i-1]])
def __init__(self, configuration, currTimeStep, initialState=None): self._configuration = configuration self._modelTime = currTimeStep pcr.setclone(configuration.cloneMap) # Read the ldd map. self.lddMap = vos.readPCRmapClone(\ configuration.routingOptions['lddMap'], configuration.cloneMap,configuration.tmpDir,configuration.globalOptions['inputDir'],True) #ensure ldd map is correct, and actually of type "ldd" self.lddMap = pcr.lddrepair(pcr.ldd(self.lddMap)) if configuration.globalOptions['landmask'] != "None": self.landmask = vos.readPCRmapClone(\ configuration.globalOptions['landmask'], configuration.cloneMap,configuration.tmpDir,configuration.globalOptions['inputDir']) else: self.landmask = pcr.defined(self.lddMap) # defining catchment areas self.catchment_class = 1.0 # number of upperSoilLayers: self.numberOfSoilLayers = int( configuration.landSurfaceOptions['numberOfUpperSoilLayers']) # preparing sub-modules self.createSubmodels(initialState) # option for debugging to PCR-GLOBWB version 1.0 self.debug_to_version_one = False if configuration.debug_to_version_one: self.debug_to_version_one = True if self.debug_to_version_one: # preparing initial folder directory self.directory_for_initial_maps = vos.getFullPath( "initials/", self.configuration.mapsDir) if os.path.exists(self.directory_for_initial_maps): shutil.rmtree(self.directory_for_initial_maps) os.makedirs(self.directory_for_initial_maps) # dump the initial state self.dumpState(self.directory_for_initial_maps, "initial")
def __init__(self, iniItems): object.__init__(self) self.noSpinUps = None # How many soil layers (excluding groundwater): self.numberOfLayers = int( iniItems.landSurfaceOptions['numberOfUpperSoilLayers']) # option to save the netcdf files of the latest cycle of spin up runs: self.spinUpOutputDir = None if 'spinUpOutputDir' in iniItems.globalOptions.keys(): self.outNCDir = str(iniItems.outNCDir) if iniItems.globalOptions['spinUpOutputDir'] not in [ "None", "False" ]: self.spinUpOutputDir = vos.getFullPath( iniItems.globalOptions['spinUpOutputDir'], self.outNCDir) if iniItems.globalOptions['spinUpOutputDir'] == "True": self.spinUpOutputDir = self.outNCDir + "/spin-up/" # setting up the convergence parameters self.setupConvergence(iniItems)
def __init__(self, iniItems,landmask,spinUp): object.__init__(self) self.cloneMap = iniItems.cloneMap self.tmpDir = iniItems.tmpDir self.inputDir = iniItems.globalOptions['inputDir'] self.landmask = landmask # option to activate water balance check self.debugWaterBalance = True if iniItems.routingOptions['debugWaterBalance'] == "False": self.debugWaterBalance = False if iniItems.groundwaterOptions['groundwaterPropertiesNC'] == str(None): # assign the recession coefficient parameter(s) self.recessionCoeff = vos.readPCRmapClone(\ iniItems.groundwaterOptions['recessionCoeff'], self.cloneMap,self.tmpDir,self.inputDir) else: groundwaterPropertiesNC = vos.getFullPath(\ iniItems.groundwaterOptions[\ 'groundwaterPropertiesNC'], self.inputDir) self.recessionCoeff = vos.netcdf2PCRobjCloneWithoutTime(\ groundwaterPropertiesNC,'recessionCoeff',\ cloneMapFileName = self.cloneMap) # groundwater recession coefficient (day-1_ self.recessionCoeff = pcr.cover(self.recessionCoeff,0.00) self.recessionCoeff = pcr.min(1.0000,self.recessionCoeff) # if 'minRecessionCoeff' in iniItems.groundwaterOptions.keys(): minRecessionCoeff = float(iniItems.groundwaterOptions['minRecessionCoeff']) else: minRecessionCoeff = 1.0e-4 # This is the minimum value used in Van Beek et al. (2011). self.recessionCoeff = pcr.max(minRecessionCoeff,self.recessionCoeff) if iniItems.groundwaterOptions['groundwaterPropertiesNC'] == str(None): # assign aquifer specific yield self.specificYield = vos.readPCRmapClone(\ iniItems.groundwaterOptions['specificYield'], self.cloneMap,self.tmpDir,self.inputDir) else: self.specificYield = vos.netcdf2PCRobjCloneWithoutTime(\ groundwaterPropertiesNC,'specificYield',\ cloneMapFileName = self.cloneMap) self.specificYield = pcr.cover(self.specificYield,0.0) self.specificYield = pcr.max(0.010,self.specificYield) # TODO: TO BE CHECKED: The resample process of specificYield self.specificYield = pcr.min(1.000,self.specificYield) if iniItems.groundwaterOptions['groundwaterPropertiesNC'] == str(None): # assign aquifer saturated conductivity self.kSatAquifer = vos.readPCRmapClone(\ iniItems.groundwaterOptions['kSatAquifer'], self.cloneMap,self.tmpDir,self.inputDir) else: self.kSatAquifer = vos.netcdf2PCRobjCloneWithoutTime(\ groundwaterPropertiesNC,'kSatAquifer',\ cloneMapFileName = self.cloneMap) self.kSatAquifer = pcr.cover(self.kSatAquifer,0.0) self.kSatAquifer = pcr.max(0.010,self.kSatAquifer) # limitAbstraction options self.limitAbstraction = False if iniItems.landSurfaceOptions['limitAbstraction'] == "True": self.limitAbstraction = True # option for limitting fossil groundwater abstractions - This option is only defined for IWMI project self.limitFossilGroundwaterAbstraction = False if self.limitAbstraction == False and\ "extraOptionsforProjectWithIWMI" in iniItems.allSections and\ iniItems.extraOptionsforProjectWithIWMI['limitFossilGroundWaterAbstraction'] == "True": logger.info('Fossil groundwater abstraction limit is used (IWMI project).') self.limitFossilGroundwaterAbstraction = True # estimate of thickness (unit: mm) of aceesible groundwater: shallow and deep totalGroundwaterThickness = vos.readPCRmapClone(\ iniItems.extraOptionsforProjectWithIWMI['estimateOfTotalGroundwaterThickness'], self.cloneMap,self.tmpDir,self.inputDir) totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, pcr.windowaverage(totalGroundwaterThickness, 1.0)) totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, pcr.windowaverage(totalGroundwaterThickness, 1.5)) totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, pcr.windowaverage(totalGroundwaterThickness, 2.5)) totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, pcr.windowaverage(totalGroundwaterThickness, 5.0)) totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, pcr.windowaverage(totalGroundwaterThickness, 7.5)) totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, pcr.mapmaximum(totalGroundwaterThickness)) # set minimum thickness to 50 m: totalGroundwaterThickness = pcr.max(50.0, totalGroundwaterThickness) # estimate of capacity (unit: m) of renewable groundwater (shallow) storGroundwaterCap = pcr.cover( vos.readPCRmapClone(\ iniItems.extraOptionsforProjectWithIWMI['estimateOfRenewableGroundwaterCapacity'], self.cloneMap,self.tmpDir,self.inputDir),\ 0.0) # fossil groundwater capacity (unit: m) self.fossilWaterCap = pcr.max(0.0,\ totalGroundwaterThickness*self.specificYield - storGroundwaterCap) # option for limitting regional groundwater abstractions - This option is only defined self.limitRegionalAnnualGroundwaterAbstraction = False if "extraOptionsforProjectWithIWMI" in iniItems.allSections and\ iniItems.extraOptionsforProjectWithIWMI['limitRegionalAnnualGroundwaterAbstraction'] == "True": logger.info('Limit for regional groundwater abstraction is used (IWMI project).') self.limitRegionalAnnualGroundwaterAbstraction = True region_ids = vos.readPCRmapClone(\ iniItems.extraOptionsforProjectWithIWMI['regionIds'], self.cloneMap,self.tmpDir,self.inputDir) self.region_ids = pcr.nominal(region_ids) self.region_ids = pcr.ifthen(self.landmask, self.region_ids) self.regionalAnnualGroundwaterAbstractionLimit = vos.readPCRmapClone(\ iniItems.extraOptionsforProjectWithIWMI['pumpingCapacity'], self.cloneMap,self.tmpDir,self.inputDir) self.regionalAnnualGroundwaterAbstractionLimit = pcr.roundup(self.regionalAnnualGroundwaterAbstractionLimit*1000.)/1000. self.regionalAnnualGroundwaterAbstractionLimit = pcr.cover(self.regionalAnnualGroundwaterAbstractionLimit, 0.0) self.regionalAnnualGroundwaterAbstractionLimit *= 1000. * 1000. * 1000. # unit: m3/year self.regionalAnnualGroundwaterAbstractionLimit = pcr.ifthen(self.landmask,\ self.regionalAnnualGroundwaterAbstractionLimit) # zones at which water allocation (surface and groundwater allocation) is determined self.usingAllocSegments = False if iniItems.landSurfaceOptions['allocationSegmentsForGroundSurfaceWater'] != "None": self.usingAllocSegments = True # incorporating groundwater distribution network: if self.usingAllocSegments and self.limitAbstraction == False: self.allocSegments = vos.readPCRmapClone(\ iniItems.landSurfaceOptions['allocationSegmentsForGroundSurfaceWater'], self.cloneMap,self.tmpDir,self.inputDir,isLddMap=False,cover=None,isNomMap=True) self.allocSegments = pcr.ifthen(self.landmask, self.allocSegments) cellArea = vos.readPCRmapClone(\ iniItems.routingOptions['cellAreaMap'], self.cloneMap,self.tmpDir,self.inputDir) cellArea = pcr.ifthen(self.landmask, cellArea) # TODO: integrate this one with the one coming from the routing module self.segmentArea = pcr.areatotal(pcr.cover(cellArea, 0.0), self.allocSegments) self.segmentArea = pcr.ifthen(self.landmask, self.segmentArea) self.report = True try: self.outDailyTotNC = iniItems.groundwaterOptions['outDailyTotNC'].split(",") self.outMonthTotNC = iniItems.groundwaterOptions['outMonthTotNC'].split(",") self.outMonthAvgNC = iniItems.groundwaterOptions['outMonthAvgNC'].split(",") self.outMonthEndNC = iniItems.groundwaterOptions['outMonthEndNC'].split(",") self.outAnnuaTotNC = iniItems.groundwaterOptions['outAnnuaTotNC'].split(",") self.outAnnuaAvgNC = iniItems.groundwaterOptions['outAnnuaAvgNC'].split(",") self.outAnnuaEndNC = iniItems.groundwaterOptions['outAnnuaEndNC'].split(",") except: self.report = False if self.report == True: self.outNCDir = iniItems.outNCDir self.netcdfObj = PCR2netCDF(iniItems) # # daily output in netCDF files: if self.outDailyTotNC[0] != "None": for var in self.outDailyTotNC: # creating the netCDF files: self.netcdfObj.createNetCDF(str(self.outNCDir)+"/"+ \ str(var)+"_dailyTot.nc",\ var,"undefined") # MONTHly output in netCDF files: # - cummulative if self.outMonthTotNC[0] != "None": for var in self.outMonthTotNC: # initiating monthlyVarTot (accumulator variable): vars(self)[var+'MonthTot'] = None # creating the netCDF files: self.netcdfObj.createNetCDF(str(self.outNCDir)+"/"+ \ str(var)+"_monthTot.nc",\ var,"undefined") # - average if self.outMonthAvgNC[0] != "None": for var in self.outMonthAvgNC: # initiating monthlyTotAvg (accumulator variable) vars(self)[var+'MonthTot'] = None # initiating monthlyVarAvg: vars(self)[var+'MonthAvg'] = None # creating the netCDF files: self.netcdfObj.createNetCDF(str(self.outNCDir)+"/"+ \ str(var)+"_monthAvg.nc",\ var,"undefined") # - last day of the month if self.outMonthEndNC[0] != "None": for var in self.outMonthEndNC: # creating the netCDF files: self.netcdfObj.createNetCDF(str(self.outNCDir)+"/"+ \ str(var)+"_monthEnd.nc",\ var,"undefined") # YEARly output in netCDF files: # - cummulative if self.outAnnuaTotNC[0] != "None": for var in self.outAnnuaTotNC: # initiating yearly accumulator variable: vars(self)[var+'AnnuaTot'] = None # creating the netCDF files: self.netcdfObj.createNetCDF(str(self.outNCDir)+"/"+ \ str(var)+"_annuaTot.nc",\ var,"undefined") # - average if self.outAnnuaAvgNC[0] != "None": for var in self.outAnnuaAvgNC: # initiating annualyVarAvg: vars(self)[var+'AnnuaAvg'] = None # initiating annualyTotAvg (accumulator variable) vars(self)[var+'AnnuaTot'] = None # creating the netCDF files: self.netcdfObj.createNetCDF(str(self.outNCDir)+"/"+ \ str(var)+"_annuaAvg.nc",\ var,"undefined") # - last day of the year if self.outAnnuaEndNC[0] != "None": for var in self.outAnnuaEndNC: # creating the netCDF files: self.netcdfObj.createNetCDF(str(self.outNCDir)+"/"+ \ str(var)+"_annuaEnd.nc",\ var,"undefined") #get initial conditions self.getICs(iniItems,spinUp)
def __init__(self, iniItems, landmask, onlyNaturalWaterBodies=False, lddMap=None): object.__init__(self) # clone map file names, temporary directory and global/absolute path of input directory self.cloneMap = iniItems.cloneMap self.tmpDir = iniItems.tmpDir self.inputDir = iniItems.globalOptions['inputDir'] self.landmask = landmask self.iniItems = iniItems # local drainage direction: if lddMap is None: self.lddMap = vos.readPCRmapClone( iniItems.routingOptions['lddMap'], self.cloneMap, self.tmpDir, self.inputDir, True) self.lddMap = pcr.lddrepair(pcr.ldd(self.lddMap)) self.lddMap = pcr.lddrepair(self.lddMap) else: self.lddMap = lddMap # the following is needed for a modflowOfflineCoupling run if 'modflowOfflineCoupling' in list(iniItems.globalOptions.keys( )) and iniItems.globalOptions[ 'modflowOfflineCoupling'] == "True" and 'routingOptions' not in iniItems.allSections: logger.info( "The 'routingOptions' are not defined in the configuration ini file. We will adopt them from the 'modflowParameterOptions'." ) iniItems.routingOptions = iniItems.modflowParameterOptions # option to activate water balance check self.debugWaterBalance = True if 'debugWaterBalance' in list(iniItems.routingOptions.keys( )) and iniItems.routingOptions['debugWaterBalance'] == "False": self.debugWaterBalance = False # option to perform a run with only natural lakes (without reservoirs) self.onlyNaturalWaterBodies = onlyNaturalWaterBodies if "onlyNaturalWaterBodies" in list(iniItems.routingOptions.keys( )) and iniItems.routingOptions['onlyNaturalWaterBodies'] == "True": logger.info( "Using only natural water bodies identified in the year 1900. All reservoirs in 1900 are assumed as lakes." ) self.onlyNaturalWaterBodies = True self.dateForNaturalCondition = "1900-01-01" # The run for a natural condition should access only this date. # names of files containing water bodies parameters if iniItems.routingOptions['waterBodyInputNC'] == str(None): self.useNetCDF = False self.fracWaterInp = iniItems.routingOptions['fracWaterInp'] self.waterBodyIdsInp = iniItems.routingOptions['waterBodyIds'] self.waterBodyTypInp = iniItems.routingOptions['waterBodyTyp'] self.resMaxCapInp = iniItems.routingOptions['resMaxCapInp'] self.resSfAreaInp = iniItems.routingOptions['resSfAreaInp'] else: self.useNetCDF = True self.ncFileInp = vos.getFullPath(\ iniItems.routingOptions['waterBodyInputNC'],\ self.inputDir) # minimum width (m) used in the weir formula # TODO: define minWeirWidth based on the GLWD, GRanD database and/or bankfull discharge formula self.minWeirWidth = 10. # lower and upper limits at which reservoir release is terminated and # at which reservoir release is equal to long-term average outflow # - default values self.minResvrFrac = 0.10 self.maxResvrFrac = 0.75 # - from the ini file if "minResvrFrac" in list(iniItems.routingOptions.keys()): minResvrFrac = iniItems.routingOptions['minResvrFrac'] self.minResvrFrac = vos.readPCRmapClone(minResvrFrac, self.cloneMap, self.tmpDir, self.inputDir) if "maxResvrFrac" in list(iniItems.routingOptions.keys()): maxResvrFrac = iniItems.routingOptions['maxResvrFrac'] self.maxResvrFrac = vos.readPCRmapClone(maxResvrFrac, self.cloneMap, self.tmpDir, self.inputDir)
def readSoilMapOfFAO(self, iniItems, optionDict = None): # a dictionary/section of options that will be used if optionDict == None: optionDict = iniItems._sections["landSurfaceOptions"] #iniItems.landSurfaceOptions # soil variable names given either in the ini or netCDF file: soilParameters = ['airEntryValue1','airEntryValue2', 'poreSizeBeta1','poreSizeBeta2', 'resVolWC1','resVolWC2', 'satVolWC1','satVolWC2', 'KSat1','KSat2', 'percolationImp'] if optionDict['soilPropertiesNC'] == str(None): for var in soilParameters: input = optionDict[str(var)] vars(self)[var] = \ vos.readPCRmapClone(input,self.cloneMap,\ self.tmpDir,self.inputDir) vars(self)[var] = pcr.scalar(vars(self)[var]) if input == "percolationImp": vars(self)[var] = pcr.cover(vars(self)[var], 0.0) # extrapolation # - TODO: Make a general extrapolation option as a function in the virtualOS.py vars(self)[var] = pcr.cover(vars(self)[var], pcr.windowaverage(vars(self)[var], 0.75)) vars(self)[var] = pcr.cover(vars(self)[var], pcr.windowaverage(vars(self)[var], 1.00)) vars(self)[var] = pcr.cover(vars(self)[var], pcr.windowaverage(vars(self)[var], 1.00)) vars(self)[var] = pcr.cover(vars(self)[var], pcr.windowaverage(vars(self)[var], 1.00)) vars(self)[var] = pcr.cover(vars(self)[var], pcr.windowaverage(vars(self)[var], 1.00)) vars(self)[var] = pcr.cover(vars(self)[var], pcr.windowaverage(vars(self)[var], 1.00)) vars(self)[var] = pcr.cover(vars(self)[var], 0.0) else: soilPropertiesNC = vos.getFullPath(\ optionDict['soilPropertiesNC'], self.inputDir) for var in soilParameters: vars(self)[var] = vos.netcdf2PCRobjCloneWithoutTime(\ soilPropertiesNC,var, \ cloneMapFileName = self.cloneMap) if var == "percolationImp": vars(self)[var] = pcr.cover(vars(self)[var], 0.0) # extrapolation # - TODO: Make a general extrapolation option as a function in the virtualOS.py vars(self)[var] = pcr.cover(vars(self)[var], pcr.windowaverage(vars(self)[var], 0.75)) vars(self)[var] = pcr.cover(vars(self)[var], pcr.windowaverage(vars(self)[var], 1.00)) vars(self)[var] = pcr.cover(vars(self)[var], pcr.windowaverage(vars(self)[var], 1.00)) vars(self)[var] = pcr.cover(vars(self)[var], pcr.windowaverage(vars(self)[var], 1.00)) vars(self)[var] = pcr.cover(vars(self)[var], pcr.windowaverage(vars(self)[var], 1.00)) vars(self)[var] = pcr.cover(vars(self)[var], pcr.windowaverage(vars(self)[var], 1.00)) vars(self)[var] = pcr.cover(vars(self)[var], 0.01) # make sure that resVolWC1 <= satVolWC1 self.resVolWC1 = pcr.min(self.resVolWC1, self.satVolWC1) self.resVolWC2 = pcr.min(self.resVolWC2, self.satVolWC2) if self.numberOfLayers == 2: self.satVolMoistContUpp = self.satVolWC1 # saturated volumetric moisture content (m3.m-3) self.satVolMoistContLow = self.satVolWC2 self.resVolMoistContUpp = self.resVolWC1 # residual volumetric moisture content (m3.m-3) self.resVolMoistContLow = self.resVolWC2 self.airEntryValueUpp = self.airEntryValue1 # air entry value (m) according to soil water retention curve of Clapp & Hornberger (1978) self.airEntryValueLow = self.airEntryValue2 self.poreSizeBetaUpp = self.poreSizeBeta1 # pore size distribution parameter according to Clapp & Hornberger (1978) self.poreSizeBetaLow = self.poreSizeBeta2 self.kSatUpp = self.KSat1 # saturated hydraulic conductivity (m.day-1) self.kSatLow = self.KSat2 if self.numberOfLayers == 3: self.satVolMoistContUpp000005 = self.satVolWC1 self.satVolMoistContUpp005030 = self.satVolWC1 self.satVolMoistContLow030150 = self.satVolWC2 self.resVolMoistContUpp000005 = self.resVolWC1 self.resVolMoistContUpp005030 = self.resVolWC1 self.resVolMoistContLow030150 = self.resVolWC2 self.airEntryValueUpp000005 = self.airEntryValue1 self.airEntryValueUpp005030 = self.airEntryValue1 self.airEntryValueLow030150 = self.airEntryValue2 self.poreSizeBetaUpp000005 = self.poreSizeBeta1 self.poreSizeBetaUpp005030 = self.poreSizeBeta1 self.poreSizeBetaLow030150 = self.poreSizeBeta2 self.kSatUpp000005 = self.KSat1 self.kSatUpp005030 = self.KSat1 self.kSatLow030150 = self.KSat2 self.percolationImp = pcr.cover(self.percolationImp, 0.0) # fractional area where percolation to groundwater store is impeded (dimensionless) # soil thickness and storage variable names # as given either in the ini or netCDF file: soilStorages = ['firstStorDepth', 'secondStorDepth', 'soilWaterStorageCap1','soilWaterStorageCap2'] if optionDict['soilPropertiesNC'] == str(None): for var in soilStorages: input = optionDict[str(var)] temp = str(var)+'Inp' vars(self)[temp] = vos.readPCRmapClone(input,\ self.cloneMap, self.tmpDir,self.inputDir) # extrapolation # - TODO: Make a general extrapolation option as a function in the virtualOS.py vars(self)[temp] = pcr.cover(vars(self)[temp], pcr.windowaverage(vars(self)[temp], 0.75)) vars(self)[temp] = pcr.cover(vars(self)[temp], pcr.windowaverage(vars(self)[temp], 1.05)) vars(self)[temp] = pcr.cover(vars(self)[temp], pcr.windowaverage(vars(self)[temp], 1.05)) vars(self)[temp] = pcr.cover(vars(self)[temp], pcr.windowaverage(vars(self)[temp], 1.05)) vars(self)[temp] = pcr.cover(vars(self)[temp], pcr.windowaverage(vars(self)[temp], 1.05)) vars(self)[temp] = pcr.cover(vars(self)[temp], pcr.windowaverage(vars(self)[temp], 1.05)) vars(self)[temp] = pcr.cover(vars(self)[temp], 0.0) else: soilPropertiesNC = vos.getFullPath(\ optionDict['soilPropertiesNC'], self.inputDir) for var in soilStorages: temp = str(var)+'Inp' vars(self)[temp] = vos.netcdf2PCRobjCloneWithoutTime(\ soilPropertiesNC,var, \ cloneMapFileName = self.cloneMap) # extrapolation # - TODO: Make a general extrapolation option as a function in the virtualOS.py vars(self)[temp] = pcr.cover(vars(self)[temp], pcr.windowaverage(vars(self)[temp], 0.75)) vars(self)[temp] = pcr.cover(vars(self)[temp], pcr.windowaverage(vars(self)[temp], 1.05)) vars(self)[temp] = pcr.cover(vars(self)[temp], pcr.windowaverage(vars(self)[temp], 1.05)) vars(self)[temp] = pcr.cover(vars(self)[temp], pcr.windowaverage(vars(self)[temp], 1.05)) vars(self)[temp] = pcr.cover(vars(self)[temp], pcr.windowaverage(vars(self)[temp], 1.05)) vars(self)[temp] = pcr.cover(vars(self)[temp], pcr.windowaverage(vars(self)[temp], 1.05)) vars(self)[temp] = pcr.cover(vars(self)[temp], 0.0) # layer thickness if self.numberOfLayers == 2: self.thickUpp = (0.30/0.30)*self.firstStorDepthInp self.thickLow = (1.20/1.20)*self.secondStorDepthInp if self.numberOfLayers == 3: self.thickUpp000005 = (0.05/0.30)*self.firstStorDepthInp self.thickUpp005030 = (0.25/0.30)*self.firstStorDepthInp self.thickLow030150 = (1.20/1.20)*self.secondStorDepthInp # soil storage if self.numberOfLayers == 2: #~ self.storCapUpp = (0.30/0.30)*self.soilWaterStorageCap1Inp #~ self.storCapLow = (1.20/1.20)*self.soilWaterStorageCap2Inp # 22 Feb 2014: We can calculate this based on thickness and porosity. self.storCapUpp = self.thickUpp * \ (self.satVolMoistContUpp - self.resVolMoistContUpp) self.storCapLow = self.thickLow * \ (self.satVolMoistContLow - self.resVolMoistContLow) self.rootZoneWaterStorageCap = self.storCapUpp + \ self.storCapLow # This is called as WMAX in the original pcrcalc script. if self.numberOfLayers == 3: self.storCapUpp000005 = self.thickUpp000005 * \ (self.satVolMoistContUpp000005 - self.resVolMoistContUpp000005) self.storCapUpp005030 = self.thickUpp005030 * \ (self.satVolMoistContUpp005030 - self.resVolMoistContUpp005030) self.storCapLow030150 = self.thickLow030150 * \ (self.satVolMoistContLow030150 - self.resVolMoistContLow030150) self.rootZoneWaterStorageCap = self.storCapUpp000005 + \ self.storCapUpp005030 + \ self.storCapLow030150
def set_input_files(self): # full path for the clone map self.cloneMap = vos.getFullPath(self.globalOptions['cloneMap'], self.globalOptions['inputDir'])
def forcingDownscalingOptions(self, iniItems): self.downscalePrecipitationOption = False self.downscaleTemperatureOption = False self.downscaleReferenceETPotOption = False if 'meteoDownscalingOptions' in iniItems.allSections: # downscaling options if iniItems.meteoDownscalingOptions[ 'downscalePrecipitation'] == "True": self.downscalePrecipitationOption = True logger.info( "Precipitation forcing will be downscaled to the cloneMap resolution." ) if iniItems.meteoDownscalingOptions[ 'downscaleTemperature'] == "True": self.downscaleTemperatureOption = True logger.info( "Temperature forcing will be downscaled to the cloneMap resolution." ) if iniItems.meteoDownscalingOptions[ 'downscaleReferenceETPot'] == "True" and self.refETPotMethod != 'Hamon': self.downscaleReferenceETPotOption = True logger.info( "Reference potential evaporation will be downscaled to the cloneMap resolution." ) # Note that for the Hamon method: referencePotET will be calculated based on temperature, # therefore, we do not have to downscale it (particularly if temperature is already provided at high resolution). if self.downscalePrecipitationOption or\ self.downscaleTemperatureOption or\ self.downscaleReferenceETPotOption: # creating anomaly DEM highResolutionDEM = vos.readPCRmapClone(\ iniItems.meteoDownscalingOptions['highResolutionDEM'], self.cloneMap,self.tmpDir,self.inputDir) highResolutionDEM = pcr.cover(highResolutionDEM, 0.0) highResolutionDEM = pcr.max(highResolutionDEM, 0.0) self.meteoDownscaleIds = vos.readPCRmapClone(\ iniItems.meteoDownscalingOptions['meteoDownscaleIds'], self.cloneMap,self.tmpDir,self.inputDir,isLddMap=False,cover=None,isNomMap=True) self.cellArea = vos.readPCRmapClone(\ iniItems.routingOptions['cellAreaMap'], self.cloneMap,self.tmpDir,self.inputDir) loweResolutionDEM = pcr.areatotal(pcr.cover(highResolutionDEM*self.cellArea, 0.0),\ self.meteoDownscaleIds)/\ pcr.areatotal(pcr.cover(self.cellArea, 0.0),\ self.meteoDownscaleIds) self.anomalyDEM = highResolutionDEM - loweResolutionDEM # unit: meter # temperature lapse rate (netCDF) file self.temperLapseRateNC = vos.getFullPath(iniItems.meteoDownscalingOptions[\ 'temperLapseRateNC'],self.inputDir) self.temperatCorrelNC = vos.getFullPath(iniItems.meteoDownscalingOptions[\ 'temperatCorrelNC'],self.inputDir) # TODO: Remove this criteria. # precipitation lapse rate (netCDF) file self.precipLapseRateNC = vos.getFullPath(iniItems.meteoDownscalingOptions[\ 'precipLapseRateNC'],self.inputDir) self.precipitCorrelNC = vos.getFullPath(iniItems.meteoDownscalingOptions[\ 'precipitCorrelNC'],self.inputDir) # TODO: Remove this criteria. else: logger.info("No forcing downscaling is implemented.") # forcing smoothing options: - THIS is still experimental. PS: MUST BE TESTED. self.forcingSmoothing = False if 'meteoDownscalingOptions' in iniItems.allSections and \ 'smoothingWindowsLength' in list(iniItems.meteoDownscalingOptions.keys()): if float(iniItems.meteoDownscalingOptions['smoothingWindowsLength'] ) > 0.0: self.forcingSmoothing = True self.smoothingWindowsLength = vos.readPCRmapClone(\ iniItems.meteoDownscalingOptions['smoothingWindowsLength'], self.cloneMap,self.tmpDir,self.inputDir) msg = "Forcing data will be smoothed with 'windowaverage' using the window length:" + str( iniItems.meteoDownscalingOptions['smoothingWindowsLength']) logger.info(msg)
def create_output_directories(self): if self.using_relative_path_for_output_directory: self.globalOptions['outputDir'] = self.make_absolute_path( self.globalOptions['outputDir']) # making the root/parent of OUTPUT directory: cleanOutputDir = False if cleanOutputDir: try: shutil.rmtree(self.globalOptions['outputDir']) except: pass # for new outputDir (not exist yet) try: os.makedirs(self.globalOptions['outputDir']) except: pass # for new outputDir (not exist yet) # making temporary directory: self.tmpDir = vos.getFullPath("tmp/", \ self.globalOptions['outputDir']) if os.path.exists(self.tmpDir): shutil.rmtree(self.tmpDir) os.makedirs(self.tmpDir) self.outNCDir = vos.getFullPath("netcdf/", \ self.globalOptions['outputDir']) if os.path.exists(self.outNCDir): shutil.rmtree(self.outNCDir) os.makedirs(self.outNCDir) # making backup for the python scripts used: self.scriptDir = vos.getFullPath("scripts/", \ self.globalOptions['outputDir']) if os.path.exists(self.scriptDir): shutil.rmtree(self.scriptDir) os.makedirs(self.scriptDir) # working/starting directory where all s path_of_this_module = os.path.abspath(os.path.dirname(__file__)) self.starting_directory = path_of_this_module for filename in glob.glob(os.path.join(path_of_this_module, '*.py')): shutil.copy(filename, self.scriptDir) # making log directory: self.logFileDir = vos.getFullPath("log/", \ self.globalOptions['outputDir']) cleanLogDir = True if os.path.exists(self.logFileDir) and cleanLogDir: shutil.rmtree(self.logFileDir) os.makedirs(self.logFileDir) # making endStateDir directory: self.endStateDir = vos.getFullPath("states/", \ self.globalOptions['outputDir']) if os.path.exists(self.endStateDir): shutil.rmtree(self.endStateDir) os.makedirs(self.endStateDir) # making pcraster maps directory: self.mapsDir = vos.getFullPath("maps/", \ self.globalOptions['outputDir']) cleanMapDir = True if os.path.exists(self.mapsDir) and cleanMapDir: shutil.rmtree(self.mapsDir) os.makedirs(self.mapsDir) # go to pcraster maps directory (so all pcr.report files will be saved in this directory) os.chdir(self.mapsDir)
def __init__(self, iniItems,landmask,spinUp): object.__init__(self) self.cloneMap = iniItems.cloneMap self.tmpDir = iniItems.tmpDir self.inputDir = iniItems.globalOptions['inputDir'] self.landmask = landmask # option to activate water balance check self.debugWaterBalance = True if iniItems.routingOptions['debugWaterBalance'] == "False": self.debugWaterBalance = False if iniItems.groundwaterOptions['groundwaterPropertiesNC'] == str(None): # assign the recession coefficient parameter(s) self.recessionCoeff = vos.readPCRmapClone(\ iniItems.groundwaterOptions['recessionCoeff'], self.cloneMap,self.tmpDir,self.inputDir) else: groundwaterPropertiesNC = vos.getFullPath(\ iniItems.groundwaterOptions[\ 'groundwaterPropertiesNC'], self.inputDir) self.recessionCoeff = vos.netcdf2PCRobjCloneWithoutTime(\ groundwaterPropertiesNC,'recessionCoeff',\ cloneMapFileName = self.cloneMap) # groundwater recession coefficient (day-1) self.recessionCoeff = pcr.cover(self.recessionCoeff,0.00) self.recessionCoeff = pcr.min(1.0000,self.recessionCoeff) # if 'minRecessionCoeff' in iniItems.groundwaterOptions.keys(): minRecessionCoeff = float(iniItems.groundwaterOptions['minRecessionCoeff']) else: minRecessionCoeff = 1.0e-4 # This is the minimum value used in Van Beek et al. (2011). self.recessionCoeff = pcr.max(minRecessionCoeff,self.recessionCoeff) if iniItems.groundwaterOptions['groundwaterPropertiesNC'] == str(None): # assign aquifer specific yield self.specificYield = vos.readPCRmapClone(\ iniItems.groundwaterOptions['specificYield'], self.cloneMap,self.tmpDir,self.inputDir) else: self.specificYield = vos.netcdf2PCRobjCloneWithoutTime(\ groundwaterPropertiesNC,'specificYield',\ cloneMapFileName = self.cloneMap) self.specificYield = pcr.cover(self.specificYield,0.0) self.specificYield = pcr.max(0.010,self.specificYield) # TODO: TO BE CHECKED: The resample process of specificYield self.specificYield = pcr.min(1.000,self.specificYield) if iniItems.groundwaterOptions['groundwaterPropertiesNC'] == str(None): # assign aquifer saturated conductivity self.kSatAquifer = vos.readPCRmapClone(\ iniItems.groundwaterOptions['kSatAquifer'], self.cloneMap,self.tmpDir,self.inputDir) else: self.kSatAquifer = vos.netcdf2PCRobjCloneWithoutTime(\ groundwaterPropertiesNC,'kSatAquifer',\ cloneMapFileName = self.cloneMap) self.kSatAquifer = pcr.cover(self.kSatAquifer,0.0) self.kSatAquifer = pcr.max(0.010,self.kSatAquifer) # limitAbstraction options self.limitAbstraction = False if iniItems.landSurfaceOptions['limitAbstraction'] == "True": self.limitAbstraction = True # option for limitting regional groundwater abstractions if iniItems.groundwaterOptions['pumpingCapacityNC'] != "None": logger.info('Limit for annual regional groundwater abstraction is used.') self.limitRegionalAnnualGroundwaterAbstraction = True self.pumpingCapacityNC = vos.getFullPath(\ iniItems.groundwaterOptions['pumpingCapacityNC'],self.inputDir,False) else: logger.warning('NO LIMIT for regional groundwater (annual) pumping. It may result too high groundwater abstraction.') self.limitRegionalAnnualGroundwaterAbstraction = False # option for limitting fossil groundwater abstractions: self.limitFossilGroundwaterAbstraction = False # # estimate of fossil groundwater capacity: if iniItems.groundwaterOptions['limitFossilGroundWaterAbstraction'] == "True": logger.info('Fossil groundwater abstractions are allowed with LIMIT.') self.limitFossilGroundwaterAbstraction = True # estimate of thickness (unit: m) of accesible groundwater: shallow and deep totalGroundwaterThickness = vos.readPCRmapClone(\ iniItems.groundwaterOptions['estimateOfTotalGroundwaterThickness'], self.cloneMap,self.tmpDir,self.inputDir) # extrapolation totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, pcr.windowaverage(totalGroundwaterThickness, 1.0)) totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, pcr.windowaverage(totalGroundwaterThickness, 1.5)) totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, pcr.windowaverage(totalGroundwaterThickness, 2.5)) totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, pcr.windowaverage(totalGroundwaterThickness, 5.0)) # totalGroundwaterThickness = pcr.cover(totalGroundwaterThickness, 0.0) # # set minimum thickness minimumThickness = pcr.scalar(float(\ iniItems.groundwaterOptions['minimumTotalGroundwaterThickness'])) totalGroundwaterThickness = pcr.max(minimumThickness, totalGroundwaterThickness) # # estimate of capacity (unit: m) of renewable groundwater (shallow) storGroundwaterCap = pcr.cover( vos.readPCRmapClone(\ iniItems.groundwaterOptions['estimateOfRenewableGroundwaterCapacity'], self.cloneMap,self.tmpDir,self.inputDir), 0.0) # # fossil groundwater capacity (unit: m) self.fossilWaterCap = pcr.ifthen(self.landmask,\ pcr.max(0.0,\ totalGroundwaterThickness*self.specificYield - storGroundwaterCap)) # zones at which groundwater allocations are determined self.usingAllocSegments = False if iniItems.landSurfaceOptions['allocationSegmentsForGroundSurfaceWater'] != "None": self.usingAllocSegments = True # incorporating groundwater distribution network: if self.usingAllocSegments: self.allocSegments = vos.readPCRmapClone(\ iniItems.landSurfaceOptions['allocationSegmentsForGroundSurfaceWater'], self.cloneMap,self.tmpDir,self.inputDir,isLddMap=False,cover=None,isNomMap=True) self.allocSegments = pcr.ifthen(self.landmask, self.allocSegments) cellArea = vos.readPCRmapClone(\ iniItems.routingOptions['cellAreaMap'], self.cloneMap,self.tmpDir,self.inputDir) cellArea = pcr.ifthen(self.landmask, cellArea) # TODO: integrate this one with the one coming from the routing module self.segmentArea = pcr.areatotal(pcr.cover(cellArea, 0.0), self.allocSegments) self.segmentArea = pcr.ifthen(self.landmask, self.segmentArea) # get initial conditions self.getICs(iniItems,spinUp) # initiate old style reporting # TODO: remove this! self.initiate_old_style_groundwater_reporting(iniItems)
def create_output_directories(self): # making the root/parent of OUTPUT directory: cleanOutputDir = False if cleanOutputDir: try: shutil.rmtree(self.globalOptions['outputDir']) except: pass # for new outputDir (not exist yet) try: os.makedirs(self.globalOptions['outputDir']) except: pass # for new outputDir (not exist yet) # making temporary directory (needed for resampling process) self.tmpDir = vos.getFullPath("tmp/", \ self.globalOptions['outputDir']) if os.path.exists(self.tmpDir): shutil.rmtree(self.tmpDir) os.makedirs(self.tmpDir) self.outNCDir = vos.getFullPath("netcdf/", \ self.globalOptions['outputDir']) if os.path.exists(self.outNCDir): shutil.rmtree(self.outNCDir) os.makedirs(self.outNCDir) # making backup for the python scripts used: self.scriptDir = vos.getFullPath("scripts/", \ self.globalOptions['outputDir']) if os.path.exists(self.scriptDir): shutil.rmtree(self.scriptDir) os.makedirs(self.scriptDir) self.path_of_this_module = os.path.abspath(os.path.dirname(__file__)) for filename in glob.glob(os.path.join(self.path_of_this_module, '*.py')): shutil.copy(filename, self.scriptDir) # making log directory: self.logFileDir = vos.getFullPath("log/", \ self.globalOptions['outputDir']) cleanLogDir = True if os.path.exists(self.logFileDir) and cleanLogDir: shutil.rmtree(self.logFileDir) os.makedirs(self.logFileDir) # making endStateDir directory # - this directory will contain the calculated groundwater head values self.endStateDir = vos.getFullPath("states/", \ self.globalOptions['outputDir']) if os.path.exists(self.endStateDir): shutil.rmtree(self.endStateDir) os.makedirs(self.endStateDir) # making pcraster maps directory # - this directory will contain all variables/maps that will be used during the pcraster-modflow coupling self.mapsDir = vos.getFullPath("maps/", \ self.globalOptions['outputDir']) cleanMapDir = True if os.path.exists(self.mapsDir) and cleanMapDir: shutil.rmtree(self.mapsDir) os.makedirs(self.mapsDir) # making temporary directory for modflow calculation and make sure that the directory is empty self.tmp_modflow_dir = "tmp_modflow/" if 'tmp_modflow_dir' in self.globalOptions.keys(): self.tmp_modflow_dir = self.globalOptions['tmp_modflow_dir'] self.tmp_modflow_dir = vos.getFullPath(self.tmp_modflow_dir, \ self.globalOptions['outputDir'])+"/" if os.path.exists(self.tmp_modflow_dir): shutil.rmtree(self.tmp_modflow_dir) os.makedirs(self.tmp_modflow_dir) # # go to the temporary directory for the modflow calulation (so that all calculation will be saved in that folder) os.chdir(self.tmp_modflow_dir)
def readSoilMapOfFAO(self, iniItems): # soil variable names given either in the ini or netCDF file: soilParameters = [ 'airEntryValue1', 'airEntryValue2', 'poreSizeBeta1', 'poreSizeBeta2', 'resVolWC1', 'resVolWC2', 'satVolWC1', 'satVolWC2', 'KSat1', 'KSat2', 'percolationImp' ] if iniItems.landSurfaceOptions['soilPropertiesNC'] == str(None): for var in soilParameters: input = iniItems.landSurfaceOptions[str(var)] vars(self)[var] = \ vos.readPCRmapClone(input,self.cloneMap,\ self.tmpDir,self.inputDir) vars(self)[var] = pcr.scalar(vars(self)[var]) vars(self)[var] = pcr.cover(vars(self)[var], 0.0) else: soilPropertiesNC = vos.getFullPath(\ iniItems.landSurfaceOptions[\ 'soilPropertiesNC'], self.inputDir) for var in soilParameters: vars(self)[var] = vos.netcdf2PCRobjCloneWithoutTime(\ soilPropertiesNC,var, \ cloneMapFileName = self.cloneMap) vars(self)[var] = pcr.cover(vars(self)[var], 0.0) if self.numberOfLayers == 2: self.satVolMoistContUpp = self.satVolWC1 # saturated volumetric moisture content (m3.m-3) self.satVolMoistContLow = self.satVolWC2 self.resVolMoistContUpp = self.resVolWC1 # residual volumetric moisture content (m3.m-3) self.resVolMoistContLow = self.resVolWC2 self.airEntryValueUpp = self.airEntryValue1 # air entry value (m) according to soil water retention curve of Clapp & Hornberger (1978) self.airEntryValueLow = self.airEntryValue2 self.poreSizeBetaUpp = self.poreSizeBeta1 # pore size distribution parameter according to Clapp & Hornberger (1978) self.poreSizeBetaLow = self.poreSizeBeta2 self.kSatUpp = self.KSat1 # saturated hydraulic conductivity (m.day-1) self.kSatLow = self.KSat2 if self.numberOfLayers == 3: self.satVolMoistContUpp000005 = self.satVolWC1 self.satVolMoistContUpp005030 = self.satVolWC1 self.satVolMoistContLow030150 = self.satVolWC2 self.resVolMoistContUpp000005 = self.resVolWC1 self.resVolMoistContUpp005030 = self.resVolWC1 self.resVolMoistContLow030150 = self.resVolWC2 self.airEntryValueUpp000005 = self.airEntryValue1 self.airEntryValueUpp005030 = self.airEntryValue1 self.airEntryValueLow030150 = self.airEntryValue2 self.poreSizeBetaUpp000005 = self.poreSizeBeta1 self.poreSizeBetaUpp005030 = self.poreSizeBeta1 self.poreSizeBetaLow030150 = self.poreSizeBeta2 self.kSatUpp000005 = self.KSat1 self.kSatUpp005030 = self.KSat1 self.kSatLow030150 = self.KSat2 self.percolationImp = self.percolationImp # fractional area where percolation to groundwater store is impeded (dimensionless) # soil thickness and storage variable names # as given either in the ini or netCDF file: soilStorages = [ 'firstStorDepth', 'secondStorDepth', 'soilWaterStorageCap1', 'soilWaterStorageCap2' ] if iniItems.landSurfaceOptions['soilPropertiesNC'] == str(None): for var in soilStorages: input = iniItems.landSurfaceOptions[str(var)] temp = str(var) + 'Inp' vars(self)[temp] = vos.readPCRmapClone(input,\ self.cloneMap, self.tmpDir,self.inputDir) vars(self)[temp] = pcr.cover(vars(self)[temp], 0.0) else: soilPropertiesNC = vos.getFullPath(\ iniItems.landSurfaceOptions[\ 'soilPropertiesNC'], self.inputDir) for var in soilStorages: temp = str(var) + 'Inp' vars(self)[temp] = vos.netcdf2PCRobjCloneWithoutTime(\ soilPropertiesNC,var, \ cloneMapFileName = self.cloneMap) vars(self)[temp] = pcr.cover(vars(self)[temp], 0.0) # layer thickness if self.numberOfLayers == 2: self.thickUpp = (0.30 / 0.30) * self.firstStorDepthInp self.thickLow = (1.20 / 1.20) * self.secondStorDepthInp if self.numberOfLayers == 3: self.thickUpp000005 = (0.05 / 0.30) * self.firstStorDepthInp self.thickUpp005030 = (0.25 / 0.30) * self.firstStorDepthInp self.thickLow030150 = (1.20 / 1.20) * self.secondStorDepthInp # soil storage if self.numberOfLayers == 2: #~ self.storCapUpp = (0.30/0.30)*self.soilWaterStorageCap1Inp #~ self.storCapLow = (1.20/1.20)*self.soilWaterStorageCap2Inp # 22 Feb 2014: We can calculate this based on thickness and porosity. self.storCapUpp = self.thickUpp * \ (self.satVolMoistContUpp - self.resVolMoistContUpp) self.storCapLow = self.thickLow * \ (self.satVolMoistContLow - self.resVolMoistContLow) self.rootZoneWaterStorageCap = self.storCapUpp + \ self.storCapLow if self.numberOfLayers == 3: self.storCapUpp000005 = self.thickUpp000005 * \ (self.satVolMoistContUpp000005 - self.resVolMoistContUpp000005) self.storCapUpp005030 = self.thickUpp005030 * \ (self.satVolMoistContUpp005030 - self.resVolMoistContUpp005030) self.storCapLow030150 = self.thickLow030150 * \ (self.satVolMoistContLow030150 - self.resVolMoistContLow030150) self.rootZoneWaterStorageCap = self.storCapUpp000005 + \ self.storCapUpp005030 + \ self.storCapLow030150
def main(): # make output directory try: os.makedirs(output_directory) except: if cleanOutputDir == True: os.system('rm -r ' + output_directory + "/*") # path for Inge's table table_path = str(os.getcwd() + "/") print(table_path) table_thickness = table_path + "table_from_inge/lookupDepth.txt" table_zscore = table_path + "table_from_inge/zscore.txt" # change the current directory/path to output directory os.chdir(output_directory) # make temporary directory tmp_directory = output_directory + "/tmp" os.makedirs(tmp_directory) vos.clean_tmp_dir(tmp_directory) # format and initialize logger logger_initialize = Logger(output_directory) # Monte Carlo simulation # logger.info( 'Performing Monte Carlo simulation to estimate aquifer properties !!!') # myModel = MonteCarloAquiferThickness(clone_map_file, \ dem_average_netcdf, dem_floodplain_netcdf, ldd_netcdf, \ table_thickness, table_zscore, \ number_of_samples, include_percentile_report) dynamic_framework = DynamicFramework(myModel, 1) mcModel = MonteCarloFramework(dynamic_framework, nrSamples=number_of_samples) mcModel.setForkSamples(True, nrCPUs=number_of_cores) mcModel.run() # report average, average variance, standard deviation and percentiles to netcdf files # sedimentary_basin_netcdf['file_name'] = vos.getFullPath( sedimentary_basin_netcdf['file_name'], output_directory) logger.info('Reporting topography parameters to a netcdf file: ' + sedimentary_basin_netcdf['file_name']) # sed_bas_netcdf = outputNetCDF.OutputNetCDF(clone_map_file) # variable_names = ["average", "average_variance", "standard_deviation"] units = ["m", "m2", "m"] pcr.setclone(clone_map_file) variable_fields = [ pcr.pcr2numpy(myModel.average, vos.MV), pcr.pcr2numpy(myModel.average_variance, vos.MV), pcr.pcr2numpy(myModel.standard_deviation, vos.MV) ] sed_bas_netcdf.createNetCDF(sedimentary_basin_netcdf['file_name'], variable_names, units) sed_bas_netcdf.changeAtrribute(sedimentary_basin_netcdf['file_name'], sedimentary_basin_netcdf['attribute']) sed_bas_netcdf.data2NetCDF(sedimentary_basin_netcdf['file_name'], variable_names, variable_fields) # # reporting percentile values if include_percentile_report: pcr.setclone(clone_map_file) for percentile in myModel.percentileList: variable_name = "percentile%04d" % (int(percentile * 100)) print(variable_name) variable_field = pcr.pcr2numpy(myModel.percentiles[percentile], vos.MV) variable_unit = "m" sed_bas_netcdf.addNewVariable( sedimentary_basin_netcdf['file_name'], variable_name, variable_unit) sed_bas_netcdf.data2NetCDF(sedimentary_basin_netcdf['file_name'], variable_name, variable_field) # Correcting or rescaling aquifer thickness map based on Margat's table logger.info( "Correcting/rescaling based on the table of Margat and van der Gun") # MargatCorrection = margat_correction.MargatCorrection(clone_map_file,\ sedimentary_basin_netcdf['file_name'],\ "average",\ margat_aquifers, tmp_directory) average_corrected = pcr.pcr2numpy(\ MargatCorrection.aquifer_thickness, vos.MV) # # saving corrected aquifer thickness value to the netcdf file sed_bas_netcdf.addNewVariable(sedimentary_basin_netcdf['file_name'], "average_corrected", "m") sed_bas_netcdf.data2NetCDF(sedimentary_basin_netcdf['file_name'], "average_corrected", average_corrected)
def __init__(self, configuration, \ modelTime, \ landmask, \ cellArea): DynamicModel.__init__(self) # configuration (based on the ini file) self.configuration = configuration # time variable/object self.modelTime = modelTime # cloneMapFileName self.cloneMapFileName = self.configuration.cloneMap pcr.setclone(self.cloneMapFileName) # cell area and landmask maps self.landmask = landmask self.cellArea = pcr.ifthen(self.landmask, cellArea) # output variables that will be compared (at daily resolution) self.debug_state_variables = [ 'temperature', 'snowCoverSWE', 'snowFreeWater', 'interceptStor', 'storUppTotal', 'storLowTotal', 'storGroundwater' ] self.debug_flux_variables = [ 'precipitation', 'referencePotET', 'interceptEvap', 'actSnowFreeWaterEvap', 'actBareSoilEvap', 'actTranspiTotal', 'actTranspiUppTotal', 'actTranspiLowTotal', 'infiltration', 'gwRecharge', 'runoff', 'directRunoff', 'interflowTotal', 'baseflow', 'actualET' ] self.debug_variables = self.debug_state_variables + self.debug_flux_variables # folder/location of oldcalc input maps self.maps_folder = self.configuration.mapsDir # folder/location of oldcalc results maps self.results_folder = self.configuration.globalOptions[ 'outputDir'] + "/oldcalc_results/" # - preparing the directory if os.path.exists(self.results_folder): shutil.rmtree(self.results_folder) os.makedirs(self.results_folder) # - preparing the folder to store netcdf files self.netcdf_folder = self.configuration.globalOptions[ 'outputDir'] + "/oldcalc_results/netcdf/" os.makedirs(self.netcdf_folder) # go to the starting directory and copy/backup the oldcalc_script and parameter_table files os.chdir(self.configuration.starting_directory) # the oldscript scripts used: self.oldcalc_script_file = vos.getFullPath( self.configuration.globalOptions['oldcalc_script_file'], self.configuration.starting_directory) self.parameter_tabel_file = vos.getFullPath( self.configuration.globalOptions['parameter_tabel_file'], self.configuration.starting_directory) # make the backup of oldscript scripts used shutil.copy(self.oldcalc_script_file, self.configuration.scriptDir) shutil.copy(self.parameter_tabel_file, self.configuration.scriptDir) # attribute information used in netcdf files: netcdfAttributeDictionary = {} netcdfAttributeDictionary[ 'institution'] = self.configuration.globalOptions['institution'] netcdfAttributeDictionary['title'] = "PCR-GLOBWB 1 output" netcdfAttributeDictionary[ 'description'] = self.configuration.globalOptions[ 'description'] + " (this is the output from the oldcalc PCR-GLOBWB version 1)" # netcdf object for reporting self.netcdf_report = PCR2netCDF(configuration, netcdfAttributeDictionary) # make/prepare netcdf files for var in self.debug_variables: short_name = varDicts.netcdf_short_name[var] unit = varDicts.netcdf_unit[var] long_name = varDicts.netcdf_long_name[var] if long_name == None: long_name = short_name netcdf_file_name = self.netcdf_folder + "/" + str( var) + "_dailyTot_output_version_one.nc" logger.info( "Creating the netcdf file for daily reporting for the variable %s to the file %s (output from PCR-GLOBWB version 1).", str(var), str(netcdf_file_name)) self.netcdf_report.createNetCDF(netcdf_file_name, short_name, unit, long_name)