The example or result data in the result folder can be downloaded here. The example or result data in the result_merge folder can be downloaded here.
We do not provide example data for the estimate_Copy_num
function because the example data for a single sample exceeds 50GB. The
input file structure required to run this function for a single sample
is as follows:
## eccDNAscope_example/sample_data/AK1
## └── result_cellranger-atac
## ├── AK1.log
## ├── AK1_fragments.tsv.gz
## ├── AK1_fragments.tsv.gz.tbi
## ├── analysis
## ├── cloupe.cloupe
## ├── cut_sites.bigwig
## ├── filtered_peak_bc_matrix
## ├── filtered_peak_bc_matrix.h5
## ├── filtered_tf_bc_matrix
## ├── filtered_tf_bc_matrix.h5
## ├── peak_annotation.tsv
## ├── peak_motif_mapping.bed
## ├── peaks.bed
## ├── possorted_bam.bam
## ├── possorted_bam.bam.bai
## ├── possorted_bam.md5
## ├── raw_peak_bc_matrix
## ├── raw_peak_bc_matrix.h5
## ├── singlecell.csv
## ├── summary.csv
## ├── summary.json
## └── web_summary.html
Attention: eccDNAscope_example/sample_data/AK1 is the
storage path for a single sample, while
result_cellranger-atac is the relative path under AK1 where
the Cell Ranger results are stored.The cellranger directory must be
generated using the standard Cell Ranger-ATAC pipeline. The following
files are required to run this function: singlecell.csv, possorted_bam.bam, possorted_bam.bam.bai
library(parallel)
samples <- c(
"eccDNAscope_example/sample_data/AK1",
"eccDNAscope_example/sample_data/CSCC1")
# Parallelly calculate the CNV_copy feature for all samples using the estimate_Copy_num function.
results <- mclapply(samples, function(dir) {
estimate_Copy_num(
eccDNA.min.copy = 5,
sample.dir = dir,
cellranger.result.dir="result_cellranger-atac",
blacklist.file="eccDNAscope_example/reference/blacklist_repeats_segdups_rmsk_hg38.bed",
bedtools.dir=".conda/envs/eccDNAscope/bin/bedtools",
output.dir="eccDNAscope_example/result"
)
}, mc.cores = length(samples))
# Merge results from all samples.
CNV_copy <- do.call(c, lapply(results, function(x) x$CNV_copy))
CNV_allcopy <- do.call(c, lapply(results, function(x) x$CNV_allcopy))
save(CNV_copy,CNV_allcopy,file='eccDNAscope_example/result_merge/CNV_statistic.Rdata')
Assign CNV_copy information to the eccDNA object
load("eccDNAscope_example/result_merge/CNV_statistic.Rdata")
combined_atac <- readRDS("eccDNAscope_example/result_merge/combined_atac_annote.rds")
combined_atac <- assign_eccDNA_features(eccDNA.object=combined_atac,
cell_type_col="celltype_ATAC",
feature_name = "CNV_copy")
Visualize the distribution of eccDNA features across cells.
# CNV_copy distribution in all cells
combined_atac@misc$p_CNV_copy_distribution
# CNV_copy distribution in each cell type
combined_atac@misc$p_CNV_copy_celltype
Before running this function, the estimate_Copy_num function must have been executed with the same output.dir parameter.
library(parallel)
samples <- c("eccDNAscope_example/sample_data/AK1",
"eccDNAscope_example/sample_data/CSCC1")
# Parallelly calculate the adapter_num feature for all samples using the estimate_Adapter_num function.
results <- mclapply(samples, function(dir) {
estimate_Adapter_num(
sample.dir = dir,
cellranger.result.dir="result_cellranger-atac",
samtools.dir=".conda/envs/eccDNAscope/bin/samtools",
bedtools.dir=".conda/envs/eccDNAscope/bin/bedtools",
output.dir="eccDNAscope_example/result" # The value of the output.dir parameter must be the same as the output.dir parameter used in the estimate_Copy_num function.
)
}, mc.cores = length(samples))
# Merge results from all samples.
adapter_num <- do.call(c, results)
save(adapter_num,file='eccDNAscope_example/result_merge/adapter_num.Rdata')
Assign adapter_num information to the eccDNA object
load("eccDNAscope_example/result_merge/adapter_num.Rdata")
combined_atac <- assign_eccDNA_features(eccDNA.object=combined_atac,
cell_type_col="celltype_ATAC",
feature_name = "adapter_num")
Visualize the distribution of eccDNA features across cells.
# adapter_num distribution in all cells
combined_atac@misc$p_adapter_num_distribution
# adapter_num distribution in each cell type
combined_atac@misc$p_adapter_num_celltype
library(parallel)
sample.file.names <- c("AK1","CSCC1")
# Parallelly calculate the eccDNA_gene_num feature for all samples using the estimate_eccDNA_gene_num function.
results <- mclapply(sample.file.names, function(sample) {
estimate_eccDNA_gene_num(
sample.file.name = sample,
adapter.result.dir="eccDNAscope_example/result"
)
}, mc.cores = length(sample.file.names))
# Merge results from all samples.
eccDNA_gene_num <- do.call(c, results)
save(eccDNA_gene_num,file='eccDNAscope_example/result_merge/eccDNA_gene_num.Rdata')
Assign eccDNA_gene_num information to the eccDNA object
load("eccDNAscope_example/result_merge/eccDNA_gene_num.Rdata")
combined_atac <- assign_eccDNA_features(eccDNA.object=combined_atac,
cell_type_col="celltype_ATAC",
feature_name = "eccDNA_gene_num")
Visualize the distribution of eccDNA features across cells.
# eccDNA_gene_num distribution in all cells
combined_atac@misc$p_eccDNA_gene_num_distribution
# eccDNA_gene_num distribution in each cell type
combined_atac@misc$p_eccDNA_gene_num_celltype
Select cells eligible for eccDNA visualization from a specific sample.
cell_type <- combined_atac$celltype_ATAC
names(cell_type) <- rownames(combined_atac@meta.data)
load("eccDNAscope_example/result/CSCC1/final_copy.Rdata") # If you have executed the first three steps, the file will be automatically generated in the output path.
final_copy_filter <- get_eccDNA_cells(final_copy=final_copy,cell_type=cell_type)
# The cell names you can choose to plot
new_exist_cell<-c()
for(i in 1:dim(final_copy_filter)[1]){
temp_data<-final_copy_filter[i,10:13]
if(length(grep('-1$',temp_data))!=0){
temp_index<-strsplit(temp_data[grep('-1$',temp_data)],':')
new_exist_cell[i]<-temp_index[[1]][[3]]
}else{
new_exist_cell[i]<-0
}
}
sort(table(new_exist_cell),decreasing = T)[1:5]
## TAGCACAAGGTTCTCA-1 <NA> <NA> <NA>
## 4 NA NA NA
## <NA>
## NA
Visualizing eccDNA in specific cell
p_one_cell <- plot_eccDNAs_in_one_cell(cell.name="TAGCACAAGGTTCTCA-1",final_copy_filter=final_copy_filter)
## >> preparing features information... 2025-8-25 21:49:42
## >> identifying nearest features... 2025-8-25 21:49:43
## >> calculating distance from peak to TSS... 2025-8-25 21:49:43
## >> assigning genomic annotation... 2025-8-25 21:49:43
## >> adding gene annotation... 2025-8-25 21:50:07
## >> assigning chromosome lengths 2025-8-25 21:50:07
## >> done... 2025-8-25 21:50:07
Filter out eccDNA-related genes eligible in the specific cell.
table(p_one_cell$one_cell$SYMBOL)
##
## PTMA
## 4
Plot the amplification structure of a single eccDNA-related gene in a specific cell.
p <- plot_single_eccDNA_in_one_cell(gene.name="PTMA",one_cell=p_one_cell$one_cell)
Integrate eccDNA-related gene amplification information across all samples.
cell_type <- combined_atac$celltype_ATAC
names(cell_type) <- rownames(combined_atac@meta.data)
all_annotation <- integrate_eccDNA_amplified_genes(adapter.result.dir="eccDNAscope_example/result",
cell_type=cell_type)
Plot the relationship between breakpoints and copy numbers of eccDNA-amplified genes
plot_eccDNA_amplified_genes(all_annotation=all_annotation)
Plot the distribution of eccDNA genomic regions
p <- plot_eccDNA_genomic_distribution(all_annotation=all_annotation)
## >> preparing features information... 2025-8-25 21:50:12
## >> identifying nearest features... 2025-8-25 21:50:12
## >> calculating distance from peak to TSS... 2025-8-25 21:50:13
## >> assigning genomic annotation... 2025-8-25 21:50:13
## >> adding gene annotation... 2025-8-25 21:50:18
## 'select()' returned 1:many mapping between keys and columns
## >> assigning chromosome lengths 2025-8-25 21:50:18
## >> done... 2025-8-25 21:50:18
p$annotation_res