Beispiel #1
0
        /// <summary>
        /// Gets the cached track if available, or calculates from scratch if not available.
        /// </summary>
        /// <param name="activity">Activity to calculate</param>
        /// <param name="chartType">Which track to calculate</param>
        /// <param name="create">Cache the track if it doesn't exist.
        /// True will always return a track.
        /// False will return the cached track, or null if not already cached.</param>
        /// <returns>Cached track if available, or empty track if not found.</returns>
        private static INumericTimeDataSeries GetMeanMaxTrack(IActivity activity, Common.TrackType chartType, out INumericTimeDataSeries timeTrack, bool create)
        {
            if (activity == null)
            {
                timeTrack = new NumericTimeDataSeries();
                return(new NumericTimeDataSeries());
            }

            string id = activity.ReferenceId + chartType;

            if (tracks.ContainsKey(id))
            {
                // Returned cached value from memory :)
                timeTrack = tracks[id + "T"];
                return(tracks[id]);
            }
            else if (create)
            {
                // Not in cache, create a new mean-max track :(
                INumericTimeDataSeries track = new NumericTimeDataSeries();
                timeTrack = null;

                switch (chartType)
                {
                case Common.TrackType.HR:
                {
                    track = GetMeanMaxTrack(activity.HeartRatePerMinuteTrack, out timeTrack, activity.StartTime);
                    break;
                }

                case Common.TrackType.Power:
                {
                    track = GetMeanMaxTrack(activity.PowerWattsTrack, out timeTrack, activity.StartTime);
                    break;
                }

                case Common.TrackType.Cadence:
                {
                    track = GetMeanMaxTrack(activity.CadencePerMinuteTrack, out timeTrack, activity.StartTime);
                    break;
                }
                }

                // Add data track and related 'T'ime track to cache for next time
                MeanMaxCache.AddTrack(track, id);
                MeanMaxCache.AddTrack(timeTrack, id + "T");

                return(track);
            }
            else
            {
                // Not previously cached, AND requested not to create a new cached item.
                timeTrack = new NumericTimeDataSeries();
                return(null);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Get critical value track.  This is the full track of critical values for various activities over a date range until 'now'.
        /// /// </summary>
        /// <param name="activities">The list of activities to consider</param>
        /// <param name="trackType">Which data track to evaluate</param>
        /// <param name="seconds">The critical period, measured in seconds.  Example, for 5 minute power this would be 300.</param>
        /// <returns>Returns a data track of values over a date range.  1 value per day.</returns>
        internal static INumericTimeDataSeries GetCriticalTrack(IEnumerable <IActivity> activities, Common.TrackType trackType, float seconds)
        {
            float criticalValue = 0;
            SortedList <DateTime, float> criticalData = new SortedList <DateTime, float>();
            INumericTimeDataSeries       criticalTrack = new NumericTimeDataSeries();
            float i = 0, count = (activities as List <IActivity>).Count;


            // Populate activity data
            foreach (IActivity activity in activities)
            {
                Progress = (int)(i++ / count * 100f);
                Application.DoEvents();

                // Filter bad data
                if (activity.StartTime.Year != 1)
                {
                    criticalValue = MeanMaxCache.GetCriticalValue(activity, trackType, seconds);
                    if (!float.IsNaN(criticalValue))
                    {
                        DateTime activityDate = activity.StartTime.Add(activity.TimeZoneUtcOffset).Date;

                        if (criticalData.ContainsKey(activityDate))
                        {
                            // Handle days with multiple activities
                            // Update with higher value
                            criticalData[activityDate] = Math.Max(criticalValue, criticalData[activityDate]);
                        }
                        else if (criticalValue != 0)
                        {
                            // Add critical value to data set
                            criticalData.Add(activityDate, criticalValue);
                        }
                    }
                }
            }

            // Construct critical data track
            DateTime firstDate;

            if (criticalData.Count > 0)
            {
                firstDate     = criticalData.Keys[0];
                criticalValue = criticalData[firstDate];
            }
            else
            {
                firstDate = DateTime.Now;
            }
            float value;

            for (DateTime day = firstDate; day < DateTime.Now;)
            {
                // Decay the critical value first, value for 'today'
                //criticalValue = criticalValue - criticalValue / GlobalSettings.Instance.TCc;

                if (criticalData.TryGetValue(day.Date, out value))
                {
                    // TODO: Determine best way to incorporate decay values
                    // Value recorded for today or previous (decayed) value
                    //criticalValue = Math.Max(value, criticalValue);
                    //criticalTrack.Add(day, criticalValue);
                    criticalTrack.Add(day, value);
                }
                else
                {
                    // Decayed value
                    //criticalTrack.Add(day, criticalValue);
                }
                // Next day
                day = day.AddDays(1);
            }

            Progress = -1;

            return(criticalTrack);
        }