From df542b0cdc3030c63e50034f41a70d8dfbfaec17 Mon Sep 17 00:00:00 2001
From: Peter Alexander <peter@blackhillock.co.uk>
Date: Tue, 15 Sep 2015 13:42:08 +0100
Subject: [PATCH] Change logging and fix units in irrigation

---
 GAMS/IntExtOpt.gms                            |  2 +-
 src/ac/ed/lurg/ModelConfig.java               |  4 +-
 src/ac/ed/lurg/ModelMain.java                 | 23 +++++----
 src/ac/ed/lurg/country/CountryManager.java    |  2 +-
 .../country/gams/GamsLocationOptimiser.java   |  6 +--
 .../country/gams/GamsRasterOptimiser.java     | 47 ++++++++++++-------
 src/ac/ed/lurg/demand/BaseConsumpManager.java |  2 +-
 src/ac/ed/lurg/demand/BioenergyDemand.java    |  2 +-
 src/ac/ed/lurg/demand/DemandCurveManager.java |  2 +-
 src/ac/ed/lurg/demand/SspManager.java         |  4 +-
 src/ac/ed/lurg/landuse/CropUsageReader.java   |  2 +-
 .../landuse/IrrigationConstraintReader.java   |  5 +-
 src/ac/ed/lurg/landuse/IrrigationItem.java    |  4 +-
 .../landuse/IrrigationMaxAmountReader.java    | 12 ++---
 src/ac/ed/lurg/output/LpjgOutputer.java       | 12 ++---
 src/ac/ed/lurg/utils/LogWriter.java           | 44 ++++++++---------
 src/ac/ed/lurg/utils/WatchDir.java            |  2 +-
 src/ac/ed/lurg/utils/WatchForFile.java        |  2 +-
 .../ed/lurg/yield/AveragingYieldResponse.java | 27 -----------
 .../yield/AveragingYieldResponsesItem.java    | 16 -------
 .../lurg/yield/LPJYieldResponseMapReader.java | 11 ++---
 src/ac/sac/raster/AbstractRasterReader.java   |  2 +-
 .../raster/AbstractTabularRasterReader.java   |  4 +-
 src/ac/sac/raster/RasterOutputer.java         |  4 +-
 24 files changed, 103 insertions(+), 138 deletions(-)
 delete mode 100644 src/ac/ed/lurg/yield/AveragingYieldResponse.java
 delete mode 100644 src/ac/ed/lurg/yield/AveragingYieldResponsesItem.java

diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms
index de122d72..9ae48a42 100644
--- a/GAMS/IntExtOpt.gms
+++ b/GAMS/IntExtOpt.gms
@@ -155,7 +155,7 @@ $gdxin
  
  MIN_FEED_CONSTRAINT .. sum(feed_crop_less_pasture, feedDM(feed_crop_less_pasture) * feedAmount(feed_crop_less_pasture)) =G= minFeedRate * (demand('meat') - netImportAmount('meat'));
  
- IRRIGATION_CONSTRAINT(location) .. irrigConstraint(location) =G= sum(crop, irrigMaxRate(crop, location) * irrigI(crop, location) * area(crop, location));
+ IRRIGATION_CONSTRAINT(location) .. irrigConstraint(location) =G= sum(crop, irrigMaxRate(crop, location) * irrigI(crop, location) * area(crop, location)) / suitableLandArea(location);
  
  AGRI_LAND_EXPANSION_CALC(location) .. agriLandExpansion(location) =G= sum(crop, area(crop, location) - previousArea(crop, location)); 
  
diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java
index 1e4673a8..842f780b 100644
--- a/src/ac/ed/lurg/ModelConfig.java
+++ b/src/ac/ed/lurg/ModelConfig.java
@@ -113,11 +113,13 @@ public class ModelConfig {
 	public static final String COUNTRY_BOUNDARY_FILE = SPATIAL_DATA_DIR + File.separator + "country_boundaries.asc";
 	public static final String IRRIGATION_COST_FILE = SPATIAL_DATA_DIR + File.separator + "irrigation_cost.asc";
 	public static final String IRRIGATION_CONSTRAINT_FILE = SPATIAL_DATA_DIR + File.separator + "blue_water_available_pseudoCRU_rcp8p5_2004_2013_grid_allhdyro_mm_3deg.txt";
-	public static final String IRRIG_MAX_WATER_FILE = YIELD_DIR + File.separator + "max_irrig_water.out";
+	public static final String IRRIG_MAX_WATER_FILENAME = getProperty("IRRIG_MAX_WATER_FILENAME", "max_irrig_water.out");
+	public static final String IRRIG_MAX_WATER_FILE = YIELD_DIR + File.separator + IRRIG_MAX_WATER_FILENAME;
 
 	// Output
 	public static final String TOTAL_LAND_COVER_FILE = OUTPUT_DIR + File.separator + "total_lc.txt";
 	public static final boolean OUTPUT_FOR_LPJG = getBooleanProperty("OUTPUT_FOR_LPJG", true);
+	public static final boolean INTERPOLATE_OUTPUT_YEARS = getBooleanProperty("INTERPOLATE_OUTPUT_YEARS", true);
 	
 	// Temporal configuration
 	public static final int START_TIMESTEP = getIntProperty("START_TIMESTEP", 0);
diff --git a/src/ac/ed/lurg/ModelMain.java b/src/ac/ed/lurg/ModelMain.java
index b683a6dd..a2cf9493 100644
--- a/src/ac/ed/lurg/ModelMain.java
+++ b/src/ac/ed/lurg/ModelMain.java
@@ -121,8 +121,9 @@ public class ModelMain {
 
 			}
 			catch (Exception e) {
-				LogWriter.printlnError("Exception processing " + ca.getCountry() + " will continue with other countries");			
-				e.printStackTrace();
+				LogWriter.printlnError("Exception processing " + ca.getCountry() + " will continue with other countries");	
+				LogWriter.print(e);
+				System.exit(1);
 			}
 
 			if (result == null) {
@@ -236,7 +237,7 @@ public class ModelMain {
 			outputFile.close();
 		}
 		catch (IOException e) {
-			e.printStackTrace();
+			LogWriter.print(e);
 		}
 	}
 
@@ -247,12 +248,12 @@ public class ModelMain {
 		if (ModelConfig.OUTPUT_FOR_LPJG) {
 			for (int outputYear : timestep.getYearsFromLast()) {
 				LogWriter.printlnError("Outputing Year: " + outputYear);
-				RasterSet<LandUseItem> landUseToOutput;
+				RasterSet<LandUseItem> landUseToOutput = null;
 
 				if (outputYear == timestep.getYear()) {
 					landUseToOutput = landUseRaster;
 				}
-				else {
+				else if (ModelConfig.INTERPOLATE_OUTPUT_YEARS) {
 					InterpolatingRasterSet<LandUseItem> intermediateLandUse = new InterpolatingRasterSet<LandUseItem>(landUseRaster.getHeaderDetails()) {
 						private static final long serialVersionUID = 1306045141011047760L;
 						protected LandUseItem createRasterData() {
@@ -263,8 +264,10 @@ public class ModelMain {
 					landUseToOutput = intermediateLandUse;
 				}
 
-				LpjgOutputer lpjOutputer = new LpjgOutputer(outputYear, landUseToOutput, yieldSurfaces);
-				lpjOutputer.writeOutput();
+				if (landUseToOutput != null) {
+					LpjgOutputer lpjOutputer = new LpjgOutputer(outputYear, landUseToOutput, yieldSurfaces);
+					lpjOutputer.writeOutput();
+				}
 			}
 		}
 
@@ -297,7 +300,7 @@ public class ModelMain {
 		Collection<CountryAgent> countryAgents = new HashSet<CountryAgent>();
 
 		RasterSet<LandCoverItem> initLC = getInitialLandCover();
-		RasterSet<IrrigationItem> allIrrigationCosts = getIrrigationData();
+		RasterSet<IrrigationItem> allIrrigationData = getIrrigationData();
 		Map<CompositeCountry, Map<CropType, CropUsageData>> cropUsageDataMap = new CropUsageReader(compositeCountryManager).getCommodityData();
 
 		for (CompositeCountry cc : countryGrouping) {
@@ -311,7 +314,7 @@ public class ModelMain {
 
 			List<RasterKey> keys = countryBoundaryRaster.getKeysFor(cc);
 			RasterSet<LandCoverItem> initCountryLC = initLC.createSubsetForKeys(keys);
-			RasterSet<IrrigationItem> irrigationCosts = allIrrigationCosts.createSubsetForKeys(keys);
+			RasterSet<IrrigationItem> irrigationData = allIrrigationData.createSubsetForKeys(keys);
 			Map<CropType, CropUsageData> countryCommodityData = cropUsageDataMap.get(cc);
 
 			if (countryCommodityData == null) {
@@ -321,7 +324,7 @@ public class ModelMain {
 				LogWriter.printlnError("No initial land cover for " +cc + ", so skipping");
 			}
 			else {
-				CountryAgent ca = new CountryAgent(demandManager, cc, initCountryLC, irrigationCosts, countryCommodityData);
+				CountryAgent ca = new CountryAgent(demandManager, cc, initCountryLC, irrigationData, countryCommodityData);
 				countryAgents.add(ca);
 				LogWriter.println("Creating country agent for: " + cc );
 			}
diff --git a/src/ac/ed/lurg/country/CountryManager.java b/src/ac/ed/lurg/country/CountryManager.java
index 00ba38a0..7ac32b52 100644
--- a/src/ac/ed/lurg/country/CountryManager.java
+++ b/src/ac/ed/lurg/country/CountryManager.java
@@ -54,7 +54,7 @@ public class CountryManager {
 		
 		} catch (Exception e) {
 			LogWriter.printlnError("Failed in reading commodity demand fits");
-			e.printStackTrace();
+			LogWriter.print(e);
 		}
 		LogWriter.println("Processed " + filename + ", create " + nameMap.size() + " country codes");
 
diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
index 3f28357f..8c95adb7 100644
--- a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
+++ b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
@@ -146,7 +146,7 @@ public class GamsLocationOptimiser {
 			for (CropType crop : CropType.getNonMeatTypes()) {
 				double maxIrrig = irrigationItem.getMaxIrrigAmount(crop);
 				
-				if (DEBUG) LogWriter.println(String.format("%d     %15s,\t %.1f,\t %.1f, \t %.1f,\t %.1f,\t\t [%.2f],\t [%.2f],\t {%.1f}", 
+				if (DEBUG) LogWriter.println(String.format("%d     %15s,\t %.1f,\t %.1f, \t %.1f,\t %.1f,\t\t [%.2f],\t [%.2f],\t {%.2f}", 
 						locationId, crop.getGamsName(), yresp.getYieldNone(crop), yresp.getYieldFertOnly(crop), yresp.getYieldIrrigOnly(crop), yresp.getYieldMax(crop), 
 						yresp.getFertParam(crop), yresp.getIrrigParam(crop), maxIrrig));
 
@@ -334,13 +334,13 @@ public class GamsLocationOptimiser {
 			try {
 				fileToDelete.delete();
 			} catch(Exception e){
-				e.printStackTrace();
+				LogWriter.print(e);
 			}
 		}
 		try {
 			directoryToDelete.delete();
 		} catch(Exception e) {
-			e.printStackTrace();
+			LogWriter.print(e);
 		}
 	}
 }
\ No newline at end of file
diff --git a/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java b/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java
index 05d9d376..105e2978 100644
--- a/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java
+++ b/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java
@@ -10,14 +10,13 @@ import java.util.Map.Entry;
 import java.util.Set;
 
 import ac.ed.lurg.ModelConfig;
-import ac.ed.lurg.landuse.LandUseItem;
 import ac.ed.lurg.landuse.IrrigationItem;
+import ac.ed.lurg.landuse.LandUseItem;
 import ac.ed.lurg.types.CropType;
 import ac.ed.lurg.types.LandCoverType;
 import ac.ed.lurg.types.YieldType;
 import ac.ed.lurg.utils.LazyTreeMap;
 import ac.ed.lurg.utils.LogWriter;
-import ac.ed.lurg.yield.AveragingYieldResponsesItem;
 import ac.ed.lurg.yield.YieldRaster;
 import ac.ed.lurg.yield.YieldResponsesItem;
 import ac.sac.raster.IntegerRasterItem;
@@ -269,7 +268,7 @@ public class GamsRasterOptimiser {
 		}.writeOutput(true); */
 
 
-		RasterSet<IrrigationItem> irrigCostRaster = rasterInputData.getIrrigationCost();
+		RasterSet<IrrigationItem> irrigRaster = rasterInputData.getIrrigationCost();
 
 		{
 			//	YieldResponsesItem yresp = yieldRaster.get(new RasterKey(40,38));//getFromCoordinates(-118.0, -33.0);
@@ -300,8 +299,8 @@ public class GamsRasterOptimiser {
 
 		if (DEBUG) LogWriter.println("Making " + numCerealCats * numPastureCats + " categories");
 
-		LazyTreeMap<Integer, AveragingYieldResponsesItem> aggregatedYields = new LazyTreeMap<Integer, AveragingYieldResponsesItem>() { 
-			protected AveragingYieldResponsesItem createValue() { return new AveragingYieldResponsesItem(); }
+		LazyTreeMap<Integer, YieldResponsesItem> aggregatedYields = new LazyTreeMap<Integer, YieldResponsesItem>() { 
+			protected YieldResponsesItem createValue() { return new YieldResponsesItem(); }
 		};
 		LazyTreeMap<Integer, LandUseItem> aggregatedAreas = new LazyTreeMap<Integer, LandUseItem>() { 
 			protected LandUseItem createValue() { return new LandUseItem(); }
@@ -315,8 +314,6 @@ public class GamsRasterOptimiser {
 
 		int countFound = 0, countMissing = 0;
 
-
-
 		for (Entry<RasterKey, YieldResponsesItem> entry : yieldRaster.entrySet()) {
 			YieldResponsesItem yresp = entry.getValue();
 			RasterKey key = entry.getKey();
@@ -335,37 +332,43 @@ public class GamsRasterOptimiser {
 					continue;
 				}
 
-				IrrigationItem irrigCost = irrigCostRaster.get(key);
+				IrrigationItem irrigItem = irrigRaster.get(key);
 
 				int cerealCat = findCategory(wheatlDivisions, yresp.getYieldNone(CropType.WHEAT) + yresp.getYieldMax(CropType.WHEAT));
 				int pastureCat = findCategory(pastureDivisions, yresp.getYieldNone(CropType.PASTURE) + yresp.getYieldMax(CropType.PASTURE));
 				Integer id = cerealCat + pastureCat * numCerealCats;
 
-				AveragingYieldResponsesItem avgYResp = aggregatedYields.lazyGet(id);
+				YieldResponsesItem aggYResp = aggregatedYields.lazyGet(id);
 				LandUseItem aggLandUse = aggregatedAreas.lazyGet(id);
-				IrrigationItem avgIrigCost = aggregatedIrrigCosts.lazyGet(id);
+				IrrigationItem aggIrig = aggregatedIrrigCosts.lazyGet(id);
 				mapping.lazyGet(id).add(key); 
 
 				// Irrigation cost
 				double suitableAreaThisTime  = landUseItem.getSuitableLand();
-				if (irrigCost!= null && suitableAreaThisTime > 0) {
-					double areaSoFar = aggLandUse.getSuitableLand();
-					avgIrigCost.setIrrigCost((avgIrigCost.getIrrigCost()*areaSoFar + suitableAreaThisTime*irrigCost.getIrrigCost()) / (areaSoFar + suitableAreaThisTime));
+				double suitableAreaSoFar = aggLandUse.getSuitableLand();
+				if (irrigItem!= null) {
+					aggIrig.setIrrigCost( aggregateMean(aggIrig.getIrrigCost(), suitableAreaSoFar, irrigItem.getIrrigCost(), suitableAreaThisTime));
+					aggIrig.setIrrigConstraint(aggregateMean(aggIrig.getIrrigConstraint(), suitableAreaSoFar, irrigItem.getIrrigConstraint(), suitableAreaThisTime));
 					//LogWriter.println(id + ", " + key + ", " + avgIrigCost.getIrrigCost() + ", from " + areaSoFar + ", " + suitableAreaThisTime + ", " + irrigCost.getIrrigCost());
 				}
 
 				// Crops yields and area fractions
 				for (CropType crop : CropType.getNonMeatTypes()) {
+					if (irrigItem!= null) {
+						aggIrig.setMaxIrrigAmount(crop, aggregateMean(aggIrig.getMaxIrrigAmount(crop), suitableAreaSoFar, irrigItem.getMaxIrrigAmount(crop), suitableAreaThisTime));
+					}
+					
+					double areaSoFar = aggLandUse.getCropArea(crop);
+					double areaThisTime = landUseItem.getCropArea(crop);
+
 					for (YieldType yieldType : YieldType.values()) {
 						double y = yresp.getYield(yieldType, crop);
 						if (Double.isNaN(y))
 							LogWriter.printlnError("Problem getting yield at, col:" + key.getCol() + ", row:"  + key.getRow() + ", x:" + yieldRaster.getXCoordin(key) + ", y:" + yieldRaster.getYCoordin(key) + ", type:" + yieldType + ", crop:" + crop);
 						else
-							avgYResp.setYield(yieldType, crop, y);
+							aggYResp.setYield(yieldType, crop, aggregateMean(aggYResp.getYield(yieldType, crop), areaSoFar, y, areaThisTime));
 					}
-
-					double areaSoFar = aggLandUse.getCropArea(crop);
-					double areaThisTime = landUseItem.getCropArea(crop);
+				
 					double updateCropland = (landUseItem.getLandCoverArea(LandCoverType.CROPLAND) + aggLandUse.getLandCoverArea(LandCoverType.CROPLAND));
 
 					if (updateCropland > 0)
@@ -400,6 +403,16 @@ public class GamsRasterOptimiser {
 
 		return new GamsLocationInput(rasterInputData.getTimestep(), aggregatedYields, aggregatedAreas, aggregatedIrrigCosts, rasterInputData.getCountryInput());
 	}
+	
+	private double aggregateMean(double aggV, double aggArea, double newV, double newArea) {
+		if (Double.isNaN(aggV))
+			return newV;
+		
+		if (newArea == 0)
+			return aggV;
+		
+		return (aggV*aggArea + newV*newArea) / (aggArea + newArea);
+	}
 
 	private int findCategory(List<Double> divisions, double yield) {
 		int category;
diff --git a/src/ac/ed/lurg/demand/BaseConsumpManager.java b/src/ac/ed/lurg/demand/BaseConsumpManager.java
index 062b6035..8af8c4c7 100644
--- a/src/ac/ed/lurg/demand/BaseConsumpManager.java
+++ b/src/ac/ed/lurg/demand/BaseConsumpManager.java
@@ -61,7 +61,7 @@ public class BaseConsumpManager {
 		
 		} catch (Exception e) {
 			LogWriter.printlnError("Failed in reading commodity demand fits");
-			e.printStackTrace();
+			LogWriter.print(e);
 		}
 		LogWriter.println("Processed " + filename + ", create " + baseConsumpMap.size() + " base consumption values");
 	}
diff --git a/src/ac/ed/lurg/demand/BioenergyDemand.java b/src/ac/ed/lurg/demand/BioenergyDemand.java
index 4b5bbeb6..2d723755 100644
--- a/src/ac/ed/lurg/demand/BioenergyDemand.java
+++ b/src/ac/ed/lurg/demand/BioenergyDemand.java
@@ -52,7 +52,7 @@ public class BioenergyDemand {
 		
 		} catch (IOException e) {
 			LogWriter.printlnError("Failed in reading commodity demand fits");
-			e.printStackTrace();
+			LogWriter.print(e);
 		}
 		LogWriter.println("Processed " + filename + ", create " + bioenergyMap.size() + " country commodity maps values");
 		
diff --git a/src/ac/ed/lurg/demand/DemandCurveManager.java b/src/ac/ed/lurg/demand/DemandCurveManager.java
index 8319f163..720c9e48 100644
--- a/src/ac/ed/lurg/demand/DemandCurveManager.java
+++ b/src/ac/ed/lurg/demand/DemandCurveManager.java
@@ -52,7 +52,7 @@ public class DemandCurveManager {
 		
 		} catch (IOException e) {
 			LogWriter.printlnError("Failed in reading commodity demand fits");
-			e.printStackTrace();
+			LogWriter.print(e);
 		}
 		LogWriter.println("Processed " + filename + ", create " + curves.size() + " demand curves");
 	}
diff --git a/src/ac/ed/lurg/demand/SspManager.java b/src/ac/ed/lurg/demand/SspManager.java
index fbd3fc56..8c76f0f0 100644
--- a/src/ac/ed/lurg/demand/SspManager.java
+++ b/src/ac/ed/lurg/demand/SspManager.java
@@ -53,14 +53,14 @@ public class SspManager {
 					sspMap.put(sspKey, sspData);
 				} catch (Exception e) {
 					LogWriter.printlnError("Failed in processing ssp line " + line);
-					e.printStackTrace();
+					LogWriter.print(e);
 				} 
 			} 
 			reader.close(); 
 		
 		} catch (Exception e) {
 			LogWriter.printlnError("Failed in reading ssp data file");
-			e.printStackTrace();
+			LogWriter.print(e);
 		} 
 		LogWriter.println("Processed " + filename + ", create " + sspMap.size() + " SSP entries");
 	}
diff --git a/src/ac/ed/lurg/landuse/CropUsageReader.java b/src/ac/ed/lurg/landuse/CropUsageReader.java
index 1680b348..9218ba71 100644
--- a/src/ac/ed/lurg/landuse/CropUsageReader.java
+++ b/src/ac/ed/lurg/landuse/CropUsageReader.java
@@ -76,7 +76,7 @@ public class CropUsageReader {
 		
 		} catch (IOException e) {
 			LogWriter.printlnError("Failed in reading commodity demand fits");
-			e.printStackTrace();
+			LogWriter.print(e);
 		}
 		LogWriter.println("Processed " + filename + ", create " + commodityMap.size() + " country commodity maps values");
 		
diff --git a/src/ac/ed/lurg/landuse/IrrigationConstraintReader.java b/src/ac/ed/lurg/landuse/IrrigationConstraintReader.java
index bed7e35e..1af03dac 100644
--- a/src/ac/ed/lurg/landuse/IrrigationConstraintReader.java
+++ b/src/ac/ed/lurg/landuse/IrrigationConstraintReader.java
@@ -2,7 +2,6 @@ package ac.ed.lurg.landuse;
 
 import java.util.Map;
 
-import ac.ed.lurg.ModelConfig;
 import ac.sac.raster.AbstractTabularRasterReader;
 import ac.sac.raster.RasterKey;
 import ac.sac.raster.RasterSet;
@@ -17,8 +16,6 @@ public class IrrigationConstraintReader extends AbstractTabularRasterReader<Irri
 		
 	@Override
 	protected void setData(RasterKey key, IrrigationItem item, Map<String, Double> rowValues) {
-		
-		item.setIrrigConstraint(getValueForCol(rowValues, "Max_irr_water") * ModelConfig.IRRIG_COST_SCALE_FACTOR);
-		
+		item.setIrrigConstraint(getValueForCol(rowValues, "Max_irr_water")); // 1 to convert from mm to litres/m2
 	}
 }
diff --git a/src/ac/ed/lurg/landuse/IrrigationItem.java b/src/ac/ed/lurg/landuse/IrrigationItem.java
index 1a2d873e..b209ed0f 100644
--- a/src/ac/ed/lurg/landuse/IrrigationItem.java
+++ b/src/ac/ed/lurg/landuse/IrrigationItem.java
@@ -12,8 +12,8 @@ public class IrrigationItem implements RasterItem {
 	// this gives a value from 1 to 0, with 1 being the most costly and 0 the least.
 	
 	private double irrigationCost; // cost per ? of irrigation
-	private double irrigConstraint;  // mm of water available
-	private Map<CropType, Double> maxIrrigAmounts = new HashMap<CropType, Double>(); // amount of water (litres/ha) used at maximum irrigation, i.e. to achieve no water stress
+	private double irrigConstraint;  // mm or litre/m2 (they are the same) of water available
+	private Map<CropType, Double> maxIrrigAmounts = new HashMap<CropType, Double>(); // amount of water (litres/m2) used at maximum irrigation, i.e. to achieve no water stress
 
 	public double getIrrigCost() {
 		return irrigationCost;
diff --git a/src/ac/ed/lurg/landuse/IrrigationMaxAmountReader.java b/src/ac/ed/lurg/landuse/IrrigationMaxAmountReader.java
index 6f0d6ed3..d8c3c8ad 100644
--- a/src/ac/ed/lurg/landuse/IrrigationMaxAmountReader.java
+++ b/src/ac/ed/lurg/landuse/IrrigationMaxAmountReader.java
@@ -18,11 +18,11 @@ public class IrrigationMaxAmountReader extends AbstractTabularRasterReader<Irrig
 	@Override
 	protected void setData(RasterKey key, IrrigationItem item, Map<String, Double> rowValues) {
 		
-		item.setMaxIrrigAmount(CropType.WHEAT, getValueForCol(rowValues, "TeWW"));
-		item.setMaxIrrigAmount(CropType.MAIZE, getValueForCol(rowValues, "TeCo"));
-		item.setMaxIrrigAmount(CropType.RICE, getValueForCol(rowValues, "TrRi"));
-		item.setMaxIrrigAmount(CropType.OILCROPS, getValueForCol(rowValues, "TeWW"));
-		item.setMaxIrrigAmount(CropType.PULSES, getValueForCol(rowValues, "TeSW"));
-		item.setMaxIrrigAmount(CropType.STARCHY_ROOTS, getValueForCol(rowValues, "TeSW"));
+		item.setMaxIrrigAmount(CropType.WHEAT, getValueForCol(rowValues, "TeWWi"));
+		item.setMaxIrrigAmount(CropType.MAIZE, getValueForCol(rowValues, "TeCoi"));
+		item.setMaxIrrigAmount(CropType.RICE, getValueForCol(rowValues, "TrRii"));
+		item.setMaxIrrigAmount(CropType.OILCROPS, getValueForCol(rowValues, "TeWWi"));
+		item.setMaxIrrigAmount(CropType.PULSES, getValueForCol(rowValues, "TeSWi"));
+		item.setMaxIrrigAmount(CropType.STARCHY_ROOTS, getValueForCol(rowValues, "TeSWi"));
 	}
 }
diff --git a/src/ac/ed/lurg/output/LpjgOutputer.java b/src/ac/ed/lurg/output/LpjgOutputer.java
index fd9b2713..95cb591e 100644
--- a/src/ac/ed/lurg/output/LpjgOutputer.java
+++ b/src/ac/ed/lurg/output/LpjgOutputer.java
@@ -88,7 +88,7 @@ public class LpjgOutputer {
 			}
 		}
 		catch (IOException e) {
-			e.printStackTrace();
+			LogWriter.print(e);
 		}
 		finally {
 			if (fertWriter != null) {
@@ -96,7 +96,7 @@ public class LpjgOutputer {
 					fertWriter.close();
 				} 
 				catch (IOException e) {
-					e.printStackTrace();
+					LogWriter.print(e);
 				}
 			}
 			if (irrigWriter != null) {
@@ -104,7 +104,7 @@ public class LpjgOutputer {
 					irrigWriter.close();
 				} 
 				catch (IOException e) {
-					e.printStackTrace();
+					LogWriter.print(e);
 				}
 			}
 		}
@@ -182,7 +182,7 @@ public class LpjgOutputer {
 			}
 		}
 		catch (IOException e) {
-			e.printStackTrace();
+			LogWriter.print(e);
 		}
 		finally {
 			if (landCoverWriter != null) {
@@ -190,7 +190,7 @@ public class LpjgOutputer {
 					landCoverWriter.close();
 				} 
 				catch (IOException e) {
-					e.printStackTrace();
+					LogWriter.print(e);
 				}
 			}
 			if (cropFractWriter != null) {
@@ -198,7 +198,7 @@ public class LpjgOutputer {
 					cropFractWriter.close();
 				} 
 				catch (IOException e) {
-					e.printStackTrace();
+					LogWriter.print(e);
 				}
 			}
 		}
diff --git a/src/ac/ed/lurg/utils/LogWriter.java b/src/ac/ed/lurg/utils/LogWriter.java
index 1f2fe093..27ca8df9 100644
--- a/src/ac/ed/lurg/utils/LogWriter.java
+++ b/src/ac/ed/lurg/utils/LogWriter.java
@@ -5,15 +5,15 @@ import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.PrintStream;
+import java.io.PrintWriter;
 
 import ac.ed.lurg.ModelConfig;
 
 public class LogWriter {
 
 	private static LogWriter logWriter;
-	private BufferedWriter logFile;
-	private boolean suppressStd;
-
+	private PrintWriter logFile;
+	
 	public static synchronized void println(String s) {
 		getLogWriter().print(s, System.out, true);
 	}
@@ -26,6 +26,13 @@ public class LogWriter {
 		getLogWriter().print(s, System.err, true);
 	}
 	
+	public static synchronized void print(Exception e) {
+	    e.printStackTrace(getLogWriter().logFile);
+	    
+		if (!ModelConfig.SUPPRESS_STD_OUTPUT)
+			e.printStackTrace();
+	}
+	
 	private static LogWriter getLogWriter() {
 		if (logWriter == null)
 			logWriter = new LogWriter(ModelConfig.OUTPUT_DIR + File.separator + "log.txt");
@@ -34,28 +41,20 @@ public class LogWriter {
 	}
 
 	private LogWriter(String outputFileName) {
-		FileWriter fstream;
 		try {
-			fstream = new FileWriter(outputFileName,false);
-			logFile = new BufferedWriter(fstream);
-			suppressStd = ModelConfig.SUPPRESS_STD_OUTPUT;
+			logFile = new PrintWriter(new BufferedWriter(new FileWriter(outputFileName,false)));
 		}
 		catch (IOException e) {
-			e.printStackTrace();
-		}		
+			LogWriter.print(e);
+		}
 	}
 
 	private void print(String s, PrintStream stream, boolean newLine) {
-		try {
-			logFile.write(s);
-			if (newLine) logFile.newLine();
-			logFile.flush();
-		}
-		catch (IOException e) {
-			e.printStackTrace();
-		}
-		
-		if (!suppressStd) {
+		logFile.write(s);
+		if (newLine) logFile.write(System.lineSeparator());
+	//	logFile.flush();  
+	
+		if (!ModelConfig.SUPPRESS_STD_OUTPUT) {
 			stream.print(s);
 			if (newLine) stream.println();
 		}
@@ -63,11 +62,6 @@ public class LogWriter {
 
 	// probably not called, but never mind as keep stream flushed
 	protected void finalize() {
-		try {
-			logFile.close();
-		}
-		catch (IOException e) {
-			e.printStackTrace();
-		}
+		logFile.close();
 	}
 }
\ No newline at end of file
diff --git a/src/ac/ed/lurg/utils/WatchDir.java b/src/ac/ed/lurg/utils/WatchDir.java
index a6bb75fa..6e1d13c9 100644
--- a/src/ac/ed/lurg/utils/WatchDir.java
+++ b/src/ac/ed/lurg/utils/WatchDir.java
@@ -33,7 +33,7 @@ public class WatchDir {
 			watcher.close();
 		} 
 		catch (IOException e) {
-			e.printStackTrace();
+			LogWriter.print(e);
 		}
 		this.stop = true;
 	}
diff --git a/src/ac/ed/lurg/utils/WatchForFile.java b/src/ac/ed/lurg/utils/WatchForFile.java
index 4ac0f3e2..d6de47c6 100644
--- a/src/ac/ed/lurg/utils/WatchForFile.java
+++ b/src/ac/ed/lurg/utils/WatchForFile.java
@@ -72,7 +72,7 @@ public class WatchForFile extends Observable implements WatchDir.Callback {
 			try {
 				wait(timeoutSec * 1000);
 			} catch (InterruptedException e) {
-				e.printStackTrace();
+				LogWriter.print(e);
 			}
 			finally {
 				stop();
diff --git a/src/ac/ed/lurg/yield/AveragingYieldResponse.java b/src/ac/ed/lurg/yield/AveragingYieldResponse.java
deleted file mode 100644
index 1676afc3..00000000
--- a/src/ac/ed/lurg/yield/AveragingYieldResponse.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package ac.ed.lurg.yield;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import ac.ed.lurg.types.YieldType;
-
-public class AveragingYieldResponse extends YieldResponse {
-	private Map<YieldType, Integer> numAreas = new HashMap<YieldType, Integer>();
-
-	// we are assuming that the areas are all the same size, i.e. countries boundaries follow equal sized grid structure
-	public void setYield(YieldType type, double yield) {
-		
-		double previousYield = 0;
-		if (yields.containsKey(type))
-			previousYield = yields.get(type);
-		
-		int prevNumAreas = 0;
-		if (numAreas.containsKey(type))
-			prevNumAreas = numAreas.get(type);
-
-		double newAvgYield = (previousYield*prevNumAreas + yield)/(prevNumAreas+1);
-		
-		yields.put(type, newAvgYield);
-		numAreas.put(type, prevNumAreas+1);
-	}
-}
diff --git a/src/ac/ed/lurg/yield/AveragingYieldResponsesItem.java b/src/ac/ed/lurg/yield/AveragingYieldResponsesItem.java
deleted file mode 100644
index 3999ed31..00000000
--- a/src/ac/ed/lurg/yield/AveragingYieldResponsesItem.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package ac.ed.lurg.yield;
-
-import ac.ed.lurg.types.CropType;
-
-public class AveragingYieldResponsesItem extends YieldResponsesItem {
-	
-	@Override
-	YieldResponse getYieldResponseForCrop(CropType crop) {
-		YieldResponse yresp = yieldResponses.get(crop);
-		if (yresp == null) {
-			yresp = new AveragingYieldResponse();
-			yieldResponses.put(crop, yresp);
-		}
-		return yresp;
-	}
-}
diff --git a/src/ac/ed/lurg/yield/LPJYieldResponseMapReader.java b/src/ac/ed/lurg/yield/LPJYieldResponseMapReader.java
index 3eb218e7..8bf54084 100644
--- a/src/ac/ed/lurg/yield/LPJYieldResponseMapReader.java
+++ b/src/ac/ed/lurg/yield/LPJYieldResponseMapReader.java
@@ -71,7 +71,6 @@ public class LPJYieldResponseMapReader extends AbstractTabularRasterReader<Yield
 			item.setYield(YieldType.FERT_MAX_IRRIG_MAX, CropType.PASTURE,  pastureYield*1.4);
 		}
 		else {
-			//	TeWWhi  TeWWme  TeWWlo  TeSWhi  TeSWme  TeSWlo  TeCohi  TeCome  TeColo  TrRihi  TrRime  TrRilo
 			double adjFactor;
 
 			boolean isSpringWheat = (getValueForCol(rowValues, "teSWhi") > getValueForCol(rowValues, "TeWWhi"));
@@ -81,11 +80,11 @@ public class LPJYieldResponseMapReader extends AbstractTabularRasterReader<Yield
 				for (IrrigationRate irrig : IrrigationRate.values()) {
 					YieldType yieldType = YieldType.getYieldType(fert, irrig);
 					
-					if (fert.equals(FertiliserRate.NO_FERT))
-						adjFactor = 10 * 0.4; // adjust no fert yield to 40% of figure
-					else if (fert.equals(FertiliserRate.MID_FERT))
-						adjFactor = 10 * 0.9;  // adjust mid fert yield to 90% of figure
-					else
+			//		if (fert.equals(FertiliserRate.NO_FERT))
+			//			adjFactor = 10 * 0.4; // adjust no fert yield to 40% of figure
+			//		else if (fert.equals(FertiliserRate.MID_FERT))
+			//			adjFactor = 10 * 0.9;  // adjust mid fert yield to 90% of figure
+			//		else
 						adjFactor = 10;  // 10 for kg/m2 to t/ha
 
 					String fertIrrigString = irrig.getId() + fert.getId();
diff --git a/src/ac/sac/raster/AbstractRasterReader.java b/src/ac/sac/raster/AbstractRasterReader.java
index 2042959e..fbd39da1 100755
--- a/src/ac/sac/raster/AbstractRasterReader.java
+++ b/src/ac/sac/raster/AbstractRasterReader.java
@@ -132,7 +132,7 @@ public abstract class AbstractRasterReader<D extends RasterItem> {
 		}
 		catch (Exception e) {
 			LogWriter.println("row:" + row + ", col:" + col);
-			e.printStackTrace();
+			LogWriter.print(e);
 		}
 
 		LogWriter.println("Reading " + filename + ", took " + (System.currentTimeMillis() - startTime) + " ms");
diff --git a/src/ac/sac/raster/AbstractTabularRasterReader.java b/src/ac/sac/raster/AbstractTabularRasterReader.java
index 1cabc85d..03fbdd8c 100644
--- a/src/ac/sac/raster/AbstractTabularRasterReader.java
+++ b/src/ac/sac/raster/AbstractTabularRasterReader.java
@@ -76,7 +76,7 @@ public abstract class AbstractTabularRasterReader<D extends RasterItem> {
 		}
 		catch (Exception e) {
 			LogWriter.printlnError("Problem reading data file " + filename);
-			e.printStackTrace();
+			LogWriter.print(e);
 			throw new RuntimeException(e);
 		}
 		finally {
@@ -84,7 +84,7 @@ public abstract class AbstractTabularRasterReader<D extends RasterItem> {
 				try {
 					in.close();
 				} catch (IOException e) {
-					e.printStackTrace();
+					LogWriter.print(e);
 				}
 		}
 
diff --git a/src/ac/sac/raster/RasterOutputer.java b/src/ac/sac/raster/RasterOutputer.java
index 52318345..02c21ceb 100644
--- a/src/ac/sac/raster/RasterOutputer.java
+++ b/src/ac/sac/raster/RasterOutputer.java
@@ -67,7 +67,7 @@ public abstract class RasterOutputer<D extends RasterItem> {
 	    	}
 	    }
 	    catch (IOException e) {
-	    	e.printStackTrace();
+			LogWriter.print(e);
 	    }
 	    finally {
 			if (fileWriter != null) {
@@ -75,7 +75,7 @@ public abstract class RasterOutputer<D extends RasterItem> {
 					fileWriter.close();
 				} 
 				catch (IOException e) {
-					e.printStackTrace();
+					LogWriter.print(e);
 				}
 			}
 	    }
-- 
GitLab