示例#1
0
def calculate(params,mask,isocode,isogrid):
    '''
    Allocation of fertilizer on the basis of agricultural landarea grid. The new map of agricultural land in km2 is returned as well
    as the N and P fertilizer.
    '''

    # Read region codes (regcodes)
    reggrid = ascraster.Asciigrid(ascii_file=params.fileregion,mask=mask,numtype=int)  

    # Make a list of isocodes for the provinces.
    regcode = list(set(reggrid.values))      

    # Read P fertilizer per region, missing regions are set to zero.
    Pfert_reg = data_class.get_data(params.filePfertuse,year=params.year,sep=params.sep,isocode=regcode,method=0,weighing=0.0)    
    print_debug("Pfert_reg",Pfert_reg)

    # Read N fertilizer per region, missing regions are set to zero.
    Nfert_reg = data_class.get_data(params.fileNfertuse,year=params.year,sep=params.sep,isocode=regcode,method=0,weighing=0.0)    
    print_debug("Nfert_reg",Nfert_reg)

    # Read agricultural land per province, missing provinces are set to zero.
    agri_area_table = data_class.get_data(params.filefertarea,year=params.year,sep=params.sep,isocode=isocode,method=0,weighing=0.0)    
    print_debug("agri_area_table",agri_area_table)

    # Read the basic map with the amount of agricultural land in km2 per grid cell
    agriland = ascraster.Asciigrid(ascii_file=params.fileagrilandarea,mask=mask,numtype=float)  

    # Read the basic map with the amount of land in km2 per grid cell
    arealand = ascraster.Asciigrid(ascii_file=params.landarea,mask=mask,numtype=float)  

    # Create two output grids with zeros and fill these with the ranking method.
    agri_area = ascraster.duplicategrid(agriland)
    agri_area.add_values(agri_area.length * [0.0])    
    Pfert = ascraster.duplicategrid(agri_area)
    Nfert = ascraster.duplicategrid(agri_area)

    # Make a dictionairy of pointers for all the isocodes in the grid.
    pointer_dict = {}
    for icell in xrange(isogrid.length):
        iso = isogrid.get_data(icell)
        if (iso != None):
            iso = int(iso)
            try:
                pointer_dict[iso].append(icell)
            except KeyError:
                pointer_dict[iso] = [icell]

    for key in isocode:
        # Select agricultural land of the key country
        # First step is to allocate the agricultural area for each province.
        weight_key = []
        qmax_key = []
        try:
            pointer1 = pointer_dict[key]
        except KeyError:
            pointer1 = []
        sumqmax = 0.0
        sumweight = 0.0
        for icell in pointer1:
            area = agriland.get_data(icell,0.0)
            maxarea = arealand.get_data(icell,0.0)
            # Fill weighing data and max data
            qmax_key.append(maxarea)
            weight_key.append(area)
            sumqmax += qmax_key[-1]
            sumweight += weight_key[-1]

        if (sumweight < 0.0001):
            # Make uniform weighing to all cells.
            for icell in range(len(weight_key)):
                weight_key[icell] =  1
                sumweight += weight_key[icell]

        # Take the table information on agricultural area.
        area_demand = agri_area_table[key]
        if (area_demand > sumqmax):
            raise MyError("It is not possible to allocate " + str(area_demand) + " km2 in provincenumber " + str(key),\
                          "Maximum area that is possible to allocate in this province is: "+str(sumqmax))
        # Do the allocation
        area_new = allocweighing.allocweighing(area_demand,sumweight,weight_key,qmax_key)

        if (abs(sum(area_new) - agri_area_table[key]) > 0.001*agri_area_table[key]):
            print "***** There is not enough allocated for agri_area for region "+str(key)+". Difference: " + str(agri_area_table[key]-sum(area_new))
            print "***** Needed for agri_area for region "+str(key)+" " + str(agri_area_table[key])

        # Fill gridded result
        for item in xrange(len(area_new)):
            agri_area.set_data(pointer1[item],area_new[item])

    # Now the fertilizer is allocated to the gridcells, based on agricultural land area. This means that
    # each grid cell will have another load  but the same application rate (kg N/ha)
    pointer_dict = {}
    for icell in xrange(reggrid.length):
        iso = reggrid.get_data(icell)
        if (iso != None):
            iso = int(iso)
            try:
                pointer_dict[iso].append(icell)
            except KeyError:
                pointer_dict[iso] = [icell]

    for key in regcode:
        weight_key = []
        qmax_key = []
        try:
            pointer1 = pointer_dict[key]
        except KeyError:
            pointer1 = []
        sumqmax = 0.0
        sumweight = 0.0
        for icell in pointer1:
            # Note the new map of the previous step is used here.
            area = agri_area.get_data(icell,0.0)
            maxarea = 10000000.
            # Fill weighing data and max data
            qmax_key.append(maxarea)
            weight_key.append(area)
            sumqmax += qmax_key[-1]
            sumweight += weight_key[-1]

        if (sumweight < 0.0001):
            # Make uniform weighing to all cells.
            for icell in range(len(weight_key)):
                weight_key[icell] =  1
                sumweight += weight_key[icell]

        # Grid these country connected population data with help of the population density map
        fert_demand = Nfert_reg[key]
        fert_new = allocweighing.allocweighing(fert_demand,sumweight,weight_key,qmax_key)

        if (abs(sum(fert_new) - Nfert_reg[key]) > 0.001*Nfert_reg[key]):
            print "***** There is not enough allocated for Nfert_reg for region "+str(key)+". Difference: " + str(Nfert_reg[key]-sum(fert_new))
            print "***** Needed for Nfert_reg for region "+str(key)+" " + str(Nfert_reg[key])

        # Fill gridded result
        for item in xrange(len(fert_new)):
            Nfert.set_data(pointer1[item],fert_new[item])

    for key in regcode:
        weight_key = []
        qmax_key = []
        try:
            pointer1 = pointer_dict[key]
        except KeyError:
            pointer1 = []
        sumqmax = 0.0
        sumweight = 0.0
        for icell in pointer1:
            # Note the new map of the previous step is used here.
            area = agri_area.get_data(icell,0.0)
            maxarea = 10000000.
            # Fill weighing data and max data
            qmax_key.append(maxarea)
            weight_key.append(area)
            sumqmax += qmax_key[-1]
            sumweight += weight_key[-1]

        if (sumweight < 0.0001):
            # Make uniform weighing to all cells.
            for icell in range(len(weight_key)):
                weight_key[icell] =  1
                sumweight += weight_key[icell]

        # Grid these country connected population data with help of the population density map
        fert_demand = Pfert_reg[key]
        # Change fertilizer from P2O5 to P
        fert_demand *= 62.0/142.0
        fert_new = allocweighing.allocweighing(fert_demand,sumweight,weight_key,qmax_key)

        if (abs(sum(fert_new) - Pfert_reg[key]* 62.0/142.0) > 0.001*Pfert_reg[key]* 62.0/142.0):
            print "***** There is not enough allocated for Pfert_reg for region "+str(key)+". Difference: " + str(Pfert_reg[key]* (62.0/142.0)-sum(fert_new))
            print "***** Needed for Pfert_reg for region "+str(key)+" " + str(Pfert_reg[key])

        # Fill gridded result
        for item in xrange(len(fert_new)):
            Pfert.set_data(pointer1[item],fert_new[item])

    # Write to output file
    agri_area.write_ascii_file(params.fileagri_area)
    Nfert.write_ascii_file(params.fileNfert)
    Pfert.write_ascii_file(params.filePfert)

    total = sum(agri_area.values)
    print "Total agricultural area in km2: ",total
    print "Total N fertilzer in kg N: ",sum(Nfert.values)
    print "Total P fertilizer in kg P: ",sum(Pfert.values)
    print "Total N fertilzer in kg N/ha: ",sum(Nfert.values)/(100*total)
    print "Total P fertilizer in kg P/ha: ",sum(Pfert.values)/(100*total)

    return agri_area,Nfert,Pfert
示例#2
0
def read_popnum(params,mask,isogrid,isocode):
    '''
    Read population numbers from grid or from table.
    If it is given on a table then a weighing grid is needed to allocate the population on the grid.
    Table and grid is returned.
    '''
 
    # Scale the population of timescen so that the
    # total population of the region is correct.
    PopNum = data_class.get_data(params.filePopNum,year=params.year,sep=params.sep)
        
    # PopNum is given in thousand people. So we have to multiply by 1000
    for key in PopNum:
        PopNum[key] *= 1000

    # Add isocodes when they are not in list isocode
    for key in PopNum:
        try:
            qq=isocode.index(key)
        except ValueError:
            # Isocode found which is not taken into account
            print "ISOCODE " + str(key) +" is not used for number of people: " + str(PopNum[key]) + " people are missed." 
            PopNum[key] = 0.0

    # Add popnum for missing isocodes. Population is zero
    for key in isocode:
        try:
            qq=PopNum[key]
        except KeyError:
            # New iso code found.
            PopNum[key] = 0.0

    print "Number of people read : " + str(sum(PopNum.itervalues())) + " is found." 
    print_debug("PopNum in read_popnum",PopNum)
            
    # Read population number grid which is used to scale the table population numbers information
    popgrid_scale = ascraster.Asciigrid(ascii_file=params.filePopNumgrid,mask=mask,numtype=float)

    # Read land area
    landarea = ascraster.Asciigrid(ascii_file=params.landarea,mask=mask,numtype=float)

    # Make new population number grid zero
    popgrid = ascraster.duplicategrid(popgrid_scale)
    popgrid.add_values(popgrid.length * [0.0])

    # Make a dictionary of pointers for all the isocodes in the grid.
    pointer_dict = {}
    for icell in xrange(isogrid.length):
        iso = isogrid.get_data(icell)
        if (iso != None):
            iso = int(iso)
            try:
                pointer_dict[iso].append(icell)
            except KeyError:
                pointer_dict[iso] = [icell]

    for key in isocode:
        if (PopNum[key] <= 0.):
            print "WEIGHING: table population is ZERO in region: " + str(key)
            continue
        # Select population of the key country
        weight_key = []
        qmax_key = []
        try:
            pointer1 = pointer_dict[key]
        except KeyError:
            print "Key: " + str(key) + " is not found in the isogrid."
            print "Table information of population numbers is changed for region: " + str(int(key)) +\
                  " from " + str(PopNum[key]) + " to 0.0"
            continue
        sumqmax = 0.0
        sumweight = 0.0
        for icell in pointer1:
            pop = popgrid_scale.get_data(icell,0.0)
            # Fill weighing data and max data
            qmax_key.append(params.max_popdens * landarea.get_data(icell,0.0))
            weight_key.append(pop)
            sumqmax += qmax_key[-1]
            sumweight += weight_key[-1]
   
        # Warn for possible errors
        if (sumweight <= 0.):
            print "WEIGHING: grid population is ZERO in region: " + str(key)
            if (len(weight_key) > 0):
                # There are cells on the grid for this region. So make a uniform distribution
                weight_key = len(weight_key) * [1.0]
                sumweight = sum(weight_key)

        if (sumqmax < PopNum[key]):
            print "WEIGHING: PopNum ",PopNum[key], " is bounded by sumqmax",sumqmax, " in region: " + str(key)

        # Grid these country population data with help of the popgrid_scale map
        PopNum_reg = PopNum[key]
        popnum_new = allocweighing.allocweighing(PopNum_reg,sumweight,weight_key,qmax_key)      
            
        if (key == debug_code):
            sum1 = 0.0
            for item in xrange(len(popnum_new)):       
                sum1 += popnum_new[item]
            print "New population number: ",sum1

        # Fill gridded result
        sum1 = 0.0
        for item in xrange(len(popnum_new)):
            popgrid.set_data(pointer1[item],popnum_new[item])
            sum1 += popnum_new[item]

        # Check whether the table information has landed in the popgrid
        if (math.fabs(sum1 - PopNum[key]) > 0.01):
            print "Table information of population numbers is changed for region: " + str(int(key)) +\
                  " from " + str(PopNum[key]) + " to " + str(sum1)

    print "Total number of people: " + str(sum(PopNum.itervalues())) + " is found." 
 
    return PopNum,popgrid
示例#3
0
          str(qReg_exp))
if (ltest1 == 1):
    print("Test3 passed.")
else:
    print("Allocation ranking method 3")
    print(qReg)
    print(qReg_exp)

# Testing allocweighing
print("Start allocation weighing method testing.")
# Test 1
sq = 100.
wReg = [1., 1., 2., 6]
sw = sum(wReg)
qmaxReg = [100., 100., 100., 100.]
qReg = allocweighing.allocweighing(sq, sw, wReg, qmaxReg)
qReg_exp = [10.0, 10.0, 20.0, 60.0]
ltest1 = 1
if (qReg != qReg_exp):
    ltest1 = 0
    print("Test 1 is not a succes. Values found: " + str(qReg) + " and " +
          str(qReg_exp))
if (ltest1 == 1):
    print("Test1 passed.")
else:
    print("Allocation weighing method")
    print(qReg)
    print(qReg_exp)

# Test 2
sq = 100.
def calculate(params, mask, isocode, isogrid, agri_area):
    """
    Allocation of manure on the basis of agricultural landarea grid. The N and P manure map is returned.
    """

    # Read heads per province. Here no interpolation is done. So the exact year must be specified.
    animals = general_class.read_general_file(params.fileanimal_heads, sep=";", key=None, out_type="list")

    # Read N and P excretion. File must contain the header Species;N_excretion;P_excretion
    excretion = general_class.read_general_file(params.fileanimal_excretion, sep=";", key="Species", out_type="dict")

    # Calculate the total N and P manure per province for each line in the animals input file
    Nmanure = {}
    Pmanure = {}
    for item in range(len(animals)):
        # Get the number of heads for the year specified.
        head = animals[item].get_val(str(params.year))
        spec = animals[item].get_val("Species")
        try:
            # Get the N and P excretion for this animal
            Nexcret = excretion[spec].get_val("N_excretion")
            Pexcret = excretion[spec].get_val("P_excretion")
        except KeyError:
            raise MyError("This animal " + spec + " has no excretion rate in file: " + params.fileanimal_excretion)
        # Multiply heads with excretion
        animals[item].add_item("Nmanure", float(Nexcret) * float(head))
        animals[item].add_item("Pmanure", float(Pexcret) * float(head))

        # Calculate total manure per province
        iso = int(animals[item].get_val("ISO-code"))
        try:
            Nmanure[iso] += animals[item].get_val("Nmanure")
            Pmanure[iso] += animals[item].get_val("Pmanure")
        except KeyError:
            Nmanure[iso] = animals[item].get_val("Nmanure")
            Pmanure[iso] = animals[item].get_val("Pmanure")

    # Create two output grids with zeros and fill these with the weighing method.
    Nmanure_grid = ascraster.duplicategrid(agri_area)
    Nmanure_grid.add_values(Nmanure_grid.length * [0.0])
    Pmanure_grid = ascraster.duplicategrid(Nmanure_grid)

    # Make a dictionairy of pointers for all the isocodes in the grid.
    pointer_dict = {}
    for icell in xrange(isogrid.length):
        iso = isogrid.get_data(icell)
        if iso != None:
            iso = int(iso)
            try:
                pointer_dict[iso].append(icell)
            except KeyError:
                pointer_dict[iso] = [icell]

    for key in isocode:
        # Select agricultural land of the key country
        # First step is to allocate the Nmanure
        weight_key = []
        qmax_key = []
        try:
            pointer1 = pointer_dict[key]
        except KeyError:
            pointer1 = []
        sumqmax = 0.0
        sumweight = 0.0
        for icell in pointer1:
            area = agri_area.get_data(icell, 0.0)
            maxarea = 10000000000
            # Fill weighing data and max data
            qmax_key.append(maxarea)
            weight_key.append(area)
            sumqmax += qmax_key[-1]
            sumweight += weight_key[-1]

        if sumweight < 0.0001:
            # Make uniform weighing to all cells.
            for icell in range(len(weight_key)):
                weight_key[icell] = 1
                sumweight += weight_key[icell]

        # Take the table information on agricultural area.
        man_demand = Nmanure[key]
        # Do the allocation
        man_new = allocweighing.allocweighing(man_demand, sumweight, weight_key, qmax_key)

        if abs(sum(man_new) - Nmanure[key]) > 0.001 * Nmanure[key]:
            print "***** There is not enough allocated for Nmanure for region " + str(key) + ". Difference: " + str(
                Nmanure[key] - sum(man_new)
            )

        # Fill gridded result
        for item in xrange(len(man_new)):
            Nmanure_grid.set_data(pointer1[item], man_new[item])

    for key in isocode:
        # Select agricultural land of the key country
        # Second step is to allocate the Pmanure
        weight_key = []
        qmax_key = []
        try:
            pointer1 = pointer_dict[key]
        except KeyError:
            pointer1 = []
        sumqmax = 0.0
        sumweight = 0.0
        for icell in pointer1:
            area = agri_area.get_data(icell, 0.0)
            maxarea = 10000000000
            # Fill weighing data and max data
            qmax_key.append(maxarea)
            weight_key.append(area)
            sumqmax += qmax_key[-1]
            sumweight += weight_key[-1]

        if sumweight < 0.0001:
            # Make uniform weighing to all cells.
            for icell in range(len(weight_key)):
                weight_key[icell] = 1
                sumweight += weight_key[icell]

        # Take the table information on agricultural area.
        man_demand = Pmanure[key]
        # Do the allocation
        man_new = allocweighing.allocweighing(man_demand, sumweight, weight_key, qmax_key)

        if abs(sum(man_new) - Pmanure[key]) > 0.001 * Pmanure[key]:
            print "***** There is not enough allocated for Pmanure for region " + str(key) + ". Difference: " + str(
                Pmanure[key] - sum(man_new)
            )

        # Fill gridded result
        for item in xrange(len(man_new)):
            Pmanure_grid.set_data(pointer1[item], man_new[item])

    # Write to output file
    Nmanure_grid.write_ascii_file(params.fileNmanure)
    Pmanure_grid.write_ascii_file(params.filePmanure)

    total = sum(agri_area.values)
    print "Total N manure in kg N: ", sum(Nmanure_grid.values)
    print "Total P manure in kg P: ", sum(Pmanure_grid.values)
    print "Total N manure in kg N/ha: ", sum(Nmanure_grid.values) / (100 * total)
    print "Total P manure in kg P/ha: ", sum(Pmanure_grid.values) / (100 * total)

    fp = open(os.path.join(params.outputdir, "manure.csv"), "w")
    lheader = True
    for item in range(len(animals)):
        animals[item].write(fp, sep=";", lheader=lheader, NoneValue="")
        lheader = False
    fp.close()

    return Nmanure_grid, Pmanure_grid
def calculate(params,mask,production,environ=None,substance=None):
    '''
    Allocation of aquaculture on the basis of river length.
    BF=brackish fishponds, FF=freshwater fishponds, MF=marine water fishponds, BC=brackish cages, 
    FC=freshwater cages, MC=marine water cages, BP=brackish pens, 
    FP=freshwater pens, MP=marine water pens 
    '''
    lbrakish = False
    lfresh = False
    lmarine = False
    lcage = False
    lponds = False
    lpens = False

    try:
        if (environ[0] == "B"):
            lbrakish = True
        elif(environ[0] == "F"):
            lfresh = True
        elif(environ[0] == "M"):
            lmarine = True
        else:
            raise MyError("Something wrong with the environment in allocation_aquaculture.",\
                          "Must start with B, F or M. Found: ", environ[0])
        if (environ[1] == "C"):
            lcage = True
        elif(environ[1] == "F"):
            lponds = True
        elif(environ[1] == "P"):
            lpens = True
        else:
            raise MyError("Something wrong with the environment in allocation_aquaculture.",\
                          "Must end with C, F or P. Found: ", environ[1])
          
    except:
        raise MyError("Something wrong with the environment in allocation_aquaculture")

    if (lmarine):
        # Read province id's of the marine cells and the weighing map.
        isogrid = ascraster.Asciigrid(ascii_file=params.fileprov_marine,mask=None,numtype=int)
        weighgrid = ascraster.Asciigrid(ascii_file=params.fileweigh_marine,mask=None,numtype=float)
    else:
        # Read province codes (isocodes)
        isogrid = ascraster.Asciigrid(ascii_file=params.fileiso,mask=mask,numtype=int)

        if (lponds ):
            # Read the ponds file with the weighing factors.
            weighgrid = ascraster.Asciigrid(ascii_file=params.filepondarea,mask=mask,numtype=float)
        elif (lcage or lpens):
            # Read the riverlength file with the weighing factors.
            weighgrid = ascraster.Asciigrid(ascii_file=params.fileriverlength,mask=mask,numtype=float)

        # Read the coastal cells.
        coastgrid = ascraster.Asciigrid(ascii_file=params.filecoast,mask=mask,numtype=int)        
        if (lfresh):
            # Exclude the coastal cells in the weighgrid
            for icell in range(weighgrid.length):
                coastval = coastgrid.get_data(icell,-1)
                if (coastval > 0.): 
                    weighgrid.set_data(icell,0.0)
        elif (lbrakish):
            # Allocate only on the coastal cells.
            for icell in range(weighgrid.length):
                coastval = coastgrid.get_data(icell,-1)
                if (coastval < 0.00001): 
                    weighgrid.set_data(icell,0.0)
        else:
            raise MyError("Something wrong with setting up weighing in allocation_aquaculture")

    total_substance ={}
    for item in range(len(production)):
        # Calculate total aquaculture per province
        if (production[item].get_val("Environment").strip() == environ):
            iso  = int(production[item].get_val("ISO-code"))
            try:
                total_substance[iso] += production[item].get_val(substance+"out")
            except KeyError:
                total_substance[iso] = production[item].get_val(substance+"out")

    # Create two output grids with zeros and fill these with the weighing method.
    out_grid = ascraster.duplicategrid(isogrid)
    out_grid.add_values(out_grid.length * [0.0])    
    
    # Make a dictionary of pointers for all the isocodes in the grid.
    pointer_dict = {}
    for icell in xrange(isogrid.length):
        iso = isogrid.get_data(icell)
        if (iso != None):
            iso = int(iso)
            try:
                pointer_dict[iso].append(icell)
            except KeyError:
                pointer_dict[iso] = [icell]

    for key in pointer_dict:
        try:
            # Take the total information.
            required_amount = total_substance[key]
        except KeyError:
            continue
        # Make everything ready for this region to allocate the stuff.
        weight_key = []
        qmax_key = []
        try:
            pointer1 = pointer_dict[key]
        except KeyError:
            pointer1 = []
        sumqmax = 0.0
        sumweight = 0.0
        for icell in pointer1:
            area = weighgrid.get_data(icell,0.0)
            maxarea = 10000000000
            # Fill weighing data and max data
            qmax_key.append(maxarea)
            weight_key.append(area)
            sumqmax += qmax_key[-1]
            sumweight += weight_key[-1]

        if (sumweight < 0.0001):
            # Make uniform weighing to all cells. There is no info for this region on the weighing.
            for icell in range(len(weight_key)):
                weight_key[icell] =  1
                sumweight += weight_key[icell]

        # Do the allocation
        allocated_amount = allocweighing.allocweighing(required_amount,sumweight,weight_key,qmax_key)

        if (abs(sum(allocated_amount) - total_substance[key]) > 0.001*total_substance[key]):
            print "***** There is not enough allocated for environment " + environ + " and substance " + substance + " for region "+str(key)+". Difference: " + str(total_substance[key]-sum(allocated_amount))

        # Fill gridded result
        for item in xrange(len(allocated_amount)):
            out_grid.set_data(pointer1[item],allocated_amount[item])

    return out_grid