diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms index 4bada6176fcdcf9b861b55a5e4c4cc210127f153..120f3b51559c714de16f93d98f02747377234956 100644 --- a/GAMS/IntExtOpt.gms +++ b/GAMS/IntExtOpt.gms @@ -178,7 +178,7 @@ $gdxin ( SUM((crop, location), area(crop, location) * unitCost(crop, location)) + SUM(location, - 1.0 * agriLandExpansion(location) + + 1.5 * agriLandExpansion(location) + 0.5 * cropIncrease(location) + 0.5 * cropDecrease(location) + 0.5 * pastureIncrease(location) + diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java index 32ac0e19ddba46389b5601960c01e2c138a544a6..0805c04689c8957afff9bc6051cadba918996fbd 100644 --- a/src/ac/ed/lurg/ModelConfig.java +++ b/src/ac/ed/lurg/ModelConfig.java @@ -126,6 +126,7 @@ public class ModelConfig { public static final String IRRIG_MAX_WATER_FILENAME = getProperty("IRRIG_MAX_WATER_FILENAME", "gsirrigation_plum.out"); public static final String PROTECTED_AREAS_FILE = SPATIAL_DATA_DIR + File.separator + "protected_areas.txt"; + // Output public static final String LAND_COVER_OUTPUT_FILE = OUTPUT_DIR + File.separator + "lc.txt"; public static final String PRICES_OUTPUT_FILE = OUTPUT_DIR + File.separator + "prices.txt"; @@ -133,6 +134,12 @@ public class ModelConfig { public static final boolean OUTPUT_FOR_LPJG = getBooleanProperty("OUTPUT_FOR_LPJG", true); public static final boolean INTERPOLATE_OUTPUT_YEARS = getBooleanProperty("INTERPOLATE_OUTPUT_YEARS", true); + public static final String INITAL_LAND_USE_FILE = OUTPUT_DIR + File.separator + "2150" + File.separator + "LandUse.txt"; + + public static final boolean IS_CALIBRATION_RUN = getBooleanProperty("IS_CALIBRATION_RUN", false); + public static final double MAX_IMPORT_CHANGE = IS_CALIBRATION_RUN ? 0.0 : getDoubleProperty("MAX_IMPORT_CHANGE", 0.1); + public static final boolean MARKET_ADJ_PRICE = IS_CALIBRATION_RUN ? false : getBooleanProperty("MARKET_ADJ_PRICE", true); + // Temporal configuration public static final int START_TIMESTEP = getIntProperty("START_TIMESTEP", 0); public static final int END_TIMESTEP = getIntProperty("END_TIMESTEP", 18); @@ -148,7 +155,6 @@ public class ModelConfig { // Other model parameters public static final boolean CHANGE_DEMAND_YEAR = getBooleanProperty("CHANGE_DEMAND_YEAR", true); public static final String SSP_SCENARIO = getProperty("SSP_SCENARIO", "SSP1_v9_130325"); - public static final double MAX_IMPORT_CHANGE = getDoubleProperty("MAX_IMPORT_CHANGE", 0.1); public static final double PASTURE_HARVEST_FRACTION = getDoubleProperty("PASTURE_HARVEST_FRACTION", 0.25); public static final double MEAT_EFFICIENCY = getDoubleProperty("MEAT_EFFICIENCY", 1.0); // 'meat' is includes feed conversion ratio already, this is tech. change or similar @@ -164,7 +170,6 @@ public class ModelConfig { public static final int BIOENERGY_CHANGE_START_YEAR = getIntProperty("BIOENERGY_CHANGE_START_YEAR", 2010); public static final double MARKET_LAMBA = getDoubleProperty("MARKET_LAMBA", 0.5); // controls international market price adjustment rate - public static final boolean MARKET_ADJ_PRICE = getBooleanProperty("MARKET_ADJ_PRICE", true); public static final double POPULATION_AGGREG_LIMIT = getDoubleProperty("POPULATION_AGGREG_LIMIT", 40.0); // in millions, smaller countries are aggregated on a regional basis @@ -184,8 +189,8 @@ public class ModelConfig { public static final boolean PROTECTED_AREAS_ENABLED = getBooleanProperty("PROTECTED_AREAS_ENABLED", true); - public static final int NUM_CEREAL_CATEGORIES = getIntProperty("NUM_CEREAL_CATEGORIES", 5); - public static final int NUM_PASTURE_CATEGORIES = getIntProperty("NUM_PASTURE_CATEGORIES", 1); + public static final int NUM_CEREAL_CATEGORIES = getIntProperty("NUM_CEREAL_CATEGORIES", 6); + public static final int NUM_PASTURE_CATEGORIES = getIntProperty("NUM_PASTURE_CATEGORIES", 6); public static final boolean DEBUG_LIMIT_COUNTRIES = getBooleanProperty("DEBUG_LIMIT_COUNTRIES", false); public static final Object DEBUG_COUNTRY_NAME = getProperty("DEBUG_COUNTRY_NAME", "United States of America"); diff --git a/src/ac/ed/lurg/ModelMain.java b/src/ac/ed/lurg/ModelMain.java index 7be0c8ec41e5eaec099a490b62ab07c8f488b02c..9ff4345727c1e1f1bb0ad834f8e00b838af0e44d 100644 --- a/src/ac/ed/lurg/ModelMain.java +++ b/src/ac/ed/lurg/ModelMain.java @@ -4,6 +4,9 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -30,7 +33,9 @@ import ac.ed.lurg.landuse.IrrigiationCostReader; import ac.ed.lurg.landuse.LandCoverItem; import ac.ed.lurg.landuse.LandCoverReader; import ac.ed.lurg.landuse.LandUseItem; +import ac.ed.lurg.landuse.LandUseReader; import ac.ed.lurg.landuse.ProtectedAreasReader; +import ac.ed.lurg.output.LandUseOutputer; import ac.ed.lurg.output.LpjgOutputer; import ac.ed.lurg.types.CommodityType; import ac.ed.lurg.types.CropToDoubleMap; @@ -142,6 +147,19 @@ public class ModelMain { LogWriter.printlnError("No results for " + ca.getCountry()); continue; } + + // some hacky code for debug purposes that keeps each gams gdx file + if (ca.getCountry().getName().equals("Spain")) { + try { + Files.copy( + FileSystems.getDefault().getPath("/Users/peteralexander/Documents/R_Workspace/UNPLUM/temp/GamsTmp/_gams_java_gdb1.gdx"), + FileSystems.getDefault().getPath("/Users/peteralexander/Documents/R_Workspace/UNPLUM/temp/GamsTmp/" + timestep.getTimestep() + ".gdx") + , StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } // update global rasters globalLandUseRaster.putAll(result.getLandUses()); @@ -172,7 +190,7 @@ public class ModelMain { double imports = totalImportCommodities.get(crop); double exports = totalExportCommodities.get(crop) * (1.0-ModelConfig.TRANSPORT_LOSSES); - GlobalPrice adjustedPrice = prevPrice.createWithUpdatedMarketPrices(imports, exports); + GlobalPrice adjustedPrice = prevPrice.createWithUpdatedMarketPrices(imports, exports, (ModelConfig.MARKET_ADJ_PRICE)); LogWriter.println(String.format("Price for %s updated from %s (imports amount %.0f, exports amount %.0f) to %s ", crop.getGamsName(), prevPrice, imports, exports, adjustedPrice)); prevWorldPrices.put(crop, adjustedPrice); } @@ -277,7 +295,6 @@ public class ModelMain { } - private void outputTimestepResults(Timestep timestep, RasterSet<LandUseItem> landUseRaster, RasterSet<IntegerRasterItem> locationIdRaster, YieldRaster yieldSurfaces) { writeLandCoverFile(timestep, landUseRaster); @@ -309,6 +326,10 @@ public class ModelMain { } } } + + LogWriter.printlnError("Outputing land uses Year: " + timestep.getYear()); + LandUseOutputer landuseOutputer = new LandUseOutputer(timestep.getYear(), landUseRaster); + landuseOutputer.writeOutput(); outputLandCover(timestep.getYear(), landUseRaster, LandCoverType.CROPLAND); outputLandCover(timestep.getYear(), landUseRaster, LandCoverType.PASTURE); @@ -338,17 +359,14 @@ public class ModelMain { public Collection<CountryAgent> createCountryAgents(Collection<CompositeCountry> countryGrouping) { Collection<CountryAgent> countryAgents = new HashSet<CountryAgent>(); - RasterSet<LandCoverItem> initLC = getInitialLandCover(); + RasterSet<LandUseItem> initLU = null; - new RasterOutputer<LandCoverItem>(initLC, "InitialCropland") { - @Override - public Double getValue(RasterKey location) { - LandCoverItem item = results.get(location); - if (item == null) - return null; - return item.getLandCoverFract(LandCoverType.CROPLAND); - } - }.writeOutput(); + if (ModelConfig.IS_CALIBRATION_RUN) { + initLU = getInitialLandCover(); + } + else { + initLU = getInitialLandUse(); // read in all land use data saved from calibrations run + } Map<CompositeCountry, Map<CropType, CropUsageData>> cropUsageDataMap = new CropUsageReader(compositeCountryManager).getCommodityData(); @@ -361,18 +379,21 @@ public class ModelMain { } List<RasterKey> keys = countryBoundaryRaster.getKeysFor(cc); - RasterSet<LandCoverItem> initCountryLC = initLC.createSubsetForKeys(keys); Map<CropType, CropUsageData> countryCommodityData = cropUsageDataMap.get(cc); Map<CropType, Double> countryTradeBarriers = tradeManager.getTradeBarriers(cc); if (countryCommodityData == null) { LogWriter.printlnError("No commodities data for " + cc + ", so skipping"); } - else if (initCountryLC.size() == 0) { - LogWriter.printlnError("No initial land cover for " +cc + ", so skipping"); - } else { - CountryAgent ca = new CountryAgent(demandManager, cc, initCountryLC, countryCommodityData, countryTradeBarriers); + RasterSet<LandUseItem> initCountryLandUse = initLU.createSubsetForKeys(keys); + + if (initCountryLandUse.size() == 0) { + LogWriter.printlnError("No initial land use for " +cc + ", so skipping"); + continue; + } + + CountryAgent ca = new CountryAgent(demandManager, cc, initCountryLandUse, countryCommodityData, countryTradeBarriers); countryAgents.add(ca); LogWriter.println("Creating country agent for: " + cc ); } @@ -380,21 +401,56 @@ public class ModelMain { return countryAgents; } - - private RasterSet<LandCoverItem> getInitialLandCover() { + + /** This is if we are starting from previously saved state (for example, from calibration runs) */ + private RasterSet<LandUseItem> getInitialLandUse() { + RasterSet<LandUseItem> initLU = new RasterSet<LandUseItem>(desiredProjection) { + private static final long serialVersionUID = 1317102740312961042L; + protected LandUseItem createRasterData() { + return new LandUseItem(); + } + }; - RasterSet<LandCoverItem> initLC = new RasterSet<LandCoverItem>(desiredProjection) { - private static final long serialVersionUID = 4642550777741425501L; - protected LandCoverItem createRasterData() { - return new LandCoverItem(); - } + new LandUseReader(initLU).getRasterDataFromFile(ModelConfig.INITAL_LAND_USE_FILE); + return initLU; + } + + /** this is if we are starting from Hurtt of other initial land covers (so we don't have land uses and intensity data) */ + private RasterSet<LandUseItem> getInitialLandCover() { + RasterSet<LandCoverItem> initialLC = new RasterSet<LandCoverItem>(desiredProjection) { + private static final long serialVersionUID = 4642550777741425501L; + protected LandCoverItem createRasterData() { + return new LandCoverItem(); + } }; - new ProtectedAreasReader(initLC).getRasterDataFromFile(ModelConfig.PROTECTED_AREAS_FILE); - new LandCoverReader(initLC).getRasterDataFromFile(ModelConfig.INITAL_LAND_COVER_FILE); - - return initLC; + new ProtectedAreasReader(initialLC).getRasterDataFromFile(ModelConfig.PROTECTED_AREAS_FILE); + new LandCoverReader(initialLC).getRasterDataFromFile(ModelConfig.INITAL_LAND_COVER_FILE); + + /* new RasterOutputer<LandCoverItem>(initLC, "InitialCropland") { + @Override + public Double getValue(RasterKey location) { + LandCoverItem item = results.get(location); + if (item == null) + return null; + return item.getLandCoverFract(LandCoverType.CROPLAND); + } + }.writeOutput(); */ + + RasterSet<LandUseItem> landUseRaster = new RasterSet<LandUseItem>(initialLC.getHeaderDetails()); + + for (Map.Entry<RasterKey, LandCoverItem> entry : initialLC.entrySet()) { + LandUseItem areasItem = new LandUseItem(); + RasterKey key = entry.getKey(); + LandCoverItem landCover = entry.getValue(); + areasItem.setLandCoverAreas(landCover); + areasItem.setCropFraction(CropType.WHEAT, 0.5); // random start, better if we could get data, but free substitution between crops so not critical + areasItem.setCropFraction(CropType.MAIZE, 0.5); + areasItem.setProtectedArea(landCover.getProtectedArea()); + landUseRaster.put(key, areasItem); + } + return landUseRaster; } private YieldRaster getYieldSurfaces(Timestep timestep) { diff --git a/src/ac/ed/lurg/country/CountryAgent.java b/src/ac/ed/lurg/country/CountryAgent.java index 3ceda6a11d99e6a043c81f7600ac6cb25e48293a..5d2773c19468273a9cd0a127c982ea38605b7a23 100644 --- a/src/ac/ed/lurg/country/CountryAgent.java +++ b/src/ac/ed/lurg/country/CountryAgent.java @@ -3,22 +3,20 @@ package ac.ed.lurg.country; import java.util.HashMap; import java.util.Map; +import ac.ed.lurg.ModelConfig; import ac.ed.lurg.Timestep; import ac.ed.lurg.country.gams.GamsCountryInput; import ac.ed.lurg.country.gams.GamsRasterInput; import ac.ed.lurg.country.gams.GamsRasterOptimiser; import ac.ed.lurg.country.gams.GamsRasterOutput; -import ac.ed.lurg.country.CountryPrice; import ac.ed.lurg.demand.DemandManager; import ac.ed.lurg.landuse.CropUsageData; import ac.ed.lurg.landuse.IrrigationItem; -import ac.ed.lurg.landuse.LandCoverItem; import ac.ed.lurg.landuse.LandUseItem; import ac.ed.lurg.types.CommodityType; import ac.ed.lurg.types.CropType; import ac.ed.lurg.utils.LogWriter; import ac.ed.lurg.yield.YieldRaster; -import ac.sac.raster.RasterKey; import ac.sac.raster.RasterSet; public class CountryAgent { @@ -33,33 +31,16 @@ public class CountryAgent { private Map<CropType, CountryPrice> currentCountryPrices; private Map<CropType, Double> tradeBarriers; - public CountryAgent(DemandManager demandManager,CompositeCountry country, RasterSet<LandCoverItem> initialLC, + public CountryAgent(DemandManager demandManager,CompositeCountry country, RasterSet<LandUseItem> cropAreaRaster, Map<CropType, CropUsageData> cropUsageData, Map<CropType, Double> tradeBarriers) { this.demandManager = demandManager; this.country = country; - RasterSet<LandUseItem> cropAreaRaster = convertInitialLC(initialLC); this.tradeBarriers = tradeBarriers; GamsRasterOutput initialData = new GamsRasterOutput(cropAreaRaster, cropUsageData); resultsTimeseries.put(new Timestep(0), initialData); } - - private RasterSet<LandUseItem> convertInitialLC(RasterSet<LandCoverItem> initialLC) { - RasterSet<LandUseItem> landUseRaster = new RasterSet<LandUseItem>(initialLC.getHeaderDetails()); - - for (Map.Entry<RasterKey, LandCoverItem> entry : initialLC.entrySet()) { - LandUseItem areasItem = new LandUseItem(); - RasterKey key = entry.getKey(); - areasItem.setLandCoverAreas(entry.getValue()); - areasItem.setCropFraction(CropType.WHEAT, 0.5); // random start, better if we could get data, but free substitution between crops so not critical - areasItem.setCropFraction(CropType.MAIZE, 0.5); - areasItem.setProtectedArea(entry.getValue()); - landUseRaster.put(key, areasItem); - } - - return landUseRaster; - } public CompositeCountry getCountry() { return country; @@ -101,17 +82,15 @@ public class CountryAgent { private GamsRasterInput getGamsRasterInput(Map<CommodityType, Double> projectedDemand, Map<CropType, CountryPrice> countryPrices, RasterSet<IrrigationItem> irrigData) { //TODO why pass in projectedDemand when currentProjectedDemand belongs to CountryAgent class already? GamsRasterOutput prevOutput; - boolean calibrate; if (currentTimestep.isInitialTimestep()) { // initialisation time-step - calibrate = true; prevOutput = resultsTimeseries.get(currentTimestep); } else { // normal (not the initial) time-step - calibrate = false; prevOutput = resultsTimeseries.get(currentTimestep.getPreviousTimestep()); } + Map<CropType, Double> baseNetImport = new HashMap<CropType, Double>(); Map<CropType, Double> maxOfProdOrSupply = new HashMap<CropType, Double>(); @@ -122,7 +101,7 @@ public class CountryAgent { maxOfProdOrSupply.put(entry.getKey(), cropUsage.getProduction() + Math.max(netImports, 0)); } - GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(country, projectedDemand, countryPrices, baseNetImport, maxOfProdOrSupply, calibrate); + GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(country, projectedDemand, countryPrices, baseNetImport, maxOfProdOrSupply); GamsRasterInput input = new GamsRasterInput(currentTimestep, countryYieldSurfaces, prevOutput.getLandUses(), irrigData, countryLevelInputs); return input; diff --git a/src/ac/ed/lurg/country/GlobalPrice.java b/src/ac/ed/lurg/country/GlobalPrice.java index 1740fc47b1c7bf874a07034310cc48f0a0914581..364758ae63e60d9e4e654b1652aab80cb2c53335 100644 --- a/src/ac/ed/lurg/country/GlobalPrice.java +++ b/src/ac/ed/lurg/country/GlobalPrice.java @@ -34,7 +34,7 @@ public class GlobalPrice { return exportAmount; } - public GlobalPrice createWithUpdatedMarketPrices(double imports, double exports) { + public GlobalPrice createWithUpdatedMarketPrices(double imports, double exports, boolean adjustPrice) { if (imports > 0 || exports > 0) { double ratio; @@ -43,7 +43,7 @@ public class GlobalPrice { else ratio = (imports-exports)/exports; - double adjustment = ModelConfig.MARKET_ADJ_PRICE ? Math.exp(ratio * ModelConfig.MARKET_LAMBA) : 1.0; + double adjustment = adjustPrice ? Math.exp(ratio * ModelConfig.MARKET_LAMBA) : 1.0; return new GlobalPrice(exportPrice * adjustment, imports, exports); } else { diff --git a/src/ac/ed/lurg/country/gams/GamsCountryInput.java b/src/ac/ed/lurg/country/gams/GamsCountryInput.java index 2bc1dbd91a610e92feb1b118bc18615a07ae4e6e..93e8fdff35a6920b64989fb1dfd56d0805d63c09 100644 --- a/src/ac/ed/lurg/country/gams/GamsCountryInput.java +++ b/src/ac/ed/lurg/country/gams/GamsCountryInput.java @@ -31,9 +31,9 @@ public class GamsCountryInput { } public static GamsCountryInput createInput(CompositeCountry country, Map<CommodityType, Double> projectedDemand, Map<CropType, CountryPrice> countryPrices, - Map<CropType, Double> baseNetImport, Map<CropType, Double> maxOfProdOrSupply, boolean calibrateToObserved) { + Map<CropType, Double> baseNetImport, Map<CropType, Double> maxOfProdOrSupply) { - double allowedImportChange = calibrateToObserved ? 0.0 : ModelConfig.MAX_IMPORT_CHANGE; + double allowedImportChange = ModelConfig.MAX_IMPORT_CHANGE; Map<CropType, ImportExportConstraint> importConstraints = new HashMap<CropType, ImportExportConstraint>(); for (Map.Entry<CropType, Double> entry : baseNetImport.entrySet()) { diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java index f8862bff36faf0d62d77d8011a90b0c008320ef4..0f3bbd1d682eaa5fc82afa4b5a8bbc47a709ee0c 100644 --- a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java +++ b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java @@ -99,7 +99,7 @@ public class GamsLocationOptimiser { double suitableLand = landUseItem.getSuitableLand(); if (DEBUG) LogWriter.println(String.format(" %d %15s,\t %.1f", locationId, "suitableLand", suitableLand)); - setGamsParamValue(landP.addRecord(locString), suitableLand, 1); + setGamsParamValueTruncate(landP.addRecord(locString), suitableLand, 3); for (CropType cropType : CropType.getNonMeatTypes()) { Vector<String> v = new Vector<String>(); @@ -128,7 +128,7 @@ public class GamsLocationOptimiser { if (DEBUG) LogWriter.println(String.format(" %d %15s,\t %.2f,\t %.3f,\t %.3f,\t %.3f", locationId, cropType.getGamsName(), area, prevFertI, prevIrrigI, prevOtherI)); - setGamsParamValue(prevCropP.addRecord(v), area, 2); + setGamsParamValue(prevCropP.addRecord(v), area, 3); setGamsParamValue(prevFertIP.addRecord(v), prevFertI, 4); setGamsParamValue(prevIrrigIP.addRecord(v), prevIrrigI, 4); setGamsParamValue(prevOtherIP.addRecord(v), prevOtherI, 4); @@ -232,12 +232,13 @@ public class GamsLocationOptimiser { } private void setGamsParamValue(GAMSParameterRecord param, double val, int places) { - param.setValue(roundForGams(val, places)); + double dOut = Math.round(val * Math.pow(10,places)) / Math.pow(10,places); + param.setValue(dOut); } - private double roundForGams(double dIn, int places) { - double dOut= Math.round(dIn * Math.pow(10,places)) / Math.pow(10,places); - return dOut; + private void setGamsParamValueTruncate(GAMSParameterRecord param, double val, int places) { + double dOut = ((int)(val * Math.pow(10,places))) / Math.pow(10,places); + param.setValue(dOut); } @SuppressWarnings("serial") diff --git a/src/ac/ed/lurg/country/gams/GamsLocationTest.java b/src/ac/ed/lurg/country/gams/GamsLocationTest.java index acd9873cb202a42c98052a28bfddc1d2e149b96b..9dafdbcb9bafa3363a3332cfdb43f64a497acbd2 100644 --- a/src/ac/ed/lurg/country/gams/GamsLocationTest.java +++ b/src/ac/ed/lurg/country/gams/GamsLocationTest.java @@ -23,7 +23,7 @@ public class GamsLocationTest { } private void run() { - GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(new CompositeCountry("Test"), getProjectedDemand(), getCountryPrices(), null, null, true); + GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(new CompositeCountry("Test"), getProjectedDemand(), getCountryPrices(), null, null); GamsLocationInput gamsInput = new GamsLocationInput(new Timestep(0), getYields(), getPreviousArea(), getIrrigationCosts(), countryLevelInputs); GamsLocationOptimiser opti = new GamsLocationOptimiser(gamsInput); diff --git a/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java b/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java index 6247744729ce65a66780e1b6fa397ec119411290..5cb364badbfc3b6ebb5d32f17c356306e2f3cc1b 100644 --- a/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java +++ b/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java @@ -67,6 +67,9 @@ public class GamsRasterOptimiser { for (Entry<RasterKey, LandUseItem> entry : toCopy.entrySet()) { LandUseItem newAreasItem = new LandUseItem(); + if (entry.getValue() == null) { + continue; + } newAreasItem.setLandCoverAreas(entry.getValue()); theCopy.put(entry.getKey(), newAreasItem); } diff --git a/src/ac/ed/lurg/country/gams/GamsRasterTest.java b/src/ac/ed/lurg/country/gams/GamsRasterTest.java index 5ac66cc6684e966552878ebd6c5c7abba609d185..995abdebaa27e8adabbd699eb9874eb5f29467e4 100644 --- a/src/ac/ed/lurg/country/gams/GamsRasterTest.java +++ b/src/ac/ed/lurg/country/gams/GamsRasterTest.java @@ -18,7 +18,7 @@ public class GamsRasterTest extends GamsLocationTest { } private void run() { - GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(new CompositeCountry("Test"), getProjectedDemand(), getCountryPrices(), null, null, true); + GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(new CompositeCountry("Test"), getProjectedDemand(), getCountryPrices(), null, null); GamsRasterInput input = new GamsRasterInput(new Timestep(0), getYieldRaster(), getPreviousAreaRaster(), getIrrigationCost(), countryLevelInputs); GamsRasterOptimiser opti = new GamsRasterOptimiser(input); diff --git a/src/ac/ed/lurg/landuse/LandCoverItem.java b/src/ac/ed/lurg/landuse/LandCoverItem.java index 882330fcff945f6a299667060fc7c79307e7eade..47698e4c95f04b2eadf466d65fac9b2f3d81b5b1 100644 --- a/src/ac/ed/lurg/landuse/LandCoverItem.java +++ b/src/ac/ed/lurg/landuse/LandCoverItem.java @@ -38,13 +38,12 @@ public class LandCoverItem implements RasterItem { landcover.put(landType, d); } - public void setProtectedArea(double proportionProtectedArea){ + public void setProtectedFract(double proportionProtectedArea){ this.proportionProtectedArea=proportionProtectedArea; } - public double getProtectedArea(){ - return proportionProtectedArea; + return proportionProtectedArea*totalArea; } /*public double getTotal() { diff --git a/src/ac/ed/lurg/landuse/LandUseItem.java b/src/ac/ed/lurg/landuse/LandUseItem.java index 7be97ed8aca74e6cad0d273f9cc4b8b6ac498bdd..41c5a7a64f91ed2111dc6de6405930d04736deb0 100644 --- a/src/ac/ed/lurg/landuse/LandUseItem.java +++ b/src/ac/ed/lurg/landuse/LandUseItem.java @@ -19,11 +19,8 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem> { private Map<LandCoverType, Double> landCoverAreas = new HashMap<LandCoverType, Double>(); private double protectedArea; //protected area in Mha - public void setProtectedArea(LandCoverItem landCover){ - if (landCover != null) { - double areaTotal = this.getTotalLandCoverArea(); - this.protectedArea = landCover.getProtectedArea()*areaTotal; - } + public void setProtectedArea(double protectedArea){ + this.protectedArea = protectedArea; } public double getProtectedArea(){ @@ -175,8 +172,8 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem> { } - public void setCropFraction(CropType c, double area) { - cropFractions.put(c, area); + public void setCropFraction(CropType c, double areaFract) { + cropFractions.put(c, areaFract); } public double getLandCoverArea(LandCoverType c) { diff --git a/src/ac/ed/lurg/landuse/LandUseReader.java b/src/ac/ed/lurg/landuse/LandUseReader.java new file mode 100644 index 0000000000000000000000000000000000000000..1b16615a2e96c089a743bc8452944fcf8e93f625 --- /dev/null +++ b/src/ac/ed/lurg/landuse/LandUseReader.java @@ -0,0 +1,41 @@ +package ac.ed.lurg.landuse; + +import java.util.Map; + +import ac.ed.lurg.types.CropType; +import ac.ed.lurg.types.LandCoverType; +import ac.sac.raster.AbstractTabularRasterReader; +import ac.sac.raster.RasterKey; +import ac.sac.raster.RasterSet; + +public class LandUseReader extends AbstractTabularRasterReader<LandUseItem> { + + private static final int MIN_COLS = 20; + + public LandUseReader(RasterSet<LandUseItem> landCover) { + super(",", MIN_COLS, landCover); + } + + @Override + protected void setData(RasterKey key, LandUseItem luData, Map<String, Double> rowValues) { + + for (LandCoverType cover : LandCoverType.values()) { + luData.setLandCoverArea(cover, getValueForCol(rowValues, cover.getName())); + } + + luData.setProtectedArea(getValueForCol(rowValues, "protected")); + + for (CropType crop : CropType.getAllItems()) { + double cropFract = getValueForCol(rowValues, crop.getGamsName() + "_A"); + if (cropFract > 0.0 | CropType.PASTURE.equals(crop)) { + luData.setCropFraction(crop, cropFract); + double fertI = getValueForCol(rowValues, crop.getGamsName() + "_FI"); + double irrigI = getValueForCol(rowValues, crop.getGamsName() + "_II"); + double otherI = getValueForCol(rowValues, crop.getGamsName() + "_OI"); + Intensity intensity = new Intensity(fertI, irrigI, otherI); + luData.setIntensity(crop, intensity); + } + } + + } +} diff --git a/src/ac/ed/lurg/landuse/ProtectedAreasReader.java b/src/ac/ed/lurg/landuse/ProtectedAreasReader.java index 6b4aaaa42e539fdd44455bbfa2adb90d26b1488f..d036f47f3bd85a2e30d84e6ca13c71ca37fbb6d3 100644 --- a/src/ac/ed/lurg/landuse/ProtectedAreasReader.java +++ b/src/ac/ed/lurg/landuse/ProtectedAreasReader.java @@ -13,7 +13,7 @@ public class ProtectedAreasReader extends AbstractRasterReader<LandCoverItem> { public void setData(LandCoverItem lcData, String token) { if (!"nan".equals(token)) { double protFrac = Double.parseDouble(token); - lcData.setProtectedArea(protFrac); + lcData.setProtectedFract(protFrac); } } diff --git a/src/ac/ed/lurg/output/LpjgOutputer.java b/src/ac/ed/lurg/output/LpjgOutputer.java index cb1fd6a86642765454df9f972bd6e700f9b4c996..26de50f3172746487bb6476c9caffa4689bab43f 100644 --- a/src/ac/ed/lurg/output/LpjgOutputer.java +++ b/src/ac/ed/lurg/output/LpjgOutputer.java @@ -7,7 +7,6 @@ import java.io.FileWriter; import java.io.IOException; import java.util.Map.Entry; -import ac.ed.lurg.ModelConfig; import ac.ed.lurg.landuse.LandUseItem; import ac.ed.lurg.types.CropType; import ac.ed.lurg.types.LandCoverType; @@ -16,34 +15,24 @@ import ac.ed.lurg.yield.YieldRaster; import ac.sac.raster.RasterKey; import ac.sac.raster.RasterSet; -public class LpjgOutputer { +public class LpjgOutputer extends AbstractLandUseOutputer { - private RasterSet<LandUseItem> landUseRaster; private YieldRaster yieldSurfaces; - private int year; public LpjgOutputer(int year, RasterSet<LandUseItem> landUseRaster, YieldRaster yieldSurfaces) { - this.year = year; - this.landUseRaster = landUseRaster; + super(year, landUseRaster); this.yieldSurfaces = yieldSurfaces; } + @Override public void writeOutput() { File outputDir = getOutputDir(year); - - writeLandCoverAndCrop(outputDir); + writeLandUseFile(outputDir); writeIntensity(outputDir); writeMarkerFile(year, false); } - private static File getOutputDir(int year) { - String outputDirName = ModelConfig.OUTPUT_DIR + File.separator + year; - File outputDir = new File(outputDirName); - outputDir.mkdirs(); - return outputDir; - } - - private void writeIntensity(File outputDir) { + protected void writeIntensity(File outputDir) { BufferedWriter fertWriter = null; BufferedWriter irrigWriter = null; @@ -126,7 +115,7 @@ public class LpjgOutputer { } } - public void writeLandCoverAndCrop(File outputDir) { + protected void writeLandUseFile(File outputDir) { BufferedWriter landCoverWriter = null; BufferedWriter cropFractWriter = null;