biopipen 0.34.0__py3-none-any.whl → 0.34.2__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.

@@ -0,0 +1,592 @@
1
+ library(rlang)
2
+ library(dplyr)
3
+ library(plotthis)
4
+ library(biopipen.utils)
5
+
6
+ sobjfile <- {{in.sobjfile | r}}
7
+ outdir <- {{out.outdir | r}}
8
+ joboutdir <- {{job.outdir | r}}
9
+ each <- {{envs.each | r}}
10
+ subset <- {{envs.subset | r}}
11
+ mutaters <- {{envs.mutaters | r}}
12
+ aggregate_by <- {{envs.aggregate_by | r}}
13
+ layer <- {{envs.layer | r}}
14
+ assay <- {{envs.assay | r}}
15
+ error <- {{ envs.error | r }}
16
+ group_by <- {{envs.group_by | default: envs[["group-by"]] | default: None | r}}
17
+ ident_1 <- {{envs.ident_1 | default: envs[["ident-1"]] | default: None | r}}
18
+ ident_2 <- {{envs.ident_2 | default: envs[["ident-2"]] | default: None | r}}
19
+ each <- {{ envs.each | r }}
20
+ dbs <- {{ envs.dbs | r }}
21
+ sigmarkers <- {{ envs.sigmarkers | r }}
22
+ enrich_style <- {{ envs.enrich_style | r }}
23
+ paired_by <- {{envs.paired_by | default: envs[["paired-by"]] | default: None | r}}
24
+ tool <- {{envs.tool | r}}
25
+ allmarker_plots_defaults <- {{ envs.allmarker_plots_defaults | r }}
26
+ allmarker_plots <- {{ envs.allmarker_plots | r }}
27
+ allenrich_plots_defaults <- {{ envs.allenrich_plots_defaults | r }}
28
+ allenrich_plots <- {{ envs.allenrich_plots | r }}
29
+ marker_plots_defaults <- {{ envs.marker_plots_defaults | r }}
30
+ marker_plots <- {{ envs.marker_plots | r }}
31
+ enrich_plots_defaults <- {{ envs.enrich_plots_defaults | r }}
32
+ enrich_plots <- {{ envs.enrich_plots | r }}
33
+ overlaps_defaults <- {{ envs.overlaps_defaults | r }}
34
+ overlaps <- {{ envs.overlaps | r }}
35
+ cases <- {{envs.cases | r}}
36
+
37
+ aggregate_by <- unique(c(aggregate_by, group_by, paired_by, each))
38
+
39
+ log <- get_logger()
40
+ reporter <- get_reporter()
41
+
42
+ log$info("Loading Seurat object ...")
43
+ srtobj <- read_obj(sobjfile)
44
+
45
+ if (!is.null(mutaters) && length(mutaters) > 0) {
46
+ log$info("Mutating metadata columns ...")
47
+ srtobj@meta.data <- srtobj@meta.data %>% mutate(!!!lapply(mutaters, parse_expr))
48
+ }
49
+
50
+ allmarker_plots <- lapply(allmarker_plots, function(x) {
51
+ list_update(allmarker_plots_defaults, x)
52
+ })
53
+ allenrich_plots <- lapply(allenrich_plots, function(x) {
54
+ list_update(allenrich_plots_defaults, x)
55
+ })
56
+ marker_plots <- lapply(marker_plots, function(x) {
57
+ list_update(marker_plots_defaults, x)
58
+ })
59
+ enrich_plots <- lapply(enrich_plots, function(x) {
60
+ list_update(enrich_plots_defaults, x)
61
+ })
62
+ overlaps <- lapply(overlaps, function(x) {
63
+ list_update(overlaps_defaults, x)
64
+ })
65
+
66
+ defaults <- list(
67
+ each = each,
68
+ error = error,
69
+ subset = subset,
70
+ aggregate_by = aggregate_by,
71
+ layer = layer,
72
+ assay = assay %||% DefaultAssay(srtobj),
73
+ group_by = group_by,
74
+ ident_1 = ident_1,
75
+ ident_2 = ident_2,
76
+ dbs = dbs,
77
+ sigmarkers = sigmarkers,
78
+ enrich_style = enrich_style,
79
+ paired_by = paired_by,
80
+ tool = tool,
81
+ allmarker_plots_defaults = allmarker_plots_defaults,
82
+ allmarker_plots = allmarker_plots,
83
+ allenrich_plots_defaults = allenrich_plots_defaults,
84
+ allenrich_plots = allenrich_plots,
85
+ marker_plots_defaults = marker_plots_defaults,
86
+ marker_plots = marker_plots,
87
+ enrich_plots_defaults = enrich_plots_defaults,
88
+ enrich_plots = enrich_plots,
89
+ overlaps_defaults = overlaps_defaults,
90
+ overlaps = overlaps
91
+ )
92
+
93
+ expand_each <- function(name, case) {
94
+ outcases <- list()
95
+
96
+ if (is.null(case$each) || is.na(case$each) || nchar(case$each) == 0 || isFALSE(each)) {
97
+ if (length(case$allmarker_plots) > 0 || length(allenrich_plots) > 0 || length(overlaps) > 0) {
98
+ stop("Cannot perform allmarker_plots, allenrich_plots, or overlaps without 'each' defined.")
99
+ }
100
+
101
+ case$aggregate_by <- unique(c(case$aggregate_by, case$group_by, case$paired_by))
102
+
103
+ case$marker_plots <- lapply(
104
+ case$marker_plots,
105
+ function(x) { list_update(case$marker_plots_defaults, x) }
106
+ )
107
+ case$marker_plots_defaults <- NULL
108
+
109
+ case$enrich_plots <- lapply(
110
+ case$enrich_plots,
111
+ function(x) { list_update(case$enrich_plots_defaults, x) }
112
+ )
113
+ case$enrich_plots_defaults <- NULL
114
+
115
+ case$overlaps <- lapply(
116
+ case$overlaps,
117
+ function(x) { list_update(case$overlaps_defaults, x) }
118
+ )
119
+ case$overlaps_defaults <- NULL
120
+
121
+ outcases[[name]] <- case
122
+ } else {
123
+ eachs <- if (!is.null(case$subset)) {
124
+ srtobj@meta.data %>%
125
+ filter(!!parse_expr(case$subset)) %>%
126
+ pull(case$each) %>% na.omit() %>% unique() %>% as.vector()
127
+ } else {
128
+ srtobj@meta.data %>%
129
+ pull(case$each) %>% na.omit() %>% unique() %>% as.vector()
130
+ }
131
+
132
+ if (length(cases) == 0 && name == "DEG Analysis") {
133
+ name <- case$each
134
+ }
135
+
136
+ case$aggregate_by <- unique(c(case$aggregate_by, case$group_by, case$paired_by, case$each))
137
+
138
+ for (each in eachs) {
139
+ newname <- paste0(case$each, "::", each)
140
+ newcase <- case
141
+
142
+ newcase$original_case <- name
143
+ newcase$each_name <- case$each
144
+ newcase$each <- each
145
+
146
+ newcase$alleach_plots_defaults <- NULL
147
+ newcase$alleach_plots <- NULL
148
+ newcase$original_subset <- case$subset
149
+
150
+ if (!is.null(case$subset)) {
151
+ newcase$subset <- paste0(case$subset, " & ", bQuote(case$each), " == '", each, "'")
152
+ } else {
153
+ newcase$subset <- paste0(bQuote(case$each), " == '", each, "'")
154
+ }
155
+
156
+ newcase$marker_plots <- lapply(
157
+ case$marker_plots,
158
+ function(x) { list_update(case$marker_plots_defaults, x) }
159
+ )
160
+ newcase$marker_plots_defaults <- NULL
161
+
162
+ newcase$enrich_plots <- lapply(
163
+ case$enrich_plots,
164
+ function(x) { list_update(case$enrich_plots_defaults, x) }
165
+ )
166
+ newcase$enrich_plots_defaults <- NULL
167
+
168
+ # Will be processed by the case itself, which collects the markers
169
+ newcase$allmarker_plots <- NULL
170
+ newcase$allmarker_plots_defaults <- NULL
171
+ newcase$allenrich_plots <- NULL
172
+ newcase$allenrich_plots_defaults <- NULL
173
+ newcase$overlaps <- NULL
174
+ newcase$overlaps_defaults <- NULL
175
+
176
+ outcases[[newname]] <- newcase
177
+ }
178
+
179
+ if (length(case$overlaps) > 0 || length(case$allmarker_plots) > 0 || length(case$allenrich_plots) > 0) {
180
+ ovcase <- case
181
+
182
+ ovcase$markers <- list()
183
+ ovcase$allmarker_plots <- lapply(
184
+ ovcase$allmarker_plots,
185
+ function(x) { list_update(ovcase$allmarker_plots_defaults, x) }
186
+ )
187
+ ovcase$allmarker_plots_defaults <- NULL
188
+
189
+ ovcase$enriches <- list()
190
+ ovcase$allenrich_plots <- lapply(
191
+ ovcase$allenrich_plots,
192
+ function(x) { list_update(ovcase$allenrich_plots_defaults, x) }
193
+ )
194
+ ovcase$allenrich_plots_defaults <- NULL
195
+
196
+ ovcase$overlaps <- lapply(
197
+ ovcase$overlaps,
198
+ function(x) { list_update(ovcase$overlaps_defaults, x) }
199
+ )
200
+ ovcase$overlaps_defaults <- NULL
201
+ outcases[[name]] <- ovcase
202
+ }
203
+ }
204
+ outcases
205
+ }
206
+ cases <- expand_cases(cases, defaults, expand_each, default_case = "DEG Analysis")
207
+
208
+ log$info("Running cases ...")
209
+
210
+ process_markers <- function(markers, info, case) {
211
+ ## Attributes lost
212
+ # markers <- markers %>%
213
+ # mutate(gene = as.character(gene)) %>%
214
+ # arrange(p_val_adj, desc(abs(avg_log2FC)))
215
+ markers$gene <- as.character(markers$gene)
216
+ markers <- markers[order(markers$p_val_adj, -abs(markers$log2FC)), ]
217
+
218
+ # Save markers
219
+ write.table(markers, file.path(info$prefix, "degs.tsv"), sep = "\t", quote = FALSE, row.names = FALSE)
220
+
221
+ sigmarkers <- markers %>% filter(!!parse_expr(case$sigmarkers))
222
+ write.table(sigmarkers, file.path(info$prefix, "sigdegs.tsv"), sep = "\t", quote = FALSE, row.names = FALSE)
223
+ reporter$add2(
224
+ list(
225
+ name = "Table",
226
+ contents = list(
227
+ list(kind = "descr", content = paste0(
228
+ "Showing top 100 DEGs ordered by p_val_adj ascendingly, then abs(log2FC) descendingly. ",
229
+ "Use 'Download the entire data' button to download all significant markers by '",
230
+ html_escape(case$sigmarkers), "'."
231
+ )),
232
+ list(kind = "table", src = file.path(info$prefix, "sigdegs.tsv"), data = list(nrows = 100))
233
+ )
234
+ ),
235
+ hs = c(info$section, info$name),
236
+ hs2 = ifelse(is.null(case$ident), "DEGs", paste0("DEGs (", case$ident, ")")),
237
+ ui = "tabs"
238
+ )
239
+
240
+ for (plotname in names(case$marker_plots)) {
241
+ plotargs <- case$marker_plots[[plotname]]
242
+ plotargs$degs <- markers
243
+ rownames(plotargs$degs) <- make.unique(markers$gene)
244
+ plotargs$outprefix <- file.path(info$prefix, paste0("degs.", slugify(plotname)))
245
+ do_call(VizBulkDEGs, plotargs)
246
+ reporter$add2(
247
+ list(
248
+ name = plotname,
249
+ contents = list(reporter$image(plotargs$outprefix, plotargs$more_formats, plotargs$save_code))),
250
+ hs = c(info$section, info$name),
251
+ hs2 = ifelse(is.null(case$ident), "DEGs", paste0("DEGs (", case$ident, ")")),
252
+ ui = "tabs"
253
+ )
254
+ }
255
+
256
+ # Do enrichment analysis
257
+ significant_markers <- unique(sigmarkers$gene)
258
+ empty <- if (case$enrich_style == "enrichr") {
259
+ data.frame(
260
+ Database = character(0),
261
+ Term = character(0),
262
+ Overlap = character(0),
263
+ P.value = numeric(0),
264
+ Adjusted.P.value = numeric(0),
265
+ Odds.Ratio = numeric(0),
266
+ Combined.Score = numeric(0),
267
+ Genes = character(0),
268
+ Rank = numeric(0)
269
+ )
270
+ } else { # clusterProfiler
271
+ data.frame(
272
+ ID = character(0),
273
+ Description = character(0),
274
+ GeneRatio = character(0),
275
+ BgRatio = character(0),
276
+ Count = integer(0),
277
+ pvalue = numeric(0),
278
+ p.adjust = numeric(0),
279
+ qvalue = numeric(0),
280
+ geneID = character(0),
281
+ Database = character(0)
282
+ )
283
+ }
284
+
285
+ if (length(significant_markers) < 5) {
286
+ if (case$error) {
287
+ stop("Error: Not enough significant DEGs with '", case$sigmarkers, "' in case '", info$name, "' found (< 5) for enrichment analysis.")
288
+ } else {
289
+ message <- paste0("Not enough significant DEGs with '", case$sigmarkers, "' found (< 5) for enrichment analysis.")
290
+ log$warn(" ! Error: {message}")
291
+ reporter$add2(
292
+ list(
293
+ name = "Warning",
294
+ contents = list(list(kind = "error", content = message, kind_ = "warning"))),
295
+ hs = c(info$section, info$name),
296
+ hs2 = "Enrichment Analysis",
297
+ ui = "tabs"
298
+ )
299
+ }
300
+ return(empty)
301
+ } else {
302
+ tryCatch({
303
+ enrich <- RunEnrichment(
304
+ significant_markers,
305
+ dbs = case$dbs, style = case$enrich_style)
306
+
307
+ write.table(enrich, file.path(info$prefix, "enrich.tsv"), sep = "\t", quote = FALSE, row.names = FALSE)
308
+ reporter$add2(
309
+ list(
310
+ name = "Table",
311
+ contents = list(list(kind = "table", src = file.path(info$prefix, "enrich.tsv"), data = list(nrows = 100)))
312
+ ),
313
+ hs = c(info$section, info$name),
314
+ hs2 = "Enrichment Analysis",
315
+ ui = "tabs"
316
+ )
317
+
318
+ # Visualize enriched terms
319
+ if (length(case$enrich_plots) > 0) {
320
+ for (db in case$dbs) {
321
+ plots <- list()
322
+ for (plotname in names(case$enrich_plots)) {
323
+ plotargs <- case$enrich_plots[[plotname]]
324
+ plotargs$data <- enrich[enrich$Database == db, , drop = FALSE]
325
+
326
+ p <- do_call(VizEnrichment, plotargs)
327
+
328
+ if (plotargs$plot_type == "bar") {
329
+ attr(p, "height") <- attr(p, "height") / 1.5
330
+ }
331
+ outprefix <- file.path(info$prefix, paste0("enrich.", slugify(db), ".", slugify(plotname)))
332
+ save_plot(p, outprefix, plotargs$devpars, formats = "png")
333
+ plots[[length(plots) + 1]] <- reporter$image(outprefix, c(), FALSE)
334
+ }
335
+ reporter$add2(
336
+ list(name = db, contents = plots),
337
+ hs = c(info$section, info$name),
338
+ hs2 = "Enrichment Analysis",
339
+ ui = "tabs"
340
+ )
341
+ }
342
+ }
343
+ return(enrich)
344
+ }, error = function(e) {
345
+ if (case$error) {
346
+ stop("Error: ", e$message)
347
+ } else {
348
+ log$warn(" ! Error: {e$message}")
349
+ reporter$add2(
350
+ list(
351
+ name = "Warning",
352
+ contents = list(list(kind = "error", content = e$message, kind_ = "warning"))),
353
+ hs = c(info$section, info$name),
354
+ hs2 = "Enrichment Analysis",
355
+ ui = "tabs"
356
+ )
357
+ }
358
+ return(empty)
359
+ })
360
+ }
361
+ }
362
+
363
+ process_allmarkers <- function(markers, plotcases, casename, groupname) {
364
+ name <- paste0(casename, "::", paste0(groupname, " (All DEGs)"))
365
+ info <- case_info(name, outdir, create = TRUE)
366
+
367
+ for (plotname in names(plotcases)) {
368
+ plotargs <- plotcases[[plotname]]
369
+ plotargs$degs <- markers
370
+ plotargs$outprefix <- file.path(info$prefix, slugify(plotname))
371
+ do_call(VizBulkDEGs, plotargs)
372
+ reporter$add2(
373
+ list(
374
+ name = plotname,
375
+ contents = list(reporter$image(plotargs$outprefix, plotargs$more_formats, plotargs$save_code))
376
+ ),
377
+ hs = c(info$section, info$name),
378
+ ui = "tabs"
379
+ )
380
+ }
381
+ }
382
+
383
+ process_allenriches <- function(enriches, plotcases, casename, groupname) {
384
+ name <- paste0(casename, "::", paste0(groupname, " (All Enrichments)"))
385
+ info <- case_info(name, outdir, create = TRUE)
386
+ dbs <- unique(as.character(enriches$Database))
387
+
388
+ for (db in dbs) {
389
+ plots <- list()
390
+ for (plotname in names(plotcases)) {
391
+ plotargs <- plotcases[[plotname]]
392
+ plotargs <- extract_vars(plotargs, "devpars")
393
+ plotargs$data <- enriches[enriches$Database == db, , drop = FALSE]
394
+ if (plotargs$plot_type == "heatmap") {
395
+ plotargs$group_by <- groupname
396
+ plotargs$show_row_names = plotargs$show_row_names %||% TRUE
397
+ plotargs$show_column_names = plotargs$show_column_names %||% TRUE
398
+ }
399
+
400
+ p <- do_call(VizEnrichment, plotargs)
401
+
402
+ if (plotargs$plot_type == "bar") {
403
+ attr(p, "height") <- attr(p, "height") / 1.5
404
+ }
405
+ outprefix <- file.path(info$prefix, paste0("allenrich.", slugify(db), ".", slugify(plotname)))
406
+ save_plot(p, outprefix, devpars, formats = "png")
407
+ plots[[length(plots) + 1]] <- reporter$image(outprefix, c(), FALSE)
408
+ }
409
+ reporter$add2(
410
+ list(name = db, contents = plots),
411
+ hs = c(info$section, info$name),
412
+ hs2 = plotname,
413
+ ui = "tabs"
414
+ )
415
+ }
416
+ }
417
+
418
+ process_overlaps <- function(markers, ovcases, casename, groupname) {
419
+ name <- paste0(casename, "::", paste0(groupname, " (Overlaps)"))
420
+ info <- case_info(name, outdir, create = TRUE)
421
+
422
+ for (plotname in names(ovcases)) {
423
+ args <- extract_vars(
424
+ ovcases[[plotname]],
425
+ sigm = "sigmarkers", "more_formats", "save_code", "devpars", "plot_type",
426
+ allow_nonexisting = TRUE
427
+ )
428
+
429
+ sigm <- sigm %||% sigmarkers
430
+ ugroups <- unique(markers[[groupname]])
431
+ m <- lapply(ugroups, function(g) {
432
+ markers[markers[[groupname]] == g, , drop = FALSE] %>%
433
+ filter(!!parse_expr(sigm)) %>%
434
+ pull("gene") %>% unique()
435
+ })
436
+ names(m) <- ugroups
437
+
438
+ if (plot_type == "venn") {
439
+ args$data <- m
440
+ args$in_form <- "list"
441
+ prefix <- file.path(info$prefix, slugify(plotname))
442
+ p <- do_call(gglogger::register(VennDiagram), args)
443
+ save_plot(p, prefix, devpars, formats = c("png", more_formats))
444
+ if (save_code) {
445
+ save_plotcode(
446
+ p, prefix,
447
+ c("library(plotthis)", "load('data.RData')", "invisible(list2env(args, .GlobalEnv))"),
448
+ "args",
449
+ auto_data_setup = FALSE
450
+ )
451
+ }
452
+ } else {
453
+ args$data <- m
454
+ args$in_form <- "list"
455
+ prefix <- file.path(info$prefix, slugify(plotname))
456
+ p <- do_call(gglogger::register(UpsetPlot), args)
457
+ save_plot(p, prefix, devpars, formats = c("png", more_formats))
458
+ if (save_code) {
459
+ save_plotcode(
460
+ p, prefix,
461
+ c("library(plotthis)", "load('data.RData')", "invisible(list2env(args, .GlobalEnv))"),
462
+ "args",
463
+ auto_data_setup = FALSE
464
+ )
465
+ }
466
+ }
467
+
468
+ reporter$add2(
469
+ list(
470
+ name = plotname,
471
+ contents = list(reporter$image(prefix, more_formats, save_code))
472
+ ),
473
+ hs = c(info$section, info$name),
474
+ ui = "tabs"
475
+ )
476
+ }
477
+ }
478
+
479
+ run_case <- function(name) {
480
+ case <- cases[[name]]
481
+ log$info("Case: {name} ...")
482
+
483
+ case <- extract_vars(
484
+ case,
485
+ "dbs", "sigmarkers", "allmarker_plots", "allenrich_plots", "marker_plots", "enrich_plots",
486
+ "overlaps", "original_case", "markers", "enriches", "each_name", "each", "enrich_style",
487
+ "aggregate_by", "subset", "layer", "assay", "group_by", "ident_1", "ident_2", "original_subset",
488
+ "paired_by", "tool", "error",
489
+ allow_nonexisting = TRUE
490
+ )
491
+
492
+ if (!is.null(markers) || !is.null(enriches)) {
493
+ if (!is.null(markers)) { # It is the overlap/allmarker case
494
+ log$info("- Summarizing DEGs in subcases (by each: {each}) ...")
495
+ # handle the overlaps / allmarkers analysis here
496
+ if (!is.data.frame(markers)) {
497
+ each_levels <- names(markers)
498
+ markers <- do_call(rbind, lapply(each_levels, function(x) {
499
+ markers_df <- markers[[x]]
500
+ if (nrow(markers_df) > 0) {
501
+ markers_df[[each]] <- x
502
+ } else {
503
+ markers_df[[each]] <- character(0) # Empty case
504
+ }
505
+ markers_df
506
+ }))
507
+ markers[[each]] <- factor(markers[[each]], levels = each_levels)
508
+ }
509
+ # gene, p_val, avg_log2FC, pct.1, pct.2, p_val_adj, diff_pct, <each>
510
+
511
+ if (length(allmarker_plots) > 0) {
512
+ log$info("- Visualizing all DEGs together ...")
513
+ exprs <- AggregateExpressionPseudobulk(
514
+ srtobj, aggregate_by = aggregate_by, layer = layer, assay = assay,
515
+ subset = original_subset, log = log
516
+ )
517
+ attr(markers, "object") <- AggregateExpressionPseudobulk(
518
+ srtobj, aggregate_by = aggregate_by, layer = layer, assay = assay,
519
+ subset = original_subset, log = log
520
+ )
521
+ attr(markers, "meta") <- attr(exprs, "meta")
522
+ attr(markers, "group_by") <- each
523
+ attr(markers, "paired_by") <- paired_by
524
+ attr(markers, "ident_1") <- NULL
525
+ attr(markers, "ident_2") <- NULL
526
+ process_allmarkers(markers, allmarker_plots, name, each)
527
+ }
528
+
529
+ if (length(overlaps) > 0) {
530
+ log$info("- Visualizing overlaps between subcases ...")
531
+ process_overlaps(markers, overlaps, name, each)
532
+ }
533
+
534
+ }
535
+
536
+ if (!is.null(enriches)) {
537
+ log$info("- Summarizing enrichments in subcases (by each: {each}) ...")
538
+ if (!is.data.frame(enriches)) {
539
+ each_levels <- names(enriches)
540
+ enriches <- do_call(rbind, lapply(each_levels, function(x) {
541
+ enrich_df <- enriches[[x]]
542
+ if (nrow(enrich_df) > 0) {
543
+ enrich_df[[each]] <- x
544
+ } else {
545
+ enrich_df[[each]] <- character(0) # Empty case
546
+ }
547
+ enrich_df
548
+ }))
549
+ enriches[[each]] <- factor(enriches[[each]], levels = each_levels)
550
+ }
551
+
552
+ if (length(allenrich_plots) > 0) {
553
+ log$info("- Visualizing all enrichments together ...")
554
+ process_allenriches(enriches, allenrich_plots, name, each)
555
+ }
556
+ }
557
+
558
+ return(invisible())
559
+ }
560
+
561
+ exprs <- AggregateExpressionPseudobulk(
562
+ srtobj, aggregate_by = aggregate_by, layer = layer, assay = assay,
563
+ subset = subset, log = log
564
+ )
565
+ markers <- RunDEGAnalysis(
566
+ exprs, group_by = group_by, ident_1 = ident_1, ident_2 = ident_2,
567
+ paired_by = paired_by, tool = tool, log = log
568
+ )
569
+
570
+ info <- case_info(name, outdir, create = TRUE)
571
+ enrich <- process_markers(markers, info = info, case = list(
572
+ dbs = dbs,
573
+ sigmarkers = sigmarkers,
574
+ enrich_style = enrich_style,
575
+ marker_plots = marker_plots,
576
+ enrich_plots = enrich_plots,
577
+ error = error,
578
+ ident = if (is.null(case$ident_2)) case$ident_1 else paste0(case$ident_1, " vs ", case$ident_2)
579
+ ))
580
+
581
+ if (!is.null(original_case) && !is.null(cases[[original_case]])) {
582
+ markers[[each_name]] <- each
583
+ cases[[original_case]]$markers[[each]] <<- markers
584
+ cases[[original_case]]$enriches[[each]] <<- enrich
585
+ }
586
+
587
+ invisible()
588
+ }
589
+
590
+ sapply(names(cases), run_case)
591
+
592
+ reporter$save(joboutdir)