// Copyright (C) Stichting Deltares 2017. All rights reserved.
//
// This file is part of Ringtoets.
//
// Ringtoets is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using Core.Common.Base.Data;
using Ringtoets.Common.Data.Calculation;
using Ringtoets.Common.Data.Hydraulics;
using Ringtoets.Common.Data.Probabilistics;
using Ringtoets.Common.IO.Configurations.Helpers;
using Ringtoets.Common.IO.Configurations.Import;
using Ringtoets.MacroStabilityInwards.Data;
using Ringtoets.MacroStabilityInwards.IO.Properties;
using Ringtoets.MacroStabilityInwards.IO.Readers;
using Ringtoets.MacroStabilityInwards.IO.Schema;
using Ringtoets.MacroStabilityInwards.Primitives;
namespace Ringtoets.MacroStabilityInwards.IO.Importers
{
///
/// Imports a macro stability inwards calculation configuration from an XML file and stores it on a
/// .
///
public class MacroStabilityInwardsCalculationConfigurationImporter : CalculationConfigurationImporter
{
private readonly IEnumerable availableHydraulicBoundaryLocations;
private readonly MacroStabilityInwardsFailureMechanism failureMechanism;
///
/// Creates a 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 failure mechanism used to check
/// if the imported objects contain the right data.
/// Thrown when any parameter is
/// null.
public MacroStabilityInwardsCalculationConfigurationImporter(string xmlFilePath,
CalculationGroup importTarget,
IEnumerable availableHydraulicBoundaryLocations,
MacroStabilityInwardsFailureMechanism failureMechanism)
: base(xmlFilePath, importTarget)
{
if (availableHydraulicBoundaryLocations == null)
{
throw new ArgumentNullException(nameof(availableHydraulicBoundaryLocations));
}
if (failureMechanism == null)
{
throw new ArgumentNullException(nameof(failureMechanism));
}
this.availableHydraulicBoundaryLocations = availableHydraulicBoundaryLocations;
this.failureMechanism = failureMechanism;
}
protected override MacroStabilityInwardsCalculationConfigurationReader CreateCalculationConfigurationReader(string xmlFilePath)
{
return new MacroStabilityInwardsCalculationConfigurationReader(xmlFilePath);
}
protected override ICalculation ParseReadCalculation(ReadMacroStabilityInwardsCalculation readCalculation)
{
var calculation = new MacroStabilityInwardsCalculationScenario(new GeneralMacroStabilityInwardsInput())
{
Name = readCalculation.Name
};
if (TryReadHydraulicBoundaryData(readCalculation, calculation)
&& TryReadSurfaceLine(readCalculation, calculation)
&& TryReadEntryExitPoint(readCalculation, calculation)
&& TryReadStochasticSoilModel(readCalculation, calculation)
&& TryReadStochasticSoilProfile(readCalculation, calculation)
&& TryReadStochasts(readCalculation, calculation))
{
return calculation;
}
return null;
}
///
/// Reads the hydraulic boundary location or the assessment level that is manually set.
///
/// The calculation read from the imported file.
/// The calculation to configure.
/// false when the has a
/// set which is not available in , true otherwise.
private bool TryReadHydraulicBoundaryData(ReadMacroStabilityInwardsCalculation readCalculation, MacroStabilityInwardsCalculationScenario macroStabilityInwardsCalculation)
{
HydraulicBoundaryLocation location;
bool locationRead = TryReadHydraulicBoundaryLocation(readCalculation.HydraulicBoundaryLocation, readCalculation.Name, availableHydraulicBoundaryLocations, out location);
if (!locationRead)
{
return false;
}
if (location != null)
{
macroStabilityInwardsCalculation.InputParameters.HydraulicBoundaryLocation = location;
}
else if (readCalculation.AssessmentLevel.HasValue)
{
macroStabilityInwardsCalculation.InputParameters.UseAssessmentLevelManualInput = true;
macroStabilityInwardsCalculation.InputParameters.AssessmentLevel = (RoundedDouble) readCalculation.AssessmentLevel.Value;
}
return true;
}
///
/// Reads the surface line.
///
/// The calculation read from the imported file.
/// The calculation to configure.
/// false when the has a
/// set which is not available in , true otherwise.
private bool TryReadSurfaceLine(ReadMacroStabilityInwardsCalculation readCalculation, MacroStabilityInwardsCalculationScenario macroStabilityInwardsCalculation)
{
if (readCalculation.SurfaceLine != null)
{
RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine = failureMechanism.SurfaceLines
.FirstOrDefault(sl => sl.Name == readCalculation.SurfaceLine);
if (surfaceLine == null)
{
Log.LogCalculationConversionError(string.Format(
Resources.PipingCalculationConfigurationImporter_ReadSurfaceLine_SurfaceLine_0_does_not_exist,
readCalculation.SurfaceLine),
macroStabilityInwardsCalculation.Name);
return false;
}
macroStabilityInwardsCalculation.InputParameters.SurfaceLine = surfaceLine;
}
return true;
}
///
/// Reads the entry point and exit point.
///
/// The calculation read from the imported file.
/// The calculation to configure.
/// false when entry or exit point is set without ,
/// or when entry or exit point is invalid, true otherwise.
private bool TryReadEntryExitPoint(ReadMacroStabilityInwardsCalculation readCalculation, MacroStabilityInwardsCalculationScenario macroStabilityInwardsCalculation)
{
bool hasEntryPoint = readCalculation.EntryPointL.HasValue;
bool hasExitPoint = readCalculation.ExitPointL.HasValue;
if (readCalculation.SurfaceLine == null && (hasEntryPoint || hasExitPoint))
{
Log.LogCalculationConversionError(Resources.PipingCalculationConfigurationImporter_ReadSurfaceLine_EntryPointL_or_ExitPointL_defined_without_SurfaceLine,
macroStabilityInwardsCalculation.Name);
return false;
}
if (hasEntryPoint)
{
double entryPoint = readCalculation.EntryPointL.Value;
try
{
macroStabilityInwardsCalculation.InputParameters.EntryPointL = (RoundedDouble) entryPoint;
}
catch (ArgumentOutOfRangeException e)
{
Log.LogOutOfRangeException(string.Format(Resources.PipingCalculationConfigurationImporter_ReadEntryExitPoint_Entry_point_invalid, entryPoint),
macroStabilityInwardsCalculation.Name,
e);
return false;
}
}
if (hasExitPoint)
{
double exitPoint = readCalculation.ExitPointL.Value;
try
{
macroStabilityInwardsCalculation.InputParameters.ExitPointL = (RoundedDouble) exitPoint;
}
catch (ArgumentOutOfRangeException e)
{
Log.LogOutOfRangeException(string.Format(Resources.PipingCalculationConfigurationImporter_ReadEntryExitPoint_Exit_point_invalid, exitPoint),
macroStabilityInwardsCalculation.Name,
e);
return false;
}
}
return true;
}
///
/// Reads the stochastic soil model.
///
/// The calculation read from the imported file.
/// The calculation to configure.
/// false when
///
/// - the has a set
/// which is not available in the failure mechanism.
/// - The does not intersect with the
/// when this is set.
///
/// true otherwise.
private bool TryReadStochasticSoilModel(ReadMacroStabilityInwardsCalculation readCalculation, MacroStabilityInwardsCalculationScenario macroStabilityInwardsCalculation)
{
if (readCalculation.StochasticSoilModel != null)
{
StochasticSoilModel soilModel = failureMechanism.StochasticSoilModels
.FirstOrDefault(ssm => ssm.Name == readCalculation.StochasticSoilModel);
if (soilModel == null)
{
Log.LogCalculationConversionError(string.Format(
Resources.PipingCalculationConfigurationImporter_ReadStochasticSoilModel_Stochastische_soil_model_0_does_not_exist,
readCalculation.StochasticSoilModel),
macroStabilityInwardsCalculation.Name);
return false;
}
if (macroStabilityInwardsCalculation.InputParameters.SurfaceLine != null
&& !soilModel.IntersectsWithSurfaceLineGeometry(macroStabilityInwardsCalculation.InputParameters.SurfaceLine))
{
Log.LogCalculationConversionError(string.Format(
Resources.PipingCalculationConfigurationImporter_ReadStochasticSoilModel_Stochastische_soil_model_0_does_not_intersect_with_surfaceLine_1,
readCalculation.StochasticSoilModel,
readCalculation.SurfaceLine),
macroStabilityInwardsCalculation.Name);
return false;
}
macroStabilityInwardsCalculation.InputParameters.StochasticSoilModel = soilModel;
}
return true;
}
///
/// Reads the stochastic soil profile.
///
/// The calculation read from the imported file.
/// The calculation to configure.
/// false when the has:
///
/// - a set but no is specified;
/// - a set which is not available in the .
///
/// true otherwise.
private bool TryReadStochasticSoilProfile(ReadMacroStabilityInwardsCalculation readCalculation, MacroStabilityInwardsCalculationScenario macroStabilityInwardsCalculation)
{
if (readCalculation.StochasticSoilProfile != null)
{
if (macroStabilityInwardsCalculation.InputParameters.StochasticSoilModel == null)
{
Log.LogCalculationConversionError(string.Format(
Resources.PipingCalculationConfigurationImporter_ReadStochasticSoilProfile_No_soil_model_provided_for_soil_profile_with_name_0,
readCalculation.StochasticSoilProfile),
macroStabilityInwardsCalculation.Name);
return false;
}
StochasticSoilProfile soilProfile = macroStabilityInwardsCalculation.InputParameters.StochasticSoilModel.StochasticSoilProfiles
.FirstOrDefault(ssp => ssp.SoilProfile.Name == readCalculation.StochasticSoilProfile);
if (soilProfile == null)
{
Log.LogCalculationConversionError(string.Format(
Resources.PipingCalculationConfigurationImporter_ReadStochasticSoilProfile_Stochastic_soil_profile_0_does_not_exist_within_soil_model_1,
readCalculation.StochasticSoilProfile, readCalculation.StochasticSoilModel),
macroStabilityInwardsCalculation.Name);
return false;
}
macroStabilityInwardsCalculation.InputParameters.StochasticSoilProfile = soilProfile;
}
return true;
}
///
/// Reads the stochasts.
///
/// The calculation read from the imported file.
/// The calculation to configure.
/// false when a stochast value (mean or standard deviation) is invalid, true otherwise.
private bool TryReadStochasts(ReadMacroStabilityInwardsCalculation readCalculation, MacroStabilityInwardsCalculationScenario macroStabilityInwardsCalculation)
{
return TryReadPhreaticLevelExit(readCalculation, macroStabilityInwardsCalculation)
&& TryReadDampingFactorExit(readCalculation, macroStabilityInwardsCalculation);
}
private bool TryReadDampingFactorExit(ReadMacroStabilityInwardsCalculation readCalculation, MacroStabilityInwardsCalculationScenario macroStabilityInwardsCalculation)
{
var distribution = (LogNormalDistribution) macroStabilityInwardsCalculation.InputParameters.DampingFactorExit.Clone();
if (!distribution.TrySetDistributionProperties(readCalculation.DampingFactorExitMean,
readCalculation.DampingFactorExitStandardDeviation,
MacroStabilityInwardsCalculationConfigurationSchemaIdentifiers.DampingFactorExitStochastName,
macroStabilityInwardsCalculation.Name))
{
return false;
}
macroStabilityInwardsCalculation.InputParameters.DampingFactorExit = distribution;
return true;
}
private bool TryReadPhreaticLevelExit(ReadMacroStabilityInwardsCalculation readCalculation, MacroStabilityInwardsCalculationScenario macroStabilityInwardsCalculation)
{
var distribution = (NormalDistribution) macroStabilityInwardsCalculation.InputParameters.PhreaticLevelExit.Clone();
if (!distribution.TrySetDistributionProperties(readCalculation.PhreaticLevelExitMean,
readCalculation.PhreaticLevelExitStandardDeviation,
MacroStabilityInwardsCalculationConfigurationSchemaIdentifiers.PhreaticLevelExitStochastName,
macroStabilityInwardsCalculation.Name))
{
return false;
}
macroStabilityInwardsCalculation.InputParameters.PhreaticLevelExit = distribution;
return true;
}
}
}