diff --git a/.Rbuildignore b/.Rbuildignore index 755a45ee8e9b8185a3809b28c767a304cd8e4a76..976eb0452c7fa503d647fe80d8347981de346ed0 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -11,3 +11,5 @@ ^_pkgdown\.yml$ ^UTechSCB-SCHNAPPs.wiki$ ^_gh-pages$ +^history +^CONTRIBUTING.md$ diff --git a/.gitignore b/.gitignore index a94fd2e2decdfcc0ce29301e34daadd8b326ee7f..68aee2e813ffd4748eea0db42e9967a0a8850bc1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # History files .Rhistory .Rapp.history +history/ # Session Data files .RData diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000000000000000000000000000000000..76408784fe6082199d337a041ea533404e857a1b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1 @@ +see wiki on how to contribute diff --git a/DESCRIPTION b/DESCRIPTION index 9591cdff71774203008eaadb7439f544f8a71a3c..393d72631d8177903d254941dcf7557bafd1c7e9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: SCHNAPPs Type: Package Title: Single Cell Shiny Application for Analysing Single Cell Transcriptomics Data -Version: 1.1.24 +Version: 1.2.1 Authors@R: c(person("Bernd", "Jagla", role = c("aut", "cre"), email = "bernd.jagla@pasteur.fr", comment = c(ORCID = "0000-0002-7696-0484"))) Maintainer: Bernd Jagla <bernd.jagla@pasteur.fr> Description: Single Cell sHiny APPlication (SCHNAPPs) is a R/Shiny based application to interact, manipulate, explore, and analyze single cell RNA-seq experiments, including MARS-seq and others. @@ -34,6 +34,7 @@ Imports: shinyTree, shinyWidgets, SingleCellExperiment, + ggpubr, SummarizedExperiment, threejs, tidyverse, diff --git a/R/schnapps-Main.R b/R/schnapps-Main.R index ffc0d6200dff6c99b4a0d5a0c84c5ca5ae2c7c06..754b023df2166f66c73924a260b700af039ec314 100644 --- a/R/schnapps-Main.R +++ b/R/schnapps-Main.R @@ -31,11 +31,15 @@ #' save(file = "scEx.Rdata", list = "scEx") #' # use "scEx.Rdata" with load data functionality within the shiny app schnapps <- function(localContributionDir = "~/Rstudio/shHubgit/Dummy/", - defaultValueSingleGene = "CD52", - defaultValueMultiGenes = "CD52, S100A4, S100A9, S100A8", - defaultValueRegExGene = "", # tip: '^CD7$|^KIT$; genes with min expression - DEBUG = FALSE, - DEBUGSAVE = FALSE) { + defaultValueSingleGene = "CD52", + defaultValueMultiGenes = "CD52, S100A4, S100A9, S100A8", + defaultValueRegExGene = "", # tip: '^CD7$|^KIT$; genes with min expression + DEBUG = FALSE, + DEBUGSAVE = FALSE, + historyPath = NULL, + historyFile = NULL + + ) { # on.exit({ # rm(list = c(".SCHNAPPs_locContributionDir", # ".SCHNAPPs_defaultValueSingleGene", @@ -53,6 +57,9 @@ schnapps <- function(localContributionDir = "~/Rstudio/shHubgit/Dummy/", assign(".SCHNAPPs_DEBUGSAVE", DEBUGSAVE, envir = .schnappsEnv) assign("DEBUG", DEBUG, envir = .schnappsEnv) assign("DEBUGSAVE", DEBUGSAVE, envir = .schnappsEnv) + assign("historyPath", historyPath, envir = .schnappsEnv) + assign("historyFile", historyFile, envir = .schnappsEnv) + # will be set during sourcing, but we need to define them, otherwise there will be a warning scShinyUI <- NULL scShinyServer <- NULL diff --git a/inst/app/contributions/DE_DataExploration/outputs.R b/inst/app/contributions/DE_DataExploration/outputs.R index 6db898cdd9b8fe215cc3a3f1098a4ac9ec3b84ef..fad5fc6310b03f36fbdd0d6c441526d82b70ebbe 100644 --- a/inst/app/contributions/DE_DataExploration/outputs.R +++ b/inst/app/contributions/DE_DataExploration/outputs.R @@ -28,7 +28,7 @@ observe(label = "ob18", { .schnappsEnv$DE_Y1 <- input$DE_dim_y }) -DE_updateInputExpPanel <- reactive({ +observe({ if (DEBUG) cat(file = stderr(), "DE_updateInputExpPanel started.\n") start.time <- base::Sys.time() on.exit({ @@ -59,7 +59,7 @@ DE_updateInputExpPanel <- reactive({ choices = colnames(projections), selected = .schnappsEnv$DE_Y1 ) - return(TRUE) + # return(TRUE) }) @@ -152,15 +152,21 @@ output$DE_panelPlot <- renderPlot({ } if (DEBUG) cat(file = stderr(), "output$DE_panelPlot\n") + clicked <- input$updatePanelPlot scEx_log <- scEx_log() projections <- projections() - genesin <- input$DE_panelplotids - cl4 <- input$DE_clusterSelectionPanelPlot - dimx4 <- input$DE_dim_x - dimy4 <- input$DE_dim_y - sameScale <- input$DE_panelplotSameScale - - if (is.null(scEx_log) | is.null(projections) | is.null(cl4)) { + DE_updateInputPPt() + genesin <- isolate(input$DE_panelplotids) + # cl4 <- input$DE_clusterSelectionPanelPlot + ppgrp <- isolate(input$DE_PPGrp) + ppCluster <- isolate(input$DE_clusterPP) + + dimx4 <- isolate(input$DE_dim_x) + dimy4 <- isolate(input$DE_dim_y) + sameScale <- isolate(input$DE_panelplotSameScale) + nCol <- isolate(as.numeric(input$DE_nCol)) + + if (is.null(scEx_log) | is.null(projections) | is.null(ppgrp)) { return(NULL) } if (.schnappsEnv$DEBUGSAVE) { @@ -193,69 +199,104 @@ output$DE_panelPlot <- renderPlot({ ylim <- NULL } } - if (cl4 == "All") { - for (i in 1:length(genesin)) { - geneIdx <- which(toupper(featureData$symbol) == genesin[i]) - Col <- rbPal(10)[ - as.numeric( - cut( - as.numeric( - assays(scEx_log)[[1]][ - rownames(featureData[geneIdx, ]), - ] - ), - breaks = 10 - ) - ) - ] - if (is(projections[, dimx4], "factor") & dimy4 == "UMI.count") { - projections[, dimy4] <- Matrix::colSums(assays(scEx_log)[["logcounts"]][geneIdx, , drop = FALSE]) - } - - plot(projections[, dimx4], projections[, dimy4], - col = Col, pch = 16, frame.plot = TRUE, ann = FALSE, ylim = ylim - ) - title(genesin[i], line = -1.2, adj = 0.05, cex.main = 2) - if (DEBUG) cat(file = stderr(), genesin[i]) - } - } else { - for (i in 1:length(genesin)) { - geneIdx <- which(toupper(featureData$symbol) == genesin[i]) - subsetTSNE <- subset(projections, dbCluster == cl4) - - Col <- rbPal(10)[ - as.numeric( - cut( - as.numeric( - assays(scEx_log)[[1]][ - rownames(featureData[geneIdx, ]), - ] - ), - breaks = 10 - ) + plotList <- list() + plotIdx <- 0 + # if (cl4 == "All") { + # for (i in 1:length(genesin)) { + # geneIdx <- which(toupper(featureData$symbol) == genesin[i]) + # Col <- rbPal(10)[ + # as.numeric( + # cut( + # as.numeric( + # assays(scEx_log)[[1]][ + # rownames(featureData[geneIdx, ]), + # ] + # ), + # breaks = 10 + # ) + # ) + # ] + # plotIdx = plotIdx +1 + # + # plotList[[plotIdx]] = ggplot(projections, aes_string(x=dimx4, y=dimy4)) + # if (is(projections[, dimx4], "factor") & dimy4 == "UMI.count") { + # projections[, dimy4] <- Matrix::colSums(assays(scEx_log)[["logcounts"]][geneIdx, , drop = FALSE]) + # plotList[[plotIdx]] = plotList[[plotIdx]] + geom_boxplot(show.legend = FALSE) + ggtitle(genesin[i]) + # } else{ + # plotList[[plotIdx]] = plotList[[plotIdx]] + geom_point(color = Col, show.legend = FALSE) + ggtitle(genesin[i]) + # + # } + # if (!is.null(ylim)) { + # plotList[[plotIdx]] = plotList[[plotIdx]] + ylim(ylim) + # } + # # plot(projections[, dimx4], projections[, dimy4], + # # col = Col, pch = 16, frame.plot = TRUE, ann = FALSE, ylim = ylim + # # ) + # # title(genesin[i], line = -1.2, adj = 0.05, cex.main = 2) + # if (DEBUG) cat(file = stderr(), genesin[i]) + # } + # } else { + for (i in 1:length(genesin)) { + geneIdx <- which(toupper(featureData$symbol) == genesin[i]) + subsetTSNE <- projections[projections[, ppCluster] %in% ppgrp, ] + + Col <- rbPal(10)[ + as.numeric( + cut( + as.numeric( + assays(scEx_log)[[1]][ + rownames(featureData[geneIdx, ]), + ] + ), + breaks = 10 ) - ] - - names(Col) <- rownames(projections) - plotCol <- Col[rownames(subsetTSNE)] - if (is(projections[, dimx4], "factor") & dimy4 == "UMI.count") { - projections[, dimy4] <- Matrix::colSums(assays(scEx_log)[["logcounts"]][geneIdx, , drop = FALSE]) - subsetTSNE <- subset(projections, dbCluster == cl4) - } - - plot(subsetTSNE[, dimx4], subsetTSNE[, dimy4], - col = plotCol, pch = 16, frame.plot = TRUE, - ann = FALSE, ylim = ylim ) - title(genesin[i], line = -1.2, adj = 0.05, cex.main = 2) - if (DEBUG) cat(file = stderr(), cl4) + ] + + names(Col) <- rownames(projections) + plotCol <- Col[rownames(subsetTSNE)] + if (is(projections[, dimx4], "factor") & dimy4 == "UMI.count") { + projections[, dimy4] <- Matrix::colSums(assays(scEx_log)[["logcounts"]][geneIdx, , drop = FALSE]) + subsetTSNE <- projections[projections[, ppCluster] %in% ppgrp, ] } - } + plotIdx <- plotIdx + 1 + + plotList[[plotIdx]] <- ggplot(subsetTSNE, aes_string(x = dimx4, y = dimy4)) + if (is(subsetTSNE[, dimx4], "factor") & dimy4 == "UMI.count") { + subsetTSNE[, dimy4] <- Matrix::colSums(assays(scEx_log)[["logcounts"]][geneIdx, rownames(subsetTSNE), drop = FALSE]) + plotList[[plotIdx]] <- plotList[[plotIdx]] + geom_boxplot(show.legend = FALSE) + ggtitle(genesin[i]) + } else { + plotList[[plotIdx]] <- plotList[[plotIdx]] + geom_point(color = plotCol, show.legend = FALSE) + ggtitle(genesin[i]) + } + if (!is.null(ylim)) { + plotList[[plotIdx]] <- plotList[[plotIdx]] + ylim(ylim) + } + # plot(subsetTSNE[, dimx4], subsetTSNE[, dimy4], + # col = plotCol, pch = 16, frame.plot = TRUE, + # ann = FALSE, ylim = ylim + # ) + # title(genesin[i], line = -1.2, adj = 0.05, cex.main = 2) + # if (DEBUG) cat(file = stderr(), ppgrp) + } + # } + require(ggpubr) + retVal <- + ggarrange( + plotlist = plotList, ncol = nCol, nrow = ceiling(length(plotList) / nCol), + label.x = "test", legend = "right", + common.legend = T + ) + retVal <- + annotate_figure(retVal, + top = text_grob(paste("using projection", ppCluster, "with elements", paste(ppgrp, collapse = ", "))) + ) printTimeEnd(start.time, "DE_panelPlot") exportTestValues(DE_panelPlot = { ls() }) + .schnappsEnv[["DE_panelPlot"]] <- retVal + retVal }) diff --git a/inst/app/contributions/DE_DataExploration/parameters.R b/inst/app/contributions/DE_DataExploration/parameters.R index eb6b12f59d5415114ea0379db0f4447597772713..490e43db15207623e9095911c035c2b72f94c37d 100644 --- a/inst/app/contributions/DE_DataExploration/parameters.R +++ b/inst/app/contributions/DE_DataExploration/parameters.R @@ -47,10 +47,12 @@ myNormalizationParameters <- list( value = 200 ), numericInput("DE_seuratSCtransform_scaleFactor", - label = "Scaling to use for transformed data", - min = 1, max = 30000, step = 10, - value = 1000 - ) + label = "Scaling to use for transformed data", + min = 1, max = 30000, step = 10, + value = 1000 + ), + textInput("DE_seuratSCtransformm_keepfeatures", "comma separated list of genes keep", value = "") + ), DE_seuratRefBased = tagList( numericInput("DE_seuratRefBased_nfeatures", @@ -63,14 +65,17 @@ myNormalizationParameters <- list( value = 200 ), numericInput("DE_seuratRefBased_scaleFactor", - label = "Scaling to use for transformed data", - min = 1, max = 30000, step = 10, - value = 1000 - ) + label = "Scaling to use for transformed data", + min = 1, max = 30000, step = 10, + value = 1000 + ), + textInput("DE_seuratRefBased_keepfeatures", "comma separated list of genes keep", value = "") ) ) -DE_seuratRefBasedFunc <- function(scEx, nfeatures = 3000, k.filter = 100, scalingFactor = 1000) { +# DE_seuratRefBasedFunc ---- +DE_seuratRefBasedFunc <- function(scEx, nfeatures = 3000, k.filter = 100, + scalingFactor = 1000, keep.features = "") { require(Seurat) cellMeta <- colData(scEx) # split in different samples @@ -86,16 +91,20 @@ DE_seuratRefBasedFunc <- function(scEx, nfeatures = 3000, k.filter = 100, scalin integrated <- tryCatch( { # save(file = "~/SCHNAPPsDebug/DE_seuratRefBased.RData", list = c(ls(), ls(envir = globalenv()))) + # load(file = "~/SCHNAPPsDebug/DE_seuratRefBased.RData") features <- SelectIntegrationFeatures(object.list = seur.list, nfeatures = nfeatures) + + keep.features = keep.features[keep.features %in% rownames(scEx)] + features = unique(c(features, keep.features)) + seur.list <- PrepSCTIntegration( object.list = seur.list, anchor.features = features, verbose = TRUE ) # take the sample with the highest number of cells as reference - reference_dataset <- order(unlist(lapply(seur.list, FUN = function(x) { - ncol(x) - })), decreasing = T)[1] - + reference_dataset <- order(unlist(lapply(seur.list, FUN = function(x) {ncol(x)})), decreasing =T)[1] + + anchors <- FindIntegrationAnchors( object.list = seur.list, normalization.method = "SCT", anchor.features = features, verbose = TRUE, k.filter = k.filter, @@ -138,6 +147,7 @@ DE_seuratRefBasedButton <- reactiveVal( label = "DE_seuratRefBasedButton", value = "" ) +# DE_seuratRefBased ---- DE_seuratRefBased <- reactive({ if (DEBUG) cat(file = stderr(), "DE_seuratRefBased started.\n") start.time <- base::Sys.time() @@ -167,13 +177,16 @@ DE_seuratRefBased <- reactive({ save(file = "~/SCHNAPPsDebug/DE_seuratRefBased.RData", list = c(ls(), ls(envir = globalenv()))) } # load(file="~/SCHNAPPsDebug/DE_seuratRefBased.RData") - - - + .schnappsEnv$normalizationFactor = scalingFactor + featureData <- rowData(scEx) + geneid <- geneName2Index(geneNames, featureData) + + # # TODO ?? define scaling factor somewhere else??? # sfactor = max(max(assays(scEx)[["counts"]]),1000) - retVal <- DE_seuratRefBasedFunc(scEx = scEx, nfeatures = nfeatures, k.filter = k.filter, scalingFactor = scalingFactor) - + retVal <- DE_seuratRefBasedFunc(scEx = scEx, nfeatures = nfeatures, k.filter = k.filter, + scalingFactor = scalingFactor, keep.features = geneid) + if (is.null(retVal)) { showNotification("An error occurred during Seurat normalization, please check console", id = "DE_seuratError", duration = NULL, type = "error") } @@ -191,7 +204,8 @@ DE_seuratRefBased <- reactive({ }) # DE_seuratSCtransformFunc ======= -DE_seuratSCtransformFunc <- function(scEx, nfeatures = 3000, k.filter = 100, scalingFactor = 1000) { +DE_seuratSCtransformFunc <- function(scEx, nfeatures = 3000, k.filter = 100, + scalingFactor = 1000, keep.features = "") { require(Seurat) cellMeta <- colData(scEx) # split in different samples @@ -208,14 +222,20 @@ DE_seuratSCtransformFunc <- function(scEx, nfeatures = 3000, k.filter = 100, sca } features <- SelectIntegrationFeatures(object.list = seur.list, nfeatures = nfeatures) + keep.features = keep.features[keep.features %in% rownames(scEx)] + features = unique(c(features, keep.features)) + seur.list <- PrepSCTIntegration( object.list = seur.list, anchor.features = features, verbose = TRUE ) + anchors <- FindIntegrationAnchors( object.list = seur.list, normalization.method = "SCT", anchor.features = features, verbose = TRUE, k.filter = k.filter ) + keep.features = keep.features[keep.features %in% rownames(scEx)] + anchors = unique(c(anchors, keep.features)) integrated <- IntegrateData( anchorset = anchors, normalization.method = "SCT", verbose = TRUE @@ -281,16 +301,18 @@ DE_seuratSCtransform <- reactive({ return(NULL) } if (.schnappsEnv$DEBUGSAVE) { - save(file = "~/SCHNAPPsDebug/DE_seuratSCtransform.RData", list = c(ls(), ls(envir = globalenv()))) + save(file = "~/SCHNAPPsDebug/DE_seuratSCtransform.RData", list = c(ls())) } # load(file="~/SCHNAPPsDebug/DE_seuratSCtransform.RData") - - - + .schnappsEnv$normalizationFactor <- scalingFactor + featureData <- rowData(scEx) + geneid <- geneName2Index(geneNames, featureData) + # # TODO ?? define scaling factor somewhere else??? # sfactor = max(max(assays(scEx)[["counts"]]),1000) - retVal <- DE_seuratSCtransformFunc(scEx = scEx, nfeatures = nfeatures, k.filter = k.filter, scalingFactor = scalingFactor) - + retVal <- DE_seuratSCtransformFunc(scEx = scEx, nfeatures = nfeatures, k.filter = k.filter, + scalingFactor = scalingFactor, keep.features = geneid) + if (is.null(retVal)) { if (DEBUG) green(cat(file = stderr(), "An error occurred during Seurat normalization, please check console\n")) showNotification("An error occurred during Seurat normalization, please check console", id = "DE_seuratError", duration = NULL, type = "error") @@ -479,6 +501,7 @@ DE_logGeneNormalization <- reactive(label = "rlogGene", { # turn normalization button green addClass("updateNormalization", "green") + .schnappsEnv$normalizationFactor <- sfactor exportTestValues(DE_logGeneNormalization = { assays(retVal)[["logcounts"]] }) @@ -572,6 +595,7 @@ DE_logNormalization <- reactive(label = "rlogNorm", { # turn normalization button green addClass("updateNormalization", "green") + .schnappsEnv$normalizationFactor <- sfactor exportTestValues(DE_logNormalization = { assays(retVal)[["logcounts"]] }) diff --git a/inst/app/contributions/DE_DataExploration/reactives.R b/inst/app/contributions/DE_DataExploration/reactives.R index 11f406837fcb1b69200648ce2109a1cdce2b7033..1be92301217aca499da32f41addc3a7a6006a3ff 100644 --- a/inst/app/contributions/DE_DataExploration/reactives.R +++ b/inst/app/contributions/DE_DataExploration/reactives.R @@ -1,6 +1,117 @@ suppressMessages(require(ggplot2)) +.schnappsEnv$coE_PPGrp <- "sampleNames" +observe({ + if (DEBUG) cat(file = stderr(), paste0("observe: DE_PPGrp\n")) + .schnappsEnv$DE_PPGrp <- input$DE_PPGrp +}) +.schnappsEnv$coE_PPSelection <- "1" +observe({ + if (DEBUG) cat(file = stderr(), paste0("observe: DE_clusterPP\n")) + .schnappsEnv$DE_clusterPP <- input$DE_clusterPP +}) + +# DE_updateInputPPt ==== +DE_updateInputPPt <- reactive({ + if (DEBUG) cat(file = stderr(), "DE_updateInputPPt started.\n") + start.time <- base::Sys.time() + on.exit({ + printTimeEnd(start.time, "DE_updateInputPPt") + if (!is.null(getDefaultReactiveDomain())) { + removeNotification(id = "DE_updateInputPPt") + } + }) + if (!is.null(getDefaultReactiveDomain())) { + showNotification("DE_updateInputPPt", id = "DE_updateInputPPt", duration = NULL) + } + tsneData <- projections() + + # Can use character(0) to remove all choices + if (is.null(tsneData)) { + return(NULL) + } + # save(file = "~/SCHNAPPsDebug/DE_updateInputPPt.Rdata", list = c(ls(), ls(envir = globalenv()))) + # load(file = "~/SCHNAPPsDebug/DE_updateInputPPt.Rdata") + + coln <- colnames(tsneData) + choices <- c() + for (cn in coln) { + if (length(levels(as.factor(tsneData[, cn]))) < 50) { + choices <- c(choices, cn) + } + } + if (length(choices) == 0) { + choices <- c("no valid columns") + } + updateSelectInput( + session, + "DE_clusterPP", + choices = choices, + selected = .schnappsEnv$DE_PPGrp + ) +}) + +observeEvent(input$DE_clusterPP,{ + projections <- projections() + if (DEBUG) cat(file = stderr(), "observeEvent: input$DE_clusterPP\n") + # Can use character(0) to remove all choices + if (is.null(projections)) { + return(NULL) + } + if(!input$DE_clusterPP %in% colnames(projections)) return(NULL) + choicesVal = levels(projections[, input$DE_clusterPP]) + updateSelectInput( + session, + "DE_PPGrp", + choices = choicesVal, + selected = .schnappsEnv$DE_clusterPP + ) + +}) + + + + +observe({ + clicked = input$save2HistScater + if (DEBUG) cat(file = stderr(), "observe input$save2HistVio \n") + start.time <- base::Sys.time() + on.exit( + if (!is.null(getDefaultReactiveDomain())) { + removeNotification(id = "save2Hist") + } + ) + # show in the app that this is running + if (!is.null(getDefaultReactiveDomain())) { + showNotification("save2Hist", id = "save2Hist", duration = NULL) + } + + add2history(type = "renderPlot", comment = "scater plot", + plotData = .schnappsEnv[["DE_scaterPNG"]]) + +}) + +observe({ + clicked = input$save2HistPanel + if (DEBUG) cat(file = stderr(), "observe input$save2HistPanel \n") + start.time <- base::Sys.time() + on.exit( + if (!is.null(getDefaultReactiveDomain())) { + removeNotification(id = "save2Hist") + } + ) + # show in the app that this is running + if (!is.null(getDefaultReactiveDomain())) { + showNotification("save2Hist", id = "save2Hist", duration = NULL) + } + + add2history(type = "renderPlot", comment = "Panel plot", + plotData = .schnappsEnv[["DE_panelPlot"]]) + +}) + + # DE_scaterPNG ---- #' DE_scaterPNG @@ -82,7 +193,7 @@ DE_scaterPNG <- reactive({ alt = "Scater plot should be here" ) # end calculation - + .schnappsEnv[["DE_scaterPNG"]] <- p1 printTimeEnd(start.time, "DE_scaterPNG") exportTestValues(DE_scaterPNG = { retVal diff --git a/inst/app/contributions/DE_DataExploration/ui.R b/inst/app/contributions/DE_DataExploration/ui.R index edd9a81d7e1ef50b7425c9e01b72f160847fd76e..d1425676acc1ab651a0ec85e29c25e883c8355a1 100644 --- a/inst/app/contributions/DE_DataExploration/ui.R +++ b/inst/app/contributions/DE_DataExploration/ui.R @@ -88,17 +88,29 @@ tabList <- list( ) ), fluidRow( - column( - width = 3, - uiOutput("DE_clusterSelectionPanelPlot") + column(width = 12, offset = 1, + actionButton("updatePanelPlot", "apply changes", width = '80%', + style = "color: #fff; background-color: #A00272; border-color: #2e6da4") + ) + ), + fluidRow( + column(width = 3, + # uiOutput("DE_clusterSelectionPanelPlot") + selectInput(inputId = "DE_clusterPP", label = "Clusters/Factor to use", + choices = c("dbCluster", "sampleNames"), + selected = "dbCluster") ), - column( - width = 3, - selectInput("DE_dim_x", - label = "X", - choices = c("tsne1", "tsne2", "tsne3"), - selected = "tsne1" - ) + column(width = 3, + selectInput(inputId = "DE_PPGrp", label = "Values to use", + choices = c("1","2"), selected = "1", multiple = TRUE) + )), + fluidRow( + column(width = 3, + selectInput("DE_dim_x", + label = "X", + choices = c("tsne1", "tsne2", "tsne3"), + selected = "tsne1" + ) ), column( width = 3, @@ -110,6 +122,14 @@ tabList <- list( ), column( 2, checkboxInput("DE_panelplotSameScale", "same scale", value = TRUE) + ), + column( + 2, + selectInput("DE_nCol", + label = "number of columns for plot", + choices = c(1:10), + selected = 4 + ) ) ), fluidRow( @@ -120,8 +140,11 @@ tabList <- list( ), fluidRow(column( 12, - jqui_resizable(plotOutput("DE_panelPlot")) - )) + jqui_resizable(plotOutput("DE_panelPlot") ) + ) + ), + br(), + actionButton("save2HistPanel", "save to history") ) ), # DE_scaterQC ---- @@ -138,7 +161,10 @@ tabList <- list( offset = 1, imageOutput("DE_scaterQC") %>% withSpinner() # PNG output with temp file ) - ) + ), + br(), + actionButton("save2HistScater", "save to history") + ) ) ) diff --git a/inst/app/contributions/coE_coExpression/outputs.R b/inst/app/contributions/coE_coExpression/outputs.R index 2dad63455cf641d81e4c488e88ca5ca99fc404dd..6fc448668c652ea609e5186fa1d8568a365f508f 100644 --- a/inst/app/contributions/coE_coExpression/outputs.R +++ b/inst/app/contributions/coE_coExpression/outputs.R @@ -97,8 +97,8 @@ output$coE_geneGrp_vio_plot <- renderPlot({ sampCol = sampCol, ccols = ccols ) - - exportTestValues(coE_geneGrp_vio_plot = { + .schnappsEnv[["coE_geneGrp_vio_plot"]] <- retVal + exportTestValues(coE_geneGrp_vio_plot = { retVal }) return(retVal) diff --git a/inst/app/contributions/coE_coExpression/reactives.R b/inst/app/contributions/coE_coExpression/reactives.R index 2cc8f43a5adfbe64784ef4a4c180a4d469ea334b..c09d3684e48964128945be9a074df489996f3010 100644 --- a/inst/app/contributions/coE_coExpression/reactives.R +++ b/inst/app/contributions/coE_coExpression/reactives.R @@ -286,6 +286,7 @@ coE_topExpCCTable <- reactive({ numProje <- projections[, nums] # colnames(numProje) genesin <- unique(genesin) + scCells <- scCells[scCells %in% colnames(assays(scEx_log)[[1]])] # we only work on cells that have been selected mat <- assays(scEx_log)[[1]][genesin, scCells, drop = FALSE] # only genes that express at least coEtgminExpr UMIs @@ -509,6 +510,27 @@ coE_geneGrp_vioFunc <- function(genesin, projections, scEx, featureData, minExpr return(p1) } +# save to history violoin observer ---- +observe({ + clicked = input$save2HistVio + if (DEBUG) cat(file = stderr(), "observe input$save2HistVio \n") + start.time <- base::Sys.time() + on.exit( + if (!is.null(getDefaultReactiveDomain())) { + removeNotification(id = "save2Hist") + } + ) + # show in the app that this is running + if (!is.null(getDefaultReactiveDomain())) { + showNotification("save2Hist", id = "save2Hist", duration = NULL) + } + + add2history(type = "renderPlot", comment = "violin plot", + plotData = .schnappsEnv[["coE_geneGrp_vio_plot"]]) + +}) + + #' coE_somFunction #' iData = expression matrix, rows = genes #' cluster genes in SOM @@ -771,7 +793,7 @@ coE_updateInputXviolinPlot <- reactive({ coln <- colnames(tsneData) choices <- c() for (cn in coln) { - if (length(levels(as.factor(tsneData[, cn]))) < 20) { + if (length(levels(as.factor(tsneData[, cn]))) < 50) { choices <- c(choices, cn) } } diff --git a/inst/app/contributions/coE_coExpression/report.Rmd b/inst/app/contributions/coE_coExpression/report.Rmd index 8b6fa8e517c71441e01c70e3505139e84c6ce8ba..5c197c8b63b3506a22fc38860edee337e0018208 100644 --- a/inst/app/contributions/coE_coExpression/report.Rmd +++ b/inst/app/contributions/coE_coExpression/report.Rmd @@ -115,7 +115,7 @@ dimY <- `r input$"coE_selected-dimension_y"` DEBUGSAVE <- FALSE grpNs <- groupNames$namesDF -grpN <- make.names(input$groupName) +grpN <- make.names(input$groupName, unique = TRUE) dimY <- input$"coE_selected-dimension_y" dimX <- input$"coE_selected-dimension_x" diff --git a/inst/app/contributions/coE_coExpression/ui.R b/inst/app/contributions/coE_coExpression/ui.R index d01243a71334d6500394d403bfdc54b56fac1c5f..a25c968ad7d65aec51b17dd7cf2431cc93cf811c 100644 --- a/inst/app/contributions/coE_coExpression/ui.R +++ b/inst/app/contributions/coE_coExpression/ui.R @@ -162,11 +162,12 @@ tabList <- list( ) ), br(), - fluidRow(column( - width = 12, - # jqui_resizable(plotly::plotlyOutput("coE_geneGrp_vio_plot") ) - jqui_resizable(plotOutput("coE_geneGrp_vio_plot")) - )) + fluidRow(column(width = 12, + # jqui_resizable(plotly::plotlyOutput("coE_geneGrp_vio_plot") ) + jqui_resizable(plotOutput("coE_geneGrp_vio_plot") ) + )), + br(), + actionButton("save2HistVio", "save to history") ) ), # SOMcluster ---- diff --git a/inst/app/contributions/gQC_generalQC/outputs.R b/inst/app/contributions/gQC_generalQC/outputs.R index 776120721ed66b6e2438e5689119416ffe9a65d1..c2c739557e2abc9d91ac46111c758f0809c8a7cd 100644 --- a/inst/app/contributions/gQC_generalQC/outputs.R +++ b/inst/app/contributions/gQC_generalQC/outputs.R @@ -173,10 +173,13 @@ output$gQC_plotUmiHist <- renderPlot({ dat <- data.frame(counts = Matrix::colSums(assays(scEx)[["counts"]])) dat$sample <- colData(scEx)$sampleNames - ggplot(data = dat, aes(counts, fill = sample)) + + retVal <- ggplot(data = dat, aes(counts, fill = sample)) + geom_histogram(bins = 50) + labs(title = "Histogram for raw counts", x = "count", y = "Frequency") + scale_fill_manual(values = scols, aesthetics = "fill") + + .schnappsEnv[["gQC_plotUmiHist"]] <- retVal + return(retVal) }) output$gQC_plotSampleHist <- renderPlot({ @@ -202,7 +205,9 @@ output$gQC_plotSampleHist <- renderPlot({ save(file = "~/SCHNAPPsDebug/sampleHist.RData", list = c(ls(), ls(envir = globalenv()))) } # load(file = "~/SCHNAPPsDebug/sampleHist.RData") - gQC_sampleHistFunc(sampleInf, scols) + retVal <- gQC_sampleHistFunc(sampleInf, scols) + .schnappsEnv[["gQC_plotSampleHist"]] <- retVal + return(retVal) }) output$gQC_variancePCA <- renderPlot({ @@ -217,12 +222,23 @@ output$gQC_variancePCA <- renderPlot({ if (!is.null(getDefaultReactiveDomain())) { showNotification("gQC_variancePCA", id = "gQC_variancePCA", duration = NULL) } - - if (DEBUG) cat(file = stderr(), "output$gQC_variancePCA\n") - h2("Variances of PCs") pca <- pca() if (is.null(pca)) { return(NULL) } - barplot(pca$var_pcs, main = "Variance captured by first PCs") + + if (.schnappsEnv$DEBUGSAVE) { + save(file = "~/SCHNAPPsDebug/gQC_variancePCA.RData", list = c(ls(), ls(envir = globalenv()))) + } + # load(file = "~/SCHNAPPsDebug/gQC_variancePCA.RData") + + # h2("Variances of PCs") + + + + df <- data.frame(var = pca$var_pcs, pc = 1:length(pca$var_pcs)) + retVal <- ggplot(data = df,aes(x=pc, y=var)) + geom_bar(stat = "identity") + .schnappsEnv[["gQC_variancePCA"]] <- retVal + return(retVal) + # barplot(pca$var_pcs, main = "Variance captured by first PCs") }) diff --git a/inst/app/contributions/gQC_generalQC/reactives.R b/inst/app/contributions/gQC_generalQC/reactives.R index af9b612028948e5cb24b2f4fd46c5478266879b3..1c9b93acd86b5feb787b8a6bd472f41685dc1908 100644 --- a/inst/app/contributions/gQC_generalQC/reactives.R +++ b/inst/app/contributions/gQC_generalQC/reactives.R @@ -4,6 +4,68 @@ suppressMessages(require(SingleCellExperiment)) # here we define reactive values/variables +# save to history violoin observer ---- +observe({ + clicked = input$save2Histumi + if (DEBUG) cat(file = stderr(), "observe input$save2HistVio \n") + start.time <- base::Sys.time() + on.exit( + if (!is.null(getDefaultReactiveDomain())) { + removeNotification(id = "save2Hist") + } + ) + # show in the app that this is running + if (!is.null(getDefaultReactiveDomain())) { + showNotification("save2Hist", id = "save2Hist", duration = NULL) + } + + add2history(type = "renderPlot", comment = "UMI histogram", + plotData = .schnappsEnv[["gQC_plotUmiHist"]]) + +}) + + +# save to history save2HistSample observer ---- +observe({ + clicked = input$save2HistSample + if (DEBUG) cat(file = stderr(), "observe input$save2HistVio \n") + start.time <- base::Sys.time() + on.exit( + if (!is.null(getDefaultReactiveDomain())) { + removeNotification(id = "save2Hist") + } + ) + # show in the app that this is running + if (!is.null(getDefaultReactiveDomain())) { + showNotification("save2Hist", id = "save2Hist", duration = NULL) + } + + add2history(type = "renderPlot", comment = "Sample histogram", + plotData = .schnappsEnv[["gQC_plotSampleHist"]]) + +}) + +# save to history save2HistSample observer ---- +observe({ + clicked = input$save2Histvar + if (DEBUG) cat(file = stderr(), "observe input$save2HistVio \n") + start.time <- base::Sys.time() + on.exit( + if (!is.null(getDefaultReactiveDomain())) { + removeNotification(id = "save2Hist") + } + ) + # show in the app that this is running + if (!is.null(getDefaultReactiveDomain())) { + showNotification("save2Hist", id = "save2Hist", duration = NULL) + } + + add2history(type = "renderPlot", comment = "PC variance", + plotData = .schnappsEnv[["gQC_variancePCA"]]) + +}) + + # gQC_scaterReadsFunc ---- #' gQC_scaterReadsFunc #' calculate the QC metrix and return updated singleCellExperiment object @@ -94,11 +156,14 @@ gQC_sampleHistFunc <- function(samples, scols) { } counts <- table(samples) - barplot(counts, - main = "histogram of number of cell per sample", - xlab = "Samples", - col = scols - ) + df <- as.data.frame(counts) + ggplot(data = df,aes(x=samples, y=Freq, fill=samples)) + geom_bar(stat = "identity") + + scale_color_manual(values=scols) + # barplot(counts, + # main = "histogram of number of cell per sample", + # xlab = "Samples", + # col=scols + # ) } diff --git a/inst/app/contributions/gQC_generalQC/report.Rmd b/inst/app/contributions/gQC_generalQC/report.Rmd index 17bce71a2f6a0922dab950038f866fa282222425..ad98363d9c1bde20111e0e50e3ac390cdf1997f6 100644 --- a/inst/app/contributions/gQC_generalQC/report.Rmd +++ b/inst/app/contributions/gQC_generalQC/report.Rmd @@ -269,7 +269,7 @@ ccols : `r clusterCols$colPal` ```{r gqc_UMAP, echo=TRUE} DEBUGSAVE <- FALSE grpNs <- groupNames$namesDF -grpN <- make.names(input$groupName) +grpN <- make.names(input$groupName, unique = TRUE) dimY <- input$"gQC_umap_main-dimension_y" dimX <- input$"gQC_umap_main-dimension_x" diff --git a/inst/app/contributions/gQC_generalQC/ui.R b/inst/app/contributions/gQC_generalQC/ui.R index ab5a5bfa8d5511d5cd227545cd6f5583a1b0dc2e..f3574352ad0f29b92d8573bda78350b42a82dd6d 100644 --- a/inst/app/contributions/gQC_generalQC/ui.R +++ b/inst/app/contributions/gQC_generalQC/ui.R @@ -22,7 +22,10 @@ tabList <- list( 10, offset = 1, plotOutput("gQC_plotUmiHist") %>% withSpinner() - )) + )), + br(), + actionButton("save2Histumi", "save to history") + ), shinydashboard::tabItem( @@ -32,7 +35,9 @@ tabList <- list( 10, offset = 1, plotOutput("gQC_plotSampleHist") %>% withSpinner() - )) + )), + br(), + actionButton("save2HistSample", "save to history") ), shinydashboard::tabItem( @@ -42,8 +47,11 @@ tabList <- list( 10, offset = 1, plotOutput("gQC_variancePCA") %>% withSpinner() - )) + )), + br(), + actionButton("save2Histvar", "save to history") ), + tsnePlotTab = shinydashboard::tabItem( tabName = "gQC_tsnePlot", shinyjs::useShinyjs(), diff --git a/inst/app/contributions/sCA_subClusterAnalysis/outputs.R b/inst/app/contributions/sCA_subClusterAnalysis/outputs.R index 82911846d6cf38914838b5a2b898875507909a40..7e39780993459661adba9c9710e8c27333b0e78f 100644 --- a/inst/app/contributions/sCA_subClusterAnalysis/outputs.R +++ b/inst/app/contributions/sCA_subClusterAnalysis/outputs.R @@ -205,6 +205,8 @@ output$sCA_volcanoPlot <- plotly::renderPlotly({ ) # retVal + .schnappsEnv[["sCA_volcanoPlot"]] <- retVal + exportTestValues(dgeVolcanoPlot = { str(retVal) }) diff --git a/inst/app/contributions/sCA_subClusterAnalysis/reactives.R b/inst/app/contributions/sCA_subClusterAnalysis/reactives.R index 1430dd1e652750f5ccb9ace48176a4812269fc29..eab8588742fc5b39b2129881570430ec329316f2 100644 --- a/inst/app/contributions/sCA_subClusterAnalysis/reactives.R +++ b/inst/app/contributions/sCA_subClusterAnalysis/reactives.R @@ -90,7 +90,7 @@ myDiffExpFunctions <- list( #' Seurat FindMarkers #' #' cellMeta = colData(scEx) -sCA_seuratFindMarkers <- function(scEx, cells.1, cells.2, test = "wilcox") { +sCA_seuratFindMarkers <- function(scEx, cells.1, cells.2, test="wilcox", normFact = 1){ if (DEBUG) cat(file = stderr(), "sCA_seuratFindMarkers started.\n") start.time <- base::Sys.time() on.exit({ @@ -107,7 +107,7 @@ sCA_seuratFindMarkers <- function(scEx, cells.1, cells.2, test = "wilcox") { showNotification("Please install DESeq2", id = "sCA_dge_deseq2NOTFOUND", duration = NULL, type = "error") } if (.schnappsEnv$DEBUGSAVE) { - save(file = "~/SCHNAPPsDebug/sCA_seuratFindMarkers.RData", list = c(ls(), ls(envir = globalenv()))) + save(file = "~/SCHNAPPsDebug/sCA_seuratFindMarkers.RData", list = c(ls())) } # load(file='~/SCHNAPPsDebug/sCA_seuratFindMarkers.RData') @@ -120,23 +120,24 @@ sCA_seuratFindMarkers <- function(scEx, cells.1, cells.2, test = "wilcox") { meta.data = meta.data ) # we remove e.g. "genes" from total seq (CD3-TotalSeqB) - useGenes <- which(rownames(seurDat@assays$RNA@data) %in% rownames(as(assays(scEx)[[1]], "dgCMatrix"))) - seurDat@assays$RNA@data <- as(assays(scEx)[[1]], "dgCMatrix")[useGenes, ] - - markers <- Seurat::FindMarkers(seurDat@assays$RNA@data, - cells.1 = cells.1, - cells.2 = cells.2, - min.pct = 0, - test.use = test - # test.use = "wilcox" # p_val avg_logFC pct.1 pct.2 p_val_adj - # test.use = "bimod" # p_val avg_logFC pct.1 pct.2 p_val_adj - # test.use = "roc" # myAUC avg_diff power pct.1 pct.2 - # test.use = "t" # p_val avg_logFC pct.1 pct.2 p_val_adj - # test.use = "negbinom" # needs UMI; p_val avg_logFC pct.1 pct.2 p_val_adj - # test.use = "poisson" # needs UMI; p_val avg_logFC pct.1 pct.2 p_val_adj - # test.use = "LR" # p_val avg_logFC pct.1 pct.2 p_val_adj - # test.use = "MAST" # not working: Assay in position 1, with name et is unlogged. Set `check_sanity = FALSE` to override and then proceed with caution. - # test.use = "DESeq2" # needs UMI # done separately because the estimating process isn't working with 0s + useGenes = which(rownames(seurDat@assays$RNA@data) %in% rownames(as(assays(scEx)[[1]], "dgCMatrix"))) + seurDat@assays$RNA@data = as(assays(scEx)[[1]], "dgCMatrix")[useGenes,] + + markers <- Seurat::FindMarkers(seurDat@assays$RNA@data/normFact, + cells.1 = cells.1, + cells.2 = cells.2, + min.pct = 0, + test.use = test, + logfc.threshold = 0.001 + # test.use = "wilcox" # p_val avg_logFC pct.1 pct.2 p_val_adj + # test.use = "bimod" # p_val avg_logFC pct.1 pct.2 p_val_adj + # test.use = "roc" # myAUC avg_diff power pct.1 pct.2 + # test.use = "t" # p_val avg_logFC pct.1 pct.2 p_val_adj + # test.use = "negbinom" # needs UMI; p_val avg_logFC pct.1 pct.2 p_val_adj + # test.use = "poisson" # needs UMI; p_val avg_logFC pct.1 pct.2 p_val_adj + # test.use = "LR" # p_val avg_logFC pct.1 pct.2 p_val_adj + # test.use = "MAST" # not working: Assay in position 1, with name et is unlogged. Set `check_sanity = FALSE` to override and then proceed with caution. + # test.use = "DESeq2" # needs UMI # done separately because the estimating process isn't working with 0s ) if (nrow(markers) > 0) { markers$symbol <- rData[rownames(markers), "symbol"] @@ -148,23 +149,27 @@ sCA_seuratFindMarkers <- function(scEx, cells.1, cells.2, test = "wilcox") { } -sCA_dge_s_wilcox <- function(scEx_log, cells.1, cells.2) { - sCA_seuratFindMarkers(scEx_log, cells.1, cells.2, test = "wilcox") +sCA_dge_s_wilcox <- function(scEx_log, cells.1, cells.2){ + normFact = .schnappsEnv$normalizationFactor + sCA_seuratFindMarkers(scEx_log, cells.1, cells.2, test="wilcox", normFact) } -sCA_dge_s_bimod <- function(scEx_log, cells.1, cells.2) { - sCA_seuratFindMarkers(scEx_log, cells.1, cells.2, test = "bimod") +sCA_dge_s_bimod <- function(scEx_log, cells.1, cells.2){ + normFact = .schnappsEnv$normalizationFactor + sCA_seuratFindMarkers(scEx_log, cells.1, cells.2, test="bimod") } -sCA_dge_s_t <- function(scEx_log, cells.1, cells.2) { - sCA_seuratFindMarkers(scEx_log, cells.1, cells.2, test = "t") +sCA_dge_s_t <- function(scEx_log, cells.1, cells.2){ + normFact = .schnappsEnv$normalizationFactor + sCA_seuratFindMarkers(scEx_log, cells.1, cells.2, test="t", normFact) } -sCA_dge_s_LR <- function(scEx_log, cells.1, cells.2) { - sCA_seuratFindMarkers(scEx_log, cells.1, cells.2, test = "LR") +sCA_dge_s_LR<- function(scEx_log, cells.1, cells.2){ + normFact = .schnappsEnv$normalizationFactor + sCA_seuratFindMarkers(scEx_log, cells.1, cells.2, test="LR", normFact) } -sCA_dge_s_negbinom <- function(scEx_log, cells.1, cells.2) { - sCA_seuratFindMarkers(scEx_log, cells.1, cells.2, test = "negbinom") +sCA_dge_s_negbinom <- function(scEx_log, cells.1, cells.2){ + sCA_seuratFindMarkers(scEx_log, cells.1, cells.2, test="negbinom", normFact = 1) } -sCA_dge_s_poisson <- function(scEx_log, cells.1, cells.2) { - sCA_seuratFindMarkers(scEx_log, cells.1, cells.2, test = "poisson") +sCA_dge_s_poisson <- function(scEx_log, cells.1, cells.2){ + sCA_seuratFindMarkers(scEx_log, cells.1, cells.2, test="poisson", normFact = 1) } @@ -198,7 +203,13 @@ sCA_dge_deseq2 <- function(scEx_log, cells.1, cells.2) { group.info[cells.2, "group"] <- "Group2" group.info[, "group"] <- factor(x = group.info[, "group"]) group.info$wellKey <- rownames(x = group.info) - data.use <- assays(scEx_log)[[1]][, rownames(group.info)] + # TODO how to handle data / transformation ? + # it uses non-transformed org data. What happens if we loaded normalized data? + # can back tronsform the data in counts? + if (is.null(.schnappsEnv$normalizationFactor)) { + .schnappsEnv$normalizationFactor = 1 + } + data.use = assays(scEx_log)[[1]][,rownames(group.info)] dds1 <- DESeq2::DESeqDataSetFromMatrix( countData = data.use, colData = group.info, @@ -252,8 +263,10 @@ sCA_dge_CellViewfunc <- function(scEx_log, cells.1, cells.2) { subsetExpression <- scEx_log[complete.cases(scEx_log[, union(cells.1, cells.2)]), ] genes.use <- rownames(subsetExpression) # expMean exponential mean - data.1 <- apply(subsetExpression[genes.use, cells.1], 1, expMean) - data.2 <- apply(subsetExpression[genes.use, cells.2], 1, expMean) + dat <- subsetExpression[genes.use, cells.1] + data.1 <- apply(dat, 1, function(x) expMean(x, .schnappsEnv$normalizationFactor)) + dat <- subsetExpression[genes.use, cells.2] + data.2 <- apply(dat, 1, function(x) expMean(x, .schnappsEnv$normalizationFactor)) total.diff <- (data.1 - data.2) genes.diff <- names(which(abs(total.diff) > .2)) @@ -283,7 +296,7 @@ sCA_dge_ttest <- function(scEx_log, cells.1, cells.2) { showNotification("sCA_dge_ttest", id = "sCA_dge_ttest", duration = NULL) } if (.schnappsEnv$DEBUGSAVE) { - save(file = "~/SCHNAPPsDebug/sCA_dge_ttest.RData", list = c(ls(), ls(envir = globalenv()))) + save(file = "~/SCHNAPPsDebug/sCA_dge_ttest.RData", list = c(ls())) } # load(file='~/SCHNAPPsDebug/sCA_dge_ttest.RData') @@ -294,9 +307,10 @@ sCA_dge_ttest <- function(scEx_log, cells.1, cells.2) { p_val <- apply(subsetExpression, 1, function(x) t.test(x[cells.1], x[cells.2])$p.value) p_val[is.na(p_val)] <- 1 - - data.1 <- apply(subsetExpression[genes.use, cells.1], 1, expMean) - data.2 <- apply(subsetExpression[genes.use, cells.2], 1, expMean) + dat <- subsetExpression[genes.use, cells.1] + data.1 <- apply(dat, 1, function(x) expMean(x, normFactor = .schnappsEnv$normalizationFactor)) + dat <- subsetExpression[genes.use, cells.2] + data.2 <- apply(dat, 1, function(x) expMean(x, normFactor = .schnappsEnv$normalizationFactor)) avg_diff <- (data.1 - data.2) retVal <- data.frame(p_val = p_val, avg_diff = avg_diff, symbol = featureData[names(p_val), "symbol"]) @@ -340,8 +354,8 @@ sCA_dge <- reactive({ gCells <- sCA_getCells(projections, cl1, db1, db2) # in case we need counts and not normalized counts - if (dgeFunc %in% c("sCA_dge_deseq2", "sCA_dge_s_poisson", "sCA_dge_s_poisson")) { - scEx_log <- scEx + if (dgeFunc %in% c("sCA_dge_deseq2", "sCA_dge_s_negbinom", "sCA_dge_s_poisson")) { + scEx_log = scEx } retVal <- do.call(dgeFunc, args = list( scEx_log = scEx_log, @@ -535,3 +549,25 @@ subCluster2Dplot <- function() { p1 }) } + +# save to history violoin observer ---- +observe({ + clicked = input$save2HistVolc + if (DEBUG) cat(file = stderr(), "observe input$save2HistVolc \n") + start.time <- base::Sys.time() + on.exit( + if (!is.null(getDefaultReactiveDomain())) { + removeNotification(id = "save2Hist") + } + ) + # show in the app that this is running + if (!is.null(getDefaultReactiveDomain())) { + showNotification("save2Hist", id = "save2Hist", duration = NULL) + } + + add2history(type = "renderPlotly", comment = "volcano plot", + plotData = .schnappsEnv[["sCA_volcanoPlot"]]) + +}) + + diff --git a/inst/app/contributions/sCA_subClusterAnalysis/ui.R b/inst/app/contributions/sCA_subClusterAnalysis/ui.R index 3f848a749f57be15ccc15a7dbcc1c50a1badc7c6..d2e151b43c342de067b2e66b2516a6586e2206e5 100644 --- a/inst/app/contributions/sCA_subClusterAnalysis/ui.R +++ b/inst/app/contributions/sCA_subClusterAnalysis/ui.R @@ -130,7 +130,9 @@ tabList <- list( width = 12, jqui_resizable(plotly::plotlyOutput("sCA_volcanoPlot")) ) - ) + ), + br(), + actionButton("save2HistVolc", "save to history") ), box( title = "Differentially Expressed Genes", solidHeader = TRUE, width = 12, status = "primary", diff --git a/inst/app/moduleServer.R b/inst/app/moduleServer.R index aee1f9a0a90915881169808e1a3bb46f72af8da5..4c1ac53182b907863f362e7d0dade074b3cd74a9 100644 --- a/inst/app/moduleServer.R +++ b/inst/app/moduleServer.R @@ -118,6 +118,29 @@ clusterServer <- function(input, output, session, } }) + # observe save 2 history ---- + observe({ + clicked = input$save2Hist + if (DEBUG) cat(file = stderr(), "observe input$save2Hist \n") + myns <- session$ns("-") + req(.schnappsEnv[[paste0("historyPlot-",myns)]]) + start.time <- base::Sys.time() + if (DEBUG) cat(file = stderr(), "cluster: save2Hist\n") + on.exit( + if (!is.null(getDefaultReactiveDomain())) { + removeNotification(id = "save2Hist") + } + ) + # show in the app that this is running + if (!is.null(getDefaultReactiveDomain())) { + showNotification("save2Hist", id = "save2Hist", duration = NULL) + } + + add2history(type = "renderPlotly", + plotData = .schnappsEnv[[paste0("historyPlot-",myns)]], + comment = paste(myns)) + + }) # clusterServer - updateInput ---- # updateInput <- @@ -142,12 +165,12 @@ clusterServer <- function(input, output, session, selected = .schnappsEnv$dim1 ) updateSelectInput(session, "dimension_y", - choices = c(colnames(projections), "UmiCountPerGenes", "UmiCountPerGenes2"), - selected = .schnappsEnv$dim2 + choices = c(colnames(projections), "histogram", "UmiCountPerGenes", "UmiCountPerGenes2"), + selected = .schnappsEnv$dim2 ) updateSelectInput(session, "dimension_col", - choices = c(colnames(projections), "UmiCountPerGenes", "UmiCountPerGenes2"), - selected = .schnappsEnv$dimCol + choices = c(colnames(projections), "cellDensity" ,"UmiCountPerGenes", "UmiCountPerGenes2"), + selected = .schnappsEnv$dimCol ) updateSelectInput(session, "divideXBy", @@ -193,7 +216,7 @@ clusterServer <- function(input, output, session, scEx_log <- scEx_log() scEx <- scEx() namedGroup <- input$groupNames - grpN <- make.names(input$groupName) + grpN <- make.names(input$groupName, unique = TRUE) grpNs <- groupNames$namesDF if (is.null(projections) | is.null(brushedPs)) { @@ -229,7 +252,7 @@ clusterServer <- function(input, output, session, } if (!namedGroup == "plot") { if (namedGroup %in% colnames(grpNs)) { - return(rownames(grpNs[grpNs[, namedGroup], ])) + return(rownames(grpNs[grpNs[, namedGroup] == "TRUE", ])) } else { return(NULL) } @@ -242,10 +265,11 @@ clusterServer <- function(input, output, session, # cells.names <- rownames(projections)[subset(brushedPs, curveNumber == 0)$pointNumber + 1] # cells.names <- rownames(projections)[subset(brushedPs)$pointNumber + 1] cells.names <- brushedPs$key + cells.names <- cells.names[cells.names %in% colnames(scEx_log)] cells.names <- unique(cells.names[!is.na(cells.names)]) - if (DEBUG) { - cat(file = stderr(), paste("curveNumbers:", unique(brushedPs$curveNumber), "\n")) - } + # if (DEBUG) { + # cat(file = stderr(), paste("curveNumbers:", unique(brushedPs$curveNumber), "\n")) + # } printTimeEnd(start.time, "selectedCellNames") exportTestValues(selectedCellNames = { cells.names @@ -266,8 +290,8 @@ clusterServer <- function(input, output, session, if (DEBUG) cat(file = stderr(), paste("selectedCellNames is null\n")) retVal <- NULL } - grpN <- make.names(input$groupName) - grpSelected <- make.names(input$groupNames) + grpN <- make.names(input$groupName, unique = TRUE) + grpSelected <- make.names(input$groupNames, unique = TRUE) grpNs <- groupNames$namesDF if (length(grpN) == 0 | length(grpNs) == 0) { if (DEBUG) cat(file = stderr(), "reactiveValues: grpN empty\n") @@ -304,7 +328,13 @@ clusterServer <- function(input, output, session, subsetData <- subset(projections, dbCluster %in% inpClusters) grpSubset <- grpNs[rownames(subsetData), ] - grpVal <- rownames(grpSubset[grpSubset[, grpN], ]) + if (!grpN %in% colnames(grpSubset)) { + if (!is.null(getDefaultReactiveDomain())) { + showNotification("group name is not available", id = "nogrpN", duration = NULL, type = "error") + } + return(NULL) + } + grpVal <- rownames(grpSubset[grpSubset[, grpN] == "TRUE", ]) if (length(grpVal) > 0) { return(grpVal) } @@ -373,7 +403,7 @@ clusterServer <- function(input, output, session, projections <- projections() grpNs <- groupNames$namesDF grpN <- make.names(input$groupName) - + grpN <- make.names(input$groupName, unique = TRUE) # returnValues$cluster <- input$clusters dimY <- input$dimension_y dimX <- input$dimension_x @@ -395,6 +425,7 @@ clusterServer <- function(input, output, session, } if (is.null(scEx) | is.null(tdata)) { if (DEBUG) cat(file = stderr(), paste("output$clusterPlot:NULL\n")) + .schnappsEnv[[paste0("historyPlot-",myns)]] <- NULL return(NULL) } # in case the normalization is not done @@ -414,7 +445,7 @@ clusterServer <- function(input, output, session, cat(file = stderr(), paste("cluster plot saving done\n")) } - # load(file=paste0("~/SCHNAPPsDebug/clusterPlot", "ns", ".RData", collapse = "."));.schnappsEnv$DEBUGSAVE=FALSE + # load("/Users/bernd/SCHNAPPsDebug/clusterPlot-coE_selected--.RData");.schnappsEnv$DEBUGSAVE=FALSE if (is.null(g_id) || nchar(g_id) == 0) { g_id <- featureData$symbol } @@ -442,9 +473,16 @@ clusterServer <- function(input, output, session, geneNames2, dimX, dimY, clId, grpN, legend.position, grpNs = grpNs, logx, logy, divXBy, divYBy, dimCol, colors = myColors ) - if (save2History) recHistory(myns, p1) + + # save p1 to .schnappsEnv for saving to history + .schnappsEnv[[paste0("historyPlot-",myns)]] <- p1 + + # add2history(type = "renderPlotly", plotData = p1, comment = paste(myns)) + # if (save2History) recHistory(myns, p1) # event_register(p1, 'plotly_selected') printTimeEnd(start.time, "clusterPlot") + # browser() + # .schnappsEnv[[paste0()]] <- p exportTestValues(clusterPlot = { p1 }) @@ -536,7 +574,7 @@ clusterServer <- function(input, output, session, cat(file = stderr(), "save: changeGroups\n") save(file = "~/SCHNAPPsDebug/changeGroups.RData", list = c(ls(), ls(envir = globalenv()))) cat(file = stderr(), "done save: changeGroups\n") - browser() + # browser() } # load(file="~/SCHNAPPsDebug/changeGroups.RData") # in case the cell selection has changed @@ -548,6 +586,7 @@ clusterServer <- function(input, output, session, grpNs[rownames(visibleCells), grpN] <- FALSE } grpNs[cells.names, grpN] <- TRUE + grpNs[, grpN] <- as.factor(grpNs[, grpN] ) # Set reactive value # cat(file = stderr(), paste("DEBUG: ",cells.names," \n")) groupNames$namesDF <- grpNs @@ -595,8 +634,9 @@ clusterServer <- function(input, output, session, if (!is.null(getDefaultReactiveDomain())) { showNotification("nCellsVisibleSelected", id = "nCellsVisibleSelected", duration = NULL) } + + grpN <- make.names(input$groupName, unique = TRUE) - grpN <- make.names(input$groupName) grpNs <- groupNames$namesDF # inpClusters <- input$clusters projections <- projections() @@ -610,8 +650,9 @@ clusterServer <- function(input, output, session, inpClusters <- levels(projections$dbCluster) subsetData <- subset(projections, dbCluster %in% inpClusters) - retVal <- paste("Number of visible cells in section", sum(grpNs[rownames(subsetData), grpN])) + retVal <- paste("Number of visible cells in section", sum(grpNs[rownames(subsetData), grpN] == "TRUE")) + exportTestValues(DummyReactive = { retVal }) @@ -726,15 +767,17 @@ clusterServer <- function(input, output, session, scEx_log <- scEx_log() # moreOptions <- input$moreOptions retVal <- selectedCellNames() - grpN <- make.names(input$groupName) - grpSelected <- make.names(input$groupNames) + grpN <- make.names(input$groupName, unique = TRUE) + grpSelected <- make.names(input$groupNames, unique = TRUE) grpNs <- groupNames$namesDF - + myns <- ns("cellSelection") if (!myshowCells) { + .schnappsEnv[[paste0("historyPlot-",myns)]] <- NULL return("") } if (is.null(projections)) { + .schnappsEnv[[paste0("historyPlot-",myns)]] <- NULL return("") } if (.schnappsEnv$DEBUGSAVE) { @@ -757,6 +800,8 @@ clusterServer <- function(input, output, session, # cells.names <- cells.names[!is.na(cells.names)] retVal <- paste(retVal, collapse = ", ") + .schnappsEnv[[paste0("historyPlot-",myns)]] <- retVal + exportTestValues(ClusterCellSelection = { retVal }) @@ -783,6 +828,27 @@ tableSelectionServer <- function(input, output, session, assign(ns("colOrder"), list(), envir = .schnappsEnv) assign(ns("modSelectedRows"), c(), envir = .schnappsEnv) + observe({ + clicked = input$save2HistTabUi + myns <- session$ns("cellNameTable") + if (DEBUG) cat(file = stderr(), "observe input$save2HistTabUi \n") + start.time <- base::Sys.time() + on.exit( + if (!is.null(getDefaultReactiveDomain())) { + removeNotification(id = "save2Hist") + } + ) + # show in the app that this is running + if (!is.null(getDefaultReactiveDomain())) { + showNotification("save2Hist", id = "save2Hist", duration = NULL) + } + req(.schnappsEnv[[paste0("historyPlot-",myns)]]) + add2history(type = "renderDT", comment = "Table", + tableData = .schnappsEnv[[paste0("historyPlot-",myns)]] ) + + }) + + output$rowSelection <- renderText({ if (DEBUG) cat(file = stderr(), "cellSelection\n") start.time <- Sys.time() @@ -802,7 +868,7 @@ tableSelectionServer <- function(input, output, session, selectedRows <- input$cellNameTable_rows_selected scEx <- scEx() # update if expanded and not showing - input$refreshtable + # input$refreshtable # we only need this for the removed genes table, so to not use too much memory we introduce this if statement inputData <- NULL @@ -896,6 +962,7 @@ tableSelectionServer <- function(input, output, session, # renderDT cellNameTable ---- output$cellNameTable <- DT::renderDT({ + myns <- session$ns("cellNameTable") if (DEBUG) cat(file = stderr(), "output$cellNameTable\n") start.time <- base::Sys.time() on.exit( @@ -915,6 +982,7 @@ tableSelectionServer <- function(input, output, session, selectedRows <- input$cellNameTable_rows_selected # searchStr <- if (is.null(dataTables)) { + .schnappsEnv[[paste0("historyPlot-",myns)]] <- NULL return(NULL) } if (.schnappsEnv$DEBUGSAVE) { @@ -958,22 +1026,24 @@ tableSelectionServer <- function(input, output, session, } } # if (DEBUG) cat(file = stderr(), paste(colState$search,"\n")) + dtout <- DT::datatable(dataTables, + rownames = F, + filter = "top", + selection = list(mode = "multiple", selected = get(ns("modSelectedRows"), envir = .schnappsEnv)), + options = list( + orderClasses = TRUE, + autoWidth = TRUE, + scrollX = TRUE, + pageLength = get(ns("pageLength"), envir = .schnappsEnv), + search = colState$search, + searchCols = searchColList, + stateSave = TRUE, + order = get(ns("colOrder"), envir = .schnappsEnv) + ) + ) + .schnappsEnv[[paste0("historyPlot-",myns)]] <- dtout return( - DT::datatable(dataTables, - rownames = F, - filter = "top", - selection = list(mode = "multiple", selected = get(ns("modSelectedRows"), envir = .schnappsEnv)), - options = list( - orderClasses = TRUE, - autoWidth = TRUE, - scrollX = TRUE, - pageLength = get(ns("pageLength"), envir = .schnappsEnv), - search = colState$search, - searchCols = searchColList, - stateSave = TRUE, - order = get(ns("colOrder"), envir = .schnappsEnv) - ) - ) + dtout ) } else { return(warning("test")) @@ -1012,6 +1082,31 @@ pHeatMapModule <- function(input, output, session, outfilePH <- NULL + # observe save 2 history ---- + observe({ + clicked <- input$save2HistHM + if (DEBUG) cat(file = stderr(), "observe input$save2Hist \n") + myns <- ns("pHeatMap") + # browser() + req(.schnappsEnv[[paste0("historyPlot-",myns)]]) + start.time <- base::Sys.time() + if (DEBUG) cat(file = stderr(), "cluster: save2Hist\n") + on.exit( + if (!is.null(getDefaultReactiveDomain())) { + removeNotification(id = "save2Hist") + } + ) + # show in the app that this is running + if (!is.null(getDefaultReactiveDomain())) { + showNotification("save2Hist", id = "save2Hist", duration = NULL) + } + + add2history(type = "tronco", + plotData = .schnappsEnv[[paste0("historyPlot-",myns)]], + comment = paste(myns)) + + }) + # pHeatMapModule - updateInput ---- # updateInput <- # this is calling projections during loading of data @@ -1075,6 +1170,7 @@ pHeatMapModule <- function(input, output, session, # moreOptions <- input$moreOptions colTree <- input$showColTree scale <- input$normRow + myns <- ns("pHeatMap") save2History <- input$save2History pWidth <- input$heatmapWidth pHeight <- input$heatmapHeight @@ -1089,6 +1185,7 @@ pHeatMapModule <- function(input, output, session, # load(file = "~/SCHNAPPsDebug/pHeatMapPlotModule.RData") if (is.null(heatmapData) | is.null(proje) | is.null(heatmapData$mat)) { + .schnappsEnv[[paste0("historyPlot-",myns)]] <- NULL return(list( src = "empty.png", contentType = "image/png", @@ -1161,6 +1258,8 @@ pHeatMapModule <- function(input, output, session, heatmapData$width <- pWidth / 72 heatmapData$height <- pHeight / 72 do.call(TRONCO::pheatmap, heatmapData) + + .schnappsEnv[[paste0("historyPlot-",myns)]] <- heatmapData # library(seriation) # hm <- hmap(x, method = "HC_ward", main = "HC_ward") @@ -1174,7 +1273,7 @@ pHeatMapModule <- function(input, output, session, # if (is.null(height)) { # height <- 96 * 7 # } - outfilePH <<- outfile + outfilePH <- outfile return(list( src = outfilePH, contentType = "image/png", diff --git a/inst/app/modulesUI.R b/inst/app/modulesUI.R index 05f6e565be219e9d14a06ad9947511d01b064070..dc1229607a540890e94cdfcf66f6509a4967d405 100644 --- a/inst/app/modulesUI.R +++ b/inst/app/modulesUI.R @@ -38,25 +38,25 @@ clusterUI <- function(id) { column( width = 4, selectInput(ns("dimension_x"), - label = "X", - choices = c("tsne1", "tsne2", "tsne3"), - selected = "tsne1" + label = "X", + choices = c("tsne1", "tsne2", "tsne3"), + selected = "tsne1" ) ), column( width = 4, selectInput(ns("dimension_y"), - label = "Y", - choices = c("tsne1", "tsne2", "tsne3"), - selected = "tsne2" + label = "Y", + choices = c("tsne1", "tsne2", "tsne3"), + selected = "tsne2" ) ), column( width = 4, selectInput(ns("dimension_col"), - label = "color", - choices = c("Gene.count"), - selected = "Gene.count" + label = "color", + choices = c("Gene.count"), + selected = "Gene.count" ) ) ), @@ -83,37 +83,37 @@ clusterUI <- function(id) { column( width = 3, selectInput(ns("divideXBy"), - label = "Divide X by", - # choices = c("None", "Gene.count", "UMI.count"), - choices = c("None", "UmiCountPerGenes", "UmiCountPerGenes2"), - selected = "None" + label = "Divide X by", + # choices = c("None", "Gene.count", "UMI.count"), + choices = c("None", "UmiCountPerGenes", "UmiCountPerGenes2"), + selected = "None" ) ), column( width = 3, selectInput(ns("divideYBy"), - label = "Divide Y by", - # choices = c("None", "Gene.count", "UMI.count"), - choices = c("None", "UmiCountPerGenes", "UmiCountPerGenes2"), - selected = "None" + label = "Divide Y by", + # choices = c("None", "Gene.count", "UMI.count"), + choices = c("None", "UmiCountPerGenes", "UmiCountPerGenes2"), + selected = "None" ) ) ), fluidRow( - column( - width = 12, - checkboxInput(ns("addToGroup"), "Add to group/otherwise overwrite", TRUE), - textInput(ns(id = "groupName"), label = "name group, also used in Plot to color selected cells red.", value = "cellGroupName"), - selectInput(ns("groupNames"), - label = "group names, !When modifying a group this list of cells is used as a reference!", - choices = c("plot"), - selected = "plot" - ), - verbatimTextOutput(ns("nCellsVisibleSelected")), - actionButton(ns("changeGroups"), "change current selection"), - checkboxInput(ns("showCells"), "show cell names", FALSE), - verbatimTextOutput(ns("cellSelection")), - uiOutput(ns("additionalOptions")) # TODO:is this still needed??? + column(width = 12, + checkboxInput(ns("addToGroup"), "Add to group/otherwise overwrite", TRUE), + textInput(ns(id = "groupName"), label = "name group, also used in Plot to color selected cells red.", value = "cellGroupName"), + selectInput(ns("groupNames"), + label = "group names, !When modifying a group this list of cells is used as a reference!", + choices = c("plot"), + selected = "plot" + ), + verbatimTextOutput(ns("nCellsVisibleSelected")), + actionButton(ns("changeGroups"), "change current selection"), + checkboxInput(ns("showCells"), "show cell names", FALSE), + verbatimTextOutput(ns("cellSelection")), + actionButton(ns("save2Hist"), "save to history"), + uiOutput(ns("additionalOptions")) # TODO:is this still needed??? ) ) ) @@ -139,21 +139,27 @@ tableSelectionUi <- function(id) { h5("Selected itmes to be copied"), align = "left" ), - verbatimTextOutput(ns("rowSelection")) + verbatimTextOutput(ns("rowSelection")), + )), + fluidRow( + column(width = 3, + actionButton(ns("save2HistTabUi"), "Save to history"), ) - ), + # , + # column( + # width = 3, + # actionButton(ns("refreshtable"), "Refresh table"), + # ) + ) + ), + box( + width = 12, fluidRow( column( width = 3, - downloadButton(ns("download_cellNameTable"), "Download table") - ), - column( - width = 3, - actionButton(ns("refreshtable"), "Refresh table"), - ) - ), + h4("Cells", offset = 1) + )), fluidRow( - h4("Cells", offset = 1), column( width = 3, checkboxInput(ns("selectAll"), "Select all rows", FALSE) @@ -177,79 +183,75 @@ tableSelectionUi <- function(id) { pHeatMapUI <- function(id) { ns <- NS(id) tagList( - box( - width = 12, - fluidRow( - column( - width = 12, - jqui_resizable(plotOutput(ns("pHeatMapPlot"), - # height = "auto", - brush = brushOpts(id = "crh1") - ), options = list(width = "99%")) - ) - ), - box( - title = "additional options", solidHeader = TRUE, width = 12, status = "primary", - collapsible = TRUE, collapsed = TRUE, - fluidRow( - column( - width = 12, - # checkboxInput(ns("moreOptions"), "show more options", FALSE), - checkboxInput(ns("showColTree"), label = "Show tree for cells", value = FALSE), - ) - ), - fluidRow( - column( - width = 6, - selectInput(ns("normRow"), - label = "scale by row (for color)", - choices = c("row", "column", "none"), - selected = "none" - ), - selectInput( - ns("ColNames"), - label = "group names", - choices = c(), - selected = "sampleNames", - multiple = TRUE - ), - - selectInput( - ns("orderNames"), - label = "order of columns", - choices = c(), - selected = "", - multiple = TRUE - ) - ), - column( - width = 6, - numericInput( - ns("heatmapWidth"), - label = "width of image in pixel", - min = 100, max = 20000, step = 10, - value = 800 - ), - numericInput( - ns("heatmapHeight"), - label = "height of image in pixel", - min = 200, max = 20000, step = 10, - value = 300 - ) - ) - ), - fluidRow( - column( - width = 12, - # uiOutput(ns("additionalOptions")), - downloadButton(ns("download_pHeatMapUI"), "Download PlotData") - ) - ) - - # checkboxInput(ns("showCells"), "show cell names", FALSE), - # - # verbatimTextOutput(ns('cellSelection')) - ) # box + box( width = 12, + fluidRow( + column(width = 12, + jqui_resizable(plotOutput(ns("pHeatMapPlot"), + # height = "auto", + brush = brushOpts(id = "crh1") + ),options = list( width="99%")) + ) + ), + box( + title = "additional options", solidHeader = TRUE, width = 12, status = 'primary', + collapsible = TRUE, collapsed = TRUE, + fluidRow( + column(width = 12, + # checkboxInput(ns("moreOptions"), "show more options", FALSE), + checkboxInput(ns("showColTree"), label = "Show tree for cells", value = FALSE), + ) + ), + fluidRow( + column(width = 6, + selectInput(ns("normRow"), + label = "scale by row (for color)", + choices = c("row", "column", "none"), + selected = "none" + ), + selectInput( + ns("ColNames"), + label = "group names", + choices = c(), + selected = "sampleNames", + multiple = TRUE + ), + + selectInput( + ns("orderNames"), + label = "order of columns", + choices = c(), + selected = "", + multiple = TRUE + ) + ), + column(width = 6, + numericInput( + ns("heatmapWidth"), + label = "width of image in pixel", + min = 100, max = 20000, step = 10, + value = 800 + ), + numericInput( + ns("heatmapHeight"), + label = "height of image in pixel", + min = 200, max = 20000, step = 10, + value = 300 + )) + ), + fluidRow( + column(width = 12, + # uiOutput(ns("additionalOptions")), + downloadButton(ns("download_pHeatMapUI"), "Download PlotData"), + actionButton(ns("save2HistHM"), "save to history") + + ) + ) + + # checkboxInput(ns("showCells"), "show cell names", FALSE), + # + # verbatimTextOutput(ns('cellSelection')) + + ) # box ) ) } diff --git a/inst/app/outputs.R b/inst/app/outputs.R index c220fcbe11af0e59d1ae08cf68c926537f6f9bbc..886ae158f051d5f5a1c45819b1394ecaca36123a 100644 --- a/inst/app/outputs.R +++ b/inst/app/outputs.R @@ -339,14 +339,19 @@ output$DEBUGSAVEstring <- renderText({ } }) -output$save2Historystring <- renderText({ - if (DEBUG) { - .schnappsEnv$saveHistorycheckbox <- input$save2History - saveHistorycheckbox <- input$save2History - } else { - NULL - } -}) +# output$currentTabInfo <- renderText({ +# # browser() +# str(input$sideBarID) +# }) + +# output$save2Historystring <- renderText({ +# if (DEBUG) { +# .schnappsEnv$saveHistorycheckbox <- input$save2History +# saveHistorycheckbox <- input$save2History +# } else { +# NULL +# } +# }) # cellSelectionMod ---- callModule(tableSelectionServer, "cellSelectionMod", inputSample) @@ -430,6 +435,53 @@ output$clusterColorSelection <- renderUI({ }) }) +# history store to file ---- +#' + +askComment <- function(failed = FALSE) { + modalDialog( + textInput("HistComment", "add a comment", value = paste("created at ",date())), + footer = tagList( + modalButton("Cancel"), + actionButton("HistCommentok", "OK") + ) + ) +} +observeEvent(input$HistCommentok, { + if (DEBUG) { + cat(file = stderr(), "writing history.\n") + } + start.time <- base::Sys.time() + on.exit({ + printTimeEnd(start.time, "HistCommentok") + if (!is.null(getDefaultReactiveDomain())) { + removeNotification(id = "HistCommentok") + } + }) + if (!is.null(getDefaultReactiveDomain())) { + showNotification("writing history", id = "HistCommentok", duration = NULL) + } + + panelLinkHistory = list("coexpressionSelected" = "coE") + id <- input$sideBarID + cat(file = stderr(), paste0("observeEvent input$save2History\n")) + save(file = "~/SCHNAPPsDebug/save2History.RData", list = c(ls(), ls(envir = globalenv()))) + # cp =load(file="~/SCHNAPPsDebug/save2History.RData") + lsS = ls(envir = .schnappsEnv) + for (pl in lsS[grep(paste0("^historyPlot-",panelLinkHistory[[id]]), lsS)]) { + cat(file = stderr(), paste0("writing to history: ",pl ,"\n")) + sp <- strsplit( pl, "-" )[[1]] + recHistory(sp[[length(sp)]], .schnappsEnv[[pl]], envir = .schnappsEnv) + + } + + removeModal() + +}) + +observeEvent(input$save2History, { + showModal(askComment()) +}) # observe: input$updateColors ---- observeEvent( @@ -704,7 +756,7 @@ observe(label = "ob27", { observe(label = "ob28", { input$newPrj - updateTextInput(session, "newPrj", value = make.names(input$newPrj)) + updateTextInput(session, "newPrj", value = make.names(input$newPrj, unique = TRUE)) }) observeEvent( diff --git a/inst/app/reactives.R b/inst/app/reactives.R index 53b843d0a3ad4f5690fe1106c2fad3ad0a9d40d4..c17dcd00a945071b6e1c183d3d6b2561d4fe9958 100644 --- a/inst/app/reactives.R +++ b/inst/app/reactives.R @@ -36,6 +36,114 @@ if ("crayon" %in% rownames(installed.packages()) == FALSE) { } +# <- reactive({ +output$dimPlotPCA <- renderPlot({ + if (DEBUG) { + cat(file = stderr(), "dimPlotPCA started.\n") + } + start.time <- base::Sys.time() + on.exit({ + printTimeEnd(start.time, "dimPlotPCA") + if (!is.null(getDefaultReactiveDomain())) { + removeNotification(id = "dimPlotPCA") + } + }) + if (!is.null(getDefaultReactiveDomain())) { + showNotification("dimPlotPCA", id = "dimPlotPCA", duration = NULL) + } + + input$updateDimPlot + scEx_log <- isolate(scEx_log()) + scEx <- isolate(scEx()) + pca <- isolate(pca()) + if (is.null(scEx_log)) { + if (DEBUG) { + cat(file = stderr(), "dimPlotPCA:NULL\n") + } + return(0) + } + # if (.schnappsEnv$DEBUGSAVE) { + save(file = "~/SCHNAPPsDebug/dimPlotPCA.RData", list = c(ls())) + # } + # load(file='~/SCHNAPPsDebug/dimPlotPCA.RData') + + # return NuLL because it is not working correctly + return(NULL) + + scEx = scEx[rownames(pca$rotation),] + scEx_log = scEx_log[rownames(pca$rotation),] + + cellMeta = colData(scEx_log) + rData = rowData(scEx) + meta.data = cellMeta[,"sampleNames", drop = FALSE] + dat = assays(scEx)[[1]][rownames(scEx_log),] + rownames(dat) = rData[rownames(scEx_log),"symbol"] + rownames(pca$rotation) = rData[rownames(pca$rotation),"symbol"] + seurDat <- CreateSeuratObject( + counts = dat, + meta.data = meta.data + ) + + # TODO use scEx_log + logDat = assays(scEx_log)[[1]] + rData = rowData(scEx_log) + rownames(logDat) = rData$symbol + seurDat@assays$RNA@data = as(logDat,"dgCMatrix") + # seurDat <- NormalizeData(seurDat, normalization.method = "LogNormalize", scale.factor = 10000) + # seurDat <- FindVariableFeatures(seurDat, selection.method = "vst", nfeatures = 2000) + + # recalculating because createDimReducObject is not working + all.genes <- rownames(seurDat) + seurDat <- ScaleData(seurDat, features = all.genes) + seurDat <- RunPCA(seurDat, features = VariableFeatures(object = seurDat)) + + colnames(pca$x) = str_replace(colnames(pca$x), "PC", "PC_") + + # not working + seurDat[["pca"]] = CreateDimReducObject(embeddings = pca$rotation, loadings = pca$x[colnames(seurDat),], stdev = pca$var_pcs, key = "PC_", assay = "RNA") + seurDat <- ProjectDim(object = seurDat, reduction = "pca", assay = "RNA") + + # DimPlot(seurDat, reduction = "pca") + + d = DimHeatmap(seurDat, dims = 1:15, cells = NULL, balanced = TRUE, fast = FALSE, projected = TRUE, reduction = "pca") + d +}) + +# add comment to history ---- + +commentModal <- function(failed = FALSE) { + modalDialog( + # TODO + # mce not working, maybe this helps eventually: https://github.com/twbs/bootstrap/issues/549 + # if ("shinyMCE" %in% rownames(installed.packages())) { + # shinyMCE::tinyMCE( + # "Comment4history", + # "Please describe your work. This will be included in the history" + # ) + # } else { + textInput("Comment4history", "Please describe your work. This will be included in the history") + # } + , + footer = tagList( + modalButton("Cancel"), + actionButton("commentok", "OK") + ) + ) +} + +# Show modal when button is clicked. +observeEvent(input$comment2History, { + showModal(commentModal()) +}) +# When OK button is pressed, attempt to load the data set. If successful, +# remove the modal. If not show another modal, but this time with a failure +# message. +observeEvent(input$commentok, { + cat(file = stderr(), paste0("commentok: \n")) + comment <- input$Comment4history + add2history(type = "text", comment = "", text2add = comment) + removeModal() +}) # inputDataFunc ---- # loads singleCellExperiment # only counts, rowData, and colData are used. Everything else needs to be recomputed @@ -1025,7 +1133,7 @@ gsRMGenesTable <- reactive({ ) } # load("~/SCHNAPPsDebug/removedGenesTable.RData") - + scEx <- assays(dataTables$scEx)[[1]] fd <- rowData(dataTables$scEx) dt <- fd[useGenes, ] @@ -1039,7 +1147,7 @@ gsRMGenesTable <- reactive({ firstCol <- firstCol <- c(firstCol, which(colnames(dt) %in% c("rowSums", "rowSamples"))) colOrder <- c(firstCol, (1:ncol(dt))[-firstCol]) dt <- dt[, colOrder] - + # dt <- dt[dt$rowSums < minGenes, ] exportTestValues(removedGenesTable = { as.data.frame(dt) @@ -1312,8 +1420,8 @@ scEx <- reactive({ minG = minG, maxG = maxG ) - - + scEx = retVal + add2history(type = "save", comment = "scEx", scEx = retVal) exportTestValues(scEx = { list(rowData(retVal), colData(retVal)) }) @@ -1397,6 +1505,8 @@ scEx_log <- reactive({ } .schnappsEnv$calculated_normalizationRadioButton <- normMethod + add2history(type = "save", comment = "scEx_log", scEx_log = scEx_log) + exportTestValues(scEx_log = { assays(scEx_log)["logcounts"] }) @@ -1468,11 +1578,13 @@ scExLogMatrixDisplay <- reactive({ # rownames(retVal) <- # make.names(rowData(scEx)$symbol, unique = TRUE) } - + rownames(retVal) <- + retVal$symbol + return(retVal) }) -pcaFunc <- function(scEx_log, rank, center, scale, pcaGenes, featureData, pcaN) { +pcaFunc <- function(scEx_log, rank, center, scale, pcaGenes, featureData, pcaN, maxGenes = 100) { if (DEBUG) { cat(file = stderr(), "pcaFunc started.\n") } @@ -1491,7 +1603,7 @@ pcaFunc <- function(scEx_log, rank, center, scale, pcaGenes, featureData, pcaN) } if (.schnappsEnv$DEBUGSAVE) { - save(file = "~/SCHNAPPsDebug/pcaFunc.RData", list = c(ls(), ls(envir = globalenv()))) + save(file = "~/SCHNAPPsDebug/pcaFunc.RData", list = c(ls())) } # load(file="~/SCHNAPPsDebug/pcaFunc.RData") genesin <- geneName2Index(pcaGenes, featureData) @@ -1548,23 +1660,41 @@ pcaFunc <- function(scEx_log, rank, center, scale, pcaGenes, featureData, pcaN) assays(scEx_log)[["logcounts"]] <- as(assays(scEx_log)[["logcounts"]], "dgCMatrix") } - BiocSingular::runPCA( - # t(assays(scEx_log)[["logcounts"]]), - scEx_log[genesin, ], - ncomponents = rank, - ntop = pcaN, - exprs_values = "logcounts", - # rank = rank, - # center = center, - scale = scale - # , - # method = "irlba", - # BPPARAM = bpparam(), - # BPPARAM = SnowParam(workers = 3, type = "SOCK), - # BPPARAM = MulticoreParam( - # workers = ifelse(detectCores()>1, detectCores()-1, 1)) - # BSPARAM = IrlbaParam() - ) + x <- assays(scEx_log)[["logcounts"]] + genesin = genesin[genesin %in% rownames(scEx_log)] + x <- as.matrix(x)[genesin, , drop = FALSE] + rv <- rowVars((as.matrix(x))) + if (scale) { + if(maxGenes > 0) { + keep <- order(rv, decreasing = TRUE)[1:maxGenes] + } else { + keep <- rv >= 1e-8 + } + x <- x[keep,,drop=FALSE]/sqrt(rv[keep]) + rv <- rep(1, nrow(x)) + } + x <- t(x) + pca <- runPCA(x, rank=rank, get.rotation=TRUE) + rownames(pca$rotation) = genesin[keep] + rownames(pca$x) = colnames(scEx_log) + pca + # BiocSingular::runPCA( + # x, + # # scEx_log[genesin, ], + # # ncomponents = rank, + # ntop = pcaN, + # # exprs_values = "logcounts", + # rank = rank, + # # center = center, + # scale = scale + # # , + # # method = "irlba", + # # BPPARAM = bpparam(), + # # BPPARAM = SnowParam(workers = 3, type = "SOCK), + # # BPPARAM = MulticoreParam( + # # workers = ifelse(detectCores()>1, detectCores()-1, 1)) + # # BSPARAM = IrlbaParam() + # ) }) if (is.null(scaterPCA)) { @@ -1575,16 +1705,16 @@ pcaFunc <- function(scEx_log, rank, center, scale, pcaGenes, featureData, pcaN) # # rownames(scaterPCA$x) = colnames(scEx_log) return(list( - # x = scaterPCA$x, - x = SingleCellExperiment::reducedDim(scaterPCA, "PCA"), - # var_pcs = scaterPCA$sdev - var_pcs = attr( - SingleCellExperiment::reducedDim(scaterPCA, "PCA"), - "percentVar" - ) + x = scaterPCA$x, + # x = SingleCellExperiment::reducedDim(scaterPCA, "PCA"), + var_pcs = scaterPCA$sdev, + rotation = scaterPCA$rotation + # var_pcs = attr( + # SingleCellExperiment::reducedDim(scaterPCA, "PCA"), + # "percentVar" + # ) )) } - # pca ---- pca <- reactive({ if (DEBUG) { @@ -1943,7 +2073,9 @@ projections <- reactive({ projections <- pd if (!is.null(pca)) { - projections <- cbind(projections, pca$x[rownames(projections), ]) + comColNames = colnames(projections) %in% colnames(pca$x) + colnames(projections)[comColNames] = paste0(colnames(projections)[comColNames], ".old") + projections <- cbind(projections, pca$x[rownames(projections),]) } withProgress(message = "Performing projections", value = 0, { @@ -1968,9 +2100,9 @@ projections <- reactive({ # browser() # TODO here, dbCluster is probably overwritten and appended a ".1" if (is(tmp, "data.frame")) { - cn <- make.names(c(colnames(projections), colnames(tmp))) + cn <- make.names(c(colnames(projections), colnames(tmp)), unique = TRUE) } else { - cn <- make.names(c(colnames(projections), make.names(proj[1]))) + cn <- make.names(c(colnames(projections), make.names(proj[1])), unique = TRUE) } if (length(tmp) == 0) { next() @@ -2036,7 +2168,8 @@ projections <- reactive({ if (!"sampleNames" %in% colnames(projections)) { projections$sampleNames <- "1" } - + add2history(type = "save", comment = "projections", projections = projections) + exportTestValues(projections = { projections }) @@ -2044,7 +2177,7 @@ projections <- reactive({ }) # initializeGroupNames ---- -# TODO shouldn't this be an observer??? +# TODO shouldn't this be an observer??? or just a function??? initializeGroupNames <- reactive({ if (DEBUG) { cat(file = stderr(), "initializeGroupNames started.\n") @@ -2067,22 +2200,31 @@ initializeGroupNames <- reactive({ if (is.null(scEx)) { return(NULL) } - if (.schnappsEnv$DEBUGSAVE) { - save(file = "~/SCHNAPPsDebug/initializeGroupNames.RData", list = c(ls(), ls(envir = globalenv()))) - } - # load(file="~/SCHNAPPsDebug/initializeGroupNames.RData") isolate({ - df <- - data.frame( - all = rep(TRUE, dim(scEx)[2]), - none = rep(FALSE, dim(scEx)[2]) - ) - rownames(df) <- colnames(scEx) - groupNames$namesDF <- df + grpNs <- groupNames$namesDF + if (.schnappsEnv$DEBUGSAVE) { + save(file = "~/SCHNAPPsDebug/initializeGroupNames.RData", list = c(ls(), ls(envir = globalenv()))) + } + # load(file="~/SCHNAPPsDebug/initializeGroupNames.RData") + # TODO ??? if cells have been removed it is possible that other cells that were excluded previously show up + # this will invalidate all previous selections. + if (is_empty(data.frame()) | !all(colnames(scEx) %in% rownames(grpNs))) { + df <- + data.frame( + all = rep(TRUE, dim(scEx)[2]), + none = rep(FALSE, dim(scEx)[2]) + ) + rownames(df) <- colnames(scEx) + groupNames$namesDF <- df + } else { + groupNames$namesDF = groupNames$namesDF[colnames(scEx),] + } }) }) -observe(label = "ob1", initializeGroupNames()) +# since initializeGroupNames depends on scEx only this will be set when the org data is changed. +observe(initializeGroupNames()) + # sample -------- sample <- reactive({ if (DEBUG) { diff --git a/inst/app/runDevApp.R b/inst/app/runDevApp.R index acc8618f00c622adfeb000dc3038981241854531..b116732ac7971967c08c694a73d2e5f4579454f3 100644 --- a/inst/app/runDevApp.R +++ b/inst/app/runDevApp.R @@ -6,14 +6,15 @@ .schnappsEnv <- new.env(parent=emptyenv()) # } - localContributionDir = "~/Rstudio/scShinyHub-github/bjContributions/" + localContributionDir = "~/Rstudio/scShinyHubContributionsBJ/" # localContributionDir = "" - defaultValueSingleGene = "LYZ" -defaultValueMultiGenes = "tbx18, wt1, msln, edf1, tagln2, anxa5, ctgf, fstl1,naca, rack1, eef2, npm1, bmp4, pparg, ucp2, vim,col1a1, col3a1, col18a1, sparc, bgn, mmp2, postn,ccl2, ccl7, il33, vcan" -defaultValueRegExGene = "" # tip: '^CD7$|^KIT$; genes with min expression + defaultValueSingleGene = "itgae" # CD52 + defaultValueMultiGenes = " itgae, cd69, itga1" # CD52, S100A9, S100A4 + defaultValueMultiGenes = "prf1, Gzmb, IFNG, PDCD1, HAVCR2, LAG3, TSC22D3,ZFP36L2" + defaultValueRegExGene = "" # tip: '^CD7$|^KIT$; genes with min expression DEBUG = TRUE DEBUGSAVE = F -historyFile = "~/Rstudio/Schnapps/history.File.pdf" +historyPath = "~/Rstudio/Schnapps/history" assign(".SCHNAPPs_locContributionDir", localContributionDir, envir = .schnappsEnv) assign(".SCHNAPPs_defaultValueSingleGene", defaultValueSingleGene, envir = .schnappsEnv) @@ -27,7 +28,7 @@ assign("defaultValueMultiGenes", defaultValueMultiGenes, envir = .schnappsEnv) assign("defaultValueRegExGene", defaultValueRegExGene, envir = .schnappsEnv) assign("DEBUG", DEBUG, envir = .schnappsEnv) assign("DEBUGSAVE", DEBUGSAVE, envir = .schnappsEnv) -assign("historyFile", historyFile, envir = .schnappsEnv) +assign("historyPath", historyPath, envir = .schnappsEnv) ls(.schnappsEnv) devscShinyApp = TRUE diff --git a/inst/app/server.R b/inst/app/server.R index 23eebc2ee16d736208dd1430dbf28cfeffa83fb2..9bcf64d0f21cd4228ed065aa6227057d48fe4927 100644 --- a/inst/app/server.R +++ b/inst/app/server.R @@ -124,7 +124,7 @@ scShinyServer <- shinyServer(function(input, output, session) { } # TODO ??? clean directory?? } - + if (exists("devscShinyApp")) { if (devscShinyApp) { packagePath <- "inst/app" @@ -138,10 +138,33 @@ scShinyServer <- shinyServer(function(input, output, session) { "Readme.txt", "report.html", "sessionData.RData", "normalizedCounts.csv", "variables.used.txt" ) - + base::options(shiny.maxRequestSize = 2000 * 1024^2) - + + ### history setup + if (exists("historyPath", envir = .schnappsEnv)) { + if (!is.null(x = .schnappsEnv$historyPath)) { + if (!dir.exists(.schnappsEnv$historyPath)){ + dir.create(.schnappsEnv$historyPath, recursive = T) + } + if (!exists("historyFile", envir = .schnappsEnv)) { + .schnappsEnv$historyFile = paste0("history.",format(Sys.time(), "%Y-%b-%d.%H.%M"),".Rmd") + } + if (is.null(.schnappsEnv$historyFile)) { + .schnappsEnv$historyFile = "history2.Rmd" + } + .schnappsEnv$historyFile <- paste0(.schnappsEnv$historyPath,"/", basename(.schnappsEnv$historyFile)) + line=paste0("---\ntitle: \"history\"\noutput: html_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\n```\n" ) + write(line,file=.schnappsEnv$historyFile,append=FALSE) + + } else { + rm("historyPath", envir = .schnappsEnv) + } + } + + # TODO check if file exists + # TODO as parameter to load user specified information # TODO have this as an option to load other files if (file.exists(paste0(packagePath, "/geneLists.RData"))) { base::load(file = paste0(packagePath, "/geneLists.RData")) @@ -150,16 +173,17 @@ scShinyServer <- shinyServer(function(input, output, session) { geneLists <- list(emtpy = list()) } } - + if (DEBUG) base::cat(file = stderr(), "ShinyServer running\n") # base calculations that are quite expensive to calculate # display name, reactive name to be executed + # TODO do we still need this? heavyCalculations <- list( c("pca", "pca"), c("scran_Cluster", "scran_Cluster"), c("projections", "projections") ) - + # base projections # display name, reactive to calculate projections projectionFunctions <- list( @@ -169,18 +193,18 @@ scShinyServer <- shinyServer(function(input, output, session) { c("before filter", "beforeFilterPrj") ) .schnappsEnv$projectionFunctions <- projectionFunctions - + # differential expression functions # used in subcluster analysis .schnappsEnv$diffExpFunctions <- list() diffExpFunctions <- list() - + # load global reactives, modules, etc ---- base::source(paste0(packagePath, "/reactives.R"), local = TRUE) base::source(paste0(packagePath, "/outputs.R"), local = TRUE) base::source(paste0(packagePath, "/modulesUI.R"), local = TRUE) base::source(paste0(packagePath, "/moduleServer.R"), local = TRUE) - + # bookmarking ---- # couldn't get bookmarking to work, esp. with the input file # setBookmarkExclude(c("bookmark1")) @@ -192,7 +216,7 @@ scShinyServer <- shinyServer(function(input, output, session) { # if (DEBUG) cat(file = stderr(), paste("bookmarking: DONE\n")) # }) # Need to exclude the buttons from themselves being bookmarked - + # load contribution reactives ---- # parse all reactives.R files under contributions to include in application uiFiles <- base::dir( @@ -205,12 +229,12 @@ scShinyServer <- shinyServer(function(input, output, session) { myProjections <- NULL myDiffExpFunctions <- NULL base::source(fp, local = TRUE) - + heavyCalculations <- append2list(myHeavyCalculations, heavyCalculations) projectionFunctions <- append2list(myProjections, projectionFunctions) diffExpFunctions <- append2list(myDiffExpFunctions, diffExpFunctions) } - + # update diffExpression radiobutton dgeChoices <- c() if (length(diffExpFunctions) > 0) { @@ -229,7 +253,7 @@ scShinyServer <- shinyServer(function(input, output, session) { choices = dgeChoices ) .schnappsEnv$diffExpFunctions <- diffExpFunctions - + # load contribution outputs ---- # parse all outputs.R files under contributions to include in application uiFiles <- base::dir( diff --git a/inst/app/serverFunctions.R b/inst/app/serverFunctions.R index 4b69d91b3f528e060a5bec0aead1bb934f7ca234..6b2f5dbd77c870e423cbf1ff98f1d087eea94395 100644 --- a/inst/app/serverFunctions.R +++ b/inst/app/serverFunctions.R @@ -1,5 +1,7 @@ suppressMessages(library(magrittr)) require(digest) + +# printTimeEnd ---- printTimeEnd <- function(start.time, messtr) { end.time <- base::Sys.time() if (DEBUG) { @@ -8,7 +10,7 @@ printTimeEnd <- function(start.time, messtr) { } -# some comments removed because they cause too much traffic +# some comments removed because they cause too much traffic ---- geneName2Index <- function(g_id, featureData) { # if (DEBUG) cat(file = stderr(), "geneName2Index started.\n") # start.time <- base::Sys.time() @@ -53,7 +55,7 @@ geneName2Index <- function(g_id, featureData) { return(geneid) } - +# updateProjectionsWithUmiCount ---- updateProjectionsWithUmiCount <- function(dimX, dimY, geneNames, geneNames2 = NULL, scEx, projections) { featureData <- rowData(scEx) # if ((dimY == "UmiCountPerGenes") | (dimX == "UmiCountPerGenes")) { @@ -88,7 +90,7 @@ updateProjectionsWithUmiCount <- function(dimX, dimY, geneNames, geneNames2 = NU } -# append to heavyCalculations +# append to heavyCalculations ---- append2list <- function(myHeavyCalculations, heavyCalculations) { for (hc in myHeavyCalculations) { if (length(hc) == 2 & is.character(hc[1]) & is.character(hc[2])) { @@ -131,12 +133,19 @@ plot2Dprojection <- function(scEx_log, projections, g_id, featureData, geneNames2 = geneNames2, scEx = scEx_log, projections = projections ) - if (!all(c(dimX, dimY, dimCol) %in% colnames(projections))) { - return(NULL) - } - if (!all(c(dimX, dimY, dimCol) %in% colnames(projections))) { - return(NULL) + # histogram as y and cellDensity as color is not allowed + + if (dimY == "histogram") { + if (!all(c(dimX, dimCol) %in% colnames(projections))) { + return(NULL) + } + } else { + # need to do proper checking of possibilities + # removing dimCol for now + if (!all(c(dimX, dimY) %in% colnames(projections))) { + return(NULL) + } } projections <- cbind(projections, expression) @@ -158,6 +167,12 @@ plot2Dprojection <- function(scEx_log, projections, g_id, featureData, } else { subsetData <- projections } + #ensure that the highest values are plotted last. + if (dimCol %in% colnames(subsetData)){ + if (is.numeric(subsetData[,dimCol])){ + subsetData <- subsetData[order(subsetData[,dimCol]),] + } + } # subsetData$dbCluster = factor(subsetData$dbCluster) # if there are more than 18 samples ggplot cannot handle different shapes and we ignore the # sample information @@ -184,7 +199,7 @@ plot2Dprojection <- function(scEx_log, projections, g_id, featureData, if (divXBy != "None") { subsetData[, dimX] <- subsetData[, dimX] / subsetData[, divXBy] } - if (divYBy != "None") { + if (divYBy != "None" & dimY != "histogram") { subsetData[, dimY] <- subsetData[, dimY] / subsetData[, divYBy] } @@ -198,8 +213,12 @@ plot2Dprojection <- function(scEx_log, projections, g_id, featureData, if (is.factor(subsetData[, dimX]) | is.logical(subsetData[, dimX])) { typeX <- NULL } - if (is.factor(subsetData[, dimY]) | is.logical(subsetData[, dimY])) { - typeY <- NULL + if (dimY != "histogram"){ + if (is.factor(subsetData[, dimY]) | is.logical(subsetData[, dimY])) { + typeY <- NULL + } + } else { + typeX = NULL } xAxis <- list( title = dimX, @@ -214,14 +233,45 @@ plot2Dprojection <- function(scEx_log, projections, g_id, featureData, if (dimX == "barcode") { subsetData$"__dimXorder" <- rank(subsetData[, dimY]) dimX <- "__dimXorder" + if (dimY == "histogram"){ + # Error message + return(NULL) + } } - - if (is.factor(subsetData[, dimX]) | is.logical(subsetData[, dimX])) { - subsetData[, dimX] <- as.character(subsetData[, dimX]) - } - if (is.factor(subsetData[, dimY]) | is.logical(subsetData[, dimY])) { - subsetData[, dimY] <- as.character(subsetData[, dimY]) - } + # save(file = "~/SCHNAPPsDebug/2dplot.RData", list = ls()) + # load("~/SCHNAPPsDebug/2dplot.RData") + + if (dimY != "histogram"){ + if (is.factor(subsetData[, dimX]) | is.logical(subsetData[, dimX])) { + subsetData[, dimX] <- as.character(subsetData[, dimX]) + } + if (is.factor(subsetData[, dimY]) | is.logical(subsetData[, dimY])) { + subsetData[, dimY] <- as.character(subsetData[, dimY]) + } + } else { + # if (is.factor(subsetData[, dimX]) | is.logical(subsetData[, dimX])) { + # # barchart + # # subsetData[, dimX] <- as.character(subsetData[, dimX]) + # } else { + # histogram + p <- plot_ly( x=~subsetData[, dimX], type = "histogram") %>% + layout( + xaxis = xAxis, + yaxis = yAxis, + title = gtitle, + dragmode = "select" + ) + return (p) + # %>% + # layout(yaxis=list(type='linear')) + # } + + } + + if (dimCol == "cellDensity") { + subsetData$cellDensity <- get_density(subsetData[,dimX], subsetData[,dimY], n = 100) + } + # dimCol = "Gene.count" # dimCol = "sampleNames" # subsetData$"__key__" = rownames(subsetData) @@ -255,9 +305,9 @@ plot2Dprojection <- function(scEx_log, projections, g_id, featureData, selectedCells <- NULL if (length(grpN) > 0) { - if (length(grpNs[rownames(subsetData), grpN]) > 0 & sum(grpNs[rownames(subsetData), grpN], na.rm = TRUE) > 0) { + if (length(grpNs[rownames(subsetData), grpN] == "TRUE") > 0 & sum(grpNs[rownames(subsetData), grpN] == "TRUE", na.rm = TRUE) > 0) { grpNSub <- grpNs[rownames(subsetData), ] - selectedCells <- rownames(grpNSub[grpNSub[, grpN], ]) + selectedCells <- rownames(grpNSub[grpNSub[, grpN] == "TRUE", ]) } } if (!is.null(selectedCells)) { @@ -305,11 +355,11 @@ plot2Dprojection <- function(scEx_log, projections, g_id, featureData, # functions should go in external file - +# n_fun ---- n_fun <- function(x) { return(data.frame(y = -0.5, label = paste0(length(x), "\ncells"))) } - +#' diffLRT ---- diffLRT <- function(x, y, xmin = 1) { lrtX <- bimodLikData(x) lrtY <- bimodLikData(y) @@ -349,8 +399,11 @@ set.ifnull <- function(x, y) { return(x) } -expMean <- function(x) { - return(log(mean(exp(x) - 1) + 1)) +expMean <- function(x, normFactor = 1) { + if (is.null(normFactor)){ + normFactor = 1 + } + return(log(mean(exp(x/normFactor) - 1) + 1)*normFactor) } @@ -395,9 +448,10 @@ heatmapPlotFromModule <- function(heatmapData, moduleName, input, projections) { # twoDplotFromModule ---- #' function to be used in markdown docs to ease the plotting of the clusterServer module +# TODO relies on reactive groupNames, should be a variable! Same goes for input$groupName! twoDplotFromModule <- function(twoDData, moduleName, input, projections, g_id, legend.position = "none") { grpNs <- groupNames$namesDF - grpN <- make.names(input$groupName) + grpN <- make.names(input$groupName, unique = TRUE) dimY <- input[[paste0(moduleName, "-dimension_y")]] dimX <- input[[paste0(moduleName, "-dimension_x")]] @@ -563,17 +617,19 @@ flattenCorrMatrix <- function(cormat, pmat) { ) } + +# recHistory ---- # record history in env # needs pdftk https://www.pdflabs.com/tools/pdftk-server/ # only save to history file if variable historyFile in schnappsEnv is set -if (!all(c("pdftools") %in% rownames(installed.packages()))) { +if (!all(c("pdftools", "gridExtra", "png") %in% rownames(installed.packages()))) { recHistory <- function(...) { return(NULL) } } else { require(pdftools) - recHistory <- function(name, plot1) { - if (!exists("historyFile", envir = .schnappsEnv)) { + recHistory <- function(name, plot1, envir = .schnappsEnv) { + if (!exists("historyFile", envir = envir)) { return(NULL) } if (!exists("history", envir = .schnappsEnv)) { @@ -581,21 +637,72 @@ if (!all(c("pdftools") %in% rownames(installed.packages()))) { } name <- paste(name, date()) tmpF <- tempfile(fileext = ".pdf") - plot1 <- - plot1 %>% layout(title = name) - if ("plotly" %in% class(plot1)) { - # requires orca bing installed (https://github.com/plotly/orca#installation) - withr::with_dir(dirname(tmpF), plotly::orca(p = plot1, file = basename(tmpF))) - if (file.exists(.schnappsEnv$historyFile)) { - tmpF2 <- tempfile(fileext = ".pdf") - file.copy(.schnappsEnv$historyFile, tmpF2) - pdf_combine(c(tmpF2, tmpF), output = .schnappsEnv$historyFile) - } else { - file.copy(tmpF, .schnappsEnv$historyFile) + cat(file = stderr(), paste0("history tmp File: ", tmpF, "\n")) + # save(file = "~/SCHNAPPsDebug/save2History2.RData", list = c(ls(), ls(envir = globalenv()))) + # cp =load(file="~/SCHNAPPsDebug/save2History2.RData") + clP <- class(plot1) + cat(file = stderr(), paste0("class: ", clP[1], "\n")) + # here we create a PDF file for a given plot that is then combined later + created <- FALSE + switch(clP[1], + "plotly" = { + cat(file = stderr(), paste0("plotly\n")) + plot1 <- plot1 %>% layout(title = name) + if ("plotly" %in% class(plot1)) { + # requires orca bing installed (https://github.com/plotly/orca#installation) + withr::with_dir(dirname(tmpF), plotly::orca(p = plot1, file = basename(tmpF))) + } + created <- TRUE + }, + "character" = { + # in case this is a link to a file: + cat(file = stderr(), paste0("character\n")) + if (file.exists(plot1)) { + if (tools::file_ext(plot1) == "png") { + pdf(tmpF) + img <- png::readPNG(plot1) + plot(1:2, type = "n") + rasterImage(img, 1.2, 1.27, 1.8, 1.73, interpolate = FALSE) + dev.off() + } + created <- TRUE + } + }, + "datatables" = { + # # // this takes too long + # cat(file = stderr(), paste0("datatables\n")) + # save(file = "~/SCHNAPPsDebug/save2History2.RData", list = c(ls(), ls(envir = globalenv()))) + # # cp =load(file="~/SCHNAPPsDebug/save2History2.RData") + # + # pdf(tmpF) + # if (nrow(img) > 20) { + # maxrow = 20 + # } else { + # maxrow = nrow(plot1) + # } + # gridExtra::grid.table(img[maxrow],) + # dev.off() + # created = TRUE } - return(TRUE) + ) + + if (!created) { + return(FALSE) } + if (file.exists(.schnappsEnv$historyFile)) { + tmpF2 <- tempfile(fileext = ".pdf") + file.copy(.schnappsEnv$historyFile, tmpF2) + tryCatch( + pdf_combine(c(tmpF2, tmpF), output = .schnappsEnv$historyFile), + error = function(x) { + cat(file = stderr(), paste0("problem while combining PDF files:", x, "\n")) + } + ) + } else { + file.copy(tmpF, .schnappsEnv$historyFile) + } + return(TRUE) # pdf(file = tmpF,onefile = TRUE) # ggsave(filename = tmpF, plot = plot1, device = pdf()) # dev.off() @@ -736,3 +843,110 @@ updateButtonColor <- function(buttonName, parameters) { # } # }) # } + +add2history <- function(type, comment = "", ...) { + if (!exists("historyPath", envir = .schnappsEnv)) { + # if this variable is not set we are not saving + return(NULL) + } + + varnames <- lapply(substitute(list(...))[-1], deparse) + arg <- list(...) + if(is.null(arg[[1]])) return(NULL) + if (.schnappsEnv$DEBUGSAVE) { + save(file = "~/SCHNAPPsDebug/add2history.RData", list = c(ls())) + } + # load(file='~/SCHNAPPsDebug/add2history.RData') + if (type == "text") { + cat(file = stderr(), paste0("history text: \n")) + assign(names(varnames[1]), arg[1]) + line <- paste0( + "\n", get(names(varnames[1])), "\n" + ) + write(line, file = .schnappsEnv$historyFile, append = TRUE) + + } + + if (type == "save") { + # browser() + tfile <- tempfile(pattern = paste0(names(varnames[1]), "."), tmpdir = .schnappsEnv$historyPath, fileext = ".RData") + assign(names(varnames[1]), arg[1]) + save(file = tfile, list = c(names(varnames[1]))) + # the load is commented out because it is not used at the moment and only takes time to load + line <- paste0( + "```{R}\n#load ", names(varnames[1]), "\n#load(file = \"", basename(tfile), + "\")\n```\n" + ) + write(line, file = .schnappsEnv$historyFile, append = TRUE) + } + + if (type == "renderPlotly") { + tfile <- tempfile(pattern = paste0(names(varnames[1]), "."), tmpdir = .schnappsEnv$historyPath, fileext = ".RData") + assign(names(varnames[1]), arg[1]) + save(file = tfile, list = c(names(varnames[1]))) + + line <- paste0( + "```{R}\n#load ", names(varnames[1]), "\nload(file = \"", basename(tfile), + "\")\nhtmltools::tagList(", names(varnames[1]), ")\n```\n" + ) + write(line, file = .schnappsEnv$historyFile, append = TRUE) + } + + if (type == "tronco") { + # browser() + tfile <- tempfile(pattern = paste0(names(varnames[1]), "."), tmpdir = .schnappsEnv$historyPath, fileext = ".RData") + assign(names(varnames[1]), arg[[1]]) + save(file = tfile, list = c(names(varnames[1]))) + + line <- paste0( + "```{R}\n#load ", names(varnames[1]), "\nload(file = \"", basename(tfile),"\")\n", + "\n", names(varnames[1]) ,"$filename <- NULL \n", + "\ndo.call(TRONCO::pheatmap, ", names(varnames[1]), ")\n```\n" + ) + write(line, file = .schnappsEnv$historyFile, append = TRUE) + } + + if (type == "renderPlot") { + tfile <- tempfile(pattern = paste0(names(varnames[1]), "."), tmpdir = .schnappsEnv$historyPath, fileext = ".RData") + assign(names(varnames[1]), arg[[1]]) + save(file = tfile, list = c(names(varnames[1]))) + + line <- paste0( + "```{R}\n#load ", names(varnames[1]), "\nload(file = \"", basename(tfile),"\")\n", + "\n", names(varnames[1]), "\n```\n" + ) + write(line, file = .schnappsEnv$historyFile, append = TRUE) + + } + + if (type == "renderDT") { + tfile <- tempfile(pattern = paste0(names(varnames[1]), "."), tmpdir = .schnappsEnv$historyPath, fileext = ".RData") + assign(names(varnames[1]), arg[[1]]) + save(file = tfile, list = c(names(varnames[1]))) + + line <- paste0( + "```{R}\n#load ", names(varnames[1]), "\nload(file = \"", basename(tfile),"\")\n", + "\n", names(varnames[1]), "\n```\n" + ) + write(line, file = .schnappsEnv$historyFile, append = TRUE) + + } +} + + + + +# Get density of points in 2 dimensions. ---- +# @param x A numeric vector. +# @param y A numeric vector. +# @param n Create a square n by n grid to compute density. +# @return The density within each square. +get_density <- function(x, y, ...) { + dens <- MASS::kde2d(x, y, ...) + ix <- findInterval(x, dens$x) + iy <- findInterval(y, dens$y) + ii <- cbind(ix, iy) + return(dens$z[ii]) +} + + diff --git a/inst/app/tabs.R b/inst/app/tabs.R index 8852b295be093f01daa0903eb9a6d1284c91fa5d..eca6e872664c5c9c167305840b1b0c38271319d8 100644 --- a/inst/app/tabs.R +++ b/inst/app/tabs.R @@ -337,6 +337,26 @@ generalParametersTab <- shinydashboard::tabItem( ), checkbsTT(item = "tabsetPCA"), ), + fluidRow( + box( + title = "DimPlot for PCA", solidHeader = TRUE, width = 12, status = 'primary', collapsible = TRUE, collapsed = TRUE, + # The id lets us use input$tabset1 on the server to find the current tab + id = "dimPlotPCA", + fluidRow( + column(12, + offset = 1, + actionButton("updateDimPlot", "generate plot", width = '80%', + style = "color: #fff; background-color: #A00272; border-color: #2e6da4") + ), + ), + fluidRow( + column(width = 12, + jqui_resizable(plotOutput("dimPlotPCA")) + ) + ), + checkbsTT(item = "dimPlotPCA"), + ) + ), fluidRow( tabBox( title = "Parameters for clustering", width = 12, diff --git a/inst/app/ui.R b/inst/app/ui.R index 3c880ee0c89b7950ad5fbb88bb6ee39a943260f9..f355a6c5f5499405d62660b1aede5434c114afa0 100644 --- a/inst/app/ui.R +++ b/inst/app/ui.R @@ -156,10 +156,13 @@ scShinyUI <- shinyUI( downloadButton("RDSsave", "Download RData", class = "butt"), if (DEBUG) checkboxInput("DEBUGSAVE", "Save for DEBUG", FALSE), verbatimTextOutput("DEBUGSAVEstring"), - if (exists("historyFile", envir = .schnappsEnv)) { - checkboxInput("save2History", "save to history file", FALSE) - }, - verbatimTextOutput("save2Historystring") + if (exists("historyPath", envir = .schnappsEnv)){ + # checkboxInput("save2History", "save to history file", FALSE) + actionButton("comment2History", "Add comment to history") + } + # , + # verbatimTextOutput("save2Historystring") + # ,verbatimTextOutput("currentTabInfo") ), # dashboard side bar shinydashboard::dashboardBody( shinyjs::useShinyjs(debug = TRUE), diff --git a/inst/develo/heatMapBIG.Rmd b/inst/develo/heatMapBIG.Rmd new file mode 100644 index 0000000000000000000000000000000000000000..5def42cf06505760e2b76e20e481fbe18e456fdc --- /dev/null +++ b/inst/develo/heatMapBIG.Rmd @@ -0,0 +1,82 @@ +--- +title: "heaptmapBIG" +author: "Bernd Jagla" +date: "9/10/2019" +output: html_document +--- + +```{r setup, include=FALSE} +load("~/Downloads/pHeatMap_data/sessionData.RData") +``` + + +```{r cars, fig.height=80, fig.width=10} + if (is.null(scale)) { + heatmapData$scale = "none" + } else { + heatmapData$scale = "row" + } + if (length(addColNames) > 0 & moreOptions) { + heatmapData$annotation_col <- proje[rownames(heatmapData$annotation_col), addColNames, drop = FALSE] + } + if (sum(orderColNames %in% colnames(proje)) > 0 & moreOptions) { + heatmapData$cluster_cols <- FALSE + colN <- rownames(psych::dfOrder(proje, orderColNames)) + colN <- colN[colN %in% colnames(heatmapData$mat)] + heatmapData$mat <- heatmapData$mat[, colN, drop = FALSE] + } +do.call(TRONCO::pheatmap, heatmapData) + + +``` + +```{r} +library("PerformanceAnalytics") +chart.Correlation(heatmapData$mat, histogram=TRUE, pch=19) +``` + + +```{r} +library("Hmisc") +colnames(heatmapData$mat) +rownames(proje) +colnames(proje) +nums <- unlist(lapply(proje, is.numeric)) +numProje = proje[,nums] +colnames(numProje) + +numProje <- t(numProje)[,colnames(heatmapData$mat)] +rownames(numProje) +corrInput <- as.matrix(rbind(numProje,heatmapData$mat)) +rownames(corrInput) +res2 <- rcorr(t(corrInput)) +# res2 +sum(rownames(res2$P) %in% colnames(proje[, nums])) +# ++++++++++++++++++++++++++++ +# flattenCorrMatrix +# ++++++++++++++++++++++++++++ +# cormat : matrix of the correlation coefficients +# pmat : matrix of the correlation p-values +flattenCorrMatrix <- function(cormat, pmat) { + ut <- upper.tri(cormat) + data.frame( + row = rownames(cormat)[row(cormat)[ut]], + column = rownames(cormat)[col(cormat)[ut]], + cor =(cormat)[ut], + p = pmat[ut] + ) +} +cormat = res2$r +pmat = res2$P +ut <- upper.tri(upper.tri(res2$r)) + + +flatMat <- flattenCorrMatrix(res2$r, res2$P) +flatMat[flatMat$column %in% colnames(proje[, nums]) & + (!flatMat$row %in% colnames(proje[, nums])) , ] +flatMat = flatMat[order(flatMat$cor, decreasing = F),] +DT::datatable(flatMat[flatMat$row == "PC5" & + flatMat$p < 0.005,]) + +``` + diff --git a/inst/develo/human_cycle_markers.rds b/inst/develo/human_cycle_markers.rds new file mode 100644 index 0000000000000000000000000000000000000000..91c5021c1d61542309f5bb428c1e6e7f7bd70d5e Binary files /dev/null and b/inst/develo/human_cycle_markers.rds differ diff --git a/inst/develo/mouse_cycle_markers.rds b/inst/develo/mouse_cycle_markers.rds new file mode 100644 index 0000000000000000000000000000000000000000..81ad872d91be411e51d43d33932e5b16ef136001 Binary files /dev/null and b/inst/develo/mouse_cycle_markers.rds differ