From 733d9b930cdb242bd29a33ddd7960d623bfc470b Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Wed, 5 Jun 2024 10:55:52 +0200 Subject: [PATCH 1/5] create central function to check milestone folders before running a part, fixes #1144 --- R/checkMilestoneFolders.R | 47 ++++++++++++++++++++++++++++++++++++ R/g.part2.R | 1 + R/g.part3.R | 10 +------- R/g.part4.R | 14 +++-------- R/g.part5.R | 4 +-- man/checkMilestoneFolders.Rd | 28 +++++++++++++++++++++ 6 files changed, 82 insertions(+), 22 deletions(-) create mode 100644 R/checkMilestoneFolders.R create mode 100644 man/checkMilestoneFolders.Rd diff --git a/R/checkMilestoneFolders.R b/R/checkMilestoneFolders.R new file mode 100644 index 000000000..2db4da7aa --- /dev/null +++ b/R/checkMilestoneFolders.R @@ -0,0 +1,47 @@ +checkMilestoneFolders = function(metadatadir, partNumber) { + if (partNumber == 1) return() + # This function checks where expected output folders exists and if necessary creates them + # Further it check whether folders with expected content are empty and if yes gives error. + paths = c(paste0(metadatadir, "/meta/basic"), + paste0(metadatadir, "/meta/ms2.out"), + paste0(metadatadir, "/meta/ms3.out"), + paste0(metadatadir, "/meta/ms4.out"), + paste0(metadatadir, "/meta/ms5.out")) + sleepqc = paste0(metadatadir, "/meta/sleep.qc") + + # Make sure folders exists + for (i in 1:partNumber) { + if (!dir.exists(paths[i])) { + dir.create(file.path(paths[i])) + } + } + if (partNumber >= 3) { + if (!dir.exists(sleepqc)) { + dir.create(file.path(sleepqc)) + } + } + + # Make sure preceding parts have files + if (partNumber == 2) { + expectedParts = 1 + } else if (partNumber == 3) { + expectedParts = 2 + } else if (partNumber == 4) { + expectedParts = 3 + } else if (partNumber == 5) { + expectedParts = c(2, 3, 4) + } + + # Give error when do data was found in the expected parts + warnAbout = NULL + for (i in expectedParts) { + N = length(dir(paths[i])) + if (N == 0) { + warnAbout = c(warnAbout, i) + } + } + if (length(warnAbout) > 0) { + stop(paste0("\nNo milestone data found for part(s) ", paste0(warnAbout, collapse = " and "), + ". Run this/these first before running part ", partNumber, "."), call. = FALSE) + } +} \ No newline at end of file diff --git a/R/g.part2.R b/R/g.part2.R index 68b0fdcdd..c60b693fb 100644 --- a/R/g.part2.R +++ b/R/g.part2.R @@ -29,6 +29,7 @@ g.part2 = function(datadir = c(), metadatadir = c(), f0 = c(), f1 = c(), #--------------------------------- # Specifying directories with meta-data and extracting filenames path = paste0(metadatadir,"/meta/basic/") #values stored per long epoch, e.g. 15 minutes + checkMilestoneFolders(metadatadir, partNumber = 2) fnames = dir(path) if (f1 > length(fnames)) f1 = length(fnames) # create output folders diff --git a/R/g.part3.R b/R/g.part3.R index c1152eaa6..c49f99960 100644 --- a/R/g.part3.R +++ b/R/g.part3.R @@ -16,15 +16,7 @@ g.part3 = function(metadatadir = c(), f0, f1, myfun = c(), params_general = params$params_general params_output = params$params_output - #---------------------------------------------------------- - # create output directory if it does not exist - if (!file.exists(paste(metadatadir, sep = ""))) { - dir.create(file.path(metadatadir)) - } - if (!file.exists(paste(metadatadir, "/meta/ms3.out", sep = ""))) { - dir.create(file.path(paste(metadatadir, "/meta", sep = ""), "ms3.out")) - dir.create(file.path(paste(metadatadir, "/meta", sep = ""), "sleep.qc")) - } + checkMilestoneFolders(metadatadir, partNumber = 3) #------------------------------------------------------ fnames = dir(paste(metadatadir,"/meta/ms2.out", sep = "")) if (f1 > length(fnames) | f1 == 0) f1 = length(fnames) diff --git a/R/g.part4.R b/R/g.part4.R index 5d4576f96..76e3eb00b 100644 --- a/R/g.part4.R +++ b/R/g.part4.R @@ -20,18 +20,11 @@ g.part4 = function(datadir = c(), metadatadir = c(), f0 = f0, f1 = f1, # possibly aided by sleep log/diary information (if available and provided by end-user) nnpp = 40 # number of nights to be displayed in the report (hard-coded not a critical parameter for most scenarios) #------------------------------------------------ - # check whether milestone 3 data exists, if not give warning + # check whether milestone 3 data exists, if not give error ms3.out = "/meta/ms3.out" - if (!file.exists(paste0(metadatadir,ms3.out))) { - if (verbose == TRUE) cat("Warning: First run g.part3 (mode = 3) before running g.part4 (mode = 4)") - } - # check whether milestone 4 data exists, if no create folder + meta.sleep.folder = paste0(metadatadir, ms3.out) ms4.out = "/meta/ms4.out" - if (file.exists(paste0(metadatadir,ms4.out))) { - } else { - dir.create(file.path(metadatadir,ms4.out)) - } - meta.sleep.folder = paste0(metadatadir,"/meta/ms3.out") + checkMilestoneFolders(metadatadir, partNumber = 4) #------------------------------------------------ # Get sleeplog data if (length(params_sleep[["loglocation"]]) > 0) { @@ -49,6 +42,7 @@ g.part4 = function(datadir = c(), metadatadir = c(), f0 = f0, f1 = f1, #------------------------------------------------ # get list of accelerometer milestone data files from sleep (produced by g.part3) fnames = dir(meta.sleep.folder) + if (f1 > length(fnames)) f1 = length(fnames) if (f0 > length(fnames)) f0 = 1 if (f1 == 0 | length(f1) == 0 | f1 > length(fnames)) f1 = length(fnames) diff --git a/R/g.part5.R b/R/g.part5.R index 18006e38b..7d59be15e 100644 --- a/R/g.part5.R +++ b/R/g.part5.R @@ -30,10 +30,8 @@ g.part5 = function(datadir = c(), metadatadir = c(), f0=c(), f1=c(), params_general = params$params_general #====================================================================== # create new folder (if not existent) for storing milestone data + checkMilestoneFolders(metadatadir, partNumber = 5) ms5.out = "/meta/ms5.out" - if (!file.exists(paste(metadatadir, ms5.out, sep = ""))) { - dir.create(file.path(metadatadir, ms5.out)) - } if (params_output[["save_ms5rawlevels"]] == TRUE | params_output[["do.sibreport"]] == TRUE) { ms5.outraw = "/meta/ms5.outraw" if (file.exists(paste(metadatadir, ms5.outraw, sep = ""))) { diff --git a/man/checkMilestoneFolders.Rd b/man/checkMilestoneFolders.Rd new file mode 100644 index 000000000..1a99354c4 --- /dev/null +++ b/man/checkMilestoneFolders.Rd @@ -0,0 +1,28 @@ +\name{checkMilestoneFolders} +\alias{checkMilestoneFolders} +\title{ + Checks for existence of folders to process +} +\description{ + Checks whether milestone folders exist, create them if needed, + and check whether folders are not empty. Only done for part 1 to 5 + and not part 6, which is different and handled inside \link{g.part6}. +} +\usage{ + checkMilestoneFolders(metadatadir, partNumber) +} +\arguments{ + \item{metadatadir}{ + Character, path to root of outputfolder. + } + \item{partNumber}{ + Numeric, number from the set 2, 3, 4 or 5. + } +} +\value{ + No value is produced +} +\keyword{internal} +\author{ + Vincent T van Hees +} From 76c8e605b70c6ec464f172105bc7353b122eaef0 Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Wed, 5 Jun 2024 10:59:17 +0200 Subject: [PATCH 2/5] minor edits to comments --- R/checkMilestoneFolders.R | 2 +- R/g.part4.R | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/R/checkMilestoneFolders.R b/R/checkMilestoneFolders.R index 2db4da7aa..4194912d8 100644 --- a/R/checkMilestoneFolders.R +++ b/R/checkMilestoneFolders.R @@ -32,7 +32,7 @@ checkMilestoneFolders = function(metadatadir, partNumber) { expectedParts = c(2, 3, 4) } - # Give error when do data was found in the expected parts + # Give error when no data was found in the expected parts warnAbout = NULL for (i in expectedParts) { N = length(dir(paths[i])) diff --git a/R/g.part4.R b/R/g.part4.R index 76e3eb00b..d431deea5 100644 --- a/R/g.part4.R +++ b/R/g.part4.R @@ -20,7 +20,6 @@ g.part4 = function(datadir = c(), metadatadir = c(), f0 = f0, f1 = f1, # possibly aided by sleep log/diary information (if available and provided by end-user) nnpp = 40 # number of nights to be displayed in the report (hard-coded not a critical parameter for most scenarios) #------------------------------------------------ - # check whether milestone 3 data exists, if not give error ms3.out = "/meta/ms3.out" meta.sleep.folder = paste0(metadatadir, ms3.out) ms4.out = "/meta/ms4.out" From 6067eaad9f3cec4b75d4754923163cb322646172 Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Wed, 5 Jun 2024 11:11:42 +0200 Subject: [PATCH 3/5] add unit test for check of milestone folders #1144 --- R/checkMilestoneFolders.R | 4 ++-- tests/testthat/test_checkMilestoneFolders.R | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 tests/testthat/test_checkMilestoneFolders.R diff --git a/R/checkMilestoneFolders.R b/R/checkMilestoneFolders.R index 4194912d8..f0583e949 100644 --- a/R/checkMilestoneFolders.R +++ b/R/checkMilestoneFolders.R @@ -12,12 +12,12 @@ checkMilestoneFolders = function(metadatadir, partNumber) { # Make sure folders exists for (i in 1:partNumber) { if (!dir.exists(paths[i])) { - dir.create(file.path(paths[i])) + dir.create(file.path(paths[i]), recursive = TRUE) } } if (partNumber >= 3) { if (!dir.exists(sleepqc)) { - dir.create(file.path(sleepqc)) + dir.create(file.path(sleepqc), recursive = TRUE) } } diff --git a/tests/testthat/test_checkMilestoneFolders.R b/tests/testthat/test_checkMilestoneFolders.R new file mode 100644 index 000000000..fed7c7282 --- /dev/null +++ b/tests/testthat/test_checkMilestoneFolders.R @@ -0,0 +1,9 @@ +library(GGIR) +context("checkMilestoneFolders") +test_that("checkMilestoneFolders creates expected folders and gives expected warnings", { + test_folder = "test_milestone_folders" + dir.create(test_folder) + expect_error(checkMilestoneFolders(test_folder, partNumber = 5)) + expect_true(dir.exists(paste0(test_folder, "/meta/ms5.out"))) + if (dir.exists(test_folder)) unlink(test_folder, recursive = TRUE) +}) \ No newline at end of file From e8b2138af79a72a8a5953252acad78982c85ed39 Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Wed, 5 Jun 2024 11:13:34 +0200 Subject: [PATCH 4/5] Update NEWS.md --- NEWS.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS.md b/NEWS.md index ea194cef6..9c550d032 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +# CHANGES IN GGIR VERSION 3.1-2 + +- Parts 2-5: Give more informative error when folders with expected milestone files are empty. #1144 + # CHANGES IN GGIR VERSION 3.1-1 - Part 2: Corrected calculation of LXhr and MXhr which had one hour offset when timing was after midnight, #1117 From 4ce9db113331474563d0646b94cd3434cf97c0d0 Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Mon, 10 Jun 2024 18:14:46 +0200 Subject: [PATCH 5/5] tidy up code comment --- R/checkMilestoneFolders.R | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/R/checkMilestoneFolders.R b/R/checkMilestoneFolders.R index f0583e949..efcc41955 100644 --- a/R/checkMilestoneFolders.R +++ b/R/checkMilestoneFolders.R @@ -1,7 +1,9 @@ checkMilestoneFolders = function(metadatadir, partNumber) { if (partNumber == 1) return() - # This function checks where expected output folders exists and if necessary creates them - # Further it check whether folders with expected content are empty and if yes gives error. + # This function checks whether expected output folder(s) exists + # If not, it creates them + # Further it check whether folders with expected content are empty. + # If yesm it gives error. paths = c(paste0(metadatadir, "/meta/basic"), paste0(metadatadir, "/meta/ms2.out"), paste0(metadatadir, "/meta/ms3.out"),