GenerateRandomNum() public static method

public static GenerateRandomNum ( DistributionType dist, double parameter1, double parameter2 ) : double
dist DistributionType
parameter1 double
parameter2 double
return double
Esempio n. 1
0
        //---------------------------------------------------------------------
        // Initialize landscape with patches of defoliation during the first year
        public static void InitializeDefoliationPatches(IInsect insect)
        {
            PlugIn.ModelCore.UI.WriteLine("   Initializing Defoliation Patches... ");
            SiteVars.InitialOutbreakProb.ActiveSiteValues   = 0.0;
            insect.Disturbed.ActiveSiteValues               = false;
            insect.NeighborhoodDefoliation.ActiveSiteValues = 0.0;

            foreach (ActiveSite site in PlugIn.ModelCore.Landscape)
            {
                double suscIndexSum = 0.0;
                double sumBio       = 0.0;


                foreach (ISpeciesCohorts speciesCohorts in SiteVars.Cohorts[site])
                //foreach (ISpeciesCohorts speciesCohorts in (Landis.Library.BiomassCohorts.ISpeciesCohorts) SiteVars.Cohorts[site]) // Rob's suggestion. Raised an error...
                {
                    foreach (ICohort cohort in speciesCohorts)
                    {
                        suscIndexSum += cohort.Biomass * (insect.SppTable[cohort.Species.Index].Susceptibility);
                        sumBio       += cohort.Biomass;
                    }
                }


                // If no biomass, no chance of defoliation, go to the next site.
                if (suscIndexSum <= 0 || sumBio <= 0)
                {
                    SiteVars.InitialOutbreakProb[site] = 0.0;
                    continue;
                }

                int suscIndex = (int)Math.Round(suscIndexSum / sumBio) - 1;

                if (suscIndex > 2.0 || suscIndex < 0)
                {
                    PlugIn.ModelCore.UI.WriteLine("SuscIndex < 0 || > 2.  Site R/C={0}/{1},suscIndex={2},suscIndexSum={3},sumBio={4}.", site.Location.Row, site.Location.Column, suscIndex, suscIndexSum, sumBio);
                    throw new ApplicationException("Error: SuscIndex is not between 2.0 and 0.0");
                }
                // Assume that there are no neighbors and draw initial defoliation from the most intense neighborhood distribution:
                DistributionType dist = insect.SusceptibleTable[suscIndex].Distribution_80.Name;


                // PlugIn.ModelCore.UI.WriteLine("suscIndex={0},suscIndexSum={1},cohortBiomass={2}.", suscIndex,suscIndexSum,sumBio);
                double value1 = insect.SusceptibleTable[suscIndex].Distribution_80.Value1;
                double value2 = insect.SusceptibleTable[suscIndex].Distribution_80.Value2;

                double probability = Distribution.GenerateRandomNum(dist, value1, value2);
                if (probability > 1.0 || probability < 0)
                {
                    PlugIn.ModelCore.UI.WriteLine("Initial Defoliation Probility < 0 || > 1.  Site R/C={0}/{1}.", site.Location.Row, site.Location.Column);
                    throw new ApplicationException("Error: Probability is not between 1.0 and 0.0");
                }
                // Try cleaning up defoliation patterns so areas outside main patches are less defoliated
                // How about using Brian's patch shape calibrator here instead. Divide probability by susIndex * PSC, to tie initial patch probs. more closely to host abundance...
                //SiteVars.InitialOutbreakProb[site] = probability;
                SiteVars.InitialOutbreakProb[site] = probability / ((double)suscIndex + 1);
                // PlugIn.ModelCore.UI.WriteLine("Susceptiblity index={0}.  Outbreak Probability={1:0.00}.  R/C={2}/{3}.", suscIndex, probability, site.Location.Row, site.Location.Column);
            }

            foreach (ActiveSite site in PlugIn.ModelCore.Landscape)
            {
                //get a random site from the stand
                double randomNum  = PlugIn.ModelCore.GenerateUniform();
                double randomNum2 = PlugIn.ModelCore.GenerateUniform();

                //Create random variability in outbreak area within a simulation so outbreaks are more variable.
                double initialAreaCalibratorRandomNum = (randomNum2 - 0.5) * insect.InitialPatchOutbreakSensitivity / 2;

                //Start spreading!
                if (randomNum < SiteVars.InitialOutbreakProb[site] * (insect.InitialPatchOutbreakSensitivity + initialAreaCalibratorRandomNum))
                {
                    //start with this site (if it's active)
                    ActiveSite currentSite = site;

                    //queue to hold sites to defoliate
                    Queue <ActiveSite> sitesToConsider = new Queue <ActiveSite>();

                    //put initial site on queue
                    sitesToConsider.Enqueue(currentSite);

                    DistributionType dist       = insect.InitialPatchDistr;
                    double           targetArea = Distribution.GenerateRandomNum(dist, insect.InitialPatchValue1, insect.InitialPatchValue2);

                    // PlugIn.ModelCore.UI.WriteLine("  Target Patch Area={0:0.0}.", targetArea);
                    double areaSelected = 0.0;

                    //loop through stand, defoliating patches of size target area
                    while (sitesToConsider.Count > 0 && areaSelected < targetArea)
                    {
                        currentSite = sitesToConsider.Dequeue();

                        // Because this is the first year, neighborhood defoliation is given a value.
                        // The value is used in Defoliate.DefoliateCohort()
                        insect.NeighborhoodDefoliation[currentSite] = SiteVars.InitialOutbreakProb[currentSite];
                        areaSelected += PlugIn.ModelCore.CellArea;
                        //insect.Disturbed[currentSite] = true;

                        //Next, add site's neighbors to the list of
                        //sites to consider.
                        //loop through the site's neighbors enqueueing all the good ones.

                        //double maxNeighborProb = 0.0;
                        //Site maxNeighbor = currentSite;
                        //bool foundNewNeighbor = false;

                        foreach (RelativeLocation loc in all_neighbor_locations)
                        {
                            Site neighbor = currentSite.GetNeighbor(loc);

                            //get a neighbor site (if it's non-null and active)
                            if (neighbor != null &&
                                neighbor.IsActive &&
                                !sitesToConsider.Contains((ActiveSite)neighbor) &&
                                !insect.Disturbed[neighbor])
                            {
                                insect.Disturbed[currentSite] = true;
                                randomNum = PlugIn.ModelCore.GenerateUniform();

                                /*if (SiteVars.InitialOutbreakProb[neighbor] > maxNeighborProb)
                                 * {
                                 *  maxNeighbor = currentSite.GetNeighbor(loc);
                                 *  maxNeighborProb = SiteVars.InitialOutbreakProb[neighbor];
                                 *  foundNewNeighbor = true;
                                 * }*/

                                //check if it's a valid neighbor:
                                if (SiteVars.InitialOutbreakProb[neighbor] > randomNum)
                                {
                                    sitesToConsider.Enqueue((ActiveSite)neighbor);
                                }
                            }
                        }

                        //if(foundNewNeighbor)
                        //    sitesToConsider.Enqueue((ActiveSite) maxNeighbor);
                    }

                    // PlugIn.ModelCore.UI.WriteLine("   Initial Patch Area Selected={0:0.0}.", areaSelected);
                }
            }
        }
Esempio n. 2
0
        //---------------------------------------------------------------------
        ///<summary>
        /// Run Biomass Insects extension at a particular timestep.
        ///</summary>
        public override void Run()
        {
            running = true;
            PlugIn.ModelCore.UI.WriteLine("   Processing landscape for Biomass Insect events ...");

            SiteVars.SiteDefoliation.ActiveSiteValues = 0;

            foreach (IInsect insect in manyInsect)
            {
                //SiteVars.BiomassRemoved.ActiveSiteValues = 0;
                //SiteVars.InitialOutbreakProb.ActiveSiteValues = 0.0;

                if (insect.MortalityYear == PlugIn.ModelCore.CurrentTime)
                {
                    Outbreak.Mortality(insect);
                }

                if (insect.MortalityYear != PlugIn.ModelCore.CurrentTime)
                {
                    insect.LastBioRemoved = 0;
                }

                // Copy the data from current to last
                foreach (ActiveSite site in PlugIn.ModelCore.Landscape)
                {
                    double thisYearDefol = insect.ThisYearDefoliation[site];
                    insect.LastYearDefoliation[site] = thisYearDefol;
                    SiteVars.SiteDefoliation[site]  += (int)Math.Round(thisYearDefol * 100);
                    if (thisYearDefol > 0)
                    {
                        SiteVars.TimeOfLastEvent[site] = PlugIn.ModelCore.CurrentTime - 1;
                        SiteVars.InsectName[site]      = insect.Name;
                    }
                }


                insect.ThisYearDefoliation.ActiveSiteValues = 0.0;

                insect.ActiveOutbreak     = false;
                insect.SingleOutbreakYear = false;

                //PlugIn.ModelCore.NormalDistribution.Mu = 0.0;
                //PlugIn.ModelCore.NormalDistribution.Sigma = 1.0;
                //double randomNum = PlugIn.ModelCore.NormalDistribution.NextDouble();
                //randomNum = PlugIn.ModelCore.NormalDistribution.NextDouble();
                double randomNum = Distribution.GenerateRandomNum(DistributionType.Normal, 0.0, 1.0);

                DistributionType distDuration = insect.DurationDistribution;

                double randomNumE = Distribution.GenerateRandomNum(distDuration, insect.DurationParameter1, insect.DurationParameter2);

                // First, has enough time passed since the last outbreak? This is calculated each year,
                // but only used in last year of an outbreak to generate next outbreak characteristics.
                double timeBetweenOutbreaks = insect.MeanTimeBetweenOutbreaks + (insect.StdDevTimeBetweenOutbreaks * randomNum);
                double duration             = System.Math.Round(randomNumE);
                if (distDuration == DistributionType.Exponential || distDuration == DistributionType.Normal)
                {
                    duration = System.Math.Max(duration + 1, 1); // Duration cannot be less than 1. Added to allow Normal distribution parameters.
                }
                else
                {
                    duration = System.Math.Max(duration, 1);  // Duration cannot be less than 1.
                }

                // Apply optional maximum - if not used maxDur = Inf
                if (duration > insect.MaxDuration)
                {
                    duration = insect.MaxDuration;
                }

                double timeAfterDuration = timeBetweenOutbreaks - duration;

                // Users can parameterize model to have overlapping outbreaks, but then patches will not initialize correctly.
                // Do below to prevent overlapping outbreaks of same insect. This will affect the realized distribution of time between outbreaks somewhat.
                while (timeAfterDuration <= 1.0)
                {
                    PlugIn.ModelCore.UI.WriteLine("CAUTION: Time Between Outbreaks TOO SMALL (< 1), you may need to adjust timing parameters:  {0}.", timeAfterDuration);
                    timeBetweenOutbreaks = timeBetweenOutbreaks + 1;
                    timeAfterDuration    = timeBetweenOutbreaks - duration;
                }

                //PlugIn.ModelCore.UI.WriteLine("Calculated time between = {0:0.00}.  inputMeanTime={1:0.00}, inputStdTime={2:0.00}., timeAftDur={3:0.00}.", timeBetweenOutbreaks, insect.MeanTimeBetweenOutbreaks, insect.StdDevTimeBetweenOutbreaks, timeAfterDuration);

                // The logic below determines whether an outbreak is active. And sets a new outbreak duration and timeBetweenOutbreaks
                // for the next outbreak if is the last year of an outbreak.

                // The very first outbreak is set first.
                if (PlugIn.ModelCore.CurrentTime == 1)
                {
                    PlugIn.ModelCore.UI.WriteLine("   Year 1:  Setting initial start and stop times.");
                    double randomNum1 = PlugIn.ModelCore.GenerateUniform();
                    //insect.OutbreakStartYear = (int) (timeBetweenOutbreaks / 2.0) + 1;
                    insect.OutbreakStartYear = Math.Max(2, (int)(randomNum1 * timeBetweenOutbreaks + 1)); // New, try making 1st start year more random. 1st outbreak has to occur > year1 to for InitializeDefoliationPatches to work properly.
                    insect.OutbreakStartYear = Math.Max(insect.OutbreakStartYear, insect.StartYear);      // BRM - optional start year (first outbreak can't be before StartYear)
                    insect.OutbreakStopYear  = insect.OutbreakStartYear + (int)duration - 1;
                    // PlugIn.ModelCore.UI.WriteLine("   {0} is not active.  StartYear={1}, StopYear={2}, CurrentYear={3}.", insect.Name, insect.OutbreakStartYear, insect.OutbreakStopYear, PlugIn.ModelCore.CurrentTime);
                }
                else if (insect.OutbreakStartYear <= PlugIn.ModelCore.CurrentTime &&
                         insect.OutbreakStopYear > PlugIn.ModelCore.CurrentTime) // first year of a multiyear outbreak
                {
                    // PlugIn.ModelCore.UI.WriteLine("   An outbreak starts or continues.  Start and stop time do not change.");
                    insect.ActiveOutbreak = true;
                    PlugIn.ModelCore.UI.WriteLine("   {0} is active.  StartYear={1}, StopYear={2}, CurrentYear={3}.", insect.Name, insect.OutbreakStartYear, insect.OutbreakStopYear, PlugIn.ModelCore.CurrentTime);

                    insect.MortalityYear = PlugIn.ModelCore.CurrentTime + 1;
                    insect.LastStartYear = insect.OutbreakStartYear; // Added here for Brian's log file.
                    insect.LastStopYear  = insect.OutbreakStopYear;  // Added here for Brian's log file.
                }
                //Special case for single year outbreak.
                else if (insect.OutbreakStartYear == PlugIn.ModelCore.CurrentTime &&
                         insect.OutbreakStopYear == PlugIn.ModelCore.CurrentTime)
                {
                    insect.ActiveOutbreak = true;
                    PlugIn.ModelCore.UI.WriteLine("   {0} is active.  StartYear={1}, StopYear={2}, CurrentYear={3}.", insect.Name, insect.OutbreakStartYear, insect.OutbreakStopYear, PlugIn.ModelCore.CurrentTime);

                    if (insect.OutbreakStartYear == insect.OutbreakStopYear) // shouldn't need this. JRF
                    {
                        insect.SingleOutbreakYear = true;
                    }
                    insect.MortalityYear     = PlugIn.ModelCore.CurrentTime + 1;
                    insect.LastStartYear     = insect.OutbreakStartYear; // Added here for Brian's log file.
                    insect.LastStopYear      = insect.OutbreakStopYear;  // Added here for Brian's log file.
                    insect.OutbreakStartYear = PlugIn.ModelCore.CurrentTime + (int)timeBetweenOutbreaks;
                    insect.OutbreakStopYear  = insect.OutbreakStartYear + (int)duration - 1;
                }

                else if (insect.OutbreakStopYear <= PlugIn.ModelCore.CurrentTime &&
                         timeAfterDuration > PlugIn.ModelCore.CurrentTime - insect.OutbreakStopYear)
                {
                    // PlugIn.ModelCore.UI.WriteLine("   In between outbreaks, reset start and stop times.");
                    insect.ActiveOutbreak = true;
                    PlugIn.ModelCore.UI.WriteLine("   {0} is active.  StartYear={1}, StopYear={2}, CurrentYear={3}.", insect.Name, insect.OutbreakStartYear, insect.OutbreakStopYear, PlugIn.ModelCore.CurrentTime);

                    insect.MortalityYear     = PlugIn.ModelCore.CurrentTime + 1;
                    insect.LastStartYear     = insect.OutbreakStartYear; // Added here for Brian's log file.
                    insect.LastStopYear      = insect.OutbreakStopYear;  // Added here for Brian's log file.
                    insect.OutbreakStartYear = PlugIn.ModelCore.CurrentTime + (int)timeBetweenOutbreaks;
                    insect.OutbreakStopYear  = insect.OutbreakStartYear + (int)duration - 1;
                }
                PlugIn.ModelCore.UI.WriteLine("  Insect Start Time = {0}, Stop Time = {1}.", insect.OutbreakStartYear, insect.OutbreakStopYear);

                // Now that logic determining when an outbreak will be active is done, tell model what to do when outbreak is occurring.
                if (insect.ActiveOutbreak)
                {
                    //  PlugIn.ModelCore.UI.WriteLine("   OutbreakStartYear={0}.", insect.OutbreakStartYear);

                    if (insect.OutbreakStartYear == PlugIn.ModelCore.CurrentTime || insect.SingleOutbreakYear)
                    {
                        // Initialize neighborhoodGrowthReduction with patches
                        Outbreak.InitializeDefoliationPatches(insect);
                    }
                    else
                    {
                        insect.NeighborhoodDefoliation.ActiveSiteValues = 0;
                    }
                }

                // Now report on the previous year's defoliation, that which has been processed
                // through biomass succession. Calculations for logfile.

                double sumDefoliation  = 0.0;
                double meanDefoliation = 0.0;
                int    numSites0_33    = 0;
                int    numSites33_66   = 0;
                int    numSites66_100  = 0;
                int    numInitialSites = 0;
                int    numSitesActive  = 0; // Just get a sum of all active sites to calculate mean defoliation accurately for log file.

                // ONly calculate for log file when outbreak or mortality is active <- Modified, JRF, add to log file each year.
                if (insect.ActiveOutbreak || insect.SingleOutbreakYear || (insect.LastStopYear + 1 >= PlugIn.ModelCore.CurrentTime) || (insect.LastBioRemoved > 0))
                {
                    foreach (ActiveSite site in PlugIn.ModelCore.Landscape)
                    {
                        sumDefoliation += insect.LastYearDefoliation[site];
                        if (insect.LastYearDefoliation[site] > 0.0 && insect.LastYearDefoliation[site] <= 0.33)
                        {
                            numSites0_33++;
                        }
                        if (insect.LastYearDefoliation[site] > 0.33 && insect.LastYearDefoliation[site] <= 0.66)
                        {
                            numSites33_66++;
                        }
                        if (insect.LastYearDefoliation[site] > 0.66 && insect.LastYearDefoliation[site] <= 1.0)
                        {
                            numSites66_100++;
                        }
                        if (insect.Disturbed[site] && SiteVars.InitialOutbreakProb[site] > 0)
                        {
                            numInitialSites++;
                        }
                        numSitesActive++;
                    }
                    if (insect.OutbreakStartYear == PlugIn.ModelCore.CurrentTime)
                    {
                        insect.InitialSites = numInitialSites;
                    }

                    if (numSites0_33 + numSites33_66 + numSites66_100 > 0)
                    {
                        meanDefoliation = sumDefoliation / (double)numSitesActive;
                    }
                    //PlugIn.ModelCore.UI.WriteLine("   sumDefoliation={0}, numSites={1}.", sumDefoliation, numSites0_33 + numSites33_66 + numSites66_100);
                }

                int totalBioRemoved = 0;
                foreach (ActiveSite site in PlugIn.ModelCore.Landscape)
                {
                    totalBioRemoved += SiteVars.BiomassRemoved[site]; // kg across all defoliated sites
                }
                insect.LastBioRemoved = totalBioRemoved;              //Assign variables for the logfile
                // PlugIn.ModelCore.UI.WriteLine("   totalBioRemoved={0}.", totalBioRemoved);


                // ONly add to log & output maps during outbreak <- Modified, JRF, add to log file each year.
                //if ((insect.ActiveOutbreak && insect.OutbreakStartYear < PlugIn.ModelCore.CurrentTime) || (meanDefoliation > 0) || (insect.LastBioRemoved > 0))
                //{

                /*  Old code for log file
                 *  if (meanDefoliation > 0)
                 *  {
                 *
                 *          log.Write("{0},{1},{2},{3},{4:0.0000},{5},{6},{7},{8},{9}",
                 *                  PlugIn.ModelCore.CurrentTime-1,  //0
                 *                  insect.Name,  //1
                 *                  insect.LastStartYear,  //2
                 *                  insect.LastStopYear,  //3
                 *                  meanDefoliation, //4
                 *                  numSites0_33, //5
                 *                  numSites33_66,  //6
                 *                  numSites66_100, //7
                 *                  insect.InitialSites, //8
                 *                  insect.LastBioRemoved //9
                 *                  );
                 *  }
                 *
                 *  else
                 *  {
                 *      log.Write("{0},{1},{2},{3},{4:0.0000},{5},{6},{7},{8},{9}",
                 *              PlugIn.ModelCore.CurrentTime - 1,  //0
                 *              insect.Name,  //1
                 *              0,  //2
                 *              0,  //3
                 *              meanDefoliation, //4
                 *              numSites0_33, //5
                 *              numSites33_66,  //6
                 *              numSites66_100, //7
                 *              0, //8
                 *              insect.LastBioRemoved //9
                 *              );
                 *  }
                 *
                 *
                 *  //foreach (IEcoregion ecoregion in Ecoregions.Dataset)
                 *  //    log.Write(",{0}", 1);
                 *
                 *  log.WriteLine("");
                 */

                eventLog.Clear();
                EventsLog el = new EventsLog();

                el.Time                     = PlugIn.ModelCore.CurrentTime - 1;
                el.InsectName               = insect.Name;
                el.MeanDefoliation          = meanDefoliation;
                el.NumSitesDefoliated0_33   = numSites0_33;
                el.NumSitesDefoliated33_66  = numSites33_66;
                el.NumSitesDefoliated66_100 = numSites66_100;
                el.NumOutbreakInitialSites  = insect.InitialSites;
                el.MortalityBiomass         = insect.LastBioRemoved;

                if (insect.ActiveOutbreak)
                {
                    el.StartYear = insect.OutbreakStartYear;
                    el.StopYear  = insect.OutbreakStopYear;
                }
                else
                {
                    el.StartYear = insect.LastStartYear;
                    el.StopYear  = insect.LastStopYear;
                }

                eventLog.AddObject(el);
                eventLog.WriteToFile();

                //----- Write Insect Defoliation/GrowthReduction maps --------
                string path = MapNames.ReplaceTemplateVars(mapNameTemplate, insect.Name, PlugIn.ModelCore.CurrentTime - 1);
                using (IOutputRaster <ShortPixel> outputRaster = modelCore.CreateRaster <ShortPixel>(path, modelCore.Landscape.Dimensions))
                {
                    ShortPixel pixel = outputRaster.BufferPixel;

                    foreach (Site site in PlugIn.ModelCore.Landscape.AllSites)
                    {
                        if (site.IsActive)
                        {
                            pixel.MapCode.Value = (short)(insect.LastYearDefoliation[site] * 100.0);
                        }
                        else
                        {
                            //  Inactive site
                            pixel.MapCode.Value = 0;
                        }

                        outputRaster.WriteBufferPixel();
                    }
                }

                //----- Write Initial Patch maps --------
                string path2 = MapNames.ReplaceTemplateVars(mapNameTemplate, ("InitialPatchMap" + insect.Name), PlugIn.ModelCore.CurrentTime);
                using (IOutputRaster <ShortPixel> outputRaster = modelCore.CreateRaster <ShortPixel>(path2, modelCore.Landscape.Dimensions))
                {
                    ShortPixel pixel = outputRaster.BufferPixel;
                    foreach (Site site in PlugIn.ModelCore.Landscape.AllSites)
                    {
                        if (site.IsActive)
                        {
                            if (insect.Disturbed[site])
                            {
                                pixel.MapCode.Value = (short)(SiteVars.InitialOutbreakProb[site] * 100);
                            }
                            else
                            {
                                pixel.MapCode.Value = 0;
                            }
                        }
                        else
                        {
                            //  Inactive site
                            pixel.MapCode.Value = 0;
                        }
                        outputRaster.WriteBufferPixel();
                        //Zero out the InitialOutbreakProb after output maps are written.
                        SiteVars.InitialOutbreakProb[site] = 0;
                    }
                }

                //----- Write Biomass Reduction maps --------
                string path3 = MapNames.ReplaceTemplateVars(mapNameTemplate, ("BiomassRemoved" + insect.Name), PlugIn.ModelCore.CurrentTime);
                using (IOutputRaster <ShortPixel> outputRaster = modelCore.CreateRaster <ShortPixel>(path3, modelCore.Landscape.Dimensions))
                {
                    ShortPixel pixel = outputRaster.BufferPixel;
                    foreach (Site site in PlugIn.ModelCore.Landscape.AllSites)
                    {
                        if (site.IsActive)
                        {
                            if (SiteVars.BiomassRemoved[site] > 0)
                            {
                                pixel.MapCode.Value = Math.Max((short)1, (short)(SiteVars.BiomassRemoved[site] / 100));     // convert to Mg/ha
                            }
                            else
                            {
                                pixel.MapCode.Value = 0;
                            }
                        }
                        else
                        {
                            //  Inactive site
                            pixel.MapCode.Value = 0;
                        }
                        outputRaster.WriteBufferPixel();
                        //Zero out the BiomassRemoved after the last insect mortality event in a given year.
                        SiteVars.BiomassRemoved[site] = 0;
                    }
                }
                //}

                //insect.ThisYearDefoliation.ActiveSiteValues = 0.0;  //reset this year to 0 for all sites, this was already done at the top of loop to initialize defoliation patchs, Outbreak.cs
            }
        }
Esempio n. 3
0
        //---------------------------------------------------------------------
        // This method replaces the delegate method.  It is called every year when
        // ACT_ANPP is calculated, for each cohort.  Therefore, this method is operating at
        // an ANNUAL time step and separate from the normal extension time step.

        public static double DefoliateCohort(ActiveSite site, ISpecies species, int cohortBiomass, int siteBiomass)
        {
            //PlugIn.ModelCore.UI.WriteLine("   Calculating insect defoliation...");

            double totalDefoliation = 0.0;  // Cohort total defoliation

            foreach (IInsect insect in manyInsect)
            {
                if (!insect.ActiveOutbreak)
                {
                    continue;
                }
                double defoliation = 0.0;

                // Calculate biomass proportion of "protective" species
                double protectBiomass = 0;
                foreach (Landis.Library.BiomassCohorts.ISpeciesCohorts spp in SiteVars.Cohorts[site])
                {
                    foreach (Landis.Library.BiomassCohorts.ICohort spp_cohort in spp)
                    {
                        if (insect.Susceptibility[spp_cohort.Species] == 4)
                        {
                            protectBiomass += spp_cohort.Biomass;
                        }
                    }
                }
                double protectProp = protectBiomass / (double)siteBiomass;

                int suscIndex = insect.Susceptibility[species] - 1;


                if (suscIndex < 0)
                {
                    suscIndex = 0;
                }
                if (suscIndex > 2)
                {
                    suscIndex = 2;
                }

                // Get the Neighborhood GrowthReduction Density
                double meanNeighborhoodDefoliation = 0.0;
                int    neighborCnt = 0;

                // If it is the first year, the neighborhood growth reduction
                // will have been initialized in Outbreak.InitializeDefoliationPatches

                if (insect.NeighborhoodDefoliation[site] > 0)
                {
                    //PlugIn.ModelCore.UI.WriteLine("   First Year of Defoliation:  Using initial patch defo={0:0.00}.", SiteVars.NeighborhoodDefoliation[site]);
                    meanNeighborhoodDefoliation = insect.NeighborhoodDefoliation[site];
                }

                // If not the first year, calculate mean neighborhood defoliation based on the
                // previous year.
                else
                {
                    double sumNeighborhoodDefoliation = 0.0;

                    //PlugIn.ModelCore.UI.WriteLine("Look at the Neighbors... ");
                    foreach (RelativeLocation relativeLoc in insect.Neighbors)
                    {
                        Site neighbor = site.GetNeighbor(relativeLoc);
                        if (neighbor != null && neighbor.IsActive)
                        {
                            neighborCnt++;

                            // The previous year...
                            //if(SiteVars.DefoliationByYear[neighbor].ContainsKey(PlugIn.ModelCore.CurrentTime - 1))
                            //    sumNeighborhoodDefoliation += SiteVars.DefoliationByYear[neighbor][PlugIn.ModelCore.CurrentTime - 1];

                            // BUG - This does not sum values in the nbrhd, just uses the last nbr value
                            //sumNeighborhoodDefoliation = Math.Min(1.0, insect.LastYearDefoliation[neighbor]);
                            // BUG FIX - BRM
                            sumNeighborhoodDefoliation += Math.Min(1.0, insect.LastYearDefoliation[neighbor]);
                        }
                    }

                    if (neighborCnt > 0.0)
                    {
                        meanNeighborhoodDefoliation = sumNeighborhoodDefoliation / (double)neighborCnt;
                    }
                }  //endif

                if (meanNeighborhoodDefoliation > 1.0 || meanNeighborhoodDefoliation < 0)
                {
                    PlugIn.ModelCore.UI.WriteLine("MeanNeighborhoodDefoliation={0}; NeighborCnt={1}.", meanNeighborhoodDefoliation, neighborCnt);
                    throw new ApplicationException("Error: Mean Neighborhood GrowthReduction is not between 1.0 and 0.0");
                }

                // First assume that there are no neighbors whatsoever:
                DistributionType dist   = insect.SusceptibleTable[suscIndex].Distribution_0.Name;
                double           value1 = insect.SusceptibleTable[suscIndex].Distribution_0.Value1;
                double           value2 = insect.SusceptibleTable[suscIndex].Distribution_0.Value2;

                if (meanNeighborhoodDefoliation <= 1.0 && meanNeighborhoodDefoliation >= 0.8)
                {
                    dist   = insect.SusceptibleTable[suscIndex].Distribution_80.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_80.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_80.Value2;
                }
                else if (meanNeighborhoodDefoliation < 0.8 && meanNeighborhoodDefoliation >= 0.6)
                {
                    dist   = insect.SusceptibleTable[suscIndex].Distribution_60.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_60.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_60.Value2;
                }
                else if (meanNeighborhoodDefoliation < 0.6 && meanNeighborhoodDefoliation >= 0.4)
                {
                    dist   = insect.SusceptibleTable[suscIndex].Distribution_40.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_40.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_40.Value2;
                }
                else if (meanNeighborhoodDefoliation < 0.4 && meanNeighborhoodDefoliation >= 0.2)
                {
                    dist   = insect.SusceptibleTable[suscIndex].Distribution_20.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_20.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_20.Value2;
                }
                else if (meanNeighborhoodDefoliation < 0.2 && meanNeighborhoodDefoliation >= 0.0)
                {
                    dist   = insect.SusceptibleTable[suscIndex].Distribution_0.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_0.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_0.Value2;
                }

                // Next, ensure that all cohorts of the same susceptibility class
                // receive the same level of defoliation.

                if (insect.HostDefoliationByYear[site].ContainsKey(PlugIn.ModelCore.CurrentTime))
                {
                    if (insect.HostDefoliationByYear[site][PlugIn.ModelCore.CurrentTime][suscIndex] <= 0.00000000)
                    {
                        defoliation = Distribution.GenerateRandomNum(dist, value1, value2);
                        // Account for protective effect of Susc Class 4
                        if (protectProp > 0)
                        {
                            double slope         = 1.0;
                            double protectReduce = 1 - (protectProp * slope);
                            if (protectReduce > 1)
                            {
                                protectReduce = 1;
                            }
                            if (protectReduce < 0)
                            {
                                protectReduce = 0;
                            }
                            defoliation = defoliation * protectReduce;
                        }
                        insect.HostDefoliationByYear[site][PlugIn.ModelCore.CurrentTime][suscIndex] = defoliation;
                    }
                    else
                    {
                        defoliation = insect.HostDefoliationByYear[site][PlugIn.ModelCore.CurrentTime][suscIndex];
                    }
                }
                else
                {
                    insect.HostDefoliationByYear[site].Add(PlugIn.ModelCore.CurrentTime, new Double[3] {
                        0.0, 0.0, 0.0
                    });
                    defoliation = Distribution.GenerateRandomNum(dist, value1, value2);
                    //if (meanNeighborhoodDefoliation <= 0.0 && defoliation > 0.0)
                    //    PlugIn.ModelCore.UI.WriteLine("THAT'S WEIRD!!  meanNeighborhoodDefoliation = {0}, defoliation={1}.", meanNeighborhoodDefoliation, defoliation);
                    // Account for protective effect of Susc Class 4
                    if (protectProp > 0)
                    {
                        double slope         = 1.0;
                        double protectReduce = 1 - (protectProp * slope);
                        if (protectReduce > 1)
                        {
                            protectReduce = 1;
                        }
                        if (protectReduce < 0)
                        {
                            protectReduce = 0;
                        }
                        defoliation = defoliation * protectReduce;
                    }
                    insect.HostDefoliationByYear[site][PlugIn.ModelCore.CurrentTime][suscIndex] = defoliation;
                }


                // Alternatively, allow defoliation to vary even among cohorts and species with
                // the same susceptibility.


                if (defoliation > 1.0 || defoliation < 0)
                {
                    PlugIn.ModelCore.UI.WriteLine("DEFOLIATION TOO BIG or SMALL:  {0}, {1}, {2}, {3}.", dist, value1, value2, defoliation);
                    throw new ApplicationException("Error: New defoliation is not between 1.0 and 0.0");
                }

                //PlugIn.ModelCore.UI.WriteLine("Cohort age={0}, species={1}, suscIndex={2}, defoliation={3}.", cohort.Age, cohort.Species.Name, (suscIndex -1), defoliation);

                // BUG - This is summed proportions across all cohorts (exceeds 1.0)
                //insect.ThisYearDefoliation[site] += defoliation;

                // BUG FIX - Weight site-level defoliation by cohort biomass
                double weightedDefoliation = (defoliation * Math.Min(1.0, (double)cohortBiomass / (double)siteBiomass));
                //PlugIn.ModelCore.UI.WriteLine("Cohort age={0}, species={1}, suscIndex={2}, cohortDefoliation={3}, weightedDefolation={4}.", cohort.Age, cohort.Species.Name, (suscIndex+1), defoliation, weightedDefoliation);
                insect.ThisYearDefoliation[site] += weightedDefoliation;


                totalDefoliation += defoliation;  // Cohort total defoliation (summed across insects)
            }

            if (totalDefoliation > 1.0)  // Cannot exceed 100% defoliation
            {
                totalDefoliation = 1.0;
            }

            if (totalDefoliation > 1.1 || totalDefoliation < 0)
            {
                PlugIn.ModelCore.UI.WriteLine("Cohort Total Defoliation = {0:0.00}.  Site R/C={1}/{2}.", totalDefoliation, site.Location.Row, site.Location.Column);
                throw new ApplicationException("Error: Total Defoliation is not between 1.1 and 0.0");
            }


            return(totalDefoliation);  // Cohort total defoliation proportion (summed across insects)
        }
Esempio n. 4
0
        //---------------------------------------------------------------------
        // This method replaces the delegate method.  It is called every year when
        // ACT_ANPP is calculated, for each cohort.  Therefore, this method is operating at
        // an ANNUAL time step and separate from the normal extension time step.

        public static double DefoliateCohort(ICohort cohort, ActiveSite site, int siteBiomass)
        {
            // PlugIn.ModelCore.UI.WriteLine("   Calculating insect defoliation...");

            int    sppIndex         = cohort.Species.Index;
            double totalDefoliation = 0.0;

            foreach (IInsect insect in manyInsect)
            {
                if (!insect.ActiveOutbreak)
                {
                    continue;
                }

                double defoliation         = 0.0;
                double weightedDefoliation = 0.0;
                int    suscIndex           = insect.SppTable[sppIndex].Susceptibility - 1;

                if (suscIndex < 0)
                {
                    suscIndex = 0;
                }

                // Get the Neighborhood GrowthReduction Density
                double meanNeighborhoodDefoliation = 0.0;
                int    neighborCnt = 0;

                // If it is the first year, the neighborhood growth reduction
                // will have been initialized in Outbreak.InitializeDefoliationPatches

                if (insect.NeighborhoodDefoliation[site] > 0)
                {
                    // PlugIn.ModelCore.UI.WriteLine("   First Year of Defoliation:  Using initial patch defo={0:0.00}.", SiteVars.NeighborhoodDefoliation[site]);
                    meanNeighborhoodDefoliation = insect.NeighborhoodDefoliation[site];
                }

                // If not the first year, calculate mean neighborhood defoliation based on the
                // previous year.
                else
                {
                    double sumNeighborhoodDefoliation = 0.0;

                    // PlugIn.ModelCore.UI.WriteLine("Look at the Neighbors... ");
                    foreach (RelativeLocation relativeLoc in insect.Neighbors)
                    {
                        Site neighbor = site.GetNeighbor(relativeLoc);
                        if (neighbor != null && neighbor.IsActive)
                        {
                            neighborCnt++;

                            // The previous year...
                            //if(SiteVars.DefoliationByYear[neighbor].ContainsKey(PlugIn.ModelCore.CurrentTime - 1))
                            //    sumNeighborhoodDefoliation += SiteVars.DefoliationByYear[neighbor][PlugIn.ModelCore.CurrentTime - 1];
                            sumNeighborhoodDefoliation += insect.LastYearDefoliation[neighbor];
                        }
                    }

                    if (neighborCnt > 0.0)
                    {
                        meanNeighborhoodDefoliation = sumNeighborhoodDefoliation / (double)neighborCnt;
                    }
                }  //endif

                if (meanNeighborhoodDefoliation > 1.0 || meanNeighborhoodDefoliation < 0)
                {
                    PlugIn.ModelCore.UI.WriteLine("MeanNeighborhoodDefoliation={0}; NeighborCnt={1}.", meanNeighborhoodDefoliation, neighborCnt);
                    throw new ApplicationException("Error: Mean Neighborhood GrowthReduction is not between 1.0 and 0.0");
                }

                // First assume that there are no neighbors whatsoever:
                DistributionType dist   = insect.SusceptibleTable[suscIndex].Distribution_0.Name;
                double           value1 = insect.SusceptibleTable[suscIndex].Distribution_0.Value1;
                double           value2 = insect.SusceptibleTable[suscIndex].Distribution_0.Value2;

                if (meanNeighborhoodDefoliation <= 1.0 && meanNeighborhoodDefoliation >= 0.8)
                {
                    dist   = insect.SusceptibleTable[suscIndex].Distribution_80.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_80.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_80.Value2;
                }
                else if (meanNeighborhoodDefoliation < 0.8 && meanNeighborhoodDefoliation >= 0.6)
                {
                    dist   = insect.SusceptibleTable[suscIndex].Distribution_60.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_60.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_60.Value2;
                }
                else if (meanNeighborhoodDefoliation < 0.6 && meanNeighborhoodDefoliation >= 0.4)
                {
                    dist   = insect.SusceptibleTable[suscIndex].Distribution_40.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_40.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_40.Value2;
                }
                else if (meanNeighborhoodDefoliation < 0.4 && meanNeighborhoodDefoliation >= 0.2)
                {
                    dist   = insect.SusceptibleTable[suscIndex].Distribution_20.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_20.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_20.Value2;
                }
                else if (meanNeighborhoodDefoliation < 0.2 && meanNeighborhoodDefoliation >= 0.0)
                {
                    dist   = insect.SusceptibleTable[suscIndex].Distribution_0.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_0.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_0.Value2;
                }

                // Next, ensure that all cohorts of the same susceptibility class
                // receive the same level of defoliation.

                if (insect.HostDefoliationByYear[site].ContainsKey(PlugIn.ModelCore.CurrentTime))
                {
                    if (insect.HostDefoliationByYear[site][PlugIn.ModelCore.CurrentTime][suscIndex] <= 0.00000000)
                    {
                        defoliation = Distribution.GenerateRandomNum(dist, value1, value2);
                        insect.HostDefoliationByYear[site][PlugIn.ModelCore.CurrentTime][suscIndex] = defoliation;
                    }
                    else
                    {
                        defoliation = insect.HostDefoliationByYear[site][PlugIn.ModelCore.CurrentTime][suscIndex];
                    }
                }
                else
                {
                    insect.HostDefoliationByYear[site].Add(PlugIn.ModelCore.CurrentTime, new Double[3] {
                        0.0, 0.0, 0.0
                    });
                    defoliation = Distribution.GenerateRandomNum(dist, value1, value2);
                    //if (meanNeighborhoodDefoliation <= 0.0 && defoliation > 0.0)
                    //     PlugIn.ModelCore.UI.WriteLine("THAT'S WEIRD!!  meanNeighborhoodDefoliation = {0}, defoliation={1}.", meanNeighborhoodDefoliation, defoliation);

                    insect.HostDefoliationByYear[site][PlugIn.ModelCore.CurrentTime][suscIndex] = defoliation;
                }


                // Alternatively, allow defoliation to vary even among cohorts and species with
                // the same susceptibility.
                if (defoliation > 1.0 || defoliation < 0)
                {
                    PlugIn.ModelCore.UI.WriteLine("DEFOLIATION TOO BIG or SMALL:  {0}, {1}, {2}, {3}.", dist, value1, value2, defoliation);
                    throw new ApplicationException("Error: New defoliation is not between 1.0 and 0.0");
                }

                // PlugIn.ModelCore.UI.WriteLine("Cohort age={0}, species={1}, suscIndex={2}, defoliation={3}.", cohort.Age, cohort.Species.Name, (suscIndex -1), defoliation);
                // For first insect in a given year, actual defoliation equals the potential defoliation drawn from insect distributions.
                // For second insect in a given year, actual defoliation can only be as high as the amount of canopy foliage left by first insect.
                // This change makes sure next year's neighborhoodDefoliation will reflect actual defoliation, rather than "potential" defoliation.
                // It should also ensure that the sum of defoliation maps for all insects adds up to 1 for a given year.

                weightedDefoliation = (Math.Min((1 - totalDefoliation), defoliation) * ((double)cohort.Biomass / (double)siteBiomass));
                // PlugIn.ModelCore.UI.WriteLine("Cohort age={0}, species={1}, suscIndex={2}, cohortDefoliation={3}, weightedDefolation={4}.", cohort.Age, cohort.Species.Name, (suscIndex+1), defoliation, weightedDefoliation);

                insect.ThisYearDefoliation[site] += weightedDefoliation;
                totalDefoliation += defoliation;
            }

            if (totalDefoliation > 1.0)  // Cannot exceed 100% defoliation
            {
                totalDefoliation = 1.0;
            }

            if (totalDefoliation > 1.1 || totalDefoliation < 0)
            {
                PlugIn.ModelCore.UI.WriteLine("Cohort Total Defoliation = {0:0.00}.  Site R/C={1}/{2}.", totalDefoliation, site.Location.Row, site.Location.Column);
                throw new ApplicationException("Error: Total Defoliation is not between 1.1 and 0.0");
            }


            return(totalDefoliation);
        }
Esempio n. 5
0
        //---------------------------------------------------------------------
        // This method replaces the delegate method.  It is called every year when
        // ACT_ANPP is calculated, for each cohort.  Therefore, this method is operating at
        // an ANNUAL time step and separate from the normal extension time step.
        //static int LastYearDefoliationCohortWasCalled = int.MinValue; // Add this for error capture. Ensure timestep for succession is annual. Previous method doesn't work with new biomass library.
        //static bool TimeStepChecked = false;

        public static double DefoliateCohort(ActiveSite site,
                                             ISpecies species,
                                             int cohortBiomass,
                                             int siteBiomass)
        {
            //    if (TimeStepChecked == false)
            //    {
            //       if (LastYearDefoliationCohortWasCalled > 0 && PlugIn.ModelCore.CurrentTime - LastYearDefoliationCohortWasCalled > 1)
            //            {
            //                throw new System.Exception("  CAUTION! If using Biomass Insects, Succession Extension should be operating at an ANNUAL time step.");
            //            }
            //        LastYearDefoliationCohortWasCalled = PlugIn.ModelCore.CurrentTime;
            //         TimeStepChecked = true;
            //    }

            //public static double DefoliateCohort(ICohort cohort, ActiveSite site, int siteBiomass)
            //{

            // PlugIn.ModelCore.UI.WriteLine("   Calculating insect defoliation...");

            int    sppIndex         = species.Index;
            double totalDefoliation = 0.0;

            foreach (IInsect insect in manyInsect)
            //foreach (IInsect insect in PlugIn.ManyInsect) // This the construction used by GrowthReduction and PartialDisturbance, why was above different? Defoliation seems to calculate out of order...
            {
                if (!insect.ActiveOutbreak)
                {
                    continue;
                }

                double defoliation         = 0.0;
                double weightedDefoliation = 0.0;
                int    suscIndex           = insect.SppTable[sppIndex].Susceptibility - 1;

                if (suscIndex < 0)
                {
                    suscIndex = 0;
                }

                // Get the Neighborhood Mean Defoliation surrounding current site.
                //This needs to be reset to zero here at the start of a new outbreak.
                double meanNeighborhoodDefoliation = 0.0;
                int    neighborCnt = 0;

                // If it is the first year, the neighborhood defoliation
                // will have been initialized in Outbreak.InitializeDefoliationPatches

                if (insect.NeighborhoodDefoliation[site] > 0)
                {
                    // PlugIn.ModelCore.UI.WriteLine("   First Year of Defoliation:  Using initial patch defo={0:0.00}.", SiteVars.NeighborhoodDefoliation[site]);
                    meanNeighborhoodDefoliation = insect.NeighborhoodDefoliation[site];
                }

                // If not the first year, calculate mean neighborhood defoliation based on the
                // previous year.
                else
                {
                    double sumNeighborhoodDefoliation = 0.0;

                    // PlugIn.ModelCore.UI.WriteLine("Look at the Neighbors... ");
                    foreach (RelativeLocation relativeLoc in insect.Neighbors)
                    {
                        Site neighbor = site.GetNeighbor(relativeLoc);
                        if (neighbor != null && neighbor.IsActive)
                        {
                            neighborCnt++;
                            sumNeighborhoodDefoliation += insect.LastYearDefoliation[neighbor];
                        }
                    }

                    if (neighborCnt > 0.0)
                    {
                        meanNeighborhoodDefoliation = sumNeighborhoodDefoliation / (double)neighborCnt;
                    }
                }  //endif

                if (meanNeighborhoodDefoliation > 1.0 || meanNeighborhoodDefoliation < 0)
                {
                    PlugIn.ModelCore.UI.WriteLine("MeanNeighborhoodDefoliation={0}; NeighborCnt={1}.", meanNeighborhoodDefoliation, neighborCnt);
                    throw new ApplicationException("Error: Mean Neighborhood Defoliation is not between 1.0 and 0.0");
                }

                // First assume that there are no neighbors whatsoever:
                DistributionType dist   = insect.SusceptibleTable[suscIndex].Distribution_0.Name;
                double           value1 = insect.SusceptibleTable[suscIndex].Distribution_0.Value1;
                double           value2 = insect.SusceptibleTable[suscIndex].Distribution_0.Value2;

                if (meanNeighborhoodDefoliation <= 1.0 && meanNeighborhoodDefoliation >= 0.8)
                {
                    dist   = insect.SusceptibleTable[suscIndex].Distribution_80.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_80.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_80.Value2;
                }
                else if (meanNeighborhoodDefoliation < 0.8 && meanNeighborhoodDefoliation >= 0.6)
                {
                    dist   = insect.SusceptibleTable[suscIndex].Distribution_60.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_60.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_60.Value2;
                }
                else if (meanNeighborhoodDefoliation < 0.6 && meanNeighborhoodDefoliation >= 0.4)
                {
                    dist   = insect.SusceptibleTable[suscIndex].Distribution_40.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_40.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_40.Value2;
                }
                else if (meanNeighborhoodDefoliation < 0.4 && meanNeighborhoodDefoliation >= 0.2)
                {
                    dist   = insect.SusceptibleTable[suscIndex].Distribution_20.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_20.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_20.Value2;
                }
                else if (meanNeighborhoodDefoliation < 0.2 && meanNeighborhoodDefoliation >= 0.0)
                {
                    dist   = insect.SusceptibleTable[suscIndex].Distribution_0.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_0.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_0.Value2;
                }

                // Next, draw defoliation value and apply to all cohorts of the same susceptibility class on current site.
                // If a defoliation has happened on the site...
                if (insect.HostDefoliationByYear[site].ContainsKey(PlugIn.ModelCore.CurrentTime))
                {
                    // These cases depend on Beta distribution always drawing a positive, non-zero value even if very small. Trying to zero-out defoliation here causes problems.
                    // If no value for defoliation of this susceptibility class has been drawn yet, draw one here from correct distribution...
                    if (insect.HostDefoliationByYear[site][PlugIn.ModelCore.CurrentTime][suscIndex] <= 0.00000000)
                    {
                        defoliation = Distribution.GenerateRandomNum(dist, value1, value2);
                        // Need this here and in each else statement: To correct for error reporting Mean Neighborhood Defoliation < 0. Bug arises when tested with 3+ insects.
                        // Looping over multiple insects in same year could produce totalDefoliation > 1. If this year's total defoliation = 1, next insect can't defoliate more.
                        defoliation = Math.Min((1 - totalDefoliation), defoliation);
                        defoliation = Math.Max(0.0001, defoliation);
                        insect.HostDefoliationByYear[site][PlugIn.ModelCore.CurrentTime][suscIndex] = defoliation;
                    }
                    //If a value for this susceptibility class already exists, use already drawn value.
                    else
                    {
                        defoliation = insect.HostDefoliationByYear[site][PlugIn.ModelCore.CurrentTime][suscIndex];
                    }
                    // Not sure why below is needed, but somehow higher defoliation is getting assigned to insect.HostDefoliationByYear[site][suscIndex] with 3rd insect.
                    defoliation = Math.Min((1 - totalDefoliation), defoliation);
                    defoliation = Math.Max(0.0001, defoliation);
                    insect.HostDefoliationByYear[site][PlugIn.ModelCore.CurrentTime][suscIndex] = defoliation;
                    //if (defoliation <= 0.0)
                    //PlugIn.ModelCore.UI.WriteLine("THAT'S WEIRD!!  meanNeighborhoodDefoliation = {0}, defoliation={1}.", meanNeighborhoodDefoliation, defoliation);
                }
                // Else if no defoliation for this SITE has been drawn yet, draw the SITE-LEVEL defoliation value...then draw and assign the SUSCEPTIBILITY CLASS value.
                else
                {
                    insect.HostDefoliationByYear[site].Add(PlugIn.ModelCore.CurrentTime, new Double[3] {
                        0.0, 0.0, 0.0
                    });
                    defoliation = Distribution.GenerateRandomNum(dist, value1, value2);
                    // Need this here and in each else statement: To correct for error reporting Mean Neighborhood Defoliation < 0. Bug arises when tested with 3+ insects.
                    // Looping over multiple insects in same year could produce totalDefoliation > 1. If this year's total defoliation = 1, next insect can't defoliate more.
                    defoliation = Math.Min((1 - totalDefoliation), defoliation);
                    defoliation = Math.Max(0.0001, defoliation);
                    //if (meanNeighborhoodDefoliation <= 0.0 && defoliation > 0.0)
                    //     PlugIn.ModelCore.UI.WriteLine("THAT'S WEIRD!!  meanNeighborhoodDefoliation = {0}, defoliation={1}.", meanNeighborhoodDefoliation, defoliation);
                    insect.HostDefoliationByYear[site][PlugIn.ModelCore.CurrentTime][suscIndex] = defoliation;
                }


                // Alternatively, allow defoliation to vary even among cohorts and species with
                // the same susceptibility.
                if (defoliation > 1.0 || defoliation < 0)
                {
                    PlugIn.ModelCore.UI.WriteLine("DEFOLIATION TOO BIG or SMALL:  {0}, {1:0.00000000}, {2:0.000000000}, {3:0.000000000}, {4:0.000000000},{5:0.000000000}.", dist, value1, value2, defoliation, meanNeighborhoodDefoliation, totalDefoliation);
                    throw new ApplicationException("Error: New defoliation is not between 1.0 and 0.0");
                }

                // PlugIn.ModelCore.UI.WriteLine("Cohort age={0}, species={1}, suscIndex={2}, defoliation={3}.", cohort.Age, cohort.Species.Name, (suscIndex -1), defoliation);
                // For first insect in a given year, actual defoliation equals the potential defoliation drawn from insect distributions.
                // For second insect in a given year, actual defoliation can only be as high as the amount of canopy foliage left by first insect.
                // This change makes sure next year's neighborhoodDefoliation will reflect actual defoliation, rather than "potential" defoliation.
                // It should also ensure that the sum of defoliation maps for all insects adds up to 1 for a given year.

                // Maybe need this here: To correct for error reporting Mean Neighborhood Defoliation < 0.
                // Looping over multiple insects in same year could produce totalDefoliation > 1. If this year's total defoliation = 1, next insect can't defoliate more.
                // This needs to be moved within each if-else statement above before assigning defoliation to HostDefoliationByYear...Doing now...
                //defoliation = Math.Min((1 - totalDefoliation),defoliation);
                // Then:

                weightedDefoliation = defoliation * ((double)cohortBiomass / (double)siteBiomass);
                //weightedDefoliation = (Math.Min((1 - totalDefoliation), defoliation) * ((double)cohortBiomass / (double)siteBiomass));

                // PlugIn.ModelCore.UI.WriteLine("Cohort age={0}, species={1}, suscIndex={2}, cohortDefoliation={3}, weightedDefolation={4}.", cohort.Age, cohort.Species.Name, (suscIndex+1), defoliation, weightedDefoliation);

                insect.ThisYearDefoliation[site] += weightedDefoliation;
                totalDefoliation += defoliation;

                if (totalDefoliation > 1.1)
                {
                    PlugIn.ModelCore.UI.WriteLine("suscIndex={0}, cohortDefoliation={1}, weightedDefolation={2},insect={3}, totalDefoliation={4}.", (suscIndex + 1), defoliation, weightedDefoliation, insect.Name, totalDefoliation);
                }
            }

            if (totalDefoliation > 1.0)  // Cannot exceed 100% defoliation.
            {
                totalDefoliation = 1.0;
            }

            if (totalDefoliation > 1.0 || totalDefoliation < 0)
            {
                PlugIn.ModelCore.UI.WriteLine("Cohort Total Defoliation = {0:0.00}.  Site R/C={1}/{2}.", totalDefoliation, site.Location.Row, site.Location.Column);
                throw new ApplicationException("Error: Total Defoliation is not between 1.0 and 0.0");
            }


            return(totalDefoliation);
        }
Esempio n. 6
0
        //---------------------------------------------------------------------
        // Initialize landscape with patches of defoliation during the first year
        public static void InitializeDefoliationPatches(IInsect insect)
        {
            PlugIn.ModelCore.UI.WriteLine("   Initializing Defoliation Patches... ");
            insect.InitialOutbreakProb.ActiveSiteValues = 0.0;
            insect.Disturbed.ActiveSiteValues           = false;

            foreach (ActiveSite site in PlugIn.ModelCore.Landscape)
            {
                double suscIndexSum   = 0.0;
                double sumBio         = 0.0;
                double protectBiomass = 0.0;

                Landis.Library.BiomassCohorts.ISiteCohorts siteCohorts = SiteVars.Cohorts[site];

                foreach (ISpeciesCohorts speciesCohorts in siteCohorts)
                {
                    foreach (ICohort cohort in speciesCohorts)
                    {
                        int sppSuscIndex = insect.Susceptibility[cohort.Species];
                        if (sppSuscIndex == 4)
                        {
                            protectBiomass += cohort.Biomass;
                            sppSuscIndex    = 3;
                        }
                        suscIndexSum += cohort.Biomass * (sppSuscIndex);
                        sumBio       += cohort.Biomass;
                    }
                }


                // If no biomass, no chance of defoliation, go to the next site.
                if (suscIndexSum <= 0 || sumBio <= 0)
                {
                    insect.InitialOutbreakProb[site] = 0.0;
                    continue;
                }

                int    siteSuscIndex = (int)Math.Round(suscIndexSum / sumBio) - 1;
                double protectProp   = protectBiomass / sumBio;

                if (siteSuscIndex > 2.0 || siteSuscIndex < 0)
                {
                    PlugIn.ModelCore.UI.WriteLine("SuscIndex < 0 || > 2.  Site R/C={0}/{1},suscIndex={2},suscIndexSum={3},sumBio={4}.", site.Location.Row, site.Location.Column, siteSuscIndex, suscIndexSum, sumBio);
                    throw new ApplicationException("Error: SuscIndex is not between 2.0 and 0.0");
                }
                // Assume that there are no neighbors whatsoever:
                DistributionType dist = insect.SusceptibleTable[siteSuscIndex].Distribution_80.Name;


                //PlugIn.ModelCore.UI.WriteLine("suscIndex={0},suscIndexSum={1},cohortBiomass={2}.", suscIndex,suscIndexSum,sumBio);
                double value1 = insect.SusceptibleTable[siteSuscIndex].Distribution_80.Value1;
                double value2 = insect.SusceptibleTable[siteSuscIndex].Distribution_80.Value2;

                double probability = Distribution.GenerateRandomNum(dist, value1, value2);

                // Account for protective effect of Susc Class 4
                if (protectProp > 0)
                {
                    double slope         = 1.0;
                    double protectReduce = 1 - (protectProp * slope);
                    if (protectReduce > 1)
                    {
                        protectReduce = 1;
                    }
                    if (protectReduce < 0)
                    {
                        protectReduce = 0;
                    }
                    probability = probability * protectReduce;
                }
                if (probability > 1.0 || probability < 0)
                {
                    PlugIn.ModelCore.UI.WriteLine("Initial Defoliation Probility < 0 || > 1.  Site R/C={0}/{1}.", site.Location.Row, site.Location.Column);
                    throw new ApplicationException("Error: Probability is not between 1.0 and 0.0");
                }

                insect.InitialOutbreakProb[site] = probability; // This probability reflects the protective effects
                //PlugIn.ModelCore.UI.WriteLine("Susceptiblity index={0}.  Outbreak Probability={1:0.00}.  R/C={2}/{3}.", suscIndex, probability, site.Location.Row, site.Location.Column);
            }

            foreach (ActiveSite site in PlugIn.ModelCore.Landscape)
            {
                //get a random site from the stand
                double randomNum  = PlugIn.ModelCore.GenerateUniform();
                double randomNum2 = PlugIn.ModelCore.GenerateUniform();

                //Create random variability in outbreak area within a simulation so outbreaks are more variable.
                double initialAreaCalibratorRandomNum = (randomNum2 - 0.5) * insect.InitialPatchOutbreakSensitivity / 2;

                //Start spreading!
                if (randomNum < insect.InitialOutbreakProb[site] * (insect.InitialPatchOutbreakSensitivity + initialAreaCalibratorRandomNum))
                //if(randomNum < SiteVars.InitialOutbreakProb[site] * insect.InitialPatchOutbreakSensitivity)
                {
                    //start with this site (if it's active)
                    ActiveSite currentSite = site;

                    //queue to hold sites to defoliate
                    Queue <ActiveSite> sitesToConsider = new Queue <ActiveSite>();

                    //put initial site on queue
                    sitesToConsider.Enqueue(currentSite);

                    DistributionType dist       = insect.InitialPatchDistr;
                    double           targetArea = Distribution.GenerateRandomNum(dist, insect.InitialPatchValue1, insect.InitialPatchValue2);

                    //PlugIn.ModelCore.UI.WriteLine("  Target Patch Area={0:0.0}.", targetArea);
                    double areaSelected = 0.0;

                    //loop through stand, defoliating patches of size target area
                    while (sitesToConsider.Count > 0 && areaSelected < targetArea)
                    {
                        currentSite = sitesToConsider.Dequeue();

                        // Because this is the first year, neighborhood defoliaiton is given a value.
                        // The value is used in Defoliate.DefoliateCohort()
                        insect.NeighborhoodDefoliation[currentSite] = insect.InitialOutbreakProb[currentSite];
                        areaSelected += PlugIn.ModelCore.CellArea;
                        insect.Disturbed[currentSite] = true;

                        //Next, add site's neighbors to the list of
                        //sites to consider.
                        //loop through the site's neighbors enqueueing all the good ones.

                        //double maxNeighborProb = 0.0;
                        //Site maxNeighbor = currentSite;
                        //bool foundNewNeighbor = false;

                        foreach (RelativeLocation loc in all_neighbor_locations)
                        {
                            Site neighbor = currentSite.GetNeighbor(loc);

                            //get a neighbor site (if it's non-null and active)
                            if (neighbor != null &&
                                neighbor.IsActive &&
                                !sitesToConsider.Contains((ActiveSite)neighbor) &&
                                !insect.Disturbed[neighbor])
                            {
                                //insect.Disturbed[currentSite] = true;
                                randomNum = PlugIn.ModelCore.GenerateUniform();

                                /*if (SiteVars.InitialOutbreakProb[neighbor] > maxNeighborProb)
                                 * {
                                 *  maxNeighbor = currentSite.GetNeighbor(loc);
                                 *  maxNeighborProb = SiteVars.InitialOutbreakProb[neighbor];
                                 *  foundNewNeighbor = true;
                                 * }*/

                                //check if it's a valid neighbor:
                                if (insect.InitialOutbreakProb[neighbor] * insect.InitialPatchShapeCalibrator > randomNum)
                                {
                                    sitesToConsider.Enqueue((ActiveSite)neighbor);
                                }
                            }
                        }

                        //if(foundNewNeighbor)
                        //    sitesToConsider.Enqueue((ActiveSite) maxNeighbor);
                    }

                    //PlugIn.ModelCore.UI.WriteLine("   Initial Patch Area Selected={0:0.0}.", areaSelected);
                }
            }
        }