Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sleep minor revisions #1242

Merged
merged 17 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,25 @@
# CHANGES IN GGIR VERSION 3.1-?

- Part 4:
vincentvanhees marked this conversation as resolved.
Show resolved Hide resolved

- Identification of daylight saving time days in the detection of the spt is improved as it had the risk to misclassify partial first/last days as daylight saving time.
vincentvanhees marked this conversation as resolved.
Show resolved Hide resolved

- In days classified as daysleeper, the window over which the fraction_night_invalid is calculated now also shifts to 6pm-6pm, as it used to report the nonwear within 12pm-12pm.


# CHANGES IN GGIR VERSION 3.1-8
vincentvanhees marked this conversation as resolved.
Show resolved Hide resolved

- Part 4: Parameter sib_must_fully_overlap_with_TimeInBed added to control whether sib should overlap fully with the start and/or end of time in bed to be considered sleep (default TRUE),
- Part 4:

- Parameter sib_must_fully_overlap_with_TimeInBed added to control whether sib should overlap fully with the start and/or end of time in bed to be considered sleep (default TRUE),
this is consistent with functionality in the past. #1223

- Handle unexpected combinations of sleep diary column names. For example, if only inbed and wakeup are available then treat these as the time in bed period, while if only sleeponset and outbed are available then these are treated as SPT window.

- Identification of daylight saving time days in the detection of the spt is improved as it had the risk to misclassify partial first/last days as daylight saving time.

- In days classified as daysleeper, the window over which the fraction_night_invalid is calculated now also shifts to 6pm-6pm, as it used to report the nonwear within 12pm-12pm.

- Part 5: Expand functionality for exploring possibility of nap detection, this includes the addition of new parameter possible_nap_gap.

- Visual report: Added new visualreport that is automatically generated when visualreport = TRUE and intended to eventually replace the problematic legacy report. Add parameter old_visualreport to turn off the old visualreport generation. #1173
Expand All @@ -14,8 +31,6 @@ this is consistent with functionality in the past. #1223
- Part 5 and 6: part6_threshold_combi when not specified now defaults to first threshold as
specified for light, moderate and vigorous intensity respectively.

- Part 4: Handle unexpected combinations of sleep diary column names. For example, if only inbed and wakeup are available then treat these as the time in bed period, while if only sleeponset and outbed are available then these are treated as SPT window.

# CHANGES IN GGIR VERSION 3.1-7

- Part 3: Improved handling of DST, #1225
Expand Down
2 changes: 1 addition & 1 deletion R/HASPT.R
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,4 @@ HASPT = function(angle, sptblocksize = 30, spt_max_gap = 60, ws3 = 5,
}
invisible(list(SPTE_start = SPTE_start, SPTE_end = SPTE_end, tib.threshold = tib.threshold,
part3_guider = part3_guider))
}
}
24 changes: 19 additions & 5 deletions R/g.sib.det.R
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ g.sib.det = function(M, IMP, I, twd = c(-12, 12),
time_SPTE_end_hr = as.numeric(format(time_SPTE_end, format = "%H"))
time_SPTE_start_hr = as.numeric(format(time_SPTE_start, format = "%H"))
t0 = as.numeric(format(iso8601chartime2POSIX(tmpTIME[1], tz = tz), format = "%H"))
t1 = as.numeric(format(iso8601chartime2POSIX(tmpTIME[length(tmpTIME)], tz = tz), format = "%H"))
# redefinition of t1 in case window ends some epochs before 12:00:00
t1hms = format(iso8601chartime2POSIX(tmpTIME[length(tmpTIME)], tz = tz), format = "%H:%M:%S")
t1hms = as.numeric(unlist(strsplit(t1hms, ":", fixed = T)))
t1 = ceiling(sum(c(t1hms[1], t1hms[2]/60, t1hms[3]/3600)))
vincentvanhees marked this conversation as resolved.
Show resolved Hide resolved
if (is.na(t1) == TRUE | is.na(t0) == TRUE) {
# if timestamp is stored in POSIX format (older versions of GGIR prior 2017)
# for example when milestone data generated by old packages is now processed
Expand Down Expand Up @@ -310,8 +313,18 @@ g.sib.det = function(M, IMP, I, twd = c(-12, 12),
if (newqqq2 > length(anglez)) newqqq2 = length(anglez)
# only try to extract SPT again if it is possible to extract a window of more than 23 hour
if (newqqq2 < length(anglez) & (newqqq2 - newqqq1) > (23*(3600/ws3)) ) {
# Recalculate nonwear percentage for new window (6pm to 6pm)
nonwear_percentage = (length(which(invalid[newqqq1:newqqq2] == 1)) / (newqqq2 - newqqq1 + 1)) * 100
guider_to_use = 1
if (params_sleep[["HASPT.algo"]][1] == "NotWorn" &&
nonwear_percentage < 25 &&
length(params_sleep[["HASPT.algo"]]) == 2) {
vincentvanhees marked this conversation as resolved.
Show resolved Hide resolved
# Nonwear percentage was low, so use alternative guider specified as second element
guider_to_use = 2
}
# new TIME (6pm tp 6pm)
tmpTIME = time[newqqq1:newqqq2]
if (params_sleep[["HASPT.algo"]][1] != "NotWorn") {
if (params_sleep[["HASPT.algo"]][guider_to_use] != "NotWorn") {
tmpANGLE = anglez[newqqq1:newqqq2]
if (do.HASPT.hip == TRUE) {
if (params_sleep[["longitudinal_axis"]] == 1) {
Expand All @@ -323,7 +336,7 @@ g.sib.det = function(M, IMP, I, twd = c(-12, 12),
}
spt_estimate_tmp = HASPT(angle = tmpANGLE, ws3 = ws3,
sptblocksize = sptblocksize, spt_max_gap = spt_max_gap,
HASPT.algo = params_sleep[["HASPT.algo"]][1],
HASPT.algo = params_sleep[["HASPT.algo"]][guider_to_use],
invalid = invalid[newqqq1:newqqq2],
HDCZA_threshold = params_sleep[["HDCZA_threshold"]],
HASPT.ignore.invalid = params_sleep[["HASPT.ignore.invalid"]],
Expand All @@ -342,7 +355,8 @@ g.sib.det = function(M, IMP, I, twd = c(-12, 12),
daysleep_offset = 0
}
}
if (qqq1 == 1 && partialFirstDay == TRUE) { # only use startTimeRecord if the start of the block send into SPTE was after noon
if (qqq1 == 1 && partialFirstDay == TRUE) {
# only use startTimeRecord if the start of the block send into SPTE was after noon
startTimeRecord = unlist(iso8601chartime2POSIX(IMP$metashort$timestamp[1], tz = desiredtz))
startTimeRecord = sum(as.numeric(startTimeRecord[c("hour", "min", "sec")]) / c(1, 60, 3600))
daysleep_offset = daysleep_offset + startTimeRecord
Expand Down Expand Up @@ -372,4 +386,4 @@ g.sib.det = function(M, IMP, I, twd = c(-12, 12),
SPTE_end = SPTE_end, SPTE_start = SPTE_start,
tib.threshold = tib.threshold, longitudinal_axis = params_sleep[["longitudinal_axis"]],
part3_guider = part3_guider))
}
}
Loading