[Xulu-commits] r74 - in branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model: . mrv sleuth

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Thu Feb 4 18:20:11 CET 2010


Author: mojays
Date: 2010-02-04 18:19:03 +0100 (Thu, 04 Feb 2010)
New Revision: 74

Added:
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/mrv/
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/mrv/MultipleResolutionValidation.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/mrv/MultipleResolutionValidationContentManager.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/CopyUrbanInActualLU.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/CopyUrbanInActualLUContentManager.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/MultipleResolutionValidation.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/MultipleResolutionValidationContentManager.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthContentManager.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModel.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibration.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationContentManager.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationSelfModification.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationSelfModificationContentManager.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelContentManager.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModification.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModificationContentManager.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModifying.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModifyingContentManager.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModel_MC.java
   branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModel_MC_ContentManager.java
Log:
- schmitzm-JAR updated to version 2.0-RC2
- models "MRV" and "SLEUTH" added

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/mrv/MultipleResolutionValidation.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/mrv/MultipleResolutionValidation.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/mrv/MultipleResolutionValidation.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,319 @@
+package edu.bonn.xulu.plugin.model.mrv;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ListProperty;
+import schmitzm.data.property.ListPropertyWriteAccess;
+import schmitzm.data.property.PropertyReadAccess;
+import schmitzm.data.property.PropertyWriteAccess;
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.model.AbstractStepModel;
+import edu.bonn.xulu.model.XuluModel;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+/**
+ * <b>MULTIPLE RESOLUTION COMPARISON</b><br>
+ * The Multiple Resolution Comparison is a Xulu-plugin that can be used in order to validate modelling results.
+ * In general, the Multiple Resolution Comparison is a method to quantify the agreement between two maps, 
+ * whereby it averages neighbouring pixels of both maps into coarser pixels in order to quantify the agreement between maps at coarser resolutions.
+ * The percent correct tends to rise at coarser resolutions, because it reduces the effect of error due to location. By comparing the results with 
+ * a Multiple Resolution Comparison of a NULL-Model (no change has taken place between t1 and t2), the NULL-Resolution can be identified,
+ * which indicates the resolution at which the modelling result is more accurate than the NULL-Model.<br>
+ * For details refer to:<br>
+ * <i>Costanza,R. (1989)</i>: Model Goodness of Fit - A Multiple Resolution Procedure. In: Ecological Modelling, vol. 47, no. 3-4, pp. 199-215.<br>
+ * <i>Pontius Jr, R.G. (2002)</i>: Statistical Methods to Partition Effects of Quantity and Location During Comparison of Categorical Maps at Multiple Resolutions. 
+ * In: Photogrammetric Engineering &amp; Remote Sensing, vol. 68, no. 10,  pp. 1041-1049.<br>
+ * <i>Pontius Jr, R.G., Huffaker, D. &amp; K. Denman (2004)</i>: Useful Techniques of Validation for Spatially Explicit Land-Change Models. 
+ * In: Ecological Modelling, vol. 179, no. 4, pp. 445-461.<br>
+ * 
+ * The following input parameters/images are required:<br>
+ * <ul>
+ *  <li><b>Number of Steps ({@code steps})</b>: Because this plugin is built as a step model, the number of (time) steps always has to be 1.</li>
+ *  <li><b>Reference Map ({@code referenceMap})</b>: A raster containing the reference (observed) land cover.</li>
+ *  <li><b>Simulation Map ({@code simulationMap})</b>: A raster containing the simulated land cover.</li>
+ * </ul>
+ * 
+ * Furthermore the following outputs are created:<br>
+ * <ul>
+ *  <li><b>Actual Validation (@code actualValidation)</b>: A raster containing the actual resolution grid with the fraction correct in every cell</li>
+ *  <li><b>Out Step ({@code outStep})</b>: A Grid List containing a grid (Actual Validation) for every resolution.</li>
+ *  <li><b>Out Results ({@code outResults})</b>: A list containing the total agreement for every resolution.</li>
+ * </ul>
+ * 
+ * Other important values are written to the status output window!<br>
+ * 
+ * @see MultipleResolutionValidationContentManager
+ * @author <a href="mailto:goetzke at uni-bonn.de">Roland Goetzke</a>
+ * @version 1.0
+ *
+ */
+public class MultipleResolutionValidation extends AbstractStepModel {
+
+	/**
+	 * Contains the actual pixel size (from 1 to n, with n being one coarse cell that contains the whole study area).
+	 * During the MRV it is subsequently aggregated in a geometric progression as a multiple of 2.
+	 */
+	private int neighborhoodRange = 0;
+	
+	/** Array containing the fraction correct for every resolution. */
+	private float[][] resultArray;
+	
+	/**
+	 * Saves the ContentManager for the model.
+	 * 
+	 * @see MultipleResolutionValidationContentManager
+	 */
+	protected MultipleResolutionValidationContentManager contManager;
+
+	// ********** Read/Write access, that has to be maintained ***
+	// ********** through the whole model run ********************
+	private PropertyReadAccess RA_steps = null;	//Number of Steps
+	private PropertyReadAccess RA_referenceMap = null; // Reference Map
+	private PropertyReadAccess RA_simulationMap = null;	//Simulation Map
+	private PropertyWriteAccess WA_actualValidation = null; // Output Grid
+	private PropertyWriteAccess WA_outStep = null;	// Step Results
+	private ListPropertyWriteAccess WA_outResults = null;	//Output Validation Results
+
+	// **************** Variables to work with *******************
+	private PropertyReadAccess steps = null; // Number of steps
+	private WritableGrid referenceMap = null; // Reference Map
+	private WritableGrid simulationMap = null;	// Simulation Map
+	private WritableGrid actualValidation = null; // Output Grid
+	private MultiGrid outStep = null;	//Step Results
+	private ListPropertyWriteAccess outResults = null;	//Output Validation Results
+
+
+	/**
+	 * Creates a new model instance.
+	 */
+	public MultipleResolutionValidation() {
+		super(new MultipleResolutionValidationContentManager());
+		this.contManager = (MultipleResolutionValidationContentManager) super.contManager;
+	}
+
+	
+	/**
+	 * Initializes the model. Like in the init method of every {@link XuluModel}
+	 * the resources are initalized. 
+	 */
+	public void performModelInit() {
+		if (contManager == null)
+			return;
+		// Get access authorisation of resource/properties
+		RA_steps = null;
+		if (contManager.getResource(0).getData() != null)
+			RA_steps = ((ScalarProperty) contManager.getResource(0).getData())
+					.getReadAccess(this);
+		RA_referenceMap = null;
+		if (contManager.getResource(1).getData() != null)
+			RA_referenceMap = ((ScalarProperty) contManager.getResource(1)
+					.getData()).getReadAccess(this);
+		RA_simulationMap = null;
+		if (contManager.getResource(2).getData() != null)
+			RA_simulationMap = ((ScalarProperty) contManager.getResource(2)
+					.getData()).getReadAccess(this);
+		WA_actualValidation = null;
+		if (contManager.getResource(3).getData() != null)
+			WA_actualValidation = ((ScalarProperty) contManager.getResource(3)
+					.getData()).getWriteAccess(this);
+		WA_outResults = null;
+		if (contManager.getResource(5).getData() != null)
+			WA_outResults = ((ListProperty) contManager.getResource(5)
+					.getData()).getWriteAccess(this);
+
+		//Assign variables to work with
+		steps = RA_steps;
+		referenceMap = (WritableGrid) RA_referenceMap.getValue();
+		simulationMap = (WritableGrid) RA_simulationMap.getValue();
+		actualValidation = (WritableGrid) WA_actualValidation.getValue();
+
+		this.stepCount = steps.getValueAsInt();
+		outStep = (MultiGrid)contManager.getResource(4).getData();
+		outResults = WA_outResults;
+	}
+
+	/**
+	* like in every model: frees the resources
+	 */
+	public void performModelDispose() {
+
+		// free resources
+		releaseAccess(RA_steps);
+		releaseAccess(RA_referenceMap);
+		releaseAccess(RA_simulationMap);
+		releaseAccess(WA_actualValidation);
+		releaseAccess(WA_outStep);
+		releaseAccess(WA_outResults);
+	}
+
+	/**
+	 * Performs the MRV. The function is implemented as a Xulu Step Model, but actually does not need any time steps. So
+	 * the stepNo MUST always be 1. The steps of the coarsening procedure are defined inside of the function. When using a 
+	 * MRV parameter file simply use 1 for the number of steps.
+	 */
+	public void performModelStep(int stepNo) {
+		
+		statusOut.println("Starting step " + stepNo + "...");
+		
+		int RoverallSum = 0; //Total number of pixels in Reference Map
+		int RnumClasses = 0; //Total number of classes in Reference Map
+		int SoverallSum = 0; //Total number of pixels in Simulation Map
+		int SnumClasses = 0; //Total number of classes in Simulation Map
+		int correct = 0;	//Number of pixels counted correct
+		double fractionCorrect = 0f;	//Fraction correct
+		long localStartTime = System.currentTimeMillis(); //current Start Time
+		int numSteps = 0;
+		
+		neighborhoodRange = (int) Math.sqrt(referenceMap.getWidth()*referenceMap.getHeight()); //maximum possible pixel size
+		numSteps = (int) ((int)1+ Math.floor(Math.log(neighborhoodRange)/Math.log(2)));	//calculates how many steps are needed by doubling the pixel size until neighborhoodRange is reached. It is the reverse of an exponential function, which is the logarithm of neighborhoodRange to the basis 2. 2 is added because the calculation starts with 1 and not with 2 (1,2,4,8,16,32,...) and an array starts with 0.
+		statusOut.println("Maximum pixel size (as multiple of original resolution): "+neighborhoodRange);
+		statusOut.println("Number of steps: "+numSteps);
+		resultArray = new float[2][1+numSteps];
+		
+		//Calculation of the fraction correct for the original Resolution
+		for (int x = 0; x < referenceMap.getWidth(); x++)
+			for (int y = 0; y < referenceMap.getHeight(); y++) {
+				float Rtmp = referenceMap.getRasterSampleAsFloat(x, y); //get value of each raster cell in reference map
+				float Stmp = simulationMap.getRasterSampleAsFloat(x, y);//get value of each raster cell in simulation map
+				if (!Float.isNaN(Rtmp) && !Float.isNaN(Stmp)){	//if the value is a number, continue ...
+					RoverallSum ++;		//count all cells in reference map
+					SoverallSum ++;		//count all cells in simulation map
+					if (Rtmp > RnumClasses)
+						RnumClasses = (int) Rtmp;	//Number of classes in reference map. If a higher cell value is detected than the actual RnumClasses, the number of classes is increased to that value
+					if (Stmp > SnumClasses)
+						SnumClasses = (int) Stmp;	//see RnumClasses
+					if (Rtmp == Stmp)
+						correct++;		//if the same cell value is detected in the simulation and the reference map, increase the number of correct pixels
+				}
+		}
+		fractionCorrect = (double) correct / (double) RoverallSum;	//divide the number of correct pixels by the number of total pixels
+
+		//Counts pixels per class
+		for (int i = 1; i <= RnumClasses; i++){		//Loop, until you reach the total number of classes
+			int Rj = 0;		//Number of classes in Reference Map
+			int Sj = 0;		//Number of classes in Simulation Map
+			for (int x = 0; x < referenceMap.getWidth(); x++)
+				for (int y = 0; y < referenceMap.getHeight(); y++){
+					float Rtmp = referenceMap.getRasterSampleAsFloat(x, y);	//get value of each raster cell in reference map
+					float Stmp = simulationMap.getRasterSampleAsFloat(x, y);//get value of each raster cell in simulation map
+					if (!Float.isNaN(Rtmp))
+						if ((int) Rtmp == i)
+							Rj++;	//if cell belongs to category i, count it (for Reference map)
+					if (!Float.isNaN(Stmp))
+						if ((int) Stmp == i)
+							Sj++;	//if cell belongs to category i, count it (for Simulation map)
+				}
+			statusOut.println("Class "+i+": Reference("+Rj+"), Simulation("+Sj+")");
+		}
+		
+		int ngrids = 0;		//number of resolution grids
+		float Vg = 0f;	//sum of the individual cell weights for the calculation of the average weighted fit after Pontius (2002)
+		float VgWeights = 0f;	//sum of the cell weights
+		float WeightedAgreement = 0f;	//total weighted agreement over all resolutions after Pontius (2002)
+		for (int r = 1; r <= neighborhoodRange; r = r+r){	//for pixel size 1 up to the maximum pixel size, where one large cell covers the whole area
+			statusOut.println(r);
+			ngrids++;		//count the number of grids
+			outStep.addGrid();	//add a grid to the outStep Output GridList
+			float SumWn = 0f;	//Sum of the weighted means 
+			int SumCells = 0;	//Number of the cells
+			float totalAgreement = 0f;	//total agreement is the weighted mean of the fraction correct over all resolution grids
+			for (int x = 0; x < referenceMap.getWidth(); x = x+r)	//for every pixel size...
+				for (int y = 0; y < referenceMap.getHeight(); y = y+r){
+					int nCells = 0;		//number of cells making up a coarse cell
+					float SumMinRS = 0f;	//when two maps are compared, the minimum value is taken (MIN), this value is the sum of all these MINs
+					float Wn = 0;	//weighted cell
+					for(int x2 = x; x2 < x+r; x2++)	//for every cell within a coarse cell...
+						for(int y2 = y; y2 < y+r; y2++){
+							if ( x2 < referenceMap.getMinX() || y2 < referenceMap.getMinY() || x2 > referenceMap.getMinX()+referenceMap.getWidth()-1 || y2 > referenceMap.getMinY()+referenceMap.getHeight()-1 ||
+									Float.isNaN(referenceMap.getRasterSampleAsFloat(x2,y2)))
+								continue;
+							nCells++;	//count all cells that have a value
+						}
+					for (int i = 0; i <= RnumClasses; i++){	//for every class i
+						int Rn = 0;		//Number of cells in the reference map
+						int Sn = 0;		//Number of cells in the simulation map
+						float Rnj = 0f;	//Portion of cells in the reference map
+						float Snj = 0f;	//Portion of cells in the simulation map
+						float MinRS = 0f;	//Both maps are compared and the Minimum (MIN) for each cell taken
+						for(int x3 = x; x3 < x+r; x3++)	//for every cell within a coarse cell...
+							for(int y3 = y; y3 < y+r; y3++){
+								if ( x3 < referenceMap.getMinX() || y3 < referenceMap.getMinY() || x3 > referenceMap.getMinX()+referenceMap.getWidth()-1 || y3 > referenceMap.getMinY()+referenceMap.getHeight()-1 ||
+										Float.isNaN(referenceMap.getRasterSampleAsFloat(x3,y3)))
+									continue;
+								float Rtmp = referenceMap.getRasterSampleAsFloat(x3, y3);	//get value of each cell in the reference map
+								float Stmp = simulationMap.getRasterSampleAsFloat(x3, y3);	//get value of each cell in the simulation map
+								if ((int) Rtmp == i)
+									Rn++;	//count all cells that belong to class i in reference map 
+								if ((int) Stmp == i)
+									Sn++;	//count all cells that belong to class i in simulation map
+							}
+						if(nCells > 0){	//if positive cells are available...
+							Rnj = (float)Rn / (float)nCells;	//compute the portion of these cells within a coarse cell in the reference map
+							Snj = (float)Sn / (float)nCells;	//compute the portion of these cells within a coarse cell in the simulation map
+						}
+						MinRS = Math.min(Rnj, Snj);	//take for every coarse cell the MIN between R and S of the portion of class i
+						SumMinRS += MinRS;	//Sum all the MIN values
+						
+					}
+					Wn = (float)nCells * SumMinRS;	//all coarse cells are weighted by multiplying the Sum of all MIN values with the number of cells that make up a coarse cell
+					 
+					//Compute output maps
+					float WnCell = 0f;
+					for(int x4 = x; x4 < x+r; x4++)	//for every cell within a coarse cell...
+						for(int y4 = y; y4 < y+r; y4++){
+							if ( x4 < referenceMap.getMinX() || y4 < referenceMap.getMinY() || x4 > referenceMap.getMinX()+referenceMap.getWidth()-1 || y4 > referenceMap.getMinY()+referenceMap.getHeight()-1 ||
+									Float.isNaN(referenceMap.getRasterSampleAsFloat(x4,y4)))
+								continue;
+							WnCell = Wn / (float)nCells; //divide the weighted sum of the MIN values by the number of positive cells
+							actualValidation.setRasterSample( WnCell ,x4 ,y4);	//for every pixel in the Actual Comparison Grid take this value
+							outStep.getGrid(ngrids-1).setRasterSample(WnCell,x4,y4);	//and write the same grid into the Output Grid List
+						}
+				
+					SumCells += (float)nCells;	//Sum all positive cells in a resolution grid
+					SumWn += Wn;	//Sum all weighted portions in a resolution grid
+				}
+			
+			//Total Agreement:
+			statusOut.println(SumWn+" / "+SumCells);
+			totalAgreement = SumWn / (float)SumCells;	//Main Results
+			statusOut.println(totalAgreement);	
+			outResults.addValue(totalAgreement);
+			resultArray[0][ngrids] = r;
+			resultArray[1][ngrids] = totalAgreement;	//write the results in an array 
+			//the result array looks like this:
+			//1	   |2	 |4	   |8    |...
+			//0.876|0.892|0.913|0.948|...
+			Vg += SumWn * totalAgreement;
+			VgWeights += SumWn;
+		}
+		
+		//From here on the results of the Multiple Resolution Comparison are written on the screen
+		
+		//those variables are needed to compute the weighted average of all fits after Costanza (1989)
+		float w = 0f;	//weight depending on resolution
+		float Fw = 0f;	//weighted fit at certain resolution
+		float SumW = 0f;	//Sum of all weights
+		float SumFw = 0f;	//Sum of all weighted agreements
+		float Ft = 0f;
+		
+		for(int i = 1; i <= ngrids; i++){
+			//print every element of the result array comma separated in one line in the status output
+			System.out.print(resultArray[1][i]+",");
+			//calculations for weighted average after Costanza (1989):
+			w = (float) Math.exp(-0.1*(resultArray[0][i] - 1));
+			Fw = resultArray[1][i]*w;
+			SumW += w;
+			SumFw += Fw;
+		}
+		
+		Ft = SumFw / SumW;	//Final calculation of the weighted average of all fits after Costanza (1989)
+		WeightedAgreement = Vg / VgWeights;	//Final calculation of the weighted average of all fits after Pontius (2002)
+		System.out.print("Ft:"+Ft+",TA:"+WeightedAgreement);	//the result is written directly behind the single fits for every resolution
+		
+		System.out.println("");
+		System.out.print("Finished step " + (stepNo) + " in "
+				+ ((System.currentTimeMillis() - localStartTime)) + " ms");
+		localStartTime = System.currentTimeMillis();
+		System.out.println(" with sum (local calculated): " + RoverallSum);
+		
+	}
+}

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/mrv/MultipleResolutionValidationContentManager.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/mrv/MultipleResolutionValidationContentManager.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/mrv/MultipleResolutionValidationContentManager.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,42 @@
+package edu.bonn.xulu.plugin.model.mrv;
+
+import edu.bonn.xulu.model.AbstractModelContentManager;
+import edu.bonn.xulu.model.DefaultModelResource;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+import edu.bonn.xulu.plugin.model.clue.ClueModelContentManager;
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ListProperty;
+import schmitzm.data.property.ScalarProperty;
+
+
+/**
+ * This class defines and handles the resources for the Xulu-Model {@link MultipleResolutionValidation}
+ * 
+ * @see ClueModelContentManager
+ * @see AverageNeighborhoodContentManager
+ * @author <a href="mailto:goetzke at uni-bonn.de">Roland Goetzke</a>
+ * @version 1.0
+ */
+public class MultipleResolutionValidationContentManager extends AbstractModelContentManager {
+
+  /**
+   * Creates a new ContentManager for the Model {@linkplain MultipleResolutionValidation}.
+   */
+  public MultipleResolutionValidationContentManager() {
+    super(6);
+    // Steps
+    resource[0]	= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Number of steps",ScalarProperty.class,Integer.class,false);
+    // Reference Map
+    resource[1] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Reference Map",ScalarProperty.class,WritableGrid.class,false);
+    // Simulation Map
+    resource[2] = new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Simulation Map",ScalarProperty.class,WritableGrid.class,false);
+    // Actual Validation
+    resource[3]	= new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Actual Validation",ScalarProperty.class,WritableGrid.class,false);
+    // Map for every Resolution
+    resource[4]	= new DefaultModelResource(ModelResource.CATEGORY_OUTPUT,"Step Results",MultiGrid.class,false);
+    // Output Values
+    resource[5]	= new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Validation Results",ListProperty.class,Double.class,false);
+  }
+}

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/CopyUrbanInActualLU.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/CopyUrbanInActualLU.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/CopyUrbanInActualLU.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,94 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.PropertyReadAccess;
+import schmitzm.data.property.PropertyWriteAccess;
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.model.AbstractStepModel;
+import appl.util.RasterUtil;
+
+public class CopyUrbanInActualLU extends AbstractStepModel {
+
+	
+	protected CopyUrbanInActualLUContentManager contManager;
+	
+	private PropertyReadAccess RA_ActualLuMap = null; 
+	private PropertyReadAccess RA_ActualUrbanMap = null;
+	private PropertyWriteAccess WA_ActualUrbanMap = null; // Output Grid
+	private PropertyReadAccess RA_UrbanLUClass = null;
+	
+	private WritableGrid ActualLuMap = null; 
+	private WritableGrid ActualUrbanMap = null;
+	private PropertyReadAccess UrbanLUClass = null;
+	
+	protected int	step = 0;
+	
+	public CopyUrbanInActualLU() {
+		super(new CopyUrbanInActualLUContentManager());
+		this.contManager = (CopyUrbanInActualLUContentManager) super.contManager;
+	}
+
+	@Override
+	public void performModelInit() {
+		// TODO Auto-generated method stub
+		if (contManager == null)
+			return;
+		RA_ActualLuMap = null;
+		if (contManager.getResource(0).getData() != null)
+			RA_ActualLuMap = ((ScalarProperty) contManager.getResource(0)
+					.getData()).getReadAccess(this);
+		RA_ActualUrbanMap = null;
+		if (contManager.getResource(1).getData() != null)
+			RA_ActualUrbanMap = ((ScalarProperty) contManager.getResource(1)
+					.getData()).getReadAccess(this);
+		WA_ActualUrbanMap = null;
+		if (contManager.getResource(1).getData() != null)
+			WA_ActualUrbanMap = ((ScalarProperty) contManager.getResource(1)
+					.getData()).getWriteAccess(this);
+		RA_UrbanLUClass = null;
+		if (contManager.getResource(2).getData() != null)
+			RA_UrbanLUClass = ((ScalarProperty) contManager.getResource(2).getData())
+					.getReadAccess(this);
+		
+		ActualLuMap = (WritableGrid) RA_ActualLuMap.getValue();
+		ActualUrbanMap = (WritableGrid) RA_ActualUrbanMap.getValue();
+		UrbanLUClass = RA_UrbanLUClass;
+		this.stepCount = 1;
+	}
+	
+	@Override
+	public void performModelDispose() {
+		// TODO Auto-generated method stub
+		releaseAccess(RA_ActualLuMap);
+		releaseAccess(RA_ActualUrbanMap);
+		releaseAccess(WA_ActualUrbanMap);
+	}
+	
+	
+	@Override
+	public void performModelStep(int stepNo) {
+		// TODO Auto-generated method stub
+		statusOut.println("Starting Copy ...");
+		
+		boolean[][] tmpGrid = new boolean[ActualLuMap.getWidth()][ActualLuMap.getHeight()];
+		
+		for (int x = 0; x < ActualLuMap.getWidth(); x++)
+			for (int y = 0; y < ActualLuMap.getHeight(); y++) {
+				float LU = ActualLuMap.getRasterSampleAsFloat(x, y);
+				float Urban = ActualUrbanMap.getRasterSampleAsFloat(x, y);
+				if (!Float.isNaN(LU) && !Float.isNaN(Urban)){
+					if ((int)Urban == 1){
+						tmpGrid[x][y] = true;
+						ActualLuMap.setRasterSample( tmpGrid[x][y] ? 1f : 0f ,x ,y);
+						}
+						
+					}	
+				}
+		
+		statusOut.println("Copy finished.");
+	}
+
+	
+
+	
+}
\ No newline at end of file

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/CopyUrbanInActualLUContentManager.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/CopyUrbanInActualLUContentManager.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/CopyUrbanInActualLUContentManager.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,26 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.model.AbstractModelContentManager;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+
+public class CopyUrbanInActualLUContentManager extends AbstractModelContentManager {
+
+	  /**
+	   * Erzeugt einen neuen ContentManager fuer das Modell {@linkplain AverageNeighborhoodParallelDemoModel}.
+	   */
+	  public CopyUrbanInActualLUContentManager() {
+
+		  super(3);
+		    // ActualLU (CLUE-S)
+		    resource[0]	= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"ActualLU",ScalarProperty.class,WritableGrid.class,false);
+		    // ActualUrban (UGM)
+		    resource[1] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"ActualUrban",ScalarProperty.class,WritableGrid.class,false);
+		    // Urban LU Class
+		    resource[2] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"UrbanLUClass",ScalarProperty.class,Integer.class,false);
+	  }  
+
+}
+	  
\ No newline at end of file

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/MultipleResolutionValidation.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/MultipleResolutionValidation.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/MultipleResolutionValidation.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,319 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ListProperty;
+import schmitzm.data.property.ListPropertyWriteAccess;
+import schmitzm.data.property.PropertyReadAccess;
+import schmitzm.data.property.PropertyWriteAccess;
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.model.AbstractStepModel;
+import edu.bonn.xulu.model.XuluModel;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+/**
+ * <b>MULTIPLE RESOLUTION COMPARISON</b><br>
+ * The Multiple Resolution Comparison is a Xulu-plugin that can be used in order to validate modelling results.
+ * In general, the Multiple Resolution Comparison is a method to quantify the agreement between two maps, 
+ * whereby it averages neighbouring pixels of both maps into coarser pixels in order to quantify the agreement between maps at coarser resolutions.
+ * The percent correct tends to rise at coarser resolutions, because it reduces the effect of error due to location. By comparing the results with 
+ * a Multiple Resolution Comparison of a NULL-Model (no change has taken place between t1 and t2), the NULL-Resolution can be identified,
+ * which indicates the resolution at which the modelling result is more accurate than the NULL-Model.<br>
+ * For details refer to:<br>
+ * <i>Costanza,R. (1989)</i>: Model Goodness of Fit - A Multiple Resolution Procedure. In: Ecological Modelling, vol. 47, no. 3-4, pp. 199-215.<br>
+ * <i>Pontius Jr, R.G. (2002)</i>: Statistical Methods to Partition Effects of Quantity and Location During Comparison of Categorical Maps at Multiple Resolutions. 
+ * In: Photogrammetric Engineering &amp; Remote Sensing, vol. 68, no. 10,  pp. 1041-1049.<br>
+ * <i>Pontius Jr, R.G., Huffaker, D. &amp; K. Denman (2004)</i>: Useful Techniques of Validation for Spatially Explicit Land-Change Models. 
+ * In: Ecological Modelling, vol. 179, no. 4, pp. 445-461.<br>
+ * 
+ * The following input parameters/images are required:<br>
+ * <ul>
+ *  <li><b>Number of Steps ({@code steps})</b>: Because this plugin is built as a step model, the number of (time) steps always has to be 1.</li>
+ *  <li><b>Reference Map ({@code referenceMap})</b>: A raster containing the reference (observed) land cover.</li>
+ *  <li><b>Simulation Map ({@code simulationMap})</b>: A raster containing the simulated land cover.</li>
+ * </ul>
+ * 
+ * Furthermore the following outputs are created:<br>
+ * <ul>
+ *  <li><b>Actual Validation (@code actualValidation)</b>: A raster containing the actual resolution grid with the fraction correct in every cell</li>
+ *  <li><b>Out Step ({@code outStep})</b>: A Grid List containing a grid (Actual Validation) for every resolution.</li>
+ *  <li><b>Out Results ({@code outResults})</b>: A list containing the total agreement for every resolution.</li>
+ * </ul>
+ * 
+ * Other important values are written to the status output window!<br>
+ * 
+ * @see MultipleResolutionValidationContentManager
+ * @author <a href="mailto:goetzke at uni-bonn.de">Roland Goetzke</a>
+ * @version 1.0
+ *
+ */
+public class MultipleResolutionValidation extends AbstractStepModel {
+
+	/**
+	 * Contains the actual pixel size (from 1 to n, with n being one coarse cell that contains the whole study area).
+	 * During the MRV it is subsequently aggregated in a geometric progression as a multiple of 2.
+	 */
+	private int neighborhoodRange = 0;
+	
+	/** Array containing the fraction correct for every resolution. */
+	private float[][] resultArray;
+	
+	/**
+	 * Saves the ContentManager for the model.
+	 * 
+	 * @see MultipleResolutionValidationContentManager
+	 */
+	protected MultipleResolutionValidationContentManager contManager;
+
+	// ********** Read/Write access, that has to be maintained ***
+	// ********** through the whole model run ********************
+	private PropertyReadAccess RA_steps = null;	//Number of Steps
+	private PropertyReadAccess RA_referenceMap = null; // Reference Map
+	private PropertyReadAccess RA_simulationMap = null;	//Simulation Map
+	private PropertyWriteAccess WA_actualValidation = null; // Output Grid
+	private PropertyWriteAccess WA_outStep = null;	// Step Results
+	private ListPropertyWriteAccess WA_outResults = null;	//Output Validation Results
+
+	// **************** Variables to work with *******************
+	private PropertyReadAccess steps = null; // Number of steps
+	private WritableGrid referenceMap = null; // Reference Map
+	private WritableGrid simulationMap = null;	// Simulation Map
+	private WritableGrid actualValidation = null; // Output Grid
+	private MultiGrid outStep = null;	//Step Results
+	private ListPropertyWriteAccess outResults = null;	//Output Validation Results
+
+
+	/**
+	 * Creates a new model instance.
+	 */
+	public MultipleResolutionValidation() {
+		super(new MultipleResolutionValidationContentManager());
+		this.contManager = (MultipleResolutionValidationContentManager) super.contManager;
+	}
+
+	
+	/**
+	 * Initializes the model. Like in the init method of every {@link XuluModel}
+	 * the resources are initalized. 
+	 */
+	public void performModelInit() {
+		if (contManager == null)
+			return;
+		// Get access authorisation of resource/properties
+		RA_steps = null;
+		if (contManager.getResource(0).getData() != null)
+			RA_steps = ((ScalarProperty) contManager.getResource(0).getData())
+					.getReadAccess(this);
+		RA_referenceMap = null;
+		if (contManager.getResource(1).getData() != null)
+			RA_referenceMap = ((ScalarProperty) contManager.getResource(1)
+					.getData()).getReadAccess(this);
+		RA_simulationMap = null;
+		if (contManager.getResource(2).getData() != null)
+			RA_simulationMap = ((ScalarProperty) contManager.getResource(2)
+					.getData()).getReadAccess(this);
+		WA_actualValidation = null;
+		if (contManager.getResource(3).getData() != null)
+			WA_actualValidation = ((ScalarProperty) contManager.getResource(3)
+					.getData()).getWriteAccess(this);
+		WA_outResults = null;
+		if (contManager.getResource(5).getData() != null)
+			WA_outResults = ((ListProperty) contManager.getResource(5)
+					.getData()).getWriteAccess(this);
+
+		//Assign variables to work with
+		steps = RA_steps;
+		referenceMap = (WritableGrid) RA_referenceMap.getValue();
+		simulationMap = (WritableGrid) RA_simulationMap.getValue();
+		actualValidation = (WritableGrid) WA_actualValidation.getValue();
+
+		this.stepCount = steps.getValueAsInt();
+		outStep = (MultiGrid)contManager.getResource(4).getData();
+		outResults = WA_outResults;
+	}
+
+	/**
+	* like in every model: frees the resources
+	 */
+	public void performModelDispose() {
+
+		// free resources
+		releaseAccess(RA_steps);
+		releaseAccess(RA_referenceMap);
+		releaseAccess(RA_simulationMap);
+		releaseAccess(WA_actualValidation);
+		releaseAccess(WA_outStep);
+		releaseAccess(WA_outResults);
+	}
+
+	/**
+	 * Performs the MRV. The function is implemented as a Xulu Step Model, but actually does not need any time steps. So
+	 * the stepNo MUST always be 1. The steps of the coarsening procedure are defined inside of the function. When using a 
+	 * MRV parameter file simply use 1 for the number of steps.
+	 */
+	public void performModelStep(int stepNo) {
+		
+		statusOut.println("Starting step " + stepNo + "...");
+		
+		int RoverallSum = 0; //Total number of pixels in Reference Map
+		int RnumClasses = 0; //Total number of classes in Reference Map
+		int SoverallSum = 0; //Total number of pixels in Simulation Map
+		int SnumClasses = 0; //Total number of classes in Simulation Map
+		int correct = 0;	//Number of pixels counted correct
+		double fractionCorrect = 0f;	//Fraction correct
+		long localStartTime = System.currentTimeMillis(); //current Start Time
+		int numSteps = 0;
+		
+		neighborhoodRange = (int) Math.sqrt(referenceMap.getWidth()*referenceMap.getHeight()); //maximum possible pixel size
+		numSteps = (int) ((int)1+ Math.floor(Math.log(neighborhoodRange)/Math.log(2)));	//calculates how many steps are needed by doubling the pixel size until neighborhoodRange is reached. It is the reverse of an exponential function, which is the logarithm of neighborhoodRange to the basis 2. 2 is added because the calculation starts with 1 and not with 2 (1,2,4,8,16,32,...) and an array starts with 0.
+		statusOut.println("Maximum pixel size (as multiple of original resolution): "+neighborhoodRange);
+		statusOut.println("Number of steps: "+numSteps);
+		resultArray = new float[2][1+numSteps];
+		
+		//Calculation of the fraction correct for the original Resolution
+		for (int x = 0; x < referenceMap.getWidth(); x++)
+			for (int y = 0; y < referenceMap.getHeight(); y++) {
+				float Rtmp = referenceMap.getRasterSampleAsFloat(x, y); //get value of each raster cell in reference map
+				float Stmp = simulationMap.getRasterSampleAsFloat(x, y);//get value of each raster cell in simulation map
+				if (!Float.isNaN(Rtmp) && !Float.isNaN(Stmp)){	//if the value is a number, continue ...
+					RoverallSum ++;		//count all cells in reference map
+					SoverallSum ++;		//count all cells in simulation map
+					if (Rtmp > RnumClasses)
+						RnumClasses = (int) Rtmp;	//Number of classes in reference map. If a higher cell value is detected than the actual RnumClasses, the number of classes is increased to that value
+					if (Stmp > SnumClasses)
+						SnumClasses = (int) Stmp;	//see RnumClasses
+					if (Rtmp == Stmp)
+						correct++;		//if the same cell value is detected in the simulation and the reference map, increase the number of correct pixels
+				}
+		}
+		fractionCorrect = (double) correct / (double) RoverallSum;	//divide the number of correct pixels by the number of total pixels
+
+		//Counts pixels per class
+		for (int i = 1; i <= RnumClasses; i++){		//Loop, until you reach the total number of classes
+			int Rj = 0;		//Number of classes in Reference Map
+			int Sj = 0;		//Number of classes in Simulation Map
+			for (int x = 0; x < referenceMap.getWidth(); x++)
+				for (int y = 0; y < referenceMap.getHeight(); y++){
+					float Rtmp = referenceMap.getRasterSampleAsFloat(x, y);	//get value of each raster cell in reference map
+					float Stmp = simulationMap.getRasterSampleAsFloat(x, y);//get value of each raster cell in simulation map
+					if (!Float.isNaN(Rtmp))
+						if ((int) Rtmp == i)
+							Rj++;	//if cell belongs to category i, count it (for Reference map)
+					if (!Float.isNaN(Stmp))
+						if ((int) Stmp == i)
+							Sj++;	//if cell belongs to category i, count it (for Simulation map)
+				}
+			statusOut.println("Klasse "+i+": Referenz("+Rj+"), Simulation("+Sj+")");
+		}
+		
+		int ngrids = 0;		//number of resolution grids
+		float Vg = 0f;	//sum of the individual cell weights for the calculation of the average weighted fit after Pontius (2002)
+		float VgWeights = 0f;	//sum of the cell weights
+		float WeightedAgreement = 0f;	//total weighted agreement over all resolutions after Pontius (2002)
+		for (int r = 1; r <= neighborhoodRange; r = r+r){	//for pixel size 1 up to the maximum pixel size, where one large cell covers the whole area
+			statusOut.println(r);
+			ngrids++;		//count the number of grids
+			outStep.addGrid();	//add a grid to the outStep Output GridList
+			float SumWn = 0f;	//Sum of the weighted means 
+			int SumCells = 0;	//Number of the cells
+			float totalAgreement = 0f;	//total agreement is the weighted mean of the fraction correct over all resolution grids
+			for (int x = 0; x < referenceMap.getWidth(); x = x+r)	//for every pixel size...
+				for (int y = 0; y < referenceMap.getHeight(); y = y+r){
+					int nCells = 0;		//number of cells making up a coarse cell
+					float SumMinRS = 0f;	//when two maps are compared, the minimum value is taken (MIN), this value is the sum of all these MINs
+					float Wn = 0;	//weighted cell
+					for(int x2 = x; x2 < x+r; x2++)	//for every cell within a coarse cell...
+						for(int y2 = y; y2 < y+r; y2++){
+							if ( x2 < referenceMap.getMinX() || y2 < referenceMap.getMinY() || x2 > referenceMap.getMinX()+referenceMap.getWidth()-1 || y2 > referenceMap.getMinY()+referenceMap.getHeight()-1 ||
+									Float.isNaN(referenceMap.getRasterSampleAsFloat(x2,y2)))
+								continue;
+							nCells++;	//count all cells that have a value
+						}
+					for (int i = 0; i <= RnumClasses; i++){	//for every class i
+						int Rn = 0;		//Number of cells in the reference map
+						int Sn = 0;		//Number of cells in the simulation map
+						float Rnj = 0f;	//Portion of cells in the reference map
+						float Snj = 0f;	//Portion of cells in the simulation map
+						float MinRS = 0f;	//Both maps are compared and the Minimum (MIN) for each cell taken
+						for(int x3 = x; x3 < x+r; x3++)	//for every cell within a coarse cell...
+							for(int y3 = y; y3 < y+r; y3++){
+								if ( x3 < referenceMap.getMinX() || y3 < referenceMap.getMinY() || x3 > referenceMap.getMinX()+referenceMap.getWidth()-1 || y3 > referenceMap.getMinY()+referenceMap.getHeight()-1 ||
+										Float.isNaN(referenceMap.getRasterSampleAsFloat(x3,y3)))
+									continue;
+								float Rtmp = referenceMap.getRasterSampleAsFloat(x3, y3);	//get value of each cell in the reference map
+								float Stmp = simulationMap.getRasterSampleAsFloat(x3, y3);	//get value of each cell in the simulation map
+								if ((int) Rtmp == i)
+									Rn++;	//count all cells that belong to class i in reference map 
+								if ((int) Stmp == i)
+									Sn++;	//count all cells that belong to class i in simulation map
+							}
+						if(nCells > 0){	//if positive cells are available...
+							Rnj = (float)Rn / (float)nCells;	//compute the portion of these cells within a coarse cell in the reference map
+							Snj = (float)Sn / (float)nCells;	//compute the portion of these cells within a coarse cell in the simulation map
+						}
+						MinRS = Math.min(Rnj, Snj);	//take for every coarse cell the MIN between R and S of the portion of class i
+						SumMinRS += MinRS;	//Sum all the MIN values
+						
+					}
+					Wn = (float)nCells * SumMinRS;	//all coarse cells are weighted by multiplying the Sum of all MIN values with the number of cells that make up a coarse cell
+					 
+					//Compute output maps
+					float WnCell = 0f;
+					for(int x4 = x; x4 < x+r; x4++)	//for every cell within a coarse cell...
+						for(int y4 = y; y4 < y+r; y4++){
+							if ( x4 < referenceMap.getMinX() || y4 < referenceMap.getMinY() || x4 > referenceMap.getMinX()+referenceMap.getWidth()-1 || y4 > referenceMap.getMinY()+referenceMap.getHeight()-1 ||
+									Float.isNaN(referenceMap.getRasterSampleAsFloat(x4,y4)))
+								continue;
+							WnCell = Wn / (float)nCells; //divide the weighted sum of the MIN values by the number of positive cells
+							actualValidation.setRasterSample( WnCell ,x4 ,y4);	//for every pixel in the Actual Comparison Grid take this value
+							outStep.getGrid(ngrids-1).setRasterSample(WnCell,x4,y4);	//and write the same grid into the Output Grid List
+						}
+				
+					SumCells += (float)nCells;	//Sum all positive cells in a resolution grid
+					SumWn += Wn;	//Sum all weighted portions in a resolution grid
+				}
+			
+			//Total Agreement:
+			statusOut.println(SumWn+" / "+SumCells);
+			totalAgreement = SumWn / (float)SumCells;	//Main Results
+			statusOut.println(totalAgreement);	
+			outResults.addValue(totalAgreement);
+			resultArray[0][ngrids] = r;
+			resultArray[1][ngrids] = totalAgreement;	//write the results in an array 
+			//the result array looks like this:
+			//1	   |2	 |4	   |8    |...
+			//0.876|0.892|0.913|0.948|...
+			Vg += SumWn * totalAgreement;
+			VgWeights += SumWn;
+		}
+		
+		//From here on the results of the Multiple Resolution Comparison are written on the screen
+		
+		//those variables are needed to compute the weighted average of all fits after Costanza (1989)
+		float w = 0f;	//weight depending on resolution
+		float Fw = 0f;	//weighted fit at certain resolution
+		float SumW = 0f;	//Sum of all weights
+		float SumFw = 0f;	//Sum of all weighted agreements
+		float Ft = 0f;
+		
+		for(int i = 1; i <= ngrids; i++){
+			//print every element of the result array comma separated in one line in the status output
+			System.out.print(resultArray[1][i]+",");
+			//calculations for weighted average after Costanza (1989):
+			w = (float) Math.exp(-0.1*(resultArray[0][i] - 1));
+			Fw = resultArray[1][i]*w;
+			SumW += w;
+			SumFw += Fw;
+		}
+		
+		Ft = SumFw / SumW;	//Final calculation of the weighted average of all fits after Costanza (1989)
+		WeightedAgreement = Vg / VgWeights;	//Final calculation of the weighted average of all fits after Pontius (2002)
+		System.out.print("Ft:"+Ft+",TA:"+WeightedAgreement);	//the result is written directly behind the single fits for every resolution
+		
+		System.out.println("");
+		System.out.print("Finished step " + (stepNo) + " in "
+				+ ((System.currentTimeMillis() - localStartTime)) + " ms");
+		localStartTime = System.currentTimeMillis();
+		System.out.println(" with sum (local calculated): " + RoverallSum);
+		
+	}
+}

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/MultipleResolutionValidationContentManager.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/MultipleResolutionValidationContentManager.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/MultipleResolutionValidationContentManager.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,42 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import edu.bonn.xulu.model.AbstractModelContentManager;
+import edu.bonn.xulu.model.DefaultModelResource;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+import edu.bonn.xulu.plugin.model.clue.ClueModelContentManager;
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ListProperty;
+import schmitzm.data.property.ScalarProperty;
+
+
+/**
+ * This class defines and handles the resources for the Xulu-Model {@link MultipleResolutionValidation}
+ * 
+ * @see ClueModelContentManager
+ * @see AverageNeighborhoodContentManager
+ * @author <a href="mailto:goetzke at uni-bonn.de">Roland Goetzke</a>
+ * @version 1.0
+ */
+public class MultipleResolutionValidationContentManager extends AbstractModelContentManager {
+
+  /**
+   * Creates a new ContentManager for the Model {@linkplain MultipleResolutionValidation}.
+   */
+  public MultipleResolutionValidationContentManager() {
+    super(6);
+    // Steps
+    resource[0]	= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Number of steps",ScalarProperty.class,Integer.class,false);
+    // Reference Map
+    resource[1] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Reference Map",ScalarProperty.class,WritableGrid.class,false);
+    // Simulation Map
+    resource[2] = new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Simulation Map",ScalarProperty.class,WritableGrid.class,false);
+    // Actual Validation
+    resource[3]	= new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Actual Validation",ScalarProperty.class,WritableGrid.class,false);
+    // Map for every Resolution
+    resource[4]	= new DefaultModelResource(ModelResource.CATEGORY_OUTPUT,"Step Results",MultiGrid.class,false);
+    // Output Values
+    resource[5]	= new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Validation Results",ListProperty.class,Double.class,false);
+  }
+}

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthContentManager.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthContentManager.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthContentManager.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,37 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import edu.bonn.xulu.model.AbstractModelContentManager;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+import edu.bonn.xulu.plugin.model.clue.ClueModelContentManager;
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ScalarProperty;
+
+
+/**
+ * This class defines and handle the three resources for the models
+ * <ol> 
+ * <li><b> </li>
+ * <li><b> {@link AverageNeighborhoodSerialDemoModel}</b></li>
+ * <li><b> {@link AverageNeighborhoodParallelDemoModel}</b></li>
+ * <li><b> {@link AVNTuned}</b></li>
+ * </ol>
+ * @see ClueModelContentManager
+ * @author automatically generated using {@link edu.bonn.xulu.plugin.appl.GeoModelCodeGenerator}
+ * @version 1.0
+ */
+public class UrbanGrowthContentManager extends AbstractModelContentManager {
+
+  /**
+   * Erzeugt einen neuen ContentManager fuer das Modell {@linkplain AverageNeighborhoodParallelDemoModel}.
+   */
+  public UrbanGrowthContentManager() {
+    super(3);
+    // Input Grid
+    resource[0] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Input Grid",ScalarProperty.class,WritableGrid.class,false);
+    // Output Grid
+    resource[1] = new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Output Grid",ScalarProperty.class,WritableGrid.class,false);
+    // Number of steps
+    resource[2] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Number of steps",ScalarProperty.class,Integer.class,false);
+  }
+}

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModel.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModel.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModel.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,947 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import java.util.HashMap;
+
+import edu.bonn.xulu.model.AbstractStepModel;
+import edu.bonn.xulu.model.XuluModel;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.PropertyReadAccess;
+import schmitzm.data.property.PropertyWriteAccess;
+import schmitzm.data.property.ScalarProperty;
+
+/**
+ *  <b>Urban Growth Model</b><br>
+ *  This Model simulates urban growth. It is based on the algorithm of the SLEUTH-Model, which has originally been written in C code and could
+ *  be run under UNIX. The SLEUTH-Model has been developed by Keith Clarke at the UC Santa Barbara, CA, within the Gigalopolis Project, funded by the
+ *  USGS. Therefore it is under public domain. The name SLEUTH has been derived from the image input requirements of the model:
+ *  Slope, Land cover, Exclusion, Urbanization, Transportation, and Hillshade.<br>
+ *  In the original SLEUTH-Model the core Urban Growth Model (UGM) calls and drives an additional land cover deltatron model (LCD). Both models are
+ *  tightly coupled, but the UGM can be run separately. Here, only the UGM part of the SLEUTH-Model has been translated into JAVA. Minor changes
+ *  in the code have been necessary. Those changes are explained within the code. In general, the UGM is a Cellular Automaton (CA). All CA elements 
+ *  in the code have been untouched and are the same as in the original UGM.<br>
+ *  This is the basic UGM code, a plain Cellular Automaton. Additional functions are implemented in other models, like:<br>
+ *  <ul>
+ *   <li><b>UGM MonteCarlo ({@link UrbanGrowthModel_MC UrbanGrowthModel_MC})</b>: The same model algorithm like this, but with Monte Carlo Iterations. The resulting map shows the probabilities for new urbanization (@link MultipleResolutionValidation MultipleResolutionValidation)</li>
+ *   <li><b>UGM Calibration ({@link UrbanGrowthModelCalibration UrbanGrowthModelCalibration})</b>: The same model algorithm like this, but in order to calibrate the model by finding the correct parameter values with the method of Multiple Resolution Comparison (@link MultipleResolutionValidation)</li>
+ *   <li><b>UGM SelfModifying({@link UrbanGrowthModelSelfModification UrbanGrowthModelSelfModifying})</b>: The same model algorithm like this, but with the possibility of self-modification of the parameter values.</li>
+ *   <li><b>UGM CalibrationSelfModifying({@link UrbanGrowthModelCalibrationSelfModification UrbanGrowthModelCalibrationSelfModification})</b>: The same model algorithm like this, but in order to calibrate the model by finding the correct parameter values with the method of Multiple Resolution Comparison (@link MultipleResolutionValidation)
+ *    While calibrating the model modifies the parameter values.</li>
+ *  </ul>
+ *  <br>
+ *  The original SLEUTH-Model can be downloaded via the <a href="http://www.ncgia.ucsb.edu/projects/gig/">Gigalopolis Website</a>. To run it, a
+ *  UNIX environment with the GNU C compiler (gcc) are required.<br>
+ *  For details refer to:<br>
+ *  <i>Clarke, K.C., Hoppen, S. & L.J. Gaydos (1997)</i>: A self-modifying cellular automaton model of historical urbanization in the San Francisco Bay area.
+ *  In: Environment and Planning B: Planning and Design, vol. 24, pp. 247-261.<br>
+ *  <i>Clarke, K.C. & L.J. Gaydos (1998)</i>: Loose-coupling a cellular automaton model and GIS: long-term urban growth prediction for San Francisco
+ *  and Washington/Baltimore. In: International Journal of Geographical Information Science, vol. 12, no. 7, pp. 699-714.<br>
+ *  <i>Jantz, C.A., Goetz, S.J. & M.K. Shelley (2003)</i>: Using the SLEUTH urban growth model to simulate the impacts of future policy scenarios
+ *  on urban land use in the Baltimore-Washington metropolitan area. In: Environment and Planning B: Planning and Design, vol: 30, pp. 251-271.<br>
+ *  
+ *  <br>
+ *  The following input parameters/images are required:<br>
+ * <ul>
+ *  <li><b>Input Grid ({@code inputGrid})</b>: A grid containing the input (initial) urban land cover.</li>
+ *  <li><b>Area Restriction ({@code areaRestr})</b>: A grid containing the area restrictions (e.g. water, natural reserves, areas with lower probability, etc.).</li>
+ *  <li><b>Transportation Grid ({@code roadGrid})</b>: A grid containing the road network.</li>
+ *  <li><b>Slope Grid ({@code slopeGrid})</b>: A grid containing the slope.</li>
+ *  <li><b>Number of steps ({@code steps})</b>: The number of time steps to compute.</li>
+ *  <li><b>Spread ({@code spread})</b>: The Spread-Coefficient.</li>
+ *  <li><b>Disp ({@code disp})</b>: The Dispersion(Diffusion)-Coefficient.</li>
+ *  <li><b>Breed ({@code breed})</b>: The Breed-Coefficient.</li>
+ *  <li><b>Road Gravity ({@code roadGravity})</b>: The Road Gravity-Coefficient.</li>
+ *  <li><b>Slope ({@code slope})</b>: The Slope-Coefficient.</li>
+ *  <li><b>Critical Slope ({@code criticalSlope})</b>: The Percentage at which urbanization on steep slopes is not possible.</li>
+ * </ul>
+ * 
+ * <br>
+ * Furthermore the following outputs are created:<br>
+ * <ul>
+ *  <li><b>Output Grid ({@code outputGrid})</b>: A grid containing the output, that is actualized in every time step.</li>
+ *  <li><b>outStep ({@code outStep})</b>: A Grid List containing the results for every time step.</li>
+ * </ul>
+ * 
+ * @see UrbanGrowthModelContentManager
+ * @author <a href="mailto:goetzke at uni-bonn.de">Roland Goetzke</a>
+ * @version 1.0
+ */
+public class UrbanGrowthModel extends AbstractStepModel {
+
+	/**
+	 * Saves the ContentManager for the model.
+	 * 
+	 * @see UrbanGrowthModelContentManager
+	 */
+	//protected UrbanGrowthModelContentManager contManager;
+
+	// ********** Read/Write access, that has to be maintained ***
+	// ********** through the whole model run ********************
+	protected PropertyReadAccess RA_steps = null; // Number of steps
+	protected PropertyReadAccess RA_inputGrid = null; // Input Grid
+	protected PropertyWriteAccess WA_outputGrid = null; // Output Grid
+	protected PropertyReadAccess RA_areaRestr = null; //Area Restrictions
+	protected PropertyReadAccess RA_roadGrid = null;	//Road Grid
+	protected PropertyReadAccess RA_slopeGrid = null;	//Slope Grid
+	protected PropertyReadAccess RA_spread = null;	//Spread-Koeffizient
+	protected PropertyReadAccess RA_disp = null;		//Dispersions-Koeffizient
+	protected PropertyReadAccess RA_breed = null;		//Breed-Koeffizient
+	protected PropertyReadAccess RA_roadGravity = null;	//Road-Gravity-Koeffizient
+	protected PropertyReadAccess RA_slope = null;	//Slope-Koeffizient
+	protected PropertyReadAccess RA_criticalSlope = null;	//Critical Slope Value
+	protected PropertyWriteAccess WA_outStep = null;	// Step Results
+
+	// **************** Variables to work with *******************
+	protected PropertyReadAccess steps = null; // Number of steps
+	protected WritableGrid inputGrid = null; // Input Grid
+	protected WritableGrid outputGrid = null; // Output Grid
+	protected WritableGrid areaRestr = null; //Area Restrictions
+	protected WritableGrid roadGrid = null;	//Road Grid
+	protected WritableGrid slopeGrid = null;	//Slope Grid
+	protected double spread = 0;	//Spread-Koeffizient
+	protected double disp = 0;	//Dispersions-Koeffizient
+	protected double breed = 0;	//Breed-Koeffizient
+	protected double roadGravity = 0;	//Road-Gravity-Koeffizient
+	protected double slope = 0;	//Slope-Koeffizient
+	protected double criticalSlope = 0;	//Critical Slope Value
+	protected MultiGrid outStep = null;	//Step Results
+		
+	/**
+	 * Moore Neighborhood as a two dimensional array. It's the central element of a Cellular Automaton.
+	 */
+	protected  static final int[][] NEIGHBOR = new int[][] {
+	      {-1,-1}, {0,-1}, {1,-1},
+	      {-1, 0},         {1, 0},
+	      {-1, 1}, {0, 1}, {1, 1}
+	  };
+	
+	/**
+	 * A Lookup-Table which relates actual slope values to slope coefficient influenced probabilities.
+	 */
+	protected  HashMap<Number,Number> slopeLUT;
+	
+	protected int areaMinX = 0;
+	protected int areaMinY = 0;
+	protected int areaMaxX = 0;
+	protected int areaMaxY = 0;
+	protected int areaWidth = 0;
+	protected int areaHeight = 0;
+	
+	protected double disp_value = 0;	//Dispersion Value
+	protected double max_RG_value = 0;	//Maximum RoadGravity Value
+	protected double rg_value = 0;		//RoadGravity Value
+	protected double max_search_index = 0;	//Maximum search index for road
+	
+	/**
+	 * Creates a new model instance.
+	 */
+	public UrbanGrowthModel(UrbanGrowthModelContentManager contManager) {
+		super(contManager);
+		this.contManager = (UrbanGrowthModelContentManager) super.contManager;
+	}
+	
+	public UrbanGrowthModel(){
+		super(new UrbanGrowthModelContentManager());
+	}
+
+	
+	/**
+	 * Initializes the model. Like in the init method of every {@link XuluModel}
+	 * the resources are initalized. 
+	 */
+	public void performModelInit() {
+		
+		if (contManager == null)
+			return;
+		// Get access authorisation of resource/properties
+		RA_steps = null;
+		if (contManager.getResource(0).getData() != null)
+			RA_steps = ((ScalarProperty) contManager.getResource(0).getData())
+					.getReadAccess(this);
+		RA_inputGrid = null;
+		if (contManager.getResource(1).getData() != null)
+			RA_inputGrid = ((ScalarProperty) contManager.getResource(1)
+					.getData()).getReadAccess(this);
+		WA_outputGrid = null;
+		if (contManager.getResource(2).getData() != null)
+			WA_outputGrid = ((ScalarProperty) contManager.getResource(2)
+					.getData()).getWriteAccess(this);
+		RA_areaRestr = null;
+		if (contManager.getResource(3).getData() != null)
+			RA_areaRestr = ((ScalarProperty) contManager.getResource(3)
+					.getData()).getReadAccess(this);
+		RA_roadGrid = null;
+		if (contManager.getResource(4).getData() != null)
+			RA_roadGrid = ((ScalarProperty) contManager.getResource(4)
+					.getData()).getReadAccess(this);
+		RA_slopeGrid = null;
+		if (contManager.getResource(5).getData() != null)
+			RA_slopeGrid = ((ScalarProperty) contManager.getResource(5)
+					.getData()).getReadAccess(this);
+		RA_spread = null;
+		if (contManager.getResource(6).getData() != null)
+			RA_spread = ((ScalarProperty) contManager.getResource(6).getData())
+					.getReadAccess(this);
+		RA_disp = null;
+		if (contManager.getResource(7).getData() != null)
+			RA_disp = ((ScalarProperty) contManager.getResource(7).getData())
+					.getReadAccess(this);
+		RA_breed = null;
+		if (contManager.getResource(8).getData() != null)
+			RA_breed = ((ScalarProperty) contManager.getResource(8).getData())
+					.getReadAccess(this);
+		RA_roadGravity = null;
+		if (contManager.getResource(9).getData() != null)
+			RA_roadGravity = ((ScalarProperty) contManager.getResource(9).getData())
+					.getReadAccess(this);
+		RA_slope = null;
+		if (contManager.getResource(10).getData() != null)
+			RA_slope = ((ScalarProperty) contManager.getResource(10).getData())
+					.getReadAccess(this);
+		RA_criticalSlope = null;
+		if (contManager.getResource(11).getData() != null)
+			RA_criticalSlope = ((ScalarProperty) contManager.getResource(11).getData())
+					.getReadAccess(this);
+
+		// Assign variables to work with
+		inputGrid = (WritableGrid) RA_inputGrid.getValue();
+		outputGrid = (WritableGrid) WA_outputGrid.getValue();
+		steps = RA_steps;
+		this.stepCount = steps.getValueAsInt();
+		areaRestr = (WritableGrid) RA_areaRestr.getValue();
+	    spread  = RA_spread.getValueAsDouble();
+	    disp	= RA_disp.getValueAsDouble();
+	    breed	= RA_breed.getValueAsDouble();
+	    roadGravity = RA_roadGravity.getValueAsDouble();
+	    slope	= RA_slope.getValueAsDouble();
+	    criticalSlope = RA_criticalSlope.getValueAsDouble();
+	    roadGrid = (WritableGrid) RA_roadGrid.getValue();
+	    slopeGrid = (WritableGrid) RA_slopeGrid.getValue();
+	    outStep = (MultiGrid)contManager.getResource(12).getData();
+	    
+	    //count the number of starting individuals
+	    int startAnz = 0;
+		startAnz = countSetIndividuals();
+		
+		statusOut.println("Number of starting cells: "+startAnz);
+		statusOut.println("Neighborhood size: "+NEIGHBOR.length);
+		
+		//calculate the maximum slope
+		int slopeMax = 0;
+		slopeMax = getSlopeMax();
+		
+		statusOut.println("Max. Slope: "+slopeMax+" %");
+				
+		//Creates a new Lookup-table
+		//slopeLUT = new HashMap<Number,Number>();
+		
+		//assigns for every slope value between 0 and the maximum slope that is below the critical slope the value calculated for the variable "lookup".
+		//all values higher than the critical slope become 1
+
+		int MaxSlopeResistance = 0;
+		MaxSlopeResistance = 100;	//Max slope resistance is 100%
+		
+		double exp = getSlopeExp(slope,MaxSlopeResistance);
+		slopeLUT = getSlopeLookup(slopeMax,exp,criticalSlope);
+		
+		//raster dimensions
+		areaMinX = inputGrid.getMinX();
+		areaMinY = inputGrid.getMinY();
+		areaMaxX = inputGrid.getMinX() + inputGrid.getWidth() - 1;
+		areaMaxY = inputGrid.getMinY() + inputGrid.getHeight() - 1;
+		areaWidth = inputGrid.getWidth();
+		areaHeight = inputGrid.getHeight();
+		
+		//coefficient calculations of for growth rules
+		disp_value = Math.round((disp*0.005)* Math.sqrt(Math.pow(inputGrid.getWidth(), 2)+(Math.pow(inputGrid.getHeight(), 2))));	//Dispersion value (Number of cells to select spontaneously)
+		statusOut.println("Dispersion-Value: "+disp_value);
+		max_RG_value = 100.0;			//Maximum possible road gravity value
+		rg_value = Math.round((roadGravity/max_RG_value)*((areaWidth + areaHeight)/16)); 	//calculation of the road gravity value
+		statusOut.println("RoadGravity-Value: "+rg_value);
+		max_search_index = Math.round(4*((int)rg_value*(1+(int)rg_value)));	//area in which to look for a road cell
+		statusOut.println("MaxSearchIndex: "+max_search_index);
+		
+		//outputGrid = inputGrid;
+	}
+
+	/**
+	* like in every model: frees the resources
+	 */
+	public void performModelDispose() {
+
+		// free resources
+		releaseAccess(RA_steps);
+		releaseAccess(RA_inputGrid);
+		releaseAccess(WA_outputGrid);
+		releaseAccess(RA_areaRestr);
+		releaseAccess(RA_spread);
+		releaseAccess(RA_disp);
+		releaseAccess(RA_breed);
+		releaseAccess(RA_roadGravity);
+		releaseAccess(RA_slope);
+		releaseAccess(RA_criticalSlope);
+		releaseAccess(RA_roadGrid);
+		releaseAccess(RA_slopeGrid);
+		releaseAccess(WA_outStep);
+	}
+	
+	/**
+	 * This is the main run of the Urban Growth Model. Depending on the input parameters the cellular automaton looks in the neighborhood of individual cells for specific conditions
+	 * and turns them from non-urban into urban, following certain growth rules. Those growth rules are:<br>
+	 *  <ol>
+	 *   <li><b>spontaneous growth</b>: controlled by dispersion (@code disp): Randomly selects potential new growth cells.</li>
+	 *   <li><b>new spreading centers</b>: controlled by breed (@code breed): Growing urban centers from spontaneous growth.</li>
+	 *   <li><b>edge</b>: controlled by spread (@code spread): Old or new urban centers spawn additional growth.</li>
+	 *   <li><b>road influenced</b>: controlled by road-gravity(@code roadGravity), dispersion (@code disp), breed (@code breed): Newly urbanized cell spawns growth along transportation network.</li>
+	 *  </ol>
+	 * @exception IllegalArgumentException 
+	 * @param stepNo
+	 */
+	public void performModelStep(int stepNo) {
+		
+		statusOut.println("Starting step " + stepNo + "...");
+		
+		//time measure
+		long localStartTime = System.currentTimeMillis();
+		
+		//cells to be created
+		boolean[][] tmpGrid = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+		Float actUrb = null;	//urban cell in the raster
+
+	
+		/*****************************************************************
+		 * DISPERSION and BREED (Growth Phase 1 and 2)
+		 *****************************************************************/
+		boolean[][] tmpGridDisp = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+		tmpGridDisp = DispersionGrowth(disp_value,breed);	//calls the method "DispersionBreed" to perform the Dispersion and Breed Growth Phase
+		int anzDispBreed = 0;	//number of cells urbanized by Dispersion and Breed
+		for (int x = 0; x < inputGrid.getWidth();x++)
+			for(int y = 0; y < inputGrid.getHeight();y++){
+				int X = inputGrid.getMinX() + x;
+				int Y = inputGrid.getMinY() + y;
+				if (tmpGridDisp[X][Y]==true){
+					anzDispBreed++;
+					tmpGrid[X][Y] = true;	//write the temporary Dispersion and Breed Cells to the overall temporary Cell array
+				}		
+			}
+		statusOut.println("Number of Spontaneous and New Spreading Center Cells: "+anzDispBreed);
+		writeToGrid(tmpGrid);	//calls the method "writeToGrid" to write the new urbanized cells to the output grid
+		
+				
+		/*********************************************************************
+		 * EDGE
+		 *********************************************************************/
+		boolean[][] tmpGridSpread = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+		tmpGridSpread = EdgeGrowth(spread);	//calls the method "EdgeGrowth" to perform the Spread (Edge Growth) Phase
+		int anzSpread = 0;	//number of cells urbanized by Spread
+		for (int x = 0; x < inputGrid.getWidth();x++)
+			for(int y = 0; y < inputGrid.getHeight();y++){
+				int X = inputGrid.getMinX() + x;
+				int Y = inputGrid.getMinY() + y;
+				if (tmpGridSpread[X][Y]==true){
+					anzSpread++;
+					tmpGrid[X][Y] = true;	//write the temporary Spread cells to the overall temporary Cell array
+				}		
+			}
+		statusOut.println("Number of Edge Growth Cells: "+anzSpread);
+		writeToGrid(tmpGrid);	//calls the method "writeToGrid" to write the new urbanized cells to the output grid
+	
+		/*********************************************************************
+		 * ROAD
+		 *********************************************************************/
+		boolean[][] tmpGridRoad = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+		tmpGridRoad = RoadGrowth(tmpGrid,rg_value,breed,disp);	//calls the method "RoadGrowth" to perform the Road weighted growth
+		int anzRoad = 0;	//number of cells urbanized by Road Growth
+		for (int x = 0; x < inputGrid.getWidth();x++)
+			for(int y = 0; y < inputGrid.getHeight();y++){
+				int X = inputGrid.getMinX() + x;
+				int Y = inputGrid.getMinY() + y;
+				if (tmpGridRoad[X][Y]==true){
+					anzRoad++;
+					tmpGrid[X][Y] = true;	//write the temporary Road Growth cells to the overall temporary Cell array
+				}		
+			}
+		statusOut.println("Number of Road Growth Cells: "+anzRoad);
+		writeToGrid(tmpGrid);	//calls the method "writeToGrid" to write the new urbanized cells to the output grid
+		
+		
+		outStep.addGrid();
+		int anzGesamt = 0;
+		
+		// Write the temporary Grid to the Output Grid
+		for (int y = 1; y < inputGrid.getHeight()-1;y++ ) {
+			for (int x = 1; x < inputGrid.getWidth()-1; x++ ) {
+				
+				int X = inputGrid.getMinX() + x;
+				int Y = inputGrid.getMinY() + y;
+				
+				if (tmpGrid[x][y] == true)
+					anzGesamt++;
+				
+				boolean lebt = outputGrid.getRasterSampleAsFloat(X , Y ) > 0f;	//a cell is alive, when it is 1
+				if (tmpGrid[x][y] == false)	//if there is nothing in the temporary raster
+					tmpGrid[x][y] = lebt;	//take the values from the current output raster
+				
+
+				outputGrid.setRasterSample( tmpGrid[x][y] ? 1f : 0f ,X ,Y);	//write the results in the output raster
+				actUrb  = (Float)outputGrid.getRasterSample(x,y);	//the actual urban extent
+				outStep.getGrid(stepNo-1).setRasterSample(actUrb,x,y);	//put the layer in the raster list containing the step results
+			}
+		}
+		
+		statusOut.println("Urban pixels at step "+stepNo+": "+anzGesamt);
+	
+		System.out.println("Finished step " + (stepNo) + " in "
+				+ ((System.currentTimeMillis() - localStartTime)) + " ms\n");
+		localStartTime = System.currentTimeMillis();
+	}
+	
+	/**
+	 * This function counts the starting individual cells for the urban growth model run and sets the outputGrid
+	 * to the base inputGrid.<br>
+	 * It only works for a binary classification with urban cells having the value 1 and non-urban
+	 * cells the value 0.
+	 * @return startAnz
+	 */
+	public int countSetIndividuals(){
+		int startAnz = 0;
+		for (int i = 0; i < inputGrid.getWidth();i++ ) {
+			for (int ii = 0; ii < inputGrid.getHeight(); ii++ ) {
+				float val = inputGrid.getRasterSampleAsFloat(i,ii);
+				if (val == 1.0 ) {
+					val = 1f;
+					startAnz++;		//count if value is 1
+				}
+			else val = 0f;
+			inputGrid.setRasterSample(val, inputGrid.getMinX() + i, inputGrid.getMinY() + ii);
+			outputGrid.setRasterSample(val, inputGrid.getMinX() + i, inputGrid.getMinY() + ii);
+			}
+		}
+		return startAnz;
+	}
+	
+	/**
+	 * Calculates the maximum slope from the Slope Raster.
+	 * @return slopeMax
+	 */
+	public int getSlopeMax(){
+		int slopeMax = 0;
+		for (int s = 0; s < inputGrid.getWidth();s++){
+			for(int ss = 0; ss < inputGrid.getHeight();ss++){
+				float slopeVal = slopeGrid.getRasterSampleAsFloat(s,ss);
+				if (slopeVal > slopeMax){
+					slopeMax = (int) slopeVal;	//if the actual slope is larger than the highest measured slope up to now, increase the maximum value to that point
+				} 
+			}
+		}
+		return slopeMax;
+		
+	}
+	
+	/**
+	 * Takes a slope value from the slope lookup-table depending on the given cell in the slope raster.
+	 * @return slopeDoubleNb
+	 */
+	public double getSlopeValue(int X,int Y, HashMap<Number,Number> slopeLUT){
+		int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(X, Y);	//takes a slope value from the slope raster
+		Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);	//looks for that slope value in the Lookup-Table and takes it as a double number
+		double slopeDoubleNb = doubleObjNb.doubleValue();	//converts the double object into a double value.
+		return slopeDoubleNb;		//returns the slope value
+	}
+	
+	/**
+	 * Calculates the exp value that is needed to generate the slope lookup-table 
+	 * @param slope
+	 * @param MaxSlopeResistance
+	 * @return exp
+	 */
+	public double getSlopeExp(double slope, int MaxSlopeResistance){
+		double exp = (slope / (MaxSlopeResistance / 2.0));
+		return exp;
+	}
+	
+	public HashMap<Number,Number> getSlopeLookup(int slopeMax,double exp,double criticalSlope){
+		//Creates a new Lookup-table
+		HashMap<Number, Number> newLUT = new HashMap<Number,Number>();
+		double[] lookup = new double[slopeMax+1];
+		Number key = 0;
+		for (int i = 0;i <= slopeMax;i++){
+			if (i <= criticalSlope){
+				double val = (criticalSlope - i) / criticalSlope;
+				lookup[i] = 1 - Math.pow(val,exp);
+				key = i;
+			} else{
+				lookup[i] = 1;
+				key = i;
+			}
+			newLUT.put(key,lookup[i]);
+			//statusOut.println("Lookup: "+key+", "+lookup[i]);
+		}	
+		return newLUT;
+	}
+	
+	/**
+	 * This is phase 1 of the growth cycle, where spontaneous growth occurs (DISPERSION). Those new cells can turn out to be
+	 * new spreading centers by urbanizing neighboring pixels (BREED {@link BreedGrowth}).
+	 * @return tmpGridDispBreed
+	 */
+	public boolean[][] DispersionGrowth(double disp_value,double breed){
+		//DISPERSION
+		int dispRandX = 0;	//x-coordinate for randomly created cell
+		int dispRandY = 0;	//y-coordinate for randomly created cell
+		float slopeRandDisp = 0;	//random value in order to compare the selected dispersion cell with the slope in that cell
+		int anzDispTreffer = 0;		//Dispersion
+		int anzBreedTreffer = 0;
+		boolean[][] tmpGridDispBreed = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+		int p = 0;	//Distribute so many new cells randomly in suitable places, until disp_value is reached.
+		do{
+			dispRandX = Math.round((float) Math.random()*areaWidth);	//Random position in x-direction
+			dispRandY = Math.round((float) Math.random()*areaHeight);	//Random position in y-direction
+			if ( dispRandX < areaMinX || dispRandY < areaMinY || dispRandX > areaMaxX || dispRandY > areaMaxY ||
+					Float.isNaN(outputGrid.getRasterSampleAsFloat(dispRandX,dispRandY)) ) 
+				continue;		//if a cell is outside the raster (NaN), break and continue loop from the beginning
+			if (areaRestr.getRasterSampleAsFloat(dispRandX,dispRandY) != 0 || outputGrid.getRasterSampleAsFloat(dispRandX,dispRandY) == 1)
+	        	continue;		//if a cell is inside an excluded area or already exists, break and continue loop from the beginning
+	        slopeRandDisp = (float) Math.random();	//a random slope value between 0.0 and 1.0
+	        double slopeDouble = getSlopeValue(dispRandX,dispRandY,slopeLUT);	//returns the slope value for the cell
+	        if(slopeDouble < slopeRandDisp){	//if the slope value of the pixel is smaller than the slope value
+	        	tmpGridDispBreed[dispRandX][dispRandY] = true;	//true is written in the temporary raster
+	        	anzDispTreffer++;		//count number of dispersion cells
+	        	
+	        	//BREED
+	        	float breedRnd = (float) Math.random()*100;		//Breed Random value
+	        	if (tmpGridDispBreed[dispRandX][dispRandY] == true && breedRnd < breed){	//if there is a new dispersion cell and you pass the Breed-Test
+	        		int[][] tmpBreedArray = new int[2][2];	//an array containing the two x and y coordinates of two urbanized cells by breed
+	        		tmpBreedArray = BreedGrowth(dispRandX,dispRandY);	//perform a breed for this cell
+	        		int x1 = tmpBreedArray[0][0];	//x-coordinate of first cell
+	        		int y1 = tmpBreedArray[0][1];	//y-coordinate of first cell
+	        		int x2 = tmpBreedArray[1][0];	//x-coordinate of second cell
+	        		int y2 = tmpBreedArray[1][1];	//y-coordinate of second cell
+	        		tmpGridDispBreed[x1][y1] = true;	//make the temporary grid true at that position
+	        		tmpGridDispBreed[x2][y2] = true;
+	        		anzBreedTreffer += 2;	//count the hits
+	        	}
+			} p++;
+		} while (p < disp_value);	//while instead of for-loop, because it can only be checked in the end
+									//if all cells could be distributed, which is not known at the beginning of the loop.
+									//a part of the cells falls in excluded areas, etc.
+		statusOut.println("Dispersion-Treffer: "+anzDispTreffer);
+		statusOut.println("Breed-Treffer: "+anzBreedTreffer);
+		return tmpGridDispBreed;	//returns a temporary Array containing the newly urbanized cells by the dispersion and breed growth rules
+	}
+	
+	/**
+	 * This is phase 2 of the growth cycle. New spreading centers can induce new growth right in the neighborhood,
+	 * which is calles "breed". This method is fired by new dispersion cells (@link DispersionGrowth), as well as
+	 * by new road cells ({@link RoadGrowth}).
+	 * @param X
+	 * @param Y
+	 * @return tmpBreedArray
+	 */
+	public int[][] BreedGrowth(int X,int Y){
+		boolean[][] tmpGridBreed = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+		int[][] tmpBreedArray = new int[2][2];	//an array containing the x and y coordinates of two cells
+		int anzBreedTreffer = 0;	//Breed
+    	int breedNb = calculateNeighbors(X,Y,0f);	//calculate number of neighbors of a new spreading center cell
+    	int nbBreedX  = 0;	//x-coordinate of neighbouring cells of new spreading center cell
+    	int nbBreedY  = 0;	//y-coordinate of neighbouring cells of new spreading center cell
+    	int RNBreed1 = 0;	//1st Random number for breed
+    	int RNBreed2 = 0;	//2nd Random number for breed
+    	float RNBreedSlope = 0f;	//Slope value of the randomly selected breed cell
+    	if (breedNb >= 2){		//if 2 or more neighbor cells are available around a new dispersion cell
+    		int anzBreedTemp = 0;	//number of temporary breed cells
+    		int[] nbPossibleBreedUrban = null;	//Array of possible breed cells
+    		RNBreed1 = 1 + Math.round((float)Math.random()*(breedNb-1));	//take the first neighbor cell by random (between 1 and the Sum of neighbor cells)
+    		RNBreed2 = 1 + Math.round((float)Math.random()*(breedNb-1));	//take the second neighbor cell by random (between 1 and the Sum of neighbor cells)
+    		do{
+    			RNBreed2 = 1 + Math.round((float)Math.random()*(breedNb-1));
+    		} while (RNBreed2 == RNBreed1);//if the second cell is the same as the first cell try again until the second random number is different from the first
+    		
+    		for (int cellBreed = 0; cellBreed < NEIGHBOR.length; cellBreed++){	//for every cell in the neighborhood...
+    			nbBreedX = X+NEIGHBOR[cellBreed][0];
+    			nbBreedY = Y+NEIGHBOR[cellBreed][1];
+    			if ( nbBreedX < areaMinX || nbBreedY < areaMinY || nbBreedX > areaMaxX || nbBreedY > areaMaxY ||
+    					Float.isNaN(outputGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY)) ) 
+    				continue;	//if a cell is outside the raster (NaN), break and continue loop from the beginning
+    			if (areaRestr.getRasterSampleAsFloat(nbBreedX,nbBreedY) != 0)
+    				continue;	//if a cell is inside an excluded area, break and continue loop from the beginning
+    			RNBreedSlope = (float)Math.random();	//a random slope value between 0.0 and 1.0
+    			double slopeDoubleNb = getSlopeValue(nbBreedX,nbBreedY,slopeLUT);	//returns the slope value for the neighboring cells which are available for breed
+    			float breedSample = outputGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY);	//takes the value from the input grid
+    			if (breedSample == 0f){		//if it is free for urbanization...
+    				anzBreedTemp++;		//increase the number of temporary breed cells
+    				nbPossibleBreedUrban = new int[] {nbBreedX,nbBreedY,anzBreedTemp};	//create a new array containing the x and y coordinates and the number of the breed pixel
+    				if (nbPossibleBreedUrban[2] == RNBreed1 || nbPossibleBreedUrban[2] == RNBreed2 && slopeDoubleNb < RNBreedSlope){	//if the cell has the same value as the first or second random value and its slope value is smaller than the random slope value...
+    					tmpBreedArray[anzBreedTreffer][0] = nbBreedX;	//x-coordinate
+    					tmpBreedArray[anzBreedTreffer][1] = nbBreedY;	//y-coordinate
+    					tmpGridBreed[nbBreedX][nbBreedY] = true;	//urbanize the cell in the temporary grid
+    					anzBreedTreffer++;		//and increase the number of breed cells
+    				}
+    			}
+    		}
+    	}
+		return tmpBreedArray; 
+	}
+	
+	
+	/**
+	 * This is phase 3 of the growth cycle, where edge growth appears based on the urban pixels that exist at 
+	 * this time (including the new spontaneous and spreading center pixels).
+	 * @return tmpGridSpread
+	 */
+	public boolean[][] EdgeGrowth(double spread){
+		
+		boolean[][] tmpGridSpread = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+		//definitions for neighborhood cells
+		int nbX = 0; // X-Coordinate of a neighboring cell
+	    int nbY = 0; // Y-Coordinate of a neighboring cell
+	    
+		int anzSpreadTreffer = 0;	//Number of Spread cells
+		
+		//iterate over all cells
+		for (int x = 0; x < inputGrid.getWidth(); x++)
+			for (int y = 0; y < inputGrid.getHeight(); y++) {		//for every cell in x/y direction...
+				
+				int areaMinXadd = areaMinX + x;		//x-coordinate cell in the raster
+				int areaMinYadd = areaMinY + y;		//y-coordinate cell in the raster
+				
+				int anzNachbarn = calculateNeighbors(x,y,1f);	//number of urban neighbors
+				
+				boolean lebt = outputGrid.getRasterSampleAsFloat(areaMinXadd, areaMinYadd ) > 0f;	//a cell is alive if it is 1
+				
+				int SpR = Math.round((float) Math.random()*100);				//a random number to compare with the spread coefficient
+				if (lebt && (anzNachbarn>=2) && (SpR < spread) && (anzNachbarn < 8)) {	//if a cell is alive, it has more or equal than two urban neighbors and less than 8 urban neighbors (at least 1 non-urban neighbor) and we pass the spread coefficient test...
+					int anzTemp = 0;		//temporary possible cells for urbanization
+					int[] nbPossibleUrban = null;	//array with coordinates of possible cells for urbanization
+					//int RN = 1 + Math.round((float)Math.random()*(8-anzNachbarn-1));	//this is an option to distribute the ranom number only between the possible cells for urbanization
+					int RN = (int) Math.round(8*Math.random());	//a random number between 0 and 8
+					float RNEdgeSlope = 0;
+					for (int nbCellChange = 0; nbCellChange < NEIGHBOR.length; nbCellChange++){	//loop over all neighbor cells
+						checkBreakingCommands();
+						nbX = x+NEIGHBOR[nbCellChange][0];
+						nbY = y+NEIGHBOR[nbCellChange][1];
+						if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+					               Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)))
+					             continue;	//if a cell is outside the raster (NaN), break and continue loop from the beginning
+						if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+				        	continue;	//if a cell is inside an excluded area, break and continue loop from the beginning
+						RNEdgeSlope = (float)Math.random();		//a random number to be compared with the slope value
+						double slopeDoubleNb = getSlopeValue(nbX,nbY,slopeLUT);	//returns the slope value for the neighboring cells which are available for breed
+	        			float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY);	//takes the value from the input gridn
+						if (rasterSample == 0f){	//if the value is 0 and thus is possible for urbanization
+							anzTemp++;				//count it
+							nbPossibleUrban = new int[] {nbX,nbY,anzTemp};	//write it with its coordinates in an array
+							//float NbValueEdge = 1f;
+							if (nbPossibleUrban[2] == RN){	//if the number in the "possible for urbanization" array is the same as the random number...
+								//int urbanNbTemp = calculateNeighbors(nbX,nbY,NbValueEdge);	//to reduce the effect of edge growth here could be included an option that allows only growth when a new urban cell has at least 2 urban neighbors
+								if (tmpGridSpread[nbX][nbY]==false && slopeDoubleNb < RNEdgeSlope){	// if the cell is non-urban and it passes the slope test //urbanNbTemp >= 2 && 
+									tmpGridSpread[nbX][nbY] = true;	//write it in the temporary raster
+									anzSpreadTreffer++;	//count the hits
+								}
+							} 
+						}
+					}
+				}
+			}
+		return tmpGridSpread;	//returns the temporary array
+	}
+	
+	/**
+	 * This is phase 4 of the growth cycle, where growth along roads appears. Every newly developed cell can induce road growth.
+	 * Therefore for a defined number of new cells (by the breed-coeffient) the algorithm looks for a road in the neighborhood.
+	 * If the new cell is located directly on a road, the algorithm starts a "road walk" ({@link roadWalk}), and moves a new cell along the road
+	 * to a defined distance. If the new cell is not on a road, it looks for a road in a defined neighborhood (by {@code rg_value}). 
+	 * If a road is found, it starts a "road walk" from there.
+	 * @param tmpGrid
+	 * @return tmpGridRoad
+	 */
+	public boolean[][] RoadGrowth(boolean[][] tmpGrid,double rg_value, double breed, double disp){
+		boolean[][] tmpGridRoad = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+		int anzGesamt = countTempUrbanCells(tmpGrid);	//number of urban cells in the temporary cell array
+		int anzRoadTreffer = 0;
+		int[] cellValue = null;	//array of cell values
+		int RSearchRoad = 0;	//Random Road Search Index
+		int r = 1;	//number between 1 and the disp-Value, whih is increased during the follwing while-loop. It determines how many pixels are selected randomly for a possible road trip
+		int anzTempRoadNb = 0;
+		
+		do{
+			RSearchRoad = Math.round((float)Math.random()*anzGesamt);	//a random value between 1 and the total amount of newly urbanized pixels
+			int anzTruePixels = 0;	
+			int roadNeighborhoodRange = 0;
+			int RSearchNbRoad = 0;
+			for (int x = 0; x < inputGrid.getWidth();x++){		//for every cell in the raster...
+				for(int y = 0; y < inputGrid.getHeight();y++){
+					int X = inputGrid.getMinX() + x;	//x-coordinate cell in the raster
+					int Y = inputGrid.getMinY() + y;	//y-coordinate cell in the raster
+					if (tmpGrid[X][Y]==true){	//if a new urbanized cell is found
+						anzTruePixels++;		//count the number of urban pixels, and...(and this is different to "countTempUrbanCells")
+						cellValue = new int[] {X,Y,anzTruePixels};	//write them with their coordinates in an array
+						int tempRoadCell[] = null;		//an array of temporary road cells
+						int tempNbRoadCell[] = null;	//an array of temporary neighboring cells of these road cells
+						if (cellValue[2] == RSearchRoad){	//randomly select a growth pixel to start search for road (by comparing the cell number with the generated random number between 1 and total amount of new cells)
+						//	statusOut.println("Randomly selected road pixel found...");
+							r++;	//increase r, because a potential road trip pixel has been selected
+							float roadValue = roadGrid.getRasterSampleAsFloat(X,Y);	//take the value from the road map for that pixel
+							if (roadValue > 0.0){		//if the value is greater than 0 and thus is a road...
+								tempRoadCell = new int[] {X,Y};		//add its coordinates to the temporary road grid
+							//	statusOut.println("Strasse in Entfernung 0: "+tempRoadCell[0]+","+tempRoadCell[1]);
+								int nbCellNew[] = roadWalk(tempRoadCell[0],tempRoadCell[1],disp);	//perform a road walk
+								if(nbCellNew != null){	//if the result of the road walk is positive,...
+									tmpGridRoad[nbCellNew[0]][nbCellNew[1]] = true;		//place a new urban pixel in the temporary Grid
+									anzRoadTreffer++;	//?!?
+									int[][] tmpBreedArray = new int[2][2];	//an array containing the x and y coordinates of two breed cells
+									tmpBreedArray = BreedGrowth(nbCellNew[0],nbCellNew[1]);	//this new urban cell can act as a new spreading center:
+									int x1 = tmpBreedArray[0][0];	//x-coordinate of first cell
+					        		int y1 = tmpBreedArray[0][1];	//y-coordinate of first cell
+					        		int x2 = tmpBreedArray[1][0];	//x-coordinate of second cell
+					        		int y2 = tmpBreedArray[1][1];	//y-coordinate of second cell
+					        		tmpGridRoad[x1][y1] = true;	//make the temporary grid true at that position
+					        		tmpGridRoad[x2][y2] = true;
+									anzRoadTreffer += 2;
+								} else{
+							//		statusOut.println("No new RoadBreedCells found directly");
+								}
+							} else{		//if the selected pixel has not been a road pixel search in the neighborhood for a road
+								int anzRoadNb = 0;
+						//		statusOut.println("no road cell on first run...");
+							
+								//With a loop look in the neighborhood for a road in an increasing radius until you reach the road gravity value
+								for (int roadSearch = 0; roadSearch <= rg_value; roadSearch++){
+								//	statusOut.println("RG_VALUE: "+rg_value+"; ROAD-SEARCH-VALUE = "+roadSearch);
+									if (anzRoadNb > 0)	//if a road is found break and continue from the beginning (the next loops will end here as well until it stops when rg_value ist reached)
+										continue;
+									for (int nbRoadCellsX = X - roadNeighborhoodRange; nbRoadCellsX <= X + roadNeighborhoodRange; nbRoadCellsX++){
+										for (int nbRoadCellsY = Y - roadNeighborhoodRange; nbRoadCellsY <= Y + roadNeighborhoodRange; nbRoadCellsY++){	//increase the neighborhood in every loop
+											if ( nbRoadCellsX < areaMinX || nbRoadCellsY < areaMinY || nbRoadCellsX > areaMaxX || nbRoadCellsY > areaMaxY ||
+													Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY)) )
+												continue;	//if a cell is outside the raster (NaN), break and continue loop from the beginning
+											float roadValueNb = roadGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY);		//take the value from the road map for that pixel
+											if (roadValueNb > 0f){	//if the value is greater than 0 and thus is a road...
+												anzRoadNb++;	//increase the number of road neighbors
+									//			statusOut.println("Number of road neighbors: "+anzRoadNb);
+											}
+										}
+									}
+									roadNeighborhoodRange++;	//increase the road neighborhood range
+									RSearchNbRoad = Math.round((float)Math.random()*anzRoadNb);		//a random value between 0 and the number of road neighbors
+									anzTempRoadNb = 0;	//number of temporary road neighbors
+									for (int nbRoadCellsX = X - roadNeighborhoodRange; nbRoadCellsX <= X + roadNeighborhoodRange; nbRoadCellsX++){
+										for (int nbRoadCellsY = Y - roadNeighborhoodRange; nbRoadCellsY <= Y + roadNeighborhoodRange; nbRoadCellsY++){	//again increase the neighborhood in every loop
+						        			//statusOut.println("TEST-ROAD: "+nbRoadCellsX+","+nbRoadCellsY);
+											if ( nbRoadCellsX < areaMinX || nbRoadCellsY < areaMinY || nbRoadCellsX > areaMaxX || nbRoadCellsY > areaMaxY ||
+													Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+												continue;	//if a cell is outside the raster (NaN), break and continue loop from the beginning
+											float roadValueNbTemp = roadGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY);	//take the road value from that pixel
+											if (roadValueNbTemp > 0f){	//if the value is greater than 0 and thus is a road... 
+												anzTempRoadNb++;	//increase the number of temporary road neighbors
+												tempNbRoadCell = new int[] {nbRoadCellsX,nbRoadCellsY,anzTempRoadNb};	//build an array of neighboring road cells with its coordinates
+											//	statusOut.println("in Array: "+tempNbRoadCell[2]+"Random: "+RSearchNbRoad+"Anzahl temporärer Zellen: "+anzTempRoadNb);
+												if (tempNbRoadCell[2]==RSearchNbRoad){	//check the position in that array with the random number
+													tempRoadCell = tempNbRoadCell;	//the main temporary road cell is moved to this position
+													//statusOut.println("Strasse in Entfernung "+roadSearch+": "+tempRoadCell[0]+","+tempRoadCell[1]+","+tempRoadCell[2]);
+													int nbCellNew[] = roadWalk(tempRoadCell[0],tempRoadCell[1],disp);	//perform a road walk
+													if(nbCellNew != null){	//if the result of the road walk is positive,...
+														tmpGridRoad[nbCellNew[0]][nbCellNew[1]] = true;	//place a new urban cell in the temporary grid
+														anzRoadTreffer++;
+														int[][] tmpBreedArray = new int[2][2];
+														tmpBreedArray = BreedGrowth(nbCellNew[0],nbCellNew[1]);
+														int x1 = tmpBreedArray[0][0];
+										        		int y1 = tmpBreedArray[0][1];
+										        		int x2 = tmpBreedArray[1][0];
+										        		int y2 = tmpBreedArray[1][1];
+										        		tmpGridRoad[x1][y1] = true;
+										        		tmpGridRoad[x2][y2] = true;
+														anzRoadTreffer += 2;
+													} else{
+												//		statusOut.println("No new road cell found after road search.");
+													}
+												}
+											} else{
+											//	statusOut.println("Nothing to find...");
+											}
+										}
+									}
+								}
+							}
+						}
+					}	
+				}
+			}
+			
+		} while (r <= breed);
+		statusOut.println("Road-Treffer: "+anzRoadTreffer);
+		return tmpGridRoad;
+	}
+	
+	/**
+	 * This method performs a walk along a road starting from an initial cell with the coordinates X, Y.
+	 * It returns the position of the final cell after the road walk, which than can start a new urbanization.
+	 * @param X
+	 * @param Y
+	 * @return nbCellNew
+	 */
+	public int[] roadWalk(int X,int Y,double disp){
+		boolean end_of_road = false;	//start with the assumption that the end of the road trip is not completed yet	
+		int run = 0;	//distance a cell is moving
+		int run_value = 0;	//maximum moving distance
+		int[] nbCellNew = null;	 //Array containing the coordinates of the new urbanized cells after the road walk
+		int[] nbCellTemp = null;	//Array containing the neighbors of the end cell
+		while(!end_of_road){	//until the end of the road is not reached...
+			end_of_road = true;		//say that this is so
+			int nbRoadX = 0;	//neighborhood of the cell
+			int nbRoadY = 0;
+			int areaMinX = inputGrid.getMinX();								//raster dimensions
+			int areaMinY = inputGrid.getMinY();
+			int areaMaxX = inputGrid.getMinX() + inputGrid.getWidth() - 1;
+			int areaMaxY = inputGrid.getMinY() + inputGrid.getHeight() - 1;
+			int roadNb = 0;		//number of neighboring cells
+			int roadNbTemp = 0;	//number of neighboring cells
+			int RN = 0;	//a random number
+						
+			int[] nbCell = null;	//Array containing a neighboring cell
+			for (int nbRoadCells = 0; nbRoadCells < NEIGHBOR.length; nbRoadCells++){	//for every neighbor of the starting cell...
+				nbRoadX = X+NEIGHBOR[nbRoadCells][0];	
+				nbRoadY = Y+NEIGHBOR[nbRoadCells][1];
+				if ( nbRoadX < areaMinX || nbRoadY < areaMinY || nbRoadX > areaMaxX || nbRoadY > areaMaxY ||
+			               Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY)) ) 
+			             continue;	//if a cell is outside the raster (NaN), break and continue loop from the beginning
+				float roadSample = roadGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY);	//take the value
+				if (roadSample > 0f)	//if a road is present (>1),
+					roadNb++;			//count it
+			}
+			
+			if (roadNb > 0){	//if neighbors are available
+				RN = 1 + Math.round((float)Math.random()*(roadNb-1));	//select a random one
+			
+				for (int nbRoadCells = 0; nbRoadCells < NEIGHBOR.length; nbRoadCells++){	//for every neighbor of the starting cell...
+					nbRoadX = X+NEIGHBOR[nbRoadCells][0];
+					nbRoadY = Y+NEIGHBOR[nbRoadCells][1];
+					if ( nbRoadX < areaMinX || nbRoadY < areaMinY || nbRoadX > areaMaxX || nbRoadY > areaMaxY ||
+							Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY)) ) 
+			             	continue;	//if a cell is outside the raster (NaN), break and continue loop from the beginning
+					float roadSample = roadGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY);	//take the value
+					if (roadSample > 0f){	//if a road is present (>1),
+						roadNbTemp++;		//count it
+						nbCell = new int[] {nbRoadX,nbRoadY,roadNbTemp};	//write it in an array
+						if (nbCell[2] == RN){	//if the number in the array is the same as the randomly selected number
+							end_of_road = false;	//the end of the road is not reached
+							run++;	//increase the run value
+							X = nbRoadX;
+							Y = nbRoadY;
+							float roadSample2 = roadGrid.getRasterSampleAsFloat(X,Y);	//take the value of the road
+							run_value = (int) (roadSample2 / 100 * disp);	//calculate how far the cell can be moved along the road
+							if (run > run_value){	//if the run-value exceeds the maximum value...
+								end_of_road = true;	//end the road walk
+								int Nb = calculateNeighbors(X,Y,0f);	//find the neighbors of the cell found
+								RN = 1 + Math.round((float)Math.random()*(Nb-1));	//select a random number between 1 and the number of neighbors
+								if (Nb > 0){	//if a neighbor is found...
+									int nbUrbanizeX = 0;
+									int nbUrbanizeY = 0;
+									int NbTemp = 0;
+									float RNRoadSlope = 0f;
+									for (int urbanizeCells = 0; urbanizeCells < NEIGHBOR.length; urbanizeCells++){	//look at every neighbor cell
+										nbUrbanizeX = X+NEIGHBOR[urbanizeCells][0];
+										nbUrbanizeY = Y+NEIGHBOR[urbanizeCells][1];
+										if ( nbUrbanizeX < areaMinX || nbUrbanizeY < areaMinY || nbUrbanizeX > areaMaxX || nbUrbanizeY > areaMaxY ||
+												Float.isNaN(outputGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY)) ) 
+											continue;	//if a cell is outside the raster (NaN), break and continue loop from the beginning
+										if (areaRestr.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY) != 0)
+											continue;	//if a cell is inside an excluded area, break and continue loop from the beginning
+										float rasterSample = outputGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY);	//take the raster value
+										RNRoadSlope = (float)Math.random();	//generate a random number in order to compare it with the slope
+										double slopeDoubleNb = getSlopeValue(nbUrbanizeX,nbUrbanizeY,slopeLUT);	//returns the slope value for the neighboring cells which are available for breed
+										if (rasterSample == 0f){	//if the raster sample is available for urbanization...
+											NbTemp++;	//count it
+											nbCellTemp = new int[] {nbUrbanizeX,nbUrbanizeY,NbTemp};	//create an array holding the coordinates and the number of that neighbor cell
+											if (nbCellTemp[2] == RN && slopeDoubleNb < RNRoadSlope){	//if its number is the same as the random number and it passes the slope-test..
+												nbCellNew = new int[] {nbCellTemp[0],nbCellTemp[1],nbCellTemp[2]};	//write its coordinates in the array to be returned
+											}
+										}	
+									}
+								
+							} else{
+								nbCellNew = null;	
+							}	break;
+						}
+						
+					}
+					
+				}
+			}
+			
+			}
+		}
+		return nbCellNew;	//return the result array
+		}
+	
+	/**
+	 * This method returns the number of neighbors of a cell X/Y. The input for this method are the coordinates of the center cell
+	 * and the value that the neighboring cells must have in order to be counted. In general this is 0 for non-urban cells and 1 
+	 * for urban cells.
+	 * @param X
+	 * @param Y
+	 * @param NbValue
+	 * @return Nb
+	 */
+	public int calculateNeighbors(int X, int Y, float NbValue){
+		int nbX = 0;
+		int nbY = 0;
+		int areaMinX = inputGrid.getMinX();								//raster dimensions
+		int areaMinY = inputGrid.getMinY();
+		int areaMaxX = inputGrid.getMinX() + inputGrid.getWidth() - 1;
+		int areaMaxY = inputGrid.getMinY() + inputGrid.getHeight() - 1;
+		int Nb = 0;
+		for (int nbCells = 0; nbCells < NEIGHBOR.length; nbCells++){
+			nbX = X+NEIGHBOR[nbCells][0];
+			nbY = Y+NEIGHBOR[nbCells][1];
+			if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+		               Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)))
+		             continue;	//if a cell is outside the raster (NaN), break and continue loop from the beginning
+			if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+	        	continue;	//if a cell is inside an excluded area, break and continue loop from the beginning
+			float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY);	//take the raster value
+			if (rasterSample == NbValue)	//if it is the same as the value we look for...
+				Nb++;	//count it
+		}
+		return Nb;
+	}
+	
+	/**
+	 * Returns the number of urban cells in the temporary cell array.
+	 * @return anzGesamt
+	 */
+	public int countTempUrbanCells(boolean[][] tmpGrid){
+		int anzGesamt = 0;
+		for (int x = 0; x < outputGrid.getWidth();x++)
+			for(int y = 0; y < outputGrid.getHeight();y++){
+				if (tmpGrid[x][y]==true){
+					anzGesamt++;
+				}		
+			}
+		return anzGesamt;
+	}
+	
+	/**
+	 * Writes a temporary grid array with boolean values to the outputGrid.
+	 * @param tmpGrid
+	 */
+	public void writeToGrid(boolean tmpGrid[][]){
+		int t = 0;
+		for (int y = 1; y < inputGrid.getHeight()-1;y++ ) {
+			for (int x = 1; x < inputGrid.getWidth()-1; x++ ) {
+			
+				int X = inputGrid.getMinX() + x;
+				int Y = inputGrid.getMinY() + y;
+			
+				boolean lebt = outputGrid.getRasterSampleAsFloat(X , Y ) > 0f;	//a cell is alive when it is 1
+				if (tmpGrid[x][y] == false)	//if there is nothing in the temporary raster
+					tmpGrid[x][y] = lebt;	//take the information from the current output grid
+				if(tmpGrid[x][y] == true)
+					t++;
+				outputGrid.setRasterSample( tmpGrid[x][y] ? 1f : 0f ,X ,Y);	//write the result to the output grid
+			}
+		}
+		statusOut.println("Temporary Urban Cells: "+t);
+	}
+}

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibration.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibration.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibration.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,691 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import edu.bonn.xulu.model.XuluModel;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ListProperty;
+import schmitzm.data.property.ListPropertyWriteAccess;
+import schmitzm.data.property.PropertyReadAccess;
+import schmitzm.data.property.PropertyWriteAccess;
+import schmitzm.data.property.ScalarProperty;
+
+/**
+ * <b>Calibration of the Urban Growth Model</b><br>
+ *  This model is based on the {@link UrbanGrowthModel Urban Growth Model}, developed by Keith Clarke at the UC Santa Barbara, CA, within the Gigalopolis Project, funded by the
+ *  USGS. It has exactly the same growth rules as its parent class, but runs with n Monte-Carlo Iterations. So the resulting map does not contain the urban extent after a model
+ *  run, but the probability for new urbanization. The more often a cell has been selected for urbanization during the Monte-Carlo Iterations, the higher is that value in the 
+ *  output map. The model performs this procedure for every combination of the different coefficients. There is not a single coefficient value as in the original model, but a starting
+ *  value, a step value and an end value. So, when starting with a coefficient of 5, a step value of 10 and an end value of 25, the model will perform 3 steps (for 5, 15, and 25). Be 
+ *  aware that entering many steps for many coefficients will result in a huge amount of possible combinations. Therefore the calibration should be performed sequential from a coarse
+ *  calibration over a fine calibration to a final calibration. The perforamce of the different model runs is measured by the {@link edu.bonn.xulu.plugin.model.mrv.MultipleResolutionValidation Multiple Resolution Comparison}.
+ *  This validation procedure has been adopted for this class and is integrated in a separate method. The original SLEUTH Urban Growth Model is calibrated by a different procedure.
+ *  For a detailed description refer to {@link UrbanGrowthModel Urban Growth Model}, {@link UrbanGrowthModel_MC Urban Growth Model MC} or 
+ *  {@link edu.bonn.xulu.plugin.model.mrv.MultipleResolutionValidation Multiple Resolution Comparison}
+ *  
+ *  <br>
+ *  In addition to the UGM parameters, these parameters are needed:<br>
+ * <ul>
+ *  <li><b>Spread Start</b>: Spread Starting Coefficient</li>
+ *  <li><b>Spread Step</b>: Spread Step Coefficient</li>
+ *  <li><b>Spread End</b>: Spread End Coefficient</li>
+ *  <li><b>Dispersion Start</b>: Dispersion Starting Coefficient</li>
+ *  <li><b>Dispersion Step</b>: Dispersion Step Coefficient</li>
+ *  <li><b>Dispersion End</b>: Dispersion End Coefficient</li>
+ *  <li><b>Breed Start</b>: Breed Starting Coefficient</li>
+ *  <li><b>Breed Step</b>: Breed Step Coefficient</li>
+ *  <li><b>Breed End</b>: Breed End Coefficient</li>
+ *  <li><b>RoadGravity Start</b>: RoadGravity Starting Coefficient</li>
+ *  <li><b>RoadGravity Step</b>: RoadGravity Step Coefficient</li>
+ *  <li><b>RoadGravity End</b>: RoadGravity End Coefficient</li>
+ *  <li><b>Slope Start</b>: Slope Starting Coefficient</li>
+ *  <li><b>Slope Step</b>: Slope Step Coefficient</li>
+ *  <li><b>Slope End</b>: Slope End Coefficient</li>
+ *  <li><b>Monte Carlo Iterations</b>: The number of Monte Carlo Iterations.</li>
+ *  <li><b>Sum Step Results</b>: List of resulting maps containing the sums over all Monte Carlo Iterations for a single parameter combination.</li>
+ * </ul>
+ * 
+ * @see UrbanGrowthModelCalibrationContentManager
+ * @see UrbanGrowthModel
+ * @see UrbanGrowthModel_MC
+ * @author <a href="mailto:goetzke at uni-bonn.de">Roland Goetzke</a>
+ * @version 1.0
+ */
+public class UrbanGrowthModelCalibration extends UrbanGrowthModel {
+
+	// ********** Read/Write access, that has to be maintained ***
+	// ********** through the whole model run ********************
+	protected PropertyReadAccess RA_referenceMap = null;	//Observed Validation Grid
+	protected PropertyReadAccess RA_spreadStart = null;	//Spread-Coefficient
+	protected PropertyReadAccess RA_spreadStep = null;	//Spread-Coefficient
+	protected PropertyReadAccess RA_spreadEnd = null;	//Spread-Coefficient
+	protected PropertyReadAccess RA_dispStart = null;		//Dispersion-Coefficient
+	protected PropertyReadAccess RA_dispStep = null;		//Dispersion-Coefficient
+	protected PropertyReadAccess RA_dispEnd = null;		//Dispersion-Coefficient
+	protected PropertyReadAccess RA_breedStart = null;		//Breed-Coefficient
+	protected PropertyReadAccess RA_breedStep = null;		//Breed-Coefficient
+	protected PropertyReadAccess RA_breedEnd = null;		//Breed-Coefficient
+	protected PropertyReadAccess RA_roadGravityStart = null;	//Road-Gravity-Coefficient
+	protected PropertyReadAccess RA_roadGravityStep = null;	//Road-Gravity-Coefficient
+	protected PropertyReadAccess RA_roadGravityEnd = null;	//Road-Gravity-Coefficient
+	protected PropertyReadAccess RA_slopeStart = null;	//Slope-Coefficient
+	protected PropertyReadAccess RA_slopeStep = null;	//Slope-Coefficient
+	protected PropertyReadAccess RA_slopeEnd = null;	//Slope-Coefficient
+	protected PropertyReadAccess RA_criticalSlope = null;	//Critical Slope Value
+	protected PropertyReadAccess RA_MonteCarlo = null;	//Number of MonteCarlo Iterations
+	protected ListPropertyWriteAccess WA_outResults = null;	//Output Validation Results
+	protected PropertyWriteAccess WA_SumOutStep = null;	// Step Results
+	
+
+	// **************** Variablen to work with *******************
+	protected WritableGrid referenceMap = null;	//Observed Validation Grid 
+	protected double spreadStart = 0;	//Spread-Coefficient
+	protected double spreadStep = 0;	//Spread-Coefficient
+	protected double spreadEnd = 0;	//Spread-Coefficient
+	protected double dispStart = 0;	//Dispersion-Coefficient
+	protected double dispStep = 0;	//Dispersion-Coefficient
+	protected double dispEnd = 0;	//Dispersion-Coefficient
+	protected double breedStart = 0;	//Breed-Coefficient
+	protected double breedStep = 0;	//Breed-Coefficient
+	protected double breedEnd = 0;	//Breed-Coefficient
+	protected double roadGravityStart = 0;	//Road-Gravity-Coefficient
+	protected double roadGravityStep = 0;	//Road-Gravity-Coefficient
+	protected double roadGravityEnd = 0;	//Road-Gravity-Coefficient
+	protected double slopeStart = 0;	//Slope-Coefficient
+	protected double slopeStep = 0;	//Slope-Coefficient
+	protected double slopeEnd = 0;	//Slope-Coefficient
+	protected double criticalSlope = 0;	//Critical Slope Value
+	protected int MonteCarlo = 0;	//Number of Monte Carlo Iterations
+	protected ListPropertyWriteAccess outResults = null;	//Output Validation Results
+	protected MultiGrid SumOutStep = null;	//Step Results
+		
+	protected int years = 0;
+	protected int neighborhoodRange = 0;
+	protected int numSteps = 0;
+	protected float[] resultArray;
+	protected float[] mrvTempResultArray;
+	protected float[] finalArray;
+	
+	/**
+	 * First Constructor
+	 * @param contManager
+	 */
+	public UrbanGrowthModelCalibration(UrbanGrowthModelCalibrationContentManager contManager) {
+		super(contManager);
+		this.contManager = (UrbanGrowthModelCalibrationContentManager) super.contManager;
+	}
+	
+	/**
+	 * Second Constructor. The Content Manager is the parent content manager as well as the child content manager
+	 */
+	public UrbanGrowthModelCalibration(){
+		super(new UrbanGrowthModelCalibrationContentManager());
+	}
+	
+	/**
+	 * Initializes the model. Like in the init method of every {@link XuluModel}
+	 * the resources are initalized. 
+	 */
+	public void performModelInit() {
+
+		if (contManager == null)
+			return;
+		// Get access authorisation of resource/properties
+		RA_steps = null;
+		if (contManager.getResource(0).getData() != null)
+			RA_steps = ((ScalarProperty) contManager.getResource(0).getData())
+					.getReadAccess(this);
+		RA_inputGrid = null;
+		if (contManager.getResource(1).getData() != null)
+			RA_inputGrid = ((ScalarProperty) contManager.getResource(1)
+					.getData()).getReadAccess(this);
+		WA_outputGrid = null;
+		if (contManager.getResource(2).getData() != null)
+			WA_outputGrid = ((ScalarProperty) contManager.getResource(2)
+					.getData()).getWriteAccess(this);
+		RA_areaRestr = null;
+		if (contManager.getResource(3).getData() != null)
+			RA_areaRestr = ((ScalarProperty) contManager.getResource(3)
+					.getData()).getReadAccess(this);
+		RA_roadGrid = null;
+		if (contManager.getResource(4).getData() != null)
+			RA_roadGrid = ((ScalarProperty) contManager.getResource(4)
+					.getData()).getReadAccess(this);
+		RA_slopeGrid = null;
+		if (contManager.getResource(5).getData() != null)
+			RA_slopeGrid = ((ScalarProperty) contManager.getResource(5)
+					.getData()).getReadAccess(this);
+		RA_referenceMap = null;
+		if(contManager.getResource(6).getData() != null)
+			RA_referenceMap = ((ScalarProperty) contManager.getResource(6)
+					.getData()).getReadAccess(this);
+		RA_spreadStart = null;
+		if (contManager.getResource(7).getData() != null)
+			RA_spreadStart = ((ScalarProperty) contManager.getResource(7).getData())
+					.getReadAccess(this);
+		RA_spreadStep = null;
+		if (contManager.getResource(8).getData() != null)
+			RA_spreadStep = ((ScalarProperty) contManager.getResource(8).getData())
+					.getReadAccess(this);
+		RA_spreadEnd = null;
+		if (contManager.getResource(9).getData() != null)
+			RA_spreadEnd = ((ScalarProperty) contManager.getResource(9).getData())
+					.getReadAccess(this);
+		RA_dispStart = null;
+		if (contManager.getResource(10).getData() != null)
+			RA_dispStart = ((ScalarProperty) contManager.getResource(10).getData())
+					.getReadAccess(this);
+		RA_dispStep = null;
+		if (contManager.getResource(11).getData() != null)
+			RA_dispStep = ((ScalarProperty) contManager.getResource(11).getData())
+					.getReadAccess(this);
+		RA_dispEnd = null;
+		if (contManager.getResource(12).getData() != null)
+			RA_dispEnd = ((ScalarProperty) contManager.getResource(12).getData())
+					.getReadAccess(this);
+		RA_breedStart = null;
+		if (contManager.getResource(13).getData() != null)
+			RA_breedStart = ((ScalarProperty) contManager.getResource(13).getData())
+					.getReadAccess(this);
+		RA_breedStep = null;
+		if (contManager.getResource(14).getData() != null)
+			RA_breedStep = ((ScalarProperty) contManager.getResource(14).getData())
+					.getReadAccess(this);
+		RA_breedEnd = null;
+		if (contManager.getResource(15).getData() != null)
+			RA_breedEnd = ((ScalarProperty) contManager.getResource(15).getData())
+					.getReadAccess(this);
+		RA_roadGravityStart = null;
+		if (contManager.getResource(16).getData() != null)
+			RA_roadGravityStart = ((ScalarProperty) contManager.getResource(16).getData())
+					.getReadAccess(this);
+		RA_roadGravityStep = null;
+		if (contManager.getResource(17).getData() != null)
+			RA_roadGravityStep = ((ScalarProperty) contManager.getResource(17).getData())
+					.getReadAccess(this);
+		RA_roadGravityEnd = null;
+		if (contManager.getResource(18).getData() != null)
+			RA_roadGravityEnd = ((ScalarProperty) contManager.getResource(18).getData())
+					.getReadAccess(this);
+		RA_slopeStart = null;
+		if (contManager.getResource(19).getData() != null)
+			RA_slopeStart = ((ScalarProperty) contManager.getResource(19).getData())
+					.getReadAccess(this);
+		RA_slopeStep = null;
+		if (contManager.getResource(20).getData() != null)
+			RA_slopeStep = ((ScalarProperty) contManager.getResource(20).getData())
+					.getReadAccess(this);
+		RA_slopeEnd = null;
+		if (contManager.getResource(21).getData() != null)
+			RA_slopeEnd = ((ScalarProperty) contManager.getResource(21).getData())
+					.getReadAccess(this);
+		RA_criticalSlope = null;
+		if (contManager.getResource(22).getData() != null)
+			RA_criticalSlope = ((ScalarProperty) contManager.getResource(22).getData())
+					.getReadAccess(this);
+		RA_MonteCarlo = null;
+		if (contManager.getResource(23).getData() != null)
+			RA_MonteCarlo = ((ScalarProperty) contManager.getResource(23).getData())
+					.getReadAccess(this);
+		WA_outResults = null;
+		if (contManager.getResource(24).getData() != null)
+			WA_outResults = ((ListProperty) contManager.getResource(24)
+					.getData()).getWriteAccess(this);
+		
+		
+		// Assign variables to work with
+		inputGrid = (WritableGrid) RA_inputGrid.getValue();
+		outputGrid = (WritableGrid) WA_outputGrid.getValue();
+		steps = RA_steps;
+		areaRestr = (WritableGrid) RA_areaRestr.getValue();
+		roadGrid = (WritableGrid) RA_roadGrid.getValue();
+	    slopeGrid = (WritableGrid) RA_slopeGrid.getValue();
+		referenceMap 	= (WritableGrid) RA_referenceMap.getValue();	
+	    spreadStart  	= RA_spreadStart.getValueAsDouble();
+	    spreadStep  	= RA_spreadStep.getValueAsDouble();
+	    spreadEnd  		= RA_spreadEnd.getValueAsDouble();
+	    dispStart		= RA_dispStart.getValueAsDouble();
+	    dispStep		= RA_dispStep.getValueAsDouble();
+	    dispEnd			= RA_dispEnd.getValueAsDouble();
+	    breedStart		= RA_breedStart.getValueAsDouble();
+	    breedStep		= RA_breedStep.getValueAsDouble();
+	    breedEnd		= RA_breedEnd.getValueAsDouble();
+	    roadGravityStart= RA_roadGravityStart.getValueAsDouble();
+	    roadGravityStep = RA_roadGravityStep.getValueAsDouble();
+	    roadGravityEnd 	= RA_roadGravityEnd.getValueAsDouble();
+	    slopeStart		= RA_slopeStart.getValueAsDouble();
+	    slopeStep		= RA_slopeStep.getValueAsDouble();
+	    slopeEnd		= RA_slopeEnd.getValueAsDouble();
+	    criticalSlope = RA_criticalSlope.getValueAsDouble();
+	    MonteCarlo 		= RA_MonteCarlo.getValueAsInt();
+		outResults 		= WA_outResults;
+		outStep 		= (MultiGrid)contManager.getResource(25).getData();
+		SumOutStep		= (MultiGrid)contManager.getResource(26).getData();
+		stepCount 		= 1;
+		years 			= steps.getValueAsInt();
+
+		//count the number of starting individuals
+	    int startAnz = 0;
+		startAnz = countSetIndividuals();
+		
+		statusOut.println("Number of starting cells: "+startAnz);
+		statusOut.println("Neighborhood size: "+NEIGHBOR.length);
+		
+		neighborhoodRange = (int) Math.sqrt(inputGrid.getWidth()*inputGrid.getHeight()); //maximum possible pixel size
+		numSteps = (int) ((int)1+ Math.floor(Math.log(neighborhoodRange)/Math.log(2)));	//calculates how many steps are needed by doubling the pixel size until neighborhoodRange is reached. It is the reverse of an exponential function, which is the logarithm of neighborhoodRange to the basis 2. 2 is added because the calculation starts with 1 and not with 2 (1,2,4,8,16,32,...) and an array starts with 0.
+		statusOut.println("Maximum pixel size (as multiple of original resolution): "+neighborhoodRange);
+		statusOut.println("Number of steps: "+numSteps);
+		
+	}
+
+	/**
+	* like in every model: frees the resources
+	 */
+	public void performModelDispose() {
+		super.performModelDispose();
+		
+		releaseAccess(RA_referenceMap);
+		releaseAccess(RA_spreadStart);
+		releaseAccess(RA_spreadStep);
+		releaseAccess(RA_spreadEnd);
+		releaseAccess(RA_dispStart);
+		releaseAccess(RA_dispStep);
+		releaseAccess(RA_dispEnd);
+		releaseAccess(RA_breedStart);
+		releaseAccess(RA_breedStep);
+		releaseAccess(RA_breedEnd);
+		releaseAccess(RA_roadGravityStart);
+		releaseAccess(RA_roadGravityStep);
+		releaseAccess(RA_roadGravityEnd);
+		releaseAccess(RA_slopeStart);
+		releaseAccess(RA_slopeStep);
+		releaseAccess(RA_slopeEnd);
+		releaseAccess(RA_MonteCarlo);
+		releaseAccess(WA_outResults);
+		releaseAccess(WA_SumOutStep);
+	}
+
+	/**
+	 * The main method of the Urban Growth Model. For a detailed description refer to the performModelStep in 
+	 * {@link UrbanGrowthModel UrbanGrowthModel}. The difference is, that the number of steps is not based on
+	 * the years that have to be modelled. The number of steps is always 1, all parameter combinations, Monte Carlo
+	 * Iterations, and time steps are performed within this method. Those combinations are included in different
+	 * for-loops. 
+	 */
+	public void performModelStep(int stepNo) {
+		
+		//Definition of variables needed in the whole model run
+		long localStartTime = System.currentTimeMillis(); //time measure
+		Float actUrb = null;	//urban cell in the raster
+		int totalSteps = 0;
+		int runs = 0;		
+	
+		//raster dimensions
+		areaMinX = inputGrid.getMinX();
+		areaMinY = inputGrid.getMinY();
+		areaMaxX = inputGrid.getMinX() + inputGrid.getWidth() - 1;
+		areaMaxY = inputGrid.getMinY() + inputGrid.getHeight() - 1;
+		areaWidth = inputGrid.getWidth();
+		areaHeight = inputGrid.getHeight();
+			
+		// Iterate the calibration for:
+		// 1. every slope value between start and end...
+		// 2. every spread value between start und end...
+		// 3. every dispersion value between start und end...
+		// 4. every breed value between start and end...
+		
+		for(int slope = (int)slopeStart;slope <= (int)slopeEnd; slope = slope+(int)slopeStep){
+			
+			//calculate the maximum slope
+			int slopeMax = 0;
+			slopeMax = getSlopeMax();
+			
+			statusOut.println("Max. Slope: "+slopeMax+" %");
+					
+			//assigns for every slope value between 0 and the maximum slope that is below the critical slope the value calculated for the variable "lookup".
+			//all values higher than the critical slope become 1
+
+			int MaxSlopeResistance = 100;	//Max slope resistance is 100%
+			double exp = getSlopeExp(slope,MaxSlopeResistance);	//calculate the exp value based on the actual slope
+			slopeLUT = getSlopeLookup(slopeMax,exp,criticalSlope);	//generate the lookup-table based on the actual exp-value
+			
+			for(int spread = (int)spreadStart; spread <= (int)spreadEnd; spread = spread+(int)spreadStep){
+				for(int disp = (int)dispStart; disp <= (int)dispEnd; disp = disp+(int)dispStep){
+					for(int breed = (int)breedStart; breed <= (int)breedEnd+1; breed = breed+(int)breedStep){
+						for(int roadGravity = (int)roadGravityStart; roadGravity <=(int)roadGravityEnd; roadGravity = roadGravity+(int)roadGravityStep){	
+									
+							//Here the original model algorithm starts. By calibrating the model each parameter combination
+							//is being iterated, so the algorithm is performed n-times. Because a lot of random values are
+							// in the model, each step should be performed a Monte Carlo number of times. The results are 
+							// averaged at the end of the algorithm. 
+							//
+							runs++;
+							mrvTempResultArray = new float[numSteps+2];
+							finalArray = new float[numSteps+2];
+														
+							//coefficient calculations of for growth rules
+							max_RG_value = 100.0;			//Maximum possible road gravity value
+							double disp_value = Math.round((disp*0.005)* Math.sqrt(Math.pow(inputGrid.getWidth(), 2)+(Math.pow(inputGrid.getHeight(), 2))));
+							double rg_value = Math.round((roadGravity/max_RG_value)*((areaWidth + areaHeight)/16));
+							statusOut.println("RG"+roadGravity+" / MaxRG:"+max_RG_value+" * (Width"+areaWidth+" + areaHeight"+areaHeight+") / 16");
+							
+							max_search_index = Math.round(4*((int)rg_value*(1+(int)rg_value)));	//area in which to look for a road cell
+							statusOut.println("MaxSearchIndex: "+max_search_index);
+														
+							for(int MC = 1; MC <= MonteCarlo; MC++){	//perform the model algoith 1-MC times
+								statusOut.println("Performing "+MonteCarlo+" Monte Carlo Iterations (years: "+stepNo);
+								totalSteps++;
+								/**
+								 * The model run is being performed for every time step. For the final evaluation 
+								 * only the image of the final step is needed.
+								 */
+								for(int timeSteps = 1;timeSteps <=years;timeSteps++){	
+									statusOut.println("Year "+timeSteps);
+									boolean[][] tmpGrid = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+									
+									/*****************************************************************
+									 * DISPERSION and BREED (Growth Phase 1 and 2)
+									 *****************************************************************/
+									boolean[][] tmpGridDisp = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+									tmpGridDisp = DispersionGrowth(disp_value,breed);	//calls the method "DispersionBreed" to perform the Dispersion and Breed Growth Phase
+									int anzDispBreed = 0;	//number of cells urbanized by Dispersion and Breed
+									for (int x = 0; x < inputGrid.getWidth();x++)
+										for(int y = 0; y < inputGrid.getHeight();y++){
+											int X = inputGrid.getMinX() + x;
+											int Y = inputGrid.getMinY() + y;
+											if (tmpGridDisp[X][Y]==true){
+												anzDispBreed++;
+												tmpGrid[X][Y] = true;	//write the temporary Dispersion and Breed Cells to the overall temporary Cell array
+											}		
+										}
+									statusOut.println("Number of Spontaneous and New Spreading Center Cells: "+anzDispBreed);
+									writeToGrid(tmpGrid);	//calls the method "writeToGrid" to write the new urbanized cells to the output grid
+									
+									/*********************************************************************
+									 * EDGE
+									 *********************************************************************/
+									boolean[][] tmpGridSpread = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+									tmpGridSpread = EdgeGrowth(spread);	//calls the method "EdgeGrowth" to perform the Spread (Edge Growth) Phase
+									int anzSpread = 0;	//number of cells urbanized by Spread
+									for (int x = 0; x < inputGrid.getWidth();x++)
+										for(int y = 0; y < inputGrid.getHeight();y++){
+											int X = inputGrid.getMinX() + x;
+											int Y = inputGrid.getMinY() + y;
+											if (tmpGridSpread[X][Y]==true){
+												anzSpread++;
+												tmpGrid[X][Y] = true;	//write the temporary Spread cells to the overall temporary Cell array
+											}		
+										}
+									statusOut.println("Number of Edge Growth Cells: "+anzSpread);
+									writeToGrid(tmpGrid);	//calls the method "writeToGrid" to write the new urbanized cells to the output grid
+								
+									/*********************************************************************
+									 * ROAD
+									 *********************************************************************/
+									boolean[][] tmpGridRoad = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+									statusOut.println("Start Road Growth...");
+									tmpGridRoad = RoadGrowth(tmpGrid,rg_value,breed,disp);	//calls the method "RoadGrowth" to perform the Road weighted growth
+									statusOut.println("Road things returned...");
+									int anzRoad = 0;	//number of cells urbanized by Road Growth
+									for (int x = 0; x < inputGrid.getWidth();x++)
+										for(int y = 0; y < inputGrid.getHeight();y++){
+											int X = inputGrid.getMinX() + x;
+											int Y = inputGrid.getMinY() + y;
+											if (tmpGridRoad[X][Y]==true){
+												anzRoad++;
+												tmpGrid[X][Y] = true;	//write the temporary Road Growth cells to the overall temporary Cell array
+											}		
+										}
+									statusOut.println("Number of Road Growth Cells: "+anzRoad);
+									writeToGrid(tmpGrid);	//calls the method "writeToGrid" to write the new urbanized cells to the output grid
+
+									// Here the main modeling algorithm ends. Next the temporary raster is written in the output raster. 
+									//With the outputGrid the next time step is calculated until the maximum number of time steps
+									//is reached. After that the next Monte Carlo iteration is performed for the specific parameter combination. 									
+									
+									// Write the temporary Grid to the Output Grid
+									int anzGesamt = 0;
+									for (int y = 1; y < inputGrid.getHeight()-1;y++ ) {
+										for (int x = 1; x < inputGrid.getWidth()-1; x++ ) {
+											
+											int X = inputGrid.getMinX() + x;
+											int Y = inputGrid.getMinY() + y;
+										
+											if (tmpGrid[x][y] == true)
+												anzGesamt++;
+											
+											boolean lebt = outputGrid.getRasterSampleAsFloat(X , Y ) > 0f;	//a cell is alive, when it is 1
+											if (tmpGrid[x][y] == false)	//if there is nothing in the temporary raster
+												tmpGrid[x][y] = lebt;	//take the values from the current output raster
+										
+											outputGrid.setRasterSample( tmpGrid[x][y] ? 1f : 0f ,X ,Y);	//write the results in the output raster
+											actUrb  = (Float)outputGrid.getRasterSample(x,y);	//the actual urban extent
+										}
+									}
+									statusOut.println("Urban pixels at step "+timeSteps+": "+anzGesamt);
+									
+									if (timeSteps == years){
+										outStep.addGrid();	//add a raster to the GridList
+										
+										// Write the temporary Grid to the Output Grid
+										for (int y = 1; y < inputGrid.getHeight()-1;y++ ) {
+											for (int x = 1; x < inputGrid.getWidth()-1; x++ ) {
+												actUrb  = (Float)outputGrid.getRasterSample(x,y);	//the actual urban extent
+												outStep.getGrid(MC-1).setRasterSample(actUrb,x,y);	//put the layer in the raster list containing the step results
+											}
+										}
+										WritableGrid simulationMap = outStep.getGrid(MC-1);		//write the final step result to the grid list
+										float[] mrv = MultipleResolutionComparison(simulationMap);	//perform the MRV
+										for(int i = 0;i < mrv.length;i++){
+											statusOut.println(mrv[i]);
+											mrvTempResultArray[i] += mrv[i];
+										}
+									}
+								}	//END OF THE TIME STEPS
+								
+								if (MC == MonteCarlo){
+									SumOutStep.addGrid();	//add a final raster to the GridList (contains the sum of all iterations)
+									
+									//statusOut.println("Step Grids: "+outStep.getGridCount());
+									
+									for (int y = 1; y < inputGrid.getHeight()-1;y++ ) {
+										for (int x = 1; x < inputGrid.getWidth()-1; x++ ) {	//for every pixel...
+											float sumUrb = 0; 	//sum of pixel values
+											for (int gridNo = 0; gridNo < MC; gridNo++){	//look in every grid of the GridList
+												float tempUrb = (Float) outStep.getGrid(gridNo).getRasterSample(x,y);	//take the pixel value
+												sumUrb  += tempUrb;		//and add its value
+											}
+											SumOutStep.getGrid(runs-1).setRasterSample(sumUrb,x,y);	//put the layer in the raster list containing the step results
+										}
+									}
+									
+									System.out.print("Slope: "+slope+" Spread: "+spread+" Disp: "+disp+" Breed: "+breed+" Road: "+roadGravity+" : ");
+									
+									for(int i = 0;i < mrvTempResultArray.length-2;i++){
+										//print every element of the result array comma separated in one line in the status output
+										finalArray[i] = mrvTempResultArray[i]/MonteCarlo;
+										System.out.print(finalArray[i]+",");
+									}
+									System.out.print("//Weighted Averages (FT, WA): ");
+									for(int j = 0;j < 2;j++){
+										//print every element of the result array comma separated in one line in the status output
+										finalArray[numSteps+j] = mrvTempResultArray[j]/MonteCarlo;
+										System.out.print(finalArray[j]+",");
+									}
+									for (int grids = MC-1; grids >= 0; grids--){
+										outStep.removeGrid(grids); 				//empty GridList
+									}
+									//statusOut.println("Step Grids nach leeren: "+outStep.getGridCount());
+							
+								} 
+								countSetIndividuals();
+								
+							}	System.out.println("");
+							
+							//END OF THE MONTE CARLO ITERATIONS
+						}	//END OF ROADGRAVITY COMBINATION
+					}	//END OF BREED COMBINATION
+				}	//END OF DISP COMBINATION
+			}	//END OF SPREAD COMBINATION
+		}	//END OF SLOPE COMBINATION
+		System.out.println("Finished "  + " in " + ((System.currentTimeMillis() - localStartTime)) + " ms\n");
+	}	//END OF MODEL STEP
+	
+	/**
+	 * <b>MULTIPLE RESOLUTION VALIDATION</b><br>
+	 * When all time steps are run, the result is being evaluated. Therefore the 
+	 * Multiple Resolution Comparison is chosen (refer to ostanza(1989), Pontius (2002), 
+	 * Pontius et al. (2005), Lesschen et al. (2005), Pontius et al. (2008a), Pontius et al. (2008b))
+	 * For the original SLEUTH model a number of landscape measures are used for validation
+	 * (refer to Clarke et al. (1997), Dietzel et al. (2007)), like e.g. the LeeSallee
+	 * or OSM. Because the same method (MRV) is used within XULU to compare the results of different models,
+	 * it was also chosen to evaluate the performance of the different calibration steps of the Urban Growth Model.
+	 */
+	public float[] MultipleResolutionComparison(WritableGrid simulationMap){
+		//Variablendefinitionen
+		int RoverallSum = 0; //Total number of pixels in Reference Map
+		int RnumClasses = 0; //Total number of classes in Reference Map
+		int SoverallSum = 0; //Total number of pixels in Simulation Map
+		int SnumClasses = 0; //Total number of classes in Simulation Map
+		int correct = 0;	//Number of pixels counted correct
+		double fractionCorrect = 0f;	//Fraction correct
+//		int numSteps = 0;
+							
+	//	neighborhoodRange = (int) Math.sqrt(referenceMap.getWidth()*referenceMap.getHeight()); //maximum possible pixel size
+	//	numSteps = (int) ((int)1+ Math.floor(Math.log(neighborhoodRange)/Math.log(2)));	//calculates how many steps are needed by doubling the pixel size until neighborhoodRange is reached. It is the reverse of an exponential function, which is the logarithm of neighborhoodRange to the basis 2. 2 is added because the calculation starts with 1 and not with 2 (1,2,4,8,16,32,...) and an array starts with 0.
+	//	statusOut.println("Maximum pixel size (as multiple of original resolution): "+neighborhoodRange);
+	//	statusOut.println("Number of steps: "+numSteps);
+		resultArray = new float[numSteps+2];
+		
+		for (int x = 0; x < referenceMap.getWidth(); x++)
+			for (int y = 0; y < referenceMap.getHeight(); y++) {
+				float Rtmp = referenceMap.getRasterSampleAsFloat(x, y); //get value of each raster cell in reference map
+				float Stmp = simulationMap.getRasterSampleAsFloat(x, y);//get value of each raster cell in simulation map
+				if (!Float.isNaN(Rtmp) && !Float.isNaN(Stmp)){	//if the value is a number, continue ...
+					RoverallSum ++;		//count all cells in reference map
+					SoverallSum ++;		//count all cells in simulation map
+					if (Rtmp > RnumClasses)
+						RnumClasses = (int) Rtmp;	//Number of classes in reference map. If a higher cell value is detected than the actual RnumClasses, the number of classes is increased to that value
+					if (Stmp > SnumClasses)
+						SnumClasses = (int) Stmp;	//see RnumClasses
+					if (Rtmp == Stmp)
+						correct++;		//if the same cell value is detected in the simulation and the reference map, increase the number of correct pixels
+				}
+		}
+		fractionCorrect = (double) correct / (double) RoverallSum;	//divide the number of correct pixels by the number of total pixels
+		
+		//Counts pixels per class
+		for (int i = 1; i <= RnumClasses; i++){		//Loop, until you reach the total number of classes
+			int Rj = 0;		//Number of classes in Reference Map
+			int Sj = 0;		//Number of classes in Simulation Map
+			for (int x = 0; x < referenceMap.getWidth(); x++)
+				for (int y = 0; y < referenceMap.getHeight(); y++){
+					float Rtmp = referenceMap.getRasterSampleAsFloat(x, y);	//get value of each raster cell in reference map
+					float Stmp = simulationMap.getRasterSampleAsFloat(x, y);//get value of each raster cell in simulation map
+					if (!Float.isNaN(Rtmp))
+						if ((int) Rtmp == i)
+							Rj++;	//if cell belongs to category i, count it (for Reference map)
+					if (!Float.isNaN(Stmp))
+						if ((int) Stmp == i)
+							Sj++;	//if cell belongs to category i, count it (for Simulation map)
+				}
+			statusOut.println("Class "+i+": Reference("+Rj+"), Simulation("+Sj+")");
+		}
+		
+		int ngrids = 0;		//number of resolution grids
+		float Vg = 0f;	//sum of the individual cell weights for the calculation of the average weighted fit after Pontius (2002)
+		float VgWeights = 0f;	//sum of the cell weights
+		float WeightedAgreement = 0f;	//total weighted agreement over all resolutions after Pontius (2002)
+		for (int r = 1; r <= neighborhoodRange; r = r+r){	//for pixel size 1 up to the maximum pixel size, where one large cell covers the whole area
+			//statusOut.println(r);
+			ngrids++;		//count the number of grids
+			float SumWn = 0f;	//Sum of the weighted means 
+			int SumCells = 0;	//Number of the cells
+			float totalAgreement = 0f;	//total agreement is the weighted mean of the fraction correct over all resolution grids
+			for (int x = 0; x < referenceMap.getWidth(); x = x+r)	//for every pixel size...
+				for (int y = 0; y < referenceMap.getHeight(); y = y+r){
+					int nCells = 0;		//number of cells making up a coarse cell
+					float SumMinRS = 0f;	//when two maps are compared, the minimum value is taken (MIN), this value is the sum of all these MINs
+					float Wn = 0;	//weighted cell
+					for(int x2 = x; x2 < x+r; x2++)	//for every cell within a coarse cell...
+						for(int y2 = y; y2 < y+r; y2++){
+							if ( x2 < referenceMap.getMinX() || y2 < referenceMap.getMinY() || x2 > referenceMap.getMinX()+referenceMap.getWidth()-1 || y2 > referenceMap.getMinY()+referenceMap.getHeight()-1 ||
+									Float.isNaN(referenceMap.getRasterSampleAsFloat(x2,y2)))
+								continue;
+							nCells++;	//count all cells that have a value
+						}
+					for (int i = 0; i <= RnumClasses; i++){	//for every class i
+						int Rn = 0;		//Number of cells in the reference map
+						int Sn = 0;		//Number of cells in the simulation map
+						float Rnj = 0f;	//Portion of cells in the reference map
+						float Snj = 0f;	//Portion of cells in the simulation map
+						float MinRS = 0f;	//Both maps are compared and the Minimum (MIN) for each cell taken
+						for(int x3 = x; x3 < x+r; x3++)	//for every cell within a coarse cell...
+							for(int y3 = y; y3 < y+r; y3++){
+								if ( x3 < referenceMap.getMinX() || y3 < referenceMap.getMinY() || x3 > referenceMap.getMinX()+referenceMap.getWidth()-1 || y3 > referenceMap.getMinY()+referenceMap.getHeight()-1 ||
+										Float.isNaN(referenceMap.getRasterSampleAsFloat(x3,y3)))
+									continue;
+								float Rtmp = referenceMap.getRasterSampleAsFloat(x3, y3);	//get value of each cell in the reference map
+								float Stmp = simulationMap.getRasterSampleAsFloat(x3, y3);	//get value of each cell in the simulation map
+								if ((int) Rtmp == i)
+									Rn++;	//count all cells that belong to class i in reference map 
+								if ((int) Stmp == i)
+									Sn++;	//count all cells that belong to class i in simulation map
+							}
+						if(nCells > 0){	//if positive cells are available...
+							Rnj = (float)Rn / (float)nCells;	//compute the portion of these cells within a coarse cell in the reference map
+							Snj = (float)Sn / (float)nCells;	//compute the portion of these cells within a coarse cell in the simulation map
+						}
+						MinRS = Math.min(Rnj, Snj);	//take for every coarse cell the MIN between R and S of the portion of class i
+						SumMinRS += MinRS;	//Sum all the MIN values
+						
+					}
+					Wn = (float)nCells * SumMinRS;	//all coarse cells are weighted by multiplying the Sum of all MIN values with the number of cells that make up a coarse cell
+										
+					SumCells += (float)nCells;	//Sum all positive cells in a resolution grid
+					SumWn += Wn;	//Sum all weighted portions in a resolution grid
+				}
+			
+			//Total Agreement:
+			//statusOut.println(SumWn+" / "+SumCells);
+			totalAgreement = SumWn / (float)SumCells;	//Main Results
+			//statusOut.println(totalAgreement);	
+			outResults.addValue(totalAgreement);
+			//resultArray[0][ngrids-1] = r;
+			resultArray[ngrids-1] = totalAgreement;	//write the results in an array 
+			//the result array looks like this:
+			//1	   |2	 |4	   |8    |...
+			//0.876|0.892|0.913|0.948|...
+			Vg += SumWn * totalAgreement;
+			VgWeights += SumWn;
+		}
+		
+		//From here on the results of the Multiple Resolution Comparison are written on the screen
+		
+		//those variables are needed to compute the weighted average of all fits after Costanza (1989)
+		float w = 0f;	//weight depending on resolution
+		float Fw = 0f;	//weighted fit at certain resolution
+		float SumW = 0f;	//Sum of all weights
+		float SumFw = 0f;	//Sum of all weighted agreements
+		float Ft = 0f;
+		
+		for(int i = 0; i <= ngrids-1; i++){
+//			System.out.print(resultArray[i]+",");
+			//calculations for weighted average after Costanza (1989):
+			w = (float) Math.exp(-0.1*(resultArray[i] - 1));
+			Fw = resultArray[i]*w;
+			SumW += w;
+			SumFw += Fw;
+		}
+		
+		Ft = SumFw / SumW;	//Final calculation of the weighted average of all fits after Costanza (1989)
+		WeightedAgreement = Vg / VgWeights;	//Final calculation of the weighted average of all fits after Pontius (2002)
+		
+//		System.out.print("Ft:"+Ft+",TA:"+WeightedAgreement);	//the result is written directly behind the single fits for every resolution
+		resultArray[numSteps] = Ft;
+//		System.out.println("");
+//		System.out.println(resultArray[numSteps+1]);
+		resultArray[numSteps+1] = WeightedAgreement;
+//		System.out.println(resultArray[numSteps+2]);
+		return resultArray;	
+	}
+}

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationContentManager.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationContentManager.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationContentManager.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,53 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ListProperty;
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.data.XuluDataException;
+import edu.bonn.xulu.model.DefaultModelResource;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+
+public class UrbanGrowthModelCalibrationContentManager extends UrbanGrowthModelContentManager {
+	
+	public UrbanGrowthModelCalibrationContentManager(int additionalRes) {
+		super(14+additionalRes);	//14, because in the parent class are 12 resources (+14 = 26)
+	    
+	    resource[6] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Reference Grid",ScalarProperty.class,WritableGrid.class,false);
+	    resource[7] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Spread Coefficient Start",ScalarProperty.class,Double.class,false);
+	    resource[8] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Spread Coefficient Step",ScalarProperty.class,Double.class,false);
+	    resource[9] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Spread Coefficient End",ScalarProperty.class,Double.class,false);
+	    resource[10]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Dispersion Coefficient Start",ScalarProperty.class,Double.class,false);
+	    resource[11]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Dispersion Coefficient Step",ScalarProperty.class,Double.class,false);
+	    resource[12]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Dispersion Coefficient End",ScalarProperty.class,Double.class,false);
+	    resource[13]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Breed Coefficient Start",ScalarProperty.class,Double.class,false);
+	    resource[14]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Breed Coefficient Step",ScalarProperty.class,Double.class,false);
+	    resource[15]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Breed Coefficient End",ScalarProperty.class,Double.class,false);
+	    resource[16]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"RoadGravity Coefficient Start",ScalarProperty.class,Double.class,false);
+	    resource[17]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"RoadGravity Coefficient Step",ScalarProperty.class,Double.class,false);
+	    resource[18]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"RoadGravity Coefficient End",ScalarProperty.class,Double.class,false);
+	    resource[19]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Coefficient Start",ScalarProperty.class,Double.class,false);
+	    resource[20]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Coefficient Step",ScalarProperty.class,Double.class,false);
+	    resource[21]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Coefficient End",ScalarProperty.class,Double.class,false);
+	    resource[22]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical Slope",ScalarProperty.class,Double.class,false);
+	    resource[23]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Number of MonteCarlo Iterations",ScalarProperty.class,Integer.class,false);
+	    resource[24]= new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Validation Results",ListProperty.class,Float.class,false);
+	    resource[25]= new DefaultModelResource(ModelResource.CATEGORY_OUTPUT,"Step Results",MultiGrid.class,false);
+	    resource[26]= new DefaultModelResource(ModelResource.CATEGORY_OUTPUT,"Sum Step Results",MultiGrid.class,false);
+	 	// ===== Ressourcen Bezeichnungen lokalisieren =====
+	    resetCaptions(null);
+	}
+
+	public UrbanGrowthModelCalibrationContentManager() {
+		this(0);
+		
+	}
+	
+	@Override
+	public void checkAndError() throws XuluDataException {
+		// TODO Auto-generated method stub
+		super.checkAndError();
+	}
+}

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationSelfModification.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationSelfModification.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationSelfModification.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,428 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import edu.bonn.xulu.model.XuluModel;
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.PropertyReadAccess;
+import schmitzm.data.property.ScalarProperty;
+
+/**
+ * <b>Calibration of the Urban Growth Model with Self Modification</b><br>
+ *  This model is based on the {@link UrbanGrowthModelCalibration Urban Growth Model Calibration}, which is a deviation of the {@link UrbanGrowthModel Urban Growth Model} developed by Keith Clarke at the UC Santa Barbara, CA, 
+ *  within the Gigalopolis Project, funded by the USGS. In addition to the calibration routine a number of main input parameters is modified during each time step. When the growth rate exceeds or falls below certain
+ *  critical values the coefficients are modified. For a detailed description refer to the <a href="http://www.ncgia.ucsb.edu/projects/gig/v2/About/gwSelfMod.htm">SLEUTH Homepage</a>.
+ *  
+ *  <br>
+ *  In addition to the UGM Calibration Coefficients, these parameters are needed:<br>
+ * <ul>
+ *  <li><b>Road Gravity Sensitivity</b>: Influences the roadGravity coefficient</li>
+ *  <li><b>Slope Sensitivity</b>: Influences the slope coefficient</li>
+ *  <li><b>Critical Low</b>: When growth rate falls below this value, the coefficients are altered</li>
+ *  <li><b>Critical High</b>: When growth rate exceeds this value, the coefficients are altered</li>
+ *  <li><b>Boom</b>: Boom Phase. The Coefficients are increased by this value.</li>
+ *  <li><b>Bust</b>: Bust Phase. The Coefficients are decreased by this value.</li>
+ * </ul>
+ * 
+ * @see UrbanGrowthModelCalibrationSelfModificationContentManager
+ * @see UrbanGrowthModelCalibration
+ * @see UrbanGrowthModelSelfModification
+ * @see UrbanGrowthModel
+ * @see UrbanGrowthModel_MC
+ * @author <a href="mailto:goetzke at uni-bonn.de">Roland Goetzke</a>
+ * @version 1.0
+ */
+public class UrbanGrowthModelCalibrationSelfModification extends UrbanGrowthModelCalibration {
+
+	// ********** Read/Write access, that has to be maintained ***
+	// ********** through the whole model run ********************
+	protected PropertyReadAccess RA_roadGravSens = null;	//RoadGravity Sensitivity
+	protected PropertyReadAccess RA_slopeSens = null;	//Slope Sensitivity
+	protected PropertyReadAccess RA_criticalLow = null;	//Critical Low
+	protected PropertyReadAccess RA_criticalHigh = null;	//Critical High
+	protected PropertyReadAccess RA_Boom = null;	//Boom
+	protected PropertyReadAccess RA_Bust = null;	//Bust
+	
+	// **************** Variablen to work with *******************
+	protected double roadGravSens = 0;	//RoadGravity Sensitivity
+	protected double slopeSens = 0;	//Slope Sensitivity
+	protected double criticalLow = 0;	//critical Low
+	protected double criticalHigh = 0;	//critical High
+	protected double boom = 0;	//Boom
+	protected double bust = 0;	//Bust
+	
+	protected int slopeMax = 0;
+	protected int totalPixels = 0;
+	protected int excldCount = 0;
+	
+	/**
+	 * First Constructor
+	 * @param contManager
+	 */
+	public UrbanGrowthModelCalibrationSelfModification(UrbanGrowthModelCalibrationSelfModificationContentManager contManager) {
+		super(contManager);
+		//this.contManager = (UrbanGrowthModelCalibrationSelfModificationContentManager) super.contManager;
+	}
+	
+	/**
+	 * Second Constructor. The Content Manager is the parent content manager as well as the child content manager
+	 */
+	public UrbanGrowthModelCalibrationSelfModification(){
+		super(new UrbanGrowthModelCalibrationSelfModificationContentManager());
+	}
+
+	/**
+	 * Initializes the model. Like in the init method of every {@link XuluModel}
+	 * the resources are initalized. 
+	 */
+	public void performModelInit() {
+		super.performModelInit();
+		this.contManager = (UrbanGrowthModelCalibrationSelfModificationContentManager) super.contManager;
+	
+		RA_roadGravSens = null;
+		if (contManager.getResource(27).getData() != null)
+			RA_roadGravSens = ((ScalarProperty) contManager.getResource(27).getData())
+					.getReadAccess(this);
+		RA_slopeSens = null;
+		if (contManager.getResource(28).getData() != null)
+			RA_slopeSens = ((ScalarProperty) contManager.getResource(28).getData())
+					.getReadAccess(this);
+		RA_criticalLow = null;
+		if (contManager.getResource(29).getData() != null)
+			RA_criticalLow = ((ScalarProperty) contManager.getResource(29).getData())
+					.getReadAccess(this);
+		RA_criticalHigh = null;
+		if (contManager.getResource(30).getData() != null)
+			RA_criticalHigh = ((ScalarProperty) contManager.getResource(30).getData())
+					.getReadAccess(this);
+		RA_Boom = null;
+		if (contManager.getResource(31).getData() != null)
+			RA_Boom = ((ScalarProperty) contManager.getResource(31).getData())
+					.getReadAccess(this);
+		RA_Bust = null;
+		if (contManager.getResource(32).getData() != null)
+			RA_Bust = ((ScalarProperty) contManager.getResource(32).getData())
+					.getReadAccess(this);
+		
+		// Assign variables to work with
+		roadGravSens = RA_roadGravSens.getValueAsDouble();
+	    slopeSens = RA_slopeSens.getValueAsDouble();
+	    criticalLow = RA_criticalLow.getValueAsDouble();
+	    criticalHigh = RA_criticalHigh.getValueAsDouble();
+	    boom = RA_Boom.getValueAsDouble();
+	    bust = RA_Bust.getValueAsDouble();
+	    
+		//Calculate total amount of pixels and number of excluded pixels
+		for (int x = 0; x < inputGrid.getWidth();x++ ) 
+			for (int y = 0; y < inputGrid.getHeight(); y++ ) {
+				if ( x < inputGrid.getMinX() || y < inputGrid.getMinY() || x > inputGrid.getMinX()+inputGrid.getWidth()-1 || y > inputGrid.getMinY()+inputGrid.getHeight()-1 ||
+			            Float.isNaN(outputGrid.getRasterSampleAsFloat(x,y)) ) //ignore neighbor, if outside the raster
+			             continue;
+				totalPixels++;
+				if (areaRestr.getRasterSampleAsFloat(x,y) != 0 && !Float.isNaN(areaRestr.getRasterSampleAsFloat(x,y)))
+					excldCount++;
+			}
+	}
+
+	/**
+	* like in every model: frees the resources
+	 */
+	public void performModelDispose() {
+		super.performModelDispose();
+		//free resources
+		releaseAccess(RA_roadGravSens);
+		releaseAccess(RA_slopeSens);
+		releaseAccess(RA_criticalLow);
+		releaseAccess(RA_criticalHigh);
+		releaseAccess(RA_Boom);
+		releaseAccess(RA_Bust);
+	}
+
+	/**
+	 * The main method of the Urban Growth Model. For a detailed description refer to the performModelStep in 
+	 * {@link UrbanGrowthModel UrbanGrowthModel} and {@link UrbanGrowthModelCalibration Urban Growth Model Calibration}. 
+	 * The difference to the plain UGM Calibration model is the Self Modification of several coefficients.
+	 */
+	public void performModelStep(int stepNo) {
+
+		//Definition of variables needed in the whole model run
+		double slopeF = 0;
+		double spreadF = 0;
+		double dispF = 0;
+		double breedF = 0;
+		double roadGravityF = 0;
+		double growthRate = 0;
+		int thisYear = 0;
+		int roadCount = 0;
+		
+		//Definition of variables needed in the whole model run
+		long localStartTime = System.currentTimeMillis(); //time measure
+		Float actUrb = null;	//urban cell in the raster
+		int totalSteps = 0;
+		int runs = 0;		
+	
+		//raster dimensions
+		areaMinX = inputGrid.getMinX();
+		areaMinY = inputGrid.getMinY();
+		areaMaxX = inputGrid.getMinX() + inputGrid.getWidth() - 1;
+		areaMaxY = inputGrid.getMinY() + inputGrid.getHeight() - 1;
+		areaWidth = inputGrid.getWidth();
+		areaHeight = inputGrid.getHeight();
+			
+		// Iterate the calibration for:
+		// 1. every slope value between start and end...
+		// 2. every spread value between start und end...
+		// 3. every dispersion value between start und end...
+		// 4. every breed value between start and end...
+		
+		for(int slope = (int)slopeStart;slope <= (int)slopeEnd; slope = slope+(int)slopeStep){
+			for(int spread = (int)spreadStart; spread <= (int)spreadEnd; spread = spread+(int)spreadStep){
+				for(int disp = (int)dispStart; disp <= (int)dispEnd; disp = disp+(int)dispStep){
+					for(int breed = (int)breedStart; breed <= (int)breedEnd+1; breed = breed+(int)breedStep){
+						for(int roadGravity = (int)roadGravityStart; roadGravity <=(int)roadGravityEnd; roadGravity = roadGravity+(int)roadGravityStep){
+														
+							//Here the original model algorithm starts. By calibrating the model each parameter combination
+							//is being iterated, so the algorithm is performed n-times. Because a lot of random values are
+							// in the model, each step should be performed a Monte Carlo number of times. The results are 
+							// averaged at the end of the algorithm. 
+							//
+							runs++;
+							mrvTempResultArray = new float[numSteps+2];
+							finalArray = new float[numSteps+2];
+
+							
+														
+							for(int MC = 1; MC <= MonteCarlo; MC++){	//perform the model algoith 1-MC times
+								statusOut.println("Performing "+MonteCarlo+" Monte Carlo Iterations (MC: "+MC+")");
+								totalSteps++;
+								
+								//In every Iteration the coefficients are set to their defined values. Within an iteration those coefficients can be modified in every step. 
+								slopeF = (double)slope;		//slopeF is slope at the beginning of the loop and is modified within the loop.
+								spreadF = (double)spread;		//spreadF is spread at the beginning of the loop and is modified within the loop.
+								dispF = (double) disp;		//dispF is disp at the beginning of the loop and is modified within the loop.
+								breedF = (double)breed;	//breedF is breed at the beginning of the loop and is modified within the loop.
+								roadGravityF = (double) roadGravity;	//roadGravityF is roadGravity at the beginning of the loop and is modified within the loop.
+								
+								/**
+								 * The model run is being performed for every time step. For the final evaluation 
+								 * only the image of the final step is needed.
+								 */
+									for(int timeSteps = 1;timeSteps <=years;timeSteps++){
+									
+										statusOut.println("Year "+timeSteps);
+										boolean[][] tmpGrid = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+
+										//recalculate the slope values
+										slopeMax = getSlopeMax();
+										int MaxSlopeResistance = 100;
+										double exp = getSlopeExp(slopeF,MaxSlopeResistance);	//calculate the exp value based on the actual slope
+										slopeLUT = getSlopeLookup(slopeMax,exp,criticalSlope);	//generate the lookup-table based on the actual exp-value
+										//statusOut.println("SlopeMax, slope exp: "+slopeMax+", "+exp);
+										
+										double disp_value = Math.round((dispF*0.005)* Math.sqrt(Math.pow(inputGrid.getWidth(), 2)+(Math.pow(inputGrid.getHeight(), 2))));
+										max_RG_value = 100.0;			//Maximum possible road gravity value
+										double rg_value = Math.round((roadGravityF/max_RG_value)*((areaWidth + areaHeight)/16));
+										//statusOut.println("RG"+roadGravityF+" / MaxRG:"+max_RG_value+" * (Width"+areaWidth+" + areaHeight"+areaHeight+") / 16");
+										
+										max_search_index = Math.round(4*((int)rg_value*(1+(int)rg_value)));	//area in which to look for a road cell
+										//statusOut.println("MaxSearchIndex: "+max_search_index);
+										
+										/*****************************************************************
+										 * DISPERSION and BREED (Growth Phase 1 and 2)
+										 *****************************************************************/
+										boolean[][] tmpGridDisp = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+										tmpGridDisp = DispersionGrowth(disp_value,breedF);	//calls the method "DispersionBreed" to perform the Dispersion and Breed Growth Phase
+										int anzDispBreed = 0;	//number of cells urbanized by Dispersion and Breed
+										for (int x = 0; x < inputGrid.getWidth();x++)
+											for(int y = 0; y < inputGrid.getHeight();y++){
+												int X = inputGrid.getMinX() + x;
+												int Y = inputGrid.getMinY() + y;
+												if (tmpGridDisp[X][Y]==true){
+													anzDispBreed++;
+													tmpGrid[X][Y] = true;	//write the temporary Dispersion and Breed Cells to the overall temporary Cell array
+												}		
+											}
+										statusOut.println("Number of Spontaneous and New Spreading Center Cells: "+anzDispBreed);
+										writeToGrid(tmpGrid);	//calls the method "writeToGrid" to write the new urbanized cells to the output grid
+										
+										/*********************************************************************
+										 * EDGE
+										 *********************************************************************/
+										boolean[][] tmpGridSpread = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+										tmpGridSpread = EdgeGrowth(spread);	//calls the method "EdgeGrowth" to perform the Spread (Edge Growth) Phase
+										int anzSpread = 0;	//number of cells urbanized by Spread
+										for (int x = 0; x < inputGrid.getWidth();x++)
+											for(int y = 0; y < inputGrid.getHeight();y++){
+												int X = inputGrid.getMinX() + x;
+												int Y = inputGrid.getMinY() + y;
+												if (tmpGridSpread[X][Y]==true){
+													anzSpread++;
+													tmpGrid[X][Y] = true;	//write the temporary Spread cells to the overall temporary Cell array
+												}		
+											}
+										statusOut.println("Number of Edge Growth Cells: "+anzSpread);
+										writeToGrid(tmpGrid);	//calls the method "writeToGrid" to write the new urbanized cells to the output grid
+									
+										/*********************************************************************
+										 * ROAD
+										 *********************************************************************/
+										boolean[][] tmpGridRoad = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+										statusOut.println("Start Road Growth...");
+										tmpGridRoad = RoadGrowth(tmpGrid,rg_value,breed,disp);	//calls the method "RoadGrowth" to perform the Road weighted growth
+										statusOut.println("Road things returned...");
+										int anzRoad = 0;	//number of cells urbanized by Road Growth
+										for (int x = 0; x < inputGrid.getWidth();x++)
+											for(int y = 0; y < inputGrid.getHeight();y++){
+												int X = inputGrid.getMinX() + x;
+												int Y = inputGrid.getMinY() + y;
+												if (tmpGridRoad[X][Y]==true){
+													anzRoad++;
+													tmpGrid[X][Y] = true;	//write the temporary Road Growth cells to the overall temporary Cell array
+												}		
+											}
+										statusOut.println("Number of Road Growth Cells: "+anzRoad);
+										writeToGrid(tmpGrid);	//calls the method "writeToGrid" to write the new urbanized cells to the output grid
+
+										// Here the main modeling algorithm ends. Next the temporary raster is written in the output raster. 
+										//With the outputGrid the next time step is calculated until the maximum number of time steps
+										//is reached. After that the next Monte Carlo iteration is performed for the specific parameter combination. 									
+										
+										// Write the temporary Grid to the Output Grid
+										int anzGesamt = 0;
+										for (int y = 1; y < inputGrid.getHeight()-1;y++ ) {
+											for (int x = 1; x < inputGrid.getWidth()-1; x++ ) {
+												
+												int X = inputGrid.getMinX() + x;
+												int Y = inputGrid.getMinY() + y;
+											
+												if (tmpGrid[x][y] == true)
+													anzGesamt++;
+												
+												boolean lebt = outputGrid.getRasterSampleAsFloat(X , Y ) > 0f;	//a cell is alive, when it is 1
+												boolean road = roadGrid.getRasterSampleAsFloat(X, Y) > 0f;	//eine Zelle beinhaltet eine Straße...
+												if (tmpGrid[x][y] == false)	//if there is nothing in the temporary raster
+													tmpGrid[x][y] = lebt;	//take the values from the current output raster
+												if(lebt == true)
+													thisYear++;		//all urban cells in this year
+												if(road == true)
+													roadCount++;	//road cells
+												
+												outputGrid.setRasterSample( tmpGrid[x][y] ? 1f : 0f ,X ,Y);	//write the results in the output raster
+												actUrb  = (Float)outputGrid.getRasterSample(x,y);	//the actual urban extent
+											}
+										}
+										statusOut.println("Urban pixels at step "+timeSteps+": "+anzGesamt);
+										
+										//SELF-MODIFICATION
+										growthRate = ((float)anzGesamt / (float)thisYear)*100;	//growth rate
+										statusOut.println("Wachstumsrate: "+growthRate+", Urban: "+anzGesamt);
+										double percent_urban = (100.0 *(thisYear+roadCount) / (totalPixels-roadCount-excldCount));
+										
+										//Boom-Year
+										if(growthRate > criticalHigh){	//if the growth rate exceeds the critical high value
+											slopeF -= (float)percent_urban * (float)slopeSens;	//decrease the slope coefficient
+											if(slopeF <= 0.01)	//if it is already very low, make it 1
+												slopeF = 1.0;
+											roadGravityF += (float)percent_urban * roadGravSens;	//increase the road Gravity
+											if(roadGravityF > 100.0)
+												roadGravityF = 100.0;
+											if(dispF < 100.0){	//increase the other coefficients by multiplying with the boom parameter
+												dispF *= boom;
+												if(dispF > 100.0)
+													dispF = 100.0;
+												breedF *= boom;
+												if(breedF > 100.0)
+													breedF = 100.0;
+												spreadF *= boom;
+												if(spreadF > 100.0)
+													spreadF = 100.0;
+											}
+										}
+										
+										//Bust-Year
+										if(growthRate < criticalLow){	//if the growth rate falls below the critical low value
+											slopeF += (float)percent_urban * (float)slopeSens;	//increase the slope coefficient
+											if(slopeF > MaxSlopeResistance)
+												slopeF = MaxSlopeResistance;
+											roadGravityF -= (float)percent_urban * roadGravSens;	//decrease the road Gravity
+											if(roadGravityF <= 0.01)
+												roadGravityF = 1.0;
+											if(growthRate < criticalLow && dispF > 0){	//decrease the other coefficients by multiplying with the bust parameter
+												dispF *= bust;
+												if(dispF <= 0.01)
+													dispF = 1.0;
+												spreadF *= bust;
+												if(spreadF <= 0.01)
+													spreadF = 1.0;
+												breedF *= bust;
+												if(breedF <= 0.01)
+													breedF = 1.0;
+											}
+										}
+										
+										
+										if (timeSteps == years){
+											outStep.addGrid();	//add a raster to the GridList
+											
+											// Write the temporary Grid to the Output Grid
+											for (int y = 1; y < inputGrid.getHeight()-1;y++ ) {
+												for (int x = 1; x < inputGrid.getWidth()-1; x++ ) {
+													actUrb  = (Float)outputGrid.getRasterSample(x,y);	//the actual urban extent
+													outStep.getGrid(MC-1).setRasterSample(actUrb,x,y);	//put the layer in the raster list containing the step results
+												}
+											}
+											WritableGrid simulationMap = outStep.getGrid(MC-1);		//write the final step result to the grid list
+											float[] mrv = MultipleResolutionComparison(simulationMap);	//perform the MRV
+											for(int i = 0;i < mrv.length;i++){
+												statusOut.println(mrv[i]);
+												mrvTempResultArray[i] += mrv[i];
+											}
+										}
+									}	//END OF THE TIME STEPS
+									
+									if (MC == MonteCarlo){
+										SumOutStep.addGrid();	//add a final raster to the GridList (contains the sum of all iterations)
+										
+										//statusOut.println("Step Grids: "+outStep.getGridCount());
+										
+										for (int y = 1; y < inputGrid.getHeight()-1;y++ ) {
+											for (int x = 1; x < inputGrid.getWidth()-1; x++ ) {	//for every pixel...
+												float sumUrb = 0; 	//sum of pixel values
+												for (int gridNo = 0; gridNo < MC; gridNo++){	//look in every grid of the GridList
+													float tempUrb = (Float) outStep.getGrid(gridNo).getRasterSample(x,y);	//take the pixel value
+													sumUrb  += tempUrb;		//and add its value
+												}
+												SumOutStep.getGrid(runs-1).setRasterSample(sumUrb,x,y);	//put the layer in the raster list containing the step results
+											}
+										}
+										
+										System.out.print("Slope: "+slope+" Spread: "+spread+" Disp: "+disp+" Breed: "+breed+" Road: "+roadGravity+" : ");
+										
+										for(int i = 0;i < mrvTempResultArray.length-2;i++){
+											//print every element of the result array comma separated in one line in the status output
+											finalArray[i] = mrvTempResultArray[i]/MonteCarlo;
+											System.out.print(finalArray[i]+",");
+										}
+										System.out.print("//Weighted Averages (FT, WA): ");
+										for(int j = 0;j < 2;j++){
+											//print every element of the result array comma separated in one line in the status output
+											finalArray[numSteps+j] = mrvTempResultArray[j]/MonteCarlo;
+											System.out.print(finalArray[j]+",");
+										}
+										for (int grids = MC-1; grids >= 0; grids--){
+											outStep.removeGrid(grids); 				//empty GridList
+										}
+										//statusOut.println("Step Grids nach leeren: "+outStep.getGridCount());
+								
+									} 
+									countSetIndividuals();
+									
+								}	System.out.println("");
+								
+								//END OF THE MONTE CARLO ITERATIONS
+							}	//END OF ROADGRAVITY COMBINATION
+						}	//END OF BREED COMBINATION
+					}	//END OF DISP COMBINATION
+				}	//END OF SPREAD COMBINATION
+			}	//END OF SLOPE COMBINATION
+			System.out.println("Finished "  + " in " + ((System.currentTimeMillis() - localStartTime)) + " ms\n");
+		}	//END OF MODEL STEP
+}
\ No newline at end of file

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationSelfModificationContentManager.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationSelfModificationContentManager.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelCalibrationSelfModificationContentManager.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,34 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.data.XuluDataException;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+
+
+public class UrbanGrowthModelCalibrationSelfModificationContentManager extends UrbanGrowthModelCalibrationContentManager {
+	
+	public UrbanGrowthModelCalibrationSelfModificationContentManager(int additionalRes) {
+		super(6+additionalRes);
+	    
+		resource[27]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Road Gravity Sensitivity",ScalarProperty.class,Double.class,false);
+	    resource[28]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Sensitivity",ScalarProperty.class,Double.class,false);
+	    resource[29]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical Low",ScalarProperty.class,Double.class,false);
+	    resource[30]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical High",ScalarProperty.class,Double.class,false);
+	    resource[31]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Boom",ScalarProperty.class,Double.class,false);
+	    resource[32]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Bust",ScalarProperty.class,Double.class,false);
+
+	 	// ===== Ressourcen Bezeichnungen lokalisieren =====
+	    resetCaptions(null);
+	}
+	
+	public UrbanGrowthModelCalibrationSelfModificationContentManager(){
+		this(0);
+	}
+	
+	@Override
+	public void checkAndError() throws XuluDataException {
+		// TODO Auto-generated method stub
+		super.checkAndError();
+	}
+}

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelContentManager.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelContentManager.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelContentManager.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,45 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.data.XuluDataException;
+import edu.bonn.xulu.model.AbstractModelContentManager;
+import edu.bonn.xulu.model.DefaultModelResource;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+public class UrbanGrowthModelContentManager extends AbstractModelContentManager {
+	
+	public UrbanGrowthModelContentManager(int additionalRes) {
+		super(13+additionalRes);
+		
+		resource[0] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Number of steps",ScalarProperty.class,Integer.class,false);
+		resource[1] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Input Grid",ScalarProperty.class,WritableGrid.class,false);
+		resource[2] = new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Output Grid",ScalarProperty.class,WritableGrid.class,false);
+		resource[3] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Area Restrictions",ScalarProperty.class,WritableGrid.class,false);
+		resource[4] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Road Grid",ScalarProperty.class,WritableGrid.class,false);
+		resource[5] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Grid",ScalarProperty.class,WritableGrid.class,false);
+	    resource[6] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Spread Coefficient",ScalarProperty.class,Double.class,false);
+	    resource[7]	= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Dispersion Coefficient",ScalarProperty.class,Double.class,false);
+	    resource[8]	= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Breed Coefficient",ScalarProperty.class,Double.class,false);
+	    resource[9] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"RoadGravity Coefficient",ScalarProperty.class,Double.class,false);
+	    resource[10]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Coefficient",ScalarProperty.class,Double.class,false);
+	    resource[11]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical Slope",ScalarProperty.class,Double.class,false);
+	    resource[12]= new DefaultModelResource(ModelResource.CATEGORY_OUTPUT,"Step Results",MultiGrid.class,false);
+	    
+	 	// ===== Ressourcen Bezeichnungen lokalisieren =====
+	    resetCaptions(null);
+	}
+	
+	public UrbanGrowthModelContentManager() {
+		this(0);
+	}
+	
+	
+	@Override
+	public void checkAndError() throws XuluDataException {
+		// TODO Auto-generated method stub
+		super.checkAndError();
+	}
+}

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModification.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModification.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModification.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,308 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import edu.bonn.xulu.model.XuluModel;
+import schmitzm.data.property.PropertyReadAccess;
+import schmitzm.data.property.ScalarProperty;
+
+/**
+ *  <b>Urban Growth Model with Self Modification</b><br>
+ *  This model is based on the {@link UrbanGrowthModel Urban Growth Model}, developed by Keith Clarke at the UC Santa Barbara, CA, within the Gigalopolis Project, funded by the
+ *  USGS. It has exactly the same growth rules as its parent class, with Self Modification of several coefficients enabled.
+ *  For a detailed description refer to {@link UrbanGrowthModel Urban Growth Model}
+ *  
+ * <br>
+ * In addition to the UGM Coefficients, these parameters are needed:<br>
+ * <ul>
+ *  <li><b>Road Gravity Sensitivity</b>: Influences the roadGravity coefficient</li>
+ *  <li><b>Slope Sensitivity</b>: Influences the slope coefficient</li>
+ *  <li><b>Critical Low</b>: When growth rate falls below this value, the coefficients are altered</li>
+ *  <li><b>Critical High</b>: When growth rate exceeds this value, the coefficients are altered</li>
+ *  <li><b>Boom</b>: Boom Phase. The Coefficients are increased by this value.</li>
+ *  <li><b>Bust</b>: Bust Phase. The Coefficients are decreased by this value.</li>
+ * </ul>
+ * 
+ * @see UrbanGrowthModelSelfModificationContentManager
+ * @see UrbanGrowthModel
+ * @author <a href="mailto:goetzke at uni-bonn.de">Roland Goetzke</a>
+ * @version 1.0
+ */
+public class UrbanGrowthModelSelfModification extends UrbanGrowthModel {
+
+	//protected UrbanGrowthModelSelfModificationContentManager contManager;
+
+	// ********** Read/Write access, that has to be maintained ***
+	// ********** through the whole model run ********************
+	private PropertyReadAccess RA_roadGravSens = null;	//RoadGravity Sensitivity
+	private PropertyReadAccess RA_slopeSens = null;	//Slope Sensitivity
+	private PropertyReadAccess RA_criticalLow = null;	//Critical Low
+	private PropertyReadAccess RA_criticalHigh = null;	//Critical High
+	private PropertyReadAccess RA_Boom = null;	//Boom
+	private PropertyReadAccess RA_Bust = null;	//Bust
+
+	//**************** Variables to work with *******************
+	protected double roadGravSens = 0;	//RoadGravity Sensitivity
+	protected double slopeSens = 0;	//Slope Sensitivity
+	protected double criticalLow = 0;	//critical Low
+	protected double criticalHigh = 0;	//critical High
+	protected double boom = 0;	//Boom
+	protected double bust = 0;	//Bust
+		
+	private int slopeMax = 0;
+	private int totalPixels = 0;
+	private int excldCount = 0;
+	
+	/**
+	 * First Constructor
+	 * @param contManager
+	 */
+	public UrbanGrowthModelSelfModification(UrbanGrowthModelSelfModificationContentManager contManager) {
+		super(contManager);
+	//	this.contManager = (UrbanGrowthModelSelfModificationContentManager) super.contManager;
+	}
+	/**
+	 * Second Constructor. The Content Manager is the parent content manager as well as the child content manager
+	 */
+	public UrbanGrowthModelSelfModification(){
+		super(new UrbanGrowthModelSelfModificationContentManager());
+	}
+
+	
+	/**
+	 * Initializes the model. Like in the init method of every {@link XuluModel}
+	 * the resources are initalized. 
+	 */
+	public void performModelInit() {
+		super.performModelInit();
+		
+		RA_roadGravSens = null;
+		if (contManager.getResource(13).getData() != null)
+			RA_roadGravSens = ((ScalarProperty) contManager.getResource(13).getData())
+					.getReadAccess(this);
+		RA_slopeSens = null;
+		if (contManager.getResource(14).getData() != null)
+			RA_slopeSens = ((ScalarProperty) contManager.getResource(14).getData())
+					.getReadAccess(this);
+		RA_criticalLow = null;
+		if (contManager.getResource(15).getData() != null)
+			RA_criticalLow = ((ScalarProperty) contManager.getResource(15).getData())
+					.getReadAccess(this);
+		RA_criticalHigh = null;
+		if (contManager.getResource(16).getData() != null)
+			RA_criticalHigh = ((ScalarProperty) contManager.getResource(16).getData())
+					.getReadAccess(this);
+		RA_Boom = null;
+		if (contManager.getResource(17).getData() != null)
+			RA_Boom = ((ScalarProperty) contManager.getResource(17).getData())
+					.getReadAccess(this);
+		RA_Bust = null;
+		if (contManager.getResource(18).getData() != null)
+			RA_Bust = ((ScalarProperty) contManager.getResource(18).getData())
+					.getReadAccess(this);
+
+		// Variables to work with
+	    roadGravSens = RA_roadGravSens.getValueAsDouble();
+	    slopeSens = RA_slopeSens.getValueAsDouble();
+	    criticalLow = RA_criticalLow.getValueAsDouble();
+	    criticalHigh = RA_criticalHigh.getValueAsDouble();
+	    boom = RA_Boom.getValueAsDouble();
+	    bust = RA_Bust.getValueAsDouble();
+
+	  //Calculate total amount of pixels and number of excluded pixels
+		for (int x = 0; x < inputGrid.getWidth();x++ ) 
+			for (int y = 0; y < inputGrid.getHeight(); y++ ) {
+				if ( x < inputGrid.getMinX() || y < inputGrid.getMinY() || x > inputGrid.getMinX()+inputGrid.getWidth()-1 || y > inputGrid.getMinY()+inputGrid.getHeight()-1 ||
+			            Float.isNaN(outputGrid.getRasterSampleAsFloat(x,y)) ) //ignore neighbor, if outside the raster
+			             continue;
+				totalPixels++;
+				if (areaRestr.getRasterSampleAsFloat(x,y) != 0 && !Float.isNaN(areaRestr.getRasterSampleAsFloat(x,y)))
+					excldCount++;
+			}
+		
+		statusOut.println("Total: "+totalPixels+", Excluded: "+excldCount);
+		
+	}
+
+	/**
+	* like in every model: frees the resources
+	 */
+	public void performModelDispose() {
+		super.performModelDispose();
+		// free resources
+		releaseAccess(RA_roadGravSens);
+		releaseAccess(RA_slopeSens);
+		releaseAccess(RA_criticalLow);
+		releaseAccess(RA_criticalHigh);
+		releaseAccess(RA_Boom);
+		releaseAccess(RA_Bust);
+	}
+
+	/**
+	 * The main method of the Urban Growth Model. For a detailed description refer to the performModelStep in 
+	 * {@link UrbanGrowthModel UrbanGrowthModel}. The difference to the plain UGM Calibration model is the Self Modification 
+	 * of several coefficients at the end of each modelling step.
+	 */
+	public void performModelStep(int stepNo) {
+		
+		long localStartTime = System.currentTimeMillis();
+		statusOut.println("Starting step " + stepNo + "...");
+		
+		int MaxSlopeResistance = 100;
+		slopeMax = getSlopeMax();
+		double exp = getSlopeExp(slope,MaxSlopeResistance);	//calculate the exp value based on the actual slope
+		statusOut.println("EXP: "+exp);
+		slopeLUT = getSlopeLookup(slopeMax,exp,criticalSlope);	//generate the lookup-table based on the actual exp-value
+
+		boolean[][] tmpGrid = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];
+		Float actUrb = null;
+
+		double growthRate = 0;
+		int thisYear = 0;
+		int roadCount = 0;
+		
+		//DISPERSION
+		double disp_value = Math.round((disp*0.005)* Math.sqrt(Math.pow(inputGrid.getWidth(), 2)+(Math.pow(inputGrid.getHeight(), 2))));
+		
+		//ROAD GRAVITY
+		double max_RG_value = 100.0;
+		double rg_value = Math.round((roadGravity/max_RG_value)*((areaWidth + areaHeight)/16)); 
+		
+
+		/*****************************************************************
+		 * DISPERSION and BREED (Growth Phase 1 and 2)
+		 *****************************************************************/
+		boolean[][] tmpGridDisp = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+		tmpGridDisp = DispersionGrowth(disp_value,breed);	//calls the method "DispersionBreed" to perform the Dispersion and Breed Growth Phase
+		int anzDispBreed = 0;	//number of cells urbanized by Dispersion and Breed
+		for (int x = 0; x < inputGrid.getWidth();x++)
+			for(int y = 0; y < inputGrid.getHeight();y++){
+				int X = inputGrid.getMinX() + x;
+				int Y = inputGrid.getMinY() + y;
+				if (tmpGridDisp[X][Y]==true){
+					anzDispBreed++;
+					tmpGrid[X][Y] = true;	//write the temporary Dispersion and Breed Cells to the overall temporary Cell array
+				}		
+			}
+		statusOut.println("Number of Spontaneous and New Spreading Center Cells: "+anzDispBreed);
+		writeToGrid(tmpGrid);	//calls the method "writeToGrid" to write the new urbanized cells to the output grid
+		
+				
+		/*********************************************************************
+		 * EDGE
+		 *********************************************************************/
+		boolean[][] tmpGridSpread = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+		tmpGridSpread = EdgeGrowth(spread);	//calls the method "EdgeGrowth" to perform the Spread (Edge Growth) Phase
+		int anzSpread = 0;	//number of cells urbanized by Spread
+		for (int x = 0; x < inputGrid.getWidth();x++)
+			for(int y = 0; y < inputGrid.getHeight();y++){
+				int X = inputGrid.getMinX() + x;
+				int Y = inputGrid.getMinY() + y;
+				if (tmpGridSpread[X][Y]==true){
+					anzSpread++;
+					tmpGrid[X][Y] = true;	//write the temporary Spread cells to the overall temporary Cell array
+				}		
+			}
+		statusOut.println("Number of Edge Growth Cells: "+anzSpread);
+		writeToGrid(tmpGrid);	//calls the method "writeToGrid" to write the new urbanized cells to the output grid
+	
+		/*********************************************************************
+		 * ROAD
+		 *********************************************************************/
+		boolean[][] tmpGridRoad = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+		tmpGridRoad = RoadGrowth(tmpGrid,rg_value,breed,disp);	//calls the method "RoadGrowth" to perform the Road weighted growth
+		int anzRoad = 0;	//number of cells urbanized by Road Growth
+		for (int x = 0; x < inputGrid.getWidth();x++)
+			for(int y = 0; y < inputGrid.getHeight();y++){
+				int X = inputGrid.getMinX() + x;
+				int Y = inputGrid.getMinY() + y;
+				if (tmpGridRoad[X][Y]==true){
+					anzRoad++;
+					tmpGrid[X][Y] = true;	//write the temporary Road Growth cells to the overall temporary Cell array
+				}		
+			}
+		statusOut.println("Number of Road Growth Cells: "+anzRoad);
+		writeToGrid(tmpGrid);	//calls the method "writeToGrid" to write the new urbanized cells to the output grid
+		
+		
+		outStep.addGrid();
+		int anzGesamt = 0;
+		
+		// Write the temporary Grid to the Output Grid
+		for (int y = 1; y < inputGrid.getHeight()-1;y++ ) {
+			for (int x = 1; x < inputGrid.getWidth()-1; x++ ) {
+				
+				int X = inputGrid.getMinX() + x;
+				int Y = inputGrid.getMinY() + y;
+				
+				if (tmpGrid[x][y] == true)
+					anzGesamt++;
+				
+				boolean lebt = outputGrid.getRasterSampleAsFloat(X , Y ) > 0f;	//a cell is alive, when it is 1
+				boolean road = roadGrid.getRasterSampleAsFloat(X, Y) > 0f;	//a cell contains a road...
+				if (tmpGrid[x][y] == false)	//if there is nothing in the temporary raster
+					tmpGrid[x][y] = lebt;	//take the values from the current output raster
+				if(lebt == true)
+					thisYear++;		//all urban cells in this year
+				if(road == true)
+					roadCount++;	//road cells
+
+				outputGrid.setRasterSample( tmpGrid[x][y] ? 1f : 0f ,X ,Y);	//write the results in the output raster
+				actUrb  = (Float)outputGrid.getRasterSample(x,y);	//the actual urban extent
+				outStep.getGrid(stepNo-1).setRasterSample(actUrb,x,y);	//put the layer in the raster list containing the step results
+			}
+		}
+		
+		
+		//SELF-MODIFICATION
+		growthRate = ((float)anzGesamt / (float)thisYear)*100;	//growth rate
+		statusOut.println("Wachstumsrate: "+growthRate+", Urban: "+anzGesamt);
+		double percent_urban = (100.0 *(thisYear+roadCount) / (totalPixels-roadCount-excldCount));
+		
+		//Boom-Year
+		if(growthRate > criticalHigh){		//if the growth rate exceeds the critical high value
+			slope -= (float)percent_urban * (float)slopeSens;	//decrease the slope coefficient
+			if(slope <= 0.01)		//if it is already very low, make it 1
+				slope = 1.0;
+			roadGravity += (float)percent_urban * roadGravSens;	//increase the road Gravity
+			if(roadGravity > 100.0)
+				roadGravity = 100.0;
+			if(disp < 100.0){		//increase the other coefficients by multiplying with the boom parameter
+				disp *= boom;
+				if(disp > 100.0)
+					disp = 100.0;
+				breed *= boom;
+				if(breed > 100.0)
+					breed = 100.0;
+				spread *= boom;
+				if(spread > 100.0)
+					spread = 100.0;
+			}
+		}
+		//Bust-Year
+		if(growthRate < criticalLow){		//if the growth rate falls below the critical low value
+			slope += (float)percent_urban * (float)slopeSens;	//increase the slope coefficient
+			if(slope > MaxSlopeResistance)
+				slope = MaxSlopeResistance;
+			roadGravity -= (float)percent_urban * roadGravSens;	//decrease the road Gravity
+			if(roadGravity <= 0.01)
+				roadGravity = 1.0;
+			if(growthRate < criticalLow && disp > 0){	//decrease the other coefficients by multiplying with the bust parameter
+				disp *= bust;
+				if(disp <= 0.01)
+					disp = 1.0;
+				spread *= bust;
+				if(spread <= 0.01)
+					spread = 1.0;
+				breed *= bust;
+				if(breed <= 0.01)
+					breed = 1.0;
+			}
+		}
+		System.out.println("thisYear: "+thisYear+", roadCount: "+roadCount+", excldCount: "+excldCount+", percent_urban: "+percent_urban);
+		System.out.println("Slope-Sensitivity: "+slope+", RoadGravity-Sensitivity: "+roadGravity+", Diffusion-Sensitivity: "+disp+", Breed-Sensitivity: "+breed+", Spread-Sensitivity: "+spread);
+		
+		System.out.println("Finished step " + (stepNo) + " in "
+				+ ((System.currentTimeMillis() - localStartTime)) + " ms\n");
+		localStartTime = System.currentTimeMillis();
+	}
+
+}

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModificationContentManager.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModificationContentManager.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModificationContentManager.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,35 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.data.XuluDataException;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+
+
+public class UrbanGrowthModelSelfModificationContentManager extends UrbanGrowthModelContentManager {
+	
+	public UrbanGrowthModelSelfModificationContentManager(int additionalRes) {
+		super(6+additionalRes);
+	
+	    resource[13]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Road Gravity Sensitivity",ScalarProperty.class,Double.class,false);
+	    resource[14]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Sensitivity",ScalarProperty.class,Double.class,false);
+	    resource[15]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical Low",ScalarProperty.class,Double.class,false);
+	    resource[16]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical High",ScalarProperty.class,Double.class,false);
+	    resource[17]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Boom",ScalarProperty.class,Double.class,false);
+	    resource[18]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Bust",ScalarProperty.class,Double.class,false);
+	    
+	 	// ===== Ressourcen Bezeichnungen lokalisieren =====
+	    resetCaptions(null);
+	}
+	
+	public UrbanGrowthModelSelfModificationContentManager() {
+		this(0);
+		
+	}
+	
+	@Override
+	public void checkAndError() throws XuluDataException {
+		// TODO Auto-generated method stub
+		super.checkAndError();
+	}
+}

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModifying.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModifying.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModifying.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,951 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import java.awt.Rectangle;
+import java.util.HashMap;
+
+import edu.bonn.xulu.model.AbstractStepModel;
+import edu.bonn.xulu.model.XuluModel;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.PropertyReadAccess;
+import schmitzm.data.property.PropertyWriteAccess;
+import schmitzm.data.property.ScalarProperty;
+
+/**
+ *  This very simple model looks at every grid cell and takes the average 
+ *  over a the surrounding cells in a specified neighborhood. It was implemented
+ *  as demonstration of the Xulu / V functionality. You can see the parallel version
+ *  of this model in {@link AverageNeighborhoodParallelDemoModel} and also a tuned
+ *  version using late-merging support in {@link AVNTuned}. 
+ * <ol>
+ * <li><b>Input Grid ({@code inputGrid}):</b> A grid with input values </li>
+ * <li><b>Output Grid ({@code outputGrid}):</b> A grid where the output is
+ * stored </li>
+ * <li><b>Number of steps ({@code steps}):</b> the number of steps to
+ * compute. </li>
+ * </ol>
+ * 
+ * @see AverageNeighborhoodContentManager
+ * @author Dominik Appl
+ * @version 1.0
+ */
+public class UrbanGrowthModelSelfModifying extends AbstractStepModel {
+
+	protected UrbanGrowthModelSelfModifyingContentManager contManager;
+
+	// ********** Lese/Schreibrechte, die fuer den gesamten ***********
+	// ********** Modellanlauf gehalten werden muessen ***********
+	private PropertyReadAccess RA_inputGrid = null; // Input Grid
+	private PropertyWriteAccess WA_outputGrid = null; // Output Grid
+	private PropertyReadAccess RA_steps = null; // Number of steps
+	private PropertyReadAccess RA_areaRestr = null; //Area Restrictions
+	private PropertyReadAccess RA_spread = null;	//Spread-Koeffizient
+	private PropertyReadAccess RA_disp = null;		//Dispersions-Koeffizient
+	private PropertyReadAccess RA_breed = null;		//Breed-Koeffizient
+	private PropertyReadAccess RA_roadGravity = null;	//Road-Gravity-Koeffizient
+	private PropertyReadAccess RA_slope = null;	//Slope-Koeffizient
+	private PropertyReadAccess RA_criticalSlope = null;	//Critical Slope Value
+	private PropertyReadAccess RA_roadGrid = null;	//Road Grid
+	private PropertyReadAccess RA_slopeGrid = null;	//Slope Grid
+	private PropertyWriteAccess WA_outStep = null;	// Step Results
+	private PropertyReadAccess RA_roadGravSens = null;	//RoadGravity Sensitivity
+	private PropertyReadAccess RA_slopeSens = null;	//Slope Sensitivity
+	private PropertyReadAccess RA_criticalLow = null;	//Critical Low
+	private PropertyReadAccess RA_criticalHigh = null;	//Critical High
+	private PropertyReadAccess RA_Boom = null;	//Boom
+	private PropertyReadAccess RA_Bust = null;	//Bust
+
+	// **************** Variablen mit denen gearbeitet wird *******************
+	private WritableGrid inputGrid = null; // Input Grid
+	private WritableGrid outputGrid = null; // Output Grid
+	private PropertyReadAccess steps = null; // Number of steps
+	private WritableGrid areaRestr = null; //Area Restrictions
+	protected double spread = 0;	//Spread-Koeffizient
+	protected double disp = 0;	//Dispersions-Koeffizient
+	protected double breed = 0;	//Breed-Koeffizient
+	protected double roadGravity = 0;	//Road-Gravity-Koeffizient
+	protected double slope = 0;	//Slope-Koeffizient
+	protected double criticalSlope = 0;	//Critical Slope Value
+	private WritableGrid roadGrid = null;	//Road Grid
+	private WritableGrid slopeGrid = null;	//Slope Grid
+	private MultiGrid outStep = null;	//Step Results
+	protected double roadGravSens = 0;	//RoadGravity Sensitivity
+	protected double slopeSens = 0;	//Slope Sensitivity
+	protected double criticalLow = 0;	//critical Low
+	protected double criticalHigh = 0;	//critical High
+	protected double boom = 0;	//Boom
+	protected double bust = 0;	//Bust
+		
+	private  static final int[][] NEIGHBOR = new int[][] {
+	      {-1,-1}, {0,-1}, {1,-1},
+	      {-1, 0},         {1, 0},
+	      {-1, 1}, {0, 1}, {1, 1}
+	  };
+	
+	protected  HashMap<Number,Number> slopeLUT;
+	private int slopeMax = 0;
+	private int totalPixels = 0;
+	private int excldCount = 0;
+	
+	/**
+	 * Erzeugt eine neue Instanz des Modells.
+	 */
+	public UrbanGrowthModelSelfModifying() {
+		super(new UrbanGrowthModelSelfModifyingContentManager());
+		this.contManager = (UrbanGrowthModelSelfModifyingContentManager) super.contManager;
+	}
+
+	
+	/**
+	 * Initializes the model. Like in the init method of every {@link XuluModel}
+	 * the resources are initalized. 
+	 */
+	public void performModelInit() {
+		if (contManager == null)
+			return;
+		// Zugriffsrechte aus Ressourcen/Propertys holen
+		RA_inputGrid = null;
+		if (contManager.getResource(0).getData() != null)
+			RA_inputGrid = ((ScalarProperty) contManager.getResource(0)
+					.getData()).getReadAccess(this);
+		WA_outputGrid = null;
+		if (contManager.getResource(1).getData() != null)
+			WA_outputGrid = ((ScalarProperty) contManager.getResource(1)
+					.getData()).getWriteAccess(this);
+		RA_steps = null;
+		if (contManager.getResource(2).getData() != null)
+			RA_steps = ((ScalarProperty) contManager.getResource(2).getData())
+					.getReadAccess(this);
+		RA_areaRestr = null;
+		if (contManager.getResource(3).getData() != null)
+			RA_areaRestr = ((ScalarProperty) contManager.getResource(3)
+					.getData()).getReadAccess(this);
+		RA_spread = null;
+		if (contManager.getResource(4).getData() != null)
+			RA_spread = ((ScalarProperty) contManager.getResource(4).getData())
+					.getReadAccess(this);
+		RA_disp = null;
+		if (contManager.getResource(5).getData() != null)
+			RA_disp = ((ScalarProperty) contManager.getResource(5).getData())
+					.getReadAccess(this);
+		RA_breed = null;
+		if (contManager.getResource(6).getData() != null)
+			RA_breed = ((ScalarProperty) contManager.getResource(6).getData())
+					.getReadAccess(this);
+		RA_roadGravity = null;
+		if (contManager.getResource(7).getData() != null)
+			RA_roadGravity = ((ScalarProperty) contManager.getResource(7).getData())
+					.getReadAccess(this);
+		RA_slope = null;
+		if (contManager.getResource(8).getData() != null)
+			RA_slope = ((ScalarProperty) contManager.getResource(8).getData())
+					.getReadAccess(this);
+		RA_criticalSlope = null;
+		if (contManager.getResource(9).getData() != null)
+			RA_criticalSlope = ((ScalarProperty) contManager.getResource(9).getData())
+					.getReadAccess(this);
+		RA_roadGrid = null;
+		if (contManager.getResource(10).getData() != null)
+			RA_roadGrid = ((ScalarProperty) contManager.getResource(10)
+					.getData()).getReadAccess(this);
+		RA_slopeGrid = null;
+		if (contManager.getResource(11).getData() != null)
+			RA_slopeGrid = ((ScalarProperty) contManager.getResource(11)
+					.getData()).getReadAccess(this);
+		RA_roadGravSens = null;
+		if (contManager.getResource(13).getData() != null)
+			RA_roadGravSens = ((ScalarProperty) contManager.getResource(13).getData())
+					.getReadAccess(this);
+		RA_slopeSens = null;
+		if (contManager.getResource(14).getData() != null)
+			RA_slopeSens = ((ScalarProperty) contManager.getResource(14).getData())
+					.getReadAccess(this);
+		RA_criticalLow = null;
+		if (contManager.getResource(15).getData() != null)
+			RA_criticalLow = ((ScalarProperty) contManager.getResource(15).getData())
+					.getReadAccess(this);
+		RA_criticalHigh = null;
+		if (contManager.getResource(16).getData() != null)
+			RA_criticalHigh = ((ScalarProperty) contManager.getResource(16).getData())
+					.getReadAccess(this);
+		RA_Boom = null;
+		if (contManager.getResource(17).getData() != null)
+			RA_Boom = ((ScalarProperty) contManager.getResource(17).getData())
+					.getReadAccess(this);
+		RA_Bust = null;
+		if (contManager.getResource(18).getData() != null)
+			RA_Bust = ((ScalarProperty) contManager.getResource(18).getData())
+					.getReadAccess(this);
+
+		// Variablen belegen mit denen gearbeitet wird
+		inputGrid = (WritableGrid) RA_inputGrid.getValue();
+		outputGrid = (WritableGrid) WA_outputGrid.getValue();
+		steps = RA_steps;
+		areaRestr = (WritableGrid) RA_areaRestr.getValue();
+		
+		this.stepCount = steps.getValueAsInt();
+	   // this.spread = RA_spread.getValueAsFloat();
+	    spread  = RA_spread.getValueAsDouble();
+	    disp	= RA_disp.getValueAsDouble();
+	    breed	= RA_breed.getValueAsDouble();
+	    roadGravity = RA_roadGravity.getValueAsDouble();
+	    slope	= RA_slope.getValueAsDouble();
+	    criticalSlope = RA_criticalSlope.getValueAsDouble();
+	    roadGrid = (WritableGrid) RA_roadGrid.getValue();
+	    slopeGrid = (WritableGrid) RA_slopeGrid.getValue();
+	    outStep = (MultiGrid)contManager.getResource(12).getData();
+	    roadGravSens = RA_roadGravSens.getValueAsDouble();
+	    slopeSens = RA_slopeSens.getValueAsDouble();
+	    criticalLow = RA_criticalLow.getValueAsDouble();
+	    criticalHigh = RA_criticalHigh.getValueAsDouble();
+	    boom = RA_Boom.getValueAsDouble();
+	    bust = RA_Bust.getValueAsDouble();
+
+		int startAnz = 0;
+		for (int i = 0; i < inputGrid.getWidth();i++ ) {
+			for (int ii = 0; ii < inputGrid.getHeight(); ii++ ) {
+				//if (inputGrid.getRasterSampleAsFloat(i,ii) == 1f);
+				float val = inputGrid.getRasterSampleAsFloat(i,ii);
+				if (val == 1.0 ) {
+					val = 1f;
+					startAnz++;
+				}
+					else val = 0f;
+				
+				inputGrid.setRasterSample(val, inputGrid.getMinX() + i, inputGrid.getMinY() + ii);
+				outputGrid.setRasterSample(val, inputGrid.getMinX() + i, inputGrid.getMinY() + ii);
+			}
+		}
+		for (int x = 0; x < inputGrid.getWidth();x++ ) 
+			for (int y = 0; y < inputGrid.getHeight(); y++ ) {
+				if ( x < inputGrid.getMinX() || y < inputGrid.getMinY() || x > inputGrid.getMinX()+inputGrid.getWidth()-1 || y > inputGrid.getMinY()+inputGrid.getHeight()-1 ||
+			            Float.isNaN(outputGrid.getRasterSampleAsFloat(x,y)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+			             continue;
+				totalPixels++;
+				if (areaRestr.getRasterSampleAsFloat(x,y) != 0 && !Float.isNaN(areaRestr.getRasterSampleAsFloat(x,y)))
+		        	//continue;	//wenn in Area Restriction oder wenn schon Siedlung da ist, mach weiter
+				//if (inputGrid.getRasterSampleAsFloat(i,ii) == 1f);
+					excldCount++;
+			}
+		
+		statusOut.println("Anzahl der startenden Individuen: "+startAnz);
+		statusOut.println(NEIGHBOR.length);
+		statusOut.println("Total: "+totalPixels+", Excluded: "+excldCount);
+		
+		
+		for (int s = 0; s < inputGrid.getWidth();s++){
+			for(int ss = 0; ss < inputGrid.getHeight();ss++){
+				float slopeVal = slopeGrid.getRasterSampleAsFloat(s,ss);
+				if (slopeVal > slopeMax){
+					slopeMax = (int) slopeVal;
+				} 
+			}
+		}
+		statusOut.println("Maximale Hangneigung: "+slopeMax);
+		
+	}
+
+	/**
+	* like in every model: frees the resources
+	 */
+	public void performModelDispose() {
+
+		// Ressourcen wieder freigeben
+		releaseAccess(RA_inputGrid);
+		releaseAccess(WA_outputGrid);
+		releaseAccess(RA_steps);
+		releaseAccess(RA_areaRestr);
+		releaseAccess(RA_spread);
+		releaseAccess(RA_disp);
+		releaseAccess(RA_breed);
+		releaseAccess(RA_roadGravity);
+		releaseAccess(RA_slope);
+		releaseAccess(RA_criticalSlope);
+		releaseAccess(RA_roadGrid);
+		releaseAccess(RA_slopeGrid);
+		releaseAccess(WA_outStep);
+		releaseAccess(RA_roadGravSens);
+		releaseAccess(RA_slopeSens);
+		releaseAccess(RA_criticalLow);
+		releaseAccess(RA_criticalHigh);
+		releaseAccess(RA_Boom);
+		releaseAccess(RA_Bust);
+	}
+
+	/**
+	 * This very simple model looks at every grid cell and takes the average
+	 * over a the surrounding cells in a specified neighborhood.
+	 * 
+	 * @param stepNo
+	 *            zu modellierender Schritt (beginnend bei 1!)
+	 */
+	public void performModelStep(int stepNo) {
+		
+		statusOut.println("Starting step " + stepNo + "...");
+		
+		//Erstellt einen Lookup-Table
+		slopeLUT = new HashMap<Number,Number>();
+		
+		int MaxSlopeResistance = 0;
+		double exp = 0.0;
+		MaxSlopeResistance = 100;
+		exp = (slope / (MaxSlopeResistance / 2));
+		double[] lookup = new double[slopeMax+1];
+		Number key = 0;
+		
+		for (int i = 0;i <= slopeMax;i++){
+			if (i <= criticalSlope){
+				double val = (criticalSlope - i) / criticalSlope;
+				lookup[i] = 1 - Math.pow(val,exp);
+				key = i;
+			} else{
+				lookup[i] = 1;
+				key = i;
+			}
+			slopeLUT.put(key,lookup[i]);
+			statusOut.println(slopeLUT.get(key));
+		}	
+		
+		Number number = slopeLUT.get(79);
+//		statusOut.println(number);
+
+		int areaMinX = inputGrid.getMinX();								//Dimensionen des Rasters
+		int areaMinY = inputGrid.getMinY();
+		int areaMaxX = inputGrid.getMinX() + inputGrid.getWidth() - 1;
+		int areaMaxY = inputGrid.getMinY() + inputGrid.getHeight() - 1;
+		int areaWidth = inputGrid.getWidth();
+		int areaHeight = inputGrid.getHeight();
+		
+		long localStartTime = System.currentTimeMillis();
+		boolean anyBodyAlive = false;
+		
+		boolean[][] tmpGrid = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];
+		Float actUrb = null;
+		
+		int nbX = 0; // X-Koordinate einer Nachbarzelle
+	    int nbY = 0; // Y-Koordinate einer Nachbarzelle
+	    int[] nbCell = null;
+	    
+		int anzSpreadTreffer = 0;
+		int anzDispTreffer = 0;
+		int anzBreedTreffer = 0;
+		int anzRoadTreffer = 0;
+		int anzGesamtTreffer = 0;
+		double growthRate = 0;
+		int thisYear = 0;
+		int roadCount = 0;
+		
+		
+		//DISPERSION
+		double disp_value = Math.round((disp*0.005)* Math.sqrt(Math.pow(inputGrid.getWidth(), 2)+(Math.pow(inputGrid.getHeight(), 2))));
+				
+		int dispRandX = 0;
+		int dispRandY = 0;
+		float slopeRandDisp = 0;
+		
+		//ROAD GRAVITY
+		double max_RG_value = 100.0;
+		double rg_value = Math.round((roadGravity/max_RG_value)*((areaWidth + areaHeight)/16)); 
+		double max_search_index = Math.round(4*((int)rg_value*(1+(int)rg_value)));
+//		statusOut.println("RG-Value:"+rg_value);
+//		statusOut.println("Max-SearchIndex"+max_search_index);
+		
+
+		/*****************************************************************
+		 * DISPERSION and BREED
+		 *****************************************************************/
+		
+		int p = 0;	//Verteile soviel neue Pixel zufällig in geeigneten Bereichen, bis disp_value erreicht ist
+		do{
+			dispRandX = Math.round((float) Math.random()*areaWidth);	//Zufallsposition in X-Richtung
+			dispRandY = Math.round((float) Math.random()*areaHeight);	//Zufallsposition in Y-Richtung
+			if ( dispRandX < areaMinX || dispRandY < areaMinY || dispRandX > areaMaxX || dispRandY > areaMaxY ||
+		            Float.isNaN(outputGrid.getRasterSampleAsFloat(dispRandX,dispRandY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+		             continue;
+		        if (areaRestr.getRasterSampleAsFloat(dispRandX,dispRandY) != 0 || outputGrid.getRasterSampleAsFloat(dispRandX,dispRandY) == 1)
+		        	continue;	//wenn in Area Restriction oder wenn schon Siedlung da ist, mach weiter
+		        slopeRandDisp = (float) Math.random();						//Zufallszahl zum Abgleich mit Slope-Koeffizient
+		        int getSlope = (int) slopeGrid.getRasterSampleAsFloat(dispRandX,dispRandY);	//holt sich den Slope-Wert aus dem Slope-Raster
+		        Double doubleObj = (Double)slopeLUT.get(getSlope);		//holt den Slope-Wert aus dem Lookup-Table (get) und konvertiert in Double
+		        double slopeDouble = doubleObj.doubleValue();			//konvertiert Double-Objekt in double-Wert
+//		        statusOut.println(getSlope+","+slopeDouble+"----Random: "+slopeRandDisp);
+		        if(slopeDouble < slopeRandDisp){
+		        	tmpGrid[dispRandX][dispRandY] = true;	//true wird ins temporäre Raster geschrieben
+		        	anzDispTreffer++;
+		        	//BREED
+		        	float breedRnd = (float) Math.random()*100;
+		        	int nbBreedX  = 0;
+		        	int nbBreedY  = 0;
+		        	int breedNb	  = 0;
+		        	float NbValue = 0f;
+		        	if (tmpGrid[dispRandX][dispRandY] == true && breedRnd < breed)
+		        		breedNb = calculateNeighbors(dispRandX,dispRandY,NbValue);
+		        			       
+		        	int RNBreed1 = 0;
+		        	int RNBreed2 = 0;
+		        	float RNBreedSlope = 0f;
+		        
+		        	if (breedNb >= 2 && tmpGrid[dispRandX][dispRandY] == true){
+		        		int anzBreedTemp = 0;
+		        		int[] nbPossibleBreedUrban = null;
+		        		RNBreed1 = 1 + Math.round((float)Math.random()*(breedNb-1));
+		        		RNBreed2 = 1 + Math.round((float)Math.random()*(breedNb-1));
+		        		if (RNBreed2 == RNBreed1)
+		        			RNBreed2 = 1 + Math.round((float)Math.random()*(breedNb-1));	
+		        		for (int cellBreed = 0; cellBreed < NEIGHBOR.length; cellBreed++){
+		        			nbBreedX = dispRandX+NEIGHBOR[cellBreed][0];
+		        			nbBreedY = dispRandY+NEIGHBOR[cellBreed][1];
+		        			if ( nbBreedX < areaMinX || nbBreedY < areaMinY || nbBreedX > areaMaxX || nbBreedY > areaMaxY ||
+		        					Float.isNaN(outputGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+		        				continue;
+		        			if (areaRestr.getRasterSampleAsFloat(nbBreedX,nbBreedY) != 0)
+		        				continue;
+		        			RNBreedSlope = (float)Math.random();
+		        			int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY);
+		        			Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+		        			double slopeDoubleNb = doubleObjNb.doubleValue();
+		        			float breedSample = outputGrid.getRasterSampleAsFloat(nbBreedX,nbBreedY);
+		        			if (breedSample == 0f){
+		        				anzBreedTemp++;
+		        				nbPossibleBreedUrban = new int[] {nbBreedX,nbBreedY,anzBreedTemp};
+		        				if (nbPossibleBreedUrban[2] == RNBreed1 || nbPossibleBreedUrban[2] == RNBreed2 && slopeDoubleNb < RNBreedSlope){
+		        					tmpGrid[nbBreedX][nbBreedY] = true;
+		        					anzBreedTreffer++;
+		        				}
+		        			}
+		        		}
+		        	} 
+				} p++;
+			} while (p < disp_value);	//while, statt for-Schleife, da Überprüfung erst am Ende vorgenommen werden kann
+									//am Anfang der Schleife ist noch nicht klar, ob alle Pixel verteilt werden können
+									//da ein Teil in Ausschlussflächen etc. landen würde
+	
+		/*********************************************************************
+		 * EDGE
+		 *********************************************************************/
+		
+		//iterate over all cells
+		for (int x = 0; x < inputGrid.getWidth(); x++)
+			for (int y = 0; y < inputGrid.getHeight(); y++) {		//für jede Zelle in x/y-Richtung
+				
+				int areaMinXadd = areaMinX + x;								//Dimensionen des Rasters
+				int areaMinYadd = areaMinY + y;
+				
+				int anzNachbarn = 0;
+				int noNachbarn = 0;
+			
+				
+				for (int nbCellIdx = 0; nbCellIdx < NEIGHBOR.length; nbCellIdx++) {
+					checkBreakingCommands();
+					nbX = x+NEIGHBOR[nbCellIdx][0];		//Nachbarschaft der Zellen
+			        nbY = y+NEIGHBOR[nbCellIdx][1];
+			        nbCell = new int[] {nbX,nbY};		//jede Nachbarzelle
+			        if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+			               Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+			             continue;
+			        if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+			        	continue;
+					float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY);
+					if (rasterSample > 0f)		//ist Nachbarzelle urban (1), wird sie gezählt
+						anzNachbarn++;
+					if (rasterSample == 0f)
+						noNachbarn++;
+				}
+				
+				boolean lebt = outputGrid.getRasterSampleAsFloat(areaMinXadd , areaMinYadd ) > 0f;	//eine Zelle lebt, wenn sie 1 ist
+				
+				//hier ist die Abfrage wieviele Nachbarzellen am Leben sind
+				//daraus ergibt sich, ob im tmpGrid die entsprechende Zelle
+				//true oder false ist
+				
+				float SpR = (float) Math.random()*100;						//eine Zufallszahl zwischen 0 und 1
+				int RN = 0; 	//hier wird eine Integer-Zufallszahl reingeschrieben
+				
+				if (lebt && (anzNachbarn>=2) && (SpR < spread) && (noNachbarn >=1)) {	//wenn eine Zelle lebt, mindestens 2 lebende Nachbarzellen hat, der Spread-Koeffizient größer als die für die Zelle berechnete Zufallszahl und mindestens einen nicht lebenden Nachbarn hat
+					int anzTemp = 0;
+					int[] nbPossibleUrban = null;
+					RN = 1 + Math.round((float)Math.random()*(noNachbarn-1));
+					float RNEdgeSlope = 0;
+					int nbUrbanX = 0;
+					int nbUrbanY = 0;
+					for (int nbCellChange = 0; nbCellChange < NEIGHBOR.length; nbCellChange++){	//dann starte eine Schleife
+						checkBreakingCommands();
+						nbX = x+NEIGHBOR[nbCellChange][0];
+						nbY = y+NEIGHBOR[nbCellChange][1];
+						if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+					               Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+					             continue;
+						if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+				        	continue;
+						RNEdgeSlope = (float)Math.random();
+	        			int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbX,nbY);
+	        			Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+	        			double slopeDoubleNb = doubleObjNb.doubleValue();
+						float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY);	//holt die Werte aus den jeweiligen Nachbarzellen
+						if (rasterSample == 0f){	//wenn der Wert 0 ist
+							anzTemp++;				//wird Anzahl der möglichen Zellen erhöht
+							nbPossibleUrban = new int[] {nbX,nbY,anzTemp};	//Koordinaten und Nummern dieser Zellen werden in Array geschrieben 
+							int urbanNbTemp = 0;
+							float NbValueEdge = 1f;
+							if (nbPossibleUrban[2] == RN){	//wenn Nummer im "PossibleUrban"-Array der Zufallszahl entspricht, die zwischen 1 und Anzahl der möglichen Zellen liegt...
+								//damit die Städte nicht zu sehr "ausfransen" steht eine Zelle nur zur Umwandlung zur Verfügung, wenn auch sie mind. 2 urbane Nachbarn hat
+								urbanNbTemp = calculateNeighbors(nbX,nbY,NbValueEdge);
+								if (urbanNbTemp >= 2 && tmpGrid[nbX][nbY]==false && slopeDoubleNb < RNEdgeSlope){
+									tmpGrid[nbX][nbY] = true;	//wird true ins temporäre Raster geschrieben
+									anzSpreadTreffer++;
+								}
+							} 
+						}
+						nbCell = new int[] {nbX,nbY,(int) rasterSample};	
+					}
+				}
+				if (anzNachbarn>0) anyBodyAlive = true;		
+			}
+		
+		/*********************************************************************
+		 * ROAD
+		 *********************************************************************/
+		
+		int anzGesamt = 0;
+		int[] cellValue = null;
+		
+		//For-Schleife zählt alle als true markierten Zellen im Temp-Raster
+		for (int x = 0; x < inputGrid.getWidth();x++)
+			for(int y = 0; y < inputGrid.getHeight();y++){
+				int X = inputGrid.getMinX() + x;
+				int Y = inputGrid.getMinY() + y;
+				if (tmpGrid[X][Y]==true){
+					anzGesamt++;
+				}		
+			}
+		
+		int RSearchRoad = 0;
+		int r = 1;	//Verteile soviel neue Pixel zufällig in geeigneten Bereichen, bis disp_value erreicht ist
+		
+		//Rectangle gridBounds = new Rectangle(0, 0, inputGrid.getWidth(), inputGrid.getHeight()); //ein Rechteck wird definiert
+		
+		do{
+			RSearchRoad = Math.round((float)Math.random()*anzGesamt);	//Zufallszahl zwischen 1 und Anzahl aller bisher neu hinzugekommener Pixel
+			int anzTruePixels = 0;
+			int roadNeighborhoodRange = 0;
+			int RSearchNbRoad = 0;
+			for (int x = 0; x < inputGrid.getWidth();x++){		//gesamtes Raster wird durchsucht
+				for(int y = 0; y < inputGrid.getHeight();y++){
+					int X = inputGrid.getMinX() + x;
+					int Y = inputGrid.getMinY() + y;
+					if (tmpGrid[X][Y]==true){
+						anzTruePixels++;		//wird true-Pixel gefunden, wird anzTruePixels hochgezählt
+						cellValue = new int[] {X,Y,anzTruePixels};	//und Koordinaten in Array geschrieben
+						int tempRoadCell[] = null;
+						int tempNbRoadCell[] = null;
+						if (cellValue[2] == RSearchRoad){
+							//statusOut.println(cellValue[0]+","+cellValue[1]+","+cellValue[2]);
+							//statusOut.println(r+","+RSearchRoad);
+							r++;
+							//JETZT NACH STRAßE SUCHEN!!
+							float roadValue = roadGrid.getRasterSampleAsFloat(X,Y);
+//							statusOut.println(roadValue);
+							if (roadValue > 0.0){
+								tempRoadCell = new int[] {X,Y};
+//								statusOut.println("Strasse in Entfernung 0: "+tempRoadCell[0]+","+tempRoadCell[1]);
+								//roadWalk(tempRoadCell[0],tempRoadCell[1]);
+								int nbCellNew[] = roadWalk(tempRoadCell[0],tempRoadCell[1]);
+								if(nbCellNew != null){
+									tmpGrid[nbCellNew[0]][nbCellNew[1]] = true;
+//									statusOut.println(nbCellNew.length);
+//									statusOut.println("Neue Zelle: "+nbCellNew[0]+","+nbCellNew[1]);
+//									statusOut.println("++++++++++++++++++++++++++++++++++++++++");
+									float nbRoadBreed = 0f;
+									int nbRoadBreedNeighbors = 0;
+									nbRoadBreedNeighbors = calculateNeighbors(nbCellNew[0],nbCellNew[1],nbRoadBreed);
+									int RNRoadBreed1 = 0;
+							        int RNRoadBreed2 = 0;
+							        int nbRoadBreedX = 0;
+							        int nbRoadBreedY = 0;
+							        int anzRoadBreedTreffer1 = 0;
+							        
+									if (nbRoadBreedNeighbors >= 2){
+										int anzBreedTemp = 0;
+										int[] nbPossibleBreedUrban = null;
+										RNRoadBreed1 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+										RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+										float RNRoadBreedSlope = 0f;
+										
+										if (RNRoadBreed2 == RNRoadBreed1)
+											RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));	
+										for (int cellBreed = 0; cellBreed < NEIGHBOR.length; cellBreed++){
+							        		nbRoadBreedX = nbCellNew[0]+NEIGHBOR[cellBreed][0];
+											nbRoadBreedY = nbCellNew[1]+NEIGHBOR[cellBreed][1];
+											if ( nbRoadBreedX < areaMinX || nbRoadBreedY < areaMinY || nbRoadBreedX > areaMaxX || nbRoadBreedY > areaMaxY ||
+										               Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+										             continue;
+											if (areaRestr.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY) != 0)
+									        	continue;
+											RNRoadBreedSlope = (float)Math.random();
+						        			int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY);
+						        			Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+						        			double slopeDoubleNb = doubleObjNb.doubleValue();
+											float breedSample = outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY);
+											if (breedSample == 0f){
+												anzBreedTemp++;
+												nbPossibleBreedUrban = new int[] {nbRoadBreedX,nbRoadBreedY,anzBreedTemp};
+												if (nbPossibleBreedUrban[2] == RNRoadBreed1 || nbPossibleBreedUrban[2] == RNRoadBreed2 && slopeDoubleNb < RNRoadBreedSlope){
+													tmpGrid[nbRoadBreedX][nbRoadBreedY] = true;
+													anzRoadBreedTreffer1++;
+													anzRoadTreffer++;
+													statusOut.println("Road-Breed-Treffer: "+anzRoadBreedTreffer1);
+												}
+											}
+										}
+							        	
+							        
+									}
+									
+								} else{
+//									statusOut.println("Keine neue Zelle gefunden");
+								}
+							} else{
+								int anzRoadNb = 0;
+								
+								//HIER MIT FOR SCHLEIFE RECHTECK WACHSEN LASSEN!!!
+								for (int roadSearch = 0; roadSearch <= rg_value; roadSearch++){
+									if (anzRoadNb > 0)
+										continue;
+									for (int nbRoadCellsX = X - roadNeighborhoodRange; nbRoadCellsX <= X + roadNeighborhoodRange; nbRoadCellsX++){
+										for (int nbRoadCellsY = Y - roadNeighborhoodRange; nbRoadCellsY <= Y + roadNeighborhoodRange; nbRoadCellsY++){
+										//	if (gridBounds.contains(nbRoadCellsX, nbRoadCellsY))
+												if ( nbRoadCellsX < areaMinX || nbRoadCellsY < areaMinY || nbRoadCellsX > areaMaxX || nbRoadCellsY > areaMaxY ||
+														Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+													continue;
+												if (areaRestr.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY) != 0)
+													continue;
+												float roadValueNb = roadGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY);
+												if (roadValueNb > 0f){
+													anzRoadNb++;
+												}
+												//statusOut.println("Strasse in Entfernung 1: "+anzRoadNb+","+nbRoadCellsX+","+nbRoadCellsY);
+										}
+									}
+									roadNeighborhoodRange++;
+									RSearchNbRoad = Math.round((float)Math.random()*anzRoadNb);
+									//statusOut.println("--> Zyklus "+roadNeighborhoodRange+"Nachbarn: "+anzRoadNb);
+									//statusOut.println(RSearchNbRoad);
+									int anzTempRoadNb = 0;
+									for (int nbRoadCellsX = X - roadNeighborhoodRange; nbRoadCellsX <= X + roadNeighborhoodRange; nbRoadCellsX++){
+										for (int nbRoadCellsY = Y - roadNeighborhoodRange; nbRoadCellsY <= Y + roadNeighborhoodRange; nbRoadCellsY++){
+//						        			statusOut.println("TEST-ROAD: "+nbRoadCellsX+","+nbRoadCellsY);
+										//	if (gridBounds.contains(nbRoadCellsX, nbRoadCellsY))
+											if ( nbRoadCellsX < areaMinX || nbRoadCellsY < areaMinY || nbRoadCellsX > areaMaxX || nbRoadCellsY > areaMaxY ||
+													Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+												continue;
+											if (areaRestr.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY) != 0)
+												continue;
+											float roadValueNbTemp = roadGrid.getRasterSampleAsFloat(nbRoadCellsX,nbRoadCellsY);
+											if (roadValueNbTemp > 0f){
+												anzTempRoadNb++;
+												tempNbRoadCell = new int[] {nbRoadCellsX,nbRoadCellsY,anzTempRoadNb};
+												if (tempNbRoadCell[2]==RSearchNbRoad){
+													//statusOut.println("Treffer: "+tempNbRoadCell[0]+","+tempNbRoadCell[1]+","+tempNbRoadCell[2]);
+													tempRoadCell = tempNbRoadCell;
+//													statusOut.println("Strasse in Entfernung "+roadSearch+": "+tempRoadCell[0]+","+tempRoadCell[1]+","+tempRoadCell[2]);
+													//roadWalk(tempRoadCell[0],tempRoadCell[1]);
+													int nbCellNew[] = roadWalk(tempRoadCell[0],tempRoadCell[1]);
+													if(nbCellNew != null){
+														tmpGrid[nbCellNew[0]][nbCellNew[1]] = true;
+//														statusOut.println(nbCellNew.length);
+//														statusOut.println("Neue Zelle: "+nbCellNew[0]+","+nbCellNew[1]);
+//														statusOut.println("++++++++++++++++++++++++++++++++++++++++");
+														
+														float nbRoadBreed = 0f;
+														int nbRoadBreedNeighbors = 0;
+														nbRoadBreedNeighbors = calculateNeighbors(nbCellNew[0],nbCellNew[1],nbRoadBreed);
+														int RNRoadBreed1 = 0;
+												        int RNRoadBreed2 = 0;
+												        int nbRoadBreedX = 0;
+												        int nbRoadBreedY = 0;
+												        int anzRoadBreedTreffer2 = 0;
+												        
+														if (nbRoadBreedNeighbors >= 2){
+															int anzBreedTemp = 0;
+															int[] nbPossibleBreedUrban = null;
+															RNRoadBreed1 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+															RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));
+															float RNRoadBreedSlope = 0f;
+															if (RNRoadBreed2 == RNRoadBreed1)
+																RNRoadBreed2 = 1 + Math.round((float)Math.random()*(nbRoadBreedNeighbors-1));	
+															for (int cellBreed = 0; cellBreed < NEIGHBOR.length; cellBreed++){
+												        		nbRoadBreedX = nbCellNew[0]+NEIGHBOR[cellBreed][0];
+																nbRoadBreedY = nbCellNew[1]+NEIGHBOR[cellBreed][1];
+																if ( nbRoadBreedX < areaMinX || nbRoadBreedY < areaMinY || nbRoadBreedX > areaMaxX || nbRoadBreedY > areaMaxY ||
+															               Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+															             continue;
+																if (areaRestr.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY) != 0)
+														        	continue;
+																RNRoadBreedSlope = (float)Math.random();
+											        			int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY);
+											        			Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+											        			double slopeDoubleNb = doubleObjNb.doubleValue();
+																float breedSample = outputGrid.getRasterSampleAsFloat(nbRoadBreedX,nbRoadBreedY);
+																if (breedSample == 0f){
+																	anzBreedTemp++;
+																	nbPossibleBreedUrban = new int[] {nbRoadBreedX,nbRoadBreedY,anzBreedTemp};
+																	if (nbPossibleBreedUrban[2] == RNRoadBreed1 || nbPossibleBreedUrban[2] == RNRoadBreed2 && slopeDoubleNb < RNRoadBreedSlope){
+																		tmpGrid[nbRoadBreedX][nbRoadBreedY] = true;
+																		anzRoadBreedTreffer2++;
+																		anzRoadTreffer++;
+																		statusOut.println("Road-Breed-Treffer: "+anzRoadBreedTreffer2);
+																	}
+																}
+															}
+												        	
+												        
+														}
+													} else{
+//														statusOut.println("Keine neue Zelle gefunden");
+													}
+												}
+											}
+										}
+									}
+								}
+							}
+						}
+					}	
+				}
+			}
+			
+		} while (r <= breed);
+		
+		statusOut.println("Spread-Treffer: "+anzSpreadTreffer);
+		statusOut.println("Dispersion-Treffer: "+anzDispTreffer);
+		statusOut.println("Breed-Treffer: "+anzBreedTreffer);
+		statusOut.println("Treffer gesamt: "+anzGesamt);
+		statusOut.println("Anzahl Road-Treffer: "+anzRoadTreffer);
+		anzGesamtTreffer = anzSpreadTreffer+anzDispTreffer+anzBreedTreffer+anzRoadTreffer;
+		
+		outStep.addGrid();
+		
+		
+		// TempGrid auf das echte Grid schreiben
+		for (int y = 1; y < inputGrid.getHeight()-1;y++ ) {
+			for (int x = 1; x < inputGrid.getWidth()-1; x++ ) {
+				
+				int X = inputGrid.getMinX() + x;
+				int Y = inputGrid.getMinY() + y;
+				
+								
+				boolean lebt = outputGrid.getRasterSampleAsFloat(X , Y ) > 0f;	//eine Zelle lebt, wenn sie 1 ist
+				boolean road = roadGrid.getRasterSampleAsFloat(X, Y) > 0f;	//eine Zelle beinhaltet eine Straße...
+				if (tmpGrid[x][y] == false)	//wenn im temporären Raster nichts drinsteht...
+					tmpGrid[x][y] = lebt;	//wird der Wert aus dem Ausgangsraster übernommen
+				if(lebt == true)
+					thisYear++;
+				if(road == true)
+					roadCount++;
+
+				outputGrid.setRasterSample( tmpGrid[x][y] ? 1f : 0f ,X ,Y);	
+				actUrb  = (Float)outputGrid.getRasterSample(x,y);
+				outStep.getGrid(stepNo-1).setRasterSample(actUrb,x,y);
+			}
+		}
+		
+		//SELF-MODIFICATION
+		growthRate = ((float)anzGesamtTreffer / (float)thisYear)*100;
+		statusOut.println("Wachstumsrate: "+growthRate+", Urban: "+anzGesamtTreffer);
+		double percent_urban = (100.0 *(thisYear+roadCount) / (totalPixels-roadCount-excldCount));
+		
+		//Boom-Year
+		if(growthRate > criticalHigh){
+			slope -= (float)percent_urban * (float)slopeSens;
+			if(slope <= 0.01)
+				slope = 1.0;
+			roadGravity += (float)percent_urban * roadGravSens;
+			if(roadGravity > 100.0)
+				roadGravity = 100.0;
+			if(disp < 100.0){
+				disp *= boom;
+				if(disp > 100.0)
+					disp = 100.0;
+				breed *= boom;
+				if(breed > 100.0)
+					breed = 100.0;
+				spread *= boom;
+				if(spread > 100.0)
+					spread = 100.0;
+			}
+		}
+		//Bust-Year
+		if(growthRate < criticalLow){
+			slope += (float)percent_urban * (float)slopeSens;
+			if(slope > MaxSlopeResistance)
+				slope = MaxSlopeResistance;
+			roadGravity -= (float)percent_urban * roadGravSens;
+			if(roadGravity <= 0.01)
+				roadGravity = 1.0;
+			if(growthRate < criticalLow && disp > 0){
+				disp *= bust;
+				if(disp <= 0.01)
+					disp = 1.0;
+				spread *= bust;
+				if(spread <= 0.01)
+					spread = 1.0;
+				breed *= bust;
+				if(breed <= 0.01)
+					breed = 1.0;
+			}
+		}
+		statusOut.println("thisYear: "+thisYear+", roadCount: "+roadCount+", excldCount: "+excldCount+", percent_urban: "+percent_urban);
+		statusOut.println("Slope-Sensitivity: "+slope+", RoadGravity-Sensitivity: "+roadGravity+", Diffusion-Sensitivity: "+disp+", Breed-Sensitivity: "+breed+", Spread-Sensitivity: "+spread);
+		
+		
+		
+		if (!anyBodyAlive) {
+			stepCount = stepNo;
+			statusOut.println("Lebt keiner mehr... höre hier auf!");
+		}
+		
+		
+		System.out.println("Finished step " + (stepNo) + " in "
+				+ ((System.currentTimeMillis() - localStartTime)) + " ms\n");
+		localStartTime = System.currentTimeMillis();
+	}
+	
+	private int[] roadWalk(int X,int Y){
+//		statusOut.println(X+","+Y);
+		boolean end_of_road;
+		end_of_road = false;
+		int run = 0;
+		int run_value = 0;
+		int[] nbCellNew = null;
+		int[] nbCellTemp = null;
+		while(!end_of_road){
+			end_of_road = true;
+			int nbRoadX = 0;
+			int nbRoadY = 0;
+			int areaMinX = inputGrid.getMinX();								//Dimensionen des Rasters
+			int areaMinY = inputGrid.getMinY();
+			int areaMaxX = inputGrid.getMinX() + inputGrid.getWidth() - 1;
+			int areaMaxY = inputGrid.getMinY() + inputGrid.getHeight() - 1;
+			int roadNb = 0;
+			int roadNbTemp = 0;
+			int RN = 0;
+						
+			int[] nbCell = null;
+			for (int nbRoadCells = 0; nbRoadCells < NEIGHBOR.length; nbRoadCells++){
+				nbRoadX = X+NEIGHBOR[nbRoadCells][0];
+				nbRoadY = Y+NEIGHBOR[nbRoadCells][1];
+				if ( nbRoadX < areaMinX || nbRoadY < areaMinY || nbRoadX > areaMaxX || nbRoadY > areaMaxY ||
+			               Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+			             continue;
+				//if (areaRestr.getRasterSampleAsFloat(nbRoadX,nbRoadY) != 0)
+		        //	continue;
+				float roadSample = roadGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY);
+				if (roadSample > 0f)
+					roadNb++;
+			}
+	//		statusOut.println("Nachbarn von temporaerer Strassenzelle: "+roadNb);
+			
+			if (roadNb > 0){
+				RN = 1 + Math.round((float)Math.random()*(roadNb-1));
+			
+				for (int nbRoadCells = 0; nbRoadCells < NEIGHBOR.length; nbRoadCells++){
+					nbRoadX = X+NEIGHBOR[nbRoadCells][0];
+					nbRoadY = Y+NEIGHBOR[nbRoadCells][1];
+					if ( nbRoadX < areaMinX || nbRoadY < areaMinY || nbRoadX > areaMaxX || nbRoadY > areaMaxY ||
+							Float.isNaN(outputGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+			             	continue;
+					float roadSample = roadGrid.getRasterSampleAsFloat(nbRoadX,nbRoadY);
+					if (roadSample > 0f){
+						roadNbTemp++;
+						nbCell = new int[] {nbRoadX,nbRoadY,roadNbTemp};
+						if (nbCell[2] == RN){
+							statusOut.println("Nachbarzelle gefunden: "+nbCell[0]+","+nbCell[1]+","+nbCell[2]);
+							end_of_road = false;
+							run++;
+							X = nbRoadX;
+							Y = nbRoadY;
+							float roadSample2 = roadGrid.getRasterSampleAsFloat(X,Y);
+							run_value = (int) (roadSample2 / 100 * disp);
+					//		statusOut.println("Run: "+run);
+					//		statusOut.println("Run_Value: "+run_value);
+					//		statusOut.println(X+","+Y+","+roadSample2);
+							if (run > run_value){
+								end_of_road = true;
+					//			statusOut.println("Endzelle erreicht!! Run:"+run+"RunValue: "+run_value);
+								float NbValue = 0f; 
+								int Nb = calculateNeighbors(X,Y,NbValue);
+					//			statusOut.println("moegliche Nachbarzellen nach RoadWalk: "+Nb);
+								RN = 1 + Math.round((float)Math.random()*(Nb-1));
+				//				statusOut.println("Random: "+RN);
+								if (Nb > 0){
+									int nbUrbanizeX = 0;
+									int nbUrbanizeY = 0;
+									int NbTemp = 0;
+									float RNRoadSlope = 0f;
+						//			statusOut.println(X+","+Y);
+									for (int urbanizeCells = 0; urbanizeCells < NEIGHBOR.length; urbanizeCells++){
+										nbUrbanizeX = X+NEIGHBOR[urbanizeCells][0];
+										nbUrbanizeY = Y+NEIGHBOR[urbanizeCells][1];
+										if ( nbUrbanizeX < areaMinX || nbUrbanizeY < areaMinY || nbUrbanizeX > areaMaxX || nbUrbanizeY > areaMaxY ||
+												Float.isNaN(outputGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+											continue;
+										if (areaRestr.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY) != 0)
+											continue;
+										float rasterSample = outputGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY);
+										RNRoadSlope = (float)Math.random();
+					        			int getSlopeNb = (int) slopeGrid.getRasterSampleAsFloat(nbUrbanizeX,nbUrbanizeY);
+					        			Double doubleObjNb = (Double)slopeLUT.get(getSlopeNb);
+					        			double slopeDoubleNb = doubleObjNb.doubleValue();
+										if (rasterSample == 0f){
+											NbTemp++;
+											nbCellTemp = new int[] {nbUrbanizeX,nbUrbanizeY,NbTemp};
+											if (nbCellTemp[2] == RN && slopeDoubleNb < RNRoadSlope){
+												nbCellNew = new int[] {nbCellTemp[0],nbCellTemp[1],nbCellTemp[2]};
+											}
+										}	
+									}
+								
+							} else{
+								nbCellNew = null;
+							}	break;
+						}
+						
+					}
+					
+				}
+			}
+			
+			}
+		}
+		return nbCellNew;
+		}
+	
+	private int calculateNeighbors(int X, int Y, float NbValue){
+		int nbX = 0;
+		int nbY = 0;
+		int areaMinX = inputGrid.getMinX();								//Dimensionen des Rasters
+		int areaMinY = inputGrid.getMinY();
+		int areaMaxX = inputGrid.getMinX() + inputGrid.getWidth() - 1;
+		int areaMaxY = inputGrid.getMinY() + inputGrid.getHeight() - 1;
+		int Nb = 0;
+		for (int nbCells = 0; nbCells < NEIGHBOR.length; nbCells++){
+			nbX = X+NEIGHBOR[nbCells][0];
+			nbY = Y+NEIGHBOR[nbCells][1];
+			if ( nbX < areaMinX || nbY < areaMinY || nbX > areaMaxX || nbY > areaMaxY ||
+		               Float.isNaN(outputGrid.getRasterSampleAsFloat(nbX,nbY)) ) //wenn Nachbarzelle außerhalb des Rasters (NaN) --> ignorieren
+		             continue;
+			if (areaRestr.getRasterSampleAsFloat(nbX,nbY) != 0)
+	        	continue;
+			float rasterSample = outputGrid.getRasterSampleAsFloat(nbX,nbY);
+			if (rasterSample == NbValue)
+				Nb++;
+		}
+	//	statusOut.println("..."+Nb+"...");
+		return Nb;
+	}
+	
+	protected static boolean checkNoData(int x, int y, WritableGrid grid) {
+	    return Float.isNaN(grid.getRasterSampleAsFloat(x,y));
+	  }
+}

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModifyingContentManager.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModifyingContentManager.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModelSelfModifyingContentManager.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,50 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.data.XuluDataException;
+import edu.bonn.xulu.model.AbstractModelContentManager;
+import edu.bonn.xulu.model.DefaultModelResource;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+
+public class UrbanGrowthModelSelfModifyingContentManager extends AbstractModelContentManager {
+	
+	public UrbanGrowthModelSelfModifyingContentManager() {
+		super(19);
+
+		resource[0] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Input Grid",ScalarProperty.class,WritableGrid.class,false);
+		resource[1] = new ValuePropertyResource(ModelResource.CATEGORY_OUTPUT,"Output Grid",ScalarProperty.class,WritableGrid.class,false);
+	    // Number of steps
+	    resource[2] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Number of steps",ScalarProperty.class,Integer.class,false);
+	    // Spread Coefficient
+	    resource[3] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Area Restrictions",ScalarProperty.class,WritableGrid.class,false);
+	    resource[4] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Spread Coefficient",ScalarProperty.class,Double.class,false);
+	    resource[5]	= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Dispersion Coefficient",ScalarProperty.class,Double.class,false);
+	    resource[6]	= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Breed Coefficient",ScalarProperty.class,Double.class,false);
+	    resource[7] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"RoadGravity Coefficient",ScalarProperty.class,Double.class,false);
+	    resource[8]	= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Coefficient",ScalarProperty.class,Double.class,false);
+	    resource[9]	= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical Slope",ScalarProperty.class,Double.class,false);
+	    resource[10]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Road Grid",ScalarProperty.class,WritableGrid.class,false);
+	    resource[11]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Grid",ScalarProperty.class,WritableGrid.class,false);
+	    resource[12]= new DefaultModelResource(ModelResource.CATEGORY_OUTPUT,"Step Results",MultiGrid.class,false);
+	    resource[13]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Road Gravity Sensitivity",ScalarProperty.class,Double.class,false);
+	    resource[14]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Slope Sensitivity",ScalarProperty.class,Double.class,false);
+	    resource[15]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical Low",ScalarProperty.class,Double.class,false);
+	    resource[16]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Critical High",ScalarProperty.class,Double.class,false);
+	    resource[17]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Boom",ScalarProperty.class,Double.class,false);
+	    resource[18]= new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Bust",ScalarProperty.class,Double.class,false);
+	    
+	 	// ===== Ressourcen Bezeichnungen lokalisieren =====
+	    resetCaptions(null);
+	}
+	
+	
+	@Override
+	public void checkAndError() throws XuluDataException {
+		// TODO Auto-generated method stub
+		super.checkAndError();
+	}
+}

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModel_MC.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModel_MC.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModel_MC.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,198 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+
+import schmitzm.data.property.PropertyReadAccess;
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.model.XuluModel;
+
+/**
+ *  <b>Urban Growth Model with Monte-Carlo Iterations</b><br>
+ *  This model is based on the {@link UrbanGrowthModel Urban Growth Model}, developed by Keith Clarke at the UC Santa Barbara, CA, within the Gigalopolis Project, funded by the
+ *  USGS. It has exactly the same growth rules as its parent class, but runs with n Monte-Carlo Iterations. So the resulting map does not contain the urban extent after a model
+ *  run, but the probability for new urbanization. The more often a cell has been selected for urbanization during the Monte-Carlo Iterations, the higher is that value in the 
+ *  output map.
+ *  For a detailed description refer to {@link UrbanGrowthModel Urban Growth Model}
+ *  
+ *  <br>
+ *  In addition to the UGM parameters, this parameter is needed:<br>
+ * <ul>
+ *  <li><b>Monte Carlo Iterations({@code slopeGrid})</b>: The number of Monte Carlo Iterations.</li>
+ * </ul>
+ * 
+ * @see UrbanGrowthModel_MC_ContentManager
+ * @see UrbanGrowthModel
+ * @author <a href="mailto:goetzke at uni-bonn.de">Roland Goetzke</a>
+ * @version 1.0
+ */
+public class UrbanGrowthModel_MC extends UrbanGrowthModel{
+	
+	protected PropertyReadAccess RA_MonteCarlo = null; // Number of MonteCarlo Iterations
+	
+	protected int MonteCarlo = 0; // Number of MonteCarlo Iterations
+	protected int years = 0;
+
+	/**
+	 * First Constructor
+	 * @param contManager
+	 */
+	public UrbanGrowthModel_MC(UrbanGrowthModel_MC_ContentManager contManager) {
+		super(contManager);
+		this.contManager = (UrbanGrowthModel_MC_ContentManager) super.contManager;
+	}
+	/**
+	 * Second Constructor. The Content Manager is the parent content manager as well as the child content manager
+	 */
+	public UrbanGrowthModel_MC(){
+		super(new UrbanGrowthModel_MC_ContentManager());
+	}
+	
+	/**
+	 * Initializes the model. Like in the init method of every {@link XuluModel}
+	 * the resources are initalized. 
+	 */
+	public void performModelInit() {
+		super.performModelInit();
+		
+		
+		RA_MonteCarlo = null;
+		if (contManager.getResource(13).getData() != null)
+			RA_MonteCarlo = ((ScalarProperty) contManager.getResource(13).getData())
+					.getReadAccess(this);
+
+		MonteCarlo  = RA_MonteCarlo.getValueAsInt();
+		this.stepCount = MonteCarlo;
+		years = steps.getValueAsInt();
+	}
+		
+	/**
+	* like in every model: frees the resources
+	 */
+	public void performModelDispose() {
+		super.performModelDispose();
+		releaseAccess(RA_MonteCarlo);
+	}
+	
+	/**
+	 * The main method of the Urban Growth Model. For a detailed description refer to the performModelStep in 
+	 * {@link UrbanGrowthModel UrbanGrowthModel}. The difference is, that the number of steps is not based on
+	 * the years that have to be modelled, but on the number of Monte-Carlo iterations the model has to perform.
+	 * In every iteration the full {@link UrbanGrowthModel UrbanGrowthModel} is included in a for-loop. In the
+	 * StepResults GridList are the results for the final year for every Monte-Carlo iteration and the sum of
+	 * all iterations, which indicates high values for pixels that have been selected several times for urbanization. 
+	 */
+	public void performModelStep(int stepNo) {
+		
+		statusOut.println("Performing "+MonteCarlo+" Monte Carlo Iterations (years: "+stepNo);
+		long localStartTime = System.currentTimeMillis(); //time measure
+		Float actUrb = null;	//urban cell in the raster
+		for(int timeSteps = 1;timeSteps <=years;timeSteps++){	//for every time step...
+			statusOut.println("Year "+timeSteps);
+			boolean[][] tmpGrid = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+							
+			/*****************************************************************
+			 * DISPERSION and BREED (Growth Phase 1 and 2)
+			 *****************************************************************/
+			boolean[][] tmpGridDisp = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+			tmpGridDisp = DispersionGrowth(disp_value,breed);	//calls the method "DispersionBreed" to perform the Dispersion and Breed Growth Phase
+			int anzDispBreed = 0;	//number of cells urbanized by Dispersion and Breed
+			for (int x = 0; x < inputGrid.getWidth();x++)
+				for(int y = 0; y < inputGrid.getHeight();y++){
+					int X = inputGrid.getMinX() + x;
+					int Y = inputGrid.getMinY() + y;
+					if (tmpGridDisp[X][Y]==true){
+						anzDispBreed++;
+						tmpGrid[X][Y] = true;	//write the temporary Dispersion and Breed Cells to the overall temporary Cell array
+					}		
+				}
+			statusOut.println("Number of Spontaneous and New Spreading Center Cells: "+anzDispBreed);
+			writeToGrid(tmpGrid);	//calls the method "writeToGrid" to write the new urbanized cells to the output grid
+				
+			/*********************************************************************
+			 * EDGE
+			 *********************************************************************/
+			boolean[][] tmpGridSpread = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+			tmpGridSpread = EdgeGrowth(spread);	//calls the method "EdgeGrowth" to perform the Spread (Edge Growth) Phase
+			int anzSpread = 0;	//number of cells urbanized by Spread
+			for (int x = 0; x < inputGrid.getWidth();x++)
+				for(int y = 0; y < inputGrid.getHeight();y++){
+					int X = inputGrid.getMinX() + x;
+					int Y = inputGrid.getMinY() + y;
+					if (tmpGridSpread[X][Y]==true){
+						anzSpread++;
+						tmpGrid[X][Y] = true;	//write the temporary Spread cells to the overall temporary Cell array
+					}		
+				}
+			statusOut.println("Number of Edge Growth Cells: "+anzSpread);
+			writeToGrid(tmpGrid);	//calls the method "writeToGrid" to write the new urbanized cells to the output grid
+			
+			/*********************************************************************
+			 * ROAD
+			 *********************************************************************/
+			
+			boolean[][] tmpGridRoad = new boolean[inputGrid.getWidth()][inputGrid.getHeight()];	//a temporary raster
+			tmpGridRoad = RoadGrowth(tmpGrid,rg_value,breed,disp);	//calls the method "RoadGrowth" to perform the Road weighted growth
+			int anzRoad = 0;	//number of cells urbanized by Road Growth
+			for (int x = 0; x < inputGrid.getWidth();x++)
+				for(int y = 0; y < inputGrid.getHeight();y++){
+					int X = inputGrid.getMinX() + x;
+					int Y = inputGrid.getMinY() + y;
+					if (tmpGridRoad[X][Y]==true){
+						anzRoad++;
+						tmpGrid[X][Y] = true;	//write the temporary Road Growth cells to the overall temporary Cell array
+					}		
+				}
+			statusOut.println("Number of Road Growth Cells: "+anzRoad);
+			writeToGrid(tmpGrid);	//calls the method "writeToGrid" to write the new urbanized cells to the output grid
+			
+			int anzGesamt = 0;
+			
+			// Write the temporary Grid to the Output Grid
+			for (int y = 1; y < inputGrid.getHeight()-1;y++ ) {
+				for (int x = 1; x < inputGrid.getWidth()-1; x++ ) {
+					
+					int X = inputGrid.getMinX() + x;
+					int Y = inputGrid.getMinY() + y;
+					
+					if (tmpGrid[x][y] == true)
+						anzGesamt++;
+					
+					boolean lebt = outputGrid.getRasterSampleAsFloat(X , Y ) > 0f;	//a cell is alive, when it is 1
+					if (tmpGrid[x][y] == false)	//if there is nothing in the temporary raster
+						tmpGrid[x][y] = lebt;	//take the values from the current output raster
+					
+					outputGrid.setRasterSample( tmpGrid[x][y] ? 1f : 0f ,X ,Y);	//write the results in the output raster
+					actUrb  = (Float)outputGrid.getRasterSample(x,y);	//the actual urban extent
+					//	outStep.getGrid(stepNo-1).setRasterSample(actUrb,x,y);	//put the layer in the raster list containing the step results
+				}
+			}
+			statusOut.println("Urban pixels at step "+timeSteps+": "+anzGesamt);	
+		}
+		outStep.addGrid();	//add a raster to the GridList
+		
+		// Write the temporary Grid to the Output Grid
+		for (int y = 1; y < inputGrid.getHeight()-1;y++ ) {
+			for (int x = 1; x < inputGrid.getWidth()-1; x++ ) {
+				actUrb  = (Float)outputGrid.getRasterSample(x,y);	//the actual urban extent
+				outStep.getGrid(stepNo-1).setRasterSample(actUrb,x,y);	//put the layer in the raster list containing the step results
+			}
+		}	
+		
+		countSetIndividuals();	//sets the outputGrid to the initial inputGrid in order to start the next modelling step with the same initial map
+		System.out.println("Finished step " + (stepNo) + " in "
+				+ ((System.currentTimeMillis() - localStartTime)) + " ms\n");
+		if (stepNo == MonteCarlo){
+			outStep.addGrid();	//add a final raster to the GridList (contains the sum of all iterations)
+			
+			for (int y = 1; y < inputGrid.getHeight()-1;y++ ) {
+				for (int x = 1; x < inputGrid.getWidth()-1; x++ ) {	//for every pixel...
+					float sumUrb = 0; 	//sum of pixel values
+					for (int gridNo = 0; gridNo <= stepNo; gridNo++){	//look in every grid of the GridList
+						float tempUrb = (Float) outStep.getGrid(gridNo).getRasterSample(x,y);	//take the pixel value
+						sumUrb  += tempUrb;		//and add its value
+					}
+					outStep.getGrid(stepNo).setRasterSample(sumUrb,x,y);	//put the layer in the raster list containing the step results
+				}
+			}	
+		}
+	}
+}

Added: branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModel_MC_ContentManager.java
===================================================================
--- branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModel_MC_ContentManager.java	2010-02-04 17:08:57 UTC (rev 73)
+++ branches/1.8-gt2-2.6/src/edu/bonn/xulu/plugin/model/sleuth/UrbanGrowthModel_MC_ContentManager.java	2010-02-04 17:19:03 UTC (rev 74)
@@ -0,0 +1,26 @@
+package edu.bonn.xulu.plugin.model.sleuth;
+
+import schmitzm.data.property.ScalarProperty;
+import edu.bonn.xulu.data.XuluDataException;
+import edu.bonn.xulu.model.ModelResource;
+import edu.bonn.xulu.model.ValuePropertyResource;
+
+public class UrbanGrowthModel_MC_ContentManager extends UrbanGrowthModelContentManager {
+
+	public UrbanGrowthModel_MC_ContentManager(int additionalRes) {
+		super(1+additionalRes);
+		resource[13] = new ValuePropertyResource(ModelResource.CATEGORY_INPUT,"Monte-Carlo Iterations",ScalarProperty.class,Integer.class,false);
+	}
+
+	public UrbanGrowthModel_MC_ContentManager() {
+		this(0);
+		
+	}
+	
+	@Override
+	public void checkAndError() throws XuluDataException {
+		// TODO Auto-generated method stub
+		super.checkAndError();
+	}
+
+}



More information about the Xulu-commits mailing list