using System.IO;
using System.Linq;
using System.Text;
using Deltares.DSoilModel.Data;
using Deltares.Geotechnics;
using Deltares.Geotechnics.IO.Importers;
using Deltares.Standard.EventPublisher;
using Deltares.Standard.Logging;
using Deltares.Standard.TestUtils;
using NUnit.Framework;
namespace Deltares.DSoilModel.Tests
{
[TestFixture]
public class DSoilModelIOTest
{
private bool oldIsDataEventPublishStopped;
[TestFixtureSetUp]
public void FixtureSetup()
{
oldIsDataEventPublishStopped = DataEventPublisher.IsDataEventPublishStopped;
DataEventPublisher.IsDataEventPublishStopped = true;
}
[TestFixtureTearDown]
public void FixtureTearDown()
{
DataEventPublisher.IsDataEventPublishStopped = oldIsDataEventPublishStopped;
}
[Test]
public void ImportOfEmptyCsvFilesResultsInWarninLogMessage()
{
// empty soilprofiles Csv
var testFile = "TestFiles/empty_soilprofiles.csv";
File.WriteAllText(testFile, @"soilprofile_id;top_level;soil_name;soiltype", Encoding.ASCII);
var project = new DSoilModelProject();
LogManager.Clear();
project.ReadSoilProfiles1DFromFile(testFile);
CheckForEmptyWarningInLog();
File.Delete(testFile);
// empty segments.csv
testFile = "TestFiles/empty_segments.csv";
File.WriteAllText(testFile, @"segment_id;soilprofile_id;probability;calculation_type", Encoding.ASCII);
LogManager.Clear();
DSoilModelIO.ReadCsvSegmentsFromFileAndAddToProject(testFile, project);
CheckForEmptyWarningInLog();
File.Delete(testFile);
// empty surfacelines.csv
testFile = "TestFiles/empty_surfacelines.csv";
File.WriteAllText(testFile, @"LocationID;Geologischprofiel;X_GridPoint;Y_GridPoint;ScenarioClusterID;X1;Y1;Z1;.....;Xn;Yn;Zn;(Profiel)", Encoding.ASCII);
LogManager.Clear();
DSoilModelIO.ReadCsvSurfaceLineFromFileAndAddToProject(testFile, project);
CheckForEmptyWarningInLog();
File.Delete(testFile);
// empty characteristicpoints.csv
testFile = "TestFiles/empty_characteristicpoints.csv";
File.WriteAllText(testFile, @"LocationID;X_Maaiveld binnenwaarts;Y_Maaiveld binnenwaarts;Z_Maaiveld binnenwaarts;X_Insteek sloot polderzijde;Y_Insteek sloot polderzijde;Z_Insteek sloot polderzijde;X_Slootbodem polderzijde;Y_Slootbodem polderzijde;Z_Slootbodem polderzijde;X_Slootbodem dijkzijde;Y_Slootbodem dijkzijde;Z_Slootbodem dijkzijde;X_Insteek sloot dijkzijde;Y_Insteek_sloot dijkzijde;Z_Insteek sloot dijkzijde;X_Teen dijk binnenwaarts;Y_Teen dijk binnenwaarts;Z_Teen dijk binnenwaarts;X_Kruin binnenberm;Y_Kruin binnenberm;Z_Kruin binnenberm;X_Insteek binnenberm;Y_Insteek binnenberm;Z_Insteek binnenberm;X_Kruin binnentalud;Y_Kruin binnentalud;Z_Kruin binnentalud;X_Verkeersbelasting kant binnenwaarts;Y_Verkeersbelasting kant binnenwaarts;Z_Verkeersbelasting kant binnenwaarts;X_Verkeersbelasting kant buitenwaarts;Y_Verkeersbelasting kant buitenwaarts;Z_Verkeersbelasting kant buitenwaarts;X_Kruin buitentalud;Y_Kruin buitentalud;Z_Kruin buitentalud;X_Insteek buitenberm;Y_Insteek buitenberm;Z_Insteek buitenberm;X_Kruin buitenberm;Y_Kruin buitenberm;Z_Kruin buitenberm;X_Teen dijk buitenwaarts;Y_Teen dijk buitenwaarts;Z_Teen dijk buitenwaarts;X_Maaiveld buitenwaarts;Y_Maaiveld buitenwaarts;Z_Maaiveld buitenwaarts;X_Dijktafelhoogte;Y_Dijktafelhoogte;Z_Dijktafelhoogte;Volgnummer", Encoding.ASCII);
LogManager.Clear();
DSoilModelIO.ReadCsvCharacteristicPointsFromFileAndAddToProject(testFile, project);
CheckForEmptyWarningInLog();
File.Delete(testFile);
}
private static void CheckForEmptyWarningInLog()
{
Assert.Greater(LogManager.Messages.Count, 0);
var logMessage = LogManager.Messages.FirstOrDefault(m => m.Message.Contains("empty"));
Assert.NotNull(logMessage);
Assert.AreEqual(logMessage.MessageType, LogMessageType.Warning);
}
[Test]
public void DamDefxImporterMustRefuseIncompleteSegments()
{
// setup, using a copy of DAM tutorial Design with the Geometries folder deleted.
string tutorial = Path.Combine(Directory.GetCurrentDirectory(), @"TestFiles\DAM Incomplete.defx");
Assert.IsTrue(File.Exists(tutorial));
// call
using (var project = new DSoilModelProject())
{
LogManager.Messages.Clear();
DSoilModelIO.ReadDamDefinitionsFromFileAndAddToProject(tutorial, project);
// assert
Assert.AreEqual(0, project.SoilSegments.Count);
Assert.AreEqual(0, project.SoilProfiles2D.Count);
Assert.AreEqual(200, project.Soils.Soils.Count);
Assert.GreaterOrEqual(LogManager.Messages.Count(m => m.MessageType == LogMessageType.Warning && m.Message.Contains("is refused as one or more profiles are missing")), 23);
}
}
///
/// Test import of defx file from Dam Tutorial design
///
[Test]
public void ImportDamSegmentsFromDefxFile()
{
// setup
string tutorial = Path.Combine(@"..\..\..\data", @"DAM\Dam Tutorial Design", "DAM Tutorial Design.defx");
Assert.IsTrue(File.Exists(tutorial));
// call
using (var project = new DSoilModelProject())
{
LogManager.Messages.Clear();
DSoilModelIO.ReadDamDefinitionsFromFileAndAddToProject(tutorial, project);
// assert
Assert.AreEqual(23, project.SoilSegments.Count);
Assert.AreEqual(23, project.SoilProfiles2D.Count);
Assert.AreEqual(200, project.Soils.Soils.Count);
Assert.IsFalse(LogManager.Messages.Any(m => m.MessageType == LogMessageType.Error ||m.MessageType == LogMessageType.FatalError));
foreach (var segment in project.SoilSegments)
{
foreach (var profile in segment.StochasticSoilModel.StochasticSoilProfiles)
{
Assert.IsTrue(profile.Profile is SoilProfile1D || profile.Profile is SoilProfile2D);
}
}
}
}
[Test]
public void ImportDuplicateMdbDoesNotCreateDuplicateSoils()
{
string mdbFile = Path.Combine(@"..\..\..\data", "D-Soil Model", "Groot Salland.mdb");
var project = new DSoilModelProject();
project.ReadSoilsFromDatabase(mdbFile);
var soilsCount = project.Soils.Soils.Count;
// importing the same file again should not add to the soil count
project.ReadSoilsFromDatabase(mdbFile);
Assert.AreEqual(soilsCount, project.Soils.Soils.Count);
}
[Test]
public void ImportMdbAquitardDoesNotOverwriteAquiferSoilWithSameName()
{
string testFolder = Path.Combine(Directory.GetCurrentDirectory(), "TestFiles");
var project = new DSoilModelProject();
// file with TestSand as aquifer
project.ReadSoilsFromDatabase(Path.Combine(testFolder, "AquiferTest.mdb"));
// file with TestSand as aquitard
project.ReadSoilsFromDatabase(Path.Combine(testFolder, "AquitardTest.mdb"));
Assert.AreEqual(3, project.Soils.Soils.Count);
Assert.AreEqual(1, project.Soils.Soils.Count(s => s.Name == "TestSand"));
Assert.AreEqual(1, project.Soils.Soils.Count(s => s.Name == "TestSand (1)"));
Assert.AreEqual(1, project.Soils.Soils.Count(s => s.Name == "TestLoam"));
Assert.AreEqual(1, project.Soils.AquiferDictionary.Count(item => item.Value == true));
}
///
/// Test of the import of surface lines from Csv file
///
[Test]
public void ImportSurfacelinesFromCsvFile()
{
const string csvFileNameAndRelativePath = @"TestFiles\DSoilModelsurfacelines.csv";
// Locate the test files.
string currentDirectory = Directory.GetCurrentDirectory();
string csvFullFileName = Path.Combine(currentDirectory, csvFileNameAndRelativePath);
using (var project = new DSoilModelProject())
{
DSoilModelIO.ReadCsvSurfaceLineFromFileAndAddToProject(csvFullFileName, project);
Assert.AreEqual(2, project.SurfaceLines.Count,
"The number of surface lines read from csv file is not right.");
Assert.AreEqual(202, project.SurfaceLines[0].Geometry.Count,
"The number of points in the surface lines read from csv file is not right.");
Assert.AreEqual(132, project.SurfaceLines[1].Geometry.Count,
"The number of points in the surface lines read from csv file is not right.");
}
}
[Test]
public void SegmentsImporterMustRefuseIncompleteSegments()
{
// setup using DAM files
const string segmentFile = "segments.csv";
const string soilprofileFile = "soilprofiles.csv";
var dir = @"..\..\..\data\\Dam\Waterboards\Delfland\regionaal\csv files\";
using (var project = new DSoilModelProject())
{
// complete import
project.SoilProfiles1D.AddRange(new SoilProfilesImporter().ReadSoilProfiles(dir + soilprofileFile, new SoilList()));
Assert.AreEqual(147, project.SoilProfiles1D.Count);
LogManager.Clear();
DSoilModelIO.ReadCsvSegmentsFromFileAndAddToProject(dir + segmentFile, project);
Assert.AreEqual(10, project.SoilSegments.Count);
Assert.AreEqual(0, LogManager.Messages.Count);
// incomplete import of segments
project.SoilProfiles1D.Clear();
project.SoilSegments.Clear();
DSoilModelIO.ReadCsvSegmentsFromFileAndAddToProject(dir + segmentFile, project);
Assert.AreEqual(0, project.SoilSegments.Count);
Assert.GreaterOrEqual(LogManager.Messages.Count, 10);
}
}
[Test]
public void StoreAndRestoreUnusedStressTables()
{
// even if a stresstable has no records, is not used by any soil, save and reopen project should not discard those
const string testFile = @"TestFiles\EmptyStressTables.soil";
using (var project = new DSoilModelProject())
{
project.StressCurves.Add(new StressCurve { Name = "StressCurve" } );
project.BondStressCurves.Add(new BondStressCurve { Name = "BondStressCurve" });
DSoilModelIO.SaveSoilDatabase(testFile, project);
}
using (var project = (DSoilModelProject) DSoilModelIO.OpenSoilDatabase(testFile))
{
Assert.AreEqual(1, project.StressCurves.Count);
Assert.AreEqual("StressCurve", project.StressCurves.First().Name);
Assert.AreEqual(1, project.BondStressCurves.Count);
Assert.AreEqual("BondStressCurve", project.BondStressCurves.First().Name);
}
}
[Test]
public void HandleSegmentCsvImportWithMissingProfiles()
{
// see issue DSB-389, dataset wit all profiles missing
var project = new DSoilModelProject();
LogManager.Clear();
project.ReadSoilProfiles1DFromFile(@"TestFiles\Missing profiles\1D_profiles.csv");
Assert.AreEqual(3, project.SoilProfiles1D.Count);
Assert.AreEqual(5, LogManager.Messages.Count(m => m.Message.Contains("undefined soil")));
LogManager.Clear();
DSoilModelIO.ReadCsvSegmentsFromFileAndAddToProject(@"TestFiles\Missing profiles\Soilsegments.csv", project, true);
Assert.AreEqual(0, project.SoilSegments.Count);
Assert.AreEqual(2, LogManager.Messages.Count(m => m.Message.Contains("profiles are missing")));
// dataset with partially missing profiles
project = new DSoilModelProject();
LogManager.Clear();
project.ReadSoilProfiles1DFromFile(@"TestFiles\Missing profiles\1D_profiles_2segmenten.csv");
Assert.AreEqual(5, project.SoilProfiles1D.Count);
Assert.AreEqual(7, LogManager.Messages.Count(m => m.Message.Contains("undefined soil")));
LogManager.Clear();
DSoilModelIO.ReadCsvSegmentsFromFileAndAddToProject(@"TestFiles\Missing profiles\Soilsegments_2segmenten.csv", project, true);
Assert.AreEqual(2, project.SoilSegments.Count);
Assert.AreEqual(2, LogManager.Messages.Count(m => m.Message.Contains("profiles are missing")));
}
}
}