From a25039efb2971349f5179b0c2555d7fd14e97dec Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Wed, 27 Sep 2023 17:00:30 +0200 Subject: [PATCH 01/13] explorative work --- R/check_params.R | 26 ++++++++++++++++--- R/myApp.R | 1 + .../params_description_ggir.tsv | 25 +++++++++--------- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/R/check_params.R b/R/check_params.R index c06a5e1..b8437a2 100644 --- a/R/check_params.R +++ b/R/check_params.R @@ -15,13 +15,29 @@ check_params = function(params = c(), tool = c()) { cnt = 1 if (length(numi) > 0) { for (i in numi) { + + val = params$value[i] + val = 0.9 + # Consider vectors specified with c() + num_value = unlist(lapply(strsplit(x = as.character(val), "[(]|[)]|[,]|c"), function(x){x[!x == ""]})) + # Consider vectors specified with : + val2expand = grep(pattern = ":", x = num_value) + if (length(val2expand) > 0) { + for (vi in 1:length(val2expand)) { + tmp = as.numeric(unlist(strsplit(num_value[val2expand[vi]], ":"))) + num_value = c(num_value, tmp[1]:tmp[2]) + } + num_value = num_value[-val2expand] + } + + # Attempt to turn into numeric try(expr = { num_value = suppressWarnings( - as.numeric(unlist(lapply(strsplit(x = as.character(params$value[i]), "[(]|[)]|[,]|c"), function(x){x[!x == ""]}))) + as.numeric(num_value) ) }, silent = TRUE) test_na = any(is.na(num_value)) - if (test_na == TRUE) { + if (test_na == TRUE || length(num_value) == 0) { blocked_params$name[cnt] = rowNames[i] blocked_params$error[cnt] = "is not numeric" cnt = cnt + 1 @@ -29,7 +45,9 @@ check_params = function(params = c(), tool = c()) { if (length(num_value) > 1) { if (tool == "GGIR") { nc = nchar(params$value[i]) - if (substr(params$value[i], 1, 2) != "c(" | substr(params$value[i], nc, nc) != ")") { + print(nc) + if ((substr(params$value[i], 1, 2) != "c(" | substr(params$value[i], nc, nc) != ")") & + length(grep(pattern = ":", x = params$value[i])) == 0) { blocked_params$name[cnt] = rowNames[i] blocked_params$error[cnt] = "numeric vector needs to start with c( and end with ), with values separated by a comma" cnt = cnt + 1 @@ -39,6 +57,8 @@ check_params = function(params = c(), tool = c()) { } if (test_na == FALSE) { if (params$class[i] == "integer") { + print(num_value) + print(rowNames[i]) if (any(round(num_value) != num_value)) { blocked_params$name[cnt] = rowNames[i] blocked_params$error[cnt] = "is not an integer" diff --git a/R/myApp.R b/R/myApp.R index 1a0d602..a2a7be9 100644 --- a/R/myApp.R +++ b/R/myApp.R @@ -13,6 +13,7 @@ # HabitusGUI::myApp(homedir="~/projects") # options("sp_evolution_status" = 2) # pkgload::load_all("."); myApp(homedir="D:/Dropbox/Work/sharedfolder/DATA/Habitus") +# myApp(homedir="D:/Dropbox/Work/sharedfolder/DATA/Habitus/GPSprocessing/Teun/Driestam") # roxygen2::roxygenise() diff --git a/inst/testfiles_ggir/params_description_ggir.tsv b/inst/testfiles_ggir/params_description_ggir.tsv index fc8e41f..fb00d58 100644 --- a/inst/testfiles_ggir/params_description_ggir.tsv +++ b/inst/testfiles_ggir/params_description_ggir.tsv @@ -2,26 +2,25 @@ parameter field subfield display class minimum maximum set priority description overwrite general TRUE set TRUE;FALSE 1 Logical (default = FALSE) to indicate if the existent analysis of milestone data should be overwritten or not. mode general TRUE integer 1 5 1;2;3;4;5 1 Numeric (default = 1:5). Specify which of the five parts of the GGIR pipeline need to be run. acc.metric general TRUE set ENMO;ENMOa;MAD;NeishabouriCount_x;NeishabouriCount_y;NeishabouriCount_z;NeishabouriCount_vm;LFENMO 0 Character to define the acceleration metric to use for description and analysis of physical activity. -windowsizes general TRUE integer 1 3600 0 Numeric vector of three values (default = c(5, 900, 3600)) to indicate the lengths of the windows in seconds for epoch, non-wear detection resolution, and non-wear detection window, respectively. -desiredtz general TRUE timezone 1 Timezone in which device was configured and experiments took place according to the timezone database (https://en.wikipedia.org/wiki/Zone.tab). If empty, then local timezone where the app is run will be used. -configtz general TRUE timezone 1 Timezone in which device was configured in the case that it is different from the timezone in which the experiment took place (see desiredtz) according to the timezone database (https://en.wikipedia.org/wiki/Zone.tab). If empty, then local timezone where the app is run will be used. -idloc general TRUE set 1;2;3;4;5;6;7 1 How participant identifier should be extracted: idloc = 1 (default), ID number is stored in the obvious header field. Note that for ActiGraph data the ID is never stored in the file header. For idloc value set to 2, 5, 6, and 7, GGIR looks at the filename and extracts the character string preceding the first occurance of a '_', ' ' (space), '.' (dot), and '-', respectively. +windowsizes general TRUE integer 1 3600 0 "Numeric vector of three values (default = c(5, 900, 3600)) to indicate the lengths of the windows in seconds for epoch, non-wear detection resolution, and non-wear detection window, respectively." +desiredtz general TRUE timezone 1 "Timezone in which device was configured and experiments took place according to the timezone database (https://en.wikipedia.org/wiki/Zone.tab). If empty, then local timezone where the app is run will be used." +configtz general TRUE timezone 1 "Timezone in which device was configured in the case that it is different from the timezone in which the experiment took place (see desiredtz) according to the timezone database (https://en.wikipedia.org/wiki/Zone.tab). If empty, then local timezone where the app is run will be used." +idloc general TRUE set 1;2;3;4;5;6;7 1 "How participant identifier should be extracted: idloc = 1 (default), ID number is stored in the obvious header field. Note that for ActiGraph data the ID is never stored in the file header. For idloc value set to 2, 5, 6, and 7, GGIR looks at the filename and extracts the character string preceding the first occurance of a '_', ' ' (space), '.' (dot), and '-', respectively." colid sleep TRUE integer 1 100 0 Column number in the sleep log spreadsheet in which the participant ID code is stored (default = 1) coln1 sleep TRUE integer 1 1000 0 Column number in the sleep log spreadsheet where the onset of the first night starts (default = 2) excludefirstlast sleep TRUE set TRUE;FALSE 0 If TRUE then the first and last night of the measurement are ignored for the sleep assessment. excludefirst.part4 sleep TRUE set TRUE;FALSE 0 If TRUE then the first night of the measurement are ignored for the sleep assessment. excludelast.part4 sleep TRUE set TRUE;FALSE 0 If TRUE then the last night of the measurement are ignored for the sleep assessment. -includenightcrit sleep TRUE integer 0 24 0 Minimum number of valid hours per night (24 hour window between noon and noon, or between 6pm and 6pm in the case that wake up occurs after noon) -nnights sleep TRUE integer 0 1000 0 Number of nights for which sleep log information should be available. It assumes that this is constant within a study. If sleep log information is missing for certain nights then leave these blank +includenightcrit sleep TRUE integer 0 24 0 "Minimum number of valid hours per night (24 hour window between noon and noon, or between 6pm and 6pm in the case that wake up occurs after noon)" boutcriter.in physical activity TRUE double 0 1 0 A number between 0 and 1 and defines what fraction of a bout needs to be below the light threshold boutcriter.lig physical activity TRUE double 0 1 0 A number between 0 and 1 and defines what fraction of a bout needs to be between the light and moderate threshold boutcriter.mvpa physical activity TRUE double 0 1 0 A number between 0 and 1 and defines what fraction of a bout needs to be above the MVPA threshold -boutdur.in physical activity TRUE double 0 1000 0 Durations of inactivty bouts in minutes to be extracted. Inactivity bouts are detected in the segments of the data which were not labelled as sleep or MVPA bouts. The default duration values is c(10,20,30), this will start with the identification of 30 minute bouts, followed by 20 minute bouts in the rest of the data, and followed by 10 minute bouts in the rest of the data -boutdur.lig physical activity TRUE double 0 1000 0 Durations of light activty bouts in minutes to be extracted. Light activity bouts are detected in the segments of the data which were not labelled as sleep, MVPA, or inactivity bouts. The default duration values is c(1,5,10), this will start with the identification of 10 minute bouts, followed by 5 minute bouts in the rest of the data, and followed by 1 minute bouts in the rest of the data -boutdur.mvpa physical activity TRUE integer 0 1000 0 Durations of mvpa bouts in minutes to be extracted. The default values is c(1,5,10) and will start with the identification of 10 minute bouts, followed by 5 minute bouts in the rest of the data, and followed by 1 minute bouts in the rest of the data. -threshold.lig physical activity TRUE integer 0 10000 0 Threshold for light physical activity to separate inactivity from light. Value can be one number or an array of multiple numbers, e.g. threshold.lig =c(30,40). If multiple numbers are entered then analysis will be replicated for each combination of threshold values. Remove this as only ENMO supported in the app: Threshold is applied to the first metric in the milestone data, so if you have only specified do.ENMO == TRUE then it will be applied to ENMO. -threshold.mod physical activity TRUE double 0 10000 0 Threshold for moderate physical activity to separate light from moderate. Value can be one number or an array of multiple numbers, e.g. threshold.mod =c(100,110). If multiple numbers are entered then analysis will be repliced for each combination of threshold values. Remove this as only ENMO supported in the app: Threshold is applied to the first metric in the milestone data, so if you have only specified do.ENMO == TRUE then it will be applied to ENMO. -threshold.vig physical activity TRUE double 0 10000 0 Threshold for vigorous physical activity to separate moderate from vigorous. Value can be one number or an array of multiple numbers, e.g. threshold.mod=c(400,500). If multiple numbers are entered then analysis will be repliced for each combination of threshold values. Remove this as only ENMO supported in the app: Threshold is applied to the first metric in the milestone data, so if you have only specified do.ENMO == TRUE then it will be applied to ENMO. +boutdur.in physical activity TRUE double 0 1000 0 "Durations of inactivty bouts in minutes to be extracted. Inactivity bouts are detected in the segments of the data which were not labelled as sleep or MVPA bouts. The default duration values is c(10,20,30), this will start with the identification of 30 minute bouts, followed by 20 minute bouts in the rest of the data, and followed by 10 minute bouts in the rest of the data" +boutdur.lig physical activity TRUE double 0 1000 0 "Durations of light activty bouts in minutes to be extracted. Light activity bouts are detected in the segments of the data which were not labelled as sleep, MVPA, or inactivity bouts. The default duration values is c(1,5,10), this will start with the identification of 10 minute bouts, followed by 5 minute bouts in the rest of the data, and followed by 1 minute bouts in the rest of the data" +boutdur.mvpa physical activity TRUE double 0 1000 0 "Durations of mvpa bouts in minutes to be extracted. The default values is c(1,5,10) and will start with the identification of 10 minute bouts, followed by 5 minute bouts in the rest of the data, and followed by 1 minute bouts in the rest of the data." +threshold.lig physical activity TRUE double 0 10000 0 "Threshold for light physical activity to separate inactivity from light. Value can be one number or an array of multiple numbers, e.g. threshold.lig =c(30,40). If multiple numbers are entered then analysis will be replicated for each combination of threshold values. Remove this as only ENMO supported in the app: Threshold is applied to the first metric in the milestone data, so if you have only specified do.ENMO == TRUE then it will be applied to ENMO." +threshold.mod physical activity TRUE double 0 10000 0 "Threshold for moderate physical activity to separate light from moderate. Value can be one number or an array of multiple numbers, e.g. threshold.mod =c(100,110). If multiple numbers are entered then analysis will be repliced for each combination of threshold values. Remove this as only ENMO supported in the app: Threshold is applied to the first metric in the milestone data, so if you have only specified do.ENMO == TRUE then it will be applied to ENMO." +threshold.vig physical activity TRUE double 0 10000 0 "Threshold for vigorous physical activity to separate moderate from vigorous. Value can be one number or an array of multiple numbers, e.g. threshold.mod=c(400,500). If multiple numbers are entered then analysis will be repliced for each combination of threshold values. Remove this as only ENMO supported in the app: Threshold is applied to the first metric in the milestone data, so if you have only specified do.ENMO == TRUE then it will be applied to ENMO." excludefirstlast.part5 physical activity TRUE set TRUE;FALSE 0 If TRUE then the first and last window (waking-waking or midnight-midnight) are ignored in the part 5 reports. includedaycrit physical activity TRUE integer 0 24 0 Minimum required number of valid hours in day specific analysis (24 hour window between midnight and midnight) -includedaycrit.part5 physical activity TRUE double 0 24 0 Inclusion criteria for number of valid hours for the waking time window, either as expressed as a ratio of 1 or as the number of hours in a 24 hour day. +includedaycrit.part5 physical activity TRUE double 0 24 0 "Inclusion criteria for number of valid hours for the waking time window, either as expressed as a ratio of 1 or as the number of hours in a 24 hour day." From a36e04eed699b9faf467fccbe85402ecfa136ef7 Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Wed, 27 Sep 2023 17:37:51 +0200 Subject: [PATCH 02/13] improve specification of integer vectors #94 --- R/check_params.R | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/R/check_params.R b/R/check_params.R index b8437a2..47a1f0b 100644 --- a/R/check_params.R +++ b/R/check_params.R @@ -17,7 +17,6 @@ check_params = function(params = c(), tool = c()) { for (i in numi) { val = params$value[i] - val = 0.9 # Consider vectors specified with c() num_value = unlist(lapply(strsplit(x = as.character(val), "[(]|[)]|[,]|c"), function(x){x[!x == ""]})) # Consider vectors specified with : @@ -29,7 +28,6 @@ check_params = function(params = c(), tool = c()) { } num_value = num_value[-val2expand] } - # Attempt to turn into numeric try(expr = { num_value = suppressWarnings( @@ -41,24 +39,8 @@ check_params = function(params = c(), tool = c()) { blocked_params$name[cnt] = rowNames[i] blocked_params$error[cnt] = "is not numeric" cnt = cnt + 1 - } else { - if (length(num_value) > 1) { - if (tool == "GGIR") { - nc = nchar(params$value[i]) - print(nc) - if ((substr(params$value[i], 1, 2) != "c(" | substr(params$value[i], nc, nc) != ")") & - length(grep(pattern = ":", x = params$value[i])) == 0) { - blocked_params$name[cnt] = rowNames[i] - blocked_params$error[cnt] = "numeric vector needs to start with c( and end with ), with values separated by a comma" - cnt = cnt + 1 - } - } - } - } - if (test_na == FALSE) { + } else if (test_na == FALSE) { if (params$class[i] == "integer") { - print(num_value) - print(rowNames[i]) if (any(round(num_value) != num_value)) { blocked_params$name[cnt] = rowNames[i] blocked_params$error[cnt] = "is not an integer" From b645b231afe815cb8d0e1344920743224dfebfd5 Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Wed, 27 Sep 2023 17:39:29 +0200 Subject: [PATCH 03/13] Update params_description_hbGPS.tsv --- inst/testfiles_hbGPS/params_description_hbGPS.tsv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inst/testfiles_hbGPS/params_description_hbGPS.tsv b/inst/testfiles_hbGPS/params_description_hbGPS.tsv index 20bf110..1917390 100644 --- a/inst/testfiles_hbGPS/params_description_hbGPS.tsv +++ b/inst/testfiles_hbGPS/params_description_hbGPS.tsv @@ -1,6 +1,6 @@ parameter field subfield display class minimum maximum set priority description -idloc general TRUE set 2;6 1 -maxBreakLengthSeconds trip TRUE integer 30 300 0 "How participant identifier should be extracted: idloc=2 looks at the filename and extracts the character string preceding the first occurance of a '_', idloc = 6 '.' (dot)" +idloc general TRUE set 2;6 1 "How participant identifier should be extracted: idloc=2 looks at the filename and extracts the character string preceding the first occurance of a '_', idloc = 6 '.' (dot)" +maxBreakLengthSeconds trip TRUE integer 30 300 0 maximum trip break duration in seconds minTripDur trip TRUE integer 30 900 0 Minimum trip duration seconds minTripDist_m trip TRUE integer 10 1000 0 Minimum trip distance in meters threshold_snr noise TRUE integer 0 1000 0 Threshold for snr From 5d37974f91a70e0bd6a738690f2feacb7ee3a12c Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Thu, 28 Sep 2023 10:20:40 +0200 Subject: [PATCH 04/13] add extEpochData_timeformat to tsv file as it is needed for count files --- inst/testfiles_ggir/params_description_ggir.tsv | 1 + 1 file changed, 1 insertion(+) diff --git a/inst/testfiles_ggir/params_description_ggir.tsv b/inst/testfiles_ggir/params_description_ggir.tsv index fb00d58..b830907 100644 --- a/inst/testfiles_ggir/params_description_ggir.tsv +++ b/inst/testfiles_ggir/params_description_ggir.tsv @@ -24,3 +24,4 @@ threshold.vig physical activity TRUE double 0 10000 0 "Threshold for vigorous excludefirstlast.part5 physical activity TRUE set TRUE;FALSE 0 If TRUE then the first and last window (waking-waking or midnight-midnight) are ignored in the part 5 reports. includedaycrit physical activity TRUE integer 0 24 0 Minimum required number of valid hours in day specific analysis (24 hour window between midnight and midnight) includedaycrit.part5 physical activity TRUE double 0 24 0 "Inclusion criteria for number of valid hours for the waking time window, either as expressed as a ratio of 1 or as the number of hours in a 24 hour day." +extEpochData_timeformat general TRUE timeformat 0 "Timestamp format in R code, e.g. %Y-%m-%d %H:%M:%S, see also https://www.stat.berkeley.edu/~s133/dates.html" From 5ea1a2cc19fa0d3ae1c4162b6f2762e5530cc4d1 Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Thu, 28 Sep 2023 10:21:07 +0200 Subject: [PATCH 05/13] #94 allow GGIR and hbGPS to be run in combination and identify time series folder --- R/myApp.R | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/R/myApp.R b/R/myApp.R index a2a7be9..511ec2a 100644 --- a/R/myApp.R +++ b/R/myApp.R @@ -1184,8 +1184,19 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { # Basic check before running function: ready_to_run_hbGPS = FALSE # Check for GGIR output (two possible sources either from this run or from a previous run) - expected_ggir_results_dir = global$ggirout_in - if (dir.exists(global$ggirout_in)) { + # expected_ggir_results_dir = global$ggirout_in + + if ("GGIR_out" %in% input$availabledata && dir.exists(global$ggirout_in)) { + expected_ggir_results_dir = global$ggirout_in + } else { + expected_ggir_results_dir = paste0(global$data_out, "/output_", basename(global$raw_acc_in)) + } + + if (dirname(expected_ggir_results_dir) != "ms5.rawout") { + expected_ggir_results_dir = paste0(expected_ggir_results_dir, "/meta/ms5.outraw") + } + + if (dir.exists(expected_ggir_results_dir)) { Nfiles_in_dir = length(dir(path = expected_ggir_results_dir, pattern = "csv", recursive = FALSE, full.names = FALSE)) if (Nfiles_in_dir > 0) { # also check for GPS files @@ -1223,15 +1234,15 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { on.exit(file.copy(from = stdout_hbGPS_tmp, to = logfile, overwrite = TRUE), add = TRUE) # Start hbGPS - x_hbGPS <- r_bg(func = function(hbGPS_shiny, ggiroutdir, gpsdir, + x_hbGPS <- r_bg(func = function(hbGPS_shiny, expected_ggir_results_dir, gpsdir, outputdir, dataset_name, configfile){ - hbGPS_shiny(ggiroutdir, gpsdir, + hbGPS_shiny(expected_ggir_results_dir, gpsdir, outputdir, dataset_name, configfile) }, args = list(hbGPS_shiny = hbGPS_shiny, - ggiroutdir = global$ggirout_in, + expected_ggir_results_dir = expected_ggir_results_dir, gpsdir = global$gps_in, outputdir = isolate(global$data_out), dataset_name = input$dataset_name, From 726f116a636ff4158dde5f6470350215bb2411ae Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Thu, 28 Sep 2023 11:04:25 +0200 Subject: [PATCH 06/13] Refocus UI from PALMSpy to hbGPS --- R/identify_tools.R | 5 +++++ R/myApp.R | 33 +++++++++++++++++---------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/R/identify_tools.R b/R/identify_tools.R index d12eb12..8df23ab 100644 --- a/R/identify_tools.R +++ b/R/identify_tools.R @@ -61,5 +61,10 @@ identify_tools = function(datatypes = c("AccRaw", "ACount", "GPS", "GIS", tools_needed = tools_needed[-which(tools_needed == "CountConverter")] } } + # Mask tools that will be deprecated + if (any(c("CountConverter", "PALMSpy") %in% tools_needed == TRUE)) { + tools_needed = tools_needed[-which(tools_needed %in% c("CountConverter", "PALMSpy"))] + } + invisible(list(tools_needed = tools_needed, iotools = iotools[which(names(iotools) %in% tools_needed)])) } \ No newline at end of file diff --git a/R/myApp.R b/R/myApp.R index 511ec2a..d5a8ff7 100644 --- a/R/myApp.R +++ b/R/myApp.R @@ -52,16 +52,16 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { ), p("\n"), checkboxGroupInput("availabledata", label = "Which type(s) of data would you like to analyse? ", - choiceNames = list("Acceleration", - "Counts (in ActiGraph .csv format) => select only when using PALMSpy", + choiceNames = list("Acceleration (all formats accepted by GGIR)", "GPS (in .csv format)", "GIS (shape files + linkage file)", "Sleep Diary (in GGIR compatible .csv format)", - "previously generated PALMS(py) output", "previously generated GGIR time series output", - "previously generated hbGPS output"), - choiceValues = list("AccRaw", "ACount", "GPS", "GIS", "SleepDiary", - "PALMSpy_out", "GGIR_out", "hbGPS_out"), width = '100%'), + "previously generated hbGPS output", + "Counts (in ActiGraph .csv format) => soon to be deprecated", + "previously generated PALMS(py) output => soon to be deprecated"), + choiceValues = list("AccRaw", "GPS", "GIS", "SleepDiary", + "GGIR_out", "hbGPS_out", "ACount", "PALMSpy_out"), width = '100%'), # Only show more check boxs if user specified available data sufficient for any of the tools conditionalPanel(condition = paste0("input.availabledata.indexOf(`AccRaw`) > -1 || ", # GGIR "(input.availabledata.indexOf(`ACount`) > -1 && ", # PALMSpy @@ -88,11 +88,12 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { hr(), checkboxGroupInput("tools", label = "Select the tools you would like to use:", choiceNames = list("GGIR (R package)", - "CountConverter (R package GGIR + actilifecounts)", - "PALMSpy (Python library)", "hbGPS (R package)", - "palmsplusr (R package)"), - choiceValues = list("GGIR", "CountConverter", "PALMSpy", "hbGPS", "palmsplusr"), width = '100%') + "palmsplusr (R package)", + "CountConverter (R package GGIR + actilifecounts) => soon to be deprecated from this app", + "PALMSpy (Python library) => soon to be deprecated from this app"), + choiceValues = list("GGIR", "hbGPS", "palmsplusr", + "CountConverter", "PALMSpy"), width = '100%') ), hr(), actionButton("page_12", "next", style = "position:absolute;right:1em;"), @@ -112,8 +113,8 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { conditionalPanel(condition = paste0("input.availabledata.indexOf(`AccRaw`) > -1 && ", "(input.tools.includes(`GGIR`) || ", "input.tools.includes(`CountConverter`))"), - shinyFiles::shinyDirButton("rawaccdir", label = "Raw accelerometry data directory...", - title = "Select raw accelerometer data directory"), + shinyFiles::shinyDirButton("rawaccdir", label = "Accelerometry data directory...", + title = "Select accelerometer data directory"), verbatimTextOutput("rawaccdir", placeholder = TRUE), hr() ), @@ -403,7 +404,7 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { showNotification("Select at least one tool", type = "error") } else { if ("GGIR" %in% input$tools == TRUE & "AccRaw" %in% input$availabledata == FALSE) { - showNotification("GGIR not possible without access to raw accelerometer data", type = "error") + showNotification("GGIR not possible without access to accelerometer data", type = "error") } else { if ("PALMSpy" %in% input$tools == TRUE & all(c("AccRaw", "ACount", "GPS") %in% input$availabledata == FALSE)) { showNotification("PALMSpy not possible without access to Accelerometer and GPS data", type = "error") @@ -424,7 +425,7 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { " run"), type = "error") } else { if ("CountConverter" %in% input$tools == TRUE & "AccRaw" %in% input$availabledata == FALSE) { - showNotification("CountConverter not possible without access to raw accelerometer data", type = "error") + showNotification("CountConverter not possible without access to accelerometer data", type = "error") } else { if ("PALMSpy_out" %in% input$availabledata & "hbGPS_out" %in% input$availabledata) { showNotification(paste0("You cannot select previously generated", @@ -474,10 +475,10 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { save(values, file = "./HabitusGUIbookmark.RData") # ----- if ("AccRaw" %in% input$availabledata & "GGIR" %in% input$tools & as.character(input$rawaccdir)[1] == "0" & is.null(selectedRawaccdir)) { - showNotification("Select raw accelerometer data directory", type = "error") + showNotification("Select accelerometer data directory", type = "error") } else { if ("AccRaw" %in% input$availabledata & "CountConverter" %in% input$tools & as.character(input$rawaccdir)[1] == "0" & is.null(selectedRawaccdir)) { - showNotification("Select raw accelerometer data directory", type = "error") + showNotification("Select accelerometer data directory", type = "error") } else { if ("ACount" %in% input$availabledata & "PALMSpy" %in% input$tools & as.character(input$countaccdir)[1] == "0" & is.null(selectedCountaccdir)) { showNotification("Select count accelerometer data directory", type = "error") From 2493ac1dbe3026747f47fe46552be9ba23f1a64e Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Thu, 28 Sep 2023 11:35:41 +0200 Subject: [PATCH 07/13] replace GGIR config template by a zipped folder with multiple templates #94 --- R/modConfigServer.R | 6 +- inst/testfiles_ggir/config.csv | 186 ------------------ .../example_config_files_GGIR.zip | Bin 0 -> 4002 bytes 3 files changed, 3 insertions(+), 189 deletions(-) delete mode 100644 inst/testfiles_ggir/config.csv create mode 100644 inst/testfiles_ggir/example_config_files_GGIR.zip diff --git a/R/modConfigServer.R b/R/modConfigServer.R index c0c144f..6fd2637 100644 --- a/R/modConfigServer.R +++ b/R/modConfigServer.R @@ -24,12 +24,12 @@ modConfigServer = function(id, tool, homedir = getwd()) { contentType = "application/json") } else if (tool() == "GGIR") { output$download = downloadHandler( - filename = "config.csv", + filename = "example_config_files_GGIR.zip", content <- function(file) { - config_default = system.file("testfiles_ggir/config.csv", package = "HabitusGUI")[1] + config_default = system.file("testfiles_ggir/example_config_files_GGIR.zip", package = "HabitusGUI")[1] if (config_default != file) file.copy(config_default, file) }, - contentType = "text/csv") + contentType = "zip") } else if (tool() == "hbGPS") { output$download = downloadHandler( filename = "config_hbGPS.csv", diff --git a/inst/testfiles_ggir/config.csv b/inst/testfiles_ggir/config.csv deleted file mode 100644 index 6ea678f..0000000 --- a/inst/testfiles_ggir/config.csv +++ /dev/null @@ -1,186 +0,0 @@ -"argument","value","context" -"datadir","c()","not applicable" -"do.report","c(2,4,5)","not applicable" -"f0","1","not applicable" -"f1","1","not applicable" -"mode","c(1,2,3,4,5)","not applicable" -"outputdir","./","not applicable" -"studyname","c()","not applicable" -"GGIRread_version","0.2.6","not applicable" -"GGIRversion","2.9.0","not applicable" -"R_version","R version 4.2.2 (2022-10-31 ucrt)","not applicable" -"qwindow","c(0,24)","params_247" -"qlevels","c()","params_247" -"qwindow_dateformat","%d-%m-%Y","params_247" -"ilevels","c()","params_247" -"IVIS_windowsize_minutes","60","params_247" -"IVIS_epochsize_seconds","c()","params_247" -"IVIS.activity.metric","2","params_247" -"IVIS_acc_threshold","20","params_247" -"qM5L5","c()","params_247" -"MX.ig.min.dur","10","params_247" -"M5L5res","10","params_247" -"winhr","5","params_247" -"iglevels","c()","params_247" -"LUXthresholds","c(0,100,500,1000,3000,5000,10000)","params_247" -"LUX_cal_constant","c()","params_247" -"LUX_cal_exponent","c()","params_247" -"LUX_day_segments","c()","params_247" -"window.summary.size","10","params_247" -"L5M5window","c(0,24)","params_247" -"cosinor","FALSE","params_247" -"includedaycrit","16","params_cleaning" -"ndayswindow","7","params_cleaning" -"strategy","1","params_cleaning" -"maxdur","0","params_cleaning" -"hrs.del.start","0","params_cleaning" -"hrs.del.end","0","params_cleaning" -"includedaycrit.part5","0.666666667","params_cleaning" -"excludefirstlast.part5","FALSE","params_cleaning" -"TimeSegments2ZeroFile","c()","params_cleaning" -"do.imp","TRUE","params_cleaning" -"data_cleaning_file","c()","params_cleaning" -"minimum_MM_length.part5","23","params_cleaning" -"excludefirstlast","FALSE","params_cleaning" -"includenightcrit","16","params_cleaning" -"excludefirst.part4","FALSE","params_cleaning" -"excludelast.part4","FALSE","params_cleaning" -"max_calendar_days","0","params_cleaning" -"nonWearEdgeCorrection","TRUE","params_cleaning" -"overwrite","FALSE","params_general" -"acc.metric","ENMO","params_general" -"maxNcores","c()","params_general" -"print.filename","FALSE","params_general" -"do.parallel","TRUE","params_general" -"windowsizes","c(5,900,3600)","params_general" -"desiredtz","","params_general" -"configtz","","params_general" -"idloc","3","params_general" -"dayborder","0","params_general" -"part5_agg2_60seconds","FALSE","params_general" -"sensor.location","wrist","params_general" -"expand_tail_max_hours","c()","params_general" -"recordingEndSleepHour","c()","params_general" -"do.anglex","FALSE","params_metrics" -"do.angley","FALSE","params_metrics" -"do.anglez","TRUE","params_metrics" -"do.zcx","FALSE","params_metrics" -"do.zcy","FALSE","params_metrics" -"do.zcz","FALSE","params_metrics" -"do.enmo","TRUE","params_metrics" -"do.lfenmo","FALSE","params_metrics" -"do.en","FALSE","params_metrics" -"do.mad","FALSE","params_metrics" -"do.enmoa","FALSE","params_metrics" -"do.roll_med_acc_x","FALSE","params_metrics" -"do.roll_med_acc_y","FALSE","params_metrics" -"do.roll_med_acc_z","FALSE","params_metrics" -"do.dev_roll_med_acc_x","FALSE","params_metrics" -"do.dev_roll_med_acc_y","FALSE","params_metrics" -"do.dev_roll_med_acc_z","FALSE","params_metrics" -"do.bfen","FALSE","params_metrics" -"do.hfen","FALSE","params_metrics" -"do.hfenplus","FALSE","params_metrics" -"do.lfen","FALSE","params_metrics" -"do.lfx","FALSE","params_metrics" -"do.lfy","FALSE","params_metrics" -"do.lfz","FALSE","params_metrics" -"do.hfx","FALSE","params_metrics" -"do.hfy","FALSE","params_metrics" -"do.hfz","FALSE","params_metrics" -"do.bfx","FALSE","params_metrics" -"do.bfy","FALSE","params_metrics" -"do.bfz","FALSE","params_metrics" -"do.brondcounts","FALSE","params_metrics" -"do.neishabouricounts","FALSE","params_metrics" -"hb","15","params_metrics" -"lb","0.2","params_metrics" -"n","4","params_metrics" -"zc.lb","0.25","params_metrics" -"zc.hb","3","params_metrics" -"zc.sb","0.01","params_metrics" -"zc.order","2","params_metrics" -"zc.scale","1","params_metrics" -"actilife_LFE","FALSE","params_metrics" -"epochvalues2csv","FALSE","params_output" -"save_ms5rawlevels","FALSE","params_output" -"save_ms5raw_format","csv","params_output" -"save_ms5raw_without_invalid","TRUE","params_output" -"storefolderstructure","FALSE","params_output" -"timewindow","c(MM,WW)","params_output" -"viewingwindow","1","params_output" -"dofirstpage","TRUE","params_output" -"visualreport","TRUE","params_output" -"week_weekend_aggregate.part5","FALSE","params_output" -"do.part3.pdf","TRUE","params_output" -"outliers.only","FALSE","params_output" -"criterror","3","params_output" -"do.visual","TRUE","params_output" -"do.sibreport","FALSE","params_output" -"do.part2.pdf","TRUE","params_output" -"mvpathreshold","100","params_phyact" -"boutcriter","0.8","params_phyact" -"mvpadur","c(1,5,10)","params_phyact" -"boutcriter.in","0.9","params_phyact" -"boutcriter.lig","0.8","params_phyact" -"boutcriter.mvpa","0.8","params_phyact" -"threshold.lig","40","params_phyact" -"threshold.mod","100","params_phyact" -"threshold.vig","400","params_phyact" -"boutdur.mvpa","c(1,5,10)","params_phyact" -"boutdur.in","c(10,20,30)","params_phyact" -"boutdur.lig","c(1,5,10)","params_phyact" -"frag.metrics","c()","params_phyact" -"chunksize","1","params_rawdata" -"spherecrit","0.3","params_rawdata" -"minloadcrit","72","params_rawdata" -"printsummary","FALSE","params_rawdata" -"do.cal","TRUE","params_rawdata" -"backup.cal.coef","retrieve","params_rawdata" -"dynrange","c()","params_rawdata" -"minimumFileSizeMB","2","params_rawdata" -"rmc.dec",".","params_rawdata" -"rmc.firstrow.acc","c()","params_rawdata" -"rmc.firstrow.header","c()","params_rawdata" -"rmc.header.length","c()","params_rawdata" -"rmc.col.acc","c(1,2,3)","params_rawdata" -"rmc.col.temp","c()","params_rawdata" -"rmc.col.time","c()","params_rawdata" -"rmc.unit.acc","g","params_rawdata" -"rmc.unit.temp","C","params_rawdata" -"rmc.unit.time","POSIX","params_rawdata" -"rmc.format.time","%Y-%m-%d %H:%M:%OS","params_rawdata" -"rmc.bitrate","c()","params_rawdata" -"rmc.dynamic_range","c()","params_rawdata" -"rmc.unsignedbit","TRUE","params_rawdata" -"rmc.origin","01/01/1970","params_rawdata" -"rmc.desiredtz","","params_rawdata" -"rmc.configtz","c()","params_rawdata" -"rmc.sf","c()","params_rawdata" -"rmc.headername.sf","c()","params_rawdata" -"rmc.headername.sn","c()","params_rawdata" -"rmc.headername.recordingid","c()","params_rawdata" -"rmc.header.structure","c()","params_rawdata" -"rmc.check4timegaps","FALSE","params_rawdata" -"rmc.noise","13","params_rawdata" -"rmc.col.wear","c()","params_rawdata" -"rmc.doresample","FALSE","params_rawdata" -"interpolationType","1","params_rawdata" -"imputeTimegaps","TRUE","params_rawdata" -"anglethreshold","5","params_sleep" -"timethreshold","5","params_sleep" -"ignorenonwear","TRUE","params_sleep" -"constrain2range","TRUE","params_sleep" -"HASPT.algo","HDCZA","params_sleep" -"HASIB.algo","vanHees2015","params_sleep" -"Sadeh_axis","","params_sleep" -"longitudinal_axis","c()","params_sleep" -"HASPT.ignore.invalid","FALSE","params_sleep" -"loglocation","c()","params_sleep" -"colid","1","params_sleep" -"coln1","2","params_sleep" -"nnights","c()","params_sleep" -"relyonguider","FALSE","params_sleep" -"def.noc.sleep","1","params_sleep" -"sleeplogsep",",","params_sleep" -"sleepwindowType","SPT","params_sleep" diff --git a/inst/testfiles_ggir/example_config_files_GGIR.zip b/inst/testfiles_ggir/example_config_files_GGIR.zip new file mode 100644 index 0000000000000000000000000000000000000000..3c960cf628a6c21d6305a227c963276b6dded968 GIT binary patch literal 4002 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 Date: Thu, 28 Sep 2023 11:40:31 +0200 Subject: [PATCH 08/13] normalizing paths when first selecting them --- R/myApp.R | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/R/myApp.R b/R/myApp.R index d5a8ff7..df900c0 100644 --- a/R/myApp.R +++ b/R/myApp.R @@ -808,7 +808,7 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { if (!"path" %in% names(rawaccdir())) return() home <- normalizePath(homedir) global$raw_acc_in <- - file.path(home, paste(unlist(rawaccdir()$path[-1]), collapse = .Platform$file.sep)) + normalizePath(file.path(home, paste(unlist(rawaccdir()$path[-1]), collapse = .Platform$file.sep))) }) observeEvent(ignoreNULL = TRUE, eventExpr = { @@ -818,7 +818,7 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { if (!"path" %in% names(countaccdir())) return() home <- normalizePath(homedir) global$count_acc_in <- - file.path(home, paste(unlist(countaccdir()$path[-1]), collapse = .Platform$file.sep)) + normalizePath(file.path(home, paste(unlist(countaccdir()$path[-1]), collapse = .Platform$file.sep))) }) observeEvent(ignoreNULL = TRUE, eventExpr = { @@ -828,7 +828,7 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { if (!"path" %in% names(gpsdir())) return() home <- normalizePath(homedir) global$gps_in <- - file.path(home, paste(unlist(gpsdir()$path[-1]), collapse = .Platform$file.sep)) + normalizePath(file.path(home, paste(unlist(gpsdir()$path[-1]), collapse = .Platform$file.sep))) }) observeEvent(ignoreNULL = TRUE, eventExpr = { @@ -838,7 +838,7 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { if (!"path" %in% names(gisdir())) return() home <- normalizePath(homedir) global$gis_in <- - file.path(home, paste(unlist(gisdir()$path[-1]), collapse = .Platform$file.sep)) + normalizePath(file.path(home, paste(unlist(gisdir()$path[-1]), collapse = .Platform$file.sep))) # send gisdir to textInput field # Can also set the label, this time for input$inText2 @@ -862,7 +862,7 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { if (!"files" %in% names(gislinkfile())) return() home <- normalizePath(homedir) global$gislinkfile_in <- - as.character(parseFilePaths(c(home = homedir), gislinkfile())$datapath) + normalizePath(as.character(parseFilePaths(c(home = homedir), gislinkfile())$datapath)) }) observeEvent(ignoreNULL = TRUE, eventExpr = { @@ -872,7 +872,7 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { if (!"path" %in% names(palmspyoutdir())) return() home <- normalizePath(homedir) global$palmspyout_in <- - file.path(home, paste(unlist(palmspyoutdir()$path[-1]), collapse = .Platform$file.sep)) + normalizePath(file.path(home, paste(unlist(palmspyoutdir()$path[-1]), collapse = .Platform$file.sep))) }) observeEvent(ignoreNULL = TRUE, eventExpr = { @@ -882,7 +882,7 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { if (!"path" %in% names(hbGPSoutdir())) return() home <- normalizePath(homedir) global$hbGPSout_in <- - file.path(home, paste(unlist(hbGPSoutdir()$path[-1]), collapse = .Platform$file.sep)) + normalizePath(file.path(home, paste(unlist(hbGPSoutdir()$path[-1]), collapse = .Platform$file.sep))) }) observeEvent(ignoreNULL = TRUE, eventExpr = { @@ -892,7 +892,7 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { if (!"path" %in% names(ggiroutdir())) return() home <- normalizePath(homedir) global$ggirout_in <- - file.path(home, paste(unlist(ggiroutdir()$path[-1]), collapse = .Platform$file.sep)) + normalizePath(file.path(home, paste(unlist(ggiroutdir()$path[-1]), collapse = .Platform$file.sep))) }) observeEvent(ignoreNULL = TRUE, eventExpr = { @@ -902,7 +902,7 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { if (!"path" %in% names(outputdir())) return() home <- normalizePath(homedir) global$data_out <- - file.path(home, paste(unlist(outputdir()$path[-1]), collapse = .Platform$file.sep)) + normalizePath(file.path(home, paste(unlist(outputdir()$path[-1]), collapse = .Platform$file.sep))) }) observeEvent(ignoreNULL = TRUE, eventExpr = { @@ -912,7 +912,7 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { if (!"files" %in% names(sleepdiaryfile())) return() home <- normalizePath(homedir) global$sleepdiaryfile <- - as.character(parseFilePaths(c(home = homedir), sleepdiaryfile())$datapath) + normalizePath(as.character(parseFilePaths(c(home = homedir), sleepdiaryfile())$datapath)) }) # Send directories to UI -------------------------------------------- From 2a9f05346d48b6a87f9c45e7749326d84b6ae733 Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Thu, 28 Sep 2023 12:08:45 +0200 Subject: [PATCH 09/13] update changelog and produce warning when participant_basis is empty --- R/palmsplusr_shiny.R | 4 +++- inst/NEWS.Rd | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/R/palmsplusr_shiny.R b/R/palmsplusr_shiny.R index f09adfd..3b11015 100644 --- a/R/palmsplusr_shiny.R +++ b/R/palmsplusr_shiny.R @@ -145,7 +145,9 @@ palmsplusr_shiny <- function(gisdir = "", participant_basis = withoutMissingId$participant_basis loca = withoutMissingId$loca write.csv(participant_basis, paste0(palmsplus_folder, "/", stringr::str_interp("participant_basis_${dataset_name}.csv"))) # store file for logging purposes only - + if (length(participant_basis) == 0 || nrow(participant_basis) == 0) { + stop("\nParticipant basis file does not include references for the expected recording IDs") + } #=========================================================================================== # Create field tables diff --git a/inst/NEWS.Rd b/inst/NEWS.Rd index d491145..aff85f2 100755 --- a/inst/NEWS.Rd +++ b/inst/NEWS.Rd @@ -1,6 +1,11 @@ \name{NEWS} \title{News for Package \pkg{HabitusGUI}} \newcommand{\cpkg}{\href{http://CRAN.R-project.org/package=#1}{\pkg{#1}}} +\section{Changes in version 0.2.0 (GitHub-only-release date: 28-09-2023)}{ + \itemize{ + \item Series of fixes based on initial testing phase, see issue #94. + } +} \section{Changes in version 0.2.0 (GitHub-only-release date: 15-09-2023)}{ \itemize{ \item Embed hbGPS #90 From fe736f7cb4407795d61100b13bc9ac840dda33a4 Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Thu, 28 Sep 2023 12:21:42 +0200 Subject: [PATCH 10/13] Update example_config_files_GGIR.zip --- .../example_config_files_GGIR.zip | Bin 4002 -> 3884 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/inst/testfiles_ggir/example_config_files_GGIR.zip b/inst/testfiles_ggir/example_config_files_GGIR.zip index 3c960cf628a6c21d6305a227c963276b6dded968..739b17ca684299298c46b0a6dbd5593b313c759d 100644 GIT binary patch delta 3791 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 F0018MG;RO@ delta 3917 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 b000000000103ZMW0O^tsCI$x&00000?r38G From 6471bf0268fb26a62a29ec635e56eb15d921c621 Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Thu, 28 Sep 2023 12:59:32 +0200 Subject: [PATCH 11/13] fix tests following all updates relating to #94 --- tests/testthat/test_check_params.R | 21 ++++++----- tests/testthat/test_identify_tools.R | 37 ++++++++++---------- tests/testthat/test_load_and_update_params.R | 6 ++-- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/tests/testthat/test_check_params.R b/tests/testthat/test_check_params.R index dfa1cc2..f298107 100644 --- a/tests/testthat/test_check_params.R +++ b/tests/testthat/test_check_params.R @@ -15,19 +15,18 @@ test_that("Parameters are checked", { paramcheck = check_params(params, tool = "GGIR") # Check that values are as expected - expect_equal(paramcheck$blocked_params$name, c("a", "c", "f", "g", "i", "e")) + expect_equal(paramcheck$blocked_params$name, c("a", "c", "f", "g", "e")) expect_equal(paramcheck$blocked_params$error, c("is not within expected range: 1 - 10", "is not an integer", "is not numeric", "is not numeric", - "numeric vector needs to start with c( and end with ), with values separated by a comma", - "is not among expected values: D, E, F")) - expect_equal(paramcheck$error_message, paste0("Error in parameter \" a \": Value 0 is not within expected", - " range: 1 - 10
Error in parameter \" c \": Value 1.1 is not", - " an integer
Error in parameter \" e \": Value A is not among", - " expected values: D, E, F
Error in parameter \" f \": Value A", - " is not numeric
Error in parameter \" g \": Value NA is not", - " numeric
Error in parameter \" i \": Value 1,2,3 numeric", - " vector needs to start with c( and end with ), with values", - " separated by a comma
", collapse = "")) + "is not among expected values: D, E, F")) + expect_equal(paramcheck$error_message, paste0("Error in parameter \" a \": Value 0 is", + " not within expected range: 1 - 10
Error", + " in parameter \" c \": Value 1.1 is not an", + " integer
Error in parameter \" e \": ", + "Value A is not among expected values: D, E,", + " F
Error in parameter \" f \": Value A ", + "is not numeric
Error in parameter \" g", + " \": Value NA is not numeric
", collapse = "")) #=================================== # Check timeformat seperately params = data.frame(value = c("%Y-%m-%d %H:%M:%S", "%Y-typo-%d %H:%M:%S"), diff --git a/tests/testthat/test_identify_tools.R b/tests/testthat/test_identify_tools.R index b364ff4..ed7ec90 100644 --- a/tests/testthat/test_identify_tools.R +++ b/tests/testthat/test_identify_tools.R @@ -7,27 +7,26 @@ test_that("Correct tools are proposed by test_identify_tools", { sce1 = identify_tools(datatypes = c("AccRaw", "ACount", "GPS", "GIS", "GGIR_out"), goals = c("PA", "Sleep", "QC", "Trips", "Environment"), available_tools = available_tools) - expect_equal(length(sce1$tools_needed), 4) - expect_equal(sce1$tools_needed, c("GGIR", "PALMSpy", "palmsplusr", "hbGPS")) + expect_equal(length(sce1$tools_needed), 3) + expect_equal(sce1$tools_needed, c("GGIR", "palmsplusr", "hbGPS")) expect_equal(sce1$iotools[[1]]@output, c("GGIR_out", "ACount")) expect_equal(sce1$iotools[[3]]@output, "palmsplusr_out") - expect_equal(sce1$iotools[[4]]@output, "palmsplusr_out") - expect_equal(sce1$iotools[[5]]@output, "hbGPS_out") + expect_equal(sce1$iotools[[4]]@output, "hbGPS_out") # Scenario 2: GIS missing sce2 = identify_tools(datatypes = c("AccRaw", "ACount", "GPS", "GGIR_out"), goals = c("PA", "Sleep", "QC", "Trips", "Environment"), available_tools = available_tools) - expect_equal(length(sce2$tools_needed), 3) - expect_equal(sce2$tools_needed, c("GGIR", "PALMSpy", "hbGPS")) - expect_equal(sce2$iotools[[2]]@output, "PALMSpy_out") + expect_equal(length(sce2$tools_needed), 2) + expect_equal(sce2$tools_needed, c("GGIR", "hbGPS")) + expect_equal(sce2$iotools[[2]]@output, "hbGPS_out") # Scenario 3: AccRaw missing sce3 = identify_tools(datatypes = c("ACount", "GPS", "GIS", "GGIR_out"), goals = c("PA", "Sleep", "QC", "Trips", "Environment"), available_tools = available_tools) - expect_equal(length(sce3$tools_needed), 3) - expect_equal(sce3$tools_needed, c("PALMSpy", "palmsplusr", "hbGPS")) + expect_equal(length(sce3$tools_needed), 2) + expect_equal(sce3$tools_needed, c("palmsplusr", "hbGPS")) expect_equal(sce3$iotools[[2]]@output, "palmsplusr_out") expect_equal(sce3$iotools[[2]]@usecases, c("Environment", "QC")) @@ -35,21 +34,21 @@ test_that("Correct tools are proposed by test_identify_tools", { sce4 = identify_tools(datatypes = c("AccRaw", "GPS", "GIS", "GGIR_out"), goals = c("PA", "Sleep", "QC", "Trips", "Environment"), available_tools = available_tools) - expect_equal(length(sce4$tools_needed), 5) - expect_equal(sce4$tools_needed, c("GGIR", "PALMSpy", "palmsplusr", "CountConverter", "hbGPS")) - expect_equal(sce4$iotools[[2]]@output, "PALMSpy_out") - expect_equal(sce4$iotools[[2]]@usecases, c("Trips", "QC", "Environment")) - expect_equal(sce4$iotools[[4]]@output, "palmsplusr_out") - expect_equal(sce4$iotools[[5]]@usecases, c("PA", "Trips", "QC", "Environment")) + expect_equal(length(sce4$tools_needed), 3) + expect_equal(sce4$tools_needed, c("GGIR", "palmsplusr", "hbGPS")) + expect_equal(sce4$iotools[[2]]@output, "palmsplusr_out") + expect_equal(sce4$iotools[[2]]@usecases, c("Environment", "QC")) + expect_equal(sce4$iotools[[4]]@output, "hbGPS_out") + expect_equal(sce4$iotools[[4]]@usecases, c("Trips", "QC", "Environment")) # Scenario 5: All data vailable, but only interest in Environment sce5 = identify_tools(datatypes = c("AccRaw", "ACount", "GPS", "GIS"), goals = c("Environment"), available_tools = available_tools) - expect_equal(length(sce5$tools_needed), 4) - expect_equal(sce5$tools_needed, c("GGIR", "PALMSpy", "palmsplusr", "hbGPS")) - expect_equal(sce5$iotools[[2]]@output, "PALMSpy_out") - expect_equal(sce5$iotools[[2]]@usecases, c("Trips", "QC", "Environment")) + expect_equal(length(sce5$tools_needed), 3) + expect_equal(sce5$tools_needed, c("GGIR", "palmsplusr", "hbGPS")) + expect_equal(sce5$iotools[[2]]@output, "palmsplusr_out") + expect_equal(sce5$iotools[[2]]@usecases, c("Environment", "QC")) # Scenario 6: hbGPS_out and GIS available sce6 = identify_tools(datatypes = c("hbGPS_out", "GIS"), diff --git a/tests/testthat/test_load_and_update_params.R b/tests/testthat/test_load_and_update_params.R index a55f5f5..a6eecb9 100644 --- a/tests/testthat/test_load_and_update_params.R +++ b/tests/testthat/test_load_and_update_params.R @@ -4,10 +4,12 @@ context("Load and update parameters from configuration files") test_that("Parameters can be loaded and updated from config files", { # Load GGIR .csv file - ggir_config_csv = system.file("testfiles_ggir/config.csv", package = "HabitusGUI")[1] + ggir_config_zip = system.file("testfiles_ggir/example_config_files_GGIR.zip", package = "HabitusGUI")[1] + ggir_config_csv = "config_GGIR_raw.csv" + unzip(ggir_config_zip, ggir_config_csv) params_ggir = load_params(file = ggir_config_csv, format = "csv_ggir") expect_equal(ncol(params_ggir), 9) - + # Load PALMSpy .json file palmspy_config_json = system.file("testfiles_palmspy/palmspy-params.json", package = "HabitusGUI")[1] params_palmspy = load_params(file = palmspy_config_json, format = "json_palmspy") From a40f1fabd6a661988fda15f12665c296385cff18 Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Thu, 28 Sep 2023 14:32:36 +0200 Subject: [PATCH 12/13] making sure palmsplusr can be run in combi with hbGPS and tidying up its console output #94 --- NAMESPACE | 1 + R/myApp.R | 15 ++++++++------- R/palmsplusr_shiny.R | 30 +++++++++++++++--------------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 488b644..686ccf1 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -41,6 +41,7 @@ importFrom(methods,new) importFrom(methods,setClass) importFrom(purrr,reduce) importFrom(readr,read_csv) +importFrom(readr,write_csv) importFrom(rlang,UQ) importFrom(rlang,parse_expr) importFrom(stats,aggregate) diff --git a/R/myApp.R b/R/myApp.R index df900c0..54d7b29 100644 --- a/R/myApp.R +++ b/R/myApp.R @@ -13,6 +13,7 @@ # HabitusGUI::myApp(homedir="~/projects") # options("sp_evolution_status" = 2) # pkgload::load_all("."); myApp(homedir="D:/Dropbox/Work/sharedfolder/DATA/Habitus") +# myApp(homedir="D:/Dropbox/Work/sharedfolder/DATA/Habitus/GPSprocessing/BEtestdata") # myApp(homedir="D:/Dropbox/Work/sharedfolder/DATA/Habitus/GPSprocessing/Teun/Driestam") # roxygen2::roxygenise() @@ -690,7 +691,7 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { } else { researchgoalsNames = reasearchgoalsNames[which(reasearchgoalsValues %in% researchgoals == TRUE)] reasearchgoalsValues = reasearchgoalsValues[which(reasearchgoalsValues %in% researchgoals == TRUE)] - researchgoalsLabel = "What is your research interest?" + researchgoalsLabel = "(Optional) Do you need guidance on which tool(s) to use? Tell us your objective(s):" } # check previously selected @@ -1311,13 +1312,13 @@ myApp <- function(homedir=getwd(), envConda = "~/miniconda3/bin/conda", ...) { } else { expected_results_dir = paste0(global$data_out,"/PALMSpy_output") } - } else if ("hbGPS_out" %in% input$availabledata) { - if (dir.exists(global$hbGPSout_in)) { - expected_results_dir = global$hbGPSout_in - } else { - expected_results_dir = paste0(global$data_out,"/hbGPS_output") - } + } else if ("hbGPS_out" %in% input$availabledata && dir.exists(global$hbGPSout_in)) { + expected_results_dir = global$hbGPSout_in + } else { + expected_results_dir = paste0(global$data_out,"/hbGPSoutput") } + + if (dir.exists(expected_results_dir)) { Nfiles_in_dir = length(dir(path = expected_results_dir, pattern = "csv", recursive = FALSE, full.names = FALSE)) if (Nfiles_in_dir > 0) { diff --git a/R/palmsplusr_shiny.R b/R/palmsplusr_shiny.R index 3b11015..4999915 100644 --- a/R/palmsplusr_shiny.R +++ b/R/palmsplusr_shiny.R @@ -10,7 +10,7 @@ #' @return palms_to_clean_lower object #' @importFrom stats end start formula as.formula #' @importFrom tidyr pivot_wider -#' @importFrom readr read_csv +#' @importFrom readr write_csv read_csv #' @import palmsplusr #' @import dplyr #' @importFrom utils head tail @@ -69,6 +69,8 @@ palmsplusr_shiny <- function(gisdir = "", sf::sf_use_s2(FALSE) # identify palms csv output files in palmsdir: palms_country_files <- list.files(path = palmsdir, pattern = "*.csv", full.names = TRUE) + # skip the combined file that hbGPS generates + palms_country_files = grep(pattern = "combined.csv", x = palms_country_files, invert = TRUE, value = TRUE) # read and combine palms csv output files csv_palms <- lapply(palms_country_files, FUN = readr::read_csv, col_types = list( identifier = readr::col_character(), @@ -81,31 +83,29 @@ palmsplusr_shiny <- function(gisdir = "", tripType = readr::col_integer(), tripMOT = readr::col_integer(), activity = readr::col_double() - )) + ), show_col_types = FALSE) PALMS_combined <- bind_rows(csv_palms) # Data cleaning: - if (verbose) cat("\nstart cleaning\n") + # if (verbose) cat("\nstart cleaning...\n") PALMS_reduced <- subset(PALMS_combined, lon > -180) palms_reduced_cleaned <- check_and_clean_palms_data(PALMS_reduced, dataset_name, outputdir) - if (verbose) cat("\ncleaning completed\n") - + # if (verbose) cat("\ncleaning completed\n") PALMS_reduced$dateTime = as.POSIXct(PALMS_reduced$dateTime, format = "%d/%m/%Y %H:%M:%S", tz = "") # Write to csv and read using read_palms to format the object as expected from the rest of the code PALMS_reduced_file = normalizePath(paste0(palmsplus_folder, "/", stringr::str_interp("PALMS_${dataset_name}_reduced.csv"))) - if (verbose) cat(paste0("\nCheck PALMS_reduced_file: ", PALMS_reduced_file)) + # if (verbose) cat(paste0("\nCheck PALMS_reduced_file: ", PALMS_reduced_file)) write.csv(palms_reduced_cleaned, PALMS_reduced_file) - palms = palmsplusr::read_palms(PALMS_reduced_file) + palms = palmsplusr::read_palms(PALMS_reduced_file, verbose = FALSE) palms$datetime = as.POSIXct(palms$datetime, format = "%d/%m/%Y %H:%M:%S", tz = "") - # Helper function to find shape files find_file = function(path, namelowercase) { allcsvfiles = dir(path, recursive = TRUE, full.names = TRUE) file_of_interest = allcsvfiles[which(tolower(basename(allcsvfiles)) == namelowercase)] return(file_of_interest) } - if (verbose) cat("\nreading basis file\n") - participant_basis = read_csv(gislinkfile) + # if (verbose) cat("\nreading basis file\n") + participant_basis = read_csv(gislinkfile, show_col_types = FALSE) # Load all shape files ---------------------------------------------------- #---------------- # NEW CODE @@ -244,7 +244,7 @@ palmsplusr_shiny <- function(gisdir = "", loca = loca, participant_basis = participant_basis, verbose = verbose) - data.table::fwrite(palmsplus, file = fns[1]) + write_csv(palmsplus, file = fns[1]) if (verbose) cat(">>>\n") } else { if (verbose) cat("skipped because insufficient input data>>>\n") @@ -261,7 +261,7 @@ palmsplusr_shiny <- function(gisdir = "", if (length(days) > 0) { if (verbose) cat(paste0(" N rows in days object: ", nrow(days))) - data.table::fwrite(x = days, file = fns[2]) + write_csv(x = days, file = fns[2]) } else { if (verbose) cat(paste0(" WARNING: no days object produced.")) } @@ -280,7 +280,7 @@ palmsplusr_shiny <- function(gisdir = "", trajectory_fields = trajectory_fields, trajectory_locations = trajectory_locations) if (length(trajectories) > 0) { - data.table::fwrite(trajectories, file = fns[3]) + write_csv(trajectories, file = fns[3]) shp_file = paste0(palmsplus_folder, "/", dataset_name, "_trajecories.shp") if (file.exists(shp_file)) file.remove(shp_file) # remove because st_write does not know how to overwrite @@ -304,7 +304,7 @@ palmsplusr_shiny <- function(gisdir = "", verbose = verbose) if (length(multimodal) > 0) { - data.table::fwrite(multimodal, file = fns[4]) + write_csv(multimodal, file = fns[4]) shp_file = paste0(palmsplus_folder, "/", dataset_name, "_multimodal.shp") if (file.exists(shp_file)) file.remove(shp_file) # remove because st_write does not know how to overwrite sf::st_write(obj = multimodal, dsn = shp_file) @@ -312,7 +312,7 @@ palmsplusr_shiny <- function(gisdir = "", } else { if (verbose) cat(paste0(" WARNING: no multimodal object produced.")) } - if (verbose) cat(">>>\n") + if (verbose) cat(">>>\n\n") } else { if (verbose) cat("skipped because insufficient input data>>>\n") } From 31a542b26e9173028c03a897e4d5244c5decfe72 Mon Sep 17 00:00:00 2001 From: Vincent van Hees Date: Thu, 28 Sep 2023 14:36:29 +0200 Subject: [PATCH 13/13] update version number in preparation for new relese --- DESCRIPTION | 4 ++-- inst/NEWS.Rd | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 383607a..2562b25 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: HabitusGUI Title: R Shiny App for Processing Behavioural Data Description: Shiny app to ease processing behavioural data with research software such as GGIR, activityCounts, PALMSpy,and palmsplusr. -Version: 0.2.0 -Date: 2022-09-30 +Version: 0.3.0 +Date: 2022-09-28 Authors@R: c(person(given = "Vincent", family = "van Hees", diff --git a/inst/NEWS.Rd b/inst/NEWS.Rd index aff85f2..a75c507 100755 --- a/inst/NEWS.Rd +++ b/inst/NEWS.Rd @@ -1,7 +1,7 @@ \name{NEWS} \title{News for Package \pkg{HabitusGUI}} \newcommand{\cpkg}{\href{http://CRAN.R-project.org/package=#1}{\pkg{#1}}} -\section{Changes in version 0.2.0 (GitHub-only-release date: 28-09-2023)}{ +\section{Changes in version 0.3.0 (GitHub-only-release date: 28-09-2023)}{ \itemize{ \item Series of fixes based on initial testing phase, see issue #94. }