Example #1
0
        private void AnalyzeFftData(BatCall mergedCall, uint[] fftData, int count)
        {
            byte[] newFftData = new byte[32];

            int fftIndex    = 8;
            int max         = fftData.Length - 7;
            int mergedIndex = 0;

            byte maxValue    = 0;
            int  maxFftIndex = 0;

            while (fftIndex < max)
            {
                uint val = fftData[fftIndex++];
                val += fftData[fftIndex++];
                val += fftData[fftIndex++];
                val += fftData[fftIndex++];
                val += fftData[fftIndex++];
                val += fftData[fftIndex++];
                val += fftData[fftIndex++];
                val += fftData[fftIndex++];
                byte average = (byte)(val / (8 * count));
                if (average > maxValue)
                {
                    maxFftIndex = mergedIndex;
                    maxValue    = average;
                }

                newFftData[mergedIndex++] = average;
            }

            mergedCall.FftData         = newFftData;
            mergedCall.MaxFrequencyBin = maxFftIndex;
        }
 public BatCallViewModel(BatNodeLog log, BatCall batCall, int index)
 {
     Index        = index;
     _log         = log;
     _batCall     = batCall;
     _fftAnalyzer = new FftAnalyzer(2, 5);
 }
Example #3
0
        public BatCall Merge(List <RawCall> rawCalls)
        {
            BatCall mergedCall = new BatCall();
            RawCall firstCall  = rawCalls[0];

            mergedCall.StartTimeMs = firstCall.StartTimeMs;

            mergedCall.ClippedSamples = 0;
            mergedCall.MissedSamples  = 0;

            List <byte> powerData   = new List <byte>();
            ulong       lastEndTime = firstCall.EndTimeMs;

            uint[] tempFftData = new uint[256];
            foreach (RawCall rawCall in rawCalls)
            {
                if (lastEndTime < rawCall.StartTimeMs)
                {
                    int delta = (int)Math.Round((rawCall.StartTimeMs - lastEndTime) / 0.251);
                    powerData.AddRange(Enumerable.Repeat((byte)0, delta));
                }

                powerData.AddRange(rawCall.PowerData);
                lastEndTime = rawCall.EndTimeMs;

                // We currently have a sample rate of 231kHz and a Buffer of 1024.
                // That means we get data from 0Hz to 115.5kHz within 256 buckets.
                // We'll combine 8 buckets together to get a range of about 3.6kHz per Bucket.
                // The fist and the last Bucket are omitted
                ushort[] fftData = rawCall.FftData;

                if (fftData.Length != 256)
                {
                    return(mergedCall);
                }

                for (int i = 0; i < rawCall.FftData.Length; i++)
                {
                    tempFftData[i] += rawCall.FftData[i];
                }

                mergedCall.Duration       += rawCall.Duration;
                mergedCall.ClippedSamples += rawCall.ClippedSamples;
                mergedCall.MissedSamples  += rawCall.MissedSamples;
            }

            AnalyzeFftData(mergedCall, tempFftData, rawCalls.Count);
            mergedCall.PowerData    = powerData.ToArray();
            mergedCall.AveragePower = (byte)Math.Round(mergedCall.PowerData.Where(p => p > 20).DefaultIfEmpty().Average(p => p));
            mergedCall.MergeCount   = rawCalls.Count;

            return(mergedCall);
        }
        public CallModel(BatCall call, BatNodeData data)
        {
            _data = data;
            Call  = call;

            StringBuilder warnings = new StringBuilder();

            if (call.MissedSamples > 0)
            {
                warnings.AppendFormat(CultureInfo.CurrentCulture, "Clipped Samples: {0}\n", call.MissedSamples);
            }
            Warnings = warnings.ToString();

            DateTime startTime = _data.LogStart.AddMilliseconds(call.StartTimeMs);

            Date          = $"{startTime:d}";
            Time          = $"{startTime:HH:mm:ss.ffff}";
            MainFrequency = $"{call.MainFrequency} kHz";
        }
Example #5
0
        public void Analyze(BatProject project, BatNode node, RawNodeData rawNodeData)
        {
            BatNodeData nodeData = node.NodeData;

            node.IsDirty = true;

            node.NodeId   = rawNodeData.NodeId;
            node.LogStart = rawNodeData.LogStart;

            nodeData.Calls.Clear();

            List <RawCall> rawCallsToMerge = new List <RawCall>();
            BatCall        currentCallData = new BatCall();

            nodeData.Calls.Add(currentCallData);
            uint endCallTime = 0;

            foreach (RawCall call in rawNodeData.Calls)
            {
                if (endCallTime + 50 >= call.StartTimeMs || rawCallsToMerge.Count == 0)
                {
                    rawCallsToMerge.Add(call);
                }
                else
                {
                    nodeData.Calls.Add(Merge(rawCallsToMerge));
                    rawCallsToMerge.Clear();
                }

                endCallTime = call.EndTimeMs;
            }

            if (rawCallsToMerge.Count > 0)
            {
                nodeData.Calls.Add(Merge(rawCallsToMerge));
            }
        }
        private void InitPlots(CallModel callModel)
        {
            BatCall call = callModel.Call;

            PlotModel  pmPower       = new PlotModel();
            LineSeries pwrLineSeries = new LineSeries();

            pwrLineSeries.LineJoin = LineJoin.Round;
            pmPower.Series.Add(pwrLineSeries);
            pmPower.Axes.Add(new LinearAxis {
                Maximum = 260, Minimum = 0, Position = AxisPosition.Left, Title = "Intensität"
            });
            pmPower.Axes.Add(new LinearAxis {
                Position = AxisPosition.Bottom, Title = "Dauer [ms]"
            });

            if (call.PowerData != null)
            {
                pwrLineSeries.Points.AddRange(call.PowerData.Select((b, i) => new DataPoint(i * 0.251, b)));
            }

            //if (call.OriginalCalls.Count > 1)
            //{
            //    int leftSum = call.OriginalCalls[0].PowerData.Length;
            //    for (int i = 0; i < call.OriginalCalls.Count-1; i++)
            //    {
            //        int width = (int)Math.Round((call.OriginalCalls[i + 1].StartTimeMs - call.OriginalCalls[i].EndTimeMs) / 0.251);
            //        double left = leftSum* 0.251;
            //        double right = left + (width* 0.251);
            //        RectangleAnnotation annotation = new RectangleAnnotation { Fill = OxyColors.LightGray, Layer = AnnotationLayer.BelowAxes, MinimumX = left, MaximumX = right, MinimumY = 0, MaximumY = 260 };
            //        //LineAnnotation lineAnnotation = new LineAnnotation { Color = OxyColors.Red, StrokeThickness = 2, LineStyle = LineStyle.Dash, Type = LineAnnotationType.Vertical, X = linePos };
            //        pmPower.Annotations.Add(annotation);
            //        leftSum = leftSum + width + call.OriginalCalls[i].PowerData.Length;
            //    }
            //}


            OnlineFilter filter = OnlineFilter.CreateBandstop(ImpulseResponse.Infinite, 20, 20, 150);

            LineSeries pwrLineSeriesAvg = new LineSeries();

            pwrLineSeriesAvg.LineJoin = LineJoin.Round;
            pwrLineSeriesAvg.Color    = OxyColors.Blue;
            pmPower.Series.Add(pwrLineSeriesAvg);

            //double[] input = call.PowerData.Select(d => (double)d).ToArray();
            //double[] data = filter.ProcessSamples(input);
            //pwrLineSeriesAvg.Points.AddRange(data.Select((d, i) => new DataPoint(i * 0.251, d)));

            int[] window  = new int[] { 2, 4, 8, 4, 2 };
            int   divisor = window.Sum();

            byte[] input = call.PowerData;
            for (int i = 0; i < input.Length; i++)
            {
                double sum = 0;
                for (int j = 0; j < 5; j++)
                {
                    int    x = i + (j - 2);
                    double q;
                    if (x < 0)
                    {
                        q = input[0];
                    }
                    else if (x >= input.Length)
                    {
                        q = input[input.Length - 1];
                    }
                    else
                    {
                        q = input[x];
                    }
                    sum += q * window[j];
                }
                pwrLineSeriesAvg.Points.Add(new DataPoint(i * 0.251, sum / divisor));
            }


            LineSeries pwrLineSeriesAvg2 = new LineSeries();

            pwrLineSeriesAvg2.LineJoin = LineJoin.Round;
            pwrLineSeriesAvg2.Color    = OxyColors.Crimson;
            pmPower.Series.Add(pwrLineSeriesAvg2);

            int avgCount = 7;

            int[] ringBuffer  = Enumerable.Repeat(-1, avgCount).ToArray();
            int   bufferIndex = 0;

            for (int i = 0; i < call.PowerData.Length; i++)
            {
                ringBuffer[bufferIndex++] = call.PowerData[i];
                if (bufferIndex >= ringBuffer.Length)
                {
                    bufferIndex = 0;
                }

                if (i > 4)
                {
                    int    c    = 0;
                    double mAvg = 0;
                    for (int j = 0; j < ringBuffer.Length; j++)
                    {
                        if (ringBuffer[j] >= 0)
                        {
                            c++;
                            mAvg += ringBuffer[j];
                        }
                    }
                    pwrLineSeriesAvg2.Points.Add(new DataPoint((i - 4) * 0.251, mAvg / c));
                }
            }


            LineAnnotation lineAnnotation = new LineAnnotation {
                Color = OxyColors.Red, StrokeThickness = 2, LineStyle = LineStyle.Dash, Type = LineAnnotationType.Horizontal, Y = call.AveragePower
            };

            pmPower.Annotations.Add(lineAnnotation);

            Power = pmPower.AddStyles();


            PlotModel    pmFreq     = new PlotModel();
            ColumnSeries freqSeries = new ColumnSeries();

            pmFreq.Series.Add(freqSeries);
            CategoryAxis item = new CategoryAxis();

            item.Position               = AxisPosition.Bottom;
            item.Title                  = "Frequenz [kHz]";
            item.GapWidth               = 0.1;
            item.IsTickCentered         = true;
            item.LabelFormatter         = i => LogAnalyzer.GetFrequencyFromFftBin((int)i).ToString(CultureInfo.CurrentCulture);
            item.MajorGridlineThickness = 0;
            pmFreq.Axes.Add(item);

            if (call.FftData != null)
            {
                freqSeries.Items.AddRange(call.FftData.Select((f, i) =>
                {
                    ColumnItem columnItem = new ColumnItem(f, i);
                    columnItem.Color      = i == call.MaxFrequencyBin ? OxyColors.Red : OxyColors.Green;
                    return(columnItem);
                }));
            }
            Frequency = pmFreq.AddStyles();
        }