//--------------------------------------------------------------------- /// <summary> /// Gets a neighboring site. /// </summary> /// <param name="neighborLocation"> /// The location of the neighboring site relative to the site. /// </param> /// <returns> /// a site that converts to false if the neighbor's location is not /// a valid location for the site's landscape. /// </returns> public Site GetNeighbor(RelativeLocation neighborLocation) { Location?neighborAbsoluteLocation = location + neighborLocation; if (neighborAbsoluteLocation.HasValue) { return(landscape.GetSite(neighborAbsoluteLocation.Value)); } return(new Site()); }
public RelativeLocationWeighted (RelativeLocation location, double weight) { this.location = location; this.weight = weight; }
//--------------------------------------------------------------------- /// <summary> /// Gets a neighboring site. /// </summary> /// <param name="neighborLocation"> /// The location of the neighboring site relative to the site. /// </param> /// <returns> /// a site that converts to false if the neighbor's location is not /// a valid location for the site's landscape. /// </returns> public Site GetNeighbor(RelativeLocation neighborLocation) { Location? neighborAbsoluteLocation = location + neighborLocation; if (neighborAbsoluteLocation.HasValue) return landscape.GetSite(neighborAbsoluteLocation.Value); return new Site(); }
//--------------------------------------------------------------------- /// <summary> /// Runs the component for a particular timestep. /// </summary> /// <param name="currentTime"> /// The current model timestep. /// </param> public override void Run() { double CellLength = PlugIn.ModelCore.CellLength; // Calculate Local Variables foreach (IMapDefinition map in mapDefs) { List<IForestType> forestTypes = map.ForestTypes; foreach (Site site in modelCore.Landscape.AllSites) { int mapCode = 0; if (site.IsActive) mapCode = CalcForestType(forestTypes, site); else mapCode = 0; SiteVars.LocalVars[site][map.Name] = mapCode; } } // Calculate Derived Variables foreach (IVariableDefinition var in varDefs) { foreach (Site site in modelCore.Landscape.AllSites) { SiteVars.DerivedVars[site][var.Name] = 0; } List<string> variables = var.Variables; List<string> operators = var.Operators; // Parse variable name into mapDef and fortype for (int i = 0; i < variables.Count; i++) { string fullVar = variables[i]; // string[] varSplit = Regex.Split(fullVar, "\\[.*?\\]"); string[] varSplit = fullVar.Split(new char[] { '[', ']' }, StringSplitOptions.RemoveEmptyEntries); string mapName = varSplit[0]; string varName = varSplit[1]; int mapCode = 0; foreach (IMapDefinition map in mapDefs) { if (map.Name == mapName) { int forTypeCnt = 1; foreach (IForestType forestType in map.ForestTypes) { if (forestType.Name == varName) { mapCode = forTypeCnt; } forTypeCnt++; } } } foreach (Site site in modelCore.Landscape.AllSites) { if (SiteVars.LocalVars[site][mapName] == mapCode) { SiteVars.DerivedVars[site][var.Name] = 1; } } } } // Calculate Neighborhood Variables foreach (INeighborVariableDefinition neighborVar in neighborVarDefs) { //Parse LocalVar string fullVar = neighborVar.LocalVariable; string[] varSplit = fullVar.Split(new char[] { '[', ']' }, StringSplitOptions.RemoveEmptyEntries); string varName = ""; int mapCode = 0; string mapName = ""; if (varSplit.Length > 1) { mapName = varSplit[0]; varName = varSplit[1]; foreach (IMapDefinition map in mapDefs) { if (map.Name == mapName) { int forTypeCnt = 1; foreach (IForestType forestType in map.ForestTypes) { if (forestType.Name == varName) { mapCode = forTypeCnt; } forTypeCnt++; } } } } else { varName = fullVar; } // Calculate neighborhood //PlugIn.ModelCore.UI.WriteLine("Creating Dispersal Neighborhood List."); List<RelativeLocation> neighborhood = new List<RelativeLocation>(); int neighborRadius = neighborVar.NeighborRadius; int numCellRadius = (int)(neighborRadius / CellLength); //PlugIn.ModelCore.UI.WriteLine("NeighborRadius={0}, CellLength={1}, numCellRadius={2}", neighborRadius, CellLength, numCellRadius); double centroidDistance = 0; double cellLength = CellLength; for (int row = (numCellRadius * -1); row <= numCellRadius; row++) { for (int col = (numCellRadius * -1); col <= numCellRadius; col++) { centroidDistance = DistanceFromCenter(row, col); //PlugIn.ModelCore.Log.WriteLine("Centroid Distance = {0}.", centroidDistance); if (centroidDistance <= neighborRadius) { neighborhood.Add(new RelativeLocation(row, col)); } } } // Calculate neighborhood value (% area of forest types) foreach (Site site in modelCore.Landscape.AllSites) { int totalNeighborCells = 0; int targetNeighborCells = 0; foreach (RelativeLocation relativeLoc in neighborhood) { Site neighbor = site.GetNeighbor(relativeLoc); if (neighbor != null && neighbor.IsActive) { if (mapName == "") { if (SiteVars.DerivedVars[neighbor][varName] > 0) targetNeighborCells++; } else if (mapName.Equals("ecoregion", StringComparison.OrdinalIgnoreCase)) { if (varName.Equals(PlugIn.ModelCore.Ecoregion[neighbor].Name, StringComparison.OrdinalIgnoreCase)) { targetNeighborCells++; } } else if (SiteVars.LocalVars[neighbor][mapName] == mapCode) { targetNeighborCells++; } totalNeighborCells++; } } double pctValue = 100.0 * (double)targetNeighborCells / (double)totalNeighborCells; // Calculate transformation double transformValue = pctValue; if (neighborVar.Transform.Equals("log10", StringComparison.OrdinalIgnoreCase)) { transformValue = Math.Log10(pctValue + 1); } else if (neighborVar.Transform.Equals("ln", StringComparison.OrdinalIgnoreCase)) { transformValue = Math.Log(pctValue + 1); } // Write Neighbhorhood Site Variable SiteVars.NeighborVars[site][neighborVar.Name] = (float)transformValue; } } // Calculate Distance Variables foreach (IDistanceVariableDefinition distanceVar in distanceVarDefs) { //Parse LocalVar string fullVar = distanceVar.LocalVariable; string[] varSplit = fullVar.Split(new char[] { '[', ']' }, StringSplitOptions.RemoveEmptyEntries); string varName = ""; int mapCode = 0; string mapName = ""; if (varSplit.Length > 1) { mapName = varSplit[0]; varName = varSplit[1]; foreach (IMapDefinition map in mapDefs) { if (map.Name == mapName) { int forTypeCnt = 1; foreach (IForestType forestType in map.ForestTypes) { if (forestType.Name == varName) { mapCode = forTypeCnt; } forTypeCnt++; } } } } else { varName = fullVar; } // Calculate distance value (meters) foreach (Site site in modelCore.Landscape.AllSites) { double minDistance = double.MaxValue; // Spiral outward algorithm (http://stackoverflow.com/questions/3330181/algorithm-for-finding-nearest-object-on-2d-grid) // Start coordinates int xs = 0; int ys = 0; // Check point (xs, ys) if (mapName == "") { if (SiteVars.DerivedVars[site][varName] > 0) minDistance = 0; } else if (mapName.Equals("ecoregion", StringComparison.OrdinalIgnoreCase)) { if (varName.Equals(PlugIn.ModelCore.Ecoregion[site].Name, StringComparison.OrdinalIgnoreCase)) { minDistance = 0; } } else if (SiteVars.LocalVars[site][mapName] == mapCode) { minDistance = 0; } int maxD1 = site.Location.Row + site.Location.Column; int maxD2 = site.Location.Row + (PlugIn.ModelCore.Landscape.Columns - site.Location.Column); int maxD3 = (PlugIn.ModelCore.Landscape.Rows - site.Location.Row) + site.Location.Column; int maxD4 = (PlugIn.ModelCore.Landscape.Rows - site.Location.Row) + (PlugIn.ModelCore.Landscape.Columns - site.Location.Column); int maxDistance = Math.Max(maxD1, maxD2); maxDistance = Math.Max(maxDistance, maxD3); maxDistance = Math.Max(maxDistance, maxD4); for (int d = 1; d < maxDistance; d++) { double minCentroidDistance = double.MaxValue; for (int i = 0; i < d + 1; i++) { int x1 = xs - d + i; int y1 = ys - i; // Check point (x1, y1) double centroidDistance = DistanceFromCenter(y1, x1); if (centroidDistance < minCentroidDistance) minCentroidDistance = centroidDistance; if (centroidDistance >= minDistance + CellLength) { break; } if (centroidDistance < minDistance) { RelativeLocation relativeloc = new RelativeLocation(y1, x1); Site neighbor = site.GetNeighbor(relativeloc); int neighborRow = neighbor.Location.Row; int neighborCol = neighbor.Location.Column; if ((neighborRow > 0 && neighborRow <= PlugIn.ModelCore.Landscape.Rows) && ((neighborCol > 0 && neighborCol <= PlugIn.ModelCore.Landscape.Columns))) { if (mapName == "") { if (SiteVars.DerivedVars[neighbor][varName] > 0) minDistance = centroidDistance; } else if (mapName.Equals("ecoregion", StringComparison.OrdinalIgnoreCase)) { if (varName.Equals(PlugIn.ModelCore.Ecoregion[neighbor].Name, StringComparison.OrdinalIgnoreCase)) { minDistance = centroidDistance; } } else if (SiteVars.LocalVars[neighbor][mapName] == mapCode) { minDistance = centroidDistance; } } } int x2 = xs + d - i; int y2 = ys + i; // Check point (x2, y2) centroidDistance = DistanceFromCenter(y2, x2); if (centroidDistance < minCentroidDistance) minCentroidDistance = centroidDistance; if (centroidDistance >= minDistance + CellLength) { break; } if (centroidDistance < minDistance) { RelativeLocation relativeloc = new RelativeLocation(y2, x2); Site neighbor = site.GetNeighbor(relativeloc); int neighborRow = neighbor.Location.Row; int neighborCol = neighbor.Location.Column; if ((neighborRow > 0 && neighborRow <= PlugIn.ModelCore.Landscape.Rows) && ((neighborCol > 0 && neighborCol <= PlugIn.ModelCore.Landscape.Columns))) { if (mapName == "") { if (SiteVars.DerivedVars[neighbor][varName] > 0) minDistance = centroidDistance; } else if (mapName.Equals("ecoregion", StringComparison.OrdinalIgnoreCase)) { if (varName.Equals(PlugIn.ModelCore.Ecoregion[neighbor].Name, StringComparison.OrdinalIgnoreCase)) { minDistance = centroidDistance; } } else if (SiteVars.LocalVars[neighbor][mapName] == mapCode) { minDistance = centroidDistance; } } } } for (int i = 1; i < d; i++) { int x1 = xs - i; int y1 = ys + d - i; // Check point (x1, y1) double centroidDistance = DistanceFromCenter(y1, x1); if (centroidDistance < minCentroidDistance) minCentroidDistance = centroidDistance; if (centroidDistance >= minDistance + CellLength) { break; } if (centroidDistance < minDistance) { RelativeLocation relativeloc = new RelativeLocation(y1, x1); Site neighbor = site.GetNeighbor(relativeloc); int neighborRow = neighbor.Location.Row; int neighborCol = neighbor.Location.Column; if ((neighborRow > 0 && neighborRow <= PlugIn.ModelCore.Landscape.Rows) && ((neighborCol > 0 && neighborCol <= PlugIn.ModelCore.Landscape.Columns))) { if (mapName == "") { if (SiteVars.DerivedVars[neighbor][varName] > 0) minDistance = centroidDistance; } else if (mapName.Equals("ecoregion", StringComparison.OrdinalIgnoreCase)) { if (varName.Equals(PlugIn.ModelCore.Ecoregion[neighbor].Name, StringComparison.OrdinalIgnoreCase)) { minDistance = centroidDistance; } } else if (SiteVars.LocalVars[neighbor][mapName] == mapCode) { minDistance = centroidDistance; } } } int x2 = xs + d - i; int y2 = ys - i; // Check point (x2, y2) centroidDistance = DistanceFromCenter(y2, x2); if (centroidDistance < minCentroidDistance) minCentroidDistance = centroidDistance; if (centroidDistance >= minDistance + CellLength) { break; } if (centroidDistance < minDistance) { RelativeLocation relativeloc = new RelativeLocation(y2, x2); Site neighbor = site.GetNeighbor(relativeloc); int neighborRow = neighbor.Location.Row; int neighborCol = neighbor.Location.Column; if ((neighborRow > 0 && neighborRow <= PlugIn.ModelCore.Landscape.Rows) && ((neighborCol > 0 && neighborCol <= PlugIn.ModelCore.Landscape.Columns))) { if (mapName == "") { if (SiteVars.DerivedVars[neighbor][varName] > 0) minDistance = centroidDistance; } else if (mapName.Equals("ecoregion", StringComparison.OrdinalIgnoreCase)) { if (varName.Equals(PlugIn.ModelCore.Ecoregion[neighbor].Name, StringComparison.OrdinalIgnoreCase)) { minDistance = centroidDistance; } } else if (SiteVars.LocalVars[neighbor][mapName] == mapCode) { minDistance = centroidDistance; } } } } if (minCentroidDistance > minDistance + CellLength) { break; } } // Calculate transformation double transformValue = minDistance; if (distanceVar.Transform.Equals("log10", StringComparison.OrdinalIgnoreCase)) { transformValue = Math.Log10(minDistance + 1); } else if (distanceVar.Transform.Equals("ln", StringComparison.OrdinalIgnoreCase)) { transformValue = Math.Log(minDistance + 1); } // Write Distance Site Variable SiteVars.DistanceVars[site][distanceVar.Name] = (float)transformValue; } } // If timestep > 1 then calculate average value across years in timestep // Landscape variables are static, but climate variabls change annually int yearsProcessed = 0; for (int time = 1; time <= Timestep; ) { // Calculate Climate Variables foreach (IClimateVariableDefinition climateVar in climateVarDefs) { Dictionary<IEcoregion, Dictionary<string, double>> ecoClimateVars = new Dictionary<IEcoregion, Dictionary<string, double>>(); string varName = climateVar.Name; string climateLibVar = climateVar.ClimateLibVariable; string climateYear = climateVar.Year; int minMonth = climateVar.MinMonth; int maxMonth = climateVar.MaxMonth; string transform = climateVar.Transform; int currentYear = PlugIn.ModelCore.CurrentTime - Timestep + time; int actualYear = currentYear; int firstActiveEco = 0; foreach (IEcoregion ecoregion in modelCore.Ecoregions) { if (ecoregion.Active) { firstActiveEco = ecoregion.Index; break; } } if (Climate.Future_MonthlyData != null) { AnnualClimate_Monthly AnnualWeather = Climate.Future_MonthlyData[Climate.Future_MonthlyData.Keys.Min()][firstActiveEco]; int maxSpinUpYear = Climate.Spinup_MonthlyData.Keys.Max(); if (PlugIn.ModelCore.CurrentTime > 0) { currentYear = (currentYear - 1) + Climate.Future_MonthlyData.Keys.Min(); if (climateYear.Equals("prev", StringComparison.OrdinalIgnoreCase)) { if (Climate.Future_MonthlyData.ContainsKey(currentYear - 1)) { AnnualWeather = Climate.Future_MonthlyData[currentYear - 1][firstActiveEco]; } else { AnnualWeather = Climate.Spinup_MonthlyData[maxSpinUpYear][firstActiveEco]; } } else if (climateYear.Equals("current", StringComparison.OrdinalIgnoreCase)) { AnnualWeather = Climate.Future_MonthlyData[currentYear][firstActiveEco]; } else { string mesg = string.Format("Year for climate variable {0} is {1}; expected 'current' or 'prev'.", climateVar.Name, climateVar.Year); throw new System.ApplicationException(mesg); } } if (PlugIn.ModelCore.CurrentTime == 0) { if (climateYear.Equals("prev", StringComparison.OrdinalIgnoreCase)) AnnualWeather = Climate.Spinup_MonthlyData[maxSpinUpYear - Timestep + time - 1][firstActiveEco]; else if (climateYear.Equals("current", StringComparison.OrdinalIgnoreCase)) AnnualWeather = Climate.Spinup_MonthlyData[maxSpinUpYear - Timestep + time][firstActiveEco]; else { string mesg = string.Format("Year for climate variable {0} is {1}; expected 'current' or 'prev'.", climateVar.Name, climateVar.Year); throw new System.ApplicationException(mesg); } } actualYear = AnnualWeather.Year; } else { if (climateYear.Equals("prev", StringComparison.OrdinalIgnoreCase)) actualYear = currentYear - 1; } if (climateVar.SourceName.Equals("library", StringComparison.OrdinalIgnoreCase)) { foreach (IEcoregion ecoregion in modelCore.Ecoregions) { if (ecoregion.Active) { if (!ecoClimateVars.ContainsKey(ecoregion)) { ecoClimateVars.Add(ecoregion, new Dictionary<string, double>()); } AnnualClimate_Monthly AnnualWeather = Climate.Future_MonthlyData[Climate.Future_MonthlyData.Keys.Min()][ecoregion.Index]; int maxSpinUpYear = Climate.Spinup_MonthlyData.Keys.Max(); if (PlugIn.ModelCore.CurrentTime == 0) { if (climateYear.Equals("prev", StringComparison.OrdinalIgnoreCase)) AnnualWeather = Climate.Spinup_MonthlyData[maxSpinUpYear - Timestep + time - 1][ecoregion.Index]; else AnnualWeather = Climate.Spinup_MonthlyData[maxSpinUpYear - Timestep + time][ecoregion.Index]; } else if (climateYear.Equals("prev", StringComparison.OrdinalIgnoreCase)) { if (!Climate.Future_MonthlyData.ContainsKey(currentYear - 1)) { AnnualWeather = Climate.Spinup_MonthlyData[maxSpinUpYear][ecoregion.Index]; } else AnnualWeather = Climate.Future_MonthlyData[currentYear - 1][ecoregion.Index]; } else { AnnualWeather = Climate.Future_MonthlyData[currentYear][ecoregion.Index]; } double monthTotal = 0; int monthCount = 0; double varValue = 0; var monthRange = Enumerable.Range(minMonth, (maxMonth - minMonth) + 1); foreach (int monthIndex in monthRange) { //if (climateVar.ClimateLibVariable == "PDSI") //{ //double monthPDSI = PDSI_Calculator.PDSI_Monthly[monthIndex-1]; // varValue = monthPDSI; //} if (climateVar.ClimateLibVariable.Equals("precip", StringComparison.OrdinalIgnoreCase)) { double monthPrecip = AnnualWeather.MonthlyPrecip[monthIndex - 1]; varValue = monthPrecip * 10.0; //Convert cm to mm } else if (climateVar.ClimateLibVariable.Equals("temp", StringComparison.OrdinalIgnoreCase)) { double monthTemp = AnnualWeather.MonthlyTemp[monthIndex - 1]; varValue = monthTemp; } else { string mesg = string.Format("Climate variable {0} is {1}; expected 'precip' or 'temp'.", climateVar.Name, climateVar.ClimateLibVariable); throw new System.ApplicationException(mesg); } monthTotal += varValue; monthCount++; } double avgValue = monthTotal / (double)monthCount; double transformValue = avgValue; if (transform.Equals("log10", StringComparison.OrdinalIgnoreCase)) { transformValue = Math.Log10(avgValue + 1); } else if (transform.Equals("ln", StringComparison.OrdinalIgnoreCase)) { transformValue = Math.Log(avgValue + 1); } if (!ecoClimateVars[ecoregion].ContainsKey(varName)) { ecoClimateVars[ecoregion].Add(varName, 0.0); } ecoClimateVars[ecoregion][varName] = transformValue; } } //foreach (IEcoregion ecoregion in modelCore.Ecoregions) foreach (Site site in modelCore.Landscape.AllSites) { IEcoregion ecoregion = PlugIn.ModelCore.Ecoregion[site]; double climateValue = 0; if (ecoregion != null) { climateValue = ecoClimateVars[ecoregion][varName]; } // Write Climate Site Variable SiteVars.ClimateVars[site][varName] = (float)climateValue; } } // if (climateVar.SourceName.Equals("library", StringComparison.OrdinalIgnoreCase)) else { double monthTotal = 0; int monthCount = 0; double varValue = 0; var monthRange = Enumerable.Range(minMonth, (maxMonth - minMonth) + 1); foreach (int monthIndex in monthRange) { string selectString = "Year = '" + actualYear + "' AND Month = '" + monthIndex + "'"; DataRow[] rows = parameters.ClimateDataTable.Select(selectString); if (rows.Length == 0) { string mesg = string.Format("Climate data is empty. No record exists for variable {0} in year {1}.", climateVar.Name, actualYear); if (actualYear == 0) { mesg = mesg + " Note that if using the options Monthly_AverageAllYears or Daily_AverageAllYears you should provide average values for climate variables listed as Year 0."; } throw new System.ApplicationException(mesg); } foreach (DataRow row in rows) { varValue = Convert.ToDouble(row[climateVar.ClimateLibVariable]); } monthTotal += varValue; monthCount++; } double avgValue = monthTotal / (double)monthCount; double transformValue = avgValue; if (transform.Equals("log10", StringComparison.OrdinalIgnoreCase)) //if (transform == "Log10") { transformValue = Math.Log10(avgValue + 1); } else if (transform.Equals("ln", StringComparison.OrdinalIgnoreCase)) //else if (transform == "ln") { transformValue = Math.Log(avgValue + 1); } foreach (Site site in modelCore.Landscape.AllSites) { SiteVars.ClimateVars[site][varName] = (float)transformValue; } } // not if (climateVar.SourceName.Equals("library", StringComparison.OrdinalIgnoreCase)) } // Calculate Species Models foreach (IModelDefinition model in modelDefs) { foreach (ActiveSite site in modelCore.Landscape.ActiveSites) { IEcoregion ecoregion = ModelCore.Ecoregion[site]; double modelPredict = 0; int paramIndex = 0; foreach (string parameter in model.Parameters) { string paramType = model.ParamTypes[paramIndex]; double paramValue = model.Values[paramIndex]; if (paramType.Equals("int", StringComparison.OrdinalIgnoreCase)) { modelPredict += paramValue; } else if (paramType.Equals("neighbor", StringComparison.OrdinalIgnoreCase)) { if (SiteVars.NeighborVars[site].ContainsKey(parameter)) { double modelValue = SiteVars.NeighborVars[site][parameter]; modelValue = modelValue * paramValue; modelPredict += modelValue; } else { string mesg = string.Format("The Neighborhood parameter {0} is listed for model {1} but is not included under NeighborhoodVariables.", parameter, model.Name); throw new System.ApplicationException(mesg); } } else if (paramType.Equals("climate", StringComparison.OrdinalIgnoreCase)) { if (SiteVars.ClimateVars[site].ContainsKey(parameter)) { double modelValue = SiteVars.ClimateVars[site][parameter]; modelValue = modelValue * paramValue; modelPredict += modelValue; } else { string mesg = string.Format("The Climate parameter {0} is listed for model {1} but is not included under ClimateVariables.", parameter, model.Name); throw new System.ApplicationException(mesg); } } else if (paramType.Equals("distance", StringComparison.OrdinalIgnoreCase)) { if (SiteVars.DistanceVars[site].ContainsKey(parameter)) { double modelValue = SiteVars.DistanceVars[site][parameter]; modelValue = modelValue * paramValue; modelPredict += modelValue; } else { string mesg = string.Format("The Distance parameter {0} is listed for model {1} but is not included under DistanceVariables.", parameter, model.Name); throw new System.ApplicationException(mesg); } } else if (paramType.Equals("biomass", StringComparison.OrdinalIgnoreCase)) { double modelValue = Util.ComputeBiomass(SiteVars.Cohorts[site]); modelValue = modelValue * paramValue; modelPredict += modelValue; } else if (paramType.Equals("lnbiomass", StringComparison.OrdinalIgnoreCase)) { double modelValue = Math.Log(Util.ComputeBiomass(SiteVars.Cohorts[site]) + 1); modelValue = modelValue * paramValue; modelPredict += modelValue; } else if (paramType.Equals("logbiomass", StringComparison.OrdinalIgnoreCase)) { double modelValue = Math.Log10(Util.ComputeBiomass(SiteVars.Cohorts[site]) + 1); modelValue = modelValue * paramValue; modelPredict += modelValue; } else if (paramType.Equals("age", StringComparison.OrdinalIgnoreCase)) { double modelValue = Util.ComputeAge(SiteVars.Cohorts[site]); modelValue = modelValue * paramValue; modelPredict += modelValue; } else if (paramType.Equals("lnage", StringComparison.OrdinalIgnoreCase)) { double modelValue = Math.Log(Util.ComputeAge(SiteVars.Cohorts[site]) + 1); modelValue = modelValue * paramValue; modelPredict += modelValue; } else if (paramType.Equals("logage", StringComparison.OrdinalIgnoreCase)) { double modelValue = Math.Log10(Util.ComputeAge(SiteVars.Cohorts[site]) + 1); modelValue = modelValue * paramValue; modelPredict += modelValue; } else if (paramType.Contains("*")) { string[] paramTypes = paramType.Split('*'); string[] splitParameters = parameter.Split('*'); double paramProduct = 1.0; if (paramTypes.Length != splitParameters.Length) { string mesg = string.Format("For model {0}, the number of parameters in {1} does not match the number of paramter types {2}.", model.Name, parameter, paramType); throw new System.ApplicationException(mesg); } else { int interactionIndex = 0; foreach (string pType in paramTypes) { string param = splitParameters[interactionIndex]; if (pType.Equals("neighbor", StringComparison.OrdinalIgnoreCase)) { if (SiteVars.NeighborVars[site].ContainsKey(param)) { double modelValue = SiteVars.NeighborVars[site][param]; paramProduct *= modelValue; } else { string mesg = string.Format("The Neighborhood parameter {0} is listed for model {1} but is not included under NeighborhoodVariables.", param, model.Name); throw new System.ApplicationException(mesg); } } else if (pType.Equals("climate", StringComparison.OrdinalIgnoreCase)) //else if (paramType == "climate") { if (SiteVars.ClimateVars[site].ContainsKey(param)) { double modelValue = SiteVars.ClimateVars[site][param]; paramProduct *= modelValue; } else { string mesg = string.Format("The Climate parameter {0} is listed for model {1} but is not included under ClimateVariables.", param, model.Name); throw new System.ApplicationException(mesg); } } else if (pType.Equals("distance", StringComparison.OrdinalIgnoreCase)) //else if (paramType == "climate") { if (SiteVars.DistanceVars[site].ContainsKey(param)) { double modelValue = SiteVars.DistanceVars[site][param]; paramProduct *= modelValue; } else { string mesg = string.Format("The Distance parameter {0} is listed for model {1} but is not included under DistanceVariables.", param, model.Name); throw new System.ApplicationException(mesg); } } else if (pType.Equals("biomass", StringComparison.OrdinalIgnoreCase)) //else if (paramType =="biomass") { double modelValue = Util.ComputeBiomass(SiteVars.Cohorts[site]); paramProduct *= modelValue; } else { string mesg = string.Format("For model {0}, parameter {1} has parameter type {2}; expected 'int', 'neighbor', 'climate', 'distance', 'biomass','lnbiomass', 'logbiomass','age', 'lnage', 'logage', or 'interaction'.", model.Name, param, pType); throw new System.ApplicationException(mesg); } interactionIndex++; } double interactionValue = paramProduct * paramValue; modelPredict += interactionValue; } } else { string mesg = string.Format("For model {0}, parameter {1} has parameter type {2}; expected 'int', 'neighbor', 'climate', 'distance', 'biomass','lnbiomass', 'logbiomass','age', 'lnage', 'logage', or 'interaction'.", model.Name, parameter, paramType); throw new System.ApplicationException(mesg); } paramIndex++; } // Back-transform model prediction float annualPredict = (float)Math.Exp(modelPredict); // Write Site Variable if ((SiteVars.SpeciesModels[site].ContainsKey(model.Name)) && time > 1) { SiteVars.SpeciesModels[site][model.Name] += annualPredict; } else { SiteVars.SpeciesModels[site][model.Name] = annualPredict; } } // foreach (ActiveSite site in modelCore.Landscape.ActiveSites) } // foreach (IModelDefinition model in modelDefs) // If no climate variables then only process once regardless of timestep if (climateVarDefs.Count() == 0) { time = Timestep; } else { time += 1; } yearsProcessed++; } // for (int time = 1; time <= Timestep) Dictionary<string, float>[] ecoregionAvgValues = new Dictionary<string, float>[ModelCore.Ecoregions.Count]; Dictionary<string, float> landscapeAvgValues = new Dictionary<string, float>(); int[] activeSiteCount = new int[ModelCore.Ecoregions.Count]; foreach (IEcoregion ecoregion in ModelCore.Ecoregions) { ecoregionAvgValues[ecoregion.Index] = new Dictionary<string, float>(); activeSiteCount[ecoregion.Index] = 0; } foreach (ActiveSite site in ModelCore.Landscape) { IEcoregion ecoregion = ModelCore.Ecoregion[site]; activeSiteCount[ecoregion.Index]++; } // Calculate average over timestep foreach (IModelDefinition model in modelDefs) { float[] ecoregionSum = new float[ModelCore.Ecoregions.Count]; float landscapeSum = 0; // Write Site Variable foreach (ActiveSite site in ModelCore.Landscape) { IEcoregion ecoregion = ModelCore.Ecoregion[site]; float averageAnnual = SiteVars.SpeciesModels[site][model.Name] / yearsProcessed; SiteVars.SpeciesModels[site][model.Name] = averageAnnual; ecoregionSum[ecoregion.Index] += averageAnnual; landscapeSum += averageAnnual; } foreach (IEcoregion ecoregion in ModelCore.Ecoregions) { //ecoregionAvgValues[ecoregion.Index].Add(model.Name, 0); ecoregionAvgValues[ecoregion.Index][model.Name] = ecoregionSum[ecoregion.Index] / activeSiteCount[ecoregion.Index]; } landscapeAvgValues[model.Name] = landscapeSum / ModelCore.Landscape.ActiveSiteCount; } // Write Log File if (parameters.LogFileName != null) { foreach (IModelDefinition model in modelDefs) { habitatLog.Clear(); SpeciesHabitatLog shlog = new SpeciesHabitatLog(); shlog.Time = ModelCore.CurrentTime; shlog.Ecoregion = "TotalLandscape"; shlog.SpeciesModelName = model.Name; //shlog.NumSites = activeSiteCount[ecoregion.Index]; shlog.Index = landscapeAvgValues[model.Name]; habitatLog.AddObject(shlog); habitatLog.WriteToFile(); /* foreach (IEcoregion ecoregion in ModelCore.Ecoregions) { habitatLog.Clear(); shlog = new SpeciesHabitatLog(); shlog.Time = ModelCore.CurrentTime; shlog.Ecoregion = ecoregion.Name; shlog.SpeciesModelName = model.Name; //shl.EcoregionIndex = ecoregion.Index; //shlog.NumSites = activeSiteCount[ecoregion.Index]; shlog.Index = ecoregionAvgValues[ecoregion.Index][model.Name]; habitatLog.AddObject(shlog); habitatLog.WriteToFile(); } * */ } } if (parameters.SpeciesLogFileNames != null) { int selectModelCount = 0; foreach (IModelDefinition model in modelDefs) { //MetadataTable<IndividualSpeciesHabitatLog> speciesLog = sppLogs[selectModelCount]; sppLogs[selectModelCount].Clear(); IndividualSpeciesHabitatLog sppLog = new IndividualSpeciesHabitatLog(); sppLog.Time = ModelCore.CurrentTime; sppLog.Ecoregion = "TotalLandscape"; sppLog.SpeciesModel = model.Name; //shlog.NumSites = activeSiteCount[ecoregion.Index]; sppLog.Index = landscapeAvgValues[model.Name]; sppLogs[selectModelCount].AddObject(sppLog); sppLogs[selectModelCount].WriteToFile(); foreach (IEcoregion ecoregion in ModelCore.Ecoregions) { sppLogs[selectModelCount].Clear(); sppLog = new IndividualSpeciesHabitatLog(); sppLog.Time = ModelCore.CurrentTime; sppLog.Ecoregion = ecoregion.Name; sppLog.SpeciesModel = model.Name; //shlog.NumSites = activeSiteCount[ecoregion.Index]; sppLog.Index = ecoregionAvgValues[ecoregion.Index][model.Name]; sppLogs[selectModelCount].AddObject(sppLog); sppLogs[selectModelCount].WriteToFile(); } selectModelCount++; } } // Ouput Maps if (!(parameters.LocalVarMapFileNames == null)) { //----- Write LocalVar maps -------- foreach (MapDefinition localVar in parameters.ReclassMaps) { string localVarPath = LocalMapFileNames.ReplaceTemplateVars(parameters.LocalVarMapFileNames, localVar.Name, PlugIn.ModelCore.CurrentTime); using (IOutputRaster<BytePixel> outputRaster = modelCore.CreateRaster<BytePixel>(localVarPath, modelCore.Landscape.Dimensions)) { BytePixel pixel = outputRaster.BufferPixel; foreach (Site site in PlugIn.ModelCore.Landscape.AllSites) { if (site.IsActive) { pixel.MapCode.Value = (byte)(SiteVars.LocalVars[site][localVar.Name] + 1); } else { // Inactive site pixel.MapCode.Value = 0; } outputRaster.WriteBufferPixel(); } } } } if (!(parameters.NeighborMapFileNames == null)) { //----- Write LocalVar maps -------- foreach (NeighborVariableDefinition neighborVar in parameters.NeighborVars) { string neighborVarPath = NeighborMapFileNames.ReplaceTemplateVars(parameters.NeighborMapFileNames, neighborVar.Name, PlugIn.ModelCore.CurrentTime); using (IOutputRaster<ShortPixel> outputRaster = modelCore.CreateRaster<ShortPixel>(neighborVarPath, modelCore.Landscape.Dimensions)) { ShortPixel pixel = outputRaster.BufferPixel; foreach (Site site in PlugIn.ModelCore.Landscape.AllSites) { if (site.IsActive) { pixel.MapCode.Value = (short)(System.Math.Round(SiteVars.NeighborVars[site][neighborVar.Name] * 100.0)); } else { // Inactive site pixel.MapCode.Value = 0; } outputRaster.WriteBufferPixel(); } } } } if (!(parameters.ClimateMapFileNames == null)) { //----- Write LocalVar maps -------- foreach (ClimateVariableDefinition climateVar in parameters.ClimateVars) { string climateVarPath = ClimateMapFileNames.ReplaceTemplateVars(parameters.ClimateMapFileNames, climateVar.Name, PlugIn.ModelCore.CurrentTime); using (IOutputRaster<ShortPixel> outputRaster = modelCore.CreateRaster<ShortPixel>(climateVarPath, modelCore.Landscape.Dimensions)) { ShortPixel pixel = outputRaster.BufferPixel; foreach (Site site in PlugIn.ModelCore.Landscape.AllSites) { if (site.IsActive) { pixel.MapCode.Value = (short)(System.Math.Round(SiteVars.ClimateVars[site][climateVar.Name] * 100.0)); } else { // Inactive site pixel.MapCode.Value = 0; } outputRaster.WriteBufferPixel(); } } } } if (!(parameters.DistanceMapFileNames == null)) { //----- Write DistanceVar maps -------- foreach (DistanceVariableDefinition distanceVar in parameters.DistanceVars) { string distanceVarPath = DistanceMapFileNames.ReplaceTemplateVars(parameters.DistanceMapFileNames, distanceVar.Name, PlugIn.ModelCore.CurrentTime); using (IOutputRaster<ShortPixel> outputRaster = modelCore.CreateRaster<ShortPixel>(distanceVarPath, modelCore.Landscape.Dimensions)) { ShortPixel pixel = outputRaster.BufferPixel; foreach (Site site in PlugIn.ModelCore.Landscape.AllSites) { if (site.IsActive) { pixel.MapCode.Value = (short)(System.Math.Round(SiteVars.DistanceVars[site][distanceVar.Name] * 100.0)); } else { // Inactive site pixel.MapCode.Value = 0; } outputRaster.WriteBufferPixel(); } } } } if (!(parameters.SpeciesMapFileNames == null)) { //----- Write Species Model maps -------- foreach (ModelDefinition sppModel in parameters.Models) { string sppModelPath = SpeciesMapFileNames.ReplaceTemplateVars(parameters.SpeciesMapFileNames, sppModel.Name, PlugIn.ModelCore.CurrentTime); using (IOutputRaster<ShortPixel> outputRaster = modelCore.CreateRaster<ShortPixel>(sppModelPath, modelCore.Landscape.Dimensions)) { ShortPixel pixel = outputRaster.BufferPixel; foreach (Site site in PlugIn.ModelCore.Landscape.AllSites) { if (site.IsActive) { pixel.MapCode.Value = (short)System.Math.Round(SiteVars.SpeciesModels[site][sppModel.Name] * 100.0); //pixel.MapCode.Value = (short)System.Math.Round(SiteVars.SpeciesModels[site][sppModel.Name]); } else { // Inactive site pixel.MapCode.Value = 0; } outputRaster.WriteBufferPixel(); } } } } }
//--------------------------------------------------------------------- private List<Site> GetNeighbors(Site site, int windDirection, double windSpeed) { if (windDirection > 7) windDirection = 7; double[] windProbs = { (((4.0 - windSpeed)/8.0) * (1+windSpeed)), //Primary direction (((4.0 - windSpeed)/8.0) * (1+windSpeed)), (((4.0 - windSpeed)/8.0)), (((4.0 - windSpeed)/8.0) * (1-windSpeed)), (((4.0 - windSpeed)/8.0) * (1-windSpeed)), //Opposite of primary direction (((4.0 - windSpeed)/8.0) * (1-windSpeed)), (((4.0 - windSpeed)/8.0)), (((4.0 - windSpeed)/8.0) * (1+windSpeed)), }; double windProb = 0.0; int index = 0; int success = 0; List<Site> neighbors = new List<Site>(9); foreach (RelativeLocation relativeLoc in neighborhood) { Site neighbor = site.GetNeighbor(relativeLoc); if (index + windDirection > 7) windProb = windProbs[index + windDirection - 8]; else windProb = windProbs[index + windDirection]; if (neighbor != null && PlugIn.ModelCore.NextDouble() < windProb) { neighbors.Add(neighbor); success++; } index++; } //Next, add the 9th neighbor, a neighbor one cell beyond the //8 nearest neighbors. //array index 0 = north; 1 = northeast, 2 = east,...,8 = northwest int[] vertical ={2,2,0,-2,-2,-2,0,2}; int[] horizontal={0,2,2,2,0,-2,-2,-2}; RelativeLocation relativeLoc9 = new RelativeLocation(vertical[windDirection], horizontal[windDirection]); Site neighbor9 = site.GetNeighbor(relativeLoc9); if (neighbor9 != null && PlugIn.ModelCore.GenerateUniform() < windSpeed) neighbors.Add(neighbor9); return neighbors; }
//--------------------------------------------------------------------- //Generate List of 4,8,12, or 24 nearest neighbors. //--------------------------------------------------------------------- private static List<RelativeLocation> GetNeighbors(int numNeighbors) { RelativeLocation[] neighborhood4 = new RelativeLocation[] { new RelativeLocation( 0, 1), // east new RelativeLocation( 1, 0), // south new RelativeLocation( 0, -1), // west new RelativeLocation(-1, 0), // north }; RelativeLocation[] neighborhood8 = new RelativeLocation[] { new RelativeLocation(-1, 1), // northeast new RelativeLocation( 1, 1), // southeast new RelativeLocation( 1, -1), // southwest new RelativeLocation( -1, -1), // northwest }; RelativeLocation[] neighborhood12 = new RelativeLocation[] { new RelativeLocation(-2, 0), // north north new RelativeLocation( 0, 2), // east east new RelativeLocation( 2, 0), // south south new RelativeLocation( 0, -2), // west west }; RelativeLocation[] neighborhood24 = new RelativeLocation[] { new RelativeLocation(-2, -2), // northwest northwest new RelativeLocation( -2, -1), // northwest south new RelativeLocation( -1, -2), // northwest east new RelativeLocation( -2, 2), // northeast northeast new RelativeLocation( -2, 1), // northeast west new RelativeLocation( -1, 2), // northeast south new RelativeLocation( 2, 2), // southeast southeast new RelativeLocation(1, 2), // southeast north new RelativeLocation(2, 1), //southeast west new RelativeLocation( 2, -2), // southwest southwest new RelativeLocation( 2, -1), // southwest east new RelativeLocation( 1, -2), // southwest north }; //Progressively add neighbors as necessary: List<RelativeLocation> neighbors = new List<RelativeLocation>(); foreach (RelativeLocation relativeLoc in neighborhood4) neighbors.Add(relativeLoc); if(numNeighbors <= 4) return neighbors; foreach (RelativeLocation relativeLoc in neighborhood8) neighbors.Add(relativeLoc); if(numNeighbors <= 8) return neighbors; foreach (RelativeLocation relativeLoc in neighborhood12) neighbors.Add(relativeLoc); if(numNeighbors <= 12) return neighbors; foreach (RelativeLocation relativeLoc in neighborhood24) neighbors.Add(relativeLoc); return neighbors; }
//--------------------------------------------------------------------- //Generate a Relative Location array (with WEIGHTS) of neighbors. //Check each cell within a block surrounding the center point. This will //create a set of POTENTIAL neighbors. These potential neighbors //will need to be later checked to ensure that they are within the landscape // and active. private static IEnumerable<RelativeLocationWeighted> GetResourceNeighborhood(IAgent agent) { float CellLength = PlugIn.ModelCore.CellLength; PlugIn.ModelCore.UI.WriteLine("Creating Neighborhood List."); int neighborRadius = agent.NeighborRadius; int numCellRadius = (int) ((double) neighborRadius / CellLength) ; PlugIn.ModelCore.UI.WriteLine("NeighborRadius={0}, CellLength={1}, numCellRadius={2}", neighborRadius, CellLength, numCellRadius); double centroidDistance = 0; double cellLength = CellLength; double neighborWeight = 0; List<RelativeLocationWeighted> neighborhood = new List<RelativeLocationWeighted>(); for(int row=(numCellRadius * -1); row<=numCellRadius; row++) { for(int col=(numCellRadius * -1); col<=numCellRadius; col++) { neighborWeight = 0; centroidDistance = DistanceFromCenter(row ,col); //PlugIn.ModelCore.Log.WriteLine("Centroid Distance = {0}.", centroidDistance); if(centroidDistance <= neighborRadius && centroidDistance > 0) { if(agent.ShapeOfNeighbor == NeighborShape.uniform) neighborWeight = 1.0; if(agent.ShapeOfNeighbor == NeighborShape.linear) { //neighborWeight = (neighborRadius - centroidDistance + (cellLength/2)) / (double) neighborRadius; neighborWeight = 1.0 - (centroidDistance / (double) neighborRadius); } if(agent.ShapeOfNeighbor == NeighborShape.gaussian) { double halfRadius = neighborRadius / 2; neighborWeight = (float) System.Math.Exp(-1 * System.Math.Pow(centroidDistance, 2) / System.Math.Pow(halfRadius, 2)); } RelativeLocation reloc = new RelativeLocation(row, col); neighborhood.Add(new RelativeLocationWeighted(reloc, neighborWeight)); } } } return neighborhood; }