// Copyright (C) Stichting Deltares 2025. All rights reserved.
//
// This file is part of the application DAM - UI.
//
// DAM - UI 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.Globalization;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Deltares.Dam.Data;
using Deltares.Dam.Data.Assemblers;
using Deltares.Standard.IO.DtoAssembler;
using NUnit.Framework;
namespace Deltares.Dam.Tests
{
[TestFixture]
public class TimeSeriesAssemblerTest
{
private const string testFileName = @"TestData\HoekscheWaard\input_dam.xml";
private const double Precision = 1e-8;
private XDocument testDoc;
private TimeSeriesAssembler assembler;
[SetUp]
public void TestFixtureSetup()
{
testDoc = XDocument.Load(testFileName);
}
#region Setup/Teardown
[SetUp]
public void TestSetup()
{
assembler = new TimeSeriesAssembler();
}
#endregion
[Test]
public void CreateDtoFromEntity()
{
var timeSerieCollection = new TimeSerieCollection();
timeSerieCollection.TimeZone = 4.75;
timeSerieCollection.Version = "1.2";
var timeSerie = new TimeSerie();
timeSerie.Type = "accumulative";
timeSerie.LocationId = "LLANFAIR-04";
timeSerie.ParameterId = "Train speed";
timeSerie.TimeStep.Unit = TimeStepUnit.Hour;
timeSerie.TimeStep.Multiplier = 12;
timeSerie.TimeStep.Divider = 60;
timeSerie.StartDateTime = new DateTime(2009, 4, 13, 11, 51, 42);
timeSerie.EndDateTime = new DateTime(2009, 5, 18, 22, 04, 16);
timeSerie.MissVal = 82.9;
timeSerie.LongName = "Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch";
timeSerie.StationName = "Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch Railway Station";
timeSerie.Units = "mph";
timeSerie.SourceOrganisation = "British Rail";
timeSerie.SourceSystem = "British railroad system";
timeSerie.FileDescription = "Llanfair trains";
timeSerie.CreationDateTime = new DateTime(2009, 6, 3, 11, 54, 17);
timeSerie.Region = "North Wales";
timeSerie.Entries.Add(new TimeSerieEntry
{
DateTime = new DateTime(2009, 4, 13, 11, 51, 42),
Value = 103.7,
Flag = 0
});
timeSerie.Entries.Add(new TimeSerieEntry
{
DateTime = new DateTime(2009, 4, 13, 12, 51, 42),
Value = 88.4,
Flag = 1
});
timeSerie.Entries.Add(new TimeSerieEntry
{
DateTime = new DateTime(2009, 4, 13, 13, 51, 42),
Value = 120.53,
Flag = 1
});
timeSerie.Entries.Add(new TimeSerieEntry
{
DateTime = new DateTime(2009, 4, 13, 14, 51, 42),
Value = 108.5,
Flag = 2
});
timeSerie.Comment = "Who knows how to pronounce Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch?";
timeSerieCollection.Series.Add(timeSerie);
timeSerie = new TimeSerie();
timeSerie.Type = "instantaneous";
timeSerie.LocationId = "GORSAF-13";
timeSerie.ParameterId = "Bus speed";
timeSerie.TimeStep.Unit = TimeStepUnit.Minute;
timeSerie.TimeStep.Multiplier = 18;
timeSerie.TimeStep.Divider = 35;
timeSerie.StartDateTime = new DateTime(2009, 3, 29, 13, 4, 17);
timeSerie.EndDateTime = new DateTime(2009, 5, 4, 8, 52, 37);
timeSerie.MissVal = 109.17;
timeSerie.Entries.Add(new TimeSerieEntry
{
DateTime = new DateTime(2009, 3, 29, 13, 4, 17),
Value = 45.7,
Flag = 0
});
timeSerie.Entries.Add(new TimeSerieEntry
{
DateTime = new DateTime(2009, 3, 29, 13, 5, 17),
Value = 55.4,
Flag = 1
});
timeSerie.Entries.Add(new TimeSerieEntry
{
DateTime = new DateTime(2009, 3, 29, 13, 6, 17),
Value = 80.57,
Flag = 1
});
timeSerie.Entries.Add(new TimeSerieEntry
{
DateTime = new DateTime(2009, 3, 29, 13, 7, 17),
Value = 120.45,
Flag = 3
});
timeSerie.Entries.Add(new TimeSerieEntry
{
DateTime = new DateTime(2009, 3, 29, 13, 8, 17),
Value = 108.45,
Flag = 1
});
timeSerie.Entries.Add(new TimeSerieEntry
{
DateTime = new DateTime(2009, 3, 29, 13, 9, 17),
Value = 115.6,
Flag = 2
});
timeSerieCollection.Series.Add(timeSerie);
// Do the thing: create XML document from TimeSeries
XDocument doc = assembler.CreateDataTransferDocument(timeSerieCollection);
// Save XML for viewing purposes
Directory.CreateDirectory(@"TestResults");
doc.Save(@"TestResults\TestSeriesTestOut.xml");
// Validate against schema
string message;
if (!assembler.ValidateSchema(doc, out message))
{
Assert.Fail("SCHEMA VALIDATION: " + message);
}
XNamespace tns = assembler.ElementNamespace;
// Version
Assert.That(doc.Root.AttributeAs(TimeSeriesAssembler.XmlVersionAttributeName), Is.EqualTo("1.2"));
// Time zone
Assert.That(Double.Parse(doc.Root.Element(tns + TimeSeriesAssembler.XmlTimeZoneElementName).Value,
CultureInfo.InvariantCulture),
Is.EqualTo(4.75));
// Series
XElement[] serieElements = doc.Root.Elements(tns + TimeSeriesAssembler.XmlSeriesElementName).ToArray();
Assert.That(serieElements.Count(), Is.EqualTo(2));
XElement headerElement = serieElements[0].Element(tns + TimeSeriesAssembler.XmlHeaderElementName);
// Header (0)
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlTypeElementName).Value, Is.EqualTo("accumulative"));
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlLocationIdElementName).Value,
Is.EqualTo("LLANFAIR-04"));
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlParameterIdElementName).Value,
Is.EqualTo("Train speed"));
XElement timeStepElement = headerElement.Element(tns + TimeSeriesAssembler.XmlTimeStepElementName);
Assert.That(timeStepElement.AttributeAs(TimeSeriesAssembler.XmlUnitAttributeName), Is.EqualTo("hour"));
Assert.That(timeStepElement.AttributeAs(TimeSeriesAssembler.XmlDividerAttributeName), Is.EqualTo(60));
Assert.That(timeStepElement.AttributeAs(TimeSeriesAssembler.XmlMultiplierAttributeName), Is.EqualTo(12));
XElement startDateElement = headerElement.Element(tns + TimeSeriesAssembler.XmlStartDateElementName);
Assert.That(startDateElement.AttributeAs(TimeSeriesAssembler.XmlDateAttributeName), Is.EqualTo("2009-04-13"));
Assert.That(startDateElement.AttributeAs(TimeSeriesAssembler.XmlTimeAttributeName), Is.EqualTo("11:51:42"));
XElement endDateElement = headerElement.Element(tns + TimeSeriesAssembler.XmlEndDateElementName);
Assert.That(endDateElement.AttributeAs(TimeSeriesAssembler.XmlDateAttributeName), Is.EqualTo("2009-05-18"));
Assert.That(endDateElement.AttributeAs(TimeSeriesAssembler.XmlTimeAttributeName), Is.EqualTo("22:04:16"));
Assert.That(Double.Parse(headerElement.Element(tns + TimeSeriesAssembler.XmlMissValElementName).Value,
CultureInfo.InvariantCulture),
Is.EqualTo(82.9));
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlLongNameElementName).Value,
Is.EqualTo("Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch"));
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlStationNameElementName).Value,
Is.EqualTo("Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch Railway Station"));
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlUnitsElementName).Value, Is.EqualTo("mph"));
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlSourceOrganisationElementName).Value,
Is.EqualTo("British Rail"));
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlSourceSystemElementName).Value,
Is.EqualTo("British railroad system"));
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlFileDescriptionElementName).Value,
Is.EqualTo("Llanfair trains"));
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlCreationDateElementName).Value,
Is.EqualTo("2009-06-03"));
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlCreationTimeElementName).Value,
Is.EqualTo("11:54:17"));
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlRegionElementName).Value, Is.EqualTo("North Wales"));
// Entries (0)
XElement[] entryElements =
serieElements[0].Elements(tns + TimeSeriesAssembler.XmlEntryElementName).ToArray();
Assert.That(entryElements.Count(), Is.EqualTo(4));
Assert.That(entryElements[0].AttributeAs(TimeSeriesAssembler.XmlDateAttributeName), Is.EqualTo("2009-04-13"));
Assert.That(entryElements[0].AttributeAs(TimeSeriesAssembler.XmlTimeAttributeName), Is.EqualTo("11:51:42"));
Assert.That(entryElements[0].AttributeAs(TimeSeriesAssembler.XmlValueAttributeName), Is.EqualTo(103.7));
Assert.That(entryElements[0].AttributeAs(TimeSeriesAssembler.XmlFlagAttributeName), Is.EqualTo(0));
Assert.That(entryElements[1].AttributeAs(TimeSeriesAssembler.XmlDateAttributeName), Is.EqualTo("2009-04-13"));
Assert.That(entryElements[1].AttributeAs(TimeSeriesAssembler.XmlTimeAttributeName), Is.EqualTo("12:51:42"));
Assert.That(entryElements[1].AttributeAs(TimeSeriesAssembler.XmlValueAttributeName), Is.EqualTo(88.4));
Assert.That(entryElements[1].AttributeAs(TimeSeriesAssembler.XmlFlagAttributeName), Is.EqualTo(1));
Assert.That(entryElements[2].AttributeAs(TimeSeriesAssembler.XmlDateAttributeName), Is.EqualTo("2009-04-13"));
Assert.That(entryElements[2].AttributeAs(TimeSeriesAssembler.XmlTimeAttributeName), Is.EqualTo("13:51:42"));
Assert.That(entryElements[2].AttributeAs(TimeSeriesAssembler.XmlValueAttributeName), Is.EqualTo(120.53));
Assert.That(entryElements[2].AttributeAs(TimeSeriesAssembler.XmlFlagAttributeName), Is.EqualTo(1));
Assert.That(entryElements[3].AttributeAs(TimeSeriesAssembler.XmlDateAttributeName), Is.EqualTo("2009-04-13"));
Assert.That(entryElements[3].AttributeAs(TimeSeriesAssembler.XmlTimeAttributeName), Is.EqualTo("14:51:42"));
Assert.That(entryElements[3].AttributeAs(TimeSeriesAssembler.XmlValueAttributeName), Is.EqualTo(108.5));
Assert.That(entryElements[3].AttributeAs(TimeSeriesAssembler.XmlFlagAttributeName), Is.EqualTo(2));
// Comment (0)
Assert.That(serieElements[0].Element(tns + TimeSeriesAssembler.XMLCommentElementName).Value,
Is.EqualTo("Who knows how to pronounce Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch?"));
headerElement = serieElements[1].Element(tns + TimeSeriesAssembler.XmlHeaderElementName);
// Header (1)
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlTypeElementName).Value, Is.EqualTo("instantaneous"));
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlLocationIdElementName).Value, Is.EqualTo("GORSAF-13"));
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlParameterIdElementName).Value,
Is.EqualTo("Bus speed"));
timeStepElement = headerElement.Element(tns + TimeSeriesAssembler.XmlTimeStepElementName);
Assert.That(timeStepElement.AttributeAs(TimeSeriesAssembler.XmlUnitAttributeName), Is.EqualTo("minute"));
Assert.That(timeStepElement.AttributeAs(TimeSeriesAssembler.XmlDividerAttributeName), Is.EqualTo(35));
Assert.That(timeStepElement.AttributeAs(TimeSeriesAssembler.XmlMultiplierAttributeName), Is.EqualTo(18));
startDateElement = headerElement.Element(tns + TimeSeriesAssembler.XmlStartDateElementName);
Assert.That(startDateElement.AttributeAs(TimeSeriesAssembler.XmlDateAttributeName), Is.EqualTo("2009-03-29"));
Assert.That(startDateElement.AttributeAs(TimeSeriesAssembler.XmlTimeAttributeName), Is.EqualTo("13:04:17"));
endDateElement = headerElement.Element(tns + TimeSeriesAssembler.XmlEndDateElementName);
Assert.That(endDateElement.AttributeAs(TimeSeriesAssembler.XmlDateAttributeName), Is.EqualTo("2009-05-04"));
Assert.That(endDateElement.AttributeAs(TimeSeriesAssembler.XmlTimeAttributeName), Is.EqualTo("08:52:37"));
Assert.That(Double.Parse(headerElement.Element(tns + TimeSeriesAssembler.XmlMissValElementName).Value,
CultureInfo.InvariantCulture),
Is.EqualTo(109.17));
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlLongNameElementName), Is.Null);
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlStationNameElementName), Is.Null);
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlUnitsElementName), Is.Null);
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlSourceOrganisationElementName), Is.Null);
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlSourceSystemElementName), Is.Null);
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlFileDescriptionElementName), Is.Null);
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlCreationDateElementName), Is.Null);
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlCreationTimeElementName), Is.Null);
Assert.That(headerElement.Element(tns + TimeSeriesAssembler.XmlRegionElementName), Is.Null);
// Entries (1)
entryElements = serieElements[1].Elements(tns + TimeSeriesAssembler.XmlEntryElementName).ToArray();
Assert.That(entryElements.Count(), Is.EqualTo(6));
Assert.That(entryElements[0].AttributeAs(TimeSeriesAssembler.XmlDateAttributeName), Is.EqualTo("2009-03-29"));
Assert.That(entryElements[0].AttributeAs(TimeSeriesAssembler.XmlTimeAttributeName), Is.EqualTo("13:04:17"));
Assert.That(entryElements[0].AttributeAs(TimeSeriesAssembler.XmlValueAttributeName), Is.EqualTo(45.7));
Assert.That(entryElements[0].AttributeAs(TimeSeriesAssembler.XmlFlagAttributeName), Is.EqualTo(0));
Assert.That(entryElements[1].AttributeAs(TimeSeriesAssembler.XmlDateAttributeName), Is.EqualTo("2009-03-29"));
Assert.That(entryElements[1].AttributeAs(TimeSeriesAssembler.XmlTimeAttributeName), Is.EqualTo("13:05:17"));
Assert.That(entryElements[1].AttributeAs(TimeSeriesAssembler.XmlValueAttributeName), Is.EqualTo(55.4));
Assert.That(entryElements[1].AttributeAs(TimeSeriesAssembler.XmlFlagAttributeName), Is.EqualTo(1));
Assert.That(entryElements[2].AttributeAs(TimeSeriesAssembler.XmlDateAttributeName), Is.EqualTo("2009-03-29"));
Assert.That(entryElements[2].AttributeAs(TimeSeriesAssembler.XmlTimeAttributeName), Is.EqualTo("13:06:17"));
Assert.That(entryElements[2].AttributeAs(TimeSeriesAssembler.XmlValueAttributeName), Is.EqualTo(80.57));
Assert.That(entryElements[2].AttributeAs(TimeSeriesAssembler.XmlFlagAttributeName), Is.EqualTo(1));
Assert.That(entryElements[3].AttributeAs(TimeSeriesAssembler.XmlDateAttributeName), Is.EqualTo("2009-03-29"));
Assert.That(entryElements[3].AttributeAs(TimeSeriesAssembler.XmlTimeAttributeName), Is.EqualTo("13:07:17"));
Assert.That(entryElements[3].AttributeAs(TimeSeriesAssembler.XmlValueAttributeName), Is.EqualTo(120.45));
Assert.That(entryElements[3].AttributeAs(TimeSeriesAssembler.XmlFlagAttributeName), Is.EqualTo(3));
Assert.That(entryElements[4].AttributeAs(TimeSeriesAssembler.XmlDateAttributeName), Is.EqualTo("2009-03-29"));
Assert.That(entryElements[4].AttributeAs(TimeSeriesAssembler.XmlTimeAttributeName), Is.EqualTo("13:08:17"));
Assert.That(entryElements[4].AttributeAs(TimeSeriesAssembler.XmlValueAttributeName), Is.EqualTo(108.45));
Assert.That(entryElements[4].AttributeAs(TimeSeriesAssembler.XmlFlagAttributeName), Is.EqualTo(1));
Assert.That(entryElements[5].AttributeAs(TimeSeriesAssembler.XmlDateAttributeName), Is.EqualTo("2009-03-29"));
Assert.That(entryElements[5].AttributeAs(TimeSeriesAssembler.XmlTimeAttributeName), Is.EqualTo("13:09:17"));
Assert.That(entryElements[5].AttributeAs(TimeSeriesAssembler.XmlValueAttributeName), Is.EqualTo(115.6));
Assert.That(entryElements[5].AttributeAs(TimeSeriesAssembler.XmlFlagAttributeName), Is.EqualTo(2));
// Comment (1)
Assert.That(serieElements[1].Element(tns + TimeSeriesAssembler.XMLCommentElementName), Is.Null);
}
[Test]
public void CreateEntityFromDto()
{
// First validate test XML against schema
var tolerance = 0.001;
string message;
if (!assembler.ValidateSchema(testDoc, out message))
{
Assert.Fail("SCHEMA VALIDATION: " + message);
}
XNamespace tns = assembler.ElementNamespace;
// Do the thing: create TimeSeries from XML element
TimeSerieCollection timeSerieCollection = assembler.CreateDomainObject(testDoc);
Assert.That(timeSerieCollection, Is.Not.Null);
// TimeSeries itself
Assert.That(timeSerieCollection.Version, Is.EqualTo("1.2"), "Version");
Assert.That(timeSerieCollection.TimeZone, Is.EqualTo(0.0), $"TimeZone");
// Number of series
Assert.That(timeSerieCollection.Series.Count, Is.EqualTo(8), "Number of series");
TimeSerie timeSerie = timeSerieCollection.Series[0];
// TimeSerie
Assert.That(timeSerie.Type, Is.EqualTo("instantaneous"));
Assert.That(timeSerie.LocationId, Is.EqualTo("LOC1"));
Assert.That(timeSerie.ParameterId, Is.EqualTo("Waterlevel"));
Assert.That(timeSerie.TimeStep.Unit.ToString().ToLower(), Is.EqualTo("second"));
Assert.That(timeSerie.TimeStep.Divider, Is.EqualTo(1));
Assert.That(timeSerie.TimeStep.Multiplier, Is.EqualTo(3600));
Assert.That(timeSerie.StartDateTime.ToString("yyyy-MM-dd HH:mm:ss"), Is.EqualTo("2009-06-17 08:00:00"));
Assert.That(timeSerie.EndDateTime.ToString("yyyy-MM-dd HH:mm:ss"), Is.EqualTo("2009-06-18 08:00:00"));
Assert.That(timeSerie.MissVal, Is.EqualTo(-999.0));
Assert.That(timeSerie.LongName, Is.Null);
Assert.That(timeSerie.StationName, Is.EqualTo("point 1"));
Assert.That(timeSerie.Units, Is.EqualTo("m"));
Assert.That(timeSerie.SourceOrganisation, Is.Null);
Assert.That(timeSerie.SourceSystem, Is.Null);
Assert.That(timeSerie.FileDescription, Is.Null);
Assert.That(timeSerie.CreationDateTime, Is.Null);
Assert.That(timeSerie.Region, Is.Null);
// Number of entries
Assert.That(timeSerie.Entries.Count, Is.EqualTo(25), "Number of entries");
Assert.That(timeSerie.Entries[0].DateTime.ToString("yyyy-MM-dd HH:mm:ss"), Is.EqualTo("2009-06-17 08:00:00"));
Assert.That(timeSerie.Entries[0].Value, Is.EqualTo(2.32).Within(tolerance));
Assert.That(timeSerie.Entries[0].Flag, Is.EqualTo(0));
// Comment
Assert.That(timeSerie.Comment, Is.Null);
}
}
}