// Copyright (C) Stichting Deltares 2024. All rights reserved. // // This file is part of the Dam Engine. // // The Dam Engine is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero 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 Affero General Public License for more details. // // You should have received a copy of the GNU Affero 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; namespace Deltares.DamEngine.Data.General.TimeSeries; public class TimeSerie { /// /// List of parameter identifiers used in Fews timeseries /// public const string WaterLevelParameterId = "Waterlevel"; public const string WaterPressureParameterId = "Waterpressure"; public const double DefaultMissingValue = -999.0; //Bka: read only not possible to serialize to DB private readonly List entries; private IList entries; public TimeSerie() { entries = new List(); ForecastDateTime = DateTime.MinValue; } public string LocationId { get; set; } public string ParameterId { get; set; } public DateTime StartDateTime { get; set; } public DateTime EndDateTime { get; set; } public DateTime ForecastDateTime { get; set; } public double MissVal { get; set; } public string Units { get; set; } public DateTime? CreationDateTime { get; set; } public virtual IList Entries { get { return entries; } set { entries = value; } } public string Comment { get; set; } /// /// Creates a shallow copy of the current time serie and applies the map function to each of its entries /// /// The time serie entry function which maps uses the current value as input /// Time serie (clone) with new calculated entries public TimeSerie Map(Func function) { return Map(ParameterId, function); } /// /// Creates a shallow copy of the current time serie and applies the map function to each of its entries /// /// The (new) id of the parameter in the cloned time serie /// The (new) location id of the cloned time serie /// The time serie entry function which maps uses the current value as input /// Time serie (clone) with new calculated entries public TimeSerie Map(string parameterId, string locationId, Func function) { return Map(this, parameterId, locationId, function); } /// /// Creates a shallow copy of the current time serie and applies the map function to each of its entries /// /// The (new) id of the parameter in the cloned time serie /// The time serie entry function which maps uses the current value as input /// Time serie (clone) with new calculated entries public TimeSerie Map(string parameterId, Func function) { return Map(this, parameterId, function); } /// /// Creates a shallow copy of the current time serie and applies the map function to each of its entries /// /// The time serie to map from /// The (new) id of the parameter in the cloned time serie /// The time serie entry function which maps uses the current value as input /// Time serie (clone) with new calculated entries public static TimeSerie Map(TimeSerie timeSerie, string parameterId, Func function) { return Map(timeSerie, parameterId, null, function); } /// /// Creates a shallow copy of the current time serie and applies the map function to each of its entries /// /// The time serie to map from /// The (new) id of the parameter in the cloned time serie /// The (new) location id of the cloned time serie /// The time serie entry function which maps uses the current value as input /// Time serie (clone) with new calculated entries public static TimeSerie Map(TimeSerie timeSerie, string parameterId, string locationId, Func function) { TimeSerie result = CreateTimeSerie(timeSerie, parameterId); if (!(string.IsNullOrEmpty(locationId) || locationId.Trim() == "")) { result.LocationId = locationId; } foreach (TimeSerieEntry entry in timeSerie.Entries) { result.Entries.Add(function(entry)); } return result; } /// /// Gets a shallow copy of the time serie without the time serie entries /// /// A copy of this time serie public TimeSerie GetShallowCopy() { var serie = new TimeSerie { ParameterId = ParameterId, LocationId = LocationId, StartDateTime = StartDateTime, EndDateTime = EndDateTime, ForecastDateTime = ForecastDateTime, MissVal = MissVal, CreationDateTime = CreationDateTime, Units = Units }; serie.Entries.Clear(); return serie; } public static TimeSerie CreateTimeSerie(string locationId) { var timeSerie = new TimeSerie { MissVal = DefaultMissingValue, ParameterId = WaterLevelParameterId, LocationId = locationId, Units = "m", Comment = "" }; return timeSerie; } /// /// Creates a time serie by copying data from the source time serie without /// time serie entries (shallow copy) /// /// The source time serie used to copy from /// The new parameter ID /// A time serie copy without time entries public static TimeSerie CreateTimeSerie(TimeSerie source, string parameterId) { TimeSerie serie = source.GetShallowCopy(); serie.ParameterId = parameterId; serie.Units = "-"; serie.Comment = ""; return serie; } public double GetValue(DateTime dateTime) { foreach (TimeSerieEntry entry in Entries) { if (entry.DateTime >= dateTime) { return entry.Value; } } return -1; } }