biopipen 0.34.0__py3-none-any.whl → 0.34.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 CHANGED
@@ -1 +1 @@
1
- __version__ = "0.34.0"
1
+ __version__ = "0.34.1"
biopipen/ns/scrna.py CHANGED
@@ -61,7 +61,8 @@ class SeuratPreparing(Proc):
61
61
  Those paths should be either paths to directoies containing `matrix.mtx`,
62
62
  `barcodes.tsv` and `features.tsv` files that can be loaded by
63
63
  [`Seurat::Read10X()`](https://satijalab.org/seurat/reference/read10x),
64
- or paths to `h5` files that can be loaded by
64
+ or paths of loom files that can be loaded by `SeuratDisk::LoadLoom()`, or paths to
65
+ `h5` files that can be loaded by
65
66
  [`Seurat::Read10X_h5()`](https://satijalab.org/seurat/reference/read10x_h5).
66
67
 
67
68
  Each sample will be loaded individually and then merged into one `Seurat` object, and then perform QC.
@@ -110,9 +111,11 @@ class SeuratPreparing(Proc):
110
111
  min_cells (type=int): The minimum number of cells that a gene must be
111
112
  expressed in to be kept. This is used in `Seurat::CreateSeuratObject()`.
112
113
  Futher QC (`envs.cell_qc`, `envs.gene_qc`) will be performed after this.
114
+ It doesn't work when data is loaded from loom files.
113
115
  min_features (type=int): The minimum number of features that a cell must
114
116
  express to be kept. This is used in `Seurat::CreateSeuratObject()`.
115
117
  Futher QC (`envs.cell_qc`, `envs.gene_qc`) will be performed after this.
118
+ It doesn't work when data is loaded from loom files.
116
119
  cell_qc: Filter expression to filter cells, using
117
120
  `tidyrseurat::filter()`.
118
121
  Available QC keys include `nFeature_RNA`, `nCount_RNA`,
@@ -587,9 +590,11 @@ class SeuratClusterStats(Proc):
587
590
  ngenes (type=json): The number of genes expressed in each cell.
588
591
  Keys are the names of the plots and values are the dicts inherited from `env.ngenes_defaults`.
589
592
  features_defaults (ns): The default parameters for `features`.
590
- - features: The features to plot.
593
+ - features (type=auto): The features to plot.
591
594
  It can be either a string with comma separated features, a list of features, a file path with `file://` prefix with features
592
595
  (one per line), or an integer to use the top N features from `VariantFeatures(srtobj)`.
596
+ It can also be a dict with the keys as the feature group names and the values as the features, which
597
+ is used for heatmap to group the features.
593
598
  - order_by (type=auto): The order of the clusters to show on the plot.
594
599
  An expression passed to `dplyr::arrange()` on the grouped meta data frame (by `ident`).
595
600
  For example, you can order the clusters by the activation score of
@@ -1082,6 +1087,16 @@ class MarkersFinder(Proc):
1082
1087
  - <more>: Other arguments passed to [`scplotter::FeatureStatPlot()`](https://pwwang.github.io/scplotter/reference/FeatureStatPlot.html).
1083
1088
  allmarker_plots (type=json): All marker plot cases.
1084
1089
  The keys are the names of the cases and the values are the dicts inherited from `allmarker_plots_defaults`.
1090
+ allenrich_plots_defaults (ns): Default options for the plots to generate for the enrichment analysis.
1091
+ - plot_type: The type of the plot.
1092
+ - devpars (ns): The device parameters for the plots.
1093
+ - res (type=int): The resolution of the plots.
1094
+ - height (type=int): The height of the plots.
1095
+ - width (type=int): The width of the plots.
1096
+ - <more>: See <https://pwwang.github.io/scplotter/reference/EnrichmentPlot.html>.
1097
+ allenrich_plots (type=json): Cases of the plots to generate for the enrichment analysis.
1098
+ The keys are the names of the cases and the values are the dicts inherited from `allenrich_plots_defaults`.
1099
+ The cases under `envs.cases` can inherit this options.
1085
1100
  marker_plots_defaults (ns): Default options for the plots to generate for the markers.
1086
1101
  - plot_type: The type of the plot.
1087
1102
  See <https://pwwang.github.io/scplotter/reference/FeatureStatPlot.html>.
@@ -1170,6 +1185,11 @@ class MarkersFinder(Proc):
1170
1185
  "genes": 10,
1171
1186
  },
1172
1187
  "allmarker_plots": {},
1188
+ "allenrich_plots_defaults": {
1189
+ "plot_type": "heatmap",
1190
+ "devpars": {"res": 100},
1191
+ },
1192
+ "allenrich_plots": {},
1173
1193
  "marker_plots_defaults": {
1174
1194
  "plot_type": None,
1175
1195
  "more_formats": [],
@@ -1617,6 +1637,15 @@ class ScFGSEA(Proc):
1617
1637
  If it is < 1, will apply it to `padj`, selecting pathways with `padj` < `top`.
1618
1638
  eps (type=float): This parameter sets the boundary for calculating the p value.
1619
1639
  See <https://rdrr.io/bioc/fgsea/man/fgseaMultilevel.html>
1640
+ allpathway_plots_defaults (ns): Default options for the plots to generate for all pathways.
1641
+ - plot_type: The type of the plot, currently either dot or heatmap (default)
1642
+ - devpars (ns): The device parameters for the plots.
1643
+ - res (type=int): The resolution of the plots.
1644
+ - height (type=int): The height of the plots.
1645
+ - width (type=int): The width of the plots.
1646
+ - <more>: See <https://pwwang.github.io/biopipen.utils.R/reference/VizGSEA.html>.
1647
+ allpathway_plots (type=json): Cases of the plots to generate for all pathways.
1648
+ The keys are the names of the cases and the values are the dicts inherited from `allpathway_plots_defaults`.
1620
1649
  minsize (type=int): Minimal size of a gene set to test. All pathways below the threshold are excluded.
1621
1650
  maxsize (type=int): Maximal size of a gene set to test. All pathways above the threshold are excluded.
1622
1651
  rest (type=json;order=98): Rest arguments for [`fgsea()`](https://rdrr.io/bioc/fgsea/man/fgsea.html)
@@ -1644,18 +1673,23 @@ class ScFGSEA(Proc):
1644
1673
  "ident-2": None,
1645
1674
  "each": None,
1646
1675
  "subset": None,
1647
- "gmtfile": "",
1676
+ "gmtfile": "KEGG_2021_Human",
1648
1677
  "method": "s2n",
1649
1678
  "top": 20,
1650
1679
  "minsize": 10,
1651
1680
  "maxsize": 100,
1652
1681
  "eps": 0,
1682
+ "allpathway_plots_defaults": {
1683
+ "plot_type": "heatmap",
1684
+ "devpars": {"res": 100},
1685
+ },
1686
+ "allpathway_plots": {},
1653
1687
  "rest": {},
1654
1688
  "cases": {},
1655
1689
  }
1656
1690
  script = "file://../scripts/scrna/ScFGSEA.R"
1657
1691
  plugin_opts = {
1658
- "report": "file://../reports/scrna/ScFGSEA.svelte",
1692
+ "report": "file://../reports/common.svelte",
1659
1693
  "report_paging": 8,
1660
1694
  }
1661
1695
 
@@ -27,6 +27,8 @@ cache <- {{ envs.cache | r }}
27
27
  rest <- {{ envs.rest | r: todot="-" }}
28
28
  allmarker_plots_defaults <- {{ envs.allmarker_plots_defaults | r }}
29
29
  allmarker_plots <- {{ envs.allmarker_plots | r }}
30
+ allenrich_plots_defaults <- {{ envs.allenrich_plots_defaults | r }}
31
+ allenrich_plots <- {{ envs.allenrich_plots | r }}
30
32
  marker_plots_defaults <- {{ envs.marker_plots_defaults | r }}
31
33
  marker_plots <- {{ envs.marker_plots | r }}
32
34
  enrich_plots_defaults <- {{ envs.enrich_plots_defaults | r }}
@@ -59,6 +61,9 @@ if (!is.null(mutaters) && length(mutaters) > 0) {
59
61
  allmarker_plots <- lapply(allmarker_plots, function(x) {
60
62
  list_update(allmarker_plots_defaults, x)
61
63
  })
64
+ allenrich_plots <- lapply(allenrich_plots, function(x) {
65
+ list_update(allenrich_plots_defaults, x)
66
+ })
62
67
  marker_plots <- lapply(marker_plots, function(x) {
63
68
  list_update(marker_plots_defaults, x)
64
69
  })
@@ -82,6 +87,8 @@ defaults <- list(
82
87
  subset = subset,
83
88
  allmarker_plots_defaults = allmarker_plots_defaults,
84
89
  allmarker_plots = allmarker_plots,
90
+ allenrich_plots_defaults = allenrich_plots_defaults,
91
+ allenrich_plots = allenrich_plots,
85
92
  marker_plots_defaults = marker_plots_defaults,
86
93
  marker_plots = marker_plots,
87
94
  enrich_plots_defaults = enrich_plots_defaults,
@@ -107,6 +114,9 @@ post_casing <- function(name, case) {
107
114
  if (length(case$ident.1) > 0 && length(case$allmarker_plots) > 0) {
108
115
  stop("Cannot perform 'allmarker_plots' with a single comparison (ident-1 is set) in case '", name, "'")
109
116
  }
117
+ if (length(case$ident.1) > 0 && length(case$allenrich_plots) > 0) {
118
+ stop("Cannot perform 'allenrich_plots' with a single comparison (ident-1 is set) in case '", name, "'")
119
+ }
110
120
 
111
121
  case$allmarker_plots <- lapply(
112
122
  case$allmarker_plots,
@@ -114,6 +124,12 @@ post_casing <- function(name, case) {
114
124
  )
115
125
  case$allmarker_plots_defaults <- NULL
116
126
 
127
+ case$allenrich_plots <- lapply(
128
+ case$allenrich_plots,
129
+ function(x) { list_update(case$allenrich_plots_defaults, x) }
130
+ )
131
+ case$allenrich_plots_defaults <- NULL
132
+
117
133
  case$marker_plots <- lapply(
118
134
  case$marker_plots,
119
135
  function(x) { list_update(case$marker_plots_defaults, x) }
@@ -179,20 +195,31 @@ post_casing <- function(name, case) {
179
195
  # Will be processed by the case itself, which collects the markers
180
196
  newcase$allmarker_plots <- NULL
181
197
  newcase$allmarker_plots_defaults <- NULL
198
+ newcase$allenrich_plots <- NULL
199
+ newcase$allenrich_plots_defaults <- NULL
182
200
  newcase$overlaps <- NULL
183
201
  newcase$overlaps_defaults <- NULL
184
202
 
185
203
  outcases[[newname]] <- newcase
186
204
  }
187
205
 
188
- if (length(case$overlaps) > 0 || length(case$allmarker_plots) > 0) {
206
+ if (length(case$overlaps) > 0 || length(case$allmarker_plots) > 0 || length(case$allenrich_plots) > 0) {
189
207
  ovcase <- case
208
+
190
209
  ovcase$markers <- list()
191
210
  ovcase$allmarker_plots <- lapply(
192
211
  ovcase$allmarker_plots,
193
212
  function(x) { list_update(ovcase$allmarker_plots_defaults, x) }
194
213
  )
195
214
  ovcase$allmarker_plots_defaults <- NULL
215
+
216
+ ovcase$enriches <- list()
217
+ ovcase$allenrich_plots <- lapply(
218
+ ovcase$allenrich_plots,
219
+ function(x) { list_update(ovcase$allenrich_plots_defaults, x) }
220
+ )
221
+ ovcase$allenrich_plots_defaults <- NULL
222
+
196
223
  ovcase$overlaps <- lapply(
197
224
  ovcase$overlaps,
198
225
  function(x) { list_update(ovcase$overlaps_defaults, x) }
@@ -255,6 +282,32 @@ process_markers <- function(markers, info, case) {
255
282
 
256
283
  # Do enrichment analysis
257
284
  significant_markers <- unique(sigmarkers$gene)
285
+ empty <- if (case$enrich_style == "enrichr") {
286
+ data.frame(
287
+ Database = character(0),
288
+ Term = character(0),
289
+ Overlap = character(0),
290
+ P.value = numeric(0),
291
+ Adjusted.P.value = numeric(0),
292
+ Odds.Ratio = numeric(0),
293
+ Combined.Score = numeric(0),
294
+ Genes = character(0),
295
+ Rank = numeric(0)
296
+ )
297
+ } else { # clusterProfiler
298
+ data.frame(
299
+ ID = character(0),
300
+ Description = character(0),
301
+ GeneRatio = character(0),
302
+ BgRatio = character(0),
303
+ Count = integer(0),
304
+ pvalue = numeric(0),
305
+ p.adjust = numeric(0),
306
+ qvalue = numeric(0),
307
+ geneID = character(0),
308
+ Database = character(0)
309
+ )
310
+ }
258
311
 
259
312
  if (length(significant_markers) < 5) {
260
313
  if (case$error) {
@@ -271,6 +324,7 @@ process_markers <- function(markers, info, case) {
271
324
  ui = "tabs"
272
325
  )
273
326
  }
327
+ return(empty)
274
328
  } else {
275
329
  tryCatch({
276
330
  enrich <- RunEnrichment(
@@ -298,7 +352,9 @@ process_markers <- function(markers, info, case) {
298
352
 
299
353
  p <- do_call(VizEnrichment, plotargs)
300
354
 
301
- attr(p, "height") <- attr(p, "height") / 1.5
355
+ if (plotargs$plot_type == "bar") {
356
+ attr(p, "height") <- attr(p, "height") / 1.5
357
+ }
302
358
  outprefix <- file.path(info$prefix, paste0("enrich.", slugify(db), ".", slugify(plotname)))
303
359
  save_plot(p, outprefix, plotargs$devpars, formats = "png")
304
360
  plots[[length(plots) + 1]] <- reporter$image(outprefix, c(), FALSE)
@@ -311,6 +367,7 @@ process_markers <- function(markers, info, case) {
311
367
  )
312
368
  }
313
369
  }
370
+ return(enrich)
314
371
  }, error = function(e) {
315
372
  if (case$error) {
316
373
  stop("Error: ", e$message)
@@ -325,6 +382,7 @@ process_markers <- function(markers, info, case) {
325
382
  ui = "tabs"
326
383
  )
327
384
  }
385
+ return(empty)
328
386
  })
329
387
  }
330
388
  }
@@ -332,6 +390,7 @@ process_markers <- function(markers, info, case) {
332
390
  process_allmarkers <- function(markers, plotcases, casename, groupname) {
333
391
  name <- paste0(casename, "::", paste0(groupname, " (All Markers)"))
334
392
  info <- case_info(name, outdir, create = TRUE)
393
+
335
394
  for (plotname in names(plotcases)) {
336
395
  plotargs <- plotcases[[plotname]]
337
396
  plotargs$degs <- markers
@@ -348,6 +407,41 @@ process_allmarkers <- function(markers, plotcases, casename, groupname) {
348
407
  }
349
408
  }
350
409
 
410
+ process_allenriches <- function(enriches, plotcases, casename, groupname) {
411
+ name <- paste0(casename, "::", paste0(groupname, " (All Enrichments)"))
412
+ info <- case_info(name, outdir, create = TRUE)
413
+ dbs <- unique(as.character(enriches$Database))
414
+
415
+ for (db in dbs) {
416
+ plots <- list()
417
+ for (plotname in names(plotcases)) {
418
+ plotargs <- plotcases[[plotname]]
419
+ plotargs <- extract_vars(plotargs, "devpars")
420
+ plotargs$data <- enriches[enriches$Database == db, , drop = FALSE]
421
+ if (plotargs$plot_type == "heatmap") {
422
+ plotargs$group_by <- groupname
423
+ plotargs$show_row_names = plotargs$show_row_names %||% TRUE
424
+ plotargs$show_column_names = plotargs$show_column_names %||% TRUE
425
+ }
426
+
427
+ p <- do_call(VizEnrichment, plotargs)
428
+
429
+ if (plotargs$plot_type == "bar") {
430
+ attr(p, "height") <- attr(p, "height") / 1.5
431
+ }
432
+ outprefix <- file.path(info$prefix, paste0("allenrich.", slugify(db), ".", slugify(plotname)))
433
+ save_plot(p, outprefix, devpars, formats = "png")
434
+ plots[[length(plots) + 1]] <- reporter$image(outprefix, c(), FALSE)
435
+ }
436
+ reporter$add2(
437
+ list(name = db, contents = plots),
438
+ hs = c(info$section, info$name),
439
+ hs2 = plotname,
440
+ ui = "tabs"
441
+ )
442
+ }
443
+ }
444
+
351
445
  process_overlaps <- function(markers, ovcases, casename, groupname) {
352
446
  name <- paste0(casename, "::", paste0(groupname, ": Overlaps"))
353
447
  info <- case_info(name, outdir, create = TRUE)
@@ -415,38 +509,71 @@ run_case <- function(name) {
415
509
 
416
510
  case <- extract_vars(
417
511
  case,
418
- "dbs", "sigmarkers", "allmarker_plots", "marker_plots", "enrich_plots", "overlaps",
419
- "original_case", "markers", "each_name", "each", "enrich_style",
512
+ "dbs", "sigmarkers", "allmarker_plots", "allenrich_plots", "marker_plots", "enrich_plots",
513
+ "overlaps", "original_case", "markers", "enriches", "each_name", "each", "enrich_style",
420
514
  allow_nonexisting = TRUE
421
515
  )
422
- if (!is.null(markers)) { # It is the overlap/allmarker case
423
- log$info("- Summarizing markers in subcases (by each: {each}) ...")
424
- # handle the overlaps / allmarkers analysis here
425
- if (!is.data.frame(markers)) {
426
- markers <- do_call(rbind, lapply(names(markers), function(x) {
427
- markers_df <- markers[[x]]
428
- markers_df[[each]] <- x
429
- markers_df
430
- }))
431
- }
432
- # gene, p_val, avg_log2FC, pct.1, pct.2, p_val_adj, diff_pct, <each>
433
516
 
434
- if (length(allmarker_plots) > 0) {
435
- log$info("- Visualizing all markers together ...")
436
- attr(markers, "object") <- srtobj
437
- attr(markers, "group.by") <- each
438
- attr(markers, "ident.1") <- NULL
439
- attr(markers, "ident.2") <- NULL
440
- process_allmarkers(markers, allmarker_plots, name, each)
517
+ if (!is.null(markers) || !is.null(enriches)) {
518
+ if (!is.null(markers)) { # It is the overlap/allmarker case
519
+ log$info("- Summarizing markers in subcases (by each: {each}) ...")
520
+ # handle the overlaps / allmarkers analysis here
521
+ if (!is.data.frame(markers)) {
522
+ each_levels <- names(markers)
523
+ markers <- do_call(rbind, lapply(each_levels, function(x) {
524
+ markers_df <- markers[[x]]
525
+ if (nrow(markers_df) > 0) {
526
+ markers_df[[each]] <- x
527
+ } else {
528
+ markers_df[[each]] <- character(0) # Empty case
529
+ }
530
+ markers_df
531
+ }))
532
+ markers[[each]] <- factor(markers[[each]], levels = each_levels)
533
+ }
534
+ # gene, p_val, avg_log2FC, pct.1, pct.2, p_val_adj, diff_pct, <each>
535
+
536
+ if (length(allmarker_plots) > 0) {
537
+ log$info("- Visualizing all markers together ...")
538
+ attr(markers, "object") <- srtobj
539
+ attr(markers, "group.by") <- each
540
+ attr(markers, "ident.1") <- NULL
541
+ attr(markers, "ident.2") <- NULL
542
+ process_allmarkers(markers, allmarker_plots, name, each)
543
+ }
544
+
545
+ if (length(overlaps) > 0) {
546
+ log$info("- Visualizing overlaps between subcases ...")
547
+ process_overlaps(markers, overlaps, name, each)
548
+ }
549
+
441
550
  }
442
551
 
443
- if (length(overlaps) > 0) {
444
- log$info("- Visualizing overlaps between subcases ...")
445
- process_overlaps(markers, overlaps, name, each)
552
+ if (!is.null(enriches)) {
553
+ log$info("- Summarizing enrichments in subcases (by each: {each}) ...")
554
+ if (!is.data.frame(enriches)) {
555
+ each_levels <- names(enriches)
556
+ enriches <- do_call(rbind, lapply(each_levels, function(x) {
557
+ enrich_df <- enriches[[x]]
558
+ if (nrow(enrich_df) > 0) {
559
+ enrich_df[[each]] <- x
560
+ } else {
561
+ enrich_df[[each]] <- character(0) # Empty case
562
+ }
563
+ enrich_df
564
+ }))
565
+ enriches[[each]] <- factor(enriches[[each]], levels = each_levels)
566
+ }
567
+
568
+ if (length(allenrich_plots) > 0) {
569
+ log$info("- Visualizing all enrichments together ...")
570
+ process_allenriches(enriches, allenrich_plots, name, each)
571
+ }
446
572
  }
447
573
 
448
574
  return(invisible())
449
575
  }
576
+
450
577
  case$object <- srtobj
451
578
  markers <- do_call(RunSeuratDEAnalysis, case)
452
579
  case$object <- NULL
@@ -454,6 +581,7 @@ run_case <- function(name) {
454
581
 
455
582
  if (is.null(case$ident.1)) {
456
583
  all_idents <- unique(as.character(markers[[case$group.by]]))
584
+ enriches <- list()
457
585
  for (ident in all_idents) {
458
586
  log$info("- {case$group.by}: {ident} ...")
459
587
  ident_markers <- markers[markers[[case$group.by]] == ident, , drop = TRUE]
@@ -461,7 +589,7 @@ run_case <- function(name) {
461
589
  info <- case_info(casename, outdir, create = TRUE)
462
590
 
463
591
  attr(ident_markers, "ident.1") <- ident
464
- process_markers(ident_markers, info = info, case = list(
592
+ enrich <- process_markers(ident_markers, info = info, case = list(
465
593
  dbs = dbs,
466
594
  sigmarkers = sigmarkers,
467
595
  enrich_style = enrich_style,
@@ -470,6 +598,7 @@ run_case <- function(name) {
470
598
  error = case$error,
471
599
  ident = NULL
472
600
  ))
601
+ enriches[[ident]] <- enrich
473
602
  }
474
603
 
475
604
  if (length(allmarker_plots) > 0) {
@@ -481,9 +610,14 @@ run_case <- function(name) {
481
610
  log$info("- Visualizing overlaps between subcases ...")
482
611
  process_overlaps(markers, overlaps, name, case$group.by)
483
612
  }
613
+
614
+ if (length(allenrich_plots) > 0) {
615
+ log$info("- Visualizing all enrichments together ...")
616
+ process_allenriches(enriches, allenrich_plots, name, case$group.by)
617
+ }
484
618
  } else {
485
619
  info <- case_info(name, outdir, create = TRUE)
486
- process_markers(markers, info = info, case = list(
620
+ enrich <- process_markers(markers, info = info, case = list(
487
621
  dbs = dbs,
488
622
  sigmarkers = sigmarkers,
489
623
  enrich_style = enrich_style,
@@ -493,9 +627,10 @@ run_case <- function(name) {
493
627
  ident = if (is.null(case$ident.2)) case$ident.1 else paste0(case$ident.1, " vs ", case$ident.2)
494
628
  ))
495
629
 
496
- if (!is.null(original_case)) {
630
+ if (!is.null(original_case) && !is.null(cases[[original_case]])) {
497
631
  markers[[each_name]] <- each
498
632
  cases[[original_case]]$markers[[each]] <<- markers
633
+ cases[[original_case]]$enriches[[each]] <<- enrich
499
634
  }
500
635
  }
501
636
 
@@ -18,6 +18,8 @@ top <- {{envs.top | r}} # nolint
18
18
  minsize <- {{envs.minSize | default: envs.minsize | r}} # nolint
19
19
  maxsize <- {{envs.maxSize | default: envs.maxsize | r}} # nolint
20
20
  eps <- {{envs.eps | r}} # nolint
21
+ allpathway_plots_defaults <- {{envs.allpathway_plots_defaults | r}} # nolint
22
+ allpathway_plots <- {{envs.allpathway_plots | r}} #
21
23
  ncores <- {{envs.ncores | r}} # nolint
22
24
  rest <- {{envs.rest | r: todot="-"}} # nolint
23
25
  cases <- {{envs.cases | r: todot="-"}} # nolint
@@ -25,6 +27,10 @@ cases <- {{envs.cases | r: todot="-"}} # nolint
25
27
  log <- get_logger()
26
28
  reporter <- get_reporter()
27
29
 
30
+ allpathway_plots <- lapply(allpathway_plots, function(x) {
31
+ list_update(allpathway_plots_defaults, x)
32
+ })
33
+
28
34
  log$info("Reading Seurat object ...")
29
35
  srtobj <- read_obj(srtfile)
30
36
  if (!"Identity" %in% colnames(srtobj@meta.data)) {
@@ -48,6 +54,8 @@ defaults <- list(
48
54
  minsize = minsize,
49
55
  maxsize = maxsize,
50
56
  eps = eps,
57
+ allpathway_plots_defaults = allpathway_plots_defaults,
58
+ allpathway_plots = allpathway_plots,
51
59
  ncores = ncores,
52
60
  rest = rest
53
61
  )
@@ -58,6 +66,10 @@ expand_each <- function(name, case) {
58
66
  case$group.by <- case$group.by %||% "Identity"
59
67
 
60
68
  if (is.null(case$each) || is.na(case$each) || nchar(case$each) == 0 || isFALSE(each)) {
69
+ if (length(case$allpathway_plots) > 0) {
70
+ stop("Cannot perform `allpathway_plots` without `each` defined.")
71
+ }
72
+
61
73
  outcases[[name]] <- case
62
74
  } else {
63
75
  eachs <- if (!is.null(case$subset)) {
@@ -77,10 +89,13 @@ expand_each <- function(name, case) {
77
89
  newname <- paste0(case$each, "::", each)
78
90
  newcase <- case
79
91
 
80
- newcase$original_case <- name
92
+ newcase$original_case <- paste0(name, " (all ", case$each,")")
81
93
  newcase$each_name <- case$each
82
94
  newcase$each <- each
83
95
 
96
+ newcase$allpathway_plots_defaults <- NULL
97
+ newcase$allpathway_plots <- NULL
98
+
84
99
  if (!is.null(case$subset)) {
85
100
  newcase$subset <- paste0(case$subset, " & ", bQuote(case$each), " == '", each, "'")
86
101
  } else {
@@ -89,6 +104,18 @@ expand_each <- function(name, case) {
89
104
 
90
105
  outcases[[newname]] <- newcase
91
106
  }
107
+
108
+ if (length(case$allpathway_plots) > 0) {
109
+ newcase <- case
110
+
111
+ newcase$gseas <- list()
112
+ newcase$allpathway_plots <- lapply(
113
+ newcase$allpathway_plots,
114
+ function(x) { list_update(newcase$allpathway_plots_defaults, x) }
115
+ )
116
+
117
+ outcases[[paste0(name, " (all ", case$each,")")]] <- newcase
118
+ }
92
119
  }
93
120
  outcases
94
121
  }
@@ -108,12 +135,50 @@ ensure_sobj <- function(expr, allow_empty) {
108
135
  })
109
136
  }
110
137
 
111
-
112
138
  do_case <- function(name) {
113
139
  log$info("- Processing case: {name} ...")
114
140
  case <- cases[[name]]
115
141
  info <- case_info(name, outdir, create = TRUE)
116
142
 
143
+ if (!is.null(case$gseas)) {
144
+
145
+ each_levels <- names(case$gseas)
146
+ gseas <- do_call(rbind, lapply(each_levels, function(x) {
147
+ gsea_df <- case$gseas[[x]]
148
+ if (nrow(gsea_df) > 0) {
149
+ gsea_df[[case$each]] <- x
150
+ } else {
151
+ gsea_df[[case$each]] <- character(0) # Empty case
152
+ }
153
+ gsea_df
154
+ }))
155
+ gseas[[case$each]] <- factor(gseas[[case$each]], levels = each_levels)
156
+
157
+ for (plotname in names(case$allpathway_plots)) {
158
+ plotargs <- case$allpathway_plots[[plotname]]
159
+ plotargs <- extract_vars(plotargs, "devpars")
160
+ plotargs$gsea_results <- gseas
161
+ plotargs$group_by <- case$each
162
+ if (plotargs$plot_type == "heatmap") {
163
+ plotargs$show_row_names <- plotargs$show_row_names %||% TRUE
164
+ plotargs$show_column_names <- plotargs$show_column_names %||% TRUE
165
+ }
166
+
167
+ p <- do_call(VizGSEA, plotargs)
168
+
169
+ outprefix <- file.path(info$prefix, paste0("all.", slugify(plotname)))
170
+ save_plot(p, outprefix, devpars, formats = "png")
171
+ reporter$add2(
172
+ list(kind = "descr", content = paste0("Pathways for all ", case$each, ".")),
173
+ list(kind = "image", src = paste0(outprefix, ".png")),
174
+ hs = c(info$section, info$name),
175
+ hs2 = plotname
176
+ )
177
+ }
178
+
179
+ return(invisible(NULL))
180
+ }
181
+
117
182
  allow_empty = !is.null(case$each)
118
183
  # prepare expression matrix
119
184
  log$info(" Preparing expression matrix...")
@@ -167,9 +232,9 @@ do_case <- function(name) {
167
232
  log$info(" Getting preranks...")
168
233
  ranks <- RunGSEAPreRank(exprs, allclasses, case$ident.1, case$ident.2, case$method)
169
234
  write.table(
170
- ranks,
171
- file.path(info$prefix, "fgsea.rank"),
172
- row.names = FALSE,
235
+ as.data.frame(ranks),
236
+ file.path(info$prefix, "fgsea.rank.txt"),
237
+ row.names = TRUE,
173
238
  col.names = TRUE,
174
239
  sep = "\t",
175
240
  quote = FALSE
@@ -216,15 +281,17 @@ do_case <- function(name) {
216
281
  quote = FALSE
217
282
  )
218
283
 
284
+ aspect.ratio <- sqrt(case$top) / sqrt(10)
219
285
  p_summary <- VizGSEA(
220
286
  result,
221
287
  plot_type = "summary",
222
- top_term = case$top
288
+ top_term = case$top,
289
+ aspect.ratio = aspect.ratio
223
290
  )
224
291
  save_plot(
225
292
  p_summary,
226
293
  file.path(info$prefix, "summary"),
227
- devpars = list(res = 100, height = attr(p_summary, "height") * 100, width = attr(p_summary, "width") * 100),
294
+ devpars = list(res = 100, height = attr(p_summary, "height") * 100 / 1.5, width = attr(p_summary, "width") * 100),
228
295
  formats = "png"
229
296
  )
230
297
 
@@ -243,13 +310,13 @@ do_case <- function(name) {
243
310
 
244
311
  reporter$add2(
245
312
  list(
246
- name = "Table",
313
+ name = paste0("Table (", case$ident.1, " vs ", case$ident.2, ")"),
247
314
  contents = list(
248
315
  list(kind = "descr", content = paste0(
249
316
  "Showing top 50 pathways by padj in descending order. ",
250
317
  "Use 'Download the entire data' button to download all pathways."
251
318
  )),
252
- list(kind = "table", src = file.path(info$prefix, "fgsea"), data = list(nrows = 50))
319
+ list(kind = "table", src = file.path(info$prefix, "fgsea.tsv"), data = list(nrows = 50))
253
320
  )
254
321
  ),
255
322
  list(
@@ -269,8 +336,14 @@ do_case <- function(name) {
269
336
  hs = c(info$section, info$name),
270
337
  ui = "tabs"
271
338
  )
339
+
340
+ if (!is.null(case$original_case) && !is.null(cases[[case$original_case]])) {
341
+ cases[[case$original_case]]$gseas[[case$each]] <<- result
342
+ }
343
+
344
+ invisible()
272
345
  }
273
346
 
274
- sapply(sort(names(cases)), function(name) do_case(name))
347
+ sapply(names(cases), function(name) do_case(name))
275
348
 
276
349
  reporter$save(joboutdir)
@@ -53,6 +53,10 @@ hvf <- NULL
53
53
  }
54
54
  }
55
55
 
56
+ if (is.list(features)) {
57
+ return(lapply(features, function(x) {.get_features(x, object) }))
58
+ }
59
+
56
60
  return (trimws(unlist(strsplit(features, ","))))
57
61
  }
58
62
 
@@ -144,7 +144,9 @@ process_markers <- function(markers, info, case) {
144
144
  p <- do_call(VizEnrichment, plotargs)
145
145
 
146
146
  outprefix <- file.path(info$prefix, paste0("enrich.", slugify(db), ".", slugify(plotname)))
147
- attr(p, "height") <- attr(p, "height") / 1.5
147
+ if (plotargs$plot_type == "bar") {
148
+ attr(p, "height") <- attr(p, "height") / 1.5
149
+ }
148
150
  save_plot(p, outprefix, plotargs$devpars, formats = "png")
149
151
  plots[[length(plots) + 1]] <- reporter$image(outprefix, c(), FALSE)
150
152
  }
@@ -7,7 +7,7 @@ library(biopipen.utils)
7
7
  screpfile <- {{in.screpfile | r}}
8
8
  outdir <- {{out.outdir | r}}
9
9
  joboutdir <- {{job.outdir | r}}
10
- envs <- {{envs | r}}
10
+ envs <- {{envs | r: todot="-"}}
11
11
  mutaters <- envs$mutaters
12
12
  cases <- envs$cases
13
13
  envs$mutaters <- NULL
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: biopipen
3
- Version: 0.34.0
3
+ Version: 0.34.1
4
4
  Summary: Bioinformatics processes/pipelines that can be run from `pipen run`
5
5
  License: MIT
6
6
  Author: pwwang
@@ -1,4 +1,4 @@
1
- biopipen/__init__.py,sha256=7wgjZxPxspP87CI4mDkFQuldkKgENXO5FaPiS8EXM88,23
1
+ biopipen/__init__.py,sha256=Z-DRdi7fjebiPt8V6ExiicJOI_-UPpu6i21-wLM1PPE,23
2
2
  biopipen/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  biopipen/core/config.py,sha256=edK5xnDhM8j27srDzsxubi934NMrglLoKrdcC8qsEPk,1069
4
4
  biopipen/core/config.toml,sha256=lZV_vbYWk6uqm19ZWJcsZCcSNqAdIfN2fOfamzxZpg4,2148
@@ -22,7 +22,7 @@ biopipen/ns/plot.py,sha256=N41_izb6zi-XArUly5WhLebapNXbTNSgGlOCCwtrDlY,18282
22
22
  biopipen/ns/protein.py,sha256=YJtlKoHI2p5yHdxKeQnNtm5QrbxDGOq1UXOdt_7tlTs,6391
23
23
  biopipen/ns/regulatory.py,sha256=gJjGVpJrdv-rg2t5UjK4AGuvtLNymaNYNvoD8PhlbvE,15929
24
24
  biopipen/ns/rnaseq.py,sha256=bKAa6friFWof4yDTWZQahm1MS-lrdetO1GqDKdfxXYc,7708
25
- biopipen/ns/scrna.py,sha256=Ip0Kc2TEtlCqbWYpkLbY6T90Bz32pMoCoVjQB8K7zw8,128961
25
+ biopipen/ns/scrna.py,sha256=cxEVHGgHF7id3eegVQLOZWwuG0iMSlP4ZnZ9nizw7ac,131196
26
26
  biopipen/ns/scrna_metabolic_landscape.py,sha256=Q95KkHg5jC6eUMSUH-wioPxOzuArP59j3CPsfDTCBM0,22096
27
27
  biopipen/ns/snp.py,sha256=iXWrw7Lmhf4_ct57HGT7JGTClCXUD4sZ2FzOgsC2pTg,28123
28
28
  biopipen/ns/stats.py,sha256=DlPyK5Vsg6ZEkV9SDS3aAw21eXzvOHgqeZDkXPhg7go,20509
@@ -51,7 +51,6 @@ biopipen/reports/scrna/DimPlots.svelte,sha256=ubIx8dgppzSB8WS_B4LN2T3bOTerP4Ck6o
51
51
  biopipen/reports/scrna/MarkersFinder.svelte,sha256=77rD1psj0VJykPDhfwS-B8mubvaasREAE6RYR2atTN4,444
52
52
  biopipen/reports/scrna/MetaMarkers.svelte,sha256=iIFRKjvVYrM1AtDWqq8UfeS8q23R8FKg2yepKAw2KSE,508
53
53
  biopipen/reports/scrna/RadarPlots.svelte,sha256=g_fp9d3vdnzk-egXPhkhhfWXOeG569Rj8rYLRIKmlLc,396
54
- biopipen/reports/scrna/ScFGSEA.svelte,sha256=Gqt-XjqsB3XgdR3XukvphwyMExZpScwqgEo7AD-gK6g,491
55
54
  biopipen/reports/scrna/TopExpressingGenes.svelte,sha256=tt5_Vjym4coFT8Bvz0s6ZcCioTOIwCj83jdCGqPCmUw,491
56
55
  biopipen/reports/scrna_metabolic_landscape/MetabolicFeatures.svelte,sha256=1RC-FuYr_M1xInPaNrEGyzPQGy2d1rZjYdKPfLAOPUs,2346
57
56
  biopipen/reports/scrna_metabolic_landscape/MetabolicPathwayActivity.svelte,sha256=VTU-D8iELO7zzK5cJg7oZTna2wu4O_gJ8d7G8N7Veg8,5473
@@ -157,19 +156,19 @@ biopipen/scripts/scrna/ExprImputation-rmagic.R,sha256=ePgbMZ_3bKbeUrjsMdkdtBM_MS
157
156
  biopipen/scripts/scrna/ExprImputation-scimpute.R,sha256=MI_bYfvCDKJsuGntUxfx_-NdrssBoQgL95-DGwJVE5s,1191
158
157
  biopipen/scripts/scrna/ExprImputation.R,sha256=GcdZJpkDpq88hRQjtLZY5-byp8V43stEFm5T-pQbU6A,319
159
158
  biopipen/scripts/scrna/LoomTo10X.R,sha256=c6F0p1udsL5UOlb84-53K5BsjSDWkdFyYTt5NQmlIec,1059
160
- biopipen/scripts/scrna/MarkersFinder.R,sha256=qS5Dsv7iKtXYc2WwNjex5dHpfvLy1cX6CukBVwc_zkM,18479
159
+ biopipen/scripts/scrna/MarkersFinder.R,sha256=eg7_z5Q2qZ_AeGhyo0WyM42QUzsHmJ5TV3hh7PFmHZg,23807
161
160
  biopipen/scripts/scrna/MetaMarkers.R,sha256=BgYaWYEj6obwqaZaDWqNPtxb1IEEAnXAeBE0Ji9PvBA,12426
162
161
  biopipen/scripts/scrna/ModuleScoreCalculator.R,sha256=-tByCPk7i070LynAb0z2ANeRxr1QqiKP0dfrJm52jH4,4198
163
162
  biopipen/scripts/scrna/RadarPlots.R,sha256=Kn1E-hpczuujpgNjR8MqeIIVN-S3PbpmfcKWGKcNCVY,14546
164
163
  biopipen/scripts/scrna/SCImpute.R,sha256=dSJOHhmJ3x_72LBRXT72dbCti5oiB85CJ-OjWtqONbk,2958
165
164
  biopipen/scripts/scrna/SCP-plot.R,sha256=QcR2zOjRlSA_z4L8l89FWPU7TGxpXlKUe4kPdZU9MuY,787291
166
- biopipen/scripts/scrna/ScFGSEA.R,sha256=AQu_buJVoRFltclhh3NyJakggRyZMuKj9q_tgzMgNwE,8655
165
+ biopipen/scripts/scrna/ScFGSEA.R,sha256=St81BfGi7pGX-y5Lsix7o0Bs2Fv_DKb1rHPXBADEa_8,11459
167
166
  biopipen/scripts/scrna/ScSimulation.R,sha256=q0-dXD9px1cApc_TxGmR-OdNHE8W1VSVWfSI57B96bo,1697
168
167
  biopipen/scripts/scrna/ScVelo.py,sha256=SPUZFgZW1Zhw-bnjJo98RK0vpuNFODQ8Q3eTguNc84k,21359
169
168
  biopipen/scripts/scrna/Seurat2AnnData.R,sha256=F8g5n2CqX4-KBggxd8ittz8TejYuqqNLMudAHdFt1QM,184
170
169
  biopipen/scripts/scrna/SeuratClusterStats-clustree.R,sha256=QmNJicjbLIXYg_RduXHGboCzPEqcFXq32flk5XAqQBg,2886
171
170
  biopipen/scripts/scrna/SeuratClusterStats-dimplots.R,sha256=tCf3BVoXroeGuMcix8BiB1CA7wUpirBow4T6P3HM02k,1541
172
- biopipen/scripts/scrna/SeuratClusterStats-features.R,sha256=Ua4dCqekb2nmx9EEgiQamju4c0p96KWLJWAmiziwiec,5197
171
+ biopipen/scripts/scrna/SeuratClusterStats-features.R,sha256=vFLTzF4hje-7JXy-hYxCZgsasbVByvVkqrTFlxzMTB0,5307
173
172
  biopipen/scripts/scrna/SeuratClusterStats-ngenes.R,sha256=BN8HSl1HoZp8ibESaCVEJPCBWzmu1AFLMgW5ZeZphS0,3077
174
173
  biopipen/scripts/scrna/SeuratClusterStats-stats.R,sha256=u8KOeWLDk7i-ZGGcgZPyNqmchkrePdKq5JLrl4ZCCT8,2297
175
174
  biopipen/scripts/scrna/SeuratClusterStats.R,sha256=lQfl97ARx_l8YNJ1rEdaU-G6EIS-mbFf2rtWLaA6unE,1824
@@ -185,7 +184,7 @@ biopipen/scripts/scrna/SeuratSubset.R,sha256=yVA11NVE2FSSw-DhxQcJRapns0tNNHdyDYi
185
184
  biopipen/scripts/scrna/SeuratTo10X.R,sha256=1mh1R0Qlo1iHVrpMLUXyLDOA92QKJ4GzTMURTFRqsWg,901
186
185
  biopipen/scripts/scrna/Slingshot.R,sha256=wo1zq2Wl6u1HODNzZGjjQLcqKeh9sh7FXPs_iKu6tqw,1750
187
186
  biopipen/scripts/scrna/Subset10X.R,sha256=dT1QY5mHaDcqOMgAtTfyU1FRBNFtfg3nMGCubvBJcSQ,2671
188
- biopipen/scripts/scrna/TopExpressingGenes.R,sha256=4z6BWnZdijN9aZaNjhwI04Vectzk01LqAYmvf_ksFag,6796
187
+ biopipen/scripts/scrna/TopExpressingGenes.R,sha256=K6p7Fac_-4GXCI_TyoLxlTaCaX11DzOihfJ6_Yrs3yk,6869
189
188
  biopipen/scripts/scrna/celltypist-wrapper.py,sha256=upyh035IqDHxljbTaoXwdDmctcx-fDwN56kGvC2xsbw,1776
190
189
  biopipen/scripts/scrna/sctype.R,sha256=NaUJkABwF5G1UVm1CCtcMbwLSj94Mo24mbYCKFqo1Bw,6524
191
190
  biopipen/scripts/scrna/seurat_anndata_conversion.py,sha256=Ya0Wn2TLg1j66N41PdiXXGE8LtE51eC8XnkGi_q2ey8,2437
@@ -214,7 +213,7 @@ biopipen/scripts/tcgamaf/MafAddChr.py,sha256=uo1utaK3Df88aU7xubKw85Ni7W06md8bQlw
214
213
  biopipen/scripts/tcgamaf/maf2vcf.pl,sha256=hJKcH-NbgWK6fmK7f3qex7ozJJl-PqCNPXqpwfcHwJg,22707
215
214
  biopipen/scripts/tcr/Attach2Seurat.R,sha256=0KZaBkuPvqOBXq4ZG3pzIIua5HL-161K5dVXRoCysy4,1366
216
215
  biopipen/scripts/tcr/CDR3AAPhyschem.R,sha256=vU-5sjFZktSzBBj4f1frIGChOV8P8Uf0mMWS2Njdsww,15204
217
- biopipen/scripts/tcr/ClonalStats.R,sha256=89bow8pli4v26nZITPmcFT1cFkL4hZr-s8gxCod-X-0,29329
216
+ biopipen/scripts/tcr/ClonalStats.R,sha256=skqPMTHL8zMGIZ2Q_gKXm9UDFRR-wFRurtrmvbQp7pg,29340
218
217
  biopipen/scripts/tcr/CloneResidency.R,sha256=3pong__cdn2bW7pctq4TLcEdcj_xNigzyKnznnmc1i8,22021
219
218
  biopipen/scripts/tcr/CloneSizeQQPlot.R,sha256=zw5WPgq_lbfdDb9Ou07boh9D2FYjXZtCQKZCP0PKMYw,4561
220
219
  biopipen/scripts/tcr/GIANA/GIANA.py,sha256=jo0d58K57CF4W6mc2Q-hQn9rLl6oLHTsr5JceP8xqN0,54874
@@ -286,7 +285,7 @@ biopipen/utils/misc.py,sha256=pDZ-INWVNqHuXYvcjmu8KqNAigkh2lsHy0BxX44CPvc,4048
286
285
  biopipen/utils/reference.py,sha256=Oc6IlA1giLxymAuI7DO-IQLHQ7-DbsWzOQE86oTDfMU,5955
287
286
  biopipen/utils/reporter.py,sha256=VwLl6xyVDWnGY7NEXyqBlkW8expKJoNQ5iTyZSELf5c,4922
288
287
  biopipen/utils/vcf.py,sha256=MmMbAtLUcKPp02jUdk9TzuET2gWSeoWn7xgoOXFysK0,9393
289
- biopipen-0.34.0.dist-info/METADATA,sha256=s814Vi4vNzzMRB4tNOx-fEDPLHv1CiUHxN7Ls1GTyPc,975
290
- biopipen-0.34.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
291
- biopipen-0.34.0.dist-info/entry_points.txt,sha256=BYqHGBQJxyFDNLYqgH64ycI5PYwnlqwYcCFsMvJgzAU,653
292
- biopipen-0.34.0.dist-info/RECORD,,
288
+ biopipen-0.34.1.dist-info/METADATA,sha256=6vO3KU_HLeykxbXJA5eCO30YyAuylO2cZr_EPwaXwfc,975
289
+ biopipen-0.34.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
290
+ biopipen-0.34.1.dist-info/entry_points.txt,sha256=BYqHGBQJxyFDNLYqgH64ycI5PYwnlqwYcCFsMvJgzAU,653
291
+ biopipen-0.34.1.dist-info/RECORD,,
@@ -1,16 +0,0 @@
1
- {% from "utils/gsea.liq" import fgsea_report -%}
2
- {% from "utils/misc.liq" import report_jobs -%}
3
- <script>
4
- import { Image, DataTable, Descr } from "$libs";
5
- import { Accordion, AccordionItem, Tabs, Tab, TabContent, InlineNotification } from "$ccs";
6
- </script>
7
-
8
- {%- macro report_job(job, h=1) -%}
9
- {{ job | render_job: h=h }}
10
- {%- endmacro -%}
11
-
12
- {%- macro head_job(job) -%}
13
- <h1>{{job.in.srtobj | stem0 | escape}}</h1>
14
- {%- endmacro -%}
15
-
16
- {{ report_jobs(jobs, head_job, report_job) }}