// Copyright (C) Stichting Deltares 2019. All rights reserved.
//
// This file is part of the application DAM - Clients Library.
//
// 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 System.Linq;
using System.Xml.Linq;
using System.IO;
using Deltares.Dam.Data.Assemblers;
using Deltares.Standard.Extensions;
namespace Deltares.Dam.Data
{
public class TimeSerieCollection
{
public TimeSerieCollection()
{
this.Series = new List();
}
public List Series { get; set; }
public string Version { get; set; }
public double TimeZone { get; set; }
///
/// Loads a time serie collection from file and validates the file with the resource embedded XSD
///
/// The file info object containing the file to load
/// When valid a loaded time serie collection
///
public static TimeSerieCollection LoadFromFile(FileInfo fileInfo)
{
return LoadFromFile(fileInfo.FullName, true);
}
///
/// Loads a time serie collection from file and validates the file with the resource embedded XSD
///
/// The file to load
/// When valid a loaded time serie collection
///
public static TimeSerieCollection LoadFromFile(string fileName)
{
return LoadFromFile(fileName, true);
}
///
/// Loads a time serie collection from file.
///
/// The file name of the time serie
/// The value indicating if the file needs to be validated
/// The loaded time serie collection
public static TimeSerieCollection LoadFromFile(string fileName, bool validateWithEmbeddedXsd)
{
string message;
var assembler = new TimeSeriesAssembler();
var doc = XDocument.Load(fileName);
if (validateWithEmbeddedXsd)
if (!assembler.ValidateSchema(doc, out message))
throw new TimeSerieSchemaValidationException(message);
return assembler.CreateDomainObject(doc);
}
///
/// Saves the time serie collection to a specified file using the time serie assembler
///
/// The name of the file
public void Save(string fileName)
{
ThrowHelper.ThrowIfFileNameNullOrEmpty(fileName, StringResourceNames.FileNameNotValid);
var timeSerieAssembler = new TimeSeriesAssembler();
XDocument doc = timeSerieAssembler.CreateDataTransferDocument(this);
doc.Save(fileName);
FileWriterUtil.RemoveThreeBytesFromXml(fileName); // apply this fix for FEWS!
}
///
/// Updates the time serie entries with new values by applying the function to each value entry
///
/// The parameter ID of the time serie to update
/// The function to apply to each entry
public void UpdateAllEntryValues(string parameterId, Func function)
{
foreach (var timeSerie in this.GetSeriesByParameterId(parameterId))
{
foreach (var sourceEntry in timeSerie.Entries)
{
if (!sourceEntry.Value.AlmostEquals(timeSerie.MissVal))
{
sourceEntry.Value = function(sourceEntry.Value);
}
}
}
}
///
/// Creates a shallow copy of the current time serie collection and applies the map function to each of its entries
///
public IEnumerable Map(IEnumerable locations, string parameterId, IEnumerable> functionList)
{
return from locationId in locations
from timeSerie in this.GetSeriesByLocationId(locationId).Where(x => x.ParameterId.Equals(parameterId))
from function in functionList
select function(timeSerie);
}
///
/// Creates a shallow copy of the current time serie collection and applies the map function to each of its entries
///
/// The locations to look for in this collection
/// The parameter to look for in this collection
/// The function to apply
/// A sequence of new time series with the applied function to its entries
public IEnumerable Map(IEnumerable locations, string parameterId, Func function)
{
return Map(locations, parameterId, new List> { function });
}
///
/// Creates a shallow copy of the current time serie collection and applies the map function to each of its entries
///
public IEnumerable Map(string locationId, string parameterId, Func function)
{
return Map(new List { locationId }, parameterId, function);
}
///
/// Searches for a time series matching the location and parameter id. There should be only 1 or none (null)
///
/// The parameter id.
/// The location id.
/// The time series matching the criterium
public TimeSerie FindSerie(string parameterId, string locationId)
{
return (from series in this.Series
where series.ParameterId.Equals(parameterId, StringComparison.InvariantCultureIgnoreCase) &&
series.LocationId.Equals(locationId, StringComparison.InvariantCultureIgnoreCase)
select series).SingleOrDefault();
}
///
/// Gets all the time series with the given parameter id.
///
/// The parameter id.
/// The time series matching the criteria
public IEnumerable GetSeriesByParameterId(string parameterId)
{
return from series in this.Series
where series.ParameterId.Equals(parameterId, StringComparison.InvariantCultureIgnoreCase)
select series;
}
///
/// Gets all the series with the given location id.
///
/// The location id.
/// The time series matching the criteria
public IEnumerable GetSeriesByLocationId(string locationId)
{
return from series in this.Series
where series.LocationId.Equals(locationId, StringComparison.InvariantCultureIgnoreCase)
select series;
}
///
/// Gets the series containing location id and parameter id.
///
/// The location id.
/// The parameter id.
/// The time series matching the criteria
public IEnumerable GetSeriesByLocationIdAndParameterId(string locationId, string parameterId)
{
return from series in this.Series
where series.LocationId.Equals(locationId, StringComparison.InvariantCultureIgnoreCase) &&
series.ParameterId.Equals(parameterId, StringComparison.InvariantCultureIgnoreCase)
select series;
}
///
/// Gets all the series containing the combined gage and location id. (using the gage_id/location_id pattern)
///
/// The combined gage and location id.
///
public IEnumerable GetSeriesByGageIdAndLocationId(string combinedGageAndLocationId)
{
var resultSeries = new List();
foreach (var serie in this.Series)
{
string gaugeLocationId = serie.LocationId.Split('/')[0];
if (combinedGageAndLocationId.Equals(gaugeLocationId, StringComparison.InvariantCultureIgnoreCase))
{
resultSeries.Add(serie);
}
}
return resultSeries;
}
public TimeSerieCollection GetShallowCopy()
{
var copy = new TimeSerieCollection
{
Version = Version,
TimeZone = TimeZone
};
copy.Series.Clear();
return copy;
}
///
/// Clears the time series.
///
public void Clear()
{
Series.Clear();
}
public TimeSerie AddNewSeries(string locationId)
{
var series = TimeSerie.CreateTimeSerie(locationId);
this.Series.Add(series);
return series;
}
}
}