示例#1
0
        private void PrepareCharts(Curve reference, Curve compare, Curve error, Report rep, TubeReport tubeReport, KeyValuePair<string, List<double>> res, bool bDrawBitmapPlots)
        {
            Chart ch = new Chart()
            {
                LabelX = "Time",
                LabelY = res.Key,
                Errors = (null != error && null != error.X) ? error.X.Length : 0,
                Title = string.Format("{0}.{1}", Path.GetFileNameWithoutExtension(this._fileName), res.Key),
                UseBitmap = bDrawBitmapPlots
            };

            if (null != compare)
            {
                ch.Series.Add(new Series()
                {
                    Color = Color.Orange,
                    ArrayString = (bDrawBitmapPlots) ? string.Empty : Series.GetArrayString(reference.X, reference.Y),
                    Title = "Base (to compare with)",
                    XAxis = (bDrawBitmapPlots) ? reference.X : null,
                    YAxis = (bDrawBitmapPlots) ? reference.Y : null
                });

                ch.Series.Add(new Series()
                {
                    Color = Color.Green,
                    ArrayString = (bDrawBitmapPlots) ? string.Empty : Series.GetArrayString(compare.X, compare.Y),
                    Title = "Result",
                    XAxis = (bDrawBitmapPlots) ? compare.X : null,
                    YAxis = (bDrawBitmapPlots) ? compare.Y : null
                });
                ch.Series.Add(new Series()
                {
                    Color = Color.LightBlue,
                    ArrayString = (bDrawBitmapPlots) ? string.Empty : Series.GetArrayString(tubeReport.Lower.X, tubeReport.Lower.Y),
                    Title = "Low Tube",
                    XAxis = (bDrawBitmapPlots) ? tubeReport.Lower.X : null,
                    YAxis = (bDrawBitmapPlots) ? tubeReport.Lower.Y : null
                });
                ch.Series.Add(new Series()
                {
                    Color = Color.LightGreen,
                    ArrayString = (bDrawBitmapPlots) ? string.Empty : Series.GetArrayString(tubeReport.Upper.X, tubeReport.Upper.Y),
                    Title = "High Tube",
                    XAxis = (bDrawBitmapPlots) ? tubeReport.Upper.X : null,
                    YAxis = (bDrawBitmapPlots) ? tubeReport.Upper.Y : null
                });
            }
            else
            {
                ch.Series.Add(new Series()
                {
                    Color = Color.Green,
                    ArrayString = (bDrawBitmapPlots) ? string.Empty : Series.GetArrayString(reference.X, reference.Y),
                    Title = "Compare",
                    XAxis = (bDrawBitmapPlots) ? reference.X : null,
                    YAxis = (bDrawBitmapPlots) ? reference.Y : null
                });
            }
            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]);
                int j = 0;
                for (int i = 0; i < compare.X.Length - 1; i++)
                {
                    if (error.X.Contains(compare.X[i]))
                    {
                        curveErrors.X[i] = compare.X[i];
                        curveErrors.Y[i] = (this._bShowRelativeErrors) ? error.Y[j++] : 1;
                    }
                    else
                    {
                        curveErrors.X[i] = compare.X[i];
                        curveErrors.Y[i] = 0;
                    }
                }

                ch.Series.Add(new Series()
                {
                    Color = Color.Red,
                    ArrayString = (bDrawBitmapPlots) ? string.Empty : Series.GetArrayString(curveErrors.X, curveErrors.Y),
                    Title = curveErrors.Name,
                    XAxis = (bDrawBitmapPlots) ? error.X : null,
                    YAxis = (bDrawBitmapPlots) ? error.Y : null
                });

                //Calculate delta error
                List<double> lDeltas = new List<double>();
                j = 0;
                for (int i = 1; i < compare.X.Length - 1; i++)
                {
                    if (j < error.X.Length)
                    {
                        while (compare.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);
                        else // handle errors in the last point (ther is no i+1)
                            lDeltas.Add((Math.Abs(error.Y[j]) * ((Math.Abs(compare.X[i] - compare.X[i - 1])))) / 2);
                        j++;
                    }
                }
                ch.DeltaError = lDeltas.Sum() / (1e-3 + compare.Y.Max(x => Math.Abs(x)));
            }
            if (tubeReport.Lower.X.ToList<double>().Count > 2)//Remember Start and Stop values for graph scaling
            {
                ch.MinValue = tubeReport.Lower.X[0];
                ch.MaxValue = tubeReport.Lower.X.Last();
            }
            rep.Chart.Add(ch);
        }
示例#2
0
        public Report PlotCsvFile(string sReportPath, Log log)
        {
            Report r = new Report(sReportPath);
            log.WriteLine("Generating plot for report");

            foreach (KeyValuePair<string, List<double>> res in _values)
            {
                Curve compare = new Curve(res.Key, this.XAxis.ToArray<double>(), res.Value.ToArray<double>());
                PrepareCharts(r, compare);
            }

            return r;
        }
示例#3
0
 //Draw result only
 private void PrepareCharts(Report rep, Curve compare)
 {
     PrepareCharts(compare, null, null, rep, null, new KeyValuePair<string, List<double>>(), false);
 }
示例#4
0
        /// <summary>
        /// Adds a set of points to chart. Draws lines between the points.
        /// </summary>
        /// <param name="name">Name, visible in legend.</param>
        /// <param name="curve">Curve with x and y values of points.</param>
        /// <param name="color">Color.</param>
        public void AddLine(string name, Curve curve, Color color)
        {
            if (curve == null)
                return;

            AddLine(name, curve.X, curve.Y, color);
        }
示例#5
0
        public Report CompareFiles(Log log, CsvFile csvBase, string sReportPath, ref Options options)
        {
            int iInvalids = 0;

            Report rep = new Report(sReportPath);
            log.WriteLine("Comparing \"{0}\" to \"{1}\"", _fileName, csvBase.ToString());

            rep.BaseFile = csvBase.ToString();
            rep.CompareFile = _fileName;

            Curve reference = new Curve();
            Curve compareCurve = new Curve();
            TubeReport tubeReport = new TubeReport();
            TubeSize size = null;
            Tube tube = new Tube(size);
            IOptions tubeOptions = new Options1(_dRangeDelta, Axes.X);

            foreach (KeyValuePair<string, List<double>> res in csvBase.Results)
            {
                if (!this.Results.ContainsKey(res.Key))
                    log.WriteLine(LogLevel.Warning, "{0} not found in \"{1}\", skipping checks.", res.Key, this._fileName);
                else
                {
                    compareCurve = new Curve(res.Key, this.XAxis.ToArray<double>(), this.Results[res.Key].ToArray<double>());

                    if (res.Value.Count == 0)
                    {
                        log.Error("{0} has no y-Values! Maybe error during parsing? Skipping", res.Key);
                        continue;
                    }
                    reference = new Curve("Reference ", csvBase.XAxis.ToArray(), csvBase.Results[res.Key].ToArray());
                    if (!reference.ImportSuccessful)
                    {
                        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)
                        log.WriteLine(LogLevel.Warning, "The resolution of the base x-axis is smaller than the compare x-axis. The better the base resolution is, the better the validation result will be!");
                    else
                        log.WriteLine(LogLevel.Debug, "The resolution of the base x-axis is good.");

                    size = new TubeSize(reference, true);
                    size.Calculate(_dRangeDelta, Axes.X, Relativity.Relative);
                    tube = new Tube(size);
                    tubeReport = tube.Calculate(reference);
                    tube.Validate(compareCurve);

                    if (tubeReport.Valid == Validity.Valid)
                        log.WriteLine(res.Key + " is valid");
                    else
                    {
                        log.WriteLine(LogLevel.Warning, "{0} is invalid! {1} errors have been found during validation.", res.Key,
                            (null != tube.Report.Errors && null != tube.Report.Errors.X) ? tube.Report.Errors.X.Length : 0);
                        iInvalids++;
                        Environment.ExitCode = 1;
                    }
                }
                if (null != tube.Report)//No charts for missing reports
                    PrepareCharts(reference, compareCurve, tube.Report.Errors, rep, tubeReport, res, options.UseBitmapPlots);
            }
            rep.Tolerance = _dRangeDelta;

            string sResult = "na";

            if (rep.TotalErrors == 0)
                sResult = "passed";
            else
                sResult = "failed";

            if (options.ComparisonFlag)
                using (TextWriter writer = File.CreateText(string.Format("{0}{1}compare_{2}.log", Path.GetDirectoryName(_fileName), Path.DirectorySeparatorChar, sResult)))
                {
                    //Content needs to be defined
                    writer.WriteLine("CSV Compare Version {0} ({1})", Info.AssemblyVersion, Assembly.GetExecutingAssembly().GetName().ProcessorArchitecture);
                    writer.WriteLine("Comparison result file for {0}", _fileName);
                    writer.WriteLine(". Time:        {0:o}", DateTime.Now);
                    writer.WriteLine(". Operation:   {0}", options.Mode);
                    writer.WriteLine(". Tolerance:   {0}", options.Tolerance);
                    writer.WriteLine(". Result:      {0}", sResult);

                    if (rep.TotalErrors > 0)
                    {
                        Chart pairMax = rep.Chart.Aggregate((l, r) => l.DeltaError > r.DeltaError ? l : r);
                        writer.WriteLine(". Biggest error: {0}=>{1}", pairMax.Title, pairMax.DeltaError);
                        writer.WriteLine(". Failed values:");

                        foreach (Chart c in (from r in rep.Chart where r.DeltaError > 0 select r).OrderByDescending(er => er.DeltaError))
                            writer.WriteLine("{0}=>{1}", c.Title, c.DeltaError);
                    }
                }

            rep.WriteReport(log, (!string.IsNullOrEmpty(options.ReportDir)) ? options.ReportDir : string.Empty, options);
            GC.Collect();//immediately forget big charts and data
            return rep;
        }
示例#6
0
        /// <summary>
        /// Adds a set of points to the error chart area.
        /// </summary>
        /// <param name="name">Name, visible in legend.</param>
        /// <param name="errors">Error points, x and y values.</param>
        public void AddErrors(string name, Curve errors)
        {
            if (errors == null)
                return;

            AddErrors(name, errors.X, errors.Y);
        }
示例#7
0
        /// <summary>
        /// Compares a test curve with a reference curve. Calculates a tube, if test curve data == null.
        /// </summary>
        /// <param name="modelName">Model name.</param>
        /// <param name="resultName">Result name.</param>
        /// <param name="referenceX">x values of reference curve.</param>
        /// <param name="referenceY">y values of reference curve.</param>
        /// <param name="testX">x values of test curve.</param>
        /// <param name="testY">y values of test curve.</param>
        /// <param name="options">Options for calculation of tube size, chart and saving.</param>
        /// <returns>Tube report.</returns>
        public TubeReport Validate(string modelName, string resultName, double[] referenceX, double[] referenceY, double[] testX, double[] testY, IOptions options)
        {
            TubeReport report = new TubeReport();
            Curve refCurve, testCurve;
            bool testExists = (testX != null && testY != null && testX.Length > 0 && testY.Length > 0);
            #if GUI
            bool saveImage = (!String.IsNullOrWhiteSpace(options.ReportFolder) && Directory.Exists(options.ReportFolder));
            #endif
            string name = modelName + " - " + resultName;

            // write log file
            if (options.Log != null)
            {
                options.Log.WriteLine(LogLevel.Done, "----------------------------------------------");
                options.Log.WriteLine(LogLevel.Done, "Model: " + modelName);
                options.Log.WriteLine(LogLevel.Done, "Result: " + resultName);
            }

            if (referenceX != null && referenceY != null && referenceX.Length != 0 && referenceY.Length != 0)
            {
                // Data import: Prepare curve data
                refCurve = new Curve("Reference " + name, referenceX, referenceY);

                if (testExists)
                    testCurve = new Curve("Test " + name, testX, testY);
                else
                    testCurve = new Curve();

                if (refCurve.ImportSuccessful && (testCurve.ImportSuccessful || !testExists))
                {
                    // Calculate tube size
                    TubeSize size = new TubeSize(refCurve);

                    if (!Double.IsNaN(options.BaseX)) // overwrite BaseX just in case it has got a value
                        size.BaseX = options.BaseX;
                    if (!Double.IsNaN(options.BaseY))
                        size.BaseY = options.BaseY;
                    if (!Double.IsNaN(options.Ratio))
                        size.Ratio = options.Ratio;

                    if (options is Options1)
                        size.Calculate(((Options1)options).Value, ((Options1)options).Axes, options.Relativity);
                    else if (options is Options2)
                        size.Calculate(((Options2)options).X, ((Options2)options).Y, options.Relativity);

                    if (size.Successful)
                    {
                        // Calculate tube
                        Tube tube = new Tube(size);
                        tube.AlgorithmOption = Algorithms.AlgorithmOptions.Rectangle;
                        report = tube.Calculate(refCurve);

                        if (tube.TubeSuccessful)
                        {
                            if (testExists)
                            {
                                // Validation
                                report = tube.Validate(testCurve);

                                if (options.Log != null)
                                {
                                    options.Log.WriteLine(LogLevel.Done, "Test curve is " + report.Valid.ToString());
                                    options.Log.WriteLine(LogLevel.Done, "Errors (points of test curve outside tube): " + report.Errors.Count.ToString());
                                }

                                if (tube.ValidationSuccessful)
                                    report.ErrorStep = Step.None;

                                // Error: Validation not successful
                                else
                                {
                                    report.ErrorStep = Step.Validation;
                                    report.Valid = Validity.Undefined;
                                    if (options.Log != null)
                                        options.Log.WriteLine(LogLevel.Error, "Validation not successful.");
                                }
                            }
                            else
                            {
                                report.ErrorStep = Step.Validation;
                                report.Valid = Validity.Undefined;
                                if (options.Log != null)
                                    options.Log.WriteLine(LogLevel.Error, "no test curve data.");
                            }

            #if GUI
                            // Visualization
                            if (saveImage || options.ShowWindow)
                            {
                                ChartControl chartControl = new ChartControl(options.DrawFastAbove, options.DrawPointsBelow, options.DrawLabelNumber);
                                chartControl.addTitle("Tube size: (" + size.X + "; " + size.Y + ")");
                                chartControl.AddLine(refCurve.Name, refCurve, Color.FromKnownColor(KnownColor.OrangeRed));
                                chartControl.AddLine("Upper", report.Upper, Color.FromKnownColor(KnownColor.MediumSpringGreen));
                                chartControl.AddLine("Lower", report.Lower, Color.FromKnownColor(KnownColor.DeepSkyBlue));

                                if (testExists)
                                {
                                    string valid = "";
                                    if (report.Valid == Validity.Valid)
                                        valid = "valid";
                                    else if (report.Valid == Validity.Invalid)
                                        valid = "invalid";
                                    chartControl.AddLine("Test: " + valid, testCurve, Color.FromKnownColor(KnownColor.BlueViolet));
                                    chartControl.AddErrors("Errors " + name, report.Errors);
                                }

                                // Visualization: save image
                                if (saveImage)
                                    chartControl.saveAsImage(options.ReportFolder + resultName + ".png", System.Drawing.Imaging.ImageFormat.Png);

                                // Visualization: show window with MS Chart Control
                                if (options.ShowWindow)
                                    if (!testExists || (options.ShowValidity == Validity.All || (options.ShowValidity == Validity.Invalid && report.Valid == Validity.Invalid) || (options.ShowValidity == Validity.Valid && report.Valid == Validity.Valid)))
                                        Application.Run(chartControl);

                            }
            #endif
                        }
                        // Error: tube calculation not successful
                        else
                        {
                            report.ErrorStep = Step.Tube;
                            report.Valid = Validity.Undefined;

                            if (options.Log != null)
                                options.Log.WriteLine(LogLevel.Error, "Tube calculation not successful.");
                        }

                        if (options.Log != null)
                        {
                            options.Log.WriteLine(LogLevel.Done, "Tube calculation algorithm: " + tube.AlgorithmOption.ToString());
                        }
                    }
                    // Error: tube size calculation not successful
                    else
                    {
                        report.ErrorStep = Step.TubeSize;
                        report.Valid = Validity.Undefined;

                        if (options.Log != null)
                        {
                            options.Log.WriteLine(LogLevel.Error, "TubeSize calculation not successful.");
                            options.Log.WriteLine(LogLevel.Error, "TubeSize.Ratio: " + size.Ratio);
                            options.Log.WriteLine(LogLevel.Error, "TubeSize.BaseX: " + size.BaseX);
                            options.Log.WriteLine(LogLevel.Error, "TubeSize.BaseY: " + size.BaseY);
                        }
                    }
                    report.Size = size;
                }
                // Error: data import not successful
                else
                {
                    report.ErrorStep = Step.DataImport;
                    report.Valid = Validity.Undefined;

                    if (options.Log != null)
                    {
                        if (!refCurve.ImportSuccessful)
                            options.Log.WriteLine(LogLevel.Error, "Reference curve: Import not successful.");
                        if (testExists && !testCurve.ImportSuccessful)
                            options.Log.WriteLine(LogLevel.Error, "Test curve: Import not successful.");
                    }
                }
                report.Reference = refCurve;
                report.Test = testCurve;
            }
            // Error: no data
            else
            {
                report.ErrorStep = Step.DataImport;
                report.Valid = Validity.Undefined;

                if (options.Log != null)
                {
                    if (referenceX != null || referenceX.Length != 0)
                        options.Log.WriteLine(LogLevel.Error, "Reference curve: Missing data.");
                    if (referenceY!= null || referenceY.Length != 0)
                        options.Log.WriteLine(LogLevel.Error, "Test curve: Missing data.");
                }
            }

            report.ModelName = modelName;
            report.ResultName = resultName;
            return report;
        }
示例#8
0
        /// <summary>
        /// Compares with tube
        /// </summary>
        /// <param name="lower">Lower tube curve values.</param>
        /// <param name="upper">Upper tube curve values.</param>
        /// <param name="test">Compare curve values.</param>
        /// <param name="time">Time values.</param>
        /// <param name="Errors">Errors.</param>
        /// <returns>Number of Errors.</returns>
        private static bool Compare(double[] lower, double[] upper, double[] test, double[] time, out int errorCount, out Curve errors)
        {
            // --------------------------------------------------------------------------------------------------------------------------------
            // ------------------------------------ Copy and modified from CsvCompare.Range.Validate ------------------------------------------
            // --------------------------------------------------------------------------------------------------------------------------------

            bool successful = true;
            double[] X, Y;
            List<double> errorsTime = new List<double>(time.Length);
            List<double> errorsDif = new List<double>(time.Length);
            errorCount = 0;

            for (int i = 0; i < test.Length && i < upper.Length && i < lower.Length; i++)
            {
                if (test[i] < lower[i] || test[i] > upper[i])
                {
                    errorCount++;
                    try
                    {
                        if (test[i] < lower[i])
                        {
                            errorsTime.Add(time[i]);
                            errorsDif.Add(Math.Abs(lower[i] - test[i]));
                        }
                        else
                        {
                            errorsTime.Add(time[i]);
                            errorsDif.Add(Math.Abs(upper[i] - test[i]));
                        }
                    }
                    catch (Exception)
                    {
                        errorsTime.Add(time[i]);
                        errorsDif.Add(1);
                        successful = false;
                    } // should never happen, just in case something goes wrong
                }
            }
            X = errorsTime.ToArray();
            Y = errorsDif.ToArray();
            errors = new Curve("Errors", X, Y);
            return successful;
        }
示例#9
0
        /// <summary>
        /// Validates if compare is inside the tube.
        /// </summary>
        /// <param name="test">Curve, that shall be compared with the reference curve.</param>
        /// <returns>TubeReport: Data about tube calculation and comparison.</returns>
        /// <remarks>Requirement: CalculateTube() must be called before.</remarks>
        public TubeReport Validate(Curve test)
        {
            if (report == null)
                return (new TubeReport());
            if (test != null && report.Lower != null && report.Upper != null && test.ImportSuccessful && report.Lower.ImportSuccessful && report.Upper.ImportSuccessful)
            {
                double[] newLower = InterpolateValues(report.Lower.X, report.Lower.Y, test.X);
                double[] newUpper = InterpolateValues(report.Upper.X, report.Upper.Y, test.X);
                Curve errors;
                int errorCount;

                report.Test = test;
                validationSuccessful = Compare(newLower, newUpper, test.Y, test.X, out errorCount, out errors);
                report.Errors = errors;

                if (validationSuccessful)
                {
                    if (report.Errors.Count == 0)
                        report.Valid = Validity.Valid;
                    else
                        report.Valid = Validity.Invalid;
                }
                // Error: validation not successful
                else
                    report.Valid = Validity.Undefined;
            }
            // Error: no data
            else
            {
                validationSuccessful = false;
                report.Valid = Validity.Undefined;
            }

            return report;
        }
示例#10
0
 /// <summary>
 /// Calculates the Tube, that consists of 2 Curves: Lower and Upper.
 /// </summary>
 /// <param name="reference">Reference curve.</param>
 /// <returns>true, if tube calculation successful;
 /// false, elsewise.</returns>
 public TubeReport Calculate(Curve reference)
 {
     if (chooseAlgorithm())
     {
         report = algorithm.Calculate(reference, size);
         tubeSuccessful = algorithm.Successful;
     }
     else
     {
         report = new TubeReport();
         tubeSuccessful = false;
     }
     return report;
 }