From 5a44d34bd12eb2777252579a9e003bdec4442423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Todor=20Kondi=C4=87?= <kontrapunkt@uclmail.net> Date: Thu, 16 Feb 2023 16:49:10 +0100 Subject: [PATCH] api, app: Make paths more flexible. --- R/api.R | 126 ++++++++++++++++++++++++++++++++++++++++++++-------- R/envopts.R | 26 ++++++++--- R/errors.R | 14 ++++++ R/state.R | 24 +++++----- 4 files changed, 152 insertions(+), 38 deletions(-) diff --git a/R/api.R b/R/api.R index 5b4c063..dd9b24a 100644 --- a/R/api.R +++ b/R/api.R @@ -13,10 +13,22 @@ ## limitations under the License. ##' @export -run <- function(project="",m=NULL,phases=NULL,help=F) { +##' @param project `character(1)`, a directory containing input data. +##' @param top_data_dir `character(1)`, a directory contining data +##' subdirs. +##' @param metfrag_db_dir `character(1)`, a directory containing +##' MetFrag DBs. +##' @param m `state`, a Shinyscreen state. +##' @param phases `character(n)`, a character vector of Shinyscreen +##' phases. +##' @param help `logical(1)`, print help? +run <- function(project="", + top_data_dir="", + metfrag_db_dir="", + m=NULL, + phases=NULL, + help=F) { - ## Get system-wide config. - eo = load_envopts() all_phases=list(setup=setup_phase, @@ -40,7 +52,14 @@ run <- function(project="",m=NULL,phases=NULL,help=F) { stop("Aborting.") } all_phases[phases] + } + + eo = prepare_paths(project=project, + projects="", + top_data_dir=top_data_dir, + metfrag_db_dir=metfrag_db_dir) + m <- if (nchar(project)!=0) new_project(project,envopts=eo) else if (!is.null(m)) m else stop("(run): Either the YAML config file (project),\n or the starting state (m) must be provided\n as the argument to the run function.") ## m$conf$project <- norm_path(m$conf$project) #FIXME: Test in all workflows! @@ -678,16 +697,74 @@ create_plots <- function(m) { m } + +prepare_paths <- function(project, + projects, + top_data_dir, + metfrag_db_dir) { + + ## Get system-wide config. + eo = load_envopts() + + ## Figure out how to run. + + + if (nchar(top_data_dir)>0) { + ## Specified `top_data_dir` overrides everything. + eo$top_data_dir = norm_path(top_data_dir) + } else { + ## If no user supplied `top_data_dir`, check if envopts + ## top_data_dir is empty. + if (nchar(eo$top_data_dir)==0L) { + ## If yes, the last attempt is to designate + ## `project` dir as `top_data_dir` directory. + if (dir.exists(project)) eo$top_data_dir=norm_path(project) + } + + } + + + ## In case `project` is a not a zero-length string. + if (nchar(project)!=0) { + ## The variable `projects` is alwas a super-directory of + ## `project`. + withr::with_dir(project,{ + eo$projects=norm_path("..") + }) + } else { + if (nchar(projects)!=0) { + eo$projects=projects + } + } + + + ## Override the default `db_dir` if `metfrag_db_dir` supplied. + if (nchar(metfrag_db_dir)>0) { + eo$metfrag$db_dir = norm_path(metfrag_db_dir) + } else { + ## If no default `db_dir`, try with `project`. + if (nchar(eo$metfrag$db_dir)==0L) { + eo$metfrag$db_dir = norm_path(project) + } + } + eo +} + prepare_app <- function(dir_before, projects, - top_data_dir) { + top_data_dir, + metfrag_db_dir) { ## Information that needs to be availabe to the shiny server. init <- list() init$dir_before <- dir_before - init$top_data_dir <- norm_path(top_data_dir) - init$projects <- norm_path(projects) - init$envopts = load_envopts() + init$envopts = prepare_paths(project="", + projects=projects, + top_data_dir=top_data_dir, + metfrag_db_dir=metfrag_db_dir) + init$top_data_dir <- init$envopts$top_data_dir + init$projects <- init$envopts$projects + check_dir_absent(init$top_data_dir,what="top-data-dir") check_dir_absent(init$projects,what="projects") @@ -717,18 +794,19 @@ prepare_app <- function(dir_before, #' containing project directories. #' @param top_data_dir `character(1)`, a location on the server side #' containing data directories. +#' @param metfrag_db_dir `character(1)`, a location on the server side +#' containing MetFrag databases. #' @param shiny_args `list`, optional list of arguments conveyed to #' `rmarkdown::run` `shiny_args` argument. #' @param render_args `list`, optional list of arguments conveyed to #' `rmarkdown::run` `render_args` argument. -#' @param metfrag_db_dir `character(1)`, a location on the server side -#' containing MetFrag databases. #' @param metfrag_runtime `character(1)`, a location on the server side #' of the MetFrag jar file. #' @return Nada. #' @author Todor Kondić -app <- function(projects=getwd(), - top_data_dir=getwd(), +app <- function(projects="", + top_data_dir="", + metfrag_db_dir="", shiny_args=list(launch.browser=F), render_args=NULL) { dir_before = getwd() @@ -737,7 +815,8 @@ app <- function(projects=getwd(), message("projects: ", projects) dir_start = prepare_app(dir_before=dir_before, projects=projects, - top_data_dir=top_data_dir) + top_data_dir=top_data_dir, + metfrag_db_dir=metfrag_db_dir) on.exit(expr=setwd(dir_before)) setwd(dir_start) @@ -749,6 +828,8 @@ app <- function(projects=getwd(), #' @title serve #' @param top_data_dir `character(1)`, a location on the server side #' containing data directories. +#' @param metfrag_db_dir `character(1)`, a location on the server side +#' containing MetFrag DBs. #' @param usersdir `character(1)`, a location on the server side #' containing individual user directories. #' @param user `character(1)`, subdir of usersdir. @@ -758,7 +839,7 @@ app <- function(projects=getwd(), #' served. #' @return Nada. #' @author Todor Kondić -serve <- function(top_data_dir,usersdir,user,host='0.0.0.0',port=7777) { +serve <- function(top_data_dir,metfrag_db_dir,usersdir,user,host='0.0.0.0',port=7777) { shiny_args <- c(list(launch.browser=F),list(host=host,port=port)) projects <- file.path(usersdir,user) if (!dir.exists(projects)) { @@ -767,7 +848,10 @@ serve <- function(top_data_dir,usersdir,user,host='0.0.0.0',port=7777) { } else { message('Using existing projects: ', projects) } - app(shiny_args=shiny_args,top_data_dir=top_data_dir,projects=projects) + app(shiny_args=shiny_args, + top_data_dir=top_data_dir, + projects=projects, + metfrag_db_dir=metfrag_db_dir) } @@ -862,14 +946,18 @@ report <- function(m) { #' @inheritParams envopts #' @return Nothing. #' @author Todor Kondić -init <- function(metfrag_db_dir="", +init <- function(projects="", + top_data_dir="", + metfrag_db_dir="", metfrag_jar="", java_bin=Sys.which("java"), metfrag_max_proc=parallel::detectCores()) { - e = envopts(metfrag_db_dir=metfrag_db_dir, - metfrag_jar=metfrag_jar, - java_bin=java_bin, - metfrag_max_proc=metfrag_max_proc) + e = envopts(projects = projects, + top_data_dir = top_data_dir, + metfrag_db_dir = metfrag_db_dir, + metfrag_jar = metfrag_jar, + java_bin = java_bin, + metfrag_max_proc = metfrag_max_proc) save_envopts(o=e) } diff --git a/R/envopts.R b/R/envopts.R index 8d58fd8..cfccd2e 100644 --- a/R/envopts.R +++ b/R/envopts.R @@ -23,26 +23,42 @@ #' @title Create a `envopts` Object -#' @details A `envopts` object is Shinyscreen way to store settings +#' @details An `envopts` object is Shinyscreen way to store settings #' related to a specific computing environment. Information such #' as the run time path to a MetFrag JAR will vary from one to #' another setup and we need to convey this to the `shinyscreen` #' pipeline. -#' @param metfrag_db_dir `character(1)`, a path to the directory which contains MetFrag databases -#' @param metfrag_jar `character(1)`, a path to MetFrag JAR file +#' @param projects `character(1)`, a directory which contains all +#' shinyscreen projects directories. A single project directory +#' contains input and output files. +#' @param top_data_dir `character(1)`, a directory which contains all +#' `data` directories. A single `data` directory contains `mzML` +#' spectrometry data files. +#' @param metfrag_db_dir `character(1)`, a path to the directory which +#' contains MetFrag databases. +#' @param metfrag_jar `character(1)`, a path to MetFrag JAR file. +#' @param java_bin `character(1)`, a path to jave runtime +#' (optional). We try to detect this. #' @param metfrag_max_proc `integer(1)`, maximum number of CPU cores #' available for MetFrag. #' @return An `envopts` object. #' @author Todor Kondić -envopts <- function(metfrag_db_dir="", +envopts <- function(projects="", + top_data_dir="", + metfrag_db_dir="", metfrag_jar="", java_bin=Sys.which("java"), metfrag_max_proc = parallel::detectCores()) { res = list(metfrag=list()) + class(res) = c("envopts","list") #Just to officially make it an #object. - check_dir_absent(metfrag_db_dir,what="mf-db-dir") + check_dir_absent_nz(projects,what="projects-dir") + res$projects = projects + check_dir_absent_nz(top_data_dir,what="top-data-dir") + res$top_data_dir=top_data_dir + check_dir_absent_nz(metfrag_db_dir,what="mf-db-dir") res$metfrag$db_dir = norm_path(metfrag_db_dir) check_file_absent(metfrag_jar,what="mf-jar") diff --git a/R/errors.R b/R/errors.R index 18db2d8..32e69d9 100644 --- a/R/errors.R +++ b/R/errors.R @@ -23,11 +23,25 @@ check_dir_absent <- function(dir,what) { if (nchar(dir)>0L && !dir.exists(dir)) stop(errorCondition(paste0("The ", what, " directory --- ", dir, "--- does not exist, or cannot be found."), class=paste0(what,'-absent'))) } +check_dir_absent_nz <- function(dir,what) { + check_notastring(dir,what) + if (nchar(dir)>0L) { + check_dir_absent(dir,what) + } +} + check_file_absent <- function(file,what) { check_notastring(file,what) if (nchar(file)>0L && !file.exists(file)) stop(errorCondition(paste0("The ", what, " file --- ", file, "--- does not exist, or cannot be found."), class=paste0(what,'-absent'))) } +check_file_absent_nz <- function(file,what) { + check_notastring(file,what) + if (nchar(file)>0L) { + check_file_absent(file,what) + } +} + check_not_one <- function(value,what) { if (length(value)!=1L) stop(errorCondition(paste0("Size of", what, " is not one."), class=paste0(what,'-not-one'))) } diff --git a/R/state.R b/R/state.R index 7ffa75d..466f597 100644 --- a/R/state.R +++ b/R/state.R @@ -174,11 +174,7 @@ new_runtime_state <- function(project,envopts,conf=NULL) { run$metfrag = .metfrag(project_path) - run$paths$data = if (is.null(conf$paths$data)) { - project_path - } else { - norm_path(conf$paths$data) - } + run$paths$data = norm_path(file.path(envopts$top_data_dir,conf$paths$data)) check_dir_absent(run$paths$data,"data-dir") @@ -248,18 +244,18 @@ import_project <- function(project,envopts=envopts) { ##' @export new_rv_state <- function() react_v(m=list2rev(new_state())) -write_conf <- function(m,fn) { - m$conf$paths$data <- get_fn_ftab(m) - if (NROW(m$input$tab$mzml)>0) tab2file(tab=m$input$tab$mzml,file=file.path(m$run$paths$project,FN_DATA_TAB)) - yaml::write_yaml(x=m$conf,file=fn) +## write_conf <- function(m,fn) { +## m$conf$paths$data <- get_fn_ftab(m) +## if (NROW(m$input$tab$mzml)>0) tab2file(tab=m$input$tab$mzml,file=file.path(m$run$paths$project,FN_DATA_TAB)) +## yaml::write_yaml(x=m$conf,file=fn) -} -write_state <- function(m,fn_conf) { - write_conf(m,fn_conf) - tab2file(tab=m$input$tab$mzml,file=file.path(m$run$paths$project,FN_DATA_TAB)) -} +## } +## write_state <- function(m,fn_conf) { +## write_conf(m,fn_conf) +## tab2file(tab=m$input$tab$mzml,file=file.path(m$run$paths$project,FN_DATA_TAB)) +## } label_cmpd_lists <- function (lists) { if (length(lists)>0) { -- GitLab