Browse code

Refine changes previously made, and minor bug fixes

Yichen Wang authored on 22/06/2022 20:55:48
Showing 9 changed files

... ...
@@ -652,10 +652,7 @@ plotTSCANClusterPseudo <- function(inSCE, useCluster, useReducedDim = "UMAP",
652 652
   by.cluster <- scuttle::aggregateAcrossCells(inSCE, ids = clusters)
653 653
   line.data <- TSCAN::reportEdges(by.cluster, mst = results$mst,
654 654
                                   clusters = NULL, use.dimred = useReducedDim)
655
-  line.data.sub <- line.data[grepl(paste0("^", useCluster, "--"),
656
-                                   line.data$edge) |
657
-                               grepl(paste0("--", useCluster, "$"),
658
-                                     line.data$edge),]
655
+  line.data.sub <- .getClustersLineData(line.data, useCluster)
659 656
 
660 657
   # Get Branch pseudotime
661 658
   tscan.pseudo <- TSCAN::orderCells(results$maptscan, mst = results$mst,
... ...
@@ -694,6 +691,9 @@ plotTSCANClusterPseudo <- function(inSCE, useCluster, useReducedDim = "UMAP",
694 691
 #' @param inSCE Input \linkS4class{SingleCellExperiment} object.
695 692
 #' @param useCluster Choose a cluster used for identifying DEG with
696 693
 #' \code{\link{runTSCANClusterDEAnalysis}}. Required.
694
+#' @param pathIndex Specifies one of the branching paths from \code{useCluster}
695
+#' and plot the top DEGs on this path. Ususally presented by the terminal
696
+#' cluster of a path. By default \code{NULL} plot top DEGs of all paths.
697 697
 #' @param useReducedDim A single character for the matrix of 2D embedding.
698 698
 #' Should exist in \code{reducedDims} slot. Default \code{"UMAP"}.
699 699
 #' @param topN Integer. Use top N genes identified. Default \code{9}.
... ...
@@ -802,55 +802,50 @@ plotTSCANDimReduceFeatures <- function(
802 802
   combinePlot = c("all", "none"))
803 803
 {
804 804
   results <- getTSCANResults(inSCE, analysisName = "Pseudotime")
805
-  if (!is.null(useCluster) && length(useCluster) != 1)
806
-    stop("`useCluster`: can only use one cluster.")
807 805
   combinePlot <- match.arg(combinePlot)
808 806
   clusters <- colData(inSCE)$TSCAN_clusters
809 807
   by.cluster <- scuttle::aggregateAcrossCells(inSCE, ids = clusters)
810 808
   line.data <- TSCAN::reportEdges(by.cluster, mst = results$mst,
811 809
                                   clusters = NULL, use.dimred = useReducedDim)
812 810
   if (!is.null(useCluster)) {
813
-    line.data <- line.data[grepl(paste0("^", useCluster, "--"),
814
-                                 line.data$edge) |
815
-                             grepl(paste0("--", useCluster, "$"),
816
-                                   line.data$edge),]
811
+    line.data <- .getClustersLineData(line.data, useCluster)
817 812
     inSCE <- inSCE[, clusters %in% useCluster]
818 813
   }
819 814
   if (by == "rownames") by <- NULL
820 815
   plotList <- list()
821
-  if (!is.na(features)) {
822
-    for (f in features) {
823
-      g <- plotSCEDimReduceFeatures(inSCE, feature = f,
824
-                                    useAssay = useAssay,
825
-                                    featureLocation = by,dim1 = 1, dim2 = 2,
826
-                                    featureDisplay = featureDisplay,
827
-                                    reducedDimName = useReducedDim,
828
-                                    title = f) +
829
-        ggplot2::geom_line(data = line.data,
830
-                           ggplot2::aes_string(x = colnames(line.data)[2],
831
-                                               y = colnames(line.data)[3],
832
-                                               group = "edge"),
833
-                           inherit.aes = FALSE)
834
-      # Text labeling code credit: scater
835
-      reddim <- as.data.frame(SingleCellExperiment::reducedDim(inSCE,
836
-                                                               useReducedDim))
837
-      text_out <- scater::retrieveCellInfo(inSCE, "TSCAN_clusters",
838
-                                           search = "colData")
839
-      by_text_x <- vapply(split(reddim[,1], text_out$val),
840
-                          stats::median, FUN.VALUE = 0)
841
-      by_text_y <- vapply(split(reddim[,2], text_out$val),
842
-                          stats::median, FUN.VALUE = 0)
843
-      g <- g + ggrepel::geom_text_repel(
844
-        data = data.frame(x = by_text_x,
845
-                          y = by_text_y,
846
-                          label = names(by_text_x)),
847
-        mapping = ggplot2::aes_string(x = "x",
848
-                                      y = "y",
849
-                                      label = "label"),
850
-        inherit.aes = FALSE
851
-      )
852
-      plotList[[f]] <- g
853
-    }
816
+  features <- stats::na.omit(features)
817
+  for (f in features) {
818
+    # Should not enter the loop if features is length zero after NA omit
819
+    g <- plotSCEDimReduceFeatures(inSCE, feature = f,
820
+                                  useAssay = useAssay,
821
+                                  featureLocation = by,dim1 = 1, dim2 = 2,
822
+                                  featureDisplay = featureDisplay,
823
+                                  reducedDimName = useReducedDim,
824
+                                  title = f) +
825
+      ggplot2::geom_line(data = line.data,
826
+                         ggplot2::aes_string(x = colnames(line.data)[2],
827
+                                             y = colnames(line.data)[3],
828
+                                             group = "edge"),
829
+                         inherit.aes = FALSE)
830
+    # Text labeling code credit: scater
831
+    reddim <- as.data.frame(SingleCellExperiment::reducedDim(inSCE,
832
+                                                             useReducedDim))
833
+    text_out <- scater::retrieveCellInfo(inSCE, "TSCAN_clusters",
834
+                                         search = "colData")
835
+    by_text_x <- vapply(split(reddim[,1], text_out$val),
836
+                        stats::median, FUN.VALUE = 0)
837
+    by_text_y <- vapply(split(reddim[,2], text_out$val),
838
+                        stats::median, FUN.VALUE = 0)
839
+    g <- g + ggrepel::geom_text_repel(
840
+      data = data.frame(x = by_text_x,
841
+                        y = by_text_y,
842
+                        label = names(by_text_x)),
843
+      mapping = ggplot2::aes_string(x = "x",
844
+                                    y = "y",
845
+                                    label = "label"),
846
+      inherit.aes = FALSE, na.rm = TRUE,
847
+    )
848
+    plotList[[f]] <- g
854 849
   }
855 850
   if (combinePlot == "all") {
856 851
     if (length(plotList) > 0)
... ...
@@ -858,3 +853,22 @@ plotTSCANDimReduceFeatures <- function(
858 853
   }
859 854
   return(plotList)
860 855
 }
856
+
857
+#' Extract edges that connects to the clusters of interest
858
+#' @param line.data data.frame of three columns. First column should be named
859
+#' "edge", the other two are coordinates of one of the vertices that this
860
+#' edge connects.
861
+#' @param useCluster Vector of clusters, that are going to be the vertices for
862
+#' edge finding.
863
+#' @return data.frame, subset rows of line.data
864
+.getClustersLineData <- function(line.data, useCluster) {
865
+  idx <- vapply(useCluster, function(x){
866
+    grepl(paste0("^", x, "--"), line.data$edge) |
867
+      grepl(paste0("--", x, "$"), line.data$edge)
868
+  }, logical(nrow(line.data)))
869
+  # `idx` returned was c("matrix", "array") class. Each column is a logical
870
+  # vector for edge selection of each cluster.
871
+  # Next, do "or" for each row.
872
+  idx <- rowSums(idx) > 0
873
+  line.data[idx,]
874
+}
... ...
@@ -8,9 +8,10 @@ nonLinearWorkflowUI <- function(id)
8 8
 }
9 9
 
10 10
 # Server
11
-nonLinearWorkflow <- function(input, output, session, parent, 
11
+nonLinearWorkflow <- function(input, output, session, parent,
12 12
                               de = FALSE,
13
-                              cv = FALSE, 
13
+                              fm = FALSE,
14
+                              cv = FALSE,
14 15
                               pa = FALSE,
15 16
                               tj = FALSE,
16 17
                               qcf = FALSE,
... ...
@@ -21,12 +22,13 @@ nonLinearWorkflow <- function(input, output, session, parent,
21 22
                               cl = FALSE)
22 23
 {
23 24
   ns <- session$ns
24
-  
25
+
25 26
   output$ui <- renderUI({
26 27
     bsCollapse(
27 28
       open = "Next Steps",
28
-      bsCollapsePanel("Next Steps", 
29
+      bsCollapsePanel("Next Steps",
29 30
                       uiOutput(ns("de")),
31
+                      uiOutput(ns("fm")),
30 32
                       uiOutput(ns("pa")),
31 33
                       uiOutput(ns("tj")),
32 34
                       uiOutput(ns("qcf")),
... ...
@@ -38,53 +40,60 @@ nonLinearWorkflow <- function(input, output, session, parent,
38 40
                       uiOutput(ns("cv")),
39 41
                       style = "success")
40 42
       )
41
-    
43
+
42 44
   })
43
-  
45
+
44 46
   if(de){
45 47
     output$de <- renderUI({
46 48
       panel(
47
-        heading = "Differential Expression & Marker Selection",
48
-        h5("Compute and visualize marker genes for each cluster using one of the many integrated statistical frameworks for differential expression:"),
49
-        actionButton(inputId = ns("goMS"), label = "Go to Marker Selection!"),
50
-        hr(),
49
+        heading = "Differential Expression",
51 50
         h5("Discover quantitative changes between experimental conditions using one of the many integrated statistical frameworks for differential expression:"),
52
-        actionButton(inputId = ns("goDE"), label = "Go to Differential Expression!")
51
+        actionButton(inputId = ns("goDE"), label = "Go to Differential Expression")
53 52
       )
54 53
     })
55 54
   }
56
-  
55
+
56
+  if(fm){
57
+    output$de <- renderUI({
58
+      panel(
59
+        heading = "Marker Selection",
60
+        h5("Compute and visualize marker genes for each cluster using one of the many integrated statistical frameworks for differential expression:"),
61
+        actionButton(inputId = ns("goMS"), label = "Go to Find Marker")
62
+      )
63
+    })
64
+  }
65
+
57 66
   if(cv){
58 67
     output$cv <- renderUI({
59 68
       panel(
60 69
         heading = "Cell Viewer",
61 70
         h5("Visualize data using scatter plot, violin plot, bar or box plots."),
62
-        actionButton(inputId = ns("goCV"), label = "Go to Cell Viewer!")
71
+        actionButton(inputId = ns("goCV"), label = "Go to Cell Viewer")
63 72
       )
64 73
     })
65 74
   }
66
-  
75
+
67 76
   if(pa){
68 77
     output$pa <- renderUI({
69 78
       panel(
70 79
         heading = "Pathway Analysis",
71
-        h5("Explore biological activity or functions with pathway analysis using either 'GSVA' or 'EnrichR' statistical frameworks:"),
72
-        actionButton(inputId = ns("goPathwayAnalysis"), label = "Go to Pathway Analysis!"),
73
-        actionButton(inputId = ns("goEnrichR"), label = "Go to EnrichR!"),
80
+        h5("Explore biological activity or functions with pathway analysis using 'VAM' or 'GSVA' statistical frameworks, or perform GSEA with 'enrichR':"),
81
+        actionButton(inputId = ns("goPathwayAnalysis"), label = "Go to Pathway Analysis"),
82
+        actionButton(inputId = ns("goEnrichR"), label = "Go to EnrichR"),
74 83
       )
75 84
     })
76 85
   }
77
-  
86
+
78 87
   if(tj){
79 88
     output$tj <- renderUI({
80 89
       panel(
81 90
         heading = "Trajectory Analysis",
82 91
         h5("Estimate Pseudotime path of cell population with TSCAN method:"),
83
-        actionButton(inputId = ns("goTSCAN"), label = "Go to Trajectory Analysis!")
92
+        actionButton(inputId = ns("goTSCAN"), label = "Go to Trajectory Analysis")
84 93
       )
85 94
     })
86 95
   }
87
-  
96
+
88 97
   if(qcf){
89 98
     output$qcf <- renderUI({
90 99
       panel(
... ...
@@ -95,17 +104,17 @@ nonLinearWorkflow <- function(input, output, session, parent,
95 104
       )
96 105
     })
97 106
   }
98
-  
107
+
99 108
   if(nbc){
100 109
     output$nbc <- renderUI({
101 110
       panel(
102 111
         heading = "Normalization & Batch-Correction",
103 112
         h5("Normalize the raw/filtered input data to remove biasness of technical variation from the data or additionally adjust for batch-effect if the data is processed in multiple batches."),
104
-        actionButton(inputId = ns("goNBC"), label = "Go to Normalization/Batch-Correction!")
113
+        actionButton(inputId = ns("goNBC"), label = "Go to Normalization/Batch-Correction")
105 114
       )
106 115
     })
107 116
   }
108
-  
117
+
109 118
   if(cw){
110 119
     output$cw <- renderUI({
111 120
       panel(
... ...
@@ -116,7 +125,7 @@ nonLinearWorkflow <- function(input, output, session, parent,
116 125
       )
117 126
     })
118 127
   }
119
-  
128
+
120 129
   if(dr){
121 130
     output$dr <- renderUI({
122 131
       panel(
... ...
@@ -126,7 +135,7 @@ nonLinearWorkflow <- function(input, output, session, parent,
126 135
       )
127 136
     })
128 137
   }
129
-  
138
+
130 139
   if(fs){
131 140
     output$fs <- renderUI({
132 141
       panel(
... ...
@@ -136,7 +145,7 @@ nonLinearWorkflow <- function(input, output, session, parent,
136 145
       )
137 146
     })
138 147
   }
139
-  
148
+
140 149
   if(cl){
141 150
     output$cl <- renderUI({
142 151
       panel(
... ...
@@ -146,14 +155,14 @@ nonLinearWorkflow <- function(input, output, session, parent,
146 155
       )
147 156
     })
148 157
   }
149
-  
158
+
150 159
   observeEvent(input$goCV,{
151 160
     showTab(inputId = "navbar",
152 161
             target = "CellViewer",
153 162
             select = TRUE,
154 163
             session = parent)
155 164
   })
156
-  
165
+
157 166
     observeEvent(input$goDE,{
158 167
       showTab(inputId = "navbar",
159 168
               target = "Differential Expression",
... ...
@@ -167,89 +176,89 @@ nonLinearWorkflow <- function(input, output, session, parent,
167 176
               select = TRUE,
168 177
               session = parent)
169 178
     })
170
-    
179
+
171 180
     observeEvent(input$goPathwayAnalysis,{
172 181
       showTab(inputId = "navbar",
173 182
               target = "Pathway Activity",
174 183
               select = TRUE,
175 184
               session = parent)
176 185
     })
177
-    
186
+
178 187
     observeEvent(input$goEnrichR,{
179 188
       showTab(inputId = "navbar",
180 189
               target = "EnrichR",
181 190
               select = TRUE,
182 191
               session = parent)
183 192
     })
184
-    
193
+
185 194
     observeEvent(input$goTSCAN,{
186 195
       showTab(inputId = "navbar",
187 196
               target = "TSCANWorkflow",
188 197
               select = TRUE,
189 198
               session = parent)
190 199
     })
191
-    
200
+
192 201
     observeEvent(input$goQC,{
193 202
       showTab(inputId = "navbar",
194 203
               target = "QC & Filtering",
195 204
               select = TRUE,
196 205
               session = parent)
197
-      updateTabsetPanel(session = parent, 
198
-                        inputId = "QCFilterTabsetPanel", 
206
+      updateTabsetPanel(session = parent,
207
+                        inputId = "QCFilterTabsetPanel",
199 208
                         selected = "QC")
200 209
     })
201
-    
210
+
202 211
     observeEvent(input$goFilter,{
203 212
       showTab(inputId = "navbar",
204 213
               target = "QC & Filtering",
205 214
               select = TRUE,
206 215
               session = parent)
207
-      updateTabsetPanel(session = parent, 
208
-                        inputId = "QCFilterTabsetPanel", 
216
+      updateTabsetPanel(session = parent,
217
+                        inputId = "QCFilterTabsetPanel",
209 218
                         selected = "Filtering")
210 219
     })
211
-    
220
+
212 221
     observeEvent(input$goNBC,{
213 222
       showTab(inputId = "navbar",
214 223
               target = "Normalization & Batch Correction",
215 224
               select = TRUE,
216 225
               session = parent)
217 226
     })
218
-    
227
+
219 228
     observeEvent(input$goCelda,{
220 229
       showTab(inputId = "navbar",
221 230
               target = "Celda",
222 231
               select = TRUE,
223 232
               session = parent)
224 233
     })
225
-    
234
+
226 235
     observeEvent(input$goSeurat,{
227 236
       showTab(inputId = "navbar",
228 237
               target = "Seurat",
229 238
               select = TRUE,
230 239
               session = parent)
231 240
     })
232
-    
241
+
233 242
     observeEvent(input$goDR,{
234 243
       showTab(inputId = "navbar",
235 244
               target = "Feature Selection & Dimensionality Reduction",
236 245
               select = TRUE,
237 246
               session = parent)
238
-      updateTabsetPanel(session = parent, 
239
-                        inputId = "FSDimRedTabsetPanel", 
247
+      updateTabsetPanel(session = parent,
248
+                        inputId = "FSDimRedTabsetPanel",
240 249
                         selected = "Dimensionality Reduction")
241 250
     })
242
-    
251
+
243 252
     observeEvent(input$goFS,{
244 253
       showTab(inputId = "navbar",
245 254
               target = "Feature Selection & Dimensionality Reduction",
246 255
               select = TRUE,
247 256
               session = parent)
248
-      updateTabsetPanel(session = parent, 
249
-                        inputId = "FSDimRedTabsetPanel", 
257
+      updateTabsetPanel(session = parent,
258
+                        inputId = "FSDimRedTabsetPanel",
250 259
                         selected = "Feature Selection")
251 260
     })
252
-    
261
+
253 262
     observeEvent(input$goCL,{
254 263
       showTab(inputId = "navbar",
255 264
               target = "Clustering",
... ...
@@ -196,10 +196,7 @@ shinyServer(function(input, output, session) {
196 196
     updateSelectInput(session, 'deRegLabel',
197 197
                       choices = c("Rownames (Default)",
198 198
                                   selectRowData))
199
-    updateSelectInput(session, 'tscanDEHMFeatureDisplay',
200
-                      choices = c("Rownames (Default)",
201
-                                  selectRowData))
202
-    updateSelectInput(session, 'tscanDERegFeatureDisplay',
199
+    updateSelectInput(session, 'tscanDEFeatureDisplay',
203 200
                       choices = c("Rownames (Default)",
204 201
                                   selectRowData))
205 202
     updateSelectInput(session, 'plotTSCANClusterDEG_featureDisplay',
... ...
@@ -1093,7 +1090,8 @@ shinyServer(function(input, output, session) {
1093 1090
                    close = "2. Create dataset:",
1094 1091
                    style = list("2. Create dataset:" = "success"))
1095 1092
 
1096
-    callModule(module = nonLinearWorkflow, id = "nlw-import", parent = session, qcf = TRUE)
1093
+    callModule(module = nonLinearWorkflow, id = "nlw-import", parent = session,
1094
+               qcf = TRUE)
1097 1095
     }))
1098 1096
 
1099 1097
   updateSeuratUIFromRDS <- function(inSCE){
... ...
@@ -1445,8 +1443,7 @@ shinyServer(function(input, output, session) {
1445 1443
     updateSelectInput(session, "deVolcFeatureDisplay", selected = selected)
1446 1444
     updateSelectInput(session, "deVioLabel", selected = selected)
1447 1445
     updateSelectInput(session, "deRegLabel", selected = selected)
1448
-    updateSelectInput(session, "tscanDEHMFeatureDisplay", selected = selected)
1449
-    updateSelectInput(session, "tscanDERegFeatureDisplay", selected = selected)
1446
+    updateSelectInput(session, "tscanDEFeatureDisplay", selected = selected)
1450 1447
     updateSelectInput(session, "plotTSCANClusterDEG_featureDisplay",
1451 1448
                       selected = selected)
1452 1449
     updateSelectInput(session, "plotTSCANDimReduceFeatures_featureDisplay",
... ...
@@ -1906,7 +1903,8 @@ shinyServer(function(input, output, session) {
1906 1903
         message(paste0(date(), " ... QC Complete"))
1907 1904
         updateQCPlots()
1908 1905
         # Show downstream analysis options
1909
-        callModule(module = nonLinearWorkflow, id = "nlw-qcf", parent = session, nbc = TRUE, cw = TRUE, cv = TRUE)
1906
+        callModule(module = nonLinearWorkflow, id = "nlw-qcf", parent = session,
1907
+                   nbc = TRUE, cw = TRUE, cv = TRUE)
1910 1908
       }
1911 1909
       delay(500, removeNotification(id = "qcNotification"))
1912 1910
   }))
... ...
@@ -2452,7 +2450,8 @@ shinyServer(function(input, output, session) {
2452 2450
 
2453 2451
         message(paste0(date(), " ... Ended normalization/transformation."))
2454 2452
         # Show downstream analysis options
2455
-        callModule(module = nonLinearWorkflow, id = "nlw-nbc", parent = session, dr = TRUE, fs = TRUE)
2453
+        callModule(module = nonLinearWorkflow, id = "nlw-nbc", parent = session,
2454
+                   dr = TRUE, fs = TRUE)
2456 2455
       }
2457 2456
     }
2458 2457
   ))
... ...
@@ -3130,7 +3129,8 @@ shinyServer(function(input, output, session) {
3130 3129
       updateReddimInputs()
3131 3130
       updateAssayInputs()
3132 3131
       # Show downstream analysis options
3133
-      callModule(module = nonLinearWorkflow, id = "nlw-dr", parent = session, cl = TRUE, cv = TRUE)
3132
+      callModule(module = nonLinearWorkflow, id = "nlw-dr", parent = session,
3133
+                 cl = TRUE, cv = TRUE)
3134 3134
 
3135 3135
       message(paste0(date(), " ... Ending Dimensionality Reduction."))
3136 3136
       updateSelectizeInput(session, "selectRedDimPlot_tsneUmap",
... ...
@@ -3357,7 +3357,7 @@ shinyServer(function(input, output, session) {
3357 3357
       }
3358 3358
       # Show downstream analysis options
3359 3359
       callModule(module = nonLinearWorkflow, id = "nlw-cl", parent = session,
3360
-                 de = TRUE, pa = TRUE, cv = TRUE, tj = TRUE)
3360
+                 de = TRUE, fm = TRUE, pa = TRUE, cv = TRUE, tj = TRUE)
3361 3361
     }
3362 3362
   ))
3363 3363
 
... ...
@@ -3462,8 +3462,8 @@ shinyServer(function(input, output, session) {
3462 3462
       updatePickerInput(session, "useClusterForPlotGene",
3463 3463
                         choices = clusterNamesList,
3464 3464
                         selected = NULL)
3465
-      updateSelectInput(session, "plotTSCANDimReduceFeatures_useCluster",
3466
-                        choices = c("Use all", clusterNamesList))
3465
+      updatePickerInput(session, "plotTSCANDimReduceFeatures_useCluster",
3466
+                        choices = clusterNamesList)
3467 3467
       updateSelectInput(session, "TSCANUseCluster",
3468 3468
                         choices = results$branchClusters)
3469 3469
       updateCollapse(session = session, "TSCANUI",
... ...
@@ -3481,6 +3481,10 @@ shinyServer(function(input, output, session) {
3481 3481
                          useReducedDim = input$TSCANVisRedDim)
3482 3482
       })
3483 3483
     })
3484
+    updateSelectInput(session, "plotTSCANClusterDEG_useReducedDim",
3485
+                      selected = input$TSCANVisRedDim)
3486
+    updateSelectInput(session, "plotTSCANDimReduceFeatures_useReducedDim",
3487
+                      selected = input$TSCANVisRedDim)
3484 3488
     session$sendCustomMessage("close_dropDownTSCAN", "")
3485 3489
   })
3486 3490
 
... ...
@@ -3498,7 +3502,7 @@ shinyServer(function(input, output, session) {
3498 3502
                       ))
3499 3503
   })
3500 3504
 
3501
-  observeEvent(input$findExpGenes, withConsoleMsgRedirect(
3505
+  observeEvent(input$runTSCANDEG, withConsoleMsgRedirect(
3502 3506
     msg = "Please wait while DE genes are being found for path. See console log for progress.",
3503 3507
     {
3504 3508
       req(vals$counts)
... ...
@@ -3516,7 +3520,7 @@ shinyServer(function(input, output, session) {
3516 3520
         })
3517 3521
       })
3518 3522
 
3519
-      message(paste0(date(), " ... Updating upregulated genes"))
3523
+      message(paste0(date(), " ... Updating up-regulated genes"))
3520 3524
       output$UpregGenesPlot <- renderPlot({
3521 3525
         isolate({
3522 3526
           plotTSCANPseudotimeGenes(inSCE = vals$counts,
... ...
@@ -3524,58 +3528,73 @@ shinyServer(function(input, output, session) {
3524 3528
                                    direction = "increasing")
3525 3529
         })
3526 3530
       })
3531
+
3532
+      message(paste0(date(), " ... Updating down-regulated genes"))
3533
+      output$DownregGenesPlot <- renderPlot({
3534
+        isolate({
3535
+          plotTSCANPseudotimeGenes(inSCE = vals$counts,
3536
+                                   pathIndex = input$pathIndexx,
3537
+                                   direction = "decreasing")
3538
+        })
3539
+      })
3540
+
3527 3541
       all.results <- getTSCANResults(vals$counts, analysisName = "DEG")
3528
-      updateSelectInput(session, "tscanDEHMexpPathIndex",
3529
-                        choices = names(all.results),
3530
-                        selected = NULL)
3531
-      updateSelectInput(session, "tscanDERegexpPathIndex",
3542
+      updateSelectInput(session, "tscanDEexpPathIndex",
3532 3543
                         choices = names(all.results),
3533
-                        selected = NULL)
3544
+                        selected = input$pathIndexx)
3534 3545
       updateCollapse(
3535 3546
         session = session, "TSCANUI",
3536
-        style = list("Identify Genes Differentially Expressed For Path" = "success"))
3537
-      callModule(module = nonLinearWorkflow, id = "nlw-Traj",
3538
-                 parent = session, de = TRUE, pa = TRUE)
3547
+        style = list("Identify Genes Differentially Expressed For Path" = "success")
3548
+      )
3549
+      callModule(module = nonLinearWorkflow, id = "nlw-Traj", parent = session,
3550
+                 de = TRUE, pa = TRUE)
3539 3551
     }
3540 3552
   ))
3541 3553
 
3542
-  #plot results on Expression plot
3543
-  observeEvent(input$tscanDEHMPlot, {
3544
-    req(vals$counts)
3545
-    if (input$tscanDEHMFeatureDisplay == "Rownames (Default)") {
3546
-      featureDisplay <- NULL
3547
-    } else {
3548
-      featureDisplay <- input$tscanDEHMFeatureDisplay
3549
-    }
3550
-    output$heatmapPlot <- renderPlot({
3551
-      isolate({
3552
-        plotTSCANPseudotimeHeatmap(inSCE = vals$counts,
3553
-                                   pathIndex = input$tscanDEHMexpPathIndex,
3554
-                                   topN = input$tscanDEHMTopGenes,
3554
+  observeEvent(input$tscanDEPlot, withConsoleMsgRedirect(
3555
+    msg = "Please wait while TSCAN DE plots are being updated. See console log for progress",
3556
+    {
3557
+      req(vals$counts)
3558
+      if (input$tscanDEFeatureDisplay == "Rownames (Default)") {
3559
+        featureDisplay <- NULL
3560
+      } else {
3561
+        featureDisplay <- input$tscanDEFeatureDisplay
3562
+      }
3563
+      message(paste0(date(), " ... Updating heatmap"))
3564
+      output$heatmapPlot <- renderPlot({
3565
+        isolate({
3566
+          plotTSCANPseudotimeHeatmap(inSCE = vals$counts,
3567
+                                     pathIndex = input$tscanDEexpPathIndex,
3568
+                                     topN = input$tscanDEHMTopGenes,
3569
+                                     featureDisplay = featureDisplay)
3570
+        })
3571
+      })
3572
+
3573
+      message(paste0(date(), " ... Updating up-regulated genes"))
3574
+      output$UpregGenesPlot <- renderPlot({
3575
+        isolate({
3576
+          plotTSCANPseudotimeGenes(inSCE = vals$counts,
3577
+                                   pathIndex = input$tscanDEexpPathIndex,
3578
+                                   direction = "increasing",
3579
+                                   topN = input$tscanDERegTopGenes,
3555 3580
                                    featureDisplay = featureDisplay)
3581
+        })
3556 3582
       })
3557
-    })
3558
-    session$sendCustomMessage("close_dropDownTscanDEHM", "")
3559
-  })
3560 3583
 
3561
-  observeEvent(input$tscanDERegPlot, {
3562
-    req(vals$counts)
3563
-    if (input$tscanDERegFeatureDisplay == "Rownames (Default)") {
3564
-      featureDisplay <- NULL
3565
-    } else {
3566
-      featureDisplay <- input$tscanDERegFeatureDisplay
3567
-    }
3568
-    output$UpregGenesPlot <- renderPlot({
3569
-      isolate({
3570
-        plotTSCANPseudotimeGenes(inSCE = vals$counts,
3571
-                                 pathIndex = input$tscanDERegexpPathIndex,
3572
-                                 direction = input$tscanDERegDirection,
3573
-                                 topN = input$tscanDERegTopGenes,
3574
-                                 featureDisplay = featureDisplay)
3584
+      message(paste0(date(), " ... Updating down-regulated genes"))
3585
+      output$DownregGenesPlot <- renderPlot({
3586
+        isolate({
3587
+          plotTSCANPseudotimeGenes(inSCE = vals$counts,
3588
+                                   pathIndex = input$tscanDEexpPathIndex,
3589
+                                   direction = "decreasing",
3590
+                                   topN = input$tscanDERegTopGenes,
3591
+                                   featureDisplay = featureDisplay)
3592
+        })
3575 3593
       })
3576
-    })
3577
-    session$sendCustomMessage("close_dropDownTscanDEReg", "")
3578
-  })
3594
+
3595
+      session$sendCustomMessage("close_dropDownTscanDE", "")
3596
+    }
3597
+  ))
3579 3598
 
3580 3599
   ###################################################
3581 3600
   ###  Run STEP 3: Identify DE genes in specific cluster
... ...
@@ -3590,29 +3609,17 @@ shinyServer(function(input, output, session) {
3590 3609
                                                useAssay = input$TSCANBranchAssaySelect,
3591 3610
                                                fdrThreshold = input$fdrThreshold_TSCAN)
3592 3611
 
3593
-      clusterAnalysisNamesList <- names(getTSCANResults(vals$counts,
3612
+      clusterAnalysisNames <- names(getTSCANResults(vals$counts,
3594 3613
                                                         analysisName = "ClusterDEAnalysis"))
3595
-      terminalNodes<- c(colnames(getTSCANResults(vals$counts,
3596
-                                                 analysisName = "ClusterDEAnalysis",
3597
-                                                 pathName = input$TSCANUseCluster)$terminalNodes))
3598
-
3599
-      terminalNodesList <- getTSCANResults(vals$counts,
3600
-                                           analysisName = "ClusterDEAnalysis",
3601
-                                           pathName = "pathIndexList")
3602
-
3603
-      updateSelectInput(session, "plotTSCANClusterDEG_useCluster",
3604
-                        choices = clusterAnalysisNamesList,
3605
-                        selected = NULL)
3606
-      updateSelectInput(session, "useListCluster",
3607
-                        choices = clusterAnalysisNamesList,
3608
-                        selected = NULL)
3609
-      updateSelectInput(session, "useVisCluster",
3610
-                        choices = clusterAnalysisNamesList,
3611
-                        selected = NULL)
3612 3614
 
3613 3615
       results <- getTSCANResults(vals$counts,
3614 3616
                                  analysisName = "ClusterDEAnalysis",
3615 3617
                                  pathName = input$TSCANUseCluster)
3618
+      pathChoices <- colnames(results$terminalNodes)
3619
+
3620
+      updateSelectInput(session, "plotTSCANClusterDEG_useCluster",
3621
+                        choices = clusterAnalysisNames,
3622
+                        selected = input$TSCANUseCluster)
3616 3623
 
3617 3624
       #plot cluster deg by default
3618 3625
       message(paste0(date(), " ... Plotting top DEG expression"))
... ...
@@ -3620,8 +3627,9 @@ shinyServer(function(input, output, session) {
3620 3627
         isolate({
3621 3628
           plotTSCANClusterDEG(inSCE = vals$counts,
3622 3629
                               useCluster = input$TSCANUseCluster,
3630
+                              pathIndex = pathChoices[1],
3623 3631
                               topN = 4,
3624
-                              useReducedDim = input$TSCANReddim)
3632
+                              useReducedDim = input$TSCANVisRedDim)
3625 3633
         })
3626 3634
       })
3627 3635
 
... ...
@@ -3638,20 +3646,20 @@ shinyServer(function(input, output, session) {
3638 3646
       })
3639 3647
 
3640 3648
       #plot cluster pseudo values by default
3641
-      message(paste0(date(), " ... Plotting pseudotime of branches for Cluster"))
3649
+      message(paste0(date(), " ... Plotting pseudotime of branches for cluster"))
3642 3650
 
3643 3651
       output$tscanCLusterPeudo <- renderPlot({
3644 3652
         isolate({
3645 3653
           plotTSCANClusterPseudo(inSCE = vals$counts,
3646 3654
                                  useCluster = input$TSCANUseCluster,
3647
-                                 useReducedDim = input$TSCANReddim)
3655
+                                 useReducedDim = input$plotTSCANClusterDEG_useReducedDim)
3648 3656
         })
3649 3657
       })
3650 3658
 
3651 3659
       updateCollapse(session = session, "TSCANUI",
3652 3660
                      style = list("Identify Genes Differentially Expressed For Branched Cluster" = "success"))
3653
-      callModule(module = nonLinearWorkflow, id = "nlw-Traj",
3654
-                 parent = session, de = TRUE, pa = TRUE)
3661
+      callModule(module = nonLinearWorkflow, id = "nlw-Traj", parent = session,
3662
+                 de = TRUE, pa = TRUE)
3655 3663
     }
3656 3664
   ))
3657 3665
 
... ...
@@ -3668,78 +3676,61 @@ shinyServer(function(input, output, session) {
3668 3676
                       selected = NULL)
3669 3677
   })
3670 3678
 
3671
-  observeEvent(input$plotTSCANClusterDEG, {
3672
-    req(vals$counts)
3673
-    if (input$plotTSCANClusterDEG_featureDisplay == "Rownames (Default)") {
3674
-      featureDisplay <- "rownames"
3675
-    } else {
3676
-      featureDisplay <- input$plotTSCANClusterDEG_featureDisplay
3677
-    }
3678
-    plot <- plotTSCANClusterDEG(inSCE = vals$counts,
3679
-                                useCluster = input$plotTSCANClusterDEG_useCluster,
3680
-                                pathIndex = input$plotTSCANClusterDEG_pathIndex,
3681
-                                useReducedDim = input$plotTSCANClusterDEG_useReducedDim,
3682
-                                topN = handleEmptyInput(input$plotTSCANClusterDEG_topN, type = "numeric"),
3683
-                                featureDisplay = featureDisplay)
3684
-    if (identical(plot, list())) {
3685
-      shinyalert(text = "No significant feature identified for the selected path.",
3686
-                 type = "warning")
3687
-    } else {
3679
+  observeEvent(input$plotTSCANClusterDEG, withConsoleMsgRedirect(
3680
+    msg = "Please wait while cluster DEG visualization is being updated. See console log for progress.",
3681
+    {
3682
+      req(vals$counts)
3683
+      results <- getTSCANResults(vals$counts,
3684
+                                 analysisName = "ClusterDEAnalysis",
3685
+                                 pathName = input$plotTSCANClusterDEG_useCluster)
3686
+      req(results)
3687
+      if (input$plotTSCANClusterDEG_featureDisplay == "Rownames (Default)") {
3688
+        featureDisplay <- "rownames"
3689
+      } else {
3690
+        featureDisplay <- input$plotTSCANClusterDEG_featureDisplay
3691
+      }
3692
+
3693
+      if (nrow(results$DEgenes[[input$plotTSCANClusterDEG_pathIndex]]) == 0) {
3694
+        shinyalert(text = "No significant feature identified for the selected path.",
3695
+                   type = "warning")
3696
+      }
3697
+      message(date(), " ... Updating UMAP with feature expression")
3698
+      plot <- plotTSCANClusterDEG(inSCE = vals$counts,
3699
+                                  useCluster = input$plotTSCANClusterDEG_useCluster,
3700
+                                  pathIndex = input$plotTSCANClusterDEG_pathIndex,
3701
+                                  useReducedDim = input$plotTSCANClusterDEG_useReducedDim,
3702
+                                  topN = handleEmptyInput(input$plotTSCANClusterDEG_topN, type = "numeric"),
3703
+                                  featureDisplay = featureDisplay)
3704
+
3688 3705
       output$tscanCLusterDEG <- renderPlot({
3689 3706
         isolate({
3690 3707
           plot
3691 3708
         })
3692 3709
       })
3693
-    }
3694 3710
 
3695
-    session$sendCustomMessage("close_dropDownTscanClusterDEG", "")
3696
-  })
3697
-
3698
-
3699
-  # Retrieve DEG table on different branches of the cluster
3700
-  observeEvent(input$useListCluster, {
3701
-    req(vals$counts)
3702
-    results <- getTSCANResults(vals$counts,
3703
-                               analysisName = "ClusterDEAnalysis",
3704
-                               pathName = input$useListCluster)
3705
-    choices <- colnames(results$terminalNodes)
3706
-    choicesOpt <- list(content = results$pathIndexList)
3707
-    updatePickerInput(session, "clusterListPathIndex",
3708
-                      choices = choices, choicesOpt = choicesOpt,
3709
-                      selected = NULL)
3710
-  })
3711
-
3712
-  observeEvent(input$DEClusterListPlot, {
3713
-    req(vals$counts)
3714
-    results <- getTSCANResults(vals$counts,
3715
-                               analysisName = "ClusterDEAnalysis",
3716
-                               pathName = input$useListCluster)
3717
-    req(results)
3718
-    df <- as.data.frame(results$DEgenes[[input$clusterListPathIndex]])
3719
-    output$tscanCLusterDEGTable <- DT::renderDataTable({
3720
-      isolate({
3721
-        DT::datatable(
3722
-          df,
3723
-          options = list(scrollX = TRUE)
3724
-        )
3711
+      message(date(), " ... Updating DEG table")
3712
+      df <- as.data.frame(results$DEgenes[[input$plotTSCANClusterDEG_pathIndex]])
3713
+      output$tscanCLusterDEGTable <- DT::renderDataTable({
3714
+        isolate({
3715
+          DT::datatable(
3716
+            df,
3717
+            options = list(scrollX = TRUE)
3718
+          )
3719
+        })
3725 3720
       })
3726
-    })
3727 3721
 
3728
-    session$sendCustomMessage("close_dropDownTscanClusterDEGTable", "")
3729
-  })
3730
-
3731
-  # Plot recomputed pseudotime on branches of the cluster
3732
-  observeEvent(input$DEClusterPlot, {
3733
-    req(vals$counts)
3734
-    output$tscanCLusterPeudo <- renderPlot({
3735
-      isolate({
3736
-        plotTSCANClusterPseudo(inSCE = vals$counts,
3737
-                               useCluster = input$useVisCluster,
3738
-                               useReducedDim = input$DEClusterRedDimNames)
3722
+      message(date(), " ... Updating UMAP with pseudotime")
3723
+      output$tscanCLusterPeudo <- renderPlot({
3724
+        isolate({
3725
+          plotTSCANClusterPseudo(inSCE = vals$counts,
3726
+                                 useCluster = input$plotTSCANClusterDEG_useCluster,
3727
+                                 useReducedDim = input$plotTSCANClusterDEG_useReducedDim)
3728
+        })
3739 3729
       })
3730
+
3731
+      session$sendCustomMessage("close_dropDownTscanClusterDEG", "")
3740 3732
     })
3741
-    session$sendCustomMessage("close_dropDownTscanClusterPseudo", "")
3742
-  })
3733
+  )
3743 3734
 
3744 3735
   ###################################################
3745 3736
   ###  Run STEP 4: Plot gene of interest
... ...
@@ -3748,7 +3739,7 @@ shinyServer(function(input, output, session) {
3748 3739
     msg = "Please wait when the expression of selected features are being plotted. See console log for progress.",
3749 3740
     {
3750 3741
       req(vals$counts)
3751
-      if (input$plotTSCANDimReduceFeatures_features == "") {
3742
+      if (is.null(input$plotTSCANDimReduceFeatures_features)) {
3752 3743
         stop("Must select at least one feature.")
3753 3744
       }
3754 3745
       if (input$plotTSCANDimReduceFeatures_featureDisplay == "Rownames (Default)") {
... ...
@@ -3757,9 +3748,6 @@ shinyServer(function(input, output, session) {
3757 3748
         featureDisplay <- input$plotTSCANDimReduceFeatures_featureDisplay
3758 3749
       }
3759 3750
       useCluster <- input$plotTSCANDimReduceFeatures_useCluster
3760
-      if (useCluster == "Use all") {
3761
-        useCluster <- NULL
3762
-      }
3763 3751
       output$TscanDimReduceFeatures <- renderPlot({
3764 3752
         isolate({
3765 3753
           plotTSCANDimReduceFeatures(inSCE = vals$counts,
... ...
@@ -3782,26 +3770,14 @@ shinyServer(function(input, output, session) {
3782 3770
     session$sendCustomMessage("close_dropDownTSCAN", "")
3783 3771
   })
3784 3772
 
3785
-  observeEvent(input$closeDropDownTscanDEHM,{
3786
-    session$sendCustomMessage("close_dropDownTscanDEHM", "")
3787
-  })
3788
-
3789
-  observeEvent(input$closeDropDownTscanDEReg,{
3790
-    session$sendCustomMessage("close_dropDownTscanDEReg", "")
3773
+  observeEvent(input$closeDropDownTscanDE,{
3774
+    session$sendCustomMessage("close_dropDownTscanDE", "")
3791 3775
   })
3792 3776
 
3793 3777
   observeEvent(input$closeDropDownTscanClusterDEG,{
3794 3778
     session$sendCustomMessage("close_dropDownTscanClusterDEG", "")
3795 3779
   })
3796 3780
 
3797
-  observeEvent(input$closeDropDownTscanClusterDEGTable,{
3798
-    session$sendCustomMessage("close_dropDownTscanClusterDEGTable", "")
3799
-  })
3800
-
3801
-  observeEvent(input$closeDropDownTscanClusterPseudo,{
3802
-    session$sendCustomMessage("close_dropDownTscanClusterPseudo", "")
3803
-  })
3804
-
3805 3781
   #-----------------------------------------------------------------------------
3806 3782
   # Page 3.2: Celda ####
3807 3783
   #-----------------------------------------------------------------------------
... ...
@@ -3939,7 +3915,8 @@ shinyServer(function(input, output, session) {
3939 3915
       selector = "div[value='Visualization']")
3940 3916
     updateNumericInput(session, "celdamodheatmapnum", min = 1, max = input$celdaLselect, value = 1)
3941 3917
     # Show downstream analysis options
3942
-    callModule(module = nonLinearWorkflow, id = "nlw-celda", parent = session, de = TRUE, pa = TRUE)
3918
+    callModule(module = nonLinearWorkflow, id = "nlw-celda", parent = session,
3919
+               de = TRUE, pa = TRUE)
3943 3920
 
3944 3921
   })
3945 3922
 
... ...
@@ -7947,7 +7924,8 @@ shinyServer(function(input, output, session) {
7947 7924
 
7948 7925
 
7949 7926
     # Show downstream analysis options
7950
-    callModule(module = nonLinearWorkflow, id = "nlw-seurat", parent = session, de = TRUE, pa = TRUE)
7927
+    callModule(module = nonLinearWorkflow, id = "nlw-seurat", parent = session,
7928
+               de = TRUE, fm = TRUE, pa = TRUE)
7951 7929
 
7952 7930
     updateCollapse(session = session, "SeuratUI", style = list("Find Markers" = "success"))
7953 7931
 
... ...
@@ -1,5 +1,6 @@
1 1
 # Check if CRAN packages are installed, otherwise prompt user to install them.
2
-requiredPackages <- c("shinyjqui", "shinyWidgets", "shinythemes", "shinyFiles")
2
+requiredPackages <- c("shinyjqui", "shinyWidgets", "shinythemes", "shinyFiles",
3
+                      "shinyBS", "shinybusy", "tidyverse")
3 4
 if(!all(requiredPackages %in% installed.packages())){
4 5
   missingPackages <- requiredPackages[which(requiredPackages %in% installed.packages() == FALSE)]
5 6
   message("Installing missing packages: ")
... ...
@@ -248,7 +249,7 @@ shinyUI(
248 249
         "Trajectory Analysis",
249 250
         tabPanel("TSCAN", value = "TSCANWorkflow", shinyPanelTSCAN)
250 251
       ),
251
-      
252
+
252 253
       tabPanel("Sample Size Calculator", shinyPanelSubsample),
253 254
       navbarMenu(
254 255
         "Curated Workflows",
... ...
@@ -266,14 +267,14 @@ shinyUI(
266 267
                tags$head(
267 268
                  tags$script(HTML(jsScriptAutoScrollConsole))
268 269
                ),
269
-               hidden(div(id = "consolePanel", style = "overflow-y:scroll; 
270
-                          max-height: 220px; width: 100%; background-color: white; 
270
+               hidden(div(id = "consolePanel", style = "overflow-y:scroll;
271
+                          max-height: 220px; width: 100%; background-color: white;
271 272
                           position: relative; bottom: 0; align: centre; padding: 0px;",
272
-                          verbatimTextOutput(outputId="consoleText", placeholder = TRUE) 
273
+                          verbatimTextOutput(outputId="consoleText", placeholder = TRUE)
273 274
                ))
274 275
         )
275 276
       ),
276
-      
277
+
277 278
       # fluidRow(
278 279
       #   column(12, id = "consoleDiv", align = "right",
279 280
       #          actionButton(inputId="interpretToggle", label = "Interpret"),
... ...
@@ -58,11 +58,11 @@ shinyPanelImport <- fluidPage(
58 58
       ),
59 59
       tags$hr(),
60 60
       conditionalPanel(condition = sprintf("input['%s'] == 'files'", "uploadChoice"),
61
-                       h3("Upload data in tab separated text format:"),
61
+                       h4("Upload data in tab separated text format:"),
62 62
                        fluidRow(
63 63
                          column(width = 4,
64 64
                                 wellPanel(
65
-                                  h4("Example count file:"),
65
+                                  h5("Example count file:"),
66 66
                                   HTML('<table class="table"><thead><tr class="header"><th>Gene</th>
67 67
                  <th>Cell1</th><th>Cell2</th><th>&#x2026;</th><th>CellN</th>
68 68
                  </tr></thead><tbody><tr class="odd"><td>Gene1</td><td>0</td>
... ...
@@ -77,7 +77,6 @@ shinyPanelImport <- fluidPage(
77 77
                                   tags$a(href = "https://drive.google.com/open?id=1n0CtM6phfkWX0O6xRtgPPg6QuPFP6pY8",
78 78
                                          "Download an example count file here.", target = "_blank"),
79 79
                                   tags$br(),
80
-                                  tags$br(),
81 80
                                   fileInput(
82 81
                                     "countsfile",
83 82
                                     HTML(
... ...
@@ -98,7 +97,7 @@ shinyPanelImport <- fluidPage(
98 97
                          ),
99 98
                          column(width = 4,
100 99
                                 wellPanel(
101
-                                  h4("Example cell annotation file:"),
100
+                                  h5("Example cell annotation file:"),
102 101
                                   HTML('<table class="table"><thead><tr class="header"><th>Cell</th>
103 102
                  <th>Annot1</th><th>&#x2026;</th></tr></thead><tbody><tr class="odd">
104 103
                  <td>Cell1</td><td>a</td><td>&#x2026;</td></tr><tr class="even">
... ...
@@ -109,7 +108,6 @@ shinyPanelImport <- fluidPage(
109 108
                                   tags$a(href = "https://drive.google.com/open?id=10IDmZQUiASN4wnzO4-WRJQopKvxCNu6J",
110 109
                                          "Download an example annotation file here.", target = "_blank"),
111 110
                                   tags$br(),
112
-                                  tags$br(),
113 111
                                   fileInput(
114 112
                                     "annotFile", "Cell annotations (optional):",
115 113
                                     accept = c(
... ...
@@ -121,7 +119,7 @@ shinyPanelImport <- fluidPage(
121 119
                          ),
122 120
                          column(width = 4,
123 121
                                 wellPanel(
124
-                                  h4("Example feature file:"),
122
+                                  h5("Example feature file:"),
125 123
                                   HTML('<table class="table"><thead><tr class="header"><th>Gene</th>
126 124
                <th>Annot2</th><th>&#x2026;</th></tr></thead><tbody><tr class="odd">
127 125
                  <td>Gene1</td><td>a</td><td>&#x2026;</td></tr><tr class="even">
... ...
@@ -132,7 +130,6 @@ shinyPanelImport <- fluidPage(
132 130
                                   tags$a(href = "https://drive.google.com/open?id=1gxXaZPq5Wrn2lNHacEVaCN2a_FHNvs4O",
133 131
                                          "Download an example feature file here.", target = "_blank"),
134 132
                                   tags$br(),
135
-                                  tags$br(),
136 133
                                   fileInput(
137 134
                                     "featureFile", "Feature annotations (optional):",
138 135
                                     accept = c(
... ...
@@ -147,67 +144,67 @@ shinyPanelImport <- fluidPage(
147 144
       ),
148 145
       conditionalPanel(
149 146
         condition = sprintf("input['%s'] == 'example'", "uploadChoice"),
150
-        h3("Choose Example Dataset:"),
151
-        selectInput("selectExampleData", label = NULL, exampleDatasets),
147
+        h4("Choose Example Dataset:"),
148
+        selectInput("selectExampleData", label = NULL, exampleDatasets, width = "340px"),
152 149
         conditionalPanel(
153 150
           condition = sprintf("input['%s'] == 'fluidigm_pollen'", "selectExampleData"),
154
-          h3(tags$a(href = "http://dx.doi.org/10.1038/nbt.2967", "130 cells from (Pollen et al. 2014), 65 at high coverage and 65 at low coverage", target = "_blank")),
151
+          h4(tags$a(href = "http://dx.doi.org/10.1038/nbt.2967", "130 cells from (Pollen et al. 2014), 65 at high coverage and 65 at low coverage", target = "_blank")),
155 152
           "Transcriptomes of cell populations in both of low-coverage (~0.27 million reads per cell) and high-coverage (~5 million reads per cell) to identify cell-type-specific biomarkers, and to compare gene expression across samples specifically for cells of a given type as well as to reconstruct developmental lineages of related cell types. Data was loaded from the 'scRNASeq' package.",
156 153
           tags$br(),
157 154
           tags$br()
158 155
         ),
159 156
         conditionalPanel(
160 157
           condition = sprintf("input['%s'] == 'allen_tasic'", "selectExampleData"),
161
-          h3(tags$a(href = "http://dx.doi.org/10.1038/nn.4216", "Mouse visual cortex cells from (Tasic et al. 2016)", target = "_blank")),
158
+          h4(tags$a(href = "http://dx.doi.org/10.1038/nn.4216", "Mouse visual cortex cells from (Tasic et al. 2016)", target = "_blank")),
162 159
           "Subset of 379 cells from the mouse visual cortex. Data was loaded from the 'scRNASeq' package.",
163 160
           tags$br(),
164 161
           tags$br()
165 162
         ),
166 163
         conditionalPanel(
167 164
           condition = sprintf("input['%s'] == 'NestorowaHSCData'", "selectExampleData"),
168
-          h3(tags$a(href = "https://www.nature.com/articles/nbt.2967", "1920 Mouse haematopoietic stem cells from (Nestorowa et al. 2015).", target= "_blank")),
165
+          h4(tags$a(href = "https://www.nature.com/articles/nbt.2967", "1920 Mouse haematopoietic stem cells from (Nestorowa et al. 2015).", target= "_blank")),
169 166
           "Data was loaded from the 'scRNASeq' package.",
170 167
           tags$br(),
171 168
           tags$br()
172 169
         ),
173 170
         conditionalPanel(
174 171
           condition = sprintf("input['%s'] == 'pbmc3k'", "selectExampleData"),
175
-          h3(tags$a(href = "https://doi.org/10.1038/ncomms14049", "2,700 peripheral blood mononuclear cells (PBMCs) from 10X Genomics", target = "_blank")),
172
+          h4(tags$a(href = "https://doi.org/10.1038/ncomms14049", "2,700 peripheral blood mononuclear cells (PBMCs) from 10X Genomics", target = "_blank")),
176 173
           "Data was loaded with the 'TENxPBMCData' package.",
177 174
           tags$br(),
178 175
           tags$br()
179 176
         ),
180 177
         conditionalPanel(
181 178
           condition = sprintf("input['%s'] == 'pbmc4k'", "selectExampleData"),
182
-          h3(tags$a(href = "https://doi.org/10.1038/ncomms14049", "4,430 peripheral blood mononuclear cells (PBMCs) from 10X Genomics", target = "_blank")),
179
+          h4(tags$a(href = "https://doi.org/10.1038/ncomms14049", "4,430 peripheral blood mononuclear cells (PBMCs) from 10X Genomics", target = "_blank")),
183 180
           "Data was loaded with the 'TENxPBMCData' package.",
184 181
           tags$br(),
185 182
           tags$br()
186 183
         ),
187 184
         conditionalPanel(
188 185
           condition = sprintf("input['%s'] == 'pbmc6k'", "selectExampleData"),
189
-          h3(tags$a(href = "https://doi.org/10.1038/ncomms14049", "5,419 peripheral blood mononuclear cells (PBMCs) from 10X Genomics", target = "_blank")),
186
+          h4(tags$a(href = "https://doi.org/10.1038/ncomms14049", "5,419 peripheral blood mononuclear cells (PBMCs) from 10X Genomics", target = "_blank")),
190 187
           "Data was loaded with the 'TENxPBMCData' package.",
191 188
           tags$br(),
192 189
           tags$br()
193 190
         ),
194 191
         conditionalPanel(
195 192
           condition = sprintf("input['%s'] == 'pbmc8k'", "selectExampleData"),
196
-          h3(tags$a(href = "https://doi.org/10.1038/ncomms14049", "8,381 peripheral blood mononuclear cells (PBMCs) from 10X Genomics", target = "_blank")),
193
+          h4(tags$a(href = "https://doi.org/10.1038/ncomms14049", "8,381 peripheral blood mononuclear cells (PBMCs) from 10X Genomics", target = "_blank")),
197 194
           "Data was loaded with the 'TENxPBMCData' package.",
198 195
           tags$br(),
199 196
           tags$br()
200 197
         ),
201 198
         conditionalPanel(
202 199
           condition = sprintf("input['%s'] == 'pbmc33k'", "selectExampleData"),
203
-          h3(tags$a(href = "https://doi.org/10.1038/ncomms14049", "33,148 peripheral blood mononuclear cells (PBMCs) from 10X Genomics", target = "_blank")),
200
+          h4(tags$a(href = "https://doi.org/10.1038/ncomms14049", "33,148 peripheral blood mononuclear cells (PBMCs) from 10X Genomics", target = "_blank")),
204 201
           "Data was loaded with the 'TENxPBMCData' package.",
205 202
           tags$br(),
206 203
           tags$br()
207 204
         ),
208 205
         conditionalPanel(
209 206
           condition = sprintf("input['%s'] == 'pbmc68k'", "selectExampleData"),
210
-          h3(tags$a(href = "https://doi.org/10.1038/ncomms14049", "68,579 peripheral blood mononuclear cells (PBMCs) from 10X Genomics", target = "_blank")),
207
+          h4(tags$a(href = "https://doi.org/10.1038/ncomms14049", "68,579 peripheral blood mononuclear cells (PBMCs) from 10X Genomics", target = "_blank")),
211 208
           "Data was loaded with the 'TENxPBMCData' package.",
212 209
           tags$br(),
213 210
           tags$br()
... ...
@@ -216,7 +213,7 @@ shinyPanelImport <- fluidPage(
216 213
       ),
217 214
       conditionalPanel(
218 215
         condition = sprintf("input['%s'] == 'rds'", "uploadChoice"),
219
-        h3("Choose an RDS file that contains a SingleCellExperiment or Seurat object:"),
216
+        h4("Choose an RDS file that contains a SingleCellExperiment or Seurat object:"),
220 217
         fileInput(
221 218
           "rdsFile", "SingleCellExperiment or Seurat RDS file:", accept = c(".rds", ".RDS")
222 219
         ),
... ...
@@ -300,14 +297,14 @@ shinyPanelImport <- fluidPage(
300 297
           )
301 298
         )
302 299
       ),
303
-      fluidRow(
304
-        column(2, actionButton("uploadData", "Import")),
305
-        column(3, actionButton("backToStepOne", "Add more sample"))
306
-      ),
307 300
 
308
-
309
-      tags$br(),
310
-      tags$br(),
301
+        column(
302
+          12,
303
+          fluidRow(
304
+            actionButton("uploadData", "Import"),
305
+            actionButton("backToStepOne", "Add one more sample")
306
+          )
307
+        ),
311 308
       style = "primary"
312 309
     ),
313 310
 
... ...
@@ -4,21 +4,12 @@ shinyPanelTSCAN <- fluidPage(
4 4
   tags$script("Shiny.addCustomMessageHandler('close_dropDownTSCAN', function(x){
5 5
                   $('html').click();
6 6
                 });"),
7
-  tags$script("Shiny.addCustomMessageHandler('close_dropDownTscanDEHM', function(x){
8
-                  $('html').click();
9
-                });"),
10
-  tags$script("Shiny.addCustomMessageHandler('close_dropDownTscanDEReg', function(x){
7
+  tags$script("Shiny.addCustomMessageHandler('close_dropDownTscanDE', function(x){
11 8
                   $('html').click();
12 9
                 });"),
13 10
   tags$script("Shiny.addCustomMessageHandler('close_dropDownTscanClusterDEG', function(x){
14 11
                   $('html').click();
15 12
                 });"),
16
-  tags$script("Shiny.addCustomMessageHandler('close_dropDownTscanClusterDEGTable', function(x){
17
-                  $('html').click();
18
-                });"),
19
-  tags$script("Shiny.addCustomMessageHandler('close_dropDownTscanClusterPseudo', function(x){
20
-                  $('html').click();
21
-                });"),
22 13
 
23 14
   h1("Trajectory Analysis - TSCAN"),
24 15
   h5(tags$a(href = paste0(docs.artPath, "trajectoryAnalysis.html"),
... ...
@@ -124,143 +115,127 @@ shinyPanelTSCAN <- fluidPage(
124 115
                         options = list(
125 116
                           `none-selected-text` = "No cluster discarded"
126 117
                         )),
127
-            actionButton("findExpGenes", "Run")
118
+            actionButton("runTSCANDEG", "Run")
128 119
           )
129 120
         ),
130 121
         column(
131 122
           8,
132
-          tabsetPanel(
133
-            tabPanel(
134
-              # Tab 2.1, DEG Heatmap ####
135
-              "Heatmap",
136
-              panel(
137
-                fluidRow(
138
-                  column(
139
-                    width = 3,
140
-                    dropdown(
123
+          panel(
124
+            fluidRow(
125
+              column(
126
+                width = 3,
127
+                dropdown(
128
+                  fluidRow(
129
+                    column(
130
+                      12,
141 131
                       fluidRow(
142
-                        column(
143
-                          12,
144
-                          fluidRow(
145
-                            actionBttn(inputId = "closeDropDownTscanDEHM",
146
-                                       label = NULL, style = "simple",
147
-                                       color = "danger", icon = icon("times"),
148
-                                       size = "xs"),
149
-                            align = "right"
150
-                          ),
151
-                          selectInput("tscanDEHMexpPathIndex",
152
-                                      "Select path terminal node:",
153
-                                      choices = "", multiple = FALSE),
154
-                          numericInput(inputId = "tscanDEHMTopGenes",
155
-                                       label = "Number of top features",
156
-                                       value = 30,
157
-                                       step = 1),
158
-                          selectInput("tscanDEHMFeatureDisplay",
159
-                                      "Display ID Type",
160
-                                      c("Rownames (Default)",
161
-                                        featureChoice)),
162
-                          actionBttn(
163
-                            inputId = "tscanDEHMPlot",
164
-                            label = "Update",
165
-                            style = "bordered",
166
-                            color = "primary",
167
-                            size = "sm"
168
-                          ),
169
-                        )
132
+                        actionBttn(inputId = "closeDropDownTscanDE",
133
+                                   label = NULL, style = "simple",
134
+                                   color = "danger", icon = icon("times"),
135
+                                   size = "xs"),
136
+                        align = "right"
170 137
                       ),
171
-                      inputId = "dropDownTscanDEHM",
172
-                      icon = icon("cog"),
173
-                      status = "primary",
174
-                      circle = FALSE,
175
-                      inline = TRUE
138
+                      selectInput("tscanDEexpPathIndex",
139
+                                  "Select path terminal node:",
140
+                                  choices = "", multiple = FALSE),
141
+                      numericInput(inputId = "tscanDEHMTopGenes",
142
+                                   label = "Number of top features for heatmap",
143
+                                   value = 30,
144
+                                   step = 1),
145
+                      numericInput(inputId = "tscanDERegTopGenes",
146
+                                   label = "Number of top features for regulation plots",
147
+                                   value = 10,
148
+                                   step = 1),
149
+                      selectInput("tscanDEFeatureDisplay",
150
+                                  "Display ID Type",
151
+                                  c("Rownames (Default)",
152
+                                    featureChoice)),
153
+                      actionBttn(
154
+                        inputId = "tscanDEPlot",
155
+                        label = "Update",
156
+                        style = "bordered",
157
+                        color = "primary",
158
+                        size = "sm"
159
+                      )
176 160
                     )
177 161
                   ),
162
+                  inputId = "dropDownTscanDE",
163
+                  icon = icon("cog"),
164
+                  status = "primary",
165
+                  circle = FALSE,
166
+                  inline = TRUE
167
+                )
168
+              ),
169
+              column(
170
+                width = 9,
171
+                fluidRow(
178 172
                   column(
179
-                    width = 9,
180
-                    fluidRow(
181
-                      column(
182
-                        width = 12,
183
-                        h6(
184
-                          "A heatmap of the expression of the top DE genes along the path in the cells on the path. "
185
-                        )
186
-                      ),
187
-                      align="center"
173
+                    width = 12,
174
+                    h6(
175
+                      "Visualization on top genes that have significant expression changes along the pseudotime path of insterest."
188 176
                     )
189
-                  )
190
-                ),
191
-                hr(),
192
-                shinyjqui::jqui_resizable(
193
-                  plotOutput(outputId = "heatmapPlot")
177
+                  ),
178
+                  align = "center"
194 179
                 )
195 180
               )
196 181
             ),
197
-            tabPanel(
198
-              # Tab 2.2, Gene expression change along pseudotime ####
199
-              "Regulated Genes",
200
-              panel(
201
-                fluidRow(
202
-                  column(
203
-                    width = 3,
204
-                    dropdown(
205
-                      fluidRow(
206
-                        column(
207
-                          12,
208
-                          fluidRow(
209
-                            actionBttn(inputId = "closeDropDownTscanDEReg",
210
-                                       label = NULL, style = "simple",
211
-                                       color = "danger", icon = icon("times"),
212
-                                       size = "xs"),
213
-                            align = "right"
214
-                          ),
215
-                          selectInput("tscanDERegexpPathIndex",
216
-                                      "Select path terminal node:",
217
-                                      choices = "", multiple = FALSE),
218
-                          radioButtons("tscanDERegDirection",
219
-                                      "Regulation",
220
-                                      choices = c("up" = "increasing",
221
-                                                  "down" = "decreasing"),
222
-                                      selected = "increasing",
223
-                                      inline = TRUE),
224
-                          numericInput(inputId = "tscanDERegTopGenes",
225
-                                       label = "Number of top features",
226
-                                       value = 10,
227
-                                       step = 1),
228
-                          selectInput("tscanDERegFeatureDisplay",
229
-                                      "Display ID Type",
230
-                                      c("Rownames (Default)",
231
-                                        featureChoice)),
232
-                          actionBttn(
233
-                            inputId = "tscanDERegPlot",
234
-                            label = "Update",
235
-                            style = "bordered",
236
-                            color = "primary",
237
-                            size = "sm"
238
-                          )
239
-                        )
240
-                      ),
241
-                      inputId = "dropDownTscanDEReg",
242
-                      icon = icon("cog"),
243
-                      status = "primary",
244
-                      circle = FALSE,
245
-                      inline = TRUE
246
-                    )
182
+            hr(),
183
+            tabsetPanel(
184
+              tabPanel(
185
+                # Tab 2.1, DEG Heatmap ####
186
+                "Heatmap",
187
+                panel(
188
+                  fluidRow(
189
+                    column(
190
+                      width = 12,
191
+                      h6(
192
+                        "A heatmap of the expression of the top DE genes along the path in the cells on the path. "
193
+                      )
194
+                    ),
195
+
247 196
                   ),
248
-                  column(
249
-                    width = 9,
250
-                    fluidRow(
251
-                      column(
252
-                        width = 12,
253
-                        h6(
254
-                          "A cell scatter plot showing the expression change along the pseudotime. Genes with top significance in the changes are displayed."
255
-                        )
256
-                      ),
257
-                      align="center"
258
-                    )
197
+                  hr(),
198
+                  shinyjqui::jqui_resizable(
199
+                    plotOutput(outputId = "heatmapPlot")
200
+                  )
201
+                )
202
+              ),
203
+              tabPanel(
204
+                # Tab 2.2, Gene expression increasing along pseudotime ####
205
+                "Up-regulated Genes",
206
+                panel(
207
+                  fluidRow(
208
+                    column(
209
+                      width = 12,
210
+                      h6(
211
+                        "A cell scatter plot showing the expression change along the pseudotime. Genes with top significance in increasing expression along the pseudotime are displayed."
212
+                      )
213
+                    ),
214
+                    align="center"
215
+                  ),
216
+                  hr(),
217
+                  shinyjqui::jqui_resizable(
218
+                    plotOutput(outputId = "UpregGenesPlot")
219
+                  )
220
+                )
221
+              ),
222
+              tabPanel(
223
+                # Tab 2.3, Gene expression decreasing along pseudotime ####
224
+                "Down-regulated Genes",
225
+                panel(
226
+                  fluidRow(
227
+                    column(
228
+                      width = 12,
229
+                      h6(
230
+                        "A cell scatter plot showing the expression change along the pseudotime. Genes with top significance in decreasing expression along the pseudotime are displayed."
231
+                      )
232
+                    ),
233
+                    align="center"
234
+                  ),
235
+                  hr(),
236
+                  shinyjqui::jqui_resizable(
237
+                    plotOutput(outputId = "DownregGenesPlot")
259 238
                   )
260
-                ),
261
-                hr(),
262
-                shinyjqui::jqui_resizable(
263
-                  plotOutput(outputId = "UpregGenesPlot")
264 239
                 )
265 240
               )
266 241
             )
... ...
@@ -296,177 +271,118 @@ shinyPanelTSCAN <- fluidPage(
296 271
         ),
297 272
         column(
298 273
           8,
299
-          tabsetPanel(
300
-            tabPanel(
301
-              # Tab 3.1, feature cluster expression scatter ####
302
-              "Top Feature Plot",
303
-              panel(
274
+          panel(
275
+            fluidRow(
276
+              column(