//--------------------------------------------------------------------- public override void LoadParameters(string dataFile, ICore mCore) { modelCore = mCore; SiteVars.Initialize(); InputParameterParser parser = new InputParameterParser(); parameters = Landis.Data.Load <IInputParameters>(dataFile, parser); WeatherDataTable = Weather.ReadWeatherFile(parameters.InitialWeatherPath, FireRegions.Dataset, parameters.SeasonParameters); }
//--------------------------------------------------------------------- ///<summary> /// Run the plug-in at a particular timestep. ///</summary> public override void Run() { SiteVars.InitializeFuelType(); modelCore.UI.WriteLine(" Processing landscape for Fire events ..."); if (FireRegions.Dataset.Count == 0) { throw new ApplicationException("Fire region data set is empty."); } SiteVars.Event.SiteValues = null; SiteVars.Severity.ActiveSiteValues = 0; SiteVars.Disturbed.ActiveSiteValues = false; SiteVars.TravelTime.ActiveSiteValues = Double.PositiveInfinity; SiteVars.MinNeighborTravelTime.ActiveSiteValues = Double.PositiveInfinity; SiteVars.RateOfSpread.ActiveSiteValues = 0.0; foreach (IFireRegion fire_region in FireRegions.Dataset) { summaryFireRegionEventCount[fire_region.Index] = 0; } summaryTotalSites = 0; summaryEventCount = 0; // Update the FireRegions Map as necessary: //modelCore.UI.WriteLine(" Dynamic Fire: Loading Dynamic Fire Regions..."); foreach (IDynamicFireRegion dyneco in dynamicEcos) { if (dyneco.Year == modelCore.CurrentTime) { modelCore.UI.WriteLine(" Reading in new Fire FireRegions Map {0}.", dyneco.MapName); foreach (IFireRegion fire_region in FireRegions.Dataset) { fire_region.FireRegionSites.Clear(); // = new List<Location>(); } FireRegions.ReadMap(dyneco.MapName); //Sites added to their respective fire_region lists } } //Update the weather table as necessary: foreach (IDynamicWeather dynweather in dynamicWeather) { if (dynweather.Year == modelCore.CurrentTime) { modelCore.UI.WriteLine(" Reading in new Weather Table {0}", dynweather.FileName); WeatherDataTable = Weather.ReadWeatherFile(dynweather.FileName, FireRegions.Dataset, seasonParameters); } } // Fill in open types as needed: modelCore.UI.WriteLine(" Dynamic Fire: Filling open types as needed ..."); foreach (ActiveSite site in modelCore.Landscape) { IFireRegion fire_region = SiteVars.FireRegion[site]; if (fire_region == null) { throw new System.ApplicationException("Error: SiteVars.FireRegion is empty."); } //if(SiteVars.CFSFuelType[site] == 0) // throw new System.ApplicationException("Error: SiteVars.CFSFuelType is empty."); if (Event.FuelTypeParms[SiteVars.CFSFuelType[site]] == null) { modelCore.UI.WriteLine("Error: SiteVars.CFSFuelType[site]={0}.", SiteVars.CFSFuelType[site]); throw new System.ApplicationException("Error: Event BaseFuel Empty."); } if (Event.FuelTypeParms[SiteVars.CFSFuelType[site]].BaseFuel == BaseFuelType.NoFuel) { if (SiteVars.PercentDeadFir[site] == 0) { SiteVars.CFSFuelType[site] = fire_region.OpenFuelType; } } } if (isDebugEnabled) { modelCore.UI.WriteLine("Done filling open types"); } modelCore.UI.WriteLine(" Dynamic Fire: Igniting Fires ..."); foreach (IFireRegion fire_region in FireRegions.Dataset) { if (isDebugEnabled) { modelCore.UI.WriteLine(" There are {0} site locations in fire region {1}", fire_region.FireRegionSites.Count, fire_region.Name); } if (fire_region.EcoIgnitionNum > 0) { //PoissonDistribution randVar = new PoissonDistribution(RandomNumberGenerator.Singleton); double doubleLambda; int ignGenerated = 0; if (isDebugEnabled) { modelCore.UI.WriteLine("{0}: EcoIgnitionNum = {1}, computing ignGenerated ...", fire_region.Name, fire_region.EcoIgnitionNum); } if (fire_region.EcoIgnitionNum < 1) { // Adjust ignition probability for multiple years // (The inverse of the probability of NOT having any ignition for the time period.) // P = 1 - (1-Pignition)^timestep //doubleLambda = 1 - System.Math.Pow(1.0 - fire_region.EcoIgnitionNum, Timestep); for (int i = 1; i <= Timestep; i++) { int annualFires = 0; if (modelCore.GenerateUniform() <= fire_region.EcoIgnitionNum) { annualFires = 1; } ignGenerated += annualFires; } } else { doubleLambda = fire_region.EcoIgnitionNum; bool boolLarge = false; // 745 is the upper limit for valid Poisson lambdas. If greater than // 745, divide by 10 and readjust back up below. if (doubleLambda > 745) { doubleLambda = doubleLambda / 10; boolLarge = true; } PlugIn.ModelCore.PoissonDistribution.Lambda = doubleLambda; //randVar.Lambda = doubleLambda; for (int i = 1; i <= Timestep; i++) { int annualFires = PlugIn.ModelCore.PoissonDistribution.Next(); if (boolLarge) { annualFires = annualFires * 10; //readjust if necessary. } ignGenerated += annualFires; } } if (isDebugEnabled) { modelCore.UI.WriteLine(" Ignitions generated = {0}; Shuffling {0} cells ...", ignGenerated, fire_region.FireRegionSites.Count); } List <Location> cellsPerFireRegion = new List <Location>(0); foreach (Location location in fire_region.FireRegionSites) { cellsPerFireRegion.Add(location); } cellsPerFireRegion = Shuffle(cellsPerFireRegion); int fireCount = 0; //Try to create poissonNumber of fires in each fire_region. //Fires should only initiate if a fire event has not previously occurred //at that site. foreach (Location siteLocation in cellsPerFireRegion) { Site site = modelCore.Landscape.GetSite(siteLocation); ActiveSite asite = (ActiveSite)site; if (fireCount >= ignGenerated) { continue; //exit loop if the required number of fires has occurred. } if (SiteVars.Event[asite] == null) { fireCount++; if (isDebugEnabled) { modelCore.UI.WriteLine(" fireCount = {0}", fireCount); } Event FireEvent = Event.Initiate(asite, Timestep, fireSizeType, bui, seasonParameters, severityCalibrate); if (isDebugEnabled) { modelCore.UI.WriteLine(" fire event {0} started at {1}", FireEvent == null ? "not ": "", asite.Location); } if (FireEvent != null) { LogEvent(modelCore.CurrentTime, FireEvent); summaryEventCount++; //fireCount++; //RMS test } } } } } // Track the time of last fire; registered in SiteVars.cs for other extensions to access. if (isDebugEnabled) { modelCore.UI.WriteLine("Assigning TimeOfLastFire site var ..."); } foreach (Site site in modelCore.Landscape.AllSites) { if (SiteVars.Disturbed[site]) { SiteVars.TimeOfLastFire[site] = modelCore.CurrentTime; } } // Write Fire severity map string path = MapNames.ReplaceTemplateVars(mapNameTemplate, modelCore.CurrentTime); modelCore.UI.WriteLine(" Writing Fire severity 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) { if (SiteVars.Disturbed[site]) { pixel.MapCode.Value = (byte)(SiteVars.Severity[site] + 2); } else { pixel.MapCode.Value = 1; } } else { // Inactive site pixel.MapCode.Value = 0; } outputRaster.WriteBufferPixel(); } } path = MapNames.ReplaceTemplateVars("./DFFS-output/TimeOfLastFire-{timestep}.img", modelCore.CurrentTime); modelCore.UI.WriteLine(" Writing Travel Time output map to {0} ...", path); using (IOutputRaster <ShortPixel> outputRaster = modelCore.CreateRaster <ShortPixel>(path, modelCore.Landscape.Dimensions)) { ShortPixel pixel = outputRaster.BufferPixel; foreach (Site site in modelCore.Landscape.AllSites) { if (site.IsActive) { pixel.MapCode.Value = (short)(SiteVars.TimeOfLastFire[site]); } else { pixel.MapCode.Value = 0; } outputRaster.WriteBufferPixel(); } } WriteSummaryLog(modelCore.CurrentTime); if (isDebugEnabled) { modelCore.UI.WriteLine("Done running extension"); } }