diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms index a0f965328e8df798d9d34628a81aadf4b9545ff8..58dd449c90665756594922dbdedc528a1b0f1a04 100644 --- a/GAMS/IntExtOpt.gms +++ b/GAMS/IntExtOpt.gms @@ -3,9 +3,8 @@ SET crop_less_pasture(crop) arable crops types includes treenuts but not pasture / cereals, fruits, oilcrops, starchyRoots, treenuts, vegetables, pulses /; SET feed_crop(crop) / cereals, oilcrops /; SET not_feed_crops(crop) / fruits, starchyRoots, treenuts, vegetables, pulses, pasture_or_meat /; - SET landuse land use type / cropland, pasture /; - PARAMETER previous_area(landuse) areas for previous timestep in ha; + PARAMETER previous_area(crop) areas for previous timestep in ha; PARAMETER demand(crop) yield in t per ha; PARAMETER yield_ref(crop) yield in t per ha; PARAMETER world_input_energy(crop) average input energy from world exports used to determine if we should import or export; @@ -76,11 +75,11 @@ $gdxin MAX_INTENSITY_CONSTRAINT(crop) .. intensity(crop) =L= maxIntensity; - CROPLAND_CHANGE_CONSTRAINT .. 1 - sum(crop_less_pasture, area(crop_less_pasture))/previous_area('cropland') =L= maxLandUseChange; + CROPLAND_CHANGE_CONSTRAINT .. 1 - sum(crop_less_pasture, area(crop_less_pasture))/sum(crop_less_pasture, previous_area(crop_less_pasture)) =L= maxLandUseChange; - PASTURE_CHANGE_CONSTRAINT .. 1 - area('pasture_or_meat')/previous_area('pasture') =L= maxLandUseChange; + PASTURE_CHANGE_CONSTRAINT .. 1 - area('pasture_or_meat')/previous_area('pasture_or_meat') =L= maxLandUseChange; - AGRI_LAND_CHANGE_CONSTRAINT .. abs(sum(crop, area(crop)) / sum(landuse, previous_area(landuse)) - 1) =L= maxLandUseChange; + AGRI_LAND_CHANGE_CONSTRAINT .. abs(sum(crop, area(crop)) / sum(crop, previous_area(crop)) - 1) =L= maxLandUseChange; NON_FEED_CROP_CONSTRAINT(not_feed_crops) .. feedAmount(not_feed_crops) =E= 0; @@ -89,7 +88,7 @@ $gdxin MIN_FEED_CONSTRAINT .. sum(feed_crop, feedDM(feed_crop) * feedAmount(feed_crop)) =G= minFeedRate * (demand('pasture_or_meat') + exportAmount('pasture_or_meat') - importAmount('pasture_or_meat')); ENERGY_EQ .. energy =E= SUM(crop, area(crop)*unit_energy(crop)) - + (sum(crop, area(crop)) - sum(landuse, previous_area(landuse))) * landChangeEnergy + + (sum(crop, area(crop)) - sum(crop, previous_area(crop))) * landChangeEnergy - sum(crop, (exportAmount(crop) - importAmount(crop) * tradeBarrier) * world_input_energy(crop)); MODEL LAND_USE /ALL/ ; diff --git a/src/ac/ed/lurg/GamsTest.java b/src/ac/ed/lurg/GamsTest.java index c853ce1ad437f8b6952d4969b97bf10c9b82641d..6df12eddb3543b977f52a5f7c75b512a75f8a1e1 100644 --- a/src/ac/ed/lurg/GamsTest.java +++ b/src/ac/ed/lurg/GamsTest.java @@ -35,8 +35,10 @@ public class GamsTest { GAMSDatabase db = ws.addDatabase(); GAMSParameter parm = db.addParameter("previous_area", 1, "the previous area for each land use"); - parm.addRecord("cropland").setValue(10.0); - parm.addRecord("pasture").setValue(90.0); + parm.addRecord("cereals").setValue(1); + parm.addRecord("fruits").setValue(1); + parm.addRecord("oilcrops").setValue(10); + parm.addRecord("pasture_or_meat").setValue(9); // meat demand in t parm = db.addParameter("demand", 1, "demand for crop"); parm.addRecord("cereals").setValue(9.597544542866817); diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java index bac0efe139007274f90a1381ee64e7816c95854a..270d9af129a59e812b81d39ad7630c7308bfb2f9 100644 --- a/src/ac/ed/lurg/ModelConfig.java +++ b/src/ac/ed/lurg/ModelConfig.java @@ -96,7 +96,7 @@ public class ModelConfig { public static final int START_TIMESTEP = getIntProperty("START_TIMESTEP", 0); - public static final int END_TIMESTEP = getIntProperty("END_TIMESTEP", 0); + public static final int END_TIMESTEP = getIntProperty("END_TIMESTEP", 1); public static final int BASE_YEAR = getIntProperty("BASE_YEAR", 2010); } \ No newline at end of file diff --git a/src/ac/ed/lurg/ModelMain.java b/src/ac/ed/lurg/ModelMain.java index 989454763fc17725253da3f4bebaa5e373901f4d..621f1558acdc44b1ca166d6b6a7c284381f4c497 100644 --- a/src/ac/ed/lurg/ModelMain.java +++ b/src/ac/ed/lurg/ModelMain.java @@ -27,7 +27,6 @@ public class ModelMain { modelContext = new ModelContext(demandManager, yieldManager); - // read initial country data (country, areas) countryAgents = new CountryAgentCreator().getAgents(modelContext); } diff --git a/src/ac/ed/lurg/country/CountryAgent.java b/src/ac/ed/lurg/country/CountryAgent.java index 7006e49dfa85d7601ea9b8dce33cea4aba6bafe9..86e2870b1f15ed500d629dbb109fa8324455e853 100644 --- a/src/ac/ed/lurg/country/CountryAgent.java +++ b/src/ac/ed/lurg/country/CountryAgent.java @@ -1,6 +1,5 @@ package ac.ed.lurg.country; -import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -8,9 +7,7 @@ import ac.ed.lurg.ModelConfig; import ac.ed.lurg.ModelContext; import ac.ed.lurg.country.gams.GamsInputData; import ac.ed.lurg.country.gams.GamsLandUseOptimiser; -import ac.ed.lurg.country.gams.GamsOutputItemData; -import ac.ed.lurg.types.Item; -import ac.ed.lurg.types.LandCoverType; +import ac.ed.lurg.types.CropType; import ac.ed.lurg.utils.LogWriter; /* @@ -20,24 +17,27 @@ public class CountryAgent implements GamsInputData { private ModelContext modelContext; private Country country; - private Map<Integer, CountryData> timeseries = new HashMap<Integer, CountryData>(); + private Map<Integer, CropAreas> cropAreasTimeseries = new HashMap<Integer, CropAreas>(); + private Map<Integer, LandCoverAreas> landUseAreasTimeseries = new HashMap<Integer, LandCoverAreas>(); + private int currentTimestep; - private Map<Item, Double> currentProjectedDemand; - private Map<Item, Double> currentRefYield; + private Map<CropType, Double> currentProjectedDemand; + private Map<CropType, Double> currentRefYield; - public CountryAgent(ModelContext modelContext, Country country, CountryData initialCountryData) { + public CountryAgent(ModelContext modelContext, Country country, CropAreas initialCropAreas, LandCoverAreas initialLandCover) { this.modelContext = modelContext; this.country = country; - timeseries.put(0, initialCountryData); + cropAreasTimeseries.put(0, initialCropAreas); + landUseAreasTimeseries.put(0, initialLandCover); } public Country getCountry() { return country; } - public double getCropArea(int timestep, Item item) { - CountryData cd = timeseries.get(timestep); + public double getCropArea(int timestep, CropType item) { + CropAreas cd = cropAreasTimeseries.get(timestep); if (cd == null) { LogWriter.printlnError("Asked for timestep that we don't have " + timestep); return Double.NaN; @@ -61,52 +61,58 @@ public class CountryAgent implements GamsInputData { GamsLandUseOptimiser opti = new GamsLandUseOptimiser(this); LogWriter.println("Running " + country.getCountryName() + ", year " + year); - Collection<GamsOutputItemData> result = opti.run(); - + CropAreas result = opti.run(); LogWriter.println("Got " + result.size() + " results"); - + cropAreasTimeseries.put(timestep, result); } @Override - public Map<Item, Double> getProjectedDemand() { + public Map<CropType, Double> getProjectedDemand() { return currentProjectedDemand; } @Override - public Map<Item, Double> getRefYield() { + public Map<CropType, Double> getRefYield() { return currentRefYield; } @Override - public double getLandCoverArea(LandCoverType landCover) { - return timeseries.get(currentTimestep).getLandCoverArea(landCover); + public Map<CropType, Double> getPreviousCropArea() { + Map<CropType, Double> previousCropAreas = new HashMap<CropType, Double>(); + int previousTimestep = currentTimestep==0 ? 0 : currentTimestep-1; + CropAreas cd = cropAreasTimeseries.get(previousTimestep); + + for (CropType crop : CropType.getAllItems()) + previousCropAreas.put(crop, cd.getCropArea(crop)); + + return previousCropAreas; } @Override - public Map<Item, Double> getWorldInputEnergy() { - Map<Item, Double> dummyInputEnergy = new HashMap<Item, Double>(); - dummyInputEnergy.put(Item.CEREALS, 9.0); - dummyInputEnergy.put(Item.FRUIT, 5.0); - dummyInputEnergy.put(Item.OILCROPS, 10.0); - dummyInputEnergy.put(Item.STARCHY_ROOTS, 5.0); - dummyInputEnergy.put(Item.PULSES, 20.0); - dummyInputEnergy.put(Item.VEGETABLES, 20.0); - dummyInputEnergy.put(Item.MEAT, 80.0); - dummyInputEnergy.put(Item.TREENUTS, 5.0); - return dummyInputEnergy; + public Map<CropType, Double> getWorldInputEnergy() { + Map<CropType, Double> dummyMap = new HashMap<CropType, Double>(); + dummyMap.put(CropType.CEREALS, 9.0); + dummyMap.put(CropType.FRUIT, 5.0); + dummyMap.put(CropType.OILCROPS, 10.0); + dummyMap.put(CropType.STARCHY_ROOTS, 5.0); + dummyMap.put(CropType.PULSES, 20.0); + dummyMap.put(CropType.VEGETABLES, 20.0); + dummyMap.put(CropType.MEAT_OR_PASTURE, 80.0); + dummyMap.put(CropType.TREENUTS, 5.0); + return dummyMap; } @Override - public Map<Item, Double> getMaxExport() { - Map<Item, Double> dummyMaxExports = new HashMap<Item, Double>(); - dummyMaxExports.put(Item.CEREALS, 24.0); - dummyMaxExports.put(Item.FRUIT, 5.0); - dummyMaxExports.put(Item.OILCROPS, 5.0); - dummyMaxExports.put(Item.STARCHY_ROOTS, 5.0); - dummyMaxExports.put(Item.PULSES, 5.0); - dummyMaxExports.put(Item.VEGETABLES, 5.0); - dummyMaxExports.put(Item.MEAT, 5.0); - dummyMaxExports.put(Item.TREENUTS, 5.0); + public Map<CropType, Double> getMaxExport() { + Map<CropType, Double> dummyMaxExports = new HashMap<CropType, Double>(); + dummyMaxExports.put(CropType.CEREALS, 24.0); + dummyMaxExports.put(CropType.FRUIT, 5.0); + dummyMaxExports.put(CropType.OILCROPS, 5.0); + dummyMaxExports.put(CropType.STARCHY_ROOTS, 5.0); + dummyMaxExports.put(CropType.PULSES, 5.0); + dummyMaxExports.put(CropType.VEGETABLES, 5.0); + dummyMaxExports.put(CropType.MEAT_OR_PASTURE, 5.0); + dummyMaxExports.put(CropType.TREENUTS, 5.0); return dummyMaxExports; } diff --git a/src/ac/ed/lurg/country/CountryAgentCreator.java b/src/ac/ed/lurg/country/CountryAgentCreator.java index 44200a85cbd72f9a1abe77d5a379e274fb9ed339..517c6fe568f46d86b7148f58b162138b5a7a2fa1 100644 --- a/src/ac/ed/lurg/country/CountryAgentCreator.java +++ b/src/ac/ed/lurg/country/CountryAgentCreator.java @@ -7,6 +7,7 @@ import java.util.HashSet; import ac.ed.lurg.ModelConfig; import ac.ed.lurg.ModelContext; +import ac.ed.lurg.types.CropType; import ac.ed.lurg.types.LandCoverType; import ac.ed.lurg.utils.LogWriter; @@ -47,19 +48,24 @@ public class CountryAgentCreator { } double arableArea = Double.parseDouble(tokens[ARABLE_COL])/1000; + double pastureArea = Double.parseDouble(tokens[PASTURE_COL])/1000; + if (pastureArea == 0) + pastureArea = arableArea * 0.05; + // double intensity = Math.sqrt(Double.parseDouble(tokens[FERT_N_COL])/arableArea); - CountryData initialCountryData = new CountryData(); - initialCountryData.setLandCoverArea(LandCoverType.LAND, Double.parseDouble(tokens[LAND_COL])/1000); - initialCountryData.setLandCoverArea(LandCoverType.ARABLE, arableArea); - initialCountryData.setLandCoverArea(LandCoverType.FOREST, Double.parseDouble(tokens[FOREST_COL])/1000); - initialCountryData.setLandCoverArea(LandCoverType.PERM_CROP, Double.parseDouble(tokens[PERM_CROP_COL])/1000); - double pasture = Double.parseDouble(tokens[PASTURE_COL])/1000; - if (pasture == 0) - pasture = arableArea * 0.05; - initialCountryData.setLandCoverArea(LandCoverType.PASTURE, pasture); + LandCoverAreas initialLandCover = new LandCoverAreas(); + initialLandCover.setLandCoverArea(LandCoverType.LAND, Double.parseDouble(tokens[LAND_COL])/1000); + initialLandCover.setLandCoverArea(LandCoverType.ARABLE, arableArea); + initialLandCover.setLandCoverArea(LandCoverType.FOREST, Double.parseDouble(tokens[FOREST_COL])/1000); + initialLandCover.setLandCoverArea(LandCoverType.PERM_CROP, Double.parseDouble(tokens[PERM_CROP_COL])/1000); + initialLandCover.setLandCoverArea(LandCoverType.PASTURE, pastureArea); - CountryAgent ca = new CountryAgent(modelContext, Country.get(countryName), initialCountryData); + CropAreas initialCropData = new CropAreas(); + initialCropData.addCropArea(CropType.CEREALS, arableArea, Double.NaN, Double.NaN, Double.NaN); // at the moment can substitute freely between arable crops so this is ok-ish + initialCropData.addCropArea(CropType.MEAT_OR_PASTURE, pastureArea, Double.NaN, Double.NaN, Double.NaN); + + CountryAgent ca = new CountryAgent(modelContext, Country.get(countryName), initialCropData, initialLandCover); countryAgents.add(ca); } diff --git a/src/ac/ed/lurg/country/CountryData.java b/src/ac/ed/lurg/country/CountryData.java deleted file mode 100644 index d0b258a3c3ca17144329b0c8e8f08cce6ad825b4..0000000000000000000000000000000000000000 --- a/src/ac/ed/lurg/country/CountryData.java +++ /dev/null @@ -1,39 +0,0 @@ -package ac.ed.lurg.country; - -import java.util.HashMap; -import java.util.Map; - -import ac.ed.lurg.types.Item; -import ac.ed.lurg.types.LandCoverType; - -/* - * Data for one year and country, but it does not know which one - */ -public class CountryData { - - private Map<Item, LandUseData> cropAreas = new HashMap<Item, LandUseData>(); - private Map<LandCoverType, Double> landCoverAreas = new HashMap<LandCoverType, Double>(); - - public double getLandCoverArea(LandCoverType c) { - Double d = landCoverAreas.get(c); - return d == null ? Double.NaN : d; - } - - public void setLandCoverArea(LandCoverType c, double d) { - landCoverAreas.put(c, d); - } - - public double getCropArea(Item c) { - LandUseData lu = cropAreas.get(c); - - if (lu != null) - return lu.getArea(); - else - return 0; - } - - public void setCropArea(Item c, double area, double intensity) { - LandUseData lu = new LandUseData(area, intensity); - cropAreas.put(c, lu); - } -} diff --git a/src/ac/ed/lurg/country/CropAreas.java b/src/ac/ed/lurg/country/CropAreas.java new file mode 100644 index 0000000000000000000000000000000000000000..15875f4606acb151ecefcfbc2c50f6b6471b16e3 --- /dev/null +++ b/src/ac/ed/lurg/country/CropAreas.java @@ -0,0 +1,32 @@ +package ac.ed.lurg.country; + +import java.util.HashMap; +import java.util.Map; + +import ac.ed.lurg.types.CropType; + +/* + * Data for one year and country, but it does not know which one + */ +public class CropAreas { + + private Map<CropType, LandUseData> cropAreas = new HashMap<CropType, LandUseData>(); + + public double getCropArea(CropType c) { + LandUseData lu = cropAreas.get(c); + + if (lu != null) + return lu.getArea(); + else + return 0; + } + + public void addCropArea(CropType c, double area, double intensity, double feedAmount, double netImports) { + LandUseData lu = new LandUseData(area, intensity, feedAmount, netImports); + cropAreas.put(c, lu); + } + + public int size() { + return cropAreas.size(); + } +} diff --git a/src/ac/ed/lurg/country/LandCoverAreas.java b/src/ac/ed/lurg/country/LandCoverAreas.java new file mode 100644 index 0000000000000000000000000000000000000000..39fb3c6651d6577c1ea88d3860f8e9dd731c2d0d --- /dev/null +++ b/src/ac/ed/lurg/country/LandCoverAreas.java @@ -0,0 +1,20 @@ +package ac.ed.lurg.country; + +import java.util.HashMap; +import java.util.Map; + +import ac.ed.lurg.types.LandCoverType; + +public class LandCoverAreas { + private Map<LandCoverType, Double> landCoverAreas = new HashMap<LandCoverType, Double>(); + + public double getLandCoverArea(LandCoverType c) { + Double d = landCoverAreas.get(c); + return d == null ? Double.NaN : d; + } + + public void setLandCoverArea(LandCoverType c, double d) { + landCoverAreas.put(c, d); + } + +} diff --git a/src/ac/ed/lurg/country/LandUseData.java b/src/ac/ed/lurg/country/LandUseData.java index c0914946fce001941db407421a29b0c96372180b..5fdcd1c86b4ab36f82864018921fae98bf7d924d 100644 --- a/src/ac/ed/lurg/country/LandUseData.java +++ b/src/ac/ed/lurg/country/LandUseData.java @@ -1,14 +1,20 @@ package ac.ed.lurg.country; +import ac.ed.lurg.types.CropType; + public class LandUseData { private double area; private double intensity; - - public LandUseData(double area, double intensity) { + public double feedAmount; + public double netImports; + + public LandUseData(double area, double intensity, double feedAmount, double netImports) { super(); this.area = area; this.intensity = intensity; + this.feedAmount = feedAmount; + this.netImports = netImports; } public double getArea() { @@ -18,4 +24,12 @@ public class LandUseData { public double getIntensity() { return intensity; } + + public double getFeedAmount() { + return feedAmount; + } + + public double getNetImports() { + return netImports; + } } diff --git a/src/ac/ed/lurg/country/gams/GamsInputData.java b/src/ac/ed/lurg/country/gams/GamsInputData.java index a242736e5541eec04e337f4a6c949688b2da408c..161239c712af7f2126d68fc1687f8f24462b4e3d 100644 --- a/src/ac/ed/lurg/country/gams/GamsInputData.java +++ b/src/ac/ed/lurg/country/gams/GamsInputData.java @@ -2,16 +2,15 @@ package ac.ed.lurg.country.gams; import java.util.Map; -import ac.ed.lurg.types.Item; -import ac.ed.lurg.types.LandCoverType; +import ac.ed.lurg.types.CropType; public interface GamsInputData { - Map<Item, Double> getProjectedDemand(); - Map<Item, Double> getRefYield(); - double getLandCoverArea(LandCoverType landCover); - Map<Item, Double> getWorldInputEnergy(); - Map<Item, Double> getMaxExport(); + Map<CropType, Double> getProjectedDemand(); + Map<CropType, Double> getRefYield(); + Map<CropType, Double> getPreviousCropArea(); + Map<CropType, Double> getWorldInputEnergy(); + Map<CropType, Double> getMaxExport(); double getMeatEfficiency(); double getMaxLandUseChange(); double getMaxIntensity(); diff --git a/src/ac/ed/lurg/country/gams/GamsLandUseOptimiser.java b/src/ac/ed/lurg/country/gams/GamsLandUseOptimiser.java index 85cb7f8e587a325fdaf97755c3ce3b2f182b5d71..3094fdda814d62331656fd3df5647301da759999 100644 --- a/src/ac/ed/lurg/country/gams/GamsLandUseOptimiser.java +++ b/src/ac/ed/lurg/country/gams/GamsLandUseOptimiser.java @@ -2,12 +2,12 @@ package ac.ed.lurg.country.gams; import java.io.File; import java.util.Collection; -import java.util.HashSet; import java.util.Map; import ac.ed.lurg.ModelConfig; -import ac.ed.lurg.types.Item; -import ac.ed.lurg.types.LandCoverType; +import ac.ed.lurg.country.CropAreas; +import ac.ed.lurg.country.LandUseData; +import ac.ed.lurg.types.CropType; import ac.ed.lurg.utils.LogWriter; import com.gams.api.GAMSDatabase; @@ -28,7 +28,7 @@ public class GamsLandUseOptimiser { this.inputData = inputData; } - public Collection<GamsOutputItemData> run() { + public CropAreas run() { File workingDirectory = new File(ModelConfig.TEMP_DIR, "GamsTest"); workingDirectory.mkdir(); @@ -40,9 +40,9 @@ public class GamsLandUseOptimiser { GAMSWorkspace ws = new GAMSWorkspace(wsInfo); GAMSDatabase db = ws.addDatabase(); + LogWriter.println("\nPrevious areas"); GAMSParameter parm = db.addParameter("previous_area", 1, "the previous area for each land use"); - addLandUseArea(parm, LandCoverType.ARABLE); - addLandUseArea(parm, LandCoverType.PASTURE); + addItemMapParm(parm, inputData.getPreviousCropArea()); LogWriter.println("\nDemand"); parm = db.addParameter("demand", 1, "demand for crop"); @@ -84,7 +84,7 @@ public class GamsLandUseOptimiser { double totalArea = 0; double area, intensity, feedAmount, exports, imports; - Collection<GamsOutputItemData> output = new HashSet<GamsOutputItemData>(); + CropAreas output = new CropAreas(); for (GAMSVariableRecord rec : varAreas) { String itemName = rec.getKeys()[0]; @@ -97,8 +97,7 @@ public class GamsLandUseOptimiser { LogWriter.println(String.format("%15s:\tarea= %.1f,\tintensity= %.3f,\tfeedAmount= %.0f,\texports= %.0f,\timports= %.0f", itemName, area, intensity, feedAmount, exports, imports)); - GamsOutputItemData itemOutput = new GamsOutputItemData(Item.getForGamsName(itemName), area, intensity, feedAmount, exports, imports); - output.add(itemOutput); + output.addCropArea(CropType.getForGamsName(itemName), area, intensity, feedAmount, imports-exports); } LogWriter.println(String.format(" Total area= %.1f", totalArea)); //cleanup(ws.workingDirectory()); @@ -106,18 +105,12 @@ public class GamsLandUseOptimiser { return output; } - private void addLandUseArea(GAMSParameter parm, LandCoverType landCover) { - double val = inputData.getLandCoverArea(landCover); - LogWriter.println(" " + landCover.getName() + ",\t\t" + val); - parm.addRecord(landCover.getName()).setValue(val); - } - private void addScalar(GAMSParameter param, double val) { param.addRecord().setValue(val); } - private void addItemMapParm(GAMSParameter parm, Map<Item, Double> itemMap) { - for (Map.Entry<Item, Double> entry : itemMap.entrySet()) { + private void addItemMapParm(GAMSParameter parm, Map<CropType, Double> itemMap) { + for (Map.Entry<CropType, Double> entry : itemMap.entrySet()) { LogWriter.println(" " + entry.getKey().getGamsName() + ",\t\t" + entry.getValue()); parm.addRecord(entry.getKey().getGamsName()).setValue(entry.getValue()); } diff --git a/src/ac/ed/lurg/country/gams/GamsOutputItemData.java b/src/ac/ed/lurg/country/gams/GamsOutputItemData.java deleted file mode 100644 index fd1b9a9afef330e8e76d1fe9cbfddb0dd8d574fd..0000000000000000000000000000000000000000 --- a/src/ac/ed/lurg/country/gams/GamsOutputItemData.java +++ /dev/null @@ -1,73 +0,0 @@ -package ac.ed.lurg.country.gams; - -import ac.ed.lurg.types.Item; - -public class GamsOutputItemData { - - private Item item; - private double area; - private double intensity; - private double feedAmount; - private double exports; - private double imports; - - public GamsOutputItemData(Item item, double area, double intensity, double feedAmount, double exports, double imports) { - super(); - this.area = area; - this.intensity = intensity; - this.feedAmount = feedAmount; - this.exports = exports; - this.imports = imports; - this.item = item; - } - - public double getArea() { - return area; - } - - public void setArea(double area) { - this.area = area; - } - - public double getIntensity() { - return intensity; - } - - public void setIntensity(double intensity) { - this.intensity = intensity; - } - - public double getFeedAmount() { - return feedAmount; - } - - public void setFeedAmount(double feedAmount) { - this.feedAmount = feedAmount; - } - - public double getExports() { - return exports; - } - - public void setExports(double exports) { - this.exports = exports; - } - - public double getImports() { - return imports; - } - - public void setImports(double imports) { - this.imports = imports; - } - - public Item getItem() { - return item; - } - - public void setItem(Item item) { - this.item = item; - } - - -} diff --git a/src/ac/ed/lurg/demand/DemandCurve.java b/src/ac/ed/lurg/demand/DemandCurve.java index b1377dc60dd408173ce1ad3f21eae05f54a1de36..fe7ebd7adf2349318e715c194a4315e12d51ff87 100644 --- a/src/ac/ed/lurg/demand/DemandCurve.java +++ b/src/ac/ed/lurg/demand/DemandCurve.java @@ -1,6 +1,6 @@ package ac.ed.lurg.demand; -import ac.ed.lurg.types.Item; +import ac.ed.lurg.types.CropType; import ac.ed.lurg.types.ModelFitType; @@ -10,9 +10,9 @@ public class DemandCurve { private double b; private double c; private ModelFitType fitType; - private Item item; + private CropType item; - DemandCurve(Item item, double a, double b, double c, ModelFitType fitType) { + DemandCurve(CropType item, double a, double b, double c, ModelFitType fitType) { super(); this.item = item; this.a = a; @@ -37,7 +37,7 @@ public class DemandCurve { return fitType; } - public Item getItem() { + public CropType getItem() { return item; } diff --git a/src/ac/ed/lurg/demand/DemandCurveManager.java b/src/ac/ed/lurg/demand/DemandCurveManager.java index 11aceb83d7e07090471f19dc17708536c5beafd6..445178552316d4de11d40c749df28604cc1c7555 100644 --- a/src/ac/ed/lurg/demand/DemandCurveManager.java +++ b/src/ac/ed/lurg/demand/DemandCurveManager.java @@ -6,7 +6,7 @@ import java.util.Collection; import java.util.HashSet; import ac.ed.lurg.ModelConfig; -import ac.ed.lurg.types.Item; +import ac.ed.lurg.types.CropType; import ac.ed.lurg.types.ModelFitType; import ac.ed.lurg.utils.LogWriter; @@ -44,7 +44,7 @@ public class DemandCurveManager { c = Double.parseDouble(tokens[C_COL]); fitType = tokens[FIT_TYPE_COL]; - DemandCurve dc = new DemandCurve(Item.getForFaoName(faoItemName), a, b, c, ModelFitType.findByName(fitType)); + DemandCurve dc = new DemandCurve(CropType.getForFaoName(faoItemName), a, b, c, ModelFitType.findByName(fitType)); curves.add(dc); } fitReader.close(); diff --git a/src/ac/ed/lurg/demand/DemandManager.java b/src/ac/ed/lurg/demand/DemandManager.java index 3afac0ccecba9ff55842290a5dad5af5cc30d3c0..b4b264c011856748920dca053d20f1105a17a032 100644 --- a/src/ac/ed/lurg/demand/DemandManager.java +++ b/src/ac/ed/lurg/demand/DemandManager.java @@ -4,7 +4,7 @@ import java.util.HashMap; import java.util.Map; import ac.ed.lurg.country.Country; -import ac.ed.lurg.types.Item; +import ac.ed.lurg.types.CropType; import ac.ed.lurg.types.ModelFitType; import ac.ed.lurg.utils.LogWriter; @@ -23,10 +23,12 @@ public class DemandManager { sspManager = new SspManager(); } - public Map<Item, Double> getDemand(Country country, int year) { - Map<Item, Double> demandMap = new HashMap<Item, Double>(); + public Map<CropType, Double> getDemand(Country country, int year) { + Map<CropType, Double> demandMap = new HashMap<CropType, Double>(); SspData sd = sspManager.get(ssp_scenario, year, country); + LogWriter.println("Got ssp data for " + country.getCountryName() + " of " + sd); + if (sd == null) { LogWriter.printlnError("No ssp data for " + ssp_scenario + ", " + year + ", " + country.getCountryName()); return demandMap; diff --git a/src/ac/ed/lurg/demand/SspData.java b/src/ac/ed/lurg/demand/SspData.java index 5dedb78ba40cc6346812e6af15c4dc6ff6b7934e..04f83c5c8caabfb31b7078f15fbbd1bc618e2c01 100644 --- a/src/ac/ed/lurg/demand/SspData.java +++ b/src/ac/ed/lurg/demand/SspData.java @@ -22,4 +22,9 @@ public class SspData { public double getGdpPc() { return gdp/population; } + + @Override + public String toString() { + return "SspData [population=" + population + ", gdp=" + gdp + "]"; + } } diff --git a/src/ac/ed/lurg/demand/SspManager.java b/src/ac/ed/lurg/demand/SspManager.java index 0699b074d4e199501903122fb3d17fc88bd423e4..46bc8ee9ade022021e0a0822a985ed798a8b96e8 100644 --- a/src/ac/ed/lurg/demand/SspManager.java +++ b/src/ac/ed/lurg/demand/SspManager.java @@ -65,10 +65,46 @@ public class SspManager { } public SspData get(String scenario, int year, Country country) { - return get(new SspKey(scenario, year, country)); + SspData targetYearData = lookup(scenario, year, country); + if (targetYearData != null) + return targetYearData; + + SspData upYearData = null, downYearData = null; + int downYear = year-1, upYear = year+1; + + for (; upYear <= year+10; upYear++) { + upYearData = lookup(scenario, upYear, country); + if (upYearData != null) + break; + } + + for (; downYear >= year-10; downYear--) { + downYearData = lookup(scenario, downYear, country); + if (downYearData != null) + break; + } + + if (upYearData!=null && downYearData != null) { + double factor = ((double)(year - downYear)) / (upYear - downYear); + + double pop = interpolate(upYearData.getPopulation(), downYearData.getPopulation(), factor); + double gdp = interpolate(upYearData.getGdp(), downYearData.getGdp(), factor); + + return new SspData(pop, gdp); + } + else { + LogWriter.printlnError("Can't find straddling year for " + year + ", " + scenario + ", " + country.getCountryName()); + return null; + } } - public SspData get(SspKey sspKey) { + private double interpolate(double up, double down, double factor) { + double res = down + factor * (up - down); + return res; + } + + private SspData lookup(String scenario, int year, Country country) { + SspKey sspKey = new SspKey(scenario, year, country); return sspMap.get(sspKey); } } diff --git a/src/ac/ed/lurg/types/CropType.java b/src/ac/ed/lurg/types/CropType.java new file mode 100644 index 0000000000000000000000000000000000000000..c2406deed50c411ae747a5050282320186e7d4df --- /dev/null +++ b/src/ac/ed/lurg/types/CropType.java @@ -0,0 +1,60 @@ +package ac.ed.lurg.types; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import ac.ed.lurg.utils.LogWriter; + +public class CropType { + private static final Map<String, CropType> faoNameCache = new HashMap<String, CropType>(); + private static final Map<String, CropType> gamsNameCache = new HashMap<String, CropType>(); + + public final static CropType MEAT_OR_PASTURE = new CropType("meatmilkeggs", "pasture_or_meat"); + public final static CropType TREENUTS = new CropType("Treenuts + (Total)", "treenuts"); + public final static CropType VEGETABLES = new CropType("Vegetables + (Total)", "vegetables"); + public final static CropType PULSES = new CropType("Pulses + (Total)", "pulses"); + public final static CropType STARCHY_ROOTS = new CropType("Starchy Roots + (Total)", "starchyRoots"); + public final static CropType FRUIT = new CropType("Fruits - Excluding Wine + (Total)", "fruits"); + public final static CropType OILCROPS = new CropType("Oilcrops + (Total)", "oilcrops"); + public final static CropType CEREALS = new CropType("Cereals - Excluding Beer + (Total)", "cereals"); + + private String faoName; + private String gamsName; + + CropType (String faoName, String gamsName) { + this.faoName = faoName; + this.gamsName = gamsName; + faoNameCache.put(faoName, this); + gamsNameCache.put(gamsName, this); + } + + public static CropType getForFaoName(String faoName) { + return getFromCache(faoNameCache, faoName); + } + + public static CropType getForGamsName(String gamsName) { + return getFromCache(gamsNameCache, gamsName); + } + + private static CropType getFromCache(Map<String, CropType> cache, String name) { + CropType type = cache.get(name); + + if (type == null) + LogWriter.printlnError("Can't find Item for " + name); + + return type; + } + + public static Collection<CropType> getAllItems() { + return faoNameCache.values(); + } + + public String getFaoName() { + return faoName; + } + + public String getGamsName() { + return gamsName; + } +} diff --git a/src/ac/ed/lurg/types/Item.java b/src/ac/ed/lurg/types/Item.java deleted file mode 100644 index ada72f223ecc3d743d8581c29d38fc3bf6036dbe..0000000000000000000000000000000000000000 --- a/src/ac/ed/lurg/types/Item.java +++ /dev/null @@ -1,60 +0,0 @@ -package ac.ed.lurg.types; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import ac.ed.lurg.utils.LogWriter; - -public class Item { - private static final Map<String, Item> faoNameCache = new HashMap<String, Item>(); - private static final Map<String, Item> gamsNameCache = new HashMap<String, Item>(); - - public final static Item MEAT = new Item("meatmilkeggs", "pasture_or_meat"); - public final static Item TREENUTS = new Item("Treenuts + (Total)", "treenuts"); - public final static Item VEGETABLES = new Item("Vegetables + (Total)", "vegetables"); - public final static Item PULSES = new Item("Pulses + (Total)", "pulses"); - public final static Item STARCHY_ROOTS = new Item("Starchy Roots + (Total)", "starchyRoots"); - public final static Item FRUIT = new Item("Fruits - Excluding Wine + (Total)", "fruits"); - public final static Item OILCROPS = new Item("Oilcrops + (Total)", "oilcrops"); - public final static Item CEREALS = new Item("Cereals - Excluding Beer + (Total)", "cereals"); - - private String faoName; - private String gamsName; - - Item(String faoName, String gamsName) { - this.faoName = faoName; - this.gamsName = gamsName; - faoNameCache.put(faoName, this); - gamsNameCache.put(gamsName, this); - } - - public static Item getForFaoName(String faoName) { - return getFromCache(faoNameCache, faoName); - } - - public static Item getForGamsName(String gamsName) { - return getFromCache(gamsNameCache, gamsName); - } - - private static Item getFromCache(Map<String, Item> cache, String name) { - Item type = cache.get(name); - - if (type == null) - LogWriter.printlnError("Can't find Item for " + name); - - return type; - } - - public static Collection<Item> getAllItems() { - return faoNameCache.values(); - } - - public String getFaoName() { - return faoName; - } - - public String getGamsName() { - return gamsName; - } -} diff --git a/src/ac/ed/lurg/yield/YieldKey.java b/src/ac/ed/lurg/yield/YieldKey.java index 0a569c4f2d3f30d9e87a4c9e8854c9982c1a2577..c744e722427add3da2364941b922dd0732b45344 100644 --- a/src/ac/ed/lurg/yield/YieldKey.java +++ b/src/ac/ed/lurg/yield/YieldKey.java @@ -1,13 +1,13 @@ package ac.ed.lurg.yield; import ac.ed.lurg.country.Country; -import ac.ed.lurg.types.Item; +import ac.ed.lurg.types.CropType; class YieldKey { private Country country; - private Item item; + private CropType item; - YieldKey (Country country, Item item) { + YieldKey (Country country, CropType item) { this.item = item; this.country = country; } @@ -16,7 +16,7 @@ class YieldKey { return country; } - public Item getItem() { + public CropType getItem() { return item; } diff --git a/src/ac/ed/lurg/yield/YieldManager.java b/src/ac/ed/lurg/yield/YieldManager.java index 370a0c15553e45dcd56e94d3edf2f962a1f96daf..132e8e5ff2f18edde0a3cad0d9fec1149aceb552 100644 --- a/src/ac/ed/lurg/yield/YieldManager.java +++ b/src/ac/ed/lurg/yield/YieldManager.java @@ -7,12 +7,12 @@ import java.util.Map; import ac.ed.lurg.ModelConfig; import ac.ed.lurg.country.Country; -import ac.ed.lurg.types.Item; +import ac.ed.lurg.types.CropType; import ac.ed.lurg.utils.LogWriter; public class YieldManager { - private Map<Country, Map<Item, Double>> cache = new HashMap<Country, Map<Item, Double>>(); + private Map<Country, Map<CropType, Double>> cache = new HashMap<Country, Map<CropType, Double>>(); private static final int COUNTRY_COL = 0; private static final int ITEM_COL = 1; @@ -42,13 +42,13 @@ public class YieldManager { itemName = tokens[ITEM_COL]; refYield = Double.parseDouble(tokens[REF_YIELD_COL]); - Map<Item, Double> countryMap = cache.get(Country.get(countryName)); + Map<CropType, Double> countryMap = cache.get(Country.get(countryName)); if (countryMap == null) { - countryMap = new HashMap<Item, Double>(); + countryMap = new HashMap<CropType, Double>(); cache.put(Country.get(countryName), countryMap); } - countryMap.put(Item.getForFaoName(itemName), refYield); + countryMap.put(CropType.getForFaoName(itemName), refYield); } catch (Exception e) { LogWriter.printlnError("Failed in processing ssp line " + line); @@ -64,7 +64,7 @@ public class YieldManager { LogWriter.println("Processed " + filename + ", create " + cache.size() + " ref yield entries"); } - public Map<Item, Double> getRefYield(Country country, int year) { + public Map<CropType, Double> getRefYield(Country country, int year) { return cache.get(country); }