diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms
index 4bada6176fcdcf9b861b55a5e4c4cc210127f153..120f3b51559c714de16f93d98f02747377234956 100644
--- a/GAMS/IntExtOpt.gms
+++ b/GAMS/IntExtOpt.gms
@@ -178,7 +178,7 @@ $gdxin
               (   SUM((crop, location), area(crop, location) * unitCost(crop, location)) +
                   
                   SUM(location, 
-                     1.0 * agriLandExpansion(location) +
+                     1.5 * agriLandExpansion(location) +
                      0.5 * cropIncrease(location) + 
                      0.5 * cropDecrease(location) + 
                      0.5 * pastureIncrease(location) + 
diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java
index 32ac0e19ddba46389b5601960c01e2c138a544a6..0805c04689c8957afff9bc6051cadba918996fbd 100644
--- a/src/ac/ed/lurg/ModelConfig.java
+++ b/src/ac/ed/lurg/ModelConfig.java
@@ -126,6 +126,7 @@ public class ModelConfig {
 	public static final String IRRIG_MAX_WATER_FILENAME = getProperty("IRRIG_MAX_WATER_FILENAME", "gsirrigation_plum.out");
 	public static final String PROTECTED_AREAS_FILE = SPATIAL_DATA_DIR + File.separator + "protected_areas.txt";
 	
+
 	// Output
 	public static final String LAND_COVER_OUTPUT_FILE = OUTPUT_DIR + File.separator + "lc.txt";
 	public static final String PRICES_OUTPUT_FILE = OUTPUT_DIR + File.separator + "prices.txt";
@@ -133,6 +134,12 @@ public class ModelConfig {
 	public static final boolean OUTPUT_FOR_LPJG = getBooleanProperty("OUTPUT_FOR_LPJG", true);
 	public static final boolean INTERPOLATE_OUTPUT_YEARS = getBooleanProperty("INTERPOLATE_OUTPUT_YEARS", true);
 	
+	public static final String INITAL_LAND_USE_FILE = OUTPUT_DIR + File.separator + "2150" + File.separator + "LandUse.txt";	
+	
+	public static final boolean IS_CALIBRATION_RUN = getBooleanProperty("IS_CALIBRATION_RUN", false);
+	public static final double MAX_IMPORT_CHANGE = IS_CALIBRATION_RUN ? 0.0 : getDoubleProperty("MAX_IMPORT_CHANGE", 0.1);
+	public static final boolean MARKET_ADJ_PRICE = IS_CALIBRATION_RUN ? false : getBooleanProperty("MARKET_ADJ_PRICE", true);
+
 	// Temporal configuration
 	public static final int START_TIMESTEP = getIntProperty("START_TIMESTEP", 0);
 	public static final int END_TIMESTEP = getIntProperty("END_TIMESTEP", 18);
@@ -148,7 +155,6 @@ public class ModelConfig {
 	// Other model parameters
 	public static final boolean CHANGE_DEMAND_YEAR = getBooleanProperty("CHANGE_DEMAND_YEAR", true);
 	public static final String SSP_SCENARIO = getProperty("SSP_SCENARIO", "SSP1_v9_130325");
-	public static final double MAX_IMPORT_CHANGE = getDoubleProperty("MAX_IMPORT_CHANGE", 0.1);
 
 	public static final double PASTURE_HARVEST_FRACTION = getDoubleProperty("PASTURE_HARVEST_FRACTION", 0.25);
 	public static final double MEAT_EFFICIENCY = getDoubleProperty("MEAT_EFFICIENCY", 1.0);  // 'meat' is includes feed conversion ratio already, this is tech. change or similar
@@ -164,7 +170,6 @@ public class ModelConfig {
 	public static final int BIOENERGY_CHANGE_START_YEAR = getIntProperty("BIOENERGY_CHANGE_START_YEAR", 2010);
 
 	public static final double MARKET_LAMBA = getDoubleProperty("MARKET_LAMBA", 0.5); // controls international market price adjustment rate
-	public static final boolean MARKET_ADJ_PRICE = getBooleanProperty("MARKET_ADJ_PRICE", true);
 
 	public static final double POPULATION_AGGREG_LIMIT = getDoubleProperty("POPULATION_AGGREG_LIMIT", 40.0);  // in millions, smaller countries are aggregated on a regional basis
 	
@@ -184,8 +189,8 @@ public class ModelConfig {
 
 	public static final boolean PROTECTED_AREAS_ENABLED = getBooleanProperty("PROTECTED_AREAS_ENABLED", true);
 
-	public static final int NUM_CEREAL_CATEGORIES = getIntProperty("NUM_CEREAL_CATEGORIES", 5);
-	public static final int NUM_PASTURE_CATEGORIES = getIntProperty("NUM_PASTURE_CATEGORIES", 1);
+	public static final int NUM_CEREAL_CATEGORIES = getIntProperty("NUM_CEREAL_CATEGORIES", 6);
+	public static final int NUM_PASTURE_CATEGORIES = getIntProperty("NUM_PASTURE_CATEGORIES", 6);
 
 	public static final boolean DEBUG_LIMIT_COUNTRIES = getBooleanProperty("DEBUG_LIMIT_COUNTRIES", false);
 	public static final Object DEBUG_COUNTRY_NAME = getProperty("DEBUG_COUNTRY_NAME", "United States of America");
diff --git a/src/ac/ed/lurg/ModelMain.java b/src/ac/ed/lurg/ModelMain.java
index 7be0c8ec41e5eaec099a490b62ab07c8f488b02c..9ff4345727c1e1f1bb0ad834f8e00b838af0e44d 100644
--- a/src/ac/ed/lurg/ModelMain.java
+++ b/src/ac/ed/lurg/ModelMain.java
@@ -4,6 +4,9 @@ import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileWriter;
 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;
@@ -30,7 +33,9 @@ import ac.ed.lurg.landuse.IrrigiationCostReader;
 import ac.ed.lurg.landuse.LandCoverItem;
 import ac.ed.lurg.landuse.LandCoverReader;
 import ac.ed.lurg.landuse.LandUseItem;
+import ac.ed.lurg.landuse.LandUseReader;
 import ac.ed.lurg.landuse.ProtectedAreasReader;
+import ac.ed.lurg.output.LandUseOutputer;
 import ac.ed.lurg.output.LpjgOutputer;
 import ac.ed.lurg.types.CommodityType;
 import ac.ed.lurg.types.CropToDoubleMap;
@@ -142,6 +147,19 @@ public class ModelMain {
 				LogWriter.printlnError("No results for " + ca.getCountry());
 				continue;
 			}
+			
+			// some hacky code for debug purposes that keeps each gams gdx file
+			if (ca.getCountry().getName().equals("Spain")) {
+				try {
+					Files.copy(
+						FileSystems.getDefault().getPath("/Users/peteralexander/Documents/R_Workspace/UNPLUM/temp/GamsTmp/_gams_java_gdb1.gdx"),
+						FileSystems.getDefault().getPath("/Users/peteralexander/Documents/R_Workspace/UNPLUM/temp/GamsTmp/" + timestep.getTimestep() + ".gdx")
+						, StandardCopyOption.REPLACE_EXISTING);
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			} 
 
 			// update global rasters
 			globalLandUseRaster.putAll(result.getLandUses());
@@ -172,7 +190,7 @@ public class ModelMain {
 
 			double imports = totalImportCommodities.get(crop);
 			double exports = totalExportCommodities.get(crop) * (1.0-ModelConfig.TRANSPORT_LOSSES);
-			GlobalPrice adjustedPrice = prevPrice.createWithUpdatedMarketPrices(imports, exports);
+			GlobalPrice adjustedPrice = prevPrice.createWithUpdatedMarketPrices(imports, exports, (ModelConfig.MARKET_ADJ_PRICE));
 			LogWriter.println(String.format("Price for %s updated from %s (imports amount %.0f, exports amount %.0f) to %s ", crop.getGamsName(), prevPrice, imports, exports, adjustedPrice));
 			prevWorldPrices.put(crop, adjustedPrice);
 		}
@@ -277,7 +295,6 @@ public class ModelMain {
 	}
 
 
-
 	private void outputTimestepResults(Timestep timestep, RasterSet<LandUseItem> landUseRaster, RasterSet<IntegerRasterItem> locationIdRaster, YieldRaster yieldSurfaces) {
 
 		writeLandCoverFile(timestep, landUseRaster);
@@ -309,6 +326,10 @@ public class ModelMain {
 				}
 			}
 		}
+		
+		LogWriter.printlnError("Outputing land uses Year: " + timestep.getYear());
+		LandUseOutputer landuseOutputer = new LandUseOutputer(timestep.getYear(), landUseRaster);
+		landuseOutputer.writeOutput();
 
 		outputLandCover(timestep.getYear(), landUseRaster, LandCoverType.CROPLAND);
 		outputLandCover(timestep.getYear(), landUseRaster, LandCoverType.PASTURE); 
@@ -338,17 +359,14 @@ public class ModelMain {
 	public Collection<CountryAgent> createCountryAgents(Collection<CompositeCountry> countryGrouping) {
 		Collection<CountryAgent> countryAgents = new HashSet<CountryAgent>();
 
-		RasterSet<LandCoverItem> initLC = getInitialLandCover();
+		RasterSet<LandUseItem> initLU = null;
 		
-		new RasterOutputer<LandCoverItem>(initLC, "InitialCropland") {
-			@Override
-			public Double getValue(RasterKey location) {
-				LandCoverItem item = results.get(location);
-				if (item == null)
-					return null;
-				return item.getLandCoverFract(LandCoverType.CROPLAND);
-			}
-		}.writeOutput();
+		if (ModelConfig.IS_CALIBRATION_RUN) {
+			initLU = getInitialLandCover();
+		}
+		else {
+			initLU = getInitialLandUse(); // read in all land use data saved from calibrations run
+		}
 		
 		Map<CompositeCountry, Map<CropType, CropUsageData>> cropUsageDataMap = new CropUsageReader(compositeCountryManager).getCommodityData();
 
@@ -361,18 +379,21 @@ public class ModelMain {
 			}
 
 			List<RasterKey> keys = countryBoundaryRaster.getKeysFor(cc);
-			RasterSet<LandCoverItem> initCountryLC = initLC.createSubsetForKeys(keys);
 			Map<CropType, CropUsageData> countryCommodityData = cropUsageDataMap.get(cc);
 			Map<CropType, Double> countryTradeBarriers =  tradeManager.getTradeBarriers(cc);
 		
 			if (countryCommodityData == null) {
 				LogWriter.printlnError("No commodities data for " + cc + ", so skipping");
 			}
-			else if (initCountryLC.size() == 0) {
-				LogWriter.printlnError("No initial land cover for " +cc + ", so skipping");
-			}
 			else {
-				CountryAgent ca = new CountryAgent(demandManager, cc, initCountryLC, countryCommodityData, countryTradeBarriers);
+				RasterSet<LandUseItem> initCountryLandUse = initLU.createSubsetForKeys(keys);
+				
+				if (initCountryLandUse.size() == 0) {
+					LogWriter.printlnError("No initial land use for " +cc + ", so skipping");
+					continue;
+				}
+
+				CountryAgent ca = new CountryAgent(demandManager, cc, initCountryLandUse, countryCommodityData, countryTradeBarriers);
 				countryAgents.add(ca);
 				LogWriter.println("Creating country agent for: " + cc );
 			}
@@ -380,21 +401,56 @@ public class ModelMain {
 
 		return countryAgents;
 	}
-
-	private RasterSet<LandCoverItem> getInitialLandCover() {
+	
+	/** This is if we are starting from previously saved state (for example, from calibration runs) */
+	private RasterSet<LandUseItem> getInitialLandUse() {
+		RasterSet<LandUseItem> initLU = new RasterSet<LandUseItem>(desiredProjection) {
+			private static final long serialVersionUID = 1317102740312961042L;
+			protected LandUseItem createRasterData() {
+				return new LandUseItem();
+			}
+		};
 		
-		RasterSet<LandCoverItem> initLC = new RasterSet<LandCoverItem>(desiredProjection) {
-		private static final long serialVersionUID = 4642550777741425501L;
-		protected LandCoverItem createRasterData() {
-			return new LandCoverItem();
-		}
+		new LandUseReader(initLU).getRasterDataFromFile(ModelConfig.INITAL_LAND_USE_FILE);
+		return initLU;
+	} 
+
+	/** this is if we are starting from Hurtt of other initial land covers (so we don't have land uses and intensity data) */
+	private RasterSet<LandUseItem> getInitialLandCover() {
+		RasterSet<LandCoverItem> initialLC = new RasterSet<LandCoverItem>(desiredProjection) {
+			private static final long serialVersionUID = 4642550777741425501L;
+			protected LandCoverItem createRasterData() {
+				return new LandCoverItem();
+			}
 		};
 		
-		new ProtectedAreasReader(initLC).getRasterDataFromFile(ModelConfig.PROTECTED_AREAS_FILE);
-		new LandCoverReader(initLC).getRasterDataFromFile(ModelConfig.INITAL_LAND_COVER_FILE);
-	
-		return initLC;
+		new ProtectedAreasReader(initialLC).getRasterDataFromFile(ModelConfig.PROTECTED_AREAS_FILE);
+		new LandCoverReader(initialLC).getRasterDataFromFile(ModelConfig.INITAL_LAND_COVER_FILE);
+		
+		/*	new RasterOutputer<LandCoverItem>(initLC, "InitialCropland") {
+			@Override
+			public Double getValue(RasterKey location) {
+				LandCoverItem item = results.get(location);
+				if (item == null)
+					return null;
+				return item.getLandCoverFract(LandCoverType.CROPLAND);
+			}
+		}.writeOutput(); */
+
+		RasterSet<LandUseItem> landUseRaster = new RasterSet<LandUseItem>(initialLC.getHeaderDetails());
+		
+		for (Map.Entry<RasterKey, LandCoverItem> entry : initialLC.entrySet()) {
+			LandUseItem areasItem = new LandUseItem();
+			RasterKey key = entry.getKey();
+			LandCoverItem landCover = entry.getValue();
+			areasItem.setLandCoverAreas(landCover);
+			areasItem.setCropFraction(CropType.WHEAT, 0.5); // random start, better if we could get data, but free substitution between crops so not critical
+			areasItem.setCropFraction(CropType.MAIZE, 0.5);
+			areasItem.setProtectedArea(landCover.getProtectedArea());
+			landUseRaster.put(key, areasItem);
+		}
 		
+		return landUseRaster;
 	} 
 
 	private YieldRaster getYieldSurfaces(Timestep timestep) {
diff --git a/src/ac/ed/lurg/country/CountryAgent.java b/src/ac/ed/lurg/country/CountryAgent.java
index 3ceda6a11d99e6a043c81f7600ac6cb25e48293a..5d2773c19468273a9cd0a127c982ea38605b7a23 100644
--- a/src/ac/ed/lurg/country/CountryAgent.java
+++ b/src/ac/ed/lurg/country/CountryAgent.java
@@ -3,22 +3,20 @@ package ac.ed.lurg.country;
 import java.util.HashMap;
 import java.util.Map;
 
+import ac.ed.lurg.ModelConfig;
 import ac.ed.lurg.Timestep;
 import ac.ed.lurg.country.gams.GamsCountryInput;
 import ac.ed.lurg.country.gams.GamsRasterInput;
 import ac.ed.lurg.country.gams.GamsRasterOptimiser;
 import ac.ed.lurg.country.gams.GamsRasterOutput;
-import ac.ed.lurg.country.CountryPrice;
 import ac.ed.lurg.demand.DemandManager;
 import ac.ed.lurg.landuse.CropUsageData;
 import ac.ed.lurg.landuse.IrrigationItem;
-import ac.ed.lurg.landuse.LandCoverItem;
 import ac.ed.lurg.landuse.LandUseItem;
 import ac.ed.lurg.types.CommodityType;
 import ac.ed.lurg.types.CropType;
 import ac.ed.lurg.utils.LogWriter;
 import ac.ed.lurg.yield.YieldRaster;
-import ac.sac.raster.RasterKey;
 import ac.sac.raster.RasterSet;
 
 public class CountryAgent {
@@ -33,33 +31,16 @@ public class CountryAgent {
 	private Map<CropType, CountryPrice> currentCountryPrices;
 	private Map<CropType, Double> tradeBarriers;
 	
-	public CountryAgent(DemandManager demandManager,CompositeCountry country, RasterSet<LandCoverItem> initialLC,
+	public CountryAgent(DemandManager demandManager,CompositeCountry country, RasterSet<LandUseItem> cropAreaRaster,
 			Map<CropType, CropUsageData> cropUsageData, Map<CropType, Double> tradeBarriers) {
 		
 		this.demandManager = demandManager;
 		this.country = country;
-		RasterSet<LandUseItem> cropAreaRaster = convertInitialLC(initialLC);
 		this.tradeBarriers = tradeBarriers;
 		
 		GamsRasterOutput initialData = new GamsRasterOutput(cropAreaRaster, cropUsageData);
 		resultsTimeseries.put(new Timestep(0), initialData);
 	}
-
-	private RasterSet<LandUseItem> convertInitialLC(RasterSet<LandCoverItem> initialLC) {
-		RasterSet<LandUseItem> landUseRaster = new RasterSet<LandUseItem>(initialLC.getHeaderDetails());
-		
-		for (Map.Entry<RasterKey, LandCoverItem> entry : initialLC.entrySet()) {
-			LandUseItem areasItem = new LandUseItem();
-			RasterKey key = entry.getKey();
-			areasItem.setLandCoverAreas(entry.getValue());
-			areasItem.setCropFraction(CropType.WHEAT, 0.5); // random start, better if we could get data, but free substitution between crops so not critical
-			areasItem.setCropFraction(CropType.MAIZE, 0.5);
-			areasItem.setProtectedArea(entry.getValue());
-			landUseRaster.put(key, areasItem);
-		}
-		
-		return landUseRaster;
-	}
 	
 	public CompositeCountry getCountry() {
 		return country;
@@ -101,17 +82,15 @@ public class CountryAgent {
 	private GamsRasterInput getGamsRasterInput(Map<CommodityType, Double> projectedDemand, Map<CropType, CountryPrice> countryPrices, RasterSet<IrrigationItem> irrigData) {
 //TODO why pass in projectedDemand when currentProjectedDemand belongs to CountryAgent class already?
 		GamsRasterOutput prevOutput;
-		boolean calibrate;
 
 		if (currentTimestep.isInitialTimestep()) {  // initialisation time-step
-			calibrate = true;
 			prevOutput = resultsTimeseries.get(currentTimestep);
 		}
 		else { // normal (not the initial) time-step
-			calibrate = false;
 			prevOutput = resultsTimeseries.get(currentTimestep.getPreviousTimestep());
 		}
 		
+		
 		Map<CropType, Double> baseNetImport = new HashMap<CropType, Double>();
 		Map<CropType, Double> maxOfProdOrSupply = new HashMap<CropType, Double>();
 
@@ -122,7 +101,7 @@ public class CountryAgent {
 			maxOfProdOrSupply.put(entry.getKey(), cropUsage.getProduction() + Math.max(netImports, 0));
 		}
 				
-		GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(country, projectedDemand, countryPrices, baseNetImport, maxOfProdOrSupply, calibrate);	
+		GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(country, projectedDemand, countryPrices, baseNetImport, maxOfProdOrSupply);	
 		GamsRasterInput input = new GamsRasterInput(currentTimestep, countryYieldSurfaces, prevOutput.getLandUses(), irrigData, countryLevelInputs);
 
 		return input;
diff --git a/src/ac/ed/lurg/country/GlobalPrice.java b/src/ac/ed/lurg/country/GlobalPrice.java
index 1740fc47b1c7bf874a07034310cc48f0a0914581..364758ae63e60d9e4e654b1652aab80cb2c53335 100644
--- a/src/ac/ed/lurg/country/GlobalPrice.java
+++ b/src/ac/ed/lurg/country/GlobalPrice.java
@@ -34,7 +34,7 @@ public class GlobalPrice {
 		return exportAmount;
 	}
 
-	public GlobalPrice createWithUpdatedMarketPrices(double imports, double exports) {
+	public GlobalPrice createWithUpdatedMarketPrices(double imports, double exports, boolean adjustPrice) {
 		if (imports > 0 || exports > 0) {
 			double ratio;
 
@@ -43,7 +43,7 @@ public class GlobalPrice {
 			else
 				ratio = (imports-exports)/exports;
 
-			double adjustment = ModelConfig.MARKET_ADJ_PRICE ? Math.exp(ratio * ModelConfig.MARKET_LAMBA) : 1.0;
+			double adjustment = adjustPrice ? Math.exp(ratio * ModelConfig.MARKET_LAMBA) : 1.0;
 			return new GlobalPrice(exportPrice * adjustment, imports, exports);
 		}
 		else {
diff --git a/src/ac/ed/lurg/country/gams/GamsCountryInput.java b/src/ac/ed/lurg/country/gams/GamsCountryInput.java
index 2bc1dbd91a610e92feb1b118bc18615a07ae4e6e..93e8fdff35a6920b64989fb1dfd56d0805d63c09 100644
--- a/src/ac/ed/lurg/country/gams/GamsCountryInput.java
+++ b/src/ac/ed/lurg/country/gams/GamsCountryInput.java
@@ -31,9 +31,9 @@ public class GamsCountryInput {
 	}
 	
 	public static GamsCountryInput createInput(CompositeCountry country, Map<CommodityType, Double> projectedDemand, Map<CropType, CountryPrice> countryPrices,
-			Map<CropType, Double> baseNetImport, Map<CropType, Double> maxOfProdOrSupply, boolean calibrateToObserved) {
+			Map<CropType, Double> baseNetImport, Map<CropType, Double> maxOfProdOrSupply) {
 			
-		double allowedImportChange = calibrateToObserved ? 0.0 : ModelConfig.MAX_IMPORT_CHANGE;		
+		double allowedImportChange = ModelConfig.MAX_IMPORT_CHANGE;		
 		Map<CropType, ImportExportConstraint> importConstraints = new HashMap<CropType, ImportExportConstraint>();
 		
 		for (Map.Entry<CropType, Double> entry : baseNetImport.entrySet()) {
diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
index f8862bff36faf0d62d77d8011a90b0c008320ef4..0f3bbd1d682eaa5fc82afa4b5a8bbc47a709ee0c 100644
--- a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
+++ b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
@@ -99,7 +99,7 @@ public class GamsLocationOptimiser {
 			
 			double suitableLand = landUseItem.getSuitableLand();
 			if (DEBUG) LogWriter.println(String.format("  %d   %15s,\t %.1f", locationId, "suitableLand", suitableLand));
-			setGamsParamValue(landP.addRecord(locString), suitableLand, 1);
+			setGamsParamValueTruncate(landP.addRecord(locString), suitableLand, 3);
 			
 			for (CropType cropType : CropType.getNonMeatTypes()) {
 				Vector<String> v = new Vector<String>();
@@ -128,7 +128,7 @@ public class GamsLocationOptimiser {
 				
 				if (DEBUG) LogWriter.println(String.format("  %d   %15s,\t %.2f,\t %.3f,\t %.3f,\t %.3f", locationId, cropType.getGamsName(), area, prevFertI, prevIrrigI, prevOtherI));
 				
-				setGamsParamValue(prevCropP.addRecord(v), area, 2);
+				setGamsParamValue(prevCropP.addRecord(v), area, 3);
 				setGamsParamValue(prevFertIP.addRecord(v), prevFertI, 4);
 				setGamsParamValue(prevIrrigIP.addRecord(v), prevIrrigI, 4);
 				setGamsParamValue(prevOtherIP.addRecord(v), prevOtherI, 4);
@@ -232,12 +232,13 @@ public class GamsLocationOptimiser {
 	}
 
 	private void setGamsParamValue(GAMSParameterRecord param, double val, int places) {
-		param.setValue(roundForGams(val, places));
+		double dOut = Math.round(val * Math.pow(10,places)) / Math.pow(10,places);
+		param.setValue(dOut);
 	}
 	
-	private double roundForGams(double dIn, int places) {
-		double dOut= Math.round(dIn * Math.pow(10,places)) / Math.pow(10,places);
-		return dOut;
+	private void setGamsParamValueTruncate(GAMSParameterRecord param, double val, int places) {
+		double dOut = ((int)(val * Math.pow(10,places))) / Math.pow(10,places);
+		param.setValue(dOut);
 	}
 	
 	@SuppressWarnings("serial")
diff --git a/src/ac/ed/lurg/country/gams/GamsLocationTest.java b/src/ac/ed/lurg/country/gams/GamsLocationTest.java
index acd9873cb202a42c98052a28bfddc1d2e149b96b..9dafdbcb9bafa3363a3332cfdb43f64a497acbd2 100644
--- a/src/ac/ed/lurg/country/gams/GamsLocationTest.java
+++ b/src/ac/ed/lurg/country/gams/GamsLocationTest.java
@@ -23,7 +23,7 @@ public class GamsLocationTest {
 	}
 	
 	private void run() {
-		GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(new CompositeCountry("Test"), getProjectedDemand(), getCountryPrices(), null, null, true);
+		GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(new CompositeCountry("Test"), getProjectedDemand(), getCountryPrices(), null, null);
 		GamsLocationInput gamsInput = new GamsLocationInput(new Timestep(0), getYields(), getPreviousArea(), getIrrigationCosts(), countryLevelInputs);
 		
 		GamsLocationOptimiser opti = new GamsLocationOptimiser(gamsInput);		
diff --git a/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java b/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java
index 6247744729ce65a66780e1b6fa397ec119411290..5cb364badbfc3b6ebb5d32f17c356306e2f3cc1b 100644
--- a/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java
+++ b/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java
@@ -67,6 +67,9 @@ public class GamsRasterOptimiser {
 
 		for (Entry<RasterKey, LandUseItem> entry : toCopy.entrySet()) {
 			LandUseItem newAreasItem = new LandUseItem();
+			if (entry.getValue() == null) {
+				continue;
+			}
 			newAreasItem.setLandCoverAreas(entry.getValue());
 			theCopy.put(entry.getKey(), newAreasItem);
 		}
diff --git a/src/ac/ed/lurg/country/gams/GamsRasterTest.java b/src/ac/ed/lurg/country/gams/GamsRasterTest.java
index 5ac66cc6684e966552878ebd6c5c7abba609d185..995abdebaa27e8adabbd699eb9874eb5f29467e4 100644
--- a/src/ac/ed/lurg/country/gams/GamsRasterTest.java
+++ b/src/ac/ed/lurg/country/gams/GamsRasterTest.java
@@ -18,7 +18,7 @@ public class GamsRasterTest extends GamsLocationTest {
 	}
 	
 	private void run() {
-		GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(new CompositeCountry("Test"), getProjectedDemand(), getCountryPrices(), null, null, true);
+		GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(new CompositeCountry("Test"), getProjectedDemand(), getCountryPrices(), null, null);
 		GamsRasterInput input = new GamsRasterInput(new Timestep(0), getYieldRaster(), getPreviousAreaRaster(), getIrrigationCost(), countryLevelInputs);
 		
 		GamsRasterOptimiser opti = new GamsRasterOptimiser(input);		
diff --git a/src/ac/ed/lurg/landuse/LandCoverItem.java b/src/ac/ed/lurg/landuse/LandCoverItem.java
index 882330fcff945f6a299667060fc7c79307e7eade..47698e4c95f04b2eadf466d65fac9b2f3d81b5b1 100644
--- a/src/ac/ed/lurg/landuse/LandCoverItem.java
+++ b/src/ac/ed/lurg/landuse/LandCoverItem.java
@@ -38,13 +38,12 @@ public class LandCoverItem implements RasterItem {
 		landcover.put(landType, d);
 	}
 	
-	public void setProtectedArea(double proportionProtectedArea){
+	public void setProtectedFract(double proportionProtectedArea){
 		this.proportionProtectedArea=proportionProtectedArea;
 	}
 	
-	
 	public double getProtectedArea(){
-		return proportionProtectedArea;
+		return proportionProtectedArea*totalArea;
 	}
 			
 	/*public double getTotal() {
diff --git a/src/ac/ed/lurg/landuse/LandUseItem.java b/src/ac/ed/lurg/landuse/LandUseItem.java
index 7be97ed8aca74e6cad0d273f9cc4b8b6ac498bdd..41c5a7a64f91ed2111dc6de6405930d04736deb0 100644
--- a/src/ac/ed/lurg/landuse/LandUseItem.java
+++ b/src/ac/ed/lurg/landuse/LandUseItem.java
@@ -19,11 +19,8 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem> {
 	private Map<LandCoverType, Double> landCoverAreas = new HashMap<LandCoverType, Double>();
 	private double protectedArea; //protected area in Mha
 	
-	public void setProtectedArea(LandCoverItem landCover){
-		if (landCover != null) {
-			double areaTotal = this.getTotalLandCoverArea();
-			this.protectedArea = landCover.getProtectedArea()*areaTotal;
-		}
+	public void setProtectedArea(double protectedArea){
+		this.protectedArea = protectedArea;
 	}
 	
 	public double getProtectedArea(){
@@ -175,8 +172,8 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem> {
 	}
 
 	
-	public void setCropFraction(CropType c, double area) {
-		cropFractions.put(c, area);
+	public void setCropFraction(CropType c, double areaFract) {
+		cropFractions.put(c, areaFract);
 	}
 	
 	public double getLandCoverArea(LandCoverType c) {
diff --git a/src/ac/ed/lurg/landuse/LandUseReader.java b/src/ac/ed/lurg/landuse/LandUseReader.java
new file mode 100644
index 0000000000000000000000000000000000000000..1b16615a2e96c089a743bc8452944fcf8e93f625
--- /dev/null
+++ b/src/ac/ed/lurg/landuse/LandUseReader.java
@@ -0,0 +1,41 @@
+package ac.ed.lurg.landuse;
+
+import java.util.Map;
+
+import ac.ed.lurg.types.CropType;
+import ac.ed.lurg.types.LandCoverType;
+import ac.sac.raster.AbstractTabularRasterReader;
+import ac.sac.raster.RasterKey;
+import ac.sac.raster.RasterSet;
+
+public class LandUseReader extends AbstractTabularRasterReader<LandUseItem> {	
+
+	private static final int MIN_COLS = 20;
+
+	public LandUseReader(RasterSet<LandUseItem> landCover) {
+		super(",", MIN_COLS, landCover);
+	}
+
+	@Override
+	protected void setData(RasterKey key, LandUseItem luData, Map<String, Double> rowValues) {
+		
+		for (LandCoverType cover : LandCoverType.values()) {
+			luData.setLandCoverArea(cover, getValueForCol(rowValues, cover.getName()));
+		}
+		
+		luData.setProtectedArea(getValueForCol(rowValues, "protected"));
+
+		for (CropType crop : CropType.getAllItems()) {
+  			double cropFract = getValueForCol(rowValues, crop.getGamsName() + "_A");
+			if (cropFract > 0.0 | CropType.PASTURE.equals(crop)) {
+				luData.setCropFraction(crop, cropFract);
+				double fertI = getValueForCol(rowValues, crop.getGamsName() + "_FI");
+				double irrigI = getValueForCol(rowValues, crop.getGamsName() + "_II");
+				double otherI = getValueForCol(rowValues, crop.getGamsName() + "_OI");
+				Intensity intensity = new Intensity(fertI, irrigI, otherI);
+				luData.setIntensity(crop, intensity);
+			}
+		}
+		
+	}
+}
diff --git a/src/ac/ed/lurg/landuse/ProtectedAreasReader.java b/src/ac/ed/lurg/landuse/ProtectedAreasReader.java
index 6b4aaaa42e539fdd44455bbfa2adb90d26b1488f..d036f47f3bd85a2e30d84e6ca13c71ca37fbb6d3 100644
--- a/src/ac/ed/lurg/landuse/ProtectedAreasReader.java
+++ b/src/ac/ed/lurg/landuse/ProtectedAreasReader.java
@@ -13,7 +13,7 @@ public class ProtectedAreasReader extends AbstractRasterReader<LandCoverItem> {
 	public void setData(LandCoverItem lcData, String token) {
 		if (!"nan".equals(token)) {	
 			double protFrac = Double.parseDouble(token);
-			lcData.setProtectedArea(protFrac);
+			lcData.setProtectedFract(protFrac);
 		}
 	}	
 	
diff --git a/src/ac/ed/lurg/output/LpjgOutputer.java b/src/ac/ed/lurg/output/LpjgOutputer.java
index cb1fd6a86642765454df9f972bd6e700f9b4c996..26de50f3172746487bb6476c9caffa4689bab43f 100644
--- a/src/ac/ed/lurg/output/LpjgOutputer.java
+++ b/src/ac/ed/lurg/output/LpjgOutputer.java
@@ -7,7 +7,6 @@ import java.io.FileWriter;
 import java.io.IOException;
 import java.util.Map.Entry;
 
-import ac.ed.lurg.ModelConfig;
 import ac.ed.lurg.landuse.LandUseItem;
 import ac.ed.lurg.types.CropType;
 import ac.ed.lurg.types.LandCoverType;
@@ -16,34 +15,24 @@ import ac.ed.lurg.yield.YieldRaster;
 import ac.sac.raster.RasterKey;
 import ac.sac.raster.RasterSet;
 
-public class LpjgOutputer {
+public class LpjgOutputer extends AbstractLandUseOutputer {
 
-	private RasterSet<LandUseItem> landUseRaster;
 	private YieldRaster yieldSurfaces;
-	private int year;
 
 	public LpjgOutputer(int year, RasterSet<LandUseItem> landUseRaster, YieldRaster yieldSurfaces) {
-		this.year = year;
-		this.landUseRaster = landUseRaster;
+		super(year, landUseRaster);
 		this.yieldSurfaces = yieldSurfaces;
 	}
 
+	@Override
 	public void writeOutput() {
 		File outputDir = getOutputDir(year);
-
-		writeLandCoverAndCrop(outputDir);
+		writeLandUseFile(outputDir);
 		writeIntensity(outputDir);
 		writeMarkerFile(year, false);
 	}
 
-	private static File getOutputDir(int year) {
-		String outputDirName = ModelConfig.OUTPUT_DIR + File.separator + year;
-		File outputDir = new File(outputDirName);
-		outputDir.mkdirs();
-		return outputDir;
-	}
-
-	private void writeIntensity(File outputDir) {
+	protected void writeIntensity(File outputDir) {
 		BufferedWriter fertWriter = null;
 		BufferedWriter irrigWriter = null;
 
@@ -126,7 +115,7 @@ public class LpjgOutputer {
 		}	
 	}
 
-	public void writeLandCoverAndCrop(File outputDir) {
+	protected void writeLandUseFile(File outputDir) {
 		BufferedWriter landCoverWriter = null;
 		BufferedWriter cropFractWriter = null;