// Copyright (C) Stichting Deltares 2016. 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 Core.Common.Base.Data; using Ringtoets.Common.Data.Calculation; using Ringtoets.Common.Data.DikeProfiles; using Ringtoets.Common.Data.Hydraulics; using Ringtoets.Common.Data.Structures; using Ringtoets.Common.IO.Configurations; using Ringtoets.Common.IO.Configurations.Helpers; using Ringtoets.Common.IO.Configurations.Import; using Ringtoets.StabilityPointStructures.Data; using Ringtoets.StabilityPointStructures.IO.Configurations.Helpers; using Ringtoets.StabilityPointStructures.IO.Properties; using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources; namespace Ringtoets.StabilityPointStructures.IO.Configurations { /// /// Class for importing a configuration of /// from an XML file and storing it on a . /// public class StabilityPointStructuresCalculationConfigurationImporter : CalculationConfigurationImporter< StabilityPointStructuresCalculationConfigurationReader, StabilityPointStructuresCalculationConfiguration> { private readonly IEnumerable availableHydraulicBoundaryLocations; private readonly IEnumerable availableForeshoreProfiles; private readonly IEnumerable availableStructures; /// /// Create new instance of /// /// The path to the XML file to import from. /// The calculation group to update. /// The hydraulic boundary locations /// used to check if the imported objects contain the right location. /// The foreshore profiles used to check if /// the imported objects contain the right foreshore profile. /// The structures used to check if /// the imported objects contain the right structure. /// Thrown when any input parameter is null. public StabilityPointStructuresCalculationConfigurationImporter( string xmlFilePath, CalculationGroup importTarget, IEnumerable hydraulicBoundaryLocations, IEnumerable foreshoreProfiles, IEnumerable structures) : base(xmlFilePath, importTarget) { if (hydraulicBoundaryLocations == null) { throw new ArgumentNullException(nameof(hydraulicBoundaryLocations)); } if (foreshoreProfiles == null) { throw new ArgumentNullException(nameof(foreshoreProfiles)); } if (structures == null) { throw new ArgumentNullException(nameof(structures)); } availableHydraulicBoundaryLocations = hydraulicBoundaryLocations; availableForeshoreProfiles = foreshoreProfiles; availableStructures = structures; } protected override StabilityPointStructuresCalculationConfigurationReader CreateCalculationConfigurationReader( string xmlFilePath) { return new StabilityPointStructuresCalculationConfigurationReader(xmlFilePath); } protected override ICalculation ParseReadCalculation(StabilityPointStructuresCalculationConfiguration readCalculation) { var calculation = new StructuresCalculation { Name = readCalculation.Name }; if (TrySetStructure(readCalculation.StructureName, calculation) && TrySetHydraulicBoundaryLocation(readCalculation.HydraulicBoundaryLocationName, calculation) && TrySetForeshoreProfile(readCalculation.ForeshoreProfileName, calculation) && TrySetEvaluationLevel(readCalculation, calculation) && TrySetFailureProbabilityRepairClosure(readCalculation, calculation) && TrySetFailureProbabilityStructureWithErosion(readCalculation, calculation) && TrySetInflowModelType(readCalculation, calculation) && TrySetLevellingCount(readCalculation, calculation) && TrySetLoadSchematizationType(readCalculation, calculation) && TrySetProbabilityCollisionSecondaryStructure(readCalculation, calculation) && TrySetStochasts(readCalculation, calculation) && TrySetStructureNormalOrientation(readCalculation, calculation) && TrySetVerticalDistance(readCalculation, calculation) && readCalculation.WaveReduction.ValidateWaveReduction(calculation.InputParameters.ForeshoreProfile, calculation.Name, Log)) { SetFactorStormDurationOpenStructure(readCalculation, calculation); SetVolumicWeightWater(readCalculation, calculation); SetWaveReductionParameters(readCalculation.WaveReduction, calculation.InputParameters); return calculation; } return null; } /// /// Sets the evaluation level. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when the evaluation level is invalid or when there is an /// evaluation level but no structure defined, true otherwise. private bool TrySetEvaluationLevel(StabilityPointStructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) { if (readCalculation.EvaluationLevel.HasValue) { if (calculation.InputParameters.Structure == null) { Log.LogCalculationConversionError(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_, Resources.CalculationConfigurationImporter_EvaluationLevel_DisplayName), calculation.Name); return false; } calculation.InputParameters.EvaluationLevel = (RoundedDouble) readCalculation.EvaluationLevel.Value; } return true; } private bool TrySetStochasts(StabilityPointStructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) { var assigner = new StabilityPointStructuresCalculationStochastAssigner( readCalculation, calculation); return assigner.Assign(); } /// /// Sets the structure normal orientation. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when the structure normal orientation is invalid or when there /// is a structure normal orientation but no structure defined, true otherwise. private bool TrySetStructureNormalOrientation(StructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) { if (readCalculation.StructureNormalOrientation.HasValue) { if (calculation.InputParameters.Structure == null) { Log.LogCalculationConversionError(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_, RingtoetsCommonIOResources.CalculationConfigurationImporter_Orientation_DisplayName), calculation.Name); return false; } double orientation = readCalculation.StructureNormalOrientation.Value; try { calculation.InputParameters.StructureNormalOrientation = (RoundedDouble) orientation; } catch (ArgumentOutOfRangeException e) { Log.LogOutOfRangeException(string.Format(RingtoetsCommonIOResources.TryReadParameter_Value_0_ParameterName_1_is_invalid, orientation, RingtoetsCommonIOResources.CalculationConfigurationImporter_Orientation_DisplayName), calculation.Name, e); return false; } } return true; } /// /// Sets the failure probability repair closure. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when the failure probability repair closure is invalid or when there /// is a failure probability repair closure but no structure defined, true otherwise. private bool TrySetFailureProbabilityRepairClosure(StabilityPointStructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) { if (!readCalculation.FailureProbabilityRepairClosure.HasValue) { return true; } if (calculation.InputParameters.Structure == null) { Log.LogCalculationConversionError(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_, Resources.CalculationConfigurationImporter_FailureProbabilityRepairClosure_DisplayName), calculation.Name); return false; } double failureProbabilityRepairClosure = readCalculation.FailureProbabilityRepairClosure.Value; try { calculation.InputParameters.FailureProbabilityRepairClosure = (RoundedDouble) failureProbabilityRepairClosure; } catch (ArgumentOutOfRangeException e) { Log.LogOutOfRangeException(string.Format(RingtoetsCommonIOResources.TryReadParameter_Value_0_ParameterName_1_is_invalid, failureProbabilityRepairClosure, Resources.CalculationConfigurationImporter_FailureProbabilityRepairClosure_DisplayName), calculation.Name, e); return false; } return true; } /// /// Sets the failure probability structure with erosion. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when the orientation is invalid or when there is a failure probability /// structure with erosion but no structure defined, true otherwise. private bool TrySetFailureProbabilityStructureWithErosion(StructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) { if (readCalculation.FailureProbabilityStructureWithErosion.HasValue) { double failureProbability = readCalculation.FailureProbabilityStructureWithErosion.Value; try { calculation.InputParameters.FailureProbabilityStructureWithErosion = (RoundedDouble) failureProbability; } catch (ArgumentOutOfRangeException e) { Log.LogOutOfRangeException(string.Format( RingtoetsCommonIOResources.TryReadParameter_Value_0_ParameterName_1_is_invalid, failureProbability, RingtoetsCommonIOResources.CalculationConfigurationImporter_FailureProbabilityStructureWithErosion_DisplayName), calculation.Name, e); return false; } } return true; } /// /// Sets the probability collision secondary structure. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when the probability collision secondary structure is invalid or /// when there is a probability collision secondary structure but no structure defined, /// true otherwise. private bool TrySetProbabilityCollisionSecondaryStructure(StabilityPointStructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) { if (readCalculation.ProbabilityCollisionSecondaryStructure.HasValue) { if (calculation.InputParameters.Structure == null) { Log.LogCalculationConversionError(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_, Resources.CalculationConfigurationImporter_ProbabilityCollisionSecondaryStructure_DisplayName), calculation.Name); return false; } double failureProbability = readCalculation.ProbabilityCollisionSecondaryStructure.Value; try { calculation.InputParameters.ProbabilityCollisionSecondaryStructure = (RoundedDouble) failureProbability; } catch (ArgumentOutOfRangeException e) { Log.LogOutOfRangeException(string.Format( RingtoetsCommonIOResources.TryReadParameter_Value_0_ParameterName_1_is_invalid, failureProbability, Resources.CalculationConfigurationImporter_ProbabilityCollisionSecondaryStructure_DisplayName), calculation.Name, e); return false; } } return true; } /// /// Sets the factor storm duration open structure. /// /// The calculation read from the imported file. /// The calculation to configure. private void SetFactorStormDurationOpenStructure(StabilityPointStructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) { if (readCalculation.FactorStormDurationOpenStructure.HasValue) { calculation.InputParameters.FactorStormDurationOpenStructure = (RoundedDouble) readCalculation.FactorStormDurationOpenStructure.Value; } } /// /// Sets the volumic weight water. /// /// The calculation read from the imported file. /// The calculation to configure. private void SetVolumicWeightWater(StabilityPointStructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) { if (readCalculation.VolumicWeightWater.HasValue) { calculation.InputParameters.VolumicWeightWater = (RoundedDouble) readCalculation.VolumicWeightWater.Value; } } /// /// Sets the inflow model type. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when the inflow model type is invalid or when there is a /// inflow model type but no structure defined, true otherwise. private bool TrySetInflowModelType(StabilityPointStructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) { if (readCalculation.InflowModelType.HasValue) { if (calculation.InputParameters.Structure == null) { Log.LogCalculationConversionError(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_, RingtoetsCommonIOResources.CalculationConfigurationImporter_InflowModelType_DisplayName), calculation.Name); return false; } calculation.InputParameters.InflowModelType = (StabilityPointStructureInflowModelType) new ConfigurationStabilityPointStructuresInflowModelTypeConverter() .ConvertTo(readCalculation.InflowModelType.Value, typeof(StabilityPointStructureInflowModelType)); } return true; } /// /// Sets the load schematization type. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when the load schematization type is invalid or when there is a /// load schematization type but no structure defined, true otherwise. private bool TrySetLoadSchematizationType(StabilityPointStructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) { if (readCalculation.LoadSchematizationType.HasValue) { if (calculation.InputParameters.Structure == null) { Log.LogCalculationConversionError(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_, Resources.CalculationConfigurationImporter_LoadSchematizationType_DisplayName), calculation.Name); return false; } calculation.InputParameters.LoadSchematizationType = (LoadSchematizationType) new ConfigurationStabilityPointStructuresLoadSchematizationTypeConverter() .ConvertTo(readCalculation.LoadSchematizationType.Value, typeof(LoadSchematizationType)); } return true; } /// /// Sets the levelling count. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when the levelling count is invalid or when there is a /// levelling count but no structure defined, true otherwise. private bool TrySetLevellingCount(StabilityPointStructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) { if (readCalculation.LevellingCount.HasValue) { if (calculation.InputParameters.Structure == null) { Log.LogCalculationConversionError(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_, Resources.CalculationConfigurationImporter_LevellingCount_DisplayName), calculation.Name); return false; } calculation.InputParameters.LevellingCount = readCalculation.LevellingCount.Value; } return true; } /// /// Sets the vertical distance. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when the vertical distance is invalid or when there is a /// vertical distance but no structure defined, true otherwise. private bool TrySetVerticalDistance(StabilityPointStructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) { if (readCalculation.VerticalDistance.HasValue) { if (calculation.InputParameters.Structure == null) { Log.LogCalculationConversionError(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_, Resources.CalculationConfigurationImporter_VerticalDistance_DisplayName), calculation.Name); return false; } calculation.InputParameters.VerticalDistance = (RoundedDouble) readCalculation.VerticalDistance.Value; } return true; } private bool TrySetHydraulicBoundaryLocation(string locationName, StructuresCalculation calculation) { HydraulicBoundaryLocation location; if (TryReadHydraulicBoundaryLocation(locationName, calculation.Name, availableHydraulicBoundaryLocations, out location)) { calculation.InputParameters.HydraulicBoundaryLocation = location; return true; } return false; } private bool TrySetStructure(string structureName, StructuresCalculation calculation) { StabilityPointStructure structure; if (TryReadStructure(structureName, calculation.Name, availableStructures, out structure)) { calculation.InputParameters.Structure = structure; return true; } return false; } private bool TrySetForeshoreProfile(string foreshoreProfileName, StructuresCalculation calculation) { ForeshoreProfile foreshoreProfile; if (TryReadForeshoreProfile(foreshoreProfileName, calculation.Name, availableForeshoreProfiles, out foreshoreProfile)) { calculation.InputParameters.ForeshoreProfile = foreshoreProfile; return true; } return false; } } }