diff --git a/hindcast/hind_config.properties b/hindcast/hind_config.properties
index f61c966e2daf0af226828556001de519e7fb6e47..26d3f0711130e7ac5b5a8c25f70011686c69d4e7 100644
--- a/hindcast/hind_config.properties
+++ b/hindcast/hind_config.properties
@@ -2,13 +2,12 @@ BASE_DIR=./hindcast
 INITAL_LAND_COVER_FILENAME=netfract_hurtt_1990.txt
 BASE_YEAR=1990
 SSP_SCENARIO=HINDCAST
-YIELD_DIR=/Users/peteralexander/Documents/LURG/LPJ/IPSL/LPJG_PLUM_expt1.1_1966-2005_ipsl_lessIO_forED
+YIELD_DIR=/Users/peteralexander/Documents/LURG/LPJ/19Jan2017/LPJG_PLUM_expt1.1_1971-2005_forED
+#YIELD_DIR=/Users/peteralexander/Documents/LURG/LPJ/IPSL/LPJG_PLUM_expt1.1_1966-2005_ipsl_lessIO_forED
 
 # irritatingly the gams file is also found under the BASE_DIR, and don't want to duplicate so need to specify exactly
 GAMS_MODEL=./GAMS/IntExtOpt.gms
 
-
-
 IS_CALIBRATION_RUN = false
 
 END_TIMESTEP=20
diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java
index 9dc548c35d756d5691a0e3552008f37c2f7040b2..db28705226a49965915c5e38b989ee9b361a68d6 100644
--- a/src/ac/ed/lurg/ModelConfig.java
+++ b/src/ac/ed/lurg/ModelConfig.java
@@ -25,7 +25,7 @@ public class ModelConfig {
 		}
 	}
 
-        public static String getSetupDetails() {
+	public static String getSetupDetails() {
 		String buildVerion = System.getProperty("BUILDVER");
 		StringBuffer sb = new StringBuffer("Build version: " + buildVerion + "\n");
 
@@ -206,7 +206,7 @@ public class ModelConfig {
 	
 	public static final double DOMESTIC_PRICE_MARKUP = getDoubleProperty("DOMESTIC_PRICE_MARKUP", 2.0);
 	public static final double TRANSPORT_LOSSES = getDoubleProperty("TRANSPORT_LOSSES", 0.05);  // in international trade
-	public static final double TRANSPORT_COST = getDoubleProperty("TRANSPORT_COST", 0.1);  // 100 $/t  see Wheat Transportation Profile - USDA
+	public static final double TRANSPORT_COST = getDoubleProperty("TRANSPORT_COST", 0.2);  // 100 $/t  see Wheat Transportation Profile - USDA
 	public static final double TRADE_BARRIER_FACTOR_DEFAULT = getDoubleProperty("TRADE_BARRIER_FACTOR_DEFAULT", 0.4);  // price factor in international trade, transport cost and real trade barriers
 	public static final double TRADE_BARRIER_ADJ = getDoubleProperty("TRADE_BARRIER_ADJ", 1.0);
 	public static final boolean ACTIVE_TRADE_BARRIERS = getBooleanProperty("ACTIVE_TRADE_BARRIERS", false);  // if set to true read in barrier information from file, otherwise use default as above
diff --git a/src/ac/ed/lurg/ModelMain.java b/src/ac/ed/lurg/ModelMain.java
index 961d9d404fd5095d147f287e2fa0f53b9c28fb69..a1af2620d2dd97ca053eafa96eed7212b8b1b063 100644
--- a/src/ac/ed/lurg/ModelMain.java
+++ b/src/ac/ed/lurg/ModelMain.java
@@ -42,7 +42,6 @@ import ac.ed.lurg.types.CommodityType;
 import ac.ed.lurg.types.CropToDoubleMap;
 import ac.ed.lurg.types.CropType;
 import ac.ed.lurg.types.LandCoverType;
-import ac.ed.lurg.types.ModelFitType;
 import ac.ed.lurg.utils.LogWriter;
 import ac.ed.lurg.yield.LPJYieldResponseMapReader;
 import ac.ed.lurg.yield.YieldRaster;
diff --git a/src/ac/ed/lurg/utils/LogWriter.java b/src/ac/ed/lurg/utils/LogWriter.java
index 8403e1b34a359d47ba192737edcaff49b65da7d1..e754cf136d0da836dd53b353c3ffa31492928d08 100644
--- a/src/ac/ed/lurg/utils/LogWriter.java
+++ b/src/ac/ed/lurg/utils/LogWriter.java
@@ -43,17 +43,23 @@ public class LogWriter {
 
 	private LogWriter(String outputFileName) {
 		try {
-			logFile = new PrintWriter(new BufferedWriter(new FileWriter(outputFileName,false)));
+			File f = new File(outputFileName);
+			if(f.exists()) 
+				logFile = new PrintWriter(new BufferedWriter(new FileWriter(outputFileName,false)));
+			else
+				System.err.println("LogWriter: outputFileName: " + outputFileName + " not found.  Perhaps not set config file properly");
 		}
 		catch (IOException e) {
-			LogWriter.print(e);
+			System.err.print(e);
 		}
 	}
 
 	private void print(String s, PrintStream stream, boolean newLine) {
-		logFile.write(s);
-		if (newLine) logFile.write(System.lineSeparator());
-		logFile.flush();  
+		if (logFile != null) {
+			logFile.write(s);
+			if (newLine) logFile.write(System.lineSeparator());
+			logFile.flush();
+		}
 	
 		if (!ModelConfig.SUPPRESS_STD_OUTPUT) {
 			stream.print(s);
diff --git a/src/ac/ed/lurg/utils/cluster/CentriodPoint.java b/src/ac/ed/lurg/utils/cluster/CentriodPoint.java
new file mode 100644
index 0000000000000000000000000000000000000000..22a1e1227ecceb185f04d223fe1fc022d2178007
--- /dev/null
+++ b/src/ac/ed/lurg/utils/cluster/CentriodPoint.java
@@ -0,0 +1,29 @@
+package ac.ed.lurg.utils.cluster;
+
+import java.util.Collection;
+import java.util.Map;
+
+public class CentriodPoint implements ClusteringPoint {
+
+	private Map<String, Double> valueMap;
+
+	public CentriodPoint(Map<String, Double> valueMap) {
+		this.valueMap = valueMap;
+	}
+
+	public double getClusteringValue(String key)  {
+		return valueMap.get(key);
+	}
+
+	public Collection<String> getAllClusteringKeys() {
+		return valueMap.keySet();
+	}
+
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+		for (Map.Entry<String, Double> e : valueMap.entrySet()) {
+			sb.append(e.getKey() + "=" + e.getValue() + " ");
+		}
+		return sb.toString();
+	}
+}
diff --git a/src/ac/ed/lurg/utils/cluster/Cluster.java b/src/ac/ed/lurg/utils/cluster/Cluster.java
new file mode 100644
index 0000000000000000000000000000000000000000..91293201851297a896d7915e0e922b8d3fe7d8ea
--- /dev/null
+++ b/src/ac/ed/lurg/utils/cluster/Cluster.java
@@ -0,0 +1,68 @@
+package ac.ed.lurg.utils.cluster;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+public class Cluster {
+
+	private Collection<ClusteringPoint> points = new HashSet<ClusteringPoint>();
+	private ClusteringPoint centroid;
+
+	public Cluster(ClusteringPoint centroid) {
+		this.centroid = centroid;
+	}
+
+	public Collection<ClusteringPoint> getPoints() {
+		return points;
+	}
+
+	protected void addPoint(ClusteringPoint point) {
+		points.add(point);
+	}
+
+	public ClusteringPoint getCentroid() {
+		return centroid;
+	}
+	
+	protected double calculateCentroid() {
+		int n_points = points.size();
+		if(n_points == 0) return 0;
+
+		Map<String, Double> centroidValues = new HashMap<String, Double>();
+
+		for(ClusteringPoint p : points) {
+	    	for (String key : p.getAllClusteringKeys()) {
+				Double soFar = centroidValues.get(key);
+				Double pointVal = p.getClusteringValue(key);
+				Double updated = soFar==null ? pointVal : pointVal + soFar;
+				centroidValues.put(key, updated);
+			}
+		}
+
+		for (Map.Entry<String, Double> e : centroidValues.entrySet())
+			centroidValues.put(e.getKey(), e.getValue()/n_points);
+
+		ClusteringPoint updatedCentroid = new CentriodPoint(centroidValues);
+		double distanceMoved = distanceFromCentroid(updatedCentroid);
+		
+		centroid = updatedCentroid;
+		return distanceMoved;
+	}
+	
+    //Calculates the distance between two points.
+    protected double distanceFromCentroid(ClusteringPoint p) {
+    	double squaredTotal=0;
+    	for (String key : centroid.getAllClusteringKeys()) {
+       		squaredTotal += Math.pow(p.getClusteringValue(key)-centroid.getClusteringValue(key), 2);
+    	}
+    	
+        return Math.sqrt(squaredTotal);
+    }
+
+
+	protected void clearPoints() {
+		points.clear();
+	}
+}
\ No newline at end of file
diff --git a/src/ac/ed/lurg/utils/cluster/ClusteringPoint.java b/src/ac/ed/lurg/utils/cluster/ClusteringPoint.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca300134f7ca0a5734ebdddd0069cd3833111723
--- /dev/null
+++ b/src/ac/ed/lurg/utils/cluster/ClusteringPoint.java
@@ -0,0 +1,11 @@
+package ac.ed.lurg.utils.cluster;
+
+import java.util.Collection;
+
+/** Interface that give information used in clustering */
+public interface ClusteringPoint {
+ 
+    public double getClusteringValue(String key);
+	public Collection<String> getAllClusteringKeys();
+
+}
\ No newline at end of file
diff --git a/src/ac/ed/lurg/utils/cluster/KMeans.java b/src/ac/ed/lurg/utils/cluster/KMeans.java
new file mode 100644
index 0000000000000000000000000000000000000000..e49a52302e6da53a8af5c7847e6c64ad9055d450
--- /dev/null
+++ b/src/ac/ed/lurg/utils/cluster/KMeans.java
@@ -0,0 +1,131 @@
+package ac.ed.lurg.utils.cluster;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Random;
+
+import ac.ed.lurg.utils.LogWriter;
+ 
+public class KMeans {
+     
+    private Collection<ClusteringPoint> points;
+    private Collection<Cluster> clusters;
+    
+    public KMeans(Collection<ClusteringPoint> points, int numClusters) {
+    	this.points = points;
+    	this.clusters = new HashSet<Cluster>();   
+    	
+        Map<String, Double> minValueMap = new HashMap<String, Double>();
+        Map<String, Double> maxValueMap = new HashMap<String, Double>();
+
+        for (ClusteringPoint p : points) {
+	    	for (String key : p.getAllClusteringKeys()) {
+	    		double currentVal = p.getClusteringValue(key);
+	    		Double minV = minValueMap.get(key);
+	    		Double maxV = maxValueMap.get(key);
+	    		double minSoFar = minV==null ? Double.POSITIVE_INFINITY : minV;
+	    		double maxSoFar = maxV==null ? Double.NEGATIVE_INFINITY : maxV;
+
+	    		if (currentVal < minSoFar)
+	    			minValueMap.put(key, currentVal);
+	    		
+	    		if (currentVal > maxSoFar)
+	    			maxValueMap.put(key, currentVal);
+	    	}
+        }
+    	
+		Random r = new Random();
+		double min, max, rand, v;
+		//Create Clusters, with random centroids
+		for (int i = 0; i < numClusters; i++) {
+			
+			Map<String, Double> randomCentroid = new HashMap<String, Double>();
+
+	    	for (Map.Entry<String, Double> e : minValueMap.entrySet()) {
+	    		min = e.getValue();
+	    		max = maxValueMap.get(e.getKey());
+	    		rand = r.nextDouble();
+	    		v = min + (max - min) * rand;
+	    		randomCentroid.put(e.getKey(), v);
+	    	}
+	    	
+	    	ClusteringPoint p = new CentriodPoint(randomCentroid);
+	    	LogWriter.println("Creating cluster at " + p);
+			Cluster cluster = new Cluster(p);
+			clusters.add(cluster);
+		}
+    }
+    
+	protected void printClusters() {
+		int i=0;
+		for (Cluster c : clusters) {
+			i++;
+			LogWriter.println("[Cluster: " + i+"]");
+			LogWriter.println("[Centroid: " + c.getCentroid() + "]");
+			LogWriter.println("[Points:");
+			for(ClusteringPoint p : c.getPoints())
+				LogWriter.println(p.toString());
+			
+			LogWriter.println("]\n");
+		}
+	}
+
+    public double calculateClusters(int maxIterations, double tolerance) {
+        int iteration = 0;
+		long startTime = System.currentTimeMillis();
+
+        while(true) {        			
+        	iteration++;
+        	double distance = 0;
+
+        	//Assign points to the closer cluster
+        	assignCluster();
+        	
+            //Calculate new centroids, and total distance between new and old centroids
+            for(Cluster c : clusters)
+            	distance += c.calculateCentroid();
+            
+        	LogWriter.println("#################");
+        	LogWriter.println("Iteration: " + iteration);
+        	LogWriter.println("Centroid distances: " + distance);
+        	printClusters();
+   	
+        	if(distance <= tolerance || iteration > maxIterations) {
+        		LogWriter.println("Finishing calculateClusters: Iteration " + iteration + ", centroid distances: " + distance);
+        		LogWriter.println("    Took " + (System.currentTimeMillis() - startTime) + " ms to run");
+        		return distance;
+        	}
+        }
+    }
+    
+    public Collection<Cluster> getClusters() {
+    	return clusters;
+    }
+    
+    private void clearPointsFromAllClusters() {
+    	for(Cluster cluster : clusters) {
+    		cluster.clearPoints();
+    	}
+    }
+    
+    private void assignCluster() {
+        clearPointsFromAllClusters();
+       
+        for(ClusteringPoint point : points) {
+        	double min = Double.MAX_VALUE;
+            Cluster cluster = null;                 
+            double distance = 0.0; 
+      	
+            for(Cluster c : clusters) {
+                distance = c.distanceFromCentroid(point);
+                if(distance < min){
+                    min = distance;
+                    cluster = c;
+                }
+            }
+            cluster.addPoint(point);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/ac/ed/lurg/utils/cluster/KMeansTest.java b/src/ac/ed/lurg/utils/cluster/KMeansTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..cbbd1cef11def6af9813b9fbd150258738038434
--- /dev/null
+++ b/src/ac/ed/lurg/utils/cluster/KMeansTest.java
@@ -0,0 +1,56 @@
+package ac.ed.lurg.utils.cluster;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+public class KMeansTest {
+
+	//Number of Clusters. This metric should be related to the number of points
+	private int NUM_CLUSTERS = 3;    
+	//Number of Points
+	private int NUM_POINTS = 10;
+	//Min and Max X and Y
+	private static final int MIN_COORDINATE = 0;
+	private static final int MAX_COORDINATE = 10;
+	private int MAX_ITERATIONS = 20;
+
+	public static void main(String[] args) {
+
+		KMeansTest kmeansTest = new KMeansTest();
+		kmeansTest.doIt();
+	}
+	
+	public void doIt() {
+		KMeans kmeans = new KMeans(createRandomPoints(MIN_COORDINATE,MAX_COORDINATE,NUM_POINTS), NUM_CLUSTERS);
+		kmeans.printClusters();
+		kmeans.calculateClusters(MAX_ITERATIONS, 0.6);
+	}
+	
+    //Creates random point
+    protected static ClusteringPoint createRandomPoint(int min, int max) {
+    	Random r = new Random();
+    	double x = min + (max - min) * r.nextDouble();
+    	double y = min + (max - min) * r.nextDouble();
+    	double z = min + (max - min) * r.nextDouble();
+
+    	Map<String, Double> values = new HashMap<String, Double>();
+    	values.put("X", x);
+    	values.put("Y", y);
+    	values.put("Z", z);
+
+    	ClusteringPoint p = new CentriodPoint(values);
+    	return p;
+    }
+    
+    protected static List<ClusteringPoint> createRandomPoints(int min, int max, int number) {
+    	List<ClusteringPoint> points = new ArrayList<ClusteringPoint>(number);
+    	for(int i = 0; i < number; i++) {
+    		points.add(createRandomPoint(min,max));
+    	}
+    	return points;
+    }
+
+}