ClonalSim is a Bioconductor-compatible R package for simulating tumor clonal evolution with realistic sequencing noise. It generates mutational profiles of heterogeneous tumor samples with hierarchical clonal structure.
ClonalSim implements a two-stage noise model:
Biological Noise (Intra-Tumor Heterogeneity)
Technical Sequencing Noise
The package provides:
ClonalSimData S4 object with:
Visualization functions:
Export formats:
# Install devtools if needed
if (!require("devtools")) install.packages("devtools")
# Install ClonalSim
devtools::install_github("gbucci/ClonalSim")
if (!require("BiocManager", quietly = TRUE))
install.packages("BiocManager")
BiocManager::install("ClonalSim")
The package requires:
library(ClonalSim)
# Run simulation with default parameters
sim <- simulateTumor()
# View summary
sim
# Get detailed statistics
summary(sim)
# Visualize results
plot(sim, type = "vaf_density")
# Get mutation data
mutations <- getMutations(sim)
head(mutations)
# Get true vs observed VAF
true_vaf <- getTrueVAF(sim) # Biological truth
observed_vaf <- getObservedVAF(sim) # With sequencing noise
# Get simulation parameters
params <- getSimParams(sim)
params$subclone_freqs
# Get clonal structure
structure <- getClonalStructure(sim)
# VAF density plot (most important)
plot(sim, type = "vaf_density")
# VAF scatter plot by mutation type
plot(sim, type = "vaf_scatter")
# Sequencing depth distribution
plot(sim, type = "depth_histogram")
# Clonal matrix heatmap
plot(sim, type = "clone_matrix")
sim_low_purity <- simulateTumor(
subclone_freqs = c(0.05, 0.10, 0.15) # Sum = 0.30 (30% tumor purity)
)
sim_deep <- simulateTumor(
sequencing_noise = list(
mean_depth = 500,
depth_dispersion = 100, # More uniform coverage
error_rate = 0.0005
)
)
sim_exome <- simulateTumor(
sequencing_noise = list(
mean_depth = 50,
depth_dispersion = 10, # More variable coverage
error_rate = 0.002
)
)
sim_high_het <- simulateTumor(
subclone_freqs = c(0.05, 0.10, 0.15, 0.20, 0.25, 0.25),
biological_noise = list(
enabled = TRUE,
concentration = 20 # Lower = more heterogeneity
)
)
sim_ideal <- simulateTumor(
biological_noise = list(enabled = FALSE),
sequencing_noise = list(enabled = FALSE)
)
Sequencing data includes both somatic and germline variants. Germline variants (heterozygous diploid) appear at VAF ~0.5 regardless of tumor purity:
# 70% purity tumor with germline contamination
sim_germline <- simulateTumor(
subclone_freqs = c(0.3, 0.4), # 70% tumor purity
germline_variants = list(
enabled = TRUE,
n_variants = 100, # Number of germline SNPs
vaf_expected = 0.5 # Heterozygous diploid
)
)
# Germline VAF stays at ~0.5 in both pure and contaminated samples
# This is because germline variants are heterozygous in BOTH tumor and normal cells
library(GenomicRanges)
gr <- toGRanges(sim)
gr
# Subset by chromosome
gr_chr1 <- gr[seqnames(gr) == "chr1"]
# Get VRanges object
vr <- toVCF(sim, sample_name = "TumorSample")
# Write to VCF file
toVCF(sim, output_file = "simulated_mutations.vcf")
# PyClone format
toPyClone(sim, file = "pyclone_input.tsv", sample_id = "sample1")
# SciClone format
toSciClone(sim, file = "sciclone_input.tsv")
# Simple CSV
toDataFrame(sim, file = "mutations.csv")
# Define custom evolutionary hierarchy
sim_custom <- simulateTumor(
subclone_freqs = c(0.1, 0.15, 0.2, 0.25, 0.3),
n_mut_per_clone = c(30, 40, 50, 40, 30),
n_mut_shared = list(
"2 3 4 5" = 20, # Shared by clones 2,3,4,5
"3 4 5" = 15, # Shared by clones 3,4,5
"4 5" = 10, # Shared by clones 4,5
"1 2" = 8 # Shared by clones 1,2
),
n_mut_founder = 15
)
# 1. Generate ground truth
set.seed(42)
sim <- simulateTumor(
subclone_freqs = c(0.2, 0.3, 0.5),
n_mut_per_clone = c(50, 75, 50)
)
# 2. Get true mutations
true_mutations <- getMutations(sim)
# 3. Export for your variant caller
toVCF(sim, output_file = "ground_truth.vcf")
# 4. Run your variant caller on the VCF
# 5. Compare results and calculate metrics
# - Sensitivity: TP / (TP + FN)
# - Precision: TP / (TP + FP)
# - VAF correlation: cor(true_vaf, called_vaf)
# View introductory vignette
browseVignettes("ClonalSim")
# Main function
?simulateTumor
# Noise model functions
?applyBiologicalNoise
?simulateDepth
?simulateSequencingReads
# Export functions
?toGRanges
?toVCF
?toPyClone
# Accessor functions
?getMutations
?getSimParams
ClonalSim is designed for:
For users who prefer the original standalone script (generates all plots automatically):
# The original script is preserved in inst/scripts/
source(system.file("scripts", "simulate_tumor_clones.R", package = "ClonalSim"))
Or directly:
# From the package directory
Rscript inst/scripts/simulate_tumor_clones.R
The ClonalSimData object contains:
# Mutations data.frame with columns:
# - Mutation: Unique identifier
# - Chromosome, Position, Ref, Alt: Genomic coordinates
# - True_VAF: Biological truth (with heterogeneity)
# - VAF: Observed VAF (with sequencing noise)
# - Depth: Sequencing coverage
# - Alt_reads: Alternative allele read count
# - Clone: Which clone(s) carry the mutation
# - Type: founder, shared, or private
# - Clone_IDs: Comma-separated clone identifiers
Biological Noise (Beta Distribution):
f, VAF ~ Beta(α, β)Technical Noise:
If you use ClonalSim in your research, please cite:
Bucci, G. (2025). ClonalSim: Simulation of Tumor Clonal Evolution with
Realistic Sequencing Noise. https://github.com/gbucci/ClonalSim
DOI: 10.5281/zenodo.17465573
Contributions are welcome! Please:
git checkout -b feature/AmazingFeature)git commit -m 'Add AmazingFeature')git push origin feature/AmazingFeature)This project is licensed under the MIT License - see the LICENSE file for details.
Created by Gabriele Bucci for bioinformatics applications in computational oncology.
browseVignettes("ClonalSim") in RNote: ClonalSim generates synthetic data for educational, research, and benchmarking purposes.