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"))); } } }