//----------------------------------------------------------------------- // // 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); } } }