using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Xml.Serialization; using Deltares.Geotechnics; using Deltares.Geotechnics.Soils; using Deltares.Standard; using Deltares.Standard.Attributes; using Deltares.Standard.EventPublisher; using Deltares.Standard.Reflection; using Deltares.Standard.Scenarios; using Deltares.Standard.Units; using Deltares.Standard.Validation; namespace Deltares.AssessmentMechanism { /// /// An object to be used for /// to hold scenario dependent data, based on a . /// public class AssessmentScenario : Scenario, IDomain, IVisibleEnabled { private AssessmentCalculationResult assessmentCalculationResult = new AssessmentCalculationResult(); private double probability; /// /// Initializes a new instance of the class without /// any definitions. /// public AssessmentScenario() { Name = String.Empty; Description = String.Empty; } /// /// Indicates the probability of the scenario /// [Clearable] [Unit(UnitType.Probability, ProbabilityUnit.Fraction)] [Format("F2", true)] [PropertyOrder(3, 0)] [Minimum(0)] [Maximum(1)] public double Probability { get { return probability; } set { this.SetAndNotify2(out probability, value, s => s.Probability); } } /// /// Gets or sets the name of the scenario. /// [PropertyOrder(1, 0)] [ReadOnly(true)] public string Name { get; set; } /// /// Gets or sets the description of the scenario. /// [PropertyOrder(1, 1)] public string Description { get; set; } [PropertyOrder(2, 0)] public bool Calculated { get { return assessmentCalculationResult.Calculated; } } /// /// Gets or sets the soil profile of the scenario from the /// on which this scenario is based. If you set a different value, the corresponding /// will replace the value for that /// /// When setting a new value while there /// is no available as /// or is not set. [XmlIgnore] [PropertyOrder(4, 0)] public SoilProfile SoilProfile { get { return Values.OfType().Select(ssp => ssp.Profile).FirstOrDefault(); } set { if (GetAvailableStochasticSoilProfiles == null) { throw new InvalidOperationException("AssessmentScenario requires to have GetAvailableStochasticSoilProfiles set."); } ScenarioItem soilProfileItem = ScenarioItems.FirstOrDefault(si => si.Value is StochasticSoilProfile); if (soilProfileItem == null) { throw new InvalidOperationException("AssessmentScenario requires to have a ScenarioItem with a StochasticSoilProfile."); } soilProfileItem.Value = GetStochasticSoilProfile(value); // Updating SoilProfile in scenario should update target -> Send event to notify this action: DataEventPublisher.AfterChange(this, s => s.SoilProfile); } } /// /// Gets or sets the result from an . /// public AssessmentCalculationResult AssessmentCalculationResult { get { return assessmentCalculationResult; } set { assessmentCalculationResult = value; } } /// /// Injection point for method to retrieve all available stochastic soil profiles /// for this scenario to be based upon. /// public Func GetAvailableStochasticSoilProfiles { get; set; } [DynamicProperties] [PropertyOrder(4, 1)] public override List Values { get { return base.Values; } } public override string ToString() { return Name ?? string.Empty; } #region IDomain public ICollection GetDomain(string property) { switch (property) { case "SoilProfile": return GetAvailableStochasticSoilProfiles != null ? GetAvailableStochasticSoilProfiles().Select(ssp => ssp.Profile).ToArray() : null; default: return null; } } #endregion private StochasticSoilProfile GetStochasticSoilProfile(SoilProfile value) { StochasticSoilProfile scenarioItemStochasticSoilProfile = null; DataEventPublisher.InvokeWithoutPublishingEvents(() => { var stochasticSoilProfile = GetAvailableStochasticSoilProfiles().FirstOrDefault(si => ReferenceEquals(si.Profile, value)); if (stochasticSoilProfile != null) { scenarioItemStochasticSoilProfile = (StochasticSoilProfile)stochasticSoilProfile.Clone(); } }); return scenarioItemStochasticSoilProfile; } #region IVisibleEnabled public bool IsVisible(string property) { return true; } public bool IsEnabled(string property) { var enabled = true; if (this.GetMemberName(s => s.SoilProfile) == property) { enabled = GetAvailableStochasticSoilProfiles != null; } return enabled; } #endregion } }