From a0a9eff53ccb922fd9e95b6d8b79f8a8c007b907 Mon Sep 17 00:00:00 2001
From: s1924442 <b.arendarczyk@sms.ed.ac.uk>
Date: Tue, 11 Jan 2022 17:23:18 +0000
Subject: [PATCH] Updated default gen2 bioenergy scenario and data files.

Tidied up BioenergyDemandManager code.
---
 src/ac/ed/lurg/ModelConfig.java               |   9 +-
 .../lurg/demand/BioenergyDemandManager.java   | 148 ++++++++++--------
 2 files changed, 85 insertions(+), 72 deletions(-)

diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java
index d0c23c3e..19f7e301 100755
--- a/src/ac/ed/lurg/ModelConfig.java
+++ b/src/ac/ed/lurg/ModelConfig.java
@@ -157,9 +157,10 @@ public class ModelConfig {
 	public static final String COUNTRY_DATA_FILE = DATA_DIR + File.separator + "country_data.csv";
 	public static final String NET_IMPORTS_FILE = DATA_DIR + File.separator + "net_imports.csv";
 	public static final String BIOENERGY_1GEN_BASE_DEMAND_FILE = DATA_DIR + File.separator + "bio_demand.csv";
-	public static final String BIOENERGY_2GEN_DEMAND_FILE = DATA_DIR + File.separator + "bioenergy_gen2_iiasa.csv";
-	public static final String BIOENERGY_FUTURE_DEMAND_FILENAME = getProperty("BIOENERGY_FUTURE_DEMAND_FILENAME", "bioenergy_futures_BAU.csv");
-	public static final String BIOENERGY_FUTURE_DEMAND_FILE = getProperty("BIOENERGY_FUTURE_DEMAND_FILE", DATA_DIR + File.separator + BIOENERGY_FUTURE_DEMAND_FILENAME);
+	public static final String BIOENERGY_2GEN_DEMAND_FILENAME = getProperty("BIOENERGY_2GEN_DEMAND_FILENAME", "bioenergy_gen2_iiasa.csv");
+	public static final String BIOENERGY_2GEN_DEMAND_FILE = getProperty("BIOENERGY_2GEN_DEMAND_FILE", DATA_DIR + File.separator + BIOENERGY_2GEN_DEMAND_FILENAME);
+	public static final String BIOENERGY_1GEN_FUTURE_DEMAND_FILENAME = getProperty("BIOENERGY_FUTURE_DEMAND_FILENAME", "bioenergy_gen1.csv");
+	public static final String BIOENERGY_1GEN_FUTURE_DEMAND_FILE = getProperty("BIOENERGY_FUTURE_DEMAND_FILE", DATA_DIR + File.separator + BIOENERGY_1GEN_FUTURE_DEMAND_FILENAME);
 	public static final String TRADE_BARRIERS_FILENAME = getProperty("TRADE_BARRIERS_FILENAME", "tradeBarriers.csv");
 	public static final String TRADE_BARRIERS_FILE = getProperty("TRADE_BARRIERS_FILE", DATA_DIR + File.separator + TRADE_BARRIERS_FILENAME);
 	public static final String TRADE_DISTORTIONS_FILE = DATA_DIR + File.separator + "tradeDistortions.csv";
@@ -327,7 +328,7 @@ public class ModelConfig {
 	public static final int BIOENERGY_CHANGE_END_YEAR = getIntProperty("BIOENERGY_CHANGE_END_YEAR", 2060);
 	// newer way
 	public static final boolean ENABLE_GEN2_BIOENERGY = getBooleanProperty("ENABLE_GEN2_BIOENERGY", true);
-	public static final String BIOENERGY_DEMAND_SCENARIO = getProperty("BIOENERGY_DEMAND_SCENARIO", "BAU");
+	public static final String BIOENERGY_DEMAND_SCENARIO = getProperty("BIOENERGY_DEMAND_SCENARIO", "SSP2_RCP45");
 	public static final String GEN2_BIOENERGY_MODEL = getProperty("GEN2_BIOENERGY_MODEL", "ENSEMBLE-MEAN");
 	public static final double BIOENERGY_DEMAND_SHIFT = IS_CALIBRATION_RUN ? 1.0 : getDoubleProperty("BIOENERGY_DEMAND_SHIFT", 1.0);
 	//	public static final double BIOENERGY_HEATING_VALUE_GJ_PER_T = getDoubleProperty("BIOENERGY_HEATING_VALUE_GJ_PER_T", 17.5); // GJ per t DM
diff --git a/src/ac/ed/lurg/demand/BioenergyDemandManager.java b/src/ac/ed/lurg/demand/BioenergyDemandManager.java
index e7798f42..c01e0cbf 100644
--- a/src/ac/ed/lurg/demand/BioenergyDemandManager.java
+++ b/src/ac/ed/lurg/demand/BioenergyDemandManager.java
@@ -4,7 +4,6 @@ import java.io.BufferedReader;
 import java.io.FileReader;
 import java.io.IOException;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
 import ac.ed.lurg.ModelConfig;
@@ -14,19 +13,21 @@ import ac.ed.lurg.types.CommodityType;
 import ac.ed.lurg.utils.Interpolator;
 import ac.ed.lurg.utils.LazyHashMap;
 import ac.ed.lurg.utils.LogWriter;
-import ac.ed.lurg.utils.StringTabularReader;
 
 public class BioenergyDemandManager {
-	private static final int COUNTRY_COL = 0; 
-	private static final int COMMODITY_COL = 2; 
-	private static final int OTHER_COL = 3; 
+	private static final int GEN1_BASE_COUNTRY_COL = 0; 
+	private static final int GEN1_BASE_COMMODITY_COL = 2; 
+	private static final int GEN1_BASE_OTHER_COL = 3; 
+	private static final int GEN1_FUTURE_SCENARIO_COL = 0; 
+	private static final int GEN1_FUTURE_YEAR_COL = 3; 
+	private static final int GEN1_FUTURE_DEMAND_COL = 4;
 	private static final int GEN2_MODEL_COL = 0;
 	private static final int GEN2_SCENARIO_COL = 1;
 	private static final int GEN2_COUNTRY_COL = 3;
 	private static final int GEN2_YEAR_COL = 4;
 	private static final int GEN2_DEMAND_COL = 6;
 	
-	private Map<SingleCountry, Map<CommodityType, Double>> bioenergyBaseData;
+	private Map<SingleCountry, Map<CommodityType, Double>> firstGenBaseData;
 	private Map<Integer, Double> firstGenGlobalMass; // a factor
 	private Map<SingleCountry, Map<Integer, Double>> secondGenMass; // in Mt DM
 	
@@ -34,42 +35,6 @@ public class BioenergyDemandManager {
 		readBioenergyBaseData();
 		readBioenergyFutureData();
 	}
-	
-	public double getFirstGenBioenergyDemand(SingleCountry country, int year, CommodityType commodity) {
-		
-		if (bioenergyBaseData != null && bioenergyBaseData.containsKey(country)) {
-			Double d = bioenergyBaseData.get(country).get(commodity);
-			double bioenergyDemandAdj = 0;
-			
-			if (ModelConfig.USE_BIOENERGY_TRAJECTORY) {
-				bioenergyDemandAdj = interpolateDemand(firstGenGlobalMass, year, 5) / firstGenGlobalMass.get(ModelConfig.BASE_YEAR);
-			}
-			else {
-				int yearsOfChange = Math.min(ModelConfig.BIOENERGY_CHANGE_END_YEAR - ModelConfig.BIOENERGY_CHANGE_START_YEAR, year - ModelConfig.BIOENERGY_CHANGE_START_YEAR);
-				bioenergyDemandAdj = yearsOfChange > 0 ?  (1.0 +  yearsOfChange * ModelConfig.BIOENERGY_CHANGE_ANNUAL_RATE) : 1.0 ;
-			}
-			return d == null ? 0 : d.doubleValue() * bioenergyDemandAdj * ModelConfig.BIOENERGY_DEMAND_SHIFT;
-		}
-		return 0.0;
-	}
-	
-	public double getSecondGenBioenergyDemand(SingleCountry country, int year) {	
-		
-		if (ModelConfig.ENABLE_GEN2_BIOENERGY && secondGenMass.containsKey(country))
-			return interpolateDemand(secondGenMass.get(country), year, 10) * ModelConfig.BIOENERGY_DEMAND_SHIFT;
-		else
-			return 0.0;
-	}
-	
-	private double interpolateDemand(Map<Integer, Double> beValues, int year, int interval) {
-		int downYear = (year/interval) * interval;
-		int upYear = downYear + interval;
-		Double lowerD = beValues.get(downYear);
-		Double upperD = beValues.get(upYear);
-		double factor = ((double)(year - downYear)) / (upYear - downYear);
-		Double d = Interpolator.interpolate(lowerD, upperD, factor);
-		return d;
-	}
 
 	@SuppressWarnings("serial")
 	private void readBioenergyBaseData() {
@@ -91,9 +56,9 @@ public class BioenergyDemandManager {
 				if (tokens.length < 4)
 					LogWriter.printlnError("Too few columns in " + filename + ", " + line);
 				
-				countryName = tokens[COUNTRY_COL];
-				commodityName = tokens[COMMODITY_COL];
-				other = Double.valueOf(tokens[OTHER_COL]);
+				countryName = tokens[GEN1_BASE_COUNTRY_COL];
+				commodityName = tokens[GEN1_BASE_COMMODITY_COL];
+				other = Double.valueOf(tokens[GEN1_BASE_OTHER_COL]);
 
 				SingleCountry country = CountryManager.getForName(countryName);
 				CommodityType crop = CommodityType.getForFaoName(commodityName);
@@ -104,49 +69,60 @@ public class BioenergyDemandManager {
 			fitReader.close(); 
 		
 		} catch (IOException e) {
-			LogWriter.printlnError("Failed in reading commodity demand fits");
+			LogWriter.printlnError("Failed in gen 1 bioenergy base data");
 			LogWriter.print(e);
 		}
 		LogWriter.println("Processed " + filename + ", create " + bioenergyMap.size() + " country commodity maps values");
 		
-		bioenergyBaseData = bioenergyMap;
+		firstGenBaseData = bioenergyMap;
 	}
 
+
 	public void readBioenergyFutureData() {
-		StringTabularReader beReader = new StringTabularReader(",", new String[]{"SCENARIO", "REGION", "Variable", "Year", "value"});
-		beReader.read(ModelConfig.BIOENERGY_FUTURE_DEMAND_FILE);
-		if (ModelConfig.USE_BIOENERGY_TRAJECTORY) firstGenGlobalMass = getGlobalBE(beReader, "Agricultural Demand|Bioenergy|1st generation");
+		if (ModelConfig.USE_BIOENERGY_TRAJECTORY) readFirstGenBioenergyFutureData();
 		
 		readSecondGenBioenergyData();
 	}
 
-	private Map<Integer, Double> getGlobalBE(StringTabularReader beReader, String variableString) {
-		Map<Integer, Double> beGlobalValues = new HashMap<Integer, Double>();
+	public void readFirstGenBioenergyFutureData() {		
+		Map<Integer, Double> bioenergyMap = new HashMap<Integer, Double>();
 		
-		Map<String, String> queryMap = new HashMap<String, String>();
-		queryMap.put("SCENARIO", ModelConfig.BIOENERGY_DEMAND_SCENARIO);
-		queryMap.put("REGION", "World");
-		queryMap.put("Variable", variableString);
-		List<Map<String, String>> rows = beReader.query(queryMap);
+		String filename = ModelConfig.BIOENERGY_1GEN_FUTURE_DEMAND_FILE;
+		try {
+			BufferedReader fitReader = new BufferedReader(new FileReader(filename)); 
+			String line, scenario;
+			Integer year;
+			Double demand;
+			fitReader.readLine(); // read header
 
-		for (Map<String, String> row : rows) {
-			String valueS = row.get("value");
-			String yearS = row.get("Year");
-			Double d = Double.valueOf(valueS);
-			Integer y = Integer.valueOf(yearS);
-			beGlobalValues.put(y, d);
-		}
+			while ((line=fitReader.readLine()) != null) {
+				String[] tokens = line.split(",");
+				
+				if (tokens.length < 5)
+					LogWriter.printlnError("Too few columns in " + filename + ", " + line);
+
+				scenario = tokens[GEN1_FUTURE_SCENARIO_COL];
+				year = Integer.valueOf(tokens[GEN1_FUTURE_YEAR_COL]);
+				demand = Double.valueOf(tokens[GEN1_FUTURE_DEMAND_COL]);
+				
+				if (scenario.equals(ModelConfig.BIOENERGY_DEMAND_SCENARIO)) {
+					bioenergyMap.put(year, demand);
+				}
+			} 
+			fitReader.close();
 		
-		if (beGlobalValues.size()==0) {
-			throw new RuntimeException("BioenergyDemandManager: not found values for " + variableString);
+		} catch (IOException e) {
+			LogWriter.printlnError("Failed in reading gen1 future bioenergy data");
+			LogWriter.print(e);
 		}
+		LogWriter.println("Processed " + filename + ", create " + bioenergyMap.size() + " country year maps values");
 		
-		return beGlobalValues;
+		firstGenGlobalMass = bioenergyMap;	
 	}
 	
+	@SuppressWarnings("serial")
 	public void readSecondGenBioenergyData() {		
 		LazyHashMap<SingleCountry, Map<Integer, Double>> bioenergyMap = new LazyHashMap<SingleCountry, Map<Integer, Double>>() {
-			private static final long serialVersionUID = 1L;
 			protected Map<Integer, Double> createValue() { return new HashMap<Integer, Double>(); }
 		};
 		
@@ -186,4 +162,40 @@ public class BioenergyDemandManager {
 		
 		secondGenMass = bioenergyMap;	
 	}
+	public double getFirstGenBioenergyDemand(SingleCountry country, int year, CommodityType commodity) {
+		
+		if (firstGenBaseData != null && firstGenBaseData.containsKey(country)) {
+			Double d = firstGenBaseData.get(country).get(commodity);
+			double bioenergyDemandAdj = 0;
+			
+			if (ModelConfig.USE_BIOENERGY_TRAJECTORY) {
+				bioenergyDemandAdj = interpolateDemand(firstGenGlobalMass, year, 5) / firstGenGlobalMass.get(ModelConfig.BASE_YEAR);
+			}
+			else {
+				int yearsOfChange = Math.min(ModelConfig.BIOENERGY_CHANGE_END_YEAR - ModelConfig.BIOENERGY_CHANGE_START_YEAR, year - ModelConfig.BIOENERGY_CHANGE_START_YEAR);
+				bioenergyDemandAdj = yearsOfChange > 0 ?  (1.0 +  yearsOfChange * ModelConfig.BIOENERGY_CHANGE_ANNUAL_RATE) : 1.0 ;
+			}
+			return d == null ? 0 : d.doubleValue() * bioenergyDemandAdj * ModelConfig.BIOENERGY_DEMAND_SHIFT;
+		}
+		return 0.0;
+	}
+	
+	public double getSecondGenBioenergyDemand(SingleCountry country, int year) {	
+		
+		if (ModelConfig.ENABLE_GEN2_BIOENERGY && secondGenMass.containsKey(country))
+			return interpolateDemand(secondGenMass.get(country), year, 10) * ModelConfig.BIOENERGY_DEMAND_SHIFT;
+		else
+			return 0.0;
+	}
+	
+	private double interpolateDemand(Map<Integer, Double> beValues, int year, int interval) {
+		int downYear = (year/interval) * interval;
+		int upYear = downYear + interval;
+		Double lowerD = beValues.get(downYear);
+		Double upperD = beValues.get(upYear);
+		double factor = ((double)(year - downYear)) / (upYear - downYear);
+		Double d = Interpolator.interpolate(lowerD, upperD, factor);
+		return d;
+	}
+	
 }
\ No newline at end of file
-- 
GitLab