//--------------------------------------------------------------------- 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; }
/// <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)); } }
/// <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)); } }
//--------------------------------------------------------------------- /// <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>(); }
//--------------------------------------------------------------------- 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); }
//--------------------------------------------------------------------- /// <summary> /// Adds a new management area to the dataset. /// </summary> public void Add(ManagementArea mgmtArea) { Require.ArgumentNotNull(mgmtArea); mgmtAreas[mgmtArea.MapCode] = mgmtArea; }
//--------------------------------------------------------------------- /// <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(); } }
//--------------------------------------------------------------------- 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(); } }