//--------------------------------------------------------------------- public RepeatHarvest(string name, IStandRankingMethod rankingMethod, ISiteSelector siteSelector, ICohortCutter cohortCutter, Planting.SpeciesList speciesToPlant, ISiteSelector additionalSiteSelector, int minTimeSinceDamage, bool preventEstablishment, int interval) : base(name, rankingMethod, siteSelector, cohortCutter, speciesToPlant, minTimeSinceDamage, preventEstablishment) { this.interval = interval; this.spreadingSiteSelector = siteSelector as StandSpreading; this.additionalSiteSelector = additionalSiteSelector; this.harvestedStands = new List <Stand>(); }
//--------------------------------------------------------------------- public RepeatHarvest(string name, IStandRankingMethod rankingMethod, ISiteSelector siteSelector, ICohortCutter cohortCutter, Planting.SpeciesList speciesToPlant, ISiteSelector additionalSiteSelector, int minTimeSinceDamage, bool preventEstablishment, int interval) : base(name, rankingMethod, siteSelector, cohortCutter, speciesToPlant, minTimeSinceDamage, preventEstablishment) { this.interval = interval; this.spreadingSiteSelector = siteSelector as StandSpreading; this.additionalSiteSelector = additionalSiteSelector; this.harvestedStands = new List<Stand>(); }
//--------------------------------------------------------------------- public AppliedPrescription(Prescription prescription, Percentage percentageToHarvest, int beginTime, int endTime) { //set prescription this.prescription = prescription; //set stand ranking method this.standSpreadSiteSelector = prescription.SiteSelectionMethod as StandSpreading; //set harvest percentage this.percentageToHarvest = percentageToHarvest; //set begin time and end time this.beginTime = beginTime; this.endTime = endTime; }
//--------------------------------------------------------------------- public AppliedPrescription(Prescription prescription, Percentage percentageToHarvest, Percentage percentStandsToHarvest, int beginTime, int endTime) { //set prescription this.prescription = prescription; //set stand ranking method this.standSpreadSiteSelector = prescription.SiteSelectionMethod as StandSpreading; //set harvest percentage this.percentageToHarvest = percentageToHarvest; //set harvest stands percentage this.percentStandsToHarvest = percentStandsToHarvest; //set begin time and end time this.beginTime = beginTime; this.endTime = endTime; }
//--------------------------------------------------------------------- public RepeatHarvest(string name, IStandRankingMethod rankingMethod, ISiteSelector siteSelector, ICohortCutter cohortCutter, Planting.SpeciesList speciesToPlant, int minTimeSinceDamage, bool preventEstablishment, int interval, int timesToRepeat = 0) : base(name, rankingMethod, siteSelector, cohortCutter, speciesToPlant, minTimeSinceDamage, preventEstablishment) { this.interval = interval; this.spreadingSiteSelector = siteSelector as StandSpreading; this.harvestedStands = new List <Stand>(); if (timesToRepeat > 1) { this.timesToRepeat = timesToRepeat; } else { this.timesToRepeat = int.MaxValue; } }
//--------------------------------------------------------------------- /// <summary> /// Harvest the area's stands according to its prescriptions. /// </summary> public void HarvestStands() { //Model.Core.UI.WriteLine("BaseHarvest: ManagementArea.cs: HarvestStands: Harvesting management area {0} ...", mapCode); //initialize each stand for harvesting (setting harvested = false) foreach (Stand stand in stands) { stand.InitializeForHarvesting(); } // Determine which are prescriptions are active. List <AppliedPrescription> activePrescriptions = new List <AppliedPrescription>(); foreach (AppliedPrescription prescription in prescriptions) { // Decide whether or not to apply prescription // tjs 2009.01.10 - prescription application // This has been modified so that if the prescription is AppliedRepeatHarvest // AND has not been harvested once, it is set to harvest. If it has been set // to harvest the first time, it will automatically be harvested by the logic // having to do with the setAside member variable (see AppliedRepeatHarvest.cs) prescription.ApplyPrescription = false; if (prescription.BeginTime <= Model.Core.CurrentTime && prescription.EndTime >= Model.Core.CurrentTime) { if (!(prescription is AppliedRepeatHarvest) || prescription.Prescription is SingleRepeatHarvest) { prescription.ApplyPrescription = true; } else if (prescription is AppliedRepeatHarvest && Model.Core.CurrentTime > 0 && ((AppliedRepeatHarvest)prescription).IsMultipleRepeatHarvest) { prescription.ApplyPrescription = true; ((AppliedRepeatHarvest)prescription).HasBeenHarvested = true; } } // if(prescription.BeginTime <= Model.Core.CurrentTime... if (prescription.ApplyPrescription) { //Model.Core.UI.WriteLine(" Applying Prescription: {0} Model.Core.CurrentTime: {1}", prescription.Prescription.Name, Model.Core.CurrentTime); if (isDebugEnabled) { log.DebugFormat(" Initializing prescription {0} ...", prescription.Prescription.Name); } //Model.Core.UI.WriteLine(" Initializing prescription {0} ...", prescription.Prescription.Name); //set harvesting areas, rank stands (by user choice method) prescription.InitializeForHarvest(stands); if (prescription.AnyUnharvestedStandsRankedAbove0) { //Model.Core.UI.WriteLine(" Adding {0}", prescription.Prescription.Name); foreach (StandRanking sr in prescription.Rankings) { //Model.Core.UI.WriteLine(" Stand {0} ranked {1}", sr.Stand.MapCode, sr.Rank); } activePrescriptions.Add(prescription); } } } if (isDebugEnabled) { Model.Core.UI.WriteLine(" Number of active prescriptions: {0}", activePrescriptions.Count); for (int i = 0; i < activePrescriptions.Count; i++) { Model.Core.UI.WriteLine(" {0}) {1}", i + 1, activePrescriptions[i].Prescription.Name); } } foreach (AppliedPrescription prescription in prescriptions) { //Model.Core.UI.WriteLine(" Looping through prescriptions... {0}.", prescription.Prescription.Name); if (prescription is AppliedRepeatHarvest) { //prescription.Prescription.SiteSelectionMethod = new CompleteStand(); //Model.Core.UI.WriteLine(" Attempting to Re-Harvest {0}.", prescription.Prescription.Name); ((AppliedRepeatHarvest)prescription).ActiveMgmtArea = this; ((AppliedRepeatHarvest)prescription).HarvestReservedStands(); ((AppliedRepeatHarvest)prescription).ActiveMgmtArea = null; } } // Loop while there are still active prescriptions that haven't // reached their target harvest areas and that still have // at least one unharvested stand ranked above 0. while (activePrescriptions.Count > 0) { double[] endProbability = new double[activePrescriptions.Count + 1]; // Assign a part of the probability interval [0, 1) to each // prescription based on how the ratio of the area remaining to // be harvested to the total area to be harvested double ratioTotal = 0.0; foreach (AppliedPrescription prescription in activePrescriptions) { ratioTotal += Math.Min(prescription.AreaRemainingRatio, prescription.StandsRemainingRatio); } if (ratioTotal > 0) { for (int i = 0; i < activePrescriptions.Count; ++i) { AppliedPrescription prescription = activePrescriptions[i]; //first prescription, start at 0 if (i == 0) { endProbability[i] = Math.Min(prescription.AreaRemainingRatio, prescription.StandsRemainingRatio) / ratioTotal; } //last prescription, end at 1.0 else if (i == activePrescriptions.Count - 1) { endProbability[i] = 1.0; } // else { double startProbability = endProbability[i - 1]; double intervalWidth = Math.Min(prescription.AreaRemainingRatio, prescription.StandsRemainingRatio) / ratioTotal; endProbability[i] = startProbability + intervalWidth; } } // for (int i = 0; i < activePrescriptions.Count; ++i) // Randomly select one of the active prescriptions and harvest the stand ranked highest by that prescription. AppliedPrescription selectedPrescription = null; double randomNum = Model.Core.GenerateUniform(); for (int i = 0; i < activePrescriptions.Count; ++i) { if (randomNum < endProbability[i]) { selectedPrescription = activePrescriptions[i]; //Model.Core.UI.WriteLine("\nSELECTED PRESCRIPTION = {0}\n", selectedPrescription.Prescription.Name); break; } } //actually harvest the stands: starting with highest ranked if (selectedPrescription is AppliedRepeatHarvest) { ((AppliedRepeatHarvest)selectedPrescription).HarvestHighestRankedStand(); } else { selectedPrescription.HarvestHighestRankedStand(); } //Model.Core.UI.WriteLine("\nSELECTED PRESCRIPTION = {0}\n", selectedPrescription.Prescription.Name); Stand stand = selectedPrescription.HighestRankedStand; if (stand != null) { //if there was a stand-adjacency constraint on this stand, enforce: foreach (IRequirement r in selectedPrescription.Prescription.StandRankingMethod.Requirements) { //look for stand-adacency constraint in list r ranking methods if (r.ToString() == "Landis.Harvest.StandAdjacency") { StandAdjacency sa = (StandAdjacency)r; //set-aside every stand in this stand's neighbor-list for the specified number of years //IF siteselection = some type of spreading, freeze the spread-list of neighbors if (selectedPrescription.Prescription.SiteSelectionMethod.ToString() == "Landis.Harvest.CompleteStandSpreading" || selectedPrescription.Prescription.SiteSelectionMethod.ToString() == "Landis.Harvest.PartialStandSpreading") { //freeze every stand in the neighbor list StandSpreading ss = (StandSpreading)selectedPrescription.Prescription.SiteSelectionMethod; //if it's spreading, go through the UnharvestedNeighbors list that was built during the site-selection spread foreach (Stand n_stand in ss.UnharvestedNeighbors) { //Model.Core.UI.WriteLine("SPREAD setting aside {0}", n_stand.MapCode); n_stand.SetAsideUntil(Model.Core.CurrentTime + sa.SetAside); } } else { //if it's not a spreading, just take all of the stand's neighbors foreach (Stand n_stand in stand.Neighbors) { //Model.Core.UI.WriteLine("NON-SPREAD setting aside {0}", n_stand.MapCode); n_stand.SetAsideUntil(Model.Core.CurrentTime + sa.SetAside); } } //found and implemented the stand adjacency, so break out of the requirements list break; } } } else { //Model.Core.UI.WriteLine("returned a null stand"); } // Check each prescription to see if there's at least one unharvested stand that the prescription ranks higher than 0. // The list is traversed in reverse order, so that the removal of items doesn't mess up the traversal. for (int i = activePrescriptions.Count - 1; i >= 0; --i) { if (!activePrescriptions[i].AnyUnharvestedStandsRankedAbove0) { //Model.Core.UI.WriteLine("removing1 {0}", activePrescriptions[i].Prescription.Name); activePrescriptions.RemoveAt(i); } } } else { for (int i = activePrescriptions.Count - 1; i >= 0; --i) { //Model.Core.UI.WriteLine("removing2 {0}", activePrescriptions[i].Prescription.Name); activePrescriptions.RemoveAt(i); } } } //endwhile }
//--------------------------------------------------------------------- protected InputValue <ISiteSelector> ReadSiteSelector(StringReader reader, out int index) { TextReader.SkipWhitespace(reader); index = reader.Index; string name = TextReader.ReadWord(reader); if (name == "") { throw new InputValueException(); // Missing value } ISiteSelector selector; StringBuilder valueAsStr = new StringBuilder(name); // Site selection -- Complete stand if (name == SiteSelection.Complete) { selector = new CompleteStand(); } // Site selection -- Target size with partial or complete spread else if (name == SiteSelection.CompleteAndSpreading || name == SiteSelection.TargetAndSpreading) { InputVar <double> minTargetSize = new InputVar <double>("the minimum target harvest size"); ReadValue(minTargetSize, reader); InputVar <double> maxTargetSize = new InputVar <double>("the maximum target harvest size"); ReadValue(maxTargetSize, reader); //validate the target size for spreading algorithms StandSpreading.ValidateTargetSizes(minTargetSize.Value, maxTargetSize.Value); if (name == SiteSelection.TargetAndSpreading) { // Site selection -- partial spread selector = new PartialStandSpreading(minTargetSize.Value.Actual, maxTargetSize.Value.Actual); } else { // Site selection -- complete stand selector = new CompleteStandSpreading(minTargetSize.Value.Actual, maxTargetSize.Value.Actual); } valueAsStr.AppendFormat(" {0}", minTargetSize.Value.String); valueAsStr.AppendFormat(" {0}", maxTargetSize.Value.String); } // Site selection -- Patch cutting else if (name == SiteSelection.Patch) { InputVar <Percentage> percentage = new InputVar <Percentage>("the site percentage for patch cutting"); ReadValue(percentage, reader); PatchCutting.ValidatePercentage(percentage.Value); InputVar <double> size = new InputVar <double>("the target patch size"); ReadValue(size, reader); PatchCutting.ValidateSize(size.Value); // priority is an optional value so we can't use ReadValue TextReader.SkipWhitespace(reader); index = reader.Index; string priority = TextReader.ReadWord(reader); selector = new PatchCutting(percentage.Value.Actual, size.Value.Actual, priority); valueAsStr.AppendFormat(" {0} {1} {2}", percentage.Value.String, size.Value.String, priority); } else { string[] methodList = new string[] { "Site selection methods:", " " + SiteSelection.Complete, " " + SiteSelection.CompleteAndSpreading, " " + SiteSelection.TargetAndSpreading, " " + SiteSelection.Patch }; throw new InputValueException(name, name + " is not a valid site selection method", new MultiLineText(methodList)); } return(new InputValue <ISiteSelector>(selector, valueAsStr.ToString())); }