// 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
}