biopipen 0.25.4__py3-none-any.whl → 0.26.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of biopipen might be problematic. Click here for more details.
- biopipen/__init__.py +1 -1
- biopipen/core/config.toml +2 -0
- biopipen/ns/rnaseq.py +142 -5
- biopipen/ns/scrna.py +17 -3
- biopipen/ns/snp.py +70 -0
- biopipen/ns/stats.py +320 -0
- biopipen/scripts/rnaseq/Simulation-ESCO.R +177 -0
- biopipen/scripts/rnaseq/Simulation-RUVcorr.R +42 -0
- biopipen/scripts/rnaseq/Simulation.R +23 -0
- biopipen/scripts/rnaseq/UnitConversion.R +323 -54
- biopipen/scripts/scrna/CellsDistribution.R +225 -147
- biopipen/scripts/scrna/MarkersFinder.R +53 -47
- biopipen/scripts/scrna/RadarPlots.R +6 -3
- biopipen/scripts/scrna/SeuratClusterStats-stats.R +37 -0
- biopipen/scripts/scrna/TopExpressingGenes.R +58 -33
- biopipen/scripts/snp/PlinkSimulation.py +88 -0
- biopipen/scripts/stats/ChowTest.R +119 -0
- biopipen/scripts/stats/DiffCoexpr.R +150 -0
- biopipen/scripts/stats/LiquidAssoc.R +136 -0
- biopipen/scripts/stats/MetaPvalue.R +128 -0
- biopipen/scripts/tcr/CloneResidency.R +37 -72
- biopipen/utils/misc.R +19 -0
- biopipen/utils/misc.py +15 -0
- {biopipen-0.25.4.dist-info → biopipen-0.26.1.dist-info}/METADATA +9 -10
- {biopipen-0.25.4.dist-info → biopipen-0.26.1.dist-info}/RECORD +27 -17
- {biopipen-0.25.4.dist-info → biopipen-0.26.1.dist-info}/WHEEL +1 -1
- {biopipen-0.25.4.dist-info → biopipen-0.26.1.dist-info}/entry_points.txt +2 -0
|
@@ -6,6 +6,7 @@ library(tidyr)
|
|
|
6
6
|
library(tibble)
|
|
7
7
|
library(dplyr)
|
|
8
8
|
library(ggplot2)
|
|
9
|
+
library(patchwork)
|
|
9
10
|
library(ggVennDiagram)
|
|
10
11
|
library(UpSetR)
|
|
11
12
|
library(circlize)
|
|
@@ -33,11 +34,11 @@ cases <- {{envs.cases | r}} # nolint
|
|
|
33
34
|
|
|
34
35
|
if (is.null(overlap)) { overlap = c() }
|
|
35
36
|
overlaps <- list()
|
|
36
|
-
log_info("
|
|
37
|
+
log_info("Loading seurat object ...")
|
|
37
38
|
srtobj <- readRDS(srtfile)
|
|
38
39
|
|
|
39
40
|
if (!is.null(mutaters) && length(mutaters) > 0) {
|
|
40
|
-
log_info("
|
|
41
|
+
log_info("Mutating seurat object ...")
|
|
41
42
|
srtobj@meta.data <- srtobj@meta.data %>%
|
|
42
43
|
mutate(!!!lapply(mutaters, parse_expr))
|
|
43
44
|
}
|
|
@@ -140,24 +141,24 @@ casename_info <- function(casename, create = FALSE) {
|
|
|
140
141
|
out
|
|
141
142
|
}
|
|
142
143
|
|
|
143
|
-
plot_heatmap <- function(
|
|
144
|
-
log_info(paste("- Running heatmap for case:", info$casename, "group:", group))
|
|
145
|
-
hmfile <- file.path(info$sec_dir, paste0(info$case_slug, ".", slugify(group), ".heatmap.png"))
|
|
146
|
-
|
|
144
|
+
plot_heatmap <- function(m, cells_by, group_by, cluster_order_val, cluster_orderby) {
|
|
147
145
|
# A matrix: 10 × 8 of type int
|
|
148
146
|
# g3 g6 g0 g1 g7 g5 g4 g8
|
|
149
147
|
# CSARDATNNEQFF 8 32 17 26 7 1 NA NA
|
|
150
148
|
# CASRQNRGSYNEQFF 2 1 20 16 NA NA 1 NA
|
|
151
149
|
# CSATSYNEQFF 2 6 3 7 1 8 6 NA
|
|
152
|
-
hmdata <-
|
|
153
|
-
|
|
154
|
-
|
|
150
|
+
hmdata <- m %>%
|
|
151
|
+
mutate(
|
|
152
|
+
!!sym(cells_by) := paste0("[", !!sym(group_by), "] ", !!sym(cells_by))
|
|
153
|
+
) %>%
|
|
154
|
+
select(!!sym(cells_by), CloneGroupClusterSize, seurat_clusters) %>%
|
|
155
|
+
distinct(!!sym(cells_by), seurat_clusters, .keep_all = TRUE) %>%
|
|
155
156
|
pivot_wider(names_from = seurat_clusters, values_from = CloneGroupClusterSize) %>%
|
|
156
|
-
tibble::column_to_rownames(
|
|
157
|
+
tibble::column_to_rownames(cells_by)
|
|
157
158
|
|
|
158
|
-
hmdata[, setdiff(levels(
|
|
159
|
+
hmdata[, setdiff(levels(m$seurat_clusters), colnames(hmdata))] <- NA
|
|
159
160
|
# order
|
|
160
|
-
hmdata <- select(hmdata, all_of(levels(
|
|
161
|
+
hmdata <- select(hmdata, all_of(levels(m$seurat_clusters)))
|
|
161
162
|
|
|
162
163
|
row_ha <- rowAnnotation(
|
|
163
164
|
Total = anno_barplot(
|
|
@@ -171,28 +172,23 @@ plot_heatmap <- function(group, meta, case, info, cluster_order_val) {
|
|
|
171
172
|
extra_width <- 0 # legend
|
|
172
173
|
if (!is.null(cluster_order_val)) {
|
|
173
174
|
ha <- list()
|
|
174
|
-
ha[[
|
|
175
|
+
ha[[cluster_orderby]] <- cluster_order_val
|
|
175
176
|
if (is.numeric(cluster_order_val)) {
|
|
176
177
|
col_fun <- colorRamp2(
|
|
177
178
|
c(min(cluster_order_val), max(cluster_order_val)),
|
|
178
179
|
c("lightyellow", "red"))
|
|
179
180
|
ha$col <- list()
|
|
180
|
-
ha$col[[
|
|
181
|
+
ha$col[[cluster_orderby]] <- col_fun
|
|
181
182
|
}
|
|
182
183
|
ha <- do_call(HeatmapAnnotation, ha)
|
|
183
184
|
extra_height <- 40
|
|
184
185
|
extra_width <- 120
|
|
185
186
|
}
|
|
186
|
-
hm_devpars <- case$hm_devpars
|
|
187
|
-
if (is.null(hm_devpars$res)) { hm_devpars$res = 100 }
|
|
188
|
-
if (is.null(hm_devpars$width)) { hm_devpars$width = ncol(hmdata) * 30 + 400 + extra_width }
|
|
189
|
-
if (is.null(hm_devpars$height)) { hm_devpars$height = nrow(hmdata) * 30 + 60 + extra_height }
|
|
190
187
|
|
|
191
188
|
col_fun <- colorRamp2(c(0, max(hmdata, na.rm = T)), c("lightyellow", "purple"))
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
name = "Size",
|
|
189
|
+
Heatmap(
|
|
190
|
+
as.matrix(hmdata),
|
|
191
|
+
name = cells_by,
|
|
196
192
|
col = col_fun,
|
|
197
193
|
na_col = "lightyellow",
|
|
198
194
|
row_names_side = "left",
|
|
@@ -203,13 +199,10 @@ plot_heatmap <- function(group, meta, case, info, cluster_order_val) {
|
|
|
203
199
|
right_annotation = row_ha,
|
|
204
200
|
top_annotation = ha
|
|
205
201
|
)
|
|
206
|
-
print(p)
|
|
207
|
-
dev.off()
|
|
208
|
-
hmfile
|
|
209
202
|
}
|
|
210
203
|
|
|
211
204
|
do_case <- function(name, case) {
|
|
212
|
-
log_info(paste("
|
|
205
|
+
log_info(paste("Running case:", name))
|
|
213
206
|
if (is.null(case$group_by) || nchar(case$group_by) == 0) {
|
|
214
207
|
stop(paste0("`group_by` must be specified for case", name))
|
|
215
208
|
}
|
|
@@ -219,9 +212,6 @@ do_case <- function(name, case) {
|
|
|
219
212
|
info <- casename_info(name, create = TRUE)
|
|
220
213
|
cells_by <- trimws(strsplit(case$cells_by, ",")[[1]])
|
|
221
214
|
|
|
222
|
-
outfile <- file.path(info$sec_dir, paste0(info$case_slug, ".png"))
|
|
223
|
-
txtfile <- file.path(info$sec_dir, paste0(info$case_slug, ".txt"))
|
|
224
|
-
|
|
225
215
|
meta <- srtobj@meta.data
|
|
226
216
|
# order the clusters if cluster_orderby is specified
|
|
227
217
|
cluster_order_val <- NULL
|
|
@@ -245,137 +235,229 @@ do_case <- function(name, case) {
|
|
|
245
235
|
if (!is.null(case$subset) && nchar(case$subset) > 0) {
|
|
246
236
|
meta <- dplyr::filter(meta, !!!parse_exprs(case$subset))
|
|
247
237
|
}
|
|
248
|
-
meta <- meta %>%
|
|
249
|
-
|
|
250
|
-
dplyr::filter(!if_all(all_of(cells_by), is.na))
|
|
238
|
+
meta <- meta %>% drop_na(case$group_by)
|
|
239
|
+
# dplyr::filter(!if_all(all_of(cells_by), is.na))
|
|
251
240
|
|
|
252
241
|
if (nrow(meta) == 0) {
|
|
253
|
-
stop(paste0("No cells left after filtering NAs for group_by
|
|
242
|
+
stop(paste0("No cells left after filtering NAs for `group_by`"))
|
|
254
243
|
}
|
|
255
244
|
|
|
256
|
-
if (length(cells_by) > 1) {
|
|
257
|
-
|
|
258
|
-
meta1 <- meta %>% drop_na(cells_by[1])
|
|
259
|
-
meta1[[new_cells_by]] <- meta1[[cells_by[1]]]
|
|
260
|
-
for (i in 2:length(cells_by)) {
|
|
261
|
-
meta2 <- meta %>% drop_na(cells_by[i])
|
|
262
|
-
meta2[[new_cells_by]] <- meta2[[cells_by[i]]]
|
|
263
|
-
meta1 <- rbind(meta1, meta2)
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
cells_by <- new_cells_by
|
|
267
|
-
case$cells_by <- cells_by
|
|
268
|
-
meta <- meta1
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
if (info$section %in% overlap) {
|
|
272
|
-
if (is.null(overlaps[[info$section]])) {
|
|
273
|
-
overlaps[[info$section]] <<- list()
|
|
274
|
-
}
|
|
275
|
-
overlaps[[info$section]][[info$case]] <<- meta %>% pull(cells_by) %>% unique()
|
|
245
|
+
if (info$section %in% overlap && length(cells_by) > 1) {
|
|
246
|
+
stop(paste0("Overlapping groups can only be done for a single `cells_by`"))
|
|
276
247
|
}
|
|
277
248
|
|
|
278
|
-
# add sizes
|
|
279
|
-
meta <- meta %>%
|
|
280
|
-
add_count(!!sym(cells_by), name = "CloneSize") %>%
|
|
281
|
-
add_count(!!sym(cells_by), !!sym(case$group_by), name = "CloneGroupSize") %>%
|
|
282
|
-
add_count(!!sym(cells_by), seurat_clusters, name = "CloneClusterSize") %>%
|
|
283
|
-
add_count(!!sym(cells_by), !!sym(case$group_by), seurat_clusters, name = "CloneGroupClusterSize")
|
|
284
|
-
|
|
285
249
|
# filter group_by values not in group_order
|
|
286
250
|
if (!is.null(case$group_order) && length(case$group_order) > 0) {
|
|
287
251
|
meta <- meta %>%
|
|
288
252
|
dplyr::filter(!!sym(case$group_by) %in% case$group_order) %>%
|
|
289
|
-
mutate(!!sym(case$group_by) := factor(!!sym(case$group_by), levels = case$group_order))
|
|
290
|
-
arrange(!!sym(case$group_by))
|
|
253
|
+
mutate(!!sym(case$group_by) := factor(!!sym(case$group_by), levels = case$group_order))
|
|
291
254
|
|
|
292
255
|
if (nrow(meta) == 0) {
|
|
293
256
|
stop(paste0(
|
|
294
257
|
"No items in `group_order` (",
|
|
295
258
|
paste0(case$group_order, collapse=", "),
|
|
296
|
-
") in column `", case$group_by ,
|
|
297
|
-
name,
|
|
259
|
+
") in column `", case$group_by ,
|
|
298
260
|
". Did you specify the correct `group_by` and `group_order`?"
|
|
299
261
|
))
|
|
300
262
|
}
|
|
301
263
|
} else {
|
|
302
|
-
meta <- meta %>%
|
|
264
|
+
meta <- meta %>% mutate(!!sym(case$group_by) := factor(!!sym(case$group_by)))
|
|
303
265
|
}
|
|
266
|
+
ngroups <- length(unique(meta[[case$group_by]]))
|
|
267
|
+
|
|
268
|
+
piecharts <- list()
|
|
269
|
+
hmdata <- NULL
|
|
270
|
+
hmrowlbls <- c()
|
|
271
|
+
hmsplits <- c()
|
|
272
|
+
hmfile <- file.path(info$sec_dir, paste0(info$case_slug, ".heatmap.png"))
|
|
273
|
+
cells_rows <- 0
|
|
274
|
+
table_files <- c()
|
|
275
|
+
for (n in seq_along(cells_by)) {
|
|
276
|
+
cby <- cells_by[n]
|
|
277
|
+
log_info("- Processing cells_by: {cby}")
|
|
278
|
+
m <- meta %>% drop_na(!!sym(cby))
|
|
279
|
+
|
|
280
|
+
# check if there are enough cells
|
|
281
|
+
if (nrow(m) == 0) {
|
|
282
|
+
stop(paste0(" No cells left after filtering NAs for `", cby, "`"))
|
|
283
|
+
}
|
|
304
284
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
285
|
+
if (info$section %in% overlap) {
|
|
286
|
+
overlaps[[info$section]] <<- overlaps[[info$section]] %||% list()
|
|
287
|
+
overlaps[[info$section]][[info$case]] <<- m %>% pull(cby) %>% unique()
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
# add sizes
|
|
291
|
+
m <- m %>%
|
|
292
|
+
add_count(!!sym(cby), name = "CloneSize") %>%
|
|
293
|
+
add_count(!!sym(cby), !!sym(case$group_by), name = "CloneGroupSize") %>%
|
|
294
|
+
add_count(!!sym(cby), seurat_clusters, name = "CloneClusterSize") %>%
|
|
295
|
+
add_count(!!sym(cby), !!sym(case$group_by), seurat_clusters, name = "CloneGroupClusterSize") %>%
|
|
296
|
+
select(
|
|
297
|
+
!!sym(cby),
|
|
298
|
+
!!sym(case$group_by),
|
|
299
|
+
seurat_clusters,
|
|
300
|
+
CloneSize,
|
|
301
|
+
CloneGroupSize,
|
|
302
|
+
CloneClusterSize,
|
|
303
|
+
CloneGroupClusterSize,
|
|
304
|
+
) %>% distinct(
|
|
305
|
+
!!sym(cby),
|
|
306
|
+
!!sym(case$group_by),
|
|
307
|
+
seurat_clusters,
|
|
308
|
+
.keep_all = TRUE
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
# apply cells order
|
|
313
|
+
if (!is.null(case$cells_order) && length(case$cells_order) > 0) {
|
|
314
|
+
m <- m %>%
|
|
315
|
+
dplyr::filter(!!sym(cby) %in% case$cells_order) %>%
|
|
316
|
+
mutate(!!sym(cby) := factor(!!sym(cby), levels = case$cells_order))
|
|
317
|
+
} else if (!is.null(case$cells_orderby)) {
|
|
318
|
+
ordered_m <- m %>% arrange(!!!parse_exprs(case$cells_orderby))
|
|
319
|
+
cells <- ordered_m %>% pull(cby) %>% unique() %>% head(case$cells_n)
|
|
320
|
+
m <- ordered_m %>% dplyr::filter(!!sym(cby) %in% cells)
|
|
321
|
+
m[[cby]] = factor(m[[cby]], levels = cells)
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
# save the filtered data
|
|
325
|
+
table_file <- file.path(info$sec_dir, paste0(info$case_slug, ".", slugify(cby), ".txt"))
|
|
326
|
+
table_files <- c(table_files, table_file)
|
|
327
|
+
write.table(
|
|
328
|
+
m, table_file,
|
|
329
|
+
sep = "\t", row.names = FALSE, col.names = TRUE, quote = FALSE
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
log_debug(" Plotting pie charts ...")
|
|
333
|
+
cells_rows <- cells_rows + length(unique(m[[cby]]))
|
|
334
|
+
if (n == 1) {
|
|
335
|
+
plot.margin <- unit(c(1,1,0,1), "cm")
|
|
336
|
+
strip.text.x <- element_text(margin = margin(b = 0.5, unit = "cm"))
|
|
337
|
+
} else if (n == length(cells_by)) {
|
|
338
|
+
plot.margin <- unit(c(0,1,1,1), "cm")
|
|
339
|
+
strip.text.x <- element_blank()
|
|
340
|
+
} else {
|
|
341
|
+
plot.margin <- unit(c(0,1,0,1), "cm")
|
|
342
|
+
strip.text.x <- element_blank()
|
|
343
|
+
}
|
|
344
|
+
p = m %>% ggplot(
|
|
345
|
+
aes(
|
|
346
|
+
x = sqrt(CloneGroupSize)/2,
|
|
347
|
+
y = CloneGroupClusterSize,
|
|
348
|
+
width = sqrt(CloneGroupSize),
|
|
349
|
+
fill = seurat_clusters
|
|
350
|
+
)
|
|
351
|
+
) +
|
|
352
|
+
geom_col(width=.01, position="fill", color = "#888888") +
|
|
353
|
+
geom_bar(stat = "identity", position = position_fill(reverse = TRUE)) +
|
|
354
|
+
coord_polar("y", start = 0) +
|
|
355
|
+
scale_fill_biopipen(name = "Cluster", limits = levels(all_clusters)) +
|
|
356
|
+
theme_void() +
|
|
357
|
+
theme(
|
|
358
|
+
plot.margin = plot.margin,
|
|
359
|
+
legend.margin = margin(l = .8, unit = "cm"),
|
|
360
|
+
legend.text = element_text(size=6),
|
|
361
|
+
legend.title = element_text(size=8),
|
|
362
|
+
legend.key.size = unit(0.5, "cm"),
|
|
363
|
+
strip.text.x = strip.text.x,
|
|
364
|
+
strip.text.y = element_text(
|
|
365
|
+
angle = 0, hjust = 1,
|
|
366
|
+
margin = margin(r = 0.5, unit = "cm"))
|
|
367
|
+
) +
|
|
368
|
+
facet_grid(vars(!!sym(cby)), vars(!!sym(case$group_by)), switch="y")
|
|
369
|
+
|
|
370
|
+
piecharts[[length(piecharts) + 1]] <- p
|
|
371
|
+
|
|
372
|
+
# heatmaps
|
|
373
|
+
log_debug(" Preparing pie charts ...")
|
|
374
|
+
hmd <- m %>%
|
|
375
|
+
arrange(!!sym(case$group_by), !!sym(cby)) %>%
|
|
376
|
+
mutate(!!sym(cby) := paste0("[", !!sym(case$group_by), "] ", !!sym(cby))) %>%
|
|
377
|
+
select(!!sym(cby), CloneGroupClusterSize, seurat_clusters) %>%
|
|
378
|
+
distinct(!!sym(cby), seurat_clusters, .keep_all = TRUE) %>%
|
|
379
|
+
pivot_wider(names_from = seurat_clusters, values_from = CloneGroupClusterSize) %>%
|
|
380
|
+
tibble::column_to_rownames(cby)
|
|
381
|
+
hmd[, setdiff(levels(m$seurat_clusters), colnames(hmd))] <- NA
|
|
382
|
+
hmd <- select(hmd, all_of(levels(m$seurat_clusters)))
|
|
383
|
+
hmsplits <- c(hmsplits, rep(cby, nrow(hmd)))
|
|
384
|
+
hmrowlbls <- c(hmrowlbls, rownames(hmd))
|
|
385
|
+
rownames(hmd) <- NULL
|
|
386
|
+
|
|
387
|
+
hmdata <- bind_rows(hmdata, hmd)
|
|
317
388
|
}
|
|
318
389
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
quote = FALSE
|
|
390
|
+
log_info(" Merging and saving pie charts ...")
|
|
391
|
+
# assemble and save pie chart plots
|
|
392
|
+
res <- devpars$res %||% 100
|
|
393
|
+
# legend, cells_by names
|
|
394
|
+
width <- devpars$width %||% (400 + 120 + 100 * ngroups)
|
|
395
|
+
# group_by names
|
|
396
|
+
height <- devpars$height %||% (120 + 100 * cells_rows)
|
|
397
|
+
piefile <- file.path(info$sec_dir, paste0(info$case_slug, ".png"))
|
|
398
|
+
png(piefile, res = res, width = width, height = height)
|
|
399
|
+
print(wrap_plots(piecharts, ncol = 1, guides = "collect"))
|
|
400
|
+
dev.off()
|
|
401
|
+
|
|
402
|
+
log_info(" Plotting and saving heatmap ...")
|
|
403
|
+
row_ha <- rowAnnotation(
|
|
404
|
+
Total = anno_barplot(
|
|
405
|
+
hmdata %>% rowSums(na.rm = T),
|
|
406
|
+
gp = gpar(fill = "lightblue", col = NA),
|
|
407
|
+
width = unit(1.5, "cm")
|
|
408
|
+
)
|
|
339
409
|
)
|
|
410
|
+
ha <- NULL
|
|
411
|
+
extra_height <- 0
|
|
412
|
+
extra_width <- 0 # legend
|
|
413
|
+
if (!is.null(cluster_order_val)) {
|
|
414
|
+
ha <- list()
|
|
415
|
+
ha[[cluster_orderby]] <- cluster_order_val
|
|
416
|
+
if (is.numeric(cluster_order_val)) {
|
|
417
|
+
col_fun <- colorRamp2(
|
|
418
|
+
c(min(cluster_order_val), max(cluster_order_val)),
|
|
419
|
+
c("lightyellow", "red"))
|
|
420
|
+
ha$col <- list()
|
|
421
|
+
ha$col[[cluster_orderby]] <- col_fun
|
|
422
|
+
}
|
|
423
|
+
ha <- do_call(HeatmapAnnotation, ha)
|
|
424
|
+
extra_height <- 40
|
|
425
|
+
extra_width <- 120
|
|
426
|
+
}
|
|
427
|
+
if (length(cells_by) == 1) {
|
|
428
|
+
hmsplits <- NULL
|
|
429
|
+
extra_width <- extra_width - 15
|
|
430
|
+
} else {
|
|
431
|
+
# keep the row order
|
|
432
|
+
hmrowlbls <- factor(hmrowlbls, levels = unique(hmrowlbls))
|
|
433
|
+
}
|
|
340
434
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
plot.margin = unit(c(1,1,1,1), "cm"),
|
|
366
|
-
legend.text = element_text(size=8),
|
|
367
|
-
legend.title = element_text(size=10)
|
|
368
|
-
) +
|
|
369
|
-
facet_grid(vars(!!sym(cells_by)), vars(!!sym(case$group_by)), switch="y")
|
|
370
|
-
|
|
371
|
-
png(outfile, res = devpars$res, width = devpars$width, height = devpars$height)
|
|
372
|
-
print(p)
|
|
435
|
+
col_fun <- colorRamp2(c(0, max(hmdata, na.rm = T)), c("lightyellow", "purple"))
|
|
436
|
+
hm_res <- hm_devpars$res %||% 100
|
|
437
|
+
hm_width <- hm_devpars$width %||% (600 + 15 * length(unique(meta$seurat_clusters)) + extra_width)
|
|
438
|
+
hm_height <- hm_devpars$height %||% (450 + 15 * cells_rows + extra_height)
|
|
439
|
+
png(hmfile, res = hm_res, width = hm_width, height = hm_height)
|
|
440
|
+
hm <- Heatmap(
|
|
441
|
+
as.matrix(hmdata),
|
|
442
|
+
name = "Size",
|
|
443
|
+
col = col_fun,
|
|
444
|
+
na_col = "lightyellow",
|
|
445
|
+
row_names_side = "left",
|
|
446
|
+
row_names_max_width = max_text_width(
|
|
447
|
+
hmrowlbls,
|
|
448
|
+
gp = gpar(fontsize = 12)
|
|
449
|
+
),
|
|
450
|
+
row_labels = hmrowlbls,
|
|
451
|
+
row_split = hmsplits,
|
|
452
|
+
cluster_rows = FALSE,
|
|
453
|
+
cluster_columns = FALSE,
|
|
454
|
+
rect_gp = gpar(col = "white", lwd = 1),
|
|
455
|
+
right_annotation = row_ha,
|
|
456
|
+
top_annotation = ha
|
|
457
|
+
)
|
|
458
|
+
print(hm)
|
|
373
459
|
dev.off()
|
|
374
460
|
|
|
375
|
-
# heatmaps
|
|
376
|
-
groups = as.character(unique(meta[[case$group_by]]))
|
|
377
|
-
hmfigs = sapply(groups, plot_heatmap, meta, case, info, cluster_order_val)
|
|
378
|
-
|
|
379
461
|
add_report(
|
|
380
462
|
list(
|
|
381
463
|
kind = "descr",
|
|
@@ -401,24 +483,20 @@ do_case <- function(name, case) {
|
|
|
401
483
|
add_report(
|
|
402
484
|
list(
|
|
403
485
|
name = "Pie Charts",
|
|
404
|
-
contents = list(list(
|
|
405
|
-
kind = "image",
|
|
406
|
-
src = outfile
|
|
407
|
-
))
|
|
486
|
+
contents = list(list(kind = "image", src = piefile))
|
|
408
487
|
),
|
|
409
488
|
list(
|
|
410
|
-
name = "
|
|
411
|
-
|
|
412
|
-
contents = lapply(seq_along(groups), function(i) {
|
|
413
|
-
list(descr = groups[i], src = hmfigs[i])
|
|
414
|
-
})
|
|
489
|
+
name = "Heatmap",
|
|
490
|
+
contents = list(list(src = hmfile, kind = "image"))
|
|
415
491
|
),
|
|
416
492
|
list(
|
|
417
493
|
name = "Distribution Table",
|
|
418
|
-
contents =
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
494
|
+
contents = do.call(c, lapply(
|
|
495
|
+
seq_along(cells_by),
|
|
496
|
+
function(i) list(
|
|
497
|
+
list(kind = "descr", content = paste0("Cells by: ", cells_by[i])),
|
|
498
|
+
list(kind = "table", data = list(nrows = 100), src = table_files[i])
|
|
499
|
+
)
|
|
422
500
|
))
|
|
423
501
|
),
|
|
424
502
|
h1 = ifelse(
|
|
@@ -435,7 +513,7 @@ do_overlap <- function(section) {
|
|
|
435
513
|
log_info(paste("- Running overlaps for section:", section))
|
|
436
514
|
overlap_cases <- overlaps[[section]]
|
|
437
515
|
if (length(overlap_cases) < 2) {
|
|
438
|
-
stop(paste0("Not enough cases for overlap for section: ", section))
|
|
516
|
+
stop(paste0(" Not enough cases for overlap for section: ", section))
|
|
439
517
|
}
|
|
440
518
|
|
|
441
519
|
sec_dir <- file.path(outdir, slugify(section))
|
|
@@ -38,7 +38,7 @@ subset <- {{ envs.subset | r }}
|
|
|
38
38
|
use_presto <- {{ envs.use_presto | r }}
|
|
39
39
|
rest <- {{ envs.rest | r: todot="-" }}
|
|
40
40
|
dotplot <- {{ envs.dotplot | r: todot="-" }}
|
|
41
|
-
cases <- {{ envs.cases | r: todot="-" }}
|
|
41
|
+
cases <- {{ envs.cases | r: todot="-", skip=1 }}
|
|
42
42
|
overlap <- {{ envs.overlap | r }}
|
|
43
43
|
cache <- {{ envs.cache | r }}
|
|
44
44
|
|
|
@@ -281,7 +281,7 @@ do_enrich <- function(info, markers, sig, volgenes) {
|
|
|
281
281
|
|
|
282
282
|
plot_volcano(markers, file.path(info$casedir, "volcano.png"), sig, volgenes)
|
|
283
283
|
|
|
284
|
-
markers_sig <- markers %>% filter(!!parse_expr(sig))
|
|
284
|
+
markers_sig <- markers %>% filter(!!parse_expr(sig)) %>% arrange(p_val_adj)
|
|
285
285
|
if (nrow(markers_sig) == 0) {
|
|
286
286
|
log_warn(" No significant markers found for case: {info$casename}")
|
|
287
287
|
return(NULL)
|
|
@@ -329,6 +329,11 @@ do_enrich <- function(info, markers, sig, volgenes) {
|
|
|
329
329
|
|
|
330
330
|
|
|
331
331
|
do_dotplot <- function(info, siggenes, dotplot, args) {
|
|
332
|
+
max_dotplot_features <- 20
|
|
333
|
+
if (length(siggenes) > max_dotplot_features) {
|
|
334
|
+
log_warn(" Too many significant markers ({length(siggenes)}), using first {max_dotplot_features} for dotplot")
|
|
335
|
+
siggenes <- siggenes[1:max_dotplot_features]
|
|
336
|
+
}
|
|
332
337
|
dotplot_devpars <- dotplot$devpars
|
|
333
338
|
if (is.null(args$ident.2)) {
|
|
334
339
|
dotplot$object <- args$object
|
|
@@ -393,51 +398,6 @@ add_case_report <- function(info, sigmarkers, siggenes) {
|
|
|
393
398
|
"#",
|
|
394
399
|
ifelse(single_section, "#", info$case)
|
|
395
400
|
)
|
|
396
|
-
add_report(
|
|
397
|
-
list(
|
|
398
|
-
title = "Significant Markers",
|
|
399
|
-
ui = "flat",
|
|
400
|
-
contents = list(
|
|
401
|
-
list(
|
|
402
|
-
kind = "descr",
|
|
403
|
-
content = paste0(
|
|
404
|
-
"The markers are found using Seurat's FindMarkers function, ",
|
|
405
|
-
"and filtered by: ",
|
|
406
|
-
html_escape(sigmarkers)
|
|
407
|
-
)
|
|
408
|
-
),
|
|
409
|
-
list(
|
|
410
|
-
kind = "table",
|
|
411
|
-
data = list(nrows = 100),
|
|
412
|
-
src = file.path(info$casedir, "markers.txt")
|
|
413
|
-
)
|
|
414
|
-
)
|
|
415
|
-
),
|
|
416
|
-
list(
|
|
417
|
-
title = "Volcano Plot",
|
|
418
|
-
ui = "flat",
|
|
419
|
-
contents = list(
|
|
420
|
-
list(
|
|
421
|
-
kind = "img",
|
|
422
|
-
src = file.path(info$casedir, "volcano.png")
|
|
423
|
-
)
|
|
424
|
-
)
|
|
425
|
-
),
|
|
426
|
-
list(
|
|
427
|
-
title = "Dot Plot",
|
|
428
|
-
ui = "flat",
|
|
429
|
-
contents = list(
|
|
430
|
-
list(
|
|
431
|
-
kind = "img",
|
|
432
|
-
src = file.path(info$casedir, "dotplot.png")
|
|
433
|
-
)
|
|
434
|
-
)
|
|
435
|
-
),
|
|
436
|
-
h1 = h1,
|
|
437
|
-
h2 = ifelse(h2 == "#", "Markers", h2),
|
|
438
|
-
h3 = ifelse(h2 == "#", "#", "Markers"),
|
|
439
|
-
ui = "tabs"
|
|
440
|
-
)
|
|
441
401
|
if (is.null(siggenes)) {
|
|
442
402
|
add_report(
|
|
443
403
|
list(
|
|
@@ -450,6 +410,52 @@ add_case_report <- function(info, sigmarkers, siggenes) {
|
|
|
450
410
|
ui = "flat"
|
|
451
411
|
)
|
|
452
412
|
} else {
|
|
413
|
+
add_report(
|
|
414
|
+
list(
|
|
415
|
+
title = "Significant Markers",
|
|
416
|
+
ui = "flat",
|
|
417
|
+
contents = list(
|
|
418
|
+
list(
|
|
419
|
+
kind = "descr",
|
|
420
|
+
content = paste0(
|
|
421
|
+
"The markers are found using Seurat's FindMarkers function, ",
|
|
422
|
+
"and filtered by: ",
|
|
423
|
+
html_escape(sigmarkers)
|
|
424
|
+
)
|
|
425
|
+
),
|
|
426
|
+
list(
|
|
427
|
+
kind = "table",
|
|
428
|
+
data = list(nrows = 100),
|
|
429
|
+
src = file.path(info$casedir, "markers.txt")
|
|
430
|
+
)
|
|
431
|
+
)
|
|
432
|
+
),
|
|
433
|
+
list(
|
|
434
|
+
title = "Volcano Plot",
|
|
435
|
+
ui = "flat",
|
|
436
|
+
contents = list(
|
|
437
|
+
list(
|
|
438
|
+
kind = "img",
|
|
439
|
+
src = file.path(info$casedir, "volcano.png")
|
|
440
|
+
)
|
|
441
|
+
)
|
|
442
|
+
),
|
|
443
|
+
list(
|
|
444
|
+
title = "Dot Plot",
|
|
445
|
+
ui = "flat",
|
|
446
|
+
contents = list(
|
|
447
|
+
list(
|
|
448
|
+
kind = "img",
|
|
449
|
+
src = file.path(info$casedir, "dotplot.png")
|
|
450
|
+
)
|
|
451
|
+
)
|
|
452
|
+
),
|
|
453
|
+
h1 = h1,
|
|
454
|
+
h2 = ifelse(h2 == "#", "Markers", h2),
|
|
455
|
+
h3 = ifelse(h2 == "#", "#", "Markers"),
|
|
456
|
+
ui = "tabs"
|
|
457
|
+
)
|
|
458
|
+
|
|
453
459
|
add_report(
|
|
454
460
|
list(
|
|
455
461
|
kind = "descr",
|
|
@@ -188,7 +188,7 @@ do_radarplot <- function(info, case, counts) {
|
|
|
188
188
|
# Save the counts
|
|
189
189
|
counts_file = file.path(info$casedir, "counts.tsv")
|
|
190
190
|
write.table(
|
|
191
|
-
rdr_data,
|
|
191
|
+
t(rdr_data),
|
|
192
192
|
counts_file,
|
|
193
193
|
sep = "\t",
|
|
194
194
|
quote = FALSE,
|
|
@@ -207,7 +207,7 @@ do_radarplot <- function(info, case, counts) {
|
|
|
207
207
|
# Save the percentages
|
|
208
208
|
perc_file = file.path(info$casedir, "percentages.tsv")
|
|
209
209
|
write.table(
|
|
210
|
-
rdr_data,
|
|
210
|
+
t(rdr_data),
|
|
211
211
|
perc_file,
|
|
212
212
|
sep = "\t",
|
|
213
213
|
quote = FALSE,
|
|
@@ -230,7 +230,10 @@ do_radarplot <- function(info, case, counts) {
|
|
|
230
230
|
colors = trimws(unlist(strsplit(case$colors, ",")))
|
|
231
231
|
}
|
|
232
232
|
p = ggradar(
|
|
233
|
-
rdr_data %>%
|
|
233
|
+
rdr_data %>%
|
|
234
|
+
as.data.frame() %>%
|
|
235
|
+
rownames_to_column("group") %>%
|
|
236
|
+
mutate(group = factor(group, levels = rownames(rdr_data))),
|
|
234
237
|
values.radar = paste0(breaks, "%"),
|
|
235
238
|
grid.min = breaks[1] / 100,
|
|
236
239
|
grid.mid = breaks[2] / 100,
|