public void TestComputePSD(int fs, int N, double Nw, double Nover, int Nzp, DetectorWindowType windowtype, double expValue00, double expValue10, double expValue0e, double expValue1e, double expValue0m, double expValue1m)
        {
            List <List <double> > dataInFreqDomain;
            List <double>         freqAll;

            Functions.ComputePSD(data, fs, N, Nw, Nover, Nzp, windowtype, out dataInFreqDomain, out freqAll);

            var slength = dataInFreqDomain[0].Count;

            NUnit.Framework.Assert.AreEqual(dataInFreqDomain.Count, 2);
            NUnit.Framework.Assert.AreEqual(slength, 1500);
            NUnit.Framework.Assert.AreEqual(dataInFreqDomain[0][0], expValue00);
            NUnit.Framework.Assert.AreEqual(dataInFreqDomain[1][0], expValue10);
            NUnit.Framework.Assert.AreEqual(dataInFreqDomain[0][slength - 1], expValue0e);
            NUnit.Framework.Assert.AreEqual(dataInFreqDomain[1][slength - 1], expValue1e);
            NUnit.Framework.Assert.AreEqual(dataInFreqDomain[0][slength / 2], expValue0m);
            NUnit.Framework.Assert.AreEqual(dataInFreqDomain[1][slength / 2], expValue1m);
            NUnit.Framework.Assert.AreEqual(freqAll.Count, 1500);
            NUnit.Framework.Assert.AreEqual(freqAll[0], 0);
            NUnit.Framework.Assert.AreEqual(freqAll[freqAll.Count - 1], 29.98);
            NUnit.Framework.Assert.AreEqual(freqAll[freqAll.Count / 2], 15);
        }
        public void TestInspectionSpectral(double analysisLength, double windowLength, DetectorWindowType windowType, double windowOverlap, int zeroPadding, int fs, bool logScale, double freqMin, double freqMax, string expectedResults)
        {
            var parameters = new InspectionAnalysisParameters();

            parameters.AnalysisLength = analysisLength;
            parameters.WindowLength   = windowLength;
            parameters.WindowType     = windowType;
            parameters.WindowOverlap  = windowOverlap;
            parameters.ZeroPadding    = zeroPadding;
            parameters.Fs             = fs;
            parameters.LogScale       = logScale;
            parameters.FreqMax        = freqMax;
            parameters.FreqMin        = freqMin;

            var result = Functions.InspectionSpectral(data, parameters);

            NUnit.Framework.Assert.AreEqual(result.X.Count, 46);
            NUnit.Framework.Assert.AreEqual(result.Y.Count, 2);
            NUnit.Framework.Assert.AreEqual(result.Y[0].Count, 46);
            NUnit.Framework.Assert.AreEqual(result.Ylabel, expectedResults);
            NUnit.Framework.Assert.AreEqual(result.Xlabel, "F (Hz)");
        }
Exemple #3
0
        public static void ComputePSD(List <List <double> > data, int fs, int N, double Nw, double Nover, int Nzp, DetectorWindowType windowtype, out List <List <double> > dataInFreqDomain, out List <double> freqAll)
        {
            double[] win;

            switch (windowtype)
            {
            case Core.Models.DetectorWindowType.hann:
                win = Window.Hann((int)Nw);
                break;

            case Core.Models.DetectorWindowType.rectwin:
                win = _rectwin((int)Nw);
                break;

            case Core.Models.DetectorWindowType.bartlett:
                win = Window.Bartlett((int)Nw);
                break;

            case Core.Models.DetectorWindowType.hamming:
                win = Window.Hamming((int)Nw);
                break;

            case Core.Models.DetectorWindowType.blackman:
                win = Window.Blackman((int)Nw);
                break;

            default:
                throw new Exception(windowtype.ToString() + " is not an acceptable window type.");
            }
            var U = win.Sum(x => Math.Pow(x, 2));

            dataInFreqDomain = new List <List <double> >();

            //find the frequency vector which should be the x axis of the spectrum
            freqAll = new List <double>();
            for (int i = 0; i < Nzp; i++)
            {
                freqAll.Add((double)fs * i / Nzp);
            }

            //comput the number of segments: (signalLength - overlap)/(windowLength - overlap)
            //round towards zero
            var M = Math.Floor((N - Nover) / (Nw - Nover));

            foreach (var sig in data)
            {
                var newSig = new List <double>();
                var dat    = sig.GetRange(0, N);
                var mean   = dat.Average();
                foreach (var p in dat)
                {
                    var pp = p - mean;
                    newSig.Add(pp);
                }
                double[] Pxx = null;
                for (int i = 0; i < M; i++)
                {
                    var start = (int)(i * (Nw - Nover));
                    var end   = (int)(i * (Nw - Nover) + Nw);
                    //Console.WriteLine("start from " + start.ToString() + ", end at " + end.ToString());
                    //to match InspectionSpectral where mean is removed before calling pwelch
                    var frag = newSig.GetRange(start, (int)Nw);
                    //to match CalcPSD_OmegaB.m where mean is not removed from the data before calling fft
                    //var frag = dat.GetRange(start, (int)Nw);
                    //Console.WriteLine("number of point " + frag.Count());

                    //double[] real = null;
                    var fragcount = frag.Count;

                    //if (fragcount % 2 == 0)
                    //{
                    //    real = new double[fragcount + 2];
                    //    real[fragcount] = 0d;
                    //    real[fragcount + 1] = 0d;
                    //}
                    //else
                    //{
                    //    real = new double[fragcount + 1];
                    //    real[fragcount] = 0d;
                    //}
                    var complex = new Complex[Nzp];
                    //multiply with filter win first
                    for (int ii = 0; ii < frag.Count; ii++)
                    {
                        //real[ii] = frag[ii] * win[ii];
                        complex[ii] = new Complex(frag[ii] * win[ii], 0);
                    }
                    //might need an empty vector to hold results, or pass by ref?
                    //Console.WriteLine(frag[0]);
                    //var fragarray = frag.ToArray();
                    //Console.WriteLine("[{0}]", string.Join(", ", real));
                    //Fourier.ForwardReal(real, fragcount, FourierOptions.Matlab);
                    //Console.WriteLine("[{0}]", string.Join(", ", real));
                    //Console.WriteLine("[{0}]", string.Join(", ", complex));
                    Fourier.Forward(complex, FourierOptions.Matlab);
                    //Console.WriteLine("[{0}]", string.Join(", ", complex));
                    //Console.WriteLine("real: {0}, imaginary: {1}, magnitude: {2}", complex[0].Real, complex[0].Imaginary, complex[0].Magnitude);

                    if (Pxx == null)
                    {
                        Pxx = new double[complex.Length];
                    }

                    for (int ii = 0; ii < complex.Length; ii++)
                    {
                        Pxx[ii] = Pxx[ii] + (Math.Pow(complex[ii].Magnitude, 2) / (U * M));
                    }
                }
                //Pxx[0] = Pxx[0] / 2;
                dataInFreqDomain.Add(Pxx.ToList());
            }
        }