using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using DHI.Generic.MikeZero.DFS.dfs123;
using Oatc.OpenMI.Sdk.Backbone;
using OpenDA.DotNet.Bridge;
using OpenDA.DotNet.Interfaces;
using DHI.Generic.MikeZero.DFS;
namespace org.openda.dotnet.DHIStochObserver
{
///
/// A DHI .NET stochastic observer class that reads DHI type .DFS files.
/// This is used as part of OpenDA.
/// Supported file types:
/// - dfs0, dfs2, dfs3.
///
/// Written by Nils van Velzen and Marc Ridler
///
public class DHIStochObserver : IStochObserver, IObservationDescriptions
{
// Only two options. Either a dfs0 file, or a dfs2/dfs3 file.
private IDfsRead _dfsInfo;
private List _selectedDataPoints;
private ITime _selectionTime;
///
/// Constructor
///
public DHIStochObserver()
{
}
///
/// Construct a DHI stoch observer from input file.
/// NOTE. Only one dfs file supported.
/// - DFS0 files may contain multiple time series of different type.
///
///
/// Directory containing a .DFS file. (in string format)
/// arguments (the dfs file name).
public void Initialize(String workingDir, String[] arguments)
{
string dfsFileName;
if (!Directory.Exists(workingDir))
{
// The workingDir does not exist
throw new FileNotFoundException("Directory does not exist:" + workingDir);
}
if (arguments != null)
{
dfsFileName = Path.Combine(workingDir, arguments[0]);
if(!File.Exists(dfsFileName))
{
throw new FileNotFoundException("File does not exist:" + dfsFileName);
}
}
else
{
throw new Exception("Argument containing the dfs file name required to initialize DHIStockObserver.");
}
// Determine Type
string fileExtension = Path.GetExtension(dfsFileName);
if (String.Compare(fileExtension, ".dfs3", StringComparison.OrdinalIgnoreCase) == 0 ||
String.Compare(fileExtension, ".dfs2", StringComparison.OrdinalIgnoreCase) == 0 ||
String.Compare(fileExtension, ".dfs0", StringComparison.OrdinalIgnoreCase) == 0
)
{
fileExtension = Path.GetExtension(dfsFileName);
}
else
{
throw new Exception("\n ERROR: Observation File Type Incorrect! Expecting dfs2, dfs3 or dfs0. \n \n");
}
if (StringComparer.OrdinalIgnoreCase.Equals(fileExtension, ".dfs3") ||
StringComparer.OrdinalIgnoreCase.Equals(fileExtension, ".dfs2"))
{
throw new NotImplementedException("not done yet");
}
else if (String.Compare(fileExtension, ".dfs0", StringComparison.OrdinalIgnoreCase) == 0)
{
_dfsInfo = new Dfs0Reader(dfsFileName);
}
else
{
throw new Exception("\n ERROR: Observation File Type Incorrect! Expecting dfs2, dfs3 or dfs0. \n \n");
}
// The Selection begins with the entire dfs file.
_selectionTime = (ITime)(new OpenDA.DotNet.Bridge.Time(_dfsInfo.StartTime.ToModifiedJulianDay()-1, _dfsInfo.EndTime.ToModifiedJulianDay()));
// Gets the data ready. Reads all the points and stores to memory.
_selectedDataPoints = _dfsInfo.GetDataFromTimeRange(new Oatc.OpenMI.Sdk.Backbone.Time(_selectionTime.BeginTime.MJD).ToDateTime(), new Oatc.OpenMI.Sdk.Backbone.Time(_selectionTime.EndTime.MJD).ToDateTime());
}
/*
* Create an new Stochastic Observer, containing a selection of the present stochastic observer.
* The selection criteria is a timeSpan. The start time of the interval is not included, the end time is
* included, i.e. t_start
* The selection criteria is the type of observations: assimilation or validation
*
* @param observationType The requested type of observations.
* @return Stochastic Observer containing the required selection.
*/
public IStochObserver createSelection(Type observationType)
{
return null;
}
/**
* Number of observations in the Stochastic Observer.
* @return The number of observations.
*/
public int getCount()
{
return 0;
}
/**
* Get the values for all observations.
* @return The observed values.
*/
public double[] getValues()
{
return _selectedDataPoints.Select(p => p.Data).ToArray();
}
//TODO: Implement. Get values plus noise.
/**
* Get realization values for all observations, for one ensemble member.
* @return The realizations.
*/
public double[] getRealizations()
{
int n = _selectedDataPoints.Count;
double[] fakeRealization = new double[n];
Random random = new Random();
//TODO: This is nonesense - fix it.
for (int i = 0; i < n; i++)
{
fakeRealization[i] = _selectedDataPoints[i].Data + _selectedDataPoints[i].Data*0.05*random.NextDouble();
}
return fakeRealization;
}
/**
* Get expectation values for all stochastic observations.
* @return The expectations.
*/
public double[] getExpectations()
{
return null;
}
/**
* Evaluate the PDF for stochastic observations, given the values for those observation.
* @param values values for observation's PDF-evaluation.
* @return The PDF evaluations.
*/
public double evaluatePDF(double[] values)
{
return 0.0;
}
/**
* Evaluate the PDF for stochastic observations, given the values for those observation.
* @param values values for observation's PDF-evaluation.
* @return The PDF evaluations.
*/
public double[] evaluateMarginalPDFs(double[] values)
{
return null;
}
/**
* Get the covariance matrix (as a vector) for the stochastic observations.
* @return The covariance matrix.
*/
public ISqrtCovariance getSqrtCovariance()
{
return null;
}
//TODO: Implement return Standard deviation.
/**
* Get the standard deviation for each each stochastic observation.
* @return The standard deviations.
*/
public double[] getStandardDeviations()
{
int n = _selectedDataPoints.Count;
double[] fakeStd = new double[n];
Random random = new Random();
//TODO: This is nonesense - fix it.
for (int i = 0; i < n; i++)
{
fakeStd[i] = _selectedDataPoints[i].Data * 0.05 * random.NextDouble();
}
return fakeStd;
}
public ITime[] Times
{
get
{
var times = _selectedDataPoints.Select(p => p.Time).ToList().ConvertAll(new Converter(DateTimeToITime)).ToArray();
return times;
}
}
/**
* free the Stochastic Observer.
*/
public void free()
{
}
/**
* Get the observation descriptions.
* @return The Observation Descriptions
*/
public IObservationDescriptions getObservationDescriptions()
{
return (IObservationDescriptions)this;
}
/* Methods from the ObservationDescriptions */
///
/// Get the exchange items describing the measures available in the stoch. observer.
///
/// All exchange items in the stoch. observer.
public List ExchangeItems
{
get { throw new NotImplementedException("ExchangeItems Not implemented."); }
}
///
/// Get properties (values) that correspond to a given key.
///
/// I key for which the value is asked
/// Properties (column of data from observation descriptions)
public IVector GetValueProperties(String Key)
{
//TODO: Check hos the key is passed. With '(' and ')'?
DataPoint point = _selectedDataPoints.First(p => System.String.CompareOrdinal(p.XYLayerPoint.ToString(), Key) == 0);
double[] vecDouble = new double[3];
vecDouble[0] = point.XYLayerPoint.X;
vecDouble[1] = point.XYLayerPoint.Y;
vecDouble[2] = (double)point.XYLayerPoint.Layer;
IVector vec = new Vector(vecDouble);
return vec;
}
///
/// Get properties (strings) that correspond to a given key.
///
/// I key for which the value is asked
/// Properties (column of data from observation descriptions)
public String[] GetStringProperties(String Key)
{
return null;
}
///
/// Get names of all keys.
///
/// error status: All keys of the observation descriptions
public String[] PropertyKeys
{
get { return _selectedDataPoints.Select(p => p.VariableID).ToArray(); }
}
///
/// Get number of properties/keys.
///
/// number of properties
public int PropertyCount
{
get { return 0; }
}
///
/// Get number of observations.
///
/// number of observations
public int ObservationCount
{
get { return 0; }
}
#region Static converts
private static ITime DateTimeToITime(DateTime dateTime)
{
return new OpenDA.DotNet.Bridge.Time(dateTime.ToModifiedJulianDay());
}
#endregion
}
}