//-----------------------------------------------------------------------
//
// Copyright (c) 2009 Deltares. All rights reserved.
//
// B. Faassen
// barry.faassen@deltares.nl
// 19-5-2009
// n.a.
//-----------------------------------------------------------------------
using Deltares.Standard.Extensions;
namespace Deltares.Dam.Data
{
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Text;
using System.Collections.Generic;
using Standard;
///
/// Parses the stability factor from the file contents of the stability output file
///
///
/// The parser looks for the [Dump] identifier and if found the [Data] id.
/// When found the next line contains several numbers. We need the first one which is the stability factor
///
public class StabilityServiceFileParser
{
enum StabilityZone { stabilityZone1a = 1, stabilityZone1b = 2, stabilityZone2a = 3, stabilityZone2b = 4, stabilityZone3a = 5, stabilityZone3b = 6 };
///
/// Gets the file content (text) from a file
///
/// The name of the file
/// The content string
public static string GetFileContents(string fileName)
{
ThrowHelper.ThrowIfStringArgumentNullOrEmpty(fileName, StringResourceNames.OutputFileNameNotValid);
ThrowHelper.ThrowIfFileNotExist(fileName, StringResourceNames.OutputFileNotExist);
string fileContents;
using (var sr = new StreamReader(fileName))
{
fileContents = sr.ReadToEnd();
}
return fileContents;
}
///
/// Parses the content to get the safety factory
///
/// The text to parse
/// The safety factor
private static double GetColumnValueNoZones(string fileContent, string columnName)
{
fileContent = ReadContentAfterIdentifier(fileContent, "[Dumps]");
fileContent = ReadContentAfterIdentifier(fileContent, "[Dump]");
fileContent = ReadContentAfterIdentifier(fileContent, "[Dump Header]");
fileContent = ReadContentAfterIdentifier(fileContent, "[Column Indication]");
int columnIndex = GetDataColumnIndex(fileContent, columnName, "[End of Column Indication]");
fileContent = ReadContentAfterIdentifier(fileContent, "[Data]");
double columnValue = GetNumberFromLine(fileContent, columnIndex);
return columnValue;
}
private static bool IsUpliftResults(string fileContent)
{
fileContent = ReadContentAfterIdentifier(fileContent, "[MODEL]");
if (fileContent.Contains(" 4 : Uplift Van"))
{
return true;
}
else
{
return false;
}
}
private static MStabResultsSingleZone GetMStabResultsNoZones(string fileContent)
{
MStabResultsSingleZone mStabResultsStruct = new MStabResultsSingleZone();
mStabResultsStruct.safetyFactor = GetColumnValueNoZones(fileContent, "Stability factor");
if (IsUpliftResults(fileContent))
mStabResultsStruct.safetyFactor = mStabResultsStruct.safetyFactor / 1.05;
mStabResultsStruct.circleSurfacePointLeftXCoordinate = GetColumnValueNoZones(fileContent, "X coordinate left surface");
mStabResultsStruct.circleSurfacePointRightXCoordinate = GetColumnValueNoZones(fileContent, "X coordinate right surface");
return mStabResultsStruct;
}
public static double GetBetaNoZones(string fileContent)
{
return GetColumnValueNoZones(fileContent, "Beta");
}
public static double GetBetaWithZones(string fileContent)
{
MStabResults mStabResults = new MStabResults();
MStabResultsSingleZone? zoneResults1 = GetMStabResultsSingleZoneFrom(fileContent, StabilityZone.stabilityZone1a, StabilityZone.stabilityZone1b);
if (zoneResults1 != null)
{
mStabResults.zone1 = zoneResults1.Value;
}
else
{
throw new StabilityFileParseException("Stabilityzone 1a or 1b should exist");
}
//mStabResults.zone2 = GetMStabResultsSingleZoneFrom(fileContent, StabilityZone.stabilityZone2a, StabilityZone.stabilityZone2b);
return mStabResults.zone1.beta;
}
///
/// Get the results from a zone (A or if not exists then B)
///
///
///
private static MStabResultsSingleZone? GetMStabResultsSingleZoneFrom(string fileContent, StabilityZone zoneA, StabilityZone zoneB)
{
MStabResultsSingleZone? mStabResultsSingleZone = null;
MStabResultsSingleZone? zoneAResults = ParseZoneResults(fileContent, (int)zoneA);
MStabResultsSingleZone? zoneBResults = null;
if (zoneAResults != null)
{
mStabResultsSingleZone = zoneAResults.Value;
}
else
{
zoneBResults = ParseZoneResults(fileContent, (int)zoneB);
if (zoneBResults != null)
{
mStabResultsSingleZone = zoneBResults.Value;
}
}
return mStabResultsSingleZone;
}
///
/// Read all relevant MStab results from file
///
///
///
public static MStabResults GetMStabResults(string fileContent)
{
MStabResults mStabResults = new MStabResults();
ThrowHelper.ThrowIfStringArgumentNullOrEmpty(fileContent, StringResourceNames.OutputFileHasNoContent);
if (ParseHasZonePlotEnabled(fileContent))
{
MStabResultsSingleZone? zoneResults1 = GetMStabResultsSingleZoneFrom(fileContent, StabilityZone.stabilityZone1a, StabilityZone.stabilityZone1b);
if (zoneResults1 != null)
{
mStabResults.zone1 = zoneResults1.Value;
}
else
{
throw new StabilityFileParseException("Stabilityzone 1a or 1b should exist");
}
mStabResults.zone2 = GetMStabResultsSingleZoneFrom(fileContent, StabilityZone.stabilityZone2a, StabilityZone.stabilityZone2b);
}
else
{
MStabResultsSingleZone? noZoneResults = GetMStabResultsNoZones(fileContent);
mStabResults.zone1 = noZoneResults.Value;
}
return mStabResults;
}
///
/// Read all relevant SlopeW results from file
///
///
///
public static MStabResults GetSlopeWResults(string fileContent)
{
MStabResults mStabResults = new MStabResults();
ThrowHelper.ThrowIfStringArgumentNullOrEmpty(fileContent, StringResourceNames.OutputFileHasNoContent);
fileContent = ReadContentAfterIdentifier(fileContent, "Bishop_Method_Fm=");
var indexEnd = fileContent.IndexOf("Applied_Lambda");
fileContent = fileContent.Substring(17, indexEnd - 18);
fileContent.Trim();
mStabResults.zone1.safetyFactor = Convert.ToDouble(fileContent);
return mStabResults;
}
public static double GetBeta(string fileContent)
{
ThrowHelper.ThrowIfStringArgumentNullOrEmpty(fileContent, StringResourceNames.OutputFileHasNoContent);
if (ParseHasZonePlotEnabled(fileContent))
{
return GetBetaWithZones(fileContent);
}
else
{
return GetBetaNoZones(fileContent);
}
}
public static bool ParseHasZonePlotEnabled(string fileContent)
{
StringReader stringReader = new StringReader(fileContent);
string line = "";
while ((line = stringReader.ReadLine()) != null)
{
if (line.EndsWith(": Zone plot on"))
{
return int.Parse(line.Substring(0, 3)).Equals(1) ? true : false;
}
}
return false;
}
private static bool ReadParameterColumnIndices(StringReader stringReader, ref int stabilityFactorIndex,
ref int xCoordinateLeftSurfaceIndex, ref int xCoordinateRightSurfaceIndex, ref int zoneNumberIndex, ref int betaIndex)
{
string line = "";
const string startCondition = "[Column Indication]";
const string endCondition = "[End of Column Indication]";
const string headerSafetyFactor = "Stability factor";
const string headerXCoordinateLeftSurface = "X coordinate left surface";
const string headerXCoordinateRightSurface = "X coordinate right surface";
const string headerZoneNumber = "Zone number";
const string headerBeta = "Beta";
bool isEndCondition = false;
stabilityFactorIndex = -1;
xCoordinateLeftSurfaceIndex = -1;
xCoordinateRightSurfaceIndex = -1;
zoneNumberIndex = -1;
while ((line = stringReader.ReadLine()) != null)
{
if (line.Equals(startCondition))
{
int columnIndex = 0;
while ((line = stringReader.ReadLine()) != null)
{
if (line.Equals(headerSafetyFactor))
stabilityFactorIndex = columnIndex;
if (line.Equals(headerXCoordinateLeftSurface))
xCoordinateLeftSurfaceIndex = columnIndex;
if (line.Equals(headerXCoordinateRightSurface))
xCoordinateRightSurfaceIndex = columnIndex;
if (line.Equals(headerZoneNumber))
zoneNumberIndex = columnIndex;
if (line.Equals(headerBeta))
betaIndex = columnIndex;
columnIndex++;
if (line.Equals(endCondition))
{
isEndCondition = true;
break;
}
}
}
if (isEndCondition)
break;
}
return ((stabilityFactorIndex >= 0) && (zoneNumberIndex >= 0) && (xCoordinateLeftSurfaceIndex >= 0) && (xCoordinateRightSurfaceIndex >= 0)) ? true : false;
}
private static MStabResultsSingleZone? ParseZoneResults(string fileContent, int stabilityZone)
{
StringReader stringReader = new StringReader(fileContent);
string line = "";
string zoneStabilityResults = null;
int stabilityFactorIndex = -1;
int xCoordinateLeftSurfaceIndex = -1;
int xCoordinateRightSurfaceIndex = -1;
int zoneNumberIndex = -1;
int betaIndex = -1;
MStabResultsSingleZone mStabResultsStruct = new MStabResultsSingleZone();
while ((line = stringReader.ReadLine()) != null)
{
if (line.Equals("[Dump]"))
{
if (!ReadParameterColumnIndices(stringReader, ref stabilityFactorIndex,
ref xCoordinateLeftSurfaceIndex, ref xCoordinateRightSurfaceIndex, ref zoneNumberIndex, ref betaIndex))
throw new StabilityFileParseException("Could not read Column Indication");
while ((line = stringReader.ReadLine()) != null)
{
if (line.Equals("[Data]"))
{
zoneStabilityResults = stringReader.ReadLine();
var zoneStabilityResultsElements = zoneStabilityResults.Split(' ').ToList().Where(x => x.Length > 0).ToArray();
if (zoneStabilityResultsElements != null)
{
if ((zoneStabilityResultsElements.Count() > stabilityFactorIndex) && (zoneStabilityResultsElements.Count() > zoneNumberIndex))
{
try
{
if (int.Parse(zoneStabilityResultsElements[zoneNumberIndex]).Equals(stabilityZone))
{
mStabResultsStruct.safetyFactor = zoneStabilityResultsElements[stabilityFactorIndex].ToType();
if (IsUpliftResults(fileContent))
mStabResultsStruct.safetyFactor = mStabResultsStruct.safetyFactor/1.05;
mStabResultsStruct.circleSurfacePointLeftXCoordinate = zoneStabilityResultsElements[xCoordinateLeftSurfaceIndex].ToType();
mStabResultsStruct.circleSurfacePointRightXCoordinate = zoneStabilityResultsElements[xCoordinateRightSurfaceIndex].ToType();
if (betaIndex > -1)
{
mStabResultsStruct.beta = zoneStabilityResultsElements[betaIndex].ToType();
}
return mStabResultsStruct;
}
}
catch (Exception e)
{
throw new StabilityFileParseException("Could not parse Stabilityzone : " + e.ToString());
}
}
else
throw new StabilityFileParseException("stabilityZone or stabilityFactorIndex not found");
}
break;
}
}
}
}
return null;
}
public static MStabResultsSingleZone? GetZoneStability1a(string fileContent)
{
return ParseZoneResults(fileContent, (int)StabilityZone.stabilityZone1a);
}
public static MStabResultsSingleZone? GetZoneStability1b(string fileContent)
{
return ParseZoneResults(fileContent, (int)StabilityZone.stabilityZone1b);
}
///
///
///
///
///
///
private static string ReadContentAfterIdentifier(string fileContent, string identifier)
{
if (!fileContent.Contains(identifier))
throw new StabilityFileParseException("Stability file doesn't contain identifier " + identifier);
fileContent = fileContent.Substring(fileContent.IndexOf(identifier));
return fileContent.Replace(identifier + Environment.NewLine, "");
}
///
///
///
///
/// Returns -1 if identifier is not found
///
/// The content to search in
/// The identifier to look for
/// The index of the column
private static int GetDataColumnIndex(string fileContent, string identifier, string endTag)
{
if (!fileContent.Contains(identifier))
throw new StabilityFileParseException();
var items = fileContent
.Substring(0, fileContent.IndexOf(endTag) - Environment.NewLine.Length)
.Replace(Environment.NewLine, ";")
.Split(';');
var foundMatch = false;
var i = -1;
if (items.Length == 1 && StringsAreEqual(items[0], identifier))
i = 0;
else if (items.Length > 1)
{
foreach (var word in items)
{
++i;
if (StringsAreEqual(word, identifier))
{
foundMatch = true;
break;
}
}
}
if (i == -1 || !foundMatch)
throw new StabilityFileParseException();
return i;
}
private static bool StringsAreEqual(string left, string right)
{
return ((!string.IsNullOrEmpty(left) || left.Trim() == "") &&
left.Equals(right, StringComparison.InvariantCulture));
}
///
///
///
///
///
private static double GetNumberFromLine(string fileContent, int idPos)
{
var doublesPattern = new Regex(@"-?\d+(?:\.\d+)?");
var matches = doublesPattern.Matches(fileContent);
return double.Parse(matches[idPos].Value, NumberStyles.Any, CultureInfo.InvariantCulture);
}
}
}