/// <summary>
 /// Calculate SCR features.
 /// </summary>
 ///
 /// <param name="timeWindow">The time window.</param>
 /// <param name="timeScale">The time scale - it can be in milliseconds or in seconds.</param>
 ///
 /// <returns>
 /// The arousal statistic according to the specified time window.
 /// </returns>
 public ArousalStatistics GetArousalStatistics(double timeWindow, TimeWindowMeasure timeScale)
 {
     signalValues = GetSignalValues();
     //The signal values receved by device are already filtered (we give the average of eight sequence values).
     //Therefore it is not needed to apply other filter.
     SignalDataByTime[] medianFilterCoordinates = GetMedianFilterPoints(signalValues);
     if (medianFilterCoordinates != null)
     {
         return(GetArousalStatisticsByMedianFilter(medianFilterCoordinates, timeWindow, timeScale));
     }
     return(GetArousalStatisticsByMedianFilter(signalValues, timeWindow, timeScale));;
 }
        /// <summary>
        /// Calculate SCR features after aplying median filter on the signal values.
        /// </summary>
        ///
        /// <param name="medianFilterCoordinates">List of new signal values after aplying median filter on raw signal values.</param>
        /// <param name="timeWindow">The time window.</param>
        /// <param name="timeMeasure">The time scale - it can be in milliseconds or in seconds.</param>
        ///
        /// <returns>
        /// The arousal statistic according to the specified time window.
        /// </returns>
        public ArousalStatistics GetArousalStatisticsByMedianFilter(SignalDataByTime[] medianFilterCoordinates, double timeWindow, TimeWindowMeasure timeMeasure)
        {
            if (timeWindow.CompareTo(0.0) <= 0)
            {
                timeWindow  = defaultTimeWindow;
                timeMeasure = TimeWindowMeasure.Seconds;
            }

            ArousalStatistics butterworthStatistics = GetArousalStatistics(medianFilterCoordinates.ToList(), timeWindow, timeMeasure, sampleRate);

            if (butterworthStatistics != null)
            {
                butterworthStatistics.TonicStatistics         = GetTonicStatistics(medianFilterCoordinates.ToList());
                butterworthStatistics.SCLAchievedArousalLevel = GetTonicLevel(butterworthStatistics.TonicStatistics.MeanAmp);
                butterworthStatistics.LowPassSignalValue      = medianFilterCoordinates[medianFilterCoordinates.Count() - 1].LowPassValue;
                butterworthStatistics.HighPassSignalValue     = medianFilterCoordinates[medianFilterCoordinates.Count() - 1].HighPassValue;
                butterworthStatistics.LastMedianFilterValue   = medianFilterCoordinates[medianFilterCoordinates.Count() - 1].SignalValue;
            }

            return(butterworthStatistics);
        }
        /// <summary>
        /// Calculate number of affected signal values depending on time window.
        /// </summary>
        ///
        /// <param name="coordinates">List of all signal values stored in the cache.</param>
        /// <param name="timeWindow">Time wondow.</param>
        /// <param name="sampleRate">Sample rate.</param>
        ///
        /// <returns>
        /// Number of affected signal values.
        /// </returns>
        private int GetNumberOfAffectedPoints(List <SignalDataByTime> coordinates, double timeWindow, TimeWindowMeasure timewindowType, int sampleRate)
        {
            timeWindow = timewindowType.Equals(TimeWindowMeasure.Milliseconds) ? (timeWindow / 1000) : timeWindow;
            int    numberOfAffectedPoints = Convert.ToInt32((1000.0 / sampleRate) * timeWindow, CultureInfo.InvariantCulture);
            double minAcceptableTime      = timeWhenSignalValuesAreExtracted - timeWindow * 1000;

            if (coordinates.Count < numberOfAffectedPoints)
            {
                return(coordinates.Count);
            }

            for (int i = (coordinates.Count - numberOfAffectedPoints - 1); i < coordinates.Count; i++)
            {
                if (coordinates[i].Time < minAcceptableTime)
                {
                    numberOfAffectedPoints--;
                }
                else
                {
                    break;
                }
            }

            if ((coordinates.Count - numberOfAffectedPoints) > 1)
            {
                for (int i = (coordinates.Count - numberOfAffectedPoints - 2); i > -1; i--)
                {
                    if (coordinates[i].Time >= minAcceptableTime)
                    {
                        numberOfAffectedPoints++;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            return(numberOfAffectedPoints);
        }
        /// <summary>
        /// Calculate arousal statistics for the passed time window in seconds.
        /// </summary>
        ///
        /// <param name="timeWindowType">The type of time window: milliseconds or seconds.</param>
        /// <param name="timeWindow">Time wondow.</param>
        ///
        /// <returns>
        /// Arousal statistics for the passed time window in seconds.
        /// </returns>
        public ArousalStatistics GetArousalStatistics(List <SignalDataByTime> highPassCoordinates, double timeWindow, TimeWindowMeasure timeWindowType, int sampleRate)
        {
            if (timeWindow.CompareTo(0) <= 0 || sampleRate <= 0 || highPassCoordinates.Count <= 0)
            {
                return(null);
            }

            int numberOfAffectedPoints = GetNumberOfAffectedPoints(highPassCoordinates, timeWindow, timeWindowType, sampleRate);

            //if (coordinates.Count < numberOfAffectedPoints) return GetArousalInfoForCoordinates(coordinates, coordinates.Count, defaultTimeWindow);
            double timeWindowInSeconds = timeWindowType.Equals(TimeWindowMeasure.Milliseconds) ? timeWindow / 1000 : timeWindow;

            return(GetArousalInfoForCoordinates(highPassCoordinates, numberOfAffectedPoints, timeWindowInSeconds));
        }