From 969796fe7c3526aa6f1450f53676fbaae45efe37 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Thu, 18 Jan 2024 18:17:43 +0100 Subject: [PATCH 01/23] exposing the app title as parameter to be possibly chosen by the user upon launching iSEEindex() --- R/iSEEindex.R | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/R/iSEEindex.R b/R/iSEEindex.R index 4dd048d..ed03f96 100644 --- a/R/iSEEindex.R +++ b/R/iSEEindex.R @@ -91,6 +91,9 @@ #' @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 app.title Character string to specify the desired title to be displayed +#' in the main window of the dashboard. Defaults to `NULL`, which displays some +#' 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. #' @@ -130,19 +133,26 @@ #' if (interactive()) { #' shiny::runApp(app, port = 1234) #' } -iSEEindex <- function(bfc, FUN.datasets, FUN.initial = NULL, default.add = TRUE, default.position = c("first", "last"), body.header = NULL, body.footer = NULL) { +iSEEindex <- 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|powered by iSEE - v%s", + packageVersion("iSEEindex"), + packageVersion("iSEE")) + } + iSEE( landingPage=.landing_page(bfc, FUN.datasets, FUN.initial, default.add, default.position, body.header, body.footer), - appTitle = sprintf("iSEEindex - v%s", - packageVersion("iSEEindex") - ) + appTitle = app.title ) } + + #' Prepare and Launch the Main App. #' #' Invokes a function that replaces the landing page by the \pkg{iSEE} From 36aa8a778698f6e041b5d1e24e11ce5a505813d8 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Fri, 19 Jan 2024 22:07:06 +0100 Subject: [PATCH 02/23] updting GHA workflow to run with Bioc 3.19 in devel --- .github/workflows/check-bioc.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check-bioc.yml b/.github/workflows/check-bioc.yml index fc5daa0..f1b31a1 100644 --- a/.github/workflows/check-bioc.yml +++ b/.github/workflows/check-bioc.yml @@ -52,9 +52,9 @@ jobs: fail-fast: false matrix: config: - - { os: ubuntu-latest, r: 'devel', bioc: '3.17', cont: "bioconductor/bioconductor_docker:devel", rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest" } - - { os: macOS-latest, r: 'devel', bioc: '3.17'} - - { os: windows-latest, r: 'devel', bioc: '3.17'} + - { os: ubuntu-latest, r: 'devel', bioc: '3.19', cont: "bioconductor/bioconductor_docker:devel", rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest" } + - { os: macOS-latest, r: 'devel', bioc: '3.19'} + - { os: windows-latest, r: 'devel', bioc: '3.19'} ## Check https://github.com/r-lib/actions/tree/master/examples ## for examples using the http-user-agent env: From bb3769e42702bc2371d3726c80a712c655fdc125 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 11 Sep 2024 16:57:40 +0200 Subject: [PATCH 03/23] adding the example files used to go with the TonsilDataAtlas package --- inst/tonsils_example/footer_tonsils.md | 15 + inst/tonsils_example/hca_tonsil_cytotoxic.R | 0 inst/tonsils_example/hca_tonsil_epithelial.R | 357 ++++++++++++++++++ .../hca_tonsil_epithelial_v2.R | 357 ++++++++++++++++++ inst/tonsils_example/hca_tonsil_myeloid.R | 0 inst/tonsils_example/header_tonsils.md | 5 + inst/tonsils_example/tonsil_package.yml | 59 +++ inst/tonsils_example/tonsilling_around.R | 49 +++ inst/tonsils_example/tour_tda_cytotoxic.txt | 0 inst/tonsils_example/tour_tda_epithelial.txt | 19 + inst/tonsils_example/tour_tda_myeloid.txt | 0 11 files changed, 861 insertions(+) create mode 100644 inst/tonsils_example/footer_tonsils.md create mode 100644 inst/tonsils_example/hca_tonsil_cytotoxic.R create mode 100644 inst/tonsils_example/hca_tonsil_epithelial.R create mode 100644 inst/tonsils_example/hca_tonsil_epithelial_v2.R create mode 100644 inst/tonsils_example/hca_tonsil_myeloid.R create mode 100644 inst/tonsils_example/header_tonsils.md create mode 100644 inst/tonsils_example/tonsil_package.yml create mode 100644 inst/tonsils_example/tonsilling_around.R create mode 100644 inst/tonsils_example/tour_tda_cytotoxic.txt create mode 100644 inst/tonsils_example/tour_tda_epithelial.txt create mode 100644 inst/tonsils_example/tour_tda_myeloid.txt diff --git a/inst/tonsils_example/footer_tonsils.md b/inst/tonsils_example/footer_tonsils.md new file mode 100644 index 0000000..f56a2da --- /dev/null +++ b/inst/tonsils_example/footer_tonsils.md @@ -0,0 +1,15 @@ +

+HCATonsilData is a Bioconductor package, developed by Ramon Massoni-Badosa. +

+ +

+iSEE is a Bioconductor package, jointly developed by Kevin Rue-Albrecht, Federico Marini, Charlotte Soneson, and Aaron Lun. +

+ +

+ +

+ +

+This set of instances of iSEE have been designed by Federico Marini and Ramon Massoni-Badosa. +

diff --git a/inst/tonsils_example/hca_tonsil_cytotoxic.R b/inst/tonsils_example/hca_tonsil_cytotoxic.R new file mode 100644 index 0000000..e69de29 diff --git a/inst/tonsils_example/hca_tonsil_epithelial.R b/inst/tonsils_example/hca_tonsil_epithelial.R new file mode 100644 index 0000000..104d855 --- /dev/null +++ b/inst/tonsils_example/hca_tonsil_epithelial.R @@ -0,0 +1,357 @@ +initial <- list() + +################################################################################ +# Settings for Reduced dimension plot 1 +################################################################################ + +initial[["ReducedDimensionPlot1"]] <- new("ReducedDimensionPlot", Type = "UMAP", XAxis = 1L, YAxis = 2L, + FacetRowByColData = "donor_id", FacetColumnByColData = "donor_id", + ColorByColumnData = "annotation_20220215", ColorByFeatureNameAssay = "logcounts", + ColorBySampleNameColor = "#FF0000", ShapeByColumnData = "donor_id", + SizeByColumnData = "age", FacetRowBy = "None", FacetColumnBy = "None", + ColorBy = "Column data", ColorByDefaultColor = "#000000", + ColorByFeatureName = "AL627309.1", ColorByFeatureSource = "---", + ColorByFeatureDynamicSource = FALSE, ColorBySampleName = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + ColorBySampleSource = "---", ColorBySampleDynamicSource = FALSE, + ShapeBy = "None", SizeBy = "None", SelectionAlpha = 0.1, + ZoomData = numeric(0), BrushData = list(xmin = 2.807778927129, + xmax = 6.2410123197737, ymin = -6.1386057683565, ymax = -2.8362244982929, + coords_css = list(xmin = 361L, xmax = 450L, ymin = 285L, + ymax = 366L), coords_img = list(xmin = 722L, xmax = 900L, + ymin = 570L, ymax = 732L), img_css_ratio = list(x = 2L, + y = 2L), mapping = list(x = "X", y = "Y", colour = "ColorBy"), + domain = list(left = -9.83895980185942, right = 9.19284266167208, + bottom = -7.93223003035989, top = 7.79266554230246), + range = list(left = 66.3150417380137, right = 1053.04109589041, + bottom = 819.98715432363, top = 48.5943700124905), + log = list(x = NULL, y = NULL), direction = "xy", brushId = "ReducedDimensionPlot1_Brush", + outputId = "ReducedDimensionPlot1"), VisualBoxOpen = TRUE, + VisualChoices = "Color", ContourAdd = FALSE, ContourColor = "#0000FF", + PointSize = 1, PointAlpha = 1, Downsample = FALSE, DownsampleResolution = 200, + CustomLabels = FALSE, CustomLabelsText = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + FontSize = 1, LegendPointSize = 1, LegendPosition = "Bottom", + HoverInfo = TRUE, LabelCenters = FALSE, LabelCentersBy = "donor_id", + LabelCentersColor = "#000000", VersionInfo = list(iSEE = structure(list( + c(2L, 8L, 0L)), class = c("package_version", "numeric_version" + ))), PanelId = c(ReducedDimensionPlot = 1L), PanelHeight = 500L, + PanelWidth = 4L, SelectionBoxOpen = FALSE, RowSelectionSource = "---", + ColumnSelectionSource = "---", DataBoxOpen = FALSE, RowSelectionDynamicSource = FALSE, + ColumnSelectionDynamicSource = FALSE, RowSelectionRestrict = FALSE, + ColumnSelectionRestrict = FALSE, SelectionHistory = list()) + +################################################################################ +# Settings for Row data table 1 +################################################################################ + +initial[["RowDataTable1"]] <- new("RowDataTable", Selected = "KRT13", Search = "KRT[0-9]", + SearchColumns = c("", "", ""), HiddenColumns = character(0), + VersionInfo = list(iSEE = structure(list(c(2L, 8L, 0L)), class = c("package_version", + "numeric_version"))), PanelId = c(RowDataTable = 1L), PanelHeight = 500L, + PanelWidth = 4L, SelectionBoxOpen = FALSE, RowSelectionSource = "---", + ColumnSelectionSource = "---", DataBoxOpen = FALSE, RowSelectionDynamicSource = FALSE, + ColumnSelectionDynamicSource = FALSE, RowSelectionRestrict = FALSE, + ColumnSelectionRestrict = FALSE, SelectionHistory = list()) + +################################################################################ +# Settings for Feature assay plot 1 +################################################################################ + +initial[["FeatureAssayPlot1"]] <- new("FeatureAssayPlot", Assay = "logcounts", XAxis = "Column data", + XAxisColumnData = "annotation_20220215", XAxisFeatureName = "AL627309.1", + XAxisFeatureSource = "---", XAxisFeatureDynamicSource = FALSE, + YAxisFeatureName = "KRT13", YAxisFeatureSource = "RowDataTable1", + YAxisFeatureDynamicSource = FALSE, FacetRowByColData = "donor_id", + FacetColumnByColData = "donor_id", ColorByColumnData = "barcode", + ColorByFeatureNameAssay = "logcounts", ColorBySampleNameColor = "#FF0000", + ShapeByColumnData = "donor_id", SizeByColumnData = "age", + FacetRowBy = "None", FacetColumnBy = "None", ColorBy = "None", + ColorByDefaultColor = "#000000", ColorByFeatureName = "AL627309.1", + ColorByFeatureSource = "---", ColorByFeatureDynamicSource = FALSE, + ColorBySampleName = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + ColorBySampleSource = "---", ColorBySampleDynamicSource = FALSE, + ShapeBy = "None", SizeBy = "None", SelectionAlpha = 0.1, + ZoomData = numeric(0), BrushData = list(), VisualBoxOpen = FALSE, + VisualChoices = "Color", ContourAdd = FALSE, ContourColor = "#0000FF", + PointSize = 1, PointAlpha = 1, Downsample = FALSE, DownsampleResolution = 200, + CustomLabels = FALSE, CustomLabelsText = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + FontSize = 1, LegendPointSize = 1, LegendPosition = "Bottom", + HoverInfo = TRUE, LabelCenters = FALSE, LabelCentersBy = "donor_id", + LabelCentersColor = "#000000", VersionInfo = list(iSEE = structure(list( + c(2L, 8L, 0L)), class = c("package_version", "numeric_version" + ))), PanelId = c(FeatureAssayPlot = 1L), PanelHeight = 500L, + PanelWidth = 4L, SelectionBoxOpen = FALSE, RowSelectionSource = "---", + ColumnSelectionSource = "ReducedDimensionPlot1", DataBoxOpen = TRUE, + RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Reduced dimension plot 2 +################################################################################ + +initial[["ReducedDimensionPlot2"]] <- new("ReducedDimensionPlot", Type = "UMAP", XAxis = 1L, YAxis = 2L, + FacetRowByColData = "donor_id", FacetColumnByColData = "donor_id", + ColorByColumnData = "barcode", ColorByFeatureNameAssay = "logcounts", + ColorBySampleNameColor = "#FF0000", ShapeByColumnData = "donor_id", + SizeByColumnData = "age", FacetRowBy = "None", FacetColumnBy = "None", + ColorBy = "Feature name", ColorByDefaultColor = "#000000", + ColorByFeatureName = "KRT13", ColorByFeatureSource = "RowDataTable1", + ColorByFeatureDynamicSource = FALSE, ColorBySampleName = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + ColorBySampleSource = "---", ColorBySampleDynamicSource = FALSE, + ShapeBy = "None", SizeBy = "None", SelectionAlpha = 0.1, + ZoomData = numeric(0), BrushData = list(), VisualBoxOpen = TRUE, + VisualChoices = "Color", ContourAdd = FALSE, ContourColor = "#0000FF", + PointSize = 1, PointAlpha = 1, Downsample = FALSE, DownsampleResolution = 200, + CustomLabels = FALSE, CustomLabelsText = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + FontSize = 1, LegendPointSize = 1, LegendPosition = "Bottom", + HoverInfo = TRUE, LabelCenters = FALSE, LabelCentersBy = "donor_id", + LabelCentersColor = "#000000", VersionInfo = list(iSEE = structure(list( + c(2L, 8L, 0L)), class = c("package_version", "numeric_version" + ))), PanelId = 2L, PanelHeight = 500L, PanelWidth = 4L, SelectionBoxOpen = FALSE, + RowSelectionSource = "---", ColumnSelectionSource = "---", + DataBoxOpen = FALSE, RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Column data plot 1 +################################################################################ + +initial[["ColumnDataPlot1"]] <- new("ColumnDataPlot", XAxis = "None", YAxis = "annotation_20220215", + XAxisColumnData = "barcode", FacetRowByColData = "donor_id", + FacetColumnByColData = "donor_id", ColorByColumnData = "barcode", + ColorByFeatureNameAssay = "logcounts", ColorBySampleNameColor = "#FF0000", + ShapeByColumnData = "donor_id", SizeByColumnData = "age", + FacetRowBy = "None", FacetColumnBy = "None", ColorBy = "None", + ColorByDefaultColor = "#000000", ColorByFeatureName = "AL627309.1", + ColorByFeatureSource = "---", ColorByFeatureDynamicSource = FALSE, + ColorBySampleName = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + ColorBySampleSource = "---", ColorBySampleDynamicSource = FALSE, + ShapeBy = "None", SizeBy = "None", SelectionAlpha = 0.1, + ZoomData = numeric(0), BrushData = list(xmin = 0.47990067299861, + xmax = 1.5127251238526, ymin = 1.4789673594537, ymax = 2.4678098848756, + coords_css = list(xmin = 135.015625, xmax = 496.015625, + ymin = 325.171875, ymax = 397.171875), coords_img = list( + xmin = 270.03125, xmax = 992.03125, ymin = 650.34375, + ymax = 794.34375), img_css_ratio = list(x = 2L, y = 2L), + mapping = list(x = "X", y = "Y", height = "2 * YWidth", + width = "2 * XWidth", group = "interaction(X, Y)"), + domain = list(left = 0.4, right = 1.6, bottom = 0.4, + top = 6.6, discrete_limits = list(x = "", y = list( + "Basal cells", "Crypt", "FDCSP epithelium", "Outer surface", + "Surface epithelium", "VEGFA+"))), range = list( + left = 214.176369863014, right = 1053.04109589041, + bottom = 951.468161386986, top = 48.5943700124905), + log = list(x = NULL, y = NULL), direction = "xy", brushId = "ColumnDataPlot1_Brush", + outputId = "ColumnDataPlot1"), VisualBoxOpen = FALSE, + VisualChoices = "Color", ContourAdd = FALSE, ContourColor = "#0000FF", + PointSize = 1, PointAlpha = 1, Downsample = FALSE, DownsampleResolution = 200, + CustomLabels = FALSE, CustomLabelsText = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + FontSize = 1, LegendPointSize = 1, LegendPosition = "Bottom", + HoverInfo = TRUE, LabelCenters = FALSE, LabelCentersBy = "donor_id", + LabelCentersColor = "#000000", VersionInfo = list(iSEE = structure(list( + c(2L, 8L, 0L)), class = c("package_version", "numeric_version" + ))), PanelId = c(ColumnDataPlot = 1L), PanelHeight = 500L, + PanelWidth = 4L, SelectionBoxOpen = FALSE, RowSelectionSource = "---", + ColumnSelectionSource = "---", DataBoxOpen = FALSE, RowSelectionDynamicSource = FALSE, + ColumnSelectionDynamicSource = FALSE, RowSelectionRestrict = FALSE, + ColumnSelectionRestrict = FALSE, SelectionHistory = list()) + +################################################################################ +# Settings for Complex heatmap 1 +################################################################################ + +initial[["ComplexHeatmapPlot1"]] <- new("ComplexHeatmapPlot", Assay = "logcounts", CustomRows = TRUE, + CustomRowsText = "KRT5\nKRT14\nKRT4\nKRT13\nKRT78\nKRT80", + ClusterRows = TRUE, ClusterRowsDistance = "spearman", ClusterRowsMethod = "ward.D2", + DataBoxOpen = FALSE, VisualChoices = "Annotations", ColumnData = "annotation_20220215", + RowData = character(0), CustomBounds = FALSE, LowerBound = 0L, + UpperBound = 0L, AssayCenterRows = FALSE, AssayScaleRows = FALSE, + DivergentColormap = "purple < black < yellow", ShowDimNames = "Rows", + LegendPosition = "Bottom", LegendDirection = "Horizontal", + VisualBoxOpen = FALSE, NamesRowFontSize = 10, NamesColumnFontSize = 10, + ShowColumnSelection = TRUE, OrderColumnSelection = TRUE, + VersionInfo = list(iSEE = structure(list(c(2L, 8L, 0L)), class = c("package_version", + "numeric_version"))), PanelId = c(ComplexHeatmapPlot = 1L), + PanelHeight = 500L, PanelWidth = 4L, SelectionBoxOpen = FALSE, + RowSelectionSource = "---", ColumnSelectionSource = "---", + RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Feature assay plot 2 +################################################################################ + +initial[["FeatureAssayPlot2"]] <- new("FeatureAssayPlot", Assay = "logcounts", XAxis = "Column data", + XAxisColumnData = "annotation_20220215", XAxisFeatureName = "AL627309.1", + XAxisFeatureSource = "---", XAxisFeatureDynamicSource = FALSE, + YAxisFeatureName = "TMPRSS2", YAxisFeatureSource = "---", + YAxisFeatureDynamicSource = FALSE, FacetRowByColData = "donor_id", + FacetColumnByColData = "donor_id", ColorByColumnData = "barcode", + ColorByFeatureNameAssay = "logcounts", ColorBySampleNameColor = "#FF0000", + ShapeByColumnData = "donor_id", SizeByColumnData = "age", + FacetRowBy = "None", FacetColumnBy = "None", ColorBy = "None", + ColorByDefaultColor = "#000000", ColorByFeatureName = "AL627309.1", + ColorByFeatureSource = "---", ColorByFeatureDynamicSource = FALSE, + ColorBySampleName = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + ColorBySampleSource = "---", ColorBySampleDynamicSource = FALSE, + ShapeBy = "None", SizeBy = "None", SelectionAlpha = 0.1, + ZoomData = numeric(0), BrushData = list(), VisualBoxOpen = FALSE, + VisualChoices = "Color", ContourAdd = FALSE, ContourColor = "#0000FF", + PointSize = 1, PointAlpha = 1, Downsample = FALSE, DownsampleResolution = 200, + CustomLabels = FALSE, CustomLabelsText = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + FontSize = 1, LegendPointSize = 1, LegendPosition = "Bottom", + HoverInfo = TRUE, LabelCenters = FALSE, LabelCentersBy = "donor_id", + LabelCentersColor = "#000000", VersionInfo = list(iSEE = structure(list( + c(2L, 8L, 0L)), class = c("package_version", "numeric_version" + ))), PanelId = 2L, PanelHeight = 500L, PanelWidth = 3L, SelectionBoxOpen = FALSE, + RowSelectionSource = "---", ColumnSelectionSource = "---", + DataBoxOpen = FALSE, RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Feature assay plot 3 +################################################################################ + +initial[["FeatureAssayPlot3"]] <- new("FeatureAssayPlot", Assay = "logcounts", XAxis = "Column data", + XAxisColumnData = "annotation_20220215", XAxisFeatureName = "AL627309.1", + XAxisFeatureSource = "---", XAxisFeatureDynamicSource = FALSE, + YAxisFeatureName = "ACE2", YAxisFeatureSource = "---", YAxisFeatureDynamicSource = FALSE, + FacetRowByColData = "donor_id", FacetColumnByColData = "donor_id", + ColorByColumnData = "barcode", ColorByFeatureNameAssay = "logcounts", + ColorBySampleNameColor = "#FF0000", ShapeByColumnData = "donor_id", + SizeByColumnData = "age", FacetRowBy = "None", FacetColumnBy = "None", + ColorBy = "None", ColorByDefaultColor = "#000000", ColorByFeatureName = "AL627309.1", + ColorByFeatureSource = "---", ColorByFeatureDynamicSource = FALSE, + ColorBySampleName = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + ColorBySampleSource = "---", ColorBySampleDynamicSource = FALSE, + ShapeBy = "None", SizeBy = "None", SelectionAlpha = 0.1, + ZoomData = numeric(0), BrushData = list(), VisualBoxOpen = FALSE, + VisualChoices = "Color", ContourAdd = FALSE, ContourColor = "#0000FF", + PointSize = 1, PointAlpha = 1, Downsample = FALSE, DownsampleResolution = 200, + CustomLabels = FALSE, CustomLabelsText = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + FontSize = 1, LegendPointSize = 1, LegendPosition = "Bottom", + HoverInfo = TRUE, LabelCenters = FALSE, LabelCentersBy = "donor_id", + LabelCentersColor = "#000000", VersionInfo = list(iSEE = structure(list( + c(2L, 8L, 0L)), class = c("package_version", "numeric_version" + ))), PanelId = 3L, PanelHeight = 500L, PanelWidth = 3L, SelectionBoxOpen = FALSE, + RowSelectionSource = "---", ColumnSelectionSource = "---", + DataBoxOpen = FALSE, RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Row data table 2 +################################################################################ + +initial[["RowDataTable2"]] <- new("RowDataTable", Selected = "LCE3E", Search = "LCE3", SearchColumns = c("", + "", ""), HiddenColumns = character(0), VersionInfo = list(iSEE = structure(list( + c(2L, 8L, 0L)), class = c("package_version", "numeric_version" + ))), PanelId = 2L, PanelHeight = 500L, PanelWidth = 3L, SelectionBoxOpen = FALSE, + RowSelectionSource = "---", ColumnSelectionSource = "---", + DataBoxOpen = FALSE, RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Reduced dimension plot 3 +################################################################################ + +initial[["ReducedDimensionPlot3"]] <- new("ReducedDimensionPlot", Type = "UMAP", XAxis = 1L, YAxis = 2L, + FacetRowByColData = "donor_id", FacetColumnByColData = "donor_id", + ColorByColumnData = "barcode", ColorByFeatureNameAssay = "logcounts", + ColorBySampleNameColor = "#FF0000", ShapeByColumnData = "donor_id", + SizeByColumnData = "age", FacetRowBy = "None", FacetColumnBy = "None", + ColorBy = "Feature name", ColorByDefaultColor = "#000000", + ColorByFeatureName = "LCE3E", ColorByFeatureSource = "RowDataTable2", + ColorByFeatureDynamicSource = FALSE, ColorBySampleName = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + ColorBySampleSource = "---", ColorBySampleDynamicSource = FALSE, + ShapeBy = "None", SizeBy = "None", SelectionAlpha = 0.1, + ZoomData = numeric(0), BrushData = list(), VisualBoxOpen = TRUE, + VisualChoices = "Color", ContourAdd = FALSE, ContourColor = "#0000FF", + PointSize = 1, PointAlpha = 1, Downsample = FALSE, DownsampleResolution = 200, + CustomLabels = FALSE, CustomLabelsText = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + FontSize = 1, LegendPointSize = 1, LegendPosition = "Bottom", + HoverInfo = TRUE, LabelCenters = FALSE, LabelCentersBy = "donor_id", + LabelCentersColor = "#000000", VersionInfo = list(iSEE = structure(list( + c(2L, 8L, 0L)), class = c("package_version", "numeric_version" + ))), PanelId = 3L, PanelHeight = 500L, PanelWidth = 3L, SelectionBoxOpen = FALSE, + RowSelectionSource = "---", ColumnSelectionSource = "---", + DataBoxOpen = FALSE, RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Complex heatmap 2 +################################################################################ + +initial[["ComplexHeatmapPlot2"]] <- new("ComplexHeatmapPlot", Assay = "logcounts", CustomRows = TRUE, + CustomRowsText = "CNFN\nLCE3A\nLCE3D\nLCE3E\nSPRR2D\nSPRR2E", + ClusterRows = FALSE, ClusterRowsDistance = "spearman", ClusterRowsMethod = "ward.D2", + DataBoxOpen = FALSE, VisualChoices = "Annotations", ColumnData = "annotation_20220215", + RowData = character(0), CustomBounds = FALSE, LowerBound = 0L, + UpperBound = 0L, AssayCenterRows = FALSE, AssayScaleRows = FALSE, + DivergentColormap = "purple < black < yellow", ShowDimNames = "Rows", + LegendPosition = "Bottom", LegendDirection = "Horizontal", + VisualBoxOpen = FALSE, NamesRowFontSize = 10, NamesColumnFontSize = 10, + ShowColumnSelection = TRUE, OrderColumnSelection = TRUE, + VersionInfo = list(iSEE = structure(list(c(2L, 8L, 0L)), class = c("package_version", + "numeric_version"))), PanelId = 2L, PanelHeight = 500L, PanelWidth = 4L, + SelectionBoxOpen = FALSE, RowSelectionSource = "---", ColumnSelectionSource = "---", + RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Complex heatmap 3 +################################################################################ + +initial[["ComplexHeatmapPlot3"]] <- new("ComplexHeatmapPlot", Assay = "logcounts", CustomRows = TRUE, + CustomRowsText = "IL1B\nS100A6\nSPIB\nMARCKSL1", ClusterRows = FALSE, + ClusterRowsDistance = "spearman", ClusterRowsMethod = "ward.D2", + DataBoxOpen = FALSE, VisualChoices = "Annotations", ColumnData = "annotation_20220215", + RowData = character(0), CustomBounds = FALSE, LowerBound = 0L, + UpperBound = 0L, AssayCenterRows = FALSE, AssayScaleRows = FALSE, + DivergentColormap = "purple < black < yellow", ShowDimNames = "Rows", + LegendPosition = "Bottom", LegendDirection = "Horizontal", + VisualBoxOpen = FALSE, NamesRowFontSize = 10, NamesColumnFontSize = 10, + ShowColumnSelection = TRUE, OrderColumnSelection = TRUE, + VersionInfo = list(iSEE = structure(list(c(2L, 8L, 0L)), class = c("package_version", + "numeric_version"))), PanelId = 3L, PanelHeight = 500L, PanelWidth = 4L, + SelectionBoxOpen = FALSE, RowSelectionSource = "---", ColumnSelectionSource = "ColumnDataPlot1", + RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Complex heatmap 4 +################################################################################ + +initial[["ComplexHeatmapPlot4"]] <- new("ComplexHeatmapPlot", Assay = "logcounts", CustomRows = TRUE, + CustomRowsText = "FDCSP\nKRTDAP\n", ClusterRows = FALSE, + ClusterRowsDistance = "spearman", ClusterRowsMethod = "ward.D2", + DataBoxOpen = FALSE, VisualChoices = "Annotations", ColumnData = "annotation_20220215", + RowData = character(0), CustomBounds = FALSE, LowerBound = 0L, + UpperBound = 0L, AssayCenterRows = FALSE, AssayScaleRows = FALSE, + DivergentColormap = "purple < black < yellow", ShowDimNames = "Rows", + LegendPosition = "Bottom", LegendDirection = "Horizontal", + VisualBoxOpen = FALSE, NamesRowFontSize = 10, NamesColumnFontSize = 10, + ShowColumnSelection = TRUE, OrderColumnSelection = TRUE, + VersionInfo = list(iSEE = structure(list(c(2L, 8L, 0L)), class = c("package_version", + "numeric_version"))), PanelId = 4L, PanelHeight = 500L, PanelWidth = 4L, + SelectionBoxOpen = FALSE, RowSelectionSource = "---", ColumnSelectionSource = "---", + RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +## Adding a tour to tell things to people - they like to hear or read about the data! + +tour <- read.delim("tour_tda_epithelial.txt", sep = ";", header = TRUE) + + + + + + diff --git a/inst/tonsils_example/hca_tonsil_epithelial_v2.R b/inst/tonsils_example/hca_tonsil_epithelial_v2.R new file mode 100644 index 0000000..104d855 --- /dev/null +++ b/inst/tonsils_example/hca_tonsil_epithelial_v2.R @@ -0,0 +1,357 @@ +initial <- list() + +################################################################################ +# Settings for Reduced dimension plot 1 +################################################################################ + +initial[["ReducedDimensionPlot1"]] <- new("ReducedDimensionPlot", Type = "UMAP", XAxis = 1L, YAxis = 2L, + FacetRowByColData = "donor_id", FacetColumnByColData = "donor_id", + ColorByColumnData = "annotation_20220215", ColorByFeatureNameAssay = "logcounts", + ColorBySampleNameColor = "#FF0000", ShapeByColumnData = "donor_id", + SizeByColumnData = "age", FacetRowBy = "None", FacetColumnBy = "None", + ColorBy = "Column data", ColorByDefaultColor = "#000000", + ColorByFeatureName = "AL627309.1", ColorByFeatureSource = "---", + ColorByFeatureDynamicSource = FALSE, ColorBySampleName = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + ColorBySampleSource = "---", ColorBySampleDynamicSource = FALSE, + ShapeBy = "None", SizeBy = "None", SelectionAlpha = 0.1, + ZoomData = numeric(0), BrushData = list(xmin = 2.807778927129, + xmax = 6.2410123197737, ymin = -6.1386057683565, ymax = -2.8362244982929, + coords_css = list(xmin = 361L, xmax = 450L, ymin = 285L, + ymax = 366L), coords_img = list(xmin = 722L, xmax = 900L, + ymin = 570L, ymax = 732L), img_css_ratio = list(x = 2L, + y = 2L), mapping = list(x = "X", y = "Y", colour = "ColorBy"), + domain = list(left = -9.83895980185942, right = 9.19284266167208, + bottom = -7.93223003035989, top = 7.79266554230246), + range = list(left = 66.3150417380137, right = 1053.04109589041, + bottom = 819.98715432363, top = 48.5943700124905), + log = list(x = NULL, y = NULL), direction = "xy", brushId = "ReducedDimensionPlot1_Brush", + outputId = "ReducedDimensionPlot1"), VisualBoxOpen = TRUE, + VisualChoices = "Color", ContourAdd = FALSE, ContourColor = "#0000FF", + PointSize = 1, PointAlpha = 1, Downsample = FALSE, DownsampleResolution = 200, + CustomLabels = FALSE, CustomLabelsText = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + FontSize = 1, LegendPointSize = 1, LegendPosition = "Bottom", + HoverInfo = TRUE, LabelCenters = FALSE, LabelCentersBy = "donor_id", + LabelCentersColor = "#000000", VersionInfo = list(iSEE = structure(list( + c(2L, 8L, 0L)), class = c("package_version", "numeric_version" + ))), PanelId = c(ReducedDimensionPlot = 1L), PanelHeight = 500L, + PanelWidth = 4L, SelectionBoxOpen = FALSE, RowSelectionSource = "---", + ColumnSelectionSource = "---", DataBoxOpen = FALSE, RowSelectionDynamicSource = FALSE, + ColumnSelectionDynamicSource = FALSE, RowSelectionRestrict = FALSE, + ColumnSelectionRestrict = FALSE, SelectionHistory = list()) + +################################################################################ +# Settings for Row data table 1 +################################################################################ + +initial[["RowDataTable1"]] <- new("RowDataTable", Selected = "KRT13", Search = "KRT[0-9]", + SearchColumns = c("", "", ""), HiddenColumns = character(0), + VersionInfo = list(iSEE = structure(list(c(2L, 8L, 0L)), class = c("package_version", + "numeric_version"))), PanelId = c(RowDataTable = 1L), PanelHeight = 500L, + PanelWidth = 4L, SelectionBoxOpen = FALSE, RowSelectionSource = "---", + ColumnSelectionSource = "---", DataBoxOpen = FALSE, RowSelectionDynamicSource = FALSE, + ColumnSelectionDynamicSource = FALSE, RowSelectionRestrict = FALSE, + ColumnSelectionRestrict = FALSE, SelectionHistory = list()) + +################################################################################ +# Settings for Feature assay plot 1 +################################################################################ + +initial[["FeatureAssayPlot1"]] <- new("FeatureAssayPlot", Assay = "logcounts", XAxis = "Column data", + XAxisColumnData = "annotation_20220215", XAxisFeatureName = "AL627309.1", + XAxisFeatureSource = "---", XAxisFeatureDynamicSource = FALSE, + YAxisFeatureName = "KRT13", YAxisFeatureSource = "RowDataTable1", + YAxisFeatureDynamicSource = FALSE, FacetRowByColData = "donor_id", + FacetColumnByColData = "donor_id", ColorByColumnData = "barcode", + ColorByFeatureNameAssay = "logcounts", ColorBySampleNameColor = "#FF0000", + ShapeByColumnData = "donor_id", SizeByColumnData = "age", + FacetRowBy = "None", FacetColumnBy = "None", ColorBy = "None", + ColorByDefaultColor = "#000000", ColorByFeatureName = "AL627309.1", + ColorByFeatureSource = "---", ColorByFeatureDynamicSource = FALSE, + ColorBySampleName = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + ColorBySampleSource = "---", ColorBySampleDynamicSource = FALSE, + ShapeBy = "None", SizeBy = "None", SelectionAlpha = 0.1, + ZoomData = numeric(0), BrushData = list(), VisualBoxOpen = FALSE, + VisualChoices = "Color", ContourAdd = FALSE, ContourColor = "#0000FF", + PointSize = 1, PointAlpha = 1, Downsample = FALSE, DownsampleResolution = 200, + CustomLabels = FALSE, CustomLabelsText = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + FontSize = 1, LegendPointSize = 1, LegendPosition = "Bottom", + HoverInfo = TRUE, LabelCenters = FALSE, LabelCentersBy = "donor_id", + LabelCentersColor = "#000000", VersionInfo = list(iSEE = structure(list( + c(2L, 8L, 0L)), class = c("package_version", "numeric_version" + ))), PanelId = c(FeatureAssayPlot = 1L), PanelHeight = 500L, + PanelWidth = 4L, SelectionBoxOpen = FALSE, RowSelectionSource = "---", + ColumnSelectionSource = "ReducedDimensionPlot1", DataBoxOpen = TRUE, + RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Reduced dimension plot 2 +################################################################################ + +initial[["ReducedDimensionPlot2"]] <- new("ReducedDimensionPlot", Type = "UMAP", XAxis = 1L, YAxis = 2L, + FacetRowByColData = "donor_id", FacetColumnByColData = "donor_id", + ColorByColumnData = "barcode", ColorByFeatureNameAssay = "logcounts", + ColorBySampleNameColor = "#FF0000", ShapeByColumnData = "donor_id", + SizeByColumnData = "age", FacetRowBy = "None", FacetColumnBy = "None", + ColorBy = "Feature name", ColorByDefaultColor = "#000000", + ColorByFeatureName = "KRT13", ColorByFeatureSource = "RowDataTable1", + ColorByFeatureDynamicSource = FALSE, ColorBySampleName = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + ColorBySampleSource = "---", ColorBySampleDynamicSource = FALSE, + ShapeBy = "None", SizeBy = "None", SelectionAlpha = 0.1, + ZoomData = numeric(0), BrushData = list(), VisualBoxOpen = TRUE, + VisualChoices = "Color", ContourAdd = FALSE, ContourColor = "#0000FF", + PointSize = 1, PointAlpha = 1, Downsample = FALSE, DownsampleResolution = 200, + CustomLabels = FALSE, CustomLabelsText = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + FontSize = 1, LegendPointSize = 1, LegendPosition = "Bottom", + HoverInfo = TRUE, LabelCenters = FALSE, LabelCentersBy = "donor_id", + LabelCentersColor = "#000000", VersionInfo = list(iSEE = structure(list( + c(2L, 8L, 0L)), class = c("package_version", "numeric_version" + ))), PanelId = 2L, PanelHeight = 500L, PanelWidth = 4L, SelectionBoxOpen = FALSE, + RowSelectionSource = "---", ColumnSelectionSource = "---", + DataBoxOpen = FALSE, RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Column data plot 1 +################################################################################ + +initial[["ColumnDataPlot1"]] <- new("ColumnDataPlot", XAxis = "None", YAxis = "annotation_20220215", + XAxisColumnData = "barcode", FacetRowByColData = "donor_id", + FacetColumnByColData = "donor_id", ColorByColumnData = "barcode", + ColorByFeatureNameAssay = "logcounts", ColorBySampleNameColor = "#FF0000", + ShapeByColumnData = "donor_id", SizeByColumnData = "age", + FacetRowBy = "None", FacetColumnBy = "None", ColorBy = "None", + ColorByDefaultColor = "#000000", ColorByFeatureName = "AL627309.1", + ColorByFeatureSource = "---", ColorByFeatureDynamicSource = FALSE, + ColorBySampleName = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + ColorBySampleSource = "---", ColorBySampleDynamicSource = FALSE, + ShapeBy = "None", SizeBy = "None", SelectionAlpha = 0.1, + ZoomData = numeric(0), BrushData = list(xmin = 0.47990067299861, + xmax = 1.5127251238526, ymin = 1.4789673594537, ymax = 2.4678098848756, + coords_css = list(xmin = 135.015625, xmax = 496.015625, + ymin = 325.171875, ymax = 397.171875), coords_img = list( + xmin = 270.03125, xmax = 992.03125, ymin = 650.34375, + ymax = 794.34375), img_css_ratio = list(x = 2L, y = 2L), + mapping = list(x = "X", y = "Y", height = "2 * YWidth", + width = "2 * XWidth", group = "interaction(X, Y)"), + domain = list(left = 0.4, right = 1.6, bottom = 0.4, + top = 6.6, discrete_limits = list(x = "", y = list( + "Basal cells", "Crypt", "FDCSP epithelium", "Outer surface", + "Surface epithelium", "VEGFA+"))), range = list( + left = 214.176369863014, right = 1053.04109589041, + bottom = 951.468161386986, top = 48.5943700124905), + log = list(x = NULL, y = NULL), direction = "xy", brushId = "ColumnDataPlot1_Brush", + outputId = "ColumnDataPlot1"), VisualBoxOpen = FALSE, + VisualChoices = "Color", ContourAdd = FALSE, ContourColor = "#0000FF", + PointSize = 1, PointAlpha = 1, Downsample = FALSE, DownsampleResolution = 200, + CustomLabels = FALSE, CustomLabelsText = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + FontSize = 1, LegendPointSize = 1, LegendPosition = "Bottom", + HoverInfo = TRUE, LabelCenters = FALSE, LabelCentersBy = "donor_id", + LabelCentersColor = "#000000", VersionInfo = list(iSEE = structure(list( + c(2L, 8L, 0L)), class = c("package_version", "numeric_version" + ))), PanelId = c(ColumnDataPlot = 1L), PanelHeight = 500L, + PanelWidth = 4L, SelectionBoxOpen = FALSE, RowSelectionSource = "---", + ColumnSelectionSource = "---", DataBoxOpen = FALSE, RowSelectionDynamicSource = FALSE, + ColumnSelectionDynamicSource = FALSE, RowSelectionRestrict = FALSE, + ColumnSelectionRestrict = FALSE, SelectionHistory = list()) + +################################################################################ +# Settings for Complex heatmap 1 +################################################################################ + +initial[["ComplexHeatmapPlot1"]] <- new("ComplexHeatmapPlot", Assay = "logcounts", CustomRows = TRUE, + CustomRowsText = "KRT5\nKRT14\nKRT4\nKRT13\nKRT78\nKRT80", + ClusterRows = TRUE, ClusterRowsDistance = "spearman", ClusterRowsMethod = "ward.D2", + DataBoxOpen = FALSE, VisualChoices = "Annotations", ColumnData = "annotation_20220215", + RowData = character(0), CustomBounds = FALSE, LowerBound = 0L, + UpperBound = 0L, AssayCenterRows = FALSE, AssayScaleRows = FALSE, + DivergentColormap = "purple < black < yellow", ShowDimNames = "Rows", + LegendPosition = "Bottom", LegendDirection = "Horizontal", + VisualBoxOpen = FALSE, NamesRowFontSize = 10, NamesColumnFontSize = 10, + ShowColumnSelection = TRUE, OrderColumnSelection = TRUE, + VersionInfo = list(iSEE = structure(list(c(2L, 8L, 0L)), class = c("package_version", + "numeric_version"))), PanelId = c(ComplexHeatmapPlot = 1L), + PanelHeight = 500L, PanelWidth = 4L, SelectionBoxOpen = FALSE, + RowSelectionSource = "---", ColumnSelectionSource = "---", + RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Feature assay plot 2 +################################################################################ + +initial[["FeatureAssayPlot2"]] <- new("FeatureAssayPlot", Assay = "logcounts", XAxis = "Column data", + XAxisColumnData = "annotation_20220215", XAxisFeatureName = "AL627309.1", + XAxisFeatureSource = "---", XAxisFeatureDynamicSource = FALSE, + YAxisFeatureName = "TMPRSS2", YAxisFeatureSource = "---", + YAxisFeatureDynamicSource = FALSE, FacetRowByColData = "donor_id", + FacetColumnByColData = "donor_id", ColorByColumnData = "barcode", + ColorByFeatureNameAssay = "logcounts", ColorBySampleNameColor = "#FF0000", + ShapeByColumnData = "donor_id", SizeByColumnData = "age", + FacetRowBy = "None", FacetColumnBy = "None", ColorBy = "None", + ColorByDefaultColor = "#000000", ColorByFeatureName = "AL627309.1", + ColorByFeatureSource = "---", ColorByFeatureDynamicSource = FALSE, + ColorBySampleName = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + ColorBySampleSource = "---", ColorBySampleDynamicSource = FALSE, + ShapeBy = "None", SizeBy = "None", SelectionAlpha = 0.1, + ZoomData = numeric(0), BrushData = list(), VisualBoxOpen = FALSE, + VisualChoices = "Color", ContourAdd = FALSE, ContourColor = "#0000FF", + PointSize = 1, PointAlpha = 1, Downsample = FALSE, DownsampleResolution = 200, + CustomLabels = FALSE, CustomLabelsText = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + FontSize = 1, LegendPointSize = 1, LegendPosition = "Bottom", + HoverInfo = TRUE, LabelCenters = FALSE, LabelCentersBy = "donor_id", + LabelCentersColor = "#000000", VersionInfo = list(iSEE = structure(list( + c(2L, 8L, 0L)), class = c("package_version", "numeric_version" + ))), PanelId = 2L, PanelHeight = 500L, PanelWidth = 3L, SelectionBoxOpen = FALSE, + RowSelectionSource = "---", ColumnSelectionSource = "---", + DataBoxOpen = FALSE, RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Feature assay plot 3 +################################################################################ + +initial[["FeatureAssayPlot3"]] <- new("FeatureAssayPlot", Assay = "logcounts", XAxis = "Column data", + XAxisColumnData = "annotation_20220215", XAxisFeatureName = "AL627309.1", + XAxisFeatureSource = "---", XAxisFeatureDynamicSource = FALSE, + YAxisFeatureName = "ACE2", YAxisFeatureSource = "---", YAxisFeatureDynamicSource = FALSE, + FacetRowByColData = "donor_id", FacetColumnByColData = "donor_id", + ColorByColumnData = "barcode", ColorByFeatureNameAssay = "logcounts", + ColorBySampleNameColor = "#FF0000", ShapeByColumnData = "donor_id", + SizeByColumnData = "age", FacetRowBy = "None", FacetColumnBy = "None", + ColorBy = "None", ColorByDefaultColor = "#000000", ColorByFeatureName = "AL627309.1", + ColorByFeatureSource = "---", ColorByFeatureDynamicSource = FALSE, + ColorBySampleName = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + ColorBySampleSource = "---", ColorBySampleDynamicSource = FALSE, + ShapeBy = "None", SizeBy = "None", SelectionAlpha = 0.1, + ZoomData = numeric(0), BrushData = list(), VisualBoxOpen = FALSE, + VisualChoices = "Color", ContourAdd = FALSE, ContourColor = "#0000FF", + PointSize = 1, PointAlpha = 1, Downsample = FALSE, DownsampleResolution = 200, + CustomLabels = FALSE, CustomLabelsText = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + FontSize = 1, LegendPointSize = 1, LegendPosition = "Bottom", + HoverInfo = TRUE, LabelCenters = FALSE, LabelCentersBy = "donor_id", + LabelCentersColor = "#000000", VersionInfo = list(iSEE = structure(list( + c(2L, 8L, 0L)), class = c("package_version", "numeric_version" + ))), PanelId = 3L, PanelHeight = 500L, PanelWidth = 3L, SelectionBoxOpen = FALSE, + RowSelectionSource = "---", ColumnSelectionSource = "---", + DataBoxOpen = FALSE, RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Row data table 2 +################################################################################ + +initial[["RowDataTable2"]] <- new("RowDataTable", Selected = "LCE3E", Search = "LCE3", SearchColumns = c("", + "", ""), HiddenColumns = character(0), VersionInfo = list(iSEE = structure(list( + c(2L, 8L, 0L)), class = c("package_version", "numeric_version" + ))), PanelId = 2L, PanelHeight = 500L, PanelWidth = 3L, SelectionBoxOpen = FALSE, + RowSelectionSource = "---", ColumnSelectionSource = "---", + DataBoxOpen = FALSE, RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Reduced dimension plot 3 +################################################################################ + +initial[["ReducedDimensionPlot3"]] <- new("ReducedDimensionPlot", Type = "UMAP", XAxis = 1L, YAxis = 2L, + FacetRowByColData = "donor_id", FacetColumnByColData = "donor_id", + ColorByColumnData = "barcode", ColorByFeatureNameAssay = "logcounts", + ColorBySampleNameColor = "#FF0000", ShapeByColumnData = "donor_id", + SizeByColumnData = "age", FacetRowBy = "None", FacetColumnBy = "None", + ColorBy = "Feature name", ColorByDefaultColor = "#000000", + ColorByFeatureName = "LCE3E", ColorByFeatureSource = "RowDataTable2", + ColorByFeatureDynamicSource = FALSE, ColorBySampleName = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + ColorBySampleSource = "---", ColorBySampleDynamicSource = FALSE, + ShapeBy = "None", SizeBy = "None", SelectionAlpha = 0.1, + ZoomData = numeric(0), BrushData = list(), VisualBoxOpen = TRUE, + VisualChoices = "Color", ContourAdd = FALSE, ContourColor = "#0000FF", + PointSize = 1, PointAlpha = 1, Downsample = FALSE, DownsampleResolution = 200, + CustomLabels = FALSE, CustomLabelsText = "bw94nf57_vm85woki_CTCCTTTCACACGGAA-1", + FontSize = 1, LegendPointSize = 1, LegendPosition = "Bottom", + HoverInfo = TRUE, LabelCenters = FALSE, LabelCentersBy = "donor_id", + LabelCentersColor = "#000000", VersionInfo = list(iSEE = structure(list( + c(2L, 8L, 0L)), class = c("package_version", "numeric_version" + ))), PanelId = 3L, PanelHeight = 500L, PanelWidth = 3L, SelectionBoxOpen = FALSE, + RowSelectionSource = "---", ColumnSelectionSource = "---", + DataBoxOpen = FALSE, RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Complex heatmap 2 +################################################################################ + +initial[["ComplexHeatmapPlot2"]] <- new("ComplexHeatmapPlot", Assay = "logcounts", CustomRows = TRUE, + CustomRowsText = "CNFN\nLCE3A\nLCE3D\nLCE3E\nSPRR2D\nSPRR2E", + ClusterRows = FALSE, ClusterRowsDistance = "spearman", ClusterRowsMethod = "ward.D2", + DataBoxOpen = FALSE, VisualChoices = "Annotations", ColumnData = "annotation_20220215", + RowData = character(0), CustomBounds = FALSE, LowerBound = 0L, + UpperBound = 0L, AssayCenterRows = FALSE, AssayScaleRows = FALSE, + DivergentColormap = "purple < black < yellow", ShowDimNames = "Rows", + LegendPosition = "Bottom", LegendDirection = "Horizontal", + VisualBoxOpen = FALSE, NamesRowFontSize = 10, NamesColumnFontSize = 10, + ShowColumnSelection = TRUE, OrderColumnSelection = TRUE, + VersionInfo = list(iSEE = structure(list(c(2L, 8L, 0L)), class = c("package_version", + "numeric_version"))), PanelId = 2L, PanelHeight = 500L, PanelWidth = 4L, + SelectionBoxOpen = FALSE, RowSelectionSource = "---", ColumnSelectionSource = "---", + RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Complex heatmap 3 +################################################################################ + +initial[["ComplexHeatmapPlot3"]] <- new("ComplexHeatmapPlot", Assay = "logcounts", CustomRows = TRUE, + CustomRowsText = "IL1B\nS100A6\nSPIB\nMARCKSL1", ClusterRows = FALSE, + ClusterRowsDistance = "spearman", ClusterRowsMethod = "ward.D2", + DataBoxOpen = FALSE, VisualChoices = "Annotations", ColumnData = "annotation_20220215", + RowData = character(0), CustomBounds = FALSE, LowerBound = 0L, + UpperBound = 0L, AssayCenterRows = FALSE, AssayScaleRows = FALSE, + DivergentColormap = "purple < black < yellow", ShowDimNames = "Rows", + LegendPosition = "Bottom", LegendDirection = "Horizontal", + VisualBoxOpen = FALSE, NamesRowFontSize = 10, NamesColumnFontSize = 10, + ShowColumnSelection = TRUE, OrderColumnSelection = TRUE, + VersionInfo = list(iSEE = structure(list(c(2L, 8L, 0L)), class = c("package_version", + "numeric_version"))), PanelId = 3L, PanelHeight = 500L, PanelWidth = 4L, + SelectionBoxOpen = FALSE, RowSelectionSource = "---", ColumnSelectionSource = "ColumnDataPlot1", + RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +################################################################################ +# Settings for Complex heatmap 4 +################################################################################ + +initial[["ComplexHeatmapPlot4"]] <- new("ComplexHeatmapPlot", Assay = "logcounts", CustomRows = TRUE, + CustomRowsText = "FDCSP\nKRTDAP\n", ClusterRows = FALSE, + ClusterRowsDistance = "spearman", ClusterRowsMethod = "ward.D2", + DataBoxOpen = FALSE, VisualChoices = "Annotations", ColumnData = "annotation_20220215", + RowData = character(0), CustomBounds = FALSE, LowerBound = 0L, + UpperBound = 0L, AssayCenterRows = FALSE, AssayScaleRows = FALSE, + DivergentColormap = "purple < black < yellow", ShowDimNames = "Rows", + LegendPosition = "Bottom", LegendDirection = "Horizontal", + VisualBoxOpen = FALSE, NamesRowFontSize = 10, NamesColumnFontSize = 10, + ShowColumnSelection = TRUE, OrderColumnSelection = TRUE, + VersionInfo = list(iSEE = structure(list(c(2L, 8L, 0L)), class = c("package_version", + "numeric_version"))), PanelId = 4L, PanelHeight = 500L, PanelWidth = 4L, + SelectionBoxOpen = FALSE, RowSelectionSource = "---", ColumnSelectionSource = "---", + RowSelectionDynamicSource = FALSE, ColumnSelectionDynamicSource = FALSE, + RowSelectionRestrict = FALSE, ColumnSelectionRestrict = FALSE, + SelectionHistory = list()) + +## Adding a tour to tell things to people - they like to hear or read about the data! + +tour <- read.delim("tour_tda_epithelial.txt", sep = ";", header = TRUE) + + + + + + diff --git a/inst/tonsils_example/hca_tonsil_myeloid.R b/inst/tonsils_example/hca_tonsil_myeloid.R new file mode 100644 index 0000000..e69de29 diff --git a/inst/tonsils_example/header_tonsils.md b/inst/tonsils_example/header_tonsils.md new file mode 100644 index 0000000..77d514b --- /dev/null +++ b/inst/tonsils_example/header_tonsils.md @@ -0,0 +1,5 @@ +[`iSEE`](https://bioconductor.org/packages/iSEE) delivers a fully interactive browser for the specific single cell dataset it refers to - in this case, the ones contained in the [`HCATonsilData`](https://bioconductor.org/packages/HCATonsilData) package. + +Every app starts with a configuration that mirrors the findings presented in the original publication, "[An Atlas of Cells in the Human Tonsil](https://www.biorxiv.org/content/10.1101/2022.06.24.497299v1)", by Massoni-Badosa et al., doi: https://doi.org/10.1101/2022.06.24.497299. + +In each instance, you can follow a tour that guides you through the main findings as they are presented. At any time, you are free to change any of the defined settings to explore in depth the dataset. diff --git a/inst/tonsils_example/tonsil_package.yml b/inst/tonsils_example/tonsil_package.yml new file mode 100644 index 0000000..79f80b3 --- /dev/null +++ b/inst/tonsils_example/tonsil_package.yml @@ -0,0 +1,59 @@ +datasets: + - id: Tonsil_epithelial + title: Tonsil Data - Epithelial + uri: runr://HCATonsilData::HCATonsilData(assayType = "RNA", cellType = "epithelial") + description: | + Tonsil Data - Epithelial, 396 cells + +

+ +

+ - id: Tonsil_cytotoxic + title: Tonsil Data - Cytotoxic + uri: runr://HCATonsilData::HCATonsilData(assayType = "RNA", cellType = "Cytotoxic") + description: | + Tonsil Data - Cytotoxic, 24065 cells + - id: Tonsil_myeloid + title: Tonsil Data - Myeloid + uri: runr://HCATonsilData::HCATonsilData(assayType = "RNA", cellType = "myeloid") + description: | + Tonsil Data - Myeloid, 5334 cells + - id: Tonsil_NBC-MBC + title: Tonsil Data - NBC-MBC + uri: runr://HCATonsilData::HCATonsilData(assayType = "RNA", cellType = "NBC-MBC") + description: | + Tonsil Data - NBC-MBC, 118010 cells + - id: Tonsil_GCBC + title: Tonsil Data - GCBC + uri: runr://HCATonsilData::HCATonsilData(assayType = "RNA", cellType = "GCBC") + description: | + Tonsil Data - GCBC, 72174 cells + - id: Tonsil_PC + title: Tonsil Data - PC + uri: runr://HCATonsilData::HCATonsilData(assayType = "RNA", cellType = "PC") + description: | + Tonsil Data - PC, 12779 cells + - id: Tonsil_CD4-T + title: Tonsil Data - CD4-T + uri: runr://HCATonsilData::HCATonsilData(assayType = "RNA", cellType = "CD4-T") + description: | + Tonsil Data - CD4-T, 52307 cells + - id: Tonsil_FDC + title: Tonsil Data - FDC + uri: runr://HCATonsilData::HCATonsilData(assayType = "RNA", cellType = "FDC") + description: | + Tonsil Data - FDC, 926 cells + - id: Tonsil_PDC + title: Tonsil Data - PDC + uri: runr://HCATonsilData::HCATonsilData(assayType = "RNA", cellType = "PDC") + description: | + Tonsil Data - PDC, 322 cells +initial: + - id: Tonsil_epithelial_full5 + datasets: + - Tonsil_epithelial + title: Tonsil_epithelial configuration 1 (R call) + 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 diff --git a/inst/tonsils_example/tonsilling_around.R b/inst/tonsils_example/tonsilling_around.R new file mode 100644 index 0000000..fdf460e --- /dev/null +++ b/inst/tonsils_example/tonsilling_around.R @@ -0,0 +1,49 @@ +library("iSEEindex") +library("BiocFileCache") +bfc <- BiocFileCache(cache = tempdir()) + + +## +# iSEEindex ---- +## +dataset_fun <- function() { + x <- yaml::read_yaml("tonsil_package.yml") + x$datasets +} +initial_fun <- function() { + x <- yaml::read_yaml("tonsil_package.yml") + x$initial +} +app <- iSEEindex_runr(bfc, dataset_fun, initial_fun, + default.add = FALSE, + app.title = "iSEE ❤️ Tonsil Data Atlas") +if (interactive()) { + shiny::runApp(app, port = 1234) +} +app <- iSEEindex_runr(bfc, dataset_fun, initial_fun, + default.add = TRUE, + default.position = "last", + app.title = "iSEE ❤️ Tonsil Data Atlas") +if (interactive()) { + shiny::runApp(app, port = 1234) +} + + + + + +# the logic: + + + +iSEEindex_runr + +.landing_page_runr + +specifically into .create_launch_observers_runr + +.launch_isee_runr + +iSEEindexRunrResource -> no need to precache + + diff --git a/inst/tonsils_example/tour_tda_cytotoxic.txt b/inst/tonsils_example/tour_tda_cytotoxic.txt new file mode 100644 index 0000000..e69de29 diff --git a/inst/tonsils_example/tour_tda_epithelial.txt b/inst/tonsils_example/tour_tda_epithelial.txt new file mode 100644 index 0000000..f31a7cd --- /dev/null +++ b/inst/tonsils_example/tour_tda_epithelial.txt @@ -0,0 +1,19 @@ +element;intro +#Welcome;Welcome to the HCA Tonsil Data Atlas instance for the epithelial cells! +#ReducedDimensionPlot1;We identified six clusters... +#ReducedDimensionPlot1_ColorBy;You can see that they are colored in the UMAP according to their annotated cell type +#RowDataTable1;From this table, you can select any gene, using the search widget (case sensitive, so make sure you type the correct name). This information can be propagated to other panels... +#FeatureAssayPlot1;... like this Feature Assay Plot, where the expression of a feature (a gene here) is plotted against any covariate of interest +#FeatureAssayPlot1_XAxisColumnData + .selectize-control;Here you can change the value for the covariate to plot against +#ReducedDimensionPlot2;Similarly, the expression of the selected gene can be overlaid on the UMAP plot. In the pre-selected configuration, you can see the clustered expression of KRT13 in surface epithelial cells. +#ColumnDataPlot1;Here is a summary of the different annotated cell types, with a visual representation of an abundance table. This +#ComplexHeatmapPlot1; This heatmap summarizes the two signatures expressed by basal and surface keratinocytes. You can change the selected features and lot more in the options below +#FeatureAssayPlot2;Surface epithelium expressed the protease TMPRSS2, activating coronaviruses in other tissues +#FeatureAssayPlot3;... but we did not detect the expression of the receptor ACE2 +#RowDataTable2;This table can be used to overlay the expression of any gene, e.g. the ones taken from the signatures presented in the later steps. Here we show how you can have multiple hits for a quick selection, namely all genes containing the LCE3 string - and use for example LCE3A, LCE3D, or LCE3E, as indicated in our manuscript +#ReducedDimensionPlot3;In this case, we display the expression of LCE3E +#ComplexHeatmapPlot2;This heatmap displays the signature for the Outer Surface, with the cornification and keratinization signatures +#ComplexHeatmapPlot3;Here's the Crypt epithelial cells, with a selection of points that can additionally be provided by other panels. For example... +#ColumnDataPlot1;... it can come from this Column Data Plot, and the selection can be updated at will. Also, it is possible to select any subset of cells from other panels - not displayed in this tour. +#ComplexHeatmapPlot4;Finally, this is the overview on the FDCSP epithelium subset, where we can show that follicular dendritic cells have been detected in tonsillar tissues. +#Thanks;Thank you for taking the tour on the epithelial cells subset of the Tonsil Data Atlas! Enjoy the exploration with iSEE! diff --git a/inst/tonsils_example/tour_tda_myeloid.txt b/inst/tonsils_example/tour_tda_myeloid.txt new file mode 100644 index 0000000..e69de29 From 683976e48b4d9e063085f95bbe3cf073ee8f594e Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 11 Sep 2024 16:57:49 +0200 Subject: [PATCH 04/23] updated roxygen note --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index d5b6fe4..8d4dc6e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -22,7 +22,7 @@ biocViews: Software, Infrastructure Encoding: UTF-8 Roxygen: list(markdown = TRUE) -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.2 Depends: SummarizedExperiment, SingleCellExperiment From bce3c83c5613b610a0b6e52d1ecb1db58c9f0ad1 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 11 Sep 2024 16:58:46 +0200 Subject: [PATCH 05/23] adding "parallel" implementation for having the runr modality implemented --- NAMESPACE | 2 + R/iSEEindex.R | 158 +++++++++++++++++++++++++++++++++++- R/iSEEindexResource-class.R | 115 +++++++++++++++++++++----- R/landing_page.R | 91 +++++++++++++++++++++ R/observers.R | 28 +++++-- R/utils-datasets.R | 71 ++++++++++++++++ 6 files changed, 433 insertions(+), 32 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 8b1b547..c2217ab 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,12 +4,14 @@ export(iSEEindex) export(iSEEindexHttpsResource) export(iSEEindexLocalhostResource) export(iSEEindexRcallResource) +export(iSEEindexRunrResource) export(iSEEindexS3Resource) export(precache) exportClasses(iSEEindexHttpsResource) exportClasses(iSEEindexLocalhostResource) exportClasses(iSEEindexRcallResource) exportClasses(iSEEindexResource) +exportClasses(iSEEindexRunrResource) exportClasses(iSEEindexS3Resource) exportMethods(precache) exportMethods(show) diff --git a/R/iSEEindex.R b/R/iSEEindex.R index ed03f96..94a9a30 100644 --- a/R/iSEEindex.R +++ b/R/iSEEindex.R @@ -52,7 +52,7 @@ #' \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.} @@ -110,7 +110,7 @@ #' ## #' # BiocFileCache ---- #' ## -#' +#' #' library(BiocFileCache) #' bfc <- BiocFileCache(cache = tempdir()) #' @@ -151,6 +151,85 @@ iSEEindex <- function(bfc, FUN.datasets, FUN.initial = NULL, default.add = TRUE, ) } +#' @examples +#' ## +#' # BiocFileCache ---- +#' ## +#' +#' library(BiocFileCache) +#' bfc <- BiocFileCache(cache = tempdir()) +#' +#' ## +#' # iSEEindex ---- +#' ## +#' +#' dataset_fun <- function() { +#' x <- yaml::read_yaml("tonsil_package.yml") +#' x$datasets +#' } +#' +#' initial_fun <- function() { +#' x <- yaml::read_yaml("tonsil_package.yml") +#' x$initial +#' } +#' +#' header_tonsils <- fluidRow( +#' shinydashboard::box( +#' width = 12, +#' collapsible = TRUE, +#' collapsed = TRUE, +#' title = "How to explore the Tonsil Atlas datasets", +#' includeMarkdown("header_tonsils.md") +#' ) +#' ) +#' +#' footer_tonsils <- fluidRow( +#' shinydashboard::box( +#' width = 12, +#' includeMarkdown("footer_tonsils.md") +#' ) +#' ) +#' +#' 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_runr(bfc, + FUN.datasets, + FUN.initial, + default.add, default.position, + body.header, + body.footer), + appTitle = app.title + ) +} + #' Prepare and Launch the Main App. @@ -207,7 +286,7 @@ iSEEindex <- function(bfc, FUN.datasets, FUN.initial = NULL, default.add = TRUE, } else { initial_id <- pObjects[[.ui_initial]] 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_metadata <- as.list(pObjects$initial_table[which_initial, , drop = FALSE]) @@ -244,3 +323,76 @@ iSEEindex <- function(bfc, FUN.datasets, FUN.initial = NULL, default.add = TRUE, invisible(NULL) # 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_runr(bfc, dataset_id, dataset_metadata)) + se2 <- try(.load_sce_runr(bfc, dataset_id, dataset_metadata)) + + + + + + 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 85a010c..e978a8b 100644 --- a/R/iSEEindexResource-class.R +++ b/R/iSEEindexResource-class.R @@ -37,9 +37,9 @@ setClass("iSEEindexResource", #' @export #' @rdname iSEEindexResource-class -#' +#' #' @param object An `iSEEindexResource` object. -#' +#' #' @return `show()` returns `NULL` after displaying a summary of the object. setMethod("show", "iSEEindexResource", function(object) @@ -51,7 +51,7 @@ setMethod("show", "iSEEindexResource", #' Generics for iSEEindexResources Objects #' #' An overview of the generics for `iSEEindexResources` objects. -#' +#' #' @param x An [`iSEEindexResource-class`] object. #' @param bfc A [BiocFileCache()] object. #' @param id A data set identifier as a character scalar. @@ -78,7 +78,7 @@ NULL #' @export #' @rdname iSEEindexResource-generics -#' +#' #' @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) @@ -87,12 +87,12 @@ setGeneric("precache", function(x, bfc, id, ...) { #' @export #' @rdname iSEEindexResource-class -#' +#' #' @param x An [`iSEEindexResource-class`] object. #' @param bfc A [BiocFileCache()] object. #' @param id A data set identifier as a character scalar. #' @param ... additional arguments passed to and from other methods. -#' +#' #' @return `precache()` throws an error if no method is found for the derived class. setMethod("precache", "iSEEindexResource", function(x, bfc, id, ...) @@ -110,10 +110,10 @@ setMethod("precache", "iSEEindexResource", #' The iSEEindexHttpsResource class represents a resource accessible through #' an HTTPS link. #' A URI for this type of resource uses the prefix \dQuote{https://}. -#' +#' #' @details #' Required metadata: -#' +#' #' \describe{ #' \item{uri}{Character scalar. URI of the resource.} #' } @@ -147,7 +147,7 @@ setClass("iSEEindexHttpsResource", contains="iSEEindexResource") #' @rdname iSEEindexHttpsResource-class #' #' @param x List of metadata. See Details. -#' +#' #' @return The constructor function `iSEEindexHttpsResource()` returns an object of object of class `iSEEindexHttpsResource`. iSEEindexHttpsResource <- function(x) { new("iSEEindexHttpsResource", uri = x[[.datasets_uri]]) @@ -174,7 +174,7 @@ setMethod("precache", "iSEEindexHttpsResource", #' #' @details #' Required metadata: -#' +#' #' \describe{ #' \item{uri}{Character scalar. URI of the resource.} #' } @@ -189,9 +189,9 @@ setMethod("precache", "iSEEindexHttpsResource", #' \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. #' } -#' +#' #' @section Absolute and relative paths: -#' +#' #' Absolute and relative paths are both supported. #' #' Absolute paths require an additional `/` (forward slash) @@ -224,7 +224,7 @@ setClass("iSEEindexLocalhostResource", contains="iSEEindexResource") #' @rdname iSEEindexLocalhostResource-class #' #' @param x List of metadata. See Details. -#' +#' #' @return The constructor function `iSEEindexLocalhostResource()` returns an object of object of class `iSEEindexLocalhostResource`. iSEEindexLocalhostResource <- function(x) { new("iSEEindexLocalhostResource", uri = x[[.datasets_uri]]) @@ -250,15 +250,15 @@ setMethod("precache", "iSEEindexLocalhostResource", #' The iSEEindexRcallResource class represents a resource accessible through #' the result of an R call. #' A URI for this type of resource uses the prefix \dQuote{rcall://}. -#' +#' #' @details #' Required metadata: -#' +#' #' \describe{ #' \item{uri}{Character scalar. R call which, once evaluated, produces a character scalar that is the URI of the resource.} #' } #' -#' @section URI format: +#' @section URI format: #' The URI must contain valid R code, once the prefix `rcall://` is removed. #' The code must return the path to an existing file on the local filesystem. #' @@ -302,7 +302,7 @@ setClass("iSEEindexRcallResource", contains="iSEEindexResource") #' @rdname iSEEindexRcallResource-class #' #' @param x List of metadata. See Details. -#' +#' #' @return The constructor function `iSEEindexRcallResource()` returns an object of object of class `iSEEindexRcallResource`. iSEEindexRcallResource <- function(x) { new("iSEEindexRcallResource", uri = x[[.datasets_uri]]) @@ -324,6 +324,77 @@ setMethod("precache", "iSEEindexRcallResource", return(object_path) }) + + +# iSEEindexRunrResource ---- + +#' The iSEEindexRunrResource class +#' +#' The iSEEindexRunrResource class represents an SE object, obtained directly +#' through an R call. +#' +#' A URI for this type of resource uses the prefix \dQuote{runr://}. +#' +#' @details +#' Required metadata: +#' +#' +#' @examples +#' iSEEindexRunrResource(list( +#' uri = "runr://HCATonsilData::HCATonsilData(assayType = 'RNA', cellType = 'epithelial')" +#' )) +NULL + +#' @export +setClass("iSEEindexRunrResource", contains="iSEEindexResource") + +#' @export +#' @rdname iSEEindexRunrResource-class +#' +#' @param x List of metadata. See Details. +#' +#' @return The constructor function `iSEEindexRunrResource()` returns an object of object of class `iSEEindexRunrResource`. +iSEEindexRunrResource <- function(x) { + new("iSEEindexRunrResource", uri = x[[.datasets_uri]]) +} + +#' @export +setMethod("precache", "iSEEindexRunrResource", + function(x, bfc, id, ...) + { + # Trim 'runr://' from the original URI and evaluate the R call, + # check that the value is an existing filepath and pass to BiocFileCache, + # which will manage the caching. + # Use action="copy" to leave the original file untouched. + call_string <- sub("runr://", "", x@uri) + env <- new.env() + + # fpath not needed per se, we should have a "valid r call and that is it" + + object_path <- eval(parse(text = call_string)) + + + # fpath <- eval(parse(text = call_string), envir = env) + # stopifnot(file.exists(fpath)) + # object_path <- bfcadd(x = bfc, rname = id, fpath = fpath, action = "copy", ...) + + + + + return(object_path) + }) + + + + + + + + + + + + # iSEEindexS3Resource ---- #' The iSEEindexS3Resource class @@ -333,10 +404,10 @@ setMethod("precache", "iSEEindexRcallResource", #' [paws.storage](https://cran.r-project.org/package=paws.storage) #' R package. #' A URI for this type of resource uses the prefix \dQuote{s3://}. -#' +#' #' @details #' Required metadata: -#' +#' #' \describe{ #' \item{uri}{Character scalar. URI of the resource.} #' } @@ -361,7 +432,7 @@ setMethod("precache", "iSEEindexRcallResource", #' \pkg{BiocFileCache}, before returning the file path to the cached file. #' } #' -#' @section URI format: +#' @section URI format: #' The URI must correspond to an existing file in an AWS S3 compatible cloud #' storage system. #' @@ -375,7 +446,7 @@ setMethod("precache", "iSEEindexRcallResource", #' #' @section Pre-caching: #' Additional arguments to the \code{\link{precache}(x, ..., temp_dir = tempdir())}: -#' +#' #' \describe{ #' \item{`temp_dir`}{Scalar character, the directory to store the downloaded file #' in before it is handed over to \pkg{BiocFileCache}. This directory will be created @@ -449,7 +520,7 @@ setClass("iSEEindexS3Resource", contains="iSEEindexResource", slots = c("region" #' @rdname iSEEindexS3Resource-class #' #' @param x List of metadata. See Details. -#' +#' #' @return The constructor function `iSEEindexS3Resource()` returns an object of object of class `iSEEindexS3Resource`. iSEEindexS3Resource <- function(x) { region <- x[[.dataset_region]] diff --git a/R/landing_page.R b/R/landing_page.R index 39a7921..236261e 100644 --- a/R/landing_page.R +++ b/R/landing_page.R @@ -108,6 +108,97 @@ } } + + + + +.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_runr(FUN, bfc, input, session, pObjects) + + .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. diff --git a/R/observers.R b/R/observers.R index da2298f..86eaff8 100644 --- a/R/observers.R +++ b/R/observers.R @@ -1,9 +1,9 @@ #' Observers for iSEEindex -#' -#' @description -#' +#' +#' @description +#' #' `.create_observers()` initialises observers for the \pkg{iSEEindex} landing page. -#' +#' #' `.create_launch_observers()` initialises observers for launching the \pkg{iSEE} main app. #' #' @param input The Shiny input object from the server function. @@ -17,11 +17,11 @@ #' @param default.position Character scalar indicating whether the default #' initial configuration should be added as the `"first"` or `"last"` option #' in the Shiny `selectizeInput()`. -#' -#' @return +#' +#' @return #' Those functions create observers in the server function in which they are called. #' In all cases, a \code{NULL} value is invisibly returned. -#' +#' #' @author Kevin Rue-Albrecht #' #' @importFrom shiny isolate observeEvent updateSelectizeInput @@ -81,3 +81,17 @@ invisible(NULL) } + + + +.create_launch_observers_runr <- function(FUN, bfc, input, session, pObjects) { + + # nocov start + observeEvent(input[[.ui_launch_button]], { + .launch_isee_runr(FUN, bfc, session, pObjects) + }, ignoreNULL=TRUE, ignoreInit=TRUE) + # nocov end + + invisible(NULL) +} + diff --git a/R/utils-datasets.R b/R/utils-datasets.R index d3c7e31..59ab4ba 100644 --- a/R/utils-datasets.R +++ b/R/utils-datasets.R @@ -45,6 +45,53 @@ object } + + + +#' @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_runr(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 @@ -104,6 +151,30 @@ constructor.FUN(x) } + +#' @examples +#' iSEEindex:::.metadata_to_object(list(uri="runr://HCATonsilData::HCATonsilData(assayType = 'RNA', cellType = 'epithelial')")) +.metadata_to_object_runr <- function(x) { + scheme <- urltools::url_parse(x[[.datasets_uri]])$scheme + scheme_titled <- str_to_title(scheme) + target_class <- sprintf("iSEEindex%sResource", scheme_titled) + constructor.FUN <- try({ + get(target_class) + }, silent = TRUE) + if (is(constructor.FUN, "try-error")) { + stop( + sprintf("No constructor function available for scheme '%s'. ", scheme), + sprintf("Consider implementing the constructor function '%s()'.", target_class) + ) + } + constructor.FUN(x) +} + + + + + + #' Check Validity of Data Sets Metadata #' #' @param x `list` of of lists of metadata. From 66a53eec0a106170f1b424928fc7c6ff05807c41 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 11 Sep 2024 16:58:55 +0200 Subject: [PATCH 06/23] re-rendering manpage --- man/iSEEindex-pkg.Rd | 11 +++++++++++ man/iSEEindex.Rd | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/man/iSEEindex-pkg.Rd b/man/iSEEindex-pkg.Rd index 167ba61..a0bd2b1 100644 --- a/man/iSEEindex-pkg.Rd +++ b/man/iSEEindex-pkg.Rd @@ -2,6 +2,7 @@ % Please edit documentation in R/iSEEindex-pkg.R \docType{package} \name{iSEEindex-pkg} +\alias{iSEEindex-package} \alias{iSEEindex-pkg} \title{iSEEindex: iSEE extension for a landing page to a custom collection of data sets} \description{ @@ -17,5 +18,15 @@ Useful links: \item \url{https://github.com/iSEE/iSEEindex} \item Report bugs at \url{https://support.bioconductor.org/t/iSEEindex} } +} +\author{ +\strong{Maintainer}: Kevin Rue-Albrecht \email{kevinrue67@gmail.com} (\href{https://orcid.org/0000-0003-3899-3872}{ORCID}) + +Other contributors: +\itemize{ + \item Thomas Sandmann \email{tomsing1@gmail.com} (\href{https://orcid.org/0000-0002-6601-8890}{ORCID}) [contributor] + \item Denali Therapeutics [funder] +} + } \keyword{internal} diff --git a/man/iSEEindex.Rd b/man/iSEEindex.Rd index fefb5d9..e1eb505 100644 --- a/man/iSEEindex.Rd +++ b/man/iSEEindex.Rd @@ -10,6 +10,7 @@ iSEEindex( FUN.initial = NULL, default.add = TRUE, default.position = c("first", "last"), + app.title = NULL, body.header = NULL, body.footer = NULL ) @@ -31,6 +32,10 @@ See \code{\link[=iSEEindex]{iSEEindex()}}.} initial configuration should be added as the \code{"first"} or \code{"last"} option in the Shiny \code{selectizeInput()}.} +\item{app.title}{Character string to specify the desired title to be displayed +in the main window of the dashboard. Defaults to \code{NULL}, which displays some +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.} From 0944a11ebd2316f1a9006d0d0d32f1525aeaf159 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Tue, 1 Oct 2024 23:18:28 +0200 Subject: [PATCH 07/23] adapting the example for the runr functionality to reflect the new location in the inst folder --- R/iSEEindex.R | 17 +++++++++++++---- inst/tonsils_example/hca_tonsil_epithelial_v2.R | 5 ++++- inst/tonsils_example/tonsil_package.yml | 3 ++- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/R/iSEEindex.R b/R/iSEEindex.R index 274e640..6a3d95d 100644 --- a/R/iSEEindex.R +++ b/R/iSEEindex.R @@ -164,29 +164,38 @@ iSEEindex <- function(bfc, FUN.datasets, FUN.initial = NULL, default.add = TRUE, #' ## #' #' dataset_fun <- function() { -#' x <- yaml::read_yaml("tonsil_package.yml") +#' x <- yaml::read_yaml( +#' system.file("tonsils_example", "tonsil_package.yml", package = "iSEEindex") +#' ) #' x$datasets #' } #' #' initial_fun <- function() { -#' x <- yaml::read_yaml("tonsil_package.yml") +#' 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("header_tonsils.md") +#' includeMarkdown( +#' system.file("tonsils_example", "header_tonsils.md", package = "iSEEindex") +#' ) #' ) #' ) #' #' footer_tonsils <- fluidRow( #' shinydashboard::box( #' width = 12, -#' includeMarkdown("footer_tonsils.md") +#' includeMarkdown( +#' system.file("tonsils_example", "footer_tonsils.md", package = "iSEEindex") +#' ) #' ) #' ) #' diff --git a/inst/tonsils_example/hca_tonsil_epithelial_v2.R b/inst/tonsils_example/hca_tonsil_epithelial_v2.R index 104d855..1afdd05 100644 --- a/inst/tonsils_example/hca_tonsil_epithelial_v2.R +++ b/inst/tonsils_example/hca_tonsil_epithelial_v2.R @@ -348,7 +348,10 @@ initial[["ComplexHeatmapPlot4"]] <- new("ComplexHeatmapPlot", Assay = "logcounts ## Adding a tour to tell things to people - they like to hear or read about the data! -tour <- read.delim("tour_tda_epithelial.txt", sep = ";", header = TRUE) +tour <- read.delim( + system.file("tonsils_example/tour_tda_epithelial.txt", package = "iSEEindex"), + sep = ";", header = TRUE +) diff --git a/inst/tonsils_example/tonsil_package.yml b/inst/tonsils_example/tonsil_package.yml index 79f80b3..80de21e 100644 --- a/inst/tonsils_example/tonsil_package.yml +++ b/inst/tonsils_example/tonsil_package.yml @@ -53,7 +53,8 @@ initial: datasets: - Tonsil_epithelial title: Tonsil_epithelial configuration 1 (R call) - uri: localhost:///Users/fede/Development/iSEEindex/hca_tonsil_epithelial_v2.R + 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 From 373b2ca8006ef9f6d9e82a8862266180360c2e7c Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 2 Oct 2024 00:06:24 +0200 Subject: [PATCH 08/23] generating some first set of content for the iSEEindexRunrResource class documentation --- .Rbuildignore | 1 + R/iSEEindexResource-class.R | 16 +++++++++++ man/iSEEindexRunrResource-class.Rd | 44 ++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 man/iSEEindexRunrResource-class.Rd diff --git a/.Rbuildignore b/.Rbuildignore index 755a8f2..a3915ba 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -10,3 +10,4 @@ ^docs$ ^doc$ ^Meta$ +^TODO\.md$ diff --git a/R/iSEEindexResource-class.R b/R/iSEEindexResource-class.R index e978a8b..9ac6559 100644 --- a/R/iSEEindexResource-class.R +++ b/R/iSEEindexResource-class.R @@ -338,6 +338,22 @@ setMethod("precache", "iSEEindexRcallResource", #' @details #' Required metadata: #' +#' \describe{ +#' \item{uri}{Character scalar. URI of the resource.} +#' } +#' +#' @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. +#' +#' \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. +#' } +#' +#' @name iSEEindexRunrResource-class +#' @rdname iSEEindexRunrResource-class +#' @aliases +#' precache,iSEEindexRunrResource-method #' #' @examples #' iSEEindexRunrResource(list( diff --git a/man/iSEEindexRunrResource-class.Rd b/man/iSEEindexRunrResource-class.Rd new file mode 100644 index 0000000..fc0ad6d --- /dev/null +++ b/man/iSEEindexRunrResource-class.Rd @@ -0,0 +1,44 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/iSEEindexResource-class.R +\name{iSEEindexRunrResource-class} +\alias{iSEEindexRunrResource-class} +\alias{precache,iSEEindexRunrResource-method} +\alias{iSEEindexRunrResource} +\title{The iSEEindexRunrResource class} +\usage{ +iSEEindexRunrResource(x) +} +\arguments{ +\item{x}{List of metadata. See Details.} +} +\value{ +The constructor function \code{iSEEindexRunrResource()} returns an object of object of class \code{iSEEindexRunrResource}. +} +\description{ +The iSEEindexRunrResource class represents an SE object, obtained directly +through an R call. +} +\details{ +A URI for this type of resource uses the prefix \dQuote{runr://}. + +Required metadata: + +\describe{ +\item{uri}{Character scalar. URI of the resource.} +} +} +\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. + +\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. +} +} + +\examples{ +iSEEindexRunrResource(list( + uri = "runr://HCATonsilData::HCATonsilData(assayType = 'RNA', cellType = 'epithelial')" +)) +} From 193d0b6bec71934fb8fed12d4d0f44927c4936b5 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 2 Oct 2024 17:05:45 +0200 Subject: [PATCH 09/23] yolo'ing the sets of changes done to have the runr up n running - so far uses a propagation of a parameter --- R/iSEEindex.R | 349 +++++++++++++++------------ R/iSEEindexResource-class.R | 32 +-- R/landing_page.R | 180 +++++++------- R/observers.R | 31 ++- R/utils-datasets.R | 146 +++++------ man/iSEEindex.Rd | 63 ++++- tests/testthat/test-observers.R | 2 +- tests/testthat/test-utils-datasets.R | 2 +- 8 files changed, 451 insertions(+), 354 deletions(-) diff --git a/R/iSEEindex.R b/R/iSEEindex.R index 6a3d95d..597b3d2 100644 --- a/R/iSEEindex.R +++ b/R/iSEEindex.R @@ -96,6 +96,7 @@ #' 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. #' @@ -107,17 +108,9 @@ #' @importFrom utils packageVersion #' #' @examples -#' ## -#' # BiocFileCache ---- -#' ## -#' -#' library(BiocFileCache) +#' library("BiocFileCache") #' bfc <- BiocFileCache(cache = tempdir()) #' -#' ## -#' # iSEEindex ---- -#' ## -#' #' dataset_fun <- function() { #' x <- yaml::read_yaml(system.file(package = "iSEEindex", "example.yaml")) #' x$datasets @@ -133,46 +126,18 @@ #' if (interactive()) { #' shiny::runApp(app, port = 1234) #' } -iSEEindex <- 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 | powered by iSEE - v%s", - packageVersion("iSEEindex"), - packageVersion("iSEE")) - } - - iSEE( - landingPage=.landing_page(bfc, FUN.datasets, FUN.initial, default.add, default.position, body.header, body.footer), - appTitle = app.title - ) -} - -#' @examples -#' ## -#' # BiocFileCache ---- -#' ## #' -#' library(BiocFileCache) -#' bfc <- BiocFileCache(cache = tempdir()) -#' -#' ## -#' # iSEEindex ---- -#' ## +#' ## Alternatively, with the example based on using runr calls #' -#' dataset_fun <- function() { +#' dataset_fun_tonsils <- function() { #' x <- yaml::read_yaml( -#' system.file("tonsils_example", "tonsil_package.yml", package = "iSEEindex") +#' system.file("tonsils_example", "tonsil_package.yml", package = "iSEEindex") #' ) #' x$datasets #' } -#' -#' initial_fun <- function() { +#' initial_fun_tonsils <- function() { #' x <- yaml::read_yaml( -#' system.file("tonsils_example", "tonsil_package.yml", package = "iSEEindex") +#' system.file("tonsils_example", "tonsil_package.yml", package = "iSEEindex") #' ) #' x$initial #' } @@ -180,16 +145,13 @@ iSEEindex <- function(bfc, FUN.datasets, FUN.initial = NULL, default.add = TRUE, #' library("shiny") #' header_tonsils <- fluidRow( #' shinydashboard::box( -#' width = 12, -#' collapsible = TRUE, -#' collapsed = TRUE, +#' 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, @@ -199,46 +161,141 @@ iSEEindex <- function(bfc, FUN.datasets, FUN.initial = NULL, default.add = TRUE, #' ) #' ) #' -#' 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) +#' app_tonsils <- iSEEindex(bfc, +#' dataset_fun_tonsils, +#' initial_fun_tonsils, +#' default.add = TRUE, +#' default.position = "last", +#' app.title = "iSEE ❤️ Tonsil Data Atlas", +#' body.header = header_tonsils, +#' body.footer = footer_tonsils, +#' already_se_object = TRUE) #' #' if (interactive()) { -#' shiny::runApp(app, port = 1234) +#' shiny::runApp(app_tonsils, port = 5678) #' } -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 - } +iSEEindex <- function(bfc, + FUN.datasets, + FUN.initial = NULL, + default.add = TRUE, + default.position = c("first", "last"), + app.title = NULL, + body.header = NULL, + body.footer = NULL, + already_se_object = FALSE) { + 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 - } + if (is.null(app.title)) { + app.title <- sprintf("iSEEindex - v%s | powered by iSEE - v%s", + packageVersion("iSEEindex"), + packageVersion("iSEE")) + } - iSEE( - landingPage=.landing_page_runr(bfc, - FUN.datasets, - FUN.initial, - default.add, default.position, - body.header, - body.footer), - appTitle = app.title - ) + iSEE( + landingPage = .landing_page(bfc, + FUN.datasets, + FUN.initial, + default.add, + default.position, + body.header, + body.footer, + already_se_object = already_se_object + ), + 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. @@ -258,10 +315,11 @@ iSEEindex_runr <- function(bfc, #' #' @param FUN A function to initialize the \pkg{iSEE} observer #' architecture. Refer to [iSEE::createLandingPage()] for more details. -#' @param bfc An [BiocFileCache()] object. +#' @param bfc A [BiocFileCache()] object. #' @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. #' @@ -273,7 +331,7 @@ iSEEindex_runr <- function(bfc, #' @importFrom shinyjs enable #' #' @rdname INTERNAL_launch_isee -.launch_isee <- function(FUN, bfc, session, pObjects) { +.launch_isee <- function(FUN, bfc, session, pObjects, already_se_object) { # nocov start dataset_id <- pObjects[[.dataset_selected_id]] which_dataset <- which(pObjects$datasets_table[[.datasets_id]] == dataset_id) @@ -284,7 +342,8 @@ iSEEindex_runr <- 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)) + se2 <- try(.load_sce(bfc, dataset_id, dataset_metadata, + already_se_object = already_se_object)) incProgress(1, detail = "Launching iSEE app") if (is(se2, "try-error")) { showNotification("Invalid SummarizedExperiment supplied.", type="error") @@ -338,70 +397,62 @@ iSEEindex_runr <- function(bfc, -.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_runr(bfc, dataset_id, dataset_metadata)) - se2 <- try(.load_sce_runr(bfc, dataset_id, dataset_metadata)) - - - - - - 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 -} +# .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 9ac6559..2c7caf5 100644 --- a/R/iSEEindexResource-class.R +++ b/R/iSEEindexResource-class.R @@ -376,29 +376,21 @@ iSEEindexRunrResource <- function(x) { #' @export setMethod("precache", "iSEEindexRunrResource", - function(x, bfc, id, ...) - { - # Trim 'runr://' from the original URI and evaluate the R call, - # check that the value is an existing filepath and pass to BiocFileCache, - # which will manage the caching. - # Use action="copy" to leave the original file untouched. - call_string <- sub("runr://", "", x@uri) - env <- new.env() - - # fpath not needed per se, we should have a "valid r call and that is it" - - object_path <- eval(parse(text = call_string)) - - - # fpath <- eval(parse(text = call_string), envir = env) - # stopifnot(file.exists(fpath)) - # object_path <- bfcadd(x = bfc, rname = id, fpath = fpath, action = "copy", ...) - + function(x, bfc, id, ...) +{ + # Trim 'runr://' from the original URI and evaluate the R call, + # We expect already that an SE object will be returned + call_string <- sub("runr://", "", x@uri) + # fpath not needed per se, we should have a "valid r call and that is it" + # this time it is called object, as it is already returning that + object <- eval(parse(text = call_string)) + ## "we have to believe" that this is already somehow cached e.g. via + ## Bioc data packages using the cache, and many times it is so - return(object_path) - }) + return(object) +}) diff --git a/R/landing_page.R b/R/landing_page.R index 236261e..a507561 100644 --- a/R/landing_page.R +++ b/R/landing_page.R @@ -11,6 +11,7 @@ #' 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. @@ -24,7 +25,14 @@ #' @importFrom shinyjs disable #' #' @rdname INTERNAL_landing_page -.landing_page <- function(bfc, FUN.datasets, FUN.initial, default.add = TRUE, default.position = c("first", "last"), body.header = NULL, body.footer = NULL) { +.landing_page <- function(bfc, + FUN.datasets, + FUN.initial, + default.add = TRUE, + default.position = c("first", "last"), + body.header = NULL, + body.footer = NULL, + already_se_object) { default.position <- match.arg(default.position) # datasets datasets_available_list <- FUN.datasets() @@ -95,7 +103,7 @@ .create_observers(input, session, pObjects, rObjects, FUN.initial, default.add, default.position) - .create_launch_observers(FUN, bfc, input, session, pObjects) + .create_launch_observers(FUN, bfc, input, session, pObjects, already_se_object = already_se_object) .render_datasets_table(output, pObjects, rObjects) @@ -110,91 +118,89 @@ - - -.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_runr(FUN, bfc, input, session, pObjects) - - .render_datasets_table(output, pObjects, rObjects) - - .render_markdown_overview(output, pObjects, rObjects) - - .render_initial_overview(output, pObjects, rObjects) - - invisible(NULL) - # nocov end - } -} +# .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 +# } +# } diff --git a/R/observers.R b/R/observers.R index 86eaff8..79e4f12 100644 --- a/R/observers.R +++ b/R/observers.R @@ -65,17 +65,22 @@ #' @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 #' #' @importFrom shiny observeEvent #' #' @rdname INTERNAL_create_observers -.create_launch_observers <- function(FUN, bfc, input, session, pObjects) { +.create_launch_observers <- function(FUN, bfc, input, session, pObjects, already_se_object) { # nocov start observeEvent(input[[.ui_launch_button]], { - .launch_isee(FUN, bfc, session, pObjects) + .launch_isee(FUN, bfc, session, pObjects, already_se_object = already_se_object) }, ignoreNULL=TRUE, ignoreInit=TRUE) # nocov end @@ -83,15 +88,15 @@ } - -.create_launch_observers_runr <- function(FUN, bfc, input, session, pObjects) { - - # nocov start - observeEvent(input[[.ui_launch_button]], { - .launch_isee_runr(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/utils-datasets.R b/R/utils-datasets.R index 59ab4ba..8eced35 100644 --- a/R/utils-datasets.R +++ b/R/utils-datasets.R @@ -8,6 +8,7 @@ #' @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? #' #' @return #' For `.load_sce()`, a [SingleCellExperiment()] object. @@ -28,66 +29,82 @@ #' #' ## Usage --- #' -#' iSEEindex:::.load_sce(bfc, id, metadata) +#' iSEEindex:::.load_sce(bfc, id, metadata, already_se_object = FALSE) #' -.load_sce <- 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) +#' ## Alternatively, using the runr approach +#' id_tonsil <- "demo_load_sce_tonsil" +#' metadata <- list( +#' uri="runr://HCATonsilData::HCATonsilData(assayType = 'RNA', cellType = 'epithelial')" +#' ) +#' iSEEindex:::.load_sce(bfc, id, metadata, already_se_object = TRUE) +.load_sce <- function(bfc, + id, + metadata, + already_se_object) { + if (!already_se_object) { + 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]] + } + # nocov end + object <- readRDS(object_path) + object <- .convert_to_sce(object) } else { - object_path <- bfc[[bfc_result$rid]] + # if providing directly an SE object, e.g. via data packages... + uri_object <- .metadata_to_object(metadata) + + object <- precache(uri_object, bfc, id) + object <- .convert_to_sce(object) } - # nocov end - object <- readRDS(object_path) - object <- .convert_to_sce(object) object } -#' @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_runr(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 -} +### #' @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 +# } @@ -135,6 +152,11 @@ #' )) #' iSEEindex:::.metadata_to_object(list(uri="s3://your-bucket/your-prefix/file.rds")) #' iSEEindex:::.metadata_to_object(list(uri="s3://your-bucket/your-prefix/file.rds")) +#' iSEEindex:::.metadata_to_object( +#' list( +#' uri="runr://HCATonsilData::HCATonsilData(assayType = 'RNA', cellType = 'epithelial')" +#' ) +#' ) .metadata_to_object <- function(x) { scheme <- urltools::url_parse(x[[.datasets_uri]])$scheme scheme_titled <- str_to_title(scheme) @@ -152,28 +174,6 @@ } -#' @examples -#' iSEEindex:::.metadata_to_object(list(uri="runr://HCATonsilData::HCATonsilData(assayType = 'RNA', cellType = 'epithelial')")) -.metadata_to_object_runr <- function(x) { - scheme <- urltools::url_parse(x[[.datasets_uri]])$scheme - scheme_titled <- str_to_title(scheme) - target_class <- sprintf("iSEEindex%sResource", scheme_titled) - constructor.FUN <- try({ - get(target_class) - }, silent = TRUE) - if (is(constructor.FUN, "try-error")) { - stop( - sprintf("No constructor function available for scheme '%s'. ", scheme), - sprintf("Consider implementing the constructor function '%s()'.", target_class) - ) - } - constructor.FUN(x) -} - - - - - #' Check Validity of Data Sets Metadata #' diff --git a/man/iSEEindex.Rd b/man/iSEEindex.Rd index e1eb505..f3842e3 100644 --- a/man/iSEEindex.Rd +++ b/man/iSEEindex.Rd @@ -12,7 +12,8 @@ iSEEindex( default.position = c("first", "last"), app.title = NULL, body.header = NULL, - body.footer = NULL + body.footer = NULL, + already_se_object = FALSE ) } \arguments{ @@ -39,6 +40,8 @@ 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. @@ -126,17 +129,9 @@ The individual sub-lists may also contain additional optional named metadata spe } \examples{ -## -# BiocFileCache ---- -## - -library(BiocFileCache) +library("BiocFileCache") bfc <- BiocFileCache(cache = tempdir()) -## -# iSEEindex ---- -## - dataset_fun <- function() { x <- yaml::read_yaml(system.file(package = "iSEEindex", "example.yaml")) x$datasets @@ -152,6 +147,54 @@ app <- iSEEindex(bfc, dataset_fun, initial_fun) if (interactive()) { shiny::runApp(app, port = 1234) } + +## Alternatively, with the example based on using runr calls + +dataset_fun_tonsils <- function() { + x <- yaml::read_yaml( + system.file("tonsils_example", "tonsil_package.yml", package = "iSEEindex") + ) + x$datasets +} +initial_fun_tonsils <- 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_tonsils <- iSEEindex(bfc, + dataset_fun_tonsils, + initial_fun_tonsils, + default.add = TRUE, + default.position = "last", + app.title = "iSEE ❤️ Tonsil Data Atlas", + body.header = header_tonsils, + body.footer = footer_tonsils, + already_se_object = TRUE) + +if (interactive()) { + shiny::runApp(app_tonsils, port = 5678) +} } \author{ Kevin Rue-Albrecht diff --git a/tests/testthat/test-observers.R b/tests/testthat/test-observers.R index 4a3c337..8b04357 100644 --- a/tests/testthat/test-observers.R +++ b/tests/testthat/test-observers.R @@ -19,7 +19,7 @@ test_that(".create_launch_observers works", { pObjects <- new.env() FUN <- function(SE, INITIAL) invisible(NULL) - out <- iSEEindex:::.create_launch_observers(FUN, bfc, input, session = NULL, pObjects) + out <- iSEEindex:::.create_launch_observers(FUN, bfc, input, session = NULL, pObjects, already_se_object = FALSE) expect_null(out) }) diff --git a/tests/testthat/test-utils-datasets.R b/tests/testthat/test-utils-datasets.R index 134a791..3a3514c 100644 --- a/tests/testthat/test-utils-datasets.R +++ b/tests/testthat/test-utils-datasets.R @@ -10,7 +10,7 @@ test_that(".load_sce works", { ## Usage --- - out <- iSEEindex:::.load_sce(bfc, id, metadata) + out <- iSEEindex:::.load_sce(bfc, id, metadata, already_se_object = FALSE) expect_s4_class(out, "SummarizedExperiment") }) From dab973b4f579b47a44d607bf2c01cfd70075f5cc Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 2 Oct 2024 21:59:52 +0200 Subject: [PATCH 10/23] going in with a simple heuristics to determine what should happen on the resource passed. path -> prefetch fully and load object -> just load Might be thinking of extra work to have an extra field in the resource class to define this more flexibly, but so far so good? --- R/utils-datasets.R | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/R/utils-datasets.R b/R/utils-datasets.R index 8eced35..cb39123 100644 --- a/R/utils-datasets.R +++ b/R/utils-datasets.R @@ -8,7 +8,6 @@ #' @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? #' #' @return #' For `.load_sce()`, a [SingleCellExperiment()] object. @@ -29,18 +28,28 @@ #' #' ## 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 From 7aecda45e80e43e7d44b56d39e88935e10dbcdf5 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 2 Oct 2024 22:00:32 +0200 Subject: [PATCH 11/23] param `already_se_object` is not required anymore, replaced by the heuristics --- R/iSEEindex.R | 16 +++++----------- R/landing_page.R | 6 ++---- R/observers.R | 5 ++--- man/iSEEindex.Rd | 8 ++------ tests/testthat/test-observers.R | 2 +- tests/testthat/test-utils-datasets.R | 2 +- 6 files changed, 13 insertions(+), 26 deletions(-) diff --git a/R/iSEEindex.R b/R/iSEEindex.R index 597b3d2..547768e 100644 --- a/R/iSEEindex.R +++ b/R/iSEEindex.R @@ -96,7 +96,6 @@ #' 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. #' @@ -168,8 +167,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 +179,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 @@ -201,8 +198,7 @@ iSEEindex <- function(bfc, default.add, default.position, body.header, - body.footer, - already_se_object = already_se_object + body.footer ), appTitle = app.title ) @@ -319,7 +315,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 +326,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 +337,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") diff --git a/R/landing_page.R b/R/landing_page.R index a507561..d8260e9 100644 --- a/R/landing_page.R +++ b/R/landing_page.R @@ -11,7 +11,6 @@ #' 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 +30,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() @@ -103,7 +101,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) diff --git a/R/observers.R b/R/observers.R index 79e4f12..50db35b 100644 --- a/R/observers.R +++ b/R/observers.R @@ -71,16 +71,15 @@ #' @param input TODO #' @param session TODO #' @param pObjects TODO -#' @param already_se_object TODO #' #' @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 diff --git a/man/iSEEindex.Rd b/man/iSEEindex.Rd index f3842e3..cb10796 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,8 +39,6 @@ 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. @@ -189,8 +186,7 @@ app_tonsils <- iSEEindex(bfc, 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) diff --git a/tests/testthat/test-observers.R b/tests/testthat/test-observers.R index 8b04357..4a3c337 100644 --- a/tests/testthat/test-observers.R +++ b/tests/testthat/test-observers.R @@ -19,7 +19,7 @@ test_that(".create_launch_observers works", { pObjects <- new.env() FUN <- function(SE, INITIAL) invisible(NULL) - out <- iSEEindex:::.create_launch_observers(FUN, bfc, input, session = NULL, pObjects, already_se_object = FALSE) + out <- iSEEindex:::.create_launch_observers(FUN, bfc, input, session = NULL, pObjects) expect_null(out) }) diff --git a/tests/testthat/test-utils-datasets.R b/tests/testthat/test-utils-datasets.R index 3a3514c..134a791 100644 --- a/tests/testthat/test-utils-datasets.R +++ b/tests/testthat/test-utils-datasets.R @@ -10,7 +10,7 @@ test_that(".load_sce works", { ## Usage --- - out <- iSEEindex:::.load_sce(bfc, id, metadata, already_se_object = FALSE) + out <- iSEEindex:::.load_sce(bfc, id, metadata) expect_s4_class(out, "SummarizedExperiment") }) From ff5eb34ebfa7e15c6b6e5e35887cc694dde70903 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 2 Oct 2024 22:00:59 +0200 Subject: [PATCH 12/23] adding another yaml, "just for the fun" and for showing a proof of principle that this could simply work --- inst/tonsils_example/tonsil_and_mix.yml | 48 +++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 inst/tonsils_example/tonsil_and_mix.yml 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. From 08cd8fefa2594df9d092d87e761ba35503b56530 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 2 Oct 2024 23:40:42 +0200 Subject: [PATCH 13/23] general cleanup, and polishing a bit what is there so far --- R/iSEEindex.R | 233 ++++++------------------ R/iSEEindexResource-class.R | 122 ++++++++----- R/landing_page.R | 109 ++--------- R/observers.R | 39 ++-- R/outputs.R | 30 +-- R/utils-datasets.R | 58 +----- R/utils-initial.R | 26 ++- man/iSEEindex.Rd | 65 ++++--- man/iSEEindexHttpsResource-class.Rd | 16 +- man/iSEEindexLocalhostResource-class.Rd | 16 +- man/iSEEindexRcallResource-class.Rd | 15 +- man/iSEEindexResource-class.Rd | 12 +- man/iSEEindexResource-generics.Rd | 6 +- man/iSEEindexRunrResource-class.Rd | 13 +- man/iSEEindexS3Resource-class.Rd | 34 ++-- 15 files changed, 317 insertions(+), 477 deletions(-) diff --git a/R/iSEEindex.R b/R/iSEEindex.R index 547768e..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 @@ -97,7 +117,8 @@ #' @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. #' -#' @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 #' @@ -192,107 +213,19 @@ iSEEindex <- function(bfc, } iSEE( - landingPage = .landing_page(bfc, - FUN.datasets, - FUN.initial, - default.add, - default.position, - body.header, - body.footer + 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. #' @@ -386,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 d8260e9..de2b95b 100644 --- a/R/landing_page.R +++ b/R/landing_page.R @@ -1,10 +1,13 @@ #' 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 @@ -39,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 @@ -51,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'))), @@ -115,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 50db35b..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,12 +74,12 @@ #' @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 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 #' @@ -85,17 +94,3 @@ 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 cb39123..8496c40 100644 --- a/R/utils-datasets.R +++ b/R/utils-datasets.R @@ -7,7 +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 metadata Named list of metadata. See individual resource classes for +#' required and optional metadata. #' #' @return #' For `.load_sce()`, a [SingleCellExperiment()] object. @@ -40,8 +41,10 @@ id, metadata) { resource_obj <- .metadata_to_object(metadata) - if (is(resource_obj, "iSEEindexHttpsResource") | is(resource_obj, "iSEEindexLocalhostResource") | - is(resource_obj, "iSEEindexRcallResource") | is(resource_obj, "iSEEindexS3Resource")) { + 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 @@ -74,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 @@ -139,6 +98,7 @@ x } + #' Convert Metadata to Class #' #' @param x Named list of metadata. @@ -183,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/man/iSEEindex.Rd b/man/iSEEindex.Rd index cb10796..3dfaf4e 100644 --- a/man/iSEEindex.Rd +++ b/man/iSEEindex.Rd @@ -41,7 +41,8 @@ info on the versions of the \code{iSEEindex} and \code{iSEE} packages.} \item{body.footer}{UI element to display \emph{below} the main landing page body.} } \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 @@ -50,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{
}}\preformatted{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." ) ) }\if{html}{\out{
}} -The individual sub-lists may also contain optional named metadata specific to individual \code{\linkS4class{iSEEindexResource}} classes (refer to the help page of those classes for details). +The individual sub-lists may also contain optional named metadata specific to +individual \code{\linkS4class{iSEEindexResource}} classes (refer to the help page of +those classes for details). -\strong{Important}: The \code{id} value is used to identify the data set file in the \pkg{BiocFileCache}. -Thus, we recommend using a dedicated \code{BiocFileCache()} for the app, using the \code{BiocFileCache(cache)} argument to specify an on-disk location (directory path) for the dedicated cache. +\strong{Important}: The \code{id} value is used to identify the data set file in the +\pkg{BiocFileCache}. +Thus, we recommend using a dedicated \code{BiocFileCache()} for the app, using the +\code{BiocFileCache(cache)} argument to specify an on-disk location (directory +path) for the dedicated cache. } \section{Initial Configurations}{ -The function passed to the argument \code{FUN.initial} must return a \code{list} that contains metadata about the available initial configurations, or \code{NULL} in the absence of any custom initial configuration (default settings will be applied to all data sets.). +The function passed to the argument \code{FUN.initial} must return a \code{list} that +contains metadata about the available initial configurations, or \code{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: @@ -122,7 +141,9 @@ Example: ) }\if{html}{\out{}} -The individual sub-lists may also contain additional optional named metadata specific to individual \code{\linkS4class{iSEEindexResource}} 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 \code{\linkS4class{iSEEindexResource}} classes (refer to the help +page of those classes for details). } \examples{ diff --git a/man/iSEEindexHttpsResource-class.Rd b/man/iSEEindexHttpsResource-class.Rd index d4f7b8a..2b99573 100644 --- a/man/iSEEindexHttpsResource-class.Rd +++ b/man/iSEEindexHttpsResource-class.Rd @@ -12,7 +12,8 @@ iSEEindexHttpsResource(x) \item{x}{List of metadata. See Details.} } \value{ -The constructor function \code{iSEEindexHttpsResource()} returns an object of object of class \code{iSEEindexHttpsResource}. +The constructor function \code{iSEEindexHttpsResource()} returns an object +of class \code{iSEEindexHttpsResource}. } \description{ The iSEEindexHttpsResource class represents a resource accessible through @@ -28,16 +29,21 @@ Required metadata: } \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. } } diff --git a/man/iSEEindexLocalhostResource-class.Rd b/man/iSEEindexLocalhostResource-class.Rd index ffe097b..154f3f3 100644 --- a/man/iSEEindexLocalhostResource-class.Rd +++ b/man/iSEEindexLocalhostResource-class.Rd @@ -12,7 +12,8 @@ iSEEindexLocalhostResource(x) \item{x}{List of metadata. See Details.} } \value{ -The constructor function \code{iSEEindexLocalhostResource()} returns an object of object of class \code{iSEEindexLocalhostResource}. +The constructor function \code{iSEEindexLocalhostResource()} returns an +object of object of class \code{iSEEindexLocalhostResource}. } \description{ The iSEEindexLocalhostResource class represents a resource accessible through @@ -33,11 +34,15 @@ This class inherits all slots from its parent class \linkS4class{iSEEindexResour \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 \verb{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 \verb{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. } } @@ -47,7 +52,8 @@ Refer to the documentation for each method for more details on the remaining arg Absolute and relative paths are both supported. Absolute paths require an additional \code{/} (forward slash) -following the double forward slash \verb{//} separating the scheme component of the URI. +following the double forward slash \verb{//} separating the scheme component of +the URI. For instance: diff --git a/man/iSEEindexRcallResource-class.Rd b/man/iSEEindexRcallResource-class.Rd index d834044..cbf336f 100644 --- a/man/iSEEindexRcallResource-class.Rd +++ b/man/iSEEindexRcallResource-class.Rd @@ -12,7 +12,8 @@ iSEEindexRcallResource(x) \item{x}{List of metadata. See Details.} } \value{ -The constructor function \code{iSEEindexRcallResource()} returns an object of object of class \code{iSEEindexRcallResource}. +The constructor function \code{iSEEindexRcallResource()} returns an object +of object of class \code{iSEEindexRcallResource}. } \description{ The iSEEindexRcallResource class represents a resource accessible through @@ -23,7 +24,8 @@ A URI for this type of resource uses the prefix \dQuote{rcall://}. 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}{ @@ -39,13 +41,16 @@ For instance: \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 \verb{rcall://} prefix, diff --git a/man/iSEEindexResource-class.Rd b/man/iSEEindexResource-class.Rd index bb2660b..ec2e099 100644 --- a/man/iSEEindexResource-class.Rd +++ b/man/iSEEindexResource-class.Rd @@ -27,7 +27,8 @@ \code{precache()} throws an error if no method is found for the derived class. } \description{ -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}{ @@ -38,11 +39,14 @@ The iSEEindexResource class is a virtual class from which classes of supported r \section{Supported methods}{ -In the following code snippets, \code{x} is an instance of a \code{\linkS4class{iSEEindexResource}} 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 +\code{\linkS4class{iSEEindexResource}} 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. } } diff --git a/man/iSEEindexResource-generics.Rd b/man/iSEEindexResource-generics.Rd index f20a9e7..774d84c 100644 --- a/man/iSEEindexResource-generics.Rd +++ b/man/iSEEindexResource-generics.Rd @@ -18,14 +18,16 @@ precache(x, bfc, id, ...) \item{...}{additional arguments passed to and from other methods.} } \value{ -\code{precache()} returns the file path to the cached copy of a resource fetched from a given URI. +\code{precache()} returns the file path to the cached copy of a resource +fetched from a given URI. } \description{ An overview of the generics for \code{iSEEindexResources} objects. } \section{Preparing and caching resources}{ -\code{precache(x, bfc, id, ...)} retrieves and caches a resource from an URI, caches it, and returns the path to the cached file. +\code{precache(x, bfc, id, ...)} retrieves and caches a resource from an URI, +caches it, and returns the path to the cached file. } \examples{ diff --git a/man/iSEEindexRunrResource-class.Rd b/man/iSEEindexRunrResource-class.Rd index fc0ad6d..ddb8e76 100644 --- a/man/iSEEindexRunrResource-class.Rd +++ b/man/iSEEindexRunrResource-class.Rd @@ -12,7 +12,8 @@ iSEEindexRunrResource(x) \item{x}{List of metadata. See Details.} } \value{ -The constructor function \code{iSEEindexRunrResource()} returns an object of object of class \code{iSEEindexRunrResource}. +The constructor function \code{iSEEindexRunrResource()} returns an object +of object of class \code{iSEEindexRunrResource}. } \description{ The iSEEindexRunrResource class represents an SE object, obtained directly @@ -29,11 +30,15 @@ Required metadata: } \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. } } diff --git a/man/iSEEindexS3Resource-class.Rd b/man/iSEEindexS3Resource-class.Rd index a5686f6..3556fa7 100644 --- a/man/iSEEindexS3Resource-class.Rd +++ b/man/iSEEindexS3Resource-class.Rd @@ -12,7 +12,8 @@ iSEEindexS3Resource(x) \item{x}{List of metadata. See Details.} } \value{ -The constructor function \code{iSEEindexS3Resource()} returns an object of object of class \code{iSEEindexS3Resource}. +The constructor function \code{iSEEindexS3Resource()} returns an object of +object of class \code{iSEEindexS3Resource}. } \description{ The iSEEindexS3Resource class represents a cloud storage resource accessible @@ -30,7 +31,8 @@ Required metadata: } \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{ @@ -40,12 +42,14 @@ Furthermore, this class defines the additional slot(s) below: \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 \verb{s3://} prefix, -parses information encoded in the remainder of the URI, +\item \code{\link{precache}(x, ..., temp_dir = tempdir())} trims the \verb{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. @@ -81,7 +85,8 @@ recursively if it doesn't already exist.} For detailed information, please consult the \href{https://github.com/paws-r/paws/blob/main/docs/credentials.md}{paws R package documentation}. -Currently, you must have the \href{https://aws.amazon.com/cli/}{AWS Command Line Interface} installed to use AWS SSO with \pkg{paws.storage}. +Currently, you must have the \href{https://aws.amazon.com/cli/}{AWS Command Line Interface} +installed to use AWS SSO with \pkg{paws.storage}. A default AWS region can be set in the file \verb{~/.aws/config}. For instance: @@ -90,7 +95,8 @@ For instance: region=eu-west-2 }\if{html}{\out{}} -Optionally, a field named \code{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 \code{region} can be added in the list of resource +metadata to set the AWS S3 region for each individual resource, e.g. \if{html}{\out{
}}\preformatted{- id: ID1 title: ReprocessedAllenData @@ -100,12 +106,16 @@ Optionally, a field named \code{region} can be added in the list of resource met region: eu-west-2 }\if{html}{\out{
}} -Regions set in individual resource metadata override the default AWS region set in \verb{~/.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 \verb{~/.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 \verb{~/.aws/config}, then the region MUST be set in the metadata. +If a default region is NOT set in \verb{~/.aws/config}, then the region MUST be +set in the metadata. -Credentials for all services can be set in the AWS shared credentials file \verb{~/.aws/credentials}. +Credentials for all services can be set in the AWS shared credentials file +\verb{~/.aws/credentials}. For instance: \if{html}{\out{
}}\preformatted{[default] From cc9b964b01bb274f0b5b3a3cb4666f32f7546ee0 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Thu, 3 Oct 2024 00:07:32 +0200 Subject: [PATCH 14/23] expanding the test suite to cover the runr usage --- DESCRIPTION | 1 + .../testthat/test-iSEEindexResources-class.R | 89 ++++++++++++------- tests/testthat/test-utils-datasets.R | 9 ++ 3 files changed, 67 insertions(+), 32 deletions(-) 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/tests/testthat/test-iSEEindexResources-class.R b/tests/testthat/test-iSEEindexResources-class.R index dd22dbf..b8e4551 100644 --- a/tests/testthat/test-iSEEindexResources-class.R +++ b/tests/testthat/test-iSEEindexResources-class.R @@ -1,126 +1,151 @@ test_that("show(iSEEindexResource) works", { - + out <- new("iSEEindexResource", uri = "https://zenodo.org/record/7304331/files/ReprocessedAllenData.rds") expect_output(show(out), "class: iSEEindexResource") - + }) test_that("precache(iSEEindexResource) throws an error", { - + out <- new("iSEEindexResource", uri = "https://zenodo.org/record/7304331/files/ReprocessedAllenData.rds") expect_error(precache(out), "no 'precache' method defined for object of class") - + }) # iSEEindexHttpsResource ---- test_that("iSEEindexS3Resource constructor works", { - + out <- iSEEindexHttpsResource(list( uri = "https://zenodo.org/record/7304331/files/ReprocessedAllenData.rds")) - + expect_identical(out@uri, "https://zenodo.org/record/7304331/files/ReprocessedAllenData.rds") }) test_that("show(iSEEindexHttpsResource) works", { - + out <- new("iSEEindexHttpsResource", uri = "https://zenodo.org/record/7304331/files/ReprocessedAllenData.rds") expect_output(show(out), "class: iSEEindexHttpsResource") - + }) test_that("precache(iSEEindexHttpsResource) returns the original URI", { - + x <- new("iSEEindexHttpsResource", uri = "https://zenodo.org/record/7304331/files/ReprocessedAllenData_config_01.R?download=1") out <- precache(x, bfc, "DUMMY") expect_true(file.exists(out)) - + bfcremove(bfc, names(out)) }) # iSEEindexLocalhostResource ---- test_that("iSEEindexLocalhostResource constructor works", { - + tf <- tempfile() file.create(tf) - + out <- iSEEindexLocalhostResource(list( uri = sprintf("localhost://%s", tf))) - + expect_identical(out@uri, sprintf("localhost://%s", tf)) }) test_that("show(iSEEindexLocalhostResource) works", { - + out <- new("iSEEindexLocalhostResource", uri = "localhost://path/to/file") expect_output(show(out), "class: iSEEindexLocalhostResource") - + }) test_that("precache(iSEEindexLocalhostResource) workls", { - + tf <- tempfile() file.create(tf) - + x <- new("iSEEindexLocalhostResource", uri = sprintf("localhost://%s", tf)) out <- precache(x, bfc, "DUMMY") expect_true(file.exists(out)) - + bfcremove(bfc, names(out)) - + unlink(tf) }) # iSEEindexRcallResource ---- test_that("iSEEindexRcallResource constructor works", { - + out <- iSEEindexRcallResource (list( uri = "rcall://system.file(package='iSEEindex','ReprocessedAllenData_config_01.R')")) - + expect_identical(out@uri, "rcall://system.file(package='iSEEindex','ReprocessedAllenData_config_01.R')") }) test_that("show(iSEEindexRcallResource) works", { - + out <- new("iSEEindexRcallResource", uri = "rcall://system.file(package='iSEEindex','ReprocessedAllenData_config_01.R')") expect_output(show(out), "class: iSEEindexRcallResource") - + }) -test_that("precache(iSEEindexRcallResource) workls", { - +test_that("precache(iSEEindexRcallResource) works", { + x <- new("iSEEindexRcallResource", uri = "rcall://system.file(package='iSEEindex','ReprocessedAllenData_config_01.R')") out <- precache(x, bfc, "DUMMY") expect_true(file.exists(out)) - + bfcremove(bfc, names(out)) }) # iSEEindexS3Resource ---- test_that("iSEEindexS3Resource constructor works", { - + out <- iSEEindexS3Resource(list( uri = "s3://example/path/to/bucket")) - + expect_identical(out@uri, "s3://example/path/to/bucket") expect_identical(out@region, NA_character_) - + out <- iSEEindexS3Resource(list( uri = "s3://example/path/to/bucket", region = "eu-west-2")) - + expect_identical(out@uri, "s3://example/path/to/bucket") expect_identical(out@region, "eu-west-2") }) test_that("show(iSEEindexS3Resource) works", { - + x <- new("iSEEindexS3Resource", uri = "s3://bucket/file.R") expect_output(show(x), "class: iSEEindexS3Resource") - + +}) + + +# iSEEindexS3Resource ---- + +test_that("iSEEindexRunrResource constructor works", { + + out <- iSEEindexRunrResource(list( + uri = "runr://scRNAseq::ReprocessedAllenData()")) + + expect_identical(out@uri, "runr://scRNAseq::ReprocessedAllenData()") +}) + +test_that("show(iSEEindexRunrResource) works", { + + x <- new("iSEEindexRunrResource", uri = "runr://scRNAseq::ReprocessedAllenData()") + expect_output(show(x), "class: iSEEindexRunrResource") + +}) + +test_that("precache(iSEEindexRunrResource) works", { + + x <- new("iSEEindexRunrResource", uri = "runr://scRNAseq::ReprocessedAllenData()") + out <- precache(x, bfc, "DUMMY") + expect_true(is(out, "SingleCellExperiment")) }) diff --git a/tests/testthat/test-utils-datasets.R b/tests/testthat/test-utils-datasets.R index 134a791..79b3a1a 100644 --- a/tests/testthat/test-utils-datasets.R +++ b/tests/testthat/test-utils-datasets.R @@ -13,6 +13,15 @@ test_that(".load_sce works", { out <- iSEEindex:::.load_sce(bfc, id, metadata) expect_s4_class(out, "SummarizedExperiment") + + + # loading directly via runr + id_allen <- "demo_load_sce_tonsil" + metadata_allen <- list( + uri="runr://scRNAseq::ReprocessedAllenData()" + ) + out <- iSEEindex:::.load_sce(bfc, id_allen, metadata_allen) + expect_s4_class(out, "SummarizedExperiment") }) # .convert_to_sce ---- From 34080f9613574f72c67a866f83c08f296bfa2860 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Thu, 3 Oct 2024 00:07:54 +0200 Subject: [PATCH 15/23] Some general information on the runr implementation is provided also in the vignette --- vignettes/resources.Rmd | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/vignettes/resources.Rmd b/vignettes/resources.Rmd index caa1275..1a0f332 100644 --- a/vignettes/resources.Rmd +++ b/vignettes/resources.Rmd @@ -180,6 +180,29 @@ Now, while the scheme `s3` is recognised by the [AWS Command Line Interface][aws In this instance, the `precache()` function has the job to parse the URI for information that is passed to the `r BiocStyle::CRANpkg("paws.storage")` package to download the file, which is then cached using `r Biocpkg("BiocFileCache")`. +## iSEEindexRunrResource + +### Structure + +This type of resource is documented in `help("iSEEindexRunrResource-class")`. + +This class is used to represent directly objects that are generated via a call to arbitrary R code. + +The URI must use the custom scheme "runr", followed by the code itself to be run to obtain the object to explore. + +Example: + +```bash +runr://function_to_call(param1 = "value1", param2 = "value2") +``` + +### Caching + +As this class does not directly specify a path, but rather focus on the object itself, the classical `r Biocpkg("BiocFileCache")`-based caching will not work automatically. + +Nonetheless, since a typical use case would be to host a collection of datasets provided in a data package, chances are that these packages implement some form of `r Biocpkg("BiocFileCache")`-enabled caching. + + # Reproducibility The `r Biocpkg("iSEEindex")` package `r Citep(bib[["iSEEindex"]])` was made possible thanks to: From a2193964b52eb94da47df7a729837d59efd22f48 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Thu, 3 Oct 2024 01:09:51 +0200 Subject: [PATCH 16/23] adding spaces and indenting --- DESCRIPTION | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3e67c5a..1ba0d93 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -6,13 +6,13 @@ Authors@R: c(person("Kevin", "Rue-Albrecht", email = "kevinrue67@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-3899-3872")), - person("Thomas", "Sandmann", email = "tomsing1@gmail.com", + person("Thomas", "Sandmann", email = "tomsing1@gmail.com", role = c("ctb"), comment = c(ORCID = "0000-0002-6601-8890")), - person("Federico", "Marini", email="marinif@uni-mainz.de", - role="aut", + person("Federico", "Marini", email = "marinif@uni-mainz.de", + role = "aut", comment = c(ORCID = '0000-0003-3252-7758')), - person("Denali Therapeutics", role = c("fnd"))) + person("Denali Therapeutics", role = c("fnd"))) Description: This package provides an interface to any collection of data sets within a single iSEE web-application. The main functionality of this package is to define a custom landing page allowing app maintainers to list a custom From 58e82a9b14b681ac286eb27ff8537d2303781015 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Thu, 3 Oct 2024 01:11:50 +0200 Subject: [PATCH 17/23] updated README files --- README.Rmd | 2 ++ README.md | 31 ++++++++++++++++--------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/README.Rmd b/README.Rmd index e39d3c4..bbc5e09 100644 --- a/README.Rmd +++ b/README.Rmd @@ -33,6 +33,7 @@ A number of built-in methods are implemented, providing access to common types o - Local filesystem - HTTPS URIs - Amazon S3 buckets +- Arbitrary R code to load objects directly Each type of resource is identified by the scheme component of its URI. Standard schemes can be used alongside custom-made ones, e.g.: @@ -40,6 +41,7 @@ Standard schemes can be used alongside custom-made ones, e.g.: - `localhost://` for local files. - `https://` for files downloaded over the HTTPS protocol. - `s3://` for files downloaded from Amazon S3 buckets. +- `runr://` to load objects directly via a call to R code The `r Biocpkg("iSEEindex")` framework enables app maintainers to independently define new methods for their own choice of standard and custom-made URI schemes. More information is available in the vignette *Implementing custom iSEEindex resources*. diff --git a/README.md b/README.md index 6ea3b3c..fa94c95 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ coverage](https://codecov.io/gh/iSEE/iSEEindex/branch/main/graph/badge.svg)](htt The goal of -*[iSEEindex](https://bioconductor.org/packages/3.16/iSEEindex)* is to +*[iSEEindex](https://bioconductor.org/packages/3.19/iSEEindex)* is to provide an interface to any collection of data sets, hosted anywhere, within a single iSEE web-application. @@ -32,6 +32,7 @@ types of resources, e.g.: - Local filesystem - HTTPS URIs - Amazon S3 buckets +- Arbitrary R code to load objects directly Each type of resource is identified by the scheme component of its URI. Standard schemes can be used alongside custom-made ones, e.g.: @@ -39,8 +40,9 @@ Standard schemes can be used alongside custom-made ones, e.g.: - `localhost://` for local files. - `https://` for files downloaded over the HTTPS protocol. - `s3://` for files downloaded from Amazon S3 buckets. +- `runr://` to load objects directly via a call to R code -The *[iSEEindex](https://bioconductor.org/packages/3.16/iSEEindex)* +The *[iSEEindex](https://bioconductor.org/packages/3.19/iSEEindex)* framework enables app maintainers to independently define new methods for their own choice of standard and custom-made URI schemes. More information is available in the vignette *Implementing custom iSEEindex @@ -51,7 +53,7 @@ with the predefined choice of data sets and initial configuration states (specific to each data set). After selecting a data set and – optionally – an initial configuration, launching the main app fetches resources from their respective URI and caches them using the -*[BiocFileCache](https://bioconductor.org/packages/3.16/BiocFileCache)* +*[BiocFileCache](https://bioconductor.org/packages/3.19/BiocFileCache)* package. Finally, data sets and configurations are loaded from the cache into the main `iSEE` application, for interactive exploration. @@ -59,7 +61,7 @@ into the main `iSEE` application, for interactive exploration. Get the latest stable `R` release from [CRAN](http://cran.r-project.org/). Then install -*[iSEEindex](https://bioconductor.org/packages/3.16/iSEEindex)* from +*[iSEEindex](https://bioconductor.org/packages/3.19/iSEEindex)* from [Bioconductor](http://bioconductor.org/) using the following code: ``` r @@ -114,26 +116,25 @@ Please run this yourself to check for any updates on how to cite ``` r print(citation('iSEEindex'), bibtex = TRUE) -#> #> To cite package 'iSEEindex' in publications use: #> -#> Rue-Albrecht K (2022). _iSEEindex: iSEE extension for a landing page -#> to a custom collection of data sets_. R package version 0.99.0, -#> . +#> Rue-Albrecht K, Marini F (2024). _iSEEindex: iSEE extension for a +#> landing page to a custom collection of data sets_. R package version +#> 1.3.1, . #> #> A BibTeX entry for LaTeX users is #> #> @Manual{, #> title = {iSEEindex: iSEE extension for a landing page to a custom collection of data sets}, -#> author = {Kevin Rue-Albrecht}, -#> year = {2022}, -#> note = {R package version 0.99.0}, +#> author = {Kevin Rue-Albrecht and Federico Marini}, +#> year = {2024}, +#> note = {R package version 1.3.1}, #> url = {https://github.com/iSEE/iSEEindex}, #> } ``` Please note that the -*[iSEEindex](https://bioconductor.org/packages/3.16/iSEEindex)* was only +*[iSEEindex](https://bioconductor.org/packages/3.19/iSEEindex)* was only made possible thanks to many other R and bioinformatics software authors, which are cited either in the vignettes and/or the paper(s) describing this package. @@ -141,7 +142,7 @@ describing this package. ## Code of Conduct Please note that the -*[iSEEindex](https://bioconductor.org/packages/3.16/iSEEindex)* project +*[iSEEindex](https://bioconductor.org/packages/3.19/iSEEindex)* project is released with a [Contributor Code of Conduct](http://bioconductor.org/about/code-of-conduct/). By contributing to this project, you agree to abide by its terms. @@ -155,7 +156,7 @@ contributing to this project, you agree to abide by its terms. *[rcmdcheck](https://CRAN.R-project.org/package=rcmdcheck)* customized to use [Bioconductor’s docker containers](https://www.bioconductor.org/help/docker/) and - *[BiocCheck](https://bioconductor.org/packages/3.16/BiocCheck)*. + *[BiocCheck](https://bioconductor.org/packages/3.19/BiocCheck)*. - Code coverage assessment is possible thanks to [codecov](https://codecov.io/gh) and *[covr](https://CRAN.R-project.org/package=covr)*. @@ -171,6 +172,6 @@ contributing to this project, you agree to abide by its terms. For more details, check the `dev` directory. This package was developed using -*[biocthis](https://bioconductor.org/packages/3.16/biocthis)*. +*[biocthis](https://bioconductor.org/packages/3.19/biocthis)*. From ce357fc07761dbe75d30b7b85c1691d3f2f2486b Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Thu, 3 Oct 2024 01:12:20 +0200 Subject: [PATCH 18/23] version bump, 1.3.2 --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 1ba0d93..0c54e87 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: iSEEindex Title: iSEE extension for a landing page to a custom collection of data sets -Version: 1.3.1 -Date: 2024-10-01 +Version: 1.3.2 +Date: 2024-10-03 Authors@R: c(person("Kevin", "Rue-Albrecht", email = "kevinrue67@gmail.com", role = c("aut", "cre"), From 5d5d40a0fe0100cd88f1467a28d99008730e14f6 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Thu, 3 Oct 2024 01:14:56 +0200 Subject: [PATCH 19/23] updated news --- NEWS.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NEWS.md b/NEWS.md index a860be4..65395e2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,8 @@ +# iSEEindex 1.3.2 + +* Added a full implementation of the `runr` resource class, defining its behavior with simple heuristics based on the fact that users can now also provide not just a path but the call to the command of R to be run (therefore, the name `runr`) to obtain an object to explore. + A typical use case would be to deploy a collection of datasets from a data package. + # iSEEindex 1.3.1 * Version bump to rebuild classes derived from `DotPlot`. From da3e086770e82455e9f423ce93fdf94ec9f96a65 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Thu, 3 Oct 2024 10:34:56 +0200 Subject: [PATCH 20/23] adding markdown too as dependency (?) --- DESCRIPTION | 1 + 1 file changed, 1 insertion(+) diff --git a/DESCRIPTION b/DESCRIPTION index 0c54e87..d54bcca 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -48,6 +48,7 @@ Suggests: knitr, RefManageR, rmarkdown, + markdown, scRNAseq, sessioninfo, testthat (>= 3.0.0), From 922945941e2dc9eb83df4acb0ee16f2c8237c027 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Fri, 4 Oct 2024 14:09:43 +0200 Subject: [PATCH 21/23] name fixed --- tests/testthat/test-utils-datasets.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-utils-datasets.R b/tests/testthat/test-utils-datasets.R index 79b3a1a..b44672c 100644 --- a/tests/testthat/test-utils-datasets.R +++ b/tests/testthat/test-utils-datasets.R @@ -16,7 +16,7 @@ test_that(".load_sce works", { # loading directly via runr - id_allen <- "demo_load_sce_tonsil" + id_allen <- "demo_load_sce_allen" metadata_allen <- list( uri="runr://scRNAseq::ReprocessedAllenData()" ) From 2e73404e7308e097d8095d66dfa022e4f9d41bbd Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Fri, 4 Oct 2024 14:09:57 +0200 Subject: [PATCH 22/23] added a yaml specific to the mixed set of resources --- inst/mixed_resources.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 inst/mixed_resources.yml diff --git a/inst/mixed_resources.yml b/inst/mixed_resources.yml new file mode 100644 index 0000000..154f2be --- /dev/null +++ b/inst/mixed_resources.yml @@ -0,0 +1,35 @@ +datasets: + - id: ReprocessedAllenData + title: ReprocessedAllenData - via https + 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: | + Buettner ESC Data (copy). + - id: AllenData_runr + title: Allen Data, via runr + uri: runr://scRNAseq::ReprocessedAllenData() + description: | + Allen Data, via runr call +initial: + - 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. From 4a86bd6fac8bf537a48b57afe2e919e4d248f899 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Fri, 4 Oct 2024 14:10:23 +0200 Subject: [PATCH 23/23] expanding a bit on the main example --- R/iSEEindex.R | 29 +++++++++++++++++++++++++++++ man/iSEEindex.Rd | 29 +++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/R/iSEEindex.R b/R/iSEEindex.R index edaba54..4f3148d 100644 --- a/R/iSEEindex.R +++ b/R/iSEEindex.R @@ -193,6 +193,35 @@ #' if (interactive()) { #' shiny::runApp(app_tonsils, port = 5678) #' } +#' +#' +#' ## This example shows that it is possible to mix different types of resources +#' ## Some provide the path, some directly the object +#' +#' dataset_fun_mix <- function() { +#' x <- yaml::read_yaml( +#' system.file("mixed_resources.yml", package = "iSEEindex") +#' ) +#' x$datasets +#' } +#' initial_fun_mix <- function() { +#' x <- yaml::read_yaml( +#' system.file("mixed_resources.yml", package = "iSEEindex") +#' ) +#' x$initial +#' } +#' +#' app_mixed <- iSEEindex(bfc, +#' dataset_fun_mix, +#' initial_fun_mix, +#' default.add = TRUE, +#' default.position = "last", +#' app.title = "iSEE ❤ multiple resource types") +#' +#' if (interactive()) { +#' shiny::runApp(app_mixed, port = 4242) +#' } +#' iSEEindex <- function(bfc, FUN.datasets, FUN.initial = NULL, diff --git a/man/iSEEindex.Rd b/man/iSEEindex.Rd index 3dfaf4e..f70b64b 100644 --- a/man/iSEEindex.Rd +++ b/man/iSEEindex.Rd @@ -212,6 +212,35 @@ app_tonsils <- iSEEindex(bfc, if (interactive()) { shiny::runApp(app_tonsils, port = 5678) } + + +## This example shows that it is possible to mix different types of resources +## Some provide the path, some directly the object + +dataset_fun_mix <- function() { + x <- yaml::read_yaml( + system.file("mixed_resources.yml", package = "iSEEindex") + ) + x$datasets +} +initial_fun_mix <- function() { + x <- yaml::read_yaml( + system.file("mixed_resources.yml", package = "iSEEindex") + ) + x$initial +} + +app_mixed <- iSEEindex(bfc, + dataset_fun_mix, + initial_fun_mix, + default.add = TRUE, + default.position = "last", + app.title = "iSEE ❤ multiple resource types") + +if (interactive()) { + shiny::runApp(app_mixed, port = 4242) +} + } \author{ Kevin Rue-Albrecht