9 Genome Assembly: Implementations
Everything on this page is generated from tools/assembly.json. If something here is wrong or out of date, the fix belongs in that file, not in this prose.
For why repeats are the whole difficulty, see Section 8.1.
9.1 Start here
The read type decides this, not a ranking. Accurate long reads and noisy long reads are different problems with different right answers, for the reason in Section 8.2: what an assembler can assume about its input determines what it can do with a tangle.
Built for reads whose errors it cannot assume away, which makes it the answer for nanopore data and for anything where read accuracy is unknown. Its repeat graph represents repeats explicitly rather than trying to traverse through them, so what could not be resolved is visible in the output rather than guessed at. (Kolmogorov et al. 2019)
The default for accurate long reads, and the reason phased assembly became routine rather than a project. It builds a graph that keeps both haplotypes rather than collapsing them, so a diploid sample yields two assemblies instead of one consensus that belongs to neither parent. Trio or Hi-C data lets it assign those haplotypes correctly. (Cheng et al. 2021)
9.2 The other assemblers
One for short reads, which remain the correct choice for small and unevenly covered genomes; one that led the field and has been overtaken by the data rather than by a better version of itself.
| Tool | Upstream | Languages | Why / why not |
|---|---|---|---|
| SPAdes | active | C++ |
The short-read assembler that is still the right answer when short reads are what you have: bacterial isolates, single-cell amplified genomes, viral samples, metagenomes. Its multi-k de Bruijn approach handles the uneven coverage those give you, which is the case general assemblers handle worst. (Bankevich et al. 2012) |
| Verkko | active | pyC++ |
Combines accurate long reads with ultra-long noisy ones in a single graph, which is the combination that produced the first complete human chromosomes: the accurate reads give the sequence and the ultra-long ones span the repeats that defeat everything else. Choose it when telomere-to-telomere is the actual goal. (Rautiainen et al. 2023) |
| Canu | maintained | C++java |
The assembler that made long reads work, by correcting them against each other before assembling. That correction step is exactly what accurate long reads made unnecessary, so its central idea has been overtaken rather than improved on. It is here because a great deal of published work used it and because it still runs. (Koren et al. 2017) |
9.3 Assessing what came out
Section 8.7 is the reason this section is as long as the assembly one. The three axes — contiguity, correctness, completeness — need different tools, and a report on one of them is not a quality claim.
Start with the reference-free check, because a new genome has no reference and because it answers the correctness question directly from the reads. Add a gene-based completeness measure, whose duplication count is the standard signal that haplotypes failed to collapse. Contiguity statistics are worth having and worth reading last.
Evaluates an assembly against the k-mers of the reads it was built from, so it needs no reference and cannot inherit a reference’s mistakes. That is what makes it the right first check for a new genome: it estimates base accuracy and completeness from evidence you already have, and it measures phasing directly rather than by proxy. (Rhie et al. 2020)
| Tool | Upstream | Languages | Why / why not |
|---|---|---|---|
| BUSCO | active | py |
Asks a biological question the k-mer methods cannot: are the genes that should be present in single copy actually present in single copy? Duplicated BUSCOs are the standard signal that haplotypes failed to collapse, and missing ones point at genuinely absent sequence. It is the number reviewers expect, which is its own argument. (Manni et al. 2021) |
| compleasm | active | py |
A reimplementation of the same completeness measure that reads the same lineage datasets and runs considerably faster. Worth knowing about because it reports more complete genes than the original on the same assembly, which is a difference in method rather than in the assembly — so the two are not interchangeable in a table of results. (Huang and Li 2023) |
| QUAST | maintained | py |
Reports the contiguity statistics — N50, longest contig, total length — and, when given a reference, misassembly counts. Useful for comparing assemblies of the same genome against each other, which is what it was built for. (Gurevich et al. 2013) |
The two gene-completeness entries above read the same lineage datasets and report different scores for the same assembly, because they identify genes differently. Neither is wrong. It does mean a completeness figure is uninterpretable without naming which tool produced it, and that scores from the two should not appear in the same comparison table.
9.4 What is not here
Scaffolding is adjacent and not surveyed. Getting from contigs to chromosomes uses evidence the assemblers above do not take — Hi-C contact maps, optical maps, genetic maps, or a related genome — and the tools are specific to which of those you have. Section 8.5 covers what the resulting Ns actually claim, which is the part worth knowing before you read someone else’s scaffolded assembly.
Polishing is also absent. When assemblers depended on error-prone reads, a separate consensus-correction pass was standard; accurate long reads have made it largely unnecessary for the recommended route above, which is a good example of a whole tool category shrinking because the data improved.
9.5 Language coverage
Assembly is C++ with Python around it, and the pattern is consistent: the graph construction is compiled, the orchestration is not. The quality tools lean Python and shell, because their work is counting and comparing rather than holding a graph of a genome in memory.
There are no bindings here, and unlike the read alignment chapter that is not a gap worth complaining about. An assembler is a batch job that runs for hours and writes a file; there is no in-process use for it to support. The place language coverage matters for this part is reading the output afterwards, which is Section 3.1.