biopipen 0.21.0__py3-none-any.whl → 0.34.26__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.
Files changed (290) hide show
  1. biopipen/__init__.py +1 -1
  2. biopipen/core/config.toml +28 -0
  3. biopipen/core/filters.py +79 -4
  4. biopipen/core/proc.py +12 -3
  5. biopipen/core/testing.py +75 -3
  6. biopipen/ns/bam.py +148 -6
  7. biopipen/ns/bed.py +75 -0
  8. biopipen/ns/cellranger.py +186 -0
  9. biopipen/ns/cellranger_pipeline.py +126 -0
  10. biopipen/ns/cnv.py +19 -3
  11. biopipen/ns/cnvkit.py +1 -1
  12. biopipen/ns/cnvkit_pipeline.py +20 -12
  13. biopipen/ns/delim.py +34 -35
  14. biopipen/ns/gene.py +68 -23
  15. biopipen/ns/gsea.py +63 -37
  16. biopipen/ns/misc.py +39 -14
  17. biopipen/ns/plot.py +304 -1
  18. biopipen/ns/protein.py +183 -0
  19. biopipen/ns/regulatory.py +290 -0
  20. biopipen/ns/rnaseq.py +142 -5
  21. biopipen/ns/scrna.py +2053 -473
  22. biopipen/ns/scrna_metabolic_landscape.py +228 -382
  23. biopipen/ns/snp.py +659 -0
  24. biopipen/ns/stats.py +484 -0
  25. biopipen/ns/tcr.py +683 -98
  26. biopipen/ns/vcf.py +236 -2
  27. biopipen/ns/web.py +97 -6
  28. biopipen/reports/bam/CNVpytor.svelte +4 -9
  29. biopipen/reports/cellranger/CellRangerCount.svelte +18 -0
  30. biopipen/reports/cellranger/CellRangerSummary.svelte +16 -0
  31. biopipen/reports/cellranger/CellRangerVdj.svelte +18 -0
  32. biopipen/reports/cnvkit/CNVkitDiagram.svelte +1 -1
  33. biopipen/reports/cnvkit/CNVkitHeatmap.svelte +1 -1
  34. biopipen/reports/cnvkit/CNVkitScatter.svelte +1 -1
  35. biopipen/reports/common.svelte +15 -0
  36. biopipen/reports/protein/ProdigySummary.svelte +16 -0
  37. biopipen/reports/scrna/CellsDistribution.svelte +4 -39
  38. biopipen/reports/scrna/DimPlots.svelte +1 -1
  39. biopipen/reports/scrna/MarkersFinder.svelte +6 -126
  40. biopipen/reports/scrna/MetaMarkers.svelte +3 -75
  41. biopipen/reports/scrna/RadarPlots.svelte +4 -20
  42. biopipen/reports/scrna_metabolic_landscape/MetabolicFeatures.svelte +61 -22
  43. biopipen/reports/scrna_metabolic_landscape/MetabolicPathwayActivity.svelte +88 -82
  44. biopipen/reports/scrna_metabolic_landscape/MetabolicPathwayHeterogeneity.svelte +70 -10
  45. biopipen/reports/snp/PlinkCallRate.svelte +24 -0
  46. biopipen/reports/snp/PlinkFreq.svelte +18 -0
  47. biopipen/reports/snp/PlinkHWE.svelte +18 -0
  48. biopipen/reports/snp/PlinkHet.svelte +18 -0
  49. biopipen/reports/snp/PlinkIBD.svelte +18 -0
  50. biopipen/reports/tcr/CDR3AAPhyschem.svelte +19 -66
  51. biopipen/reports/tcr/ClonalStats.svelte +16 -0
  52. biopipen/reports/tcr/CloneResidency.svelte +3 -93
  53. biopipen/reports/tcr/Immunarch.svelte +4 -155
  54. biopipen/reports/tcr/TCRClusterStats.svelte +3 -45
  55. biopipen/reports/tcr/TESSA.svelte +11 -28
  56. biopipen/reports/utils/misc.liq +22 -7
  57. biopipen/scripts/bam/BamMerge.py +11 -15
  58. biopipen/scripts/bam/BamSampling.py +90 -0
  59. biopipen/scripts/bam/BamSort.py +141 -0
  60. biopipen/scripts/bam/BamSplitChroms.py +10 -10
  61. biopipen/scripts/bam/BamSubsetByBed.py +38 -0
  62. biopipen/scripts/bam/CNAClinic.R +41 -5
  63. biopipen/scripts/bam/CNVpytor.py +153 -54
  64. biopipen/scripts/bam/ControlFREEC.py +13 -14
  65. biopipen/scripts/bam/SamtoolsView.py +33 -0
  66. biopipen/scripts/bed/Bed2Vcf.py +5 -5
  67. biopipen/scripts/bed/BedConsensus.py +5 -5
  68. biopipen/scripts/bed/BedLiftOver.sh +6 -4
  69. biopipen/scripts/bed/BedtoolsIntersect.py +54 -0
  70. biopipen/scripts/bed/BedtoolsMakeWindows.py +47 -0
  71. biopipen/scripts/bed/BedtoolsMerge.py +4 -4
  72. biopipen/scripts/cellranger/CellRangerCount.py +138 -0
  73. biopipen/scripts/cellranger/CellRangerSummary.R +181 -0
  74. biopipen/scripts/cellranger/CellRangerVdj.py +112 -0
  75. biopipen/scripts/cnv/AneuploidyScore.R +55 -20
  76. biopipen/scripts/cnv/AneuploidyScoreSummary.R +221 -163
  77. biopipen/scripts/cnv/TMADScore.R +25 -9
  78. biopipen/scripts/cnv/TMADScoreSummary.R +57 -86
  79. biopipen/scripts/cnvkit/CNVkitAccess.py +7 -6
  80. biopipen/scripts/cnvkit/CNVkitAutobin.py +26 -18
  81. biopipen/scripts/cnvkit/CNVkitBatch.py +6 -6
  82. biopipen/scripts/cnvkit/CNVkitCall.py +3 -3
  83. biopipen/scripts/cnvkit/CNVkitCoverage.py +4 -3
  84. biopipen/scripts/cnvkit/CNVkitDiagram.py +5 -5
  85. biopipen/scripts/cnvkit/CNVkitFix.py +3 -3
  86. biopipen/scripts/cnvkit/CNVkitGuessBaits.py +12 -8
  87. biopipen/scripts/cnvkit/CNVkitHeatmap.py +5 -5
  88. biopipen/scripts/cnvkit/CNVkitReference.py +6 -5
  89. biopipen/scripts/cnvkit/CNVkitScatter.py +5 -5
  90. biopipen/scripts/cnvkit/CNVkitSegment.py +5 -5
  91. biopipen/scripts/cnvkit/guess_baits.py +166 -93
  92. biopipen/scripts/delim/RowsBinder.R +1 -1
  93. biopipen/scripts/delim/SampleInfo.R +116 -118
  94. biopipen/scripts/gene/GeneNameConversion.R +67 -0
  95. biopipen/scripts/gene/GenePromoters.R +61 -0
  96. biopipen/scripts/gsea/Enrichr.R +5 -5
  97. biopipen/scripts/gsea/FGSEA.R +184 -50
  98. biopipen/scripts/gsea/GSEA.R +2 -2
  99. biopipen/scripts/gsea/PreRank.R +5 -5
  100. biopipen/scripts/misc/Config2File.py +2 -2
  101. biopipen/scripts/misc/Plot.R +80 -0
  102. biopipen/scripts/misc/Shell.sh +15 -0
  103. biopipen/scripts/misc/Str2File.py +2 -2
  104. biopipen/scripts/plot/Heatmap.R +3 -3
  105. biopipen/scripts/plot/Manhattan.R +147 -0
  106. biopipen/scripts/plot/QQPlot.R +146 -0
  107. biopipen/scripts/plot/ROC.R +88 -0
  108. biopipen/scripts/plot/Scatter.R +112 -0
  109. biopipen/scripts/plot/VennDiagram.R +5 -9
  110. biopipen/scripts/protein/MMCIF2PDB.py +33 -0
  111. biopipen/scripts/protein/PDB2Fasta.py +60 -0
  112. biopipen/scripts/protein/Prodigy.py +119 -0
  113. biopipen/scripts/protein/ProdigySummary.R +140 -0
  114. biopipen/scripts/protein/RMSD.py +178 -0
  115. biopipen/scripts/regulatory/MotifAffinityTest.R +102 -0
  116. biopipen/scripts/regulatory/MotifAffinityTest_AtSNP.R +127 -0
  117. biopipen/scripts/regulatory/MotifAffinityTest_MotifBreakR.R +104 -0
  118. biopipen/scripts/regulatory/MotifScan.py +159 -0
  119. biopipen/scripts/regulatory/VariantMotifPlot.R +78 -0
  120. biopipen/scripts/regulatory/motifs-common.R +324 -0
  121. biopipen/scripts/rnaseq/Simulation-ESCO.R +180 -0
  122. biopipen/scripts/rnaseq/Simulation-RUVcorr.R +45 -0
  123. biopipen/scripts/rnaseq/Simulation.R +21 -0
  124. biopipen/scripts/rnaseq/UnitConversion.R +325 -54
  125. biopipen/scripts/scrna/AnnData2Seurat.R +40 -0
  126. biopipen/scripts/scrna/CCPlotR-patch.R +161 -0
  127. biopipen/scripts/scrna/CellCellCommunication.py +150 -0
  128. biopipen/scripts/scrna/CellCellCommunicationPlots.R +93 -0
  129. biopipen/scripts/scrna/CellSNPLite.py +30 -0
  130. biopipen/scripts/scrna/CellTypeAnnotation-celltypist.R +185 -0
  131. biopipen/scripts/scrna/CellTypeAnnotation-direct.R +68 -31
  132. biopipen/scripts/scrna/CellTypeAnnotation-hitype.R +27 -22
  133. biopipen/scripts/scrna/CellTypeAnnotation-sccatch.R +28 -20
  134. biopipen/scripts/scrna/CellTypeAnnotation-sctype.R +48 -25
  135. biopipen/scripts/scrna/CellTypeAnnotation.R +37 -1
  136. biopipen/scripts/scrna/CellsDistribution.R +456 -167
  137. biopipen/scripts/scrna/DimPlots.R +1 -1
  138. biopipen/scripts/scrna/ExprImputation-alra.R +109 -0
  139. biopipen/scripts/scrna/ExprImputation-rmagic.R +256 -0
  140. biopipen/scripts/scrna/{ExprImpution-scimpute.R → ExprImputation-scimpute.R} +8 -5
  141. biopipen/scripts/scrna/ExprImputation.R +7 -0
  142. biopipen/scripts/scrna/LoomTo10X.R +51 -0
  143. biopipen/scripts/scrna/MQuad.py +25 -0
  144. biopipen/scripts/scrna/MarkersFinder.R +679 -400
  145. biopipen/scripts/scrna/MetaMarkers.R +265 -161
  146. biopipen/scripts/scrna/ModuleScoreCalculator.R +66 -11
  147. biopipen/scripts/scrna/PseudoBulkDEG.R +678 -0
  148. biopipen/scripts/scrna/RadarPlots.R +355 -134
  149. biopipen/scripts/scrna/ScFGSEA.R +298 -100
  150. biopipen/scripts/scrna/ScSimulation.R +65 -0
  151. biopipen/scripts/scrna/ScVelo.py +617 -0
  152. biopipen/scripts/scrna/Seurat2AnnData.R +7 -0
  153. biopipen/scripts/scrna/SeuratClusterStats-clustree.R +87 -0
  154. biopipen/scripts/scrna/SeuratClusterStats-dimplots.R +36 -30
  155. biopipen/scripts/scrna/SeuratClusterStats-features.R +138 -187
  156. biopipen/scripts/scrna/SeuratClusterStats-ngenes.R +81 -0
  157. biopipen/scripts/scrna/SeuratClusterStats-stats.R +78 -89
  158. biopipen/scripts/scrna/SeuratClusterStats.R +47 -10
  159. biopipen/scripts/scrna/SeuratClustering.R +36 -233
  160. biopipen/scripts/scrna/SeuratLoading.R +2 -2
  161. biopipen/scripts/scrna/SeuratMap2Ref.R +84 -113
  162. biopipen/scripts/scrna/SeuratMetadataMutater.R +16 -6
  163. biopipen/scripts/scrna/SeuratPreparing.R +223 -173
  164. biopipen/scripts/scrna/SeuratSubClustering.R +64 -0
  165. biopipen/scripts/scrna/SeuratTo10X.R +27 -0
  166. biopipen/scripts/scrna/Slingshot.R +65 -0
  167. biopipen/scripts/scrna/Subset10X.R +2 -2
  168. biopipen/scripts/scrna/TopExpressingGenes.R +169 -135
  169. biopipen/scripts/scrna/celltypist-wrapper.py +195 -0
  170. biopipen/scripts/scrna/scvelo_paga.py +313 -0
  171. biopipen/scripts/scrna/seurat_anndata_conversion.py +98 -0
  172. biopipen/scripts/scrna_metabolic_landscape/MetabolicFeatures.R +447 -82
  173. biopipen/scripts/scrna_metabolic_landscape/MetabolicPathwayActivity.R +348 -241
  174. biopipen/scripts/scrna_metabolic_landscape/MetabolicPathwayHeterogeneity.R +188 -166
  175. biopipen/scripts/snp/MatrixEQTL.R +217 -0
  176. biopipen/scripts/snp/Plink2GTMat.py +148 -0
  177. biopipen/scripts/snp/PlinkCallRate.R +199 -0
  178. biopipen/scripts/snp/PlinkFilter.py +100 -0
  179. biopipen/scripts/snp/PlinkFreq.R +291 -0
  180. biopipen/scripts/snp/PlinkFromVcf.py +81 -0
  181. biopipen/scripts/snp/PlinkHWE.R +85 -0
  182. biopipen/scripts/snp/PlinkHet.R +96 -0
  183. biopipen/scripts/snp/PlinkIBD.R +196 -0
  184. biopipen/scripts/snp/PlinkSimulation.py +124 -0
  185. biopipen/scripts/snp/PlinkUpdateName.py +124 -0
  186. biopipen/scripts/stats/ChowTest.R +146 -0
  187. biopipen/scripts/stats/DiffCoexpr.R +152 -0
  188. biopipen/scripts/stats/LiquidAssoc.R +135 -0
  189. biopipen/scripts/stats/Mediation.R +108 -0
  190. biopipen/scripts/stats/MetaPvalue.R +130 -0
  191. biopipen/scripts/stats/MetaPvalue1.R +74 -0
  192. biopipen/scripts/tcgamaf/Maf2Vcf.py +2 -2
  193. biopipen/scripts/tcgamaf/MafAddChr.py +2 -2
  194. biopipen/scripts/tcr/Attach2Seurat.R +3 -2
  195. biopipen/scripts/tcr/CDR3AAPhyschem.R +211 -143
  196. biopipen/scripts/tcr/CDR3Clustering.R +343 -0
  197. biopipen/scripts/tcr/ClonalStats.R +526 -0
  198. biopipen/scripts/tcr/CloneResidency.R +255 -131
  199. biopipen/scripts/tcr/CloneSizeQQPlot.R +4 -4
  200. biopipen/scripts/tcr/GIANA/GIANA.py +1356 -797
  201. biopipen/scripts/tcr/GIANA/GIANA4.py +1362 -789
  202. biopipen/scripts/tcr/GIANA/query.py +164 -162
  203. biopipen/scripts/tcr/Immunarch-basic.R +31 -9
  204. biopipen/scripts/tcr/Immunarch-clonality.R +25 -5
  205. biopipen/scripts/tcr/Immunarch-diversity.R +352 -134
  206. biopipen/scripts/tcr/Immunarch-geneusage.R +45 -5
  207. biopipen/scripts/tcr/Immunarch-kmer.R +68 -8
  208. biopipen/scripts/tcr/Immunarch-overlap.R +84 -4
  209. biopipen/scripts/tcr/Immunarch-spectratyping.R +35 -6
  210. biopipen/scripts/tcr/Immunarch-tracking.R +38 -6
  211. biopipen/scripts/tcr/Immunarch-vjjunc.R +165 -0
  212. biopipen/scripts/tcr/Immunarch.R +63 -11
  213. biopipen/scripts/tcr/Immunarch2VDJtools.R +2 -2
  214. biopipen/scripts/tcr/ImmunarchFilter.R +4 -4
  215. biopipen/scripts/tcr/ImmunarchLoading.R +38 -29
  216. biopipen/scripts/tcr/SampleDiversity.R +1 -1
  217. biopipen/scripts/tcr/ScRepCombiningExpression.R +40 -0
  218. biopipen/scripts/tcr/ScRepLoading.R +166 -0
  219. biopipen/scripts/tcr/TCRClusterStats.R +176 -22
  220. biopipen/scripts/tcr/TCRDock.py +110 -0
  221. biopipen/scripts/tcr/TESSA.R +102 -118
  222. biopipen/scripts/tcr/VJUsage.R +5 -5
  223. biopipen/scripts/tcr/immunarch-patched.R +142 -0
  224. biopipen/scripts/tcr/vdjtools-patch.sh +1 -1
  225. biopipen/scripts/vcf/BcftoolsAnnotate.py +91 -0
  226. biopipen/scripts/vcf/BcftoolsFilter.py +90 -0
  227. biopipen/scripts/vcf/BcftoolsMerge.py +31 -0
  228. biopipen/scripts/vcf/BcftoolsSort.py +113 -0
  229. biopipen/scripts/vcf/BcftoolsView.py +73 -0
  230. biopipen/scripts/vcf/TruvariBench.sh +14 -7
  231. biopipen/scripts/vcf/TruvariBenchSummary.R +16 -13
  232. biopipen/scripts/vcf/TruvariConsistency.R +1 -1
  233. biopipen/scripts/vcf/Vcf2Bed.py +2 -2
  234. biopipen/scripts/vcf/VcfAnno.py +11 -11
  235. biopipen/scripts/vcf/VcfDownSample.sh +22 -10
  236. biopipen/scripts/vcf/VcfFilter.py +5 -5
  237. biopipen/scripts/vcf/VcfFix.py +7 -7
  238. biopipen/scripts/vcf/VcfFix_utils.py +13 -4
  239. biopipen/scripts/vcf/VcfIndex.py +3 -3
  240. biopipen/scripts/vcf/VcfIntersect.py +3 -3
  241. biopipen/scripts/vcf/VcfLiftOver.sh +5 -0
  242. biopipen/scripts/vcf/VcfSplitSamples.py +4 -4
  243. biopipen/scripts/vcf/bcftools_utils.py +52 -0
  244. biopipen/scripts/web/Download.py +8 -4
  245. biopipen/scripts/web/DownloadList.py +5 -5
  246. biopipen/scripts/web/GCloudStorageDownloadBucket.py +82 -0
  247. biopipen/scripts/web/GCloudStorageDownloadFile.py +23 -0
  248. biopipen/scripts/web/gcloud_common.py +49 -0
  249. biopipen/utils/gene.py +108 -60
  250. biopipen/utils/misc.py +146 -20
  251. biopipen/utils/reference.py +64 -20
  252. biopipen/utils/reporter.py +177 -0
  253. biopipen/utils/vcf.py +1 -1
  254. biopipen-0.34.26.dist-info/METADATA +27 -0
  255. biopipen-0.34.26.dist-info/RECORD +292 -0
  256. {biopipen-0.21.0.dist-info → biopipen-0.34.26.dist-info}/WHEEL +1 -1
  257. {biopipen-0.21.0.dist-info → biopipen-0.34.26.dist-info}/entry_points.txt +6 -2
  258. biopipen/ns/bcftools.py +0 -111
  259. biopipen/ns/scrna_basic.py +0 -255
  260. biopipen/reports/delim/SampleInfo.svelte +0 -36
  261. biopipen/reports/scrna/GeneExpressionInvistigation.svelte +0 -32
  262. biopipen/reports/scrna/ScFGSEA.svelte +0 -35
  263. biopipen/reports/scrna/SeuratClusterStats.svelte +0 -82
  264. biopipen/reports/scrna/SeuratMap2Ref.svelte +0 -20
  265. biopipen/reports/scrna/SeuratPreparing.svelte +0 -38
  266. biopipen/reports/scrna/TopExpressingGenes.svelte +0 -55
  267. biopipen/reports/scrna_metabolic_landscape/MetabolicFeaturesIntraSubset.svelte +0 -31
  268. biopipen/reports/utils/gsea.liq +0 -110
  269. biopipen/scripts/bcftools/BcftoolsAnnotate.py +0 -42
  270. biopipen/scripts/bcftools/BcftoolsFilter.py +0 -79
  271. biopipen/scripts/bcftools/BcftoolsSort.py +0 -19
  272. biopipen/scripts/gene/GeneNameConversion.py +0 -66
  273. biopipen/scripts/scrna/ExprImpution-alra.R +0 -32
  274. biopipen/scripts/scrna/ExprImpution-rmagic.R +0 -29
  275. biopipen/scripts/scrna/ExprImpution.R +0 -7
  276. biopipen/scripts/scrna/GeneExpressionInvistigation.R +0 -132
  277. biopipen/scripts/scrna/Write10X.R +0 -11
  278. biopipen/scripts/scrna_metabolic_landscape/MetabolicFeaturesIntraSubset.R +0 -150
  279. biopipen/scripts/tcr/TCRClustering.R +0 -280
  280. biopipen/utils/common_docstrs.py +0 -61
  281. biopipen/utils/gene.R +0 -49
  282. biopipen/utils/gsea.R +0 -193
  283. biopipen/utils/io.R +0 -20
  284. biopipen/utils/misc.R +0 -114
  285. biopipen/utils/mutate_helpers.R +0 -433
  286. biopipen/utils/plot.R +0 -173
  287. biopipen/utils/rnaseq.R +0 -48
  288. biopipen/utils/single_cell.R +0 -115
  289. biopipen-0.21.0.dist-info/METADATA +0 -22
  290. biopipen-0.21.0.dist-info/RECORD +0 -218
@@ -0,0 +1,678 @@
1
+ library(rlang)
2
+ library(dplyr)
3
+ library(plotthis)
4
+ library(Seurat)
5
+ library(biopipen.utils)
6
+
7
+ sobjfile <- {{in.sobjfile | r}}
8
+ outdir <- {{out.outdir | r}}
9
+ joboutdir <- {{job.outdir | r}}
10
+ each <- {{envs.each | r}}
11
+ subset <- {{envs.subset | r}}
12
+ ncores <- {{envs.ncores | r}}
13
+ mutaters <- {{envs.mutaters | r}}
14
+ cache <- {{ envs.cache | r }}
15
+ aggregate_by <- {{envs.aggregate_by | r}}
16
+ layer <- {{envs.layer | r}}
17
+ assay <- {{envs.assay | r}}
18
+ error <- {{ envs.error | r }}
19
+ group_by <- {{envs.group_by | default: envs[["group-by"]] | default: None | r}}
20
+ ident_1 <- {{envs.ident_1 | default: envs[["ident-1"]] | default: None | r}}
21
+ ident_2 <- {{envs.ident_2 | default: envs[["ident-2"]] | default: None | r}}
22
+ each <- {{ envs.each | r }}
23
+ dbs <- {{ envs.dbs | r }}
24
+ sigmarkers <- {{ envs.sigmarkers | r }}
25
+ enrich_style <- {{ envs.enrich_style | r }}
26
+ paired_by <- {{envs.paired_by | default: envs[["paired-by"]] | default: None | r}}
27
+ tool <- {{envs.tool | r}}
28
+ allmarker_plots_defaults <- {{ envs.allmarker_plots_defaults | r }}
29
+ allmarker_plots <- {{ envs.allmarker_plots | r }}
30
+ allenrich_plots_defaults <- {{ envs.allenrich_plots_defaults | r }}
31
+ allenrich_plots <- {{ envs.allenrich_plots | r }}
32
+ marker_plots_defaults <- {{ envs.marker_plots_defaults | r }}
33
+ marker_plots <- {{ envs.marker_plots | r }}
34
+ enrich_plots_defaults <- {{ envs.enrich_plots_defaults | r }}
35
+ enrich_plots <- {{ envs.enrich_plots | r }}
36
+ overlaps_defaults <- {{ envs.overlaps_defaults | r }}
37
+ overlaps <- {{ envs.overlaps | r }}
38
+ cases <- {{envs.cases | r}}
39
+
40
+ aggregate_by <- unique(c(aggregate_by, group_by, paired_by, each))
41
+ if (isTRUE(cache)) { cache <- joboutdir }
42
+
43
+ log <- get_logger()
44
+ reporter <- get_reporter()
45
+
46
+ log$info("Loading Seurat object ...")
47
+ srtobj <- read_obj(sobjfile)
48
+
49
+ if (!is.null(mutaters) && length(mutaters) > 0) {
50
+ log$info("Mutating metadata columns ...")
51
+ srtobj@meta.data <- srtobj@meta.data %>% mutate(!!!lapply(mutaters, parse_expr))
52
+ }
53
+
54
+ allmarker_plots <- lapply(allmarker_plots, function(x) {
55
+ list_update(allmarker_plots_defaults, x)
56
+ })
57
+ allenrich_plots <- lapply(allenrich_plots, function(x) {
58
+ list_update(allenrich_plots_defaults, x)
59
+ })
60
+ marker_plots <- lapply(marker_plots, function(x) {
61
+ list_update(marker_plots_defaults, x)
62
+ })
63
+ enrich_plots <- lapply(enrich_plots, function(x) {
64
+ list_update(enrich_plots_defaults, x)
65
+ })
66
+ overlaps <- lapply(overlaps, function(x) {
67
+ list_update(overlaps_defaults, x)
68
+ })
69
+
70
+ defaults <- list(
71
+ each = each,
72
+ error = error,
73
+ subset = subset,
74
+ aggregate_by = aggregate_by,
75
+ layer = layer,
76
+ assay = assay %||% DefaultAssay(srtobj),
77
+ group_by = group_by,
78
+ ident_1 = ident_1,
79
+ ident_2 = ident_2,
80
+ dbs = dbs,
81
+ ncores = ncores,
82
+ sigmarkers = sigmarkers,
83
+ enrich_style = enrich_style,
84
+ paired_by = paired_by,
85
+ tool = tool,
86
+ cache = cache,
87
+ allmarker_plots_defaults = allmarker_plots_defaults,
88
+ allmarker_plots = allmarker_plots,
89
+ allenrich_plots_defaults = allenrich_plots_defaults,
90
+ allenrich_plots = allenrich_plots,
91
+ marker_plots_defaults = marker_plots_defaults,
92
+ marker_plots = marker_plots,
93
+ enrich_plots_defaults = enrich_plots_defaults,
94
+ enrich_plots = enrich_plots,
95
+ overlaps_defaults = overlaps_defaults,
96
+ overlaps = overlaps
97
+ )
98
+
99
+ expand_each <- function(name, case) {
100
+ outcases <- list()
101
+
102
+ if (is.null(case$each) || is.na(case$each) || nchar(case$each) == 0 || isFALSE(each)) {
103
+ if (length(case$allmarker_plots) > 0 || length(allenrich_plots) > 0 || length(overlaps) > 0) {
104
+ stop("Cannot perform allmarker_plots, allenrich_plots, or overlaps without 'each' defined.")
105
+ }
106
+
107
+ case$aggregate_by <- unique(c(case$aggregate_by, case$group_by, case$paired_by))
108
+
109
+ case$marker_plots <- lapply(
110
+ case$marker_plots,
111
+ function(x) { list_update(case$marker_plots_defaults, x) }
112
+ )
113
+ case$marker_plots_defaults <- NULL
114
+
115
+ case$enrich_plots <- lapply(
116
+ case$enrich_plots,
117
+ function(x) { list_update(case$enrich_plots_defaults, x) }
118
+ )
119
+ case$enrich_plots_defaults <- NULL
120
+
121
+ case$overlaps <- lapply(
122
+ case$overlaps,
123
+ function(x) { list_update(case$overlaps_defaults, x) }
124
+ )
125
+ case$overlaps_defaults <- NULL
126
+
127
+ outcases[[name]] <- case
128
+ } else {
129
+ eachs <- if (!is.null(case$subset)) {
130
+ srtobj@meta.data %>%
131
+ filter(!!parse_expr(case$subset)) %>%
132
+ pull(case$each) %>% na.omit() %>% unique() %>% as.vector()
133
+ } else {
134
+ srtobj@meta.data %>%
135
+ pull(case$each) %>% na.omit() %>% unique() %>% as.vector()
136
+ }
137
+
138
+ if (length(cases) == 0 && name == "DEG Analysis") {
139
+ name <- case$each
140
+ } else {
141
+ name <- paste0(name, " (", case$each, ")")
142
+ }
143
+
144
+ case$aggregate_by <- unique(c(case$aggregate_by, case$group_by, case$paired_by, case$each))
145
+
146
+ for (each in eachs) {
147
+ newname <- paste0(name, "::", each)
148
+ newcase <- case
149
+
150
+ newcase$original_case <- name
151
+ newcase$each_name <- case$each
152
+ newcase$each <- each
153
+
154
+ newcase$alleach_plots_defaults <- NULL
155
+ newcase$alleach_plots <- NULL
156
+ newcase$original_subset <- case$subset
157
+
158
+ if (!is.null(case$subset)) {
159
+ newcase$subset <- paste0(case$subset, " & ", bQuote(case$each), " == '", each, "'")
160
+ } else {
161
+ newcase$subset <- paste0(bQuote(case$each), " == '", each, "'")
162
+ }
163
+
164
+ newcase$marker_plots <- lapply(
165
+ case$marker_plots,
166
+ function(x) { list_update(case$marker_plots_defaults, x) }
167
+ )
168
+ newcase$marker_plots_defaults <- NULL
169
+
170
+ newcase$enrich_plots <- lapply(
171
+ case$enrich_plots,
172
+ function(x) { list_update(case$enrich_plots_defaults, x) }
173
+ )
174
+ newcase$enrich_plots_defaults <- NULL
175
+
176
+ # Will be processed by the case itself, which collects the markers
177
+ newcase$allmarker_plots <- NULL
178
+ newcase$allmarker_plots_defaults <- NULL
179
+ newcase$allenrich_plots <- NULL
180
+ newcase$allenrich_plots_defaults <- NULL
181
+ newcase$overlaps <- NULL
182
+ newcase$overlaps_defaults <- NULL
183
+
184
+ outcases[[newname]] <- newcase
185
+ }
186
+
187
+ if (length(case$overlaps) > 0 || length(case$allmarker_plots) > 0 || length(case$allenrich_plots) > 0) {
188
+ ovcase <- case
189
+
190
+ ovcase$allexprs <- list()
191
+ ovcase$markers <- list()
192
+ ovcase$allmarker_plots <- lapply(
193
+ ovcase$allmarker_plots,
194
+ function(x) { list_update(ovcase$allmarker_plots_defaults, x) }
195
+ )
196
+ ovcase$allmarker_plots_defaults <- NULL
197
+
198
+ ovcase$enriches <- list()
199
+ ovcase$allenrich_plots <- lapply(
200
+ ovcase$allenrich_plots,
201
+ function(x) { list_update(ovcase$allenrich_plots_defaults, x) }
202
+ )
203
+ ovcase$allenrich_plots_defaults <- NULL
204
+
205
+ ovcase$overlaps <- lapply(
206
+ ovcase$overlaps,
207
+ function(x) { list_update(ovcase$overlaps_defaults, x) }
208
+ )
209
+ ovcase$overlaps_defaults <- NULL
210
+ outcases[[name]] <- ovcase
211
+ }
212
+ }
213
+ outcases
214
+ }
215
+ cases <- expand_cases(cases, defaults, expand_each, default_case = "DEG Analysis")
216
+
217
+ log$info("Running cases ...")
218
+
219
+ process_markers <- function(markers, info, case) {
220
+ ## Attributes lost
221
+ # markers <- markers %>%
222
+ # mutate(gene = as.character(gene)) %>%
223
+ # arrange(p_val_adj, desc(abs(avg_log2FC)))
224
+
225
+ empty <- if (case$enrich_style == "enrichr") {
226
+ data.frame(
227
+ Database = character(0),
228
+ Term = character(0),
229
+ Overlap = character(0),
230
+ P.value = numeric(0),
231
+ Adjusted.P.value = numeric(0),
232
+ Odds.Ratio = numeric(0),
233
+ Combined.Score = numeric(0),
234
+ Genes = character(0),
235
+ Rank = numeric(0)
236
+ )
237
+ } else { # clusterProfiler
238
+ data.frame(
239
+ ID = character(0),
240
+ Description = character(0),
241
+ GeneRatio = character(0),
242
+ BgRatio = character(0),
243
+ Count = integer(0),
244
+ pvalue = numeric(0),
245
+ p.adjust = numeric(0),
246
+ qvalue = numeric(0),
247
+ geneID = character(0),
248
+ Database = character(0)
249
+ )
250
+ }
251
+ if (is.null(markers) || nrow(markers) == 0) {
252
+ if (case$error) {
253
+ stop("Error: No markers found in case '", info$name, "'.")
254
+ } else {
255
+ log$warn("! Warning: No markers found in case '", info$name, "'.")
256
+ reporter$add2(
257
+ list(
258
+ name = "Warning",
259
+ contents = list(list(kind = "error", content = "No markers found.", kind_ = "warning"))),
260
+ hs = c(info$section, info$name),
261
+ hs2 = "DEG Analysis",
262
+ ui = "tabs"
263
+ )
264
+ return(empty)
265
+ }
266
+ }
267
+ markers$gene <- as.character(markers$gene)
268
+ markers$p_val_adj <- as.numeric(markers$p_val_adj)
269
+ markers$log2FC <- as.numeric(markers$log2FC)
270
+ markers <- markers[order(markers$p_val_adj, -abs(markers$log2FC)), ]
271
+
272
+ # Save markers
273
+ write.table(markers, file.path(info$prefix, "degs.tsv"), sep = "\t", quote = FALSE, row.names = FALSE)
274
+
275
+ sigmarkers <- markers %>% filter(!!parse_expr(case$sigmarkers))
276
+ write.table(sigmarkers, file.path(info$prefix, "sigdegs.tsv"), sep = "\t", quote = FALSE, row.names = FALSE)
277
+ reporter$add2(
278
+ list(
279
+ name = "Table",
280
+ contents = list(
281
+ list(kind = "descr", content = paste0(
282
+ "Showing top 100 DEGs ordered by p_val_adj ascendingly, then abs(log2FC) descendingly. ",
283
+ "Use 'Download the entire data' button to download all significant markers by '",
284
+ html_escape(case$sigmarkers), "'."
285
+ )),
286
+ list(kind = "table", src = file.path(info$prefix, "sigdegs.tsv"), data = list(nrows = 100))
287
+ )
288
+ ),
289
+ hs = c(info$section, info$name),
290
+ hs2 = ifelse(is.null(case$ident), "DEGs", paste0("DEGs (", case$ident, ")")),
291
+ ui = "tabs"
292
+ )
293
+
294
+ for (plotname in names(case$marker_plots)) {
295
+ plotargs <- case$marker_plots[[plotname]]
296
+ plotargs$degs <- markers
297
+ rownames(plotargs$degs) <- make.unique(markers$gene)
298
+ plotargs$outprefix <- file.path(info$prefix, paste0("degs.", slugify(plotname)))
299
+ do_call(VizBulkDEGs, plotargs)
300
+ reporter$add2(
301
+ list(
302
+ name = plotname,
303
+ contents = list(reporter$image(plotargs$outprefix, plotargs$more_formats, plotargs$save_code))),
304
+ hs = c(info$section, info$name),
305
+ hs2 = ifelse(is.null(case$ident), "DEGs", paste0("DEGs (", case$ident, ")")),
306
+ ui = "tabs"
307
+ )
308
+ }
309
+
310
+ # Do enrichment analysis
311
+ significant_markers <- unique(sigmarkers$gene)
312
+ empty <- if (case$enrich_style == "enrichr") {
313
+ data.frame(
314
+ Database = character(0),
315
+ Term = character(0),
316
+ Overlap = character(0),
317
+ P.value = numeric(0),
318
+ Adjusted.P.value = numeric(0),
319
+ Odds.Ratio = numeric(0),
320
+ Combined.Score = numeric(0),
321
+ Genes = character(0),
322
+ Rank = numeric(0)
323
+ )
324
+ } else { # clusterProfiler
325
+ data.frame(
326
+ ID = character(0),
327
+ Description = character(0),
328
+ GeneRatio = character(0),
329
+ BgRatio = character(0),
330
+ Count = integer(0),
331
+ pvalue = numeric(0),
332
+ p.adjust = numeric(0),
333
+ qvalue = numeric(0),
334
+ geneID = character(0),
335
+ Database = character(0)
336
+ )
337
+ }
338
+
339
+ if (length(significant_markers) < 5) {
340
+ if (case$error) {
341
+ stop("Error: Not enough significant DEGs with '", case$sigmarkers, "' in case '", info$name, "' found (< 5) for enrichment analysis.")
342
+ } else {
343
+ message <- paste0("Not enough significant DEGs with '", case$sigmarkers, "' found (< 5) for enrichment analysis.")
344
+ log$warn("! Error: {message}")
345
+ reporter$add2(
346
+ list(
347
+ name = "Warning",
348
+ contents = list(list(kind = "error", content = message, kind_ = "warning"))),
349
+ hs = c(info$section, info$name),
350
+ hs2 = "Enrichment Analysis",
351
+ ui = "tabs"
352
+ )
353
+ }
354
+ return(empty)
355
+ } else {
356
+ tryCatch({
357
+ enrich <- RunEnrichment(
358
+ significant_markers,
359
+ dbs = case$dbs, style = case$enrich_style)
360
+
361
+ write.table(enrich, file.path(info$prefix, "enrich.tsv"), sep = "\t", quote = FALSE, row.names = FALSE)
362
+ reporter$add2(
363
+ list(
364
+ name = "Table",
365
+ contents = list(list(kind = "table", src = file.path(info$prefix, "enrich.tsv"), data = list(nrows = 100)))
366
+ ),
367
+ hs = c(info$section, info$name),
368
+ hs2 = "Enrichment Analysis",
369
+ ui = "tabs"
370
+ )
371
+
372
+ # Visualize enriched terms
373
+ if (length(case$enrich_plots) > 0) {
374
+ for (db in case$dbs) {
375
+ plots <- list()
376
+ for (plotname in names(case$enrich_plots)) {
377
+ plotargs <- case$enrich_plots[[plotname]]
378
+ plotargs$data <- enrich[enrich$Database == db, , drop = FALSE]
379
+
380
+ p <- do_call(VizEnrichment, plotargs)
381
+
382
+ if (plotargs$plot_type == "bar") {
383
+ attr(p, "height") <- attr(p, "height") / 1.5
384
+ }
385
+ outprefix <- file.path(info$prefix, paste0("enrich.", slugify(db), ".", slugify(plotname)))
386
+ save_plot(p, outprefix, plotargs$devpars, formats = "png")
387
+ plots[[length(plots) + 1]] <- reporter$image(outprefix, c(), FALSE)
388
+ }
389
+ reporter$add2(
390
+ list(name = db, contents = plots),
391
+ hs = c(info$section, info$name),
392
+ hs2 = "Enrichment Analysis",
393
+ ui = "tabs"
394
+ )
395
+ }
396
+ }
397
+ return(enrich)
398
+ }, error = function(e) {
399
+ if (case$error) {
400
+ stop("Error: ", e$message)
401
+ } else {
402
+ log$warn("! Error: {e$message}")
403
+ reporter$add2(
404
+ list(
405
+ name = "Warning",
406
+ contents = list(list(kind = "error", content = e$message, kind_ = "warning"))),
407
+ hs = c(info$section, info$name),
408
+ hs2 = "Enrichment Analysis",
409
+ ui = "tabs"
410
+ )
411
+ }
412
+ return(empty)
413
+ })
414
+ }
415
+ }
416
+
417
+ process_allmarkers <- function(markers, plotcases, casename, groupname) {
418
+ name <- paste0(casename, "::", paste0(groupname, " (All DEGs)"))
419
+ info <- case_info(name, outdir, create = TRUE)
420
+
421
+ for (plotname in names(plotcases)) {
422
+ plotargs <- plotcases[[plotname]]
423
+ plotargs$degs <- markers
424
+ plotargs$outprefix <- file.path(info$prefix, slugify(plotname))
425
+ do_call(VizBulkDEGs, plotargs)
426
+ reporter$add2(
427
+ list(
428
+ name = plotname,
429
+ contents = list(reporter$image(plotargs$outprefix, plotargs$more_formats, plotargs$save_code))
430
+ ),
431
+ hs = c(info$section, info$name),
432
+ ui = "tabs"
433
+ )
434
+ }
435
+ }
436
+
437
+ process_allenriches <- function(enriches, plotcases, casename, groupname) {
438
+ name <- paste0(casename, "::", paste0(groupname, " (All Enrichments)"))
439
+ info <- case_info(name, outdir, create = TRUE)
440
+ dbs <- unique(as.character(enriches$Database))
441
+
442
+ for (db in dbs) {
443
+ plots <- list()
444
+ for (plotname in names(plotcases)) {
445
+ plotargs <- plotcases[[plotname]]
446
+ plotargs <- extract_vars(plotargs, "devpars")
447
+ plotargs$data <- enriches[enriches$Database == db, , drop = FALSE]
448
+ if (plotargs$plot_type == "heatmap") {
449
+ plotargs$group_by <- groupname
450
+ plotargs$show_row_names = plotargs$show_row_names %||% TRUE
451
+ plotargs$show_column_names = plotargs$show_column_names %||% TRUE
452
+ }
453
+
454
+ p <- do_call(VizEnrichment, plotargs)
455
+
456
+ if (plotargs$plot_type == "bar") {
457
+ attr(p, "height") <- attr(p, "height") / 1.5
458
+ }
459
+ outprefix <- file.path(info$prefix, paste0("allenrich.", slugify(db), ".", slugify(plotname)))
460
+ save_plot(p, outprefix, devpars, formats = "png")
461
+ plots[[length(plots) + 1]] <- reporter$image(outprefix, c(), FALSE)
462
+ }
463
+ reporter$add2(
464
+ list(name = db, contents = plots),
465
+ hs = c(info$section, info$name),
466
+ hs2 = plotname,
467
+ ui = "tabs"
468
+ )
469
+ }
470
+ }
471
+
472
+ process_overlaps <- function(markers, ovcases, casename, groupname) {
473
+ name <- paste0(casename, "::", paste0(groupname, " (Overlaps)"))
474
+ info <- case_info(name, outdir, create = TRUE)
475
+
476
+ for (plotname in names(ovcases)) {
477
+ args <- extract_vars(
478
+ ovcases[[plotname]],
479
+ sigm = "sigmarkers", "more_formats", "save_code", "devpars", "plot_type",
480
+ allow_nonexisting = TRUE
481
+ )
482
+
483
+ sigm <- sigm %||% sigmarkers
484
+ ugroups <- unique(markers[[groupname]])
485
+ m <- lapply(ugroups, function(g) {
486
+ markers[markers[[groupname]] == g, , drop = FALSE] %>%
487
+ filter(!!parse_expr(sigm)) %>%
488
+ pull("gene") %>% unique()
489
+ })
490
+ names(m) <- ugroups
491
+
492
+ if (plot_type == "venn") {
493
+ args$data <- m
494
+ args$in_form <- "list"
495
+ prefix <- file.path(info$prefix, slugify(plotname))
496
+ p <- do_call(gglogger::register(VennDiagram), args)
497
+ save_plot(p, prefix, devpars, formats = c("png", more_formats))
498
+ if (save_code) {
499
+ save_plotcode(
500
+ p, prefix,
501
+ c("library(plotthis)", "load('data.RData')", "invisible(list2env(args, .GlobalEnv))"),
502
+ "args",
503
+ auto_data_setup = FALSE
504
+ )
505
+ }
506
+ } else {
507
+ args$data <- m
508
+ args$in_form <- "list"
509
+ prefix <- file.path(info$prefix, slugify(plotname))
510
+ p <- do_call(gglogger::register(UpsetPlot), args)
511
+ save_plot(p, prefix, devpars, formats = c("png", more_formats))
512
+ if (save_code) {
513
+ save_plotcode(
514
+ p, prefix,
515
+ c("library(plotthis)", "load('data.RData')", "invisible(list2env(args, .GlobalEnv))"),
516
+ "args",
517
+ auto_data_setup = FALSE
518
+ )
519
+ }
520
+ }
521
+
522
+ reporter$add2(
523
+ list(
524
+ name = plotname,
525
+ contents = list(reporter$image(prefix, more_formats, save_code))
526
+ ),
527
+ hs = c(info$section, info$name),
528
+ ui = "tabs"
529
+ )
530
+ }
531
+ }
532
+
533
+ run_case <- function(name) {
534
+ case <- cases[[name]]
535
+ log$info("----------------------------------------")
536
+ log$info("Case: {name} ...")
537
+
538
+ case <- extract_vars(
539
+ case,
540
+ "dbs", "sigmarkers", "allmarker_plots", "allenrich_plots", "marker_plots", "enrich_plots",
541
+ "overlaps", "original_case", "markers", "enriches", "each_name", "each", "enrich_style",
542
+ "aggregate_by", "subset", "layer", "assay", "group_by", "ident_1", "ident_2", "original_subset",
543
+ "paired_by", "tool", "error", "ncores", "cache", "allexprs",
544
+ allow_nonexisting = TRUE
545
+ )
546
+
547
+ if (!is.null(markers) || !is.null(enriches)) {
548
+ if (!is.null(markers) && length(markers) > 0) {
549
+ log$info("Summarizing DEGs in subcases (by each: {each}) ...")
550
+ # handle the overlaps / allmarkers analysis here
551
+ if (!is.data.frame(markers)) {
552
+ each_levels <- names(markers)
553
+ markers <- do_call(rbind, lapply(each_levels, function(x) {
554
+ markers_df <- markers[[x]]
555
+ if (is.null(markers_df) || nrow(markers_df) == 0) {
556
+ return(NULL)
557
+ }
558
+ if (nrow(markers_df) > 0) {
559
+ markers_df[[each]] <- x
560
+ } else {
561
+ markers_df[[each]] <- character(0) # Empty case
562
+ }
563
+ markers_df
564
+ }))
565
+ markers[[each]] <- factor(markers[[each]], levels = each_levels)
566
+ }
567
+ # gene, p_val, avg_log2FC, pct.1, pct.2, p_val_adj, diff_pct, <each>
568
+
569
+ if (!is.data.frame(allexprs)) {
570
+ meta <- do_call(rbind, lapply(allexprs, attr, "meta"))
571
+ allexprs <- do_call(cbind, allexprs)
572
+ } else {
573
+ meta <- attr(allexprs, "meta")
574
+ }
575
+
576
+ if (length(allmarker_plots) > 0) {
577
+ log$info("Visualizing all DEGs together ...")
578
+ attr(markers, "object") <- allexprs
579
+ attr(markers, "meta") <- meta
580
+ attr(markers, "group_by") <- each
581
+ attr(markers, "paired_by") <- paired_by
582
+ attr(markers, "ident_1") <- NULL
583
+ attr(markers, "ident_2") <- NULL
584
+ process_allmarkers(markers, allmarker_plots, name, each)
585
+ }
586
+
587
+ if (length(overlaps) > 0) {
588
+ log$info("Visualizing overlaps between subcases ...")
589
+ process_overlaps(markers, overlaps, name, each)
590
+ }
591
+
592
+ }
593
+
594
+ if (!is.null(enriches) && length(enriches) > 0) {
595
+ log$info("Summarizing enrichments in subcases (by each: {each}) ...")
596
+ if (!is.data.frame(enriches)) {
597
+ each_levels <- names(enriches)
598
+ enriches <- do_call(rbind, lapply(each_levels, function(x) {
599
+ enrich_df <- enriches[[x]]
600
+ if (is.null(enrich_df) || nrow(enrich_df) == 0) {
601
+ return(NULL)
602
+ }
603
+ if (nrow(enrich_df) > 0) {
604
+ enrich_df[[each]] <- x
605
+ } else {
606
+ enrich_df[[each]] <- character(0) # Empty case
607
+ }
608
+ enrich_df
609
+ }))
610
+ if (!is.null(enriches) && nrow(enriches) > 0) {
611
+ enriches[[each]] <- factor(enriches[[each]], levels = each_levels)
612
+ }
613
+ }
614
+
615
+ if (length(allenrich_plots) > 0 && !is.null(enriches) && nrow(enriches) > 0) {
616
+ log$info("Visualizing all enrichments together ...")
617
+ process_allenriches(enriches, allenrich_plots, name, each)
618
+ }
619
+ }
620
+
621
+ return(invisible())
622
+ }
623
+
624
+ info <- case_info(name, outdir, create = TRUE)
625
+ exprs <- AggregateExpressionPseudobulk(
626
+ srtobj, aggregate_by = aggregate_by, layer = layer, assay = assay,
627
+ subset = subset, log = log
628
+ )
629
+ markers <- tryCatch(
630
+ {
631
+ RunDEGAnalysis(
632
+ exprs, group_by = group_by, ident_1 = ident_1, ident_2 = ident_2,
633
+ paired_by = paired_by, tool = tool, log = log, ncores = ncores,
634
+ cache = cache
635
+ )
636
+ }, error = function(e) {
637
+ if (error) {
638
+ stop("Error: ", e$message)
639
+ } else {
640
+ log$warn("! Error: {e$message}")
641
+ reporter$add2(
642
+ list(
643
+ name = "Warning",
644
+ contents = list(list(kind = "error", content = e$message, kind_ = "warning"))),
645
+ hs = c(info$section, info$name),
646
+ hs2 = "DEG Analysis",
647
+ ui = "tabs"
648
+ )
649
+ return(invisible())
650
+ }
651
+ }
652
+ )
653
+
654
+ enrich <- process_markers(markers, info = info, case = list(
655
+ dbs = dbs,
656
+ sigmarkers = sigmarkers,
657
+ enrich_style = enrich_style,
658
+ marker_plots = marker_plots,
659
+ enrich_plots = enrich_plots,
660
+ error = error,
661
+ ident = if (is.null(case$ident_2)) case$ident_1 else paste0(case$ident_1, " vs ", case$ident_2)
662
+ ))
663
+
664
+ if (!is.null(original_case) && !is.null(cases[[original_case]])) {
665
+ if (!is.null(markers)) {
666
+ markers[[each_name]] <- each
667
+ }
668
+ cases[[original_case]]$markers[[each]] <<- markers
669
+ cases[[original_case]]$enriches[[each]] <<- enrich
670
+ cases[[original_case]]$allexprs[[each]] <<- exprs
671
+ }
672
+
673
+ invisible()
674
+ }
675
+
676
+ sapply(names(cases), run_case)
677
+
678
+ reporter$save(joboutdir)