public object[][] ExportData()
        {
            object[][] data = new object[WhiskerAngle.Frames.Length + 5][];

            for (int i = 0; i < data.Length; i++)
            {
                data[i] = new object[(Whiskers.Length * 5) + 1];

                if (i < 4)
                {
                    continue;
                }

                if (i == 4)
                {
                    data[4][0] = "Frame";
                    continue;
                }

                data[i][0] = i - 4;
            }

            for (int i = 0; i < Whiskers.Length; i++)
            {
                data[0][1 + (i * 5)] = Whiskers[i].Whisker.WhiskerName;

                data[1][1 + (i * 5)] = "Mean Protraction Velocity: ";
                data[1][2 + (i * 5)] = Whiskers[i].MeanProtractionVelocity;

                data[2][1 + (i * 5)] = "Mean Retraction Velocity: ";
                data[2][2 + (i * 5)] = Whiskers[i].MeanRetractionVelocity;

                data[3][1 + (i * 5)] = "Max Amplitude";
                data[3][2 + (i * 5)] = Whiskers[i].MaxAmplitude;

                data[4][1 + (i * 5)] = "Action";
                data[4][2 + (i * 5)] = "Current Velocity";
                data[4][3 + (i * 5)] = "Current Amplitude";
                data[4][4 + (i * 5)] = "Max Angle";
                data[4][5 + (i * 5)] = "Min Angle";

                for (int j = 5; j < data.Length + 5; j++)
                {
                    IProtractionRetractionBase protractRetract = Whiskers[i].GetCurrentProtractionRetraction(j - 4);

                    if (protractRetract == null)
                    {
                        continue;
                    }

                    data[j][1 + (i * 5)] = protractRetract.Name;
                    data[j][2 + (i * 5)] = protractRetract.MeanAngularVelocity;
                    data[j][3 + (i * 5)] = protractRetract.Amplitude;
                    data[j][4 + (i * 5)] = protractRetract.MaxAngle;
                    data[j][5 + (i * 5)] = protractRetract.MinAngle;
                }
            }

            return(data);
        }
        private void CreateAngularVelocitySignal()
        {
            if (AngleSignal == null || AngleSignal.Length == 0)
            {
                return;
            }

            bool error = false;

            double[] smoothedAngleSignal = SmoothingFunctions.BoxCarSmooth(AngleSignal);

            if (smoothedAngleSignal == null || smoothedAngleSignal.Length == 0)
            {
                return;
            }

            int[][] peaksAndValleys = SmoothingFunctions.FindPeaksAndValleys(smoothedAngleSignal);
            int[]   peaks           = peaksAndValleys[0];
            int[]   valleys         = peaksAndValleys[1];

            if (peaks.Length == 0 || valleys.Length == 0)
            {
                return;
            }

            int[] rawPeaks = new int[peaks.Length];
            for (int i = 0; i < peaks.Length; i++)
            {
                int closestPeak = SmoothingFunctions.FindClosestPeak(peaks[i], AngleSignal);

                if (rawPeaks.Contains(closestPeak))
                {
                    ErrorOccured("The signal is too noisy, accurate results can not be guaranteed");
                    error = true;
                }

                rawPeaks[i] = closestPeak;
            }

            int[] rawValleys = new int[valleys.Length];
            for (int i = 0; i < valleys.Length; i++)
            {
                int closestValley = SmoothingFunctions.FindClosestValley(valleys[i], AngleSignal);

                if (rawValleys.Contains(closestValley))
                {
                    ErrorOccured("The signal is too noisy, accurate results can not be guaranteed");
                    error = true;
                }

                rawValleys[i] = closestValley;
            }

            List <IProtractionRetractionBase> data = new List <IProtractionRetractionBase>();

            int  peakCounter   = 0;
            int  valleyCounter = 0;
            int  currentPeak   = rawPeaks[peakCounter];
            int  currentValley = rawValleys[valleyCounter];
            bool protract      = currentPeak > currentValley;
            Dictionary <int, IProtractionRetractionBase> protractionRetractionDictionary = new Dictionary <int, IProtractionRetractionBase>();

            while (true)
            {
                if (protract)
                {
                    double deltaTime = Math.Abs(currentPeak - currentValley) / GlobalSettings.GlobalSettings.FrameRateSettings.OriginalFrameRate;
                    IProtractionRetractionBase protraction = ModelResolver.Resolve <IProtractionData>();
                    protraction.UpdateData(AngleSignal[currentValley], AngleSignal[currentPeak], deltaTime);
                    data.Add(protraction);

                    for (int i = currentValley; i < currentPeak; i++)
                    {
                        if (!protractionRetractionDictionary.ContainsKey(i))
                        {
                            protractionRetractionDictionary.Add(i, protraction);
                        }
                        else
                        {
                            ErrorOccured("The signal is too noisy, accurate results can not be guaranteed");
                            error = true;
                        }
                    }

                    valleyCounter++;

                    if (valleyCounter >= rawValleys.Length)
                    {
                        break;
                    }

                    currentValley = rawValleys[valleyCounter];

                    protract = false;
                }
                else
                {
                    double deltaTime = Math.Abs(currentPeak - currentValley) / GlobalSettings.GlobalSettings.FrameRateSettings.OriginalFrameRate;
                    IProtractionRetractionBase retraction = ModelResolver.Resolve <IRetractionData>();
                    retraction.UpdateData(AngleSignal[currentValley], AngleSignal[currentPeak], deltaTime);
                    data.Add(retraction);

                    for (int i = currentPeak; i < currentValley; i++)
                    {
                        if (!protractionRetractionDictionary.ContainsKey(i))
                        {
                            protractionRetractionDictionary.Add(i, retraction);
                        }
                        else
                        {
                            ErrorOccured("The signal is too noisy, accurate results can not be guaranteed");
                            error = true;
                        }
                    }

                    peakCounter++;

                    if (peakCounter >= rawPeaks.Length)
                    {
                        break;
                    }

                    currentPeak = rawPeaks[peakCounter];

                    protract = true;
                }
            }

            ProtractionRetractionData       = data;
            ProtractionRetractionDictionary = protractionRetractionDictionary;

            MeanProtractionVelocity = ProtractionRetractionData.Where(x => x is IProtractionData).Select(x => x.MeanAngularVelocity).Mean();
            MeanRetractionVelocity  = ProtractionRetractionData.Where(x => x is IRetractionData).Select(x => x.MeanAngularVelocity).Mean();

            double maxAngle = ProtractionRetractionData.Select(x => x.MaxAngle).Max();
            double minAngle = ProtractionRetractionData.Select(x => x.MinAngle).Min();

            MaxAmplitude = Math.Abs(maxAngle - minAngle);

            if (!error)
            {
                ModelObjectState = ModelObjectState.New;
            }
        }
 public ProtractionRetractionDataBaseViewModel(IProtractionRetractionBase model)
 {
     Model = model;
 }
 public ProtractionRetractionDataBaseViewModel(IProtractionRetractionBase model)
 {
     Model = model;
 }
        public void UpdateFrameNumber(int frameNumber)
        {
            IProtractionRetractionBase data = Model.GetCurrentProtractionRetraction(frameNumber);

            CurrentProtractionRetraction = data == null ? null : new ProtractionRetractionDataBaseViewModel(data);
        }