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
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
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