From 0d5063441910089a25a3c289e0cc7b222bcc170d Mon Sep 17 00:00:00 2001 From: Matthias Schaefer Date: Sat, 28 Mar 2026 20:49:29 +0100 Subject: [PATCH 01/16] Do not plot curves, if checks are skipped --- Modelica_ResultCompare/CsvFile.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Modelica_ResultCompare/CsvFile.cs b/Modelica_ResultCompare/CsvFile.cs index f21a139..91d6bbf 100644 --- a/Modelica_ResultCompare/CsvFile.cs +++ b/Modelica_ResultCompare/CsvFile.cs @@ -290,6 +290,7 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt size = null; tube = new Tube(size); log.WriteLine(LogLevel.Warning, "{0} not found in \"{1}\", skipping checks.", res.Key, this._fileName); + continue; } else { From 69cd3e7efffdca7d1d64bf514ac0fb2062f08777 Mon Sep 17 00:00:00 2001 From: Matthias Schaefer Date: Tue, 19 May 2026 12:54:02 +0200 Subject: [PATCH 02/16] introduce separate tolerance in horizontal direction; Calculation of tubes only based on common time interval of reference and compareCurve --- Modelica_ResultCompare/CsvFile.cs | 155 +++++++++++++++--- Modelica_ResultCompare/CurveCompare/Curve.cs | 1 + .../CurveCompare/Options/Options1.cs | 11 +- Modelica_ResultCompare/CurveCompare/Tube.cs | 10 +- .../CurveCompare/TubeSize.cs | 13 +- Modelica_ResultCompare/Options.cs | 3 + Modelica_ResultCompare/Program.cs | 1 + Modelica_ResultCompare/Report.cs | 14 +- 8 files changed, 170 insertions(+), 38 deletions(-) diff --git a/Modelica_ResultCompare/CsvFile.cs b/Modelica_ResultCompare/CsvFile.cs index 91d6bbf..9b94b06 100644 --- a/Modelica_ResultCompare/CsvFile.cs +++ b/Modelica_ResultCompare/CsvFile.cs @@ -12,12 +12,14 @@ using System.Threading.Tasks; using CurveCompare; + namespace CsvCompare { /// This class parses CSV files and holds results in a dictionary public class CsvFile:IDisposable { private double _dRangeDelta = 0.002; + private double _dRangeDeltaT = 0.002; private string _fileName = string.Empty; private List _xAxis = new List(); private Dictionary> _values = new Dictionary>(); @@ -32,6 +34,10 @@ public class CsvFile:IDisposable public Dictionary> Results { get { return _values; } } /// This value can be used to produce a offset between base and comparison values public double RangeDelta { get { return _dRangeDelta; } set { _dRangeDelta = value; } } + + /// This value can be used to produce a offset between base and comparison values + public double RangeDeltaT { get { return _dRangeDeltaT; } set { _dRangeDeltaT = value; } } + /// This value enables/disables relative error differences in the error graph public bool ShowRelativeErrors { @@ -58,6 +64,24 @@ public CsvFile(string fileName, Options options, Log log) if (!Double.TryParse(options.Tolerance, out _dRangeDelta)) log.WriteLine(LogLevel.Warning, "could not parse given tolerance argument: \"{0}\", using default \"{1}\".", options.Tolerance, _dRangeDelta); } + //understand 0.002 + if (null != options.TimeTolerance) + { + if (!Double.TryParse(options.TimeTolerance, NumberStyles.AllowDecimalPoint, toleranceProvider, out _dRangeDeltaT)) + { + //understand 0,002 + toleranceProvider.NumberDecimalSeparator = ","; + if (!Double.TryParse(options.TimeTolerance, NumberStyles.AllowDecimalPoint, toleranceProvider, out _dRangeDeltaT)) + //understand 2e-2 etc. + if (!Double.TryParse(options.TimeTolerance, out _dRangeDeltaT)) + log.WriteLine(LogLevel.Warning, "could not parse given time tolerance argument: \"{0}\", using default \"{1}\".", options.TimeTolerance, _dRangeDelta); + _dRangeDeltaT = _dRangeDelta; + } + } + else + { + _dRangeDeltaT = _dRangeDelta; + } if (File.Exists(fileName)) { @@ -266,6 +290,71 @@ public Report CompareFiles(Log log, CsvFile csvBase, ref Options options) return CompareFiles(log, csvBase, null, ref options); } + + static Curve Trim_curve(Curve curve, + double start_time, + double end_time) + { + int start_idx = 0; + int end_idx = curve.Count; + + /* Find first valid sample */ + while (start_idx < curve.Count && + curve.X[start_idx] < start_time) + { + start_idx++; + } + + /* Find last valid sample */ + while (end_idx > start_idx && + curve.X[end_idx - 1] > end_time) + { + end_idx--; + } + + int new_size = end_idx - start_idx; + double[] TargetValues = new double[new_size]; + double[] TargetTime = new double[new_size]; + /* Shift data to beginning */ + for (int i = 0; i < new_size; ++i) + { + TargetTime[i] = curve.X[start_idx + i]; + TargetValues[i] = curve.Y[start_idx + i]; + } + Curve NewCurve = new Curve(curve.Name, TargetTime, TargetValues); + return NewCurve; //curve.ReplaceData(TargetTime, TargetValues); + } + public double[] GetCommonInterval(Curve reference, Curve compareCurve) + { + double[] common_interval = new double[2] { 0.0, 0.0 }; + + if (compareCurve.Count == 0 || reference.Count == 0) + { + return common_interval; + } + // Determine common interval + double common_start = + (reference.X[0] > compareCurve.X[0]) + ? reference.X[0] + : compareCurve.X[0]; + + double common_stop = + (reference.X[reference.X.Length - 1] < + compareCurve.X[compareCurve.X.Length - 1]) + ? reference.X[reference.X.Length - 1] + : compareCurve.X[compareCurve.X.Length - 1]; + if (common_start > common_stop) + { + return common_interval; + } + common_interval[0] = common_start; + common_interval[1] = common_stop; + return common_interval; + + // Trim_curve(compareCurve, common_start, common_stop); + //Trim_curve(reference, common_start, common_stop); + } + public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Options options) { int iInvalids = 0; @@ -275,13 +364,15 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt rep.BaseFile = csvBase.ToString(); rep.CompareFile = _fileName; - + double[] common_interval = new double [2]; Curve reference = new Curve(); Curve compareCurve = new Curve(); + Curve trimmedReference = new Curve(); + Curve trimmedCompareCurve = new Curve(); TubeReport report = new TubeReport(); TubeSize size = null; Tube tube = new Tube(size); - IOptions tubeOptions = new Options1(_dRangeDelta, Axes.X); + IOptions tubeOptions = new Options1(_dRangeDelta, _dRangeDeltaT, Axes.X); foreach (KeyValuePair> res in csvBase.Results) { @@ -314,16 +405,30 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt else log.WriteLine(LogLevel.Debug, "The resolution of the base x-axis is good."); - // The actual nominal attribute should be used, but is unfortunately unavailable in the CSV files. - // A default nominal value of 0.001 was chosen as a compromise between having many false negatives - // and passing wrong result files. - // See discussion in https://github.com/modelica/ModelicaStandardLibrary/issues/4421 + common_interval = GetCommonInterval(compareCurve, reference); + + if (common_interval != null && common_interval[0] != common_interval[1]) + { + trimmedReference = Trim_curve(reference, common_interval[0], common_interval[1]); + trimmedCompareCurve = Trim_curve(compareCurve, common_interval[0], common_interval[1]); + } + else + { + trimmedReference = reference; + trimmedCompareCurve = compareCurve; + + } + + // The actual nominal attribute should be used, but is unfortunately unavailable in the CSV files. + // A default nominal value of 0.001 was chosen as a compromise between having many false negatives + // and passing wrong result files. + // See discussion in https://github.com/modelica/ModelicaStandardLibrary/issues/4421 const double defaultNominalValue = 0.001; const bool useLegacyBaseAndRatio = true; - size = new TubeSize(reference, defaultNominalValue, useLegacyBaseAndRatio); - size.Calculate(_dRangeDelta, Axes.X, Relativity.Relative); + size = new TubeSize(trimmedReference, defaultNominalValue, useLegacyBaseAndRatio); + size.Calculate(_dRangeDelta, _dRangeDeltaT, Axes.X, Relativity.Relative); tube = new Tube(size); - var calcResult = tube.Calculate(reference); + var calcResult = tube.Calculate(trimmedReference); bool calcSuccess = calcResult.Item2; if (!calcSuccess) { @@ -332,7 +437,7 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt continue; } report = calcResult.Item1; - bool validationSuccess = Tube.Validate(compareCurve, report); + bool validationSuccess = Tube.Validate(trimmedCompareCurve, report); if (!validationSuccess) { log.Error("Error in the validation of the tube. Skipping {0}", res.Key); @@ -351,9 +456,10 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt } } if (null != report) //No charts for missing reports - PrepareCharts(reference, compareCurve, report.Errors, rep, report, res, options.UseBitmapPlots); + PrepareCharts(reference, compareCurve, trimmedCompareCurve, report.Errors, rep, report, res, options.UseBitmapPlots); } rep.Tolerance = _dRangeDelta; + rep.TimeTolerance = _dRangeDeltaT; string sResult = "na"; @@ -371,6 +477,7 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt writer.WriteLine(". Time: {0:o}", DateTime.Now); writer.WriteLine(". Operation: {0}", options.Mode); writer.WriteLine(". Tolerance: {0}", options.Tolerance); + writer.WriteLine(". TimeTolerance: {0}", options.TimeTolerance); writer.WriteLine(". Result: {0}", sResult); if (rep.TotalErrors > 0) @@ -392,10 +499,10 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt private void PrepareCharts(Report rep, Curve compare)//Draw result only { - PrepareCharts(compare, null, null, rep, null, new KeyValuePair>(compare.Name, null), false); + PrepareCharts(compare, null, null,null, rep, null, new KeyValuePair>(compare.Name, null), false); } - private void PrepareCharts(Curve reference, Curve compare, Curve error, Report rep, TubeReport tubeReport, KeyValuePair> res, bool bDrawBitmapPlots) + private void PrepareCharts(Curve reference, Curve compare, Curve trimmedCompare, Curve error, Report rep, TubeReport tubeReport, KeyValuePair> res, bool bDrawBitmapPlots) { Chart ch = new Chart() @@ -457,15 +564,15 @@ private void PrepareCharts(Curve reference, Curve compare, Curve error, Report r if (null != error && null != error.X && error.X.Length > 0) { //Get complete error curve as "error" only holds error points - Curve curveErrors = new Curve("ERRORS", new double[compare.X.Length], new double[compare.X.Length]); + Curve curveErrors = new Curve("ERRORS", new double[trimmedCompare.X.Length], new double[trimmedCompare.X.Length]); int j = 0; - for (int i = 0; i < compare.X.Length - 1; i++) + for (int i = 0; i <= trimmedCompare.X.Length - 1; i++) { - curveErrors.X[i] = compare.X[i]; - if (error.X.Contains(compare.X[i])) + curveErrors.X[i] = trimmedCompare.X[i]; + if (error.X.Contains(trimmedCompare.X[i])) { curveErrors.Y[i] = (this._bShowRelativeErrors) ? error.Y[j] : 1; - if (compare.X[i + 1] > compare.X[i]) + if ( i == trimmedCompare.X.Length - 1 || trimmedCompare.X[i + 1] > trimmedCompare.X[i]) { j++; } @@ -488,24 +595,24 @@ private void PrepareCharts(Curve reference, Curve compare, Curve error, Report r //Calculate delta error List lDeltas = new List(); j = 0; - for (int i = 1; i < compare.X.Length - 1; i++) + for (int i = 1; i < trimmedCompare.X.Length - 1; i++) { if (j < error.X.Length) { - while (compare.X[i] < error.X[j]) + while (trimmedCompare.X[i] < error.X[j]) { i++; continue; } - if (i < compare.X.Length - 1) - lDeltas.Add((Math.Abs(error.Y[j]) * ((Math.Abs(compare.X[i] - compare.X[i - 1])) + (Math.Abs(compare.X[i + 1] - compare.X[i])))) / 2); + if (i < trimmedCompare.X.Length - 1) + lDeltas.Add((Math.Abs(error.Y[j]) * ((Math.Abs(trimmedCompare.X[i] - trimmedCompare.X[i - 1])) + (Math.Abs(trimmedCompare.X[i + 1] - trimmedCompare.X[i])))) / 2); else // handle errors in the last point (there is no i+1) - lDeltas.Add((Math.Abs(error.Y[j]) * ((Math.Abs(compare.X[i] - compare.X[i - 1])))) / 2); + lDeltas.Add((Math.Abs(error.Y[j]) * ((Math.Abs(trimmedCompare.X[i] - trimmedCompare.X[i - 1])))) / 2); j++; } } - ch.DeltaError = lDeltas.Sum() / (1e-3 + compare.Y.Max(x => Math.Abs(x))); + ch.DeltaError = lDeltas.Sum() / (1e-3 + trimmedCompare.Y.Max(x => Math.Abs(x))); } if (null != tubeReport && tubeReport.Lower.X.ToList().Count > 2)//Remember Start and Stop values for graph scaling { diff --git a/Modelica_ResultCompare/CurveCompare/Curve.cs b/Modelica_ResultCompare/CurveCompare/Curve.cs index ddab032..bc43207 100644 --- a/Modelica_ResultCompare/CurveCompare/Curve.cs +++ b/Modelica_ResultCompare/CurveCompare/Curve.cs @@ -49,6 +49,7 @@ public bool ImportSuccessful { get { return importSuccessful; } } + /// /// Creates an empty Curve with members = null. /// diff --git a/Modelica_ResultCompare/CurveCompare/Options/Options1.cs b/Modelica_ResultCompare/CurveCompare/Options/Options1.cs index 1994857..3890625 100644 --- a/Modelica_ResultCompare/CurveCompare/Options/Options1.cs +++ b/Modelica_ResultCompare/CurveCompare/Options/Options1.cs @@ -15,7 +15,7 @@ namespace CurveCompare /// public class Options1 : IOptions { - double val; + double val, valT; Axes axes; bool formerBaseAndRatio; double baseX, baseY, ratio; @@ -34,6 +34,12 @@ public double Value { get { return val; } } + + public double ValueT + { + get { return valT; } + } + /// /// States, if value is x (half width of rectangle) or y (half height of rectangle). /// @@ -154,9 +160,10 @@ public bool DrawLabelNumber /// Always use normal drawing methods, never fast drawing methods: drawFastAbove = 0 /// Always draw points: drawPointsBelow = Int32.MaxValue /// - public Options1(double value, Axes axes) + public Options1(double value, double valueT, Axes axes) { this.val = value; + this.valT = ValueT; this.axes = axes; relativity = Relativity.Relative; baseX = Double.NaN; diff --git a/Modelica_ResultCompare/CurveCompare/Tube.cs b/Modelica_ResultCompare/CurveCompare/Tube.cs index 7bf981a..8565146 100644 --- a/Modelica_ResultCompare/CurveCompare/Tube.cs +++ b/Modelica_ResultCompare/CurveCompare/Tube.cs @@ -173,11 +173,11 @@ private static double[] InterpolateValues(double[] sourceTimeLine, double[] sour for (int i = 0; i < targetTimeLine.Length; i++) { - if (targetTimeLine[i] > sourceTimeLine[sourceTimeLine.Length - 1])//Prevent extrapolating - { - Array.Resize(ref TargetValues, i); - break; - } + //if (targetTimeLine[i] > sourceTimeLine[sourceTimeLine.Length - 1])//Prevent extrapolating at the end + //{ + // //Array.Resize(ref TargetValues, i); + // break; + //} x = targetTimeLine[i]; diff --git a/Modelica_ResultCompare/CurveCompare/TubeSize.cs b/Modelica_ResultCompare/CurveCompare/TubeSize.cs index 41c9510..ef58121 100644 --- a/Modelica_ResultCompare/CurveCompare/TubeSize.cs +++ b/Modelica_ResultCompare/CurveCompare/TubeSize.cs @@ -127,7 +127,7 @@ private void SetFormerBaseAndRatio(double nominalValue) /// Calculation fails, if (Ratio = 0 or BaseX = 0 or BaseY = 0). /// If calculation fails, [set Ratio and BaseX and BaseY != 0] or [call Calculate(double x, double y, Relativity relativity) with parameter Relativity.Absolute] /// Relative value is out of expected range [0,1]. - public void Calculate(double value, Axes axes, Relativity relativity) + public void Calculate(double value, double valueT, Axes axes, Relativity relativity) { successful = false; @@ -137,17 +137,20 @@ public void Calculate(double value, Axes axes, Relativity relativity) { if ((value < 0) || (value > 1)) throw new ArgumentOutOfRangeException("Relative value is out of expected range [0,1]."); - + + if ((valueT < 0) || (valueT > 1)) + throw new ArgumentOutOfRangeException("Relative value is out of expected range [0,1]."); + if (axes == Axes.Y && baseY > 0) { y = value * baseY; - x = y / ratio; + x = valueT * baseX; successful = true; } else if (axes == Axes.X && baseX > 0) { - x = value * baseX; - y = ratio * x; + x = valueT * baseX; + y = value * baseY; successful = true; } } diff --git a/Modelica_ResultCompare/Options.cs b/Modelica_ResultCompare/Options.cs index 7323ec8..8603d30 100644 --- a/Modelica_ResultCompare/Options.cs +++ b/Modelica_ResultCompare/Options.cs @@ -52,6 +52,9 @@ public class Options [Option('t', "tolerance", Required = false, DefaultValue = "0.002", HelpText = "Set the width of the tube at discontinuity in x-direction [Default is 0.002].")] public string Tolerance { get; set; } + [Option('x', "timetolerance", Required = false, HelpText = "Set the width of the tube at discontinuity in y-direction [Default is equal to tolerance].")] + public string TimeTolerance { get; set; } + [Option('v', "verbosity", DefaultValue = 4, Required = false, HelpText = "Sets the verbosity of the output (1 most to 4[Default] less verbose).")] public int Verbosity { get; set; } diff --git a/Modelica_ResultCompare/Program.cs b/Modelica_ResultCompare/Program.cs index d566a55..6d75305 100644 --- a/Modelica_ResultCompare/Program.cs +++ b/Modelica_ResultCompare/Program.cs @@ -102,6 +102,7 @@ private static void Run(string[] cmdArgs) _log.WriteLine(LogLevel.Debug, "Successfully parsed the following options:"); _log.WriteLine(LogLevel.Debug, "Operation mode is {0}", options.Mode); _log.WriteLine(LogLevel.Debug, "Tolerance is {0}", options.Tolerance); + _log.WriteLine(LogLevel.Debug, "TimeTolerance is {0}", options.TimeTolerance); if (options.Delimiter == 0) { diff --git a/Modelica_ResultCompare/Report.cs b/Modelica_ResultCompare/Report.cs index d83f101..d5ed19b 100644 --- a/Modelica_ResultCompare/Report.cs +++ b/Modelica_ResultCompare/Report.cs @@ -540,7 +540,10 @@ public bool WriteReport(Log log, Options options) if (null != options.Tolerance) writer.WriteLine(" Tolerance:{0}", options.Tolerance); - + + if (null != options.TimeTolerance) + writer.WriteLine(" Tolerance:{0}", options.TimeTolerance); + if (!String.IsNullOrEmpty(options.Logfile)) { writer.WriteLine(" Logfile:{0}", options.Logfile); @@ -653,7 +656,7 @@ public sealed class Report : IDisposable private string _metaPath; private List _chart = new List(); private List _data = new List(); - private double _tolerance; + private double _tolerance, _timetolerance; private double _dAvErr = 0; private int _iTotalErrors = -1; private bool _bRelative = false; @@ -663,6 +666,12 @@ public double Tolerance get { return _tolerance; } set { _tolerance = value; } } + + public double TimeTolerance + { + get { return _timetolerance; } + set { _timetolerance = value; } + } public string Message { get { return _message; } set { _message = value; } } public string FileName { get { return _path; } set { _path = value; } } public string MetaPath { get { return _metaPath; } set { _metaPath = value; } } @@ -851,6 +860,7 @@ private void WriteHeader(TextWriter writer, Options options) writer.WriteLine(" Compare file:{1}", this.CompareFile.Replace("\\", "/"), this.CompareFile); writer.WriteLine(" Tolerance:{0}", _tolerance); + writer.WriteLine(" Time Tolerance:{0}", _timetolerance); writer.WriteLine(" Timestamp:{0} [UTC]", DateTime.UtcNow); int iTested = _chart.Count - (from c in _chart where c.Errors == -1 select c).Count(); From c6c56308c24e092e7f4087d8dbafbd8190774c08 Mon Sep 17 00:00:00 2001 From: Matthias Schaefer Date: Tue, 19 May 2026 15:51:16 +0200 Subject: [PATCH 03/16] Revert "introduce separate tolerance in horizontal direction; Calculation of tubes only based on common time interval of reference and compareCurve" This reverts commit 69cd3e7efffdca7d1d64bf514ac0fb2062f08777. --- Modelica_ResultCompare/CsvFile.cs | 155 +++--------------- Modelica_ResultCompare/CurveCompare/Curve.cs | 1 - .../CurveCompare/Options/Options1.cs | 11 +- Modelica_ResultCompare/CurveCompare/Tube.cs | 10 +- .../CurveCompare/TubeSize.cs | 13 +- Modelica_ResultCompare/Options.cs | 3 - Modelica_ResultCompare/Program.cs | 1 - Modelica_ResultCompare/Report.cs | 14 +- 8 files changed, 38 insertions(+), 170 deletions(-) diff --git a/Modelica_ResultCompare/CsvFile.cs b/Modelica_ResultCompare/CsvFile.cs index 9b94b06..91d6bbf 100644 --- a/Modelica_ResultCompare/CsvFile.cs +++ b/Modelica_ResultCompare/CsvFile.cs @@ -12,14 +12,12 @@ using System.Threading.Tasks; using CurveCompare; - namespace CsvCompare { /// This class parses CSV files and holds results in a dictionary public class CsvFile:IDisposable { private double _dRangeDelta = 0.002; - private double _dRangeDeltaT = 0.002; private string _fileName = string.Empty; private List _xAxis = new List(); private Dictionary> _values = new Dictionary>(); @@ -34,10 +32,6 @@ public class CsvFile:IDisposable public Dictionary> Results { get { return _values; } } /// This value can be used to produce a offset between base and comparison values public double RangeDelta { get { return _dRangeDelta; } set { _dRangeDelta = value; } } - - /// This value can be used to produce a offset between base and comparison values - public double RangeDeltaT { get { return _dRangeDeltaT; } set { _dRangeDeltaT = value; } } - /// This value enables/disables relative error differences in the error graph public bool ShowRelativeErrors { @@ -64,24 +58,6 @@ public CsvFile(string fileName, Options options, Log log) if (!Double.TryParse(options.Tolerance, out _dRangeDelta)) log.WriteLine(LogLevel.Warning, "could not parse given tolerance argument: \"{0}\", using default \"{1}\".", options.Tolerance, _dRangeDelta); } - //understand 0.002 - if (null != options.TimeTolerance) - { - if (!Double.TryParse(options.TimeTolerance, NumberStyles.AllowDecimalPoint, toleranceProvider, out _dRangeDeltaT)) - { - //understand 0,002 - toleranceProvider.NumberDecimalSeparator = ","; - if (!Double.TryParse(options.TimeTolerance, NumberStyles.AllowDecimalPoint, toleranceProvider, out _dRangeDeltaT)) - //understand 2e-2 etc. - if (!Double.TryParse(options.TimeTolerance, out _dRangeDeltaT)) - log.WriteLine(LogLevel.Warning, "could not parse given time tolerance argument: \"{0}\", using default \"{1}\".", options.TimeTolerance, _dRangeDelta); - _dRangeDeltaT = _dRangeDelta; - } - } - else - { - _dRangeDeltaT = _dRangeDelta; - } if (File.Exists(fileName)) { @@ -290,71 +266,6 @@ public Report CompareFiles(Log log, CsvFile csvBase, ref Options options) return CompareFiles(log, csvBase, null, ref options); } - - static Curve Trim_curve(Curve curve, - double start_time, - double end_time) - { - int start_idx = 0; - int end_idx = curve.Count; - - /* Find first valid sample */ - while (start_idx < curve.Count && - curve.X[start_idx] < start_time) - { - start_idx++; - } - - /* Find last valid sample */ - while (end_idx > start_idx && - curve.X[end_idx - 1] > end_time) - { - end_idx--; - } - - int new_size = end_idx - start_idx; - double[] TargetValues = new double[new_size]; - double[] TargetTime = new double[new_size]; - /* Shift data to beginning */ - for (int i = 0; i < new_size; ++i) - { - TargetTime[i] = curve.X[start_idx + i]; - TargetValues[i] = curve.Y[start_idx + i]; - } - Curve NewCurve = new Curve(curve.Name, TargetTime, TargetValues); - return NewCurve; //curve.ReplaceData(TargetTime, TargetValues); - } - public double[] GetCommonInterval(Curve reference, Curve compareCurve) - { - double[] common_interval = new double[2] { 0.0, 0.0 }; - - if (compareCurve.Count == 0 || reference.Count == 0) - { - return common_interval; - } - // Determine common interval - double common_start = - (reference.X[0] > compareCurve.X[0]) - ? reference.X[0] - : compareCurve.X[0]; - - double common_stop = - (reference.X[reference.X.Length - 1] < - compareCurve.X[compareCurve.X.Length - 1]) - ? reference.X[reference.X.Length - 1] - : compareCurve.X[compareCurve.X.Length - 1]; - if (common_start > common_stop) - { - return common_interval; - } - common_interval[0] = common_start; - common_interval[1] = common_stop; - return common_interval; - - // Trim_curve(compareCurve, common_start, common_stop); - //Trim_curve(reference, common_start, common_stop); - } - public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Options options) { int iInvalids = 0; @@ -364,15 +275,13 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt rep.BaseFile = csvBase.ToString(); rep.CompareFile = _fileName; - double[] common_interval = new double [2]; + Curve reference = new Curve(); Curve compareCurve = new Curve(); - Curve trimmedReference = new Curve(); - Curve trimmedCompareCurve = new Curve(); TubeReport report = new TubeReport(); TubeSize size = null; Tube tube = new Tube(size); - IOptions tubeOptions = new Options1(_dRangeDelta, _dRangeDeltaT, Axes.X); + IOptions tubeOptions = new Options1(_dRangeDelta, Axes.X); foreach (KeyValuePair> res in csvBase.Results) { @@ -405,30 +314,16 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt else log.WriteLine(LogLevel.Debug, "The resolution of the base x-axis is good."); - common_interval = GetCommonInterval(compareCurve, reference); - - if (common_interval != null && common_interval[0] != common_interval[1]) - { - trimmedReference = Trim_curve(reference, common_interval[0], common_interval[1]); - trimmedCompareCurve = Trim_curve(compareCurve, common_interval[0], common_interval[1]); - } - else - { - trimmedReference = reference; - trimmedCompareCurve = compareCurve; - - } - - // The actual nominal attribute should be used, but is unfortunately unavailable in the CSV files. - // A default nominal value of 0.001 was chosen as a compromise between having many false negatives - // and passing wrong result files. - // See discussion in https://github.com/modelica/ModelicaStandardLibrary/issues/4421 + // The actual nominal attribute should be used, but is unfortunately unavailable in the CSV files. + // A default nominal value of 0.001 was chosen as a compromise between having many false negatives + // and passing wrong result files. + // See discussion in https://github.com/modelica/ModelicaStandardLibrary/issues/4421 const double defaultNominalValue = 0.001; const bool useLegacyBaseAndRatio = true; - size = new TubeSize(trimmedReference, defaultNominalValue, useLegacyBaseAndRatio); - size.Calculate(_dRangeDelta, _dRangeDeltaT, Axes.X, Relativity.Relative); + size = new TubeSize(reference, defaultNominalValue, useLegacyBaseAndRatio); + size.Calculate(_dRangeDelta, Axes.X, Relativity.Relative); tube = new Tube(size); - var calcResult = tube.Calculate(trimmedReference); + var calcResult = tube.Calculate(reference); bool calcSuccess = calcResult.Item2; if (!calcSuccess) { @@ -437,7 +332,7 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt continue; } report = calcResult.Item1; - bool validationSuccess = Tube.Validate(trimmedCompareCurve, report); + bool validationSuccess = Tube.Validate(compareCurve, report); if (!validationSuccess) { log.Error("Error in the validation of the tube. Skipping {0}", res.Key); @@ -456,10 +351,9 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt } } if (null != report) //No charts for missing reports - PrepareCharts(reference, compareCurve, trimmedCompareCurve, report.Errors, rep, report, res, options.UseBitmapPlots); + PrepareCharts(reference, compareCurve, report.Errors, rep, report, res, options.UseBitmapPlots); } rep.Tolerance = _dRangeDelta; - rep.TimeTolerance = _dRangeDeltaT; string sResult = "na"; @@ -477,7 +371,6 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt writer.WriteLine(". Time: {0:o}", DateTime.Now); writer.WriteLine(". Operation: {0}", options.Mode); writer.WriteLine(". Tolerance: {0}", options.Tolerance); - writer.WriteLine(". TimeTolerance: {0}", options.TimeTolerance); writer.WriteLine(". Result: {0}", sResult); if (rep.TotalErrors > 0) @@ -499,10 +392,10 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt private void PrepareCharts(Report rep, Curve compare)//Draw result only { - PrepareCharts(compare, null, null,null, rep, null, new KeyValuePair>(compare.Name, null), false); + PrepareCharts(compare, null, null, rep, null, new KeyValuePair>(compare.Name, null), false); } - private void PrepareCharts(Curve reference, Curve compare, Curve trimmedCompare, Curve error, Report rep, TubeReport tubeReport, KeyValuePair> res, bool bDrawBitmapPlots) + private void PrepareCharts(Curve reference, Curve compare, Curve error, Report rep, TubeReport tubeReport, KeyValuePair> res, bool bDrawBitmapPlots) { Chart ch = new Chart() @@ -564,15 +457,15 @@ private void PrepareCharts(Curve reference, Curve compare, Curve trimmedCompare, if (null != error && null != error.X && error.X.Length > 0) { //Get complete error curve as "error" only holds error points - Curve curveErrors = new Curve("ERRORS", new double[trimmedCompare.X.Length], new double[trimmedCompare.X.Length]); + Curve curveErrors = new Curve("ERRORS", new double[compare.X.Length], new double[compare.X.Length]); int j = 0; - for (int i = 0; i <= trimmedCompare.X.Length - 1; i++) + for (int i = 0; i < compare.X.Length - 1; i++) { - curveErrors.X[i] = trimmedCompare.X[i]; - if (error.X.Contains(trimmedCompare.X[i])) + curveErrors.X[i] = compare.X[i]; + if (error.X.Contains(compare.X[i])) { curveErrors.Y[i] = (this._bShowRelativeErrors) ? error.Y[j] : 1; - if ( i == trimmedCompare.X.Length - 1 || trimmedCompare.X[i + 1] > trimmedCompare.X[i]) + if (compare.X[i + 1] > compare.X[i]) { j++; } @@ -595,24 +488,24 @@ private void PrepareCharts(Curve reference, Curve compare, Curve trimmedCompare, //Calculate delta error List lDeltas = new List(); j = 0; - for (int i = 1; i < trimmedCompare.X.Length - 1; i++) + for (int i = 1; i < compare.X.Length - 1; i++) { if (j < error.X.Length) { - while (trimmedCompare.X[i] < error.X[j]) + while (compare.X[i] < error.X[j]) { i++; continue; } - if (i < trimmedCompare.X.Length - 1) - lDeltas.Add((Math.Abs(error.Y[j]) * ((Math.Abs(trimmedCompare.X[i] - trimmedCompare.X[i - 1])) + (Math.Abs(trimmedCompare.X[i + 1] - trimmedCompare.X[i])))) / 2); + if (i < compare.X.Length - 1) + lDeltas.Add((Math.Abs(error.Y[j]) * ((Math.Abs(compare.X[i] - compare.X[i - 1])) + (Math.Abs(compare.X[i + 1] - compare.X[i])))) / 2); else // handle errors in the last point (there is no i+1) - lDeltas.Add((Math.Abs(error.Y[j]) * ((Math.Abs(trimmedCompare.X[i] - trimmedCompare.X[i - 1])))) / 2); + lDeltas.Add((Math.Abs(error.Y[j]) * ((Math.Abs(compare.X[i] - compare.X[i - 1])))) / 2); j++; } } - ch.DeltaError = lDeltas.Sum() / (1e-3 + trimmedCompare.Y.Max(x => Math.Abs(x))); + ch.DeltaError = lDeltas.Sum() / (1e-3 + compare.Y.Max(x => Math.Abs(x))); } if (null != tubeReport && tubeReport.Lower.X.ToList().Count > 2)//Remember Start and Stop values for graph scaling { diff --git a/Modelica_ResultCompare/CurveCompare/Curve.cs b/Modelica_ResultCompare/CurveCompare/Curve.cs index bc43207..ddab032 100644 --- a/Modelica_ResultCompare/CurveCompare/Curve.cs +++ b/Modelica_ResultCompare/CurveCompare/Curve.cs @@ -49,7 +49,6 @@ public bool ImportSuccessful { get { return importSuccessful; } } - /// /// Creates an empty Curve with members = null. /// diff --git a/Modelica_ResultCompare/CurveCompare/Options/Options1.cs b/Modelica_ResultCompare/CurveCompare/Options/Options1.cs index 3890625..1994857 100644 --- a/Modelica_ResultCompare/CurveCompare/Options/Options1.cs +++ b/Modelica_ResultCompare/CurveCompare/Options/Options1.cs @@ -15,7 +15,7 @@ namespace CurveCompare /// public class Options1 : IOptions { - double val, valT; + double val; Axes axes; bool formerBaseAndRatio; double baseX, baseY, ratio; @@ -34,12 +34,6 @@ public double Value { get { return val; } } - - public double ValueT - { - get { return valT; } - } - /// /// States, if value is x (half width of rectangle) or y (half height of rectangle). /// @@ -160,10 +154,9 @@ public bool DrawLabelNumber /// Always use normal drawing methods, never fast drawing methods: drawFastAbove = 0 /// Always draw points: drawPointsBelow = Int32.MaxValue /// - public Options1(double value, double valueT, Axes axes) + public Options1(double value, Axes axes) { this.val = value; - this.valT = ValueT; this.axes = axes; relativity = Relativity.Relative; baseX = Double.NaN; diff --git a/Modelica_ResultCompare/CurveCompare/Tube.cs b/Modelica_ResultCompare/CurveCompare/Tube.cs index 8565146..7bf981a 100644 --- a/Modelica_ResultCompare/CurveCompare/Tube.cs +++ b/Modelica_ResultCompare/CurveCompare/Tube.cs @@ -173,11 +173,11 @@ private static double[] InterpolateValues(double[] sourceTimeLine, double[] sour for (int i = 0; i < targetTimeLine.Length; i++) { - //if (targetTimeLine[i] > sourceTimeLine[sourceTimeLine.Length - 1])//Prevent extrapolating at the end - //{ - // //Array.Resize(ref TargetValues, i); - // break; - //} + if (targetTimeLine[i] > sourceTimeLine[sourceTimeLine.Length - 1])//Prevent extrapolating + { + Array.Resize(ref TargetValues, i); + break; + } x = targetTimeLine[i]; diff --git a/Modelica_ResultCompare/CurveCompare/TubeSize.cs b/Modelica_ResultCompare/CurveCompare/TubeSize.cs index ef58121..41c9510 100644 --- a/Modelica_ResultCompare/CurveCompare/TubeSize.cs +++ b/Modelica_ResultCompare/CurveCompare/TubeSize.cs @@ -127,7 +127,7 @@ private void SetFormerBaseAndRatio(double nominalValue) /// Calculation fails, if (Ratio = 0 or BaseX = 0 or BaseY = 0). /// If calculation fails, [set Ratio and BaseX and BaseY != 0] or [call Calculate(double x, double y, Relativity relativity) with parameter Relativity.Absolute] /// Relative value is out of expected range [0,1]. - public void Calculate(double value, double valueT, Axes axes, Relativity relativity) + public void Calculate(double value, Axes axes, Relativity relativity) { successful = false; @@ -137,20 +137,17 @@ public void Calculate(double value, double valueT, Axes axes, Relativity relativ { if ((value < 0) || (value > 1)) throw new ArgumentOutOfRangeException("Relative value is out of expected range [0,1]."); - - if ((valueT < 0) || (valueT > 1)) - throw new ArgumentOutOfRangeException("Relative value is out of expected range [0,1]."); - + if (axes == Axes.Y && baseY > 0) { y = value * baseY; - x = valueT * baseX; + x = y / ratio; successful = true; } else if (axes == Axes.X && baseX > 0) { - x = valueT * baseX; - y = value * baseY; + x = value * baseX; + y = ratio * x; successful = true; } } diff --git a/Modelica_ResultCompare/Options.cs b/Modelica_ResultCompare/Options.cs index 8603d30..7323ec8 100644 --- a/Modelica_ResultCompare/Options.cs +++ b/Modelica_ResultCompare/Options.cs @@ -52,9 +52,6 @@ public class Options [Option('t', "tolerance", Required = false, DefaultValue = "0.002", HelpText = "Set the width of the tube at discontinuity in x-direction [Default is 0.002].")] public string Tolerance { get; set; } - [Option('x', "timetolerance", Required = false, HelpText = "Set the width of the tube at discontinuity in y-direction [Default is equal to tolerance].")] - public string TimeTolerance { get; set; } - [Option('v', "verbosity", DefaultValue = 4, Required = false, HelpText = "Sets the verbosity of the output (1 most to 4[Default] less verbose).")] public int Verbosity { get; set; } diff --git a/Modelica_ResultCompare/Program.cs b/Modelica_ResultCompare/Program.cs index 6d75305..d566a55 100644 --- a/Modelica_ResultCompare/Program.cs +++ b/Modelica_ResultCompare/Program.cs @@ -102,7 +102,6 @@ private static void Run(string[] cmdArgs) _log.WriteLine(LogLevel.Debug, "Successfully parsed the following options:"); _log.WriteLine(LogLevel.Debug, "Operation mode is {0}", options.Mode); _log.WriteLine(LogLevel.Debug, "Tolerance is {0}", options.Tolerance); - _log.WriteLine(LogLevel.Debug, "TimeTolerance is {0}", options.TimeTolerance); if (options.Delimiter == 0) { diff --git a/Modelica_ResultCompare/Report.cs b/Modelica_ResultCompare/Report.cs index d5ed19b..d83f101 100644 --- a/Modelica_ResultCompare/Report.cs +++ b/Modelica_ResultCompare/Report.cs @@ -540,10 +540,7 @@ public bool WriteReport(Log log, Options options) if (null != options.Tolerance) writer.WriteLine(" Tolerance:{0}", options.Tolerance); - - if (null != options.TimeTolerance) - writer.WriteLine(" Tolerance:{0}", options.TimeTolerance); - + if (!String.IsNullOrEmpty(options.Logfile)) { writer.WriteLine(" Logfile:{0}", options.Logfile); @@ -656,7 +653,7 @@ public sealed class Report : IDisposable private string _metaPath; private List _chart = new List(); private List _data = new List(); - private double _tolerance, _timetolerance; + private double _tolerance; private double _dAvErr = 0; private int _iTotalErrors = -1; private bool _bRelative = false; @@ -666,12 +663,6 @@ public double Tolerance get { return _tolerance; } set { _tolerance = value; } } - - public double TimeTolerance - { - get { return _timetolerance; } - set { _timetolerance = value; } - } public string Message { get { return _message; } set { _message = value; } } public string FileName { get { return _path; } set { _path = value; } } public string MetaPath { get { return _metaPath; } set { _metaPath = value; } } @@ -860,7 +851,6 @@ private void WriteHeader(TextWriter writer, Options options) writer.WriteLine(" Compare file:{1}", this.CompareFile.Replace("\\", "/"), this.CompareFile); writer.WriteLine(" Tolerance:{0}", _tolerance); - writer.WriteLine(" Time Tolerance:{0}", _timetolerance); writer.WriteLine(" Timestamp:{0} [UTC]", DateTime.UtcNow); int iTested = _chart.Count - (from c in _chart where c.Errors == -1 select c).Count(); From 94cdc1ee69178f7becabda6d3541662502b9ad8c Mon Sep 17 00:00:00 2001 From: Matthias Schaefer Date: Tue, 19 May 2026 16:10:01 +0200 Subject: [PATCH 04/16] Add separate tolerance in horizontal direction (time-axis) --- Modelica_ResultCompare/CsvFile.cs | 29 ++++++++++++++++++++++++++--- Modelica_ResultCompare/Options.cs | 3 +++ Modelica_ResultCompare/Program.cs | 1 + Modelica_ResultCompare/Report.cs | 14 ++++++++++++-- 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/Modelica_ResultCompare/CsvFile.cs b/Modelica_ResultCompare/CsvFile.cs index 91d6bbf..43a8804 100644 --- a/Modelica_ResultCompare/CsvFile.cs +++ b/Modelica_ResultCompare/CsvFile.cs @@ -18,6 +18,7 @@ namespace CsvCompare public class CsvFile:IDisposable { private double _dRangeDelta = 0.002; + private double _dRangeDeltaT = 0.002; private string _fileName = string.Empty; private List _xAxis = new List(); private Dictionary> _values = new Dictionary>(); @@ -32,6 +33,8 @@ public class CsvFile:IDisposable public Dictionary> Results { get { return _values; } } /// This value can be used to produce a offset between base and comparison values public double RangeDelta { get { return _dRangeDelta; } set { _dRangeDelta = value; } } + /// This value can be used to produce a offset between base and comparison values + public double RangeDeltaT { get { return _dRangeDeltaT; } set { _dRangeDeltaT = value; } } /// This value enables/disables relative error differences in the error graph public bool ShowRelativeErrors { @@ -58,7 +61,26 @@ public CsvFile(string fileName, Options options, Log log) if (!Double.TryParse(options.Tolerance, out _dRangeDelta)) log.WriteLine(LogLevel.Warning, "could not parse given tolerance argument: \"{0}\", using default \"{1}\".", options.Tolerance, _dRangeDelta); } - + + //understand 0.002 + if (null != options.TimeTolerance) + { + if (!Double.TryParse(options.TimeTolerance, NumberStyles.AllowDecimalPoint, toleranceProvider, out _dRangeDeltaT)) + { + //understand 0,002 + toleranceProvider.NumberDecimalSeparator = ","; + if (!Double.TryParse(options.TimeTolerance, NumberStyles.AllowDecimalPoint, toleranceProvider, out _dRangeDeltaT)) + //understand 2e-2 etc. + if (!Double.TryParse(options.TimeTolerance, out _dRangeDeltaT)) + log.WriteLine(LogLevel.Warning, "could not parse given time tolerance argument: \"{0}\", using default \"{1}\".", options.TimeTolerance, _dRangeDelta); + _dRangeDeltaT = _dRangeDelta; + } + } + else + { + _dRangeDeltaT = _dRangeDelta; + } + if (File.Exists(fileName)) { _fileName = Path.GetFullPath(fileName); @@ -281,7 +303,7 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt TubeReport report = new TubeReport(); TubeSize size = null; Tube tube = new Tube(size); - IOptions tubeOptions = new Options1(_dRangeDelta, Axes.X); + IOptions tubeOptions = new Options1(_dRangeDelta, _dRangeDeltaT , Axes.X); foreach (KeyValuePair> res in csvBase.Results) { @@ -321,7 +343,7 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt const double defaultNominalValue = 0.001; const bool useLegacyBaseAndRatio = true; size = new TubeSize(reference, defaultNominalValue, useLegacyBaseAndRatio); - size.Calculate(_dRangeDelta, Axes.X, Relativity.Relative); + size.Calculate(_dRangeDelta, _dRangeDeltaT, Axes.X, Relativity.Relative); tube = new Tube(size); var calcResult = tube.Calculate(reference); bool calcSuccess = calcResult.Item2; @@ -371,6 +393,7 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt writer.WriteLine(". Time: {0:o}", DateTime.Now); writer.WriteLine(". Operation: {0}", options.Mode); writer.WriteLine(". Tolerance: {0}", options.Tolerance); + writer.WriteLine(". TimeTolerance: {0}", options.TimeTolerance); writer.WriteLine(". Result: {0}", sResult); if (rep.TotalErrors > 0) diff --git a/Modelica_ResultCompare/Options.cs b/Modelica_ResultCompare/Options.cs index 7323ec8..8603d30 100644 --- a/Modelica_ResultCompare/Options.cs +++ b/Modelica_ResultCompare/Options.cs @@ -52,6 +52,9 @@ public class Options [Option('t', "tolerance", Required = false, DefaultValue = "0.002", HelpText = "Set the width of the tube at discontinuity in x-direction [Default is 0.002].")] public string Tolerance { get; set; } + [Option('x', "timetolerance", Required = false, HelpText = "Set the width of the tube at discontinuity in y-direction [Default is equal to tolerance].")] + public string TimeTolerance { get; set; } + [Option('v', "verbosity", DefaultValue = 4, Required = false, HelpText = "Sets the verbosity of the output (1 most to 4[Default] less verbose).")] public int Verbosity { get; set; } diff --git a/Modelica_ResultCompare/Program.cs b/Modelica_ResultCompare/Program.cs index d566a55..6d75305 100644 --- a/Modelica_ResultCompare/Program.cs +++ b/Modelica_ResultCompare/Program.cs @@ -102,6 +102,7 @@ private static void Run(string[] cmdArgs) _log.WriteLine(LogLevel.Debug, "Successfully parsed the following options:"); _log.WriteLine(LogLevel.Debug, "Operation mode is {0}", options.Mode); _log.WriteLine(LogLevel.Debug, "Tolerance is {0}", options.Tolerance); + _log.WriteLine(LogLevel.Debug, "TimeTolerance is {0}", options.TimeTolerance); if (options.Delimiter == 0) { diff --git a/Modelica_ResultCompare/Report.cs b/Modelica_ResultCompare/Report.cs index d83f101..d5ed19b 100644 --- a/Modelica_ResultCompare/Report.cs +++ b/Modelica_ResultCompare/Report.cs @@ -540,7 +540,10 @@ public bool WriteReport(Log log, Options options) if (null != options.Tolerance) writer.WriteLine(" Tolerance:{0}", options.Tolerance); - + + if (null != options.TimeTolerance) + writer.WriteLine(" Tolerance:{0}", options.TimeTolerance); + if (!String.IsNullOrEmpty(options.Logfile)) { writer.WriteLine(" Logfile:{0}", options.Logfile); @@ -653,7 +656,7 @@ public sealed class Report : IDisposable private string _metaPath; private List _chart = new List(); private List _data = new List(); - private double _tolerance; + private double _tolerance, _timetolerance; private double _dAvErr = 0; private int _iTotalErrors = -1; private bool _bRelative = false; @@ -663,6 +666,12 @@ public double Tolerance get { return _tolerance; } set { _tolerance = value; } } + + public double TimeTolerance + { + get { return _timetolerance; } + set { _timetolerance = value; } + } public string Message { get { return _message; } set { _message = value; } } public string FileName { get { return _path; } set { _path = value; } } public string MetaPath { get { return _metaPath; } set { _metaPath = value; } } @@ -851,6 +860,7 @@ private void WriteHeader(TextWriter writer, Options options) writer.WriteLine(" Compare file:{1}", this.CompareFile.Replace("\\", "/"), this.CompareFile); writer.WriteLine(" Tolerance:{0}", _tolerance); + writer.WriteLine(" Time Tolerance:{0}", _timetolerance); writer.WriteLine(" Timestamp:{0} [UTC]", DateTime.UtcNow); int iTested = _chart.Count - (from c in _chart where c.Errors == -1 select c).Count(); From b2c676cd476472282de35bb801d59a3d85603198 Mon Sep 17 00:00:00 2001 From: Matthias Schaefer Date: Tue, 19 May 2026 16:48:04 +0200 Subject: [PATCH 05/16] improved tube calculation: Only consider the common time interval of reference and compareCurve for width of tube, Consider slope of the referenceCurve at the beginning and the end of the tube in case of rectangular tube algorithm to avoid horizontal tube endings --- Modelica_ResultCompare/CsvFile.cs | 113 +++++++++++++++--- .../CurveCompare/Algorithms/Rectangle.cs | 37 ++++-- 2 files changed, 126 insertions(+), 24 deletions(-) diff --git a/Modelica_ResultCompare/CsvFile.cs b/Modelica_ResultCompare/CsvFile.cs index 91d6bbf..de29c4d 100644 --- a/Modelica_ResultCompare/CsvFile.cs +++ b/Modelica_ResultCompare/CsvFile.cs @@ -265,7 +265,69 @@ public Report CompareFiles(Log log, CsvFile csvBase, ref Options options) else return CompareFiles(log, csvBase, null, ref options); } + + static Curve Trim_curve(Curve curve, + double start_time, + double end_time) + { + int start_idx = 0; + int end_idx = curve.Count; + + /* Find first valid sample */ + while (start_idx < curve.Count && + curve.X[start_idx] < start_time) + { + start_idx++; + } + + /* Find last valid sample */ + while (end_idx > start_idx && + curve.X[end_idx - 1] > end_time) + { + end_idx--; + } + + int new_size = end_idx - start_idx; + double[] TargetValues = new double[new_size]; + double[] TargetTime = new double[new_size]; + /* Shift data to beginning */ + for (int i = 0; i < new_size; ++i) + { + TargetTime[i] = curve.X[start_idx + i]; + TargetValues[i] = curve.Y[start_idx + i]; + } + Curve NewCurve = new Curve(curve.Name, TargetTime, TargetValues); + return NewCurve; + } + + public double[] GetCommonInterval(Curve reference, Curve compareCurve) + { + double[] common_interval = new double[2] { 0.0, 0.0 }; + if (compareCurve.Count == 0 || reference.Count == 0) + { + return common_interval; + } + // Determine common interval + double common_start = + (reference.X[0] > compareCurve.X[0]) + ? reference.X[0] + : compareCurve.X[0]; + + double common_stop = + (reference.X[reference.X.Length - 1] < + compareCurve.X[compareCurve.X.Length - 1]) + ? reference.X[reference.X.Length - 1] + : compareCurve.X[compareCurve.X.Length - 1]; + if (common_start > common_stop) + { + return common_interval; + } + common_interval[0] = common_start; + common_interval[1] = common_stop; + return common_interval; + } + public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Options options) { int iInvalids = 0; @@ -276,8 +338,11 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt rep.BaseFile = csvBase.ToString(); rep.CompareFile = _fileName; + double[] common_interval = new double [2]; Curve reference = new Curve(); Curve compareCurve = new Curve(); + Curve trimmedReference = new Curve(); + Curve trimmedCompareCurve = new Curve(); TubeReport report = new TubeReport(); TubeSize size = null; Tube tube = new Tube(size); @@ -314,13 +379,27 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt else log.WriteLine(LogLevel.Debug, "The resolution of the base x-axis is good."); + common_interval = GetCommonInterval(compareCurve, reference); + + if (common_interval != null && common_interval[0] != common_interval[1]) + { + trimmedReference = Trim_curve(reference, common_interval[0], common_interval[1]); + trimmedCompareCurve = Trim_curve(compareCurve, common_interval[0], common_interval[1]); + } + else + { + trimmedReference = reference; + trimmedCompareCurve = compareCurve; + + } + // The actual nominal attribute should be used, but is unfortunately unavailable in the CSV files. // A default nominal value of 0.001 was chosen as a compromise between having many false negatives // and passing wrong result files. // See discussion in https://github.com/modelica/ModelicaStandardLibrary/issues/4421 const double defaultNominalValue = 0.001; - const bool useLegacyBaseAndRatio = true; - size = new TubeSize(reference, defaultNominalValue, useLegacyBaseAndRatio); + const bool useLegacyBaseAndRatio = false; + size = new TubeSize(trimmedReference, defaultNominalValue, useLegacyBaseAndRatio); size.Calculate(_dRangeDelta, Axes.X, Relativity.Relative); tube = new Tube(size); var calcResult = tube.Calculate(reference); @@ -332,7 +411,7 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt continue; } report = calcResult.Item1; - bool validationSuccess = Tube.Validate(compareCurve, report); + bool validationSuccess = Tube.Validate(trimmedCompareCurve, report); if (!validationSuccess) { log.Error("Error in the validation of the tube. Skipping {0}", res.Key); @@ -351,7 +430,7 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt } } if (null != report) //No charts for missing reports - PrepareCharts(reference, compareCurve, report.Errors, rep, report, res, options.UseBitmapPlots); + PrepareCharts(reference, compareCurve, trimmedCompareCurve, report.Errors, rep, report, res, options.UseBitmapPlots); } rep.Tolerance = _dRangeDelta; @@ -392,10 +471,10 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt private void PrepareCharts(Report rep, Curve compare)//Draw result only { - PrepareCharts(compare, null, null, rep, null, new KeyValuePair>(compare.Name, null), false); + PrepareCharts(compare, null, null, null, rep, null, new KeyValuePair>(compare.Name, null), false); } - private void PrepareCharts(Curve reference, Curve compare, Curve error, Report rep, TubeReport tubeReport, KeyValuePair> res, bool bDrawBitmapPlots) + private void PrepareCharts(Curve reference, Curve compare, Curve trimmedCompare, Curve error, Report rep, TubeReport tubeReport, KeyValuePair> res, bool bDrawBitmapPlots) { Chart ch = new Chart() @@ -457,15 +536,15 @@ private void PrepareCharts(Curve reference, Curve compare, Curve error, Report r if (null != error && null != error.X && error.X.Length > 0) { //Get complete error curve as "error" only holds error points - Curve curveErrors = new Curve("ERRORS", new double[compare.X.Length], new double[compare.X.Length]); + Curve curveErrors = new Curve("ERRORS", new double[trimmedCompare.X.Length], new double[trimmedCompare.X.Length]); int j = 0; - for (int i = 0; i < compare.X.Length - 1; i++) + for (int i = 0; i <= trimmedCompare.X.Length - 1; i++) { - curveErrors.X[i] = compare.X[i]; - if (error.X.Contains(compare.X[i])) + curveErrors.X[i] = trimmedCompare.X[i]; + if (error.X.Contains(trimmedCompare.X[i])) { curveErrors.Y[i] = (this._bShowRelativeErrors) ? error.Y[j] : 1; - if (compare.X[i + 1] > compare.X[i]) + if (i == trimmedCompare.X.Length - 1 || trimmedCompare.X[i + 1] > trimmedCompare.X[i]) { j++; } @@ -488,24 +567,24 @@ private void PrepareCharts(Curve reference, Curve compare, Curve error, Report r //Calculate delta error List lDeltas = new List(); j = 0; - for (int i = 1; i < compare.X.Length - 1; i++) + for (int i = 1; i < trimmedCompare.X.Length - 1; i++) { if (j < error.X.Length) { - while (compare.X[i] < error.X[j]) + while (trimmedCompare.X[i] < error.X[j]) { i++; continue; } - if (i < compare.X.Length - 1) - lDeltas.Add((Math.Abs(error.Y[j]) * ((Math.Abs(compare.X[i] - compare.X[i - 1])) + (Math.Abs(compare.X[i + 1] - compare.X[i])))) / 2); + if (i < trimmedCompare.X.Length - 1) + lDeltas.Add((Math.Abs(error.Y[j]) * ((Math.Abs(trimmedCompare.X[i] - trimmedCompare.X[i - 1])) + (Math.Abs(trimmedCompare.X[i + 1] - trimmedCompare.X[i])))) / 2); else // handle errors in the last point (there is no i+1) - lDeltas.Add((Math.Abs(error.Y[j]) * ((Math.Abs(compare.X[i] - compare.X[i - 1])))) / 2); + lDeltas.Add((Math.Abs(error.Y[j]) * ((Math.Abs(trimmedCompare.X[i] - trimmedCompare.X[i - 1])))) / 2); j++; } } - ch.DeltaError = lDeltas.Sum() / (1e-3 + compare.Y.Max(x => Math.Abs(x))); + ch.DeltaError = lDeltas.Sum() / (1e-3 + trimmedCompare.Y.Max(x => Math.Abs(x))); } if (null != tubeReport && tubeReport.Lower.X.ToList().Count > 2)//Remember Start and Stop values for graph scaling { diff --git a/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs b/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs index 0fc9acc..000d747 100644 --- a/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs +++ b/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs @@ -81,12 +81,18 @@ private static Curve CalculateLower(Curve reference, TubeSize size) // ignore identical point at the beginning b = 0; + + // calculate slope at the beginning while (b + 1 < reference.Count && (reference.X[b] - reference.X[b + 1] == 0) && (reference.Y[b] - reference.Y[b + 1] == 0)) b++; - + if (reference.X[b + 1] != reference.X[b]) + m0 = (reference.Y[b + 1] - reference.Y[b]) / (reference.X[b + 1] - reference.X[b]); + else + m0 = 0; + // add point down left LX.Add(reference.X[b] - size.X); - LY.Add(reference.Y[b] - size.Y); + LY.Add(reference.Y[b] - size.Y - 2* m0 * size.X); if (b + 1 < reference.Count) { @@ -195,9 +201,14 @@ private static Curve CalculateLower(Curve reference, TubeSize size) } } + // calculate slope at the end + if (reference.X[reference.Count - 1] != reference.X[reference.Count - 2]) + m0 = (reference.Y[reference.Count - 1] - reference.Y[reference.Count - 2]) / (reference.X[reference.Count - 1] - reference.X[reference.Count - 2]); + else + m0 = 0; // add point down right LX.Add(reference.X[reference.Count - 1] + size.X); - LY.Add(reference.Y[reference.Count - 1] - size.Y); + LY.Add(reference.Y[reference.Count - 1] - size.Y + 2 * m0 * size.X); // ------------------------------------------------------------------------------------------------------------- // -------------- 2. Remove points and add intersection points in case of backward order ----------------------- @@ -238,10 +249,16 @@ private static Curve CalculateUpper(Curve reference, TubeSize size) b = 0; while (b + 1 < reference.Count && (reference.X[b] - reference.X[b + 1] == 0) && (reference.Y[b] - reference.Y[b + 1] == 0)) b++; + + // calculate slope at the beginning + if (reference.X[b + 1] != reference.X[b]) + m0 = (reference.Y[b + 1] - reference.Y[b]) / (reference.X[b + 1] - reference.X[b]); + else + m0 = 0; // add point top left UX.Add(reference.X[b] - size.X); - UY.Add(reference.Y[b] + size.Y); + UY.Add(reference.Y[b] + size.Y - 2*m0*size.X); if (b + 1 < reference.Count) { @@ -350,9 +367,15 @@ private static Curve CalculateUpper(Curve reference, TubeSize size) } } - // add point top right - UX.Add(reference.X[reference.Count - 1] + size.X); - UY.Add(reference.Y[reference.Count - 1] + size.Y); + + // calculate slope at the end + if (reference.X[reference.Count - 1] != reference.X[reference.Count - 2]) + m0 = (reference.Y[reference.Count - 1] - reference.Y[reference.Count - 2]) / (reference.X[reference.Count - 1] - reference.X[reference.Count - 2]); + else + m0 = 0; + // add point down right + LX.Add(reference.X[reference.Count - 1] + size.X); + LY.Add(reference.Y[reference.Count - 1] - size.Y + 2 * m0 * size.X); // --------------------------------------------------------------------------------------------------------- // -------------- 2. Remove points and add intersection points in case of backward order ------------------- From c58ea8162a315e1a93afb007d4c6b6ecdfab98ca Mon Sep 17 00:00:00 2001 From: Matthias Schaefer Date: Tue, 19 May 2026 17:20:29 +0200 Subject: [PATCH 06/16] BugFix in calculation of upperTube in rectagle Algorithm --- Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs b/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs index 000d747..d6df8ae 100644 --- a/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs +++ b/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs @@ -374,8 +374,8 @@ private static Curve CalculateUpper(Curve reference, TubeSize size) else m0 = 0; // add point down right - LX.Add(reference.X[reference.Count - 1] + size.X); - LY.Add(reference.Y[reference.Count - 1] - size.Y + 2 * m0 * size.X); + UX.Add(reference.X[reference.Count - 1] + size.X); + UY.Add(reference.Y[reference.Count - 1] + size.Y + 2 * m0 * size.X); // --------------------------------------------------------------------------------------------------------- // -------------- 2. Remove points and add intersection points in case of backward order ------------------- From 911f1d7b71276e6a777a7a0d395c511e4f718a1b Mon Sep 17 00:00:00 2001 From: Matthias Schaefer Date: Wed, 20 May 2026 09:18:33 +0200 Subject: [PATCH 07/16] Remove TimeTolerance Setting from this branch, because it belongs in its own branch --- Modelica_ResultCompare/CsvFile.cs | 27 ++------------------------- Modelica_ResultCompare/Options.cs | 5 +---- Modelica_ResultCompare/Program.cs | 1 - Modelica_ResultCompare/Report.cs | 11 +---------- 4 files changed, 4 insertions(+), 40 deletions(-) diff --git a/Modelica_ResultCompare/CsvFile.cs b/Modelica_ResultCompare/CsvFile.cs index 21433ad..d3ec3a3 100644 --- a/Modelica_ResultCompare/CsvFile.cs +++ b/Modelica_ResultCompare/CsvFile.cs @@ -18,7 +18,6 @@ namespace CsvCompare public class CsvFile:IDisposable { private double _dRangeDelta = 0.002; - private double _dRangeDeltaT = 0.002; private string _fileName = string.Empty; private List _xAxis = new List(); private Dictionary> _values = new Dictionary>(); @@ -34,8 +33,6 @@ public class CsvFile:IDisposable /// This value can be used to produce a offset between base and comparison values public double RangeDelta { get { return _dRangeDelta; } set { _dRangeDelta = value; } } /// This value can be used to produce a offset between base and comparison values - public double RangeDeltaT { get { return _dRangeDeltaT; } set { _dRangeDeltaT = value; } } - /// This value enables/disables relative error differences in the error graph public bool ShowRelativeErrors { get { return _bShowRelativeErrors; } @@ -62,25 +59,6 @@ public CsvFile(string fileName, Options options, Log log) log.WriteLine(LogLevel.Warning, "could not parse given tolerance argument: \"{0}\", using default \"{1}\".", options.Tolerance, _dRangeDelta); } - //understand 0.002 - if (null != options.TimeTolerance) - { - if (!Double.TryParse(options.TimeTolerance, NumberStyles.AllowDecimalPoint, toleranceProvider, out _dRangeDeltaT)) - { - //understand 0,002 - toleranceProvider.NumberDecimalSeparator = ","; - if (!Double.TryParse(options.TimeTolerance, NumberStyles.AllowDecimalPoint, toleranceProvider, out _dRangeDeltaT)) - //understand 2e-2 etc. - if (!Double.TryParse(options.TimeTolerance, out _dRangeDeltaT)) - log.WriteLine(LogLevel.Warning, "could not parse given time tolerance argument: \"{0}\", using default \"{1}\".", options.TimeTolerance, _dRangeDelta); - _dRangeDeltaT = _dRangeDelta; - } - } - else - { - _dRangeDeltaT = _dRangeDelta; - } - if (File.Exists(fileName)) { _fileName = Path.GetFullPath(fileName); @@ -368,7 +346,7 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt TubeReport report = new TubeReport(); TubeSize size = null; Tube tube = new Tube(size); - IOptions tubeOptions = new Options1(_dRangeDelta, _dRangeDeltaT , Axes.X); + IOptions tubeOptions = new Options1(_dRangeDelta, Axes.X); foreach (KeyValuePair> res in csvBase.Results) { @@ -422,7 +400,7 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt const double defaultNominalValue = 0.001; const bool useLegacyBaseAndRatio = false; size = new TubeSize(trimmedReference, defaultNominalValue, useLegacyBaseAndRatio); - size.Calculate(_dRangeDelta, _dRangeDeltaT, Axes.X, Relativity.Relative); + size.Calculate(_dRangeDelta, Axes.X, Relativity.Relative); tube = new Tube(size); var calcResult = tube.Calculate(reference); @@ -473,7 +451,6 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt writer.WriteLine(". Time: {0:o}", DateTime.Now); writer.WriteLine(". Operation: {0}", options.Mode); writer.WriteLine(". Tolerance: {0}", options.Tolerance); - writer.WriteLine(". TimeTolerance: {0}", options.TimeTolerance); writer.WriteLine(". Result: {0}", sResult); if (rep.TotalErrors > 0) diff --git a/Modelica_ResultCompare/Options.cs b/Modelica_ResultCompare/Options.cs index 8603d30..92e79e0 100644 --- a/Modelica_ResultCompare/Options.cs +++ b/Modelica_ResultCompare/Options.cs @@ -49,12 +49,9 @@ public class Options [Option('i', "inline", DefaultValue = false, HelpText = "If set, javascript and style sheet files are inserted as inline text in every html output file")] public bool InlineScripts { get; set; } - [Option('t', "tolerance", Required = false, DefaultValue = "0.002", HelpText = "Set the width of the tube at discontinuity in x-direction [Default is 0.002].")] + [Option('t', "tolerance", Required = false, DefaultValue = "0.002", HelpText = "Set the width of the tube at discontinuity [Default is 0.002].")] public string Tolerance { get; set; } - [Option('x', "timetolerance", Required = false, HelpText = "Set the width of the tube at discontinuity in y-direction [Default is equal to tolerance].")] - public string TimeTolerance { get; set; } - [Option('v', "verbosity", DefaultValue = 4, Required = false, HelpText = "Sets the verbosity of the output (1 most to 4[Default] less verbose).")] public int Verbosity { get; set; } diff --git a/Modelica_ResultCompare/Program.cs b/Modelica_ResultCompare/Program.cs index 6d75305..d566a55 100644 --- a/Modelica_ResultCompare/Program.cs +++ b/Modelica_ResultCompare/Program.cs @@ -102,7 +102,6 @@ private static void Run(string[] cmdArgs) _log.WriteLine(LogLevel.Debug, "Successfully parsed the following options:"); _log.WriteLine(LogLevel.Debug, "Operation mode is {0}", options.Mode); _log.WriteLine(LogLevel.Debug, "Tolerance is {0}", options.Tolerance); - _log.WriteLine(LogLevel.Debug, "TimeTolerance is {0}", options.TimeTolerance); if (options.Delimiter == 0) { diff --git a/Modelica_ResultCompare/Report.cs b/Modelica_ResultCompare/Report.cs index d5ed19b..3b76c4f 100644 --- a/Modelica_ResultCompare/Report.cs +++ b/Modelica_ResultCompare/Report.cs @@ -541,9 +541,6 @@ public bool WriteReport(Log log, Options options) if (null != options.Tolerance) writer.WriteLine(" Tolerance:{0}", options.Tolerance); - if (null != options.TimeTolerance) - writer.WriteLine(" Tolerance:{0}", options.TimeTolerance); - if (!String.IsNullOrEmpty(options.Logfile)) { writer.WriteLine(" Logfile:{0}", options.Logfile); @@ -656,7 +653,7 @@ public sealed class Report : IDisposable private string _metaPath; private List _chart = new List(); private List _data = new List(); - private double _tolerance, _timetolerance; + private double _tolerance; private double _dAvErr = 0; private int _iTotalErrors = -1; private bool _bRelative = false; @@ -667,11 +664,6 @@ public double Tolerance set { _tolerance = value; } } - public double TimeTolerance - { - get { return _timetolerance; } - set { _timetolerance = value; } - } public string Message { get { return _message; } set { _message = value; } } public string FileName { get { return _path; } set { _path = value; } } public string MetaPath { get { return _metaPath; } set { _metaPath = value; } } @@ -860,7 +852,6 @@ private void WriteHeader(TextWriter writer, Options options) writer.WriteLine(" Compare file:{1}", this.CompareFile.Replace("\\", "/"), this.CompareFile); writer.WriteLine(" Tolerance:{0}", _tolerance); - writer.WriteLine(" Time Tolerance:{0}", _timetolerance); writer.WriteLine(" Timestamp:{0} [UTC]", DateTime.UtcNow); int iTested = _chart.Count - (from c in _chart where c.Errors == -1 select c).Count(); From 3837d3d90c855a6f8a8efd495ce005686b6b0851 Mon Sep 17 00:00:00 2001 From: Matthias Schaefer Date: Wed, 20 May 2026 09:34:43 +0200 Subject: [PATCH 08/16] Separate the features --- Modelica_ResultCompare/CsvFile.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Modelica_ResultCompare/CsvFile.cs b/Modelica_ResultCompare/CsvFile.cs index d3ec3a3..cde8b8f 100644 --- a/Modelica_ResultCompare/CsvFile.cs +++ b/Modelica_ResultCompare/CsvFile.cs @@ -371,7 +371,6 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt { log.Error("Error in the calculation of the tubes. Skipping {0}", res.Key); rep.Chart.Add(new Chart() { Title = res.Key, Errors = 1 }); - continue; } if (reference.X.Length < compareCurve.X.Length) From 55e090d2864940b0940832cbcc64760f2b1dacd2 Mon Sep 17 00:00:00 2001 From: Matthias Schaefer Date: Wed, 20 May 2026 09:38:12 +0200 Subject: [PATCH 09/16] Separate the features --- Modelica_ResultCompare/CsvFile.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modelica_ResultCompare/CsvFile.cs b/Modelica_ResultCompare/CsvFile.cs index cde8b8f..b31d191 100644 --- a/Modelica_ResultCompare/CsvFile.cs +++ b/Modelica_ResultCompare/CsvFile.cs @@ -355,7 +355,6 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt size = null; tube = new Tube(size); log.WriteLine(LogLevel.Warning, "{0} not found in \"{1}\", skipping checks.", res.Key, this._fileName); - continue; } else { @@ -371,6 +370,7 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt { log.Error("Error in the calculation of the tubes. Skipping {0}", res.Key); rep.Chart.Add(new Chart() { Title = res.Key, Errors = 1 }); + continue; } if (reference.X.Length < compareCurve.X.Length) From 392e332b78694e77d527b892613bd9c82866bdde Mon Sep 17 00:00:00 2001 From: Matthias Schaefer Date: Wed, 20 May 2026 09:45:58 +0200 Subject: [PATCH 10/16] Undo whitespace changes --- Modelica_ResultCompare/CsvFile.cs | 7 ++----- Modelica_ResultCompare/Report.cs | 4 +--- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/Modelica_ResultCompare/CsvFile.cs b/Modelica_ResultCompare/CsvFile.cs index b31d191..1d95f22 100644 --- a/Modelica_ResultCompare/CsvFile.cs +++ b/Modelica_ResultCompare/CsvFile.cs @@ -32,7 +32,7 @@ public class CsvFile:IDisposable public Dictionary> Results { get { return _values; } } /// This value can be used to produce a offset between base and comparison values public double RangeDelta { get { return _dRangeDelta; } set { _dRangeDelta = value; } } - /// This value can be used to produce a offset between base and comparison values + /// This value enables/disables relative error differences in the error graph public bool ShowRelativeErrors { get { return _bShowRelativeErrors; } @@ -57,8 +57,7 @@ public CsvFile(string fileName, Options options, Log log) //understand 2e-2 etc. if (!Double.TryParse(options.Tolerance, out _dRangeDelta)) log.WriteLine(LogLevel.Warning, "could not parse given tolerance argument: \"{0}\", using default \"{1}\".", options.Tolerance, _dRangeDelta); - } - + } if (File.Exists(fileName)) { _fileName = Path.GetFullPath(fileName); @@ -389,7 +388,6 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt { trimmedReference = reference; trimmedCompareCurve = compareCurve; - } // The actual nominal attribute should be used, but is unfortunately unavailable in the CSV files. @@ -400,7 +398,6 @@ public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Opt const bool useLegacyBaseAndRatio = false; size = new TubeSize(trimmedReference, defaultNominalValue, useLegacyBaseAndRatio); size.Calculate(_dRangeDelta, Axes.X, Relativity.Relative); - tube = new Tube(size); var calcResult = tube.Calculate(reference); bool calcSuccess = calcResult.Item2; diff --git a/Modelica_ResultCompare/Report.cs b/Modelica_ResultCompare/Report.cs index 3b76c4f..5ba58d8 100644 --- a/Modelica_ResultCompare/Report.cs +++ b/Modelica_ResultCompare/Report.cs @@ -539,8 +539,7 @@ public bool WriteReport(Log log, Options options) writer.WriteLine(" Verbosity:{0}", options.Verbosity.ToString(CultureInfo.CurrentCulture)); if (null != options.Tolerance) - writer.WriteLine(" Tolerance:{0}", options.Tolerance); - + writer.WriteLine(" Tolerance:{0}", options.Tolerance); if (!String.IsNullOrEmpty(options.Logfile)) { writer.WriteLine(" Logfile:{0}", options.Logfile); @@ -663,7 +662,6 @@ public double Tolerance get { return _tolerance; } set { _tolerance = value; } } - public string Message { get { return _message; } set { _message = value; } } public string FileName { get { return _path; } set { _path = value; } } public string MetaPath { get { return _metaPath; } set { _metaPath = value; } } From cd0f42aaf3fc19d4bb21a39e947a1cfcb02d70f9 Mon Sep 17 00:00:00 2001 From: Matthias Schaefer Date: Wed, 20 May 2026 09:48:14 +0200 Subject: [PATCH 11/16] Undo whitespace changes --- Modelica_ResultCompare/CsvFile.cs | 3 ++- Modelica_ResultCompare/Report.cs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Modelica_ResultCompare/CsvFile.cs b/Modelica_ResultCompare/CsvFile.cs index 1d95f22..5f8d3a0 100644 --- a/Modelica_ResultCompare/CsvFile.cs +++ b/Modelica_ResultCompare/CsvFile.cs @@ -57,7 +57,8 @@ public CsvFile(string fileName, Options options, Log log) //understand 2e-2 etc. if (!Double.TryParse(options.Tolerance, out _dRangeDelta)) log.WriteLine(LogLevel.Warning, "could not parse given tolerance argument: \"{0}\", using default \"{1}\".", options.Tolerance, _dRangeDelta); - } + } + if (File.Exists(fileName)) { _fileName = Path.GetFullPath(fileName); diff --git a/Modelica_ResultCompare/Report.cs b/Modelica_ResultCompare/Report.cs index 5ba58d8..c6e0550 100644 --- a/Modelica_ResultCompare/Report.cs +++ b/Modelica_ResultCompare/Report.cs @@ -540,6 +540,7 @@ public bool WriteReport(Log log, Options options) if (null != options.Tolerance) writer.WriteLine(" Tolerance:{0}", options.Tolerance); + if (!String.IsNullOrEmpty(options.Logfile)) { writer.WriteLine(" Logfile:{0}", options.Logfile); From a8259002de7a2844457b534f321482b032091bcc Mon Sep 17 00:00:00 2001 From: Matthias Schaefer Date: Wed, 20 May 2026 09:49:23 +0200 Subject: [PATCH 12/16] Undo whitespace changes --- Modelica_ResultCompare/Report.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modelica_ResultCompare/Report.cs b/Modelica_ResultCompare/Report.cs index c6e0550..d83f101 100644 --- a/Modelica_ResultCompare/Report.cs +++ b/Modelica_ResultCompare/Report.cs @@ -539,7 +539,7 @@ public bool WriteReport(Log log, Options options) writer.WriteLine(" Verbosity:{0}", options.Verbosity.ToString(CultureInfo.CurrentCulture)); if (null != options.Tolerance) - writer.WriteLine(" Tolerance:{0}", options.Tolerance); + writer.WriteLine(" Tolerance:{0}", options.Tolerance); if (!String.IsNullOrEmpty(options.Logfile)) { From 8ae4c9d81ea8198657a3bb37b8e83ea1ae8b7216 Mon Sep 17 00:00:00 2001 From: Matthias Schaefer Date: Fri, 26 Jun 2026 08:23:07 +0200 Subject: [PATCH 13/16] Adapted TubeCalculation at end of tubes --- .../CurveCompare/Algorithms/Rectangle.cs | 55 +++++++++++-------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs b/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs index d6df8ae..d465248 100644 --- a/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs +++ b/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs @@ -81,7 +81,7 @@ private static Curve CalculateLower(Curve reference, TubeSize size) // ignore identical point at the beginning b = 0; - + // calculate slope at the beginning while (b + 1 < reference.Count && (reference.X[b] - reference.X[b + 1] == 0) && (reference.Y[b] - reference.Y[b + 1] == 0)) b++; @@ -89,10 +89,13 @@ private static Curve CalculateLower(Curve reference, TubeSize size) m0 = (reference.Y[b + 1] - reference.Y[b]) / (reference.X[b + 1] - reference.X[b]); else m0 = 0; - + // add point down left LX.Add(reference.X[b] - size.X); - LY.Add(reference.Y[b] - size.Y - 2* m0 * size.X); + if (m0 > 0) + LY.Add(reference.Y[b] - size.Y - 2 * m0 * size.X); + else + LY.Add(reference.Y[b] - size.Y); if (b + 1 < reference.Count) { @@ -102,9 +105,9 @@ private static Curve CalculateLower(Curve reference, TubeSize size) m0 = (reference.Y[b + 1] - reference.Y[b]) / (reference.X[b + 1] - reference.X[b]); else if (s0 > 0) - m0 = Double.PositiveInfinity; - else - m0 = Double.NegativeInfinity; + m0 = Double.PositiveInfinity; + else + m0 = Double.NegativeInfinity; if (s0 == 1) { @@ -128,9 +131,9 @@ private static Curve CalculateLower(Curve reference, TubeSize size) m1 = (reference.Y[i + 1] - reference.Y[i]) / (reference.X[i + 1] - reference.X[i]); else if (s1 > 0) - m1 = Double.PositiveInfinity; - else - m1 = Double.NegativeInfinity; + m1 = Double.PositiveInfinity; + else + m1 = Double.NegativeInfinity; // add no point for equal slopes of reference curve if (!(m0 == m1)) @@ -208,7 +211,10 @@ private static Curve CalculateLower(Curve reference, TubeSize size) m0 = 0; // add point down right LX.Add(reference.X[reference.Count - 1] + size.X); - LY.Add(reference.Y[reference.Count - 1] - size.Y + 2 * m0 * size.X); + if (m0 < 0) + LY.Add(reference.Y[reference.Count - 1] - size.Y + 2 * m0 * size.X); + else + LY.Add(reference.Y[reference.Count - 1] - size.Y); // ------------------------------------------------------------------------------------------------------------- // -------------- 2. Remove points and add intersection points in case of backward order ----------------------- @@ -249,7 +255,7 @@ private static Curve CalculateUpper(Curve reference, TubeSize size) b = 0; while (b + 1 < reference.Count && (reference.X[b] - reference.X[b + 1] == 0) && (reference.Y[b] - reference.Y[b + 1] == 0)) b++; - + // calculate slope at the beginning if (reference.X[b + 1] != reference.X[b]) m0 = (reference.Y[b + 1] - reference.Y[b]) / (reference.X[b + 1] - reference.X[b]); @@ -258,7 +264,10 @@ private static Curve CalculateUpper(Curve reference, TubeSize size) // add point top left UX.Add(reference.X[b] - size.X); - UY.Add(reference.Y[b] + size.Y - 2*m0*size.X); + if (m0 < 0) + UY.Add(reference.Y[b] + size.Y - 2 * m0 * size.X); + else + UY.Add(reference.Y[b] + size.Y); if (b + 1 < reference.Count) { @@ -268,9 +277,9 @@ private static Curve CalculateUpper(Curve reference, TubeSize size) m0 = (reference.Y[b + 1] - reference.Y[b]) / (reference.X[b + 1] - reference.X[b]); else if (s0 > 0) - m0 = Double.PositiveInfinity; - else - m0 = Double.NegativeInfinity; + m0 = Double.PositiveInfinity; + else + m0 = Double.NegativeInfinity; if (s0 == -1) { @@ -294,9 +303,9 @@ private static Curve CalculateUpper(Curve reference, TubeSize size) m1 = (reference.Y[i + 1] - reference.Y[i]) / (reference.X[i + 1] - reference.X[i]); else if (s1 > 0) - m1 = Double.PositiveInfinity; - else - m1 = Double.NegativeInfinity; + m1 = Double.PositiveInfinity; + else + m1 = Double.NegativeInfinity; // add no point for equal slopes of reference curve if (!(m0 == m1)) @@ -367,7 +376,7 @@ private static Curve CalculateUpper(Curve reference, TubeSize size) } } - + // calculate slope at the end if (reference.X[reference.Count - 1] != reference.X[reference.Count - 2]) m0 = (reference.Y[reference.Count - 1] - reference.Y[reference.Count - 2]) / (reference.X[reference.Count - 1] - reference.X[reference.Count - 2]); @@ -375,8 +384,10 @@ private static Curve CalculateUpper(Curve reference, TubeSize size) m0 = 0; // add point down right UX.Add(reference.X[reference.Count - 1] + size.X); - UY.Add(reference.Y[reference.Count - 1] + size.Y + 2 * m0 * size.X); - + if (m0 > 0) + UY.Add(reference.Y[reference.Count - 1] + size.Y + 2 * m0 * size.X); + else + UY.Add(reference.Y[reference.Count - 1] + size.Y); // --------------------------------------------------------------------------------------------------------- // -------------- 2. Remove points and add intersection points in case of backward order ------------------- // --------------------------------------------------------------------------------------------------------- @@ -456,7 +467,7 @@ private static int RemoveLoop(List X, List Y, bool lower) k++; //while ((X[i] < X[k] || (X[i] == X[k] && Y[i] < Y[k])) && i < j) while ((X[i] < X[k] || (lower && X[i] == X[k] && Y[i] < Y[k] && !(k + 1 < X.Count && X[k] == X[k + 1] && Y[k + 1] < Y[k])) || (!lower && X[i] == X[k] && Y[i] > Y[k] && !(k + 1 < X.Count && X[k] == X[k + 1] && Y[k + 1] > Y[k]))) && i < j) - i++; + i++; // it holds X[i - 1] < X[k] <= X[i], particularly X[i] != X[i - 1] // for i < j and X[i - 1] < X[k] it holds X[i - 1] < X[k] <= X[i], particularly X[i] != X[i - 1] // linear interpolation of (x, y) = (X[k], y) on segment (i - 1, i) From 0a9bba6dbd11dc33a0edd3920c3c31efabe0419b Mon Sep 17 00:00:00 2001 From: Matthias Schaefer Date: Fri, 26 Jun 2026 08:26:29 +0200 Subject: [PATCH 14/16] New calculation of reference size: max(mean/2 + height/2, nominalValue) --- .../CurveCompare/TubeSize.cs | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/Modelica_ResultCompare/CurveCompare/TubeSize.cs b/Modelica_ResultCompare/CurveCompare/TubeSize.cs index 41c9510..a2aae40 100644 --- a/Modelica_ResultCompare/CurveCompare/TubeSize.cs +++ b/Modelica_ResultCompare/CurveCompare/TubeSize.cs @@ -14,7 +14,7 @@ namespace CurveCompare /// public class TubeSize { - private double x, y, baseX, baseY, ratio; + private double x, y, baseX, baseY, ratio, mean, width; private Curve reference; bool successful; @@ -81,7 +81,8 @@ public TubeSize(Curve reference, double nominalValue, bool formerBaseAndRatio) if (formerBaseAndRatio) SetFormerBaseAndRatio(nominalValue); else - SetStandardBaseAndRatio(nominalValue); + // SetStandardBaseAndRatio(nominalValue); + SetNewBaseAndRatio(nominalValue); successful = false; } /// @@ -104,6 +105,27 @@ private void SetStandardBaseAndRatio(double nominalValue) else ratio = 0; } + + private void SetNewBaseAndRatio(double nominalValue) + { + // set baseX + baseX = reference.X.Max() - reference.X.Min(); //reference.X.Max() - reference.X.Min() + Math.Abs(reference.X.Min()); + if (baseX == 0) // nonsense case, no data + baseX = Math.Abs(reference.X.Max()); + if (baseX == 0) // nonsense case, no data + baseX = 1; + // set baseY + width = Math.Abs((reference.Y.Max() - reference.Y.Min()) / 2); // half the range/width of the curve in y- direction + mean = Math.Abs((reference.Y.Max() + reference.Y.Min()) / 4); // half the median of the curve in y- direction + + + baseY = Math.Max(width + mean, nominalValue); + // set ratio + if (baseX != 0) + ratio = baseY / baseX; + else + ratio = 0; + } /// /// Calculates former standard values for BaseX , BaseY and Ratio. /// @@ -127,7 +149,7 @@ private void SetFormerBaseAndRatio(double nominalValue) /// Calculation fails, if (Ratio = 0 or BaseX = 0 or BaseY = 0). /// If calculation fails, [set Ratio and BaseX and BaseY != 0] or [call Calculate(double x, double y, Relativity relativity) with parameter Relativity.Absolute] /// Relative value is out of expected range [0,1]. - public void Calculate(double value, Axes axes, Relativity relativity) + public void Calculate(double value, double valueT, Axes axes, Relativity relativity) { successful = false; @@ -138,16 +160,19 @@ public void Calculate(double value, Axes axes, Relativity relativity) if ((value < 0) || (value > 1)) throw new ArgumentOutOfRangeException("Relative value is out of expected range [0,1]."); + if ((valueT < 0) || (valueT > 1)) + throw new ArgumentOutOfRangeException("Relative value is out of expected range [0,1]."); + if (axes == Axes.Y && baseY > 0) { y = value * baseY; - x = y / ratio; + x = valueT * baseX; successful = true; } else if (axes == Axes.X && baseX > 0) { - x = value * baseX; - y = ratio * x; + x = valueT * baseX; + y = value * baseY; successful = true; } } From 606127604302414853ef8d583dcbf8221bd1d3fb Mon Sep 17 00:00:00 2001 From: Matthias Schaefer Date: Fri, 26 Jun 2026 08:31:12 +0200 Subject: [PATCH 15/16] remove identation difference --- .../CurveCompare/Algorithms/Rectangle.cs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs b/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs index d465248..dc842a4 100644 --- a/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs +++ b/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs @@ -105,9 +105,9 @@ private static Curve CalculateLower(Curve reference, TubeSize size) m0 = (reference.Y[b + 1] - reference.Y[b]) / (reference.X[b + 1] - reference.X[b]); else if (s0 > 0) - m0 = Double.PositiveInfinity; - else - m0 = Double.NegativeInfinity; + m0 = Double.PositiveInfinity; + else + m0 = Double.NegativeInfinity; if (s0 == 1) { @@ -131,9 +131,9 @@ private static Curve CalculateLower(Curve reference, TubeSize size) m1 = (reference.Y[i + 1] - reference.Y[i]) / (reference.X[i + 1] - reference.X[i]); else if (s1 > 0) - m1 = Double.PositiveInfinity; - else - m1 = Double.NegativeInfinity; + m1 = Double.PositiveInfinity; + else + m1 = Double.NegativeInfinity; // add no point for equal slopes of reference curve if (!(m0 == m1)) @@ -277,9 +277,9 @@ private static Curve CalculateUpper(Curve reference, TubeSize size) m0 = (reference.Y[b + 1] - reference.Y[b]) / (reference.X[b + 1] - reference.X[b]); else if (s0 > 0) - m0 = Double.PositiveInfinity; - else - m0 = Double.NegativeInfinity; + m0 = Double.PositiveInfinity; + else + m0 = Double.NegativeInfinity; if (s0 == -1) { @@ -303,9 +303,9 @@ private static Curve CalculateUpper(Curve reference, TubeSize size) m1 = (reference.Y[i + 1] - reference.Y[i]) / (reference.X[i + 1] - reference.X[i]); else if (s1 > 0) - m1 = Double.PositiveInfinity; - else - m1 = Double.NegativeInfinity; + m1 = Double.PositiveInfinity; + else + m1 = Double.NegativeInfinity; // add no point for equal slopes of reference curve if (!(m0 == m1)) From ea9a4d2efd1d94306e64d4de3e08bdd4f87c09f0 Mon Sep 17 00:00:00 2001 From: Matthias Schaefer Date: Thu, 16 Jul 2026 12:26:41 +0200 Subject: [PATCH 16/16] Allow CSVComparison for Examples with StopTime=0 --- .../CurveCompare/Algorithms/Rectangle.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs b/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs index dc842a4..f572c99 100644 --- a/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs +++ b/Modelica_ResultCompare/CurveCompare/Algorithms/Rectangle.cs @@ -85,6 +85,10 @@ private static Curve CalculateLower(Curve reference, TubeSize size) // calculate slope at the beginning while (b + 1 < reference.Count && (reference.X[b] - reference.X[b + 1] == 0) && (reference.Y[b] - reference.Y[b + 1] == 0)) b++; + + if (reference.X.Length == b + 1) + b--; + if (reference.X[b + 1] != reference.X[b]) m0 = (reference.Y[b + 1] - reference.Y[b]) / (reference.X[b + 1] - reference.X[b]); else @@ -256,6 +260,9 @@ private static Curve CalculateUpper(Curve reference, TubeSize size) while (b + 1 < reference.Count && (reference.X[b] - reference.X[b + 1] == 0) && (reference.Y[b] - reference.Y[b + 1] == 0)) b++; + if (reference.X.Length == b + 1) + b--; + // calculate slope at the beginning if (reference.X[b + 1] != reference.X[b]) m0 = (reference.Y[b + 1] - reference.Y[b]) / (reference.X[b + 1] - reference.X[b]);