using System;
using System.Collections.Generic;
using System.Linq;
using Deltares.Standard.Application;
namespace Deltares.Dam.Data
{
public abstract class TimeSeriesProcessor
{
internal readonly static LogHelper Logger = LogHelper.Create("Time Series Processor");
#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
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 (var timeSeries in InputTimeSeriesCollection.Series)
{
foreach (var location in OutputLocations)
{
foreach (var parameter in OutputParameters)
{
var copyOfSeries = timeSeries.GetShallowCopy();
foreach (var entry in timeSeries.Entries)
{
// get copy of the input entry
var 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);
}
}
}
}
}
}