public async Task<EvaluationResultModel> RunEvaluationDuringMeasurementAsync(EvaluationDataModel evaluationData, EvaluationSettingModel evaluationSetting)
 {
     return await Task.Run<EvaluationResultModel>(() =>
     {
         return Run(evaluationData, evaluationSetting);
     });
 }
 private EvaluationResultModel Run(EvaluationDataModel evaluationData, EvaluationSettingModel evaluationSetting)
 {
     EvaluationResultModel evaluationResult = new EvaluationResultModel();
     AnalysisVectorLength(evaluationData, evaluationResult);
     AssumingAcceleromterSteps(evaluationResult, evaluationSetting);
     AssumingGyrometerSteps(evaluationResult, evaluationSetting);
     DetectSteps(evaluationResult, evaluationSetting);
     return evaluationResult;
 }
        public async Task<EvaluationResultModel> RunEvaluationAfterMeasurementAsync(EvaluationDataModel evaluationData, EvaluationSettingModel evaluationSetting)
        {

            return await Task.Run<EvaluationResultModel>(() =>
            {
                _lastKnownStep = TimeSpan.Zero;
                lastAssumedAcclerometerStepTime = TimeSpan.Zero;
                lastAssumedGyrometerStepTime = TimeSpan.Zero;
                return Run(evaluationData, evaluationSetting);
            });
        }
        private void AssumingAcceleromterSteps(EvaluationResultModel evaluationResultModel, EvaluationSettingModel evaluationSetting)
        {
            double accelerometerThreshold = evaluationSetting.AccelermeterVectorLengthThreshold;
            var evaluationList = evaluationResultModel.EvaluationResultList;

            if (evaluationList != null && evaluationList.Count > 2)
            {
                // detect Steps
                for (int i = 1; i < evaluationList.Count - 1; i++)
                {
                    double twicePreviousAccelerometerVectorLength = evaluationList.ElementAt(i).AccelerometerVectorLength;
                    double previousAccelerometerVectorLength = evaluationList.ElementAt(i).AccelerometerVectorLength;
                    double currentAccelerometerVectorLength = evaluationList.ElementAt(i).AccelerometerVectorLength;
                    double nextAccelerometerVectorLength = evaluationList.ElementAt(i).AccelerometerVectorLength;
                    double twiceNextAccelerometerVectorLength = evaluationList.ElementAt(i).AccelerometerVectorLength;

                    // is evaluation value not the first one && is evaluation value not the last one
                    if (i > 0)
                    {
                        previousAccelerometerVectorLength = evaluationList.ElementAt(i - 1).AccelerometerVectorLength;
                    }
                    if (i > 1)
                    {
                        twicePreviousAccelerometerVectorLength = evaluationList.ElementAt(i - 2).AccelerometerVectorLength;
	                }

                    if (i < evaluationList.Count - 1)
                    {
                        nextAccelerometerVectorLength = evaluationList.ElementAt(i + 1).AccelerometerVectorLength;
                    }
                    if (i < evaluationList.Count - 2)
                    {
                        twiceNextAccelerometerVectorLength = evaluationList.ElementAt(i + 2).AccelerometerVectorLength;
                    }

                    // Assume accelerometer step
                    if (// find peak
                        (currentAccelerometerVectorLength - previousAccelerometerVectorLength) * (currentAccelerometerVectorLength - nextAccelerometerVectorLength) > 0d &&
                        (currentAccelerometerVectorLength - twicePreviousAccelerometerVectorLength) * (currentAccelerometerVectorLength - twiceNextAccelerometerVectorLength) > 0d &&
                        // check threshold
                        currentAccelerometerVectorLength.CompareTo(accelerometerThreshold) > 0)
                    {
                        // Set assumed step
                        evaluationList.ElementAt(i).IsAssumedAccelerometerStep = true;
                    }
                }
            }
        }
        //###########################################################################
        //######################## Init MeasurementTask #############################
        //###########################################################################

        public void Run(IBackgroundTaskInstance taskInstance)
        {
            Debug.WriteLine(
                "####################################################\n" +
                "############### Run MeasurementTask ################\n" +
                "####################################################");

            _taskInstance = taskInstance;
            // GET TASKARGRUMENTS
            _taskArguments = GetTaskArgumentsFromTriggerDetails((DeviceUseDetails)_taskInstance.TriggerDetails);

            if (_taskArguments != null)
            {
                // init different sensors
                InitAccelerometer(_taskArguments);
                InitGyrometer(_taskArguments);
                InitOrientationSensor(_taskArguments);
                InitGeolocationSensor(_taskArguments);

                taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled);

                // create new measurement data model
                _measurementData = new MeasurementData(_taskArguments.Filename, _taskArguments.SampleBufferSize);
                _measurementData.ListsHasSwitched += MeasurementData_ReadingsListsHasSwitched;

                //set evaluation setting model
                _evaluationSettingModel = new EvaluationSettingModel(_taskArguments.SampleBufferSize, _taskArguments.AccelerometerThreshold, 
                    _taskArguments.GyrometerThreshold, _taskArguments.StepDistance, _taskArguments.PeakJoinDistance);

                _deferral = _taskInstance.GetDeferral();
                Debug.WriteLine(
                    "####################################################\n" +
                    "########## MeasurementTask initialisiert ###########\n" +
                    "####################################################");
            }
            else
            {
                Debug.WriteLine(
                    "####################################################\n" +
                    "############# MeasurementTask aborted ##############\n" +
                    "####################################################");
            }
        }
        private async void StartEvaluationAppBarButton_Click(object sender, RoutedEventArgs e)
        {
            // Show loader
            _mainPage.ShowLoader();

            //prepare timer
            Stopwatch stopwatch = new Stopwatch();

            SettingViewModel setting = _evaluationPageViewModel.MeasurementViewModel.Setting;
            //prepare evaluation settings and evaluation data
            uint processedSampleCount = setting.EvaluationSettingViewModel.SampleBufferSize;
            double accelerometerThreshold = setting.EvaluationSettingViewModel.AccelerometerThreshold;
            double gyrometerThreshold = setting.EvaluationSettingViewModel.GyrometerThreshold;
            uint stepDistance = setting.EvaluationSettingViewModel.StepDistance;
            uint peakJoinDistance = setting.EvaluationSettingViewModel.PeakJoinDistance;
            EvaluationSettingModel evaluationSettingModel = new EvaluationSettingModel(processedSampleCount, accelerometerThreshold, gyrometerThreshold, stepDistance, peakJoinDistance);
            
            EvaluationDataModel evaluationDataModel = _evaluationPageViewModel.EvaluationDataModel;

            //set evaluation state to started
            _evaluationPageViewModel.EvaluationState = EvaluationState.Started;
            ((StartEvaluationCommand)_evaluationPageViewModel.StartEvaluationCommand).OnCanExecuteChanged();

            //process evaluation
            stopwatch.Start();
            _evaluationPageViewModel.EvalautionResultModel = await _measurementEvaluationService.RunEvaluationAfterMeasurementAsync(evaluationDataModel, evaluationSettingModel);
            uint totalDetectedSteps = _evaluationPageViewModel.EvalautionResultModel.DetectedSteps;
            _evaluationPageViewModel.MeasurementViewModel.TotalSteps = totalDetectedSteps;

            //propagate update
            MeasurementModel measurement = _mainPage.GlobalMeasurementModel.GetMeasurementById(_evaluationPageViewModel.MeasurementViewModel.Id);
            _mainPage.GlobalMeasurementModel.UpdateMeasurementInList(_evaluationPageViewModel.MeasurementViewModel);

            // Save evaluation if necessary
            if (setting.EvaluationSettingViewModel.IsRecordSamples)
            {
                await EvaluationService.SaveEvaluationDataToFileAsync(measurement.Filename, _evaluationPageViewModel.EvalautionResultModel);
            }

            //set evaluation state to stopped
            stopwatch.Stop();
            _evaluationPageViewModel.EvaluationState = EvaluationState.Stopped;
            ((StartEvaluationCommand)_evaluationPageViewModel.StartEvaluationCommand).OnCanExecuteChanged();
            _mainPage.ShowNotifyMessage(String.Format("Messung wurde innerhalb von '{0:f4}' Sekunden erneut ausgewertet.", stopwatch.Elapsed.Duration().TotalSeconds), NotifyLevel.Info);

            // hide loader
            _mainPage.HideLoader();
        }
        private void DetectSteps(EvaluationResultModel evaluationResultModel, EvaluationSettingModel evaluationSetting)
        {
            TimeSpan stepTimeDistence = evaluationSetting.StepDistance;
            TimeSpan assumedStepsPairingThreshold = evaluationSetting.PeakJoinDistance;
            
            var evaluationList = evaluationResultModel.EvaluationResultList;

            if (evaluationList != null && evaluationList.Count > 0)
            {
                // detect Steps
                for (int i = 0; i < evaluationList.Count; i++)
                {
                    // check timespan between to detected steps
                    if (evaluationList.ElementAt(i).MeasurementTime.Subtract(_lastKnownStep) > stepTimeDistence)
                    {
                        // Set assumed accelerometer step
                        if (evaluationList.ElementAt(i).IsAssumedAccelerometerStep)
                        {
                            lastAssumedAcclerometerStepTime = evaluationList.ElementAt(i).MeasurementTime;
                        }

                        // Set assumed gyrometer step
                        if (evaluationList.ElementAt(i).IsAssumedGyrometerStep)
                        {
                            lastAssumedGyrometerStepTime = evaluationList.ElementAt(i).MeasurementTime;
                        }

                        // Vergleichen der zuletzt gefundenen peaks
                        if (lastAssumedAcclerometerStepTime != TimeSpan.Zero &&
                            lastAssumedGyrometerStepTime != TimeSpan.Zero)
                        {
                            //Tritt ein, wenn der zuletzt vermutete Accelerometerschritt nach dem zuletzt vermuteten Gyrometerschritt liegt und kleiner als der Schwellwert ist.
                            //oder
                            //Tritt ein, wenn der zuletzt vermutete Acceleroemeterschritt vor dem zuletzt vermuteten Gyrometerschritt liegt und kleiner als der Schwellwert ist.
                            if ((lastAssumedAcclerometerStepTime.CompareTo(lastAssumedGyrometerStepTime) >= 0 &&
                                lastAssumedAcclerometerStepTime.Subtract(lastAssumedGyrometerStepTime) < assumedStepsPairingThreshold)
                                ||
                                (lastAssumedAcclerometerStepTime.CompareTo(lastAssumedGyrometerStepTime) < 0 &&
                                    lastAssumedGyrometerStepTime.Subtract(lastAssumedAcclerometerStepTime) < assumedStepsPairingThreshold))
                            {
                                evaluationList.ElementAt(i).IsDetectedStep = true;
                                _lastKnownStep = evaluationList.ElementAt(i).MeasurementTime;
                                lastAssumedGyrometerStepTime = TimeSpan.Zero;
                                lastAssumedAcclerometerStepTime = TimeSpan.Zero;
                            }

                            // Tritt ein, wenn der zuletzt vermutete Acceleroemeterschritt nach dem zuletzt vermuteten Gyrometerschritt liegt und größer als der Schwellwert ist.
                            else if (lastAssumedAcclerometerStepTime.CompareTo(lastAssumedGyrometerStepTime) > 0 &&
                                    lastAssumedAcclerometerStepTime.Subtract(lastAssumedGyrometerStepTime) > assumedStepsPairingThreshold)
                            {
                                // Setzt den vermuteten Gyrometerschritt auf null zurück, weil der pairing Schwellwert überschritten wurde.
                                lastAssumedGyrometerStepTime = TimeSpan.Zero;
                            }

                            //Tritt ein, wenn der zuletzt vermutete Acceleroemeterschritt vor dem zuletzt vermuteten Gyrometerschritt liegt und größer als der Schwellwert ist.
                            else if (lastAssumedAcclerometerStepTime.CompareTo(lastAssumedGyrometerStepTime) < 0 &&
                                    lastAssumedGyrometerStepTime.Subtract(lastAssumedAcclerometerStepTime) < assumedStepsPairingThreshold)
                            {
                                // Setzt den vermuteten Accelerometerschritt auf null zurück, weil der pairing Schwellwert überschritten wurde.
                                lastAssumedAcclerometerStepTime = TimeSpan.Zero;
                            }
                        }
                    }
                }
            }
        }