biopipen 0.21.2__py3-none-any.whl → 0.22.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of biopipen might be problematic. Click here for more details.
- biopipen/__init__.py +1 -1
- biopipen/core/filters.py +142 -0
- biopipen/ns/scrna.py +19 -1
- biopipen/ns/tcr.py +30 -10
- biopipen/reports/delim/SampleInfo.svelte +2 -22
- biopipen/reports/scrna/CellsDistribution.svelte +4 -39
- biopipen/reports/scrna/MarkersFinder.svelte +6 -126
- biopipen/reports/scrna/MetaMarkers.svelte +3 -75
- biopipen/reports/scrna/RadarPlots.svelte +4 -20
- biopipen/reports/scrna/ScFGSEA.svelte +4 -23
- biopipen/reports/scrna/SeuratClusterStats.svelte +3 -69
- biopipen/reports/scrna/SeuratPreparing.svelte +3 -26
- biopipen/reports/scrna/TopExpressingGenes.svelte +3 -41
- biopipen/reports/scrna_metabolic_landscape/MetabolicFeatures.svelte +17 -16
- biopipen/reports/scrna_metabolic_landscape/MetabolicFeaturesIntraSubset.svelte +13 -16
- biopipen/reports/scrna_metabolic_landscape/MetabolicPathwayActivity.svelte +44 -52
- biopipen/reports/scrna_metabolic_landscape/MetabolicPathwayHeterogeneity.svelte +2 -8
- biopipen/reports/tcr/CDR3AAPhyschem.svelte +18 -65
- biopipen/reports/tcr/CloneResidency.svelte +3 -93
- biopipen/reports/tcr/Immunarch.svelte +4 -168
- biopipen/reports/tcr/TCRClusterStats.svelte +3 -45
- biopipen/reports/tcr/TESSA.svelte +11 -28
- biopipen/scripts/delim/SampleInfo.R +41 -7
- biopipen/scripts/scrna/CellsDistribution.R +127 -16
- biopipen/scripts/scrna/MarkersFinder.R +245 -100
- biopipen/scripts/scrna/MetaMarkers.R +163 -82
- biopipen/scripts/scrna/RadarPlots.R +163 -110
- biopipen/scripts/scrna/ScFGSEA.R +51 -11
- biopipen/scripts/scrna/SeuratClusterStats-dimplots.R +26 -13
- biopipen/scripts/scrna/SeuratClusterStats-features.R +58 -53
- biopipen/scripts/scrna/SeuratClusterStats-stats.R +39 -21
- biopipen/scripts/scrna/SeuratClusterStats.R +4 -2
- biopipen/scripts/scrna/SeuratClustering.R +73 -26
- biopipen/scripts/scrna/SeuratMetadataMutater.R +13 -1
- biopipen/scripts/scrna/SeuratPreparing.R +93 -19
- biopipen/scripts/scrna/TopExpressingGenes.R +100 -18
- biopipen/scripts/scrna_metabolic_landscape/MetabolicFeatures.R +21 -8
- biopipen/scripts/scrna_metabolic_landscape/MetabolicFeaturesIntraSubset.R +25 -3
- biopipen/scripts/scrna_metabolic_landscape/MetabolicPathwayActivity.R +1 -0
- biopipen/scripts/scrna_metabolic_landscape/MetabolicPathwayHeterogeneity.R +14 -3
- biopipen/scripts/tcr/Attach2Seurat.R +2 -1
- biopipen/scripts/tcr/CDR3AAPhyschem.R +123 -10
- biopipen/scripts/tcr/CloneResidency.R +114 -34
- biopipen/scripts/tcr/Immunarch-basic.R +18 -4
- biopipen/scripts/tcr/Immunarch-clonality.R +14 -0
- biopipen/scripts/tcr/Immunarch-diversity.R +123 -18
- biopipen/scripts/tcr/Immunarch-geneusage.R +23 -1
- biopipen/scripts/tcr/Immunarch-kmer.R +45 -3
- biopipen/scripts/tcr/Immunarch-overlap.R +62 -0
- biopipen/scripts/tcr/Immunarch-spectratyping.R +18 -2
- biopipen/scripts/tcr/Immunarch-tracking.R +24 -1
- biopipen/scripts/tcr/Immunarch-vjjunc.R +17 -2
- biopipen/scripts/tcr/Immunarch.R +7 -0
- biopipen/scripts/tcr/ImmunarchLoading.R +22 -23
- biopipen/scripts/tcr/TCRClusterStats.R +124 -11
- biopipen/scripts/tcr/TCRClustering.R +8 -9
- biopipen/scripts/tcr/TESSA.R +66 -41
- biopipen/utils/misc.R +96 -1
- {biopipen-0.21.2.dist-info → biopipen-0.22.1.dist-info}/METADATA +1 -1
- {biopipen-0.21.2.dist-info → biopipen-0.22.1.dist-info}/RECORD +62 -62
- {biopipen-0.21.2.dist-info → biopipen-0.22.1.dist-info}/WHEEL +0 -0
- {biopipen-0.21.2.dist-info → biopipen-0.22.1.dist-info}/entry_points.txt +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
source("{{biopipen_dir}}/utils/misc.R")
|
|
1
2
|
library(dplyr)
|
|
2
3
|
library(tidyr)
|
|
3
4
|
library(tibble)
|
|
@@ -8,10 +9,12 @@ library(hash)
|
|
|
8
9
|
library(glmnet)
|
|
9
10
|
library(broom.mixed)
|
|
10
11
|
library(stringr)
|
|
12
|
+
library(slugify)
|
|
11
13
|
|
|
12
14
|
immdatafile = {{in.immdata | quote}}
|
|
13
15
|
srtobjfile = {{in.srtobj | r}}
|
|
14
16
|
outdir = {{out.outdir | quote}}
|
|
17
|
+
joboutdir = {{job.outdir | quote}}
|
|
15
18
|
group_name = {{envs.group | r}}
|
|
16
19
|
comparison = {{envs.comparison | r}}
|
|
17
20
|
prefix = {{envs.prefix | r}}
|
|
@@ -141,7 +144,7 @@ for (i in 1:3){
|
|
|
141
144
|
}
|
|
142
145
|
|
|
143
146
|
# Loading metadata from srtobjfile
|
|
144
|
-
|
|
147
|
+
log_info("Loading metadata from srtobjfile")
|
|
145
148
|
if (is.null(srtobjfile)) {
|
|
146
149
|
metadata = NULL
|
|
147
150
|
} else {
|
|
@@ -161,7 +164,7 @@ if (is.null(srtobjfile)) {
|
|
|
161
164
|
}
|
|
162
165
|
}
|
|
163
166
|
|
|
164
|
-
|
|
167
|
+
log_info("Loading immdata from immdatafile")
|
|
165
168
|
immdata = readRDS(immdatafile)
|
|
166
169
|
|
|
167
170
|
|
|
@@ -190,7 +193,7 @@ merge_data = function(sam) {
|
|
|
190
193
|
if (!is.null(prefix) && nchar(prefix) > 0) {
|
|
191
194
|
# Replace the placeholder like {Sample} with the data in other columns
|
|
192
195
|
# in the same row
|
|
193
|
-
sdata = sdata %>% mutate(.prefix_len = nchar(glue(
|
|
196
|
+
sdata = sdata %>% mutate(.prefix_len = nchar(glue(prefix)))
|
|
194
197
|
# Remove the prefix in the rownames of sdata
|
|
195
198
|
rownames(sdata) = substring(rownames(sdata), sdata$.prefix_len + 1)
|
|
196
199
|
sdata = sdata %>% select(-.prefix_len)
|
|
@@ -215,17 +218,17 @@ merge_data = function(sam) {
|
|
|
215
218
|
|
|
216
219
|
# Expanded and merged with metadata
|
|
217
220
|
# Now we are able to select the cells using group and comparison
|
|
218
|
-
|
|
221
|
+
log_info("Merging data with metadata for each sample")
|
|
219
222
|
merged = NULL
|
|
220
223
|
for (sam in immdata$meta$Sample) {
|
|
221
|
-
|
|
224
|
+
log_info("- For sample {sam}")
|
|
222
225
|
md = merge_data(sam)
|
|
223
226
|
merged = if (is.null(merged)) md else rbind(merged, md)
|
|
224
227
|
}
|
|
225
228
|
|
|
226
229
|
# Statistics about the cell numbers with groups avaiable in metadata
|
|
227
230
|
# !!group_name, TotalCells, AvailCells, AvailCellsPct
|
|
228
|
-
|
|
231
|
+
log_info("Calculating statistics")
|
|
229
232
|
if (is.null(subset_cols)) {
|
|
230
233
|
stats = merged %>%
|
|
231
234
|
# group by group_name
|
|
@@ -259,9 +262,45 @@ if (is.null(subset_cols)) {
|
|
|
259
262
|
}
|
|
260
263
|
|
|
261
264
|
# save the stats
|
|
262
|
-
write.table(
|
|
265
|
+
write.table(
|
|
266
|
+
stats,
|
|
267
|
+
file = file.path(outdir, "stats.txt"),
|
|
268
|
+
sep = "\t",
|
|
269
|
+
quote = FALSE,
|
|
270
|
+
row.names = FALSE,
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
add_report(
|
|
274
|
+
list(
|
|
275
|
+
kind = "descr",
|
|
276
|
+
content = "Statistics about the cells mapped to the comparison groups. Columns:"
|
|
277
|
+
),
|
|
278
|
+
list(
|
|
279
|
+
kind = "list",
|
|
280
|
+
items = c(
|
|
281
|
+
"_Group: The group name in the comparison, or null, if cells are not mapped to any group",
|
|
282
|
+
"TotalCells: The total number of cells. This number should be the same for all groups",
|
|
283
|
+
"CellsPerGroup: The number of cells in the mapped group",
|
|
284
|
+
paste0(
|
|
285
|
+
"AvailCellsPerGroup: The number of cells with CDR3 length between ",
|
|
286
|
+
CDR3_MINLEN,
|
|
287
|
+
" and ",
|
|
288
|
+
CDR3_MAXLEN,
|
|
289
|
+
" for each group. These cells are used for the analysis"
|
|
290
|
+
),
|
|
291
|
+
"AvailCellsPct: The percentage of AvailCellsPerGroup over CellsPerGroup"
|
|
292
|
+
)
|
|
293
|
+
),
|
|
294
|
+
list(
|
|
295
|
+
kind = "table",
|
|
296
|
+
src = file.path(outdir, "stats.txt")
|
|
297
|
+
),
|
|
298
|
+
h1 = "Available Cells"
|
|
299
|
+
)
|
|
263
300
|
|
|
264
|
-
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
log_info("Add amino acid features")
|
|
265
304
|
merged = merged %>%
|
|
266
305
|
filter(!is.na(.Group) & length >= CDR3_MINLEN & length <= CDR3_MAXLEN) %>%
|
|
267
306
|
add_percentAA() %>%
|
|
@@ -269,13 +308,13 @@ merged = merged %>%
|
|
|
269
308
|
|
|
270
309
|
|
|
271
310
|
do_one_subset = function(s) {
|
|
272
|
-
|
|
311
|
+
log_info(paste("Processing subset", s))
|
|
273
312
|
if (is.null(s)) {
|
|
274
313
|
data = merged
|
|
275
314
|
odir = file.path(outdir, "ALL")
|
|
276
315
|
} else {
|
|
277
316
|
data = merged %>% filter(.Subset == s)
|
|
278
|
-
odir = file.path(outdir, s)
|
|
317
|
+
odir = file.path(outdir, slugify(s))
|
|
279
318
|
}
|
|
280
319
|
dir.create(odir, recursive = TRUE, showWarnings = FALSE)
|
|
281
320
|
|
|
@@ -342,6 +381,55 @@ do_one_subset = function(s) {
|
|
|
342
381
|
print(g)
|
|
343
382
|
dev.off()
|
|
344
383
|
|
|
384
|
+
add_report(
|
|
385
|
+
list(
|
|
386
|
+
kind = "descr",
|
|
387
|
+
content = "Estimated coefficients for each feature and position in the CDR3"
|
|
388
|
+
),
|
|
389
|
+
h1 = ifelse(
|
|
390
|
+
is.null(s),
|
|
391
|
+
"Estimated OR (per s.d.)",
|
|
392
|
+
paste0(paste(subset_cols, collapse = ", "), " - ", s)
|
|
393
|
+
),
|
|
394
|
+
h2 = ifelse(
|
|
395
|
+
is.null(s),
|
|
396
|
+
"#",
|
|
397
|
+
"Estimated OR (per s.d.)"
|
|
398
|
+
)
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
add_report(
|
|
402
|
+
list(
|
|
403
|
+
name = "Plot",
|
|
404
|
+
contents = list(
|
|
405
|
+
list(
|
|
406
|
+
kind = "image",
|
|
407
|
+
src = file.path(odir, "estimated_coefficients.png")
|
|
408
|
+
)
|
|
409
|
+
)
|
|
410
|
+
),
|
|
411
|
+
list(
|
|
412
|
+
name = "Estimates",
|
|
413
|
+
contents = list(
|
|
414
|
+
list(
|
|
415
|
+
kind = "table",
|
|
416
|
+
src = file.path(odir, "estimates.txt")
|
|
417
|
+
)
|
|
418
|
+
)
|
|
419
|
+
),
|
|
420
|
+
h1 = ifelse(
|
|
421
|
+
is.null(s),
|
|
422
|
+
"Estimated OR (per s.d.)",
|
|
423
|
+
paste0(paste(subset_cols, collapse = ", "), " - ", s)
|
|
424
|
+
),
|
|
425
|
+
h2 = ifelse(
|
|
426
|
+
is.null(s),
|
|
427
|
+
"#",
|
|
428
|
+
"Estimated OR (per s.d.)"
|
|
429
|
+
),
|
|
430
|
+
ui = "tabs"
|
|
431
|
+
)
|
|
432
|
+
|
|
345
433
|
# distributions
|
|
346
434
|
data$mid_hydro = sapply(data$midseq, function(x) get_feat_score(x, AA_MAPS[[2]]))
|
|
347
435
|
data$smid_hydro = scale(data$mid_hydro)[,1]
|
|
@@ -372,6 +460,29 @@ do_one_subset = function(s) {
|
|
|
372
460
|
png(file.path(odir, "distribution.png"), width=1000, height=1000, res=100)
|
|
373
461
|
print(g)
|
|
374
462
|
dev.off()
|
|
463
|
+
|
|
464
|
+
add_report(
|
|
465
|
+
list(
|
|
466
|
+
kind = "table_image",
|
|
467
|
+
descr = paste0(
|
|
468
|
+
"Hydrophobicity values are averaged over the CDR3 for each TCR and ",
|
|
469
|
+
"then scaled to have a mean of 0 and a variance of 1. ",
|
|
470
|
+
"Horizontal lines depict the mean for each population"
|
|
471
|
+
),
|
|
472
|
+
src = file.path(odir, "distribution.png")
|
|
473
|
+
),
|
|
474
|
+
h1 = ifelse(
|
|
475
|
+
is.null(s),
|
|
476
|
+
"Hydrophobicity Distribution",
|
|
477
|
+
paste0(paste(subset_cols, collapse = ", "), " - ", s)
|
|
478
|
+
),
|
|
479
|
+
h2 = ifelse(
|
|
480
|
+
is.null(s),
|
|
481
|
+
"#",
|
|
482
|
+
"Hydrophobicity Distribution"
|
|
483
|
+
)
|
|
484
|
+
)
|
|
485
|
+
|
|
375
486
|
}
|
|
376
487
|
|
|
377
488
|
if (is.null(subset_cols)) {
|
|
@@ -380,3 +491,5 @@ if (is.null(subset_cols)) {
|
|
|
380
491
|
subsets = na.omit(unique(merged$.Subset))
|
|
381
492
|
sapply(subsets, do_one_subset)
|
|
382
493
|
}
|
|
494
|
+
|
|
495
|
+
save_report(joboutdir)
|
|
@@ -10,6 +10,7 @@ library(ggplot2)
|
|
|
10
10
|
library(ggprism)
|
|
11
11
|
library(ggVennDiagram)
|
|
12
12
|
library(UpSetR)
|
|
13
|
+
library(slugify)
|
|
13
14
|
|
|
14
15
|
theme_set(theme_prism())
|
|
15
16
|
|
|
@@ -17,6 +18,7 @@ theme_set(theme_prism())
|
|
|
17
18
|
immfile <- {{ in.immdata | quote }}
|
|
18
19
|
metafile <- {{ in.metafile | r }}
|
|
19
20
|
outdir <- {{ out.outdir | quote }}
|
|
21
|
+
joboutdir <- {{ job.outdir | quote }}
|
|
20
22
|
|
|
21
23
|
subject_key <- {{ envs.subject | r }}
|
|
22
24
|
group_key <- {{ envs.group | r }}
|
|
@@ -29,7 +31,7 @@ cases <- {{ envs.cases | r }}
|
|
|
29
31
|
|
|
30
32
|
# Fill up cases using `envs.xxx` if not provided and compose a DEFAULT case
|
|
31
33
|
# if no cases are provided
|
|
32
|
-
|
|
34
|
+
log_info("Preparing cases...")
|
|
33
35
|
if (is.null(cases) || length(cases) == 0) {
|
|
34
36
|
cases <- list(
|
|
35
37
|
DEFAULT = list(
|
|
@@ -60,11 +62,11 @@ if (is.null(cases) || length(cases) == 0) {
|
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
64
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
log_info("Preparing data ...")
|
|
66
|
+
log_info("- Loading immdata ...")
|
|
65
67
|
immdata <- readRDS(immfile)
|
|
66
68
|
|
|
67
|
-
|
|
69
|
+
log_info("- Expanding immdata$data to cell-level ...")
|
|
68
70
|
cldata <- do_call(rbind, lapply(names(immdata$data), function(name) {
|
|
69
71
|
dat <- immdata$data[[name]] %>% separate_rows(Barcode, sep = ";") # Split barcodes
|
|
70
72
|
dat$Sample <- name
|
|
@@ -76,7 +78,7 @@ cldata <- do_call(rbind, lapply(names(immdata$data), function(name) {
|
|
|
76
78
|
}))
|
|
77
79
|
|
|
78
80
|
if (!is.null(metafile)) {
|
|
79
|
-
|
|
81
|
+
log_info("- Loading metafile ...")
|
|
80
82
|
# Check if extension is rds/RDS, if so, it should be a Seurat object
|
|
81
83
|
if (endsWith(metafile, ".rds") || endsWith(metafile, ".RDS")) {
|
|
82
84
|
meta <- readRDS(metafile)@meta.data
|
|
@@ -86,14 +88,14 @@ if (!is.null(metafile)) {
|
|
|
86
88
|
)
|
|
87
89
|
}
|
|
88
90
|
|
|
89
|
-
|
|
91
|
+
log_info("- Merging metafile to cldata ...")
|
|
90
92
|
cldata <- cbind(
|
|
91
93
|
cldata,
|
|
92
94
|
meta[cldata$Barcode, setdiff(colnames(meta), colnames(cldata)), drop = FALSE]
|
|
93
95
|
)
|
|
94
96
|
}
|
|
95
97
|
|
|
96
|
-
|
|
98
|
+
log_info("Applying mutaters ...")
|
|
97
99
|
if (!is.null(mutaters) && length(mutaters) > 0) {
|
|
98
100
|
cldata <- cldata %>% mutate(!!!lapply(mutaters, parse_expr))
|
|
99
101
|
}
|
|
@@ -115,7 +117,7 @@ get_groups <- function(order) {
|
|
|
115
117
|
}
|
|
116
118
|
|
|
117
119
|
perpare_case <- function(casename, case) {
|
|
118
|
-
|
|
120
|
+
log_info("Preparing case: {casename} ...")
|
|
119
121
|
# Check if required keys are provided
|
|
120
122
|
if (is.null(case$subject) || length(case$subject) == 0) {
|
|
121
123
|
stop(paste("`subject` is required for case:", casename))
|
|
@@ -133,13 +135,12 @@ perpare_case <- function(casename, case) {
|
|
|
133
135
|
))
|
|
134
136
|
} else if (!any(has_comma)) {
|
|
135
137
|
if (length(case$order) > 2) {
|
|
136
|
-
|
|
138
|
+
log_warn(
|
|
137
139
|
paste0(
|
|
138
140
|
"- Order of groups in case:", casename,
|
|
139
141
|
" is not recommended, please use comma to separate groups. \n",
|
|
140
142
|
"Instead of `['A', 'B', 'C']`, use `['A,B', 'A,C', 'B,C']`."
|
|
141
|
-
)
|
|
142
|
-
immediate. = TRUE
|
|
143
|
+
)
|
|
143
144
|
)
|
|
144
145
|
case$order <- sapply(
|
|
145
146
|
combn(case$order, 2, simplify = FALSE),
|
|
@@ -162,19 +163,19 @@ perpare_case <- function(casename, case) {
|
|
|
162
163
|
|
|
163
164
|
# Create case-specific directories
|
|
164
165
|
# Scatter plots
|
|
165
|
-
scatter_dir <- file.path(outdir, casename, "scatter")
|
|
166
|
+
scatter_dir <- file.path(outdir, slugify(casename, tolower = FALSE), "scatter")
|
|
166
167
|
dir.create(scatter_dir, recursive = TRUE, showWarnings = FALSE)
|
|
167
168
|
|
|
168
169
|
# Venn diagrams
|
|
169
|
-
venn_dir <- file.path(outdir, casename, "venn")
|
|
170
|
+
venn_dir <- file.path(outdir, slugify(casename, tolower = FALSE), "venn")
|
|
170
171
|
dir.create(venn_dir, recursive = TRUE, showWarnings = FALSE)
|
|
171
172
|
|
|
172
173
|
# Upset plots
|
|
173
|
-
upset_dir <- file.path(outdir, casename, "upset")
|
|
174
|
+
upset_dir <- file.path(outdir, slugify(casename, tolower = FALSE), "upset")
|
|
174
175
|
dir.create(upset_dir, recursive = TRUE, showWarnings = FALSE)
|
|
175
176
|
|
|
176
177
|
# Counts
|
|
177
|
-
counts_dir <- file.path(outdir, casename, "counts")
|
|
178
|
+
counts_dir <- file.path(outdir, slugify(casename, tolower = FALSE), "counts")
|
|
178
179
|
dir.create(counts_dir, recursive = TRUE, showWarnings = FALSE)
|
|
179
180
|
|
|
180
181
|
case
|
|
@@ -376,6 +377,7 @@ plot_upset <- function(counts, singletons) {
|
|
|
376
377
|
}
|
|
377
378
|
|
|
378
379
|
handle_subject <- function(i, subjects, casename, case) {
|
|
380
|
+
casedir = file.path(outdir, slugify(casename, tolower = FALSE))
|
|
379
381
|
# Generate a residency table
|
|
380
382
|
# | CDR3.aa | Tumor | Normal |
|
|
381
383
|
# | SEABESRWEFAEF | 0 | 10 |
|
|
@@ -387,7 +389,7 @@ handle_subject <- function(i, subjects, casename, case) {
|
|
|
387
389
|
as.character() %>%
|
|
388
390
|
paste(collapse = "-")
|
|
389
391
|
|
|
390
|
-
|
|
392
|
+
log_info("Handling {i} {case$subject} ...")
|
|
391
393
|
|
|
392
394
|
if (!is.null(case$subset)) {
|
|
393
395
|
counts <- cldata %>% filter(!!parse_expr(case$subset))
|
|
@@ -412,10 +414,7 @@ handle_subject <- function(i, subjects, casename, case) {
|
|
|
412
414
|
case$order <- sapply(combn(groups, 2, simplify = FALSE), function(x) paste(x, collapse = ","))
|
|
413
415
|
}
|
|
414
416
|
if (length(unique(counts[[case$group]])) < 2) {
|
|
415
|
-
|
|
416
|
-
paste0("-", casename, ", Subject doesn't have enough groups:", subject),
|
|
417
|
-
immediate. = TRUE
|
|
418
|
-
)
|
|
417
|
+
log_warn("{casename}, Subject doesn't have enough groups: {subject}")
|
|
419
418
|
return()
|
|
420
419
|
}
|
|
421
420
|
singletons = counts %>%
|
|
@@ -437,7 +436,7 @@ handle_subject <- function(i, subjects, casename, case) {
|
|
|
437
436
|
|
|
438
437
|
# Save samples to group_by so they can be aligned accordingly in the report
|
|
439
438
|
if (!is.null(section)) {
|
|
440
|
-
group_dir <- file.path(
|
|
439
|
+
group_dir <- file.path(casedir, "section")
|
|
441
440
|
dir.create(group_dir, showWarnings = FALSE)
|
|
442
441
|
|
|
443
442
|
sgroups <- subject_row %>%
|
|
@@ -445,60 +444,90 @@ handle_subject <- function(i, subjects, casename, case) {
|
|
|
445
444
|
pull(section) %>%
|
|
446
445
|
unique() %>%
|
|
447
446
|
paste(collapse = "-")
|
|
448
|
-
group_file <- file.path(group_dir, paste0(sgroups, ".txt"))
|
|
447
|
+
group_file <- file.path(group_dir, paste0(slugify(sgroups), ".txt"))
|
|
449
448
|
cat(subject, file = group_file, sep = "\n", append = TRUE)
|
|
450
449
|
}
|
|
451
450
|
|
|
452
451
|
# Save counts
|
|
453
|
-
counts_dir <- file.path(
|
|
452
|
+
counts_dir <- file.path(casedir, "counts")
|
|
453
|
+
countfile <- file.path(counts_dir, paste0(slugify(subject), ".txt"))
|
|
454
454
|
write.table(
|
|
455
455
|
counts,
|
|
456
|
-
file =
|
|
456
|
+
file = countfile,
|
|
457
457
|
sep = "\t",
|
|
458
458
|
row.names = TRUE,
|
|
459
459
|
col.names = TRUE,
|
|
460
460
|
quote = FALSE
|
|
461
461
|
)
|
|
462
|
+
add_report(
|
|
463
|
+
list(kind = "table", src = countfile, ds_name = subject),
|
|
464
|
+
h1 = ifelse(casename == "DEFAULT", "Clone Size Tables", casename),
|
|
465
|
+
h2 = ifelse(casename == "DEFAULT", "#", "Clone size Tables"),
|
|
466
|
+
ui = "dropdown_switcher"
|
|
467
|
+
)
|
|
462
468
|
|
|
463
469
|
# scatter plot
|
|
464
470
|
# Make plots B ~ A, C ~ B, and C ~ A for order A, B, C
|
|
465
471
|
# combns <- combn(groups, 2, simplify = FALSE)
|
|
466
|
-
scatter_dir <- file.path(
|
|
472
|
+
scatter_dir <- file.path(casedir, "scatter")
|
|
467
473
|
for (j in seq_along(case$order)) {
|
|
468
474
|
pair <- strsplit(case$order[j], ",")[[1]]
|
|
469
475
|
if (length(setdiff(pair, groups)) > 0) {
|
|
470
|
-
|
|
476
|
+
log_warn(
|
|
471
477
|
paste0(
|
|
472
478
|
"- One of the comparisons doesn't exist in case (", casename,
|
|
473
479
|
") for subject (", subject, "): ",
|
|
474
480
|
case$order[j]
|
|
475
|
-
)
|
|
476
|
-
immediate. = TRUE
|
|
481
|
+
)
|
|
477
482
|
)
|
|
478
483
|
next
|
|
479
484
|
}
|
|
480
485
|
scatter_p <- plot_scatter(counts, subject, pair[1], pair[2])
|
|
481
486
|
scatter_png <- file.path(
|
|
482
487
|
scatter_dir,
|
|
483
|
-
paste0("scatter_", subject, "_", pair[1], "_", pair[2], ".png")
|
|
488
|
+
paste0("scatter_", slugify(subject), "_", slugify(pair[1]), "_", slugify(pair[2]), ".png")
|
|
484
489
|
)
|
|
485
490
|
png(scatter_png, res = 100, height = 800, width = 1000)
|
|
486
491
|
print(scatter_p)
|
|
487
492
|
dev.off()
|
|
493
|
+
|
|
494
|
+
add_report(
|
|
495
|
+
list(
|
|
496
|
+
name = paste0(subject, " (", pair[1], " - ", pair[2], ")"),
|
|
497
|
+
src = scatter_png
|
|
498
|
+
),
|
|
499
|
+
h1 = ifelse(casename == "DEFAULT", "Residency Plots", casename),
|
|
500
|
+
h2 = ifelse(casename == "DEFAULT", "#", "Residency Plots"),
|
|
501
|
+
ui = "table_of_images:3"
|
|
502
|
+
)
|
|
488
503
|
}
|
|
489
504
|
|
|
490
505
|
# upset/venn
|
|
491
|
-
venn_dir <- file.path(
|
|
492
|
-
venn_png <- file.path(venn_dir, paste0("venn_", subject, ".png"))
|
|
506
|
+
venn_dir <- file.path(casedir, "venn")
|
|
507
|
+
venn_png <- file.path(venn_dir, paste0("venn_", slugify(subject), ".png"))
|
|
493
508
|
png(venn_png, res = 100, height = 600, width = 800)
|
|
494
509
|
print(plot_venndg(counts, groups, singletons))
|
|
495
510
|
dev.off()
|
|
496
511
|
|
|
497
|
-
|
|
498
|
-
|
|
512
|
+
add_report(
|
|
513
|
+
list(src = venn_png),
|
|
514
|
+
h1 = ifelse(casename == "DEFAULT", "Overlapping Clones (Venn Diagram)", casename),
|
|
515
|
+
h2 = ifelse(casename == "DEFAULT", "#", "Overlapping Clones (Venn Diagram)"),
|
|
516
|
+
ui = "table_of_images:3"
|
|
517
|
+
)
|
|
518
|
+
|
|
519
|
+
upset_dir <- file.path(casedir, "upset")
|
|
520
|
+
upset_png <- file.path(upset_dir, paste0("upset_", slugify(subject), ".png"))
|
|
499
521
|
png(upset_png, res = 100, height = 600, width = 800)
|
|
500
522
|
print(plot_upset(counts, singletons))
|
|
501
523
|
dev.off()
|
|
524
|
+
|
|
525
|
+
add_report(
|
|
526
|
+
list(src = upset_png),
|
|
527
|
+
h1 = ifelse(casename == "DEFAULT", "Overlapping Clones (UpSet Plots)", casename),
|
|
528
|
+
h2 = ifelse(casename == "DEFAULT", "#", "Overlapping Clones (UpSet Plots)"),
|
|
529
|
+
ui = "table_of_images:3"
|
|
530
|
+
)
|
|
502
531
|
}
|
|
503
532
|
|
|
504
533
|
handle_case <- function(casename, case) {
|
|
@@ -513,9 +542,60 @@ handle_case <- function(casename, case) {
|
|
|
513
542
|
distinct(!!!syms(case$subject)) %>%
|
|
514
543
|
drop_na()
|
|
515
544
|
}
|
|
545
|
+
add_report(
|
|
546
|
+
list(ds_name = "Select a subject ..."),
|
|
547
|
+
h1 = ifelse(casename == "DEFAULT", "Clone Size Tables", casename),
|
|
548
|
+
h2 = ifelse(casename == "DEFAULT", "#", "Clone size Tables"),
|
|
549
|
+
ui = "dropdown_switcher"
|
|
550
|
+
)
|
|
551
|
+
add_report(
|
|
552
|
+
list(
|
|
553
|
+
kind = "descr",
|
|
554
|
+
content = paste0(
|
|
555
|
+
"The residency plots showing the clones of paired samples (x-axis and y-axis). ",
|
|
556
|
+
"The size of the dot represents the relative abundance of the clone. ",
|
|
557
|
+
"The color of the dot represents the type of the clone: "
|
|
558
|
+
)
|
|
559
|
+
),
|
|
560
|
+
list(
|
|
561
|
+
kind = "list",
|
|
562
|
+
items = c(
|
|
563
|
+
"Collapsed (clones that are less abundant in the y-axis sample)",
|
|
564
|
+
"Dual (clones that are equally abundant in both samples)",
|
|
565
|
+
"Expanded (clones that are more abundant in the y-axis sample)",
|
|
566
|
+
"(x-axis sample) Multiplet (clones that are only present in the x-axis sample, with multiple cells)",
|
|
567
|
+
"(x-axis sample) Singleton (clones that are only present in the x-axis sample, with a single cell)",
|
|
568
|
+
"(y-axis sample) Multiplet (clones that are only present in the y-axis sample, with multiple cells)",
|
|
569
|
+
"(y-axis sample) Singleton (clones that are only present in the y-axis sample, with a single cell)"
|
|
570
|
+
)
|
|
571
|
+
),
|
|
572
|
+
h1 = ifelse(casename == "DEFAULT", "Residency Plots", casename),
|
|
573
|
+
h2 = ifelse(casename == "DEFAULT", "#", "Residency Plots"),
|
|
574
|
+
ui = "flat"
|
|
575
|
+
)
|
|
576
|
+
add_report(
|
|
577
|
+
list(
|
|
578
|
+
kind = "descr",
|
|
579
|
+
content = "For samples in each subject, showing the overlapping clones between samples in Venn diagrams."
|
|
580
|
+
),
|
|
581
|
+
h1 = ifelse(casename == "DEFAULT", "Overlapping Clones (Venn Diagram)", casename),
|
|
582
|
+
h2 = ifelse(casename == "DEFAULT", "#", "Overlapping Clones (Venn Diagram)"),
|
|
583
|
+
ui = "flat"
|
|
584
|
+
)
|
|
585
|
+
add_report(
|
|
586
|
+
list(
|
|
587
|
+
kind = "descr",
|
|
588
|
+
content = "For samples in each subject, showing the overlapping clones between samples in UpSet plots."
|
|
589
|
+
),
|
|
590
|
+
h1 = ifelse(casename == "DEFAULT", "Overlapping Clones (UpSet Plots)", casename),
|
|
591
|
+
h2 = ifelse(casename == "DEFAULT", "#", "Overlapping Clones (UpSet Plots)"),
|
|
592
|
+
ui = "flat"
|
|
593
|
+
)
|
|
516
594
|
sapply(seq_len(nrow(subjects)), handle_subject, subjects, casename, case)
|
|
517
595
|
}
|
|
518
596
|
|
|
519
597
|
for (casename in names(cases)) {
|
|
520
598
|
handle_case(casename, cases[[casename]])
|
|
521
|
-
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
save_report(joboutdir)
|
|
@@ -70,8 +70,22 @@ do_one_case_basic = function(name, case, method) {
|
|
|
70
70
|
}
|
|
71
71
|
ofig = file.path(odir, paste0(name, ".png"))
|
|
72
72
|
png(ofig, width = case$devpars$width, height = case$devpars$height, res = case$devpars$res)
|
|
73
|
-
print(p)
|
|
73
|
+
print(p + scale_fill_biopipen())
|
|
74
74
|
dev.off()
|
|
75
|
+
|
|
76
|
+
add_report(
|
|
77
|
+
list(
|
|
78
|
+
src = ofig,
|
|
79
|
+
name = if (name == "DEFAULT") NULL else name
|
|
80
|
+
),
|
|
81
|
+
h1 = "Exploratory Analysis",
|
|
82
|
+
h2 = switch(method,
|
|
83
|
+
len = "CDR3 length distribution",
|
|
84
|
+
volume = "Clonotype volume (Number of clonotypes)",
|
|
85
|
+
count = "Clonotype abundances"
|
|
86
|
+
),
|
|
87
|
+
ui = "table_of_images"
|
|
88
|
+
)
|
|
75
89
|
}
|
|
76
90
|
|
|
77
91
|
# Do cases
|
|
@@ -82,11 +96,11 @@ do_cases_basic = function(cases, method) {
|
|
|
82
96
|
}
|
|
83
97
|
}
|
|
84
98
|
|
|
85
|
-
volumes = fill_up_cases_basic(volumes)
|
|
86
|
-
do_cases_basic(volumes, "volume")
|
|
87
|
-
|
|
88
99
|
lens = fill_up_cases_basic(lens)
|
|
89
100
|
do_cases_basic(lens, "len")
|
|
90
101
|
|
|
102
|
+
volumes = fill_up_cases_basic(volumes)
|
|
103
|
+
do_cases_basic(volumes, "volume")
|
|
104
|
+
|
|
91
105
|
counts = fill_up_cases_basic(counts)
|
|
92
106
|
do_cases_basic(counts, "count")
|
|
@@ -82,6 +82,20 @@ do_one_case_clonality = function(name, case, method) {
|
|
|
82
82
|
png(ofig, width = case$devpars$width, height = case$devpars$height, res = case$devpars$res)
|
|
83
83
|
print(p)
|
|
84
84
|
dev.off()
|
|
85
|
+
|
|
86
|
+
add_report(
|
|
87
|
+
list(
|
|
88
|
+
src = ofig,
|
|
89
|
+
name = if (name == "DEFAULT") NULL else name
|
|
90
|
+
),
|
|
91
|
+
h1 = "Clonality Analysis",
|
|
92
|
+
h2 = switch(method,
|
|
93
|
+
top = "Top Clones",
|
|
94
|
+
rare = "Rare Clones",
|
|
95
|
+
homeo = "Clonal Space Homeostasis"
|
|
96
|
+
),
|
|
97
|
+
ui = "table_of_images"
|
|
98
|
+
)
|
|
85
99
|
}
|
|
86
100
|
|
|
87
101
|
# Do cases
|