/// <summary>A function that resets phenology to a specified stage</summary> public void SetToStage(double newStage) { int oldPhaseIndex = IndexFromPhaseName(CurrentPhase.Name); stagesPassedToday.Clear(); if (newStage <= 0) { throw new Exception(this + "Must pass positive stage to set to"); } if (newStage > phases.Count() + 1) { throw new Exception(this + " Trying to set to non-existant stage"); } currentPhaseIndex = Convert.ToInt32(Math.Floor(newStage), CultureInfo.InvariantCulture) - 1; if (newStage < Stage) { //Make a list of phases to rewind List <IPhase> phasesToRewind = new List <IPhase>(); foreach (IPhase phase in phases) { if ((IndexFromPhaseName(phase.Name) >= currentPhaseIndex) && (IndexFromPhaseName(phase.Name) <= oldPhaseIndex)) { phasesToRewind.Add(phase); } } foreach (IPhase phase in phasesToRewind) { if (!(phase is IPhaseWithTarget) && !(phase is GotoPhase) && !(phase is EndPhase) && !(phase is PhotoperiodPhase) && !(phase is LeafDeathPhase) && !(phase is DAWSPhase)) { throw new Exception("Can not rewind over phase of type " + phase.GetType()); } if (phase is IPhaseWithTarget) { IPhaseWithTarget rewindingPhase = phase as IPhaseWithTarget; AccumulatedTT -= rewindingPhase.ProgressThroughPhase; AccumulatedEmergedTT -= rewindingPhase.ProgressThroughPhase; phase.ResetPhase(); } else { phase.ResetPhase(); } } AccumulatedEmergedTT = Math.Max(0, AccumulatedEmergedTT); } else { //Make a list of phases to fast forward List <IPhase> phasesToFastForward = new List <IPhase>(); foreach (IPhase phase in phases) { if (IndexFromPhaseName(phase.Name) >= oldPhaseIndex) { phasesToFastForward.Add(phase); } } foreach (IPhase phase in phasesToFastForward) { if (phase is EndPhase) { stagesPassedToday.Add(phase.Start); //Fixme. This is a pretty ordinary bit of programming to get around the fact we use a phenological stage to match observed values. We should change this so plant has a harvest tag to match on. } stagesPassedToday.Add(phase.End); PhaseChangedType PhaseChangedData = new PhaseChangedType(); PhaseChangedData.StageName = phase.End; PhaseChanged?.Invoke(plant, PhaseChangedData); } } if (phases[currentPhaseIndex] is IPhaseWithTarget) { IPhaseWithTarget currentPhase = (phases[currentPhaseIndex] as IPhaseWithTarget); currentPhase.ProgressThroughPhase = currentPhase.Target * (newStage - currentPhaseIndex - 1); if (currentPhase.ProgressThroughPhase == 0) { stagesPassedToday.Add(currentPhase.Start); } } if ((phases[currentPhaseIndex] is PhotoperiodPhase) || (phases[currentPhaseIndex] is LeafDeathPhase)) { stagesPassedToday.Add(phases[currentPhaseIndex].Start); } StageWasReset?.Invoke(this, new EventArgs()); }
/// <summary>A function that resets phenology to a specified stage</summary> public void SetToStage(double newStage) { string stageOnEvent = CurrentPhase.End; double oldPhaseIndex = IndexFromPhaseName(CurrentPhase.Name); stagesPassedToday.Clear(); if (newStage <= 0) { throw new Exception(this + "Must pass positive stage to set to"); } if (newStage > phases.Count() + 1) { throw new Exception(this + " Trying to set to non-existant stage"); } currentPhaseIndex = Convert.ToInt32(Math.Floor(newStage)) - 1; if (!(phases[currentPhaseIndex] is IPhaseWithTarget)) { throw new Exception("Can not set phenology to phase of type " + phases[currentPhaseIndex].GetType()); } if (currentPhaseIndex <= oldPhaseIndex) { //Make a list of phases to rewind List <IPhase> phasesToRewind = new List <IPhase>(); foreach (IPhase phase in phases) { if ((IndexFromPhaseName(phase.Name) >= currentPhaseIndex) && (IndexFromPhaseName(phase.Name) <= oldPhaseIndex)) { phasesToRewind.Add(phase); } } foreach (IPhase phase in phasesToRewind) { AccumulatedTT -= phase.TTinPhase; AccumulatedEmergedTT -= phase.TTinPhase; phase.ResetPhase(); } AccumulatedEmergedTT = Math.Max(0, AccumulatedEmergedTT); } else { //Make a list of phases fast forward List <IPhase> phasesToFastForward = new List <IPhase>(); foreach (IPhase phase in phases) { if (IndexFromPhaseName(phase.Name) >= oldPhaseIndex) { phasesToFastForward.Add(phase); } } foreach (IPhase phase in phasesToFastForward) { stagesPassedToday.Add(phase.End); if (PhaseChanged != null) { PhaseChangedType PhaseChangedData = new PhaseChangedType(); PhaseChangedData.StageName = phase.End; PhaseChanged.Invoke(plant, PhaseChangedData); } } } IPhaseWithTarget currentPhase = (phases[currentPhaseIndex] as IPhaseWithTarget); currentPhase.TTinPhase = currentPhase.Target * (newStage - currentPhaseIndex - 1); if (currentPhase.TTinPhase == 0) { stagesPassedToday.Add(currentPhase.Start); } if (StageWasReset != null) { StageWasReset.Invoke(this, new EventArgs()); } }