public List<DetectedInterval> DetectIntervals(SessionDto session) { var sessionData = session.SessionData; var interval = session.Interval; var potentialIntervalStart = new SessionDataDto(); var detectedIntervalEnd = new SessionDataDto(); var detectedIntervals = new List<DetectedInterval>(); for (var x = 0; x < sessionData.Count; x++) { bool potentialIntervalDetected = false; bool intervalDetected = false; for (var p = x; p < sessionData.Count; p++) { // get average of proceeding 14 seconds of powers - time taken for rider to reach maximum power var currentPowers = new List<double>(); var proceedingPowers = new List<double>(); for (var i = 0; i < 14; i++) { if (p + (i + 1) < sessionData.Count) { if (sessionData[p + i].Power == 0) // rider must be applying power for next 14 seconds { break; } currentPowers.Add(sessionData[p + i].Power); // get power for the next 14 seconds proceedingPowers.Add(sessionData[(p + 1) + i].Power); // get power for the next 14 seconds starting at current power +1 } } if (currentPowers.Count == 0) // no powers added to the last - last detected power was 0 { break; } var currentPowersAverage = currentPowers.Average(); var proceedingPowersAverage = proceedingPowers.Average(); // check for potential interval if (currentPowersAverage < proceedingPowersAverage) { if (!potentialIntervalDetected) { potentialIntervalStart = sessionData[p]; potentialIntervalDetected = true; } } else // possible that cyclist built up speed and reached interval speed to maintain { var potentialIntervalPowerToMaintain = sessionData[p].Power; var percentage = ((potentialIntervalPowerToMaintain * 40) / 100); var minimumPowerRange = potentialIntervalPowerToMaintain - percentage; var maximumPowerRange = potentialIntervalPowerToMaintain + percentage; var minimumIntervalDuration = 10; // interval power must be maintained for atleast 10 seconds var timer = 0; var counter = 1; for (var q = p; q < sessionData.Count; q++) { if (sessionData[q].Power > minimumPowerRange && sessionData[q].Power < maximumPowerRange) { timer += interval * counter; } else { if (timer > minimumIntervalDuration) { intervalDetected = true; detectedIntervalEnd = sessionData[q]; var startTime = potentialIntervalStart.Row * interval; var finishTime = detectedIntervalEnd.Row * interval; var intervalData = GetSessionDataSubset(new SessionDataSubsetDto() // get interval summary { MinimumSecond = startTime, MaximumSecond = finishTime, Unit = 0, SessionId = session.Id }); detectedIntervals.Add(new DetectedInterval(startTime, finishTime, intervalData.AveragePower, true)); } break; } } } if (intervalDetected) { x = detectedIntervalEnd.Row * interval; // start detecting new interval at the end of the detected interval potentialIntervalStart = sessionData[detectedIntervalEnd.Row]; break; } } } // detect workout and rest periods var totalCount = sessionData.Count(); var totalPower = sessionData.Sum(s => s.Power); var averagePower = Math.Round(totalPower / totalCount, 2, MidpointRounding.AwayFromZero); var minimumIntervalPower = ((averagePower * 80) / 100); // workout periods must be greater than 30% of average session power for (var f = 0; f < detectedIntervals.Count; f ++) { detectedIntervals[f].IsRest = detectedIntervals[f].AveragePower < minimumIntervalPower; } return detectedIntervals; }
public void DateTimeDaysForSessionHeaderRowsShouldBeCalculatedByInterval() { var interval = 1; var startDate = new DateTime(2016, 05, 10, 23, 59, 59, 1); // hh:mm:s:ms - 09:30:5:100 var sessionRow1 = new SessionDataDto() { Row = 0 }; var sessionRow2 = new SessionDataDto() { Row = 1 }; var sessionRow3 = new SessionDataDto() { Row = 2 }; // calculate seconds for each session header row sessionRow1.Date = DateFormat.CalculateSessionDataRowDate(startDate, interval, sessionRow1.Row); sessionRow2.Date = DateFormat.CalculateSessionDataRowDate(startDate, interval, sessionRow2.Row); sessionRow3.Date = DateFormat.CalculateSessionDataRowDate(startDate, interval, sessionRow3.Row); // assert seconds Assert.AreEqual(59, sessionRow1.Date.Second); Assert.AreEqual(0, sessionRow2.Date.Second); Assert.AreEqual(1, sessionRow3.Date.Second); // assert minutes Assert.AreEqual(10, sessionRow1.Date.Day); Assert.AreEqual(11, sessionRow2.Date.Day); Assert.AreEqual(11, sessionRow3.Date.Day); }