def __init__(self, config='config.ini'): print "Tethys starts..." # instantiate functions self.Disaggregation = disagg self.OutWriter = OutWriter # compile config file self.settings = IniReader.getSimulatorSettings(config) # instantiate logger and log file sys.stdout = Logger() sys.stdout.log = open(self.settings.OutputFolder + "logfile.log", "w") # write settings to log IniReader.PrintInfo(self.settings) # instantiate output variables for model run self.gridded_data = None self.gis_data = None # run model and save outputs self.run_model() # clean up log sys.stdout.log.close() sys.stdout = sys.__stdout__ print "Tethys ends."
def getPopYearData(settings): '''Update the population maps to include a unique map for each historical time period''' pop = {} GPW_pop = ArrayCSVReader(settings.Population_GPW, 1) HYDE_pop = ArrayCSVReader(settings.Population_HYDE, 1) H_years = [ 1750, 1760, 1770, 1780, 1790, 1800, 1810, 1820, 1830, 1840, 1850, 1860, 1870, 1880, 1890, 1900, 1910, 1920, 1930, 1940, 1950, 1960, 1970, 1980 ] G_years = [1990, 1995, 2000, 2005, 2010, 2015] years = [int(x) for x in settings.years] years_new = years[:] mainlog = Logger.getlogger() oldlvl = mainlog.setlevel(Logger.DEBUG) for i in range(0, len(years)): if years[i] < 1990: if years[i] >= max(H_years): years_new[i] = max(H_years) else: for j in range(0, len(H_years) - 1): if years[i] >= H_years[j] and years[i] < H_years[j + 1]: years_new[i] = H_years[j] # use previous year if not str(years_new[i]) in pop: pop[str(years_new[i])] = HYDE_pop[:, H_years.index(years_new[i])] #pop[str(years_new[i])] = importHYDE(settings.pop + "HYDE/popc_" + str(years_new[i]) + "AD.asc", settings.mapsize, settings.mapIndex) mainlog.write('------Use HYDE ' + str(years_new[i]) + ' Population Data for ' + str(years[i]) + '\n') elif years[i] >= 1990: if years[i] >= max(G_years): years_new[i] = max(G_years) else: for j in range(0, len(G_years) - 1): if years[i] >= G_years[j] and years[i] < G_years[j + 1]: years_new[i] = G_years[j] # use previous year if not str(years_new[i]) in pop: pop[str(years_new[i])] = GPW_pop[:, G_years.index(years_new[i])] #pop[str(years_new[i])] = importGPW(settings.pop + "GPW/popc_v3_" + str(years_new[i]) + ".asc", settings.mapsize, settings.mapIndex) mainlog.write('------Use GPW ' + str(years_new[i]) + ' Population Data for ' + str(years[i]) + '\n') pop['years'] = years # years (integer) from settings pop['years_new'] = years_new # years to import population data (integer) corresponding to years mainlog.setlevel(oldlvl) return pop
def print_info(self): log = Logger.getlogger() oldlvl = log.setlevel(Logger.INFO) log.write('Project Name : {}\n'.format(self.ProjectName)) log.write('Input Folder : {}\n'.format(self.InputFolder)) log.write('Output Folder : {}\n'.format(self.OutputFolder)) log.write('GCAM Database Folder: {}\n'.format( os.path.join(self.GCAM_DBpath, self.GCAM_DBfile))) log.write('Region Info Folder : {}\n'.format(self.rgnmapdir))
def getIrrYearData(settings): '''Update the irrigation maps to include a unique map for each historical time period''' irr = {} GMIA_irr = ArrayCSVReader(settings.Irrigation_GMIA, 1) HYDE_irr = ArrayCSVReader(settings.Irrigation_HYDE, 1) H_years = [ 1900, 1910, 1920, 1930, 1940, 1950, 1960, 1970, 1980, 1990, 2000 ] G_years = [2005] years = [int(x) for x in settings.years] years_new = years[:] mainlog = Logger.getlogger() oldlvl = mainlog.setlevel(Logger.DEBUG) for i in range(0, len(years)): if years[i] < 2005: if years[i] >= max(H_years): years_new[i] = max(H_years) else: for j in range(0, len(H_years) - 1): if years[i] >= H_years[j] and years[i] < H_years[j + 1]: years_new[i] = H_years[j] # use previous year if not str(years_new[i]) in irr: irr[str(years_new[i])] = HYDE_irr[:, H_years.index(years_new[i])] #irr[str(years_new[i])] = importHYDE(settings.irr1 + "HYDE/crop" + str(years_new[i]) + "AD.asc", settings.mapsize) mainlog.write('------Use HYDE ' + str(years_new[i]) + ' Irrigation Area Data for ' + str(years[i]) + '\n') elif years[i] >= 2005: if years[i] >= max(G_years): years_new[i] = max(G_years) else: for j in range(0, len(G_years) - 1): if years[i] >= G_years[j] and years[i] < G_years[j + 1]: years_new[i] = G_years[j] # use previous year if not str(years_new[i]) in irr: irr[str(years_new[i])] = GMIA_irr[:] #irr[str(years_new[i])] = importGMIA(settings.irr1 + "GMIA/gmia_v5_aei_ha.asc", settings.mapsize) mainlog.write('------Use FAO-GMIA ' + str(years_new[i]) + ' Irrigation Area Data for ' + str(years[i]) + '\n') irr['years'] = years # years (integer) from settings irr['years_new'] = years_new # years to import irrigation data (integer) corresponding to years mainlog.setlevel(oldlvl) return irr
def run_disaggregation(settings): ''' License: BSD 2-Clause, see LICENSE and DISCLAIMER files Copyright (c) 2017, Battelle Memorial Institute Module: run_disaggregation Main Function of Tethys Steps for water disaggregation 1. Read in the GCAM Data and Get the number of years 2. Read in the GIS data 3. Rearranging data and map indices 4. Create proxy maps for population, livestock and irrigation and downscale non-Agriculture (domestic, electricity, manufacturing and mining), livestock and irrigation water withdrawals to grid scale 5. Compute Total Water withdrawal 6. Diagnostics of Spatial Downscaling 7. Temporal Downscaling (annually -> monthly) 8. Diagnostics of Temporal Downscaling # Input: - settings class DataReader.ConfigSettings, required input and control parameters # Output: - OUT class DataWriter.OUTWritter, data for output, gridded results for each withdrawal category ''' mainlog = Logger.getlogger() oldlvl = mainlog.setlevel(Logger.INFO) # initialize output parameters OUT = OUTSettings() # 1. Read in the GCAMData # a. Population tables # b. irrigation tables # c. livestock tables # d. Results of water withdrawals from GCAM by sectors and regions starttime1 = time.time() # Set-up timer mainlog.write('---Read in and format GCAM data---\n') GCAMData = get_gcam_data(settings) endtime1 = time.time() mainlog.write("------Time Cost: %s seconds ---\n" % (endtime1 - starttime1)) # e. Get the number of years settings.years = [int(i) for i in settings.years] if settings.years: settings.NY = len(settings.years) mainlog.write('---Number of years: {}\n'.format(settings.NY)) mainlog.write('------ {}\n'.format(str(settings.years))) else: (_, size) = GCAMData['pop_tot'].shape settings.NY = size mainlog.write('---Number of years: {}\n'.format(settings.NY)) # 2. Read in the GIS data # a. Coordinates of grids # b. Area of grids # c. Population maps # d. irrigation maps # e. livestock maps # f. mask shape files of GCAM regions, river basins, countries, states, etc. mainlog.write( '---Read in the GIS data (asc/txt/csv format) and the region map data (csv format)---\n' ) GISData = GISReader.getGISData(settings) rgnmapData = GISReader.getRegionMapData(settings.InputRegionFile) endtime2 = time.time() mainlog.write("------Time Cost: %s seconds ---\n" % (endtime2 - endtime1)) mainlog.write('---Mapsize: {}\n'.format(settings.mapsize)) # 3. Rearranging data and map indices # Rearrange all the input data into a common framework (from 2D to 1D) mainlog.write('---Rearranging data and map indices\n') Rearranging(settings.mapsize, GISData, rgnmapData) endtime3 = time.time() mainlog.write("------Time Cost: %s seconds ---\n" % (endtime3 - endtime2)) # 4. Create proxy maps and downscale non-Agriculture (domestic, electricity, manufacturing and mining) water # withdrawals to grid scale # a. Create a population proxy map mainlog.write( '---Create a population map as proxy of non-agricultural water withdrawals\n' ) ProxyMaps.PopulationMap(settings.mapsize, GISData, GCAMData, rgnmapData, settings, OUT) endtime4 = time.time() mainlog.write("------Time Cost: %s seconds ---\n" % (endtime4 - endtime3)) # b. Create a livestock proxy map and downscale livestock water withdrawal to grid scale mainlog.write( '---Create an livestock map as proxy of livestock water withdrawal\n') ProxyMaps.LivestockMap(settings.mapsize, GISData, GCAMData, rgnmapData, settings.NY, OUT) endtime5 = time.time() mainlog.write("------Time Cost: %s seconds ---\n" % (endtime5 - endtime4)) # c. Create an irrigation proxy map and downscale irrigation water withdrawal to grid scale mainlog.write( '---Create an irrigation map as proxy of agricultural water withdrawal\n' ) ProxyMaps.IrrigationMap(settings.mapsize, GISData, GCAMData, rgnmapData, settings.NY, OUT, settings.subreg) endtime6 = time.time() mainlog.write("------Time Cost: %s seconds ---\n" % (endtime6 - endtime5)) # 5. Total Water Withdrawal mainlog.write( '---Aggregate to compute total water withdrawal at grid scale\n') TotalWaterUse.TotalWaterUse(settings, GISData, rgnmapData, OUT) endtime7 = time.time() mainlog.write("------Time Cost: %s seconds ---\n" % (endtime7 - endtime6)) # 6. Diagnostics of Spatial Downscaling if settings.PerformDiagnostics: DiagnosticsSD.compare_downscaled_GCAMinput(settings, GCAMData, OUT) # 7. Temporal Downscaling if settings.PerformTemporal: mainlog.write( '---Temporal downscaling for Domestic, Electricity, Irrigation, Livestock, Mining and Manufacturing\n' ) endtime6 = time.time() TemporalDownscaling.GetDownscaledResults(settings, OUT, GISData['mapindex'], rgnmapData['rgnmapNONAG'], GISData['BasinIDs']) endtime7 = time.time() mainlog.write("------Time Cost: %s seconds ---\n" % (endtime7 - endtime6)) # 8. Diagnostics of Temporal Downscaling if settings.PerformDiagnostics and settings.PerformTemporal: DiagnosticsTD.compare_temporal_downscaled(settings, OUT, GISData) return OUT, GISData
def GetDownscaledResults(settings, OUT, mapindex, regionID, basinID): """Determine the temporal downscaling years""" mainlog = Logger.getlogger() startyear = int(settings.temporal_climate.split("_")[-2][:4]) endyear = int(settings.temporal_climate.split("_")[-1][:4]) TempYears = list(range(startyear, endyear + 1)) TDYears = sorted(list(set(TempYears).intersection(settings.years))) TDYearsD = np.diff(TDYears) # Interval of TD Years GCAM_TDYears_Index = [settings.years.index(i) for i in TDYears] if settings.TemporalInterpolation and all(item > 1 for item in TDYearsD): # Linear interpolation to GCAM time periods W = OUT.wddom[mapindex,:] OUT.WDom = LinearInterpolationAnnually(W[:,GCAM_TDYears_Index],TDYears) W = OUT.wdelec[mapindex,:] OUT.WEle = LinearInterpolationAnnually(W[:,GCAM_TDYears_Index],TDYears) W = OUT.wdirr[mapindex,:] OUT.WIrr = LinearInterpolationAnnually(W[:,GCAM_TDYears_Index],TDYears) W = OUT.wdliv[mapindex,:] OUT.WLiv = LinearInterpolationAnnually(W[:,GCAM_TDYears_Index],TDYears) W = OUT.wdmin[mapindex,:] OUT.WMin = LinearInterpolationAnnually(W[:,GCAM_TDYears_Index],TDYears) W = OUT.wdmfg[mapindex,:] OUT.WMfg = LinearInterpolationAnnually(W[:,GCAM_TDYears_Index],TDYears) # Update the TDYears to new values TDYears = list(np.interp(np.arange(min(TDYears), max(TDYears) + 1), TDYears, TDYears).astype(int)) else: W = OUT.wddom[mapindex,:] OUT.WDom = W[:,GCAM_TDYears_Index] W = OUT.wdelec[mapindex,:] OUT.WEle = W[:,GCAM_TDYears_Index] W = OUT.wdirr[mapindex,:] OUT.WIrr = W[:,GCAM_TDYears_Index] W = OUT.wdliv[mapindex,:] OUT.WLiv = W[:,GCAM_TDYears_Index] W = OUT.wdmin[mapindex,:] OUT.WMin = W[:,GCAM_TDYears_Index] W = OUT.wdmfg[mapindex,:] OUT.WMfg = W[:,GCAM_TDYears_Index] settings.TDYears = TDYears # Index of TDYears in Temperature data and GCAM Temp_TDYears_Index = [TempYears.index(i) for i in TDYears] Temp_TDMonths_Index = np.zeros((len(TDYears)*12,), dtype = int) for i in Temp_TDYears_Index: N = Temp_TDYears_Index.index(i) Temp_TDMonths_Index[N*12:(N+1)*12] = np.arange(i*12, (i+1)*12) mainlog.write('------ Temporal downscaling is available for Year: {}\n'.format(TDYears), Logger.DEBUG) # load climate data tclim = np.load(settings.temporal_climate) dom = {} dom['tas'] = tclim['tas'][:, Temp_TDMonths_Index] dom['DomesticR'] = ArrayCSVRead(settings.Domestic_R, 1) ele = {} ele['hdd'] = tclim['hdd'][:, Temp_TDMonths_Index] ele['cdd'] = tclim['cdd'][:, Temp_TDMonths_Index] # The parameters pb, ph, pc, pu, pit are all obtained from GCAM. ele['building'] = ArrayCSVRead(settings.Elec_Building,0)[:,Temp_TDYears_Index] ele['industry'] = ArrayCSVRead(settings.Elec_Industry,0)[:,Temp_TDYears_Index] ele['heating'] = ArrayCSVRead(settings.Elec_Building_heat,0)[:,Temp_TDYears_Index] ele['cooling'] = ArrayCSVRead(settings.Elec_Building_cool,0)[:,Temp_TDYears_Index] ele['others'] = ArrayCSVRead(settings.Elec_Building_others,0)[:,Temp_TDYears_Index] ele['region'] = regionID # Monthly Irrigation Data from other models only available during 1971-2010 endyear = int(settings.Irr_MonthlyData.split("_")[-1][:4]) if endyear < TDYears[-1]: TempYears_irr = list(range(startyear,endyear+1)) TDYears_irr = sorted(list(set(TempYears_irr).intersection(settings.years))) Temp_TDYears_Index = [TempYears_irr.index(i) for i in TDYears_irr] Temp_TDMonths_Index = np.zeros((len(TDYears)*12,), dtype = int) for i in Temp_TDYears_Index: N = Temp_TDYears_Index.index(i) Temp_TDMonths_Index[N*12:(N+1)*12] = np.arange(i*12, (i+1)*12) irr, irrprofile = GetMonthlyIrrigationData(settings.Irr_MonthlyData, Temp_TDMonths_Index, settings.coords) """Domestic""" OUT.twddom = Domestic_Temporal_Downscaling(dom, OUT.WDom, settings.TDYears) """Electricity""" OUT.twdelec = Electricity_Temporal_Downscaling(ele, OUT.WEle, settings.TDYears) """Irrigation""" OUT.twdirr = Irrigation_Temporal_Downscaling(irr, irrprofile, OUT.WIrr, settings.TDYears, basinID) """Livestock, Mining and Manufacturing""" OUT.twdliv = AnnualtoMontlyUniform(OUT.WLiv, TDYears) OUT.twdmin = AnnualtoMontlyUniform(OUT.WMin, TDYears) OUT.twdmfg = AnnualtoMontlyUniform(OUT.WMfg, TDYears)
def compare_downscaled_GCAMinput(Settings, GCAMData, OUT): mainlog = Logger.getlogger() ## These calculations will be performed ONLY if we are logging debug-level output. ## Otherwise, we skip the output and the calculations if mainlog.minlvl > Logger.DEBUG: return mainlog.write( '---Spatial Downscaling Diagnostics (Global): downscaled results vs. aggregated results from GCAM (Total Water, km3/yr)\n', Logger.DEBUG) NY = Settings.NY value = np.zeros((NY, 3), dtype=float) for y in range(0, NY): # Global Total For Each Year in log # Global_DS Global Total [km3/yr] from downscaled results value[y, 0] = sum(OUT.rtotal[:, y]) # Global_GCAM Global Total [km3/yr] from GCAM inputs value[y,1] = sum(GCAMData['rgn_wddom'][:,y]) + sum(GCAMData['rgn_wdelec'][:,y]) + sum(GCAMData['rgn_wdmfg'][:,y]) + sum(GCAMData['rgn_wdmining'][:,y]) \ + sum(GCAMData['irrV'][:,y+3]) + sum(GCAMData['wdliv'][:,y]) value[y, 2] = value[y, 0] - value[y, 1] if Settings.years: yrout = Settings.years[y] else: yrout = y + 1 mainlog.write( ' Year {0[0]:4d}: {0[1]:.6f} {0[2]:.6f} Diff= {0[3]:.6f}\n' .format([yrout, value[y, 0], value[y, 1], value[y, 2]]), Logger.DEBUG) # Comprehensive Diagnostics information to file: category = [ 'Domestic', 'Electricity', 'Manufacturing', 'Mining', 'Livestock', 'Irrigation', 'Non-Agriculture', 'Agriculture', 'Total' ] group = ['Downscaled_', 'GCAM_', 'Diff_'] Sector = ['Year', 'Region ID', 'Region Name', 'GCAM Population (millions)'] Unit = " (km3/yr)" headerline = ",".join(Sector) + "," + ",".join( [prefix + s + Unit for prefix in group for s in category]) extension = '.csv' OutputFilename = os.path.join( Settings.OutputFolder, 'Diagnostics_Spatial_Downscaling{}'.format(extension)) Regions = pd.read_csv(Settings.RegionNames, index_col='region_id').to_dict()['region'] NR = len(Regions) # Regions.insert(0, 'Global') # Add "Global" to regions Regions[0] = 'Global' Years = Settings.years Population = GCAMData['pop_tot'] / 1e6 # Add Global data to all Population = np.vstack([sum(Population), Population]) OUT.rtotal = np.vstack([sum(OUT.rtotal), OUT.rtotal]) OUT.rnonag = np.vstack([sum(OUT.rnonag), OUT.rnonag]) OUT.rdom = np.vstack([sum(OUT.rdom), OUT.rdom]) OUT.relec = np.vstack([sum(OUT.relec), OUT.relec]) OUT.rmfg = np.vstack([sum(OUT.rmfg), OUT.rmfg]) OUT.rmin = np.vstack([sum(OUT.rmin), OUT.rmin]) OUT.rirr = np.vstack([sum(OUT.rirr), OUT.rirr]) OUT.rliv = np.vstack([sum(OUT.rliv), OUT.rliv]) GCAMOUT = OUTSettings() wdliv = np.zeros((NR, NY), dtype=float) irrV = np.zeros((NR, NY), dtype=float) for IN in range(0, NR): wdliv[IN,:] = GCAMData['wdliv'][0*NR+IN,:] + GCAMData['wdliv'][1*NR+IN,:] + GCAMData['wdliv'][2*NR+IN,:] + \ GCAMData['wdliv'][3*NR+IN,:] + GCAMData['wdliv'][4*NR+IN,:] + GCAMData['wdliv'][5*NR+IN,:] ls = np.where(GCAMData['irrV'][:, 0].astype(int) - 1 == IN)[0] irrV[IN, :] = sum(GCAMData['irrV'][ls, 3:]) nonAG = GCAMData['rgn_wddom'] + GCAMData['rgn_wdelec'] + GCAMData[ 'rgn_wdmfg'] + GCAMData['rgn_wdmining'] AG = irrV + wdliv total = nonAG + AG GCAMOUT.rtotal = np.vstack([sum(total), total]) GCAMOUT.rnonag = np.vstack([sum(nonAG), nonAG]) GCAMOUT.rdom = np.vstack( [sum(GCAMData['rgn_wddom']), GCAMData['rgn_wddom']]) GCAMOUT.relec = np.vstack( [sum(GCAMData['rgn_wdelec']), GCAMData['rgn_wdelec']]) GCAMOUT.rmfg = np.vstack( [sum(GCAMData['rgn_wdmfg']), GCAMData['rgn_wdmfg']]) GCAMOUT.rmin = np.vstack( [sum(GCAMData['rgn_wdmining']), GCAMData['rgn_wdmining']]) GCAMOUT.rirr = np.vstack([sum(irrV), irrV]) GCAMOUT.rliv = np.vstack([sum(wdliv), wdliv]) values = [ ] # 'Year', 'Region ID', 'Region Name', 'GCAM Population (millions)' and all the category*group for j in range(0, NY): for i in range(0, NR + 1): DS = np.array([ OUT.rdom[i, j], OUT.relec[i, j], OUT.rmfg[i, j], OUT.rmin[i, j], OUT.rliv[i, j], OUT.rirr[i, j], OUT.rnonag[i, j], OUT.rliv[i, j] + OUT.rirr[i, j], OUT.rtotal[i, j] ]) GCAM = np.array([ GCAMOUT.rdom[i, j], GCAMOUT.relec[i, j], GCAMOUT.rmfg[i, j], GCAMOUT.rmin[i, j], GCAMOUT.rliv[i, j], GCAMOUT.rirr[i, j], GCAMOUT.rnonag[i, j], GCAMOUT.rliv[i, j] + GCAMOUT.rirr[i, j], GCAMOUT.rtotal[i, j] ]) Diff = DS.tolist() + GCAM.tolist() + (DS - GCAM).tolist() if Years is not None: data = [Years[j], str(i), Regions[i]] + [ "%.2f" % Population[i, j] ] + ["%.3f" % x for x in Diff] else: data = ['Index ' + str(j), str(i), Regions[i]] + ["%.2f" % Population[i, j] ] + ["%.3f" % x for x in Diff] values.append(data) values = np.array(values) with open(OutputFilename, 'w') as outfile: np.savetxt(outfile, values, delimiter=',', header=headerline, fmt='%s', comments='') mainlog.write( '------Diagnostics information is saved to: {}\n'.format( OutputFilename), Logger.DEBUG)
def compare_temporal_downscaled(Settings, OUT, GISData): mainlog = Logger.getlogger() ## The outputs produced in this function are an extension of the debugging ## logs; therefore, if the logging level is set above DEBUG, we skip the ## calculations and the output if mainlog.minlvl > Logger.DEBUG: return mapindex = GISData['mapindex'] BasinIDs = GISData['BasinIDs'] BasinNames = GISData['BasinNames'] NB = np.max(BasinIDs) years = Settings.TDYears NY = len(years) NM = len(mapindex) mainlog.write( '---Temporal Downscaling Diagnostics (Global): downscaled results vs. results before temporal downscaling (Total Water, km3/yr)\n', Logger.DEBUG) mainlog.write('------Irrigation------\n') W = OUT.WIrr[:, :] value = np.zeros((NY, 3), dtype=float) for j in years: N = years.index(j) value[N, 0] = np.sum(OUT.twdirr[:, N * 12:(N + 1) * 12]) value[N, 1] = np.sum(W[:, N]) value[N, 2] = value[N, 0] - value[N, 1] mainlog.write( ' Year {0[0]:4d}: {0[1]:.6f} {0[2]:.6f} Diff= {0[3]:.6e}\n' .format([j, value[N, 0], value[N, 1], value[N, 2]]), Logger.DEBUG) # Print out the basin level comparison Sector = [ 'Year', 'Basin ID', 'Basin Name', 'After Spatial Downscaling', 'After Temporal Downscaling', 'Diff' ] Unit = " (km3/yr)" headerline = ",".join(Sector) + Unit Wtd_basin = np.zeros((NB, NY), dtype=float) W_basin = np.zeros((NB, NY), dtype=float) for index in range(0, NM): for y in range(0, NY): if not np.isnan(W[index, y]) and BasinIDs[index] > 0: W_basin[BasinIDs[index] - 1, y] += W[index, y] Wtd_basin[BasinIDs[index] - 1, y] += np.sum(OUT.twdirr[index, y * 12:(y + 1) * 12]) values = [] for j in years: N = years.index(j) for i in range(0, NB): data = [str(j), str(i + 1), BasinNames[i]] + [ "%.3f" % W_basin[i, N] ] + ["%.3f" % Wtd_basin[i, N] ] + ["%.3f" % (W_basin[i, N] - Wtd_basin[i, N])] values.append(data) with open( os.path.join(Settings.OutputFolder, 'Diagnostics_Temporal_Downscaling_Irrigation.csv'), 'w') as outfile: np.savetxt(outfile, values, delimiter=',', header=headerline, fmt='%s', comments='') mainlog.write('------Domestic------\n', Logger.DEBUG) W = OUT.WDom[:, :] value = np.zeros((NY, 3), dtype=float) for j in years: N = years.index(j) value[N, 0] = np.sum(OUT.twddom[:, N * 12:(N + 1) * 12]) value[N, 1] = np.sum(W[:, N]) value[N, 2] = value[N, 0] - value[N, 1] mainlog.write( ' Year {0[0]:4d}: {0[1]:.6f} {0[2]:.6f} Diff= {0[3]:.6e}\n' .format([j, value[N, 0], value[N, 1], value[N, 2]]), Logger.DEBUG) Domestic_TD__Diagnostics_Plot(OUT.twddom, GISData, Settings.OutputFolder) mainlog.write('------Electricity Generation------\n') W = OUT.WEle[:, :] value = np.zeros((NY, 3), dtype=float) for j in years: N = years.index(j) value[N, 0] = np.sum(OUT.twdelec[:, N * 12:(N + 1) * 12]) value[N, 1] = np.sum(W[:, N]) value[N, 2] = value[N, 0] - value[N, 1] mainlog.write( ' Year {0[0]:4d}: {0[1]:.6f} {0[2]:.6f} Diff= {0[3]:.6e}\n' .format([j, value[N, 0], value[N, 1], value[N, 2]]), Logger.DEBUG) Electricity_TD__Diagnostics_Plot(OUT.twdelec, GISData, Settings.OutputFolder)
def PopulationMap(mapsize, GISData, GCAMData, rgnmapData, settings, OUT): # Total Non-Agricultural Water withdrawal in 1990, 2005, ... 2050, and 2010 # population in millions in year 2000 mainlog = Logger.getlogger() NY = settings.NY # non-agricultural (dom, elec, mfg, mining) total water withdrawals in (km3/yr) for each of the GCAM regions # population map for all years 1990, 2005:2095 ms = (mapsize[0] * mapsize[1], NY) # withd_nonAg_map = np.full(ms, np.NaN, dtype=float) withd_dom_map = np.full(ms, np.NaN, dtype=float) withd_elec_map = np.full(ms, np.NaN, dtype=float) withd_mfg_map = np.full(ms, np.NaN, dtype=float) withd_mining_map = np.full(ms, np.NaN, dtype=float) # use historical population maps for y in range(0, NY): # population map mainlog.write('{}\n'.format(GISData['pop']['years'][y]), Logger.DEBUG) yearstr = str(GISData['pop']['years_new'][y]) pop = np.zeros(rgnmapData['map_rgn_nonag'].shape, dtype=float) pop[GISData['mapindex']] = GISData['pop'][yearstr] # make some minor fixes to the region mapping map_rgn_nonag = rgnmapadjust( mapsize, pop, rgnmapData['map_rgn_nonag'], '------[Adjusting map_rgn_nonag with population]: ') map_rgn_ag = rgnmapadjust( mapsize, pop, rgnmapData['map_rgn_ag'], '------[Adjusting map_rgn_ag with population]: ') rgnmapData['map_rgn_nonag'] = np.copy(map_rgn_nonag) rgnmapData['map_rgn_ag'] = np.copy(map_rgn_ag) # Adjust population map to be consistent with GCAM assumptions. We will use # the non-ag region map for this because in all current setups it is more detailed. pop_fac_Ag = np.zeros((rgnmapData['nrgnNONAG'], NY), dtype=float) pop_fac_nonAg = np.zeros((rgnmapData['nrgnNONAG'], NY), dtype=float) # Correction to pop_fac` for i in range(1, rgnmapData['nrgnNONAG'] + 1): index1 = np.where(map_rgn_nonag == i)[0] index2 = np.where(map_rgn_ag == i)[0] pop_fac_nonAg[i - 1, :] = GCAMData['pop_tot'][i - 1, :NY] / np.sum( pop[index1]) pop_fac_Ag[i - 1, :] = GCAMData['pop_tot'][i - 1, :NY] / np.sum( pop[index2]) # index of all cells that have valid regions mapindex_valid = np.where(map_rgn_nonag > 0)[0] pop_tot_y = GCAMData['pop_tot'][:, y] # single time slice regional pop pop_pro_rata = pop[mapindex_valid] * pop_fac_nonAg[ map_rgn_nonag[mapindex_valid] - 1, y] / pop_tot_y[map_rgn_nonag[mapindex_valid] - 1] withd_dom_map[mapindex_valid, y] = pop_scale_reshape(GCAMData['rgn_wddom'][:, y], pop_pro_rata, map_rgn_nonag, mapindex_valid) withd_elec_map[mapindex_valid, y] = pop_scale_reshape(GCAMData['rgn_wdelec'][:, y], pop_pro_rata, map_rgn_nonag, mapindex_valid) withd_mfg_map[mapindex_valid, y] = pop_scale_reshape(GCAMData['rgn_wdmfg'][:, y], pop_pro_rata, map_rgn_nonag, mapindex_valid) pop_pro_rata = pop[mapindex_valid] * pop_fac_Ag[ map_rgn_ag[mapindex_valid] - 1, y] / pop_tot_y[map_rgn_ag[mapindex_valid] - 1] withd_mining_map[mapindex_valid, y] = pop_scale_reshape(GCAMData['rgn_wdmining'][:, y], pop_pro_rata, map_rgn_ag, mapindex_valid) # total non-ag withdrawal can be computed from these four maps withd_nonAg_map = withd_dom_map + withd_elec_map + withd_mfg_map + withd_mining_map # The maps have the nan values replaced by zero, if we want to keep the nans (for plotting), comment the following 5 lines withd_dom_map[np.isnan(withd_dom_map)] = 0 withd_elec_map[np.isnan(withd_elec_map)] = 0 withd_mfg_map[np.isnan(withd_mfg_map)] = 0 withd_mining_map[np.isnan(withd_mining_map)] = 0 withd_nonAg_map[np.isnan(withd_nonAg_map)] = 0 OUT.wdnonag = withd_nonAg_map OUT.wddom = withd_dom_map OUT.wdelec = withd_elec_map OUT.wdmfg = withd_mfg_map OUT.wdmin = withd_mining_map return withd_nonAg_map
def rgnmapadjust(mapsize, map_pop, map_rgn, label): ''' function rgn_map_adjust in matlab code Find unassigned grid cells with nonzero population and assign them to an adjacent region, if possible. Arguments: mapsize - Dimensions of the map array (typically [360, 720]) map_pop - Population map, dimensioned as mapsize map_rgn - Region map, dimensioned as mapsize label - String to prefix to diagnostic output Return value: adjusted region map. ''' mainlog = Logger.getlogger() new_map_rgn = np.copy(map_rgn) #map_pop = map_pop.reshape(map_rgn.shape, order='F') map_pop[np.isnan(map_pop)] = 0 # find problem cells adjust = np.where((map_pop > 0) & (map_rgn == 0))[0] # adjust each cell if possible mapsub = ind2sub(mapsize, adjust) row = mapsub[:, 0] col = mapsub[:, 1] # coordinates for adjacent cells, with protection for cells at the edges row0 = row - 1 row0[np.where(row0 < 0)] = 0 row1 = row + 1 row1[np.where(row1 > mapsize[0] - 1)] = mapsize[0] - 1 # make columns wrap col0 = col - 1 col0[np.where(col0 < 0)] = mapsize[1] - 1 col1 = col + 1 col1[np.where(col1 > mapsize[1] - 1)] = 0 # Create a matrix where each column is the region mapping for the adjacent cells in each of the 8 directions. # Then take the max along each row. Assign the result to the corresponding center cell. I1 = sub2ind(mapsize, row, col) I2 = sub2ind(mapsize, row0, col0) I3 = sub2ind(mapsize, row0, col) I4 = sub2ind(mapsize, row0, col1) I5 = sub2ind(mapsize, row, col0) I6 = sub2ind(mapsize, row, col1) I7 = sub2ind(mapsize, row1, col0) I8 = sub2ind(mapsize, row1, col) I9 = sub2ind(mapsize, row1, col1) for i in range(0, len(I1)): new_map_rgn[I1[i]] = max(map_rgn[I2[i]], map_rgn[I3[i]], map_rgn[I4[i]], map_rgn[I5[i]], map_rgn[I6[i]], map_rgn[I7[i]], map_rgn[I8[i]], map_rgn[I9[i]]) fixedcells = np.where((map_pop > 0) & (map_rgn == 0) & (new_map_rgn > 0))[0] ## log diagnostics mainlog.write( label + 'Cells with pop/irr data but no region: {}\n'.format(len(adjust)), Logger.DEBUG) mainlog.write( label + 'Cells adjusted to an adjacent region: {}\n'.format(len(fixedcells)), Logger.DEBUG) mainlog.write( label + 'Cells not adjusted: {}\n'.format(len(adjust) - len(fixedcells)), Logger.DEBUG) return new_map_rgn
def IrrigationMap(mapsize, GISData, GCAMData, rgnmapData, NY, OUT, subreg): mainlog = Logger.getlogger() # Need to downscale the agricultural water withdrawal data for GCAM years # using the existing map of areas equipped with irrigation as a proxy for disaggregation from # AEZ to grid scale CHALLENGE: where to add new agricultural lands mapAreaExt = GISData['mapAreaExt'] # float, unit is km2 # STEP 1: read in AEZ grid map AEZ map to match the aggregate withdrawal by GCAM, this loop reads # the ascii data and rearranges in right format and omits missing data -9999 mapAEZ = np.zeros(mapAreaExt.shape, dtype=int) if subreg == 0: mapAEZ[GISData['mapindex']] = GISData['aez'] elif subreg == 1: mapAEZ[GISData['mapindex']] = GISData['BasinIDs'] naez = np.amax(mapAEZ) # STEP 2: calculate the total amount of irrigated lands in each GCAM region from the GCAM output files. # The irrArea file from GCAM has the format: # 1: GCAM regions 1-nrgn # 2: AEZs 1-18 # 3: crops 1-17 # 4 .. nyear+3: values for GCAM output years # We are going to reorganize this into irrArea(rgn,aez,crop,year)(but the name irrArea is already taken, so we'll call it tempA_all) nrgnAG = rgnmapData['nrgnAG'] r1 = SizeR(GCAMData['irrArea']) try: r2 = SizeR(GCAMData['irrShare']) q2 = SizeC(GCAMData['irrShare']) except: r2 = 0 q2 = 0 r3 = SizeR(GCAMData['irrV']) ncrops = max(max(GCAMData['irrArea'][:, 2].astype(int)), max(GCAMData['irrV'][:, 2].astype(int))) tempA_all = np.zeros((nrgnAG, naez, ncrops, NY), dtype=float) tempS_all = np.zeros((nrgnAG, naez, ncrops, NY), dtype=float) tempV_all = np.zeros((nrgnAG, naez, ncrops, NY), dtype=float) for i in range(0, r1): for y in range(0, NY): tempA_all[GCAMData['irrArea'][i, 0].astype(int) - 1, GCAMData['irrArea'][i, 1].astype(int) - 1, GCAMData['irrArea'][i, 2].astype(int) - 1, y] = GCAMData['irrArea'][i, y + 3] * 1000 # convert from thousands of km2 to km2 # if irrShare was read in, then reorganize the same way we did with irrArea. # Otherwise, set all irrigation shares to one (indicating that irrArea really is irrigated area, # as calculated in GCAM, not total planted area, as in older versions of GCAM.) if r2 > 1 or q2 > 1: for i in range(0, r2): for y in range(0, NY): tempS_all[GCAMData['irrShare'][i, 0].astype(int) - 1, GCAMData['irrShare'][i, 1].astype(int) - 1, GCAMData['irrShare'][i, 2].astype(int) - 1, y] = GCAMData['irrShare'][i, y + 3] else: tempS_all = np.ones((nrgnAG, naez, ncrops, NY), dtype=float) # Same reorganization for irrVolume. Result goes to tempV_all for i in range(0, r3): for y in range(0, NY): tempV_all[GCAMData['irrV'][i, 0].astype(int) - 1, GCAMData['irrV'][i, 1].astype(int) - 1, GCAMData['irrV'][i, 2].astype(int) - 1, y] = GCAMData['irrV'][i, y + 3] # STEP 3: now that we have computed the total irrigated lands, we can aggregate all # the numbers for all the crops; we only keep the value per gcam region and aez irr_A = np.zeros((nrgnAG, naez, NY), dtype=float) irr_V = np.zeros((nrgnAG, naez, NY), dtype=float) for i in range(0, nrgnAG): for j in range(0, naez): for y in range(0, NY): for k in range(0, ncrops): irr_A[i, j, y] += tempA_all[i, j, k, y] * tempS_all[i, j, k, y] irr_V[i, j, y] += tempV_all[i, j, k, y] ms = (mapsize[0] * mapsize[1], NY) irrA_grid = np.full(ms, np.NaN, dtype=float) #irrA_frac = np.full(ms, np.NaN, dtype = float) withd_irr_map = np.full(ms, np.NaN, dtype=float) # GIS results # use historical irrigation area maps # STEP 4: read a grid map of the irrigated area in km2 in a certain year for y in range(0, NY): mainlog.write('{}\n'.format(GISData['irr']['years'][y]), Logger.DEBUG) yearstr = str(GISData['irr']['years_new'][y]) irr = np.zeros(rgnmapData['map_rgn_ag'].shape, dtype=float) irr[GISData['mapindex']] = GISData['irr'][yearstr] # add GCAM-AEZ labels to all cells with irrigation values # XXX maybe this should be done further up when we do the population adjustments map_rgn_ag = rgnmapadjust(mapsize, irr, rgnmapData['map_rgn_ag'], '------[Adjusting map_rgn_ag with irr]: ') mapAEZ = rgnmapadjust( mapsize, irr, mapAEZ, '------[Adjusting map' + GISData['AEZstring'] + ' with irr]: ') # if we need to do this step for mapAEZ? rgnmapData['map_rgn_ag'] = np.copy(map_rgn_ag) # STEP 5: calculate the total amount of irrigated lands from the GIS maps irrAx = np.zeros( (nrgnAG, naez), dtype=float ) # this is the max total available area of all grids with some irrigation irrA = np.zeros( (nrgnAG, naez), dtype=float ) # this is the existing area that is equipped with irrigation totA = np.zeros((nrgnAG, naez), dtype=float) # total land in each rgn, AEZ combo for index in range(0, mapsize[0] * mapsize[1]): temp = mapAreaExt[index] > 0 and map_rgn_ag[index] > 0 and mapAEZ[ index] > 0 if temp: irrA[map_rgn_ag[index] - 1, mapAEZ[index] - 1] += irr[index] totA[map_rgn_ag[index] - 1, mapAEZ[index] - 1] += mapAreaExt[index] if irr[index] > 0: irrAx[map_rgn_ag[index] - 1, mapAEZ[index] - 1] += mapAreaExt[index] else: irr[index] = 0 # STEP 6: for i in range(0, nrgnAG): for j in range(0, naez): # To be efficient, the most important step in the loop is to identify the valid irr cell(index in 360*720 grid) for each region and each aez ls = np.where((map_rgn_ag - 1 == i) & (mapAEZ - 1 == j))[0] if len(ls) > 0 and irr_A[i, j, y] > 0: ls1 = [] ls2 = [] for index in ls: if irr[index] == 0: ls1.append(index) else: ls2.append(index) # if irrigation area appears in GCAM but not in GIS (none of the grids are equipped with irrigation in the selcted year) # uniformly distributed irrigation area based on the total area if irrA[i, j] == 0 or irrAx[i, j] == 0: for index in ls: irrA_grid[index, y] = mapAreaExt[index] / totA[ i, j] * irr_A[i, j, y] #irrA_frac[index, y] = irr_A[i,j,y]/totA[i,j] else: # if irrigation area appears in both the GIS matrix and the GCAM output matrix, # then we need to scale up/down the values # in the GIS grid map values to match GCAM total values diff = 99 counter = 0 num_new = 0 while diff > 0.00001: # [i j counter diff] cum_area = 0 cum_diff = 0 if counter == 0: num = 0 counter1 = 0 counter2 = 0 for index in ls1: irrA_grid[index, y] = np.NaN #irrA_frac[index, y] = np.NaN counter2 += 1 for index in ls2: z = irr[index] / irrA[i, j] * irr_A[i, j, y] irrA_grid[index, y] = min(z, mapAreaExt[index]) #irrA_frac[index, y] = irrA_grid[index, y]/mapAreaExt[index] if z > mapAreaExt[index]: cum_diff += z - mapAreaExt[index] counter1 += 1 else: num += 1 cum_area += irrA_grid[index, y] # if all irrigation grids (ls2) have irrigation area larger than total area (ls2) # and no-irrigation grids (ls1) existed # (total irrigation area (ls2) - total area) = irrigated areas are distributed uniformly over # non-irrigated grids (ls1) if num == 0 and counter2 > 0: cum_area1 = cum_area cum_diff = 0 cum_area = 0 cum_diff0 = 0 z = (irr_A[i, j, y] - cum_area1) / counter2 for index in ls1: irrA_grid[index, y] = min( z, mapAreaExt[index]) #irrA_frac[index, y] = irrA_grid[index, y]/mapAreaExt[index] if z > mapAreaExt[index]: cum_diff0 += z - mapAreaExt[index] cum_area = cum_area1 + irrA_grid[index, y] if cum_diff0 > 0: mainlog.write( '{} {} {} {} {} {} {} \n'. format( '[Year Index, Region ID,', GISData['AEZstring'], ' ID, irr from GCAM not assigned (km3) (condition 0)]:', y + 1, i + 1, j + 1, cum_diff0 * irr_V[i, j, y] / irr_A[i, j, y]), Logger.WARNING) else: # if (num == 0 and counter2 == 0) or num > 0 for index in ls1: irrA_grid[index, y] = np.NaN #irrA_frac[index, y] = np.NaN counter3 = 0 for index in ls2: if irrA_grid[index, y] < mapAreaExt[index]: z = irrA_grid[index, y] + diff / max(1, num) irrA_grid[index, y] = min( z, mapAreaExt[index]) #irrA_frac[index, y] = irrA_grid[index, y]/mapAreaExt[index] if z > mapAreaExt[index]: cum_diff += z - mapAreaExt[index] num_new = num - 1 cum_area += irrA_grid[index, y] else: cum_area += irrA_grid[index, y] num_new = num - 1 counter3 += 1 num = num_new if cum_diff == 0 and counter3 == len(ls2): mainlog.write( '{} {} {} {} {} {} {} \n'.format( '[Year Index, Region ID,', GISData['AEZstring'], ' ID, irr from GCAM not assigned (km3) (condition 1)]:', y + 1, i + 1, j + 1, diff * irr_V[i, j, y] / irr_A[i, j, y]), Logger.WARNING) counter += 1 diff = cum_diff for index in ls: if not np.isnan(irrA_grid[index, y]): withd_irr_map[index, y] = irrA_grid[ index, y] * irr_V[i, j, y] / irr_A[i, j, y] elif len(ls) == 0 and irr_A[i, j, y] > 0 and irr_V[i, j, y] > 0: # GCAM has irrigation data for a region and a AEZ/basin. # But from region map and AEZ/basin map, there are no cells belong to both. # Thus, GCAM data will not be included for downscaling. # It will cause the difference in Spatial Downscaling Diagnostics mainlog.write( '{} {} {} {} {} {} {} \n'.format( '[Year Index, Region ID,', GISData['AEZstring'], 'ID, irr from GCAM not assigned (km3) (No overlapping cells)]:', y + 1, i + 1, j + 1, irr_V[i, j, y]), Logger.WARNING) # this loop will replace all the nan values with zeros to be able to take sums, if we want to keep the nans (for plotting), comment following 2 lines irrA_grid[np.isnan(irrA_grid)] = 0 withd_irr_map[np.isnan(withd_irr_map)] = 0 # Total Agricultural Water withdrawal in years OUT.wdirr = withd_irr_map return withd_irr_map
def LivestockMap(mapsize, GISData, GCAMData, rgnmapData, NY, OUT): mainlog = Logger.getlogger() oldlvl = mainlog.setlevel(Logger.DEBUG) # count how many animals live in each GCAM region first map_rgn_ag = rgnmapData['map_rgn_ag'] nrgnAG = rgnmapData['nrgnAG'] tot_livestock = np.zeros( (nrgnAG, 6), dtype=float) # Livestock totals at GCAM scale in year 2005 # 67420 -> 360*720 buffalo = np.zeros(map_rgn_ag.shape, dtype=float) cattle = np.zeros(map_rgn_ag.shape, dtype=float) goat = np.zeros(map_rgn_ag.shape, dtype=float) sheep = np.zeros(map_rgn_ag.shape, dtype=float) poultry = np.zeros(map_rgn_ag.shape, dtype=float) pig = np.zeros(map_rgn_ag.shape, dtype=float) buffalo[GISData['mapindex']] = GISData['Buffalo'] cattle[GISData['mapindex']] = GISData['Cattle'] goat[GISData['mapindex']] = GISData['Goat'] sheep[GISData['mapindex']] = GISData['Sheep'] poultry[GISData['mapindex']] = GISData['Poultry'] pig[GISData['mapindex']] = GISData['Pig'] ls = np.where(map_rgn_ag > 0)[0] for index in ls: IN = map_rgn_ag[index] tot_livestock[IN - 1, 0] += buffalo[index] tot_livestock[IN - 1, 1] += cattle[index] tot_livestock[IN - 1, 2] += goat[index] tot_livestock[IN - 1, 3] += sheep[index] tot_livestock[IN - 1, 4] += poultry[index] tot_livestock[IN - 1, 5] += pig[index] # now create a spatial distribution for each GCAM region # withd_liv: these are the GCAM results of total volume of livestock water withdrawal in # km3 in each GCAM region per animal type in the years 1990, 2005:5:2095 # variables are nrgn GCAM regions x 6 animals (1:Buffalo, 2:Cattle, 3-Goat, 4-Sheep, 5-Poultry, 6-Pig) # # Next, we distribute those volumes using the spatial distribution of the gis maps # these will be the GIS downscaled matrices livestock = np.zeros((mapsize[0] * mapsize[1], 6), dtype=float) withd_liv_map = np.zeros((mapsize[0] * mapsize[1], NY), dtype=float) for y in range(0, NY): for index in ls: IN = map_rgn_ag[index] if buffalo[index] != 0: livestock[index, 0] = GCAMData['wdliv'][ 0 * nrgnAG + IN - 1, y] * buffalo[index] / tot_livestock[IN - 1, 0] if cattle[index] != 0: livestock[index, 1] = GCAMData['wdliv'][ 1 * nrgnAG + IN - 1, y] * cattle[index] / tot_livestock[IN - 1, 1] if goat[index] != 0: livestock[index, 2] = GCAMData['wdliv'][ 2 * nrgnAG + IN - 1, y] * goat[index] / tot_livestock[IN - 1, 2] if sheep[index] != 0: livestock[index, 3] = GCAMData['wdliv'][ 3 * nrgnAG + IN - 1, y] * sheep[index] / tot_livestock[IN - 1, 3] if poultry[index] != 0: livestock[index, 4] = GCAMData['wdliv'][ 4 * nrgnAG + IN - 1, y] * poultry[index] / tot_livestock[IN - 1, 4] if pig[index] != 0: livestock[index, 5] = GCAMData['wdliv'][ 5 * nrgnAG + IN - 1, y] * pig[index] / tot_livestock[IN - 1, 5] withd_liv_map[:, y] = np.sum(livestock, axis=1) OUT.wdliv = withd_liv_map fmtstr = '[Year Index, Region ID, {:7s} from GCAM not assigned (no GIS data)]: {} {} {}\n' dat = GCAMData['wdliv'] for y in range(0, NY): for IN in range(0, nrgnAG): if GCAMData['wdliv'][0 * nrgnAG + IN, y] > 0 and tot_livestock[IN, 0] == 0: mainlog.write( fmtstr.format('buffalo', y + 1, IN + 1, dat[0 * nrgnAG + IN, y])) if GCAMData['wdliv'][1 * nrgnAG + IN, y] > 0 and tot_livestock[IN, 1] == 0: mainlog.write( fmtstr.format('cattle', y + 1, IN + 1, dat[1 * nrgnAG + IN, y])) if GCAMData['wdliv'][2 * nrgnAG + IN, y] > 0 and tot_livestock[IN, 2] == 0: mainlog.write( fmtstr.format('goat', y + 1, IN + 1, dat[2 * nrgnAG + IN, y])) if GCAMData['wdliv'][3 * nrgnAG + IN, y] > 0 and tot_livestock[IN, 3] == 0: mainlog.write( fmtstr.format('sheep', y + 1, IN + 1, dat[3 * nrgnAG + IN, y])) if GCAMData['wdliv'][4 * nrgnAG + IN, y] > 0 and tot_livestock[IN, 4] == 0: mainlog.write( fmtstr.format('poultry', y + 1, IN + 1, dat[4 * nrgnAG + IN, y])) if GCAMData['wdliv'][5 * nrgnAG + IN, y] > 0 and tot_livestock[IN, 5] == 0: mainlog.write( fmtstr.format('pig', y + 1, IN + 1, dat[5 * nrgnAG + IN, y])) mainlog.setlevel(oldlvl) return withd_liv_map
def OutWriter(Settings, OUT, GISData): mainlog = Logger.getlogger() if Settings.OutputUnit: temp = 'mm' else: temp = 'km3' if Settings.OutputFormat == 1: mainlog.write( 'Save the gridded water usage results for each withdrawal category in CSV format (Unit: ' + temp + '/yr)\n', Logger.INFO) elif Settings.OutputFormat == 2: mainlog.write( 'Save the gridded water usage results for each withdrawal category in NetCDF format (Unit: ' + temp + '/yr)\n', Logger.INFO) else: mainlog.write( 'Save the gridded water usage results for each withdrawal category in CSV and NetCDF format (Unit: ' + temp + '/yr)\n', Logger.INFO) if Settings.PerformTemporal: TDMonthStr = np.chararray((len(Settings.TDYears) * 12, ), itemsize=6) for y in Settings.TDYears: N = Settings.TDYears.index(y) TDMonthStr[N * 12:(N + 1) * 12] = [str(y) + str(i).zfill(2) for i in range(1, 13)] mainlog.write( 'Save the monthly water usage results for each withdrawal category (Unit: ' + temp + '/month)\n', Logger.INFO) for attr in list(OUT.__dict__.keys()): value = OUT.__dict__[attr] if value is not None: OutputFilename = os.path.join(Settings.OutputFolder, attr) if attr[0] == "r": # regional output newvalue = value[:, :] #with open(OutputFilename + '.csv', 'w') as outfile: # np.savetxt(outfile, newvalue, delimiter=',') elif attr[0] == "w": # gridded output newvalue = value[GISData[ 'mapindex'], :] # Only output 67420 cells (with coordinates) if Settings.OutputFormat == 1: writecsv(OutputFilename, newvalue, Settings, temp, GISData) elif Settings.OutputFormat == 2: writeNETCDF(OutputFilename + '.nc', newvalue, GISData, temp, Settings.years) else: writecsv(OutputFilename, newvalue, Settings, temp, GISData) writeNETCDF(OutputFilename + '.nc', newvalue, GISData, temp, Settings.years) elif attr[0] == "t": # temporal downscaling output if Settings.OutputFormat == 1: writecsvMonthly(OutputFilename, value, TDMonthStr, temp, GISData) elif Settings.OutputFormat == 2: writeNETCDFmonthly(OutputFilename + '.nc', value, GISData, temp, TDMonthStr) else: writecsvMonthly(OutputFilename, value, TDMonthStr, temp, GISData) writeNETCDFmonthly(OutputFilename + '.nc', value, GISData, temp, TDMonthStr)