Exemple #1
0
        //---------------------------------------------------------------------
        public static void Initialize(string inputMapName)
        {
            status                = PlugIn.ModelCore.Landscape.NewSiteVar <int>(0);
            lethalTemp            = PlugIn.ModelCore.Landscape.NewSiteVar <int>();
            totalBiomassRemoved   = PlugIn.ModelCore.Landscape.NewSiteVar <int>(0);
            avgSoilTemp           = PlugIn.ModelCore.Landscape.NewSiteVar <float>();
            avg_WetnessIndex      = PlugIn.ModelCore.Landscape.NewSiteVar <float>();
            avg_pSI               = PlugIn.ModelCore.Landscape.NewSiteVar <float>();
            avg_pID               = PlugIn.ModelCore.Landscape.NewSiteVar <float>();
            speciesBiomassRemoved = PlugIn.ModelCore.Landscape.NewSiteVar <Dictionary <ISpecies, int> >();
            foreach (ActiveSite site in PlugIn.ModelCore.Landscape.ActiveSites)
            {
                speciesBiomassRemoved[site] = new Dictionary <ISpecies, int>();
            }

            cohorts           = PlugIn.ModelCore.GetSiteVar <ISiteCohorts>("Succession.BiomassCohorts");
            timeOfLastDisease = PlugIn.ModelCore.GetSiteVar <int>("Pathogen.TimeOfLastDisease");  // If other pathogen disturbance extension is active, use the registered site var from it
            if (timeOfLastDisease == null)
            {
                timeOfLastDisease = PlugIn.ModelCore.Landscape.NewSiteVar <int>();
                foreach (Site site in PlugIn.ModelCore.Landscape.AllSites)
                {
                    if (site.IsActive)
                    {
                        timeOfLastDisease[site] = -9999;
                    }
                    else
                    {
                        timeOfLastDisease[site] = 0;
                    }
                }
                PlugIn.ModelCore.RegisterSiteVar(SiteVars.TimeOfLastDisease, "Pathogen.TimeOfLastDisease");
            }
            monthlyPressureHead = PlugIn.ModelCore.GetSiteVar <float[]>("Succession.MonthlyPressureHead");
            extremeMinTemp      = PlugIn.ModelCore.GetSiteVar <float>("Succession.ExtremeMinTemp");
            monthlySoilTemp     = PlugIn.ModelCore.GetSiteVar <SortedList <float, float>[]>("Succession.MonthlySoilTemp");
            fieldCapacity       = PlugIn.ModelCore.GetSiteVar <float>("Succession.SoilFieldCapacity");

            if (inputMapName == null)
            {
                foreach (Site site in PlugIn.ModelCore.Landscape.AllSites)
                {
                    if (site.IsActive)
                    {
                        status[site] = 1;
                    }
                    else
                    {
                        status[site] = 0;
                    }
                }
            }
            else
            {
                IInputRaster <IntPixel> map;

                try
                {
                    map = PlugIn.ModelCore.OpenRaster <IntPixel>(inputMapName);
                }
                catch (FileNotFoundException)
                {
                    string message = string.Format("Error: The file {0} does not exist", inputMapName);
                    throw new System.ApplicationException(message);
                }

                if (map.Dimensions != PlugIn.ModelCore.Landscape.Dimensions)
                {
                    string message = string.Format("Error: The input map {0} does not have the same dimension (row, column) as the ecoregions map", inputMapName);
                    throw new System.ApplicationException(message);
                }

                using (map)
                {
                    IntPixel pixel = map.BufferPixel;
                    foreach (Site site in PlugIn.ModelCore.Landscape.AllSites)
                    {
                        map.ReadBufferPixel();
                        int mapCode = (int)pixel.MapCode.Value;

                        if (mapCode < 0 || mapCode > 3)
                        {
                            string message = string.Format("Error: The input map {0} has values outside the range of 0-3", inputMapName);
                            throw new System.ApplicationException(message);
                        }
                        if (site.IsActive)
                        {
                            status[site] = mapCode;
                        }
                    }
                }
            }
        }
Exemple #2
0
        //---------------------------------------------------------------------

        ///<summary>
        /// Run the plug-in at a particular timestep.
        ///</summary>
        public override void Run()
        {
            ModelCore.UI.WriteLine("Processing landscape for root rot ...");

            ActualYear = 0;

            // new Event for each timestep
            Event newEvent        = new Event();
            int   lethalTempSites = 0;

            foreach (ActiveSite site in ModelCore.Landscape.ActiveSites)
            {
                newEvent.currentSite = site;
                int status = SiteVars.Status[site];
                SiteVars.SpeciesBiomassRemoved[site] = new Dictionary <ISpecies, int>();
                SiteVars.TotalBiomassRemoved[site]   = 0;
                SiteVars.AvgSoilTemp[site]           = 999;
                SiteVars.Avg_pSI[site]          = (float)-1.0;
                SiteVars.Avg_WetnessIndex[site] = (float)-1.0;
                SiteVars.Avg_pID[site]          = (float)-1.0;


                int newStatus = status;
                if (status > 0) // Status 0 = Nonactive, not processed
                {
                    IEcoregion ecoregion = PlugIn.ModelCore.Ecoregion[site];
                    //float tmin = ecoMinTemp[ecoregion];
                    float tmin  = SiteVars.ExtremeMinTemp[site];
                    float dTemp = (tmin - Parameters.LethalTemp) / Math.Abs(Parameters.LethalTemp);
                    dTemp = Math.Min(dTemp, 1);
                    dTemp = Math.Max(dTemp, 0);

                    bool presence = (status > 1);
                    if (dTemp < PlugIn.ModelCore.GenerateUniform())
                    {
                        presence                  = false;
                        lethalTempSites          += 1;
                        newStatus                 = 1; // If Presence == false, site transitions to Susceptible (S) regardless of current state
                        SiteVars.LethalTemp[site] = (int)Math.Round(tmin);
                    }
                    else  // If Presence == true, other transitions are possible based on Conducive Environment
                    {
                        SiteVars.LethalTemp[site] = 99;
                        presence = true;
                        float pSI = 0;
                        //float pSD = 0;
                        float pID = 0;
                        //float pIS = 0;
                        float pDI = 0;
                        //float pDS = 0;
                        if (status == 3) // Site currently Diseased (D) can transition to Susceptible (S) or Infected (I)
                        {
                            // probability of D converting to S only based on presenece - handled above

                            // probability of D converting to I (pDI)
                            float maxSusceptibility = 0;
                            float pDIavg            = 0;

                            foreach (ISpeciesCohorts speciesCohorts in SiteVars.Cohorts[site])
                            {
                                foreach (ICohort cohort in speciesCohorts)
                                {
                                    float speciesSuscept = Parameters.SusceptibilityTable[cohort.Species][0];
                                    if (speciesSuscept > maxSusceptibility)
                                    {
                                        maxSusceptibility = speciesSuscept;
                                        break;
                                    }
                                }
                            }

                            if (maxSusceptibility == 0)
                            {
                                pDIavg = 1;
                            }
                            else
                            {
                                float midpoint = (float)((Parameters.PhDry - Parameters.PhWet) / 2.0);
                                float m2       = (float)(1.0 / (midpoint - Parameters.PhWet));
                                float b2       = (float)-1.0 * Parameters.PhWet * m2;
                                float m3       = (float)(1.0 / (midpoint - Parameters.PhDry));
                                float b3       = (float)-1.0 * Parameters.PhDry * m3;

                                float pDIsum   = 0;
                                float pDIcount = 0;
                                for (int m = 0; m < SiteVars.MonthlyPressureHead[site].Count(); m++)
                                {
                                    if (!(SiteVars.MonthlySoilTemp[site][m] == null))
                                    {
                                        float pressureHead = SiteVars.MonthlyPressureHead[site][m];
                                        if (pressureHead < Parameters.PhWet)
                                        {
                                            pDI = 0;
                                        }
                                        else if (pressureHead > Parameters.PhDry)
                                        {
                                            pDI = 0;
                                        }
                                        else if (pressureHead <= (Parameters.PhDry - Parameters.PhWet) / 2)
                                        {
                                            pDI = m2 * pressureHead + b2;
                                        }
                                        else
                                        {
                                            pDI = m3 * pressureHead + b3;
                                        }
                                        pDI     = Math.Min(pDI, Parameters.MaxProbDI);
                                        pDIsum += pDI;
                                        pDIcount++;
                                    }
                                }
                                if (pDIcount > 0)
                                {
                                    pDIavg = pDIsum / pDIcount;
                                }
                            }
                            if (pDIavg >= PlugIn.ModelCore.GenerateUniform())
                            {
                                newStatus = 2;
                            }
                        }
                        else if (status == 2)  // Site currently Infected (I) can transition to Diseased (D) or Susceptible (S)
                        {
                            // probability of I converting to S only based on presenece - handled above

                            // probability of I converting to D
                            pID = Calc_pID(Parameters, site);
                            SiteVars.Avg_pID[site] = pID;
                            if (pID >= PlugIn.ModelCore.GenerateUniform())
                            {
                                newStatus = 3;
                            }
                        }
                        else if (status == 1)  // Site currently Susceptible (S) can transition to Infected (I) or Diseased (D)
                        {
                            // probability of S converting to I
                            float pSIsum        = 0;
                            int   pSIcount      = 0;
                            float soilTempsum   = 0;
                            int   soilTempcount = 0;
                            float wetnessSum    = 0;
                            int   wetnessCount  = 0;

                            for (int m = 0; m < SiteVars.MonthlyPressureHead[site].Count(); m++)
                            {
                                float WetnessIndex = 0;
                                float depthKey     = Parameters.SoilTDepth;
                                SortedList <float, float> soilTemps = SiteVars.MonthlySoilTemp[site][m];
                                if (!(soilTemps == null))
                                {
                                    if (!soilTemps.ContainsKey(depthKey))
                                    {
                                        List <float> keys  = soilTemps.Keys.ToList <float>();
                                        int          index = keys.BinarySearch(depthKey);
                                        if (index < 0)
                                        {
                                            depthKey = keys[(~index)];
                                        }
                                        else
                                        {
                                            depthKey = keys[index];
                                        }
                                    }
                                    float soilTemp = soilTemps[depthKey];
                                    soilTempsum += soilTemp;
                                    soilTempcount++;
                                    if (SiteVars.MonthlyPressureHead[site][m] < Parameters.PhWet)
                                    {
                                        WetnessIndex = 1;
                                    }
                                    else
                                    {
                                        WetnessIndex = (float)((1.0 / (Parameters.PhWet - Parameters.PhDry)) * SiteVars.MonthlyPressureHead[site][m] - (Parameters.PhDry / (Parameters.PhWet - Parameters.PhDry)));
                                        WetnessIndex = (float)Math.Max(0, WetnessIndex);
                                    }
                                    wetnessSum += WetnessIndex;
                                    wetnessCount++;
                                    if (soilTemp < Parameters.MinSoilTemp)
                                    {
                                        pSI = 0;
                                    }
                                    else
                                    {
                                        float FC = SiteVars.FieldCapacity[site];
                                        pSI = (float)(0.006711 + 0.556566 * WetnessIndex + 0.013227 * FC - 0.008511 * WetnessIndex * FC);
                                    }
                                    pSIsum += pSI;
                                    pSIcount++;
                                }
                            }
                            float pSIAvg = 0;
                            if (pSIcount > 0)
                            {
                                pSIAvg = pSIsum / (float)pSIcount;
                            }
                            SiteVars.Avg_pSI[site] = pSIAvg;
                            float soilTempAvg = 0;
                            if (soilTempcount > 0)
                            {
                                soilTempAvg = soilTempsum / (float)soilTempcount;
                            }
                            SiteVars.AvgSoilTemp[site] = soilTempAvg;
                            float wetnessAvg = 0;
                            if (wetnessCount > 0)
                            {
                                wetnessAvg = wetnessSum / (float)wetnessCount;
                            }
                            SiteVars.Avg_WetnessIndex[site] = wetnessAvg;

                            if (pSIAvg >= PlugIn.ModelCore.GenerateUniform())
                            {
                                // probability of S converting to D is contingent on S converting to I
                                pID = Calc_pID(Parameters, site);
                                SiteVars.Avg_pID[site] = pID;
                                if (pID >= PlugIn.ModelCore.GenerateUniform())
                                {
                                    newStatus = 3;
                                }
                                else
                                {
                                    newStatus = 2;
                                }
                            }
                        }
                    }
                }
                if (newStatus == 1) // Uninfected
                {
                    newEvent.UninfectedSites += 1;
                }
                else if (newStatus == 2) // Infected
                {
                    newEvent.InfectedSites += 1;
                }
                else if (newStatus == 3) // Diseased - can cause damage
                {
                    newEvent.DiseasedSites += 1;
                    int damage = SiteVars.Cohorts[site].ReduceOrKillBiomassCohorts(newEvent);
                    if (damage > 0)
                    {
                        newEvent.TotalSitesDamaged += 1;
                    }
                    SiteVars.TimeOfLastDisease[site] = PlugIn.ModelCore.CurrentTime;
                }

                SiteVars.Status[site] = newStatus;
            }
            newEvent.Absent = (float)lethalTempSites;
            // Write logs
            LogEvent(PlugIn.ModelCore.CurrentTime, newEvent);

            // Write output maps
            string     path       = "";
            Dimensions dimensions = new Dimensions(ModelCore.Landscape.Rows, ModelCore.Landscape.Columns);

            //  Write Pathogen Status map
            if (outMapNameTemplate != null)
            {
                path = MapNames.ReplaceTemplateVars(outMapNameTemplate, ModelCore.CurrentTime);
                using (IOutputRaster <IntPixel> outputRaster = ModelCore.CreateRaster <IntPixel>(path, dimensions))
                {
                    IntPixel pixel = outputRaster.BufferPixel;
                    foreach (Site site in ModelCore.Landscape.AllSites)
                    {
                        if (site.IsActive)
                        {
                            pixel.MapCode.Value = (int)(SiteVars.Status[site]);
                        }
                        else
                        {
                            //  Inactive site
                            pixel.MapCode.Value = 0;
                        }
                        outputRaster.WriteBufferPixel();
                    }
                }
            }
            //  Write Time of Last Pathogen map
            if (toldMapNameTemplate != null)
            {
                path = MapNames.ReplaceTemplateVars(toldMapNameTemplate, ModelCore.CurrentTime);
                using (IOutputRaster <IntPixel> outputRaster = ModelCore.CreateRaster <IntPixel>(path, dimensions))
                {
                    IntPixel pixel = outputRaster.BufferPixel;
                    foreach (Site site in ModelCore.Landscape.AllSites)
                    {
                        if (site.IsActive)
                        {
                            pixel.MapCode.Value = (int)(SiteVars.TimeOfLastDisease[site]);
                        }
                        else
                        {
                            //  Inactive site
                            pixel.MapCode.Value = 0;
                        }
                        outputRaster.WriteBufferPixel();
                    }
                }
            }
            //  Write Lethal Temp map
            if (lethalTempMapNameTemplate != null)
            {
                path = MapNames.ReplaceTemplateVars(lethalTempMapNameTemplate, ModelCore.CurrentTime);
                using (IOutputRaster <IntPixel> outputRaster = ModelCore.CreateRaster <IntPixel>(path, dimensions))
                {
                    IntPixel pixel = outputRaster.BufferPixel;
                    foreach (Site site in ModelCore.Landscape.AllSites)
                    {
                        if (site.IsActive)
                        {
                            pixel.MapCode.Value = (int)(SiteVars.LethalTemp[site]);
                        }
                        else
                        {
                            //  Inactive site
                            pixel.MapCode.Value = 99;
                        }
                        outputRaster.WriteBufferPixel();
                    }
                }
            }
            //  Write TotalBiomassRemoved map
            if (totalBiomassRemovedMapNameTemplate != null)
            {
                path = MapNames.ReplaceTemplateVars(totalBiomassRemovedMapNameTemplate, ModelCore.CurrentTime);
                using (IOutputRaster <IntPixel> outputRaster = ModelCore.CreateRaster <IntPixel>(path, dimensions))
                {
                    IntPixel pixel = outputRaster.BufferPixel;
                    foreach (Site site in ModelCore.Landscape.AllSites)
                    {
                        if (site.IsActive)
                        {
                            pixel.MapCode.Value = (int)(SiteVars.TotalBiomassRemoved[site]);
                        }
                        else
                        {
                            //  Inactive site
                            pixel.MapCode.Value = 0;
                        }
                        outputRaster.WriteBufferPixel();
                    }
                }
            }
            //  Write SpeciesBiomassRemoved maps
            if (speciesBiomassRemovedMapNameTemplate != null)
            {
                foreach (ISpecies spc in PlugIn.ModelCore.Species)
                {
                    path = MapNames.ReplaceTemplateVars(speciesBiomassRemovedMapNameTemplate, spc.Name, ModelCore.CurrentTime);
                    using (IOutputRaster <IntPixel> outputRaster = ModelCore.CreateRaster <IntPixel>(path, dimensions))
                    {
                        IntPixel pixel = outputRaster.BufferPixel;
                        foreach (Site site in ModelCore.Landscape.AllSites)
                        {
                            if ((site.IsActive) && (SiteVars.SpeciesBiomassRemoved[site].ContainsKey(spc)))
                            {
                                pixel.MapCode.Value = (int)(SiteVars.SpeciesBiomassRemoved[site][spc]);
                            }
                            else
                            {
                                //  Inactive site
                                pixel.MapCode.Value = 0;
                            }
                            outputRaster.WriteBufferPixel();
                        }
                    }
                }
            }

            //Write additional outputs
            if (soilTempMapNameTemplate != null)
            {
                path = MapNames.ReplaceTemplateVars(soilTempMapNameTemplate, ModelCore.CurrentTime);
                using (IOutputRaster <IntPixel> outputRaster = ModelCore.CreateRaster <IntPixel>(path, dimensions))
                {
                    IntPixel pixel = outputRaster.BufferPixel;
                    foreach (Site site in ModelCore.Landscape.AllSites)
                    {
                        if (site.IsActive)
                        {
                            pixel.MapCode.Value = (int)(Math.Round(SiteVars.AvgSoilTemp[site]));
                        }
                        else
                        {
                            //  Inactive site
                            pixel.MapCode.Value = 999;
                        }
                        outputRaster.WriteBufferPixel();
                    }
                }
            }
            //Write additional outputs
            if (wetnessIndexMapNameTemplate != null)
            {
                path = MapNames.ReplaceTemplateVars(wetnessIndexMapNameTemplate, ModelCore.CurrentTime);
                using (IOutputRaster <IntPixel> outputRaster = ModelCore.CreateRaster <IntPixel>(path, dimensions))
                {
                    IntPixel pixel = outputRaster.BufferPixel;
                    foreach (Site site in ModelCore.Landscape.AllSites)
                    {
                        if (site.IsActive)
                        {
                            pixel.MapCode.Value = (int)(Math.Round(SiteVars.Avg_WetnessIndex[site] * 100));
                        }
                        else
                        {
                            //  Inactive site
                            pixel.MapCode.Value = 999;
                        }
                        outputRaster.WriteBufferPixel();
                    }
                }
            }
            //Write additional outputs
            if (pSIMapNameTemplate != null)
            {
                path = MapNames.ReplaceTemplateVars(pSIMapNameTemplate, ModelCore.CurrentTime);
                using (IOutputRaster <IntPixel> outputRaster = ModelCore.CreateRaster <IntPixel>(path, dimensions))
                {
                    IntPixel pixel = outputRaster.BufferPixel;
                    foreach (Site site in ModelCore.Landscape.AllSites)
                    {
                        if (site.IsActive)
                        {
                            pixel.MapCode.Value = (int)(Math.Round(SiteVars.Avg_pSI[site] * 100));
                        }
                        else
                        {
                            //  Inactive site
                            pixel.MapCode.Value = 999;
                        }
                        outputRaster.WriteBufferPixel();
                    }
                }
            }
            //Write additional outputs
            if (pIDMapNameTemplate != null)
            {
                path = MapNames.ReplaceTemplateVars(pIDMapNameTemplate, ModelCore.CurrentTime);
                using (IOutputRaster <IntPixel> outputRaster = ModelCore.CreateRaster <IntPixel>(path, dimensions))
                {
                    IntPixel pixel = outputRaster.BufferPixel;
                    foreach (Site site in ModelCore.Landscape.AllSites)
                    {
                        if (site.IsActive)
                        {
                            pixel.MapCode.Value = (int)(Math.Round(SiteVars.Avg_pID[site] * 100));
                        }
                        else
                        {
                            //  Inactive site
                            pixel.MapCode.Value = 999;
                        }
                        outputRaster.WriteBufferPixel();
                    }
                }
            }
        }