From 6dd506d3d8b0cc35f4fca2a61a9761088046ac8d Mon Sep 17 00:00:00 2001
From: Bart Arendarczyk <s1924442@ed.ac.uk>
Date: Tue, 6 Jun 2023 09:23:18 +0100
Subject: [PATCH] Added unmanaged forest area to outputs.

---
 src/ac/ed/lurg/ModelConfig.java             |  2 +-
 src/ac/ed/lurg/ModelMain.java               | 11 ++++++++---
 src/ac/ed/lurg/landuse/LandCoverItem.java   |  9 +++++++++
 src/ac/ed/lurg/landuse/LandCoverReader.java |  1 +
 src/ac/ed/lurg/landuse/LandUseItem.java     | 21 ++++++++++++++++++++-
 src/ac/ed/lurg/output/LandUseOutputer.java  | 18 +++++++++++-------
 6 files changed, 50 insertions(+), 12 deletions(-)

diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java
index 22a137dc..e157c58e 100755
--- a/src/ac/ed/lurg/ModelConfig.java
+++ b/src/ac/ed/lurg/ModelConfig.java
@@ -590,7 +590,7 @@ public class ModelConfig {
 	public static final int CARBON_WOOD_MAX_TIME = getIntProperty("CARBON_WOOD_MAX_TIME", 160); // upper data limit, years
 	
 	// Carbon
-	public static final boolean IS_CARBON_ON = getBooleanProperty("IS_CARBON_ON", false);
+	public static final boolean IS_CARBON_ON = !IS_CALIBRATION_RUN && getBooleanProperty("IS_CARBON_ON", false);
 	public static final String CARBON_DEMAND_FILENAME = getProperty("CARBON_DEMAND_FILENAME", "carbon_demand.csv");
 	public static final String CARBON_DEMAND_FILE = getProperty("CARBON_DEMAND_FILE", DATA_DIR + File.separator + CARBON_DEMAND_FILENAME);
 	public static final int CARBON_HORIZON = getIntProperty("CARBON_HORIZON", 30); // time period for calculating carbon credits
diff --git a/src/ac/ed/lurg/ModelMain.java b/src/ac/ed/lurg/ModelMain.java
index 72d76eec..844c5e55 100644
--- a/src/ac/ed/lurg/ModelMain.java
+++ b/src/ac/ed/lurg/ModelMain.java
@@ -181,16 +181,21 @@ public class ModelMain {
 
 	private void writeLandCoverFile(Timestep timestep, RasterSet<LandUseItem> landUseRaster) {
 		try {
-			StringBuffer sbHeadings = new StringBuffer("Year,Cropland,Pasture,TimberForest,CarbonForest,Natural,Suitable,EnergyCrop,FertCrop,IrrigCrop,ManIntCrop,ManIntPast");
+			StringBuffer sbHeadings = new StringBuffer("Year,Cropland,Pasture,TimberForest,CarbonForest,UnmanagedForest,OtherNatural,Suitable,EnergyCrop,FertCrop,IrrigCrop,ManIntCrop,ManIntPast");
 			BufferedWriter outputFile = FileWriterHelper.getFileWriter(timestep, ModelConfig.LAND_COVER_OUTPUT_FILE, sbHeadings.toString());
 
+			double naturalArea = LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.NATURAL);
+			double unmanForestArea = LandUseItem.getTotalUnmanagedForestArea(landUseRaster.values());
+			double otherNaturalArea = naturalArea - unmanForestArea;
+
 			StringBuffer sbData = new StringBuffer();
-			sbData.append(String.format("%d,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f", timestep.getYear(),
+			sbData.append(String.format("%d,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f", timestep.getYear(),
 					LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.CROPLAND),
 					LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.PASTURE),
 					LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.TIMBER_FOREST),
 					LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.CARBON_FOREST),
-					LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.NATURAL),
+					unmanForestArea,
+					otherNaturalArea,
 					LandUseItem.getSuitableTotal(landUseRaster.values(), timestep.getYear()))
 					);
 						
diff --git a/src/ac/ed/lurg/landuse/LandCoverItem.java b/src/ac/ed/lurg/landuse/LandCoverItem.java
index 6638bd7f..ae162417 100644
--- a/src/ac/ed/lurg/landuse/LandCoverItem.java
+++ b/src/ac/ed/lurg/landuse/LandCoverItem.java
@@ -22,6 +22,7 @@ public class LandCoverItem implements RasterItem {
 	private double totalArea;
 	private double maxCroplandFraction; // due to slope
 	private double protectedFraction;
+	private double unmanagedForestFraction;
 
 	/** Area in Mha */ 
 	public Double getLandCoverArea(LandCoverType landType) {
@@ -68,6 +69,14 @@ public class LandCoverItem implements RasterItem {
 	public void setProtectedFraction(double protectedFraction) {
 		this.protectedFraction = protectedFraction;
 	}
+
+	public void setUnmanagedForestFraction(double unmanagedForestFraction) {
+		this.unmanagedForestFraction = unmanagedForestFraction;
+	}
+
+	public double getUnmanagedForestFraction() {
+		return unmanagedForestFraction;
+	}
 	
 	public LandCoverTile getLandCoverTiles() {
 		createLandCoverTiles();
diff --git a/src/ac/ed/lurg/landuse/LandCoverReader.java b/src/ac/ed/lurg/landuse/LandCoverReader.java
index 2b0495a5..32b57327 100644
--- a/src/ac/ed/lurg/landuse/LandCoverReader.java
+++ b/src/ac/ed/lurg/landuse/LandCoverReader.java
@@ -27,6 +27,7 @@ public class LandCoverReader extends AbstractTabularRasterReader<LandCoverItem>
 		lcData.setLandCoverFract(LandCoverType.CARBON_FOREST, 0.0); // TODO custom initial timber/carbon forest allocation
 		lcData.setLandCoverFract(LandCoverType.BARREN, getValueForCol(rowValues, "barren"));
 		lcData.setLandCoverFract(LandCoverType.URBAN, getValueForCol(rowValues, "urban"));
+		lcData.setUnmanagedForestFraction(getValueForCol(rowValues, "unmanaged_forest"));
 	}
 	
 	@Override
diff --git a/src/ac/ed/lurg/landuse/LandUseItem.java b/src/ac/ed/lurg/landuse/LandUseItem.java
index 4dda4083..4c44d174 100644
--- a/src/ac/ed/lurg/landuse/LandUseItem.java
+++ b/src/ac/ed/lurg/landuse/LandUseItem.java
@@ -17,9 +17,10 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial
 	private Map<CropType, Double> cropFractions = new HashMap<CropType, Double>();
 	private LandCoverTile landCoverAreas = new LandCoverTile();
 	private Map<LccKey, Double> landCoverChange = new HashMap<LccKey, Double>(); // land cover change for previous timestep
+	private double maxCroplandArea = 0;
 	private double protectedFraction; // protected fraction of total area
+	private double unmanagedForestFraction; // assume constant fraction
 	private double forestRotationIntensity;
-	private double maxCroplandArea = 0;
 	
 	public LandUseItem() {}
 
@@ -32,6 +33,7 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial
 			setMaxCroplandArea(landCover.getMaxCroplandArea());
 			setProtectedFraction(landCover.getProtectedFraction());
 			this.landCoverAreas = (landCover.getLandCoverTiles());
+			this.unmanagedForestFraction = landCover.getUnmanagedForestFraction();
 		} else {
 			maxCroplandArea = getTotalLandArea();
 		}
@@ -46,6 +48,7 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial
 		protectedFraction = (luItemToCopy.protectedFraction);
 		forestRotationIntensity = (luItemToCopy.forestRotationIntensity);
 		maxCroplandArea = (luItemToCopy.maxCroplandArea);
+		unmanagedForestFraction = (luItemToCopy.unmanagedForestFraction);
 	}
 
 	public void overwriteLandCoverAreas(LandCoverTile landCoverAreas) {
@@ -113,6 +116,10 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial
 		return maxCroplandArea;
 	}
 
+	public double getUnmanagedForestFraction() {
+		return unmanagedForestFraction;
+	}
+
 	public double getAreaSuitableForCropland() { // how much land can be converted to cropland
 		if (getLandCoverArea(LandCoverType.CROPLAND) > getMaxCroplandArea()) {
 			LogWriter.printlnWarning("Cropland exceeds maximum area!");
@@ -436,6 +443,18 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial
 		return total;
 	}
 
+	public static double getTotalUnmanagedForestArea(Collection<? extends LandUseItem> landUses) {
+		double total = 0;
+		for (LandUseItem a : landUses) {
+			if (a!=null) {
+				Double d = a.getLandCoverArea(LandCoverType.NATURAL) * a.getUnmanagedForestFraction();
+				if (d!=null)
+					total += d;
+			}
+		}
+		return total;
+	}
+
 	public static double getTotalCropArea(Collection<LandUseItem> landUses, CropType crop) {
 		double total = 0;
 		for (LandUseItem a : landUses)
diff --git a/src/ac/ed/lurg/output/LandUseOutputer.java b/src/ac/ed/lurg/output/LandUseOutputer.java
index 4af83db6..3bdb9d06 100644
--- a/src/ac/ed/lurg/output/LandUseOutputer.java
+++ b/src/ac/ed/lurg/output/LandUseOutputer.java
@@ -30,11 +30,9 @@ public class LandUseOutputer extends AbstractLandUseOutputer {
 			String landCoverFileName = outputDir.getPath() + File.separator + "LandUse.txt";
 			fertWriter = new BufferedWriter(new FileWriter(landCoverFileName, false));
 		
-			StringBuffer sbHeader = new StringBuffer("Lon Lat area suitable protected pa_fraction");
+			StringBuffer sbHeader = new StringBuffer("Lon Lat area suitable protected pa_fraction ");
 			
-			for (LandCoverType cover : LandCoverType.values()) {
-				sbHeader.append(" " + cover.getName());
-			}
+			sbHeader.append(" cropland pasture timberForest carbonForest unmanagedForest otherNatural barren urban");
 			
 			for (CropType crop : CropType.getNonMeatTypes()) {
 				String cropString = crop.getGamsName();
@@ -62,9 +60,15 @@ public class LandUseOutputer extends AbstractLandUseOutputer {
 				sbData.append(String.format(" %.8f", item.getTotalLandArea(LandProtectionType.PROTECTED)));
 				sbData.append(String.format(" %.8f", item.getTotalLandArea(LandProtectionType.PROTECTED)/item.getTotalLandArea()));
 				
-				for (LandCoverType cover : LandCoverType.values()) {
-					sbData.append(String.format(" %.8f", item.getLandCoverArea(cover)));
-				}
+				double unmanForestFract = item.getUnmanagedForestFraction();
+				sbData.append(String.format(" %.8f", item.getLandCoverArea(LandCoverType.CROPLAND)));
+				sbData.append(String.format(" %.8f", item.getLandCoverArea(LandCoverType.PASTURE)));
+				sbData.append(String.format(" %.8f", item.getLandCoverArea(LandCoverType.TIMBER_FOREST)));
+				sbData.append(String.format(" %.8f", item.getLandCoverArea(LandCoverType.CARBON_FOREST)));
+				sbData.append(String.format(" %.8f", item.getLandCoverArea(LandCoverType.NATURAL) * unmanForestFract)); // unmanagedForest
+				sbData.append(String.format(" %.8f", item.getLandCoverArea(LandCoverType.NATURAL) * (1 - unmanForestFract))); // otherNatural
+				sbData.append(String.format(" %.8f", item.getLandCoverArea(LandCoverType.BARREN)));
+				sbData.append(String.format(" %.8f", item.getLandCoverArea(LandCoverType.URBAN)));
 
 				for (CropType crop : CropType.getNonMeatTypes()) {
 					double cropFract = item.getCropFraction(crop);
-- 
GitLab