diff --git a/DESCRIPTION b/DESCRIPTION index aabef0f..3e67c5a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -48,6 +48,7 @@ Suggests: knitr, RefManageR, rmarkdown, + scRNAseq, sessioninfo, testthat (>= 3.0.0), yaml diff --git a/R/iSEEindex.R b/R/iSEEindex.R index 597b3d2..edaba54 100644 --- a/R/iSEEindex.R +++ b/R/iSEEindex.R @@ -6,15 +6,19 @@ #' states prepared by the app maintainer. #' #' @section Data Sets: -#' The function passed to the argument `FUN.datasets` must return a `list` that contains metadata about the available data sets. +#' The function passed to the argument `FUN.datasets` must return a `list` that +#' contains metadata about the available data sets. #' #' For each data set, required metadata are: #' #' \describe{ #' \item{id}{A unique identifier for the data set.} -#' \item{title}{A short human-readable title for the data set, displayed in the 'Info' panel when the data set is selected.} -#' \item{uri}{A Uniform Resource Identifier (URI) that indicates the location of the data file that contains the data set.} -#' \item{description}{A more detailed description of the data set, displayed in the 'Info' panel when the data set is selected.} +#' \item{title}{A short human-readable title for the data set, displayed in the +#' 'Info' panel when the data set is selected.} +#' \item{uri}{A Uniform Resource Identifier (URI) that indicates the location of +#' the data file that contains the data set.} +#' \item{description}{A more detailed description of the data set, displayed in +#' the 'Info' panel when the data set is selected.} #' } #' #' Example: @@ -22,40 +26,54 @@ #' ``` #' list( #' list( -#' id = "dataset01", -#' title = "Dataset 01", -#' uri = "https://example.com/1.rds", -#' description = "My first data set." +#' id = "dataset01", +#' title = "Dataset 01", +#' uri = "https://example.com/1.rds", +#' description = "My first data set." #' ), #' list( -#' id = "dataset02", -#' title = "Dataset 02", -#' uri = "https://example.com/1.rds", -#' description = "My second data set." +#' id = "dataset02", +#' title = "Dataset 02", +#' uri = "https://example.com/1.rds", +#' description = "My second data set." #' ) #' ) #' ``` #' -#' The individual sub-lists may also contain optional named metadata specific to individual [`iSEEindexResource-class`] classes (refer to the help page of those classes for details). +#' The individual sub-lists may also contain optional named metadata specific to +#' individual [`iSEEindexResource-class`] classes (refer to the help page of +#' those classes for details). #' -#' **Important**: The `id` value is used to identify the data set file in the \pkg{BiocFileCache}. -#' Thus, we recommend using a dedicated `BiocFileCache()` for the app, using the `BiocFileCache(cache)` argument to specify an on-disk location (directory path) for the dedicated cache. +#' **Important**: The `id` value is used to identify the data set file in the +#' \pkg{BiocFileCache}. +#' Thus, we recommend using a dedicated `BiocFileCache()` for the app, using the +#' `BiocFileCache(cache)` argument to specify an on-disk location (directory +#' path) for the dedicated cache. #' #' @section Initial Configurations: -#' The function passed to the argument `FUN.initial` must return a `list` that contains metadata about the available initial configurations, or `NULL` in the absence of any custom initial configuration (default settings will be applied to all data sets.). +#' The function passed to the argument `FUN.initial` must return a `list` that +#' contains metadata about the available initial configurations, or `NULL` in +#' the absence of any custom initial configuration (default settings will be +#' applied to all data sets.). #' #' For each initial configuration, required metadata are: #' #' \describe{ #' \item{id}{A unique identifier for the initial configuration.} -#' \item{title}{A short human-readable title for the initial configuration, representing the initial configuration in the 'Initial settings' dropdown menu.} -#' \item{uri}{A Uniform Resource Identifier (URI) that indicates the location of the R script that contains the initial configuration.} -#' \item{description}{A more detailed description of the initial configuration, displayed in the 'Configure and launch' panel when the initial configuration is selected.} +#' \item{title}{A short human-readable title for the initial configuration, +#' representing the initial configuration in the 'Initial settings' dropdown menu.} +#' \item{uri}{A Uniform Resource Identifier (URI) that indicates the location of +#' the R script that contains the initial configuration.} +#' \item{description}{A more detailed description of the initial configuration, +#' displayed in the 'Configure and launch' panel when the initial configuration +#' is selected.} #' } #' #' For each initial configuration, optional metadata are: #' \describe{ -#' \item{datasets}{A series of data set identifiers for which the configuration should be made available. If missing, the configuration will be available for all data sets.} +#' \item{datasets}{A series of data set identifiers for which the configuration +#' should be made available. If missing, the configuration will be available for +#' all data sets.} #' } #' #' Example: @@ -78,7 +96,9 @@ #' ) #' ``` #' -#' The individual sub-lists may also contain additional optional named metadata specific to individual [`iSEEindexResource-class`] classes (refer to the help page of those classes for details). +#' The individual sub-lists may also contain additional optional named metadata +#' specific to individual [`iSEEindexResource-class`] classes (refer to the help +#' page of those classes for details). #' #' @param bfc An [BiocFileCache()] object. #' @param FUN.datasets A function that returns a `list` of metadata for @@ -96,9 +116,9 @@ #' info on the versions of the `iSEEindex` and `iSEE` packages. #' @param body.header UI element to display \emph{above} the main landing page body. #' @param body.footer UI element to display \emph{below} the main landing page body. -#' @param already_se_object TODO #' -#' @return An [iSEE::iSEE()] app with a custom landing page using a [BiocFileCache()] to cache a selection of data sets. +#' @return An [iSEE::iSEE()] app with a custom landing page using a +#' [BiocFileCache()] to cache a selection of data sets. #' #' @author Kevin Rue-Albrecht #' @@ -168,8 +188,7 @@ #' default.position = "last", #' app.title = "iSEE ❤️ Tonsil Data Atlas", #' body.header = header_tonsils, -#' body.footer = footer_tonsils, -#' already_se_object = TRUE) +#' body.footer = footer_tonsils) #' #' if (interactive()) { #' shiny::runApp(app_tonsils, port = 5678) @@ -181,8 +200,7 @@ iSEEindex <- function(bfc, default.position = c("first", "last"), app.title = NULL, body.header = NULL, - body.footer = NULL, - already_se_object = FALSE) { + body.footer = NULL) { stopifnot(is(bfc, "BiocFileCache")) if (is.null(FUN.initial)) { FUN.initial <- function() NULL @@ -195,108 +213,19 @@ iSEEindex <- function(bfc, } iSEE( - landingPage = .landing_page(bfc, - FUN.datasets, - FUN.initial, - default.add, - default.position, - body.header, - body.footer, - already_se_object = already_se_object + landingPage = .landing_page( + bfc, + FUN.datasets, + FUN.initial, + default.add, + default.position, + body.header, + body.footer ), appTitle = app.title ) } -#### #' @examples -#### #' ## -#### #' ## -#### #' -#### #' library(BiocFileCache) -#### #' bfc <- BiocFileCache(cache = tempdir()) -#### #' -#### #' ## -#### #' ## -#### #' -#### #' dataset_fun <- function() { -#### #' x <- yaml::read_yaml( -#### #' system.file("tonsils_example", "tonsil_package.yml", package = "iSEEindex") -#### #' ) -#### #' x$datasets -#### #' } -#### #' -#### #' initial_fun <- function() { -#### #' x <- yaml::read_yaml( -#### #' system.file("tonsils_example", "tonsil_package.yml", package = "iSEEindex") -#### #' ) -#### #' x$initial -#### #' } -#### #' -#### #' library("shiny") -#### #' header_tonsils <- fluidRow( -#### #' shinydashboard::box( -#### #' width = 12, -#### #' collapsible = TRUE, -#### #' collapsed = TRUE, -#### #' title = "How to explore the Tonsil Atlas datasets", -#### #' includeMarkdown( -#### #' system.file("tonsils_example", "header_tonsils.md", package = "iSEEindex") -#### #' ) -#### #' ) -#### #' ) -#### #' -#### #' footer_tonsils <- fluidRow( -#### #' shinydashboard::box( -#### #' width = 12, -#### #' includeMarkdown( -#### #' system.file("tonsils_example", "footer_tonsils.md", package = "iSEEindex") -#### #' ) -#### #' ) -#### #' ) -#### #' -#### #' app <- iSEEindex_runr(bfc, dataset_fun, initial_fun, -#### #' default.add = TRUE, -#### #' default.position = "last", -#### #' app.title = "iSEE ❤️ Tonsil Data Atlas", -#### #' body.header = header_tonsils, -#### #' body.footer = footer_tonsils) -#### #' -#### #' if (interactive()) { -#### #' shiny::runApp(app, port = 1234) -#### #' } -#### # iSEEindex_runr <- function(bfc, -#### # FUN.datasets, -#### # FUN.initial = NULL, -#### # default.add = TRUE, -#### # default.position = c("first", "last"), -#### # app.title = NULL, -#### # body.header = NULL, -#### # body.footer = NULL) { -#### # stopifnot(is(bfc, "BiocFileCache")) -#### # if (is.null(FUN.initial)) { -#### # FUN.initial <- function() NULL -#### # } -#### # -#### # if (is.null(app.title)) { -#### # app.title <- sprintf("iSEEindex - v%s", -#### # packageVersion("iSEEindex")) -#### # } else { -#### # app.title <- app.title -#### # } -#### # -#### # iSEE( -#### # landingPage=.landing_page(bfc, -#### # FUN.datasets, -#### # FUN.initial, -#### # default.add, default.position, -#### # body.header, -#### # body.footer, -#### # already_se_object = TRUE), -#### # appTitle = app.title -#### # ) -#### # } - - #' Prepare and Launch the Main App. #' @@ -319,7 +248,6 @@ iSEEindex <- function(bfc, #' @param session The Shiny session object from the server function. #' @param pObjects An environment containing global parameters generated in the #' landing page. -#' @param already_se_object TODO propagated #' #' @return A `NULL` value is invisibly returned. #' @@ -331,7 +259,7 @@ iSEEindex <- function(bfc, #' @importFrom shinyjs enable #' #' @rdname INTERNAL_launch_isee -.launch_isee <- function(FUN, bfc, session, pObjects, already_se_object) { +.launch_isee <- function(FUN, bfc, session, pObjects) { # nocov start dataset_id <- pObjects[[.dataset_selected_id]] which_dataset <- which(pObjects$datasets_table[[.datasets_id]] == dataset_id) @@ -342,8 +270,7 @@ iSEEindex <- function(bfc, withProgress(message = sprintf("Loading '%s'", dataset_title), value = 0, max = 2, { incProgress(1, detail = "(Down)loading object") - se2 <- try(.load_sce(bfc, dataset_id, dataset_metadata, - already_se_object = already_se_object)) + se2 <- try(.load_sce(bfc, dataset_id, dataset_metadata)) incProgress(1, detail = "Launching iSEE app") if (is(se2, "try-error")) { showNotification("Invalid SummarizedExperiment supplied.", type="error") @@ -392,67 +319,3 @@ iSEEindex <- function(bfc, # nocov end } - - - - - -# .launch_isee_runr <- function(FUN, bfc, session, pObjects) { -# # nocov start -# dataset_id <- pObjects[[.dataset_selected_id]] -# which_dataset <- which(pObjects$datasets_table[[.datasets_id]] == dataset_id) -# # TODO: refactor as function that takes data set identifier and returns uri -# dataset_metadata <- as.list(pObjects$datasets_table[which_dataset, , drop=FALSE]) -# # TODO: refactor as function that takes data set identifier and returns title -# dataset_title <- pObjects$datasets_table[which_dataset, .datasets_title, drop=TRUE] -# withProgress(message = sprintf("Loading '%s'", dataset_title), -# value = 0, max = 2, { -# incProgress(1, detail = "(Down)loading object") -# se2 <- try(.load_sce(bfc, dataset_id, dataset_metadata, already_se_object = TRUE)) -# incProgress(1, detail = "Launching iSEE app") -# if (is(se2, "try-error")) { -# showNotification("Invalid SummarizedExperiment supplied.", type="error") -# } else { -# if (is.null(pObjects$initial_table)) { -# initial <- NULL -# tour <- NULL -# } else { -# initial_id <- pObjects[[.ui_initial]] -# which_initial <- which( -# pObjects$initial_table[[.initial_config_id]] == initial_id & -# pObjects$initial_table[[.initial_datasets_id]] == dataset_id -# ) -# initial_metadata <- as.list(pObjects$initial_table[which_initial, , drop = FALSE]) -# initial_message <- capture.output( -# init <- try(.parse_initial(bfc, dataset_id, initial_id, initial_metadata)), -# type = "message") -# initial <- init$initial -# tour <- init$tour -# } -# if (is(init, "try-error")) { -# showModal(modalDialog( -# title = "Invalid initial state", -# p("An error occured while evaluating the script:"), -# markdown(paste0(c("```", initial_message, "```"), collapse = "\n")), -# p("Contact the app maintainer for further help."), -# footer = NULL, -# size = "l", -# easyClose = TRUE -# )) -# return(NULL) -# } -# FUN(SE=se2, INITIAL=initial, TOUR=tour) -# shinyjs::enable(iSEE:::.generalOrganizePanels) # organize panels -# shinyjs::enable(iSEE:::.generalLinkGraph) # link graph -# shinyjs::enable(iSEE:::.generalExportOutput) # export content -# shinyjs::enable(iSEE:::.generalCodeTracker) # tracked code -# shinyjs::enable(iSEE:::.generalPanelSettings) # panel settings -# shinyjs::enable(iSEE:::.generalVignetteOpen) # open vignette -# shinyjs::enable(iSEE:::.generalSessionInfo) # session info -# shinyjs::enable(iSEE:::.generalCitationInfo) # citation info -# } -# }, session = session) -# -# invisible(NULL) -# # nocov end -# } diff --git a/R/iSEEindexResource-class.R b/R/iSEEindexResource-class.R index 2c7caf5..4371437 100644 --- a/R/iSEEindexResource-class.R +++ b/R/iSEEindexResource-class.R @@ -2,7 +2,8 @@ #' The iSEEindexResource class #' -#' The iSEEindexResource class is a virtual class from which classes of supported resource must be derived. +#' The iSEEindexResource class is a virtual class from which classes of +#' supported resource must be derived. #' #' @section Slot overview: #' \itemize{ @@ -10,11 +11,14 @@ #' } #' #' @section Supported methods: -#' In the following code snippets, \code{x} is an instance of a [`iSEEindexResource-class`] class. -#' Refer to the documentation for each method for more details on the remaining arguments. +#' In the following code snippets, \code{x} is an instance of a +#' [`iSEEindexResource-class`] class. +#' Refer to the documentation for each method for more details on the remaining +#' arguments. #' #' \itemize{ -#' \item \code{\link{precache}(x, bfc, id, ...)} throws an error, encouraging users to develop a method for derived classes that are not supported yet. +#' \item \code{\link{precache}(x, bfc, id, ...)} throws an error, encouraging +#' users to develop a method for derived classes that are not supported yet. #' } #' #' @author Kevin Rue-Albrecht @@ -58,7 +62,8 @@ setMethod("show", "iSEEindexResource", #' @param ... additional arguments passed to and from other methods. #' #' @section Preparing and caching resources: -#' `precache(x, bfc, id, ...)` retrieves and caches a resource from an URI, caches it, and returns the path to the cached file. +#' `precache(x, bfc, id, ...)` retrieves and caches a resource from an URI, +#' caches it, and returns the path to the cached file. #' #' @author Kevin Rue-Albrecht #' @@ -79,7 +84,8 @@ NULL #' @export #' @rdname iSEEindexResource-generics #' -#' @return `precache()` returns the file path to the cached copy of a resource fetched from a given URI. +#' @return `precache()` returns the file path to the cached copy of a resource +#' fetched from a given URI. setGeneric("precache", function(x, bfc, id, ...) { stopifnot(is(x, "iSEEindexResource"), length(x) == 1L) standardGeneric("precache") @@ -119,14 +125,19 @@ setMethod("precache", "iSEEindexResource", #' } #' #' @section Slot overview: -#' This class inherits all slots from its parent class \linkS4class{iSEEindexResource}. +#' This class inherits all slots from its parent class +#' \linkS4class{iSEEindexResource}. #' #' @section Supported methods: -#' In the following code snippets, \code{x} is an instance of a \linkS4class{iSEEindexHttpsResource} class. -#' Refer to the documentation for each method for more details on the remaining arguments. +#' In the following code snippets, \code{x} is an instance of a +#' \linkS4class{iSEEindexHttpsResource} class. +#' Refer to the documentation for each method for more details on the remaining +#' arguments. #' #' \itemize{ -#' \item \code{\link{precache}(x, bfc, id, ...)} caches the resource located at the given URI using \pkg{BiocFileCache} and returns the file path to the cached file. +#' \item \code{\link{precache}(x, bfc, id, ...)} caches the resource located at +#' the given URI using \pkg{BiocFileCache} and returns the file path to the +#' cached file. #' } #' #' @author Kevin Rue-Albrecht @@ -148,7 +159,8 @@ setClass("iSEEindexHttpsResource", contains="iSEEindexResource") #' #' @param x List of metadata. See Details. #' -#' @return The constructor function `iSEEindexHttpsResource()` returns an object of object of class `iSEEindexHttpsResource`. +#' @return The constructor function `iSEEindexHttpsResource()` returns an object +#' of class `iSEEindexHttpsResource`. iSEEindexHttpsResource <- function(x) { new("iSEEindexHttpsResource", uri = x[[.datasets_uri]]) } @@ -183,11 +195,15 @@ setMethod("precache", "iSEEindexHttpsResource", #' This class inherits all slots from its parent class \linkS4class{iSEEindexResource}. #' #' @section Supported methods: -#' In the following code snippets, \code{x} is an instance of a \linkS4class{iSEEindexLocalhostResource} class. -#' Refer to the documentation for each method for more details on the remaining arguments. +#' In the following code snippets, \code{x} is an instance of a +#' \linkS4class{iSEEindexLocalhostResource} class. +#' Refer to the documentation for each method for more details on the remaining +#' arguments. #' #' \itemize{ -#' \item \code{\link{precache}(x, ...)} trims the `localhost://` prefix, and caches a copy of the resource located at the resulting file path using \pkg{BiocFileCache}, before returning the file path to the cached file. +#' \item \code{\link{precache}(x, ...)} trims the `localhost://` prefix, and +#' caches a copy of the resource located at the resulting file path using +#' \pkg{BiocFileCache}, before returning the file path to the cached file. #' } #' #' @section Absolute and relative paths: @@ -195,7 +211,8 @@ setMethod("precache", "iSEEindexHttpsResource", #' Absolute and relative paths are both supported. #' #' Absolute paths require an additional `/` (forward slash) -#' following the double forward slash `//` separating the scheme component of the URI. +#' following the double forward slash `//` separating the scheme component of +#' the URI. #' #' For instance: #' @@ -225,7 +242,8 @@ setClass("iSEEindexLocalhostResource", contains="iSEEindexResource") #' #' @param x List of metadata. See Details. #' -#' @return The constructor function `iSEEindexLocalhostResource()` returns an object of object of class `iSEEindexLocalhostResource`. +#' @return The constructor function `iSEEindexLocalhostResource()` returns an +#' object of object of class `iSEEindexLocalhostResource`. iSEEindexLocalhostResource <- function(x) { new("iSEEindexLocalhostResource", uri = x[[.datasets_uri]]) } @@ -255,7 +273,8 @@ setMethod("precache", "iSEEindexLocalhostResource", #' Required metadata: #' #' \describe{ -#' \item{uri}{Character scalar. R call which, once evaluated, produces a character scalar that is the URI of the resource.} +#' \item{uri}{Character scalar. R call which, once evaluated, produces a +#' character scalar that is the URI of the resource.} #' } #' #' @section URI format: @@ -269,11 +288,14 @@ setMethod("precache", "iSEEindexLocalhostResource", #' ``` #' #' @section Slot overview: -#' This class inherits all slots from its parent class \linkS4class{iSEEindexResource}. +#' This class inherits all slots from its parent class +#' \linkS4class{iSEEindexResource}. #' #' @section Supported methods: -#' In the following code snippets, \code{x} is an instance of a \linkS4class{iSEEindexRcallResource} class. -#' Refer to the documentation for each method for more details on the remaining arguments. +#' In the following code snippets, \code{x} is an instance of a +#' \linkS4class{iSEEindexRcallResource} class. +#' Refer to the documentation for each method for more details on the remaining +#' arguments. #' #' \itemize{ #' \item \code{\link{precache}(x, ...)} trims the `rcall://` prefix, @@ -303,7 +325,8 @@ setClass("iSEEindexRcallResource", contains="iSEEindexResource") #' #' @param x List of metadata. See Details. #' -#' @return The constructor function `iSEEindexRcallResource()` returns an object of object of class `iSEEindexRcallResource`. +#' @return The constructor function `iSEEindexRcallResource()` returns an object +#' of object of class `iSEEindexRcallResource`. iSEEindexRcallResource <- function(x) { new("iSEEindexRcallResource", uri = x[[.datasets_uri]]) } @@ -325,7 +348,6 @@ setMethod("precache", "iSEEindexRcallResource", }) - # iSEEindexRunrResource ---- #' The iSEEindexRunrResource class @@ -343,11 +365,15 @@ setMethod("precache", "iSEEindexRcallResource", #' } #' #' @section Supported methods: -#' In the following code snippets, \code{x} is an instance of a \linkS4class{iSEEindexRunrResource} class. -#' Refer to the documentation for each method for more details on the remaining arguments. +#' In the following code snippets, \code{x} is an instance of a +#' \linkS4class{iSEEindexRunrResource} class. +#' Refer to the documentation for each method for more details on the remaining +#' arguments. #' #' \itemize{ -#' \item \code{\link{precache}(x, bfc, id, ...)} caches the resource located at the given URI using \pkg{BiocFileCache} and returns the file path to the cached file. +#' \item \code{\link{precache}(x, bfc, id, ...)} caches the resource located at +#' the given URI using \pkg{BiocFileCache} and returns the file path to the +#' cached file. #' } #' #' @name iSEEindexRunrResource-class @@ -369,7 +395,8 @@ setClass("iSEEindexRunrResource", contains="iSEEindexResource") #' #' @param x List of metadata. See Details. #' -#' @return The constructor function `iSEEindexRunrResource()` returns an object of object of class `iSEEindexRunrResource`. +#' @return The constructor function `iSEEindexRunrResource()` returns an object +#' of object of class `iSEEindexRunrResource`. iSEEindexRunrResource <- function(x) { new("iSEEindexRunrResource", uri = x[[.datasets_uri]]) } @@ -394,15 +421,6 @@ setMethod("precache", "iSEEindexRunrResource", - - - - - - - - - # iSEEindexS3Resource ---- #' The iSEEindexS3Resource class @@ -421,7 +439,8 @@ setMethod("precache", "iSEEindexRunrResource", #' } #' #' @section Slot overview: -#' This class inherits all slots from its parent class \linkS4class{iSEEindexResource}. +#' This class inherits all slots from its parent class +#' \linkS4class{iSEEindexResource}. #' #' Furthermore, this class defines the additional slot(s) below: #' \describe{ @@ -429,12 +448,14 @@ setMethod("precache", "iSEEindexRunrResource", #' } #' #' @section Supported methods: -#' In the following code snippets, \code{x} is an instance of a \linkS4class{iSEEindexS3Resource} class. -#' Refer to the documentation for each method for more details on the remaining arguments. +#' In the following code snippets, \code{x} is an instance of a +#' \linkS4class{iSEEindexS3Resource} class. +#' Refer to the documentation for each method for more details on the remaining +#' arguments. #' #' \itemize{ -#' \item \code{\link{precache}(x, ..., temp_dir = tempdir())} trims the `s3://` prefix, -#' parses information encoded in the remainder of the URI, +#' \item \code{\link{precache}(x, ..., temp_dir = tempdir())} trims the `s3://` +#' prefix, parses information encoded in the remainder of the URI, #' downloads the resource from AWS S3 using that information, #' and caches a copy of the resource located at the resulting file path using #' \pkg{BiocFileCache}, before returning the file path to the cached file. @@ -465,7 +486,8 @@ setMethod("precache", "iSEEindexRunrResource", #' For detailed information, please consult the #' [paws R package documentation](https://github.com/paws-r/paws/blob/main/docs/credentials.md). #' -#' Currently, you must have the [AWS Command Line Interface](https://aws.amazon.com/cli/) installed to use AWS SSO with \pkg{paws.storage}. +#' Currently, you must have the [AWS Command Line Interface](https://aws.amazon.com/cli/) +#' installed to use AWS SSO with \pkg{paws.storage}. #' #' A default AWS region can be set in the file `~/.aws/config`. #' For instance: @@ -475,7 +497,8 @@ setMethod("precache", "iSEEindexRunrResource", #' region=eu-west-2 #' ``` #' -#' Optionally, a field named `region` can be added in the list of resource metadata to set the AWS S3 region for each individual resource, e.g. +#' Optionally, a field named `region` can be added in the list of resource +#' metadata to set the AWS S3 region for each individual resource, e.g. #' #' ``` #' - id: ID1 @@ -486,12 +509,16 @@ setMethod("precache", "iSEEindexRunrResource", #' region: eu-west-2 #' ``` #' -#' Regions set in individual resource metadata override the default AWS region set in `~/.aws/config` (if any). -#' The region metadata does not need to be set for resources that should use the default region, and resource classes that do not require region information. +#' Regions set in individual resource metadata override the default AWS region +#' set in `~/.aws/config` (if any). +#' The region metadata does not need to be set for resources that should use the +#' default region, and resource classes that do not require region information. #' -#' If a default region is NOT set in `~/.aws/config`, then the region MUST be set in the metadata. +#' If a default region is NOT set in `~/.aws/config`, then the region MUST be +#' set in the metadata. #' -#' Credentials for all services can be set in the AWS shared credentials file `~/.aws/credentials`. +#' Credentials for all services can be set in the AWS shared credentials file +#' `~/.aws/credentials`. #' For instance: #' #' ``` @@ -529,7 +556,8 @@ setClass("iSEEindexS3Resource", contains="iSEEindexResource", slots = c("region" #' #' @param x List of metadata. See Details. #' -#' @return The constructor function `iSEEindexS3Resource()` returns an object of object of class `iSEEindexS3Resource`. +#' @return The constructor function `iSEEindexS3Resource()` returns an object of +#' object of class `iSEEindexS3Resource`. iSEEindexS3Resource <- function(x) { region <- x[[.dataset_region]] if (is.null(region) || identical(nchar(region), 0L)) { diff --git a/R/landing_page.R b/R/landing_page.R index a507561..de2b95b 100644 --- a/R/landing_page.R +++ b/R/landing_page.R @@ -1,17 +1,19 @@ #' Landing page function #' #' @param bfc A [BiocFileCache()] object. -#' @param FUN.datasets A function that returns a `data.frame` of metadata for available data sets. -#' @param FUN.initial A function that returns a `data.frame` of metadata for initial configuration states. +#' @param FUN.datasets A function that returns a `data.frame` of metadata for +#' available data sets. +#' @param FUN.initial A function that returns a `data.frame` of metadata for +#' initial configuration states. #' @param default.add Logical scalar indicating whether a default -#' initial configuration should be added as a choice in the Shiny `selectizeInput()`. +#' initial configuration should be added as a choice in the Shiny +#' `selectizeInput()`. #' See [iSEEindex()]. #' @param default.position Character scalar indicating whether the default #' initial configuration should be added as the `"first"` or `"last"` option #' in the Shiny `selectizeInput()`. #' @param body.header UI element to display \emph{above} the main landing page body. #' @param body.footer UI element to display \emph{below} the main landing page body. -#' @param already_se_object TODO to be propagated #' #' @return A `function` that defines UI elements and observers for the #' landing page of the app. @@ -31,8 +33,7 @@ default.add = TRUE, default.position = c("first", "last"), body.header = NULL, - body.footer = NULL, - already_se_object) { + body.footer = NULL) { default.position <- match.arg(default.position) # datasets datasets_available_list <- FUN.datasets() @@ -41,7 +42,8 @@ # initial configurations initial_available_list <- FUN.initial() .check_initial_list(initial_available_list) - initial_available_table <- .initial_to_dataframe(initial_available_list, datasets_available_table[[.datasets_id]]) + initial_available_table <- .initial_to_dataframe(initial_available_list, + datasets_available_table[[.datasets_id]]) # landing page function (return value) function (FUN, input, output, session) { # nocov start @@ -53,7 +55,8 @@ shinydashboard::box(title = "Available Data Sets", collapsible = FALSE, width = NULL, selectizeInput(.ui_dataset_columns, label = "Show columns:", - choices = setdiff(colnames(datasets_available_table), c(.datasets_id, .datasets_uri, .datasets_description)), + choices = setdiff(colnames(datasets_available_table), + c(.datasets_id, .datasets_uri, .datasets_description)), selected = c(.datasets_title), multiple = TRUE, options = list(plugins=list('remove_button', 'drag_drop'))), @@ -103,7 +106,7 @@ .create_observers(input, session, pObjects, rObjects, FUN.initial, default.add, default.position) - .create_launch_observers(FUN, bfc, input, session, pObjects, already_se_object = already_se_object) + .create_launch_observers(FUN, bfc, input, session, pObjects) .render_datasets_table(output, pObjects, rObjects) @@ -117,100 +120,14 @@ } - -# .landing_page_runr <- function(bfc, FUN.datasets, FUN.initial, default.add = TRUE, default.position = c("first", "last"), body.header = NULL, body.footer = NULL) { -# default.position <- match.arg(default.position) -# # datasets -# datasets_available_list <- FUN.datasets() -# .check_datasets_list(datasets_available_list) -# datasets_available_table <- .datasets_to_dataframe(datasets_available_list) -# # initial configurations -# initial_available_list <- FUN.initial() -# .check_initial_list(initial_available_list) -# initial_available_table <- .initial_to_dataframe(initial_available_list, datasets_available_table[[.datasets_id]]) -# # landing page function (return value) -# function (FUN, input, output, session) { -# # nocov start -# output$allPanels <- renderUI({ -# tagList( -# body.header, -# fluidRow( -# column(width = 7L, -# shinydashboard::box(title = "Available Data Sets", -# collapsible = FALSE, width = NULL, -# selectizeInput(.ui_dataset_columns, label = "Show columns:", -# choices = setdiff(colnames(datasets_available_table), c(.datasets_id, .datasets_uri, .datasets_description)), -# selected = c(.datasets_title), -# multiple = TRUE, -# options = list(plugins=list('remove_button', 'drag_drop'))), -# DTOutput(.ui_dataset_table) -# )), -# column(width = 5L, -# shinydashboard::tabBox(id = .ui_box_dataset, title = "Selected dataset", -# side = "left", -# width = NULL, -# tabPanel("Info", -# uiOutput(.ui_markdown_overview)), -# tabPanel("Configure and launch", -# fluidRow( -# column(width = 10L, -# selectizeInput(.ui_initial, label = "Initial settings:", -# choices = character(0))), -# column(width = 2L, -# br(), -# actionButton(.ui_launch_button, label="Launch!", -# style="color: #ffffff; background-color: #0092AC; border-color: #2e6da4")) -# ), -# uiOutput(.ui_initial_overview)) -# ) -# ) -# ), -# body.footer -# ) # tagList -# }) # renderUI -# -# ## Disable navbar buttons that are not linked to any observer yet -# shinyjs::disable(iSEE:::.generalOrganizePanels) # organize panels -# shinyjs::disable(iSEE:::.generalLinkGraph) # link graph -# shinyjs::disable(iSEE:::.generalExportOutput) # export content -# shinyjs::disable(iSEE:::.generalCodeTracker) # tracked code -# shinyjs::disable(iSEE:::.generalPanelSettings) # panel settings -# shinyjs::disable(iSEE:::.generalVignetteOpen) # open vignette -# shinyjs::disable(iSEE:::.generalSessionInfo) # session info -# shinyjs::disable(iSEE:::.generalCitationInfo) # citation info -# -# pObjects <- .create_persistent_objects( -# datasets_available_table, -# initial_available_table) -# rObjects <- reactiveValues( -# rerender_datasets=1L, -# rerender_overview=1L, -# rerender_initial=1L) -# -# .create_observers(input, session, pObjects, rObjects, FUN.initial, default.add, default.position) -# -# .create_launch_observers(FUN, bfc, input, session, pObjects, already_se_object = TRUE) -# -# .render_datasets_table(output, pObjects, rObjects) -# -# .render_markdown_overview(output, pObjects, rObjects) -# -# .render_initial_overview(output, pObjects, rObjects) -# -# invisible(NULL) -# # nocov end -# } -# } - - - - #' Create persistent objects #' #' @param datasets_table A `data.frame` of metadata for all available data sets. -#' @param initial_table A `data.frame` of metadata for all available initial configuration scripts. +#' @param initial_table A `data.frame` of metadata for all available initial +#' configuration scripts. #' -#' @return An environment containing several global variables for use throughout the application. +#' @return An environment containing several global variables for use throughout +#' the application. #' #' @author Kevin Rue-Albrecht #' diff --git a/R/observers.R b/R/observers.R index 79e4f12..9731fd8 100644 --- a/R/observers.R +++ b/R/observers.R @@ -4,13 +4,16 @@ #' #' `.create_observers()` initialises observers for the \pkg{iSEEindex} landing page. #' -#' `.create_launch_observers()` initialises observers for launching the \pkg{iSEE} main app. +#' `.create_launch_observers()` initialises observers for launching the +#' \pkg{iSEE} main app. #' #' @param input The Shiny input object from the server function. #' @param session The Shiny session object from the server function. -#' @param pObjects An environment containing global parameters generated in the landing page. +#' @param pObjects An environment containing global parameters generated in the +#' landing page. #' @param rObjects A reactive list of values generated in the landing page. -#' @param FUN.initial A function that returns available scripts for initial configurations states for a given data set identifier. +#' @param FUN.initial A function that returns available scripts for initial +#' configurations states for a given data set identifier. #' @param default.add Logical scalar indicating whether a default #' initial configuration should be added as a choice in the Shiny `selectizeInput()`. #' See [iSEEindex()]. @@ -28,7 +31,13 @@ #' @importFrom rintrojs introjs #' #' @rdname INTERNAL_create_observers -.create_observers <- function(input, session, pObjects, rObjects, FUN.initial, default.add, default.position) { +.create_observers <- function(input, + session, + pObjects, + rObjects, + FUN.initial, + default.add, + default.position) { # nocov start observeEvent(input[[.dataset_selected_row]], { @@ -65,38 +74,23 @@ #' @param FUN A function to initialize the \pkg{iSEE} observer #' architecture. Refer to [iSEE::createLandingPage()] for more details. -#' #' @param bfc A [BiocFileCache()] object. #' landing page. -#' @param input TODO -#' @param session TODO -#' @param pObjects TODO -#' @param already_se_object TODO +#' @param input The Shiny input object from the server function. +#' @param session The Shiny session object from the server function. +#' @param pObjects An environment containing global parameters generated in the +#' landing page. #' #' @importFrom shiny observeEvent #' #' @rdname INTERNAL_create_observers -.create_launch_observers <- function(FUN, bfc, input, session, pObjects, already_se_object) { +.create_launch_observers <- function(FUN, bfc, input, session, pObjects) { # nocov start observeEvent(input[[.ui_launch_button]], { - .launch_isee(FUN, bfc, session, pObjects, already_se_object = already_se_object) + .launch_isee(FUN, bfc, session, pObjects) }, ignoreNULL=TRUE, ignoreInit=TRUE) # nocov end invisible(NULL) } - - -# -# .create_launch_observers_runr <- function(FUN, bfc, input, session, pObjects) { -# -# # nocov start -# observeEvent(input[[.ui_launch_button]], { -# .launch_isee(FUN, bfc, session, pObjects, already_se_object = TRUE) -# }, ignoreNULL=TRUE, ignoreInit=TRUE) -# # nocov end -# -# invisible(NULL) -# } - diff --git a/R/outputs.R b/R/outputs.R index a102296..814fda9 100644 --- a/R/outputs.R +++ b/R/outputs.R @@ -1,14 +1,15 @@ #' Render Table of Available Data Sets #' #' @param output The Shiny output object from the server function. -#' @param pObjects An environment containing global parameters generated in the landing page. +#' @param pObjects An environment containing global parameters generated in the +#' landing page. #' @param rObjects A reactive list of values generated in the landing page. #' #' @return Adds a rendered [DT::datatable()] to `output`. #' A \code{NULL} value is invisibly returned. -#' +#' #' @author Kevin Rue-Albrecht -#' +#' #' @importFrom DT datatable renderDT #' #' @rdname INTERNAL_render_datasets_table @@ -32,17 +33,20 @@ } #' Render Overview of Selected Data Set -#' +#' #' @description -#' -#' `.render_markdown_overview()` renders an overview of the selected data set using Markdown. -#' -#' `.render_initial_overview()` renders an overview of the selected initial configuration using Markdown. +#' +#' `.render_markdown_overview()` renders an overview of the selected data set +#' using Markdown. +#' +#' `.render_initial_overview()` renders an overview of the selected initial +#' configuration using Markdown. #' #' @param output The Shiny output object from the server function. -#' @param pObjects An environment containing global parameters generated in the landing page. +#' @param pObjects An environment containing global parameters generated in the +#' landing page. #' @param rObjects A reactive list of values generated in the landing page. -#' +#' #' @details #' Currently, those functions expect a column named `uri` in the metadata table #' of available data sets, which it uses as the identifier for each data set. @@ -50,9 +54,9 @@ #' @return #' `.render_markdown_overview()` and `.render_initial_overview()` both #' add a rendered [shiny::markdown()] to `output`. -#' +#' #' In both cases, a \code{NULL} value is invisibly returned. -#' +#' #' @author Kevin Rue-Albrecht #' #' @importFrom shiny markdown renderUI @@ -97,7 +101,7 @@ initial_id <- pObjects[[.ui_initial]] dataset_id <- pObjects[[.dataset_selected_id]] which_initial <- which( - pObjects$initial_table[[.initial_config_id]] == initial_id & + pObjects$initial_table[[.initial_config_id]] == initial_id & pObjects$initial_table[[.initial_datasets_id]] == dataset_id ) initial_info <- pObjects$initial_table[which_initial, .initial_description, drop=TRUE] diff --git a/R/utils-datasets.R b/R/utils-datasets.R index 8eced35..8496c40 100644 --- a/R/utils-datasets.R +++ b/R/utils-datasets.R @@ -7,8 +7,8 @@ #' #' @param bfc A [BiocFileCache()] object. #' @param id A data set identifier as a character scalar. -#' @param metadata Named list of metadata. See individual resource classes for required and optional metadata. -#' @param already_se_object Logical, TODO - shall we default this to FALSE? +#' @param metadata Named list of metadata. See individual resource classes for +#' required and optional metadata. #' #' @return #' For `.load_sce()`, a [SingleCellExperiment()] object. @@ -29,18 +29,30 @@ #' #' ## Usage --- #' -#' iSEEindex:::.load_sce(bfc, id, metadata, already_se_object = FALSE) +#' iSEEindex:::.load_sce(bfc, id, metadata) #' #' ## Alternatively, using the runr approach #' id_tonsil <- "demo_load_sce_tonsil" -#' metadata <- list( +#' metadata_tonsil <- list( #' uri="runr://HCATonsilData::HCATonsilData(assayType = 'RNA', cellType = 'epithelial')" #' ) -#' iSEEindex:::.load_sce(bfc, id, metadata, already_se_object = TRUE) +#' iSEEindex:::.load_sce(bfc, id_tonsil, metadata_tonsil) .load_sce <- function(bfc, id, - metadata, - already_se_object) { + metadata) { + resource_obj <- .metadata_to_object(metadata) + if (is(resource_obj, "iSEEindexHttpsResource") | + is(resource_obj, "iSEEindexLocalhostResource") | + is(resource_obj, "iSEEindexRcallResource") | + is(resource_obj, "iSEEindexS3Resource")) { + already_se_object <- FALSE + } else if (is(resource_obj, "iSEEindexRunrResource")) { + already_se_object <- TRUE + } else { + # without knowing too much about it... + already_se_object <- FALSE + } + if (!already_se_object) { bfc_result <- bfcquery(bfc, id, field = "rname", exact = TRUE) # nocov start @@ -65,50 +77,6 @@ - -### #' @examples -### #' -### #' library(BiocFileCache) -### #' bfc <- BiocFileCache(tempdir()) -### #' id <- "demo_load_sce_tonsil" -### #' metadata <- list(uri="runr://HCATonsilData::HCATonsilData(assayType = 'RNA', cellType = 'epithelial')") -### #' -### #' ## Usage --- -### #' -### #' iSEEindex:::.load_sce_runr(bfc, id, metadata) -# .load_sce_runr <- function(bfc, id, metadata) { -# bfc_result <- bfcquery(bfc, id, field = "rname", exact = TRUE) -# # nocov start -# # if (nrow(bfc_result) == 0) { -# # uri_object <- .metadata_to_object(metadata) -# # object_path <- precache(uri_object, bfc, id) -# # } else { -# # object_path <- bfc[[bfc_result$rid]] -# # } -# -# uri_object <- .metadata_to_object(metadata) -# -# object_call <- precache(uri_object, bfc, id) -# # if (nrow(bfc_result) == 0) { -# # uri_object <- .metadata_to_object(metadata) -# # object_path <- precache(uri_object, bfc, id) -# # } else { -# # object_path <- bfc[[bfc_result$rid]] -# # } -# -# -# # nocov end -# # object <- readRDS(object_path) -# -# object <- object_call -# -# object <- .convert_to_sce(object) -# object -# } - - - - #' @param x An object Coercible to SingleCellExperiment #' #' @return @@ -130,6 +98,7 @@ x } + #' Convert Metadata to Class #' #' @param x Named list of metadata. @@ -174,12 +143,12 @@ } - #' Check Validity of Data Sets Metadata #' #' @param x `list` of of lists of metadata. #' -#' @return Invisible `NULL` if the metadata table is valid. Otherwise, throw an error. +#' @return Invisible `NULL` if the metadata table is valid. Otherwise, throw an +#' error. #' #' @author Kevin Rue-Albrecht #' diff --git a/R/utils-initial.R b/R/utils-initial.R index 993aa5c..48161a2 100644 --- a/R/utils-initial.R +++ b/R/utils-initial.R @@ -18,10 +18,10 @@ #' added to the choices for all data sets. #' That default option launches an initial state that includes one panel of #' each type compatible with the information present in the data set. -#' +#' #' The default initial configuration is always added for data sets which are not #' associated with any custom initial configuration. -#' +#' #' The option `default.add` controls whether the default initial configuration #' is added to the choices for data sets associated with at least one custom #' initial configuration. @@ -32,13 +32,16 @@ #' @author Kevin Rue-Albrecht #' #' @rdname INTERNAL_initial_choices -.initial_choices <- function(id, available, default.add = TRUE, default.position = c("first", "last")) { +.initial_choices <- function(id, + available, + default.add = TRUE, + default.position = c("first", "last")) { default.position <- match.arg(default.position) which_initial <- available[[.initial_datasets_id]] == id config_subset_table <- available[which_initial, , drop=FALSE] initial_choices <- config_subset_table[[.initial_config_id]] names(initial_choices) <- config_subset_table[[.initial_title]] - + if (default.add) { default_choice <- c("Default" = .initial_default_choice) if (identical(default.position, "first")) { @@ -47,27 +50,29 @@ initial_choices <- c(initial_choices, default_choice) } } - + initial_choices } #' Parses an Initial Application State script -#' +#' #' @description #' Parses the selected initial application state script. #' This can be a custom R script or the default initial state that creates #' one panel of each class compatible with the contents of the data set. -#' +#' #' The same script may define two objects `initial` and `tour` (see 'Value'). #' #' @param bfc A [BiocFileCache()] object. #' @param dataset_id Character scalar. Identifier of the data set selected. #' @param config_id Character scalar. Identifier of the configuration file to load. -#' @param metadata Named list of metadata. See individual resource classes for required and optional metadata. +#' @param metadata Named list of metadata. See individual resource classes for +#' required and optional metadata. #' #' @return A `list` of two elements. #' \describe{ -#' \item{initial}{A list of [Panel-class] objects, representing an initial app state} +#' \item{initial}{A list of [Panel-class] objects, representing an initial app +#' state} #' \item{tour}{A `data.frame` representing an \pkg{rintrojs} interactive tour} #' } #' @@ -113,7 +118,8 @@ #' #' @param x `list` of lists of metadata. #' -#' @return Invisible `NULL` if the metadata table is valid. Otherwise, throw an error. +#' @return Invisible `NULL` if the metadata table is valid. Otherwise, throw an +#' error. #' #' @author Kevin Rue-Albrecht #' diff --git a/inst/tonsils_example/tonsil_and_mix.yml b/inst/tonsils_example/tonsil_and_mix.yml new file mode 100644 index 0000000..a9e30fc --- /dev/null +++ b/inst/tonsils_example/tonsil_and_mix.yml @@ -0,0 +1,48 @@ +datasets: + - id: Tonsil_epithelial + title: Tonsil Data - Epithelial + uri: runr://HCATonsilData::HCATonsilData(assayType = "RNA", cellType = "epithelial") + description: | + Tonsil Data - Epithelial, 396 cells + +
+ +
+ - id: ReprocessedAllenData + title: ReprocessedAllenData + uri: https://zenodo.org/record/8076991/files/ReprocessedAllenData.rds + description: | + Reprocessed Allen Data. + - id: BuettnerESCData + title: BuettnerESCData + uri: https://zenodo.org/record/8076991/files/BuettnerESCData.rds + description: | + Reprocessed Allen Data (copy). +initial: + - id: Tonsil_epithelial_full5 + datasets: + - Tonsil_epithelial + title: Tonsil_epithelial configuration 1 (R call) + uri: rcall://system.file(package='iSEEindex','tonsils_example/hca_tonsil_epithelial_v2.R') + # uri: localhost:///Users/fede/Development/iSEEindex/hca_tonsil_epithelial_v2.R + # uri: rcall://system.file(package='iSEEindex','ReprocessedAllenData_config_01.R') + description: | + touring around, first go + - id: config01rcall + datasets: + - ReprocessedAllenData + title: Example configuration 1 (R call) + uri: rcall://system.file(package='iSEEindex','ReprocessedAllenData_config_01.R') + description: | + One `ReducedDimensionPlot` panel, one `ColumnDataTable` panel. + + File distributed with the `iSEEindex` package. + - id: config02rcall + datasets: + - ReprocessedAllenData + title: Example configuration 2 (R call) + uri: rcall://system.file(package='iSEEindex','ReprocessedAllenData_config_02.R') + description: | + One `RowDataTable` panel, one `ColumnDataTable` panel. + + File distributed with the `iSEEindex` package. diff --git a/man/iSEEindex.Rd b/man/iSEEindex.Rd index f3842e3..3dfaf4e 100644 --- a/man/iSEEindex.Rd +++ b/man/iSEEindex.Rd @@ -12,8 +12,7 @@ iSEEindex( default.position = c("first", "last"), app.title = NULL, body.header = NULL, - body.footer = NULL, - already_se_object = FALSE + body.footer = NULL ) } \arguments{ @@ -40,11 +39,10 @@ info on the versions of the \code{iSEEindex} and \code{iSEE} packages.} \item{body.header}{UI element to display \emph{above} the main landing page body.} \item{body.footer}{UI element to display \emph{below} the main landing page body.} - -\item{already_se_object}{TODO} } \value{ -An \code{\link[iSEE:iSEE]{iSEE::iSEE()}} app with a custom landing page using a \code{\link[=BiocFileCache]{BiocFileCache()}} to cache a selection of data sets. +An \code{\link[iSEE:iSEE]{iSEE::iSEE()}} app with a custom landing page using a +\code{\link[=BiocFileCache]{BiocFileCache()}} to cache a selection of data sets. } \description{ Generate an \pkg{iSEE} app that includes a landing page enabling @@ -53,57 +51,75 @@ states prepared by the app maintainer. } \section{Data Sets}{ -The function passed to the argument \code{FUN.datasets} must return a \code{list} that contains metadata about the available data sets. +The function passed to the argument \code{FUN.datasets} must return a \code{list} that +contains metadata about the available data sets. For each data set, required metadata are: \describe{ \item{id}{A unique identifier for the data set.} -\item{title}{A short human-readable title for the data set, displayed in the 'Info' panel when the data set is selected.} -\item{uri}{A Uniform Resource Identifier (URI) that indicates the location of the data file that contains the data set.} -\item{description}{A more detailed description of the data set, displayed in the 'Info' panel when the data set is selected.} +\item{title}{A short human-readable title for the data set, displayed in the +'Info' panel when the data set is selected.} +\item{uri}{A Uniform Resource Identifier (URI) that indicates the location of +the data file that contains the data set.} +\item{description}{A more detailed description of the data set, displayed in +the 'Info' panel when the data set is selected.} } Example: \if{html}{\out{