public SessionSummaryDto CalculateWorkoutSummary(SessionDto session, List<DetectedInterval> detectedIntervals, int unit) { var sessionSummaryDtoList = new List<SessionSummaryDto>(); for (var w = 0; w < detectedIntervals.Count; w++) { var sessionDataSubsetDto = new SessionDataSubsetDto() { MinimumSecond = (double)detectedIntervals[w].StartTime, MaximumSecond = (double)detectedIntervals[w].FinishTime, SessionId = session.Id, Unit = unit }; var sessionSummaryDto = GetSessionDataSubset(sessionDataSubsetDto); sessionSummaryDtoList.Add(sessionSummaryDto); } var totalCount = sessionSummaryDtoList.Count(); // calculate speed var averageSpeed = Math.Round(sessionSummaryDtoList.Sum(x => x.AverageSpeed) / totalCount, 2, MidpointRounding.AwayFromZero); var maximumSpeed = sessionSummaryDtoList.MaxBy(s => s.MaximumSpeed).MaximumSpeed; // calculate distance var totalDistance = Math.Round(sessionSummaryDtoList.Sum(x => x.TotalDistance), 2, MidpointRounding.AwayFromZero); // calculate altitiude var averageAltitude = Math.Round(sessionSummaryDtoList.Sum(x => x.AverageAltitude) / totalCount, 2, MidpointRounding.AwayFromZero); var maximumAltitude = sessionSummaryDtoList.MaxBy(s => s.MaximumAltitude).MaximumAltitude; // calculate heart rate var averageHeartRate = Math.Round(sessionSummaryDtoList.Sum(x => x.AverageHeartRate / totalCount), 2, MidpointRounding.AwayFromZero); var minimumHeartRate = sessionSummaryDtoList.MinBy(s => s.MinimumHeartRate).MinimumHeartRate; var maximumHeartRate = sessionSummaryDtoList.MinBy(s => s.MaximumHeartRate).MaximumHeartRate; // calculate power var averagePower = Math.Round(sessionSummaryDtoList.Sum(x => x.AveragePower) / totalCount, 2, MidpointRounding.AwayFromZero); var maximumPower = sessionSummaryDtoList.MaxBy(s => s.MaximumPower).MaximumPower; // calculate cadence var averageCadence = Math.Round(sessionSummaryDtoList.Sum(x => x.AverageCadence) / totalCount, 2, MidpointRounding.AwayFromZero); var maximumCadence = sessionSummaryDtoList.MaxBy(s => s.MaximumCadence).MaximumCadence; var workoutSummary = new SessionSummaryDto() { AverageAltitude = averageAltitude, MaximumAltitude = maximumAltitude, AverageHeartRate = averageHeartRate, MinimumHeartRate = minimumHeartRate, MaximumHeartRate = maximumHeartRate, AveragePower = averagePower, MaximumPower = maximumPower, AverageCadence = averageCadence, MaximumCadence = maximumCadence, AverageSpeed = averageSpeed, MaximumSpeed = maximumSpeed, TotalDistance = totalDistance, Date = session.Date, SessionId = session.Id }; return workoutSummary; }
public SessionSummaryDto GetSingleIntervalSummary(SessionDataSubsetDto sessionDataSubsetDto) { var singleIntervalSummary = GetSessionDataSubset(sessionDataSubsetDto); return singleIntervalSummary; }
public SessionSummaryDto GetSessionDataSubset(SessionDataSubsetDto sessionDataSubsetDto) { var minimumSeconds = sessionDataSubsetDto.MinimumSecond; var maximumSeconds = sessionDataSubsetDto.MaximumSecond; var totalTimeInHours = (maximumSeconds - minimumSeconds) / 3600; var requestedUnitIsMetric = sessionDataSubsetDto.Unit == 0; var session = _context.Sessions.Single(x => x.Id == sessionDataSubsetDto.SessionId); var sModeIsMetric = session.SMode.ToString("D9").IsMetric(); // pad int to 9 decimals if zero var sessionData = _context.SessionData.Where(x => x.SessionId == sessionDataSubsetDto.SessionId).ToList().OrderBy(x => x.Row) .Select(sd => new SessionDataDto() { Id = sd.Id, HeartRate = sd.HeartRate, Speed = sd.Speed, Cadence = sd.Cadence, Altitude = sd.Altitude, Power = sd.Power, SessionId = sd.SessionId, Date = DateFormat.CalculateSessionDataRowDate(session.Date, session.Interval, sd.Row) }).ToList(); var filteredSessionData = sessionData.FilterListDates(session.Date, minimumSeconds, maximumSeconds); // filter sessions by min and max seconds var totalCount = filteredSessionData.Count(); double maximumSpeed; double averageSpeed; double totalSpeed; double totalDistance; double averageAltitude; double maximumAltitude; double totalAltitude; if (requestedUnitIsMetric) // return metric values { if (sModeIsMetric) { // calculate speed - divided speed by 10 as speed is *10 in file totalSpeed = filteredSessionData.Sum(s => s.Speed); averageSpeed = Math.Round((totalSpeed / 10) / totalCount, 2, MidpointRounding.AwayFromZero); maximumSpeed = Math.Round(filteredSessionData.MaxBy(s => s.Speed).Speed / 10, 2, MidpointRounding.AwayFromZero); // calculate distance totalDistance = Math.Round(averageSpeed * totalTimeInHours, 2, MidpointRounding.AwayFromZero); // calculate altitiude totalAltitude = filteredSessionData.Sum(s => s.Altitude / 10); averageAltitude = Math.Round(totalAltitude / totalCount, 2, MidpointRounding.AwayFromZero); maximumAltitude = Math.Round(filteredSessionData.MaxBy(s => s.Altitude).Altitude / 10, 2, MidpointRounding.AwayFromZero); } else { // calculate speed - divided speed by 10 as speed is *10 in file - converted kilometres to miles totalSpeed = filteredSessionData.Sum(s => s.Speed); averageSpeed = ((totalSpeed / 10) / totalCount).ConvertToKilometres(); maximumSpeed = (filteredSessionData.MaxBy(s => s.Speed).Speed / 10).ConvertToKilometres(); // calculate distance totalDistance = ((totalSpeed / 10) / totalCount * totalTimeInHours).ConvertToKilometres(); // calculate altitiude - convert metres to feet totalAltitude = filteredSessionData.Sum(s => s.Altitude / 10); averageAltitude = (totalAltitude / totalCount).ConvertToMetres(); maximumAltitude = (filteredSessionData.MaxBy(s => s.Altitude).Altitude / 10).ConvertToMetres(); } } else // return imperial values { if (sModeIsMetric) { // calculate speed - divided speed by 10 as speed is *10 in file - converted kilometres to miles totalSpeed = filteredSessionData.Sum(s => s.Speed); averageSpeed = ((totalSpeed / 10) / totalCount).ConvertToMiles(); maximumSpeed = (filteredSessionData.MaxBy(s => s.Speed).Speed / 10).ConvertToMiles(); // calculate distance totalDistance = ((totalSpeed / 10) / totalCount * totalTimeInHours).ConvertToMiles(); // calculate altitiude - convert metres to feet totalAltitude = filteredSessionData.Sum(s => s.Altitude / 10); averageAltitude = (totalAltitude / totalCount).ConvertToFeet(); maximumAltitude = (filteredSessionData.MaxBy(s => s.Altitude).Altitude / 10).ConvertToFeet(); } else { // calculate speed - divided speed by 10 as speed is *10 in file totalSpeed = filteredSessionData.Sum(s => s.Speed); averageSpeed = Math.Round((totalSpeed / 10) / totalCount, 2, MidpointRounding.AwayFromZero); maximumSpeed = Math.Round( filteredSessionData.MaxBy(s => s.Speed).Speed / 10, 2, MidpointRounding.AwayFromZero); // calculate distance totalDistance = Math.Round(averageSpeed * totalTimeInHours, 2, MidpointRounding.AwayFromZero); // calculate altitiude totalAltitude = filteredSessionData.Sum(s => s.Altitude / 10); averageAltitude = Math.Round(totalAltitude / totalCount, 2, MidpointRounding.AwayFromZero); maximumAltitude = Math.Round(filteredSessionData.MaxBy(s => s.Altitude).Altitude / 10, 2, MidpointRounding.AwayFromZero); } } // calculate heart rate var totalHeartRate = filteredSessionData.Sum(s => s.HeartRate); var averageHeartRate = Math.Round(totalHeartRate / totalCount, 2, MidpointRounding.AwayFromZero); var minimumHeartRate = filteredSessionData.MinBy(s => s.HeartRate).HeartRate; var maximumHeartRate = filteredSessionData.MaxBy(s => s.HeartRate).HeartRate; // calculate power var totalPower = filteredSessionData.Sum(s => s.Power); var averagePower = Math.Round(totalPower / totalCount, 2, MidpointRounding.AwayFromZero); var maximumPower = Math.Round(filteredSessionData.MaxBy(s => s.Power).Power, 2, MidpointRounding.AwayFromZero); // calculate cadence var totalCadence = filteredSessionData.Sum(s => s.Cadence); var averageCadence = Math.Round(totalCadence / totalCount, 2, MidpointRounding.AwayFromZero); var maximumCadence = Math.Round(filteredSessionData.MaxBy(s => s.Cadence).Cadence, 2, MidpointRounding.AwayFromZero); // calculate normalized power var filteredSessionDto = new SessionDto() { Interval = session.Interval, SessionData = filteredSessionData }; var normalizedPower = filteredSessionDto.CalculateNormalizedPower(); // calculate intensity factor var functionalThresholdPower = _context.Athletes.Single(a => a.Id == session.AthleteId).FunctionalThresholdPower; var intensityFactor = normalizedPower.CalculateIntensityFactor(functionalThresholdPower); // calculate training stress score var sessionTimeInSeconds = filteredSessionData.Count * filteredSessionDto.Interval; //session.Length.TimeOfDay.TotalSeconds; double trainingStressScore = 0; string trainingStressScoreStatus = ""; if (normalizedPower != 0) { trainingStressScore = Metrics.CalculateTrainingStressScore(sessionTimeInSeconds, normalizedPower, intensityFactor, functionalThresholdPower); trainingStressScoreStatus = Metrics.TrainingStressScoreStatus(trainingStressScore); } var sessionSummaryDto = new SessionSummaryDto() { AverageAltitude = averageAltitude, MaximumAltitude = maximumAltitude, AverageHeartRate = averageHeartRate, MinimumHeartRate = minimumHeartRate, MaximumHeartRate = maximumHeartRate, AveragePower = averagePower, MaximumPower = maximumPower, AverageCadence = averageCadence, MaximumCadence = maximumCadence, AverageSpeed = averageSpeed, MaximumSpeed = maximumSpeed, TotalDistance = totalDistance, NormalizedPower = normalizedPower, IntensityFactor = intensityFactor, TrainingStressScore = trainingStressScore, TrainingStressScoreStatus = trainingStressScoreStatus, Date = session.Date, SessionId = session.Id }; return sessionSummaryDto; }
public void SubsetOfSessionDataShouldBeReturnedForSpecifiedSeconds() { var sessionDataSubsetdto = new SessionDataSubsetDto() { MinimumSecond = 2, MaximumSecond = 4, SessionId = 1 }; var filteredDates = _sessionRepository.GetSessionDataSubset(sessionDataSubsetdto); var averageSpeed = filteredDates.AverageSpeed; var averageHeartRate = filteredDates.AverageHeartRate; var averageAltitude = filteredDates.AverageAltitude; var averagePower = filteredDates.AveragePower; Assert.AreEqual(29.63, averageSpeed); Assert.AreEqual(132.0, averageHeartRate); Assert.AreEqual(3.2, averageAltitude); Assert.AreEqual(704.33, averagePower); }
public HttpResponseMessage GetSingleIntervalSummary(HttpRequestMessage request, SessionDataSubsetDto sessionDataSubsetDto) { return CreateHttpResponse(request, () => { var intervalSummary = _sessionRepository.GetSingleIntervalSummary(sessionDataSubsetDto); HttpResponseMessage response = request.CreateResponse(HttpStatusCode.OK, intervalSummary); return response; }); }
public HttpResponseMessage GetSessionDataSubset(HttpRequestMessage request, SessionDataSubsetDto sessionDataSubsetDto) { return CreateHttpResponse(request, () => { var sessionSummaryDto = _sessionRepository.GetSessionDataSubset(sessionDataSubsetDto); HttpResponseMessage response = request.CreateResponse(HttpStatusCode.OK, sessionSummaryDto); return response; }); }