public static void InitializeMetadata(int Timestep, string MapFileName, string eventLogName)
        {
            ScenarioReplicationMetadata scenRep = new ScenarioReplicationMetadata()
            {
                RasterOutCellArea = PlugIn.ModelCore.CellArea,
                TimeMin           = PlugIn.ModelCore.StartTime,
                TimeMax           = PlugIn.ModelCore.EndTime,
            };

            Extension = new ExtensionMetadata(PlugIn.ModelCore)
                        //Extension = new ExtensionMetadata()
            {
                Name         = PlugIn.ExtensionName,
                TimeInterval = Timestep,
                ScenarioReplicationMetadata = scenRep
            };

            //---------------------------------------
            //          table outputs:
            //---------------------------------------

            CreateDirectory(eventLogName);
            PlugIn.eventLog = new MetadataTable <EventsLog>(eventLogName);
            //PlugIn.eventLog = new MetadataTable<EventsLog>("Harvest-event-log.csv");
            //PlugIn.summaryLog = new MetadataTable<SummaryLog>("Harvest-summary-log.csv");

            PlugIn.ModelCore.UI.WriteLine("   Generating event table...");
            OutputMetadata tblOut_events = new OutputMetadata()
            {
                Type      = OutputType.Table,
                Name      = "EventLog",
                FilePath  = PlugIn.eventLog.FilePath,
                Visualize = false,
            };

            tblOut_events.RetriveFields(typeof(EventsLog));
            Extension.OutputMetadatas.Add(tblOut_events);

            //---------------------------------------
            //          map outputs:
            //---------------------------------------

            //OutputMetadata mapOut_BiomassRemoved = new OutputMetadata()
            //{
            //    Type = OutputType.Map,
            //    Name = "biomass removed",
            //    FilePath = @HarvestMapName,
            //    Map_DataType = MapDataType.Continuous,
            //    Map_Unit = FieldUnits.Mg_ha,
            //    Visualize = true,
            //};
            //Extension.OutputMetadatas.Add(mapOut_BiomassRemoved);


            OutputMetadata mapOut_biomassRemoved = new OutputMetadata()
            {
                Type         = OutputType.Map,
                Name         = "BiomassRemoved",
                FilePath     = MapNames.ReplaceTemplateVars(MapFileName, Timestep),
                Map_DataType = MapDataType.Continuous,
                Visualize    = true,
                //Map_Unit = "categorical",
            };

            Extension.OutputMetadatas.Add(mapOut_biomassRemoved);

            //---------------------------------------
            MetadataProvider mp = new MetadataProvider(Extension);

            mp.WriteMetadataToXMLFile("Metadata", Extension.Name, Extension.Name);
        }
        //---------------------------------------------------------------------
        ///<summary>
        /// Run the plug-in at a particular timestep.
        ///</summary>
        public override void Run()
        {
            modelCore.UI.WriteLine("   Processing Drought Disturbance ...");

            double totalRemoved = 0;
            int    totalKilled  = 0;
            double dy_sum       = 0;
            int    siteCount    = 0;

            double[] removedSpp      = new double[PlugIn.ModelCore.Species.Count];
            int[]    killedSpp       = new int[PlugIn.ModelCore.Species.Count];
            double[] extraRemovedSpp = new double[PlugIn.ModelCore.Species.Count];
            foreach (ISpecies species in PlugIn.ModelCore.Species)
            {
                removedSpp[species.Index]      = 0;
                killedSpp[species.Index]       = 0;
                extraRemovedSpp[species.Index] = 0;
            }

            foreach (ActiveSite site in PlugIn.ModelCore.Landscape)
            {
                double siteBioRemoved = 0;
                double dy             = SiteVars.DroughtYears[site];
                if (dy > dy_max)
                {
                    dy = dy_max;
                }
                dy_sum    += dy;
                siteCount += 1;
                if (dy > dy_min)
                {
                    // Sort Cohorts be decreasing age
                    List <ICohort> cohortList = new List <ICohort>();
                    foreach (ISpeciesCohorts speciesCohorts in SiteVars.Cohorts[site])
                    {
                        foreach (ICohort cohort in speciesCohorts)
                        {
                            cohortList.Add(cohort);
                        }
                    }
                    cohortList = cohortList.OrderByDescending(x => x.Age).ToList();


                    foreach (ISpecies species in PlugIn.ModelCore.Species)
                    {
                        double bioRemovedSpp      = removedSpp[species.Index];
                        int    cohortKilledSpp    = killedSpp[species.Index];
                        double extraBioRemovedSpp = extraRemovedSpp[species.Index];
                        // Calculate 95% CI of intercept and slope
                        double int_max   = parameters.Drought_Y[species] + (1.96 * parameters.Drought_YSE[species]);
                        double int_min   = parameters.Drought_Y[species] - (1.96 * parameters.Drought_YSE[species]);
                        double slope_max = parameters.Drought_B[species] + (1.96 * parameters.Drought_BSE[species]);
                        double slope_min = parameters.Drought_B[species] - (1.96 * parameters.Drought_BSE[species]);

                        // Calculate upper and lower CI predicted values
                        double maxPropMort   = int_max + slope_max * dy;
                        double minPropMort   = int_min + slope_min * dy;
                        double rangePropMort = maxPropMort - minPropMort;

                        int bioRemoved      = 0;
                        int cohortsKilled   = 0;
                        int extraRemoved    = 0;
                        int woodyRemoved    = 0;
                        int nonWoodyRemoved = 0;

                        if (rangePropMort > 0)
                        {
                            double Tbiomass        = 0;
                            double propLongev      = 0;
                            int    oldestCohortBio = 0;
                            //foreach (ISpeciesCohorts speciesCohorts in SiteVars.Cohorts[site])
                            //{
                            //foreach (ICohort cohort in speciesCohorts)
                            foreach (ICohort cohort in cohortList)
                            {
                                if (cohort.Species == species)
                                {
                                    Tbiomass += cohort.Biomass;
                                    if (((double)cohort.Age / (double)cohort.Species.Longevity) > propLongev)
                                    {
                                        propLongev      = (double)cohort.Age / (double)cohort.Species.Longevity;
                                        oldestCohortBio = cohort.Biomass;
                                    }
                                }
                            }
                            //}
                            if (Tbiomass > 0)
                            {
                                double predictPctMort   = (minPropMort + (rangePropMort * propLongev));
                                double backTransPctMort = predictPctMort;
                                double backTrans0       = 0;
                                if (parameters.BackTransform == "EXP")
                                {
                                    // Back-transform - EXP()
                                    backTransPctMort = Math.Exp(predictPctMort);
                                    if (parameters.IntCorrect == "Y")
                                    {
                                        backTrans0 = Math.Exp(parameters.Drought_Y[species]);
                                    }
                                }
                                else if (parameters.BackTransform == "SQUARE")
                                {
                                    //Back-transform - Square
                                    backTransPctMort = Math.Pow(predictPctMort, 2);
                                    if (parameters.IntCorrect == "Y")
                                    {
                                        backTrans0 = Math.Pow(parameters.Drought_Y[species], 2);
                                    }
                                }
                                // Account for timestep
                                double actualPctMort = (backTransPctMort - backTrans0) * Timestep;
                                //double actualPctMort = predictPctMort * Timestep;
                                actualPctMort = Math.Min(actualPctMort, 100);
                                //Convert to proportion
                                double actualPropMort = actualPctMort / 100.0;

                                // Calculate biomass removed
                                bioRemoved = (int)Math.Round(Tbiomass * actualPropMort);

                                /*
                                 * // Drought kills oldest cohort 50% of time
                                 * if (bioRemoved < oldestCohortBio)
                                 * {
                                 *  int oldBioDiff = oldestCohortBio - bioRemoved;
                                 *  if (PlugIn.ModelCore.GenerateUniform() > 0.5)
                                 *      bioRemoved += oldBioDiff;
                                 *  else
                                 *  {
                                 *      bioRemoved -= oldBioDiff;
                                 *      if (bioRemoved < 0)
                                 *          bioRemoved = 0;
                                 *  }
                                 * }
                                 */

                                int remainBioRem = bioRemoved;

                                //Remove biomass from cohorts, starting with the oldest
                                //foreach (ISpeciesCohorts speciesCohorts in SiteVars.Cohorts[site])
                                //{
                                //foreach (ICohort cohort in speciesCohorts)
                                foreach (ICohort cohort in cohortList)
                                {
                                    if (cohort.Species == species)
                                    {
                                        if (remainBioRem > 0)
                                        {
                                            int nonWoody = cohort.ComputeNonWoodyBiomass(site);
                                            int woody    = (cohort.Biomass - nonWoody);
                                            if (cohort.Biomass > remainBioRem)
                                            {
                                                if ((remainBioRem / cohort.Biomass) > 0.9)
                                                {
                                                    extraRemoved = (cohort.Biomass - remainBioRem);
                                                    remainBioRem = cohort.Biomass;
                                                    cohortsKilled++;
                                                }
                                                else
                                                {
                                                    double nonWoodRatio = (double)nonWoody / (double)woody;
                                                    nonWoody = (int)Math.Round(remainBioRem * nonWoodRatio);
                                                    woody    = remainBioRem - nonWoody;
                                                }

                                                PartialDisturbance.RecordBiomassReduction(cohort, remainBioRem);
                                                remainBioRem     = 0;
                                                woodyRemoved    += woody;
                                                nonWoodyRemoved += nonWoody;
                                            }
                                            else
                                            {
                                                remainBioRem = remainBioRem - cohort.Biomass;
                                                PartialDisturbance.RecordBiomassReduction(cohort, cohort.Biomass);
                                                cohortsKilled++;
                                                woodyRemoved    += woody;
                                                nonWoodyRemoved += nonWoody;
                                            }
                                        }
                                    }
                                }
                            }
                            //}
                        }
                        siteBioRemoved += bioRemoved;
                        bioRemovedSpp  += bioRemoved;
                        Landis.Extension.Succession.Biomass.ForestFloor.AddWoody(woodyRemoved, species, site);
                        Landis.Extension.Succession.Biomass.ForestFloor.AddLitter(nonWoodyRemoved, species, site);
                        cohortKilledSpp               += cohortsKilled;
                        extraBioRemovedSpp            += extraRemoved;
                        removedSpp[species.Index]      = bioRemovedSpp;
                        killedSpp[species.Index]       = cohortKilledSpp;
                        extraRemovedSpp[species.Index] = extraBioRemovedSpp;
                        totalKilled += cohortsKilled;
                    }
                    PartialDisturbance.ReduceCohortBiomass(site);
                }
                SiteVars.DroughtBioRemoved[site] = (ushort)siteBioRemoved;
                totalRemoved += siteBioRemoved;
            }
            double avg_dy = dy_sum / siteCount;

            int i = 0;

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

            el.Time           = ModelCore.CurrentTime;
            el.AverageDrought = avg_dy;
            el.BiomassRemoved = new double[PlugIn.ModelCore.Species.Count];
            foreach (ISpecies species in PlugIn.ModelCore.Species)
            {
                el.BiomassRemoved[i] = removedSpp[species.Index];
                i = i + 1;
            }
            i = 0;
            el.TotalBiomassRemoved  = totalRemoved;
            el.CohortsKilledSpecies = new int[PlugIn.ModelCore.Species.Count];
            foreach (ISpecies species in PlugIn.ModelCore.Species)
            {
                el.CohortsKilledSpecies[i] = killedSpp[species.Index];
                i = i + 1;
            }
            i = 0;
            el.TotalCohortsKilled = totalKilled;
            el.ExtraRemoved       = new double[PlugIn.ModelCore.Species.Count];
            foreach (ISpecies species in PlugIn.ModelCore.Species)
            {
                el.ExtraRemoved[i] = extraRemovedSpp[species.Index];
                i = i + 1;
            }
            eventLog.AddObject(el);
            eventLog.WriteToFile();

            //  Write Biomass Removed map
            string path = MapNames.ReplaceTemplateVars(mapNameTemplate, modelCore.CurrentTime);

            modelCore.UI.WriteLine("   Writing Drought Biomass Removed map to {0} ...", path);
            using (IOutputRaster <ShortPixel> outputRaster = modelCore.CreateRaster <ShortPixel>(path, modelCore.Landscape.Dimensions))
            {
                ShortPixel pixel = outputRaster.BufferPixel;
                foreach (Site site in modelCore.Landscape.AllSites)
                {
                    if (site.IsActive)
                    {
                        pixel.MapCode.Value = (short)(SiteVars.DroughtBioRemoved[site]);
                    }
                    else
                    {
                        //  Inactive site
                        pixel.MapCode.Value = 0;
                    }
                    outputRaster.WriteBufferPixel();
                }
            }
            // Modify establishment
            if (avg_dy >= dy_min)
            {
                foreach (ISpecies species in PlugIn.ModelCore.Species)
                {
                    double drought_Mod = 1.0;
                    if (parameters.Drought_Sens[species] == 2)
                    {
                        drought_Mod = 0.5;
                    }
                    else if (parameters.Drought_Sens[species] == 3)
                    {
                        drought_Mod = 0.0;
                    }
                    if (drought_Mod < 1)
                    {
                        foreach (IEcoregion ecoregion in PlugIn.ModelCore.Ecoregions)
                        {
                            Landis.Extension.Succession.Biomass.SpeciesData.EstablishModifier[species, ecoregion] *= drought_Mod;
                        }
                    }
                }
            }
            else
            {
                modelCore.UI.WriteLine("   Drought does not exceed threshold this timestep ...");
            }
        }