Skip to content

Commit

Permalink
Merge pull request #1234 from wadpac/garmin
Browse files Browse the repository at this point in the history
Add UNIXmsec as additional timestamp format option for read.myacc.csv functionality
  • Loading branch information
vincentvanhees authored Nov 25, 2024
2 parents 2cc32ce + 5d0b308 commit fed05c7
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 27 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

- Part 2: Code revisions in preparation for expansion of functionality to better facilitate external function produced event data. #653 and #1228

- Part 1: Ad-hoc csv file formats (read.myacc.csv functionality) now also excepts "UNIXmsec" as optional timestamp format. #1233

- Part 5: Improved handling of partially available and non-available qwindow segments in the recording #1229

# CHANGES IN GGIR VERSION 3.1-6
Expand Down
39 changes: 20 additions & 19 deletions R/appendRecords.R
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,28 @@ appendRecords = function(metadatadir, desiredtz = "", idloc = 1, maxRecordingInt
} else {
N = overlap - 1
}
NEWSHORT = df[nrow(df), ]
NEWSHORT[1:N, ] = NEWSHORT
T0 = as.POSIXct(x = NEWSHORT$timestamp[1], format = "%Y-%m-%dT%H:%M:%S%z", tz = tz) + epochSize
NEWSHORT$timestamp = POSIXtime2iso8601(seq(T0, T0 + (N * epochSize) - 1, by = epochSize), tz)
if (pattern != "long") {
NEWSHORT[, grep(pattern = pattern, x = colnames(NEWSHORT), invert = TRUE, ignore.case = TRUE)] = 0
} else {
enCol = grep("en", colnames(NEWSHORT), ignore.case = TRUE)
NEWSHORT[, enCol] = 1
NEWSHORT$clippingscore = 0
NEWSHORT$nonwearscore = 3
if (any(colnames(NEWSHORT) %in% c("lightmean", "lightpeak"))) {
NEWSHORT$lightmean = 0
NEWSHORT$lightpeak = 0
}
if ("temperaturemean" %in% colnames(NEWSHORT)) {
NEWSHORT$temperaturemean = 0
if (N > 0) {
NEWSHORT = df[nrow(df), ]
NEWSHORT[1:N, ] = NEWSHORT
T0 = as.POSIXct(x = NEWSHORT$timestamp[1], format = "%Y-%m-%dT%H:%M:%S%z", tz = tz) + epochSize
NEWSHORT$timestamp = POSIXtime2iso8601(seq(T0, T0 + (N * epochSize) - 1, by = epochSize), tz)
if (pattern != "long") {
NEWSHORT[, grep(pattern = pattern, x = colnames(NEWSHORT), invert = TRUE, ignore.case = TRUE)] = 0
} else {
enCol = grep("en", colnames(NEWSHORT), ignore.case = TRUE)
NEWSHORT[, enCol] = 1
NEWSHORT$clippingscore = 0
NEWSHORT$nonwearscore = 3
if (any(colnames(NEWSHORT) %in% c("lightmean", "lightpeak"))) {
NEWSHORT$lightmean = 0
NEWSHORT$lightpeak = 0
}
if ("temperaturemean" %in% colnames(NEWSHORT)) {
NEWSHORT$temperaturemean = 0
}
}
df = rbind(df, NEWSHORT)
}

df = rbind(df, NEWSHORT)
return(df)
}
# insert missing values in metashort
Expand Down
10 changes: 8 additions & 2 deletions R/g.part5.R
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,14 @@ g.part5 = function(datadir = c(), metadatadir = c(), f0=c(), f1=c(),
desiredtz = params_general[["desiredtz"]],
sibDefinition = sibDef,
nightsi)
# Fix missing nights in part 4 data:
summarysleep_tmp2 = g.part5.fixmissingnight(summarysleep_tmp2, sleeplog = sleeplog, ID)
if (nrow(summarysleep_tmp2) > 0) {
if (!all(is.na(summarysleep_tmp$sleepparam))) {
# Fix missing nights in part 4 data:
summarysleep_tmp2 = g.part5.fixmissingnight(summarysleep_tmp2, sleeplog = sleeplog, ID)
} else {
summarysleep_tmp2 = summarysleep_tmp2[-which(is.na(summarysleep_tmp$sleepparam)), ]
}
}
#Initialise diur variable, which will indicate the diurnal rhythm: 0 if wake/daytime, 1 if sleep/nighttime
ts$diur = 0
if (nrow(summarysleep_tmp2) > 0) {
Expand Down
14 changes: 10 additions & 4 deletions R/read.myacc.csv.R
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ read.myacc.csv = function(rmc.file=c(), rmc.nrow=Inf, rmc.skip=c(), rmc.dec=".",
configtz = NULL,
header = NULL) {

if (length(rmc.col.time) > 0 && !(rmc.unit.time %in% c("POSIX", "character", "UNIXsec", "ActivPAL"))) {
stop("\nUnrecognized rmc.col.time value. The only accepted values are \"POSIX\", \"character\", \"UNIXsec\", and \"ActivPAL\".", call. = FALSE)
if (length(rmc.col.time) > 0 && !(rmc.unit.time %in% c("POSIX", "character", "UNIXsec", "UNIXmsec", "ActivPAL"))) {
stop(paste0("\nUnrecognized rmc.col.time value. The only accepted values are \"POSIX\", ",
"\"character\", \"UNIXsec\", \"UNIXmsec\", and \"ActivPAL\"."), call. = FALSE)
}

if (!is.null(rmc.desiredtz) || !is.null(rmc.configtz)) {
Expand Down Expand Up @@ -257,8 +258,13 @@ read.myacc.csv = function(rmc.file=c(), rmc.nrow=Inf, rmc.skip=c(), rmc.dec=".",
}
} else if (rmc.unit.time == "character") {
P$time = as.POSIXct(P$time, format = rmc.format.time, origin = rmc.origin, tz = configtz)
} else if (rmc.unit.time == "UNIXsec" && rmc.origin != "1970-01-01") {
P$time = as.POSIXct(P$time, origin = rmc.origin, tz = desiredtz)
} else if (rmc.unit.time == "UNIXsec" || rmc.unit.time == "UNIXmsec") {
if (rmc.unit.time == "UNIXmsec") {
P$time = P$time / 1000
}
if (rmc.origin != "1970-01-01") {
P$time = as.POSIXct(P$time, origin = rmc.origin, tz = desiredtz)
}
} else if (rmc.unit.time == "ActivPAL") {
# origin should be specified as: "1899-12-30"
rmc.origin = "1899-12-30"
Expand Down
3 changes: 2 additions & 1 deletion man/GGIR.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,8 @@ GGIR(mode = 1:5,
\item{rmc.unit.time}{
Character (default = "POSIX").
Character with unit of timestamps: "POSIX", "UNIXsec" (seconds since origin, see argument \code{rmc.origin}),
Character with unit of timestamps: "POSIX", "UNIXsec" (seconds since origin,
see argument \code{rmc.origin}), "UNIXmsec" (same as UNIXsec but in milliseconds),
"character", or "ActivPAL" (exotic timestamp format only used in the ActivPAL
activity monitor).}
Expand Down
35 changes: 35 additions & 0 deletions tests/testthat/test_read.myacc.csv.R
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ test_that("read.myacc.csv can handle files without header, no decimal places in
testfile[4] = "testcsv4.csv"
write.csv(S3, file = testfile[4], row.names = FALSE)

# UNIXsec
testfile[5] = "testcsv5.csv"
S5 = S1
S5$time = as.numeric(S5$time)
write.csv(S5, file = testfile[5], row.names = FALSE)

# UNIXmsec
testfile[6] = "testcsv6.csv"
S6 = S5
S6$time = S6$time * 1000
write.csv(S6, file = testfile[6], row.names = FALSE)

# attempt to load
D1 = read.myacc.csv(rmc.file = testfile[1], rmc.nrow = 20, rmc.dec = ".",
rmc.firstrow.acc = 1, rmc.firstrow.header = c(),
Expand Down Expand Up @@ -196,6 +208,29 @@ test_that("read.myacc.csv can handle files without header, no decimal places in
expect_that(ncol(D4$data), equals(4))
expect_that(D4$header, equals("no header"))

# Timestamps in UNIXsec
D5 = read.myacc.csv(rmc.file = testfile[5], rmc.nrow = 20, rmc.dec = ".",
rmc.firstrow.acc = 1, rmc.firstrow.header = c(),
rmc.col.acc = c(1,3,4), rmc.col.temp = 5, rmc.col.time = 2,
rmc.unit.acc = "g",
rmc.unit.time = "UNIXsec",
desiredtz = "Europe/London", rmc.sf = sf)

expect_equal(mean(D5$data$x), 0.1078671, tol = 0.0001)
expect_equal(mean(D5$data$y), -0.06675716, tol = 0.0001)
expect_equal(D5$data$time[1], 1667394076, tol = 0.1)

# Timestamps in UNIXmsec
D6 = read.myacc.csv(rmc.file = testfile[6], rmc.nrow = 20, rmc.dec = ".",
rmc.firstrow.acc = 1, rmc.firstrow.header = c(),
rmc.col.acc = c(1,3,4), rmc.col.temp = 5, rmc.col.time = 2,
rmc.unit.acc = "g",
rmc.unit.time = "UNIXmsec",
desiredtz = "Europe/London", rmc.sf = sf)
expect_equal(mean(D6$data$x), 0.1078671, tol = 0.0001)
expect_equal(mean(D6$data$y), -0.06675716, tol = 0.0001)
expect_equal(D6$data$time[1], 1667394076, tol = 0.1)

for (i in 1:length(testfile)) {
expect_true(file.exists(testfile[i]))
if (file.exists(testfile[i])) file.remove(testfile[i])
Expand Down
2 changes: 1 addition & 1 deletion vignettes/readmyacccsv.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Below we present a summary of the available input arguments. Please see the [par
### Arguments for files including timestamps

- `rmc.col.time` - Scalar with column (number) in which the timestamps are stored. Leave in default setting if timestamps are not stored.
- `rmc.unit.time` - Character with unit of timestamps: "POSIX", "UNIXsec" (seconds since origin, see argument rmc.origin), "character", or "ActivPAL" (exotic timestamp format only used in the ActivPAL activity monitor).
- `rmc.unit.time` - Character with unit of timestamps: "POSIX", "UNIXsec" (seconds since origin, see argument rmc.origin), "UNIXmsec" (milliseconds since origin, see argument rmc.origin), "character", or "ActivPAL" (exotic timestamp format only used in the ActivPAL activity monitor).
- `rmc.format.time` - Character string giving a date-time format as used by \link[base]{strptime}. Only used for rmc.unit.time: character and POSIX.
- `rmc.origin` - Origin of time when unit of time is UNIXsec, e.g. 1970-1-1.

Expand Down

0 comments on commit fed05c7

Please sign in to comment.