diff --git a/src/ac/ed/lurg/InternationalMarket.java b/src/ac/ed/lurg/InternationalMarket.java index c3fb641f4815adfc34b5c7589f0e92050fe3e71c..47a1f0c68cf76f7a745940b282e3951ef450992c 100644 --- a/src/ac/ed/lurg/InternationalMarket.java +++ b/src/ac/ed/lurg/InternationalMarket.java @@ -48,7 +48,7 @@ public class InternationalMarket { for (Entry<CropType, CropUsageData> entry : cropUsage.entrySet()) { CropType c = entry.getKey(); - double countryNetImports = entry.getValue().getNetImports(); + double countryNetImports = entry.getValue().getShockedNetImports() != null ? entry.getValue().getShockedNetImports() : entry.getValue().getNetImports(); if (countryNetImports > 0) totalImportCommodities.incrementValue(c, countryNetImports); diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java index 1f059d7d10a6b33ff78dfb908485f127b269264c..0e61741ef57370b0520e87e9d257c8f4ad9ce891 100755 --- a/src/ac/ed/lurg/ModelConfig.java +++ b/src/ac/ed/lurg/ModelConfig.java @@ -176,6 +176,7 @@ public class ModelConfig { public static final String SUBSIDY_RATE_FILE = getProperty("SUBSIDY_RATE_FILE", DATA_DIR + File.separator + SUBSIDY_RATE_FILENAME); public static final String ANIMAL_RATES_FILE = DATA_DIR + File.separator + "animal_numbers.csv";; public static final String INITIAL_CONSUMER_PRICE_FILE = DATA_DIR + File.separator + "consumerprices.csv";; + public static final String PRODUCTIONSHOCKS_PARAMETER_FILE = getProperty("PRODUCTIONSHOCKS_PARAMETER_FILE", OUTPUT_DIR + File.separator+ "productionShocks.csv"); // yield data public static final String YIELD_DIR_BASE = getProperty("YIELD_DIR_BASE"); diff --git a/src/ac/ed/lurg/country/CountryAgent.java b/src/ac/ed/lurg/country/CountryAgent.java index 1ef4d75d347aedcdaac16bb45c8848a633665c8b..1ab0bae7bd5af0801462f251fef50ea94e647042 100644 --- a/src/ac/ed/lurg/country/CountryAgent.java +++ b/src/ac/ed/lurg/country/CountryAgent.java @@ -102,7 +102,7 @@ public class CountryAgent extends AbstractCountryAgent { } public GamsRasterOutput determineProduction(Timestep timestep, YieldRaster countryYieldSurfaces, RasterSet<IrrigationItem> irrigData, - Map<CropType, GlobalPrice> worldPrices, double globalGen2EcIncrease) { + Map<CropType, GlobalPrice> worldPrices, double globalGen2EcIncrease, Map<CropType,Double> productionShocks) { currentTimestep = timestep; calculateCountryPrices(worldPrices, currentTimestep); @@ -137,6 +137,14 @@ public class CountryAgent extends AbstractCountryAgent { GamsRasterOutput result = opti.run(); + for (Entry<CropType, Double> entry : productionShocks.entrySet()) { + if(entry != null) { + CropType crop = entry.getKey(); + double shockValue = entry.getValue(); + result.getCropUsageData().get(crop).updateForShock(shockValue); + } + + } // No longer need this as even profit max calcs imports in GAMS now // if (!ModelConfig.ORIG_LEAST_COST_MIN) { // GamsCountryInput countryInput = input.getCountryInput(); diff --git a/src/ac/ed/lurg/country/CountryAgentManager.java b/src/ac/ed/lurg/country/CountryAgentManager.java index 3c59266712c3800427b72d0b7068906098dee646..faae8d2aae50c875f01f4d4561f96c4cb53c1bb2 100644 --- a/src/ac/ed/lurg/country/CountryAgentManager.java +++ b/src/ac/ed/lurg/country/CountryAgentManager.java @@ -15,6 +15,7 @@ import ac.ed.lurg.landuse.CropUsageData; import ac.ed.lurg.landuse.IrrigationItem; import ac.ed.lurg.landuse.IrrigationRasterSet; import ac.ed.lurg.landuse.LandUseItem; +import ac.ed.lurg.shock.ProductionShockManager; import ac.ed.lurg.types.CropType; import ac.ed.lurg.utils.LogWriter; import ac.ed.lurg.yield.YieldRaster; @@ -26,6 +27,7 @@ public class CountryAgentManager { private AbstractDemandManager demandManager; private TradeManager tradeBarrierManager; private SubsidyRateManager subsidyRateManager; + private ProductionShockManager productionShockManager; private InternationalMarket internationalMarket; private CountryBoundaryRaster countryBoundaryRaster; private RasterSet<IntegerRasterItem> clusterIdRaster; @@ -45,6 +47,7 @@ public class CountryAgentManager { this.internationalMarket = internationalMarket; this.globalLandUseRaster = globalLandUseRaster; tradeBarrierManager = new TradeManager(compositeCountryManager); + productionShockManager = new ProductionShockManager(); subsidyRateManager = new SubsidyRateManager(compositeCountryManager); craftyManager = new CraftyProdManager(); } @@ -108,10 +111,11 @@ public class CountryAgentManager { Collection<RasterKey> countryKeys = countryBoundaryRaster.getKeysFor(ca.getCountry()); YieldRaster countryYieldSurfaces = yieldSurfaces.createSubsetForKeys(countryKeys); RasterSet<IrrigationItem> irrigData = currentIrrigationData.createSubsetForKeys(countryKeys); + Map<CropType, Double> productionShocks=productionShockManager.getShocksForCountry(timestep, ca.getCountry()); // do the optimization try { - ca.determineProduction(timestep, countryYieldSurfaces, irrigData, internationalMarket.getWorldPrices(), gen2Increase); + ca.determineProduction(timestep, countryYieldSurfaces, irrigData, internationalMarket.getWorldPrices(), gen2Increase, productionShocks); // update global rasters globalLandUseRaster.putAll(ca.getLandUses()); diff --git a/src/ac/ed/lurg/landuse/CropUsageData.java b/src/ac/ed/lurg/landuse/CropUsageData.java index aaa9019951914c05c7fe3f5848a38db7648eb9c0..1299392bb2643ad1dcebc578a2f617c5cc54c1c7 100644 --- a/src/ac/ed/lurg/landuse/CropUsageData.java +++ b/src/ac/ed/lurg/landuse/CropUsageData.java @@ -9,6 +9,8 @@ public class CropUsageData { private double prod; private double prodCost; private double area; + private Double shockedNetImports; + private Double shockedProd; public CropUsageData(double prod) { this.prod = prod; @@ -44,6 +46,14 @@ public class CropUsageData { return prod; } + public Double getShockedNetImports() { + return shockedNetImports; + } + + public Double getShockedProduction() { + return shockedProd; + } + public double getProdCost() { return prodCost; } @@ -55,4 +65,14 @@ public class CropUsageData { public double getArea(){ return area; } + + public void updateForShock(double shockValue) { + + double productionLoss = prod*shockValue; + this.shockedProd = prod - productionLoss; + this.shockedNetImports = netImports + productionLoss; + + } + + } diff --git a/src/ac/ed/lurg/shock/ProductionShockManager.java b/src/ac/ed/lurg/shock/ProductionShockManager.java new file mode 100644 index 0000000000000000000000000000000000000000..717f3eed84b6ae8a7d27314050003ba9f331a06c --- /dev/null +++ b/src/ac/ed/lurg/shock/ProductionShockManager.java @@ -0,0 +1,53 @@ +package ac.ed.lurg.shock; + +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import ac.ed.lurg.ModelConfig; +import ac.ed.lurg.Timestep; +import ac.ed.lurg.country.CompositeCountry; +import ac.ed.lurg.types.CropType; +import ac.ed.lurg.utils.LogWriter; +import ac.ed.lurg.utils.StringTabularReader; + + +public class ProductionShockManager { + + private StringTabularReader productionShockReader; + + public ProductionShockManager() { + + String shockFile = ModelConfig.PRODUCTIONSHOCKS_PARAMETER_FILE; + productionShockReader = new StringTabularReader(",", new String[]{"year", "country", "crop", "shockFactor", "region"}); + + if (new File(shockFile).isFile()) + productionShockReader.read(shockFile); + else + LogWriter.println("Can't find a production shock file (" +shockFile + "), so will not shock production"); + } + + public Map<CropType, Double> getShocksForCountry(Timestep timestep, CompositeCountry cc) { + Map<CropType, Double> shocks = new HashMap<CropType, Double>(); + + Map<String, String> queryMap = new HashMap<String, String>(); + queryMap.put("year", Integer.toString(timestep.getYear())); + queryMap.put("country", cc.getName()); + + List<Map<String, String>> rows = productionShockReader.query(queryMap); + for (Map<String, String> row : rows) { + String cropTypeS = row.get("crop"); + String shockFactorS = row.get("shockFactor"); + CropType crop = CropType.getForFaoName(cropTypeS); + Double shockFactor = Double.valueOf(shockFactorS); + + LogWriter.println("Got production shock at " + timestep + ": " + cc.getName() + " " + cropTypeS + " " + shockFactorS); + + shocks.put(crop, shockFactor); + } + return shocks; + + } + +} diff --git a/src/ac/ed/lurg/yield/YieldResponse.java b/src/ac/ed/lurg/yield/YieldResponse.java index eb4dda28ba44a3c193c4dd7032516c86c1a19fbd..66c9272c1b86c5614feef1c7606b007bdd45cff7 100644 --- a/src/ac/ed/lurg/yield/YieldResponse.java +++ b/src/ac/ed/lurg/yield/YieldResponse.java @@ -64,7 +64,7 @@ public class YieldResponse { public void adjustYields(double adjustment) { for (Map.Entry<YieldType, Double> entry : yields.entrySet()) { - yields.put(entry.getKey(), entry.getValue() * adjustment); + yields.put(entry.getKey(), entry.getValue() * (1-adjustment)); } } } \ No newline at end of file