aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/ProcessAnalyser.cs
blob: be6a25a77d272823f9a6ef6700df7e6c56eb89ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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<ProcessSample> _reader;
        public IReader<ProcessSample> 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<List<IAnalyzerResult>> Process(List<ProcessSample> csvRows, bool backgroundMode)
        {
            return Task.Factory.StartNew<List<IAnalyzerResult>>(() =>
            {
                List<IAnalyzerResult> results = new List<IAnalyzerResult>();
                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<ProcessSample> 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<double> 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<ProcessSample> 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<ProcessSample> samples, IList<OxyPlot.DataPoint> 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<ProcessSample> 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();
            }
        }

    }
}