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