Пример #1
0
        /****************************************************************************
        *  TrimFFT
        *  Trim FFT array prior to Lorentzian fitting based on user specifications
        ****************************************************************************/
        public FFTData TrimFFT(FFTData fftData, LorentzSettings lorentzSettings)
        {
            FFTData fftTrimData = new FFTData();

            int startIndex = Array.FindIndex(fftData.freq, x => x >= lorentzSettings.trimStartFreq);
            int stopIndex  = Array.FindIndex(fftData.freq, x => x >= lorentzSettings.trimStopFreq);

            fftTrimData.fft  = fftData.fft.ToList().Skip(startIndex + 1).Take(stopIndex - startIndex).ToArray();
            fftTrimData.freq = fftData.freq.ToList().ToList().Skip(startIndex + 1).Take(stopIndex - startIndex).ToArray();

            return(fftTrimData);
        }
Пример #2
0
 public SpectrumDisplay()
 {
     this.GetObservable(FFTDataProperty)
     .Throttle(TimeSpan.FromMilliseconds(250))
     .ObserveOn(RxApp.MainThreadScheduler)
     .Subscribe(x =>
     {
         if (FFTData != null)
         {
             FFTData = new double[FFTData.GetLength(0), FFTData.GetLength(1)];
         }
     });
 }
Пример #3
0
        /// <summary>
        /// Updates the plugin
        /// </summary>
        public override void Refresh()
        {
            // paint red linestrip
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();

            // size
            float width  = 100;
            float height = 100;

            // margins
            float bottom = 10;
            float top    = 10;
            float left   = 10;
            float right  = 10;

            float size = 1024;

            if ((System.Boolean)showSecondLine.Value)
            {
                float[] rev = FFTData.Reverse().ToArray <float>();
                GL.Color3((Color)colorSecondLine.Value);
                GL.Begin(BeginMode.LineStrip);
                for (int i = 0; i < rev.Length; i++)
                {
                    float p = rev[i];
                    float w = width - left - right;
                    float h = height - top - bottom;
                    float x = left + (i * w / size);
                    float y = bottom + (p * h * (float)Math.Sqrt(size - i));
                    GL.Vertex2(x, y);
                }
                GL.End();
            }

            GL.Color3((Color)colorFirstLine.Value);
            GL.Begin(BeginMode.LineStrip);
            for (int i = 0; i < FFTData.Length; i++)
            {
                float p = FFTData[i];
                float w = width - left - right;
                float h = height - top - bottom;
                float x = left + (i * w / size);
                float e = (float)0.5 + ((float)1.5 * (i / size));
                float y = bottom + (p * h * (float)Math.Sqrt(i));
                GL.Vertex2(x, y);
            }
            GL.End();
        }
Пример #4
0
 /// <summary>
 /// Calculate and render the display update rate of the scope view.
 /// </summary>
 private void RenderFftStats(FFTData data)
 {
     if (DateTime.Now.Subtract(_lastFftRenderTime).TotalMilliseconds > 200)
     {
         if (data != null)
         {
             lblFFTResolution.Text = "Resolution: " + data.ResolutionBandWith.ToString("F0") + "Hz";
             lblFFTFrequency.Text  = "Base frequency: " + data.BaseFrequency.ToString("F0") + "Hz";
         }
         else
         {
             lblFFTResolution.Text = "Resolution: ?";
             lblFFTFrequency.Text  = "Base frequency: ?";
         }
         _lastFftRenderTime = DateTime.Now;
     }
 }
Пример #5
0
        void RenderFFTData(FFTData data)
        {
            try
            {
                spectrum.Series.RemoveAt(0);
                spectrum.Series.Add("Series1");
                spectrum.Series["Series1"].ChartArea  = "ChartArea1";
                spectrum.Series["Series1"].ChartType  = SeriesChartType.Line;
                spectrum.Series["Series1"].MarkerSize = 1;

                if (data != null)
                {
                    double[] yPoints = rbDbm.Checked ? data.FreqDomain : data.Vrms;
                    double[] xPoints = Enumerable.Range(0, yPoints.Count()).Select(s => s * (double)data.SamplesPerSecond / data.FreqDomain.Length / 2).ToArray();

                    spectrum.ChartAreas["ChartArea1"].CursorX.Interval = data.SamplesPerSecond / (double)data.FreqDomain.Length / 2.0;        //matches cursor step size to X axis step size
                    spectrum.Series["Series1"].Points.DataBindXY(xPoints, yPoints);
                }
                RenderFftStats(data);
            }
            catch (Exception) { }
        }
Пример #6
0
        // LORENTZIAN FITTING //

        /****************************************************************************
        *  GetLorentzParams
        *  Get lorentzian fitting parameters
        ****************************************************************************/
        public void GetLorentzParams(FFTData fftData, LorentzSettings lorentzSettings, ref LorentzParams lorentzParams)
        {
            double[][] dataPoints = new double[][] { fftData.freq, fftData.fft };


            LMA algorithm;

            if (lorentzSettings.isYShiftLorentz)
            {
                LMAFunction lorentzShift = new LorenzianFunctionShift();

                double[] startPoint = new double[4];

                try
                {
                    startPoint[0] = lorentzSettings.startPointLP.A;
                }
                catch (Exception)
                {
                    startPoint[0] = 10;
                }

                try
                {
                    startPoint[1] = lorentzSettings.startPointLP.f0;
                }
                catch (Exception)
                {
                    startPoint[1] = 25;
                }

                try
                {
                    startPoint[2] = lorentzSettings.startPointLP.gamma;
                }
                catch (Exception)
                {
                    startPoint[2] = 1;
                }

                try
                {
                    startPoint[3] = lorentzSettings.startPointLP.up;
                }
                catch (Exception)
                {
                    startPoint[3] = 1;
                }



                algorithm = new LMA(lorentzShift, startPoint,
                                    dataPoints, null, new GeneralMatrix(4, 4), 1d - 20, lorentzSettings.nIter);

                algorithm.Fit();

                lorentzParams.A     = algorithm.Parameters[0];
                lorentzParams.gamma = algorithm.Parameters[2];
                lorentzParams.f0    = algorithm.Parameters[1];
                lorentzParams.up    = algorithm.Parameters[3];
            }
            else
            {
                LMAFunction lorentz = new LorenzianFunction();

                double[] startPoint = new double[3];

                try
                {
                    startPoint[0] = lorentzSettings.startPointLP.A;
                }
                catch (Exception)
                {
                    startPoint[0] = 10;
                }

                try
                {
                    startPoint[1] = lorentzSettings.startPointLP.f0;
                }
                catch (Exception)
                {
                    startPoint[1] = 25;
                }

                try
                {
                    startPoint[2] = lorentzSettings.startPointLP.gamma;
                }
                catch (Exception)
                {
                    startPoint[2] = 1;
                }

                algorithm = new LMA(lorentz, startPoint,
                                    dataPoints, null, new GeneralMatrix(3, 3), 1d - 20, lorentzSettings.nIter);

                algorithm.Fit();

                lorentzParams.A     = algorithm.Parameters[0];
                lorentzParams.gamma = algorithm.Parameters[2];
                lorentzParams.f0    = algorithm.Parameters[1];
                lorentzParams.up    = 0;
            }
        }
Пример #7
0
        // FFT CALCULATIONS //

        /****************************************************************************
        * GetFFT
        *  Get the raw FFT of an array
        ****************************************************************************/
        private FFTData GetFFT(int[] amp, int[] time, FFTSettings fftSettings, double[] lastfft, int SampleCount)
        {
            FFTData fftData = new FFTData();

            double[] fft  = new double[amp.Length];
            double[] freq = new double[amp.Length / 2];
            //AForge.Math.Complex[] fftComplex = new AForge.Math.Complex[amp.Length];
            Complex[] fftComplex = new Complex[amp.Length];


            // if FFT style has changed, reset the averaging by making last FFT null.
            if (fftSettings.isFftStyleChange)
            {
                lastfft = null;
            }

            //calculate fft
            for (int i = 0; i < amp.Length; i++)
            {
                //fftComplex[i] = new AForge.Math.Complex();
                fftComplex[i] = new Complex(amp[i], 0);
            }
            //AForge.Math.FourierTransform.FFT(fftComplex, AForge.Math.FourierTransform.Direction.Forward);
            Accord.Math.Transforms.FourierTransform2.FFT(fftComplex, Accord.Math.FourierTransform.Direction.Forward);


            // transform fft based on user selected style
            for (int i = 0; i < amp.Length; i++)
            {
                time[i] = time[i] - time.Min();
                switch (fftSettings.Fftstyle)
                {
                case 0:                                                //Log
                    fft[i] = 20 * Math.Log10(fftComplex[i].Magnitude); // decibels=20Log,  http://www.arrl.org/files/file/Instructor%20resources/A%20Tutorial%20on%20the%20Dec-N0AX.pdf
                    if (fft[i] == Double.NegativeInfinity || fft[i] == Double.NaN)
                    {
                        fft[i] = 0;
                    }
                    break;

                case 1:     // Log - Complex Conjugate
                    fft[i] = 20 * Math.Log10(Complex.Conjugate(fftComplex[i]).Magnitude *fftComplex[i].Magnitude);
                    if (fft[i] == Double.NegativeInfinity || fft[i] == Double.NaN)
                    {
                        fft[i] = 0;
                    }
                    break;

                case 2:     // Magnitude
                    fft[i] = fftComplex[i].Magnitude;
                    break;

                case 3:     // Magnitude - Complex Conjugate
                    fft[i] = Complex.Conjugate(fftComplex[i]).Magnitude *fftComplex[i].Magnitude;
                    break;

                default:
                    break;
                }

                if (i % 2 == 0)
                {
                    freq[i / 2] = /*Math.Pow(2,1024/SampleCount-1) */ (1024 / SampleCount) * Convert.ToDouble(i / 2) * 1e3 / (time[9] - time[8]);
                }
            }

            fft = fft.Take(fft.Length / 2).ToArray();

            // transform FFT based on user selected averaging technique- New Average = (New Spectrum • 1/N) + (Old Average) • (N−1)/N
            if (lastfft == null)
            {
                fftSettings.isFftMovAvg  = false;
                fftSettings.isFftContAvg = false;
            }
            if (fftSettings.isFftMovAvg)
            {
                for (int i = 0; i < fft.Length; i++)
                {
                    fft[i] = fft[i] * 1 / fftSettings.nFftMovAvg + lastfft[i] * (fftSettings.nFftMovAvg - 1) / fftSettings.nFftMovAvg;
                }
            }
            if (fftSettings.isFftContAvg)
            {
                for (int i = 0; i < fft.Length; i++)
                {
                    try
                    {
                        fft[i] = fft[i] * 1 / fftSettings.nFftContAvg + lastfft[i] * (fftSettings.nFftContAvg - 1) / fftSettings.nFftContAvg;
                    }
                    catch (Exception)
                    {
                    }
                }

                fftSettings.nFftContAvg++;
            }

            fftData.fft  = fft;
            fftData.freq = freq;

            return(fftData);
        }