using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.CSV; using Tango.DispenserAnalyzer.UI.Analysis; using Tango.DispenserAnalyzer.UI.Models; namespace Tango.DispenserAnalyzer.UI.Analyzers { [Analyzer("process")] public class ProcessAnalyser : IProcessAnalyzer { private IReader _reader; public IReader Reader { get { return _reader; } set { _reader = value; } } public bool ShowChartAfterProcess { get{ return false; } } public bool AvailableCompareResults { get { return true; } } public ProcessAnalyser() { Reader = new ProcessReader(); } public Task> Process(List csvRows, bool backgroundMode) { return Task.Factory.StartNew>(() => { List results = new List(); ProcessAnalyzerResult result = new ProcessAnalyzerResult(); result.BackgroundMode = backgroundMode; double delta = (double)Settings.GetValueByName(AnalyzerSettingsEnum.TimeInterval); int startPoint = delta == 0? 0 : (int)((double)Settings.GetValueByName(AnalyzerSettingsEnum.StartCalculation) / delta); if (startPoint > csvRows.Count) startPoint = 0; int endPoint = delta == 0 ? (csvRows.Count -1) : (int)((double)Settings.GetValueByName(AnalyzerSettingsEnum.EndCalculation) / delta); int takePoints = endPoint <= csvRows.Count ? (endPoint - startPoint) : (csvRows.Count - 1 - startPoint); List rangeValues = csvRows.Skip(startPoint).Take(takePoints).ToList(); result.MinValue = rangeValues.Min(x => x.Value); result.MaxValue = rangeValues.Max(x => x.Value); result.AverageValue = rangeValues.Average(x => x.Value); result.StandardDeviation = ProcessAnalyser.StdDev(rangeValues.Select(x => x.Value)); result.StandardError = rangeValues.Count > 0 ? (result.StandardDeviation / (Math.Sqrt(rangeValues.Count))) : 0; result.Result = AnalyzerResultValue.Passed; Task.Run(() => { ProcessAnalyser.Filtering(csvRows); }).Wait(); result.CreateMovingAvgGraph(csvRows); results.Add(result); return results; }); } public static double StdDev(IEnumerable values) { double avg = values.Average(); double sum = values.Sum(v => (v - avg) * (v - avg)); double denominator = values.Count() - 1; return denominator > 0.0 ? Math.Sqrt(sum / denominator) : -1; } public static void Filtering(List source) { int periodAverage = (int)((double)Settings.GetValueByName(AnalyzerSettingsEnum.MovingAvg)); int count = source.Count;// (source.Count < periodAverage) ? source.Count : source.Count - periodAverage; for (int i = 0; i < count; i++) { source[i].Value = source.Skip(i).Take(periodAverage).Average(x => x.Value); } } public void GetPoints(List samples, IList points) { samples.ForEach(x => { points.Add(new OxyPlot.DataPoint(x.TimeIntervalSec, x.Value)); }); } } public class ProcessAnalyzerResult : AnalyzerResultBase { [Description("Selected Area")] public string Header { get; set; } [Description("Average Value")] public double AverageValue { get; set; } [Description("Max value")] public double MaxValue { get; set; } [Description("Min value")] public double MinValue { get; set; } [Description("Standard deviation value")] public double StandardDeviation { get; set; } [Description("Standard error value")] public double StandardError { get; set; } public ProcessAnalyzerResult() { double from = (double)Settings.GetValueByName(AnalyzerSettingsEnum.StartCalculation); double to = (double)Settings.GetValueByName(AnalyzerSettingsEnum.EndCalculation); Header = $"from {from} to {to} seconds"; AverageValue = MaxValue = MinValue = 0.0; Result = AnalyzerResultValue.Undetermined; IsShowLineChartResult = true; } public void CreateMovingAvgGraph(List avgValues) { if (!BackgroundMode) { var points = LineChart.Points; points.Clear(); avgValues.ForEach(x => { points.Add(new OxyPlot.DataPoint(x.TimeIntervalSec, x.Value)); }); LineChart.Title = $"Moving Average Values"; LineChart.UpdateData(); } } } }