diff --git a/debug_config.properties b/debug_config.properties index 6f97253c832cd0d8951ab8fb1e968b6b2fcf3d2f..a59915593399115739bbf169389cc39e26bfb4eb 100644 --- a/debug_config.properties +++ b/debug_config.properties @@ -1,6 +1,6 @@ BASE_DIR=.. -YIELD_DIR=/Users/palexand/Documents/LURG/LPJ/CMIP_emulated_test_forPLUM_20200821180759/GFDL-ESM4_ssp126_v20200821_rmol/sim_LPJ-GUESS +YIELD_DIR=/Users/palexand/Documents/LURG/LPJ/LPJGPLUM_remap6p7_20190225/rcp26 END_TIMESTEP=0 @@ -8,22 +8,17 @@ END_FIRST_STAGE_CALIBRATION=10 TIMESTEP_SIZE=1 IS_CALIBRATION_RUN=true +DEBUG_JUST_DEMAND_OUTPUT=true GENERATE_NEW_YIELD_CLUSTERS=false DEMAND_PRICE_IMPORT_AND_PROD_COST=true -YIELD_FILENAME=yield_intpinfs_rmol.out -IRRIG_MAX_WATER_FILENAME=gsirrigation_intpinfs_rmol.out - -MIN_FERT_AMOUNT=10 -MID_FERT_AMOUNT=60 -MAX_FERT_AMOUNT=200 -FERT_AMOUNT_PADDING=3 +EXTRAPOLATE_YIELD_FERT_RESPONSE=false -LPJG_TIMESTEP_SIZE=10 +DEBUG_LIMIT_COUNTRIES=false +DEBUG_COUNTRY_NAME=Italy -EXTRAPOLATE_YIELD_FERT_RESPONSE=false +ADJUST_DIET_PREFS=true -DEBUG_LIMIT_COUNTRIES=true -DEBUG_COUNTRY_NAME=Italy \ No newline at end of file +TARGET_DIET_FILE=/Users/palexand/Downloads/Tau_diet.csv \ No newline at end of file diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java index 4fef2280345dfae929a76cfdbb2cc5f8d9bc0485..e289c2a0ee0b43aa2ee306913809f7d593d4c0b6 100755 --- a/src/ac/ed/lurg/ModelConfig.java +++ b/src/ac/ed/lurg/ModelConfig.java @@ -187,7 +187,7 @@ public class ModelConfig { public static final String YIELD_DIR = getProperty("YIELD_DIR", YIELD_DIR_BASE + File.separator + YIELD_DIR_TOP); public static final int LPJG_MONITOR_TIMEOUT_SEC = getIntProperty("LPJG_MONITOR_TIMEOUT", 60*60*2); public static final String ANPP_FILENAME = getProperty("ANPP_FILENAME", "anpp.out"); - public static final String YIELD_FILENAME = getProperty("YIELD_FILENAME", "yieldPH.out"); + public static final String YIELD_FILENAME = getProperty("YIELD_FILENAME", "yield.out"); public static final boolean PASTURE_FERT_RESPONSE_FROM_LPJ = getBooleanProperty("PASTURE_FERT_RESPONSE_FROM_LPJ", false);; public static final double CALIB_FACTOR_CEREAL_C3 = getDoubleProperty("CALIB_FACTOR_CEREAL_C3", 1.046); @@ -410,4 +410,9 @@ public class ModelConfig { public static final String CRAFTY_PRODUCTION_DIR = getProperty("CRAFTY_PRODUCTION_DIR", OUTPUT_DIR + File.separator + "crafty"); public static final boolean EXTRAPOLATE_YIELD_FERT_RESPONSE = getBooleanProperty("EXTRAPOLATE_YIELD_FERT_RESPONSE", false); + + public static final boolean ADJUST_DIET_PREFS = getBooleanProperty("ADJUST_DIET_PREFS", false); + public static final int DIET_CHANGE_START_YEAR = getIntProperty("DIET_CHANGE_START_YEAR", 2020); + public static final int DIET_CHANGE_END_YEAR = getIntProperty("DIET_CHANGE_END_YEAR", 2040); + public static final String TARGET_DIET_FILE = getProperty("TARGET_DIET_FILE", DATA_DIR + File.separator + "TargetDiet.txt"); } diff --git a/src/ac/ed/lurg/country/CountryAgent.java b/src/ac/ed/lurg/country/CountryAgent.java index 7eaca36eacdd2fcca2a59723815c727ce85fe849..c3accb6cdf740b2608333b80ca5b5b18deff2fd8 100644 --- a/src/ac/ed/lurg/country/CountryAgent.java +++ b/src/ac/ed/lurg/country/CountryAgent.java @@ -5,7 +5,6 @@ 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; import java.util.List; diff --git a/src/ac/ed/lurg/country/gams/GamsDemandOptimiser.java b/src/ac/ed/lurg/country/gams/GamsDemandOptimiser.java index 516c0fe30441c440e7cdba5de6eaba466852bc61..bb42fd0030d9517f47a1aabd2e3482085b5e5a80 100755 --- a/src/ac/ed/lurg/country/gams/GamsDemandOptimiser.java +++ b/src/ac/ed/lurg/country/gams/GamsDemandOptimiser.java @@ -37,23 +37,50 @@ public class GamsDemandOptimiser { wsInfo.setWorkingDirectory(workingDirectory.getAbsolutePath()); GAMSWorkspace ws = new GAMSWorkspace(wsInfo); - GAMSDatabase inDB = ws.addDatabase(); - setupInDB(inDB); - - GAMSJob gamsJob = ws.addJobFromFile(ModelConfig.DEMAND_GAMS_MODEL); GAMSOptions opt = ws.addOptions(); - - opt.defines("gdx_parameters", new File(ModelConfig.DEMAND_PARAM_FILE).getAbsolutePath()); + GAMSJob gamsJob = ws.addJobFromFile(ModelConfig.DEMAND_GAMS_MODEL); + + GAMSDatabase inDB = ws.addDatabase(); + setupPriceGdpDB(inDB); + ArrayList<GAMSDatabase> dbs = new ArrayList<GAMSDatabase>(); + dbs.add(inDB); opt.defines("gdx_prices_and_gdp", inDB.getName()); + if (ModelConfig.ADJUST_DIET_PREFS) { + LogWriter.println("Adusting diet params"); + GAMSDatabase originalParamDb = ws.addDatabaseFromGDX(new File(ModelConfig.DEMAND_PARAM_FILE).getAbsolutePath()); + GAMSDatabase adjustedParamDb = ws.addDatabase(originalParamDb); + adjustDietParams(adjustedParamDb); + dbs.add(adjustedParamDb); + opt.defines("gdx_parameters", adjustedParamDb.getName()); + } + else + opt.defines("gdx_parameters", new File(ModelConfig.DEMAND_PARAM_FILE).getAbsolutePath()); + long startTime = System.currentTimeMillis(); - gamsJob.run(opt, inDB); + gamsJob.run(opt, dbs.toArray(new GAMSDatabase[dbs.size()])); LogWriter.println("Took " + (System.currentTimeMillis() - startTime) + " ms to run"); return handleResults(gamsJob.OutDB()); } - private void setupInDB(GAMSDatabase inDB) { + private void adjustDietParams(GAMSDatabase adjustedParamDb) { + // get original parameters + GAMSParameter tauParam = adjustedParamDb.getParameter("tau"); + TauCalculationManager tauManager = TauCalculationManager.getInstance(); + + for (GAMSParameterRecord rec : tauParam) { + String key = rec.getKeys()[0]; + double initialTau = rec.getValue(); + + CommodityType commodity = CommodityType.getForGamsName(key); + double adjusted = tauManager.getFinalTau(inputData.getYear(), initialTau, commodity); + LogWriter.println(String.format("%14s: initialTau=%.6f, adjusted=%.6f", key, initialTau, adjusted)); + rec.setValue(adjusted); + } + } + + private void setupPriceGdpDB(GAMSDatabase inDB) { GAMSParameter gdpPcP = inDB.addParameter("gdp_pc", 0); double gdpPc = inputData.getGdpPc(); LogWriter.println(String.format("gdp_pc = %.5f", gdpPc)); diff --git a/src/ac/ed/lurg/country/gams/TauCalculationManager.java b/src/ac/ed/lurg/country/gams/TauCalculationManager.java new file mode 100644 index 0000000000000000000000000000000000000000..05879e5bdadc6560603720baea294909f209c3f3 --- /dev/null +++ b/src/ac/ed/lurg/country/gams/TauCalculationManager.java @@ -0,0 +1,81 @@ +package ac.ed.lurg.country.gams; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import ac.ed.lurg.ModelConfig; +import ac.ed.lurg.types.CommodityType; +import ac.ed.lurg.utils.LogWriter; + +public class TauCalculationManager { + // to change Tau parameters of the elastic demand diet curves which changes the diet at high income country (saturation level) + // Tau is changed for each commodity (unique for all countries) + // Change from START_YEAR from the "normal" coefficients from Gouel & Guimbard 2019 based on historical data (higher income country trend to have a rich in sugar, fat and animal protein diet + // To a diet specified and created in the plumv2>Data>Tau_diet.csv file (in this case an Healthy diet from EAT LANCET article) + + private Map<CommodityType, Double> shiftTauMap = new HashMap<CommodityType, Double>(); + + private static final int ITEM_COL = 0; + private static final int SHIFT_TAU_COL = 1; + + + private static TauCalculationManager tcm; + public static TauCalculationManager getInstance() { + if (tcm == null) + tcm = new TauCalculationManager(); + + return tcm; + } + + private TauCalculationManager() { + readTauFromFile(); + } + + public double getFinalTau(int year, double initialTau, CommodityType commodity) { + double shiftTau = shiftTauMap.get(commodity); + double tau; + + if(year > ModelConfig.DIET_CHANGE_START_YEAR && year < ModelConfig.DIET_CHANGE_END_YEAR) + tau = initialTau + ((year - ModelConfig.DIET_CHANGE_START_YEAR) * (shiftTau - initialTau) / (ModelConfig.DIET_CHANGE_END_YEAR- ModelConfig.DIET_CHANGE_START_YEAR)); // interpolation + else if (year >= ModelConfig.DIET_CHANGE_END_YEAR) + tau = shiftTau; + else + tau = initialTau; + + return tau; + } + + //Read File for Tau and tau diet change + private void readTauFromFile() { + String filename = ModelConfig.TARGET_DIET_FILE; + try { + BufferedReader fitReader = new BufferedReader(new FileReader(filename)); + String line, gamsName; + Double shiftTau; + fitReader.readLine(); // read header + + while ((line=fitReader.readLine()) != null) { + String[] tokens = line.split(","); + + if (tokens.length < 2) + LogWriter.printlnError("Too few columns in " + filename + ", " + line); + + gamsName = tokens[ITEM_COL]; + shiftTau = Double.parseDouble(tokens[SHIFT_TAU_COL]); + + CommodityType commodity = CommodityType.getForGamsName(gamsName); + + shiftTauMap.put(commodity,shiftTau); + } + fitReader.close(); + + } catch (IOException e) { + LogWriter.printlnError("Failed in reading Tau file"); + LogWriter.print(e); + } + LogWriter.println("Processed " + filename); + } +} \ No newline at end of file diff --git a/src/ac/ed/lurg/types/CommodityType.java b/src/ac/ed/lurg/types/CommodityType.java index 4a0dc9e9ec26d4bd6aa38d09caf82eeee6613d35..5c3b8e5e282866cd2c1bd8561498dc9f74ce824d 100644 --- a/src/ac/ed/lurg/types/CommodityType.java +++ b/src/ac/ed/lurg/types/CommodityType.java @@ -62,6 +62,10 @@ public enum CommodityType { return commodity; } + public static CommodityType getForGamsName(String gamsName) { + return getForGamsName(gamsName, false); + } + public static CommodityType getForGamsName(String gamsName, boolean allowNulls) { CommodityType commodity = gamsNameCache.get(gamsName); diff --git a/src/ac/ed/lurg/yield/YieldClusterPoint.java b/src/ac/ed/lurg/yield/YieldClusterPoint.java index 7b3882eb2f70f7e23173bd9d18872f6ab639eeff..75943f0479f3bd33d36da3413b562fb459addc10 100644 --- a/src/ac/ed/lurg/yield/YieldClusterPoint.java +++ b/src/ac/ed/lurg/yield/YieldClusterPoint.java @@ -6,7 +6,6 @@ import java.util.Collection; import ac.ed.lurg.landuse.IrrigationItem; import ac.ed.lurg.types.CropType; import ac.ed.lurg.types.YieldType; -import ac.ed.lurg.utils.LogWriter; import ac.ed.lurg.utils.cluster.ClusteringPoint; import ac.sac.raster.RasterKey;