From c96e3813ef7be00b94261592e3b2fe2c332dd9b3 Mon Sep 17 00:00:00 2001 From: Kevin Rue-Albrecht Date: Tue, 3 Sep 2024 16:17:36 +0100 Subject: [PATCH 01/14] textOutput works --- NAMESPACE | 10 ++ R/panel_SampleIdentificationCenter.R | 195 ++++++++---------------- man/SampleIdentificationCenter-class.Rd | 6 +- 3 files changed, 78 insertions(+), 133 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 65c400a..eeb8785 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,8 +2,13 @@ export(SampleIdentificationCenter) exportClasses(SampleIdentificationCenter) +exportMethods(.createObservers) +exportMethods(.defineOutput) +exportMethods(.definePanelTour) exportMethods(.fullName) +exportMethods(.generateOutput) exportMethods(.panelColor) +exportMethods(.renderOutput) exportMethods(initialize) import(SummarizedExperiment) import(iSEE) @@ -13,6 +18,11 @@ importClassesFrom(iSEE,ColumnTable) importFrom(iSEE,.emptyDefault) importFrom(methods,callNextMethod) importFrom(methods,new) +importFrom(shiny,nearPoints) +importFrom(shiny,renderPlot) +importFrom(shiny,renderUI) +importFrom(shiny,tagList) +importFrom(shiny,wellPanel) importFrom(shinyAce,aceEditor) importMethodsFrom(iSEE,.fullName) importMethodsFrom(iSEE,.panelColor) diff --git a/R/panel_SampleIdentificationCenter.R b/R/panel_SampleIdentificationCenter.R index 64ed395..6b3564f 100644 --- a/R/panel_SampleIdentificationCenter.R +++ b/R/panel_SampleIdentificationCenter.R @@ -20,6 +20,7 @@ #' #' #' @examples +#' library(iSEE) #' library(scRNAseq) #' #' # Example data ---- @@ -39,7 +40,10 @@ #' if (interactive()) { #' iSEE(sce, initial=list( #' ReducedDimensionPlot(), -#' SampleIdentificationCenter()) +#' SampleIdentificationCenter( +#' ColumnSelectionSource = "ReducedDimensionPlot1" +#' ) +#' ) #' ) #' } #' @@ -50,19 +54,20 @@ #' @name SampleIdentificationCenter-class NULL +# Constants ----- + +.editor_suffix <- "_editor" + # Definition ------------------------------------------------------------------- collated <- character(0) -.plotBinResolution <- "Content" -collated[.plotBinResolution] <- "numeric" - #' @export #' @importClassesFrom iSEE ColumnTable ColumnDataTable #' @import SummarizedExperiment #' @importFrom shinyAce aceEditor setClass("SampleIdentificationCenter", - contains = "ColumnDataTable" , + contains = "Panel" , slots = collated ) @@ -89,68 +94,12 @@ setMethod(".panelColor", "SampleIdentificationCenter", function(x) "#00C4DA") setMethod("initialize", "SampleIdentificationCenter", function(.Object, ...) { args <- list(...) - # args <- .emptyDefault(args, .plotBinResolution, 100) - # args[["Downsample"]] <- FALSE - do.call(callNextMethod, c(list(.Object), args)) }) # Interface -------------------------------------------------------------------- -#' @export -#' @importFrom shiny tagList -setMethod(".defineDataInterface", "SampleIdentificationCenter", function(x) { - panel_name <- .getEncodedName(x) - - .addSpecificTour(class(x), .plotBinResolution, function(panel_name) { - data.frame( - element=paste0("#", panel_name, "_", .plotBinResolution), - intro="Here, we can change the bin size of the plot. -Larger values will result in larger bins, sacrificing resolution for more stable counts. -One should avoid setting this too low as then the plot just collapses to showing each point as a separate bin." - ) - }) - - tagList( - .numericInput.iSEE(x, .plotBinResolution, label="Bin resolution:", - min=1, value=x[[.plotBinResolution]], step = 1) - ) - - -}) - -#' #' @export -#' #' @importFrom shiny tagList -#' setMethod(".defineInterface", "SampleIdentificationCenter", function(x) { -#' plot_name <- .getEncodedName(x) -#' -#' .addSpecificTour(class(x), .plotBinResolution, function(plot_name) { -#' data.frame( -#' element=paste0("#", plot_name, "_", .plotBinResolution), -#' intro="Here, we can change the bin size of the plot. -#' Larger values will result in larger bins, sacrificing resolution for more stable counts. -#' One should avoid setting this too low as then the plot just collapses to showing each point as a separate bin." -#' ) -#' }) -#' -#' tagList( -#' .numericInput.iSEE(x, .plotBinResolution, label="Bin resolution:", -#' min=1, value=x[[.plotBinResolution]], step = 1) -#' ) -#' }) - -#' #' @export -#' setMethod(".allowableColorByDataChoices", "SampleIdentificationCenter", function(x, se) { -#' .getCachedCommonInfo(se, "ColumnDotPlot")$continuous.colData.names -#' }) - - - -#' @export -setMethod(".defineDataInterface", "SampleIdentificationCenter", function(x) { - NULL -}) # Observers -------------------------------------------------------------------- @@ -161,10 +110,6 @@ setMethod(".createObservers", "SampleIdentificationCenter", function(x, se, inpu panel_name <- .getEncodedName(x) - .createProtectedParameterObservers(panel_name, - fields=c(.plotBinResolution), - input=input, pObjects=pObjects, rObjects=rObjects) - invisible(NULL) }) @@ -173,83 +118,69 @@ setMethod(".createObservers", "SampleIdentificationCenter", function(x, se, inpu #' @export #' @importFrom shiny tagList -setMethod(".defineOutput", "SampleIdentificationCenter", function(x) { +setMethod(".generateOutput", "SampleIdentificationCenter", function(x, se, all_memory, all_contents) { + print(".generateOutput-SampleIdentificationCenter") panel_name <- .getEncodedName(x) - - id_editor <- paste0(panel_name, "_editor") - id_rationale <- paste0(panel_name, "_rationale") - id_copypaste <- paste0(panel_name, "_copypaste") - id_commander <- paste0(panel_name, "_commander") - - .addSpecificTour(class(x), "editor", function(panel_name) { - data.frame( - element=paste0("#", panel_name, "_editor"), - intro="editor context help." - ) - }) - - .addSpecificTour(class(x), "rationale", function(panel_name) { - data.frame( - element=paste0("#", panel_name, "_rationale"), - intro="rationale context help." - ) - }) - - .addSpecificTour(class(x), "copypaste", function(panel_name) { - data.frame( - element=paste0("#", panel_name, "_copypaste"), - intro="_copypaste context help." - ) - }) - - .addSpecificTour(class(x), "commander", function(panel_name) { - data.frame( - element=paste0("#", panel_name, "_commander"), - intro="_commander context help." - ) - }) + + all_cmds <- list() + + panel_env <- new.env() + panel_env$se <- se + + all_cmds$select <- .processMultiSelections(x, all_memory, all_contents, panel_env) + print(all_cmds) + .textEval(all_cmds, panel_env) + print(ls(panel_env)) + + selected_names <- panel_env$col_selected[["active"]] + print(selected_names) + + list( + commands=all_cmds, + contents=selected_names, + varname="varname_SampleIdentificationCenter") +}) +#' @export +#' @importFrom shiny tagList +setMethod(".defineOutput", "SampleIdentificationCenter", function(x) { + print(".defineOutput-SampleIdentificationCenter") + panel_name <- .getEncodedName(x) + + print(x) + tagList( - span(id = paste0(id_editor, "_specific_help"), - style="display:inline-block; padding-bottom:5px;", - HTML("Selected cells: ?")), - aceEditor(id_editor, - mode="markdown", - theme="xcode", - autoComplete="disabled", - value=slot(x, "Content"), - debounce=1000, - height="500px" - ), - - span(id = paste0(id_rationale, "_specific_help"), - style="display:inline-block; padding-bottom:5px;", - HTML("Specify the rationale for the selection: ?")), - textInput(id_rationale, label = "", - placeholder = "Tell me why"), - - span(id = paste0(id_copypaste, "_specific_help"), - style="display:inline-block; padding-bottom:5px;", - HTML("Copy to clipboard ?")), - br(), - actionButton(id_copypaste, label = "Copy to clipboard", icon = icon("copy")), - br(), - - span(id = paste0(id_commander, "_specific_help"), - style="display:inline-block; padding-bottom:5px;", - HTML("Generate the full command: ?")), - br(), - actionButton(id_commander, label = "Create command!", icon = icon("magic")), - hr() - + textOutput(panel_name) ) }) +#' @export +#' @importFrom shiny renderPlot tagList wellPanel nearPoints renderUI +setMethod(".renderOutput", "SampleIdentificationCenter", function(x, se, output, pObjects, rObjects) { + print(".renderOutput-SampleIdentificationCenter") + panel_name <- .getEncodedName(x) + force(se) # defensive programming to avoid difficult bugs due to delayed evaluation. + + # nocov start + output[[panel_name]] <- renderText({ + paste0(.retrieveOutput(panel_name, se, pObjects, rObjects)$contents, collapse = "\n") + }) + # nocov end + + callNextMethod() +}) +# Transmission ------- - +#' @export +setMethods(".multiSelectionResponsive", "SampleIdentificationCenter", function(x, dims = character(0)){ + if ("column" %in% dims) { + return(TRUE) + } + return(FALSE) +}) # Tour definition --------------------------------------------------------- diff --git a/man/SampleIdentificationCenter-class.Rd b/man/SampleIdentificationCenter-class.Rd index 735cea1..6328224 100644 --- a/man/SampleIdentificationCenter-class.Rd +++ b/man/SampleIdentificationCenter-class.Rd @@ -29,6 +29,7 @@ In the following code snippets, \code{x} is an instance of a } \examples{ +library(iSEE) library(scRNAseq) # Example data ---- @@ -48,7 +49,10 @@ rowData(sce)$n_cells <- rowSums(assay(sce, "tophat_counts") > 0) if (interactive()) { iSEE(sce, initial=list( ReducedDimensionPlot(), - SampleIdentificationCenter()) + SampleIdentificationCenter( + ColumnSelectionSource = "ReducedDimensionPlot1" + ) + ) ) } From f094bb3ca282edb80a27ad05cb5231d0ac608c1f Mon Sep 17 00:00:00 2001 From: Kevin Rue-Albrecht Date: Tue, 3 Sep 2024 16:41:56 +0100 Subject: [PATCH 02/14] aceditor working --- R/panel_SampleIdentificationCenter.R | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/R/panel_SampleIdentificationCenter.R b/R/panel_SampleIdentificationCenter.R index 6b3564f..0df79a6 100644 --- a/R/panel_SampleIdentificationCenter.R +++ b/R/panel_SampleIdentificationCenter.R @@ -56,8 +56,6 @@ NULL # Constants ----- -.editor_suffix <- "_editor" - # Definition ------------------------------------------------------------------- collated <- character(0) @@ -137,8 +135,13 @@ setMethod(".generateOutput", "SampleIdentificationCenter", function(x, se, all_m list( commands=all_cmds, - contents=selected_names, - varname="varname_SampleIdentificationCenter") + contents=aceEditor( + panel_name, + mode="r", + theme="solarized_light", + value=paste0(selected_names, collapse = "\n"), + height=paste0(slot(x, .organizationHeight), "px")), + varname=panel_name) }) @@ -151,7 +154,7 @@ setMethod(".defineOutput", "SampleIdentificationCenter", function(x) { print(x) tagList( - textOutput(panel_name) + uiOutput(panel_name) ) }) @@ -164,8 +167,8 @@ setMethod(".renderOutput", "SampleIdentificationCenter", function(x, se, output, force(se) # defensive programming to avoid difficult bugs due to delayed evaluation. # nocov start - output[[panel_name]] <- renderText({ - paste0(.retrieveOutput(panel_name, se, pObjects, rObjects)$contents, collapse = "\n") + output[[panel_name]] <- renderUI({ + .retrieveOutput(panel_name, se, pObjects, rObjects)$contents }) # nocov end From b948b01bc10f8a16d68c93632f6a854fdcf3d81e Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 4 Sep 2024 11:09:33 +0200 Subject: [PATCH 03/14] fixing namespace imports --- DESCRIPTION | 3 ++- NAMESPACE | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 82eab40..bcdb35d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -12,10 +12,11 @@ Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.3.2 Depends: + iSEE, SummarizedExperiment Imports: - iSEE, methods, + shiny, shinyAce Suggests: scRNAseq, diff --git a/NAMESPACE b/NAMESPACE index eeb8785..e254d09 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -15,6 +15,7 @@ import(iSEE) import(methods) importClassesFrom(iSEE,ColumnDataTable) importClassesFrom(iSEE,ColumnTable) +importClassesFrom(iSEE,Panel) importFrom(iSEE,.emptyDefault) importFrom(methods,callNextMethod) importFrom(methods,new) @@ -22,6 +23,7 @@ importFrom(shiny,nearPoints) importFrom(shiny,renderPlot) importFrom(shiny,renderUI) importFrom(shiny,tagList) +importFrom(shiny,uiOutput) importFrom(shiny,wellPanel) importFrom(shinyAce,aceEditor) importMethodsFrom(iSEE,.fullName) From 4fa083109e11cf7f0969523edc08913eb94ae871 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 4 Sep 2024 11:09:52 +0200 Subject: [PATCH 04/14] adding aliases for the methods --- R/panel_SampleIdentificationCenter.R | 34 +++++++++++++++++-------- man/SampleIdentificationCenter-class.Rd | 10 ++++++++ 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/R/panel_SampleIdentificationCenter.R b/R/panel_SampleIdentificationCenter.R index 0df79a6..8686dbb 100644 --- a/R/panel_SampleIdentificationCenter.R +++ b/R/panel_SampleIdentificationCenter.R @@ -18,6 +18,18 @@ #' In the following code snippets, `x` is an instance of a #' [SampleIdentificationCenter-class] class. #' +#' @docType methods +#' +#' @aliases +#' SampleIdentificationCenter SampleIdentificationCenter-class +#' .createObservers,SampleIdentificationCenter-method +#' .defineOutput,SampleIdentificationCenter-method +#' .definePanelTour,SampleIdentificationCenter-method +#' .fullName,SampleIdentificationCenter-method +#' .generateOutput,SampleIdentificationCenter-method +#' .panelColor,SampleIdentificationCenter-method +#' .renderOutput,SampleIdentificationCenter-method +#' initialize,SampleIdentificationCenter-method #' #' @examples #' library(iSEE) @@ -61,7 +73,7 @@ NULL collated <- character(0) #' @export -#' @importClassesFrom iSEE ColumnTable ColumnDataTable +#' @importClassesFrom iSEE ColumnTable ColumnDataTable Panel #' @import SummarizedExperiment #' @importFrom shinyAce aceEditor setClass("SampleIdentificationCenter", @@ -115,24 +127,24 @@ setMethod(".createObservers", "SampleIdentificationCenter", function(x, se, inpu # Panel output ----------------------------------------------------------------- #' @export -#' @importFrom shiny tagList +#' @importFrom shiny tagList uiOutput setMethod(".generateOutput", "SampleIdentificationCenter", function(x, se, all_memory, all_contents) { print(".generateOutput-SampleIdentificationCenter") panel_name <- .getEncodedName(x) - + all_cmds <- list() - + panel_env <- new.env() panel_env$se <- se - + all_cmds$select <- .processMultiSelections(x, all_memory, all_contents, panel_env) print(all_cmds) .textEval(all_cmds, panel_env) print(ls(panel_env)) - + selected_names <- panel_env$col_selected[["active"]] print(selected_names) - + list( commands=all_cmds, contents=aceEditor( @@ -150,9 +162,9 @@ setMethod(".generateOutput", "SampleIdentificationCenter", function(x, se, all_m setMethod(".defineOutput", "SampleIdentificationCenter", function(x) { print(".defineOutput-SampleIdentificationCenter") panel_name <- .getEncodedName(x) - + print(x) - + tagList( uiOutput(panel_name) ) @@ -165,13 +177,13 @@ setMethod(".renderOutput", "SampleIdentificationCenter", function(x, se, output, print(".renderOutput-SampleIdentificationCenter") panel_name <- .getEncodedName(x) force(se) # defensive programming to avoid difficult bugs due to delayed evaluation. - + # nocov start output[[panel_name]] <- renderUI({ .retrieveOutput(panel_name, se, pObjects, rObjects)$contents }) # nocov end - + callNextMethod() }) diff --git a/man/SampleIdentificationCenter-class.Rd b/man/SampleIdentificationCenter-class.Rd index 6328224..220a88c 100644 --- a/man/SampleIdentificationCenter-class.Rd +++ b/man/SampleIdentificationCenter-class.Rd @@ -1,7 +1,17 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/panel_SampleIdentificationCenter.R +\docType{methods} \name{SampleIdentificationCenter-class} \alias{SampleIdentificationCenter-class} +\alias{SampleIdentificationCenter} +\alias{.createObservers,SampleIdentificationCenter-method} +\alias{.defineOutput,SampleIdentificationCenter-method} +\alias{.definePanelTour,SampleIdentificationCenter-method} +\alias{.fullName,SampleIdentificationCenter-method} +\alias{.generateOutput,SampleIdentificationCenter-method} +\alias{.panelColor,SampleIdentificationCenter-method} +\alias{.renderOutput,SampleIdentificationCenter-method} +\alias{initialize,SampleIdentificationCenter-method} \title{The SampleIdentificationCenter class} \description{ The SampleIdentificationCenter is a \linkS4class{ColumnDataTable} subclass that is dedicated From dac6662cd1603dec0060fcddf3f8f7fda3f07721 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 4 Sep 2024 12:37:23 +0200 Subject: [PATCH 05/14] noting down some possible next half-obvious to do items --- R/panel_SampleIdentificationCenter.R | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/R/panel_SampleIdentificationCenter.R b/R/panel_SampleIdentificationCenter.R index 8686dbb..d22194e 100644 --- a/R/panel_SampleIdentificationCenter.R +++ b/R/panel_SampleIdentificationCenter.R @@ -66,7 +66,7 @@ #' @name SampleIdentificationCenter-class NULL -# Constants ----- +# Constants -------------------------------------------------------------------- # Definition ------------------------------------------------------------------- @@ -110,6 +110,11 @@ setMethod("initialize", "SampleIdentificationCenter", function(.Object, ...) { # Interface -------------------------------------------------------------------- +# TODO - placeholder + +## Idea: have a radio button/checkbox to control what the editor can give +## Idea: have a textInput where to record the reason why one would select those cells +## These elements could just "refine" the behavior of the content returned by the text editor # Observers -------------------------------------------------------------------- @@ -187,7 +192,7 @@ setMethod(".renderOutput", "SampleIdentificationCenter", function(x, se, output, callNextMethod() }) -# Transmission ------- +# Transmission ----------------------------------------------------------------- #' @export setMethods(".multiSelectionResponsive", "SampleIdentificationCenter", function(x, dims = character(0)){ @@ -197,7 +202,7 @@ setMethods(".multiSelectionResponsive", "SampleIdentificationCenter", function(x return(FALSE) }) -# Tour definition --------------------------------------------------------- +# Tour definition -------------------------------------------------------------- #' @export setMethod(".definePanelTour", "SampleIdentificationCenter", function(x) { From aafe4003cb45434c20cd30dbc789a1408b898a76 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 4 Sep 2024 12:40:33 +0200 Subject: [PATCH 06/14] setting up GHA --- .github/workflows/R-CMD-check.yaml | 321 +++++++++++++++++++++++++++++ 1 file changed, 321 insertions(+) create mode 100644 .github/workflows/R-CMD-check.yaml diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml new file mode 100644 index 0000000..65a51f9 --- /dev/null +++ b/.github/workflows/R-CMD-check.yaml @@ -0,0 +1,321 @@ +## Read more about GitHub actions the features of this GitHub Actions workflow +## at https://lcolladotor.github.io/biocthis/articles/biocthis.html#use_bioc_github_action +## +## For more details, check the biocthis developer notes vignette at +## https://lcolladotor.github.io/biocthis/articles/biocthis_dev_notes.html +## +## You can add this workflow to other packages using: +## > biocthis::use_bioc_github_action() +## +## Using GitHub Actions exposes you to many details about how R packages are +## compiled and installed in several operating system.s +### If you need help, please follow the steps listed at +## https://github.com/r-lib/actions#where-to-find-help +## +## If you found an issue specific to biocthis's GHA workflow, please report it +## with the information that will make it easier for others to help you. +## Thank you! + +## Acronyms: +## * GHA: GitHub Action +## * OS: operating system + +on: + push: + pull_request: + +name: R-CMD-check-bioc + +## These environment variables control whether to run GHA code later on that is +## specific to testthat, covr, and pkgdown. +## +## If you need to clear the cache of packages, update the number inside +## cache-version as discussed at https://github.com/r-lib/actions/issues/86. +## Note that you can always run a GHA test without the cache by using the word +## "/nocache" in the commit message. +env: + has_testthat: 'true' + run_covr: 'true' + run_pkgdown: 'true' + has_RUnit: 'false' + cache-version: 'cache-v1' + run_docker: 'false' + +jobs: + build-check: + runs-on: ${{ matrix.config.os }} + name: ${{ matrix.config.os }} (${{ matrix.config.r }}) + container: ${{ matrix.config.cont }} + ## Environment variables unique to this job. + + strategy: + fail-fast: false + matrix: + config: + - { os: ubuntu-latest, r: 'devel', bioc: '3.20', cont: "bioconductor/bioconductor_docker:devel", rspm: "https://packagemanager.rstudio.com/cran/__linux__/jammy/latest" } + - { os: macOS-latest, r: 'devel', bioc: '3.20'} + - { os: windows-latest, r: 'devel', bioc: '3.20'} + ## Check https://github.com/r-lib/actions/tree/master/examples + ## for examples using the http-user-agent + env: + R_REMOTES_NO_ERRORS_FROM_WARNINGS: true + RSPM: ${{ matrix.config.rspm }} + NOT_CRAN: true + TZ: UTC + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + + steps: + + ## Set the R library to the directory matching the + ## R packages cache step further below when running on Docker (Linux). + - name: Set R Library home on Linux + if: runner.os == 'Linux' + run: | + mkdir /__w/_temp/Library + echo ".libPaths('/__w/_temp/Library')" > ~/.Rprofile + + ## Most of these steps are the same as the ones in + ## https://github.com/r-lib/actions/blob/master/examples/check-standard.yaml + ## If they update their steps, we will also need to update ours. + - name: Checkout Repository + uses: actions/checkout@v3 + + ## R is already included in the Bioconductor docker images + - name: Setup R from r-lib + if: runner.os != 'Linux' + uses: r-lib/actions/setup-r@v2 + with: + r-version: ${{ matrix.config.r }} + http-user-agent: ${{ matrix.config.http-user-agent }} + + ## pandoc is already included in the Bioconductor docker images + - name: Setup pandoc from r-lib + if: runner.os != 'Linux' + uses: r-lib/actions/setup-pandoc@v2 + + - name: Query dependencies + run: | + install.packages('remotes') + saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) + shell: Rscript {0} + + - name: Restore R package cache + if: "!contains(github.event.head_commit.message, '/nocache') && runner.os != 'Linux'" + uses: actions/cache@v3 + with: + path: ${{ env.R_LIBS_USER }} + key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-devel-r-devel-${{ hashFiles('.github/depends.Rds') }} + restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-devel-r-devel- + + - name: Cache R packages on Linux + if: "!contains(github.event.head_commit.message, '/nocache') && runner.os == 'Linux' " + uses: actions/cache@v3 + with: + path: /home/runner/work/_temp/Library + key: ${{ env.cache-version }}-${{ runner.os }}-biocversion-devel-r-devel-${{ hashFiles('.github/depends.Rds') }} + restore-keys: ${{ env.cache-version }}-${{ runner.os }}-biocversion-devel-r-devel- + + - name: Install Linux system dependencies + if: runner.os == 'Linux' + run: | + sysreqs=$(Rscript -e 'cat("apt-get update -y && apt-get install -y", paste(gsub("apt-get install -y ", "", remotes::system_requirements("ubuntu", "20.04")), collapse = " "))') + echo $sysreqs + sudo -s eval "$sysreqs" + + - name: Install macOS system dependencies + if: matrix.config.os == 'macOS-latest' + run: | + ## Enable installing XML from source if needed + brew install libxml2 + echo "XML_CONFIG=/opt/homebrew/opt/libxml2/bin/xml2-config" >> $GITHUB_ENV + + ## Required to install magick as noted at + ## https://github.com/r-lib/usethis/commit/f1f1e0d10c1ebc75fd4c18fa7e2de4551fd9978f#diff-9bfee71065492f63457918efcd912cf2 + brew install imagemagick@6 + + ## For textshaping, required by ragg, and required by pkgdown + brew install harfbuzz fribidi + + ## For installing usethis's dependency gert + brew install libgit2 + + ## Required for tcltk + brew install xquartz --cask + + ## Required for terra + brew install gdal + + ## Temporary fix for freetype (https://github.com/r-lib/ragg/issues/170; Sep 2024) + #brew install --cask https://raw.githubusercontent.com/Homebrew/homebrew-core/d28afc3bfdb5d24eab02157bfffcc9e17ed6666c/Formula/f/freetype.rb + brew unlink freetype + curl -L https://raw.githubusercontent.com/Homebrew/homebrew-core/3db6dc6c4baf5a75e345f380cc4e8224c1ae5ae0/Formula/f/freetype.rb > freetype.rb && brew install freetype.rb + + - name: Install binary units for macOS + if: matrix.config.os == 'macOS-latest' + run: | + ## temporary fix due to issue in udunits (Sep 2024) + install.packages('https://cran.rstudio.com/bin/macosx/big-sur-arm64/contrib/4.4/units_0.8-5.tgz') + shell: Rscript {0} + + - name: Install Windows system dependencies + if: runner.os == 'Windows' + run: | + ## Edit below if you have any Windows system dependencies + shell: Rscript {0} + + - name: Install BiocManager + run: | + message(paste('****', Sys.time(), 'installing BiocManager ****')) + remotes::install_cran("BiocManager") + shell: Rscript {0} + + - name: Set BiocVersion + run: | + BiocManager::install(version = "${{ matrix.config.bioc }}", ask = FALSE, force = TRUE) + shell: Rscript {0} + + - name: Install dependencies pass 1 + run: | + ## Try installing the package dependencies in steps. First the local + ## dependencies, then any remaining dependencies to avoid the + ## issues described at + ## https://stat.ethz.ch/pipermail/bioc-devel/2020-April/016675.html + ## https://github.com/r-lib/remotes/issues/296 + ## Ideally, all dependencies should get installed in the first pass. + + ## Set the repos source depending on the OS + ## Alternatively use https://storage.googleapis.com/bioconductor_docker/packages/ + ## though based on https://bit.ly/bioc2021-package-binaries + ## the Azure link will be the main one going forward. + gha_repos <- if( + .Platform$OS.type == "unix" && Sys.info()["sysname"] != "Darwin" + ) c( + "AnVIL" = "https://bioconductordocker.blob.core.windows.net/packages/3.20/bioc", + BiocManager::repositories() + ) else BiocManager::repositories() + + ## For running the checks + message(paste('****', Sys.time(), 'installing rcmdcheck and BiocCheck ****')) + install.packages(c("rcmdcheck", "BiocCheck"), repos = gha_repos) + + ## Pass #1 at installing dependencies + ## This pass uses AnVIL-powered fast binaries + ## details at https://github.com/nturaga/bioc2021-bioconductor-binaries + ## The speed gains only apply to the docker builds. + message(paste('****', Sys.time(), 'pass number 1 at installing dependencies: local dependencies ****')) + remotes::install_local(dependencies = TRUE, repos = gha_repos, build_vignettes = FALSE, upgrade = TRUE) + continue-on-error: true + shell: Rscript {0} + + - name: Install dependencies pass 2 + run: | + ## Pass #2 at installing dependencies + ## This pass does not use AnVIL and will thus update any packages + ## that have seen been updated in Bioconductor + message(paste('****', Sys.time(), 'pass number 2 at installing dependencies: any remaining dependencies ****')) + remotes::install_local(dependencies = TRUE, repos = BiocManager::repositories(), build_vignettes = TRUE, upgrade = TRUE, force = TRUE) + shell: Rscript {0} + + - name: Install BiocGenerics + if: env.has_RUnit == 'true' + run: | + ## Install BiocGenerics + BiocManager::install("BiocGenerics") + shell: Rscript {0} + + - name: Install covr + if: github.ref == 'refs/heads/devel' && env.run_covr == 'true' && runner.os == 'Linux' + run: | + remotes::install_cran("covr") + shell: Rscript {0} + + - name: Install pkgdown + if: github.ref == 'refs/heads/devel' && env.run_pkgdown == 'true' && runner.os == 'Linux' + run: | + remotes::install_cran("pkgdown") + shell: Rscript {0} + + - name: Session info + run: | + options(width = 100) + pkgs <- installed.packages()[, "Package"] + sessioninfo::session_info(pkgs, include_base = TRUE) + shell: Rscript {0} + + - name: Run CMD check + env: + _R_CHECK_CRAN_INCOMING_: false + DISPLAY: 99.0 + run: | + options(crayon.enabled = TRUE) + rcmdcheck::rcmdcheck( + args = c("--no-manual", "--no-vignettes", "--timings"), + build_args = c("--no-manual", "--keep-empty-dirs", "--no-resave-data"), + error_on = "warning", + check_dir = "check" + ) + shell: Rscript {0} + + ## Might need an to add this to the if: && runner.os == 'Linux' + - name: Reveal testthat details + if: env.has_testthat == 'true' + run: find . -name testthat.Rout -exec cat '{}' ';' + + - name: Run RUnit tests + if: env.has_RUnit == 'true' + run: | + BiocGenerics:::testPackage() + shell: Rscript {0} + + - name: Run BiocCheck + env: + DISPLAY: 99.0 + run: | + BiocCheck::BiocCheck( + dir('check', 'tar.gz$', full.names = TRUE), + `quit-with-status` = FALSE, + `no-check-R-ver` = TRUE, + `no-check-bioc-help` = TRUE + ) + shell: Rscript {0} + + - name: Test coverage + if: github.ref == 'refs/heads/devel' && env.run_covr == 'true' && runner.os == 'Linux' + run: | + covr::codecov() + shell: Rscript {0} + + - name: Install package + if: github.ref == 'refs/heads/devel' && env.run_pkgdown == 'true' && runner.os == 'Linux' + run: R CMD INSTALL . + + - name: Build and deploy pkgdown site + if: github.ref == 'refs/heads/devel' && env.run_pkgdown == 'true' && runner.os == 'Linux' + run: | + git config --global user.name "$GITHUB_ACTOR" + git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com" + git config --global --add safe.directory /__w/iSEE/iSEEhex + Rscript -e "pkgdown::deploy_to_branch(new_process = FALSE)" + shell: bash {0} + ## Note that you need to run pkgdown::deploy_to_branch(new_process = FALSE) + ## at least one locally before this will work. This creates the gh-pages + ## branch (erasing anything you haven't version controlled!) and + ## makes the git history recognizable by pkgdown. + + - name: Upload check results + if: failure() + uses: actions/upload-artifact@master + with: + name: ${{ runner.os }}-biocversion-devel-r-devel-results + path: check + + - uses: docker/build-push-action@v1 + if: "!contains(github.event.head_commit.message, '/nodocker') && env.run_docker == 'true' && runner.os == 'Linux' " + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + repository: isee/iseehex + tag_with_ref: true + tag_with_sha: true + tags: latest From 449cf9b8e15bdbab2181e6833cde4d97a0f99f0c Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 4 Sep 2024 12:40:49 +0200 Subject: [PATCH 07/14] GHA badge added in the meanwhile --- README.Rmd | 1 + README.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/README.Rmd b/README.Rmd index 7975903..5f01021 100644 --- a/README.Rmd +++ b/README.Rmd @@ -17,6 +17,7 @@ knitr::opts_chunk$set( # iSEEid +[![R-CMD-check-bioc](https://github.com/iSEE/iSEEid/actions/workflows/R-CMD-check-bioc.yaml/badge.svg)](https://github.com/iSEE/iSEEid/actions/workflows/R-CMD-check-bioc.yaml) The goal of iSEEid is to use `iSEE` to `id`entify cells diff --git a/README.md b/README.md index b0eefda..11ce999 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ # iSEEid + +[![R-CMD-check-bioc](https://github.com/iSEE/iSEEid/actions/workflows/R-CMD-check-bioc.yaml/badge.svg)](https://github.com/iSEE/iSEEid/actions/workflows/R-CMD-check-bioc.yaml) The goal of iSEEid is to use `iSEE` to `id`entify cells From 72a865ee9fba0d61f5818523d625774780d35937 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 4 Sep 2024 14:15:54 +0200 Subject: [PATCH 08/14] adding BiocStyle for rendering the vignette --- DESCRIPTION | 1 + 1 file changed, 1 insertion(+) diff --git a/DESCRIPTION b/DESCRIPTION index bcdb35d..2809e51 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -23,6 +23,7 @@ Suggests: scater, knitr, rmarkdown, + BiocStyle, testthat (>= 3.0.0) VignetteBuilder: knitr Config/testthat/edition: 3 From af959c02fec990c995a100c7a5501db1c5ab8364 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 4 Sep 2024 15:10:08 +0200 Subject: [PATCH 09/14] adding Rbuildignore, some extra fields in DESCRIPTION, details on authors in the vignette --- .Rbuildignore | 7 +++++++ DESCRIPTION | 2 ++ vignettes/Introduction_to_iSEEid.Rmd | 16 +++++++++------- 3 files changed, 18 insertions(+), 7 deletions(-) create mode 100644 .Rbuildignore diff --git a/.Rbuildignore b/.Rbuildignore new file mode 100644 index 0000000..ed74521 --- /dev/null +++ b/.Rbuildignore @@ -0,0 +1,7 @@ +^iSEEid\.Rproj$ +^\.Rproj\.user$ +^LICENSE\.md$ +^README\.Rmd$ +^CODE_OF_CONDUCT\.md$ +TODO.md$ +^\.github$ diff --git a/DESCRIPTION b/DESCRIPTION index 2809e51..0bbe471 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -25,5 +25,7 @@ Suggests: rmarkdown, BiocStyle, testthat (>= 3.0.0) +URL: https://github.com/iSEE/iSEEid +BugReports: https://github.com/iSEE/iSEEid/issues VignetteBuilder: knitr Config/testthat/edition: 3 diff --git a/vignettes/Introduction_to_iSEEid.Rmd b/vignettes/Introduction_to_iSEEid.Rmd index e191c6e..2dd8b65 100644 --- a/vignettes/Introduction_to_iSEEid.Rmd +++ b/vignettes/Introduction_to_iSEEid.Rmd @@ -1,18 +1,20 @@ --- title: "Introduction to iSEEid" author: - - name: Kevin Rue-Albrecht + - name: Federico Marini affiliation: - - University of Oxford - email: kevin.rue-albrecht@imm.ox.ac.uk + - Institute of Medical Biostatistics, Epidemiology and Informatics (IMBEI), University Medical Center Mainz, Germany + - Research Center for Immunotherapy (FZI), Mainz, Germany + email: marinif@uni-mainz.de - name: Kevin Rue-Albrecht affiliation: - - University of Oxford + - University of Oxford, Oxford, United Kingdom email: kevin.rue-albrecht@imm.ox.ac.uk - - name: Kevin Rue-Albrecht + - name: Charlotte Soneson affiliation: - - University of Oxford - email: kevin.rue-albrecht@imm.ox.ac.uk + - Friedrich Miescher Institute for Biomedical Research, Basel, Switzerland + - SIB Swiss Institute of Bioinformatics + email: charlottesoneson@gmail.com output: BiocStyle::html_document: self_contained: yes From 9c5109991c609c28ce84103b946905456abffc5a Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Wed, 4 Sep 2024 15:21:23 +0200 Subject: [PATCH 10/14] title, description, biocViews added --- DESCRIPTION | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 0bbe471..292493d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,12 +1,17 @@ Package: iSEEid -Title: What the Package Does (One Line, Title Case) +Title: iSEE extension to assist in identifying sets of samples/cells Version: 0.1.0 Authors@R: c( person("Federico", "Marini", role= c("aut", "cre"), email = "marinif@uni-mainz.de", comment = c(ORCID = '0000-0003-3252-7758')), person("Kevin", "Rue-Albrecht", role = c("aut"), email = "kevinrue67@gmail.com", comment = c(ORCID = "0000-0003-3899-3872")), person("Charlotte", "Soneson", role = c("aut"), email = "charlottesoneson@gmail.com", comment = c(ORCID = '0000-0003-3833-2169'))) -Description: What the package does (one paragraph). +Description: This package provides a dedicated panel to assist the sample + identification within a single iSEE web-application. The main functionality + of this package can be adopted to efficiently select samples (e.g. cells) + that need to be identified and annotated in the analysis workflow. With + iSEEid, the iSEE framework fully qualifies to be an ideal companion for + assigning appropriate labels to large omics datasets. License: MIT + file LICENSE Encoding: UTF-8 Roxygen: list(markdown = TRUE) @@ -28,4 +33,7 @@ Suggests: URL: https://github.com/iSEE/iSEEid BugReports: https://github.com/iSEE/iSEEid/issues VignetteBuilder: knitr +biocViews: CellBasedAssays, Clustering, DimensionReduction, FeatureExtraction, + GeneExpression, GUI, ImmunoOncology, ShinyApps, SingleCell, Transcription, + Transcriptomics, Visualization Config/testthat/edition: 3 From a00b5ce35f9f4fc35f9f3b6bf333c23791469b92 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Mon, 9 Sep 2024 15:57:43 +0200 Subject: [PATCH 11/14] from vector to commands --- R/panel_SampleIdentificationCenter.R | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/R/panel_SampleIdentificationCenter.R b/R/panel_SampleIdentificationCenter.R index d22194e..f4bb7d7 100644 --- a/R/panel_SampleIdentificationCenter.R +++ b/R/panel_SampleIdentificationCenter.R @@ -212,3 +212,27 @@ setMethod(".definePanelTour", "SampleIdentificationCenter", function(x) { prev }) + + +cellids_to_command <- function(cellids, + object_name = "se", + coldata_annotation = "cell_type", + comment_rationale = "") { + cmd <- c() + cmd <- paste0(cmd, + "## This is your SummarizedExperiment object\n# ", object_name, + "\n\n## In this slot you store your annotation e.g. your cell label\n# ", + "colData(", object_name, ")[['", coldata_annotation, "']]", + "\n\n## To rename the selected cells to their new label, you can use\n", + "colData(", object_name, ")[['", coldata_annotation, "']][\n", + " c(", + paste0(.quoteElement(cellids), collapse = ",\n "), + "\n )] <- 'new_cell_type'\n" + ) + +} + +.quoteElement <- function(x) { + paste0("'", x, "'") +} + From bd1c28f3635eb7042f3d24deb8854111a0ad39d3 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Mon, 9 Sep 2024 15:58:50 +0200 Subject: [PATCH 12/14] * adding thoughts on how this should work based on the input widgets * microtour inserted * observers added (needed?) --- R/panel_SampleIdentificationCenter.R | 63 +++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 10 deletions(-) diff --git a/R/panel_SampleIdentificationCenter.R b/R/panel_SampleIdentificationCenter.R index f4bb7d7..741c9dc 100644 --- a/R/panel_SampleIdentificationCenter.R +++ b/R/panel_SampleIdentificationCenter.R @@ -36,11 +36,11 @@ #' library(scRNAseq) #' #' # Example data ---- -#' sce <- ReprocessedAllenData(assays="tophat_counts") +#' sce <- ReprocessedAllenData(assays = "tophat_counts") #' class(sce) #' #' library(scater) -#' sce <- logNormCounts(sce, exprs_values="tophat_counts") +#' sce <- logNormCounts(sce, exprs_values = "tophat_counts") #' #' sce <- runPCA(sce, ncomponents=4) #' sce <- runTSNE(sce) @@ -50,7 +50,7 @@ #' # launch the app itself ---- #' #' if (interactive()) { -#' iSEE(sce, initial=list( +#' iSEE(sce, initial = list( #' ReducedDimensionPlot(), #' SampleIdentificationCenter( #' ColumnSelectionSource = "ReducedDimensionPlot1" @@ -72,6 +72,12 @@ NULL collated <- character(0) +.EditorUsage <- "EditorUsageMode" +.AnnotationRationale <- "AnnotationRationale" + +collated[.EditorUsage] <- "logical" +collated[.AnnotationRationale] <- "character" + #' @export #' @importClassesFrom iSEE ColumnTable ColumnDataTable Panel #' @import SummarizedExperiment @@ -112,6 +118,28 @@ setMethod("initialize", "SampleIdentificationCenter", function(.Object, ...) { # TODO - placeholder +#' @export +#' @importFrom shiny tagList +setMethod(".defineDataInterface", "SampleIdentificationCenter", function(x) { + panel_name <- .getEncodedName(x) + + .addSpecificTour(class(x), .EditorUsage, function(panel_name) { + data.frame( + element = paste0("#", panel_name, "_", .EditorUsage), + intro = "Help editor usage" + ) + }) + + tagList( + .checkboxInput.iSEE(x, .EditorUsage, label = "Provide commands in the text editor", + value = TRUE), + span(id = paste0(.AnnotationRationale, "_specific_help"), + style = "display:inline-block; padding-bottom:5px;", + HTML("Specify the rationale for the selection: ?")), + textInput(inputId = .AnnotationRationale, label = "Annotation rationale") + ) + +}) ## Idea: have a radio button/checkbox to control what the editor can give ## Idea: have a textInput where to record the reason why one would select those cells ## These elements could just "refine" the behavior of the content returned by the text editor @@ -125,6 +153,11 @@ setMethod(".createObservers", "SampleIdentificationCenter", function(x, se, inpu panel_name <- .getEncodedName(x) + .createProtectedParameterObservers(panel_name, + fields = c(.EditorUsage, + .AnnotationRationale), + input = input, pObjects = pObjects, rObjects = rObjects) + invisible(NULL) }) @@ -150,15 +183,25 @@ setMethod(".generateOutput", "SampleIdentificationCenter", function(x, se, all_m selected_names <- panel_env$col_selected[["active"]] print(selected_names) + # print(panel_name[["EditorUsageMode"]]) + + # TODO: I just need to access the editor mode and the text input field from the same panel + # helpz? + + # here: if only samples, provide only samples. --> paste0(selected_names, collapse = "\n") + # If wanting the command: use the line below + full_editor_content <- cellids_to_command(selected_names) + list( - commands=all_cmds, - contents=aceEditor( + commands = all_cmds, + contents = aceEditor( panel_name, - mode="r", - theme="solarized_light", - value=paste0(selected_names, collapse = "\n"), - height=paste0(slot(x, .organizationHeight), "px")), - varname=panel_name) + mode = "r", + theme = "solarized_light", + # value = paste0(selected_names, collapse = "\n"), + value = full_editor_content, + height = paste0(slot(x, .organizationHeight), "px")), + varname = panel_name) }) From 551a906e208d0d60cc419fe7e54890ec0f92da5e Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Mon, 9 Sep 2024 15:59:14 +0200 Subject: [PATCH 13/14] rendered info on manpages --- man/iSEEid-pkg.Rd | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/man/iSEEid-pkg.Rd b/man/iSEEid-pkg.Rd index ba15abf..769c9ea 100644 --- a/man/iSEEid-pkg.Rd +++ b/man/iSEEid-pkg.Rd @@ -7,7 +7,15 @@ \alias{iSEEid-pkg} \title{iSEEid} \description{ -What the package does (one paragraph). +This package provides a dedicated panel to assist the sample identification within a single iSEE web-application. The main functionality of this package can be adopted to efficiently select samples (e.g. cells) that need to be identified and annotated in the analysis workflow. With iSEEid, the iSEE framework fully qualifies to be an ideal companion for assigning appropriate labels to large omics datasets. +} +\seealso{ +Useful links: +\itemize{ + \item \url{https://github.com/iSEE/iSEEid} + \item Report bugs at \url{https://github.com/iSEE/iSEEid/issues} +} + } \author{ \strong{Maintainer}: Federico Marini \email{marinif@uni-mainz.de} (\href{https://orcid.org/0000-0003-3252-7758}{ORCID}) From 320de69daf28b380b53e603f0f7b0d9676b3b239 Mon Sep 17 00:00:00 2001 From: Federico Marini Date: Mon, 9 Sep 2024 16:06:13 +0200 Subject: [PATCH 14/14] adding concept for the returned output --- R/panel_SampleIdentificationCenter.R | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/R/panel_SampleIdentificationCenter.R b/R/panel_SampleIdentificationCenter.R index 741c9dc..bcac779 100644 --- a/R/panel_SampleIdentificationCenter.R +++ b/R/panel_SampleIdentificationCenter.R @@ -190,8 +190,16 @@ setMethod(".generateOutput", "SampleIdentificationCenter", function(x, se, all_m # here: if only samples, provide only samples. --> paste0(selected_names, collapse = "\n") # If wanting the command: use the line below + full_editor_content <- cellids_to_command(selected_names) + ## conceptually: + # if (editor_return_commands) { + # editor_contents = full_editor_content + # } else { + # editor_contents = paste0(selected_names, collapse = "\n") + # } + list( commands = all_cmds, contents = aceEditor( @@ -273,6 +281,10 @@ cellids_to_command <- function(cellids, "\n )] <- 'new_cell_type'\n" ) + # TODO: consider to add the rationale as a line below/above + + return(cmd) + } .quoteElement <- function(x) {