//--------------------------------------------------------------------- ///<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"); } }
public static void InitializeMetadata(string mapNameTemplate, string eventLogName, string summaryLogName) { ScenarioReplicationMetadata scenRep = new ScenarioReplicationMetadata() { RasterOutCellArea = PlugIn.ModelCore.CellArea, TimeMin = PlugIn.ModelCore.StartTime, TimeMax = PlugIn.ModelCore.EndTime, }; Extension = new ExtensionMetadata(PlugIn.ModelCore) //Extension = new ExtensionMetadata() { Name = PlugIn.ExtensionName, TimeInterval = PlugIn.ModelCore.CurrentTime, ScenarioReplicationMetadata = scenRep }; //--------------------------------------- // table outputs: //--------------------------------------- CreateDirectory(eventLogName); CreateDirectory(summaryLogName); PlugIn.eventLog = new MetadataTable <EventsLog>(eventLogName); PlugIn.summaryLog = new MetadataTable <SummaryLog>(summaryLogName); //PlugIn.eventLog = new MetadataTable<EventsLog>("Harvest-event-log.csv"); //PlugIn.summaryLog = new MetadataTable<SummaryLog>("Harvest-summary-log.csv"); PlugIn.ModelCore.UI.WriteLine(" Generating event table..."); OutputMetadata tblOut_events = new OutputMetadata() { Type = OutputType.Table, Name = "EventLog", FilePath = PlugIn.eventLog.FilePath, Visualize = false, }; tblOut_events.RetriveFields(typeof(EventsLog)); Extension.OutputMetadatas.Add(tblOut_events); PlugIn.ModelCore.UI.WriteLine(" Generating summary table..."); OutputMetadata tblOut_summary = new OutputMetadata() { Type = OutputType.Table, Name = "SummaryLog", FilePath = PlugIn.summaryLog.FilePath, Visualize = true, }; tblOut_summary.RetriveFields(typeof(SummaryLog)); Extension.OutputMetadatas.Add(tblOut_summary); //--------------------------------------- // map outputs: //--------------------------------------- OutputMetadata mapOut_fire_severity = new OutputMetadata() { Type = OutputType.Map, Name = "Fire_Severity_Map", FilePath = MapNames.ReplaceTemplateVars(mapNameTemplate, PlugIn.ModelCore.CurrentTime), Map_DataType = MapDataType.Continuous, Visualize = true, //Map_Unit = "categorical", }; Extension.OutputMetadatas.Add(mapOut_fire_severity); OutputMetadata mapOut_last_fire = new OutputMetadata() { Type = OutputType.Map, Name = "Time_Of_Last_Fire", FilePath = MapNames.ReplaceTemplateVars("./DFFS-output/TimeOfLastFire-{timestep}.img", PlugIn.ModelCore.CurrentTime), Map_DataType = MapDataType.Continuous, Visualize = true, //Map_Unit = "categorical", }; Extension.OutputMetadatas.Add(mapOut_last_fire); //--------------------------------------- MetadataProvider mp = new MetadataProvider(Extension); mp.WriteMetadataToXMLFile("Metadata", Extension.Name, Extension.Name); }