Index: Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.IO/ClosingStructuresCalculationConfigurationReader.cs =================================================================== diff -u -r04a0742040ae09f8839510470014d2b273e67a78 -r9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 --- Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.IO/ClosingStructuresCalculationConfigurationReader.cs (.../ClosingStructuresCalculationConfigurationReader.cs) (revision 04a0742040ae09f8839510470014d2b273e67a78) +++ Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.IO/ClosingStructuresCalculationConfigurationReader.cs (.../ClosingStructuresCalculationConfigurationReader.cs) (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -23,17 +23,17 @@ using System.Collections.Generic; using System.Xml.Linq; using Core.Common.Base.IO; +using Ringtoets.ClosingStructures.IO.Properties; using Ringtoets.Common.IO.Configurations; using Ringtoets.Common.IO.Configurations.Helpers; using Ringtoets.Common.IO.Readers; using Ringtoets.Common.IO.Schema; -using Ringtoets.ClosingStructures.IO.Properties; using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources; namespace Ringtoets.ClosingStructures.IO { /// - /// Reader for reading a height structure calculation configuration from XML and creating a collection + /// Reader for reading a closing structure calculation configuration from XML and creating a collection /// of corresponding . /// public class ClosingStructuresCalculationConfigurationReader : CalculationConfigurationReader @@ -93,40 +93,36 @@ protected override ClosingStructuresCalculationConfiguration ParseCalculationElement(XElement calculationElement) { - var configuration = new ClosingStructuresCalculationConfiguration(calculationElement.Attribute(ConfigurationSchemaIdentifiers.NameAttribute).Value); - configuration.FailureProbabilityStructureWithErosion = calculationElement.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.FailureProbabilityStructureWithErosionElement); - configuration.StructureNormalOrientation = calculationElement.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.Orientation); + var configuration = new ClosingStructuresCalculationConfiguration(calculationElement.Attribute(ConfigurationSchemaIdentifiers.NameAttribute).Value) + { + FailureProbabilityStructureWithErosion = calculationElement.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.FailureProbabilityStructureWithErosionElement), + StructureNormalOrientation = calculationElement.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.Orientation), + InflowModelType = (ConfigurationClosingStructureInflowModelType?) + calculationElement.GetConvertedValueFromDescendantStringElement( + ClosingStructuresConfigurationSchemaIdentifiers.InflowModelType), + FactorStormDurationOpenStructure = calculationElement.GetDoubleValueFromDescendantElement(ClosingStructuresConfigurationSchemaIdentifiers.FactorStormDurationOpenStructure), + FailureProbabilityOpenStructure = calculationElement.GetDoubleValueFromDescendantElement(ClosingStructuresConfigurationSchemaIdentifiers.FailureProbabilityOpenStructure), + FailureProbabilityReparation = calculationElement.GetDoubleValueFromDescendantElement(ClosingStructuresConfigurationSchemaIdentifiers.FailureProbabilityReparation), + ProbabilityOrFrequencyOpenStructureBeforeFlooding = calculationElement.GetDoubleValueFromDescendantElement(ClosingStructuresConfigurationSchemaIdentifiers.ProbabilityOrFrequencyOpenStructureBeforeFlooding), + IdenticalApertures = calculationElement.GetIntegerValueFromDescendantElement(ClosingStructuresConfigurationSchemaIdentifiers.IdenticalApertures), + ForeshoreProfileName = calculationElement.GetStringValueFromDescendantElement(ConfigurationSchemaIdentifiers.ForeshoreProfileNameElement), + HydraulicBoundaryLocationName = calculationElement.GetStringValueFromDescendantElement(ConfigurationSchemaIdentifiers.HydraulicBoundaryLocationElement), + StructureName = calculationElement.GetStringValueFromDescendantElement(ConfigurationSchemaIdentifiers.StructureElement), + WaveReduction = GetWaveReductionParameters(calculationElement), + AreaFlowApertures = GetStandardDeviationStochastParameters(calculationElement, ClosingStructuresConfigurationSchemaIdentifiers.AreaFlowAperturesStochastName), + DrainCoefficient = GetStandardDeviationStochastParameters(calculationElement, ClosingStructuresConfigurationSchemaIdentifiers.DrainCoefficientStochastName), + InsideWaterLevel = GetStandardDeviationStochastParameters(calculationElement, ClosingStructuresConfigurationSchemaIdentifiers.InsideWaterLevelStochastName), + LevelCrestStructureNotClosing = GetStandardDeviationStochastParameters(calculationElement, ClosingStructuresConfigurationSchemaIdentifiers.LevelCrestStructureNotClosingStochastName), + ThresholdHeightOpenWeir = GetStandardDeviationStochastParameters(calculationElement, ClosingStructuresConfigurationSchemaIdentifiers.ThresholdHeightOpenWeirStochastName), + AllowedLevelIncreaseStorage = GetStandardDeviationStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.AllowedLevelIncreaseStorageStochastName), + FlowWidthAtBottomProtection = GetStandardDeviationStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.FlowWidthAtBottomProtectionStochastName), + ModelFactorSuperCriticalFlow = GetStandardDeviationStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.ModelFactorSuperCriticalFlowStochastName), + WidthFlowApertures = GetStandardDeviationStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.WidthFlowAperturesStochastName), + CriticalOvertoppingDischarge = GetVariationCoefficientStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.CriticalOvertoppingDischargeStochastName), + StorageStructureArea = GetVariationCoefficientStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.StorageStructureAreaStochastName), + StormDuration = GetVariationCoefficientStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.StormDurationStochastName) + }; - configuration.InflowModelType = (ConfigurationClosingStructureInflowModelType?) - calculationElement.GetConvertedValueFromDescendantStringElement( - ClosingStructuresConfigurationSchemaIdentifiers.InflowModelType); - configuration.FactorStormDurationOpenStructure = calculationElement.GetDoubleValueFromDescendantElement(ClosingStructuresConfigurationSchemaIdentifiers.FactorStormDurationOpenStructure); - configuration.FailureProbabilityOpenStructure = calculationElement.GetDoubleValueFromDescendantElement(ClosingStructuresConfigurationSchemaIdentifiers.FailureProbabilityOpenStructure); - configuration.FailureProbabilityReparation = calculationElement.GetDoubleValueFromDescendantElement(ClosingStructuresConfigurationSchemaIdentifiers.FailureProbabilityReparation); - configuration.ProbabilityOrFrequencyOpenStructureBeforeFlooding = calculationElement.GetDoubleValueFromDescendantElement(ClosingStructuresConfigurationSchemaIdentifiers.ProbabilityOrFrequencyOpenStructureBeforeFlooding); - configuration.IdenticalApertures = calculationElement.GetIntegerValueFromDescendantElement(ClosingStructuresConfigurationSchemaIdentifiers.IdenticalApertures); - - configuration.ForeshoreProfileName = calculationElement.GetStringValueFromDescendantElement(ConfigurationSchemaIdentifiers.ForeshoreProfileNameElement); - configuration.HydraulicBoundaryLocationName = calculationElement.GetStringValueFromDescendantElement(ConfigurationSchemaIdentifiers.HydraulicBoundaryLocationElement); - configuration.StructureName = calculationElement.GetStringValueFromDescendantElement(ConfigurationSchemaIdentifiers.StructureElement); - - configuration.WaveReduction = GetWaveReductionParameters(calculationElement); - - configuration.AreaFlowApertures = GetStandardDeviationStochastParameters(calculationElement, ClosingStructuresConfigurationSchemaIdentifiers.AreaFlowAperturesStochastName); - configuration.DrainCoefficient = GetStandardDeviationStochastParameters(calculationElement, ClosingStructuresConfigurationSchemaIdentifiers.DrainCoefficientStochastName); - configuration.InsideWaterLevel = GetStandardDeviationStochastParameters(calculationElement, ClosingStructuresConfigurationSchemaIdentifiers.InsideWaterLevelStochastName); - configuration.LevelCrestStructureNotClosing = GetStandardDeviationStochastParameters(calculationElement, ClosingStructuresConfigurationSchemaIdentifiers.LevelCrestStructureNotClosingStochastName); - configuration.ThresholdHeightOpenWeir = GetStandardDeviationStochastParameters(calculationElement, ClosingStructuresConfigurationSchemaIdentifiers.ThresholdHeightOpenWeirStochastName); - - configuration.AllowedLevelIncreaseStorage = GetStandardDeviationStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.AllowedLevelIncreaseStorageStochastName); - configuration.FlowWidthAtBottomProtection = GetStandardDeviationStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.FlowWidthAtBottomProtectionStochastName); - configuration.ModelFactorSuperCriticalFlow = GetStandardDeviationStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.ModelFactorSuperCriticalFlowStochastName); - configuration.WidthFlowApertures = GetStandardDeviationStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.WidthFlowAperturesStochastName); - - configuration.CriticalOvertoppingDischarge = GetVariationCoefficientStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.CriticalOvertoppingDischargeStochastName); - configuration.StorageStructureArea = GetVariationCoefficientStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.StorageStructureAreaStochastName); - configuration.StormDuration = GetVariationCoefficientStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.StormDurationStochastName); - return configuration; } Index: Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresCalculationConfiguration.cs =================================================================== diff -u --- Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresCalculationConfiguration.cs (revision 0) +++ Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresCalculationConfiguration.cs (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -0,0 +1,44 @@ +// 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 Ringtoets.Common.IO.Configurations; + +namespace Ringtoets.HeightStructures.IO.Configurations +{ + /// + /// Configuration of a height structure calculation. + /// + public class HeightStructuresCalculationConfiguration : StructuresCalculationConfiguration + { + /// + /// Creates a new instance of . + /// + /// The name of the . + /// Thrown when is null. + public HeightStructuresCalculationConfiguration(string name) : base(name) {} + + /// + /// Gets or sets the stochast configuration for the crest level for the structure. + /// + public MeanStandardDeviationStochastConfiguration LevelCrestStructure { get; set; } + } +} \ No newline at end of file Index: Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresCalculationConfigurationExporter.cs =================================================================== diff -u --- Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresCalculationConfigurationExporter.cs (revision 0) +++ Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresCalculationConfigurationExporter.cs (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -0,0 +1,94 @@ +// 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 Ringtoets.Common.Data.Calculation; +using Ringtoets.Common.Data.Structures; +using Ringtoets.Common.IO.Configurations; +using Ringtoets.Common.IO.Configurations.Helpers; +using Ringtoets.Common.IO.Exporters; +using Ringtoets.HeightStructures.Data; + +namespace Ringtoets.HeightStructures.IO.Configurations +{ + /// + /// Exports a height structures calculation configuration and stores it as an XML file. + /// + public class HeightStructuresCalculationConfigurationExporter : SchemaCalculationConfigurationExporter< + HeightStructuresCalculationConfigurationWriter, + StructuresCalculation, + HeightStructuresCalculationConfiguration> + { + /// + /// Creates a new instance of . + /// + /// The calculation configuration to export. + /// The path of the XML file to export to. + /// Thrown when is null. + /// Thrown when is invalid. + public HeightStructuresCalculationConfigurationExporter(IEnumerable calculations, string filePath) : base(calculations, filePath) {} + + protected override HeightStructuresCalculationConfiguration ToConfiguration(StructuresCalculation calculation) + { + HeightStructuresInput input = calculation.InputParameters; + var calculationConfiguration = new HeightStructuresCalculationConfiguration(calculation.Name); + + calculationConfiguration.HydraulicBoundaryLocationName = input.HydraulicBoundaryLocation?.Name; + + if (input.Structure != null) + { + calculationConfiguration.StructureName = input.Structure.Name; + calculationConfiguration.StructureNormalOrientation = input.StructureNormalOrientation; + calculationConfiguration.FailureProbabilityStructureWithErosion = input.FailureProbabilityStructureWithErosion; + + calculationConfiguration.FlowWidthAtBottomProtection = input.FlowWidthAtBottomProtection.ToStochastConfiguration(); + calculationConfiguration.WidthFlowApertures = input.WidthFlowApertures.ToStochastConfiguration(); + calculationConfiguration.StorageStructureArea = input.StorageStructureArea.ToStochastConfiguration(); + calculationConfiguration.AllowedLevelIncreaseStorage = input.AllowedLevelIncreaseStorage.ToStochastConfiguration(); + calculationConfiguration.LevelCrestStructure = input.LevelCrestStructure.ToStochastConfiguration(); + calculationConfiguration.CriticalOvertoppingDischarge = input.CriticalOvertoppingDischarge.ToStochastConfiguration(); + } + + if (input.ForeshoreProfile != null) + { + calculationConfiguration.ForeshoreProfileName = input.ForeshoreProfile?.Name; + calculationConfiguration.WaveReduction = new WaveReductionConfiguration + { + UseForeshoreProfile = input.UseForeshore, + UseBreakWater = input.UseBreakWater, + BreakWaterType = (ConfigurationBreakWaterType?) new ConfigurationBreakWaterTypeConverter().ConvertFrom(input.BreakWater.Type), + BreakWaterHeight = input.BreakWater.Height + }; + } + + calculationConfiguration.StormDuration = input.StormDuration.ToStochastConfigurationWithMean(); + calculationConfiguration.ModelFactorSuperCriticalFlow = input.ModelFactorSuperCriticalFlow.ToStochastConfigurationWithMean(); + + return calculationConfiguration; + } + + protected override HeightStructuresCalculationConfigurationWriter CreateWriter(string filePath) + { + return new HeightStructuresCalculationConfigurationWriter(filePath); + } + } +} \ No newline at end of file Index: Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresCalculationConfigurationImporter.cs =================================================================== diff -u --- Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresCalculationConfigurationImporter.cs (revision 0) +++ Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresCalculationConfigurationImporter.cs (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -0,0 +1,379 @@ +// 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.Probabilistics; +using Ringtoets.Common.Data.Structures; +using Ringtoets.Common.IO.Configurations; +using Ringtoets.Common.IO.Configurations.Helpers; +using Ringtoets.Common.IO.FileImporters; +using Ringtoets.Common.IO.Schema; +using Ringtoets.HeightStructures.Data; +using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources; + +namespace Ringtoets.HeightStructures.IO.Configurations +{ + /// + /// Class for importing a configuration of from an XML file and storing + /// it on a . + /// + public class HeightStructuresCalculationConfigurationImporter + : CalculationConfigurationImporter + { + 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 parameter is null. + public HeightStructuresCalculationConfigurationImporter( + 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 HeightStructuresCalculationConfigurationReader CreateCalculationConfigurationReader(string xmlFilePath) + { + return new HeightStructuresCalculationConfigurationReader(xmlFilePath); + } + + protected override ICalculation ParseReadCalculation(HeightStructuresCalculationConfiguration readCalculation) + { + var calculation = new StructuresCalculation + { + Name = readCalculation.Name + }; + + if (TryReadStructure(readCalculation.StructureName, calculation) + && TryReadHydraulicBoundaryLocation(readCalculation.HydraulicBoundaryLocationName, calculation) + && TryReadForeshoreProfile(readCalculation.ForeshoreProfileName, calculation) + && TryReadStochasts(readCalculation, calculation) + && TryReadOrientation(readCalculation, calculation) + && TryReadFailureProbabilityStructureWithErosion(readCalculation, calculation) + && ValidateWaveReduction(readCalculation.WaveReduction, calculation.InputParameters.ForeshoreProfile, calculation.Name)) + { + ReadWaveReductionParameters(readCalculation.WaveReduction, calculation.InputParameters); + return calculation; + } + return null; + } + + private bool TryReadStochasts(HeightStructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) + { + if (!ValidateStochasts(readCalculation)) + { + return false; + } + + return TryReadStandardDeviationStochast( + calculation, + HeightStructuresConfigurationSchemaIdentifiers.LevelCrestStructureStochastName, + readCalculation.LevelCrestStructure, + i => i.LevelCrestStructure, + (i, d) => i.LevelCrestStructure = d) + && TryReadStandardDeviationStochast( + calculation, + ConfigurationSchemaIdentifiers.AllowedLevelIncreaseStorageStochastName, + readCalculation.AllowedLevelIncreaseStorage, + i => i.AllowedLevelIncreaseStorage, + (i, d) => i.AllowedLevelIncreaseStorage = d) + && TryReadStandardDeviationStochast( + calculation, + ConfigurationSchemaIdentifiers.FlowWidthAtBottomProtectionStochastName, + readCalculation.FlowWidthAtBottomProtection, + i => i.FlowWidthAtBottomProtection, + (i, d) => i.FlowWidthAtBottomProtection = d) + && TryReadStandardDeviationStochast( + calculation, + ConfigurationSchemaIdentifiers.ModelFactorSuperCriticalFlowStochastName, + readCalculation.ModelFactorSuperCriticalFlow, + i => i.ModelFactorSuperCriticalFlow, + (i, d) => i.ModelFactorSuperCriticalFlow = d) + && TryReadStandardDeviationStochast( + calculation, + ConfigurationSchemaIdentifiers.WidthFlowAperturesStochastName, + readCalculation.WidthFlowApertures, + i => i.WidthFlowApertures, + (i, d) => i.WidthFlowApertures = d) + && TryReadVariationCoefficientStochast( + calculation, + ConfigurationSchemaIdentifiers.CriticalOvertoppingDischargeStochastName, + readCalculation.CriticalOvertoppingDischarge, + i => i.CriticalOvertoppingDischarge, + (i, d) => i.CriticalOvertoppingDischarge = d) + && TryReadVariationCoefficientStochast( + calculation, + ConfigurationSchemaIdentifiers.StorageStructureAreaStochastName, + readCalculation.StorageStructureArea, + i => i.StorageStructureArea, + (i, d) => i.StorageStructureArea = d) + && TryReadVariationCoefficientStochast( + calculation, + ConfigurationSchemaIdentifiers.StormDurationStochastName, + readCalculation.StormDuration, + i => i.StormDuration, + (i, d) => i.StormDuration = d); + } + + private bool ValidateStochasts(HeightStructuresCalculationConfiguration readCalculation) + { + if (readCalculation.StormDuration?.VariationCoefficient != null) + { + LogReadCalculationConversionError("Er kan geen variatiecoëfficiënt voor stochast 'stormduur' opgegeven worden.", readCalculation.Name); + return false; + } + if (readCalculation.ModelFactorSuperCriticalFlow?.StandardDeviation != null) + { + LogReadCalculationConversionError("Er kan geen standaardafwijking voor stochast 'modelfactoroverloopdebiet' opgegeven worden.", readCalculation.Name); + return false; + } + return true; + } + + /// + /// Reads the stochast parameters. + /// + /// The calculation to configure. + /// The stochast's name. + /// The configuration of the stochast. + /// The function for obtaining the stochast to read. + /// The function to set the stochast with the read parameters. + /// true if reading all required stochast parameters was successful, + /// false otherwise. + private bool TryReadStandardDeviationStochast( + StructuresCalculation calculation, + string stochastName, + MeanStandardDeviationStochastConfiguration stochastConfiguration, + Func getStochast, + Action setStochast) + where T : IDistribution + { + if (stochastConfiguration == null) + { + return true; + } + var distribution = (T) getStochast(calculation.InputParameters).Clone(); + + if (!distribution.TrySetDistributionProperties(stochastConfiguration, + stochastName, + calculation.Name)) + { + return false; + } + setStochast(calculation.InputParameters, distribution); + return true; + } + + /// + /// Reads the stochast parameters. + /// + /// The calculation to configure. + /// The stochast's name. + /// The configuration of the stochast. + /// The function for obtaining the stochast to read. + /// The function to set the stochast with the read parameters. + /// true if reading all required stochast parameters was successful, + /// false otherwise. + private bool TryReadVariationCoefficientStochast( + StructuresCalculation calculation, + string stochastName, + MeanVariationCoefficientStochastConfiguration stochastConfiguration, + Func getStochast, + Action setStochast) + where T : IVariationCoefficientDistribution + { + if (stochastConfiguration == null) + { + return true; + } + var distribution = (T) getStochast(calculation.InputParameters).Clone(); + + if (!distribution.TrySetDistributionProperties(stochastConfiguration, + stochastName, + calculation.Name)) + { + return false; + } + setStochast(calculation.InputParameters, distribution); + return true; + } + + /// + /// Reads the orientation. + /// + /// The calculation read from the imported file. + /// The calculation to configure. + /// false when the orientation is invalid or when there is an orientation but + /// no structure defined, true otherwise. + private bool TryReadOrientation(StructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) + { + if (readCalculation.StructureNormalOrientation.HasValue) + { + if (calculation.InputParameters.Structure == null) + { + LogReadCalculationConversionError( + 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) + { + LogOutOfRangeException( + string.Format(RingtoetsCommonIOResources.TryReadParameter_Value_0_ParameterName_1_is_invalid, + orientation, + RingtoetsCommonIOResources.CalculationConfigurationImporter_Orientation_DisplayName), + calculation.Name, + e); + + return false; + } + } + + return true; + } + + /// + /// Reads 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 TryReadFailureProbabilityStructureWithErosion(StructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) + { + if (readCalculation.FailureProbabilityStructureWithErosion.HasValue) + { + if (calculation.InputParameters.Structure == null) + { + LogReadCalculationConversionError( + string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_, + RingtoetsCommonIOResources.CalculationConfigurationImporter_FailureProbabilityStructureWithErosion_DisplayName), + calculation.Name); + + return false; + } + + double failureProbability = readCalculation.FailureProbabilityStructureWithErosion.Value; + + try + { + calculation.InputParameters.FailureProbabilityStructureWithErosion = (RoundedDouble) failureProbability; + } + catch (ArgumentOutOfRangeException e) + { + LogOutOfRangeException( + string.Format( + RingtoetsCommonIOResources.TryReadParameter_Value_0_ParameterName_1_is_invalid, + failureProbability, + RingtoetsCommonIOResources.CalculationConfigurationImporter_FailureProbabilityStructureWithErosion_DisplayName), + calculation.Name, + e); + + return false; + } + } + + return true; + } + + private bool TryReadHydraulicBoundaryLocation(string locationName, StructuresCalculation calculation) + { + HydraulicBoundaryLocation location; + + if (TryReadHydraulicBoundaryLocation(locationName, calculation.Name, availableHydraulicBoundaryLocations, out location)) + { + calculation.InputParameters.HydraulicBoundaryLocation = location; + return true; + } + + return false; + } + + private bool TryReadStructure(string structureName, StructuresCalculation calculation) + { + HeightStructure structure; + + if (TryReadStructure(structureName, calculation.Name, availableStructures, out structure)) + { + calculation.InputParameters.Structure = structure; + return true; + } + + return false; + } + + private bool TryReadForeshoreProfile(string foreshoreProfileName, StructuresCalculation calculation) + { + ForeshoreProfile foreshoreProfile; + + if (TryReadForeshoreProfile(foreshoreProfileName, calculation.Name, availableForeshoreProfiles, out foreshoreProfile)) + { + calculation.InputParameters.ForeshoreProfile = foreshoreProfile; + return true; + } + + return false; + } + } +} \ No newline at end of file Index: Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresCalculationConfigurationReader.cs =================================================================== diff -u --- Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresCalculationConfigurationReader.cs (revision 0) +++ Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresCalculationConfigurationReader.cs (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -0,0 +1,163 @@ +// 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 System.Xml.Linq; +using Core.Common.Base.IO; +using Ringtoets.Common.IO.Configurations; +using Ringtoets.Common.IO.Configurations.Helpers; +using Ringtoets.Common.IO.Readers; +using Ringtoets.Common.IO.Schema; +using Ringtoets.HeightStructures.IO.Properties; +using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources; + +namespace Ringtoets.HeightStructures.IO.Configurations +{ + /// + /// Reader for reading a height structure calculation configuration from XML and creating a collection + /// of corresponding . + /// + public class HeightStructuresCalculationConfigurationReader : CalculationConfigurationReader + { + private const string hrLocatieSchemaName = "HrLocatieSchema.xsd"; + private const string orientatieSchemaName = "OrientatieSchema.xsd"; + private const string golfReductieSchemaName = "GolfReductieSchema.xsd"; + private const string voorlandProfielSchemaName = "VoorlandProfielSchema.xsd"; + private const string stochastSchemaName = "StochastSchema.xsd"; + private const string stochastStandaardafwijkingSchemaName = "StochastStandaardafwijkingSchema.xsd"; + private const string stochastVariatiecoefficientSchemaName = "StochastVariatiecoefficientSchema.xsd"; + private const string structureBaseSchemaName = "KunstwerkenBasisSchema.xsd"; + + /// + /// Creates a new instance of . + /// + /// The file path to the XML file. + /// Thrown when is invalid. + /// Thrown when: + /// + /// points to a file that does not exist. + /// points to a file that does not contain valid XML. + /// points to a file that does not pass the schema validation. + /// points to a file that does not contain configuration elements. + /// + /// + public HeightStructuresCalculationConfigurationReader(string filePath) + : base(filePath, + Resources.KunstwerkenHoogteSchema, + new Dictionary + { + { + hrLocatieSchemaName, RingtoetsCommonIOResources.HrLocatieSchema + }, + { + orientatieSchemaName, RingtoetsCommonIOResources.OrientatieSchema + }, + { + voorlandProfielSchemaName, RingtoetsCommonIOResources.VoorlandProfielSchema + }, + { + golfReductieSchemaName, RingtoetsCommonIOResources.GolfReductieSchema + }, + { + stochastSchemaName, RingtoetsCommonIOResources.StochastSchema + }, + { + stochastStandaardafwijkingSchemaName, RingtoetsCommonIOResources.StochastStandaardafwijkingSchema + }, + { + stochastVariatiecoefficientSchemaName, RingtoetsCommonIOResources.StochastVariatiecoefficientSchema + }, + { + structureBaseSchemaName, RingtoetsCommonIOResources.KunstwerkenBasisSchema + } + }) {} + + protected override HeightStructuresCalculationConfiguration ParseCalculationElement(XElement calculationElement) + { + var configuration = new HeightStructuresCalculationConfiguration(calculationElement.Attribute(ConfigurationSchemaIdentifiers.NameAttribute).Value); + configuration.FailureProbabilityStructureWithErosion = calculationElement.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.FailureProbabilityStructureWithErosionElement); + configuration.StructureNormalOrientation = calculationElement.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.Orientation); + + configuration.ForeshoreProfileName = calculationElement.GetStringValueFromDescendantElement(ConfigurationSchemaIdentifiers.ForeshoreProfileNameElement); + configuration.HydraulicBoundaryLocationName = calculationElement.GetStringValueFromDescendantElement(ConfigurationSchemaIdentifiers.HydraulicBoundaryLocationElement); + configuration.StructureName = calculationElement.GetStringValueFromDescendantElement(ConfigurationSchemaIdentifiers.StructureElement); + + configuration.WaveReduction = GetWaveReductionParameters(calculationElement); + + configuration.LevelCrestStructure = GetStandardDeviationStochastParameters(calculationElement, HeightStructuresConfigurationSchemaIdentifiers.LevelCrestStructureStochastName); + configuration.AllowedLevelIncreaseStorage = GetStandardDeviationStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.AllowedLevelIncreaseStorageStochastName); + configuration.FlowWidthAtBottomProtection = GetStandardDeviationStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.FlowWidthAtBottomProtectionStochastName); + configuration.ModelFactorSuperCriticalFlow = GetStandardDeviationStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.ModelFactorSuperCriticalFlowStochastName); + configuration.WidthFlowApertures = GetStandardDeviationStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.WidthFlowAperturesStochastName); + + configuration.CriticalOvertoppingDischarge = GetVariationCoefficientStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.CriticalOvertoppingDischargeStochastName); + configuration.StorageStructureArea = GetVariationCoefficientStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.StorageStructureAreaStochastName); + configuration.StormDuration = GetVariationCoefficientStochastParameters(calculationElement, ConfigurationSchemaIdentifiers.StormDurationStochastName); + + return configuration; + } + + private static WaveReductionConfiguration GetWaveReductionParameters(XElement calculationElement) + { + XElement waveReduction = calculationElement.GetDescendantElement(ConfigurationSchemaIdentifiers.WaveReduction); + if (waveReduction != null) + { + return new WaveReductionConfiguration + { + BreakWaterType = (ConfigurationBreakWaterType?) calculationElement.GetConvertedValueFromDescendantStringElement(ConfigurationSchemaIdentifiers.BreakWaterType), + BreakWaterHeight = calculationElement.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.BreakWaterHeight), + UseBreakWater = calculationElement.GetBoolValueFromDescendantElement(ConfigurationSchemaIdentifiers.UseBreakWater), + UseForeshoreProfile = calculationElement.GetBoolValueFromDescendantElement(ConfigurationSchemaIdentifiers.UseForeshore) + }; + } + return null; + } + + private static MeanVariationCoefficientStochastConfiguration GetVariationCoefficientStochastParameters(XElement calculationElement, string stochastName) + { + XElement element = calculationElement.GetStochastElement(stochastName); + if (element != null) + { + return new MeanVariationCoefficientStochastConfiguration + { + Mean = element.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.MeanElement), + VariationCoefficient = element.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.VariationCoefficientElement) + }; + } + return null; + } + + private static MeanStandardDeviationStochastConfiguration GetStandardDeviationStochastParameters(XElement calculationElement, string stochastName) + { + XElement element = calculationElement.GetStochastElement(stochastName); + if (element != null) + { + return new MeanStandardDeviationStochastConfiguration + { + Mean = element.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.MeanElement), + StandardDeviation = element.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.StandardDeviationElement) + }; + } + return null; + } + } +} \ No newline at end of file Index: Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresCalculationConfigurationWriter.cs =================================================================== diff -u --- Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresCalculationConfigurationWriter.cs (revision 0) +++ Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresCalculationConfigurationWriter.cs (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -0,0 +1,54 @@ +// 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.Xml; +using Ringtoets.Common.IO.Writers; + +namespace Ringtoets.HeightStructures.IO.Configurations +{ + /// + /// Writer for writing in XML format to file. + /// + public class HeightStructuresCalculationConfigurationWriter : StructureCalculationConfigurationWriter + { + /// + /// Creates a new instance of . + /// + /// The path of the file to write to. + /// Thrown when is invalid. + /// A valid path: + /// + /// is not empty or null, + /// does not consist out of only whitespace characters, + /// does not contain an invalid character, + /// does not end with a directory or path separator (empty file name). + /// + public HeightStructuresCalculationConfigurationWriter(string filePath) : base(filePath) {} + + protected override void WriteSpecificStochasts(HeightStructuresCalculationConfiguration configuration, XmlWriter writer) + { + WriteDistributionWhenAvailable(writer, + HeightStructuresConfigurationSchemaIdentifiers.LevelCrestStructureStochastName, + configuration.LevelCrestStructure); + } + } +} \ No newline at end of file Index: Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresConfigurationSchemaIdentifiers.cs =================================================================== diff -u --- Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresConfigurationSchemaIdentifiers.cs (revision 0) +++ Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Configurations/HeightStructuresConfigurationSchemaIdentifiers.cs (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -0,0 +1,38 @@ +// 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. + +namespace Ringtoets.HeightStructures.IO.Configurations +{ + /// + /// Container of identifiers related to height structure calculation configuration schema definitions. + /// + public static class HeightStructuresConfigurationSchemaIdentifiers + { + #region stochasts + + /// + /// The identifier for the level crest structure stochast name. + /// + public const string LevelCrestStructureStochastName = "kerendehoogte"; + + #endregion + } +} \ No newline at end of file Fisheye: Tag 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 refers to a dead (removed) revision in file `Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/HeightStructuresCalculationConfiguration.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 refers to a dead (removed) revision in file `Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/HeightStructuresCalculationConfigurationExporter.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 refers to a dead (removed) revision in file `Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/HeightStructuresCalculationConfigurationImporter.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 refers to a dead (removed) revision in file `Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/HeightStructuresCalculationConfigurationReader.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 refers to a dead (removed) revision in file `Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/HeightStructuresCalculationConfigurationWriter.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 refers to a dead (removed) revision in file `Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/HeightStructuresConfigurationSchemaIdentifiers.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Ringtoets.HeightStructures.IO.csproj =================================================================== diff -u -r5b07686bb3f89f1fa1017c4bf2cf8964ae9bd95c -r9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 --- Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Ringtoets.HeightStructures.IO.csproj (.../Ringtoets.HeightStructures.IO.csproj) (revision 5b07686bb3f89f1fa1017c4bf2cf8964ae9bd95c) +++ Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/Ringtoets.HeightStructures.IO.csproj (.../Ringtoets.HeightStructures.IO.csproj) (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -45,12 +45,12 @@ Properties\GlobalAssembly.cs - - - - - - + + + + + + Index: Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.Plugin/HeightStructuresPlugin.cs =================================================================== diff -u -rb25389d952b8ac86e61c5e822124b2c250ae3e55 -r9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 --- Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.Plugin/HeightStructuresPlugin.cs (.../HeightStructuresPlugin.cs) (revision b25389d952b8ac86e61c5e822124b2c250ae3e55) +++ Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.Plugin/HeightStructuresPlugin.cs (.../HeightStructuresPlugin.cs) (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -49,6 +49,7 @@ using Ringtoets.HeightStructures.Forms.PropertyClasses; using Ringtoets.HeightStructures.Forms.Views; using Ringtoets.HeightStructures.IO; +using Ringtoets.HeightStructures.IO.Configurations; using Ringtoets.HeightStructures.Service; using RingtoetsCommonFormsResources = Ringtoets.Common.Forms.Properties.Resources; using RingtoetsCommonDataResources = Ringtoets.Common.Data.Properties.Resources; Index: Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Configurations/HeightStructuresCalculationConfigurationExporterTest.cs =================================================================== diff -u --- Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Configurations/HeightStructuresCalculationConfigurationExporterTest.cs (revision 0) +++ Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Configurations/HeightStructuresCalculationConfigurationExporterTest.cs (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -0,0 +1,237 @@ +// 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.Collections.Generic; +using System.IO; +using Core.Common.Base.Data; +using Core.Common.TestUtil; +using NUnit.Framework; +using Ringtoets.Common.Data.Calculation; +using Ringtoets.Common.Data.DikeProfiles; +using Ringtoets.Common.Data.Probabilistics; +using Ringtoets.Common.Data.Structures; +using Ringtoets.Common.Data.TestUtil; +using Ringtoets.Common.IO.TestUtil; +using Ringtoets.HeightStructures.Data; +using Ringtoets.HeightStructures.Data.TestUtil; +using Ringtoets.HeightStructures.IO.Configurations; + +namespace Ringtoets.HeightStructures.IO.Test.Configurations +{ + [TestFixture] + public class HeightStructuresCalculationConfigurationExporterTest + : CustomSchemaCalculationConfigurationExporterDesignGuidelinesTestFixture< + HeightStructuresCalculationConfigurationExporter, + HeightStructuresCalculationConfigurationWriter, + StructuresCalculation, + HeightStructuresCalculationConfiguration> + { + private static IEnumerable Calculations + { + get + { + yield return new TestCaseData("completeConfiguration", new[] + { + CreateFullCalculation() + }) + .SetName("Calculation configuration with all parameters set"); + yield return new TestCaseData("sparseConfiguration", new[] + { + CreateSparseCalculation() + }) + .SetName("Calculation configuration with none of its parameters set"); + yield return new TestCaseData("configurationWithStructure", new[] + { + CreateCalculationWithStructure() + }) + .SetName("Calculation configuration with a structure set"); + yield return new TestCaseData("configurationWithForeshoreProfile", new[] + { + CreateCalculationWithForeshoreProfile() + }) + .SetName("Calculation configuration with foreshore profile"); + yield return new TestCaseData("configurationWithUseBreakWater", new[] + { + CreateCalculationWithUseBreakWater() + }) + .SetName("Calculation configuration with use breakwater true"); + yield return new TestCaseData("folderWithSubfolderAndCalculation", new[] + { + new CalculationGroup("Testmap", false) + { + Children = + { + CreateFullCalculation(), + new CalculationGroup("Nested", false) + { + Children = + { + CreateSparseCalculation() + } + } + } + } + }) + .SetName("Calculation configuration with hierarchy"); + } + } + + [Test] + [TestCaseSource(nameof(Calculations))] + public void Export_ValidData_ReturnTrueAndWritesFile(string fileName, ICalculationBase[] calculations) + { + // Setup + string testDirectory = TestHelper.GetTestDataPath( + TestDataPath.Ringtoets.HeightStructures.IO, + nameof(HeightStructuresCalculationConfigurationExporter)); + + string expectedXmlFilePath = Path.Combine(testDirectory, $"{fileName}.xml"); + + // Call and Assert + WriteAndValidate(calculations, expectedXmlFilePath); + } + + private static ICalculation CreateSparseCalculation() + { + return new StructuresCalculation + { + Name = "sparse config" + }; + } + + private static StructuresCalculation CreateFullCalculation() + { + return new TestHeightStructuresCalculation + { + Name = "full config", + InputParameters = + { + HydraulicBoundaryLocation = new TestHydraulicBoundaryLocation("Locatie1"), + Structure = new TestHeightStructure("kunstwerk1"), + ForeshoreProfile = new TestForeshoreProfile("profiel1"), + FailureProbabilityStructureWithErosion = 1e-6, + StructureNormalOrientation = (RoundedDouble) 67.1, + UseBreakWater = true, + UseForeshore = true, + BreakWater = + { + Type = BreakWaterType.Dam, + Height = (RoundedDouble) 1.234 + }, + StormDuration = new VariationCoefficientLogNormalDistribution + { + Mean = (RoundedDouble) 6.0, + CoefficientOfVariation = (RoundedDouble) 1.2222 + }, + ModelFactorSuperCriticalFlow = new NormalDistribution + { + Mean = (RoundedDouble) 1.10, + StandardDeviation = (RoundedDouble) 1.2222 + }, + FlowWidthAtBottomProtection = new LogNormalDistribution + { + Mean = (RoundedDouble) 15.2, + StandardDeviation = (RoundedDouble) 0.1 + }, + WidthFlowApertures = new NormalDistribution + { + Mean = (RoundedDouble) 13.2, + StandardDeviation = (RoundedDouble) 0.3 + }, + StorageStructureArea = new VariationCoefficientLogNormalDistribution + { + Mean = (RoundedDouble) 15000, + CoefficientOfVariation = (RoundedDouble) 0.01 + }, + AllowedLevelIncreaseStorage = new LogNormalDistribution + { + Mean = (RoundedDouble) 0.2, + StandardDeviation = (RoundedDouble) 0.01 + }, + LevelCrestStructure = new NormalDistribution + { + Mean = (RoundedDouble) 4.3, + StandardDeviation = (RoundedDouble) 0.2 + }, + CriticalOvertoppingDischarge = new VariationCoefficientLogNormalDistribution + { + Mean = (RoundedDouble) 2, + CoefficientOfVariation = (RoundedDouble) 0.1 + } + } + }; + } + + private static StructuresCalculation CreateCalculationWithForeshoreProfile() + { + return new StructuresCalculation + { + Name = "with foreshore profile", + InputParameters = + { + ForeshoreProfile = new TestForeshoreProfile("profiel1"), + UseForeshore = true + } + }; + } + + private static StructuresCalculation CreateCalculationWithUseBreakWater() + { + return new StructuresCalculation + { + Name = "with use breakwater", + InputParameters = + { + ForeshoreProfile = new TestForeshoreProfile("profiel1"), + BreakWater = + { + Type = BreakWaterType.Caisson, + Height = (RoundedDouble) 1.23 + }, + UseBreakWater = true, + UseForeshore = false + } + }; + } + + private static StructuresCalculation CreateCalculationWithStructure() + { + return new StructuresCalculation + { + Name = "with structure", + InputParameters = + { + Structure = new TestHeightStructure("kunstwerk1"), + } + }; + } + + protected override StructuresCalculation CreateCalculation() + { + return new TestHeightStructuresCalculation(); + } + + protected override HeightStructuresCalculationConfigurationExporter CallConfigurationFilePathConstructor(IEnumerable calculations, string filePath) + { + return new HeightStructuresCalculationConfigurationExporter(calculations, filePath); + } + } +} \ No newline at end of file Index: Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Configurations/HeightStructuresCalculationConfigurationImporterTest.cs =================================================================== diff -u --- Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Configurations/HeightStructuresCalculationConfigurationImporterTest.cs (revision 0) +++ Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Configurations/HeightStructuresCalculationConfigurationImporterTest.cs (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -0,0 +1,517 @@ +// 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 System.IO; +using System.Linq; +using Core.Common.Base.Data; +using Core.Common.Base.Geometry; +using Core.Common.TestUtil; +using NUnit.Framework; +using Ringtoets.Common.Data.Calculation; +using Ringtoets.Common.Data.DikeProfiles; +using Ringtoets.Common.Data.Hydraulics; +using Ringtoets.Common.Data.Structures; +using Ringtoets.Common.Data.TestUtil; +using Ringtoets.Common.IO.FileImporters; +using Ringtoets.HeightStructures.Data; +using Ringtoets.HeightStructures.Data.TestUtil; +using Ringtoets.HeightStructures.IO.Configurations; + +namespace Ringtoets.HeightStructures.IO.Test.Configurations +{ + [TestFixture] + public class HeightStructuresCalculationConfigurationImporterTest + { + private readonly string importerPath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.HeightStructures.IO, nameof(HeightStructuresCalculationConfigurationImporter)); + + [Test] + public void Constructor_ExpectedValues() + { + // Call + var importer = new HeightStructuresCalculationConfigurationImporter("", + new CalculationGroup(), + Enumerable.Empty(), + Enumerable.Empty(), + Enumerable.Empty()); + + // Assert + Assert.IsInstanceOf>(importer); + } + + [Test] + public void Constructor_HydraulicBoundaryLocationsNull_ThrowArgumentNullException() + { + // Call + TestDelegate test = () => new HeightStructuresCalculationConfigurationImporter("", + new CalculationGroup(), + null, + Enumerable.Empty(), + Enumerable.Empty()); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("hydraulicBoundaryLocations", exception.ParamName); + } + + [Test] + public void Constructor_ForeshoreProfilesNull_ThrowArgumentNullException() + { + // Call + TestDelegate test = () => new HeightStructuresCalculationConfigurationImporter("", + new CalculationGroup(), + Enumerable.Empty(), + null, + Enumerable.Empty()); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("foreshoreProfiles", exception.ParamName); + } + + [Test] + public void Constructor_StructuresNull_ThrowArgumentNullException() + { + // Call + TestDelegate test = () => new HeightStructuresCalculationConfigurationImporter("", + new CalculationGroup(), + Enumerable.Empty(), + Enumerable.Empty(), + null); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("structures", exception.ParamName); + } + + [Test] + [SetCulture("nl-NL")] + [TestCase("validConfigurationModelFactorSuperCriticalFlowStandardDeviation.xml", + "Er kan geen standaardafwijking voor stochast 'modelfactoroverloopdebiet' opgegeven worden.")] + [TestCase("validConfigurationStormDurationVariationCoefficient.xml", + "Er kan geen variatiecoëfficiënt voor stochast 'stormduur' opgegeven worden.")] + [TestCase("validConfigurationFailureProbabilityStructureErosionWithoutStructure.xml", + "Er is geen kunstwerk opgegeven om de faalkans gegeven erosie bodem aan toe te voegen.")] + [TestCase("validConfigurationOrientationWithoutStructure.xml", + "Er is geen kunstwerk opgegeven om de oriëntatie aan toe te voegen.")] + [TestCase("validConfigurationInvalidFailureProbabilityStructureErosion.xml", + "Een waarde van '1,1' als faalkans gegeven erosie bodem is ongeldig. De waarde voor de faalkans moet in het bereik [0,0, 1,0] liggen.")] + [TestCase("validConfigurationInvalidOrientation.xml", + "Een waarde van '-12' als oriëntatie is ongeldig. De waarde voor de oriëntatie moet in het bereik [0,00, 360,00] liggen.")] + [TestCase("validConfigurationWaveReductionWithoutForeshoreProfile.xml", + "Er is geen voorlandprofiel opgegeven om golfreductie parameters aan toe te voegen.")] + [TestCase("validConfigurationInvalidAllowedLevelIncreaseStorageMean.xml", + "Een gemiddelde van '-0,2' is ongeldig voor stochast 'peilverhogingkomberging'. Gemiddelde moet groter zijn dan 0.")] + [TestCase("validConfigurationInvalidAllowedLevelIncreaseStorageStandardDeviation.xml", + "Een standaardafwijking van '-0,01' is ongeldig voor stochast 'peilverhogingkomberging'. Standaardafwijking (σ) moet groter zijn dan of gelijk zijn aan 0.")] + [TestCase("validConfigurationInvalidCriticalOvertoppingDischargeMean.xml", + "Een gemiddelde van '-2' is ongeldig voor stochast 'kritiekinstromenddebiet'. Gemiddelde moet groter zijn dan 0.")] + [TestCase("validConfigurationInvalidCriticalOvertoppingDischargeVariationCoefficient.xml", + "Een variatiecoëfficiënt van '-0,1' is ongeldig voor stochast 'kritiekinstromenddebiet'. Variatiecoëfficiënt (CV) moet groter zijn dan of gelijk zijn aan 0.")] + [TestCase("validConfigurationInvalidFlowWidthAtBottomProtectionMean.xml", + "Een gemiddelde van '-15,2' is ongeldig voor stochast 'breedtebodembescherming'. Gemiddelde moet groter zijn dan 0.")] + [TestCase("validConfigurationInvalidFlowWidthAtBottomProtectionStandardDeviation.xml", + "Een standaardafwijking van '-0,1' is ongeldig voor stochast 'breedtebodembescherming'. Standaardafwijking (σ) moet groter zijn dan of gelijk zijn aan 0.")] + [TestCase("validConfigurationInvalidLevelCrestStructureStandardDeviation.xml", + "Een standaardafwijking van '-0,1' is ongeldig voor stochast 'kerendehoogte'. Standaardafwijking (σ) moet groter zijn dan of gelijk zijn aan 0.")] + [TestCase("validConfigurationInvalidStorageStructureAreaMean.xml", + "Een gemiddelde van '-15000' is ongeldig voor stochast 'kombergendoppervlak'. Gemiddelde moet groter zijn dan 0.")] + [TestCase("validConfigurationInvalidStorageStructureAreaVariationCoefficient.xml", + "Een variatiecoëfficiënt van '-0,01' is ongeldig voor stochast 'kombergendoppervlak'. Variatiecoëfficiënt (CV) moet groter zijn dan of gelijk zijn aan 0.")] + [TestCase("validConfigurationInvalidStormDurationMean.xml", + "Een gemiddelde van '-6' is ongeldig voor stochast 'stormduur'. Gemiddelde moet groter zijn dan 0.")] + [TestCase("validConfigurationInvalidWidthFlowAperturesStandardDeviation.xml", + "Een standaardafwijking van '-0,1' is ongeldig voor stochast 'breedtedoorstroomopening'. Standaardafwijking (σ) moet groter zijn dan of gelijk zijn aan 0.")] + public void Import_ValidConfigurationInvalidData_LogMessageAndContinueImport(string file, string expectedErrorMessage) + { + // Setup + string filePath = Path.Combine(importerPath, file); + + var calculationGroup = new CalculationGroup(); + var structure = new TestHeightStructure("kunstwerk1"); + var foreshoreProfile = new TestForeshoreProfile("profiel 1"); + + var importer = new HeightStructuresCalculationConfigurationImporter(filePath, + calculationGroup, + Enumerable.Empty(), + new ForeshoreProfile[] + { + foreshoreProfile + }, + new HeightStructure[] + { + structure + }); + var successful = false; + + // Call + Action call = () => successful = importer.Import(); + + // Assert + string expectedMessage = $"{expectedErrorMessage} Berekening 'Berekening 1' is overgeslagen."; + TestHelper.AssertLogMessageWithLevelIsGenerated(call, Tuple.Create(expectedMessage, LogLevelConstant.Error), 1); + Assert.IsTrue(successful); + CollectionAssert.IsEmpty(calculationGroup.Children); + } + + [TestCase("validConfigurationUnknownForeshoreProfile.xml", + "Het voorlandprofiel 'unknown' bestaat niet.")] + [TestCase("validConfigurationUnknownHydraulicBoundaryLocation.xml", + "De locatie met hydraulische randvoorwaarden 'unknown' bestaat niet.")] + [TestCase("validConfigurationUnknownStructure.xml", + "Het kunstwerk 'unknown' bestaat niet.")] + public void Import_ValidConfigurationUnknownData_LogMessageAndContinueImport(string file, string expectedErrorMessage) + { + // Setup + string filePath = Path.Combine(importerPath, file); + + var calculationGroup = new CalculationGroup(); + + var importer = new HeightStructuresCalculationConfigurationImporter(filePath, + calculationGroup, + Enumerable.Empty(), + Enumerable.Empty(), + Enumerable.Empty()); + var successful = false; + + // Call + Action call = () => successful = importer.Import(); + + // Assert + string expectedMessage = $"{expectedErrorMessage} Berekening 'Berekening 1' is overgeslagen."; + TestHelper.AssertLogMessageWithLevelIsGenerated(call, Tuple.Create(expectedMessage, LogLevelConstant.Error), 1); + Assert.IsTrue(successful); + CollectionAssert.IsEmpty(calculationGroup.Children); + } + + [Test] + public void Import_UseForeshoreButForshoreProfileWithoutGeometry_LogMessageAndContinueImport() + { + // Setup + string filePath = Path.Combine(importerPath, "validConfigurationCalculationUseForeshoreWithoutGeometry.xml"); + + var calculationGroup = new CalculationGroup(); + var foreshoreProfile = new TestForeshoreProfile("Voorlandprofiel"); + var importer = new HeightStructuresCalculationConfigurationImporter( + filePath, + calculationGroup, + Enumerable.Empty(), + new[] + { + foreshoreProfile + }, + Enumerable.Empty()); + + var successful = false; + + // Call + Action call = () => successful = importer.Import(); + + // Assert + const string expectedMessage = "Het opgegeven voorlandprofiel 'Voorlandprofiel' heeft geen voorlandgeometrie en kan daarom niet gebruikt worden. Berekening 'Berekening 1' is overgeslagen."; + TestHelper.AssertLogMessageWithLevelIsGenerated(call, Tuple.Create(expectedMessage, LogLevelConstant.Error), 1); + Assert.IsTrue(successful); + CollectionAssert.IsEmpty(calculationGroup.Children); + } + + [Test] + public void Import_FullCalculationConfigruation_DataAddedToModel() + { + // Setup + string filePath = Path.Combine(importerPath, "validFullConfiguration.xml"); + + var calculationGroup = new CalculationGroup(); + var hydraulicBoundaryLocation = new TestHydraulicBoundaryLocation("Locatie1"); + var foreshoreProfile = new TestForeshoreProfile("profiel1", new List + { + new Point2D(0,3) + }); + var structure = new TestHeightStructure("kunstwerk1"); + var importer = new HeightStructuresCalculationConfigurationImporter( + filePath, + calculationGroup, + new[] + { + hydraulicBoundaryLocation + }, + new[] + { + foreshoreProfile + }, + new[] + { + structure + }); + + // Call + var successful = importer.Import(); + + // Assert + Assert.IsTrue(successful); + var expectedCalculation = new StructuresCalculation + { + Name = "Berekening 1", + InputParameters = + { + HydraulicBoundaryLocation = hydraulicBoundaryLocation, + Structure = structure, + ForeshoreProfile = foreshoreProfile, + StructureNormalOrientation = (RoundedDouble) 67.1, + FailureProbabilityStructureWithErosion = 1e-6, + UseBreakWater = true, + UseForeshore = true, + BreakWater = + { + Height = (RoundedDouble) 1.23, + Type = BreakWaterType.Dam + }, + StormDuration = + { + Mean = (RoundedDouble) 6.0 + }, + ModelFactorSuperCriticalFlow = + { + Mean = (RoundedDouble) 1.10 + }, + FlowWidthAtBottomProtection = + { + Mean = (RoundedDouble) 15.2, + StandardDeviation = (RoundedDouble) 0.1 + }, + WidthFlowApertures = + { + Mean = (RoundedDouble) 15.2, + StandardDeviation = (RoundedDouble) 0.1 + }, + StorageStructureArea = + { + Mean = (RoundedDouble) 15000, + CoefficientOfVariation = (RoundedDouble) 0.01 + }, + AllowedLevelIncreaseStorage = + { + Mean = (RoundedDouble) 0.2, + StandardDeviation = (RoundedDouble) 0.01 + }, + LevelCrestStructure = + { + Mean = (RoundedDouble) 4.3, + StandardDeviation = (RoundedDouble) 0.1 + }, + CriticalOvertoppingDischarge = + { + Mean = (RoundedDouble) 2, + CoefficientOfVariation = (RoundedDouble) 0.1 + } + } + }; + + Assert.AreEqual(1, calculationGroup.Children.Count); + AssertCalculation(expectedCalculation, (StructuresCalculation)calculationGroup.Children[0]); + } + + [Test] + public void Import_StochastWithMeanOnly_DataAddedToModel() + { + // Setup + string filePath = Path.Combine(importerPath, "validConfigurationStochastMeansOnly.xml"); + + var calculationGroup = new CalculationGroup(); + var structure = new TestHeightStructure("kunstwerk1"); + var importer = new HeightStructuresCalculationConfigurationImporter( + filePath, + calculationGroup, + Enumerable.Empty(), + Enumerable.Empty(), + new[] + { + structure + }); + + var expectedCalculation = new StructuresCalculation + { + Name = "Berekening 1", + InputParameters = + { + Structure = structure, + StormDuration = + { + Mean = (RoundedDouble) 6.0 + }, + ModelFactorSuperCriticalFlow = + { + Mean = (RoundedDouble) 1.10 + }, + FlowWidthAtBottomProtection = + { + Mean = (RoundedDouble) 15.2, + }, + WidthFlowApertures = + { + Mean = (RoundedDouble) 15.2, + }, + StorageStructureArea = + { + Mean = (RoundedDouble) 15000, + }, + AllowedLevelIncreaseStorage = + { + Mean = (RoundedDouble) 0.2, + }, + LevelCrestStructure = + { + Mean = (RoundedDouble) 4.3, + }, + CriticalOvertoppingDischarge = + { + Mean = (RoundedDouble) 2, + } + } + }; + + // Call + var successful = importer.Import(); + + // Assert + Assert.IsTrue(successful); + Assert.AreEqual(1, calculationGroup.Children.Count); + AssertCalculation(expectedCalculation, (StructuresCalculation)calculationGroup.Children[0]); + } + + [Test] + public void Import_StochastWithStandardDeviationOrVariationCoefficientOnly_DataAddedToModel() + { + // Setup + string filePath = Path.Combine(importerPath, "validConfigurationStochastStandardDeviationVariationCoefficientOnly.xml"); + + var calculationGroup = new CalculationGroup(); + var structure = new TestHeightStructure("kunstwerk1"); + var importer = new HeightStructuresCalculationConfigurationImporter( + filePath, + calculationGroup, + Enumerable.Empty(), + Enumerable.Empty(), + new[] + { + structure + }); + + var expectedCalculation = new StructuresCalculation + { + Name = "Berekening 1", + InputParameters = + { + Structure = structure, + FlowWidthAtBottomProtection = + { + StandardDeviation = (RoundedDouble) 0.1 + }, + WidthFlowApertures = + { + StandardDeviation = (RoundedDouble) 0.1 + }, + StorageStructureArea = + { + CoefficientOfVariation = (RoundedDouble) 0.01 + }, + AllowedLevelIncreaseStorage = + { + StandardDeviation = (RoundedDouble) 0.01 + }, + LevelCrestStructure = + { + StandardDeviation = (RoundedDouble) 0.1 + }, + CriticalOvertoppingDischarge = + { + CoefficientOfVariation = (RoundedDouble) 0.1 + } + } + }; + + // Call + var successful = importer.Import(); + + // Assert + Assert.IsTrue(successful); + Assert.AreEqual(1, calculationGroup.Children.Count); + AssertCalculation(expectedCalculation, (StructuresCalculation)calculationGroup.Children[0]); + } + + [Test] + [TestCase("validConfigurationEmptyCalculation.xml")] + [TestCase("validConfigurationEmptyStochasts.xml")] + [TestCase("validConfigurationEmptyStochastsElement.xml")] + [TestCase("validConfigurationEmptyWaveReduction.xml")] + public void Import_EmptyConfigurations_DataAddedToModel(string file) + { + // Setup + string filePath = Path.Combine(importerPath, file); + + var calculationGroup = new CalculationGroup(); + var structure = new TestHeightStructure("kunstwerk1"); + var importer = new HeightStructuresCalculationConfigurationImporter( + filePath, + calculationGroup, + Enumerable.Empty(), + Enumerable.Empty(), + new[] + { + structure + }); + + var expectedCalculation = new StructuresCalculation + { + Name = "Berekening 1" + }; + + // Call + var successful = importer.Import(); + + // Assert + Assert.IsTrue(successful); + Assert.AreEqual(1, calculationGroup.Children.Count); + AssertCalculation(expectedCalculation, (StructuresCalculation)calculationGroup.Children[0]); + } + + private static void AssertCalculation(StructuresCalculation expectedCalculation, StructuresCalculation actualCalculation) + { + Assert.AreEqual(expectedCalculation.Name, actualCalculation.Name); + Assert.AreSame(expectedCalculation.InputParameters.HydraulicBoundaryLocation, actualCalculation.InputParameters.HydraulicBoundaryLocation); + Assert.AreEqual(expectedCalculation.InputParameters.StructureNormalOrientation, actualCalculation.InputParameters.StructureNormalOrientation); + Assert.AreSame(expectedCalculation.InputParameters.ForeshoreProfile, actualCalculation.InputParameters.ForeshoreProfile); + Assert.AreSame(expectedCalculation.InputParameters.Structure, actualCalculation.InputParameters.Structure); + Assert.AreEqual(expectedCalculation.InputParameters.UseForeshore, actualCalculation.InputParameters.UseForeshore); + Assert.AreEqual(expectedCalculation.InputParameters.UseBreakWater, actualCalculation.InputParameters.UseBreakWater); + Assert.AreEqual(expectedCalculation.InputParameters.BreakWater.Height, actualCalculation.InputParameters.BreakWater.Height); + Assert.AreEqual(expectedCalculation.InputParameters.BreakWater.Type, actualCalculation.InputParameters.BreakWater.Type); + DistributionAssert.AreEqual(expectedCalculation.InputParameters.LevelCrestStructure, actualCalculation.InputParameters.LevelCrestStructure); + DistributionAssert.AreEqual(expectedCalculation.InputParameters.AllowedLevelIncreaseStorage, actualCalculation.InputParameters.AllowedLevelIncreaseStorage); + DistributionAssert.AreEqual(expectedCalculation.InputParameters.FlowWidthAtBottomProtection, actualCalculation.InputParameters.FlowWidthAtBottomProtection); + DistributionAssert.AreEqual(expectedCalculation.InputParameters.ModelFactorSuperCriticalFlow, actualCalculation.InputParameters.ModelFactorSuperCriticalFlow); + DistributionAssert.AreEqual(expectedCalculation.InputParameters.CriticalOvertoppingDischarge, actualCalculation.InputParameters.CriticalOvertoppingDischarge); + DistributionAssert.AreEqual(expectedCalculation.InputParameters.StorageStructureArea, actualCalculation.InputParameters.StorageStructureArea); + DistributionAssert.AreEqual(expectedCalculation.InputParameters.StormDuration, actualCalculation.InputParameters.StormDuration); + DistributionAssert.AreEqual(expectedCalculation.InputParameters.WidthFlowApertures, actualCalculation.InputParameters.WidthFlowApertures); + } + } +} \ No newline at end of file Index: Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Configurations/HeightStructuresCalculationConfigurationReaderTest.cs =================================================================== diff -u --- Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Configurations/HeightStructuresCalculationConfigurationReaderTest.cs (revision 0) +++ Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Configurations/HeightStructuresCalculationConfigurationReaderTest.cs (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -0,0 +1,484 @@ +// 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.Collections.Generic; +using Core.Common.TestUtil; +using NUnit.Framework; +using Ringtoets.Common.IO.Readers; +using System.IO; +using System.Linq; +using System.Xml.Schema; +using Core.Common.Base.IO; +using Ringtoets.Common.IO.Configurations; +using Ringtoets.HeightStructures.IO.Configurations; + +namespace Ringtoets.HeightStructures.IO.Test.Configurations +{ + [TestFixture] + public class HeightStructuresCalculationConfigurationReaderTest + { + private readonly string testDirectoryPath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.HeightStructures.IO, + nameof(HeightStructuresCalculationConfigurationReader)); + + private static IEnumerable InvalidConfigurations + { + get + { + yield return new TestCaseData("invalidCalculationFailureProbabilityStructureWithErosionEmpty.xml", + "The 'faalkansgegevenerosiebodem' element is invalid - The value '' is invalid according to its datatype 'Double'") + .SetName("invalidCalculationFailureProbabilityStructureWithErosionEmpty"); + yield return new TestCaseData("invalidCalculationFailureProbabilityStructureWithErosionNoDouble.xml", + "The 'faalkansgegevenerosiebodem' element is invalid - The value 'nul' is invalid according to its datatype 'Double'") + .SetName("invalidCalculationFailureProbabilityStructureWithErosionNoDouble"); + yield return new TestCaseData("invalidCalculationFailureProbabilityStructureWithErosionWrongCulture.xml", + "The 'faalkansgegevenerosiebodem' element is invalid - The value '0,5' is invalid according to its datatype 'Double'") + .SetName("invalidCalculationFailureProbabilityStructureWithErosionWrongCulture"); + + yield return new TestCaseData("invalidCalculationForeshoreProfileEmpty.xml", + "The 'voorlandprofiel' element is invalid - The value '' is invalid according to its datatype 'String'") + .SetName("invalidCalculationForeshoreProfileEmpty"); + + yield return new TestCaseData("invalidCalculationHydraulicBoundaryLocationEmpty.xml", + "The 'hrlocatie' element is invalid - The value '' is invalid according to its datatype 'String'") + .SetName("invalidCalculationHydraulicBoundaryLocationEmpty"); + + yield return new TestCaseData("invalidCalculationMultipleFailureProbabilityStructureWithErosion.xml", + "Element 'faalkansgegevenerosiebodem' cannot appear more than once if content model type is \"all\".") + .SetName("invalidCalculationMultipleFailureProbabilityStructureWithErosion"); + yield return new TestCaseData("invalidCalculationMultipleForeshoreProfile.xml", + "Element 'voorlandprofiel' cannot appear more than once if content model type is \"all\".") + .SetName("invalidCalculationMultipleForeshoreProfile"); + yield return new TestCaseData("invalidCalculationMultipleHydraulicBoundaryLocation.xml", + "Element 'hrlocatie' cannot appear more than once if content model type is \"all\".") + .SetName("invalidCalculationMultipleHydraulicBoundaryLocation"); + yield return new TestCaseData("invalidCalculationMultipleOrientation.xml", + "Element 'orientatie' cannot appear more than once if content model type is \"all\".") + .SetName("invalidCalculationMultipleOrientation"); + yield return new TestCaseData("invalidCalculationMultipleStructure.xml", + "Element 'kunstwerk' cannot appear more than once if content model type is \"all\".") + .SetName("invalidCalculationMultipleStructure"); + + yield return new TestCaseData("invalidCalculationOrientationEmpty.xml", + "The 'orientatie' element is invalid - The value '' is invalid according to its datatype 'Double'") + .SetName("invalidCalculationOrientationEmpty"); + yield return new TestCaseData("invalidCalculationOrientationNoDouble.xml", + "The 'orientatie' element is invalid - The value 'nul' is invalid according to its datatype 'Double'") + .SetName("invalidCalculationOrientationNoDouble"); + yield return new TestCaseData("invalidCalculationOrientationWrongCulture.xml", + "The 'orientatie' element is invalid - The value '0,5' is invalid according to its datatype 'Double'") + .SetName("invalidCalculationOrientationWrongCulture"); + + yield return new TestCaseData("invalidCalculationStructureEmpty.xml", + "The 'kunstwerk' element is invalid - The value '' is invalid according to its datatype 'String'") + .SetName("invalidCalculationStructureEmpty"); + + yield return new TestCaseData("invalidStochastNoName.xml", + "The required attribute 'naam' is missing.") + .SetName("invalidStochastNoName"); + yield return new TestCaseData("invalidStochastUnknownName.xml", + "The 'naam' attribute is invalid - The value 'Test' is invalid according to its datatype 'nameType' - The Enumeration constraint failed.") + .SetName("invalidStochastUnknownName"); + yield return new TestCaseData("invalidStochastMultipleMean.xml", + "Element 'verwachtingswaarde' cannot appear more than once if content model type is \"all\".") + .SetName("invalidStochastMultipleMean"); + yield return new TestCaseData("invalidStochastMultipleStandardDeviation.xml", + "Element 'standaardafwijking' cannot appear more than once if content model type is \"all\".") + .SetName("invalidStochastMultipleStandardDeviation"); + yield return new TestCaseData("invalidStochastMultipleVariationCoefficient.xml", + "Element 'variatiecoefficient' cannot appear more than once if content model type is \"all\".") + .SetName("invalidStochastMultipleVariationCoefficient"); + yield return new TestCaseData("invalidStochastMeanEmpty.xml", + "The 'verwachtingswaarde' element is invalid - The value '' is invalid according to its datatype 'Double'") + .SetName("invalidStochastMeanEmpty"); + yield return new TestCaseData("invalidStochastMeanNoDouble.xml", + "The 'verwachtingswaarde' element is invalid - The value 'string' is invalid according to its datatype 'Double'") + .SetName("invalidStochastMeanNoDouble"); + yield return new TestCaseData("invalidStochastMeanWrongCulture.xml", + "The 'verwachtingswaarde' element is invalid - The value '1,2' is invalid according to its datatype 'Double'") + .SetName("invalidStochastMeanWrongCulture"); + yield return new TestCaseData("invalidStochastStandardDeviationEmpty.xml", + "The 'standaardafwijking' element is invalid - The value '' is invalid according to its datatype 'Double'") + .SetName("invalidStochastStandardDeviationEmpty"); + yield return new TestCaseData("invalidStochastStandardDeviationNoDouble.xml", + "The 'standaardafwijking' element is invalid - The value 'string' is invalid according to its datatype 'Double'") + .SetName("invalidStochastStandardDeviationNoDouble"); + yield return new TestCaseData("invalidStochastStandardDeviationWrongCulture.xml", + "The 'standaardafwijking' element is invalid - The value '1,2' is invalid according to its datatype 'Double'") + .SetName("invalidStochastStandardDeviationWrongCulture"); + yield return new TestCaseData("invalidStochastVariationCoefficientEmpty.xml", + "The 'variatiecoefficient' element is invalid - The value '' is invalid according to its datatype 'Double'") + .SetName("invalidStochastVariationCoefficientEmpty"); + yield return new TestCaseData("invalidStochastVariationCoefficientNoDouble.xml", + "The 'variatiecoefficient' element is invalid - The value 'string' is invalid according to its datatype 'Double'") + .SetName("invalidStochastVariationCoefficientNoDouble"); + yield return new TestCaseData("invalidStochastVariationCoefficientWrongCulture.xml", + "The 'variatiecoefficient' element is invalid - The value '1,2' is invalid according to its datatype 'Double'") + .SetName("invalidStochastVariationCoefficientWrongCulture"); + + yield return new TestCaseData("invalidMultipleAllowedLevelIncreaseStochast.xml", + "There is a duplicate key sequence 'peilverhogingkomberging' for the 'uniqueStochastNameConstraint' key or unique identity constraint.") + .SetName("invalidMultipleAllowedLevelIncreaseStochast"); + yield return new TestCaseData("invalidMultipleCriticalOvertoppingDischargeStochast.xml", + "There is a duplicate key sequence 'kritiekinstromenddebiet' for the 'uniqueStochastNameConstraint' key or unique identity constraint.") + .SetName("invalidMultipleCriticalOvertoppingDischargeStochast"); + yield return new TestCaseData("invalidMultipleFlowWidthAtBottomProtectionStochast.xml", + "There is a duplicate key sequence 'breedtebodembescherming' for the 'uniqueStochastNameConstraint' key or unique identity constraint.") + .SetName("invalidMultipleFlowWidthAtBottomProtectionStochast"); + yield return new TestCaseData("invalidMultipleLevelCrestStructureStochast.xml", + "There is a duplicate key sequence 'kerendehoogte' for the 'uniqueStochastNameConstraint' key or unique identity constraint.") + .SetName("invalidMultipleLevelCrestStructureStochast"); + yield return new TestCaseData("invalidMultipleModelFactorSuperCriticalFlowStochast.xml", + "There is a duplicate key sequence 'modelfactoroverloopdebiet' for the 'uniqueStochastNameConstraint' key or unique identity constraint.") + .SetName("invalidMultipleModelFactorSuperCriticalFlowStochast"); + yield return new TestCaseData("invalidMultipleStorageStructureAreaStochast.xml", + "There is a duplicate key sequence 'kombergendoppervlak' for the 'uniqueStochastNameConstraint' key or unique identity constraint.") + .SetName("invalidMultipleStorageStructureAreaStochast"); + yield return new TestCaseData("invalidMultipleStormDurationStochast.xml", + "There is a duplicate key sequence 'stormduur' for the 'uniqueStochastNameConstraint' key or unique identity constraint.") + .SetName("invalidMultipleStormDurationStochast"); + yield return new TestCaseData("invalidMultipleWidthFlowAperturesStochast.xml", + "There is a duplicate key sequence 'breedtedoorstroomopening' for the 'uniqueStochastNameConstraint' key or unique identity constraint.") + .SetName("invalidMultipleWidthFlowAperturesStochast"); + + yield return new TestCaseData("invalidUseBreakWaterEmpty.xml", + "The 'damgebruiken' element is invalid - The value '' is invalid according to its datatype 'Boolean'") + .SetName("invalidUseBreakWaterEmpty"); + yield return new TestCaseData("invalidUseBreakWaterNoBoolean.xml", + "The 'damgebruiken' element is invalid - The value 'string' is invalid according to its datatype 'Boolean'") + .SetName("invalidUseBreakWaterNoBoolean"); + yield return new TestCaseData("invalidMultipleUseBreakWaters.xml", + "Element 'damgebruiken' cannot appear more than once if content model type is \"all\".") + .SetName("invalidMultipleUseBreakWaters"); + + yield return new TestCaseData("invalidBreakWaterTypeEmpty.xml", + "The 'damtype' element is invalid - The value '' is invalid according to its datatype 'String' - The Enumeration constraint failed.") + .SetName("invalidBreakWaterTypeEmpty"); + yield return new TestCaseData("invalidMultipleBreakWaterTypes.xml", + "Element 'damtype' cannot appear more than once if content model type is \"all\".") + .SetName("invalidMultipleBreakWaterTypes"); + yield return new TestCaseData("invalidBreakWaterTypeUnsupportedString.xml", + "The 'damtype' element is invalid - The value 'invalid' is invalid according to its datatype 'String' - The Enumeration constraint failed.") + .SetName("invalidBreakWaterTypeUnsupportedString"); + + yield return new TestCaseData("invalidBreakWaterHeightEmpty.xml", + "The 'damhoogte' element is invalid - The value '' is invalid according to its datatype 'Double'") + .SetName("invalidBreakWaterHeightEmpty"); + yield return new TestCaseData("invalidBreakWaterHeightNoDouble.xml", + "The 'damhoogte' element is invalid - The value 'string' is invalid according to its datatype 'Double'") + .SetName("invalidBreakWaterHeightNoDouble"); + yield return new TestCaseData("invalidBreakWaterHeightWrongCulture.xml", + "The 'damhoogte' element is invalid - The value '1,2' is invalid according to its datatype 'Double'") + .SetName("invalidBreakWaterHeightWrongCulture"); + yield return new TestCaseData("invalidMultipleBreakWaterHeights.xml", + "Element 'damhoogte' cannot appear more than once if content model type is \"all\".") + .SetName("invalidMultipleBreakWaterHeights"); + + yield return new TestCaseData("invalidUseForeshoreEmpty.xml", + "The 'voorlandgebruiken' element is invalid - The value '' is invalid according to its datatype 'Boolean'") + .SetName("invalidUseForeshoreEmpty"); + yield return new TestCaseData("invalidUseForeshoreNoBoolean.xml", + "The 'voorlandgebruiken' element is invalid - The value 'string' is invalid according to its datatype 'Boolean'") + .SetName("invalidUseForeshoreNoBoolean"); + yield return new TestCaseData("invalidMultipleUseForeshore.xml", + "Element 'voorlandgebruiken' cannot appear more than once if content model type is \"all\".") + .SetName("invalidMultipleUseForeshores"); + } + } + + [Test] + public void Constructor_WithFilePath_ReturnsNewInstance() + { + // Setup + var existingPath = Path.Combine(testDirectoryPath, "validConfigurationEmptyCalculation.xml"); + + // Call + var reader = new HeightStructuresCalculationConfigurationReader(existingPath); + + // Assert + Assert.IsInstanceOf>(reader); + } + + [Test] + [TestCaseSource(nameof(InvalidConfigurations))] + public void Constructor_FileInvalidBasedOnSchemaDefinition_ThrowCriticalFileReadException(string fileName, string expectedParsingMessage) + { + // Setup + string filePath = Path.Combine(testDirectoryPath, fileName); + + // Call + TestDelegate call = () => new HeightStructuresCalculationConfigurationReader(filePath); + + // Assert + var exception = Assert.Throws(call); + Assert.IsInstanceOf(exception.InnerException); + StringAssert.Contains(expectedParsingMessage, exception.InnerException?.Message); + } + + [Test] + [TestCase("validConfigurationEmptyStochasts")] + [TestCase("validConfigurationEmptyCalculation")] + public void Read_ValidConfigurationWithEmptyCalculationOrWithEmptyStochasts_NoValuesSet(string fileName) + { + // Setup + string filePath = Path.Combine(testDirectoryPath, $"{fileName}.xml"); + var reader = new HeightStructuresCalculationConfigurationReader(filePath); + + // Call + IList readConfigurationItems = reader.Read().ToList(); + + // Assert + Assert.AreEqual(1, readConfigurationItems.Count); + + var calculation = (HeightStructuresCalculationConfiguration) readConfigurationItems[0]; + Assert.IsNull(calculation.StructureNormalOrientation); + Assert.IsNull(calculation.StructureName); + Assert.IsNull(calculation.HydraulicBoundaryLocationName); + Assert.IsNull(calculation.ForeshoreProfileName); + Assert.IsNull(calculation.FailureProbabilityStructureWithErosion); + + Assert.IsNull(calculation.LevelCrestStructure); + Assert.IsNull(calculation.AllowedLevelIncreaseStorage); + Assert.IsNull(calculation.CriticalOvertoppingDischarge); + Assert.IsNull(calculation.FlowWidthAtBottomProtection); + Assert.IsNull(calculation.ModelFactorSuperCriticalFlow); + Assert.IsNull(calculation.StorageStructureArea); + Assert.IsNull(calculation.StormDuration); + Assert.IsNull(calculation.WidthFlowApertures); + + Assert.IsNull(calculation.WaveReduction); + } + + [Test] + [TestCase("validFullConfiguration")] + [TestCase("validFullConfiguration_differentOrder")] + public void Read_ValidFullConfigurations_ExpectedValues(string fileName) + { + // Setup + string filePath = Path.Combine(testDirectoryPath, $"{fileName}.xml"); + var reader = new HeightStructuresCalculationConfigurationReader(filePath); + + // Call + IList readConfigurationItems = reader.Read().ToList(); + + // Assert + Assert.AreEqual(1, readConfigurationItems.Count); + + var calculation = (HeightStructuresCalculationConfiguration) readConfigurationItems[0]; + Assert.AreEqual(67.1, calculation.StructureNormalOrientation); + Assert.AreEqual("kunstwerk1", calculation.StructureName); + Assert.AreEqual("Locatie1", calculation.HydraulicBoundaryLocationName); + Assert.AreEqual("profiel1", calculation.ForeshoreProfileName); + Assert.AreEqual(1e-6, calculation.FailureProbabilityStructureWithErosion); + + Assert.AreEqual(4.3, calculation.LevelCrestStructure.Mean); + Assert.AreEqual(0.1, calculation.LevelCrestStructure.StandardDeviation); + + Assert.AreEqual(0.2, calculation.AllowedLevelIncreaseStorage.Mean); + Assert.AreEqual(0.01, calculation.AllowedLevelIncreaseStorage.StandardDeviation); + Assert.AreEqual(2, calculation.CriticalOvertoppingDischarge.Mean); + Assert.AreEqual(0.1, calculation.CriticalOvertoppingDischarge.VariationCoefficient); + Assert.AreEqual(15.2, calculation.FlowWidthAtBottomProtection.Mean); + Assert.AreEqual(0.1, calculation.FlowWidthAtBottomProtection.StandardDeviation); + Assert.AreEqual(1.10, calculation.ModelFactorSuperCriticalFlow.Mean); + Assert.AreEqual(0.12, calculation.ModelFactorSuperCriticalFlow.StandardDeviation); + Assert.AreEqual(15000, calculation.StorageStructureArea.Mean); + Assert.AreEqual(0.01, calculation.StorageStructureArea.VariationCoefficient); + Assert.AreEqual(6.0, calculation.StormDuration.Mean); + Assert.AreEqual(0.12, calculation.StormDuration.VariationCoefficient); + Assert.AreEqual(15.2, calculation.WidthFlowApertures.Mean); + Assert.AreEqual(0.1, calculation.WidthFlowApertures.StandardDeviation); + + Assert.AreEqual(ConfigurationBreakWaterType.Dam, calculation.WaveReduction.BreakWaterType); + Assert.AreEqual(1.234, calculation.WaveReduction.BreakWaterHeight); + Assert.IsTrue(calculation.WaveReduction.UseBreakWater); + Assert.IsTrue(calculation.WaveReduction.UseForeshoreProfile); + } + + [Test] + public void Read_ValidFullConfigurationsContainingInfinity_ExpectedValues() + { + // Setup + string filePath = Path.Combine(testDirectoryPath, "validFullConfigurationContainingInfinity.xml"); + var reader = new HeightStructuresCalculationConfigurationReader(filePath); + + // Call + IList readConfigurationItems = reader.Read().ToList(); + + // Assert + Assert.AreEqual(1, readConfigurationItems.Count); + + var calculation = (HeightStructuresCalculationConfiguration) readConfigurationItems[0]; + Assert.IsTrue(double.IsNegativeInfinity(calculation.StructureNormalOrientation.Value)); + Assert.IsNull(calculation.StructureName); + Assert.IsNull(calculation.HydraulicBoundaryLocationName); + Assert.IsNull(calculation.ForeshoreProfileName); + Assert.IsTrue(double.IsNegativeInfinity(calculation.FailureProbabilityStructureWithErosion.Value)); + + Assert.IsTrue(double.IsNegativeInfinity(calculation.LevelCrestStructure.Mean.Value)); + Assert.IsTrue(double.IsNegativeInfinity(calculation.LevelCrestStructure.StandardDeviation.Value)); + + Assert.IsTrue(double.IsPositiveInfinity(calculation.AllowedLevelIncreaseStorage.Mean.Value)); + Assert.IsTrue(double.IsNegativeInfinity(calculation.AllowedLevelIncreaseStorage.StandardDeviation.Value)); + Assert.IsTrue(double.IsPositiveInfinity(calculation.CriticalOvertoppingDischarge.Mean.Value)); + Assert.IsTrue(double.IsPositiveInfinity(calculation.CriticalOvertoppingDischarge.VariationCoefficient.Value)); + Assert.IsTrue(double.IsNegativeInfinity(calculation.FlowWidthAtBottomProtection.Mean.Value)); + Assert.IsTrue(double.IsPositiveInfinity(calculation.FlowWidthAtBottomProtection.StandardDeviation.Value)); + Assert.IsTrue(double.IsNegativeInfinity(calculation.ModelFactorSuperCriticalFlow.Mean.Value)); + Assert.IsTrue(double.IsPositiveInfinity(calculation.ModelFactorSuperCriticalFlow.StandardDeviation.Value)); + Assert.IsTrue(double.IsPositiveInfinity(calculation.StorageStructureArea.Mean.Value)); + Assert.IsTrue(double.IsPositiveInfinity(calculation.StorageStructureArea.VariationCoefficient.Value)); + Assert.IsTrue(double.IsNegativeInfinity(calculation.StormDuration.Mean.Value)); + Assert.IsTrue(double.IsNegativeInfinity(calculation.StormDuration.VariationCoefficient.Value)); + Assert.IsTrue(double.IsPositiveInfinity(calculation.WidthFlowApertures.Mean.Value)); + Assert.IsTrue(double.IsPositiveInfinity(calculation.WidthFlowApertures.StandardDeviation.Value)); + + Assert.IsNull(calculation.WaveReduction.BreakWaterType); + Assert.IsTrue(double.IsNegativeInfinity(calculation.WaveReduction.BreakWaterHeight.Value)); + Assert.IsNull(calculation.WaveReduction.UseBreakWater); + Assert.IsNull(calculation.WaveReduction.UseForeshoreProfile); + } + + [Test] + public void Read_ValidFullConfigurationsContainingNaN_ExpectedValues() + { + // Setup + string filePath = Path.Combine(testDirectoryPath, "validFullConfigurationContainingNaN.xml"); + var reader = new HeightStructuresCalculationConfigurationReader(filePath); + + // Call + IList readConfigurationItems = reader.Read().ToList(); + + // Assert + Assert.AreEqual(1, readConfigurationItems.Count); + + var calculation = (HeightStructuresCalculationConfiguration) readConfigurationItems[0]; + Assert.IsNaN(calculation.StructureNormalOrientation); + Assert.IsNull(calculation.StructureName); + Assert.IsNull(calculation.HydraulicBoundaryLocationName); + Assert.IsNull(calculation.ForeshoreProfileName); + Assert.IsNaN(calculation.FailureProbabilityStructureWithErosion); + + Assert.IsNaN(calculation.LevelCrestStructure.Mean); + Assert.IsNaN(calculation.LevelCrestStructure.StandardDeviation); + + Assert.IsNaN(calculation.AllowedLevelIncreaseStorage.Mean); + Assert.IsNaN(calculation.AllowedLevelIncreaseStorage.StandardDeviation); + Assert.IsNaN(calculation.CriticalOvertoppingDischarge.Mean); + Assert.IsNaN(calculation.CriticalOvertoppingDischarge.VariationCoefficient); + Assert.IsNaN(calculation.FlowWidthAtBottomProtection.Mean); + Assert.IsNaN(calculation.FlowWidthAtBottomProtection.StandardDeviation); + Assert.IsNaN(calculation.ModelFactorSuperCriticalFlow.Mean); + Assert.IsNaN(calculation.ModelFactorSuperCriticalFlow.StandardDeviation); + Assert.IsNaN(calculation.StorageStructureArea.Mean); + Assert.IsNaN(calculation.StorageStructureArea.VariationCoefficient); + Assert.IsNaN(calculation.StormDuration.Mean); + Assert.IsNaN(calculation.StormDuration.VariationCoefficient); + Assert.IsNaN(calculation.WidthFlowApertures.Mean); + Assert.IsNaN(calculation.WidthFlowApertures.StandardDeviation); + + Assert.IsNull(calculation.WaveReduction.BreakWaterType); + Assert.IsNaN(calculation.WaveReduction.BreakWaterHeight); + Assert.IsNull(calculation.WaveReduction.UseBreakWater); + Assert.IsNull(calculation.WaveReduction.UseForeshoreProfile); + } + + [Test] + public void Read_ValidPartialConfigurations_ExpectedValues() + { + // Setup + string filePath = Path.Combine(testDirectoryPath, "validPartialConfiguration.xml"); + var reader = new HeightStructuresCalculationConfigurationReader(filePath); + + // Call + IList readConfigurationItems = reader.Read().ToList(); + + // Assert + Assert.AreEqual(1, readConfigurationItems.Count); + + var calculation = (HeightStructuresCalculationConfiguration) readConfigurationItems[0]; + Assert.IsNull(calculation.StructureNormalOrientation); + Assert.IsNull(calculation.StructureName); + Assert.AreEqual("Locatie1", calculation.HydraulicBoundaryLocationName); + Assert.AreEqual("profiel1", calculation.ForeshoreProfileName); + Assert.IsNull(calculation.FailureProbabilityStructureWithErosion); + + Assert.IsNull(calculation.LevelCrestStructure); + + Assert.IsNull(calculation.AllowedLevelIncreaseStorage); + Assert.AreEqual(2, calculation.CriticalOvertoppingDischarge.Mean); + Assert.AreEqual(0.1, calculation.CriticalOvertoppingDischarge.VariationCoefficient); + Assert.IsNull(calculation.FlowWidthAtBottomProtection); + Assert.IsNull(calculation.ModelFactorSuperCriticalFlow); + Assert.AreEqual(15000, calculation.StorageStructureArea.Mean); + Assert.IsNull(calculation.StorageStructureArea.VariationCoefficient); + Assert.AreEqual(6.0, calculation.StormDuration.Mean); + Assert.IsNull(calculation.StormDuration.VariationCoefficient); + Assert.IsNull(calculation.WidthFlowApertures.Mean); + Assert.AreEqual(0.1, calculation.WidthFlowApertures.StandardDeviation); + + Assert.IsNull(calculation.WaveReduction.BreakWaterType); + Assert.IsNull(calculation.WaveReduction.BreakWaterHeight); + Assert.IsTrue(calculation.WaveReduction.UseBreakWater); + Assert.IsTrue(calculation.WaveReduction.UseForeshoreProfile); + } + + [Test] + public void Read_ValidConfigurationsEmptyStochastElements_ExpectedValues() + { + // Setup + string filePath = Path.Combine(testDirectoryPath, "validConfigurationEmptyStochastElements.xml"); + var reader = new HeightStructuresCalculationConfigurationReader(filePath); + + // Call + IList readConfigurationItems = reader.Read().ToList(); + + // Assert + Assert.AreEqual(1, readConfigurationItems.Count); + + var calculation = (HeightStructuresCalculationConfiguration) readConfigurationItems[0]; + Assert.IsNull(calculation.StructureNormalOrientation); + Assert.IsNull(calculation.StructureName); + Assert.IsNull(calculation.HydraulicBoundaryLocationName); + Assert.IsNull(calculation.ForeshoreProfileName); + Assert.IsNull(calculation.FailureProbabilityStructureWithErosion); + + Assert.IsNull(calculation.LevelCrestStructure.Mean); + Assert.IsNull(calculation.LevelCrestStructure.StandardDeviation); + + Assert.IsNull(calculation.AllowedLevelIncreaseStorage.Mean); + Assert.IsNull(calculation.AllowedLevelIncreaseStorage.StandardDeviation); + Assert.IsNull(calculation.CriticalOvertoppingDischarge.Mean); + Assert.IsNull(calculation.CriticalOvertoppingDischarge.VariationCoefficient); + Assert.IsNull(calculation.FlowWidthAtBottomProtection.Mean); + Assert.IsNull(calculation.FlowWidthAtBottomProtection.StandardDeviation); + Assert.IsNull(calculation.ModelFactorSuperCriticalFlow.Mean); + Assert.IsNull(calculation.ModelFactorSuperCriticalFlow.StandardDeviation); + Assert.IsNull(calculation.StorageStructureArea.Mean); + Assert.IsNull(calculation.StorageStructureArea.VariationCoefficient); + Assert.IsNull(calculation.StormDuration.Mean); + Assert.IsNull(calculation.StormDuration.VariationCoefficient); + Assert.IsNull(calculation.WidthFlowApertures.Mean); + Assert.IsNull(calculation.WidthFlowApertures.StandardDeviation); + + Assert.IsNull(calculation.WaveReduction); + } + } +} \ No newline at end of file Index: Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Configurations/HeightStructuresCalculationConfigurationTest.cs =================================================================== diff -u --- Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Configurations/HeightStructuresCalculationConfigurationTest.cs (revision 0) +++ Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Configurations/HeightStructuresCalculationConfigurationTest.cs (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -0,0 +1,69 @@ +// 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 NUnit.Framework; +using Ringtoets.Common.IO.Configurations; +using Ringtoets.HeightStructures.IO.Configurations; + +namespace Ringtoets.HeightStructures.IO.Test.Configurations +{ + [TestFixture] + public class HeightStructuresCalculationConfigurationTest + { + [Test] + public void Constructor_NameNull_ThrowsArgumentNullException() + { + // Call + TestDelegate call = () => new HeightStructuresCalculationConfiguration(null); + + // Assert + string paramName = Assert.Throws(call).ParamName; + Assert.AreEqual("value", paramName); + } + + [Test] + public void Constructor_WithName_ExpectedValues() + { + // Call + var configuration = new HeightStructuresCalculationConfiguration("some name"); + + // Assert + Assert.IsInstanceOf(configuration); + Assert.AreEqual("some name", configuration.Name); + Assert.IsNull(configuration.LevelCrestStructure); + } + + [Test] + public void SimpleProperties_SetNewValues_NewValuesSet() + { + // Setup + var levelCrestStructure = new MeanStandardDeviationStochastConfiguration(); + var configuration = new HeightStructuresCalculationConfiguration("some name"); + + // Call + configuration.LevelCrestStructure = levelCrestStructure; + + // Assert + Assert.AreSame(levelCrestStructure, configuration.LevelCrestStructure); + } + } +} \ No newline at end of file Index: Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Configurations/HeightStructuresCalculationConfigurationWriterTest.cs =================================================================== diff -u --- Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Configurations/HeightStructuresCalculationConfigurationWriterTest.cs (revision 0) +++ Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Configurations/HeightStructuresCalculationConfigurationWriterTest.cs (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -0,0 +1,170 @@ +// 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.Collections.Generic; +using System.IO; +using Core.Common.TestUtil; +using NUnit.Framework; +using Ringtoets.Common.IO.Configurations; +using Ringtoets.Common.IO.TestUtil; +using Ringtoets.Common.IO.Writers; +using Ringtoets.HeightStructures.IO.Configurations; + +namespace Ringtoets.HeightStructures.IO.Test.Configurations +{ + [TestFixture] + public class HeightStructuresCalculationConfigurationWriterTest + : CustomSchemaCalculationConfigurationWriterDesignGuidelinesTestFixture< + HeightStructuresCalculationConfigurationWriter, + HeightStructuresCalculationConfiguration> + { + private readonly string testDataPath = TestHelper.GetTestDataPath( + TestDataPath.Ringtoets.HeightStructures.IO, + nameof(HeightStructuresCalculationConfigurationWriter)); + + private static IEnumerable Calculations + { + get + { + yield return new TestCaseData("completeConfiguration", new[] + { + CreateFullCalculation() + }) + .SetName("Calculation configuration with all parameters set"); + yield return new TestCaseData("sparseConfiguration", new[] + { + new HeightStructuresCalculationConfiguration("sparse config") + }) + .SetName("Calculation configuration with none of its parameters set"); + yield return new TestCaseData("folderWithSubfolderAndCalculation", new IConfigurationItem[] + { + new CalculationGroupConfiguration("Testmap", new IConfigurationItem[] + { + CreateFullCalculation(), + new CalculationGroupConfiguration("Nested", new IConfigurationItem[] + { + new HeightStructuresCalculationConfiguration("Berekening 2") + }) + }) + }) + .SetName("Calculation configurations in a hierarchy"); + } + } + + protected override void AssertDefaultConstructedInstance(HeightStructuresCalculationConfigurationWriter writer) + { + Assert.IsInstanceOf>(writer); + } + + [Test] + [TestCaseSource(nameof(Calculations))] + public void Write_ValidCalculation_ValidFile(string expectedFileName, IConfigurationItem[] configuration) + { + // Setup + string filePath = TestHelper.GetScratchPadPath($"{nameof(HeightStructuresCalculationConfigurationWriterTest)}.{nameof(Write_ValidCalculation_ValidFile)}.{expectedFileName}.xml"); + + try + { + var writer = new HeightStructuresCalculationConfigurationWriter(filePath); + + // Call + writer.Write(configuration); + + // Assert + Assert.IsTrue(File.Exists(filePath)); + + string actualXml = File.ReadAllText(filePath); + string expectedXmlFilePath = Path.Combine(testDataPath, $"{expectedFileName}.xml"); + string expectedXml = File.ReadAllText(expectedXmlFilePath); + + Assert.AreEqual(expectedXml, actualXml); + } + finally + { + File.Delete(filePath); + } + } + + private static HeightStructuresCalculationConfiguration CreateFullCalculation() + { + return new HeightStructuresCalculationConfiguration("Berekening 1") + { + HydraulicBoundaryLocationName = "Locatie1", + StructureName = "kunstwerk1", + ForeshoreProfileName = "profiel1", + FailureProbabilityStructureWithErosion = 1e-6, + StructureNormalOrientation = 67.1, + WaveReduction = new WaveReductionConfiguration + { + UseBreakWater = true, + BreakWaterType = ConfigurationBreakWaterType.Dam, + BreakWaterHeight = 1.23, + UseForeshoreProfile = true + }, + StormDuration = new MeanVariationCoefficientStochastConfiguration + { + Mean = 6.0, + VariationCoefficient= 0.22 + }, + ModelFactorSuperCriticalFlow = new MeanStandardDeviationStochastConfiguration + { + Mean = 1.1, + StandardDeviation = 0.14 + }, + FlowWidthAtBottomProtection = new MeanStandardDeviationStochastConfiguration + { + Mean = 15.2, + StandardDeviation = 0.1 + }, + WidthFlowApertures = new MeanStandardDeviationStochastConfiguration + { + Mean = 13.2, + StandardDeviation = 0.3 + }, + StorageStructureArea = new MeanVariationCoefficientStochastConfiguration + { + Mean = 15000, + VariationCoefficient = 0.01 + }, + AllowedLevelIncreaseStorage = new MeanStandardDeviationStochastConfiguration + { + Mean = 0.2, + StandardDeviation = 0.01 + }, + LevelCrestStructure = new MeanStandardDeviationStochastConfiguration + { + Mean = 4.3, + StandardDeviation = 0.2 + }, + CriticalOvertoppingDischarge = new MeanVariationCoefficientStochastConfiguration + { + Mean = 2, + VariationCoefficient = 0.1 + } + }; + } + + protected override HeightStructuresCalculationConfigurationWriter CreateWriterInstance(string filePath) + { + return new HeightStructuresCalculationConfigurationWriter(filePath); + } + } +} \ No newline at end of file Fisheye: Tag 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 refers to a dead (removed) revision in file `Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/HeightStructuresCalculationConfigurationExporterTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 refers to a dead (removed) revision in file `Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/HeightStructuresCalculationConfigurationImporterTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 refers to a dead (removed) revision in file `Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/HeightStructuresCalculationConfigurationReaderTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 refers to a dead (removed) revision in file `Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/HeightStructuresCalculationConfigurationTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 refers to a dead (removed) revision in file `Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/HeightStructuresCalculationConfigurationWriterTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Ringtoets.HeightStructures.IO.Test.csproj =================================================================== diff -u -r5b07686bb3f89f1fa1017c4bf2cf8964ae9bd95c -r9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 --- Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Ringtoets.HeightStructures.IO.Test.csproj (.../Ringtoets.HeightStructures.IO.Test.csproj) (revision 5b07686bb3f89f1fa1017c4bf2cf8964ae9bd95c) +++ Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.IO.Test/Ringtoets.HeightStructures.IO.Test.csproj (.../Ringtoets.HeightStructures.IO.Test.csproj) (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -50,11 +50,11 @@ Properties\GlobalAssembly.cs - - - - - + + + + + Index: Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.Plugin.Test/ExportInfos/HeightStructuresCalculationContextExportInfoTest.cs =================================================================== diff -u -rbe64b9f33b3065a4d80c0a93c1cafe3d74f43513 -r9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 --- Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.Plugin.Test/ExportInfos/HeightStructuresCalculationContextExportInfoTest.cs (.../HeightStructuresCalculationContextExportInfoTest.cs) (revision be64b9f33b3065a4d80c0a93c1cafe3d74f43513) +++ Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.Plugin.Test/ExportInfos/HeightStructuresCalculationContextExportInfoTest.cs (.../HeightStructuresCalculationContextExportInfoTest.cs) (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -31,6 +31,7 @@ using Ringtoets.HeightStructures.Data.TestUtil; using Ringtoets.HeightStructures.Forms.PresentationObjects; using Ringtoets.HeightStructures.IO; +using Ringtoets.HeightStructures.IO.Configurations; using CoreCommonGuiResources = Core.Common.Gui.Properties.Resources; namespace Ringtoets.HeightStructures.Plugin.Test.ExportInfos Index: Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.Plugin.Test/ExportInfos/HeightStructuresCalculationGroupContextExportInfoTest.cs =================================================================== diff -u -r82db5c5ee21fae9e20fee1412dbb29b1c47b038a -r9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 --- Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.Plugin.Test/ExportInfos/HeightStructuresCalculationGroupContextExportInfoTest.cs (.../HeightStructuresCalculationGroupContextExportInfoTest.cs) (revision 82db5c5ee21fae9e20fee1412dbb29b1c47b038a) +++ Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.Plugin.Test/ExportInfos/HeightStructuresCalculationGroupContextExportInfoTest.cs (.../HeightStructuresCalculationGroupContextExportInfoTest.cs) (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -32,6 +32,7 @@ using Ringtoets.HeightStructures.Data.TestUtil; using Ringtoets.HeightStructures.Forms.PresentationObjects; using Ringtoets.HeightStructures.IO; +using Ringtoets.HeightStructures.IO.Configurations; using CoreCommonGuiResources = Core.Common.Gui.Properties.Resources; namespace Ringtoets.HeightStructures.Plugin.Test.ExportInfos Index: Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.Plugin.Test/ImportInfos/HeightStructuresCalculationGroupContextImportInfoTest.cs =================================================================== diff -u -r512bebcd5570951b18657513c56843d9e2f8e969 -r9a0e768e9ddbc5e4917201fdb864bb2247e5cd90 --- Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.Plugin.Test/ImportInfos/HeightStructuresCalculationGroupContextImportInfoTest.cs (.../HeightStructuresCalculationGroupContextImportInfoTest.cs) (revision 512bebcd5570951b18657513c56843d9e2f8e969) +++ Ringtoets/HeightStructures/test/Ringtoets.HeightStructures.Plugin.Test/ImportInfos/HeightStructuresCalculationGroupContextImportInfoTest.cs (.../HeightStructuresCalculationGroupContextImportInfoTest.cs) (revision 9a0e768e9ddbc5e4917201fdb864bb2247e5cd90) @@ -31,7 +31,7 @@ using Ringtoets.HeightStructures.Data; using Ringtoets.HeightStructures.Forms.PresentationObjects; using Ringtoets.HeightStructures.IO; - +using Ringtoets.HeightStructures.IO.Configurations; using RingtoetsCommonFormsResources = Ringtoets.Common.Forms.Properties.Resources; namespace Ringtoets.HeightStructures.Plugin.Test.ImportInfos