// Copyright (C) Stichting Deltares 2017. All rights reserved. // // This file is part of Ringtoets. // // Ringtoets is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using Core.Common.Base.Data; using Ringtoets.AssemblyTool.Data; using Ringtoets.Common.Data.AssemblyTool; using Ringtoets.Common.Data.Contribution; using Ringtoets.Common.Data.Hydraulics; namespace Ringtoets.Common.Data.AssessmentSection { /// /// Extension methods for . /// public static class AssessmentSectionExtensions { /// /// Gets the normative assessment level for a . /// /// The assessment section to get the normative assessment level from. /// The hydraulic boundary location to get the normative assessment level for. /// The normative assessment level or when: /// /// is null; /// is not part of ; /// contains no corresponding calculation output. /// /// /// Thrown when /// is null. /// Thrown when /// contains an invalid value of . /// Thrown when /// contains a valid value of , but unsupported. public static RoundedDouble GetNormativeAssessmentLevel(this IAssessmentSection assessmentSection, HydraulicBoundaryLocation hydraulicBoundaryLocation) { if (assessmentSection == null) { throw new ArgumentNullException(nameof(assessmentSection)); } HydraulicBoundaryLocationCalculation calculation = GetNormativeHydraulicBoundaryLocationCalculation(assessmentSection, hydraulicBoundaryLocation); return GetAssessmentLevelFromCalculation(calculation); } /// /// Gets the normative for a . /// /// The assessment section to get the from. /// The hydraulic boundary location to get the normative /// for. /// The normative or null when: /// /// is null; /// is not part of . /// /// /// Thrown when /// is null. /// Thrown when /// contains an invalid value of . /// Thrown when /// contains a valid value of , but unsupported. public static HydraulicBoundaryLocationCalculation GetNormativeHydraulicBoundaryLocationCalculation(this IAssessmentSection assessmentSection, HydraulicBoundaryLocation hydraulicBoundaryLocation) { if (assessmentSection == null) { throw new ArgumentNullException(nameof(assessmentSection)); } IEnumerable calculations = GetHydraulicBoundaryLocationCalculations(assessmentSection); return GetHydraulicBoundaryLocationCalculationFromCalculations(hydraulicBoundaryLocation, calculations); } /// /// Gets the assessment level for a based on . /// /// The assessment section to get the assessment level from. /// The hydraulic boundary location to get the assessment level for. /// The category type to use while obtaining the assessment level. /// The assessment level or when: /// /// is null; /// is not part of ; /// contains no corresponding calculation output. /// /// /// Thrown when /// is null. /// Thrown when /// is an invalid . /// Thrown when /// is a valid but unsupported . public static RoundedDouble GetAssessmentLevel(this IAssessmentSection assessmentSection, HydraulicBoundaryLocation hydraulicBoundaryLocation, AssessmentSectionCategoryType categoryType) { if (assessmentSection == null) { throw new ArgumentNullException(nameof(assessmentSection)); } HydraulicBoundaryLocationCalculation calculation = GetHydraulicBoundaryLocationCalculation(assessmentSection, hydraulicBoundaryLocation, categoryType); return GetAssessmentLevelFromCalculation(calculation); } /// /// Gets the for a /// based on . /// The assessment section to get the from. /// The hydraulic boundary location to get the for. /// The category type to use while obtaining the . /// The , or null when: /// /// is null; /// is not part of . /// /// /// Thrown when /// is null. /// Thrown when /// is an invalid . /// Thrown when /// is a valid but unsupported . public static HydraulicBoundaryLocationCalculation GetHydraulicBoundaryLocationCalculation(this IAssessmentSection assessmentSection, HydraulicBoundaryLocation hydraulicBoundaryLocation, AssessmentSectionCategoryType categoryType) { if (assessmentSection == null) { throw new ArgumentNullException(nameof(assessmentSection)); } return GetHydraulicBoundaryLocationCalculationFromCalculations(hydraulicBoundaryLocation, GetHydraulicBoundaryLocationCalculations(assessmentSection, categoryType)); } /// /// Gets the norm based on . /// /// The assessment section to get the norm from. /// The category type to use while obtaining the norm. /// The norm corresponding to the provided category type. /// Thrown when /// is null. /// Thrown when /// is an invalid . /// Thrown when /// is a valid but unsupported . public static double GetNorm(this IAssessmentSection assessmentSection, AssessmentSectionCategoryType categoryType) { if (assessmentSection == null) { throw new ArgumentNullException(nameof(assessmentSection)); } if (!Enum.IsDefined(typeof(AssessmentSectionCategoryType), categoryType)) { throw new InvalidEnumArgumentException(nameof(categoryType), (int) categoryType, typeof(AssessmentSectionCategoryType)); } IEnumerable categories = AssemblyToolCategoriesFactory.CreateAssessmentSectionAssemblyCategories( assessmentSection.FailureMechanismContribution.SignalingNorm, assessmentSection.FailureMechanismContribution.LowerLimitNorm); switch (categoryType) { case AssessmentSectionCategoryType.FactorizedSignalingNorm: return categories.First(c => c.Group == AssessmentSectionAssemblyCategoryGroup.A) .LowerBoundary; case AssessmentSectionCategoryType.SignalingNorm: return categories.First(c => c.Group == AssessmentSectionAssemblyCategoryGroup.B) .LowerBoundary; case AssessmentSectionCategoryType.LowerLimitNorm: return categories.First(c => c.Group == AssessmentSectionAssemblyCategoryGroup.C) .LowerBoundary; case AssessmentSectionCategoryType.FactorizedLowerLimitNorm: return categories.First(c => c.Group == AssessmentSectionAssemblyCategoryGroup.D) .LowerBoundary; default: throw new NotSupportedException(); } } /// /// Gets the relevant collection of based on the of the /// assessment section. /// /// The to get the collections of /// from. /// A collection of from the /// based on the . /// Thrown when /// contains an invalid value of . /// Thrown when /// contains a valid value of , but unsupported. private static IEnumerable GetHydraulicBoundaryLocationCalculations(IAssessmentSection assessmentSection) { NormType normType = assessmentSection.FailureMechanismContribution.NormativeNorm; if (!Enum.IsDefined(typeof(NormType), normType)) { throw new InvalidEnumArgumentException(nameof(normType), (int) normType, typeof(NormType)); } IEnumerable calculations; switch (normType) { case NormType.Signaling: calculations = assessmentSection.WaterLevelCalculationsForSignalingNorm; break; case NormType.LowerLimit: calculations = assessmentSection.WaterLevelCalculationsForLowerLimitNorm; break; default: throw new NotSupportedException(); } return calculations; } /// /// Gets the collection of that belongs to /// the given . /// /// The assessment section to get the calculations from. /// The used to determine which calculations to return. /// A collection of . /// Thrown when /// is an invalid . /// Thrown when /// is a valid but unsupported . private static IEnumerable GetHydraulicBoundaryLocationCalculations(IAssessmentSection assessmentSection, AssessmentSectionCategoryType categoryType) { if (!Enum.IsDefined(typeof(AssessmentSectionCategoryType), categoryType)) { throw new InvalidEnumArgumentException(nameof(categoryType), (int) categoryType, typeof(AssessmentSectionCategoryType)); } IEnumerable calculations; switch (categoryType) { case AssessmentSectionCategoryType.FactorizedSignalingNorm: calculations = assessmentSection.WaterLevelCalculationsForFactorizedSignalingNorm; break; case AssessmentSectionCategoryType.SignalingNorm: calculations = assessmentSection.WaterLevelCalculationsForSignalingNorm; break; case AssessmentSectionCategoryType.LowerLimitNorm: calculations = assessmentSection.WaterLevelCalculationsForLowerLimitNorm; break; case AssessmentSectionCategoryType.FactorizedLowerLimitNorm: calculations = assessmentSection.WaterLevelCalculationsForFactorizedLowerLimitNorm; break; default: throw new NotSupportedException(); } return calculations; } private static HydraulicBoundaryLocationCalculation GetHydraulicBoundaryLocationCalculationFromCalculations(HydraulicBoundaryLocation hydraulicBoundaryLocation, IEnumerable calculations) { return calculations.FirstOrDefault(c => ReferenceEquals(c.HydraulicBoundaryLocation, hydraulicBoundaryLocation)); } private static RoundedDouble GetAssessmentLevelFromCalculation(HydraulicBoundaryLocationCalculation calculation) { return calculation?.Output?.Result ?? RoundedDouble.NaN; } } }