def upscale_riverlength(ldd, order, factor): """ Upscales the riverlength using 'factor' The resulting maps can be resampled (e.g. using resample.exe) by factor and should include the accurate length as determined with the original higher resolution maps. This function is **depricated**, use are_riverlength instead as this version is very slow for large maps Input: - ldd - minimum streamorder to include Output: - distance per factor cells """ strorder = pcr.streamorder(ldd) strorder = pcr.ifthen(strorder >= order, strorder) dist = pcr.cover( pcr.max(pcr.celllength(), pcr.ifthen(pcr.boolean(strorder), pcr.downstreamdist(ldd))), 0, ) totdist = pcr.max( pcr.ifthen( pcr.boolean(strorder), pcr.windowtotal(pcr.ifthen(pcr.boolean(strorder), dist), pcr.celllength() * factor), ), dist, ) return totdist
def getWaterBodyDimensions(self): # Lake properties max depth and total lake area lakeMaxDepth = ((3.0 * self.waterBodyStorage) / (self.waterBodyShapeFactor**2))**(1. / 3.) lakeArea = (lakeMaxDepth * self.waterBodyShapeFactor)**2 # reservoir properties max depth at outlet and total reservoir area reservoirMaxDepth = ((6.0 * self.waterBodyStorage) / (self.waterBodyShapeFactor**2))**(1. / 3.) reservoirArea = 0.5 * (reservoirMaxDepth * self.waterBodyShapeFactor)**2 # dynamic waterbody area, cannot exceed static waterbody extent as defined by input self.dynamicArea = pcr.cover(pcr.ifthenelse(pcr.scalar(self.waterBodyTyp) == 1, lakeArea,\ pcr.ifthen(pcr.scalar(self.waterBodyTyp) == 2, reservoirArea)), 0.) self.dynamicArea = pcr.min(self.dynamicArea, self.waterBodyArea) # dynamic water fraction in gridcell self.dynamicFracWat = self.dynamicArea * self.waterBodyRelativeFrac / self.cellArea #TODO check if this is correct self.dynamicFracWat = pcr.cover( pcr.min(pcr.max(self.dynamicFracWat, 0.), self.fracWat), 0.) self.dynamicFracWat = self.fracWat #TODO remove this line self.dynamicFracWat = ifthen(self.landmask, self.dynamicFracWat) self.maxWaterDepth = pcr.cover(pcr.ifthenelse(pcr.scalar(self.waterBodyTyp) == 1, lakeMaxDepth,\ pcr.ifthen(pcr.scalar(self.waterBodyTyp) == 2, reservoirMaxDepth)))
def subcatch_order_a(ldd, oorder): """ Determines subcatchments using the catchment order This version uses the last cell BELOW order to derive the catchments. In general you want the _b version Input: - ldd - order - order to use Output: - map with catchment for the given streamorder """ outl = find_outlet(ldd) large = pcr.subcatchment(ldd, pcr.boolean(outl)) stt = pcr.streamorder(ldd) sttd = pcr.downstream(ldd, stt) pts = pcr.ifthen((pcr.scalar(sttd) - pcr.scalar(stt)) > 0.0, sttd) dif = pcr.upstream( ldd, pcr.cover( pcr.ifthen( large, pcr.uniqueid(pcr.boolean(pcr.ifthen(stt == pcr.ordinal(oorder), pts))), ), 0, ), ) dif = pcr.cover(pcr.scalar(outl), dif) # Add catchment outlet dif = pcr.ordinal(pcr.uniqueid(pcr.boolean(dif))) sc = pcr.subcatchment(ldd, dif) return sc, dif, stt
def overview(self, msr, pollution_threshold=2): """Give the overview of costs and st.dev for dem and minor embankments. """ msr_type = msr.settings.loc['msr_type', 1] name = msr_type + '_' + msr.settings.loc['ID'] # Separate between clean and polluted areas area_clean = pcr.ifthen(self.pollution_zones >= pollution_threshold,\ pcr.nominal(1)) area_polluted = pcr.ifthen(self.pollution_zones < pollution_threshold,\ pcr.nominal(1)) area_clean = pcr.defined(msr.area) & pcr.defined(area_clean) area_clean = pcr.ifthen(area_clean, pcr.boolean(1)) area_polluted = pcr.defined(msr.area) &\ pcr.defined(area_polluted) area_polluted = pcr.ifthen(area_polluted, pcr.boolean(1)) # Calculate costs and stddev for all earthwork types. flpl_low_values = self.dem_lowering(msr, area_polluted) minemb_low_values = self.minemb_lowering(msr, area_polluted) groyne_lowering_values = self.groyne_lowering(msr) cost_ew = pd.concat( [flpl_low_values, groyne_lowering_values, minemb_low_values]) cost_df = cost_ew.iloc[:, 0:1].T cost_df.index = [name] std_df = cost_ew.iloc[:, 1:2].T std_df.index = [name] return cost_df, std_df
def getICs(self, initial_condition): avgInflow = initial_condition['avgLakeReservoirInflowShort'] avgOutflow = initial_condition['avgLakeReservoirOutflowLong'] if initial_condition['waterBodyStorage'] is not None: # read directly waterBodyStorage = initial_condition['waterBodyStorage'] else: # calculate waterBodyStorage at cells where lakes and/or reservoirs are defined # storageAtLakeAndReservoirs = pcr.cover(\ pcr.ifthen(pcr.scalar(self.waterBodyIds) > 0., initial_condition['channelStorage']), 0.0) # # - move only non negative values and use rounddown values storageAtLakeAndReservoirs = pcr.max( 0.00, pcr.rounddown(storageAtLakeAndReservoirs)) # # lake and reservoir storages = waterBodyStorage (m3) ; values are given for the entire lake / reservoir cells waterBodyStorage = pcr.ifthen(pcr.scalar(self.waterBodyIds) > 0., \ pcr.areatotal(storageAtLakeAndReservoirs,\ self.waterBodyIds)) self.avgInflow = pcr.cover(avgInflow, 0.0) # unit: m3/s self.avgOutflow = pcr.cover(avgOutflow, 0.0) # unit: m3/s self.waterBodyStorage = pcr.cover(waterBodyStorage, 0.0) # unit: m3 self.avgInflow = pcr.ifthen(self.landmask, self.avgInflow) self.avgOutflow = pcr.ifthen(self.landmask, self.avgOutflow) self.waterBodyStorage = pcr.ifthen(self.landmask, self.waterBodyStorage)
def get_initial_heads(self): if self.iniItems.modflowTransientInputOptions['groundwaterHeadIni'] != "None": # using a pre-defined groundwater head described in the ini/configuration file self.groundwaterHead = vos.readPCRmapClone(self.modflowTransientInputOptions['groundwaterHeadIni'],\ self.cloneMap, self.tmpDir, self.inputDir) else: # using the digital elevation model as the initial head self.groundwaterHead = self.dem_average # calculate/simulate a steady state condition (until the modflow converge) self.modflow_converged = False while self.modflow_converged == False: self.modflow_simulation("steady-state", self.groundwaterHead, None,1,1,self.criteria_HCLOSE[self.iteration_HCLOSE],\ self.criteria_RCLOSE[self.iteration_RCLOSE]) # extrapolating the calculated heads for areas/cells outside the landmask (to remove isolated cells) # TODO: Using Deltares's trick to remove isolated cells. # # - the calculate groundwater head within the landmask region self.groundwaterHead = pcr.ifthen(self.landmask, self.groundwaterHead) # - keep the ocean values (dem <= 0.0) - this is in order to maintain the 'behaviors' of sub marine groundwater discharge self.groundwaterHead = pcr.cover(self.groundwaterHead, pcr.ifthen(self.dem_average <= 0.0, self.dem_average)) # - extrapolation # self.groundwaterHead = pcr.cover(self.groundwaterHead, pcr.windowaverage(self.groundwaterHead, 3.*pcr.clone().cellSize())) self.groundwaterHead = pcr.cover(self.groundwaterHead, pcr.windowaverage(self.groundwaterHead, 5.*pcr.clone().cellSize())) self.groundwaterHead = pcr.cover(self.groundwaterHead, self.dem_average) # TODO: Define the window sizes as part of the configuration file. # after having the initial head, set the following variable to True to indicate the first month of the model simulation self.firstMonthOfSimulation = True
def snaptomap(points, mmap): """ Snap the points in _points_ to nearest non missing values in _mmap_. Can be used to move gauge locations to the nearest rivers. Input: - points - map with points to move - mmap - map with points to move to Return: - map with shifted points """ points = pcr.cover(points, 0) # Create unique id map of mmap cells unq = pcr.nominal(pcr.cover(pcr.uniqueid(pcr.defined(mmap)), pcr.scalar(0.0))) # Now fill holes in mmap map with lues indicating the closes mmap cell. dist_cellid = pcr.scalar(pcr.spreadzone(unq, 0, 1)) # Get map with values at location in points with closes mmap cell dist_cellid = pcr.ifthenelse(points > 0, dist_cellid, 0) # Spread this out dist_fill = pcr.spreadzone(pcr.nominal(dist_cellid), 0, 1) # Find the new (moved) locations npt = pcr.uniqueid(pcr.boolean(pcr.ifthen(dist_fill == unq, unq))) # Now recreate the original value in the points maps ptcover = pcr.spreadzone(pcr.cover(points, 0), 0, 1) # Now get the org point value in the pt map nptorg = pcr.ifthen(npt > 0, ptcover) return nptorg
def readPCRmapClone(v,cloneMapFileName,tmpDir,absolutePath=None,isLddMap=False,cover=None,isNomMap=False): # v: inputMapFileName or floating values # cloneMapFileName: If the inputMap and cloneMap have different clones, # resampling will be done. #logger.info('read file/values: '+str(v)) if v == "None": PCRmap = str("None") elif not re.match(r"[0-9.-]*$",v): if absolutePath != None: v = getFullPath(v,absolutePath) # print(v) sameClone = isSameClone(v,cloneMapFileName) if sameClone == True: PCRmap = pcr.readmap(v) else: # resample using GDAL: output = tmpDir+'temp.map' warp = gdalwarpPCR(v,output,cloneMapFileName,tmpDir,isLddMap,isNomMap) # read from temporary file and delete the temporary file: PCRmap = pcr.readmap(output) if isLddMap == True: PCRmap = pcr.ifthen(pcr.scalar(PCRmap) < 10., PCRmap) if isLddMap == True: PCRmap = pcr.ldd(PCRmap) if isNomMap == True: PCRmap = pcr.ifthen(pcr.scalar(PCRmap) > 0., PCRmap) if isNomMap == True: PCRmap = pcr.nominal(PCRmap) co = 'rm '+str(tmpDir)+'*.*' cOut,err = subprocess.Popen(co, stdout=subprocess.PIPE,stderr=open('/dev/null'),shell=True).communicate() else: PCRmap = pcr.scalar(float(v)) if cover != None: PCRmap = pcr.cover(PCRmap, cover) co = None; cOut = None; err = None; warp = None del co; del cOut; del err; del warp stdout = None; del stdout stderr = None; del stderr return PCRmap
def readPCRmapClone(v,cloneMapFileName,tmpDir,absolutePath=None,isLddMap=False,cover=None,isNomMap=False): # v: inputMapFileName or floating values # cloneMapFileName: If the inputMap and cloneMap have different clones, # resampling will be done. print(v) if v == "None": PCRmap = str("None") elif not re.match(r"[0-9.-]*$",v): if absolutePath != None: v = getFullPath(v,absolutePath) # print(v) sameClone = isSameClone(v,cloneMapFileName) if sameClone == True: PCRmap = pcr.readmap(v) else: # resample using GDAL: output = tmpDir+'temp.map' warp = gdalwarpPCR(v,output,cloneMapFileName,tmpDir,isLddMap,isNomMap) # read from temporary file and delete the temporary file: PCRmap = pcr.readmap(output) if isLddMap == True: PCRmap = pcr.ifthen(pcr.scalar(PCRmap) < 10., PCRmap) if isLddMap == True: PCRmap = pcr.ldd(PCRmap) if isNomMap == True: PCRmap = pcr.ifthen(pcr.scalar(PCRmap) > 0., PCRmap) if isNomMap == True: PCRmap = pcr.nominal(PCRmap) co = 'rm '+str(tmpDir)+'*.*' cOut,err = subprocess.Popen(co, stdout=subprocess.PIPE,stderr=open('/dev/null'),shell=True).communicate() else: PCRmap = pcr.scalar(float(v)) if cover != None: PCRmap = pcr.cover(PCRmap, cover) co = None; cOut = None; err = None; warp = None del co; del cOut; del err; del warp stdout = None; del stdout stderr = None; del stderr return PCRmap
def test_03(self): """ nonspatial condition in ifthen """ nr_rows = 2 nr_cols = 3 nr_cells = nr_rows * nr_cols pcraster.setclone(nr_rows, nr_cols, 5, 1, 1) raster = pcraster.ifthen(pcraster.boolean(1), pcraster.scalar(4.567)) for idx in range(1, nr_cells + 1): value, isValid = pcraster.cellvalue(raster, idx) self.assertEqual(isValid, True) self.assertAlmostEqual(value, 4.567, 6) raster = pcraster.ifthen(pcraster.boolean(0), pcraster.scalar(4.567)) for idx in range(1, nr_cells + 1): value, isValid = pcraster.cellvalue(raster, idx) self.assertEqual(isValid, False) raster = pcraster.ifthen(pcraster.scalar(1), pcraster.scalar(4.567)) for idx in range(1, nr_cells + 1): value, isValid = pcraster.cellvalue(raster, idx) self.assertEqual(isValid, True) self.assertAlmostEqual(value, 4.567, 6) raster = pcraster.ifthen(pcraster.scalar(0), pcraster.scalar(4.567)) for idx in range(1, nr_cells + 1): value, isValid = pcraster.cellvalue(raster, idx) self.assertEqual(isValid, False)
def readPCRmapClone(v, cloneMapFileName, tmpDir, absolutePath=None, isLddMap=False, cover=None, isNomMap=False): # v: inputMapFileName or floating values # cloneMapFileName: If the inputMap and cloneMap have different clones, # resampling will be done. logger.debug('read file/values: ' + str(v)) if v == "None": #~ PCRmap = str("None") PCRmap = None # 29 July: I made an experiment by changing the type of this object. elif not re.match(r"[0-9.-]*$", v): if absolutePath != None: v = getFullPath(v, absolutePath) # print v # print cloneMapFileName sameClone = isSameClone(v, cloneMapFileName) if sameClone == True: PCRmap = pcr.readmap(v) else: # resample using GDAL: output = tmpDir + 'temp.map' warp = gdalwarpPCR(v, output, cloneMapFileName, tmpDir, isLddMap, isNomMap) # read from temporary file and delete the temporary file: PCRmap = pcr.readmap(output) if isLddMap == True: PCRmap = pcr.ifthen(pcr.scalar(PCRmap) < 10., PCRmap) if isLddMap == True: PCRmap = pcr.ldd(PCRmap) if isNomMap == True: PCRmap = pcr.ifthen(pcr.scalar(PCRmap) > 0., PCRmap) if isNomMap == True: PCRmap = pcr.nominal(PCRmap) if os.path.isdir(tmpDir): shutil.rmtree(tmpDir) os.makedirs(tmpDir) else: PCRmap = pcr.spatial(pcr.scalar(float(v))) if cover != None: PCRmap = pcr.cover(PCRmap, cover) co = None cOut = None err = None warp = None del co del cOut del err del warp stdout = None del stdout stderr = None del stderr # SM: revisit this PCRmap = pcr.pcr2numpy(PCRmap, np.nan) return PCRmap
def basic_post_processing(self): self.groundwaterHeadLayer1 = pcr.ifthen( self._model.landmask, self._model.modflow.groundwaterHeadLayer1) self.groundwaterHeadLayer2 = pcr.ifthen( self._model.landmask, self._model.modflow.groundwaterHeadLayer2) self.groundwaterDepth = pcr.ifthen( self._model.landmask, self._model.modflow.groundwaterDepth)
def ReverseMap(MAP): MAX = int(np.max(pcr.pcr2numpy(MAP,np.NAN))) REV_MAP = pcr.ordinal(pcr.ifthen(pcr.scalar(MAP) == pcr.scalar(-9999), pcr.scalar(0))) for i in range(MAX+1): if i > 0: print i REV_MAP = pcr.cover(pcr.ifthen(pcr.ordinal(MAP) == pcr.ordinal(i), pcr.ordinal(pcr.scalar(MAX+1)-pcr.scalar(i))),REV_MAP) REV_MAP = pcr.cover(REV_MAP, pcr.ordinal(MAP)) return REV_MAP
def getLakeOutflow(self, avgChannelDischarge, length_of_time_step=vos.secondsPerDay()): # waterHeight (m): temporary variable, a function of storage: minWaterHeight = ( 0.001 ) # (m) Rens used 0.001 m as the limit # this is to make sure there is always lake outflow, # but it will be still limited by available self.waterBodyStorage waterHeight = pcr.cover( pcr.max( minWaterHeight, (self.waterBodyStorage - pcr.cover(self.waterBodyCap, 0.0)) / self.waterBodyArea, ), 0.0, ) # weirWidth (m) : # - estimated from avgOutflow (m3/s) using the bankfull discharge formula # avgOutflow = self.avgOutflow avgOutflow = pcr.ifthenelse( avgOutflow > 0.0, avgOutflow, pcr.max(avgChannelDischarge, self.avgInflow, 0.001), ) # This is needed when new lakes/reservoirs introduced (its avgOutflow is still zero). avgOutflow = pcr.areamaximum(avgOutflow, self.waterBodyIds) # bankfullWidth = pcr.cover(pcr.scalar(4.8) * ((avgOutflow)**(0.5)), 0.0) weirWidthUsed = bankfullWidth weirWidthUsed = pcr.max( weirWidthUsed, self.minWeirWidth ) # TODO: minWeirWidth based on the GRanD database weirWidthUsed = pcr.cover( pcr.ifthen(pcr.scalar(self.waterBodyIds) > 0.0, weirWidthUsed), 0.0) # avgInflow <= lakeOutflow (weirFormula) <= waterBodyStorage lakeOutflowInM3PerSec = pcr.max( self.weirFormula(waterHeight, weirWidthUsed), self.avgInflow) # unit: m3/s # estimate volume of water relased by lakes lakeOutflow = lakeOutflowInM3PerSec * length_of_time_step # unit: m3 lakeOutflow = pcr.min(self.waterBodyStorage, lakeOutflow) # lakeOutflow = pcr.ifthen( pcr.scalar(self.waterBodyIds) > 0.0, lakeOutflow) lakeOutflow = pcr.ifthen( pcr.scalar(self.waterBodyTyp) == 1, lakeOutflow) # TODO: Consider endorheic lake/basin. No outflow for endorheic lake/basin! return lakeOutflow
def involved_stakeholders(path_measures): # From user input measure_dir_area = os.path.join(path_measures, 'area.map') path_restraints = os.path.join(os.getcwd(), '..', 'input_files', 'input', 'restraints') # Read inputs owner_count_point = pcr.readmap( os.path.join(path_restraints, 'owner_point_number.map')) owner_type = pcr.readmap(os.path.join(path_restraints, 'owner_type.map')) owner_uid = pcr.readmap(os.path.join(path_restraints, 'owner_nr.map')) # Distribute point values to corresponding areas owner_count = pcr.areamaximum(owner_count_point, owner_uid) # Mask with measure area owner_count_measure = pcr.ifthen(measure_dir_area, owner_count) owner_type_measure = pcr.ifthen(measure_dir_area, owner_type) owner_uid_measure = pcr.ifthen(measure_dir_area, owner_uid) df = _maps_to_dataframe( [owner_count_measure, owner_type_measure, owner_uid_measure], ['count', 'type', 'uid']) owner_types = df['type'].values owner_types = np.unique(owner_types) owner_types_label = [ 'Public Works and Water Management', 'Waterboard', 'Municipality', 'Company', 'Citizen', 'State Forestry Servive', 'Province', 'Geldersch and Brabants Landschap', 'Foundation', 'Sand/gravel/clay company', 'other' ] content = 'Owner type,Number of stakeholders involved\n' for ot in owner_types: newdf = df.loc[df['type'] == ot] newdf = newdf.drop_duplicates() tot_own = newdf['count'].sum() row_content = '{},{}\n'.format(owner_types_label[int(ot) - 1], int(tot_own)) content = '{}{}'.format(content, row_content) df = pd.read_csv(StringIO(content)) return df
def getICs(self, iniItems, iniConditions=None): #print iniItems.groundwaterOptions['storGroundwaterFossilIni'] # initial condition for storGroundwater (unit: m) if iniConditions == None: # when the model just start self.storGroundwater = vos.readPCRmapClone(\ iniItems.groundwaterOptions['storGroundwaterIni'], self.cloneMap,self.tmpDir,self.inputDir) self.avgAbstraction = vos.readPCRmapClone(\ iniItems.groundwaterOptions['avgTotalGroundwaterAbstractionIni'], self.cloneMap,self.tmpDir,self.inputDir) else: # during/after spinUp self.storGroundwater = iniConditions['groundwater'][ 'storGroundwater'] self.avgAbstraction = iniConditions['groundwater'][ 'avgTotalGroundwaterAbstractionIni'] # initial condition for storGroundwaterFossil (unit: m) # # Note that storGroundwaterFossil should not be depleted during the spin-up. # if iniItems.groundwaterOptions['storGroundwaterFossilIni'] != "Maximum": #logger.info("Using a pre-defined initial condition for fossil groundwater storage.") self.storGroundwaterFossil = vos.readPCRmapClone(\ iniItems.groundwaterOptions['storGroundwaterFossilIni'], self.cloneMap,self.tmpDir,self.inputDir) # if self.limitFossilGroundwaterAbstraction and iniItems.groundwaterOptions[ 'storGroundwaterFossilIni'] != "Maximum": #logger.info("The pre-defined initial condition for fossil groundwater is limited by fossilWaterCap (full capacity).") self.storGroundwaterFossil = pcr.min(self.storGroundwaterFossil, self.fossilWaterCap) # if self.limitFossilGroundwaterAbstraction and iniItems.groundwaterOptions[ 'storGroundwaterFossilIni'] == "Maximum": #logger.info("Assuming 'full' fossilWaterCap as the initial condition for fossil groundwater storage.") self.storGroundwaterFossil = self.fossilWaterCap # make sure that active storGroundwater and avgAbstraction cannot be negative # self.storGroundwater = pcr.cover(self.storGroundwater, 0.0) self.storGroundwater = pcr.max(0., self.storGroundwater) self.storGroundwater = pcr.ifthen(self.landmask,\ self.storGroundwater) # self.avgAbstraction = pcr.cover(self.avgAbstraction, 0.0) self.avgAbstraction = pcr.max(0., self.avgAbstraction) self.avgAbstraction = pcr.ifthen(self.landmask,\ self.avgAbstraction) # storGroundwaterFossil can be negative (particularly if limitFossilGroundwaterAbstraction == False) self.storGroundwaterFossil = pcr.ifthen(self.landmask,\ self.storGroundwaterFossil)
def getLakeOutflow( self, avgChannelDischarge, length_of_time_step=vos.secondsPerDay() ): # waterHeight (m): temporary variable, a function of storage: minWaterHeight = ( 0.001 ) # (m) Rens used 0.001 m as the limit # this is to make sure there is always lake outflow, # but it will be still limited by available self.waterBodyStorage waterHeight = pcr.cover( pcr.max( minWaterHeight, (self.waterBodyStorage - pcr.cover(self.waterBodyCap, 0.0)) / self.waterBodyArea, ), 0.0, ) # weirWidth (m) : # - estimated from avgOutflow (m3/s) using the bankfull discharge formula # avgOutflow = self.avgOutflow avgOutflow = pcr.ifthenelse( avgOutflow > 0.0, avgOutflow, pcr.max(avgChannelDischarge, self.avgInflow, 0.001), ) # This is needed when new lakes/reservoirs introduced (its avgOutflow is still zero). avgOutflow = pcr.areamaximum(avgOutflow, self.waterBodyIds) # bankfullWidth = pcr.cover(pcr.scalar(4.8) * ((avgOutflow) ** (0.5)), 0.0) weirWidthUsed = bankfullWidth weirWidthUsed = pcr.max( weirWidthUsed, self.minWeirWidth ) # TODO: minWeirWidth based on the GRanD database weirWidthUsed = pcr.cover( pcr.ifthen(pcr.scalar(self.waterBodyIds) > 0.0, weirWidthUsed), 0.0 ) # avgInflow <= lakeOutflow (weirFormula) <= waterBodyStorage lakeOutflowInM3PerSec = pcr.max( self.weirFormula(waterHeight, weirWidthUsed), self.avgInflow ) # unit: m3/s # estimate volume of water relased by lakes lakeOutflow = lakeOutflowInM3PerSec * length_of_time_step # unit: m3 lakeOutflow = pcr.min(self.waterBodyStorage, lakeOutflow) # lakeOutflow = pcr.ifthen(pcr.scalar(self.waterBodyIds) > 0.0, lakeOutflow) lakeOutflow = pcr.ifthen(pcr.scalar(self.waterBodyTyp) == 1, lakeOutflow) # TODO: Consider endorheic lake/basin. No outflow for endorheic lake/basin! return lakeOutflow
def selectCatchments(ldd, pitsMap, pitsDict, continentList, cloneMap): catchments = pcr.ifthen(pcr.boolean(pcr.readmap(cloneMap)) == 0, pcr.scalar(1)) for continent in pitsDict.iterkeys(): continentNr = pitsDict[continent][0] pitsContinent = pitsDict[continent][1:] print 'updating catchments for ', continent for pitNr in pitsContinent: pitMap = pcr.ifthen(pitsMap == pitNr, pcr.scalar(continentNr)) catchment = pcr.catchment(ldd, pcr.nominal(pitMap)) catchment = pcr.ifthen(pcr.boolean(catchment) == 1, catchment) catchments = pcr.cover(catchments, pcr.scalar(catchment)) return catchments
def representativePoint(nominalMap): """Select a representative point for a nominal map """ pcr.setglobaloption('unitcell') filled = pcr.cover(nominalMap, 0) edges = pcr.windowdiversity(filled, 3) > 1 edges = pcr.ifthen(pcr.defined(nominalMap), edges) edges = map_edges(nominalMap) | edges dist = pcr.spread(edges, 0, 1) dist = dist + pcr.uniform(pcr.defined(nominalMap)) points = dist == pcr.areamaximum(dist, nominalMap) return pcr.ifthen(points, nominalMap)
def basic_post_processing(self): # groundwater head and groundwater depth (unit: m) for i in range(1, self._model.modflow.number_of_layers + 1): # groundwater head and groundwater depth for each layer (unit: m) var_head_name = 'groundwaterHeadLayer' + str(i) vars(self)[var_head_name] = pcr.ifthen( self._model.landmask, vars(self._model.modflow)[var_head_name]) var_depth_name = 'groundwaterDepthLayer' + str(i) vars(self)[var_depth_name] = pcr.ifthen( self._model.landmask, self._model.modflow.dem_average - vars(self)[var_head_name]) # groundwater head and groundwater depth at the top layer (unit: m) if i == self._model.modflow.number_of_layers: self.groundwaterHead = pcr.ifthen(self._model.landmask, vars(self)[var_head_name]) self.groundwaterDepth = pcr.ifthen(self._model.landmask, vars(self)[var_depth_name]) # total baseflow (unit: m3/day) if "totalBaseflowVolumeRate" in self.variables_for_report: # initiate the (accumulated) value (for accumulating the fluxes from all layers) self.totalBaseflowVolumeRate = pcr.scalar(0.0) # Note that positive values in flow/flux variables indicate water entering aquifer/groundwater bodies. for i in range(1, self._model.modflow.number_of_layers + 1): # from the river leakage var_name = 'riverLeakageLayer' + str(i) self.totalBaseflowVolumeRate += vars( self._model.modflow)[var_name] # from the drain package var_name = 'drainLayer' + str(i) self.totalBaseflowVolumeRate += vars( self._model.modflow)[var_name] # report only in the landmask region if i == self._model.modflow.number_of_layers: self.totalBaseflowVolumeRate = pcr.ifthen(self._model.landmask, \ self.totalBaseflowVolumeRate) # relative groundwater head (at the top layer) above the minimum elevation within the grid cell # - this is needed for coupling with PCR-GLOBWB self.relativeGroundwaterHead = pcr.ifthen( self._model.landmask, self.groundwaterHead - self._model.modflow.dem_minimum)
def classify( inmap, lower=[0, 10, 20, 30], upper=[10, 20, 30, 40], classes=[2, 2, 3, 4] ): """ classify a scaler maps accroding to the boundaries given in classes. """ result = pcr.ordinal(pcr.cover(-1)) for l, u, c in zip(lower, upper, classes): result = pcr.cover( pcr.ifthen(inmap >= l, pcr.ifthen(inmap < u, pcr.ordinal(c))), result ) return pcr.ifthen(result >= 0, result)
def relocation(self, reloc_area): """Sum up the cost and st.dev of dike relocation.""" reloc_area = pcr.cover(pcr.boolean(reloc_area), pcr.boolean(0)) buffer_m = 1.5 * pcr.clone().cellSize( ) # buffer 1 cell in 8 directions reloc_buffered = pcr.spreadmaxzone(reloc_area, 0, 1, buffer_m) reloc_length = pcr.ifthen(reloc_buffered, self.dike_length) cost_spatial = 0.001 * reloc_length * self.dike_reloc_distr.mean std_spatial = 0.001 * reloc_length * self.dike_reloc_distr.stddev area = pcr.ifthen(reloc_area, pcr.boolean(1)) cost = area_total_value(cost_spatial, area) std = area_total_value(std_spatial, area) return cost, std
def valueReport(val,valName,outDir): #-return global and country values #-open text files valNameFile= '%s\\%s.txt' % (outDir,valName) if year == staYear and month == staMonth: valName= open(valNameFile,'w') else: valName= open(valNameFile,'a') #-calculate country value (km3/year) cntValue= pcr.areatotal(val,country)/conv for nrCnt in range(cntTot+1): if year == staYear and month == staMonth: valName.write('%d ' % (nrCnt)) for nrCnt in range(cntTot+1): cntPoint= pcr.ifthen(countryLocations==int(nrCnt),cntValue) cntPoint= pcr.cellvalue(pcr.maptotal(cntPoint),int(1))[0] if nrCnt==int(0): valName.write('\n%04d %02d ' % (year,month)) else: valName.write('%02f ' % (cntPoint)) #-calculate global total (km3/year) glbValue= pcr.maptotal(val)/conv glbPoint= pcr.cellvalue(glbValue,int(1))[0] valName.write('%02f' % (glbPoint)) #-close text files valName.close() return cntValue,glbValue,valName
def totalCatchmentStores(self, total_land_stores): total_per_catchment = self.routing.channelStorage if self.numberOfSoilLayers == 2: total = \ self.landSurface.interceptStor +\ self.landSurface.snowFreeWater +\ self.landSurface.snowCoverSWE +\ self.landSurface.topWaterLayer +\ self.landSurface.storUpp +\ self.landSurface.storLow +\ self.groundwater.storGroundwater if self.numberOfSoilLayers == 3: total = \ self.landSurface.interceptStor +\ self.landSurface.snowFreeWater +\ self.landSurface.snowCoverSWE +\ self.landSurface.topWaterLayer +\ self.landSurface.storUpp000005 +\ self.landSurface.storUpp005030 +\ self.landSurface.storLow030150 +\ self.groundwater.storGroundwater total = pcr.ifthen(self.landmask, total) return total
def zonalSumArea(nominalMap, areaClass): """Memory efficient method to sum up the surface area of the different classes in the nominal map. Separate by the regions in areaClass input: nominalMap: nominal map, e.g. ecotope map areaClass: regions to compute surface areas over """ #-create a pointMap of the output locations, one for each areaClass outputPointMap = pcrr.pointPerClass(areaClass) #-iniate output DataFrame dfInit = pcrr.getCellValues(outputPointMap, mapList = [areaClass], columns = ['areaClass']) #-loop over the classes in nominalMap and compute the summed area per areaClass IDs = np.unique(pcr.pcr2numpy(nominalMap, -9999))[1:] dfList = [] for ID in IDs[:]: pcrID = pcr.nominal(ID) pcr.setglobaloption('unittrue') IDArea = pcr.ifthen(nominalMap == pcrID, pcr.cellarea()) sectionSum = pcr.areatotal(IDArea, areaClass) df = pcrr.getCellValues(outputPointMap, [sectionSum], [ID]) # df columns = rowIdx, colIdx, ID df = df.drop(['rowIdx', 'colIdx'], axis=1) dfList.append(df) dfOut = dfInit.join(dfList) #return dfInit, df, dfOut, dfList return dfOut
def subcatch_stream(ldd, stream, threshold): """ Derive catchments based upon strahler threshold Input: ldd -- pcraster object direction, local drain directions stream -- pcraster object direction, streamorder threshold -- integer, strahler threshold, subcatchments ge threshold are derived output: stream_ge -- pcraster object, streams of strahler order ge threshold subcatch -- pcraster object, subcatchments of strahler order ge threshold """ # derive stream order # stream = pcr.streamorder(ldd) stream_ge = pcr.ifthen(stream >= threshold, stream) stream_up_sum = pcr.ordinal(pcr.upstream(ldd, pcr.cover(pcr.scalar(stream_ge), 0))) # detect any transfer of strahler order, to a higher strahler order. transition_strahler = pcr.ifthenelse(pcr.downstream(ldd, stream_ge) != stream_ge, pcr.boolean(1), pcr.ifthenelse(pcr.nominal(ldd) == 5, pcr.boolean(1), pcr.ifthenelse(pcr.downstream(ldd, pcr.scalar(stream_up_sum)) > pcr.scalar(stream_ge), pcr.boolean(1), pcr.boolean(0)))) # make unique ids (write to file) transition_unique = pcr.ordinal(pcr.uniqueid(transition_strahler)) # derive upstream catchment areas (write to file) subcatch = pcr.nominal(pcr.subcatchment(ldd, transition_unique)) return stream_ge, subcatch
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, self.input_variable_name, \ str(self.modelTime.fulldate), \ useDoy = None, \ cloneMapFileName = self.clonemap_file_name, \ LatitudeLongitude = True) self.cell_value = pcr.cover(self.cell_value, 0.0) self.cell_value = pcr.ifthen(self.landmask, self.cell_value) logger.info("Calculating basin value for time %s", self.modelTime.currTime) self.basin_value = pcr.catchmenttotal(self.cell_value * 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, \ self.variable_name, \ pcr.pcr2numpy(self.basin_value, vos.MV), \ timeStamp)
def mapEllipse(r_a, r_b, azimuth, latC, lonC, lat, lon, numberStepsArc= 360): '''Maps an ellipse for the given spatial attributes using a predefined number \ of steps along the arc: r_a: length of semi_major axis r_b: length of semi_major axis azimuth: angle of semi_major axis with the centroid to north latC: latitude of centroid lonC: longitude of centroid lat: map of latitude lon: map of longitude numberStepsArc= 360 (default) where r= r_a*r_b/(r_a**2*sin(theta)**2+r_b**2*cos(theta)**2)**0.5 \n''' #-compute theta as the azimuth and rotated towards the semi-major axis theta= np.linspace(0.,360.-360./numberStepsArc,numberStepsArc) radius= (r_a*r_b)/(r_a**2*(np.sin(theta*deg2Rad))**2+r_b**2*(np.cos(theta*deg2Rad))**2)**0.5 theta= (theta+azimuth) % 360. lat1, lon1= getDestinationPoint(latC, lonC, radius, theta) ellipse= pcr.boolean(0) for iCnt in xrange(lat1.size): ellipse= ellipse | \ (pcr.abs(lat-lat1[iCnt]) == pcr.mapminimum(pcr.abs(lat-lat1[iCnt]))) & \ (pcr.abs(lon-lon1[iCnt]) == pcr.mapminimum(pcr.abs(lon-lon1[iCnt]))) ellipse= pcr.ifthen(ellipse, ellipse) #-return ellipse return ellipse
def totalLandStores(self): if self.numberOfSoilLayers == 2: total = \ self.landSurface.interceptStor +\ self.landSurface.snowFreeWater +\ self.landSurface.snowCoverSWE +\ self.landSurface.topWaterLayer +\ self.landSurface.storUpp +\ self.landSurface.storLow +\ self.groundwater.storGroundwater if self.numberOfSoilLayers == 3: total = \ self.landSurface.interceptStor +\ self.landSurface.snowFreeWater +\ self.landSurface.snowCoverSWE +\ self.landSurface.topWaterLayer +\ self.landSurface.storUpp000005 +\ self.landSurface.storUpp005030 +\ self.landSurface.storLow030150 +\ self.groundwater.storGroundwater # ADDED: include one more variable if ActivateCoupling is set to True # ---------------------------------------------------------------------------------------------------------------- if self.ActivateCoupling == 'True': # add floodplainWaterLayer to total stores total += self.landSurface.floodplainWaterLayer # ---------------------------------------------------------------------------------------------------------------- total = pcr.ifthen(self.landmask, total) return total
def subcatch_stream(ldd, stream, threshold): """ Derive catchments based upon strahler threshold Input: ldd -- pcraster object direction, local drain directions stream -- pcraster object direction, streamorder threshold -- integer, strahler threshold, subcatchments ge threshold are derived output: stream_ge -- pcraster object, streams of strahler order ge threshold subcatch -- pcraster object, subcatchments of strahler order ge threshold """ # derive stream order # stream = pcr.streamorder(ldd) stream_ge = pcr.ifthen(stream >= threshold, stream) stream_up_sum = pcr.ordinal( pcr.upstream(ldd, pcr.cover(pcr.scalar(stream_ge), 0))) # detect any transfer of strahler order, to a higher strahler order. transition_strahler = pcr.ifthenelse( pcr.downstream(ldd, stream_ge) != stream_ge, pcr.boolean(1), pcr.ifthenelse( pcr.nominal(ldd) == 5, pcr.boolean(1), pcr.ifthenelse( pcr.downstream(ldd, pcr.scalar(stream_up_sum)) > pcr.scalar(stream_ge), pcr.boolean(1), pcr.boolean(0)))) # make unique ids (write to file) transition_unique = pcr.ordinal(pcr.uniqueid(transition_strahler)) # derive upstream catchment areas (write to file) subcatch = pcr.nominal(pcr.subcatchment(ldd, transition_unique)) return stream_ge, subcatch
def checkWaterBalance(self, storesAtBeginning, storesAtEnd): # for the entire modules: snow + interception + soil + groundwater + waterDemand # except: river/routing precipitation = pcr.ifthen(self.landmask,\ self.meteo.precipitation) # unit: m runoff = pcr.ifthen(self.landmask,self.routing.runoff) vos.waterBalanceCheck([precipitation],\ [runoff],\ [storesAtBeginning],\ [storesAtEnd],\ 'all modules (including water demand), but except river/routing',\ True,\ self._modelTime.fulldate,threshold=1e-3)
def initial(self): """ initial part of the polder module """ # ************************************************************ # ***** POLDERS # ************************************************************ settings = LisSettings.instance() option = settings.options binding = settings.binding if option['simulatePolders']: PolderSites = loadmap('PolderSites') PolderSites = pcraster.ifthen( (pcraster.defined(PolderSites) & self.var.IsChannel), PolderSites) # Get rid of any polders that are not part of the channel network # IMPORTANT: current implementation can become unstable with kin. # wave!! # Flag that is boolean(1) for polder sites and boolean(0) otherwise # total storage capacity of Polder area [m3] PolderArea = pcraster.lookupscalar(str(binding['TabPolderArea']), PolderSites) PolderLevel = binding['PolderInitialLevelValue'] # Initial polder level [m] self.var.PolderStorageIniM3 = pcraster.cover( PolderLevel * PolderArea, pcraster.scalar(0.0)) # Compute polder storage [m3] self.var.PolderStorageM3 = self.var.PolderStorageIniM3
def totalLandWaterStores(self): # unit: m, not including surface water bodies if self.numberOfSoilLayers == 2: total = \ self.landSurface.interceptStor +\ self.landSurface.snowFreeWater +\ self.landSurface.snowCoverSWE +\ self.landSurface.topWaterLayer +\ self.landSurface.storUpp +\ self.landSurface.storLow +\ self.groundwater.storGroundwater if self.numberOfSoilLayers == 3: total = \ self.landSurface.interceptStor +\ self.landSurface.snowFreeWater +\ self.landSurface.snowCoverSWE +\ self.landSurface.topWaterLayer +\ self.landSurface.storUpp000005 +\ self.landSurface.storUpp005030 +\ self.landSurface.storLow030150 +\ self.groundwater.storGroundwater total = pcr.ifthen(self.landmask, total) return total
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
def get(self,fileName,valueScale= 'scalar'): #-set variable and varType varType= self.varTypes.get(valueScale.lower(),'FLOAT32') variable= 'valueField' field= getattr(spatialDataSet(fileName,variable,varType,valueScale,\ self.xMin,self.yMin,self.xMax,self.yMax,self.gridResolution,self.gridResolution,self.resampleRatio),variable) #if '.map' in fileName: #pcr.report(pcr.ifthen(self.clone,field),'temp_%s' % os.path.split(fileName)[1]) return pcr.ifthen(self.clone,field)
def agriZone_Ep_Sa_cropG(self, k): """ - Potential evaporation is decreased by energy used for interception evaporation - Formula for evaporation based on LP - Outgoing fluxes are determined based on (value in previous timestep + inflow) and if this leads to negative storage, the outgoing fluxes are corrected to rato --> Eu is no longer taken into account for this correction - Qa u is determined from overflow from Sa - Fa is based on storage in Sa - Code for ini-file: 4 """ JarvisCoefficients.calcEp(self, k) self.PotEvaporation = pcr.cover(pcr.ifthenelse(self.EpHour >= 0, self.EpHour, 0), 0) self.samax2 = self.samax[k] * self.cropG self.Qaadd = pcr.max(self.Sa_t[k] - self.samax2, 0) self.Qa = pcr.max(self.Pe - (self.samax2 - self.Sa_t[k]), 0) + self.Qaadd self.Sa[k] = self.Sa_t[k] + (self.Pe - self.Qa) self.SaN = pcr.min(self.Sa[k] / self.samax2, 1) self.SuN = self.Su[k] / self.sumax[k] self.Ea1 = pcr.max((self.PotEvaporation - self.Ei), 0) * pcr.min( self.Sa[k] / (self.samax2 * self.LP[k]), 1 ) self.Fa1 = pcr.ifthenelse( self.SaN > 0, self.Fmin[k] + (self.Fmax[k] - self.Fmin[k]) * e ** (-self.decF[k] * (1 - self.SaN)), 0, ) self.Sa[k] = self.Sa_t[k] + (self.Pe - self.Qa) - self.Fa1 - self.Ea1 self.Sa_diff = pcr.ifthenelse(self.Sa[k] < 0, self.Sa[k], 0) self.Fa = ( self.Fa1 + (self.Fa1 / pcr.ifthenelse(self.Fa1 + self.Ea1 > 0, self.Fa1 + self.Ea1, 1)) * self.Sa_diff ) self.Ea = ( self.Ea1 + (self.Ea1 / pcr.ifthenelse(self.Fa1 + self.Ea1 > 0, self.Fa1 + self.Ea1, 1)) * self.Sa_diff ) self.Sa[k] = self.Sa_t[k] + (self.Pe - self.Qa) - self.Ea - self.Fa self.Sa[k] = pcr.ifthenelse(self.Sa[k] < 0, 0, self.Sa[k]) self.Sa_diff2 = pcr.ifthen(self.Sa[k] < 0, self.Sa[k]) self.wbSa_[k] = self.Pe - self.Ea - self.Qa - self.Fa - self.Sa[k] + self.Sa_t[k] self.Ea_[k] = self.Ea self.Qa_[k] = self.Qa self.Fa_[k] = self.Fa
def area_river_burnin(ldd, dem, order, Area): """ Calculates the lowest values in as DEM for each erea in an area map for river of order *order* Input: - ldd - dem - order - Area map Output: - dem """ strorder = pcr.streamorder(ldd) strordermax = pcr.areamaximum(strorder, Area) maxordcell = pcr.ifthen(strordermax > order, strordermax) riverdem = pcr.areaminimum(dem, Area) return pcr.ifthen(pcr.boolean(maxordcell), riverdem)
def kinAlphaComposite(self,watStor,mask): #-given the total water storage and the mask specifying the occurrence of # floodplain conditions, retrns the Q-A relationship for the kinematic # wave and the associated parameters floodplainStorage= pcr.ifthen(mask,watStor) floodFrac, floodZ, dynamicWetA, dynamicAlphaQ= self.kinAlphaDynamic(floodplainStorage) staticWetA, staticAlphaQ= self.kinAlphaStatic(watStor) floodFrac= pcr.ifthenelse(mask,floodFrac,0.) floodZ= pcr.ifthenelse(mask,floodZ,0.) wetA= pcr.ifthenelse(mask,dynamicWetA,staticWetA) alphaQ= pcr.ifthenelse(mask,dynamicAlphaQ,staticAlphaQ) return floodFrac,floodZ,wetA,alphaQ
def derive_HAND(dem, ldd, accuThreshold, rivers=None, basin=None, up_area=None, neg_HAND=None): """ Function derives Height-Above-Nearest-Drain. See http://www.sciencedirect.com/science/article/pii/S003442570800120X Input: dem -- pcraster object float32, elevation data ldd -- pcraster object direction, local drain directions accuThreshold -- upstream amount of cells as threshold for river delineation rivers=None -- you can provide a rivers layer here. Pixels that are identified as river should have a value > 0, other pixels a value of zero. basin=None -- set a boolean pcraster map where areas with True are estimated using the nearest drain in ldd distance and areas with False by means of the nearest friction distance. Friction distance estimated using the upstream area as weight (i.e. drains with a bigger upstream area have a lower friction) the spreadzone operator is used in this case. up_area=None -- provide the upstream area (if not assigned a guesstimate is prepared, assuming the LDD covers a full catchment area) neg_HAND=None -- if set to 1, HAND maps can have negative values when elevation outside of stream is lower than stream (for example when there are natural embankments) Output: hand -- pcraster bject float32, height, normalised to nearest stream dist -- distance to nearest stream measured in cell lengths according to D8 directions """ if rivers is None: # prepare stream from a strahler threshold stream = pcr.ifthenelse(pcr.accuflux(ldd, 1) >= accuThreshold, pcr.boolean(1), pcr.boolean(0)) else: # convert stream network to boolean stream = pcr.boolean(pcr.cover(rivers, 0)) # determine height in river (in DEM*100 unit as ordinal) height_river = pcr.ifthenelse(stream, pcr.ordinal(dem*100), 0) if basin is None: up_elevation = pcr.scalar(pcr.subcatchment(ldd, height_river)) else: # use basin to allocate areas outside basin to the nearest stream. Nearest is weighted by upstream area if up_area is None: up_area = pcr.accuflux(ldd, 1) up_area = pcr.ifthen(stream, up_area) # mask areas outside streams friction = 1./pcr.scalar(pcr.spreadzone(pcr.cover(pcr.ordinal(up_area), 0), 0, 0)) # if basin, use nearest river within subcatchment, if outside basin, use weighted-nearest river up_elevation = pcr.ifthenelse(basin, pcr.scalar(pcr.subcatchment(ldd, height_river)), pcr.scalar(pcr.spreadzone(height_river, 0, friction))) # replace areas outside of basin by a spread zone calculation. # make negative HANDS also possible if neg_HAND == 1: hand = (pcr.scalar(pcr.ordinal(dem*100))-up_elevation)/100 # convert back to float in DEM units else: hand = pcr.max(pcr.scalar(pcr.ordinal(dem*100))-up_elevation, 0)/100 # convert back to float in DEM units dist = pcr.ldddist(ldd, stream, 1) # compute horizontal distance estimate return hand, dist
def readPCRmapClone(v,cloneMapFileName,tmpDir,absolutePath=None,isLddMap=False,cover=None,isNomMap=False,inputEPSG="EPSG:4326",outputEPSG="EPSG:4326",method="near"): # v: inputMapFileName or floating values # cloneMapFileName: If the inputMap and cloneMap have different clones, # resampling will be done. logger.debug('read file/values: '+str(v)) if v == "None": PCRmap = str("None") elif not re.match(r"[0-9.-]*$",v): if absolutePath != None: v = getFullPath(v,absolutePath) # print(v) sameClone = isSameClone(v,cloneMapFileName) if sameClone == True: PCRmap = pcr.readmap(v) else: # resample using GDAL: output = tmpDir+'temp.map' # if no re-projection needed: if inputEPSG == outputEPSG or outputEPSG == None: warp = gdalwarpPCR(v,output,cloneMapFileName,tmpDir,isLddMap,isNomMap) else: warp = gdalwarpPCR(v,output,cloneMapFileName,tmpDir,isLddMap,isNomMap,inputEPSG,outputEPSG,method) # read from temporary file and delete the temporary file: PCRmap = pcr.readmap(output) if isLddMap == True: PCRmap = pcr.ifthen(pcr.scalar(PCRmap) < 10., PCRmap) if isLddMap == True: PCRmap = pcr.ldd(PCRmap) if isNomMap == True: PCRmap = pcr.ifthen(pcr.scalar(PCRmap) > 0., PCRmap) if isNomMap == True: PCRmap = pcr.nominal(PCRmap) if os.path.isdir(tmpDir): shutil.rmtree(tmpDir) os.makedirs(tmpDir) else: PCRmap = pcr.scalar(float(v)) if cover != None: PCRmap = pcr.cover(PCRmap, cover) co = None; cOut = None; err = None; warp = None del co; del cOut; del err; del warp stdout = None; del stdout stderr = None; del stderr return PCRmap
def getICs(self, initial_condition): avgInflow = initial_condition["avgLakeReservoirInflowShort"] avgOutflow = initial_condition["avgLakeReservoirOutflowLong"] # if not isinstance(initial_condition["waterBodyStorage"], type(None)): # read directly waterBodyStorage = initial_condition["waterBodyStorage"] else: # calculate waterBodyStorage at cells where lakes and/or reservoirs are defined # storageAtLakeAndReservoirs = pcr.cover( pcr.ifthen( pcr.scalar(self.waterBodyIds) > 0.0, initial_condition["channelStorage"], ), 0.0, ) # # - move only non negative values and use rounddown values storageAtLakeAndReservoirs = pcr.max( 0.00, pcr.rounddown(storageAtLakeAndReservoirs) ) # # lake and reservoir storages = waterBodyStorage (m3) ; values are given for the entire lake / reservoir cells waterBodyStorage = pcr.ifthen( pcr.scalar(self.waterBodyIds) > 0.0, pcr.areatotal(storageAtLakeAndReservoirs, self.waterBodyIds), ) self.avgInflow = pcr.cover(avgInflow, 0.0) # unit: m3/s self.avgOutflow = pcr.cover(avgOutflow, 0.0) # unit: m3/s self.waterBodyStorage = pcr.cover(waterBodyStorage, 0.0) # unit: m3 self.avgInflow = pcr.ifthen(self.landmask, self.avgInflow) self.avgOutflow = pcr.ifthen(self.landmask, self.avgOutflow) self.waterBodyStorage = pcr.ifthen(self.landmask, self.waterBodyStorage)
def upscale_riverlength(ldd, order, factor): """ Upscales the riverlength using 'factor' The resulting maps can be resampled (e.g. using resample.exe) by factor and should include the accurate length as determined with the original higher resolution maps. This function is **depricated**, use are_riverlength instead as this version is very slow for large maps Input: - ldd - minimum streamorder to include Output: - distance per factor cells """ strorder = pcr.streamorder(ldd) strorder = pcr.ifthen(strorder >= order, strorder) dist = pcr.cover( pcr.max( pcr.celllength(), pcr.ifthen(pcr.boolean(strorder), pcr.downstreamdist(ldd)) ), 0, ) totdist = pcr.max( pcr.ifthen( pcr.boolean(strorder), pcr.windowtotal( pcr.ifthen(pcr.boolean(strorder), dist), pcr.celllength() * factor ), ), dist, ) return totdist
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
def derive_HAND(dem, ldd, accuThreshold, rivers=None, basin=None): """ Function derives Height-Above-Nearest-Drain. See http://www.sciencedirect.com/science/article/pii/S003442570800120X Input: dem -- pcraster object float32, elevation data ldd -- pcraster object direction, local drain directions accuThreshold -- upstream amount of cells as threshold for river delineation rivers=None -- you can provide a rivers layer here. Pixels that are identified as river should have a value > 0, other pixels a value of zero. basin=None -- set a boolean pcraster map where areas with True are estimated using the nearest drain in ldd distance and areas with False by means of the nearest friction distance. Friction distance estimated using the upstream area as weight (i.e. drains with a bigger upstream area have a lower friction) the spreadzone operator is used in this case. Output: hand -- pcraster bject float32, height, normalised to nearest stream dist -- distance to nearest stream measured in cell lengths according to D8 directions """ if rivers is None: stream = pcr.ifthenelse( pcr.accuflux(ldd, 1) >= accuThreshold, pcr.boolean(1), pcr.boolean(0) ) else: stream = pcr.boolean(pcr.cover(rivers, 0)) height_river = pcr.ifthenelse(stream, pcr.ordinal(dem * 100), 0) if basin is None: up_elevation = pcr.scalar(pcr.subcatchment(ldd, height_river)) else: drainage_surf = pcr.ifthen(rivers, pcr.accuflux(ldd, 1)) weight = 1.0 / pcr.scalar( pcr.spreadzone(pcr.cover(pcr.ordinal(drainage_surf), 0), 0, 0) ) up_elevation = pcr.ifthenelse( basin, pcr.scalar(pcr.subcatchment(ldd, height_river)), pcr.scalar(pcr.spreadzone(height_river, 0, weight)), ) # replace areas outside of basin by a spread zone calculation. hand = pcr.max(pcr.scalar(pcr.ordinal(dem * 100)) - up_elevation, 0) / 100 dist = pcr.ldddist(ldd, stream, 1) return hand, dist
def agriZone_Jarvis(self, k): """ - Potential evaporation is decreased by energy used for interception evaporation - Formula for evaporation based on Jarvis stress functions - Outgoing fluxes are determined based on (value in previous timestep + inflow) and if this leads to negative storage, the outgoing fluxes are corrected to rato --> Eu is no longer taken into account for this correction - Qa u is determined from overflow from Sa - Code for ini-file: 1 """ self.Qa = pcr.max(self.Pe - (self.samax[k] - self.Sa_t[k]), 0) self.Sa[k] = self.Sa_t[k] + (self.Pe - self.Qa) self.SaN = pcr.min(self.Sa[k] / self.samax2, 1) self.SuN = self.Su[k] / self.sumax[k] JarvisCoefficients.calcEu( self, k, 1 ) # calculation of Ea based on Jarvis stress functions self.Ea1 = self.Eu self.Fa1 = self.Fmin[k] + (self.Fmax[k] - self.Fmin[k]) * e ** ( -self.decF[k] * self.SuN ) self.Sa[k] = self.Sa_t[k] + (self.Pe - self.Qa) - self.Fa1 - self.Ea1 self.Sa_diff = pcr.ifthenelse(self.Sa[k] < 0, self.Sa[k], 0) self.Fa = ( self.Fa1 + (self.Fa1 / pcr.ifthenelse(self.Fa1 + self.Ea1 > 0, self.Fa1 + self.Ea1, 1)) * self.Sa_diff ) self.Ea = ( self.Ea1 + (self.Ea1 / pcr.ifthenelse(self.Fa1 + self.Ea1 > 0, self.Fa1 + self.Ea1, 1)) * self.Sa_diff ) self.Sa[k] = self.Sa_t[k] + (self.Pe - self.Qa) - self.Ea - self.Fa self.Sa[k] = pcr.ifthenelse(self.Sa[k] < 0, 0, self.Sa[k]) self.Sa_diff2 = pcr.ifthen(self.Sa[k] < 0, self.Sa[k]) self.wbSa_[k] = self.Pe - self.Ea - self.Qa - self.Fa - self.Sa[k] + self.Sa_t[k] self.Ea_[k] = self.Ea self.Qa_[k] = self.Qa self.Fa_[k] = self.Fa
def area_percentile(inmap, area, n, order, percentile): """ calculates percentile of inmap per area n is the number of points in each area, order, the sorter order of inmap per area (output of areaorder(inmap,area)) n is the output of pcr.areatotal(pcr.spatial(pcr.scalar(1.0)),area) Input: - inmap - area map - n - order (riverorder) - percentile Output: - percentile map """ i = pcr.rounddown((n * percentile) / 100.0 + 0.5) # index in order map perc = pcr.ifthen(i == order, inmap) return pcr.areaaverage(perc, area)
def area_riverlength_factor(ldd, Area, Clength): """ ceates correction factors for riverlength for the largest streamorder in each area Input: - ldd - Area - Clength (1d length of a cell (pcr.sqrt(Area)) Output: - distance per area """ strorder = pcr.streamorder(ldd) strordermax = pcr.areamaximum(strorder, Area) dist = pcr.downstreamdist(ldd) # count nr of strorder cells in each area nr = pcr.areatotal(pcr.ifthen(strorder == strordermax, dist), Area) # N = pcr.sqrt(pcr.areatotal(pcr.scalar(pcr.boolean(Area)),Area)) N = Clength factor = nr / N return factor
# set the pcraster clone, ldd, landmask, and cell area map msg = "Setting the clone, ldd, landmask, and cell area maps" + ":" logger.info(msg) # - clone clone_map_file = input_files['clone_map_05min'] pcr.setclone(clone_map_file) # - ldd ldd = vos.readPCRmapClone(input_files['ldd_map_05min'], clone_map_file, output_files['tmp_folder'], None, True) ldd = pcr.lddrepair(pcr.ldd(ldd)) ldd = pcr.lddrepair(ldd) # - landmask landmask = pcr.ifthen(pcr.defined(ldd), pcr.boolean(1.0)) # - cell area cell_area = vos.readPCRmapClone(input_files['cell_area_05min'], clone_map_file, output_files['tmp_folder']) # set the basin map msg = "Setting the basin map" + ":" logger.info(msg) basin_map = pcr.nominal(\ vos.readPCRmapClone(input_files['basin_map_05min'], input_files['clone_map_05min'], output_files['tmp_folder'], None, False, None, True)) #~ pcr.aguila(basin_map)
pass try: os.makedirs(tmp_directory) except: pass # initiate the netcd file and object: tssNetCDF = ConvertMapsToNetCDF4(cloneMapFile = cloneMapFileName, attribute = attributeDictionary, cellSizeInArcMinutes = cellSizeInArcMinutes) tssNetCDF.createNetCDF(ncFileName,varNames,varUnits) index = 0 # for posCnt # set clone and define land mask region pcr.setclone(landmask05minFile) landmask = pcr.defined(pcr.readmap(landmask05minFile)) landmask = pcr.ifthen(landmask, landmask) # cell area at 5 arc min resolution cellArea = vos.readPCRmapClone(cellArea05minFile, cloneMapFileName,tmp_directory) cellArea = pcr.ifthen(landmask,cellArea) # ids for every 30 arc min grid: uniqueIDs30min = vos.readPCRmapClone(uniqueIDs30minFile, cloneMapFileName,tmp_directory) uniqueIDs30min = pcr.nominal(pcr.ifthen(landmask, uniqueIDs30min)) for iYear in range(staYear,endYear+1): for iMonth in range(1,12+1): timeStamp = datetime.datetime(int(iYear),int(iMonth),int(1),int(0))
ncFileName = netcdf_file[bias_type][var_name]['file_name'], \ varName = variable_name, \ varUnit = variable_unit, \ longName = var_long_name, \ comment = varDict.comment[var_name] ) # store the variables to pcraster map and netcdf files: data_dictionary = {} for return_period in return_periods: # variable name variable_name = str(return_period) + "_of_" + varDict.netcdf_short_name[var_name] # report to a pcraster map pcr.report(pcr.ifthen(landmask, extreme_values[bias_type][return_period]), bias_type + "_" + variable_name + ".map") # put it into a dictionary data_dictionary[variable_name] = pcr.pcr2numpy(extreme_values[bias_type][return_period], vos.MV) # save the variables to a netcdf file netcdf_report.dictionary_of_data_to_netcdf(netcdf_file[bias_type][var_name]['file_name'], \ data_dictionary, \ timeBounds) # saving "return_period_historical": the return period in present days (historical run) belonging to future extreme values # - to pcraster files only for return_period in return_periods: # report to a pcraster map pcr.report(pcr.ifthen(landmask, extreme_values['return_period_historical'][return_period]), 'return_period_historical_corresponding_to' + "_" + str(return_period) + ".map")
msg =' all done' logger.info(msg) print print # set the global clone map clone_map_file = "/projects/0/dfguu/users/edwinhs/data/HydroSHEDS/hydro_basin_without_lakes/integrating_ldd/version_9_december_2016/merged_ldd.map" pcr.setclone(clone_map_file) # set the landmask # - using the following landmask (defined to exclude river basins with limited output of PCR-GLOBWB / limited output of extreme value analyses) landmask_30sec_file = "/projects/0/aqueduct/users/edwinsut/data/landmasks_for_extreme_value_analysis_and_downscaling/landmask_downscaling/landmask_downscaling_30sec.map" msg = "Set the (high resolution) landmask based on the file: " + str(landmask_30sec_file) logger.info(msg) landmask_30sec = pcr.defined(pcr.readmap(landmask_30sec_file)) landmask_used = pcr.ifthen(landmask_30sec, landmask_30sec) # boolean maps to mask out permanent water bodies (lakes and reservoirs): reservoirs_30sec_file = "/projects/0/aqueduct/users/edwinsut/data/reservoirs_and_lakes_30sec/grand_reservoirs_v1_1.boolean.map" msg = "Set the (high resolution) reservoirs based on the file: " + str(reservoirs_30sec_file) logger.info(msg) reservoirs_30sec = pcr.cover(pcr.readmap(reservoirs_30sec_file), pcr.boolean(0.0)) lakes_30sec_file = "/projects/0/aqueduct/users/edwinsut/data/reservoirs_and_lakes_30sec/glwd1_lakes.boolean.map" msg = "Set the (high resolution) lakes based on the file: " + str(lakes_30sec_file) logger.info(msg) lakes_30sec = pcr.cover(pcr.readmap(lakes_30sec_file), pcr.boolean(0.0)) # # cells that do not belong lakes and reservoirs non_permanent_water_bodies = pcr.ifthenelse(reservoirs_30sec, pcr.boolean(0.0), pcr.boolean(1.0)) non_permanent_water_bodies = pcr.ifthen(non_permanent_water_bodies, non_permanent_water_bodies) non_permanent_water_bodies = pcr.ifthenelse( lakes_30sec, pcr.boolean(0.0), non_permanent_water_bodies)
def agriZone_Ep_Sa_beta_frostSamax_surfTemp(self, k): """ - Potential evaporation is decreased by energy used for interception evaporation - Formula for evaporation based on LP - Outgoing fluxes are determined based on (value in previous timestep + inflow) and if this leads to negative storage, the outgoing fluxes are corrected to rato --> Eu is no longer taken into account for this correction - Qa u is determined from overflow from Sa --> incorporation of beta function - Fa is based on storage in Sa - Fa is decreased in case of frozen soil - Code for ini-file: 13 """ JarvisCoefficients.calcEp(self, k) self.PotEvaporation = self.EpHour self.FrDur[k] = pcr.min( self.FrDur[k] + pcr.ifthenelse( self.TempSurf > 0, self.ratFT[k] * self.TempSurf, self.TempSurf ) * self.dayDeg[k], 0, ) self.Ft = pcr.min( pcr.max( self.FrDur[k] / (self.FrDur1[k] - self.FrDur0[k]) - self.FrDur0[k] / (self.FrDur1[k] - self.FrDur0[k]), self.samin[k], ), 1, ) self.samax2 = self.samax[k] * pcr.scalar(self.catchArea) * self.Ft self.Qaadd = pcr.max(self.Sa_t[k] + self.Pe - self.samax2, 0) self.Sa[k] = self.Sa_t[k] + (self.Pe - self.Qaadd) self.SaN = pcr.min(self.Sa[k] / self.samax2, 1) self.SuN = self.Su[k] / self.sumax[k] self.Ea1 = pcr.max((self.PotEvaporation - self.Ei), 0) * pcr.min( self.Sa[k] / (self.samax2 * self.LP[k]), 1 ) self.Qa1 = (self.Pe - self.Qaadd) * (1 - (1 - self.SaN) ** self.beta[k]) self.Fa1 = pcr.ifthenelse( self.SaN > 0, self.Fmin[k] + (self.Fmax[k] - self.Fmin[k]) * e ** (-self.decF[k] * (1 - self.SaN)), 0, ) self.Sa[k] = self.Sa_t[k] + (self.Pe - self.Qaadd) - self.Qa1 - self.Fa1 - self.Ea1 self.Sa_diff = pcr.ifthenelse(self.Sa[k] < 0, self.Sa[k], 0) self.Qa = ( self.Qa1 + ( self.Qa1 / pcr.ifthenelse( self.Fa1 + self.Ea1 + self.Qa1 > 0, self.Fa1 + self.Ea1 + self.Qa1, 1 ) ) * self.Sa_diff ) self.Fa = ( self.Fa1 + ( self.Fa1 / pcr.ifthenelse( self.Fa1 + self.Ea1 + self.Qa1 > 0, self.Fa1 + self.Ea1 + self.Qa1, 1 ) ) * self.Sa_diff ) self.Ea = ( self.Ea1 + ( self.Ea1 / pcr.ifthenelse( self.Fa1 + self.Ea1 + self.Qa1 > 0, self.Fa1 + self.Ea1 + self.Qa1, 1 ) ) * self.Sa_diff ) self.Sa[k] = self.Sa_t[k] + (self.Pe - self.Qaadd) - self.Ea - self.Fa - self.Qa self.Sa[k] = pcr.ifthenelse(self.Sa[k] < 0, 0, self.Sa[k]) self.Sa_diff2 = pcr.ifthen(self.Sa[k] < 0, self.Sa[k]) self.wbSa_[k] = ( self.Pe - self.Ea - self.Qa - self.Qaadd - self.Fa - self.Sa[k] + self.Sa_t[k] ) self.Ea_[k] = self.Ea self.Qa_[k] = self.Qa + self.Qaadd self.Fa_[k] = self.Fa self.Ft_[k] = self.Ft
def subcatch_stream(ldd, threshold, stream=None, min_strahler=-999, max_strahler=999, assign_edge=False, assign_existing=False, up_area=None, basin=None): """ Derive catchments based upon strahler threshold Input: ldd -- pcraster object direction, local drain directions threshold -- integer, strahler threshold, subcatchments ge threshold are derived stream=None -- pcraster object ordinal, stream order map (made with pcr.streamorder), if provided, stream order map is not generated on the fly but used from this map. Useful when a subdomain within a catchment is provided, which would cause edge effects in the stream order map min_strahler=-999 -- integer, minimum strahler threshold of river catchments to return max_strahler=999 -- integer, maximum strahler threshold of river catchments to return assign_unique=False -- if set to True, unassigned connected areas at the edges of the domain are assigned a unique id as well. If set to False, edges are not assigned assign_existing=False == if set to True, unassigned edges are assigned to existing basins with an upstream weighting. If set to False, edges are assigned to unique IDs, or not assigned output: stream_ge -- pcraster object, streams of strahler order ge threshold subcatch -- pcraster object, subcatchments of strahler order ge threshold """ # derive stream order if stream is None: stream = pcr.streamorder(ldd) stream_ge = pcr.ifthen(stream >= threshold, stream) stream_up_sum = pcr.ordinal(pcr.upstream(ldd, pcr.cover(pcr.scalar(stream_ge), 0))) # detect any transfer of strahler order, to a higher strahler order. transition_strahler = pcr.ifthenelse(pcr.downstream(ldd, stream_ge) != stream_ge, pcr.boolean(1), pcr.ifthenelse(pcr.nominal(ldd) == 5, pcr.boolean(1), pcr.ifthenelse(pcr.downstream(ldd, pcr.scalar(stream_up_sum)) > pcr.scalar(stream_ge), pcr.boolean(1), pcr.boolean(0)))) # make unique ids (write to file) transition_unique = pcr.ordinal(pcr.uniqueid(transition_strahler)) # derive upstream catchment areas (write to file) subcatch = pcr.nominal(pcr.subcatchment(ldd, transition_unique)) # mask out areas outside basin if basin is not None: subcatch = pcr.ifthen(basin, subcatch) if assign_edge: # fill unclassified areas (in pcraster equal to zero) with a unique id, above the maximum id assigned so far unique_edge = pcr.clump(pcr.ifthen(subcatch==0, pcr.ordinal(0))) subcatch = pcr.ifthenelse(subcatch==0, pcr.nominal(pcr.mapmaximum(pcr.scalar(subcatch)) + pcr.scalar(unique_edge)), pcr.nominal(subcatch)) elif assign_existing: # unaccounted areas are added to largest nearest draining basin if up_area is None: up_area = pcr.ifthen(pcr.boolean(pcr.cover(stream_ge, 0)), pcr.accuflux(ldd, 1)) riverid = pcr.ifthen(pcr.boolean(pcr.cover(stream_ge, 0)), subcatch) friction = 1./pcr.scalar(pcr.spreadzone(pcr.cover(pcr.ordinal(up_area), 0), 0, 0)) # *(pcr.scalar(ldd)*0+1) delta = pcr.ifthen(pcr.scalar(ldd)>=0, pcr.ifthen(pcr.cover(subcatch, 0)==0, pcr.spreadzone(pcr.cover(riverid, 0), 0, friction))) subcatch = pcr.ifthenelse(pcr.boolean(pcr.cover(subcatch, 0)), subcatch, delta) # finally, only keep basins with minimum and maximum river order flowing through them strahler_subcatch = pcr.areamaximum(stream, subcatch) subcatch = pcr.ifthen(pcr.ordinal(strahler_subcatch) >= min_strahler, pcr.ifthen(pcr.ordinal(strahler_subcatch) <= max_strahler, subcatch)) return stream_ge, pcr.ordinal(subcatch)
# set the pcraster clone, ldd and landmask maps msg = "Setting the clone, ldd and landmask maps" + ":" logger.info(msg) # - clone clone_map_file = input_files['clone_map_05min'] pcr.setclone(clone_map_file) # - ldd ldd = vos.readPCRmapClone(input_files['ldd_map_05min'], clone_map_file, output_files['tmp_folder'], None, True) ldd = pcr.lddrepair(pcr.ldd(ldd)) ldd = pcr.lddrepair(ldd) # - landmask landmask = pcr.ifthen(pcr.defined(ldd), pcr.boolean(1.0)) # set the cell areas for 5 arc-min and half arc-degree cells msg = "Setting the cell areas for 5 arc-min and half arc-degree cells" + ":" logger.info(msg) # - 5 arc-min cell_area = vos.readPCRmapClone(input_files['cell_area_05min'], clone_map_file, output_files['tmp_folder']) cell_area = pcr.ifthen(landmask, cell_area) # netcdf general setup: netcdf_setup = {} netcdf_setup['format'] = "NETCDF4"
# set the pcraster clone, ldd, landmask, and cell area map msg = "Setting the clone, ldd, landmask, and cell area maps" + ":" logger.info(msg) # - clone clone_map_file = input_files['clone_map_05min'] pcr.setclone(clone_map_file) # - ldd ldd = vos.readPCRmapClone(input_files['ldd_map_05min'], clone_map_file, output_files['tmp_folder'], None, True) ldd = pcr.lddrepair(pcr.ldd(ldd)) ldd = pcr.lddrepair(ldd) # - landmask landmask = pcr.ifthen(pcr.defined(ldd), pcr.boolean(1.0)) # - cell area cell_area = vos.readPCRmapClone(input_files['cell_area_05min'], clone_map_file, output_files['tmp_folder']) # read the hydrological year msg = "Reading the hydrological year types" + ":" logger.info(msg) hydro_year_type = pcr.nominal(\ vos.readPCRmapClone(input_files['hydro_year_05min'], input_files['clone_map_05min'], output_files['tmp_folder'], None, False, None, True)) hydro_year_type = pcr.cover(hydro_year_type, pcr.nominal(1.0))
def identifyModelPixel(self,tmpDir,\ catchmentAreaAll,\ landMaskClass,\ xCoordinate,yCoordinate,id): # TODO: Include an option to consider average discharge. logger.info("Identify model pixel for the grdc station "+str(id)+".") # make a temporary directory: randomDir = self.makeRandomDir(tmpDir) # coordinate of grdc station xCoord = float(self.attributeGRDC["grdc_longitude_in_arc_degree"][str(id)]) yCoord = float(self.attributeGRDC["grdc_latitude_in_arc_degree"][str(id)]) # identify the point at pcraster model point = pcr.ifthen((pcr.abs(xCoordinate - xCoord) == pcr.mapminimum(pcr.abs(xCoordinate - xCoord))) &\ (pcr.abs(yCoordinate - yCoord) == pcr.mapminimum(pcr.abs(yCoordinate - yCoord))), \ pcr.boolean(1)) # expanding the point point = pcr.windowmajority(point, self.cell_size_in_arc_degree * 5.0) point = pcr.ifthen(catchmentAreaAll > 0, point) point = pcr.boolean(point) # values based on the model; modelCatchmentArea = pcr.ifthen(point, catchmentAreaAll) # unit: km2 model_x_ccordinate = pcr.ifthen(point, xCoordinate) # unit: arc degree model_y_ccordinate = pcr.ifthen(point, yCoordinate) # unit: arc degree # calculate (absolute) difference with GRDC data # - initiating all of them with the values of MV diffCatchArea = pcr.abs(pcr.scalar(vos.MV)) # difference between the model and grdc catchment area (unit: km2) diffDistance = pcr.abs(pcr.scalar(vos.MV)) # distance between the model pixel and grdc catchment station (unit: arc degree) diffLongitude = pcr.abs(pcr.scalar(vos.MV)) # longitude difference (unit: arc degree) diffLatitude = pcr.abs(pcr.scalar(vos.MV)) # latitude difference (unit: arc degree) # # - calculate (absolute) difference with GRDC data try: diffCatchArea = pcr.abs(modelCatchmentArea-\ float(self.attributeGRDC["grdc_catchment_area_in_km2"][str(id)])) except: logger.info("The difference in the model and grdc catchment area cannot be calculated.") try: diffLongitude = pcr.abs(model_x_ccordinate - xCoord) except: logger.info("The difference in longitude cannot be calculated.") try: diffLatitude = pcr.abs(model_y_ccordinate - yCoord) except: logger.info("The difference in latitude cannot be calculated.") try: diffDistance = (diffLongitude**(2) + \ diffLatitude**(2))**(0.5) # TODO: calculate distance in meter except: logger.info("Distance cannot be calculated.") # identify masks masks = pcr.ifthen(pcr.boolean(point), landMaskClass) # export the difference to temporary files: maps and txt catchmentAreaMap = randomDir+"/"+vos.get_random_word()+".area.map" diffCatchAreaMap = randomDir+"/"+vos.get_random_word()+".dare.map" diffDistanceMap = randomDir+"/"+vos.get_random_word()+".dist.map" diffLatitudeMap = randomDir+"/"+vos.get_random_word()+".dlat.map" diffLongitudeMap = randomDir+"/"+vos.get_random_word()+".dlon.map" diffLatitudeMap = randomDir+"/"+vos.get_random_word()+".dlat.map" # maskMap = randomDir+"/"+vos.get_random_word()+".mask.map" diffColumnFile = randomDir+"/"+vos.get_random_word()+".cols.txt" # output # pcr.report(pcr.ifthen(point,modelCatchmentArea), catchmentAreaMap) pcr.report(pcr.ifthen(point,diffCatchArea ), diffCatchAreaMap) pcr.report(pcr.ifthen(point,diffDistance ), diffDistanceMap ) pcr.report(pcr.ifthen(point,diffLatitude ), diffLongitudeMap) pcr.report(pcr.ifthen(point,diffLongitude ), diffLatitudeMap ) pcr.report(pcr.ifthen(point,masks ), maskMap) # cmd = 'map2col '+catchmentAreaMap +' '+\ diffCatchAreaMap +' '+\ diffDistanceMap +' '+\ diffLongitudeMap +' '+\ diffLatitudeMap +' '+\ maskMap+' '+diffColumnFile print(cmd); os.system(cmd) # use R to sort the file cmd = 'R -f saveIdentifiedPixels.R '+diffColumnFile print(cmd); os.system(cmd) try: # read the output file (from R) f = open(diffColumnFile+".sel") ; allLines = f.read() ; f.close() # split the content of the file into several lines allLines = allLines.replace("\r",""); allLines = allLines.split("\n") selectedPixel = allLines[0].split(";") model_longitude_in_arc_degree = float(selectedPixel[0]) model_latitude_in_arc_degree = float(selectedPixel[1]) model_catchment_area_in_km2 = float(selectedPixel[2]) model_landmask = str(selectedPixel[7]) log_message = "Model pixel for grdc station "+str(id)+" is identified (lat/lon in arc degree): " log_message += str(model_latitude_in_arc_degree) + " ; " + str(model_longitude_in_arc_degree) logger.info(log_message) self.attributeGRDC["model_longitude_in_arc_degree"][str(id)] = model_longitude_in_arc_degree self.attributeGRDC["model_latitude_in_arc_degree"][str(id)] = model_latitude_in_arc_degree self.attributeGRDC["model_catchment_area_in_km2"][str(id)] = model_catchment_area_in_km2 self.attributeGRDC["model_landmask"][str(id)] = model_landmask except: logger.info("Model pixel for grdc station "+str(id)+" can NOT be identified.") self.cleanRandomDir(randomDir)
# initiate the netcd object: tssNetCDF = MakingNetCDF(cloneMapFile = cloneMapFileName, \ attribute = attributeDictionary, \ cellSizeInArcMinutes = cellSizeInArcMinutes) # making netcdf files: for var in variable_names: tssNetCDF.createNetCDF(output[var]['file_name'], var, output[var]['unit']) # class (country) ids uniqueIDsFile = "/projects/0/dfguu/users/edwin/data/country_shp_from_tianyi/World_Polys_High.map" uniqueIDs = pcr.nominal(\ vos.readPCRmapClone(uniqueIDsFile, cloneMapFileName, tmp_directory, None, False, None, True)) uniqueIDs = pcr.readmap(uniqueIDsFile) uniqueIDs = pcr.ifthen(pcr.scalar(uniqueIDs) >= 0.0, uniqueIDs) # landmask landmask = pcr.defined(pcr.readmap(landmask05minFile)) landmask = pcr.ifthen(landmask, landmask) # - extending landmask with uniqueIDs landmask = pcr.cover(landmask, pcr.defined(uniqueIDs)) # extending class (country) ids max_step = 5 for i in range(1, max_step+1, 1): cmd = "Extending class: step "+str(i)+" from " + str(max_step) print(cmd) uniqueIDs = pcr.cover(uniqueIDs, pcr.windowmajority(uniqueIDs, 0.5)) # - use only cells within the landmask uniqueIDs = pcr.ifthen(landmask, uniqueIDs)