NTP Analyzer  0.8.2
Analyze the operation of time servers
HostGraph.cs
Go to the documentation of this file.
1 //
2 // Copyright (c) 2013-2017 Carsten Sonne Larsen <cs@innolan.net>
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 
22 using System;
23 using System.Collections.Generic;
24 using System.Drawing;
25 using System.Globalization;
26 using NPlot;
27 using Ntp.Analyzer.Data;
28 using Ntp.Analyzer.Data.Sql;
29 using Ntp.Analyzer.Interface;
30 using Ntp.Analyzer.Objects;
31 
32 namespace Ntp.Analyzer.Graph
33 {
34  public sealed class HostGraph : DispersionGraph
35  {
36  public HostGraph(IHostGraphConfiguration configuration, Host host)
37  : base(configuration)
38  {
39  config = configuration;
40  this.host = host;
41  frequency = new List<double>();
42  stability = new List<double>();
43  }
44 
45  private readonly IHostGraphConfiguration config;
46  private readonly List<double> frequency;
47  private readonly Host host;
48  private readonly List<double> stability;
49 
50  protected override string YLabel => "Milliseconds";
51 
52  protected override void AddPlots()
53  {
54  base.AddPlots();
55 
56  string freqDesc = config.Gfrequency.HasValue
57  ? " x " + config.Gfrequency.Value.ToString("0.00", CultureInfo.InvariantCulture)
58  : string.Empty;
59 
60  var frequencyPlot = SetupPlot("Frequency" + freqDesc, Color.Green, Time, frequency);
61  var stabilityPlot = SetupPlot("Stability", Color.Black, Time, stability);
62 
63  if (config.Stability.HasValue)
64  Surface.Add(stabilityPlot, PlotSurface2D.XAxisPosition.Bottom, PlotSurface2D.YAxisPosition.Left);
65 
66  if (config.Gfrequency.HasValue)
67  Surface.Add(frequencyPlot, PlotSurface2D.XAxisPosition.Bottom, PlotSurface2D.YAxisPosition.Left);
68  }
69 
70  protected override void LoadData()
71  {
73  dataMapper.FilterHost = host;
74  dataMapper.FilterTime = DateTime.UtcNow.Subtract(GraphTimeSpan);
75 
76  foreach (var reading in dataMapper)
77  {
78  Time.Add(config.GraphTime == DateTimeKind.Local ? reading.LocalTime : reading.UtcTime);
79 
80  if (config.Offset.HasValue) Offset.Add(reading.Offset*config.Offset.Value);
81  else Offset.Add(0.0);
82 
83  if (config.Jitter.HasValue) Jitter.Add(reading.Jitter*config.Jitter.Value);
84  else Jitter.Add(0.0);
85 
86  if (config.Gfrequency.HasValue) frequency.Add(reading.Frequency*config.Gfrequency.Value);
87  else frequency.Add(0.0);
88 
89  if (config.Stability.HasValue) stability.Add(reading.Stability*config.Stability.Value);
90  else stability.Add(0.0);
91  }
92 
93  if (config.FilterFactor.HasValue)
94  CleanSeries();
95  }
96 
100  private void CleanSeries()
101  {
102  double totalOffset = 0.0;
103  double totalJitter = 0.0;
104  double totalFrequency = 0.0;
105  double totalStability = 0.0;
106 
107  // Calculate mean value
108  for (int i = 0; i < Time.Count; i++)
109  {
110  totalOffset += Math.Abs(Offset[i]);
111  totalJitter += Math.Abs(Jitter[i]);
112  totalFrequency += Math.Abs(frequency[i]);
113  totalStability += Math.Abs(stability[i]);
114  }
115 
116  double avgOffset = totalOffset/Time.Count;
117  double avgJitter = totalJitter/Time.Count;
118  double avgFrequency = totalFrequency/Time.Count;
119  double avgStability = totalStability/Time.Count;
120 
121  var indexes = new List<int>();
122 
123  // Find invalid values
124  for (int i = 0; i < Time.Count; i++)
125  {
126  if (Math.Abs(Offset[i]) > avgOffset*config.FilterFactor ||
127  Math.Abs(Jitter[i]) > avgJitter*config.FilterFactor ||
128  Math.Abs(frequency[i]) > avgFrequency*config.FilterFactor ||
129  Math.Abs(stability[i]) > avgStability*config.FilterFactor)
130  {
131  indexes.Add(i);
132  }
133  }
134 
135  // Remove invalid values
136  for (int i = indexes.Count - 1; i >= 0; i--)
137  {
138  Time.RemoveAt(indexes[i]);
139  Offset.RemoveAt(indexes[i]);
140  Jitter.RemoveAt(indexes[i]);
141  frequency.RemoveAt(indexes[i]);
142  stability.RemoveAt(indexes[i]);
143  }
144  }
145  }
146 }
A dispersion graph contains an series of offsets and jitter values together with a time coordinate...
HostGraph(IHostGraphConfiguration configuration, Host host)
Definition: HostGraph.cs:36
DateTime FilterTime
Gets or sets the time to use when extracting data. Only readings with a timestamp later than FilterTi...
HostReadingDatabaseMapper HostReadings
Gets the host reading mapper.
Definition: DataFace.cs:75
readonly List< double > stability
Definition: HostGraph.cs:48
override void LoadData()
Definition: HostGraph.cs:70
override void AddPlots()
Definition: HostGraph.cs:52
Singleton facade class used to access memory persistent data.
Definition: DataFace.cs:30
void CleanSeries()
Cleans the value series from values out side boundaries.
Definition: HostGraph.cs:100
readonly IHostGraphConfiguration config
Definition: HostGraph.cs:45
static DataFace Instance
Gets the Singleton instance.
Definition: DataFace.cs:51
readonly List< double > frequency
Definition: HostGraph.cs:46