Exemple #1
0
def waterBalanceCheck(fluxesIn,fluxesOut,preStorages,endStorages,processName,PrintOnlyErrors,dateStr,threshold=1e-5,landmask=None):
    """ Returns the water balance for a list of input, output, and storage map files  """
    # modified by Edwin (22 Apr 2013)

    inMap   = pcr.spatial(pcr.scalar(0.0))
    outMap  = pcr.spatial(pcr.scalar(0.0))
    dsMap   = pcr.spatial(pcr.scalar(0.0))
    
    for fluxIn in fluxesIn:
        inMap   += fluxIn
    for fluxOut in fluxesOut:
        outMap  += fluxOut
    for preStorage in preStorages:
        dsMap   += preStorage
    for endStorage in endStorages:
        dsMap   -= endStorage

    a,b,c = getMinMaxMean(inMap + dsMap- outMap)
    if abs(a) > threshold or abs(b) > threshold:
        if PrintOnlyErrors: 
            
            msg  = "\n"
            msg += "\n"
            msg  = "\n"
            msg += "\n"
            msg += "##############################################################################################################################################\n"
            msg += "WARNING !!!!!!!! Water Balance Error %s Min %f Max %f Mean %f" %(processName,a,b,c)
            msg += "\n"
            msg += "##############################################################################################################################################\n"
            msg += "\n"
            msg += "\n"
            msg += "\n"
            
            logger.error(msg)
Exemple #2
0
def lattometres(lat):
    """"
    Determines the length of one degree lat/long at a given latitude (in meter).
    Code taken from http:www.nga.mil/MSISiteContent/StaticFiles/Calculators/degree.html
    Input: map with lattitude values for each cell
    Returns: length of a cell lat, length of a cell long
    """
    # radlat = pcr.spatial(lat * ((2.0 * math.pi)/360.0))
    # radlat = lat * (2.0 * math.pi)/360.0
    pcr.setglobaloption("degrees")
    radlat = pcr.spatial(lat)  # pcraster cos/sin work in degrees!

    m1 = 111132.92  # latitude calculation term 1
    m2 = -559.82  # latitude calculation term 2
    m3 = 1.175  # latitude calculation term 3
    m4 = -0.0023  # latitude calculation term 4
    p1 = 111412.84  # longitude calculation term 1
    p2 = -93.5  # longitude calculation term 2
    p3 = 0.118  # longitude calculation term 3
    # # Calculate the length of a degree of latitude and longitude in meters

    latlen = (
        m1
        + (m2 * pcr.cos(2.0 * radlat))
        + (m3 * pcr.cos(4.0 * radlat))
        + (m4 * pcr.cos(6.0 * radlat))
    )
    longlen = (
        (p1 * pcr.cos(radlat))
        + (p2 * pcr.cos(3.0 * radlat))
        + (p3 * pcr.cos(5.0 * radlat))
    )

    return latlen, longlen
Exemple #3
0
def find_outlet(ldd):
    """
    Tries to find the outlet of the largest catchment in the Ldd

    Input:
        - Ldd

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

    return outlet
Exemple #4
0
  def sample(self, expression):
    """
    Sampling the current values of 'expression' at the given locations for the current timestep
    """

    arrayRowPos = self._userModel.currentTimeStep() - self._userModel.firstTimeStep()

    #if isinstance(expression, float):
    #  expression = pcraster.scalar(expression)

    try:
      # store the data type for tss file header
      if self._spatialDatatype == None:
        self._spatialDatatype = str(expression.dataType())
    except AttributeError as e:
      datatype, sep, tail = str(e).partition(" ")
      msg = "Argument must be a PCRaster map, type %s given. If necessary use data conversion functions like scalar()" % (datatype)
      raise AttributeError(msg)

    if self._spatialIdGiven:
      if expression.dataType() == pcraster.Scalar or expression.dataType() == pcraster.Directional:
        tmp = pcraster.areaaverage(pcraster.spatial(expression), pcraster.spatial(self._spatialId))
      else:
        tmp = pcraster.areamajority(pcraster.spatial(expression), pcraster.spatial(self._spatialId))

      col = 0
      for cellIndex in self._sampleAddresses:
        value, valid = pcraster.cellvalue(tmp, cellIndex)
        if not valid:
          value = Decimal("NaN")

        self._sampleValues[arrayRowPos][col] = value
        col += 1
    else:
      if expression.dataType() == pcraster.Scalar or expression.dataType() == pcraster.Directional:
         tmp = pcraster.maptotal(pcraster.spatial(expression))\
               / pcraster.maptotal(pcraster.scalar(pcraster.defined(pcraster.spatial(expression))))
      else:
         tmp = pcraster.mapmaximum(pcraster.maptotal(pcraster.areamajority(pcraster.spatial(expression),\
               pcraster.spatial(pcraster.nominal(1)))))

      value, valid = pcraster.cellvalue(tmp, 1)
      if not valid:
        value = Decimal("NaN")

      self._sampleValues[arrayRowPos] = value

    if self._userModel.currentTimeStep() == self._userModel.nrTimeSteps():
       self._writeTssFile()
Exemple #5
0
def waterBalanceCheck(fluxesIn,fluxesOut,preStorages,endStorages,processName,PrintOnlyErrors,dateStr,threshold=1e-5,landmask=None):
    """ Returns the water balance for a list of input, output, and storage map files  """
    # modified by Edwin (22 Apr 2013)

    inMap   = pcr.spatial(pcr.scalar(0.0))
    outMap  = pcr.spatial(pcr.scalar(0.0))
    dsMap   = pcr.spatial(pcr.scalar(0.0))
    for fluxIn in fluxesIn:
        inMap   += fluxIn
    for fluxOut in fluxesOut:
        outMap  += fluxOut
    for preStorage in preStorages:
        dsMap   += preStorage
    for endStorage in endStorages:
        dsMap   -= endStorage

    a,b,c = getMinMaxMean(inMap + dsMap- outMap)
    if abs(a) > threshold or abs(b) > threshold:
        if PrintOnlyErrors: 
            print "WBError %s Min %f Max %f Mean %f" %(processName,a,b,c)
            print ""
            
    wb = inMap + dsMap - outMap
    maxWBError = pcr.cellvalue(pcr.mapmaximum(pcr.abs(wb)), 1, 1)[0]
Exemple #6
0
  def arbitraryMapEquals(self, firstMap, secondMap):
    import math
    def floatEquals(float1, float2):
      threshold = 1e-6
      return math.fabs(float1 - float2) <= threshold
    if((firstMap.dataType() == _pcraster.Scalar) | \
         (firstMap.dataType() == _pcraster.Directional)):
      result = _pcraster._closeAtTolerance(firstMap, secondMap)
    else:
      result = pcraster.pcreq(firstMap, secondMap)

    minMap = pcraster.mapminimum(pcraster.spatial(pcraster.scalar(result)))
    value, isValid = pcraster.cellvalue(minMap, 1)

    assert isValid
    return floatEquals(value, 1.0)
Exemple #7
0
  def test_003(self):
      """ pcr2numpy should not run out of memory """

      nrRows, nrCols, cellSize = 200, 200, 1.0
      west, north = 0.0, 0.0
      pcraster.setclone(nrRows, nrCols, cellSize, west, north)

      raster = pcraster.uniform(1)

      process = psutil.Process(os.getpid())
      mem = process.memory_info()
      init_mem = mem.rss / 2**10

      nr_iterations = 50
      mem_increase = False

      # small memory increase can occur at runtime
      # allow for, but less than iterations * size(raster)
      max_diff = 400

      for it in range(0, nr_iterations):
        pcraster.pcr2numpy(raster, numpy.nan)
        mem = process.memory_info()
        curr_mem = mem.rss / 2**10
        if curr_mem - init_mem > max_diff:
          mem_increase = True

      raster = pcraster.spatial(pcraster.boolean(1))

      for it in range(0, nr_iterations):
        pcraster.pcr2numpy(raster, numpy.nan)
        mem = process.memory_info()
        curr_mem = mem.rss / 2**10
        if curr_mem - init_mem > max_diff:
          mem_increase = True

      raster = pcraster.nominal(pcraster.uniform(1) * 10)

      for it in range(0, nr_iterations):
        pcraster.pcr2numpy(raster, numpy.nan)
        mem = process.memory_info()
        curr_mem = mem.rss / 2**10
        if curr_mem - init_mem > max_diff:
          mem_increase = True

      self.assertEqual(mem_increase, False)
def dayLength(doy, lat):
    """ daylength fraction of day  """
    lat = lat * pcr.scalar(math.pi) / 180.0
    M_PI_2 = pcr.spatial(pcr.scalar(math.pi / 2.0))
    dec = pcr.sin((6.224111 + 0.017202 * doy) * 180 / math.pi)
    dec = pcr.scalar(0.39785 * pcr.sin(
        (4.868961 + .017203 * doy + 0.033446 * pcr.sin(dec * 180 / math.pi)) *
        180 / math.pi))
    dec = pcr.scalar(pcr.asin(dec))
    lat = pcr.ifthenelse(
        pcr.abs(lat) > M_PI_2, (M_PI_2 - pcr.scalar(0.01)) *
        pcr.ifthenelse(lat > 0, pcr.scalar(1.0), pcr.scalar(-1.0)), lat)
    arg = pcr.tan(dec) * pcr.tan(lat * 180.0 / math.pi) * -1
    h = pcr.scalar(pcr.acos(arg))
    h = h / 180 * math.pi
    h = pcr.ifthenelse(arg > 1.0, 0.0, h)  # /* sun stays below horizon */
    h = pcr.ifthenelse(arg < -1.0, math.pi, h)  # /* sun stays above horizon */
    return (h / math.pi)
Exemple #9
0
def areastat(Var, Area):
    """
    Calculate several statistics of *Var* for each unique id in *Area*

    Input:
        - Var
        - Area

    Output:
        - Standard_Deviation,Average,Max,Min

    """
    Avg = pcr.areaaverage(Var, Area)
    Sq = (Var - Avg) ** 2
    N = pcr.areatotal(pcr.spatial(pcr.cellarea()), Area) / pcr.cellarea()
    Sd = (pcr.areatotal(Sq, Area) / N) ** 0.5
    Max = pcr.areamaximum(Var, Area)
    Min = pcr.areaminimum(Var, Area)

    return Sd, Avg, Max, Min
Exemple #10
0
def areastat(Var, Area):
    """
    Calculate several statistics of *Var* for each unique id in *Area*

    Input:
        - Var
        - Area

    Output:
        - Standard_Deviation,Average,Max,Min

    """
    Avg = pcr.areaaverage(Var, Area)
    Sq = (Var - Avg) ** 2
    N = pcr.areatotal(pcr.spatial(pcr.cellarea()), Area) / pcr.cellarea()
    Sd = (pcr.areatotal(Sq, Area) / N) ** 0.5
    Max = pcr.areamaximum(Var, Area)
    Min = pcr.areaminimum(Var, Area)

    return Sd, Avg, Max, Min
def main():

    # output folder (and tmp folder)
    clean_out_folder = True
    if os.path.exists(out_folder):
        if clean_out_folder:
            shutil.rmtree(out_folder)
            os.makedirs(out_folder)
    else:
        os.makedirs(out_folder)
    os.chdir(out_folder)
    os.system("pwd")

    # set the clone map
    print("set the clone")
    pcr.setclone(global_ldd_30min_inp_file)

    # define the landmask
    print("define the landmask")
    # - based on the 30min input
    landmask_30min = define_landmask(input_file = global_landmask_30min_file,\
                                      clone_map_file = global_ldd_30min_inp_file,\
                                      output_map_file = "landmask_30min_only.map")
    # - based on the 05min input
    landmask_05min = define_landmask(input_file = global_landmask_05min_file,\
                                      clone_map_file = global_ldd_30min_inp_file,\
                                      output_map_file = "landmask_05min_only.map")
    # - based on the 06min input
    landmask_06min = define_landmask(input_file = global_landmask_06min_file,\
                                      clone_map_file = global_ldd_30min_inp_file,\
                                      output_map_file = "landmask_06min_only.map")
    # - based on the 30sec input
    landmask_30sec = define_landmask(input_file = global_landmask_30sec_file,\
                                      clone_map_file = global_ldd_30min_inp_file,\
                                      output_map_file = "landmask_30sec_only.map")
    # - based on the 30sec input
    landmask_03sec = define_landmask(input_file = global_landmask_03sec_file,\
                                      clone_map_file = global_ldd_30min_inp_file,\
                                      output_map_file = "landmask_03sec_only.map")
    #
    # - merge all landmasks
    landmask = pcr.cover(landmask_30min, landmask_05min, landmask_06min,
                         landmask_30sec, landmask_03sec)
    pcr.report(landmask, "global_landmask_extended_30min.map")
    # ~ pcr.aguila(landmask)

    # extend ldd
    print("extend/define the ldd")
    ldd_map = pcr.readmap(global_ldd_30min_inp_file)
    ldd_map = pcr.ifthen(landmask, pcr.cover(ldd_map, pcr.ldd(5)))
    pcr.report(ldd_map, "global_ldd_extended_30min.map")
    # ~ pcr.aguila(ldd_map)

    # catchment map and size
    catchment_map = pcr.catchment(ldd_map, pcr.pit(ldd_map))
    catchment_size = pcr.areatotal(pcr.spatial(pcr.scalar(1.0)), catchment_map)
    # ~ pcr.aguila(catchment_size)

    # identify small islands
    print("identify small islands")
    # - maps of islands smaller than 15000 cells (at half arc degree resolution)
    island_map = pcr.ifthen(landmask, pcr.clump(pcr.defined(ldd_map)))
    island_size = pcr.areatotal(pcr.spatial(pcr.scalar(1.0)), island_map)
    island_map = pcr.ifthen(island_size < 15000., island_map)
    # ~ # - use catchments (instead of islands)
    # ~ island_map  = catchment_map
    # ~ island_size = catchment_size
    # ~ island_map  = pcr.ifthen(island_size < 10000., island_map)
    # - sort from the largest island
    # -- take one cell per island as a representative
    island_map_rep_size = pcr.ifthen(
        pcr.areaorder(island_size, island_map) == 1.0, island_size)
    # -- sort from the largest island
    island_map_rep_ids = pcr.areaorder(
        island_map_rep_size * -1.00,
        pcr.ifthen(pcr.defined(island_map_rep_size), pcr.nominal(1.0)))
    # -- map of smaller islands, sorted from the largest one
    island_map = pcr.areamajority(pcr.nominal(island_map_rep_ids), island_map)

    # identify the biggest island for every group of small islands within a certain window (arcdeg cells)
    print("the biggest island for every group of small islands")
    large_island_map = pcr.ifthen(
        pcr.scalar(island_map) == pcr.windowminimum(pcr.scalar(island_map),
                                                    15.), island_map)
    # ~ pcr.aguila(large_island_map)

    # identify big catchments
    print("identify large catchments")
    catchment_map = pcr.catchment(ldd_map, pcr.pit(ldd_map))
    catchment_size = pcr.areatotal(pcr.spatial(pcr.scalar(1.0)), catchment_map)

    # ~ # - identify all large catchments with size >= 50 cells (at the resolution of 30 arcmin) = 50 x (50^2) km2 = 125000 km2
    # ~ large_catchment_map = pcr.ifthen(catchment_size >= 50, catchment_map)
    # ~ # - identify all large catchments with size >= 10 cells (at the resolution of 30 arcmin)
    # ~ large_catchment_map = pcr.ifthen(catchment_size >= 10, catchment_map)
    # ~ # - identify all large catchments with size >= 5 cells (at the resolution of 30 arcmin)
    # ~ large_catchment_map = pcr.ifthen(catchment_size >= 5, catchment_map)
    # ~ # - identify all large catchments with size >= 20 cells (at the resolution of 30 arcmin)
    # ~ large_catchment_map = pcr.ifthen(catchment_size >= 20, catchment_map)

    # - identify all large catchments with size >= 25 cells (at the resolution of 30 arcmin)
    large_catchment_map = pcr.ifthen(catchment_size >= 25, catchment_map)

    # - give the codes that are different than islands
    large_catchment_map = pcr.nominal(
        pcr.scalar(large_catchment_map) +
        10. * vos.getMinMaxMean(pcr.scalar(large_island_map))[1])

    # merge biggest islands and big catchments
    print("merge large catchments and islands")
    large_catchment_and_island_map = pcr.cover(large_catchment_map,
                                               large_island_map)
    # ~ large_catchment_and_island_map = pcr.cover(large_island_map, large_catchment_map)
    large_catchment_and_island_map_size = pcr.areatotal(
        pcr.spatial(pcr.scalar(1.0)), large_catchment_and_island_map)

    # - sort from the largest one
    # -- take one cell per island as a representative
    large_catchment_and_island_map_rep_size = pcr.ifthen(
        pcr.areaorder(large_catchment_and_island_map_size,
                      large_catchment_and_island_map) == 1.0,
        large_catchment_and_island_map_size)
    # -- sort from the largest
    large_catchment_and_island_map_rep_ids = pcr.areaorder(
        large_catchment_and_island_map_rep_size * -1.00,
        pcr.ifthen(pcr.defined(large_catchment_and_island_map_rep_size),
                   pcr.nominal(1.0)))
    # -- map of largest catchments and islands, sorted from the largest one
    large_catchment_and_island_map = pcr.areamajority(
        pcr.nominal(large_catchment_and_island_map_rep_ids),
        large_catchment_and_island_map)
    # ~ pcr.report(large_catchment_and_island_map, "large_catchments_and_islands.map")

    # ~ # perform cdo fillmiss2 in order to merge the small catchments to the nearest large catchments
    # ~ print("spatial interpolation/extrapolation using cdo fillmiss2 to get initial subdomains")
    # ~ cmd = "gdal_translate -of NETCDF large_catchments_and_islands.map large_catchments_and_islands.nc"
    # ~ print(cmd); os.system(cmd)
    # ~ cmd = "cdo fillmiss2 large_catchments_and_islands.nc large_catchments_and_islands_filled.nc"
    # ~ print(cmd); os.system(cmd)
    # ~ cmd = "gdal_translate -of PCRaster large_catchments_and_islands_filled.nc large_catchments_and_islands_filled.map"
    # ~ print(cmd); os.system(cmd)
    # ~ cmd = "mapattr -c " + global_ldd_30min_inp_file + " " + "large_catchments_and_islands_filled.map"
    # ~ print(cmd); os.system(cmd)
    # ~ # - initial subdomains
    # ~ subdomains_initial = pcr.nominal(pcr.readmap("large_catchments_and_islands_filled.map"))
    # ~ subdomains_initial = pcr.areamajority(subdomains_initial, catchment_map)
    # ~ pcr.aguila(subdomains_initial)

    # spatial interpolation/extrapolation in order to merge the small catchments to the nearest large catchments
    print("spatial interpolation/extrapolation to get initial subdomains")
    field = large_catchment_and_island_map
    cellID = pcr.nominal(pcr.uniqueid(pcr.defined(field)))
    zoneID = pcr.spreadzone(cellID, 0, 1)
    field = pcr.areamajority(field, zoneID)
    subdomains_initial = field
    subdomains_initial = pcr.areamajority(subdomains_initial, catchment_map)
    pcr.aguila(subdomains_initial)

    pcr.report(subdomains_initial, "global_subdomains_30min_initial.map")

    print(str(int(vos.getMinMaxMean(pcr.scalar(subdomains_initial))[0])))
    print(str(int(vos.getMinMaxMean(pcr.scalar(subdomains_initial))[1])))

    # ~ print(str(int(vos.getMinMaxMean(pcr.scalar(subdomains_initial_clump))[0])))
    # ~ print(str(int(vos.getMinMaxMean(pcr.scalar(subdomains_initial_clump))[1])))

    print("Checking all subdomains, avoid too large subdomains")

    num_of_masks = int(vos.getMinMaxMean(pcr.scalar(subdomains_initial))[1])

    # clone code that will be assigned
    assigned_number = 0

    subdomains_final = pcr.ifthen(
        pcr.scalar(subdomains_initial) < -7777, pcr.nominal(0))

    for nr in range(1, num_of_masks + 1, 1):

        msg = "Processing the landmask %s" % (str(nr))
        print(msg)

        mask_selected_boolean = pcr.ifthen(subdomains_initial == nr,
                                           pcr.boolean(1.0))

        # ~ if nr == 1: pcr.aguila(mask_selected_boolean)

        xmin, ymin, xmax, ymax = boundingBox(mask_selected_boolean)
        area_in_degree2 = (xmax - xmin) * (ymax - ymin)

        # ~ print(str(area_in_degree2))

        # check whether the size of bounding box is ok
        # - initial check value
        check_ok = True

        reference_area_in_degree2 = 2500.
        if area_in_degree2 > 1.50 * reference_area_in_degree2: check_ok = False
        if (xmax - xmin) > 10 * (ymax - ymin): check_ok = False

        if check_ok == True:

            msg = "Clump is not needed."
            msg = "\n\n" + str(msg) + "\n\n"
            print(msg)

            # assign the clone code
            assigned_number = assigned_number + 1

            # update global landmask for river and land
            mask_selected_nominal = pcr.ifthen(mask_selected_boolean,
                                               pcr.nominal(assigned_number))
            subdomains_final = pcr.cover(subdomains_final,
                                         mask_selected_nominal)

        if check_ok == False:

            msg = "Clump is needed."
            msg = "\n\n" + str(msg) + "\n\n"
            print(msg)

            # make clump
            clump_ids = pcr.nominal(pcr.clump(mask_selected_boolean))

            # merge clumps that are close together
            clump_ids_window_majority = pcr.windowmajority(clump_ids, 10.0)
            clump_ids = pcr.areamajority(clump_ids_window_majority, clump_ids)
            # ~ pcr.aguila(clump_ids)

            # minimimum and maximum values
            min_clump_id = int(
                pcr.cellvalue(pcr.mapminimum(pcr.scalar(clump_ids)), 1)[0])
            max_clump_id = int(
                pcr.cellvalue(pcr.mapmaximum(pcr.scalar(clump_ids)), 1)[0])

            for clump_id in range(min_clump_id, max_clump_id + 1, 1):

                msg = "Processing the clump %s of %s from the landmask %s" % (
                    str(clump_id), str(max_clump_id), str(nr))
                msg = "\n\n" + str(msg) + "\n\n"
                print(msg)

                # identify mask based on the clump
                mask_selected_boolean_from_clump = pcr.ifthen(
                    clump_ids == pcr.nominal(clump_id), mask_selected_boolean)
                mask_selected_boolean_from_clump = pcr.ifthen(
                    mask_selected_boolean_from_clump,
                    mask_selected_boolean_from_clump)

                # check whether the clump is empty
                check_mask_selected_boolean_from_clump = pcr.ifthen(
                    mask_selected_boolean, mask_selected_boolean_from_clump)
                check_if_empty = float(
                    pcr.cellvalue(
                        pcr.mapmaximum(
                            pcr.scalar(
                                pcr.defined(
                                    check_mask_selected_boolean_from_clump))),
                        1)[0])

                if check_if_empty == 0.0:

                    msg = "Map is empty !"
                    msg = "\n\n" + str(msg) + "\n\n"
                    print(msg)

                else:

                    msg = "Map is NOT empty !"
                    msg = "\n\n" + str(msg) + "\n\n"
                    print(msg)

                    # assign the clone code
                    assigned_number = assigned_number + 1

                    # update global landmask for river and land
                    mask_selected_nominal = pcr.ifthen(
                        mask_selected_boolean_from_clump,
                        pcr.nominal(assigned_number))
                    subdomains_final = pcr.cover(subdomains_final,
                                                 mask_selected_nominal)

    # ~ # kill all aguila processes if exist
    # ~ os.system('killall aguila')

    pcr.aguila(subdomains_final)

    print("")
    print("")
    print("")

    print("The subdomain map is READY.")

    pcr.report(subdomains_final, "global_subdomains_30min_final.map")

    num_of_masks = int(vos.getMinMaxMean(pcr.scalar(subdomains_final))[1])
    print(num_of_masks)

    print("")
    print("")
    print("")

    for nr in range(1, num_of_masks + 1, 1):

        mask_selected_boolean = pcr.ifthen(subdomains_final == nr,
                                           pcr.boolean(1.0))

        xmin, ymin, xmax, ymax = boundingBox(mask_selected_boolean)
        area_in_degree2 = (xmax - xmin) * (ymax - ymin)

        print(
            str(nr) + " ; " + str(area_in_degree2) + " ; " +
            str((xmax - xmin)) + " ; " + str((ymax - ymin)))

    print("")
    print("")
    print("")

    print("Number of subdomains: " + str(num_of_masks))

    print("")
    print("")
    print("")

    # spatial extrapolation in order to cover the entire map
    print("spatial interpolation/extrapolation to cover the entire map")
    field = subdomains_final
    cellID = pcr.nominal(pcr.uniqueid(pcr.defined(field)))
    zoneID = pcr.spreadzone(cellID, 0, 1)
    field = pcr.areamajority(field, zoneID)
    subdomains_final_filled = field
    pcr.aguila(subdomains_final_filled)

    pcr.report(subdomains_final_filled,
               "global_subdomains_30min_final_filled.map")
                       edwin_code_pcrglobwb_catchment_area_km2)

    # make correction if required
    abs_diff_value = pcr.cellvalue(pcr.mapmaximum(abs_diff), 1)[0]
    usgs_drain_area_km2 = pcr.cellvalue(pcr.mapmaximum(usgs_drain_area_km2),
                                        1)[0]

    if (usgs_drain_area_km2 > 1000.0) and \
       (abs_diff_value > 0.10 * usgs_drain_area_km2):

        # class within 0.1 arc degree windows
        edwin_code = pcr.windowmajority(edwin_code, 0.1)

        # find the most accurate cell:
        areaorder = pcr.areaorder(
            pcr.windowmaximum(pcr.spatial(pcr.scalar(usgs_drain_area_km2)),
                              0.1) - pcrglobwb_catchment_area_km2, edwin_code)

        # select pixel
        edwin_code = pcr.ifthen(areaorder == 1., edwin_code)

        # pcrglobwb catchment area
        edwin_code_pcrglobwb_catchment_area_km2 = pcr.ifthen(
            areaorder == 1., pcrglobwb_catchment_area_km2)

    # save using map2col
    pcr.report(edwin_code, "edwin_code.map")
    pcr.report(edwin_code_pcrglobwb_catchment_area_km2,
               "edwin_code_pcrglobwb_catchment_area_km2.map")
    cmd = "map2col edwin_code.map edwin_code_pcrglobwb_catchment_area_km2.map edwin_code_pcrglobwb_catchment_area_km2.tmp"
    print(cmd)
Exemple #13
0
def main():
    """
        
    :ivar masterdem: digital elevation model
    :ivar dem: digital elevation model
    :ivar river: optional river map
    """

    # Default values
    strRiver = 8
    masterdem = "dem.map"
    step1dir = "step1"
    step2dir = "step2"
    workdir = "."
    inifile = "wflow_prepare.ini"
    recreate = False
    snapgaugestoriver = False

    try:
        opts, args = getopt.getopt(sys.argv[1:], "W:hI:f",['version'])
    except getopt.error as msg:
        usage(msg)

    for o, a in opts:
        if o == "-W":
            workdir = a
        if o == "-I":
            inifile = a
        if o == "-h":
            usage()
        if o == "-f":
            recreate = True
        if o == "--version":
            import wflow
            print("wflow version: ", wflow.__version__)
            sys.exit(0)

    pcr.setglobaloption("unitcell")
    os.chdir(workdir)

    config = OpenConf(workdir + "/" + inifile)

    masterdem = configget(config, "files", "masterdem", "dem.map")
    pcr.setclone(masterdem)

    strRiver = int(configget(config, "settings", "riverorder", "4"))

    try:
        gauges_x = config.get("settings", "gauges_x")
        gauges_y = config.get("settings", "gauges_y")
    except:
        print("gauges_x and  gauges_y are required entries in the ini file")
        sys.exit(1)

    step1dir = configget(config, "directories", "step1dir", "step1")
    step2dir = configget(config, "directories", "step2dir", "step2")
    # upscalefactor = float(config.get("settings","upscalefactor"))

    corevolume = float(configget(config, "settings", "corevolume", "1E35"))
    catchmentprecipitation = float(
        configget(config, "settings", "catchmentprecipitation", "1E35")
    )
    corearea = float(configget(config, "settings", "corearea", "1E35"))
    outflowdepth = float(configget(config, "settings", "lddoutflowdepth", "1E35"))

    initialscale = int(configget(config, "settings", "initialscale", "1"))
    csize = float(configget(config, "settings", "cellsize", "1"))

    snapgaugestoriver = bool(
        int(configget(config, "settings", "snapgaugestoriver", "1"))
    )
    lddglobaloption = configget(config, "settings", "lddglobaloption", "lddout")
    pcr.setglobaloption(lddglobaloption)
    lu_water = configget(config, "files", "lu_water", "")
    lu_paved = configget(config, "files", "lu_paved", "")

    # X/Y coordinates of the gauges the system    
    X = np.fromstring(gauges_x, sep=',')
    Y = np.fromstring(gauges_y, sep=',')

    tr.Verbose = 1

    # make the directories to save results in
    if not os.path.isdir(step1dir + "/"):
        os.makedirs(step1dir)
    if not os.path.isdir(step2dir):
        os.makedirs(step2dir)

    if initialscale > 1:
        print("Initial scaling of DEM...")
        os.system(
            "resample -r "
            + str(initialscale)
            + " "
            + masterdem
            + " "
            + step1dir
            + "/dem_scaled.map"
        )
        print("Reading dem...")
        dem = pcr.readmap(step1dir + "/dem_scaled.map")
        ldddem = dem
    else:
        print ("Reading dem...")
        dem = pcr.readmap(masterdem)
        ldddem = dem

    try:
        catchmask = config.get("files", "catchment_mask")
    except:
        print("No catchment mask...")
    else:
        print("clipping DEM with mask.....")
        mask = pcr.readmap(catchmask)
        ldddem = pcr.ifthen(pcr.boolean(mask), ldddem)
        dem = pcr.ifthen(pcr.boolean(mask), dem)

    # See if there is a shape file of the river to burn in
    try:
        rivshp = config.get("files", "river")
    except:
        print("no river file specified")
        outletpointX = float(configget(config, "settings", "outflowpointX", "0.0"))
        outletpointY = float(configget(config, "settings", "outflowpointY", "0.0"))
    else:
        print("river file specified.....")
        try:
            outletpointX = float(configget(config, "settings", "outflowpointX", "0.0"))
            outletpointY = float(configget(config, "settings", "outflowpointY", "0.0"))
        except:
            print(
                "Need to specify the river outletpoint (a point at the end of the river within the current map)"
            )
            exit(1)

        outletpointmap = tr.points_to_map(dem, outletpointX, outletpointY, 0.5)
        pcr.report(outletpointmap, step1dir + "/outletpoint.map")
        # rivshpattr = config.get("files","riverattr")
        pcr.report(dem * 0.0, step1dir + "/nilmap.map")
        thestr = (
            "gdal_translate -of GTiff "
            + step1dir
            + "/nilmap.map "
            + step1dir
            + "/riverburn.tif"
        )
        os.system(thestr)
        rivshpattr = os.path.splitext(os.path.basename(rivshp))[0]
        os.system(
            "gdal_rasterize -burn 1 -l "
            + rivshpattr
            + " "
            + rivshp
            + " "
            + step1dir
            + "/riverburn.tif"
        )
        thestr = (
            "gdal_translate -of PCRaster "
            + step1dir
            + "/riverburn.tif "
            + step1dir
            + "/riverburn.map"
        )
        os.system(thestr)
        riverburn = pcr.readmap(step1dir + "/riverburn.map")
        # Determine regional slope assuming that is the way the river should run
        # Determine regional slope assuming that is the way the river should run
        # pcr.setglobaloption("unitcell")
        # demregional=pcr.windowaverage(dem,100)
        ldddem = pcr.ifthenelse(riverburn >= 1.0, dem - 1000, dem)

    pcr.setglobaloption("unittrue")
    upscalefactor = int(csize / pcr.celllength())

    print("Creating ldd...")
    ldd = tr.lddcreate_save(
        step1dir + "/ldd.map",
        ldddem,
        recreate,
        outflowdepth=outflowdepth,
        corevolume=corevolume,
        catchmentprecipitation=catchmentprecipitation,
        corearea=corearea,
    )

    print("Determining streamorder...")
    stro = pcr.streamorder(ldd)
    pcr.report(stro, step1dir + "/streamorder.map")
    strdir = pcr.ifthen(stro >= strRiver, stro)
    pcr.report(strdir, step1dir + "/streamorderrive.map")
    pcr.report(pcr.boolean(pcr.ifthen(stro >= strRiver, stro)), step1dir + "/rivers.map")

    pcr.setglobaloption("unittrue")
    # outlet (and other gauges if given)
    # TODO: check is x/y set if not skip this
    print("Outlet...")

    outlmap = tr.points_to_map(dem, X, Y, 0.5)

    if snapgaugestoriver:
        print("Snapping gauges to nearest river cells...")
        pcr.report(outlmap, step1dir + "/orggauges.map")
        outlmap = tr.snaptomap(outlmap, strdir)

    # noutletmap = tr.points_to_map(dem,XX,YY,0.5)
    # pcr.report(noutletmap,'noutlet.map')

    pcr.report(outlmap, step1dir + "/gauges.map")

    # check if there is a pre-define catchment map
    try:
        catchmask = config.get("files", "catchment_mask")
    except:
        print("No catchment mask, finding outlet")
        # Find catchment (overall)
        outlet = tr.find_outlet(ldd)
        sub = tr.subcatch(ldd, outlet)
        pcr.report(sub, step1dir + "/catchment_overall.map")
    else:
        print("reading and converting catchment mask.....")
        os.system(
            "resample -r "
            + str(initialscale)
            + " "
            + catchmask
            + " "
            + step1dir
            + "/catchment_overall.map"
        )
        sub = pcr.readmap(step1dir + "/catchment_overall.map")

    print("Scatch...")
    sd = tr.subcatch(ldd, pcr.ifthen(outlmap > 0, outlmap))
    pcr.report(sd, step1dir + "/scatch.map")

    pcr.setglobaloption("unitcell")
    print("Upscalefactor: " + str(upscalefactor))

    if upscalefactor > 1:
        gc.collect()
        print("upscale river length1 (checkerboard map)...")
        ck = tr.checkerboard(dem, upscalefactor)
        pcr.report(ck, step1dir + "/ck.map")
        pcr.report(dem, step1dir + "/demck.map")
        print("upscale river length2...")
        fact = tr.area_riverlength_factor(ldd, ck, upscalefactor)
        pcr.report(fact, step1dir + "/riverlength_fact.map")

        # print("make dem statistics...")
        dem_ = pcr.areaaverage(dem, ck)
        pcr.report(dem_, step1dir + "/demavg.map")

        print("Create DEM statistics...")
        dem_ = pcr.areaminimum(dem, ck)
        pcr.report(dem_, step1dir + "/demmin.map")
        dem_ = pcr.areamaximum(dem, ck)
        pcr.report(dem_, step1dir + "/demmax.map")
        # calculate percentiles
        order = pcr.areaorder(dem, ck)
        n = pcr.areatotal(pcr.spatial(pcr.scalar(1.0)), ck)
        #: calculate 25 percentile
        perc = tr.area_percentile(dem, ck, n, order, 25.0)
        pcr.report(perc, step1dir + "/dem25.map")
        perc = tr.area_percentile(dem, ck, n, order, 10.0)
        pcr.report(perc, step1dir + "/dem10.map")
        perc = tr.area_percentile(dem, ck, n, order, 50.0)
        pcr.report(perc, step1dir + "/dem50.map")
        perc = tr.area_percentile(dem, ck, n, order, 33.0)
        pcr.report(perc, step1dir + "/dem33.map")
        perc = tr.area_percentile(dem, ck, n, order, 66.0)
        pcr.report(perc, step1dir + "/dem66.map")
        perc = tr.area_percentile(dem, ck, n, order, 75.0)
        pcr.report(perc, step1dir + "/dem75.map")
        perc = tr.area_percentile(dem, ck, n, order, 90.0)
        pcr.report(perc, step1dir + "/dem90.map")
    else:
        print("No fancy scaling done. Going strait to step2....")
        pcr.report(dem, step1dir + "/demavg.map")
        Xul = float(config.get("settings", "Xul"))
        Yul = float(config.get("settings", "Yul"))
        Xlr = float(config.get("settings", "Xlr"))
        Ylr = float(config.get("settings", "Ylr"))
        gdalstr = (
            "gdal_translate  -projwin "
            + str(Xul)
            + " "
            + str(Yul)
            + " "
            + str(Xlr)
            + " "
            + str(Ylr)
            + " -of PCRaster  "
        )
        # gdalstr = "gdal_translate  -a_ullr " + str(Xul) + " " + str(Yul) + " " +str(Xlr) + " " +str(Ylr) + " -of PCRaster  "
        print(gdalstr)
        pcr.report(pcr.cover(1.0), step1dir + "/wflow_riverlength_fact.map")
        # Now us gdat tp convert the maps
        os.system(
            gdalstr
            + step1dir
            + "/wflow_riverlength_fact.map"
            + " "
            + step2dir
            + "/wflow_riverlength_fact.map"
        )
        os.system(
            gdalstr + step1dir + "/demavg.map" + " " + step2dir + "/wflow_dem.map"
        )
        os.system(
            gdalstr + step1dir + "/demavg.map" + " " + step2dir + "/wflow_demmin.map"
        )
        os.system(
            gdalstr + step1dir + "/demavg.map" + " " + step2dir + "/wflow_demmax.map"
        )
        os.system(
            gdalstr + step1dir + "/gauges.map" + " " + step2dir + "/wflow_gauges.map"
        )
        os.system(
            gdalstr + step1dir + "/rivers.map" + " " + step2dir + "/wflow_river.map"
        )
        os.system(
            gdalstr
            + step1dir
            + "/streamorder.map"
            + " "
            + step2dir
            + "/wflow_streamorder.map"
        )
        os.system(
            gdalstr + step1dir + "/gauges.map" + " " + step2dir + "/wflow_outlet.map"
        )
        os.system(
            gdalstr + step1dir + "/scatch.map" + " " + step2dir + "/wflow_catchment.map"
        )
        os.system(gdalstr + step1dir + "/ldd.map" + " " + step2dir + "/wflow_ldd.map")
        os.system(
            gdalstr + step1dir + "/scatch.map" + " " + step2dir + "/wflow_subcatch.map"
        )

        if lu_water:
            os.system(gdalstr + lu_water + " " + step2dir + "/WaterFrac.map")

        if lu_paved:
            os.system(gdalstr + lu_paved + " " + step2dir + "/PathFrac.map")

        try:
            lumap = config.get("files", "landuse")
        except:
            print("no landuse map...creating uniform map")
            # clone=pcr.readmap(step2dir + "/wflow_dem.map")
            pcr.setclone(step2dir + "/wflow_dem.map")
            pcr.report(pcr.nominal(1), step2dir + "/wflow_landuse.map")
        else:
            os.system(
                "resample --clone "
                + step2dir
                + "/wflow_dem.map "
                + lumap
                + " "
                + step2dir
                + "/wflow_landuse.map"
            )

        try:
            soilmap = config.get("files", "soil")
        except:
            print("no soil map..., creating uniform map")
            pcr.setclone(step2dir + "/wflow_dem.map")
            pcr.report(pcr.nominal(1), step2dir + "/wflow_soil.map")
        else:
            os.system(
                "resample --clone "
                + step2dir
                + "/wflow_dem.map "
                + soilmap
                + " "
                + step2dir
                + "/wflow_soil.map"
            )
yMin= -35.0
yMax= 37.5
sampleResolution= 0.5
resampleRatio= 1.
#-class to clip map during read
clippedRead= pcrPartialRead(xMin,xMax,yMin,yMax,sampleResolution,resampleRatio,clone)
cellAreaMap= os.path.join(mapsDir,'cellarea30.map')
cellArea= clippedRead.get(cellAreaMap,'scalar')
#-channel and floodplain characteristics
LDDMap= os.path.join(mapsDir,'lddsound_30min.map')	
LDD= pcr.lddrepair(clippedRead.get(LDDMap,'ldd'))	
channelGradient= clippedRead.get(os.path.join(mapsDir,'globalgradchannel.map'))
channelWidth= clippedRead.get(os.path.join(mapsDir,'channel_width.map'))
channelLength= clippedRead.get(os.path.join(mapsDir,'channel_length.map'))
channelDepth= clippedRead.get(os.path.join(mapsDir,'channel_depth.map'))
floodplainMask= pcr.spatial(pcr.boolean(1)) # NOTE: set to zero for static, to one for dynamic floodplains
channelManN= 0.04
floodplainManN= 0.10
#-flood plain parameterization
#-root of file name with maps of relative elvation above floodplain
# and associated fractions
relZFileName= 'elev%04d.map'
areaFractions=[0.0,0.01,0.05,0.10,0.20,0.30,0.40,\
  0.50,0.60,0.70,0.80,0.90,1.00]
# reduction parameter of smoothing interval and error threshold
reductionKK= 0.5
criterionKK= 40.
#-modelSignature
if pcr.cellvalue(pcr.mapmaximum(pcr.scalar(floodplainMask)),1)[0] == 1:
	modelSignature= forcingDataSet+'_dynamic-routing'
else:

# finding the month that give the maximum discharge (from the climatology time series)
msg = "Identifying the month with peak discharge (from climatology time series):"
logger.info(msg)	
# - read the maximum monthly discharge for every basin
maximum_discharge = vos.netcdf2PCRobjClone(input_files['maximumClimatologyDischargeMonthAvg'], \
                                           "discharge", 1,\
                                           useDoy = "Yes",
                                           cloneMapFileName  = clone_map_file,\
                                           LatitudeLongitude = True,\
                                           specificFillValue = None)
maximum_discharge = pcr.areamaximum(\
                  pcr.cover(maximum_discharge, 0.0), basin_map)
# - find the month with maximum discharge
maximum_month = pcr.spatial(pcr.scalar(1.0))
for i_month in range(1, 12 + 1):
    # read the climatology discharge time series
    discharge_for_this_month = vos.netcdf2PCRobjClone(input_files['climatologyDischargeMonthAvg'], \
                                                      "discharge", i_month,\
                                                      useDoy = "Yes",
                                                      cloneMapFileName  = clone_map_file,\
                                                      LatitudeLongitude = True,\
                                                      specificFillValue = None)
    # upscale it to the basin scale
    discharge_for_this_month = pcr.areamaximum(discharge_for_this_month, basin_map)
    maximum_month = pcr.ifthenelse(discharge_for_this_month == maximum_discharge, pcr.scalar(i_month), maximum_month)
pcr.report(maximum_month, "maximum_month.map")
    	
# defining the hydrological year type
msg = "Defining the type of hydrological year:"
    def report_summary(self, landWaterStoresAtBeginning, landWaterStoresAtEnd,\
                             surfaceWaterStoresAtBeginning, surfaceWaterStoresAtEnd):

        # set total to 0 on first day of the year                             
        if self._modelTime.doy == 1 or self._modelTime.isFirstTimestep():

            # set all accumulated variables to zero

            self.precipitationAcc  = pcr.ifthen(self.landmask, pcr.spatial(pcr.scalar(0.0))) 

            for var in self.landSurface.fluxVars: vars(self)[var+'Acc'] = pcr.ifthen(self.landmask, pcr.spatial(pcr.scalar(0.0)))            

            self.baseflowAcc                  = pcr.ifthen(self.landmask, pcr.spatial(pcr.scalar(0.0)))

            self.surfaceWaterInfAcc           = pcr.ifthen(self.landmask, pcr.spatial(pcr.scalar(0.0)))

            self.runoffAcc                    = pcr.ifthen(self.landmask, pcr.spatial(pcr.scalar(0.0)))
            self.unmetDemandAcc               = pcr.ifthen(self.landmask, pcr.spatial(pcr.scalar(0.0)))

            self.waterBalanceAcc              = pcr.ifthen(self.landmask, pcr.spatial(pcr.scalar(0.0)))
            self.absWaterBalanceAcc           = pcr.ifthen(self.landmask, pcr.spatial(pcr.scalar(0.0)))

            # non irrigation water use (unit: m) 
            self.nonIrrigationWaterUseAcc     = pcr.ifthen(self.landmask, pcr.spatial(pcr.scalar(0.0)))
            
            # non irrigation return flow to water body and water body evaporation (unit: m) 
            self.nonIrrReturnFlowAcc          = pcr.ifthen(self.landmask, pcr.spatial(pcr.scalar(0.0)))
            self.waterBodyEvaporationAcc      = pcr.ifthen(self.landmask, pcr.spatial(pcr.scalar(0.0)))

            # surface water input/loss volume (m3) and outgoing volume (m3) at pits 
            self.surfaceWaterInputAcc         = pcr.ifthen(self.landmask, pcr.spatial(pcr.scalar(0.0)))
            self.dischargeAtPitAcc            = pcr.ifthen(self.landmask, pcr.spatial(pcr.scalar(0.0)))
            
            # also save the storages at the first day of the year (or the first time step)
            # - land surface storage (unit: m)
            self.storageAtFirstDay            = pcr.ifthen(self.landmask, landWaterStoresAtBeginning)
            # - channel storages (unit: m3)
            self.channelVolumeAtFirstDay      = pcr.ifthen(self.landmask, surfaceWaterStoresAtBeginning)
            
        # accumulating until the last day of the year:
        self.precipitationAcc   += self.meteo.precipitation
        for var in self.landSurface.fluxVars: vars(self)[var+'Acc'] += vars(self.landSurface)[var]            

        self.baseflowAcc         += self.groundwater.baseflow

        self.surfaceWaterInfAcc  += self.groundwater.surfaceWaterInf
        
        self.runoffAcc           += self.routing.runoff
        self.unmetDemandAcc      += self.groundwater.unmetDemand

        self.waterBalance = \
          (landWaterStoresAtBeginning - landWaterStoresAtEnd +\
           self.meteo.precipitation + self.landSurface.irrGrossDemand + self.groundwater.surfaceWaterInf -\
           self.landSurface.actualET - self.routing.runoff - self.groundwater.nonFossilGroundwaterAbs)

        self.waterBalanceAcc    += self.waterBalance
        self.absWaterBalanceAcc += pcr.abs(self.waterBalance)

        # consumptive water use for non irrigation demand (m)
        self.nonIrrigationWaterUseAcc += self.routing.nonIrrWaterConsumption 
        
        self.waterBodyEvaporationAcc  += self.routing.waterBodyEvaporation

        self.surfaceWaterInputAcc     += self.routing.local_input_to_surface_water  # unit: m3
        self.dischargeAtPitAcc        += self.routing.outgoing_volume_at_pits       # unit: m3
        
        if self._modelTime.isLastDayOfYear() or self._modelTime.isLastTimeStep():
            
            logger.info("")
            msg = 'The following summary values do not include storages in surface water bodies (lake, reservoir and channel storages).'
            logger.info(msg)                        # TODO: Improve these water balance checks. 

            totalCellArea = vos.getMapTotal(pcr.ifthen(self.landmask, self.routing.cellArea))
            msg = 'Total area = %e km2'\
                    % (totalCellArea/1e6)
            logger.info(msg)

            deltaStorageOneYear = vos.getMapVolume( \
                                     pcr.ifthen(self.landmask,landWaterStoresAtBeginning) - \
                                     pcr.ifthen(self.landmask,self.storageAtFirstDay),
                                     self.routing.cellArea)
            msg = 'Delta total storage days 1 to %i in %i = %e km3 = %e mm'\
                % (    int(self._modelTime.doy),\
                       int(self._modelTime.year),\
                       deltaStorageOneYear/1e9,\
                       deltaStorageOneYear*1000/totalCellArea)
            logger.info(msg)

            variableList = ['precipitation',
                            'baseflow',
                            'surfaceWaterInf',
                            'runoff',
                            'unmetDemand']
            variableList += self.landSurface.fluxVars
            variableList += ['waterBalance','absWaterBalance','irrigationEvaporationWaterUse','nonIrrigationWaterUse']                

            # consumptive water use for irrigation (unit: m)
            self.irrigationEvaporationWaterUseAcc = vos.getValDivZero(self.irrGrossDemandAcc,\
                                                           self.precipitationAcc + self.irrGrossDemandAcc) * self.actualETAcc

            for var in variableList:
                volume = vos.getMapVolume(\
                            self.__getattribute__(var + 'Acc'),\
                            self.routing.cellArea)

                #~ # an eperiment: To test an improved version of map total - still need to be tested 
                #~ if var == "actSurfaceWaterAbstract" or var == "allocSurfaceWaterAbstract":
                    #~ volume = vos.getMapTotalHighPrecisionButOnlyForPositiveValues(self.__getattribute__(var + 'Acc') * self.routing.cellArea)

                msg = 'Accumulated %s days 1 to %i in %i = %e km3 = %e mm'\
                    % (var,int(self._modelTime.doy),\
                           int(self._modelTime.year),volume/1e9,volume*1000/totalCellArea)    # TODO: Calculation does not always start from day 1.
                logger.info(msg)

            logger.info("")
            msg = 'The following summary is for surface water bodies.'
            logger.info(msg) 

            deltaChannelStorageOneYear = vos.getMapTotal( \
                                         pcr.ifthen(self.landmask,surfaceWaterStoresAtEnd) - \
                                         pcr.ifthen(self.landmask,self.channelVolumeAtFirstDay))
            msg = 'Delta surface water storage days 1 to %i in %i = %e km3 = %e mm'\
                % (    int(self._modelTime.doy),\
                       int(self._modelTime.year),\
                       deltaChannelStorageOneYear/1e9,\
                       deltaChannelStorageOneYear*1000/totalCellArea)
            logger.info(msg)
            
            variableList = ['waterBodyEvaporation']
            for var in variableList:
                volume = vos.getMapVolume(\
                            self.__getattribute__(var + 'Acc'),\
                            self.routing.cellArea)
                msg = 'Accumulated %s days 1 to %i in %i = %e km3 = %e mm'\
                    % (var,int(self._modelTime.doy),\
                           int(self._modelTime.year),volume/1e9,volume*1000/totalCellArea)
                logger.info(msg)


            # surface water balance check 
            surfaceWaterInputTotal = vos.getMapTotal(self.surfaceWaterInputAcc)
            msg = 'Accumulated %s days 1 to %i in %i = %e km3 = %e mm'\
                    % ("surfaceWaterInput",int(self._modelTime.doy),\
                           int(self._modelTime.year),surfaceWaterInputTotal/1e9,surfaceWaterInputTotal*1000/totalCellArea)
            logger.info(msg)

            dischargeAtPitTotal = vos.getMapTotal(self.dischargeAtPitAcc)
            msg = 'Accumulated %s days 1 to %i in %i = %e km3 = %e mm'\
                    % ("dischargeAtPitTotal",int(self._modelTime.doy),\
                           int(self._modelTime.year),dischargeAtPitTotal/1e9,      dischargeAtPitTotal*1000/totalCellArea)
            logger.info(msg)

            surfaceWaterBalance = deltaChannelStorageOneYear - surfaceWaterInputTotal + dischargeAtPitTotal  
            msg = 'Accumulated %s days 1 to %i in %i = %e km3 = %e mm'\
                    % ("surfaceWaterBalance",int(self._modelTime.doy),\
                           int(self._modelTime.year),surfaceWaterBalance/1e9,      surfaceWaterBalance*1000/totalCellArea)
            logger.info(msg)
Exemple #17
0
def waterBalance(  fluxesIn,  fluxesOut,  deltaStorages,  processName,   PrintOnlyErrors,  dateStr,threshold=1e-5):
    """ Returns the water balance for a list of input, output, and storage map files and """

    inMap = pcr.spatial(pcr.scalar(0.0))
    dsMap = pcr.spatial(pcr.scalar(0.0))
    outMap = pcr.spatial(pcr.scalar(0.0))
    inflow = 0
    outflow = 0
    deltaS = 0
    for fluxIn in fluxesIn:
        inflow += getMapTotal(fluxIn)
        inMap += fluxIn
    for fluxOut in fluxesOut:
        outflow += getMapTotal(fluxOut)
        outMap += fluxOut
    for deltaStorage in deltaStorages:
        deltaS += getMapTotal(deltaStorage)
        dsMap += deltaStorage

    #if PrintOnlyErrors:
    a,b,c = getMinMaxMean(inMap + dsMap- outMap)
    # if abs(a) > 1e-5 or abs(b) > 1e-5:
    # if abs(a) > 1e-4 or abs(b) > 1e-4:
    if abs(a) > threshold or abs(b) > threshold:
        print "WBError %s Min %f Max %f Mean %f" %(processName,a,b,c)
    #    if abs(inflow + deltaS - outflow) > 1e-5:
    #        print "Water balance Error for %s on %s: in = %f\tout=%f\tdeltaS=%f\tBalance=%f" \
    #        %(processName,dateStr,inflow,outflow,deltaS,inflow + deltaS - outflow)
    #else:
    #   print "Water balance for %s: on %s in = %f\tout=%f\tdeltaS=%f\tBalance=%f" \
    #        %(processName,dateStr,inflow,outflow,deltaS,inflow + deltaS - outflow)

    wb = inMap + dsMap - outMap
    maxWBError = pcr.cellvalue(pcr.mapmaximum(pcr.abs(wb)), 1, 1)[0]

    #if maxWBError > 0.001 / 1000:
        #row = 0
        #col = 0
        #cellID = 1
        #troubleCell = 0

        #print "Water balance for %s on %s: %f mm !!! " %(processName,dateStr,maxWBError * 1000)
        #pcr.report(wb,"%s-WaterBalanceError-%s" %(processName,dateStr))

        #npWBMError = pcr2numpy(wb, -9999)
        #(nr, nc) = np.shape(npWBMError)
        #for r in range(0, nr):
            #for c in range(0, nc):

                ## print r,c

                #if npWBMError[r, c] != -9999.0:
                    #val = npWBMError[r, c]
                    #if math.fabs(val) > 0.0001 / 1000:

                        ## print npWBMError[r,c]

                        #row = r
                        #col = c
                        #troubleCell = cellID
                #cellID += 1
        #print 'Water balance for %s on %s: %f mm row %i col %i cellID %i!!! ' % (
            #processName,
            #dateStr,
            #maxWBError * 1000,
            #row,
            #col,
            #troubleCell,
            #)

    return inMap + dsMap - outMap
Exemple #18
0
    def modflow_simulation(self,\
                           simulation_type,\
                           initial_head,\
                           currTimeStep = None,\
                           PERLEN = 1.0, 
                           NSTP   = 1, \
                           HCLOSE = 1.0,\
                           RCLOSE = 10.* 400.*400.,\
                           MXITER = 50,\
                           ITERI = 30,\
                           NPCOND = 1,\
                           RELAX = 1.00,\
                           NBPOL = 2,\
                           DAMP = 1,\
                           ITMUNI = 4, LENUNI = 2, TSMULT = 1.0):
        
        # initiate pcraster modflow object if modflow is not called yet:
        if self.modflow_has_been_called == False or self.modflow_converged == False:
            self.initiate_modflow()
            self.modflow_has_been_called = True

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

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

        print "here"

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

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

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

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

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

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

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

    # output folder (and tmp folder)
    clean_out_folder = True
    if os.path.exists(out_folder):
        if clean_out_folder:
            shutil.rmtree(out_folder)
            os.makedirs(out_folder)
    else:
        os.makedirs(out_folder)
    os.chdir(out_folder)
    os.system("pwd")

    # set the clone map
    print("set the clone")
    pcr.setclone(global_ldd_30min_inp_file)

    # define the landmask
    print("define the landmask")
    # - based on the 30min input
    landmask_30min = define_landmask(input_file = global_landmask_30min_file,\
                                      clone_map_file = global_ldd_30min_inp_file,\
                                      output_map_file = "landmask_30min_only")
    # - based on the 05min input
    landmask_05min = define_landmask(input_file = global_landmask_05min_file,\
                                      clone_map_file = global_ldd_30min_inp_file,\
                                      output_map_file = "landmask_05min_only")
    # - based on the 30sec input
    landmask_30sec = define_landmask(input_file = global_landmask_30sec_file,\
                                      clone_map_file = global_ldd_30min_inp_file,\
                                      output_map_file = "landmask_30sec_only")
    # - based on the 30sec input
    landmask_03sec = define_landmask(input_file = global_landmask_03sec_file,\
                                      clone_map_file = global_ldd_30min_inp_file,\
                                      output_map_file = "landmask_03sec_only")
    #
    # - merge all landmasks
    landmask = pcr.cover(landmask_30min, landmask_05min, landmask_30sec,
                         landmask_03sec)
    pcr.report(landmask, "global_landmask_30min_final.map")
    # ~ pcr.aguila(landmask)

    # extend ldd
    print("extend/define the ldd")
    ldd_map = pcr.readmap(global_ldd_30min_inp_file)
    ldd_map = pcr.ifthen(landmask, pcr.cover(ldd_map, pcr.ldd(5)))
    pcr.report(ldd_map, "global_ldd_final.map")
    # ~ pcr.aguila(ldd_map)

    # identify small islands
    print("identify small islands")
    # - maps of islands smaller than 10000 cells (at half arc degree resolution)
    island_map = pcr.ifthen(landmask, pcr.clump(pcr.defined(ldd_map)))
    island_size = pcr.areatotal(pcr.spatial(pcr.scalar(1.0)), island_map)
    island_map = pcr.ifthen(island_size < 10000., island_map)

    UNTIL_THIS

    # identify the biggest island for every group of small islands within the windows 10x10 arcdeg cells

    # - sort from the largest catchment
    catchment_pits_boolean = pcr.ifthen(
        pcr.scalar(pcr.pit(ldd_map)) > 0.0, pcr.boolean(1.0))
    catchment_pits_boolean = pcr.ifthen(catchment_pits_boolean,
                                        catchment_pits_boolean)
    pcr.aguila(catchment_pits_boolean)
    catchment_map = pcr.nominal(
        pcr.areaorder(catchment_size * -1.0,
                      pcr.nominal(catchment_pits_boolean)))

    island_map = pcr.ifthen(island_size == pcr.windowmaximum(island_size, 10.),
                            island_map)
    pcr.aguila(island_map)

    # identify big catchments

    # merge biggest islands and big catchments

    # make catchment and island map
    print("make catchment and island map")

    # - catchment map
    catchment_map = pcr.catchment(ldd_map, pcr.pit(ldd_map))
    pcr.report(catchment_map, "global_catchment_not_sorted.map")
    os.system("mapattr -p global_catchment_not_sorted.map")
    num_of_catchments = int(vos.getMinMaxMean(pcr.scalar(catchment_map))[1])

    # - maps of islands smaller than 10000 cells
    island_map = pcr.ifthen(landmask, pcr.clump(pcr.defined(ldd_map)))
    island_size = pcr.areatotal(pcr.spatial(pcr.scalar(1.0)), island_map)
    island_map = pcr.ifthen(island_size < 10000., island_map)
    island_map = pcr.nominal(
        pcr.scalar(pcr.ifthen(landmask, pcr.clump(island_map))) +
        pcr.scalar(num_of_catchments) * 100.)
    pcr.aguila(island_map)

    island_size = pcr.ifthen(pcr.defined(island_map), island_size)

    island_map = pcr.ifthen(island_size == pcr.windowmaximum(island_size, 10.),
                            island_map)
    pcr.aguila(island_map)

    catchment_map = pcr.cover(island_map, catchment_map)
    catchment_size = pcr.areatotal(pcr.spatial(pcr.scalar(1.0)), catchment_map)

    # - calculate the size
    catchment_size = pcr.areatotal(pcr.spatial(pcr.scalar(1.0)), catchment_map)
    # - sort from the largest catchment
    catchment_pits_boolean = pcr.ifthen(
        pcr.scalar(pcr.pit(ldd_map)) > 0.0, pcr.boolean(1.0))
    catchment_pits_boolean = pcr.ifthen(catchment_pits_boolean,
                                        catchment_pits_boolean)
    pcr.aguila(catchment_pits_boolean)
    catchment_map = pcr.nominal(
        pcr.areaorder(catchment_size * -1.0,
                      pcr.nominal(catchment_pits_boolean)))
    catchment_map = pcr.catchment(ldd_map, catchment_map)
    pcr.report(catchment_map, "global_catchment_final.map")
    os.system("mapattr -p global_catchment_final.map")
    # - calculate the size
    catchment_size = pcr.areatotal(pcr.spatial(pcr.scalar(1.0)), catchment_map)
    pcr.report(catchment_size, "global_catchment_size_in_number_of_cells.map")

    # number of catchments
    num_of_catchments = int(vos.getMinMaxMean(pcr.scalar(catchment_map))[1])

    # size of the largest catchment
    catchment_size_max = vos.getMinMaxMean(catchment_size)[1]
    print("")
    print(str(float(catchment_size_max)))
    print("")

    # identify all large catchments with size >= 50 cells (at the resolution of 30 arcmin) = 50 x (50^2) km2 = 125000 km2
    print("identify catchments with the minimum size of 50 cells")
    catchment_map_ge_50 = pcr.ifthen(catchment_size >= 50, catchment_map)
    pcr.report(catchment_map_ge_50, "global_catchment_ge_50_cells.map")

    # include the island
    catchment_map_ge_50 = pcr.cover(island_map, catchment_map_ge_50)

    # perform cdo fillmiss2 in order to merge the small catchments to the nearest large catchments
    cmd = "gdal_translate -of NETCDF global_catchment_ge_50_cells.map global_catchment_ge_50_cells.nc"
    print(cmd)
    os.system(cmd)
    cmd = "cdo fillmiss2 global_catchment_ge_50_cells.nc global_catchment_ge_50_cells_filled.nc"
    print(cmd)
    os.system(cmd)
    cmd = "cdo fillmiss2 global_catchment_ge_50_cells_filled.nc global_catchment_ge_50_cells_filled.nc"
    print(cmd)
    os.system(cmd)
    cmd = "gdal_translate -of PCRaster global_catchment_ge_50_cells_filled.nc global_catchment_ge_50_cells_filled.map"
    print(cmd)
    os.system(cmd)
    cmd = "mapattr -c " + global_ldd_30min_inp_file + " " + "global_catchment_ge_50_cells_filled.map"
    print(cmd)
    os.system(cmd)
    # - initial subdomains
    subdomains_initial = pcr.nominal(
        pcr.readmap("global_catchment_ge_50_cells_filled.map"))
    subdomains_initial = pcr.areamajority(subdomains_initial, catchment_map)
    pcr.aguila(subdomains_initial)
    # - initial subdomains clump
    subdomains_initial_clump = pcr.clump(subdomains_initial)
    pcr.aguila(subdomains_initial_clump)

    print(str(int(vos.getMinMaxMean(pcr.scalar(subdomains_initial))[0])))
    print(str(int(vos.getMinMaxMean(pcr.scalar(subdomains_initial))[1])))

    print(str(int(vos.getMinMaxMean(pcr.scalar(subdomains_initial_clump))[0])))
    print(str(int(vos.getMinMaxMean(pcr.scalar(subdomains_initial_clump))[1])))

    # - remove temporay files (not used)
    cmd = "rm global_catchment_ge_50_cells_filled*"
    print(cmd)
    os.system(cmd)

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

mldd.setStream(
         # TODO Create overload which takes strings, or handle internally.
         pcraster.readmap(os.path.join(dataPath, "ELddF000.out")),
         pcraster.readmap(os.path.join(dataPath, "NELddF00.out")),
         pcraster.readmap(os.path.join(dataPath, "NLddF000.out")),
         pcraster.readmap(os.path.join(dataPath, "NWLddF00.out")),
         pcraster.readmap(os.path.join(dataPath, "SELddF00.out")),
         pcraster.readmap(os.path.join(dataPath, "SLddF000.out")),
         pcraster.readmap(os.path.join(dataPath, "SWLddF00.out")),
         pcraster.readmap(os.path.join(dataPath, "WLddF000.out")))
mldd.addStream(
         pcraster.readmap(os.path.join(dataPath, "ELddF000.out")))
mldd.setDem(pcraster.spatial(pcraster.scalar(1)))


upstream = mldd.upstream(pcraster.spatial(pcraster.scalar(1)))
pcraster.report(upstream, "upstream.map")

accuflux = mldd.accuflux(pcraster.ifthen(pcraster.defined(upstream),
         pcraster.spatial(pcraster.scalar(1))))
pcraster.report(accuflux, "accuflux.map")

dem = mldd.getDem()
pcraster.report(dem, "dem.map")

streamN, streamNE, streamE, streamSE, streamS, streamSW, streamW, streamNW = \
         mldd.getStream()
Exemple #22
0
    def read_forcings(self, currTimeStep):

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        # TODO: Please also consider endorheic lakes!

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        # cropping only in the landmask region:
        self.fracWat = pcr.ifthen(self.landmask, self.fracWat)
        self.waterBodyIds = pcr.ifthen(self.landmask, self.waterBodyIds)
        self.waterBodyOut = pcr.ifthen(self.landmask, self.waterBodyOut)
        self.waterBodyArea = pcr.ifthen(self.landmask, self.waterBodyArea)
        self.waterBodyTyp = pcr.ifthen(self.landmask, self.waterBodyTyp)
        self.waterBodyCap = pcr.ifthen(self.landmask, self.waterBodyCap)
Exemple #24
0
#~ pcr.aguila(basin_area)

# finding the month that give the maximum discharge (from the climatology time series)
msg = "Identifying the month with peak discharge (from climatology time series):"
logger.info(msg)
# - read the maximum monthly discharge for every basin
maximum_discharge = vos.netcdf2PCRobjClone(input_files['maximumClimatologyDischargeMonthAvg'], \
                                           "discharge", 1,\
                                           useDoy = "Yes",
                                           cloneMapFileName  = clone_map_file,\
                                           LatitudeLongitude = True,\
                                           specificFillValue = None)
maximum_discharge = pcr.areamaximum(\
                  pcr.cover(maximum_discharge, 0.0), basin_map)
# - find the month with maximum discharge
maximum_month = pcr.spatial(pcr.scalar(1.0))
for i_month in range(1, 12 + 1):
    # read the climatology discharge time series
    discharge_for_this_month = vos.netcdf2PCRobjClone(input_files['climatologyDischargeMonthAvg'], \
                                                      "discharge", i_month,\
                                                      useDoy = "Yes",
                                                      cloneMapFileName  = clone_map_file,\
                                                      LatitudeLongitude = True,\
                                                      specificFillValue = None)
    # upscale it to the basin scale
    discharge_for_this_month = pcr.areamaximum(discharge_for_this_month,
                                               basin_map)
    maximum_month = pcr.ifthenelse(
        discharge_for_this_month == maximum_discharge, pcr.scalar(i_month),
        maximum_month)
pcr.report(maximum_month, "maximum_month.map")
Exemple #25
0
pcraster.setclone(os.path.join(dataPath, "ELddF000.out"))

mldd = pcraster.mldd.initialise(pcraster.clone())

mldd.setStream(
    # TODO Create overload which takes strings, or handle internally.
    pcraster.readmap(os.path.join(dataPath, "ELddF000.out")),
    pcraster.readmap(os.path.join(dataPath, "NELddF00.out")),
    pcraster.readmap(os.path.join(dataPath, "NLddF000.out")),
    pcraster.readmap(os.path.join(dataPath, "NWLddF00.out")),
    pcraster.readmap(os.path.join(dataPath, "SELddF00.out")),
    pcraster.readmap(os.path.join(dataPath, "SLddF000.out")),
    pcraster.readmap(os.path.join(dataPath, "SWLddF00.out")),
    pcraster.readmap(os.path.join(dataPath, "WLddF000.out")))
mldd.addStream(pcraster.readmap(os.path.join(dataPath, "ELddF000.out")))
mldd.setDem(pcraster.spatial(pcraster.scalar(1)))

upstream = mldd.upstream(pcraster.spatial(pcraster.scalar(1)))
pcraster.report(upstream, "upstream.map")

accuflux = mldd.accuflux(
    pcraster.ifthen(pcraster.defined(upstream),
                    pcraster.spatial(pcraster.scalar(1))))
pcraster.report(accuflux, "accuflux.map")

dem = mldd.getDem()
pcraster.report(dem, "dem.map")

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

    """

        if not isinstance(tssFilename, str):
            raise Exception(
                "timeseries output filename must be of type string")

        self._outputFilename = tssFilename
        self._maxId = 1
        self._spatialId = None
        self._spatialDatatype = None
        self._spatialIdGiven = False
        self._userModel = model
        self._writeHeader = not noHeader
        # array to store the timestep values
        self._sampleValues = None

        _idMap = False
        if isinstance(idMap, str) or isinstance(idMap,
                                                pcraster._pcraster.Field):
            _idMap = True

        nrRows = self._userModel.nrTimeSteps() - self._userModel.firstTimeStep(
        ) + 1

        if _idMap:
            self._spatialId = idMap
            if isinstance(idMap, str):
                self._spatialId = pcraster.readmap(idMap)

            _allowdDataTypes = [
                pcraster.Nominal, pcraster.Ordinal, pcraster.Boolean
            ]
            if self._spatialId.dataType() not in _allowdDataTypes:
                raise Exception(
                    "idMap must be of type Nominal, Ordinal or Boolean")

            if self._spatialId.isSpatial():
                self._maxId, valid = pcraster.cellvalue(
                    pcraster.mapmaximum(pcraster.ordinal(self._spatialId)), 1)
            else:
                self._maxId = 1

            # cell indices of the sample locations
            self._sampleAddresses = []
            for cellId in range(1, self._maxId + 1):
                self._sampleAddresses.append(self._getIndex(cellId))

            self._spatialIdGiven = True
            nrCols = self._maxId
            self._sampleValues = [[Decimal("NaN")] * nrCols
                                  for _ in [0] * nrRows]
        else:
            self._sampleValues = [[Decimal("NaN")] * 1 for _ in [0] * nrRows]

    def _getIndex(self, cellId):
        """
    returns the cell index of a sample location
    """
        nrCells = pcraster.clone().nrRows() * pcraster.clone().nrCols()
        found = False
        cell = 1
        index = 0

        while found == False:
            if pcraster.cellvalue(self._spatialId,
                                  cell)[1] == True and pcraster.cellvalue(
                                      self._spatialId, cell)[0] == cellId:
                index = cell
                found = True
            cell += 1
            if cell > nrCells:
                raise RuntimeError(
                    "could not find a cell with the index number %d" %
                    (cellId))

        return index

    def sample(self, expression):
        """
    Sampling the current values of 'expression' at the given locations for the current timestep
    """

        arrayRowPos = self._userModel.currentTimeStep(
        ) - self._userModel.firstTimeStep()

        #if isinstance(expression, float):
        #  expression = pcraster.scalar(expression)

        try:
            # store the data type for tss file header
            if self._spatialDatatype == None:
                self._spatialDatatype = str(expression.dataType())
        except AttributeError, e:
            datatype, sep, tail = str(e).partition(" ")
            msg = "Argument must be a PCRaster map, type %s given. If necessary use data conversion functions like scalar()" % (
                datatype)
            raise AttributeError(msg)

        if self._spatialIdGiven:
            if expression.dataType() == pcraster.Scalar or expression.dataType(
            ) == pcraster.Directional:
                tmp = pcraster.areaaverage(pcraster.spatial(expression),
                                           pcraster.spatial(self._spatialId))
            else:
                tmp = pcraster.areamajority(pcraster.spatial(expression),
                                            pcraster.spatial(self._spatialId))

            col = 0
            for cellIndex in self._sampleAddresses:
                value, valid = pcraster.cellvalue(tmp, cellIndex)
                if not valid:
                    value = Decimal("NaN")

                self._sampleValues[arrayRowPos][col] = value
                col += 1
        else:
            if expression.dataType() == pcraster.Scalar or expression.dataType(
            ) == pcraster.Directional:
                tmp = pcraster.maptotal(pcraster.spatial(expression))\
                      / pcraster.maptotal(pcraster.scalar(pcraster.defined(pcraster.spatial(expression))))
            else:
                tmp = pcraster.mapmaximum(pcraster.maptotal(pcraster.areamajority(pcraster.spatial(expression),\
                      pcraster.spatial(pcraster.nominal(1)))))

            value, valid = pcraster.cellvalue(tmp, 1)
            if not valid:
                value = Decimal("NaN")

            self._sampleValues[arrayRowPos] = value

        if self._userModel.currentTimeStep() == self._userModel.nrTimeSteps():
            self._writeTssFile()
Exemple #28
0
def waterBalance(  fluxesIn,  fluxesOut,  deltaStorages,  processName,   PrintOnlyErrors,  dateStr,threshold=1e-5):
    """ Returns the water balance for a list of input, output, and storage map files and """

    inMap = pcr.spatial(pcr.scalar(0.0))
    dsMap = pcr.spatial(pcr.scalar(0.0))
    outMap = pcr.spatial(pcr.scalar(0.0))
    inflow = 0
    outflow = 0
    deltaS = 0
    for fluxIn in fluxesIn:
        inflow += getMapTotal(fluxIn)
        inMap += fluxIn
    for fluxOut in fluxesOut:
        outflow += getMapTotal(fluxOut)
        outMap += fluxOut
    for deltaStorage in deltaStorages:
        deltaS += getMapTotal(deltaStorage)
        dsMap += deltaStorage

    #if PrintOnlyErrors:
    a,b,c = getMinMaxMean(inMap + dsMap- outMap)
    # if abs(a) > 1e-5 or abs(b) > 1e-5:
    # if abs(a) > 1e-4 or abs(b) > 1e-4:
    if abs(a) > threshold or abs(b) > threshold:
        print "WBError %s Min %f Max %f Mean %f" %(processName,a,b,c)
    #    if abs(inflow + deltaS - outflow) > 1e-5:
    #        print "Water balance Error for %s on %s: in = %f\tout=%f\tdeltaS=%f\tBalance=%f" \
    #        %(processName,dateStr,inflow,outflow,deltaS,inflow + deltaS - outflow)
    #else:
    #   print "Water balance for %s: on %s in = %f\tout=%f\tdeltaS=%f\tBalance=%f" \
    #        %(processName,dateStr,inflow,outflow,deltaS,inflow + deltaS - outflow)

    wb = inMap + dsMap - outMap
    maxWBError = pcr.cellvalue(pcr.mapmaximum(pcr.abs(wb)), 1, 1)[0]

    #if maxWBError > 0.001 / 1000:
        #row = 0
        #col = 0
        #cellID = 1
        #troubleCell = 0

        #print "Water balance for %s on %s: %f mm !!! " %(processName,dateStr,maxWBError * 1000)
        #pcr.report(wb,"%s-WaterBalanceError-%s" %(processName,dateStr))

        #npWBMError = pcr2numpy(wb, -9999)
        #(nr, nc) = np.shape(npWBMError)
        #for r in range(0, nr):
            #for c in range(0, nc):

                ## print r,c

                #if npWBMError[r, c] != -9999.0:
                    #val = npWBMError[r, c]
                    #if math.fabs(val) > 0.0001 / 1000:

                        ## print npWBMError[r,c]

                        #row = r
                        #col = c
                        #troubleCell = cellID
                #cellID += 1
        #print 'Water balance for %s on %s: %f mm row %i col %i cellID %i!!! ' % (
            #processName,
            #dateStr,
            #maxWBError * 1000,
            #row,
            #col,
            #troubleCell,
            #)

    return inMap + dsMap - outMap
Exemple #29
0
mldd = pcraster.mldd.initialise(pcraster.clone())

mldd.setStream(
    # TODO Create overload which takes strings, or handle internally.
    pcraster.readmap(os.path.join(dataPath, "ELddF000.out")),
    pcraster.readmap(os.path.join(dataPath, "NELddF00.out")),
    pcraster.readmap(os.path.join(dataPath, "NLddF000.out")),
    pcraster.readmap(os.path.join(dataPath, "NWLddF00.out")),
    pcraster.readmap(os.path.join(dataPath, "SELddF00.out")),
    pcraster.readmap(os.path.join(dataPath, "SLddF000.out")),
    pcraster.readmap(os.path.join(dataPath, "SWLddF00.out")),
    pcraster.readmap(os.path.join(dataPath, "WLddF000.out")),
)
mldd.addStream(pcraster.readmap(os.path.join(dataPath, "ELddF000.out")))
mldd.setDem(pcraster.spatial(pcraster.scalar(1)))


upstream = mldd.upstream(pcraster.spatial(pcraster.scalar(1)))
pcraster.report(upstream, "upstream.map")

accuflux = mldd.accuflux(pcraster.ifthen(pcraster.defined(upstream), pcraster.spatial(pcraster.scalar(1))))
pcraster.report(accuflux, "accuflux.map")

dem = mldd.getDem()
pcraster.report(dem, "dem.map")

streamN, streamNE, streamE, streamSE, streamS, streamSW, streamW, streamNW = mldd.getStream()

pcraster.report(streamN, "streamN.map")
pcraster.report(streamNE, "streamNE.map")
    def modflow_simulation(self,\
                           simulation_type,\
                           initial_head_layer_1, initial_head_layer_2,\
                           currTimeStep = None,\
                           NSTP   = 1, \
                           HCLOSE = 0.5,\
                           RCLOSE = 100.* 400.*400.,\
                           MXITER = 300,\
                           ITERI = 100,\
                           NPCOND = 1,\
                           RELAX = 1.00,\
                           NBPOL = 2,\
                           DAMP = 1,\
                           ITMUNI = 4, LENUNI = 2, PERLEN = 1.0, TSMULT = 1.0):
        # initiate pcraster modflow object
        self.initiate_modflow()

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

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

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

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

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

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

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

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

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

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

        # calculate groundwater depth only in the landmask region
        self.groundwaterDepth = pcr.ifthen(
            self.landmask, self.dem_average - self.groundwaterHeadLayer2)
Exemple #31
0
    def read_forcings(self, currTimeStep):

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    # Default values
    strRiver = 8
    masterdem = "dem.map"
    step1dir = "step1"
    step2dir = "step2"
    workdir = "."
    inifile = "wflow_prepare.ini"
    recreate = False
    snapgaugestoriver = False

    try:
        opts, args = getopt.getopt(sys.argv[1:], "W:hI:f")
    except getopt.error as msg:
        usage(msg)

    for o, a in opts:
        if o == "-W":
            workdir = a
        if o == "-I":
            inifile = a
        if o == "-h":
            usage()
        if o == "-f":
            recreate = True

    pcr.setglobaloption("unitcell")
    os.chdir(workdir)

    config = OpenConf(workdir + "/" + inifile)

    masterdem = configget(config, "files", "masterdem", "dem.map")
    pcr.setclone(masterdem)

    strRiver = int(configget(config, "settings", "riverorder", "4"))

    try:
        gauges_x = config.get("settings", "gauges_x")
        gauges_y = config.get("settings", "gauges_y")
    except:
        print("gauges_x and  gauges_y are required entries in the ini file")
        sys.exit(1)

    step1dir = configget(config, "directories", "step1dir", "step1")
    step2dir = configget(config, "directories", "step2dir", "step2")
    # upscalefactor = float(config.get("settings","upscalefactor"))

    corevolume = float(configget(config, "settings", "corevolume", "1E35"))
    catchmentprecipitation = float(
        configget(config, "settings", "catchmentprecipitation", "1E35"))
    corearea = float(configget(config, "settings", "corearea", "1E35"))
    outflowdepth = float(
        configget(config, "settings", "lddoutflowdepth", "1E35"))

    initialscale = int(configget(config, "settings", "initialscale", "1"))
    csize = float(configget(config, "settings", "cellsize", "1"))

    snapgaugestoriver = bool(
        int(configget(config, "settings", "snapgaugestoriver", "1")))
    lddglobaloption = configget(config, "settings", "lddglobaloption",
                                "lddout")
    pcr.setglobaloption(lddglobaloption)
    lu_water = configget(config, "files", "lu_water", "")
    lu_paved = configget(config, "files", "lu_paved", "")

    # X/Y coordinates of the gauges the system
    exec("X=tr.array(" + gauges_x + ")")
    exec("Y=tr.array(" + gauges_y + ")")

    tr.Verbose = 1

    # make the directories to save results in
    mkoutputdirs(step1dir, step2dir)

    ldddem = readdem(initialscale, masterdem, step1dir)
    dem = ldddem

    try:
        catchmask = config.get("files", "catchment_mask")
    except:
        print("No catchment mask...")
    else:
        print("clipping DEM with mask.....")
        mask = pcr.readmap(catchmask)
        ldddem = pcr.ifthen(pcr.boolean(mask), ldddem)
        dem = pcr.ifthen(pcr.boolean(mask), dem)

    # See if there is a shape file of the river to burn in
    try:
        rivshp = config.get("files", "river")
    except:
        print("no river file specified")
        outletpointX = float(
            configget(config, "settings", "outflowpointX", "0.0"))
        outletpointY = float(
            configget(config, "settings", "outflowpointY", "0.0"))
    else:
        print("river file specified.....")
        try:
            outletpointX = float(
                configget(config, "settings", "outflowpointX", "0.0"))
            outletpointY = float(
                configget(config, "settings", "outflowpointY", "0.0"))
        except:
            print(
                "Need to specify the river outletpoint (a point at the end of the river within the current map)"
            )
            exit(1)

        outletpointmap = tr.points_to_map(dem, outletpointX, outletpointY, 0.5)
        pcr.report(outletpointmap, step1dir + "/outletpoint.map")
        rivshpattr = config.get("files", "riverattr")
        pcr.report(dem * 0.0, step1dir + "/nilmap.map")
        thestr = ("gdal_translate -of GTiff " + step1dir + "/nilmap.map " +
                  step1dir + "/riverburn.tif")
        os.system(thestr)
        os.system("gdal_rasterize -burn 1 -l " + rivshpattr + " " + rivshp +
                  " " + step1dir + "/riverburn.tif")
        thestr = ("gdal_translate -of PCRaster " + step1dir +
                  "/riverburn.tif " + step1dir + "/riverburn.map")
        os.system(thestr)
        riverburn = pcr.readmap(step1dir + "/riverburn.map")
        # Determine regional slope assuming that is the way the river should run
        pcr.setglobaloption("unitcell")
        demregional = pcr.windowaverage(dem, 100)
        ldddem = pcr.ifthenelse(riverburn >= 1.0, demregional - 1000, dem)

    pcr.setglobaloption("unittrue")
    upscalefactor = int(csize / pcr.celllength())

    print("Creating ldd...")
    ldd = tr.lddcreate_save(
        step1dir + "/ldd.map",
        ldddem,
        recreate,
        outflowdepth=outflowdepth,
        corevolume=corevolume,
        catchmentprecipitation=catchmentprecipitation,
        corearea=corearea,
    )

    print("Determining streamorder...")
    stro = pcr.streamorder(ldd)
    pcr.report(stro, step1dir + "/streamorder.map")
    strdir = pcr.ifthen(stro >= strRiver, stro)
    pcr.report(strdir, step1dir + "/streamorderrive.map")
    pcr.report(pcr.boolean(pcr.ifthen(stro >= strRiver, stro)),
               step1dir + "/rivers.map")

    pcr.setglobaloption("unittrue")
    # outlet (and other gauges if given)
    # TODO: check is x/y set if not skip this
    print("Outlet...")

    outlmap = tr.points_to_map(dem, X, Y, 0.5)

    if snapgaugestoriver:
        print("Snapping gauges to nearest river cells...")
        pcr.report(outlmap, step1dir + "/orggauges.map")
        outlmap = tr.snaptomap(outlmap, strdir)

    # noutletmap = tr.points_to_map(dem,XX,YY,0.5)
    # pcr.report(noutletmap,'noutlet.map')

    pcr.report(outlmap, step1dir + "/gauges.map")

    # check if there is a pre-define catchment map
    try:
        catchmask = config.get("files", "catchment_mask")
    except:
        print("No catchment mask, finding outlet")
        # Find catchment (overall)
        outlet = tr.find_outlet(ldd)
        sub = pcr.subcatch(ldd, outlet)
        pcr.report(sub, step1dir + "/catchment_overall.map")
    else:
        print("reading and converting catchment mask.....")
        os.system("resample -r " + str(initialscale) + " " + catchmask + " " +
                  step1dir + "/catchment_overall.map")
        sub = pcr.readmap(step1dir + "/catchment_overall.map")

    print("Scatch...")
    sd = pcr.subcatch(ldd, pcr.ifthen(outlmap > 0, outlmap))
    pcr.report(sd, step1dir + "/scatch.map")

    pcr.setglobaloption("unitcell")
    print("Upscalefactor: " + str(upscalefactor))

    if upscalefactor > 1:
        gc.collect()
        print("upscale river length1 (checkerboard map)...")
        ck = tr.checkerboard(dem, upscalefactor)
        pcr.report(ck, step1dir + "/ck.map")
        pcr.report(dem, step1dir + "/demck.map")
        print("upscale river length2...")
        fact = tr.area_riverlength_factor(ldd, ck, upscalefactor)
        pcr.report(fact, step1dir + "/riverlength_fact.map")

        # print("make dem statistics...")
        dem_ = pcr.areaaverage(dem, ck)
        pcr.report(dem_, step1dir + "/demavg.map")

        print("Create DEM statistics...")
        dem_ = pcr.areaminimum(dem, ck)
        pcr.report(dem_, step1dir + "/demmin.map")
        dem_ = pcr.areamaximum(dem, ck)
        pcr.report(dem_, step1dir + "/demmax.map")
        # calculate percentiles
        order = pcr.areaorder(dem, ck)
        n = pcr.areatotal(pcr.spatial(pcr.scalar(1.0)), ck)
        #: calculate 25 percentile
        perc = tr.area_percentile(dem, ck, n, order, 25.0)
        pcr.report(perc, step1dir + "/dem25.map")
        perc = tr.area_percentile(dem, ck, n, order, 10.0)
        pcr.report(perc, step1dir + "/dem10.map")
        perc = tr.area_percentile(dem, ck, n, order, 50.0)
        pcr.report(perc, step1dir + "/dem50.map")
        perc = tr.area_percentile(dem, ck, n, order, 33.0)
        pcr.report(perc, step1dir + "/dem33.map")
        perc = tr.area_percentile(dem, ck, n, order, 66.0)
        pcr.report(perc, step1dir + "/dem66.map")
        perc = tr.area_percentile(dem, ck, n, order, 75.0)
        pcr.report(perc, step1dir + "/dem75.map")
        perc = tr.area_percentile(dem, ck, n, order, 90.0)
        pcr.report(perc, step1dir + "/dem90.map")
    else:
        print("No fancy scaling done. Going strait to step2....")
        pcr.report(dem, step1dir + "/demavg.map")
        Xul = float(config.get("settings", "Xul"))
        Yul = float(config.get("settings", "Yul"))
        Xlr = float(config.get("settings", "Xlr"))
        Ylr = float(config.get("settings", "Ylr"))
        gdalstr = ("gdal_translate  -projwin " + str(Xul) + " " + str(Yul) +
                   " " + str(Xlr) + " " + str(Ylr) + " -of PCRaster  ")
        # gdalstr = "gdal_translate  -a_ullr " + str(Xul) + " " + str(Yul) + " " +str(Xlr) + " " +str(Ylr) + " -of PCRaster  "
        print(gdalstr)
        pcr.report(pcr.cover(1.0), step1dir + "/wflow_riverlength_fact.map")
        # Now us gdat tp convert the maps
        os.system(gdalstr + step1dir + "/wflow_riverlength_fact.map" + " " +
                  step2dir + "/wflow_riverlength_fact.map")
        os.system(gdalstr + step1dir + "/demavg.map" + " " + step2dir +
                  "/wflow_dem.map")
        os.system(gdalstr + step1dir + "/demavg.map" + " " + step2dir +
                  "/wflow_demmin.map")
        os.system(gdalstr + step1dir + "/demavg.map" + " " + step2dir +
                  "/wflow_demmax.map")
        os.system(gdalstr + step1dir + "/gauges.map" + " " + step2dir +
                  "/wflow_gauges.map")
        os.system(gdalstr + step1dir + "/rivers.map" + " " + step2dir +
                  "/wflow_river.map")
        os.system(gdalstr + step1dir + "/streamorder.map" + " " + step2dir +
                  "/wflow_streamorder.map")
        os.system(gdalstr + step1dir + "/gauges.map" + " " + step2dir +
                  "/wflow_outlet.map")
        os.system(gdalstr + step1dir + "/scatch.map" + " " + step2dir +
                  "/wflow_catchment.map")
        os.system(gdalstr + step1dir + "/ldd.map" + " " + step2dir +
                  "/wflow_ldd.map")
        os.system(gdalstr + step1dir + "/scatch.map" + " " + step2dir +
                  "/wflow_subcatch.map")

        if lu_water:
            os.system(gdalstr + lu_water + " " + step2dir + "/WaterFrac.map")

        if lu_paved:
            os.system(gdalstr + lu_paved + " " + step2dir + "/PathFrac.map")

        try:
            lumap = config.get("files", "landuse")
        except:
            print("no landuse map...creating uniform map")
            # clone=pcr.readmap(step2dir + "/wflow_dem.map")
            pcr.setclone(step2dir + "/wflow_dem.map")
            pcr.report(pcr.nominal(1), step2dir + "/wflow_landuse.map")
        else:
            os.system("resample --clone " + step2dir + "/wflow_dem.map " +
                      lumap + " " + step2dir + "/wflow_landuse.map")

        try:
            soilmap = config.get("files", "soil")
        except:
            print("no soil map..., creating uniform map")
            pcr.setclone(step2dir + "/wflow_dem.map")
            pcr.report(pcr.nominal(1), step2dir + "/wflow_soil.map")
        else:
            os.system("resample --clone " + step2dir + "/wflow_dem.map " +
                      soilmap + " " + step2dir + "/wflow_soil.map")

    ##################################
    # Step 2 starts here
    ##################################

    pcr.setclone(step2dir + "/cutout.map")

    strRiver = int(configget(config, "settings", "riverorder_step2", "4"))

    corevolume = float(configget(config, "settings", "corevolume", "1E35"))
    catchmentprecipitation = float(
        configget(config, "settings", "catchmentprecipitation", "1E35"))
    corearea = float(configget(config, "settings", "corearea", "1E35"))
    outflowdepth = float(
        configget(config, "settings", "lddoutflowdepth", "1E35"))
    lddmethod = configget(config, "settings", "lddmethod", "dem")
    lddglobaloption = configget(config, "settings", "lddglobaloption",
                                "lddout")
    pcr.setglobaloption(lddglobaloption)

    nrrow = round(abs(Yul - Ylr) / csize)
    nrcol = round(abs(Xlr - Xul) / csize)
    mapstr = ("mapattr -s -S -R " + str(nrrow) + " -C " + str(nrcol) + " -l " +
              str(csize) + " -x " + str(Xul) + " -y " + str(Yul) +
              " -P yb2t " + step2dir + "/cutout.map")

    os.system(mapstr)
    pcr.setclone(step2dir + "/cutout.map")

    lu_water = configget(config, "files", "lu_water", "")
    lu_paved = configget(config, "files", "lu_paved", "")

    if lu_water:
        os.system("resample --clone " + step2dir + "/cutout.map " + lu_water +
                  " " + step2dir + "/wflow_waterfrac.map")

    if lu_paved:
        os.system("resample --clone " + step2dir + "/cutout.map " + lu_paved +
                  " " + step2dir + "/PathFrac.map")

    #
    try:
        lumap = config.get("files", "landuse")
    except:
        print("no landuse map...creating uniform map")
        clone = pcr.readmap(step2dir + "/cutout.map")
        pcr.report(pcr.nominal(clone), step2dir + "/wflow_landuse.map")
    else:
        os.system("resample --clone " + step2dir + "/cutout.map " + lumap +
                  " " + step2dir + "/wflow_landuse.map")

    try:
        soilmap = config.get("files", "soil")
    except:
        print("no soil map..., creating uniform map")
        clone = pcr.readmap(step2dir + "/cutout.map")
        pcr.report(pcr.nominal(clone), step2dir + "/wflow_soil.map")
    else:
        os.system("resample --clone " + step2dir + "/cutout.map " + soilmap +
                  " " + step2dir + "/wflow_soil.map")

    resamplemaps(step1dir, step2dir)

    dem = pcr.readmap(step2dir + "/wflow_dem.map")
    demmin = pcr.readmap(step2dir + "/wflow_demmin.map")
    demmax = pcr.readmap(step2dir + "/wflow_demmax.map")
    catchcut = pcr.readmap(step2dir + "/catchment_cut.map")
    # now apply the area of interest (catchcut) to the DEM
    # dem=pcr.ifthen(catchcut >=1 , dem)
    #

    # See if there is a shape file of the river to burn in
    try:
        rivshp = config.get("files", "river")
    except:
        print("no river file specified")
        riverburn = pcr.readmap(step2dir + "/wflow_riverburnin.map")
    else:
        print("river file speficied.....")
        rivshpattr = config.get("files", "riverattr")
        pcr.report(dem * 0.0, step2dir + "/nilmap.map")
        thestr = ("gdal_translate -of GTiff " + step2dir + "/nilmap.map " +
                  step2dir + "/wflow_riverburnin.tif")
        os.system(thestr)
        os.system("gdal_rasterize -burn 1 -l " + rivshpattr + " " + rivshp +
                  " " + step2dir + "/wflow_riverburnin.tif")
        thestr = ("gdal_translate -of PCRaster " + step2dir +
                  "/wflow_riverburnin.tif " + step2dir +
                  "/wflow_riverburnin.map")
        os.system(thestr)
        riverburn = pcr.readmap(step2dir + "/wflow_riverburnin.map")
        # ldddem = pcr.ifthenelse(riverburn >= 1.0, dem -1000 , dem)

    # Only burn within the original catchment
    riverburn = pcr.ifthen(pcr.scalar(catchcut) >= 1, riverburn)
    # Now setup a very high wall around the catchment that is scale
    # based on the distance to the catchment so that it slopes away from the
    # catchment
    if lddmethod != "river":
        print("Burning in highres-river ...")
        disttocatch = pcr.spread(pcr.nominal(catchcut), 0.0, 1.0)
        demmax = pcr.ifthenelse(
            pcr.scalar(catchcut) >= 1.0,
            demmax,
            demmax + (pcr.celllength() * 100.0) / disttocatch,
        )
        pcr.setglobaloption("unitcell")
        demregional = pcr.windowaverage(demmin, 100)
        demburn = pcr.cover(
            pcr.ifthen(pcr.boolean(riverburn), demregional - 100.0), demmax)
    else:
        print("using average dem..")
        demburn = dem

    ldd = tr.lddcreate_save(
        step2dir + "/ldd.map",
        demburn,
        True,
        outflowdepth=outflowdepth,
        corevolume=corevolume,
        catchmentprecipitation=catchmentprecipitation,
        corearea=corearea,
    )

    # Find catchment (overall)
    outlet = tr.find_outlet(ldd)
    sub = pcr.subcatch(ldd, outlet)
    pcr.report(sub, step2dir + "/wflow_catchment.map")
    pcr.report(outlet, step2dir + "/wflow_outlet.map")

    # make river map
    strorder = pcr.streamorder(ldd)
    pcr.report(strorder, step2dir + "/wflow_streamorder.map")

    river = pcr.ifthen(pcr.boolean(strorder >= strRiver), strorder)
    pcr.report(river, step2dir + "/wflow_river.map")

    # make subcatchments
    # os.system("col2map --clone " + step2dir + "/cutout.map gauges.col " + step2dir + "/wflow_gauges.map")
    exec("X=tr.array(" + gauges_x + ")")
    exec("Y=tr.array(" + gauges_y + ")")

    pcr.setglobaloption("unittrue")

    outlmap = tr.points_to_map(dem, X, Y, 0.5)
    pcr.report(outlmap, step2dir + "/wflow_gauges_.map")

    if snapgaugestoriver:
        print("Snapping gauges to river")
        pcr.report(outlmap, step2dir + "/wflow_orggauges.map")
        outlmap = tr.snaptomap(outlmap, river)

    outlmap = pcr.ifthen(outlmap > 0, outlmap)
    pcr.report(outlmap, step2dir + "/wflow_gauges.map")

    scatch = pcr.subcatch(ldd, outlmap)
    pcr.report(scatch, step2dir + "/wflow_subcatch.map")
Exemple #33
0
    def initial(self):

        # make sure that you start from the script directory
        os.chdir(self.script_directory)

        # In this part (premcloop), we initiate parameters/variables/objects that are changing throughout all monte carlo samples.

        msg = "\n"
        msg += "Sample number: " + str(self.currentSampleNumber())
        msg += "\n"
        print(msg)

        # conductivities for the BCF package, see: http://pcraster.geo.uu.nl/pcraster/4.1.0/doc/modflow/bcf.html
        inp_soil_conductivity = self.model_setup['soil_conductivity'][
            int(str(self.currentSampleNumber())) - 1]
        self.soil_conductivity = pcr.spatial(pcr.scalar(inp_soil_conductivity))

        #
        # - horizontal and vertical conductivity
        self.hConductivity = self.soil_conductivity
        self.vConductivity = self.hConductivity
        # - for one layer model, vConductivity is just dummy and never used
        # - layer type, we use LAYTYPE = 0 (harmonic mean) and LAYCON = 0 (confined, constant transmissivities and storage coefficients)

        # storage coefficients for the BCF package, see: http://pcraster.geo.uu.nl/pcraster/4.1.0/doc/modflow/bcf.html
        # - sand porosity (m3.m-3)                                                                                         # TODO: Find the value from Sebastian paper.
        self.sand_porosity = pcr.spatial(pcr.scalar(0.25))
        #
        # - primary and secondary storage coefficients
        self.primary_storage_coefficient = self.sand_porosity
        self.secondary_storage_coefficient = self.primary_storage_coefficient
        # - for LAYCON = 0 (and 1), secondary_storage_coefficient is just dummy and never used

        # The following are CURRENTLY just the same for all samples.
        ############################################################################

        # defining the layer (one layer model), thickness (m), top and bottom elevations
        self.thickness = 15.0
        # - thickness value is suggested by Kim Cohen (put reference here)
        self.top_elevation = self.input_dem
        self.bottom_elevation = self.top_elevation - self.thickness

        # DIS parameters, see http://pcraster.geo.uu.nl/pcraster/4.1.0/doc/modflow/dis.html
        #  - time and spatial units
        self.ITMUNI = 4  # indicating that the time unit is "days"
        self.LENUNI = 2  # indicating that the spatial unit is "meters"
        # - PERLEN: duration of stress period (days)
        # -- 10 minute stress period = 600 seconds stress period
        self.length_of_stress_period = 600. / (24. * 60. * 60.)
        self.PERLEN = self.length_of_stress_period
        # - NSTP: number of sub time steps within the PERLEN
        self.NSTP = 1
        # - TSMULT # always 1 by default
        self.TSMULT = 1
        # - SSTR: transient (0) or steady state (1)
        self.SSTR = 0

        # values for the IBOND of the BAS package, see: http://pcraster.geo.uu.nl/pcraster/4.1.0/doc/modflow/bas.html
        # - Alternative 1: all cells are active
        self.ibound = pcr.spatial(pcr.nominal(1.))
        #~ # - Alternative 2: in the ocean region (x < -75 m), assume the heads will follow the tides
        #~ self.ibound = pcr.ifthenelse(pcr.xcoordinate(clone_map) < -75., pcr.nominal(-1.), pcr.nominal(1.))
        #~ pcr.aguila(self.ibound)

        # ibound with regional groundwater head values
        if self.model_setup['regional_groundwater_head']['activation']:
            self.ibound = pcr.ifthenelse(
                pcr.xcoordinate(pcr.boolean(1.0)) >=
                self.model_setup['regional_groundwater_head']['starting_x'],
                pcr.nominal(-1.), self.ibound)

        # parameter values for the SOLVER package
        self.MXITER = 50  # maximum number of outer iterations           # Deltares use 50
        self.ITERI = 30  # number of inner iterations                   # Deltares use 30
        self.NPCOND = 1  # 1 - Modified Incomplete Cholesky, 2 - Polynomial matrix conditioning method
        self.HCLOSE = 0.001  # HCLOSE (unit: m)
        self.RCLOSE = 0.001  # RCLOSE (unit: m3)
        self.RELAX = 1.00  # relaxation parameter used with NPCOND = 1
        self.NBPOL = 2  # indicates whether the estimate of the upper bound on the maximum eigenvalue is 2.0 (but we don ot use it, since NPCOND = 1)
        self.DAMP = 1  # no damping (DAMP introduced in MODFLOW 2000)

        # the initial head for the BAS package, see: http://pcraster.geo.uu.nl/pcraster/4.1.0/doc/modflow/bas.html
        # - Gerben recommends to start using 0.8 m
        self.initial_head = pcr.spatial(pcr.scalar(0.8))

        # regional groundwater head
        if self.model_setup['regional_groundwater_head']['activation']:
            self.initial_head = pcr.ifthenelse(
                pcr.xcoordinate(pcr.boolean(1.0)) >=
                self.model_setup['regional_groundwater_head']['starting_x'],
                self.model_setup['regional_groundwater_head']['value'],
                self.initial_head)

        # initialise timeoutput object for reporting time series in txt files
        # - groundwater head
        self.head_obs_point = pcr.readmap(
            "input_files/groundwater_well_coordinates.map")
        self.reportGwHeadTss = TimeoutputTimeseries("groundwater_head",
                                                    self,
                                                    self.head_obs_point,
                                                    noHeader=False)

        # Save model parameter values (and other information) to a txt file.
        # - output directory (that will contain result)
        output_directory = self.output_folder + "/" + str(
            self.currentSampleNumber())
        try:
            os.makedirs(output_directory)
        except:
            pass
        # - file name for this information
        information_file = output_directory + "/" + "info.txt"
        file_info = open(information_file, 'w')
        write_line = ""
        # - DEM
        write_line += "DEM (m): " + str(self.model_setup['dem_file_name'])
        write_line += "\n"
        # - tide
        write_line += "Tide input file name: " + str(
            self.model_setup['tide_file_name'])
        write_line += "\n"
        # - starting date
        write_line += "Starting date and time: " + str(
            self.model_setup['start_datetime'])
        write_line += "\n"
        # - soil conductivity
        write_line += "Soil conductivity (m.day-1): " + str(
            inp_soil_conductivity)
        write_line += "\n"
        # - regional groundwater head (optional):
        if self.model_setup['regional_groundwater_head']['activation']:
            write_line += "Regional groundwater head is fixed to : " + str(
                self.model_setup['regional_groundwater_head']['value'])
            write_line += "\n"
            write_line += "for all cells in  with x coordinate >=: " + str(
                self.model_setup['regional_groundwater_head']['starting_x'])
            write_line += "\n"
        else:
            write_line += "NO regional groundwater head. "
            write_line += "\n"
        # - sample number
        write_line += "PCRaster sample number: " + str(
            self.currentSampleNumber())
        write_line += "\n"
        file_info.write(write_line)
        # - close the file
        file_info.close()

        # initiate netcdf files for groundwater head
        netcdf_variable_name = "groundwater_head"
        self.netcdf_file_name = self.output_folder + "/" + str(
            self.currentSampleNumber()) + "/" + netcdf_variable_name + ".nc"
        self.model_setup['netcdf_attributes']['notes'] = write_line
        self.netcdf_writer.create_netcdf_file(
            self.netcdf_file_name, self.model_setup['netcdf_attributes'])
        # - create variable
        netcdf_variable_unit = "m"
        self.netcdf_writer.create_variable(self.netcdf_file_name,
                                           netcdf_variable_name,
                                           netcdf_variable_unit)