// Copyright (C) Stichting Deltares 2016. All rights reserved. // // This file is part of Ringtoets. // // Ringtoets 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.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using Ringtoets.HydraRing.Calculation.Data.Output; using Ringtoets.HydraRing.Calculation.Exceptions; using Ringtoets.HydraRing.IO; namespace Ringtoets.HydraRing.Calculation.Parsers { /// /// Parser for overtopping wave height results. /// public class OvertoppingCalculationWaveHeightParser : IHydraRingFileParser { private const string overtoppingStart = "Submechanism = Overtopping RTO"; private const string overflowStart = "Submechanism = Overflow"; private const string combineWindDirectionStart = "Status = Combined over wind directions"; private const string governingWindDirectionStart = "Governing wind direction"; private const string overtoppingWaveHeight = "Wave height (Hs)"; private const string windDirection = "Wind direction"; private const string closingSituation = "Closing situation"; private const string beta = "Beta"; private const char equalsCharacter = '='; private readonly List overtoppingResults; private readonly List overflowResults; private int governingWindDirection = -1; /// /// Creates a new instance of . /// public OvertoppingCalculationWaveHeightParser() { overtoppingResults = new List(); overflowResults = new List(); } /// /// Gets the output that was parsed from the output file. /// public OvertoppingCalculationWaveHeightOutput Output { get; private set; } public void Parse(string workingDirectory, int sectionId) { string fileName = string.Format("{0}{1}", sectionId, HydraRingFileConstants.OutputFileSuffix); try { ReadFile(Path.Combine(workingDirectory, fileName)); SetOutputs(); } catch { throw new HydraRingFileParserException(); } } private void SetOutputs() { OvertoppingResult relevantOvertoppingResult = null; foreach (OvertoppingResult overtoppingResult in overtoppingResults.Where(o => o.WindDirection == governingWindDirection)) { if (relevantOvertoppingResult == null || overtoppingResult.Beta < relevantOvertoppingResult.Beta) { relevantOvertoppingResult = overtoppingResult; } } if (relevantOvertoppingResult != null && overflowResults.Any()) { GeneralResult governingOverflowResult = overflowResults .First(o => o.WindDirection == governingWindDirection && o.ClosingSituation == relevantOvertoppingResult.ClosingSituation); Output = new OvertoppingCalculationWaveHeightOutput( relevantOvertoppingResult.WaveHeight, relevantOvertoppingResult.Beta < governingOverflowResult.Beta); } } private void ReadFile(string filePath) { using (var file = new StreamReader(File.OpenRead(filePath))) { while (!file.EndOfStream) { string currentLine = file.ReadLine(); TryParseOvertoppingSection(currentLine, file); TryParseOverflowSection(currentLine, file); TryParseCombinationWindDirectionSection(currentLine, file); } } } private void TryParseOvertoppingSection(string startLine, StreamReader file) { if (startLine.Contains(overtoppingStart)) { var overtoppingResult = new OvertoppingResult(); while (!file.EndOfStream && double.IsNaN(overtoppingResult.Beta)) { string readLine = file.ReadLine(); TryParseWaveHeight(readLine, overtoppingResult); TryParseWindDirection(readLine, overtoppingResult); TryParseClosingSituation(readLine, overtoppingResult); TryParseBeta(readLine, overtoppingResult); } overtoppingResults.Add(overtoppingResult); } } private void TryParseOverflowSection(string startLine, StreamReader file) { if (startLine.Contains(overflowStart)) { var overflowResult = new GeneralResult(); while (!file.EndOfStream && double.IsNaN(overflowResult.Beta)) { string readLine = file.ReadLine(); TryParseWindDirection(readLine, overflowResult); TryParseClosingSituation(readLine, overflowResult); TryParseBeta(readLine, overflowResult); } overflowResults.Add(overflowResult); } } private void TryParseCombinationWindDirectionSection(string startLine, StreamReader file) { if (startLine.Contains(combineWindDirectionStart)) { while (!file.EndOfStream && governingWindDirection == -1) { string readLine = file.ReadLine(); TryParseGoverningWindDirection(readLine); } } } private void TryParseGoverningWindDirection(string line) { if (line.Contains(governingWindDirectionStart)) { string governingWindDirectionString = line.Split(equalsCharacter)[1].Trim(); governingWindDirection = int.Parse(governingWindDirectionString); } } private void TryParseWaveHeight(string line, OvertoppingResult overtoppingResult) { if (line.Contains(overtoppingWaveHeight)) { string resultAsString = line.Split(equalsCharacter)[1].Trim(); overtoppingResult.WaveHeight = double.Parse(resultAsString, CultureInfo.InvariantCulture); } } private void TryParseWindDirection(string line, GeneralResult generalResult) { if (line.Contains(windDirection)) { string resultAsString = line.Split(equalsCharacter)[1].Trim(); generalResult.WindDirection = int.Parse(resultAsString, CultureInfo.InvariantCulture); } } private void TryParseClosingSituation(string line, GeneralResult generalResult) { if (line.Contains(closingSituation)) { string resultAsString = line.Split(equalsCharacter)[1].Trim(); generalResult.ClosingSituation = int.Parse(resultAsString, CultureInfo.InvariantCulture); } } private void TryParseBeta(string line, GeneralResult generalResult) { if (line.Contains(beta)) { string resultAsString = line.Split(equalsCharacter)[1].Trim(); generalResult.Beta = double.Parse(resultAsString, CultureInfo.InvariantCulture); } } private class GeneralResult { public GeneralResult() { Beta = double.NaN; } public int WindDirection { get; set; } public int ClosingSituation { get; set; } public double Beta { get; set; } } private class OvertoppingResult : GeneralResult { public double WaveHeight { get; set; } } } }