private static NgMattSleepSession JoinSessions(NgMattSleepSession priorSession, NgMattSleepSession subsequentSession)
        {
            NgMattSleepSession joined = new NgMattSleepSession()
            {
                SessionId = priorSession.SessionId, Start = priorSession.Start, End = subsequentSession.End
            };
            List <Movement> movements = new List <Movement>(priorSession.Movements);

            movements.AddRange(subsequentSession.Movements);
            joined.Movements = movements.AsReadOnly();
            return(joined);
        }
Ejemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="session"></param>
        /// <returns></returns>
        public static SqiResult CalculateSQI(NgMattSleepSession session)
        {
            try
            {
                if (session == null || session.Movements == null || session.Movements.Count < 1)
                {
                    return(null);
                }

                //group movements by hour
                Dictionary <int, List <Movement> > groupedMovements = new Dictionary <int, List <Movement> >();

                DateTime currentTime = session.Movements.First().Start;
                int      currentHour = 1;

                foreach (Movement movement in session.Movements)
                {
                    if (!groupedMovements.ContainsKey(currentHour))
                    {
                        groupedMovements.Add(currentHour, new List <Movement>());
                    }

                    while (movement.Start >= currentTime.AddHours(1))
                    {
                        currentTime = currentTime.AddHours(1);
                        currentHour++;

                        groupedMovements.Add(currentHour, new List <Movement>());
                    }

                    groupedMovements[currentHour].Add(movement);
                }

                int points = 0;
                foreach (var group in groupedMovements)
                {
                    points += GetPointsForMovementGroup(group);
                }

                double sqi_raw     = (double)points / groupedMovements.Count; //SQI = points / total number of hours slept
                double sqi_percent = GetSqiPercentage(sqi_raw);               //gives a value between 0 and 100

                return(new SqiResult()
                {
                    NumberOfMovements = session.Movements.Count, Points = points, SQI_Percent = sqi_percent
                });
            }
            catch (Exception ex)
            {
                Logging.Logger.AddLogEntry(Logging.Logger.LogEntryCategories.Error, "Error while calculating SQI for session with id: " + session.SessionId, ex, "SleepQualityIndex");
                return(null);
            }
        }
        /// <summary>
        /// Expects a list of sleep sessions that were all recorded for one person during one or more nights (sleep sessions).
        /// This method attempts to split and recombine the sleep sessions in a way that in the end the correct number of sleep sessions is found.
        /// </summary>
        /// <param name="sourceSessions"></param>
        /// <returns></returns>
        public static List <NgMattSleepSession> PreprocessSleepSessions(List <NgMattSleepSession> sourceSessions)
        {
            return(sourceSessions); //feature is currently deactivated to make sure the received sessions are all inserted into the database 1:1

            sourceSessions = sourceSessions.OrderBy(s => s.Start).ToList();
            List <NgMattSleepSession> processedSessions = new List <NgMattSleepSession>();
            NgMattSleepSession        lastSession       = null;

            foreach (NgMattSleepSession source in sourceSessions)
            {
                if (source.Length > TimeSpan.FromHours(14))
                {
                    Logger.AddLogEntry(Logger.LogEntryCategories.Warning, "A very long session was uploaded (" + source.Length.TotalHours + " hours). Start of session: " + source.Start, null, "SleepSessionPreprocessor");
                }

                if (lastSession == null)
                {
                    lastSession = source;
                    continue;
                }

                if (lastSession.Start.AddHours(1) < lastSession.Start) //if the current and the last session are apart by more than 1 hour, they can not be joined together
                {
                    if (lastSession.Length.TotalHours > 1)
                    {
                        processedSessions.Add(lastSession); //add the last session to the output list if the sleep duration was at least 1 hour
                    }
                    else
                    {
                        Logger.AddLogEntry(Logger.LogEntryCategories.Debug, "Discarding session with length: " + (int)lastSession.Length.TotalMinutes + "min", null, "SleepSessionPreprocessor");
                    }

                    lastSession = source;
                    continue;
                }

                //join the 2 sessions together and continue one with the resulting session
                Logger.AddLogEntry(Logger.LogEntryCategories.Debug, "Joining the following 2 sessions: " + lastSession.Start + " / " + lastSession.End + " and " + source.Start + " / " + source.End + ". Total number of movements: " + (lastSession.Movements.Count + source.Movements.Count), null, "SleepSessionPreprocessor");
                NgMattSleepSession joinedSession = JoinSessions(lastSession, source);
                lastSession = joinedSession;
                processedSessions.Add(lastSession);
            }

            Logger.AddLogEntry(Logger.LogEntryCategories.Debug, "Returning processed sessions. Source session count: " + sourceSessions.Count + ". Resulting session count: " + processedSessions, null, "SleepSessionPreprocessor");
            return(processedSessions);
        }