예제 #1
0
        //---------------------------------------------------------------------

        public AppliedRepeatHarvest(RepeatHarvest repeatHarvest,
                                    Percentage percentageToHarvest,
                                    Percentage percentStandsToHarvest,
                                    int beginTime,
                                    int endTime)
            : base(repeatHarvest,
                   percentageToHarvest,
                   percentStandsToHarvest,
                   beginTime,
                   endTime)
        {
            this.repeatHarvest = repeatHarvest;
            // tjs 2009.01.09
            hasBeenHarvested = false;
            if (repeatHarvest is SingleRepeatHarvest)
            {
                isMultipleRepeatHarvest = false;
                setAside = SetAsideForSingleHarvest;
            }
            else
            {
                isMultipleRepeatHarvest = true;
                setAside = SetAsideForMultipleHarvests;
            }
            this.reservedStands = new Queue <ReservedStand>();
            this.ActiveMgmtArea = null;
        }
예제 #2
0
 /// <summary>
 /// Creates a new instance.
 /// </summary>
 /// <param name="site">The prescription that just finished its repeat harvest</param>
 public Args(AppliedPrescription prescription, ManagementArea mgmtArea, uint repeatNumber, bool lastHarvest)
 {
     Prescription = prescription;
     MgmtArea     = mgmtArea;
     RepeatNumber = repeatNumber;
     LastHarvest  = lastHarvest;
 }
 /// <summary>
 /// Signals that a prescription is finished with a repeat step
 /// </summary>
 public static void OnRepeatHarvestFinished(object sender,
                                            AppliedPrescription prescription,
                                            ManagementArea mgmtArea,
                                            uint repeatNumber,
                                            bool lastHarvest)
 {
     if (RepeatPrescriptionFinishedEvent != null)
     {
         RepeatPrescriptionFinishedEvent(sender, new RepeatHarvestPrescriptionFinishedEvent.Args(prescription, mgmtArea, repeatNumber, lastHarvest));
     }
 }
예제 #4
0
        /// <summary>
        /// Reads the input map of management areas.
        /// </summary>
        /// <param name="path">
        /// Path to the map.
        /// </param>
        /// <param name="managementAreas">
        /// Management areas that have prescriptions applied to them.
        /// </param>
        public static void ReadMap(string path,
                                   IManagementAreaDataset managementAreas)
        {
            IInputRaster <UIntPixel> map;

            try {
                map = Model.Core.OpenRaster <UIntPixel>(path);
            }
            catch (FileNotFoundException) {
                string mesg = string.Format("Error: The file {0} does not exist", path);
                throw new System.ApplicationException(mesg);
            }

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

            List <uint> inactiveMgmtAreas = new List <uint>();

            using (map) {
                UIntPixel pixel = map.BufferPixel;
                foreach (Site site in Model.Core.Landscape.AllSites)
                {
                    map.ReadBufferPixel();
                    if (site.IsActive)
                    {
                        uint           mapCode  = pixel.MapCode.Value;
                        ManagementArea mgmtArea = managementAreas.Find(mapCode);
                        if (mgmtArea == null)
                        {
                            if (!inactiveMgmtAreas.Contains(mapCode))
                            {
                                inactiveMgmtAreas.Add(mapCode);
                            }
                        }
                        else
                        {
                            mgmtArea.OnMap = true;
                            SiteVars.ManagementArea[site] = mgmtArea;
                        }
                    }
                }
            }

            // Inform user about non-active areas: those that don't have any
            // applied prescriptions.
            if (inactiveMgmtAreas.Count > 0)
            {
                Model.Core.UI.WriteLine("   Inactive management areas: {0}",
                                        MapCodesToString(inactiveMgmtAreas));
            }
        }
예제 #5
0
        //---------------------------------------------------------------------

        /// <summary>
        /// A new Stand Object, given a map code
        /// </summary>
        public Stand(uint mapCode)
        {
            this.mapCode                   = mapCode;
            this.siteLocations             = new List <Location>();
            this.activeArea                = Model.Core.CellArea;
            this.mgmtArea                  = null;
            this.neighbors                 = new List <Stand>();
            this.ma_neighbors              = new List <Stand>(); //new list for neighbors not in this management area
            this.yearAgeComputed           = Model.Core.StartTime;
            this.setAsideUntil             = Model.Core.StartTime;
            this.timeLastHarvested         = -1;
            this.DamageTable               = new CohortCounts();
            this.rejectedPrescriptionNames = new List <string>();
        }
예제 #6
0
        //---------------------------------------------------------------------

        public void WriteLogEntry(ManagementArea mgmtArea, Stand stand)
        {
            int damagedSites = 0;
            int cohortsDamaged = 0;
            int cohortsKilled = 0;
            int standPrescriptionNumber = 0;
            double biomassRemoved = 0.0;
            double biomassRemovedPerHa = 0.0;
            //ModelCore.UI.WriteLine("BiomassHarvest:  PlugIn.cs: WriteLogEntry: mgmtArea {0}, Stand {1} ", mgmtArea.Prescriptions.Count, stand.MapCode);

            foreach (ActiveSite site in stand) {
                //set the prescription name for this site
                if (HarvestMgmtLib.SiteVars.Prescription[site] != null)
                {
                    standPrescriptionNumber = HarvestMgmtLib.SiteVars.Prescription[site].Number;
                    HarvestMgmtLib.SiteVars.PrescriptionName[site] = HarvestMgmtLib.SiteVars.Prescription[site].Name;
                    HarvestMgmtLib.SiteVars.TimeOfLastEvent[site] = modelCore.CurrentTime;
                }

                cohortsDamaged += SiteVars.CohortsPartiallyDamaged[site];
                cohortsKilled += HarvestMgmtLib.SiteVars.CohortsDamaged[site];


                if (SiteVars.CohortsPartiallyDamaged[site] > 0 || HarvestMgmtLib.SiteVars.CohortsDamaged[site] > 0)
                {
                    damagedSites++;

                    //Conversion from [g m-2] to [Mg ha-1] to [Mg]
                    biomassRemoved += SiteVars.BiomassRemoved[site] / 100.0 * modelCore.CellArea;
                }
            }

            totalSites[standPrescriptionNumber] += stand.SiteCount;
            totalDamagedSites[standPrescriptionNumber] += damagedSites;
            totalCohortsDamaged[standPrescriptionNumber] += cohortsDamaged;
            totalCohortsKilled[standPrescriptionNumber] += cohortsKilled;


            //csv string for log file, contains species kill count
            string species_count = "";
            foreach (ISpecies species in modelCore.Species) {
                int cohortCount = stand.DamageTable[species];
                species_count += string.Format("{0},", cohortCount);
                totalSpeciesCohorts[standPrescriptionNumber, species.Index] += cohortCount;
            }

            //now that the damage table for this stand has been recorded, clear it!!
            stand.ClearDamageTable();

            //write to log file:
            biomassRemovedPerHa = biomassRemoved / (double) damagedSites / modelCore.CellArea;

            if(biomassRemoved <= 0.0)
                return;

            log.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9:0.000},{10:0.000},{11},{12}{13}",
                          modelCore.CurrentTime,
                          mgmtArea.MapCode,
                          stand.PrescriptionName,
                          stand.MapCode,
                          stand.EventId,
                          stand.Age,
                          stand.HarvestedRank,
                          stand.SiteCount,
                          damagedSites,
                          biomassRemoved,  // Mg
                          biomassRemovedPerHa, // Mg/ha
                          cohortsDamaged,
                          cohortsKilled,
                          species_count);
        }
예제 #7
0
        //---------------------------------------------------------------------

        /// <summary>
        /// Adds a new management area to the dataset.
        /// </summary>
        public void Add(ManagementArea mgmtArea)
        {
            Require.ArgumentNotNull(mgmtArea);
            mgmtAreas[mgmtArea.MapCode] = mgmtArea;
        }
예제 #8
0
        //---------------------------------------------------------------------

        /// <summary>
        /// Reads harvest implementations: which prescriptions are applied to
        /// which management areas.
        /// </summary>
        protected void ReadHarvestImplementations(ManagementAreaDataset mgmtAreas,
                                                  List <Prescription> prescriptions)
        {
            ReadName(Names.HarvestImplementations);

            InputVar <ushort>     mgmtAreaMapCode  = new InputVar <ushort>("Mgmt Area");
            InputVar <string>     prescriptionName = new InputVar <string>("Prescription");
            InputVar <int>        beginTimeVar     = new InputVar <int>("Begin Time");
            InputVar <int>        endTimeVar       = new InputVar <int>("End Time");
            InputVar <Percentage> areaToHarvest    = new InputVar <Percentage>("Area To Harvest");

            while (!AtEndOfInput && CurrentName != Names.PrescriptionMaps)
            {
                StringReader currentLine = new StringReader(CurrentLine);

                //  Mgmt Area column
                ReadValue(mgmtAreaMapCode, currentLine);
                ushort         mapCode  = mgmtAreaMapCode.Value.Actual;
                ManagementArea mgmtArea = mgmtAreas.Find(mapCode);
                if (mgmtArea == null)
                {
                    //add the management area, and add it to the collection of management areas
                    mgmtArea = new ManagementArea(mapCode);
                    mgmtAreas.Add(mgmtArea);
                }

                //  Prescription column
                ReadValue(prescriptionName, currentLine);
                string       name         = prescriptionName.Value.Actual;
                Prescription prescription = prescriptions.Find(new MatchName(name).Predicate);
                if (prescription == null)
                {
                    throw new InputValueException(prescriptionName.Value.String,
                                                  prescriptionName.Value.String + " is an unknown prescription name");
                }



                //  Area to Harvest column
                ReadValue(areaToHarvest, currentLine);
                //get percentage to harvest (type Percentage ensures that it is in percent format)
                Percentage percentageToHarvest = areaToHarvest.Value.Actual;
                //check for valid percentage
                if (percentageToHarvest <= 0.0 || percentageToHarvest > 1.0)
                {
                    throw new InputValueException(areaToHarvest.Value.String,
                                                  "Percentage must be between 0% and 100%");
                }

                //  Begin Time and End Time columns
                //  They are optional, so the possibilities are:
                //
                //          Begin Time   End Time
                //          ----------   --------
                //      1)   present     present
                //      2)   present     missing
                //      3)   missing     missing

                //  The default values for the starting and ending times for
                //  an applied prescription.
                int beginTime = scenarioStart;
                int endTime   = scenarioEnd;

                TextReader.SkipWhitespace(currentLine);
                if (currentLine.Peek() != -1)
                {
                    ReadValue(beginTimeVar, currentLine);
                    beginTime = beginTimeVar.Value.Actual;
                    if (beginTime < scenarioStart)
                    {
                        throw new InputValueException(beginTimeVar.Value.String,
                                                      string.Format("Year {0} is before the scenario start year ({1})",
                                                                    beginTimeVar.Value.String,
                                                                    scenarioStart));
                    }
                    if (beginTime > scenarioEnd)
                    {
                        //throw new InputValueException(beginTimeVar.Value.String,
                        //                              string.Format("Year {0} is after the scenario' end year ({1})",
                        //                                            beginTimeVar.Value.String,
                        //                                            scenarioEnd));
                        string        line1    = string.Format("   NOTE: Begin year {0} is after the scenario' end year {1}", beginTimeVar.Value.String, scenarioEnd);
                        string        line2    = string.Format("         on line {0} of the harvest input file...", LineNumber);
                        List <string> noteList = new List <string>();
                        noteList.Add(line1);
                        noteList.Add(line2);
                        parserNotes.Add(noteList);
                    }

                    TextReader.SkipWhitespace(currentLine);
                    if (currentLine.Peek() != -1)
                    {
                        ReadValue(endTimeVar, currentLine);
                        endTime = endTimeVar.Value.Actual;
                        if (endTime < beginTime)
                        {
                            throw new InputValueException(endTimeVar.Value.String,
                                                          string.Format("Year {0} is before the Begin Time ({1})",
                                                                        endTimeVar.Value.String,
                                                                        beginTimeVar.Value.String));
                        }
                        if (endTime > scenarioEnd)
                        {
                            //    throw new InputValueException(endTimeVar.Value.String,
                            //                                  string.Format("Year {0} is after the scenario' end year ({1})",
                            //                                                endTimeVar.Value.String,
                            //                                                scenarioEnd));

                            string        line1    = string.Format("   NOTE: End Year {0} is after the scenario' end year {1}", endTimeVar.Value.String, scenarioEnd);
                            string        line2    = string.Format("         on line {0} of the harvest input file...", LineNumber);
                            List <string> noteList = new List <string>();
                            noteList.Add(line1);
                            noteList.Add(line2);
                            parserNotes.Add(noteList);
                        }

                        CheckNoDataAfter("the " + endTimeVar.Name + " column",
                                         currentLine);
                    }
                }


                //if the perscription has already been applied to this management area
                //NOTE: .IsApplied has been modified, and this has been moved to AFTER the
                //begin and end times are founded.
                if (mgmtArea.IsApplied(prescriptionName.Value.String, beginTime, endTime))
                {
                    throw new InputValueException(prescriptionName.Value.String,
                                                  "Prescription {0} has already been applied to management area {1} with begin time = {2} and end time = {3}",
                                                  prescriptionName.Value.String, mgmtArea.MapCode, beginTime, endTime);
                }

                //begin applying prescription to this management area
                mgmtArea.ApplyPrescription(prescription,
                                           percentageToHarvest,
                                           beginTime,
                                           endTime);



                CheckNoDataAfter("the " + prescriptionName.Name + " column",
                                 currentLine);
                GetNextLine();
            }
        }
예제 #9
0
        //---------------------------------------------------------------------

        public void WriteLogEntry(ManagementArea mgmtArea, Stand stand)
        {
            int damagedSites = 0;
            int cohortsDamaged = 0;
            int cohortsKilled = 0;
            int standPrescriptionNumber = 0;
            double biomassRemoved = 0.0;
            double biomassRemovedPerHa = 0.0;

            foreach (ActiveSite site in stand)
            {
                //set the prescription name for this site
                if (HarvestMgmtLib.SiteVars.Prescription[site] != null)
                {
                    standPrescriptionNumber = HarvestMgmtLib.SiteVars.Prescription[site].Number;
                    HarvestMgmtLib.SiteVars.PrescriptionName[site] = HarvestMgmtLib.SiteVars.Prescription[site].Name;
                    HarvestMgmtLib.SiteVars.TimeOfLastEvent[site] = modelCore.CurrentTime;
                }

                cohortsDamaged += SiteVars.CohortsPartiallyDamaged[site];
                cohortsKilled += HarvestMgmtLib.SiteVars.CohortsDamaged[site];


                if (SiteVars.CohortsPartiallyDamaged[site] > 0 || HarvestMgmtLib.SiteVars.CohortsDamaged[site] > 0)
                {
                    damagedSites++;

                    //Conversion from [g m-2] to [Mg]
                    biomassRemoved += SiteVars.BiomassRemoved[site] / 100.0 * modelCore.CellArea;
                }
            }
            totalSites[standPrescriptionNumber] += stand.SiteCount;
            totalDamagedSites[standPrescriptionNumber] += damagedSites;
            totalCohortsDamaged[standPrescriptionNumber] += cohortsDamaged;
            totalCohortsKilled[standPrescriptionNumber] += cohortsKilled;

            //int array for metadata, contains species harvest count
            int[] species_count = new int[modelCore.Species.Count];

            //if this is the right species match, add it's count to the csv string
            foreach (ISpecies species in modelCore.Species)
            {
                //bool assigned = false;
                //loop through dictionary of species kill count
                //foreach (KeyValuePair<string, int> kvp in stand.DamageTable)
                //{
                //    if (species.Name == kvp.Key)
                //    {
                //        assigned = true;
                //        species_count[species.Index] += kvp.Value;
                //    }
                //}
                //if (!assigned)
                //{
                //    //put a 0 there if it's not assigned (because none were found in the dictionary)
                //    species_count[species.Index] = 0;
                //}
                //totalSpeciesCohorts[standPrescriptionNumber, species.Index] += species_count[species.Index];

                int cohortCount = stand.DamageTable[species];
                species_count[species.Index] = cohortCount;
                totalSpeciesCohorts[standPrescriptionNumber, species.Index] += cohortCount;
            }

            //now that the damage table for this stand has been recorded, clear it!!
            stand.ClearDamageTable();

            //write to log file:
            biomassRemovedPerHa = biomassRemoved / (double)damagedSites / modelCore.CellArea;

            if (biomassRemoved <= 0.0)
                return;

            eventLog.Clear();
            EventsLog el = new EventsLog();
            el.Time = modelCore.CurrentTime;
            el.ManagementArea = mgmtArea.MapCode;
            el.Prescription = stand.PrescriptionName;
            el.StandMapCode = stand.MapCode;
            el.EventID = stand.EventId;
            el.StandAge = stand.Age;
            el.StandRank = stand.HarvestedRank;
            el.StandSiteCount = stand.SiteCount;
            el.HarvestedSites = damagedSites;
            el.MgBiomassRemoved = biomassRemoved;  // Mg
            el.MgBioRemovedPerDamagedHa = biomassRemovedPerHa; // Mg/ha
            el.CohortsHarvestedPartial = cohortsDamaged;
            el.CohortsHarvestedComplete = cohortsKilled;
            el.CohortsHarvested_ = species_count;

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

        }
        //---------------------------------------------------------------------
        public void WriteLogEntry(ManagementArea mgmtArea, Stand stand)
        {
            int damagedSites = 0;
            int cohortsDamaged = 0;
            int cohortsKilled = 0;
            int standPrescriptionNumber = 0;
            double biomassRemoved = 0.0;
            double biomassRemovedPerHa = 0.0;
            IDictionary<ISpecies, double> totalBiomassBySpecies = new Dictionary<ISpecies, double>();

            //ModelCore.UI.WriteLine("BiomassHarvest:  PlugIn.cs: WriteLogEntry: mgmtArea {0}, Stand {1} ", mgmtArea.Prescriptions.Count, stand.MapCode);

            foreach (ActiveSite site in stand) {
                //set the prescription name for this site
                if (HarvestMgmtLib.SiteVars.Prescription[site] != null)
                {
                    standPrescriptionNumber = HarvestMgmtLib.SiteVars.Prescription[site].Number;
                    HarvestMgmtLib.SiteVars.PrescriptionName[site] = HarvestMgmtLib.SiteVars.Prescription[site].Name;
                    HarvestMgmtLib.SiteVars.TimeOfLastEvent[site] = modelCore.CurrentTime;
                }

                cohortsDamaged += Landis.Library.BiomassHarvest.SiteVars.CohortsPartiallyDamaged[site];
                cohortsKilled += (HarvestMgmtLib.SiteVars.CohortsDamaged[site] - Landis.Library.BiomassHarvest.SiteVars.CohortsPartiallyDamaged[site]);

                if (Landis.Library.BiomassHarvest.SiteVars.CohortsPartiallyDamaged[site] > 0 || HarvestMgmtLib.SiteVars.CohortsDamaged[site] > 0)
                {
                    damagedSites++;

                    //Conversion from [g m-2] to [Mg ha-1] to [Mg]
                    biomassRemoved += SiteVars.BiomassRemoved[site] / 100.0 * modelCore.CellArea;
                    IDictionary<ISpecies, int> siteBiomassBySpecies = SiteVars.BiomassBySpecies[site];
                    if (siteBiomassBySpecies != null)
                    {
                        // Sum up total biomass for each species
                        foreach (ISpecies species in modelCore.Species)
                        {
                            int addValue = 0;
                            siteBiomassBySpecies.TryGetValue(species, out addValue);
                            double oldValue;
                            if (totalBiomassBySpecies.TryGetValue(species, out oldValue))
                            {
                                totalBiomassBySpecies[species] += addValue / 100.0 * modelCore.CellArea;
                            }
                            else
                            {
                                totalBiomassBySpecies.Add(species, addValue / 100.0 * modelCore.CellArea);
                            }
                        }
                    }
                }
            }

            totalSites[standPrescriptionNumber] += stand.SiteCount;
            totalDamagedSites[standPrescriptionNumber] += damagedSites;
            totalCohortsDamaged[standPrescriptionNumber] += cohortsDamaged;
            totalCohortsKilled[standPrescriptionNumber] += cohortsKilled;
            totalBiomassRemoved[standPrescriptionNumber] += biomassRemoved;

            //csv string for log file, contains species affected count
            //string species_count = "";
            //csv string for log file, contains biomass by species
            //string species_biomass = "";
            double[] species_cohorts = new double[modelCore.Species.Count];
            double[] species_biomass = new double[modelCore.Species.Count];

            double biomass_value;
            foreach (ISpecies species in modelCore.Species) {
                int cohortCount = stand.DamageTable[species];
                //species_count += string.Format("{0},", cohortCount);
                species_cohorts[species.Index] = cohortCount;
                totalSpeciesCohorts[standPrescriptionNumber, species.Index] += cohortCount;
                totalBiomassBySpecies.TryGetValue(species, out biomass_value);
                //species_biomass += string.Format("{0},", biomass_value);
                species_biomass[species.Index] = biomass_value;
                totalSpeciesBiomass[standPrescriptionNumber, species.Index] += biomass_value;
            }

            //Trim trailing comma so we don't add an extra column
            //species_biomass = species_biomass.TrimEnd(',');

            //now that the damage table for this stand has been recorded, clear it!!
            stand.ClearDamageTable();

            //write to log file:
            if (biomassRemoved > 0.0)
                biomassRemovedPerHa = biomassRemoved / (double) damagedSites / modelCore.CellArea;

            //log.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9:0.000},{10:0.000},{11},{12},{13}{14}",
            //              modelCore.CurrentTime,
            //              mgmtArea.MapCode,
            //              stand.PrescriptionName,
            //              stand.MapCode,
            //              stand.EventId,
            //              stand.Age,*
            //              stand.HarvestedRank,*
            //              stand.SiteCount,*
            //              damagedSites,*
            //              biomassRemoved,  // Mg *
            //              biomassRemovedPerHa, // Mg/ha *
            //              cohortsDamaged,
            //              cohortsKilled,
            //              species_count,
            //              species_biomass);

            eventLog.Clear();
            EventsLog el = new EventsLog();
            el.Time = modelCore.CurrentTime;
            el.ManagementArea = mgmtArea.MapCode;
            el.Prescription = stand.PrescriptionName;
            el.Stand = stand.MapCode;
            el.EventID = stand.EventId;
            el.StandAge = stand.Age;
            el.StandRank = Convert.ToInt32(stand.HarvestedRank);
            el.NumberOfSites = stand.SiteCount;
            el.HarvestedSites = damagedSites;
            el.MgBiomassRemoved = biomassRemoved;
            el.MgBioRemovedPerDamagedHa = biomassRemovedPerHa;
            el.TotalCohortsPartialHarvest = cohortsDamaged;
            el.TotalCohortsCompleteHarvest = cohortsKilled;
            el.CohortsHarvested_ = species_cohorts;
            el.BiomassHarvestedMg_ = species_biomass;

            eventLog.AddObject(el);
            eventLog.WriteToFile();
        }
        //---------------------------------------------------------------------

        /// <summary>
        /// Reads harvest implementations: which prescriptions are applied to
        /// which management areas.
        /// </summary>
        protected void ReadHarvestImplementations(ManagementAreaDataset mgmtAreas,
                                                  List <Prescription> prescriptions)
        {
            ReadName(Names.HarvestImplementations);

            InputVar <ushort>     mgmtAreaMapCode  = new InputVar <ushort>("Mgmt Area");
            InputVar <string>     prescriptionName = new InputVar <string>("Prescription");
            InputVar <int>        beginTimeVar     = new InputVar <int>("Begin Time");
            InputVar <int>        endTimeVar       = new InputVar <int>("End Time");
            InputVar <Percentage> areaToHarvest    = new InputVar <Percentage>("Area To Harvest");
            InputVar <Percentage> standsToHarvest  = new InputVar <Percentage>("Stands To Harvest");
            StringReader          sr100            = new StringReader("100%");

            while (!AtEndOfInput && CurrentName != Names.PrescriptionMaps)
            {
                StringReader currentLine = new StringReader(CurrentLine);

                //  Mgmt Area column
                ReadValue(mgmtAreaMapCode, currentLine);
                ushort         mapCode  = mgmtAreaMapCode.Value.Actual;
                ManagementArea mgmtArea = mgmtAreas.Find(mapCode);
                if (mgmtArea == null)
                {
                    //add the management area, and add it to the collection of management areas
                    mgmtArea = new ManagementArea(mapCode);
                    mgmtAreas.Add(mgmtArea);
                }

                //  Prescription column
                ReadValue(prescriptionName, currentLine);
                string       name         = prescriptionName.Value.Actual;
                Prescription prescription = prescriptions.Find(new MatchName(name).Predicate);
                if (prescription == null)
                {
                    throw new InputValueException(prescriptionName.Value.String,
                                                  prescriptionName.Value.String + " is an unknown prescription name");
                }


                TextReader.SkipWhitespace(currentLine);
                //  Area to Harvest column
                string strVal = TextReader.ReadWord(currentLine);
                sr100 = new StringReader("100%");
                //If the keyword 'Stands' is attached to the area %, then applies to % of stands to harvest instead of area
                if (strVal.Contains("Stands"))
                {
                    char[]       trimChar = { 'S', 't', 'a', 'n', 'd', 's' };
                    string       clipText = strVal.TrimEnd(trimChar);
                    StringReader testRead = new StringReader(clipText);
                    ReadValue(standsToHarvest, testRead);
                    ReadValue(areaToHarvest, sr100);
                }
                else
                {
                    StringReader testRead = new StringReader(strVal);
                    //  Area to Harvest column
                    ReadValue(areaToHarvest, testRead);
                    ReadValue(standsToHarvest, sr100);
                }
                //get percentage to harvest (type Percentage ensures that it is in percent format)
                Percentage percentageToHarvest = areaToHarvest.Value.Actual;
                //check for valid percentage
                if (percentageToHarvest <= 0.0 || percentageToHarvest > 1.0)
                {
                    throw new InputValueException(areaToHarvest.Value.String,
                                                  "Percentage must be between 0% and 100%");
                }
                //get percentage of stands to harvest (type Percentage ensures that it is in percent format)
                Percentage percentStandsToHarvest = standsToHarvest.Value.Actual;
                //check for valid percentage
                if (percentStandsToHarvest <= 0.0 || percentStandsToHarvest > 1.0)
                {
                    throw new InputValueException(standsToHarvest.Value.String,
                                                  "Percentage must be between 0% and 100%");
                }

                //  Begin Time and End Time columns
                //  They are optional, so the possibilities are:
                //
                //          Begin Time   End Time
                //          ----------   --------
                //      1)   present     present
                //      2)   present     missing
                //      3)   missing     missing

                //  The default values for the starting and ending times for
                //  an applied prescription.
                int beginTime = scenarioStart;
                int endTime   = scenarioEnd;

                TextReader.SkipWhitespace(currentLine);
                if (currentLine.Peek() != -1)
                {
                    ReadValue(beginTimeVar, currentLine);
                    beginTime = beginTimeVar.Value.Actual;
                    if (beginTime < scenarioStart)
                    {
                        throw new InputValueException(beginTimeVar.Value.String,
                                                      string.Format("Year {0} is before the scenario start year ({1})",
                                                                    beginTimeVar.Value.String,
                                                                    scenarioStart));
                    }
                    if (beginTime > scenarioEnd)
                    {
                        throw new InputValueException(beginTimeVar.Value.String,
                                                      string.Format("Year {0} is after the scenario' end year ({1})",
                                                                    beginTimeVar.Value.String,
                                                                    scenarioEnd));
                    }

                    TextReader.SkipWhitespace(currentLine);
                    if (currentLine.Peek() != -1)
                    {
                        ReadValue(endTimeVar, currentLine);
                        endTime = endTimeVar.Value.Actual;
                        if (endTime < beginTime)
                        {
                            throw new InputValueException(endTimeVar.Value.String,
                                                          string.Format("Year {0} is before the Begin Time ({1})",
                                                                        endTimeVar.Value.String,
                                                                        beginTimeVar.Value.String));
                        }
                        if (endTime > scenarioEnd)
                        {
                            throw new InputValueException(endTimeVar.Value.String,
                                                          string.Format("Year {0} is after the scenario' end year ({1})",
                                                                        endTimeVar.Value.String,
                                                                        scenarioEnd));
                        }

                        CheckNoDataAfter("the " + endTimeVar.Name + " column",
                                         currentLine);
                    }
                }


                //if the perscription has already been applied to this management area
                //NOTE: .IsApplied has been modified, and this has been moved to AFTER the
                //begin and end times are founded.
                if (mgmtArea.IsApplied(prescriptionName.Value.String, beginTime, endTime))
                {
                    throw new InputValueException(prescriptionName.Value.String,
                                                  "Prescription {0} has already been applied to management area {1} with begin time = {2} and end time = {3}",
                                                  prescriptionName.Value.String, mgmtArea.MapCode, beginTime, endTime);
                }

                //begin applying prescription to this management area
                mgmtArea.ApplyPrescription(prescription,
                                           percentageToHarvest,
                                           percentStandsToHarvest,
                                           beginTime,
                                           endTime);



                CheckNoDataAfter("the " + prescriptionName.Name + " column",
                                 currentLine);
                GetNextLine();
            }
        }