// Copyright (C) Stichting Deltares 2024. 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.Collections.Generic; using Deltares.Standard.Application; namespace Deltares.Dam.Data; public abstract class TimeSeriesProcessor { internal readonly static LogHelper Logger = LogHelper.Create("Time Series Processor"); public ICalculator Calculator { protected get; set; } /// /// Gets or sets the output parameter ID. /// /// This name or ID is used in the output (FEWS) time series /// /// The output parameter ID. /// public IEnumerable OutputParameters { get; set; } /// /// Sets the input time series, used in the calculations /// public TimeSerieCollection InputTimeSeriesCollection { protected get; set; } /// /// Gets or sets the output location ID colletion used for creating the output time series /// public virtual IEnumerable OutputLocations { get; set; } /// /// Gets or the output time series /// public TimeSerieCollection OutputTimeSeriesCollection { get; set; } /// /// Resets the monitoring point list /// public virtual void Initialize() { if (OutputTimeSeriesCollection == null) { OutputTimeSeriesCollection = InputTimeSeriesCollection.GetShallowCopy(); } else { OutputTimeSeriesCollection.Clear(); } } /// /// Loads the input time series. /// /// Name of the file. public void LoadInputTimeSeries(string fileName) { ThrowHelper.ThrowIfFileNameNullOrEmpty(fileName); try { // load the input time serie containing all water levels InputTimeSeriesCollection = TimeSerieCollection.LoadFromFile(fileName); } catch (Exception e) { throw new InvalidOperationException("There was an error loading the input time series", e); } } /// /// Saves the output time series to the specified file /// /// /// The output file that will contain the monitored and calculated results for each time entry public void SaveResultsToFile(string fileName) { if (OutputTimeSeriesCollection == null) { throw new InvalidOperationException("No output time series collection to write"); } if (string.IsNullOrWhiteSpace(fileName)) { fileName = DefaultOutputFileName; } // save the time serie to the output file OutputTimeSeriesCollection.Save(fileName); } /// /// Processes the FEWS input time series files to ouput /// time series /// public virtual void Process() { if (InputTimeSeriesCollection == null) { return; } if (OutputTimeSeriesCollection == null) { throw new InvalidOperationException("No output time series set to write the results to"); } if (OutputLocations == null) { throw new InvalidOperationException("No output locations set. Set or override OutputLocations"); } if (OutputParameters == null) { throw new InvalidOperationException("No output parameters set. Set or override OutputParameters"); } try { // Process the time series entries for each sensor and set the // value in the output time series CreateOutputSeries(); } catch (Exception e) { const string message = "There was an error processing the time series"; Logger.LogFatal(message, e); throw new InvalidOperationException(message, e); } } /// /// Processes the actual input to the output collection. This is a template method which will /// be called in the public ProcessSeries() method (if not overriden) /// protected virtual void CreateOutputSeries() { foreach (TimeSerie timeSeries in InputTimeSeriesCollection.Series) { foreach (string location in OutputLocations) { foreach (string parameter in OutputParameters) { TimeSerie copyOfSeries = timeSeries.GetShallowCopy(); foreach (TimeSerieEntry entry in timeSeries.Entries) { // get copy of the input entry TimeSerieEntry copyOfEntry = entry.GetShallowCopy(); // calculate its value copyOfEntry.Value = Calculator.Calculate(location, parameter) ?? MissingValue; // set parameter and location id's and add the projected entry to the output copyOfSeries.LocationId = location; copyOfSeries.ParameterId = parameter; copyOfSeries.Entries.Add(copyOfEntry); } // add the output series to the output collection OutputTimeSeriesCollection.Series.Add(copyOfSeries); } } } } #region Constants /// /// Defines the default output file /// private const string DefaultOutputFileName = "output.xml"; /// e /// Defines the water level location id used in the FEWS time serie /// public const string WaterLevelInputLocationID = "outside"; /// /// Defines the parameter id of the water level defined in the FEWS time serie /// public const string WaterLevelInputParameterID = "Waterlevel"; /// /// Defines the parameter id for water pressure used in the FEWS time serie /// public const string WaterPressureParameterID = "Waterpressure"; /// /// Defines the sensor state missing value /// internal const double MissingValue = -999; #endregion }