Delly: calling structural and copy-number variants from short and long reads
DELLY2: Structural variant discovery by integrated paired-end and split-read analysis
At a glance
- What is it?
- Delly is a C++ structural variant caller that combines paired-end, split-read and read-depth evidence to discover and genotype deletions, insertions, tandem duplications, inversions and translocations at single-nucleotide resolution, with separate subcommands for short-read, long-read, assembly and copy-number workflows.
- Who is it for?
- Adopt Delly if you need single-nucleotide-resolution structural variant calls from short-read or long-read data, since the same tool covers discovery, genotyping and filtering without a separate panel of scripts. Do not adopt it for whole-exome or targeted copy-number data, because the README states that delly cnv is a whole-genome read-depth method and that those data are not supported.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 9 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Delly calls, and the three signals behind it
Delly is described as an integrated structural variant (SV) and copy-number variant (CNV) prediction method that can discover, genotype and visualize deletions, insertions, tandem duplications, inversions and translocations at single-nucleotide resolution in short-read and long-read whole-genome sequencing data.
The mechanism is stated plainly: it uses paired-ends, split-reads and read-depth to discover and genotype SVs in the genome.
Three independent signals is what makes it integrated rather than a single-algorithm tool, and each covers a different failure mode. Paired-end evidence catches events where the two ends of a read pair map far apart, which is the classic signature of a deletion or a rearrangement, but it localises the breakpoint only to a window between the mapped positions. Split-read evidence localises precisely: a read spanning the junction aligns partly to one location and partly to another, which is what buys the single-nucleotide resolution. Read-depth covers the class of events that produce no discordant reads at all, such as a tandem duplication or a copy-number change, because the depth signal changes without any read mapping inconsistently.
So the call is a consensus over signals that fail in different ways, and each of the subcommands and filters in the tool exists to manage that.
The tool was published in Bioinformatics as an integrated paired-end and split-read analysis method, and the project is hosted under the dellytools organisation with separate repositories for the companion tools. The primary language is C++, the licence is BSD-3-Clause, the default branch is main, and the recent releases are v2.7.0 from 2026-10-05, v2.6.0 from 2026-08-17 and v2.5.1 from 2026-07-23. The last push was on 2026-10-14, so the project is being worked on continuously.
The topics list cancer-genomics, germline, tumor, rearrangement, sv-discovery and svs, which reflects the two clinical uses the tool is built for.
Installing it, and the input requirements that come first
Delly is distributed in five ways, and the choice between them mostly reflects how your cluster is set up.
It is available as a pre-compiled binary, a Singularity container (SIF file), a Docker container, via Bioconda, or via Homebrew. Bioconda is the badge in the README, which is the usual route for a bioinformatics pipeline on a cluster, and the Docker image is on Docker Hub under dellytools/delly.
Building from source is one command.
git clone --recursive https://github.com/dellytools/delly.git && cd delly/ && make allThe recursive clone matters because the Makefile builds HTSlib from the src/htslib submodule when the default include and library directories are used. The Makefile shows the whole dependency arrangement, with the C++17 standard flag, the Boost libraries it links against, and the static build option that adds -static -static-libgcc plus the hts, z, lzma, bz2 and deflate libraries. There is also a DEBUG variable with two levels, one of which pulls in the gperftools profiler and tcmalloc.
The input requirements are stated before anything else runs, and they are not optional.
Delly needs a sorted, indexed and duplicate marked BAM or CRAM file for every input sample. An indexed reference genome is required to identify split-reads and to decode CRAM files.
Duplicate marking in particular is not a formality. A duplicate-marked BAM is what a standard alignment pipeline produces, and if you feed Delly raw or improperly marked alignments, duplicate reads inflate the evidence for events that are artefacts of the library preparation rather than features of the genome. That is a failure mode that will not announce itself clearly in the output.
The indexed reference is needed for two separate things, and the split-read part is the one people forget. A reference index is required to look up candidate breakpoint sequences, so a reference without an .fai is not enough.
The repository ships an example/ directory with both short-read and long-read data, including sr.bam, lr.bam, their .bai index files and a small ref.fa with its .fai, so you can exercise the tool before touching your own data.
Short-read and long-read discovery
The two main subcommands are sr for short reads and lr for long reads, and the interface is the same shape for both.
Short-read discovery is the basic case.
delly sr -g ref.fa input.bam > delly.vcfThe README then gives the recommended short-read form, which writes BCF and uses an exclude map.
delly sr -g hg38.fa -x human.hg38.excl.tsv -o delly.bcf input.bamAn exclude map is recommended for short reads, and it exists because of where false positives come from. The human exclude templates are hosted by the EMBL, and the reference in the README is a human GRCh38 map. Excluding known noisy regions removes calls in places where the reference and the reads disagree for systematic reasons rather than because of a variant.
The output can be redirected to a BCF file, and the README notes you can view it back with bcftools.
bcftools view delly.bcf > delly.vcfLong-read discovery takes a platform flag, with -y ont for Oxford Nanopore data and -y pb for PacBio.
delly lr -y ont -o delly.bcf -g hg38.fa input.bam
delly lr -y pb -o delly.bcf -g hg38.fa input.bamThe two platforms behave differently enough that the flag is not cosmetic. Nanopore reads carry more errors and a different error profile from PacBio reads, and the platform flag tells the caller how to interpret the evidence and how much confidence to place on it.
Long reads are where split-read evidence really pays off, because a single long read can span a breakpoint completely, and a structural variant discovered this way is localised exactly rather than to a window.
One general instruction applies to every subcommand: the sample's reference must match the reference you pass with -g, and the input must be the duplicate-marked alignment. The commands all follow the same pattern of -g for the genome, -o for output and the input files last.
Somatic calling and the panel of normals
Somatic SV calling is available for short reads through the sr subcommand and for long reads through lr.
At least one tumor sample and a matched control sample are required for SV discovery.
delly [sr|lr] -o t1.bcf -g hg38.fa tumor1.bam control1.bamDiscovery with a matched control produces a set of candidate sites that includes both germline variants, present in the control, and somatic ones, present only in the tumor. Separating them is the filter's job, and somatic filtering requires a tab-delimited sample description file where the first column is the sample id, as in the VCF/BCF file, and the second column is either tumor or control.
delly filter -f somatic -o t1.somatic.bcf -s samples.tsv t1.bcfThat two-column format is worth pinning down before you run anything, because a sample description file with the columns in the wrong order produces a filter that runs and gives you nonsense rather than an error.
For tumor-only sequencing applications, or for additional germline SV filtering, the README points to a panel of normals approach using sansa's PoN filtering.
sansa somatic -a pon.bcf t1.bcfThe panel of normals is the standard answer to the tumor-only problem. Without a matched control from the same individual, the only way to tell a somatic variant from a rare germline one is to compare against a set of known samples and treat any site seen in that set as likely germline. This is a real limitation of the approach rather than a gap in the tool, and the reference to sansa in a separate repository tells you the panel handling is a companion project.
The two-pass structure of somatic calling is worth internalising: discovery produces a candidate set, and the filter applies the somatic-versus-germline decision. Running the filter without the sample description file, or running discovery with the wrong -g reference, are the two mistakes that produce plausible but incorrect output.
Germline calling as a merge-then-genotype workflow
Germline SV calling exists for both short and long reads, and the workflow is different in kind from the somatic one. It is not a single command, and the structure is deliberate.
SV discovery is done by sample for high-coverage genomes.
delly [sr|lr] -g hg38.fa -o s1.bcf sample1.bamThen the SV sites are merged into an SV site list, with the -l flag for long reads.
delly merge -l -g hg38.fa -o sites.bcf s1.bcf s2.bcf ... sN.bcfThat merged site list is then genotyped across all samples in parallel.
delly [sr|lr] -g hg38.fa -v sites.bcf -o s1.geno.bcf s1.bam
delly [sr|lr] -g hg38.fa -v sites.bcf -o sN.geno.bcf sN.bamThe reason for the two stages is a computational one. Discovery per sample is expensive, because it scans all the evidence in that sample. Genotyping against a fixed site list is cheap, because the candidate positions are already known. Running discovery once per sample and then a cheap parallel genotyping pass across the cohort is what makes cohort-scale germline calling tractable, and it is the same reason cohort calling is done in chunks.
The genotyped outputs are merged with bcftools, and the README notes this can be done in chunks if necessary.
bcftools merge -m id -O b -o merged.bcf s1.geno.bcf s2.geno.bcf ... sN.geno.bcfThe germline SV filter is then applied, with the -l flag for long reads.
delly filter -l --hwe 0.000001 -f germline -o germline.bcf merged.bcfThe Hardy-Weinberg threshold of 0.000001 is a statistical filter on the cohort genotypes, removing sites whose allele frequencies are inconsistent with what a population would produce. It is a cohort-level check rather than a per-sample one, which is another reason the workflow has to be run over all samples before the filter is applied.
For short reads, the README again recommends the exclude file, which is the same exclude map used in the discovery step.
Copy-number calling and the whole-genome limitation
The CNV subcommand is a whole-genome read-depth method with GC-bias and mappability correction. The README is explicit about the consequence: whole-exome or targeted data are not supported.
That single sentence rules out a very common use case, and it is worth internalising before you plan a pipeline around it. A read-depth method needs a genome-wide depth profile to segment, and a targeted panel does not produce one. If your data is exome or panel, you need a different tool, and swapping the pipeline later means redoing the coverage work.
The command generates read-depth profiles as well as calls.
delly cnv -g hg38.fa -c out.cov.gz -o out.bcf -u out.seg.bed input.bamThe -c output is the coverage profile and the -u output is the segmentation, and both are usable downstream.
For somatic copy-number alterations the README directs you to the more sensitive somatic mode.
delly cnv -m somatic -g hg38.fa -c out.cov.gz -o out.bcf -u out.seg.bed input.bamThe exclude map can also be used here, and is recommended for short reads.
delly cnv -g hg38.fa -x human.GRCh38.map.excl.tsv.gz -c out.cov.gz -o out.bcf -u out.seg.bed input.bamPlotting is done with the R scripts in the repository's R/ directory, and the README gives the invocation for the coverage profile and the segmentation together.
Rscript R/rd.R out.cov.gz out.seg.bedYou can visualise the CNV calls themselves instead of the raw segmentation, by extracting them with bcftools first.
bcftools query -i 'FILTER="PASS" && QUAL>200' -f "%CHROM\t%POS\t%INFO/END\t%ID[\t%RDCN]\n" out.bcf > seg.bedThat query is also a useful demonstration of the output format. Each record carries the chromosome, position and end, the ID, and then the copy number in the RDCN field. The filter on PASS and a quality threshold of 200 means the plot shows only high-confidence calls.
Germline CNV calling follows the same merge-then-genotype shape as germline SV calling: call CNVs per sample, merge them into a unified CNV site list with delly merge -e, genotype each sample against that list with the -v flag, merge the genotypes with bcftools, and apply the germline filter.
For plotting copy-number distributions across many samples, the README suggests bcftools query to produce a TSV and then Rscript R/cnv.R, and notes this is optional and useful for a large number of samples, above a hundred.
Assembly-based calling and where Delly stops
The asm subcommand handles assembly-based SV discovery, and it takes a genome mode flag.
For a haplotype-resolved assembly:
delly asm -y diploid -g hg38.fa s1.h1.bam s1.h2.bam s2.h1.bam s2.h2.bam ...For a so-called squashed assembly:
delly asm -y squashed -g hg38.fa s1.bam s2.bam ...The two modes differ in what the input represents. A diploid assembly gives two haplotypes per sample, so you pass both. A squashed assembly collapses the haplotypes into one representative per sample.
The assembly workflow has a constraint that follows from what an assembly lacks, and the README states it clearly: an assembly-derived SV panel can be constructed using delly merge but requires -v 0, as assemblies have no read coverage.
delly merge -l -v 0 -g hg38.fa -o panel.bcf s1.asm.bcf s2.asm.bcf ... sN.asm.bcfAn assembly has no read depth, so any depth-based quality filter has nothing to work with and has to be disabled. That is a small detail with a large consequence: the assembly path is a discovery mode, and the genotypes it produces have to come from reads later.
There are also other things Delly does not do, and the README is clear about the CNV one. Whole-exome and targeted data are not supported by delly cnv. Beyond that, the tool is a structural and copy-number caller, not a general variant caller: small variants are not its concern, and a pipeline that expects one tool to produce a unified VCF of everything is expecting something Delly does not offer.
The output format is BCF, so it fits into a bcftools-based workflow naturally, and the companion Python package in the repository adds the delly2bnd script, which converts between the BND-style records and the simpler breakend representation.
Editorial conclusion
Adopt Delly if you need single-nucleotide-resolution structural variant calls from short-read or long-read data, since the same tool covers discovery, genotyping and filtering without a separate panel of scripts. Do not adopt it for whole-exome or targeted copy-number data, because the README states that delly cnv is a whole-genome read-depth method and that those data are not supported. Before you run it, prepare a sorted, indexed and duplicate-marked BAM or CRAM and an indexed reference genome, and note the last push was on 2026-10-14 with v2.7.0 from 2026-10-05.
Frequently asked questions
What does Delly discover and how?
Delly is an integrated structural and copy-number variant prediction method that discovers, genotypes and visualizes deletions, insertions, tandem duplications, inversions and translocations at single-nucleotide resolution in short-read and long-read whole-genome sequencing data. It uses paired-ends, split-reads and read-depth as the three evidence types.
How do I install Delly and what input does it need?
It ships as a pre-compiled binary, a Singularity container, a Docker container, a Bioconda package and a Homebrew formula, or you can build it with git clone --recursive https://github.com/dellytools/delly.git && cd delly/ && make all. Each sample needs a sorted, indexed and duplicate marked BAM or CRAM, plus an indexed reference genome for split-read identification and CRAM decoding.
How do I run Delly for short reads versus long reads?
The sr subcommand handles short reads and lr handles long reads, with -y ont for Oxford Nanopore and -y pb for PacBio data. Both take -g for the reference genome and -o for the output, and the README recommends an exclude map for short reads.
What is the germline SV calling workflow in Delly?
Discovery is done per sample with the sr or lr subcommand, the sites are merged into one site list with delly merge, that list is genotyped across all samples in parallel with the -v flag, the genotyped files are merged with bcftools, and the germline filter is applied with delly filter -l --hwe 0.000001 -f germline.
Does Delly support whole-exome or targeted data for CNV calling?
No. The README states that delly cnv is a whole-genome read-depth method with GC-bias and mappability correction, and that whole-exome or targeted data are not supported. For somatic copy-number alterations it points to the more sensitive somatic mode with the -m somatic flag.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/dellytools-delly)Was this useful?