//--------------------------------------------------------------------------- private static double MinJanuaryTempModifier(AnnualClimate_Monthly weather, ISpecies species) // Is the January mean temperature greater than the species specified minimum? { int speciesMinimum = SpeciesData.MinJanTemp[species]; if (weather.MonthlyTemp[0] < speciesMinimum) { return(0.0); } else { return(1.0); } }
public static double Calculate(ISpecies species, ActiveSite site)//, int years) { IEcoregion climateRegion = PlugIn.ModelCore.Ecoregion[site]; int swhc = (int)((SiteVars.SoilFieldCapacity[site] - SiteVars.SoilWiltingPoint[site]) * SiteVars.SoilDepth[site]); int swhc_index = PlugIn.SWHC_List.BinarySearch(swhc); double tempMultiplier = 0.0; double soilMultiplier = 0.0; double minJanTempMultiplier = 0.0; //if (!ecoregion.Active || ClimateRegionData.ActiveSiteCount[ecoregion] < 1) // continue; double establishProbability = 0.0; AnnualClimate_Monthly ecoClimate = ClimateRegionData.AnnualWeather[climateRegion]; if (ecoClimate == null) { throw new System.ApplicationException("Error in Establishment: CLIMATE NULL."); } double ecoDryDays = SiteVars.DryDays[site]; // CalculateSoilMoisture(ecoClimate, climateRegion, ecoClimate.Year); soilMultiplier = SoilMoistureMultiplier(ecoClimate, species, ecoDryDays); tempMultiplier = BotkinDegreeDayMultiplier(ecoClimate, species); minJanTempMultiplier = MinJanuaryTempModifier(ecoClimate, species); // Liebig's Law of the Minimum is applied to the four multipliers for each year: double minMultiplier = System.Math.Min(tempMultiplier, soilMultiplier); minMultiplier = System.Math.Min(minJanTempMultiplier, minMultiplier); establishProbability += minMultiplier; establishProbability *= PlugIn.ProbEstablishAdjust; avgSoilMoisturelimit[species.Index, climateRegion.Index, swhc_index] += soilMultiplier; avgMATlimit[species.Index, climateRegion.Index, swhc_index] += tempMultiplier; avgJanuaryTlimit[species.Index, climateRegion.Index, swhc_index] += minJanTempMultiplier; avgPest[species.Index, climateRegion.Index, swhc_index] += establishProbability; Climate_SWHC_Count[climateRegion.Index, swhc_index]++; //if (establishProbability > 0.0) // PlugIn.ModelCore.UI.WriteLine("Spp={0}, Pest={1:0.000}: tM={2:0.0}, sM={3:0.0}, jM={4:0.0}", species.Name, establishProbability, tempMultiplier, soilMultiplier, minJanTempMultiplier); return(establishProbability); }
//public static void InitializeLogFile() //{ // string logFileName = "NECN-prob-establish-log.csv"; // PlugIn.ModelCore.UI.WriteLine(" Opening a NECN log file \"{0}\" ...", logFileName); // try { // log = Landis.Data.CreateTextFile(logFileName); // } // catch (Exception err) { // string mesg = string.Format("{0}", err.Message); // throw new System.ApplicationException(mesg); // } // log.AutoFlush = true; // log.WriteLine("Time, Species, ClimateRegion, NumberSitesChecked, AvgTempMult, AvgMinJanTempMult, AvgSoilMoistureMult, AvgProbEst"); //} public static double Calculate(ISpecies species, ActiveSite site) { IEcoregion climateRegion = PlugIn.ModelCore.Ecoregion[site]; double tempMultiplier = 0.0; double soilMultiplier = 0.0; double minJanTempMultiplier = 0.0; double establishProbability = 0.0; AnnualClimate_Monthly ecoClimate = ClimateRegionData.AnnualWeather[climateRegion]; if (ecoClimate == null) { throw new System.ApplicationException("Error in Establishment: CLIMATE NULL."); } double ecoDryDays = SiteVars.DryDays[site]; soilMultiplier = SoilMoistureMultiplier(ecoClimate, species, ecoDryDays); tempMultiplier = BotkinDegreeDayMultiplier(ecoClimate, species); minJanTempMultiplier = MinJanuaryTempModifier(ecoClimate, species); // Liebig's Law of the Minimum is applied to the four multipliers for each year: double minMultiplier = System.Math.Min(tempMultiplier, soilMultiplier); minMultiplier = System.Math.Min(minJanTempMultiplier, minMultiplier); establishProbability += minMultiplier; establishProbability *= PlugIn.ProbEstablishAdjust; avgSoilMoisturelimit[species.Index, climateRegion.Index] += soilMultiplier; avgMATlimit[species.Index, climateRegion.Index] += tempMultiplier; avgJanuaryTlimit[species.Index, climateRegion.Index] += minJanTempMultiplier; avgPest[species.Index, climateRegion.Index] += establishProbability; avgDryDays[species.Index, climateRegion.Index] += ecoDryDays; avgBeginGDD[species.Index, climateRegion.Index] += ecoClimate.BeginGrowing; avgEndGDD[species.Index, climateRegion.Index] += ecoClimate.EndGrowing; numberCalculations[species.Index, climateRegion.Index]++; return(establishProbability); }
//--------------------------------------------------------------------------- private static double CalculateSoilMoisture(AnnualClimate_Monthly weather, IEcoregion ecoregion, int year, ActiveSite site) // Calculate fraction of growing season with unfavorable soil moisture // for growth (Dry_Days_in_Grow_Seas) used in SoilMoistureMultiplier to determine soil // moisture growth multipliers. // // Simulates method of Thorthwaite and Mather (1957) as modified by Pastor and Post (1984). // // This method necessary to estimate annual soil moisture at the ECOREGION scale, whereas // the SiteVar AvailableWater exists at the site level and is updated monthly. //field_cap = centimeters of water the soil can hold at field capacity //field_dry = centimeters of water below which tree growth stops // (-15 bars) // NOTE: Because the original LINKAGES calculations were based on a 100 cm rooting depth, // 100 cm are used here, although soil depth may be given differently for Century // calculations. //beg_grow_seas = year day on which the growing season begins //end_grow_seas = year day on which the growing season ends //latitude = latitude of region (degrees north) { double xFieldCap, // waterAvail, // aExponentET, // oldWaterAvail, // monthlyRain, // potWaterLoss, // potentialET, tempFac, // xAccPotWaterLoss, // changeSoilMoisture, // oldJulianDay, // dryDayInterp; // double fieldCapacity = SiteVars.SoilFieldCapacity[site] * (double)SiteVars.SoilDepth[site]; // ClimateRegionData.SoilDepth[ecoregion]; double wiltingPoint = SiteVars.SoilWiltingPoint[site] * (double)SiteVars.SoilDepth[site]; // ClimateRegionData.SoilDepth[ecoregion]; //double fieldCapacity = ClimateRegionData.FieldCapacity[ecoregion] * 100.0; //double wiltingPoint = ClimateRegionData.WiltingPoint[ecoregion] * 100.0; //Initialize water content of soil in January to Field_Cap (mm) xFieldCap = 10.0 * fieldCapacity; waterAvail = fieldCapacity; //Initialize Thornwaithe parameters: // //TE = temperature efficiency //aExponentET = exponent of evapotranspiration function //pot_et = potential evapotranspiration //aet = actual evapotranspiration //acc_pot_water_loss = accumulated potential water loss double actualET = 0.0; double accPotWaterLoss = 0.0; double tempEfficiency = 0.0; for (int i = 0; i < 12; i++) { tempFac = 0.2 * weather.MonthlyTemp[i]; if (tempFac > 0.0) { tempEfficiency += System.Math.Pow(tempFac, 1.514); } } aExponentET = 0.675 * System.Math.Pow(tempEfficiency, 3) - 77.1 * (tempEfficiency * tempEfficiency) + 17920.0 * tempEfficiency + 492390.0; aExponentET *= (0.000001); //Initialize the number of dry days and current day of year int dryDays = 0; double julianDay = 15.0; double annualPotentialET = 0.0; for (int i = 0; i < 12; i++) { double daysInMonth = AnnualClimate.DaysInMonth(i, year); oldWaterAvail = waterAvail; monthlyRain = weather.MonthlyPrecip[i]; tempFac = 10.0 * weather.MonthlyTemp[i]; //Calc potential evapotranspiriation (potentialET) Thornwaite and Mather, //1957. Climatology 10:83 - 311. if (tempFac > 0.0) { potentialET = 1.6 * (System.Math.Pow((tempFac / tempEfficiency), aExponentET)) * AnnualClimate.LatitudeCorrection(i, PlugIn.Parameters.Latitude); //ClimateRegionData.Latitude[ecoregion]); } else { potentialET = 0.0; } annualPotentialET += potentialET; //Calc potential water loss this month potWaterLoss = monthlyRain - potentialET; //If monthlyRain doesn't satisfy potentialET, add this month's potential //water loss to accumulated water loss from soil if (potWaterLoss < 0.0) { accPotWaterLoss += potWaterLoss; xAccPotWaterLoss = accPotWaterLoss * 10; //Calc water retained in soil given so much accumulated potential //water loss Pastor and Post. 1984. Can. J. For. Res. 14:466:467. waterAvail = fieldCapacity * System.Math.Exp((.000461 - 1.10559 / xFieldCap) * (-1.0 * xAccPotWaterLoss)); if (waterAvail < 0.0) { waterAvail = 0.0; } //changeSoilMoisture - during this month changeSoilMoisture = waterAvail - oldWaterAvail; //Calc actual evapotranspiration (AET) if soil water is drawn down actualET += (monthlyRain - changeSoilMoisture); } //If monthlyRain satisfies potentialET, don't draw down soil water else { waterAvail = oldWaterAvail + potWaterLoss; if (waterAvail >= fieldCapacity) { waterAvail = fieldCapacity; } changeSoilMoisture = waterAvail - oldWaterAvail; //If soil partially recharged, reduce accumulated potential //water loss accordingly accPotWaterLoss += changeSoilMoisture; //If soil completely recharged, reset accumulated potential //water loss to zero if (waterAvail >= fieldCapacity) { accPotWaterLoss = 0.0; } //If soil water is not drawn upon, add potentialET to AET actualET += potentialET; } oldJulianDay = julianDay; julianDay += daysInMonth; dryDayInterp = 0.0; //Increment number of dry days, truncate //at end of growing season if ((julianDay > weather.BeginGrowing) && (oldJulianDay < weather.EndGrowing)) { if ((oldWaterAvail >= wiltingPoint) && (waterAvail >= wiltingPoint)) { dryDayInterp += 0.0; // NONE below wilting point } else if ((oldWaterAvail > wiltingPoint) && (waterAvail < wiltingPoint)) { dryDayInterp = daysInMonth * (wiltingPoint - waterAvail) / (oldWaterAvail - waterAvail); if ((oldJulianDay < weather.BeginGrowing) && (julianDay > weather.BeginGrowing)) { if ((julianDay - weather.BeginGrowing) < dryDayInterp) { dryDayInterp = julianDay - weather.BeginGrowing; } } if ((oldJulianDay < weather.EndGrowing) && (julianDay > weather.EndGrowing)) { dryDayInterp = weather.EndGrowing - julianDay + dryDayInterp; } if (dryDayInterp < 0.0) { dryDayInterp = 0.0; } } else if ((oldWaterAvail < wiltingPoint) && (waterAvail > wiltingPoint)) { dryDayInterp = daysInMonth * (wiltingPoint - oldWaterAvail) / (waterAvail - oldWaterAvail); if ((oldJulianDay < weather.BeginGrowing) && (julianDay > weather.BeginGrowing)) { dryDayInterp = oldJulianDay + dryDayInterp - weather.BeginGrowing; } if (dryDayInterp < 0.0) { dryDayInterp = 0.0; } if ((oldJulianDay < weather.EndGrowing) && (julianDay > weather.EndGrowing)) { if ((weather.EndGrowing - oldJulianDay) < dryDayInterp) { dryDayInterp = weather.EndGrowing - oldJulianDay; } } } else // ALL below wilting point { dryDayInterp = daysInMonth; if ((oldJulianDay < weather.BeginGrowing) && (julianDay > weather.BeginGrowing)) { dryDayInterp = julianDay - weather.BeginGrowing; } if ((oldJulianDay < weather.EndGrowing) && (julianDay > weather.EndGrowing)) { dryDayInterp = weather.EndGrowing - oldJulianDay; } } dryDays += (int)dryDayInterp; } } //END MONTHLY CALCULATIONS //Convert AET from cm to mm //actualET *= 10.0; //Calculate AET multiplier //(used to be done in decomp) //float aetMf = min((double)AET,600.0); //AET_Mult = (-1. * aetMf) / (-1200. + aetMf); return(dryDays); }
//--------------------------------------------------------------------- // Note: If the succession time step is > 0, then an average Pest is calculated, // based on each ecoregion-climate year. The average is used because establishment // determines reproductive success, which occurs only once for the given successional // time step. // Note: If one of the three multipliers dominates, // expect to see Pest highly correlated with that multiplier. // Note: N is not included here as it is site level quality and Pest represent // ecoregion x climate qualities. N limits have been folded into PlugIn.SufficientLight. public static Species.AuxParm <Ecoregions.AuxParm <double> > GenerateNewEstablishProbabilities(int years) { Species.AuxParm <Ecoregions.AuxParm <double> > EstablishProbability; EstablishProbability = CreateSpeciesEcoregionParm <double>(PlugIn.ModelCore.Species, PlugIn.ModelCore.Ecoregions); double[,] avgTempMultiplier = new double[PlugIn.ModelCore.Species.Count, PlugIn.ModelCore.Ecoregions.Count]; double[,] avgSoilMultiplier = new double[PlugIn.ModelCore.Species.Count, PlugIn.ModelCore.Ecoregions.Count]; double[,] avgMinJanTempMultiplier = new double[PlugIn.ModelCore.Species.Count, PlugIn.ModelCore.Ecoregions.Count]; for (int y = 0; y < years; ++y) { foreach (IEcoregion ecoregion in PlugIn.ModelCore.Ecoregions) { if (!ecoregion.Active || EcoregionData.ActiveSiteCount[ecoregion] < 1) { continue; } int actualYear = PlugIn.ModelCore.TimeSinceStart + y; //AnnualClimate_Monthly ecoClimate = EcoregionData.AnnualWeather[ecoregion]; //[y]; //new AnnualClimate_Monthly(ecoregion, actualYear, EcoregionData.Latitude[ecoregion], Climate.Phase.Future_Climate, actualYear); AnnualClimate_Monthly ecoClimate = EcoregionData.AnnualWeather[ecoregion]; if (ecoClimate == null) { throw new System.ApplicationException("Error in Establishment: CLIMATE NULL."); } double ecoDryDays = CalculateSoilMoisture(ecoClimate, ecoregion, y); foreach (ISpecies species in PlugIn.ModelCore.Species) { double tempMultiplier = BotkinDegreeDayMultiplier(ecoClimate, species); double soilMultiplier = SoilMoistureMultiplier(ecoClimate, species, ecoDryDays); double minJanTempMultiplier = MinJanuaryTempModifier(ecoClimate, species); // Liebig's Law of the Minimum is applied to the four multipliers for each year: double minMultiplier = System.Math.Min(tempMultiplier, soilMultiplier); minMultiplier = System.Math.Min(minJanTempMultiplier, minMultiplier); EstablishProbability[species][ecoregion] += minMultiplier; avgTempMultiplier[species.Index, ecoregion.Index] += tempMultiplier; avgSoilMultiplier[species.Index, ecoregion.Index] += soilMultiplier; avgMinJanTempMultiplier[species.Index, ecoregion.Index] += minJanTempMultiplier; } } } foreach (IEcoregion ecoregion in PlugIn.ModelCore.Ecoregions) { foreach (ISpecies species in PlugIn.ModelCore.Species) { EstablishProbability[species][ecoregion] /= (double)years; EstablishProbability[species][ecoregion] *= PlugIn.ProbEstablishAdjust; if (PlugIn.ModelCore.CurrentTime > 0 && EcoregionData.ActiveSiteCount[ecoregion] > 0) { avgTempMultiplier[species.Index, ecoregion.Index] /= (double)years; avgSoilMultiplier[species.Index, ecoregion.Index] /= (double)years; avgMinJanTempMultiplier[species.Index, ecoregion.Index] /= (double)years; log.Write("{0}, {1}, {2},", PlugIn.ModelCore.CurrentTime, ecoregion.Name, species.Name); log.Write("{0:0.00},", avgTempMultiplier[species.Index, ecoregion.Index]); log.Write("{0:0.00},", avgMinJanTempMultiplier[species.Index, ecoregion.Index]); log.Write("{0:0.00},", avgSoilMultiplier[species.Index, ecoregion.Index]); log.Write("{0:0.00},", PlugIn.ProbEstablishAdjust); log.WriteLine("{0:0.00}", EstablishProbability[species][ecoregion]); } } } return(EstablishProbability); }
//--------------------------------------------------------------------- /// <summary> /// Runs the component for a particular timestep. /// </summary> /// <param name="currentTime"> /// The current model timestep. /// </param> public override void Run() { // 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 = Regex.Split(fullVar, "[]"); 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 double CellLength = PlugIn.ModelCore.CellLength; 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 (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)) //if (neighborVar.Transform == "log10") { transformValue = Math.Log10(pctValue + 1); } else if (neighborVar.Transform.Equals("ln", StringComparison.OrdinalIgnoreCase)) //else if (neighborVar.Transform == "ln") { transformValue = Math.Log(pctValue + 1); } // Write Site Variable SiteVars.NeighborVars[site][neighborVar.Name] = (float)transformValue; } } // 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; 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 = (PlugIn.ModelCore.CurrentTime - 1) + Climate.Future_MonthlyData.Keys.Min(); if (climateYear == "prev") { if (Climate.Future_MonthlyData.ContainsKey(currentYear - 1)) { AnnualWeather = Climate.Future_MonthlyData[currentYear - 1][firstActiveEco]; } else { AnnualWeather = Climate.Spinup_MonthlyData[maxSpinUpYear][firstActiveEco]; } } else { AnnualWeather = Climate.Future_MonthlyData[currentYear][firstActiveEco]; } } if (PlugIn.ModelCore.CurrentTime == 0) { if (climateYear == "prev") { AnnualWeather = Climate.Spinup_MonthlyData[maxSpinUpYear - 1][firstActiveEco]; } else { AnnualWeather = Climate.Spinup_MonthlyData[maxSpinUpYear][firstActiveEco]; } } actualYear = AnnualWeather.Year; } else { if (climateYear == "prev") { actualYear = currentYear - 1; } } if (climateVar.SourceName == "Library") { 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 == "prev") { AnnualWeather = Climate.Spinup_MonthlyData[maxSpinUpYear - 1][ecoregion.Index]; } else { AnnualWeather = Climate.Spinup_MonthlyData[maxSpinUpYear][ecoregion.Index]; } } else if (climateYear == "prev") { 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)) //if (climateVar.ClimateLibVariable == "Precip") { double monthPrecip = AnnualWeather.MonthlyPrecip[monthIndex - 1]; varValue = monthPrecip * 10.0; //Convert cm to mm } else if (climateVar.ClimateLibVariable.Equals("temp", StringComparison.OrdinalIgnoreCase)) //else if (climateVar.ClimateLibVariable == "Temp") { 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)) //if (transform == "Log10") { transformValue = Math.Log10(avgValue + 1); } else if (transform.Equals("ln", StringComparison.OrdinalIgnoreCase)) //else if (transform == "ln") { transformValue = Math.Log(avgValue + 1); } if (!ecoClimateVars[ecoregion].ContainsKey(varName)) { ecoClimateVars[ecoregion].Add(varName, 0.0); } ecoClimateVars[ecoregion][varName] = transformValue; } } foreach (Site site in modelCore.Landscape.AllSites) { IEcoregion ecoregion = PlugIn.ModelCore.Ecoregion[site]; double climateValue = 0; if (ecoregion != null) { climateValue = ecoClimateVars[ecoregion][varName]; } // Write Site Variable SiteVars.ClimateVars[site][varName] = (float)climateValue; } } 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; } } } 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 Species Models foreach (IModelDefinition model in modelDefs) { float [] ecoregionSum = new float[ModelCore.Ecoregions.Count]; float landscapeSum = 0; foreach (Site site in modelCore.Landscape.AllSites) { 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)) //if (paramType == "int") { modelPredict += paramValue; } else if (paramType.Equals("neighbor", StringComparison.OrdinalIgnoreCase)) //else if (paramType == "neighbor") { double modelValue = SiteVars.NeighborVars[site][parameter] * paramValue; modelPredict += modelValue; } else if (paramType.Equals("climate", StringComparison.OrdinalIgnoreCase)) //else if (paramType == "climate") { double modelValue = SiteVars.ClimateVars[site][parameter] * paramValue; modelPredict += modelValue; } else if (paramType.Equals("biomass", StringComparison.OrdinalIgnoreCase)) //else if (paramType =="biomass") { double modelValue = Util.ComputeBiomass(SiteVars.Cohorts[site]) * paramValue; modelPredict += modelValue; } else { string mesg = string.Format("For model {0}, parameter {1} has parameter type {2}; expected 'int', 'neighbor','climate' or 'biomass'.", model.Name, parameter, paramType); throw new System.ApplicationException(mesg); } paramIndex++; } // Back-transform model prediction float finalPredict = (float)Math.Exp(modelPredict); // Write Site Variable SiteVars.SpeciesModels[site][model.Name] = (float)finalPredict; if (site.IsActive) { ecoregionSum[ecoregion.Index] += finalPredict; landscapeSum += finalPredict; } } 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; } foreach (IModelDefinition model in modelDefs) { habitatLog.Write("{0},", ModelCore.CurrentTime); habitatLog.Write("{0},", model.Name); habitatLog.Write("{0}", landscapeAvgValues[model.Name]); foreach (IEcoregion ecoregion in ModelCore.Ecoregions) { habitatLog.Write(",{0}", ecoregionAvgValues[ecoregion.Index][model.Name]); } habitatLog.WriteLine(""); } /* * foreach (IModelDefinition model in modelDefs) * { * foreach (IEcoregion ecoregion in ModelCore.Ecoregions) * { * habitatLog.Clear(); * SpeciesHabitatLog shl = new SpeciesHabitatLog(); * shl.Time = ModelCore.CurrentTime; * shl.Ecoregion = ecoregion.Name; * shl.EcoregionIndex = ecoregion.Index; * shl.NumSites = activeSiteCount[ecoregion.Index]; * //shl.SppHabitat[ecoregion.Index][model.Name] = avgHabitat[ecoregion.Index][; * } * } * */ // Ouput Maps if (!(parameters.LocalVarMapFileNames == null)) { //----- Write LocalVar maps -------- foreach (MapDefinition localVar in parameters.ReclassMaps) { string localVarPath = MapFileNames.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.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(); } } } } }