//--------------------------------------------------------------------- public static int CalculateDomAgeForestType(Site site, IForestType forestType) { List <ISpecies> speciesList = new List <ISpecies>(); int speciesIndex = 0; foreach (ISpecies species in modelCore.Species) { if (forestType[speciesIndex] == 1) { speciesList.Add(species); } speciesIndex++; } Dictionary <int, int> ageDictionary = new Dictionary <int, int>(); foreach (ISpeciesCohorts sppCohorts in SiteVars.BiomassCohorts[site]) { if (speciesList.Contains(sppCohorts.Species)) { foreach (ICohort cohort in sppCohorts) { int age = cohort.Age; int biomass = cohort.Biomass; if (ageDictionary.ContainsKey(age)) { ageDictionary[age] = ageDictionary[age] + biomass; } else { ageDictionary[age] = biomass; } } } } int domAge = 0; int maxValue = 0; foreach (var i in ageDictionary) { if (i.Value > maxValue) { domAge = i.Key; maxValue = i.Value; } } return(domAge); }
//--------------------------------------------------------------------- private void CheckForestType(IForestType forestType, string[] speciesWithMultiplier1, string[] speciesWithMultiplierNeg1) { foreach (Species.ISpecies species in ParametersParser.SpeciesDataset) { int expectedMultiplier = 0; if (InArray(speciesWithMultiplier1, species.Name)) { expectedMultiplier = 1; } else if (InArray(speciesWithMultiplierNeg1, species.Name)) { expectedMultiplier = -1; } Assert.AreEqual(expectedMultiplier, forestType[species.Index]); } }
//--------------------------------------------------------------------- private byte CalcForestType(IForestType[] forestTypes, Site site) { int forTypeCnt = 0; double[] forTypValue = new double[forestTypes.Length]; Species.IDataset SpeciesDataset = modelCore.Species; foreach(ISpecies species in SpeciesDataset) { double sppValue = 0.0; //Biomass.ICohort cohort = cohorts[site][species]; //sppValue = cohort.Biomass;//Util.ComputeBiomass(cohorts[site][species]); sppValue = Util.ComputeBiomass(cohorts[site][species]); forTypeCnt = 0; foreach(IForestType ftype in forestTypes) { if(ftype[species.Index] != 0) { if(ftype[species.Index] == -1) forTypValue[forTypeCnt] -= sppValue; if(ftype[species.Index] == 1) forTypValue[forTypeCnt] += sppValue; } forTypeCnt++; } } int finalForestType = 0; double maxValue = 0.0; forTypeCnt = 0; foreach(IForestType ftype in forestTypes) { //System.Console.WriteLine("ForestTypeNum={0}, Value={1}.",forTypeCnt,forTypValue[forTypeCnt]); if(forTypValue[forTypeCnt]>maxValue) { maxValue = forTypValue[forTypeCnt]; finalForestType = forTypeCnt+1; } forTypeCnt++; } return (byte) finalForestType; }
//--------------------------------------------------------------------- public MapDefinition(string name, IForestType[] forestTypes) { this.name = name; this.forestTypes = forestTypes; }
//--------------------------------------------------------------------- /// <summary> /// Writes a trailer file. /// </summary> /// <param name="gisFilePath"> /// Path of the .gis file that the trailer file is associated with. /// The name of the trailer file is the path with the ".gis" /// extension replaced with ".trl". /// </param> /// <param name="forestTypes"> /// List of forest types assigned to classes 1, 2, ... /// </param> public static void Write(string gisFilePath, IForestType[] forestTypes) { string trlFilePath = Path.ChangeExtension(gisFilePath, ".trl"); using (BinaryWriter writer = new BinaryWriter(File.Open(trlFilePath, FileMode.Create))) { // Record 1 writer.Write(Trail74Record); // Records 2 to 7 (color scheme) // record color values // ------ ------------ // 2 green classes 0 - 127 (doc says 0-128 but that's 129 values) // 3 green classes 128 - 255 (doc says 129-255 but that's only 127 values) // 4 red classes 0 - 127 (see note for green) // 5 red classes 128 - 255 (see note for green) // 6 blue classes 0 - 127 (see note for green) // 7 blue classes 128 - 255 (see note for green) writer.Write(PadTo256Values(green)); writer.Write(PadTo256Values(red)); writer.Write(PadTo256Values(blue)); // Record 8 writer.Write(Trail74Record); // Records 9 to 16 (histogram values) for (int record = 9; record <= 16; record++) writer.Write(allZeroesRecord); // Records 17 on up (class names: 4 per record) writer.Write(MakeClassName(Class0Name)); foreach (IForestType forestType in forestTypes) writer.Write(MakeClassName(forestType.Name)); } }
//--------------------------------------------------------------------- private byte CalcForestType(Site site, IForestType[] forestTypes) { int forTypeCnt = 0; double[] forTypValue = new double[forestTypes.Length]; Species.IDataset SpeciesDataset = modelCore.Species; foreach(ISpecies species in SpeciesDataset) { ushort maxSpeciesAge = 0; double sppValue = 0.0; //ISpeciesCohorts speciesCohorts = cohorts[species]; maxSpeciesAge = AgeCohort.Util.GetMaxAge(cohorts[site][species]); //MaxAge(speciesCohorts); if(maxSpeciesAge > 0) { sppValue = (double) maxSpeciesAge / (double) species.Longevity * (double) reclassCoefs[species.Index]; forTypeCnt = 0; foreach(IForestType ftype in forestTypes) { if(ftype[species.Index] != 0) { if(ftype[species.Index] == -1) forTypValue[forTypeCnt] -= sppValue; if(ftype[species.Index] == 1) forTypValue[forTypeCnt] += sppValue; } forTypeCnt++; } } } int finalForestType = 0; double maxValue = 0.0; forTypeCnt = 0; foreach(IForestType ftype in forestTypes) { //System.Console.WriteLine("ForestTypeNum={0}, Value={1}.",forTypeCnt,forTypValue[forTypeCnt]); if(forTypValue[forTypeCnt]>maxValue) { maxValue = forTypValue[forTypeCnt]; finalForestType = forTypeCnt+1; } forTypeCnt++; } return (byte) finalForestType; }
//--------------------------------------------------------------------- private void CheckForestType(IForestType forestType, string[] speciesWithMultiplier1, string[] speciesWithMultiplierNeg1) { foreach (Species.ISpecies species in ParametersParser.SpeciesDataset) { int expectedMultiplier = 0; if (InArray(speciesWithMultiplier1, species.Name)) expectedMultiplier = 1; else if (InArray(speciesWithMultiplierNeg1, species.Name)) expectedMultiplier = -1; Assert.AreEqual(expectedMultiplier, forestType[species.Index]); } }
//--------------------------------------------------------------------- /// <summary> /// Runs the component for a particular timestep. /// </summary> /// <param name="currentTime"> /// The current model timestep. /// </param> public override void Run() { // The index variable increments with each suitability file - an index of multiple wildlife input files int index = 0; foreach (string suitabilityFile in suitabilityFiles) { // get suitability parameters ISuitabilityParameters mySuitabilityParameters = suitabilityParameters[index]; foreach (Site site in modelCore.Landscape.ActiveSites) { double suitabilityValue = 0; // calculate dominant age as site variable (DomAge), store for retrieval // Note: DomAge site variable is an array of values giving dominant age for this year and last year UpdateDominantAge(site); // calculate forest type as site variable (ForestType), store for retreival // Note: ForestType site variable is an array of values giving the index of forest type for this year and last year UpdateForestType(index, mySuitabilityParameters, site); // depending on suitability type, calculate final suitability value if (mySuitabilityParameters.SuitabilityType == "AgeClass_ForestType") { // get forest type (calculated above with UpdateForestType) int currentForestType = SiteVars.ForestType[site][index][0]; if (currentForestType > 0) { IForestType forestType = mySuitabilityParameters.ForestTypes[0].ForestTypes[currentForestType - 1]; // calculate dominant age among species in forest type int domFTAge = CalculateDomAgeForestType(site, forestType); // look up suitability in suitabilityTable for combination of forest type and age Dictionary <int, double> suitabilityRow = mySuitabilityParameters.Suitabilities[forestType.Name]; foreach (KeyValuePair <int, double> item in suitabilityRow) { int ageLimit = item.Key; if (domFTAge <= ageLimit) { suitabilityValue = item.Value; break; } } } else { suitabilityValue = 0; } // write sitevar for suitability value SiteVars.SuitabilityValue[site][index] = suitabilityValue; } // if suitabilityType == AgeClass_TimeSinceDisturbance: else if (mySuitabilityParameters.SuitabilityType == "AgeClass_TimeSinceDisturbance") { int ageAtDisturbanceYear = 0; int timeSinceDisturbance = 0; double suitabilityWeight = 0.0; // if disturbanceType == "Fire" then: if (mySuitabilityParameters.DisturbanceType == "Fire") { // Check if fire severity output exists if (SiteVars.FireSeverity == null) { string mesg = string.Format("The DisturbanceType is Fire, but FireSeverity SiteVariable is not defined. Please double-check that a fire extension is running."); throw new System.ApplicationException(mesg); } else { // Check this year fire severity int currentFireSeverity = (int)SiteVars.FireSeverity[site]; int timeofLastFire = SiteVars.TimeOfLastFire[site]; // if > 0 then update sites with new values if (currentFireSeverity > 0 && timeofLastFire == ModelCore.CurrentTime) { // translate to suitability weight suitabilityWeight = mySuitabilityParameters.FireSeverities[currentFireSeverity]; SiteVars.SuitabilityWeight[site][index] = suitabilityWeight; // if suitability weight > 0 then if (suitabilityWeight > 0) { // store sitevar YearOfFire by index SiteVars.YearOfFire[site][index] = ModelCore.CurrentTime; // read previous year dominant age int prevYearDomAge = SiteVars.DominantAge[site][1]; // store sitevar AgeAtFireYear by index SiteVars.AgeAtFireYear[site][index] = prevYearDomAge; } } // read sitevar AgeAtDisturbanceYear for age value ageAtDisturbanceYear = SiteVars.AgeAtFireYear[site][index]; // read sitevar YearOfFire int yearOfFire = SiteVars.YearOfFire[site][index]; // calculate timeSinceDisturbance = currentYear - YearOfFire timeSinceDisturbance = ModelCore.CurrentTime - yearOfFire; } } // if disturbanceType == "Harvest" then: else if (mySuitabilityParameters.DisturbanceType == "Harvest") { // Check if harvest prescription output exists if (SiteVars.PrescriptionName == null) { string mesg = string.Format("The DisturbanceType is Harvest, but prescriptionName SiteVariable is not defined. Please double-check that a Harvest extension is running."); throw new System.ApplicationException(mesg); } else { // Check this year harvest prescription names string currentprescriptionName = SiteVars.PrescriptionName[site]; int timeofLastHarvest = SiteVars.TimeOfLastHarvest[site]; // if != null then if (currentprescriptionName != null && timeofLastHarvest == ModelCore.CurrentTime) { // translate to suitability weight suitabilityWeight = mySuitabilityParameters.HarvestPrescriptions[currentprescriptionName]; // if suitability weight > 0 then if (suitabilityWeight > 0) { // store sitevar YearOfHarvest by index SiteVars.YearOfHarvest[site][index] = ModelCore.CurrentTime; // read previous year dominant age int prevYearDomAge = SiteVars.DominantAge[site][1]; // store sitevar AgeAtHarvestYear by index SiteVars.AgeAtHarvestYear[site][index] = prevYearDomAge; // store sitevar SuitabilityWeight by index SiteVars.SuitabilityWeight[site][index] = suitabilityWeight; } } // read sitevar AgeAtDisturbanceYear for age value ageAtDisturbanceYear = SiteVars.AgeAtHarvestYear[site][index]; // read sitevar YearOfHarvest int yearOfHarvest = SiteVars.YearOfHarvest[site][index]; // calculate timeSinceDisturbance = currentYear - YearOfHarvest timeSinceDisturbance = ModelCore.CurrentTime - yearOfHarvest; } } // look up suitabilty in suitabilityTable for combination of AgeAtDisturbanceYear and timeSinceDisturbance foreach (KeyValuePair <string, Dictionary <int, double> > suitabilityRow in mySuitabilityParameters.Suitabilities) { int maxTimeSinceDist = int.Parse(suitabilityRow.Key); if (timeSinceDisturbance <= maxTimeSinceDist) { foreach (KeyValuePair <int, double> item in suitabilityRow.Value) { int ageLimit = item.Key; if (ageAtDisturbanceYear <= ageLimit) { suitabilityValue = (item.Value * SiteVars.SuitabilityWeight[site][index]); break; } } break; } } // write sitevar for suitability value SiteVars.SuitabilityValue[site][index] = suitabilityValue; } // if suitabilityType == ForestType_TimeSinceDisturbance: else if (mySuitabilityParameters.SuitabilityType == "ForestType_TimeSinceDisturbance") { int forestTypeAtDisturbanceYear = 0; int timeSinceDisturbance = 0; double suitabilityWeight = 0.0; // if disturbanceType == "Fire" then: if (mySuitabilityParameters.DisturbanceType == "Fire") { // Check if fire output exists if (SiteVars.FireSeverity == null) { string mesg = string.Format("The DisturbanceType is Fire, but FireSeverity SiteVariable is not defined. Please double-check that a Fire extension is running."); throw new System.ApplicationException(mesg); } else { // Check this year fire severity int currentFireSeverity = SiteVars.FireSeverity[site]; int timeofLastFire = SiteVars.TimeOfLastFire[site]; // if > 0 then if (currentFireSeverity > 0 && timeofLastFire == ModelCore.CurrentTime) { // translate to suitability weight suitabilityWeight = mySuitabilityParameters.FireSeverities[currentFireSeverity]; // if suitability weight > 0 then if (suitabilityWeight > 0) { // store sitevar YearOfFire by index SiteVars.YearOfFire[site][index] = ModelCore.CurrentTime; // read previous year forest type int prevYearForType = SiteVars.ForestType[site][index][1]; // store sitevar forestTypeAtFireYear by index SiteVars.ForestTypeAtFireYear[site][index] = prevYearForType; // store sitevar SuitabilityWeight by index SiteVars.SuitabilityWeight[site][index] = suitabilityWeight; } } } // read sitevar ForestTypeFireYear for age value forestTypeAtDisturbanceYear = SiteVars.ForestTypeAtFireYear[site][index]; // read sitevar YearOfFire int yearOfFire = SiteVars.YearOfFire[site][index]; // calculate timeSinceDisturbance = currentYear - YearOfFire timeSinceDisturbance = ModelCore.CurrentTime - yearOfFire; } // if disturbanceType == "Harvest" then: else if (mySuitabilityParameters.DisturbanceType == "Harvest") { // Check if harvest prescription output exists if (SiteVars.PrescriptionName == null) { string mesg = string.Format("The DisturbanceType is Harvest, but prescriptionName SiteVariable is not defined. Please double-check that a Harvest extension is running."); throw new System.ApplicationException(mesg); } else { // Check this year harvest prescription names string currentprescriptionName = SiteVars.PrescriptionName[site]; int timeofLastHarvest = SiteVars.TimeOfLastHarvest[site]; // if != null then if (currentprescriptionName != null && timeofLastHarvest == ModelCore.CurrentTime) { // translate to suitability weight suitabilityWeight = mySuitabilityParameters.HarvestPrescriptions[currentprescriptionName]; // if suitability weight > 0 then if (suitabilityWeight > 0) { // store sitevar YearOfHarvest by index SiteVars.YearOfHarvest[site][index] = ModelCore.CurrentTime; // read previous year forest type int prevYearForType = SiteVars.ForestType[site][index][1]; // store sitevar forestTypeAtHarvestYear by index SiteVars.ForestTypeAtHarvestYear[site][index] = prevYearForType; // store sitevar SuitabilityWeight by index SiteVars.SuitabilityWeight[site][index] = suitabilityWeight; } } // read sitevar AgeAtHarvestYear for age value forestTypeAtDisturbanceYear = SiteVars.ForestTypeAtHarvestYear[site][index]; // read sitevar YearOfHarvest int yearOfHarvest = SiteVars.YearOfHarvest[site][index]; // calculate timeSinceDisturbance = currentYear - YearOfHarvest timeSinceDisturbance = ModelCore.CurrentTime - yearOfHarvest; } } if (forestTypeAtDisturbanceYear > 0) { IForestType forestType = mySuitabilityParameters.ForestTypes[0].ForestTypes[forestTypeAtDisturbanceYear - 1]; // look up suitability in suitabilityTable for combination of forest type and timeSinceDisturbance Dictionary <int, double> suitabilityRow = mySuitabilityParameters.Suitabilities[forestType.Name]; foreach (KeyValuePair <int, double> item in suitabilityRow) { int maxTimeSinceDist = item.Key; if (timeSinceDisturbance <= maxTimeSinceDist) { suitabilityValue = (item.Value * SiteVars.SuitabilityWeight[site][index]); break; } } } else { suitabilityValue = 0; } // write sitevar for suitability value SiteVars.SuitabilityValue[site][index] = suitabilityValue; } } // if output timestep then write all maps if ((ModelCore.CurrentTime % parameters.OutputTimestep) == 0) { string mapName = mySuitabilityParameters.HabitatName; string path = MapFileNames.ReplaceTemplateVars(mapNameTemplate, mapName, modelCore.CurrentTime); ModelCore.UI.WriteLine(" Writing Habitat Output map to {0} ...", path); using (IOutputRaster <IntPixel> outputRaster = modelCore.CreateRaster <IntPixel>(path, modelCore.Landscape.Dimensions)) { IntPixel pixel = outputRaster.BufferPixel; foreach (Site site in modelCore.Landscape.AllSites) { if (site.IsActive) { pixel.MapCode.Value = (int)(SiteVars.SuitabilityValue[site][index] * 100); } else { pixel.MapCode.Value = 0; } outputRaster.WriteBufferPixel(); } } } /*Copied from biomass-reclass * foreach (IMapDefinition map in mapDefs) * { * List<IForestType> forestTypes = map.ForestTypes; * * string path = MapFileNames.ReplaceTemplateVars(mapNameTemplate, map.Name, modelCore.CurrentTime); * modelCore.Log.WriteLine(" Writing Biomass Reclass map to {0} ...", path); * using (IOutputRaster<BytePixel> outputRaster = modelCore.CreateRaster<BytePixel>(path, modelCore.Landscape.Dimensions)) * { * BytePixel pixel = outputRaster.BufferPixel; * foreach (Site site in modelCore.Landscape.AllSites) * { * if (site.IsActive) * pixel.MapCode.Value = CalcForestType(forestTypes, site); * else * pixel.MapCode.Value = 0; * * outputRaster.WriteBufferPixel(); * } * } * * } * */ index++; } }
//--------------------------------------------------------------------- public static int CalculateDomAgeForestType(Site site, IForestType forestType) { List<ISpecies> speciesList = new List<ISpecies>(); int speciesIndex = 0; foreach (ISpecies species in modelCore.Species) { if (forestType[speciesIndex] == 1) speciesList.Add(species); speciesIndex++; } Dictionary<int, int> ageDictionary = new Dictionary<int, int>(); foreach (ISpeciesCohorts sppCohorts in SiteVars.BiomassCohorts[site]) { if (speciesList.Contains(sppCohorts.Species)) { foreach (ICohort cohort in sppCohorts) { int age = cohort.Age; int biomass = cohort.Biomass; if (ageDictionary.ContainsKey(age)) { ageDictionary[age] = ageDictionary[age] + biomass; } else { ageDictionary[age] = biomass; } } } } int domAge = 0; int maxValue = 0; foreach (var i in ageDictionary) { if (i.Value > maxValue) { domAge = i.Key; maxValue = i.Value; } } return domAge; }