using System; using System.Collections.Generic; using System.Linq; using System.Windows.Media; using DTS.Common.Enums.Sensors; using DTS.Common.Interface; using DTS.Common.Strings; // ReSharper disable UnassignedGetOnlyAutoProperty namespace DTS.Viewer.Graph.Model { public class TestDataSeries : Common.Base.BasePropertyChanged, ITestDataSeries { private bool _HIC = false; public bool HIC { get => _HIC; set => SetProperty(ref _HIC, value, "HIC"); } private string _hicValue; public string HICValue { get => _hicValue; set => SetProperty(ref _hicValue, value, "HICValue"); } private string _T1Time; public string T1Time { get => _T1Time; set => SetProperty(ref _T1Time, value, "T1Time"); } private string _T2Time; public string T2Time { get => _T2Time; set => SetProperty(ref _T2Time, value, "T2Time"); } private string _testGroup = string.Empty; public string TestGroup { get => _testGroup; set => SetProperty(ref _testGroup, value, "TestGroup"); } private string _testId = string.Empty; public string TestId { get => _testId; set => SetProperty(ref _testId, value, "TestId"); } private string _testSetupName = string.Empty; public string TestSetupName { get => _testSetupName; set => SetProperty(ref _testSetupName, value, "TestSetupName"); } private string _channelId = string.Empty; public string ChannelId { get => _channelId; set => SetProperty(ref _channelId, value, "ChannelId"); } private double[] _x = new double[0]; public double[] Xvalue { get => _x; set => SetProperty(ref _x, value, "X"); } private double[] _y = new double[0]; public double[] Yvalue { get => _y; set => SetProperty(ref _y, value, "Y"); } // 34455: Move from Brush to byte[] to make it thread-safe private byte[] _graphColorARGB = new byte[] { Colors.Blue.A, Colors.Blue.R, Colors.Blue.G, Colors.Blue.B }; public Brush GraphColor { get => new SolidColorBrush(Color.FromArgb(_graphColorARGB[0], _graphColorARGB[1], _graphColorARGB[2], _graphColorARGB[3])); set { var valueColor = ((SolidColorBrush)value).Color; var colorValues = new byte[] { valueColor.A, valueColor.R, valueColor.G, valueColor.B }; SetProperty(ref _graphColorARGB, colorValues, "GraphColor"); } } public bool IsSaved { get; } public string HardwareChannel { get; set; } public string GroupName { get; set; } public string SWAAF { get; set; } public string Bridge { get; set; } public string HWAAF { get; set; } public string SampleRate { get; set; } public string ISOCode { get; set; } public string ISOChannelName { get; set; } public string UserCode { get; set; } public string UserChannelName { get; set; } public string ChannelName { get; set; } public string Description { get; set; } public string SensorSN { get; set; } public string SensorSNDisplay { get => SensorConstants.IsTestSpecificEmbedded(SensorSN) ? Strings.Table_NA : SensorSN; } public string EngineeringUnits { get; set; } public string Excitation { get; set; } public string Polarity { get; set; } private string _minY = Strings.Table_NA; public string MinY { get => _minY; set => SetProperty(ref _minY, value, "MinY"); } private string _maxY = Strings.Table_NA; public string MaxY { get => _maxY; set => SetProperty(ref _maxY, value, "MaxY"); } private string _avgY = Strings.Table_NA; public string AvgY { get => _avgY; set => SetProperty(ref _avgY, value, "AvgY"); } private string _stdDevY; public string StdDevY { get => _stdDevY; set => SetProperty(ref _stdDevY, value, "StdDevY"); } private double _peakMagnitude = 0; /// /// holds the peak magnitude of frequencies in signal /// only valid when FFT true /// 6402 Implement ability to switch to FFT live in the Review /// public double PeakMagnitude { get => _peakMagnitude; set => SetProperty(ref _peakMagnitude, value, "PeakMagnitude"); } private double _peakFrequency = 0; /// /// holds the frequency of the highest magnitude in signal /// only valid when FFT true /// 6402 Implement ability to switch to FFT live in the Review /// public double PeakFrequency { get => _peakFrequency; set => SetProperty(ref _peakFrequency, value, "PeakFrequency"); } private double _grms = 0; /// /// holds the root-mean-squared acceleration /// only calculated in PSD results graphs /// public double GRMS { get => _grms; set => SetProperty(ref _grms, value, "GRMS"); } private bool _fft = false; /// /// holds whether series is an FFT of signal data /// 6402 Implement ability to switch to FFT live in the Review /// public bool FFT { get => _fft; set => SetProperty(ref _fft, value, "FFT"); } private string _T0EUValue = ""; /// /// this is the T0 value regardless of units ... it's not really EU but since it's already in use I'm not going to change it /// public string T0EUValue { get => _T0EUValue; set => SetProperty(ref _T0EUValue, value, "T0EUValue"); } private double CalculateStdDev(double[] values) { double ret = 0; if (!values.Any()) return ret; //Compute the Average var avg = values.Average(); //Perform the Sum of (value-avg)_2_2 var sum = values.Sum(d => Math.Pow(d - avg, 2)); //Put it all together ret = Math.Sqrt(sum / (values.Length - 1)); return ret; } private const string STAT_FORMAT = "G5"; /// /// sets Ave/StdDev/Min/MaxT0 stats using internal YValues (something like PSD or FFT) /// public void SetStatsFromYValues() { SetStatsFromYValues(Yvalue); } /// /// sets Ave/StdDev/Min/Max/T0 stats using the passed in input range (something like PSD or FFT) /// /// public void SetStatsFromYValues(double[] values) { if (null == values || 0 == values.Length) { SetStatsFromYValues(double.NaN, double.NaN, double.NaN, double.NaN, double.NaN); } else { SetStatsFromYValues(values.Min(), values.Max(), values.Average(), CalculateStdDev(values), double.NaN); } } /// /// formats and sets the current unit stats /// /// /// /// /// /// private void SetStatsFromYValues(double min, double max, double ave, double stdDev, double t0Value) { StdDevY = double.IsNaN(stdDev) ? Strings.Table_NA : stdDev.ToString(STAT_FORMAT); AvgY = double.IsNaN(ave) ? Strings.Table_NA : ave.ToString(STAT_FORMAT); MinY = double.IsNaN(min) ? Strings.Table_NA : min.ToString(STAT_FORMAT); MaxY = double.IsNaN(max) ? Strings.Table_NA : max.ToString(STAT_FORMAT); T0EUValue = double.IsNaN(t0Value) ? Strings.Table_NA : t0Value.ToString(STAT_FORMAT); } /// /// sets stats (ave/min/max) using values from passed in channel where it was already calculated when reading data /// /// public void SetStatsFromChannel(ITestChannel channel) { SetStatsFromYValues(channel.MinY, channel.MaxY, channel.AveY, channel.StdDevY, channel.T0Value); } public string RecordingMode { get; set; } } }