diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java index 3e7ee5c75890e93f4e1656c24e4f1c9746868464..902a83bc112742cd634f08d614c5891d02a9bcdb 100644 --- a/src/ac/ed/lurg/ModelConfig.java +++ b/src/ac/ed/lurg/ModelConfig.java @@ -113,15 +113,20 @@ public class ModelConfig { public static final int START_TIMESTEP = getIntProperty("START_TIMESTEP", 0); public static final int END_TIMESTEP = getIntProperty("END_TIMESTEP", 1); + public static final int TIMESTEP_SIZE = getIntProperty("END_TIMESTEP", 5); public static final int BASE_YEAR = getIntProperty("BASE_YEAR", 2010); - public static final double MAX_IMPORT_CHANGE = getDoubleProperty("MAX_IMPORT_CHANGE", 0.2); + public static final double MAX_IMPORT_CHANGE = getDoubleProperty("MAX_IMPORT_CHANGE", 0.1); public static final String SSP_SCENARIO = getProperty("SSP_SCENARIO", "SSP2_v9_130325"); // Output public static final boolean WRITE_JPEG_IMAGES = getBooleanProperty("WRITE_JPEG_IMAGES", Boolean.TRUE); public static final int LPJG_MONITOR_TIMEOUT_SEC = getIntProperty("LPJG_MONITOR_TIMEOUT", 60*60*2); - public static final double PASTURE_HARVEST_FRACTION = getDoubleProperty("PASTURE_HARVEST_FRACTION", 0.5); + // + public static final double PASTURE_HARVEST_FRACTION = getDoubleProperty("PASTURE_HARVEST_FRACTION", 0.5); + public static final double MEAT_EFFICIENCY = getDoubleProperty("MEAT_EFFICIENCY", 0.5); + public static final double LAND_CHANGE_COST = getDoubleProperty("LAND_CHANGE_COST", 2.0); + public static final double MIN_FEED_RATE = getDoubleProperty("MIN_FEED_RATE", 0.15); } \ No newline at end of file diff --git a/src/ac/ed/lurg/ModelMain.java b/src/ac/ed/lurg/ModelMain.java index 30a5a2a1e17997974ae8e08f78306264a6462f21..318d4e44b8e9ffa7ce81f154e5666cdbaa4f2466 100644 --- a/src/ac/ed/lurg/ModelMain.java +++ b/src/ac/ed/lurg/ModelMain.java @@ -66,21 +66,21 @@ public class ModelMain { /* run the model */ private void run() { for (int i = ModelConfig.START_TIMESTEP; i <= ModelConfig.END_TIMESTEP; i++) { + Timestep timestep = new Timestep(i); try { - doTimestep(i); + doTimestep(timestep); } catch (Exception e) { - LpjgOutputer.writeMarkerFile(ModelConfig.BASE_YEAR + i, true); + LpjgOutputer.writeMarkerFile(timestep, true); throw new RuntimeException(e); } } } - private void doTimestep(int timestep) { - int year = ModelConfig.BASE_YEAR + timestep; - LogWriter.println("Timestep: " + timestep + ", year:" + year); + private void doTimestep(Timestep timestep) { + LogWriter.println(timestep.toString()); - YieldRaster yieldSurfaces = getYieldSurfaces(year); // this will wait for the marker file from LPJ if configured to do so + YieldRaster yieldSurfaces = getYieldSurfaces(timestep); // this will wait for the marker file from LPJ if configured to do so // YieldResponsesItem yresp = yieldSurfaces.getFromCoordinates(-50.0, -4.0); // LogWriter.printlnError("Test key: " + yresp.getYieldMax(CropType.CEREALS) + ", " + yresp.getYieldFertOnly(CropType.CEREALS) + ", " + yresp.getYieldIrrigOnly(CropType.CEREALS)); @@ -140,12 +140,12 @@ public class ModelMain { prevWorldInputCost = totalWorldInputCost.divideBy(totalQuantity); // output results - outputTimestepResults(year, globalIntensityRaster, globalCropAreaRaster, globalLocationIdRaster, yieldSurfaces); + outputTimestepResults(timestep, globalIntensityRaster, globalCropAreaRaster, globalLocationIdRaster, yieldSurfaces); } - private void outputTimestepResults(int year, RasterSet<IntensitiesItem> intensityRaster, RasterSet<AreasItem> cropAreaRaster, RasterSet<IntegerRasterItem> locationIdRaster, YieldRaster yieldSurfaces) { + private void outputTimestepResults(Timestep timestep, RasterSet<IntensitiesItem> intensityRaster, RasterSet<AreasItem> cropAreaRaster, RasterSet<IntegerRasterItem> locationIdRaster, YieldRaster yieldSurfaces) { - LpjgOutputer lpjOutputer = new LpjgOutputer(year, intensityRaster, cropAreaRaster, yieldSurfaces); + LpjgOutputer lpjOutputer = new LpjgOutputer(timestep, intensityRaster, cropAreaRaster, yieldSurfaces); lpjOutputer.writeOutput(); /* new RasterOutputer<IntegerRasterItem>(locationIdRaster, "locId" + year) { @@ -184,8 +184,8 @@ public class ModelMain { }.writeOutput(ModelConfig.WRITE_JPEG_IMAGES); outputAreas(year, cropAreaRaster, CropType.MAIZE); */ - outputAreas(year, cropAreaRaster, CropType.WHEAT); - outputAreas(year, cropAreaRaster, CropType.PASTURE); + outputAreas(timestep.getYear(), cropAreaRaster, CropType.WHEAT); + outputAreas(timestep.getYear(), cropAreaRaster, CropType.PASTURE); } private void outputAreas(int year, RasterSet<AreasItem> cropAreaRaster, final CropType crop) { @@ -243,7 +243,7 @@ public class ModelMain { RasterSet<IrrigationCostItem> allIrrigationCosts = getIrrigationCosts(); Map<Country, Map<CropType, CropUsageData>> cropUsageDataMap = CropUsageData.readCommodityData(); - HashSet<String> countryExclusionList = new HashSet<String>(Arrays.asList("Sierra Leone", "Togo", "United Arab Emirates")); //"French Polynesia", "Cabo Verde", "Samoa", "Saint Vincent and the Grenadines")); + HashSet<String> countryExclusionList = new HashSet<String>(Arrays.asList("Bangladesh", "Indonesia", "Sierra Leone", "Togo", "United Arab Emirates")); //"French Polynesia", "Cabo Verde", "Samoa", "Saint Vincent and the Grenadines")); for (Map.Entry<Country, List<RasterKey>> entry : countryToKeysMap.entrySet()) { Country country = entry.getKey(); @@ -251,9 +251,9 @@ public class ModelMain { // DEBUG code - if (!(country.getCountryName().equals("United States of America") || country.getCountryName().equals("Russian Federationxx") || country.getCountryName().equals("Chinaxx")) ) { //|| country.getCountryName().equals("China") - continue; - } + // if (!(country.getCountryName().equals("United States of Americaxx") || country.getCountryName().equals("Russian Federationxx") || country.getCountryName().equals("Indonesia")) ) { //|| country.getCountryName().equals("China") + // continue; + // } if (demandManager.getPopulation(country, 2010) < 50 || countryExclusionList.contains(country.getCountryName())) { LogWriter.printlnError("Skipping " + country); @@ -285,9 +285,9 @@ public class ModelMain { return initLC; } - private YieldRaster getYieldSurfaces(int year) { + private YieldRaster getYieldSurfaces(Timestep timestep) { LPJYieldResponseMapReader yieldReader = new LPJYieldResponseMapReader(desiredProjection); - return yieldReader.getRasterData(ModelConfig.YIELD_DIR + File.separator + year); + return yieldReader.getRasterData(ModelConfig.YIELD_DIR + File.separator + timestep.getYieldYear()); } private RasterSet<IrrigationCostItem> getIrrigationCosts() { diff --git a/src/ac/ed/lurg/Timestep.java b/src/ac/ed/lurg/Timestep.java new file mode 100644 index 0000000000000000000000000000000000000000..aa783df4ad6b64e00c2bc8f759f51c78be2f0f1d --- /dev/null +++ b/src/ac/ed/lurg/Timestep.java @@ -0,0 +1,66 @@ +package ac.ed.lurg; + + +public class Timestep { + + private int timestep; + + public Timestep(int timestep) { + this.timestep = timestep; + } + + public int getTimestep() { + return timestep; + } + + public int getYear() { + return ModelConfig.TIMESTEP_SIZE * (timestep - ModelConfig.START_TIMESTEP) + ModelConfig.BASE_YEAR; + } + + public int getYieldYear() { + if (isInitialTimestep()) { + return ModelConfig.BASE_YEAR; + } + else { + return getPreviousTimestep().getYear(); + } + } + + @Override + public String toString() { + return "Timestep: " + timestep + ", year:" + getYear(); + } + + public boolean isInitialTimestep() { + return timestep == ModelConfig.START_TIMESTEP; + } + + public Timestep getPreviousTimestep() { + if (timestep == ModelConfig.START_TIMESTEP) + throw new RuntimeException("Can't getPreviousTimestep for " + timestep); + + return new Timestep(timestep-1); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + timestep; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Timestep other = (Timestep) obj; + if (timestep != other.timestep) + return false; + return true; + } +} diff --git a/src/ac/ed/lurg/country/CountryAgent.java b/src/ac/ed/lurg/country/CountryAgent.java index 4b2507f1f10591aa7b382291219d5c0eec5696e9..48b826c078cd8836ea7974573724f99c36c29ca6 100644 --- a/src/ac/ed/lurg/country/CountryAgent.java +++ b/src/ac/ed/lurg/country/CountryAgent.java @@ -4,6 +4,7 @@ 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; @@ -25,9 +26,9 @@ public class CountryAgent { private DemandManager demandManager; private Country country; - private Map<Integer, GamsRasterOutput> resultsTimeseries = new HashMap<Integer, GamsRasterOutput>(); + private Map<Timestep, GamsRasterOutput> resultsTimeseries = new HashMap<Timestep, GamsRasterOutput>(); - private int currentTimestep; + private Timestep currentTimestep; private YieldRaster countryYieldSurfaces; private RasterSet<IrrigationCostItem> irrigationCostRaster; @@ -41,7 +42,7 @@ public class CountryAgent { GamsRasterOutput initialData = new GamsRasterOutput(cropAreaRaster, cropUsageData); - resultsTimeseries.put(0, initialData); + resultsTimeseries.put(new Timestep(0), initialData); } private RasterSet<AreasItem> convertInitialLC(RasterSet<LandCoverItem> initialLC) { @@ -63,13 +64,12 @@ public class CountryAgent { return country; } - public GamsRasterOutput determineProduction(int timestep, YieldRaster countryYieldSurfaces, Map<CropType, Double> worldInputEnergy) { + public GamsRasterOutput determineProduction(Timestep timestep, YieldRaster countryYieldSurfaces, Map<CropType, Double> worldInputEnergy) { currentTimestep = timestep; this.countryYieldSurfaces = countryYieldSurfaces; // get projected demand - int year = ModelConfig.BASE_YEAR + currentTimestep; - Map<CommodityType, Double> projectedDemand = demandManager.getDemand(country, year); + Map<CommodityType, Double> projectedDemand = demandManager.getDemand(country, timestep.getYear()); if (projectedDemand.size() == 0) { LogWriter.printlnError("No demand for country " + country + " so skipping it"); @@ -97,14 +97,14 @@ public class CountryAgent { Map<CropType, Double> cropAdjs; boolean calibrate; - if (ModelConfig.START_TIMESTEP == currentTimestep) { // initialisation time-step + if (currentTimestep.isInitialTimestep()) { // initialisation time-step calibrate = true; prevOutput = resultsTimeseries.get(currentTimestep); cropAdjs = null; } else { // normal (not the initial) time-step calibrate = false; - prevOutput = resultsTimeseries.get(currentTimestep - 1); + prevOutput = resultsTimeseries.get(currentTimestep.getPreviousTimestep()); cropAdjs = prevOutput.getCropAdjustments(); } diff --git a/src/ac/ed/lurg/country/gams/GamsCountryInput.java b/src/ac/ed/lurg/country/gams/GamsCountryInput.java index e904f4e2fc71eadda6a22c36d31ef3b908479cad..736cf89ac4c86805c01632f6c3c28e3b13bf8d7b 100644 --- a/src/ac/ed/lurg/country/gams/GamsCountryInput.java +++ b/src/ac/ed/lurg/country/gams/GamsCountryInput.java @@ -97,15 +97,15 @@ public class GamsCountryInput { // } public double getMeatEfficiency() { - return 0.5; // this is already handled by the feed conversion efficiency for each animal product + return ModelConfig.MEAT_EFFICIENCY; // this is already handled by the feed conversion efficiency for each animal product } public double getLandChangeEnergy() { - return 2.0; + return ModelConfig.LAND_CHANGE_COST; } public double getMinFeedRate() { - return 0.15; + return ModelConfig.MIN_FEED_RATE; } public Map<CropType, Double> getCropAdjustments() { diff --git a/src/ac/ed/lurg/output/LpjgOutputer.java b/src/ac/ed/lurg/output/LpjgOutputer.java index 571353493db74128394dd47b4a1ee09eaa669c0b..44f8671a5543f4a1c78cb38eebf13eb18dce158a 100644 --- a/src/ac/ed/lurg/output/LpjgOutputer.java +++ b/src/ac/ed/lurg/output/LpjgOutputer.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.util.Map.Entry; import ac.ed.lurg.ModelConfig; +import ac.ed.lurg.Timestep; import ac.ed.lurg.landuse.AreasItem; import ac.ed.lurg.landuse.IntensitiesItem; import ac.ed.lurg.types.CropType; @@ -23,25 +24,25 @@ public class LpjgOutputer { private RasterSet<IntensitiesItem> intensityRaster; private RasterSet<AreasItem> cropAreaRaster; private YieldRaster yieldSurfaces; - private int year; + private Timestep timestep; - public LpjgOutputer(int year, RasterSet<IntensitiesItem> intensityRaster, RasterSet<AreasItem> cropAreaRaster, YieldRaster yieldSurfaces) { - this.year = year; + public LpjgOutputer(Timestep timestep, RasterSet<IntensitiesItem> intensityRaster, RasterSet<AreasItem> cropAreaRaster, YieldRaster yieldSurfaces) { + this.timestep = timestep; this.intensityRaster = intensityRaster; this.cropAreaRaster = cropAreaRaster; this.yieldSurfaces = yieldSurfaces; } public void writeOutput() { - File outputDir = getOutputDir(year); + File outputDir = getOutputDir(timestep); writeLandCoverAndCrop(outputDir); writeIntensity(outputDir); - writeMarkerFile(year, false); + writeMarkerFile(timestep, false); } - private static File getOutputDir(int yr) { - String outputDirName = ModelConfig.OUTPUT_DIR + File.separator + yr; + private static File getOutputDir(Timestep timestep) { + String outputDirName = ModelConfig.OUTPUT_DIR + File.separator + timestep.getYear(); File outputDir = new File(outputDirName); outputDir.mkdirs(); return outputDir; @@ -52,8 +53,8 @@ public class LpjgOutputer { } - public static void writeMarkerFile(int year, boolean errorStatus) { - File outputDir = getOutputDir(year); + public static void writeMarkerFile(Timestep timestep, boolean errorStatus) { + File outputDir = getOutputDir(timestep); File markerFile = new File(outputDir.getPath() + File.separator + (errorStatus ? "error" : "done"));