diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms index b6cd76f213b41e6827fac3c23c0b231872a292ac..ea7633f87f066438767b97df30803a5a4d549555 100644 --- a/GAMS/IntExtOpt.gms +++ b/GAMS/IntExtOpt.gms @@ -9,8 +9,8 @@ SET feed_crop_less_pasture(feed_crop) / wheat, maize, rice, oilcrops, pulses, starchyRoots, fruitveg /; SET import_crop(all_types) / monogastrics, ruminants, wheat, maize, rice, oilcrops, pulses, starchyRoots, fruitveg, sugar, energycrops/; - SET land_cover / cropland, pasture, timberForest, carbonForest, otherNatural /; - SET wood_producing / timberForest, carbonForest, otherNatural /; + SET land_cover / cropland, pasture, timberForest, carbonForest, natural /; +* SET wood_producing / timberForest, carbonForest, natural /; ALIAS (land_cover, land_cover_before); ALIAS (land_cover, land_cover_after); @@ -140,9 +140,9 @@ $gdxin totalFeedDM total_cost total cost of domestic supply including net imports; - POSITIVE VARIABLE cropArea, nonCropArea, fertI, irrigI, otherIntensity, ruminantFeed, monogastricFeed, importAmount, exportAmount, + POSITIVE VARIABLE cropArea, fertI, irrigI, otherIntensity, ruminantFeed, monogastricFeed, importAmount, exportAmount, agriLandExpansion, cropIncrease, cropDecrease, pastureDecrease, pastureIncrease, totalFeedDM, - woodHarvest, carbonFlux; + landCoverArea, landCoverChange, woodHarvest, carbonFlux; EQUATIONS UNIT_COST_EQ(crop, location) cost per area @@ -223,9 +223,6 @@ $gdxin PASTURE_IMPORT_CONSTRAINT .. importAmount('pasture') =E= 0; PASTURE_EXPORT_CONSTRAINT .. exportAmount('pasture') =E= 0; - MAX_NET_IMPORT_CONSTRAINT(import_crop) .. importAmount(import_crop) - exportAmount(import_crop) =L= maxNetImport(import_crop); - MIN_NET_IMPORT_CONSTRAINT(import_crop) .. importAmount(import_crop) - exportAmount(import_crop) =G= minNetImport(import_crop); - IRRIGATION_CONSTRAINT(location) .. irrigConstraint(location) * suitableLandArea(location) * (1.0 - unhandledCropRate) =G= sum(crop, irrigMaxRate(crop, location) * irrigI(crop, location) * cropArea(crop, location)); AGRI_LAND_EXPANSION_CALC(location) .. agriLandExpansion(location) =G= sum(crop, cropArea(crop, location) - previousCropArea(crop, location)); @@ -236,20 +233,20 @@ $gdxin PASTURE_DECREASE_CONV_CALC(location) .. pastureDecrease(location) =G= -(cropArea('pasture', location) - previousCropArea('pasture', location)); PASTURE_TOTAL_CHANGE_CONSTRAINT(location) .. pastureIncrease(location) -pastureDecrease(location) =G= cropArea('pasture', location) - previousCropArea('pasture', location); - CROPLAND_LAND_COVER_CAL(location) .. sum(land_cover, landCoverArea('cropland', location)) =E= sum(crop_less_pasture, cropArea(crop, location)) / (1.0 - unhandledCropRate); + CROPLAND_LAND_COVER_CALC(location) .. landCoverArea('cropland', location) =E= sum(crop_less_pasture, cropArea(crop_less_pasture, location)) / (1.0 - unhandledCropRate); - PASTURE_LAND_COVER_CAL(location) .. sum(land_cover, landCoverArea('pasture', location)) =E= cropArea('pasture', location); + PASTURE_LAND_COVER_CALC(location) .. landCoverArea('pasture', location) =E= cropArea('pasture', location); * MINIMUM_LAND_COVER_CONSTRAINT(location, land_cover) .. landCoverArea(land_cover, location)) =G= minimumLandCover(land_cover_after, location); - LAND_COVER_CHANGE_CALC(land_cover, location) .. landCoverArea(land_cover, location) =E= previousLandCover(land_cover, location) + - sum(land_cover_before, lcChange(land_cover_before, land_cover, location)) - sum(land_cover_after, lcChange(land_cover, land_cover_after, location)); + LAND_COVER_CHANGE_CALC(land_cover, location) .. landCoverArea(land_cover, location) =E= previousLandCoverArea(land_cover, location) + + sum(land_cover_before, landCoverChange(land_cover_before, land_cover, location)) - sum(land_cover_after, landCoverChange(land_cover, land_cover_after, location)); - LAND_COVER_CHANGE_CONSTRAINT(land_cover, location) .. sum(land_cover_after, landCoverChange(land_cover, land_cover_after, location)) =L= previousLandCover(land_cover, location); + LAND_COVER_CHANGE_CONSTRAINT(land_cover, location) .. sum(land_cover_after, landCoverChange(land_cover, land_cover_after, location)) =L= previousLandCoverArea(land_cover, location); * TOTAL_LAND_COVER_CONSTRAINT(location) .. sum(land_cover, landCoverArea(land_cover, location)) =E= suitableArea(location); - WOOD_HARVEST_CALC(location) .. woodHarvest(location) =E= sum((land_cover_before, land_cover_after, location), landCoverChange(land_cover_before, land_cover_after, location) * woodYield(land_cover_before, land_cover_after, location)); + WOOD_HARVEST_CALC(location) .. woodHarvest(location) =E= sum((land_cover_before, land_cover_after), landCoverChange(land_cover_before, land_cover_after, location) * woodYield(land_cover_before, land_cover_after, location)); CARBON_FLUX_CALC(location) .. carbonFlux(location) =E= sum((land_cover_before, land_cover_after), landCoverChange(land_cover_before, land_cover_after, location) * carbonFluxRate(land_cover_before, land_cover_after, location)); diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java index 859fc7e0f1caedb95fc34a9e0f2918e6ed27ed9c..8703013576acb0a8e3fe121ed5e10e19c2710b55 100755 --- a/src/ac/ed/lurg/ModelConfig.java +++ b/src/ac/ed/lurg/ModelConfig.java @@ -18,7 +18,8 @@ public class ModelConfig { private Properties configFile; private static ModelConfig modelConfig; - public static final String CONFIG_FILE = System.getProperty("CONFIG_FILE"); + //public static final String CONFIG_FILE = System.getProperty("CONFIG_FILE"); + public static final String CONFIG_FILE = "C:\\Users\\Bart\\git\\plumv2\\debug_config.properties"; private static StringTabularReader shocksReader; @@ -244,8 +245,11 @@ public class ModelConfig { public static final String YIELDSHOCKS_PARAMETER_FILE = getProperty("YIELDSHOCKS_PARAMETER_FILE", OUTPUT_DIR + File.separator+ "yieldshocks.csv"); public static final String PRICESHOCKS_PARAMETER_FILE = getProperty("PRICESHOCKS_PARAMETER_FILE", OUTPUT_DIR + File.separator+ "priceshocks.csv"); public static final String EXPORT_RESTRICTIONS_FILE = getProperty("EXPORT_RESTRICTIONS_FILE", OUTPUT_DIR + File.separator+ "exportrestictions.csv"); - public static final String CARBON_FLUX_FILE = SPATIAL_DATA_DIR + File.separator + "carbon_flux_"; - public static final String WOOD_YIELD_FILE = SPATIAL_DATA_DIR + File.separator + "wood_yield_"; + + // Wood/carbon data + public static final String FOREST_DIR = SPATIAL_DATA_DIR + File.separator + "forestry"; + //public static final String CARBON_FLUX_FILE = FOREST_DIR + File.separator + "carbon_flux_"; + //public static final String WOOD_YIELD_FILE = FOREST_DIR + File.separator + "wood_yield_"; // Output public static final String LAND_COVER_OUTPUT_FILE = OUTPUT_DIR + File.separator + "lc.txt"; diff --git a/src/ac/ed/lurg/ModelMain.java b/src/ac/ed/lurg/ModelMain.java index e8d6d12d0805f86337dc54f3cdeb09846dd314a1..e01d8ac4f9a04483df989dcf3d4951d88ad8b396 100644 --- a/src/ac/ed/lurg/ModelMain.java +++ b/src/ac/ed/lurg/ModelMain.java @@ -48,7 +48,6 @@ import ac.ed.lurg.output.LandUseOutputer; import ac.ed.lurg.output.LpjgOutputer; import ac.ed.lurg.types.CommodityType; import ac.ed.lurg.types.CropType; -import ac.ed.lurg.types.GamsLandCoverType; import ac.ed.lurg.types.LandCoverType; import ac.ed.lurg.utils.FileWriterHelper; import ac.ed.lurg.utils.LogWriter; @@ -142,6 +141,8 @@ public class ModelMain { double gen2Increase = (gen2EcDDemand>previousGen2EcDDemand) ? gen2EcDDemand - previousGen2EcDDemand : 0.0; CarbonFluxRasterSet currentCarbonFluxData = getCarbonFluxData(timestep); + LogWriter.println("Carbon flux data read"); + LogWriter.println("Data: " + currentCarbonFluxData.get(1, 1).getCarbonFluxes()); WoodYieldRasterSet currentWoodYieldData = getWoodYieldData(timestep); countryAgents.determineProductionForAll(timestep, yieldSurfaces, currentIrrigationData, gen2Increase, currentCarbonFluxData, currentWoodYieldData); @@ -187,7 +188,31 @@ public class ModelMain { LogWriter.print(e); } } + +/* + private void writeGamsLandCoverFile(Timestep timestep, RasterSet<LandUseItem> landUseRaster) { + try { + StringBuffer sbHeadings = new StringBuffer("Year,Cropland,Pasture,timberForest,carbonForest,Natural"); + BufferedWriter outputFile = FileWriterHelper.getFileWriter(timestep, ModelConfig.LAND_COVER_OUTPUT_FILE, sbHeadings.toString()); + + StringBuffer sbData = new StringBuffer(); + sbData.append(String.format("%d,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f", timestep.getYear(), + LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.CROPLAND), + LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.PASTURE), + LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.TIMBER_FOREST), + LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.CARBON_FOREST), + LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.NATURAL) + )); + + outputFile.write(sbData.toString()); + outputFile.newLine(); + outputFile.close(); + } catch (IOException e) { + LogWriter.print(e); + } + } +*/ private void writeGlobalMarketFile(Timestep timestep) { try { BufferedWriter outputFile = FileWriterHelper.getFileWriter(timestep, ModelConfig.PRICES_OUTPUT_FILE, "Year,Crop,Imports (Mt),Exports (Mt),New export price, Stock Levels (Mt)"); @@ -610,11 +635,9 @@ public class ModelMain { // Set initial GAMS land covers for (LandUseItem item : landUseRaster.values()) { - item.setGamsLandCoverArea(GamsLandCoverType.CROPLAND, item.getLandCoverArea(LandCoverType.CROPLAND)); - item.setGamsLandCoverArea(GamsLandCoverType.PASTURE, item.getLandCoverArea(LandCoverType.PASTURE)); - item.setGamsLandCoverArea(GamsLandCoverType.TIMBER_FOREST, item.getLandCoverArea(LandCoverType.MANAGED_FOREST)); - item.setGamsLandCoverArea(GamsLandCoverType.CARBON_FOREST, 0.0); - item.setGamsLandCoverArea(GamsLandCoverType.OTHER_NATURAL, item.getLandCoverArea(LandCoverType.OTHER_NATURAL) + item.getLandCoverArea(LandCoverType.UNMANAGED_FOREST)); + item.setLandCoverArea(LandCoverType.TIMBER_FOREST, item.getLandCoverArea(LandCoverType.MANAGED_FOREST)); + item.setLandCoverArea(LandCoverType.CARBON_FOREST, 0.0); + item.setLandCoverArea(LandCoverType.NATURAL, item.getLandCoverArea(LandCoverType.OTHER_NATURAL) + item.getLandCoverArea(LandCoverType.UNMANAGED_FOREST)); } return landUseRaster; @@ -640,14 +663,14 @@ public class ModelMain { /** Get carbon flux data */ private CarbonFluxRasterSet getCarbonFluxData(Timestep timestep) { CarbonFluxRasterSet carbonFluxData = new CarbonFluxRasterSet(desiredProjection); - new CarbonFluxReader(carbonFluxData).getRasterDataFromFile(ModelConfig.CARBON_FLUX_FILE + timestep.getYieldYear() + ".out"); + new CarbonFluxReader(carbonFluxData).getRasterDataFromFile(timestep.getYearSubDir(ModelConfig.FOREST_DIR) + File.separator + "cflux_net.out"); return carbonFluxData; } /** Get carbon wood yield data */ private WoodYieldRasterSet getWoodYieldData(Timestep timestep) { WoodYieldRasterSet woodYieldData = new WoodYieldRasterSet(desiredProjection); - new WoodYieldReader(woodYieldData).getRasterDataFromFile(ModelConfig.WOOD_YIELD_FILE + timestep.getYieldYear() + ".out"); + new WoodYieldReader(woodYieldData).getRasterDataFromFile(timestep.getYearSubDir(ModelConfig.FOREST_DIR) + File.separator + "wood_yield.out"); return woodYieldData; } diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java index c13a265d968e52ea6a3bf838405e020121acc6d6..616dc301fae2324dda673c220955bb110009a29f 100644 --- a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java +++ b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java @@ -31,7 +31,6 @@ import ac.ed.lurg.landuse.LandUseItem; import ac.ed.lurg.landuse.WoodYieldItem; import ac.ed.lurg.types.CommodityType; import ac.ed.lurg.types.CropType; -import ac.ed.lurg.types.GamsLandCoverType; import ac.ed.lurg.types.LandCoverType; import ac.ed.lurg.types.Parameter; import ac.ed.lurg.types.YieldType; @@ -71,14 +70,16 @@ public class GamsLocationOptimiser { opt.defines("gdxincname", inDB.getName()); long startTime = System.currentTimeMillis(); - gamsJob.run(opt, inDB); + gamsJob.run(opt, inDB); if (ModelConfig.CLEANUP_GAMS_DIR) cleanup(ws.workingDirectory()); LogWriter.println("Took " + (System.currentTimeMillis() - startTime) + " ms to run"); + return handleResults(gamsJob.OutDB()); + } private void setupInDB(GAMSDatabase inDB) { @@ -168,11 +169,11 @@ public class GamsLocationOptimiser { } // Previous land covers - for (GamsLandCoverType lc : GamsLandCoverType.values()) { + for (LandCoverType lc : LandCoverType.getGamsTypes()) { Vector<String> v = new Vector<String>(); v.add(lc.getName()); v.add(locString); - setGamsParamValue(prevLandCoverP.addRecord(v), landUseItem.getGamsLandCoverArea(lc), 3); + setGamsParamValue(prevLandCoverP.addRecord(v), landUseItem.getLandCoverArea(lc), 3); } } @@ -348,8 +349,8 @@ public class GamsLocationOptimiser { String locString = Integer.toString(locationId); CarbonFluxItem cFlux = entry.getValue(); - for (GamsLandCoverType prevLC : GamsLandCoverType.values()) { - for (GamsLandCoverType newLC : GamsLandCoverType.values()) { + for (LandCoverType prevLC : LandCoverType.getGamsTypes()) { + for (LandCoverType newLC : LandCoverType.getGamsTypes()) { Vector<String> v = new Vector<String>(); v.add(prevLC.getName()); v.add(newLC.getName()); @@ -368,8 +369,8 @@ public class GamsLocationOptimiser { String locString = Integer.toString(locationId); WoodYieldItem wYield = entry.getValue(); - for (GamsLandCoverType prevLC : GamsLandCoverType.values()) { - for (GamsLandCoverType newLC : GamsLandCoverType.values()) { + for (LandCoverType prevLC : LandCoverType.getGamsTypes()) { + for (LandCoverType newLC : LandCoverType.getGamsTypes()) { Vector<String> v = new Vector<String>(); v.add(prevLC.getName()); v.add(newLC.getName()); @@ -508,10 +509,10 @@ public class GamsLocationOptimiser { totalCropArea+totalPastureArea, totalCropArea, totalPastureArea)); - // Land cover areas + // Land cover areas (exc. cropland and pasture) GAMSVariable varLandCoverArea = outDB.getVariable("landCoverArea"); double landCoverArea; - + for (GAMSVariableRecord rec : varLandCoverArea) { String lc = rec.getKeys()[0]; String locationName = rec.getKeys()[1]; @@ -521,11 +522,44 @@ public class GamsLocationOptimiser { LandUseItem landUseItem = landUses.lazyGet(locId); - landUseItem.setGamsLandCoverArea(GamsLandCoverType.getForName(lc), landCoverArea); + switch(lc) { + case "forestT": + landUseItem.setLandCoverArea(LandCoverType.TIMBER_FOREST, landCoverArea); + break; + case "forestC": + landUseItem.setLandCoverArea(LandCoverType.CARBON_FOREST, landCoverArea); + break; + case "natural": + landUseItem.setLandCoverArea(LandCoverType.NATURAL, landCoverArea); + break; + } + + } + + // Land cover change + GAMSVariable varLandCoverChange = outDB.getVariable("landCoverChange"); + + Map<Integer, Map<LandCoverType, Map<LandCoverType, Double>>> landCoverChange = new HashMap<Integer, Map<LandCoverType, Map<LandCoverType, Double>>>(); + + for (GAMSVariableRecord rec : varLandCoverChange) { + String fromLC = rec.getKeys()[0]; + String toLC = rec.getKeys()[1]; + String locationName = rec.getKeys()[2]; + int locId = Integer.parseInt(locationName); + + double change = rec.getLevel(); + + Map<LandCoverType, Double> toMap = new HashMap<LandCoverType, Double>(); + toMap.put(LandCoverType.getForName(toLC), change); + + Map<LandCoverType, Map<LandCoverType, Double>> fromMap = new HashMap<LandCoverType, Map<LandCoverType, Double>>(); + fromMap.put(LandCoverType.getForName(fromLC), toMap); + + landCoverChange.put(locId, fromMap); } - GamsLocationOutput results = new GamsLocationOutput(modelStatus, landUses, cropUsageData); + GamsLocationOutput results = new GamsLocationOutput(modelStatus, landUses, cropUsageData, landCoverChange); return results; } diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOutput.java b/src/ac/ed/lurg/country/gams/GamsLocationOutput.java index 48c7ccfd08c2d834ee673a7efeab75c45d7232fe..f750626770b92f66dbe035c9fafb10ca21429431 100644 --- a/src/ac/ed/lurg/country/gams/GamsLocationOutput.java +++ b/src/ac/ed/lurg/country/gams/GamsLocationOutput.java @@ -1,5 +1,6 @@ package ac.ed.lurg.country.gams; +import java.util.HashMap; import java.util.Map; import com.gams.api.GAMSGlobals.ModelStat; @@ -7,20 +8,24 @@ import com.gams.api.GAMSGlobals.ModelStat; import ac.ed.lurg.landuse.CropUsageData; import ac.ed.lurg.landuse.LandUseItem; import ac.ed.lurg.types.CropType; +import ac.ed.lurg.types.LandCoverType; public class GamsLocationOutput { ModelStat status; Map<Integer, LandUseItem> landUses; // data mapped from id (not raster) private Map<CropType, CropUsageData> cropUsageData; + Map<Integer, Map<LandCoverType, Map<LandCoverType, Double>>> landCoverChange = new HashMap<Integer, Map<LandCoverType, Map<LandCoverType, Double>>>(); public GamsLocationOutput(ModelStat status, Map<Integer, LandUseItem> landUses, - Map<CropType, CropUsageData> cropUsageData) { + Map<CropType, CropUsageData> cropUsageData, + Map<Integer, Map<LandCoverType, Map<LandCoverType, Double>>> landCoverChange) { super(); this.status = status; this.landUses = landUses; this.cropUsageData = cropUsageData; + this.landCoverChange = landCoverChange; } public ModelStat getStatus() { @@ -33,4 +38,8 @@ public class GamsLocationOutput { public Map<CropType, CropUsageData> getCommoditiesData() { return cropUsageData; } + + public Map<Integer, Map<LandCoverType, Map<LandCoverType, Double>>> getLandCoverChange() { + return landCoverChange; + } } diff --git a/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java b/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java index 23511eec9008d441632e20f371bad387550831b8..f5f18ff404be173ab91daeb38c88c4d222bbbff3 100644 --- a/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java +++ b/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java @@ -5,14 +5,12 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import ac.ed.lurg.ModelConfig; import ac.ed.lurg.landuse.CarbonFluxItem; import ac.ed.lurg.landuse.Intensity; import ac.ed.lurg.landuse.IrrigationItem; import ac.ed.lurg.landuse.LandUseItem; import ac.ed.lurg.landuse.WoodYieldItem; import ac.ed.lurg.types.CropType; -import ac.ed.lurg.types.GamsLandCoverType; import ac.ed.lurg.types.LandCoverType; import ac.ed.lurg.types.YieldType; import ac.ed.lurg.utils.LazyTreeMap; @@ -100,7 +98,7 @@ public class GamsRasterOptimiser { for (Map.Entry<Integer, LandUseItem> entry : gamsOutput.getLandUses().entrySet()) { Integer locId = entry.getKey(); LandUseItem newLandUseAggItem = entry.getValue(); - LandUseItem prevLandUseAggItem = prevAreasAgg.get(locId); +// LandUseItem prevLandUseAggItem = prevAreasAgg.get(locId); Set<RasterKey> keys = new HashSet<RasterKey>(); for (Entry<RasterKey, IntegerRasterItem> mapEntry : mapping.entrySet()) { @@ -109,7 +107,36 @@ public class GamsRasterOptimiser { if (iri != null && locId == iri.getInt()) keys.add(mapEntry.getKey()); } - + + // Allocate land cover change to grid cells + // pasture, cropland, carbonForest, timberForest, natural + Map<Integer, Map<LandCoverType, Map<LandCoverType, Double>>> landCoverChange = gamsOutput.getLandCoverChange(); + + for (LandCoverType fromLC : LandCoverType.getGamsTypes()) { + for (LandCoverType toLC : LandCoverType.getGamsTypes()) { + double change = landCoverChange.get(locId).get(fromLC).get(toLC); + allocAllLandCropsTop(newLandUseRaster, keys, toLC, fromLC, change, locId); + } + } + + // Allocate derived land cover areas + // managedForest, unmanagedForest, otherNatural + for (RasterKey key : keys) { + LandUseItem newLandUseItem = newLandUseRaster.get(key); + LandUseItem prevLandUseItem = rasterInputData.getPreviousLandUses().get(key); + + if (newLandUseItem != null) { + newLandUseItem.setLandCoverArea(LandCoverType.MANAGED_FOREST, newLandUseItem.getLandCoverArea(LandCoverType.TIMBER_FOREST) + newLandUseItem.getLandCoverArea(LandCoverType.CARBON_FOREST)); + + double prevUnmanagedForest = prevLandUseItem.getLandCoverArea(LandCoverType.UNMANAGED_FOREST); + double prevOtherNatural = prevLandUseItem.getLandCoverArea(LandCoverType.OTHER_NATURAL); + double prevUnmanagedForestToNaturalProp = (prevOtherNatural > 0 || prevUnmanagedForest > 0) ? prevUnmanagedForest / (prevOtherNatural + prevUnmanagedForest) : 0.5; + newLandUseItem.setLandCoverArea(LandCoverType.UNMANAGED_FOREST, newLandUseItem.getLandCoverArea(LandCoverType.NATURAL) * prevUnmanagedForestToNaturalProp); + newLandUseItem.setLandCoverArea(LandCoverType.OTHER_NATURAL, newLandUseItem.getLandCoverArea(LandCoverType.NATURAL) * (1 - prevUnmanagedForestToNaturalProp)); + + } + } +/* double gamsPastureChange = newLandUseAggItem.getLandCoverArea(LandCoverType.PASTURE) - prevLandUseAggItem.getLandCoverArea(LandCoverType.PASTURE); double gamsCroplandChange = newLandUseAggItem.getLandCoverArea(LandCoverType.CROPLAND) - prevLandUseAggItem.getLandCoverArea(LandCoverType.CROPLAND); RasterSet<LandUseItem> landUseItemsForLocation = newLandUseRaster.createSubsetForKeys(keys); @@ -185,7 +212,7 @@ public class GamsRasterOptimiser { double totalPastureChange = protectedAreasPastureChange + gamsPastureChange; double totalCroplandChange = protectedAreasCroplandChange + gamsCroplandChange; - + double pastureFromCrop = 0; double pastureFromNatural = 0; double cropFromNatural = 0; @@ -230,7 +257,7 @@ public class GamsRasterOptimiser { allocAllLandCropsTop(newLandUseRaster, keys, LandCoverType.CROPLAND, LandCoverType.OTHER_NATURAL, cropFromNatural * (1-prevForestToNaturalFraction), locId); if (DEBUG) checkedTotalAreas(landUseItemsForLocation, locId + " after"); - +*/ for (RasterKey key : keys) { LandUseItem newLandUseItem = newLandUseRaster.get(key); if (newLandUseItem != null) { @@ -241,48 +268,16 @@ public class GamsRasterOptimiser { } } - } - - return newLandUseRaster; - } -/* - private void allocGamsLandCovers(RasterSet<LandUseItem> newLandUseRaster, Set<RasterKey> keys, GamsLandCoverType toLC, GamsLandCoverType fromLC, double change) { - GamsLandCoverType toType = toLC; - GamsLandCoverType fromType = fromLC; + - // reverse direction if negative - if (change < 0) { - change = -change; - toType = fromLC; - fromType = toLC; } - double totalShortfall = 0; - Set<RasterKey> keysWithSpace = new HashSet<RasterKey>(); - double totalUnprotectedLC = 0; - - for (RasterKey key : keys) { - LandUseItem newLandUseItem = newLandUseRaster.get(key); - totalUnprotectedLC += newLandUseItem.getUnprotectedLandCoverArea(fromType); - } - for (RasterKey key : keys) { - //if (DEBUG) LogWriter.println(" Processing raster key " + key); - LandUseItem newLandUseItem = newLandUseRaster.get(key); - - if (newLandUseItem!=null) { - double cellChange = (fromType.isProtectable() && totalUnprotectedLC > 0) ? change * newLandUseItem.getUnprotectedLandCoverArea(fromType)/totalUnprotectedLC : change / keys.size(); - double shortfall = newLandUseItem.moveAreas(toType, fromType, cellChange); - if (shortfall == 0) - keysWithSpace.add(key); - else - totalShortfall += shortfall; - } - } + + return newLandUseRaster; } -*/ private void allocAllLandCropsTop(RasterSet<LandUseItem> newLandUseRaster, Set<RasterKey> keys, LandCoverType toLC, LandCoverType fromLC, double change, Integer locId) { LandCoverType toType = toLC; @@ -459,13 +454,25 @@ public class GamsRasterOptimiser { } // Aggregate carbon fluxes and wood yields - for (GamsLandCoverType prevLC : GamsLandCoverType.values()) { - for (GamsLandCoverType newLC : GamsLandCoverType.values()) { - aggCFlux.setCarbonFlux(prevLC, newLC, aggregateMean(aggCFlux.getCarbonFlux(prevLC, newLC), suitableAreaSoFar, - carbonFluxItem.getCarbonFlux(prevLC, newLC), suitableAreaThisTime)); + for (LandCoverType prevLC : LandCoverType.getGamsTypes()) { + for (LandCoverType newLC : LandCoverType.getGamsTypes()) { + + if (!aggCFlux.checkForKeys(prevLC, newLC)) { // if not seen yet + //LogWriter.println("prevLC: " + prevLC + ", newLC: " + newLC); + //LogWriter.println("Data: " + carbonFluxItem.getCarbonFluxes()); + aggCFlux.setCarbonFlux(prevLC, newLC, carbonFluxItem.getCarbonFlux(prevLC, newLC)); + } else { + aggCFlux.setCarbonFlux(prevLC, newLC, aggregateMean(aggCFlux.getCarbonFlux(prevLC, newLC), suitableAreaSoFar, + carbonFluxItem.getCarbonFlux(prevLC, newLC), suitableAreaThisTime)); + } + + if (!aggWYield.checkForKeys(prevLC, newLC)) { + aggWYield.setWoodYield(prevLC, newLC, woodYieldItem.getWoodYield(prevLC, newLC)); + } else { + aggWYield.setWoodYield(prevLC, newLC, aggregateMean(aggWYield.getWoodYield(prevLC, newLC), suitableAreaSoFar, + woodYieldItem.getWoodYield(prevLC, newLC), suitableAreaThisTime)); + } - aggWYield.setWoodYield(prevLC, newLC, aggregateMean(aggWYield.getWoodYield(prevLC, newLC), suitableAreaSoFar, - woodYieldItem.getWoodYield(prevLC, newLC), suitableAreaThisTime)); } } @@ -532,12 +539,14 @@ public class GamsRasterOptimiser { aggLandUse.setLandCoverArea(landType, areaSoFar + areaThisTime); } + /* // Gams land cover areas for (GamsLandCoverType landType : GamsLandCoverType.values()) { double areaThisTime = landUseItem.getGamsLandCoverArea(landType); double areaSoFar = aggLandUse.getGamsLandCoverArea(landType); aggLandUse.setGamsLandCoverArea(landType, areaSoFar + areaThisTime); } + */ } } diff --git a/src/ac/ed/lurg/landuse/CarbonFluxItem.java b/src/ac/ed/lurg/landuse/CarbonFluxItem.java index 4aa1ae4187f4333f4373486f27659a72a6a14672..ce7452d61ef1f98bdc2219cbe10043514e9e9eef 100644 --- a/src/ac/ed/lurg/landuse/CarbonFluxItem.java +++ b/src/ac/ed/lurg/landuse/CarbonFluxItem.java @@ -4,19 +4,40 @@ import ac.sac.raster.RasterItem; import java.util.HashMap; import java.util.Map; -import ac.ed.lurg.types.GamsLandCoverType; +import ac.ed.lurg.types.LandCoverType; public class CarbonFluxItem implements RasterItem { - Map<GamsLandCoverType, Map<GamsLandCoverType, Double>> carbonFluxes = new HashMap<GamsLandCoverType, Map<GamsLandCoverType, Double>>(); + Map<LandCoverType, Map<LandCoverType, Double>> carbonFluxes = new HashMap<LandCoverType, Map<LandCoverType, Double>>(); - public void setCarbonFlux(GamsLandCoverType previousLandCover, GamsLandCoverType newLandCover, double carbonFlux) { - Map<GamsLandCoverType, Double> cfMap = new HashMap<GamsLandCoverType, Double>(); - cfMap.put(newLandCover, carbonFlux); - carbonFluxes.put(previousLandCover, cfMap); + public void setCarbonFlux(LandCoverType previousLandCover, LandCoverType newLandCover, double carbonFlux) { + + if (carbonFluxes.containsKey(previousLandCover)) { + carbonFluxes.get(previousLandCover).put(newLandCover, carbonFlux); + } else { + Map<LandCoverType, Double> cfMap = new HashMap<LandCoverType, Double>(); + cfMap.put(newLandCover, carbonFlux); + carbonFluxes.put(previousLandCover, cfMap); + } } - public Double getCarbonFlux(GamsLandCoverType previousLandCover, GamsLandCoverType newLandCover) { + public double getCarbonFlux(LandCoverType previousLandCover, LandCoverType newLandCover) { return carbonFluxes.get(previousLandCover).get(newLandCover); } + + public boolean checkForKeys(LandCoverType previousLandCover, LandCoverType newLandCover) { + if (carbonFluxes.containsKey(previousLandCover)) { + if (carbonFluxes.get(previousLandCover).containsKey(newLandCover)) { + return true; + } else { + return false; + } + } else { + return false; + } + } + + public Map<LandCoverType, Map<LandCoverType, Double>> getCarbonFluxes() { + return carbonFluxes; + } } diff --git a/src/ac/ed/lurg/landuse/CarbonFluxReader.java b/src/ac/ed/lurg/landuse/CarbonFluxReader.java index d5d1087d1e3d067888d4f6bb3e0ef68233644745..b79d5e933bca64cd0d6c20ff0ee6d02b12f17ce8 100644 --- a/src/ac/ed/lurg/landuse/CarbonFluxReader.java +++ b/src/ac/ed/lurg/landuse/CarbonFluxReader.java @@ -2,14 +2,14 @@ package ac.ed.lurg.landuse; import java.util.Map; -import ac.ed.lurg.types.GamsLandCoverType; +import ac.ed.lurg.types.LandCoverType; import ac.sac.raster.AbstractTabularRasterReader; import ac.sac.raster.RasterKey; import ac.sac.raster.RasterSet; public class CarbonFluxReader extends AbstractTabularRasterReader<CarbonFluxItem> { - private static final int MIN_COLS = 18; + private static final int MIN_COLS = 27; public CarbonFluxReader(RasterSet<CarbonFluxItem> carbonFluxes) { super("[ |\t]+", MIN_COLS, carbonFluxes); @@ -17,30 +17,35 @@ public class CarbonFluxReader extends AbstractTabularRasterReader<CarbonFluxItem @Override protected void setData(RasterKey key, CarbonFluxItem item, Map<String, Double> rowValues) { - item.setCarbonFlux(GamsLandCoverType.CROPLAND, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "crop_to_ntrl")); - item.setCarbonFlux(GamsLandCoverType.CROPLAND, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "crop_to_forT")); - item.setCarbonFlux(GamsLandCoverType.CROPLAND, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "crop_to_forC")); - item.setCarbonFlux(GamsLandCoverType.CROPLAND, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "crop_to_past")); + item.setCarbonFlux(LandCoverType.CROPLAND, LandCoverType.NATURAL, getValueForCol(rowValues, "crop_to_ntrl")); + item.setCarbonFlux(LandCoverType.CROPLAND, LandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "crop_to_forT")); + item.setCarbonFlux(LandCoverType.CROPLAND, LandCoverType.CARBON_FOREST, getValueForCol(rowValues, "crop_to_forC")); + item.setCarbonFlux(LandCoverType.CROPLAND, LandCoverType.PASTURE, getValueForCol(rowValues, "crop_to_past")); + item.setCarbonFlux(LandCoverType.CROPLAND, LandCoverType.CROPLAND, getValueForCol(rowValues, "crop_to_crop")); - item.setCarbonFlux(GamsLandCoverType.PASTURE, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "past_to_ntrl")); - item.setCarbonFlux(GamsLandCoverType.PASTURE, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "past_to_forT")); - item.setCarbonFlux(GamsLandCoverType.PASTURE, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "past_to_forC")); - item.setCarbonFlux(GamsLandCoverType.PASTURE, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "past_to_crop")); + item.setCarbonFlux(LandCoverType.PASTURE, LandCoverType.NATURAL, getValueForCol(rowValues, "past_to_ntrl")); + item.setCarbonFlux(LandCoverType.PASTURE, LandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "past_to_forT")); + item.setCarbonFlux(LandCoverType.PASTURE, LandCoverType.CARBON_FOREST, getValueForCol(rowValues, "past_to_forC")); + item.setCarbonFlux(LandCoverType.PASTURE, LandCoverType.CROPLAND, getValueForCol(rowValues, "past_to_crop")); + item.setCarbonFlux(LandCoverType.PASTURE, LandCoverType.PASTURE, getValueForCol(rowValues, "past_to_past")); - item.setCarbonFlux(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "ntrl_to_past")); - item.setCarbonFlux(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "ntrl_to_forT")); - item.setCarbonFlux(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "ntrl_to_forC")); - item.setCarbonFlux(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "ntrl_to_crop")); + item.setCarbonFlux(LandCoverType.NATURAL, LandCoverType.PASTURE, getValueForCol(rowValues, "ntrl_to_past")); + item.setCarbonFlux(LandCoverType.NATURAL, LandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "ntrl_to_forT")); + item.setCarbonFlux(LandCoverType.NATURAL, LandCoverType.CARBON_FOREST, getValueForCol(rowValues, "ntrl_to_forC")); + item.setCarbonFlux(LandCoverType.NATURAL, LandCoverType.CROPLAND, getValueForCol(rowValues, "ntrl_to_crop")); + item.setCarbonFlux(LandCoverType.NATURAL, LandCoverType.NATURAL, getValueForCol(rowValues, "ntrl_to_ntrl")); - item.setCarbonFlux(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "forT_to_past")); - item.setCarbonFlux(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "forT_to_ntrl")); - item.setCarbonFlux(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "forT_to_forC")); - item.setCarbonFlux(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "forT_to_crop")); + item.setCarbonFlux(LandCoverType.TIMBER_FOREST, LandCoverType.PASTURE, getValueForCol(rowValues, "forT_to_past")); + item.setCarbonFlux(LandCoverType.TIMBER_FOREST, LandCoverType.NATURAL, getValueForCol(rowValues, "forT_to_ntrl")); + item.setCarbonFlux(LandCoverType.TIMBER_FOREST, LandCoverType.CARBON_FOREST, getValueForCol(rowValues, "forT_to_forC")); + item.setCarbonFlux(LandCoverType.TIMBER_FOREST, LandCoverType.CROPLAND, getValueForCol(rowValues, "forT_to_crop")); + item.setCarbonFlux(LandCoverType.TIMBER_FOREST, LandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "forT_to_forT")); - item.setCarbonFlux(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "forC_to_past")); - item.setCarbonFlux(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "forC_to_ntrl")); - item.setCarbonFlux(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "forC_to_forT")); - item.setCarbonFlux(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "forC_to_crop")); + item.setCarbonFlux(LandCoverType.CARBON_FOREST, LandCoverType.PASTURE, getValueForCol(rowValues, "forC_to_past")); + item.setCarbonFlux(LandCoverType.CARBON_FOREST, LandCoverType.NATURAL, getValueForCol(rowValues, "forC_to_ntrl")); + item.setCarbonFlux(LandCoverType.CARBON_FOREST, LandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "forC_to_forT")); + item.setCarbonFlux(LandCoverType.CARBON_FOREST, LandCoverType.CROPLAND, getValueForCol(rowValues, "forC_to_crop")); + item.setCarbonFlux(LandCoverType.CARBON_FOREST, LandCoverType.CARBON_FOREST, getValueForCol(rowValues, "forC_to_forC")); } diff --git a/src/ac/ed/lurg/landuse/LandUseItem.java b/src/ac/ed/lurg/landuse/LandUseItem.java index a01d32a4da168546c64ef4a1ea0b8958dc70db57..f30e7b0673d27347d5b07f8c387a8479626e0b42 100644 --- a/src/ac/ed/lurg/landuse/LandUseItem.java +++ b/src/ac/ed/lurg/landuse/LandUseItem.java @@ -8,7 +8,6 @@ import java.util.Map; import ac.ed.lurg.ModelConfig; import ac.ed.lurg.types.CropToDouble; import ac.ed.lurg.types.CropType; -import ac.ed.lurg.types.GamsLandCoverType; import ac.ed.lurg.types.LandCoverType; import ac.ed.lurg.utils.Interpolator; import ac.sac.raster.InterpolatingRasterItem; @@ -20,7 +19,7 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial private Map<CropType, Double> cropFractions = new HashMap<CropType, Double>(); private Map<LandCoverType, Double> landCoverAreas = new HashMap<LandCoverType, Double>(); private Map<LandCoverType, Double> unprotectedAreas = new HashMap<LandCoverType, Double>(); - private Map<GamsLandCoverType, Double> gamsLandCoverAreas = new HashMap<GamsLandCoverType, Double>(); + //private Map<GamsLandCoverType, Double> gamsLandCoverAreas = new HashMap<GamsLandCoverType, Double>(); private double protectedArea; //protected area in Mha private double unavailableArea; //area unavailable due to altitude etc private double suitableArea; @@ -251,7 +250,7 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial public double getTotalLandCoverArea() { double d = 0; - for (LandCoverType l : LandCoverType.values()) + for (LandCoverType l : LandCoverType.getLuhTypes()) d += getLandCoverArea(l); return d; @@ -288,7 +287,7 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial public double getTotalUnprotectedNatural() { double unprotectedNatural = 0; - for (LandCoverType landType : LandCoverType.values()) { + for (LandCoverType landType : LandCoverType.getLuhTypes()) { if (landType.isProtectable()) { unprotectedNatural += unprotectedAreas.get(landType); } @@ -428,7 +427,7 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial return total; } - + /* public double getGamsLandCoverArea(GamsLandCoverType landCoverType) { return gamsLandCoverAreas.get(landCoverType); } @@ -442,7 +441,8 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial gamsLandCoverAreas.put(c, landCover); } - /** move areas from one land cover to another, return any residual not possible */ + + // move areas from one land cover to another, return any residual not possible public void moveGamsAreas(GamsLandCoverType toType, GamsLandCoverType fromType, double changeReq) { double prevTo = getGamsLandCoverArea(toType); @@ -452,7 +452,7 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial setGamsLandCoverArea(fromType, prevFrom - changeReq); } - + */ @Override public String toString() { return "LandUseItem: [landCoverAreas=" + landCoverAreas + ", protectedArea=" + protectedArea + ", unavailableArea=" + unavailableArea + "]"; diff --git a/src/ac/ed/lurg/landuse/WoodYieldItem.java b/src/ac/ed/lurg/landuse/WoodYieldItem.java index 04eef0a1f5b45725773db303da8f5a50c63af210..3da2875900ce54598fe1ee17c7d82b09491d24e9 100644 --- a/src/ac/ed/lurg/landuse/WoodYieldItem.java +++ b/src/ac/ed/lurg/landuse/WoodYieldItem.java @@ -3,19 +3,36 @@ package ac.ed.lurg.landuse; import java.util.HashMap; import java.util.Map; -import ac.ed.lurg.types.GamsLandCoverType; +import ac.ed.lurg.types.LandCoverType; import ac.sac.raster.RasterItem; public class WoodYieldItem implements RasterItem { - Map<GamsLandCoverType, Map<GamsLandCoverType, Double>> woodYields = new HashMap<GamsLandCoverType, Map<GamsLandCoverType, Double>>(); + Map<LandCoverType, Map<LandCoverType, Double>> woodYields = new HashMap<LandCoverType, Map<LandCoverType, Double>>(); - public void setWoodYield(GamsLandCoverType previousLandCover, GamsLandCoverType newLandCover, double woodYield) { - Map<GamsLandCoverType, Double> cfMap = new HashMap<GamsLandCoverType, Double>(); - cfMap.put(newLandCover, woodYield); - woodYields.put(previousLandCover, cfMap); + public void setWoodYield(LandCoverType previousLandCover, LandCoverType newLandCover, double woodYield) { + if (woodYields.containsKey(previousLandCover)) { + woodYields.get(previousLandCover).put(newLandCover, woodYield); + } else { + Map<LandCoverType, Double> cfMap = new HashMap<LandCoverType, Double>(); + cfMap.put(newLandCover, woodYield); + woodYields.put(previousLandCover, cfMap); + } } - public Double getWoodYield(GamsLandCoverType previousLandCover, GamsLandCoverType newLandCover) { + public double getWoodYield(LandCoverType previousLandCover, LandCoverType newLandCover) { return woodYields.get(previousLandCover).get(newLandCover); } + + public boolean checkForKeys(LandCoverType previousLandCover, LandCoverType newLandCover) { + if (woodYields.containsKey(previousLandCover)) { + if (woodYields.get(previousLandCover).containsKey(newLandCover)) { + return true; + } else { + return false; + } + } else { + return false; + } + } + } diff --git a/src/ac/ed/lurg/landuse/WoodYieldReader.java b/src/ac/ed/lurg/landuse/WoodYieldReader.java index b8b5a99f8b8102bd42308c5a8159f27b64ef0b2b..7c693c54036a4cfaf3dcece71f3f9bbe0068f360 100644 --- a/src/ac/ed/lurg/landuse/WoodYieldReader.java +++ b/src/ac/ed/lurg/landuse/WoodYieldReader.java @@ -2,44 +2,49 @@ package ac.ed.lurg.landuse; import java.util.Map; -import ac.ed.lurg.types.GamsLandCoverType; +import ac.ed.lurg.types.LandCoverType; import ac.sac.raster.AbstractTabularRasterReader; import ac.sac.raster.RasterKey; import ac.sac.raster.RasterSet; public class WoodYieldReader extends AbstractTabularRasterReader<WoodYieldItem> { - private static final int MIN_COLS = 18; + private static final int MIN_COLS = 27; public WoodYieldReader(RasterSet<WoodYieldItem> woodYield) { super("[ |\t]+", MIN_COLS, woodYield); } protected void setData(RasterKey key, WoodYieldItem item, Map<String, Double> rowValues) { - item.setWoodYield(GamsLandCoverType.CROPLAND, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "crop_to_ntrl")); - item.setWoodYield(GamsLandCoverType.CROPLAND, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "crop_to_forT")); - item.setWoodYield(GamsLandCoverType.CROPLAND, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "crop_to_forC")); - item.setWoodYield(GamsLandCoverType.CROPLAND, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "crop_to_past")); + item.setWoodYield(LandCoverType.CROPLAND, LandCoverType.NATURAL, getValueForCol(rowValues, "crop_to_ntrl")); + item.setWoodYield(LandCoverType.CROPLAND, LandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "crop_to_forT")); + item.setWoodYield(LandCoverType.CROPLAND, LandCoverType.CARBON_FOREST, getValueForCol(rowValues, "crop_to_forC")); + item.setWoodYield(LandCoverType.CROPLAND, LandCoverType.PASTURE, getValueForCol(rowValues, "crop_to_past")); + item.setWoodYield(LandCoverType.CROPLAND, LandCoverType.CROPLAND, getValueForCol(rowValues, "crop_to_crop")); - item.setWoodYield(GamsLandCoverType.PASTURE, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "past_to_ntrl")); - item.setWoodYield(GamsLandCoverType.PASTURE, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "past_to_forT")); - item.setWoodYield(GamsLandCoverType.PASTURE, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "past_to_forC")); - item.setWoodYield(GamsLandCoverType.PASTURE, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "past_to_crop")); + item.setWoodYield(LandCoverType.PASTURE, LandCoverType.NATURAL, getValueForCol(rowValues, "past_to_ntrl")); + item.setWoodYield(LandCoverType.PASTURE, LandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "past_to_forT")); + item.setWoodYield(LandCoverType.PASTURE, LandCoverType.CARBON_FOREST, getValueForCol(rowValues, "past_to_forC")); + item.setWoodYield(LandCoverType.PASTURE, LandCoverType.CROPLAND, getValueForCol(rowValues, "past_to_crop")); + item.setWoodYield(LandCoverType.PASTURE, LandCoverType.PASTURE, getValueForCol(rowValues, "past_to_past")); - item.setWoodYield(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "ntrl_to_past")); - item.setWoodYield(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "ntrl_to_forT")); - item.setWoodYield(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "ntrl_to_forC")); - item.setWoodYield(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "ntrl_to_crop")); + item.setWoodYield(LandCoverType.NATURAL, LandCoverType.PASTURE, getValueForCol(rowValues, "ntrl_to_past")); + item.setWoodYield(LandCoverType.NATURAL, LandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "ntrl_to_forT")); + item.setWoodYield(LandCoverType.NATURAL, LandCoverType.CARBON_FOREST, getValueForCol(rowValues, "ntrl_to_forC")); + item.setWoodYield(LandCoverType.NATURAL, LandCoverType.CROPLAND, getValueForCol(rowValues, "ntrl_to_crop")); + item.setWoodYield(LandCoverType.NATURAL, LandCoverType.NATURAL, getValueForCol(rowValues, "ntrl_to_ntrl")); - item.setWoodYield(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "forT_to_past")); - item.setWoodYield(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "forT_to_ntrl")); - item.setWoodYield(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "forT_to_forC")); - item.setWoodYield(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "forT_to_crop")); + item.setWoodYield(LandCoverType.TIMBER_FOREST, LandCoverType.PASTURE, getValueForCol(rowValues, "forT_to_past")); + item.setWoodYield(LandCoverType.TIMBER_FOREST, LandCoverType.NATURAL, getValueForCol(rowValues, "forT_to_ntrl")); + item.setWoodYield(LandCoverType.TIMBER_FOREST, LandCoverType.CARBON_FOREST, getValueForCol(rowValues, "forT_to_forC")); + item.setWoodYield(LandCoverType.TIMBER_FOREST, LandCoverType.CROPLAND, getValueForCol(rowValues, "forT_to_crop")); + item.setWoodYield(LandCoverType.TIMBER_FOREST, LandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "forT_to_forT")); - item.setWoodYield(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "forC_to_past")); - item.setWoodYield(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "forC_to_ntrl")); - item.setWoodYield(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "forC_to_forT")); - item.setWoodYield(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "forC_to_crop")); + item.setWoodYield(LandCoverType.CARBON_FOREST, LandCoverType.PASTURE, getValueForCol(rowValues, "forC_to_past")); + item.setWoodYield(LandCoverType.CARBON_FOREST, LandCoverType.NATURAL, getValueForCol(rowValues, "forC_to_ntrl")); + item.setWoodYield(LandCoverType.CARBON_FOREST, LandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "forC_to_forT")); + item.setWoodYield(LandCoverType.CARBON_FOREST, LandCoverType.CROPLAND, getValueForCol(rowValues, "forC_to_crop")); + item.setWoodYield(LandCoverType.CARBON_FOREST, LandCoverType.CARBON_FOREST, getValueForCol(rowValues, "forC_to_forC")); } } diff --git a/src/ac/ed/lurg/output/LpjgOutputer.java b/src/ac/ed/lurg/output/LpjgOutputer.java index 6b0219d277c8946d8af3a66a0ce44d62bff0ae1a..35e23308e4572b31481471ce44fec3c49f9f0e7f 100644 --- a/src/ac/ed/lurg/output/LpjgOutputer.java +++ b/src/ac/ed/lurg/output/LpjgOutputer.java @@ -24,6 +24,7 @@ public class LpjgOutputer extends AbstractLandUseOutputer { public void writeOutput() { File outputDir = getOutputDir(year); writeLandUseFile(outputDir); + writeGamsLandCoverFile(outputDir); writeIntensity(outputDir); writeMarkerFile(year, false); } @@ -164,4 +165,52 @@ public class LpjgOutputer extends AbstractLandUseOutputer { } } } + + protected void writeGamsLandCoverFile(File outputDir) { + + BufferedWriter landCoverWriter = null; + try { + String landCoverFileName = outputDir.getPath() + File.separator + "GamsLandCoverFract.txt"; + landCoverWriter = new BufferedWriter(new FileWriter(landCoverFileName, false)); + landCoverWriter.write("Lon Lat Year CROPLAND PASTURE TIMBER CARBON NATURAL BARREN URBAN"); + landCoverWriter.newLine(); + + for (Entry<RasterKey, LandUseItem> entry : landUseRaster.entrySet()) { + RasterKey key = entry.getKey(); + LandUseItem item = entry.getValue(); + double lat = landUseRaster.getXCoordin(key); + double lon = landUseRaster.getYCoordin(key); + + double expectedArea = landUseRaster.getAreaMha(key); + double area = item.getTotalLandCoverArea(); + + if (area > 0 && Math.abs((expectedArea-area)/expectedArea) > 0.01) { // zero area, due to data not being found, already reported so ignored here + LogWriter.printlnError("Land cover areas look strange " + key + ": expected=" + expectedArea + ", actual=" + area); + } + + double crop = item.getLandCoverFract(LandCoverType.CROPLAND); + double pasture = item.getLandCoverFract(LandCoverType.PASTURE); + double timberForest = item.getLandCoverFract(LandCoverType.TIMBER_FOREST); + double carbonForest = item.getLandCoverFract(LandCoverType.CARBON_FOREST); + double natural = item.getLandCoverFract(LandCoverType.NATURAL); + double barren = item.getLandCoverFract(LandCoverType.BARREN); + double urban = item.getLandCoverFract(LandCoverType.URBAN); + landCoverWriter.write(String.format("%.2f %.2f %d %.14f %.14f %.14f %.14f %.14f %.14f %.14f", lat, lon, year, crop, pasture, timberForest, carbonForest, natural, barren, urban)); + landCoverWriter.newLine(); + } + } + catch (IOException e) { + LogWriter.print(e); + } + finally { + if (landCoverWriter != null) { + try { + landCoverWriter.close(); + } + catch (IOException e) { + LogWriter.print(e); + } + } + } + } } diff --git a/src/ac/ed/lurg/types/LandCoverType.java b/src/ac/ed/lurg/types/LandCoverType.java index 6c0c8428eb59c97872fe94902445c4cb1f478179..64eb252de701ce00bbe7607430bc0b3ba295449b 100644 --- a/src/ac/ed/lurg/types/LandCoverType.java +++ b/src/ac/ed/lurg/types/LandCoverType.java @@ -1,21 +1,33 @@ package ac.ed.lurg.types; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +import ac.ed.lurg.utils.LogWriter; + public enum LandCoverType { - MANAGED_FOREST ("managedForest", true), - UNMANAGED_FOREST ("unmanagedForest", true), - OTHER_NATURAL ("otherNatural", true), - CROPLAND ("cropland", false), - PASTURE ("pasture", false), - BARREN ("barren", false), - URBAN("urban", false); + MANAGED_FOREST ("managedForest", true, false), // This is TIMBER_FOREST + CARBON_FOREST + UNMANAGED_FOREST ("unmanagedForest", true, false), + OTHER_NATURAL ("otherNatural", true, false), + CROPLAND ("cropland", false, true), + PASTURE ("pasture", false, true), + BARREN ("barren", false, false), + URBAN("urban", false, false), + TIMBER_FOREST("timberForest", true, true), + CARBON_FOREST("carbonForest", true, true), + NATURAL("natural", true, true); // This is OTHER_NATURAL + UNMANAGED_FOREST private String name; private boolean isProtectable; + private boolean isGamsType; - LandCoverType(String name, boolean isProtectable) { + LandCoverType(String name, boolean isProtectable, boolean isGamsType) { this.name = name; this.isProtectable = isProtectable; + this.isGamsType = isGamsType; } public String getName() { @@ -25,5 +37,46 @@ public enum LandCoverType { public boolean isProtectable() { return isProtectable; } + + private static final Map<String, LandCoverType> nameCache = new HashMap<String, LandCoverType>(); + static { + for (LandCoverType c : values()) { + nameCache.put(c.getName(), c); + + } + } + + public static LandCoverType getForName(String name) { + LandCoverType type = nameCache.get(name); + + if (type == null) + LogWriter.printlnError("Can't find LandCoverType for " + name); + + return type; + } + + public static Collection<LandCoverType> getLuhTypes() { + + Collection<LandCoverType> luhTypes = new HashSet<LandCoverType>(); + + for (LandCoverType c : values()) + if (!c.isGamsType) + luhTypes.add(c); + + return luhTypes; + + } + + public static Collection<LandCoverType> getGamsTypes() { + + Collection<LandCoverType> gamsTypes = new HashSet<LandCoverType>(); + + for (LandCoverType c : values()) + if (c.isGamsType) + gamsTypes.add(c); + + return gamsTypes; + + } }