Telomere-Aware Contig Optimization for long-read genome assembly comparison and refinement
TACO is a reproducible multi-assembler pipeline for long-read genome assembly benchmarking, backbone selection, and conservative chromosome-end improvement. It was developed for small to moderate eukaryotic genomes, with a particular focus on fungal genomes, but also includes taxon-aware settings for plants, vertebrates, insects, and other organisms.
From one input read set, TACO runs compatible assemblers, standardizes their outputs, evaluates assembly quality with BUSCO, QUAST, telomere metrics, and optional Merqury, then follows one of two workflows: assembly-only benchmarking or full telomere-aware refinement.
TACO was developed at the Grainger Bioinformatics Center, Field Museum of Natural History.
What TACO is: TACO compares multiple long-read assemblies generated from a single dataset, selects the best-supported backbone assembly, and conservatively improves it using telomere-supported contigs from all assemblers. It produces a primary-style chromosome-level candidate assembly with provenance tracking, final QC, and coverage diagnostics.
What TACO is not: TACO does not perform Hi-C scaffolding, does not require Hi-C data, and does not attempt full chromosome scaffolding. It is not a diploid/polyploid phasing tool. For scaffolding, use TACO output as input to a dedicated scaffolder such as YaHS or 3D-DNA.
- Overview
- Workflow At A Glance
- Key Features
- Installation
- Quick Start
- Command-Line Reference
- Sequencing Platform Support
- Pipeline Steps
- Compare Mode (
--compare) - Telomere Detection
- Assembly Representation Modes
- Assembly Selection Strategy
- Outputs And Reports
- Project Structure
- Troubleshooting
- Use Of AI Assistance
- Citation
- License
Genome assemblers often produce different results from the same long-read dataset. One assembler may recover longer contigs, another may preserve more complete chromosome ends, and another may provide a better balance of completeness, contiguity, and redundancy. TACO makes these comparisons systematic, interpretable, and reproducible.
TACO operates in two modes. In assembly-only mode (--assembly-only), the pipeline runs all compatible assemblers, standardizes their outputs, evaluates quality with BUSCO, QUAST, telomere detection, and optional Merqury, then produces a unified comparison table. In full refinement mode (default), TACO continues into telomere-pool construction, backbone refinement, final QC, and report cleanup.
| Goal | Command mode | Steps run | Main result |
|---|---|---|---|
| Compare assemblers without changing any assembly | --assembly-only |
0-10, then 14B | assemblies/assembly_info.csv and final_results/assembly_only_result.csv |
| Produce a refined candidate assembly | default full mode | 0-14 | final_results/final_assembly.fasta and final_results/final_result.csv |
| Resume final QC and reporting after refinement | -s 13-14 |
13, then 14A | refreshed final QC metrics and final report |
| Rebuild only the full final report/cleanup | -s 14 |
14A | final_results/final_result.csv |
| Rebuild only assembly-only summary/cleanup | --assembly-only -s 14 |
14B | final_results/assembly_only_result.csv |
| Add a comparison against an external assembly | add --compare <fasta> to any of the above |
adds 14C | final_results/compare_report/ (per-contig synteny, weak regions, alignment gaps, Circos input, optional QUAST -R/dnadiff/paftools/mash) |
TACO uses public step numbers 0-14. Step 13 is purify + final QC: it screens foreign sequence (13A), resolves chimeras (13B), emits the purified assembly (13C), and only then measures it (13D) — so the reported metrics always describe the assembly TACO delivers. Step 14 is mode-adaptive: 14A runs in full mode for final reporting and cleanup, while 14B runs only when --assembly-only is set. 14C runs in addition to 14A whenever --compare is supplied — it produces a passive contig-to-contig comparison report against final.merged.fasta without touching the assembly itself.
- Runs up to nine long-read assemblers (HiCanu, NextDenovo, Peregrine, IPA, Flye, Hifiasm, LJA, MBG, Raven) from a single command
- Supports PacBio HiFi, Oxford Nanopore, and PacBio CLR reads via
--platform; automatically selects compatible assemblers per platform - Input QC (Step 0): validates reads, estimates coverage, warns for low depth
- Standardizes assembly outputs for direct cross-assembler comparison
- Hybrid telomere detection with de novo k-mer discovery, built-in motif families, and per-end composite scoring
- Three-tier telomere classification: strict T2T, single-end strong, and telomere-supported
- Benchmarks all assembler outputs and the final refined assembly with BUSCO, QUAST, telomere metrics, and Merqury QV/completeness when available
- Taxon-aware scoring: BUSCO S rewarded, BUSCO D penalized, Merqury QV/completeness, telomere metrics, N50, contig count, and genome size deviation — with per-taxon weights for fungal, plant, vertebrate, insect, and other genomes
- Taxon-aware BUSCO lineage defaults:
--taxon fungal→ fungi_odb10 (broad fungal; pass--busco ascomycota_odb10for a sub-lineage),--taxon plant→ embryophyta, etc. - Assembly-only mode (
--assembly-only) for publication-ready assembler benchmarking without refinement - Conservative telomere-aware backbone refinement: D-aware duplicate filter, read-coverage diagnostic for partial overlaps, BUSCO trial validation, and "do no harm" safety comparison
- Structural quickmerge validation with parent alignment checks
- Cross-assembler concordance checking: a contig that one assembler presents as telomere-to-telomere while the other assemblies split it is flagged as a possible mis-join and, by default, does not earn the T2T scoring reward — so a single assembler's chimera cannot win backbone selection. Needs no reference genome (
--concordance-mode) - Mis-join detection against
--compare: reports contigs that absorb two or more reference sequences, with the implied junction coordinate - Purification (Step 13A-13C, on by default): removes foreign sequence and repairs chimeras before final QC. Removal needs two independent signals — depth and composition, judged as robust z-scores against the assembly's heaviest cluster plus an absolute effect size — and is vetoed for telomere-bearing contigs, organelles, collapsed repeats, and anything that would discard over 25% of the assembly.
final.merged.fastakeeps the unfiltered merge and removals are preserved inpurify_excluded.fasta, so no sequence is destroyed (--purify-mode off,--metagenome) - Coverage QC: sliding-window read depth analysis with GFF3 output for genome browser visualization
- Full provenance tracking: GFF3 annotation tracing every contig to its original assembler, with quickmerge region-level mapping
- Mode-aware final reporting: Step 14A creates the full final comparison report; Step 14B creates the assembly-only summary
- Optional machine-readable benchmark logs with
--benchmark, plus decision tables and version tracking for reproducible reporting
See INSTALLATION.md for detailed instructions.
git clone https://github.com/yksun/TACO.git
cd TACO
conda env create -f taco-env.yml
conda activate taco
pip install -e .
# Verify
taco --helpAfter installation, the taco command is available system-wide within the conda environment.
TACO requires a Unix-like system (Linux or macOS) with Python >= 3.8 and Conda. Most dependencies are installed via taco-env.yml. TACO's Python modules use only the standard library with no additional pip packages. Canu, Peregrine, and IPA require manual installation (see INSTALLATION.md). If any assembler is absent or fails, TACO skips that step and continues with the others.
Full refinement run (comparison + telomere-aware refinement):
mkdir -p my_project && cd my_project
taco -g 12m -t 16 \
--fastq /path/to/reads.fastq \
--taxon fungalAssembly-only comparison (benchmarking only):
taco -g 12m -t 16 \
--fastq /path/to/reads.fastq \
--taxon fungal \
--assembly-onlyMerqury QV scoring (enabled by default):
Merqury is automatically enabled for all platforms when merqury.sh and meryl are installed. TACO builds a reads .meryl k-mer database from input reads, runs Merqury on every assembler output (Step 10), and on the final refined assembly during final QC (Step 13). Per-assembly Merqury files are written under merqury/{assembler}/ with prefixes such as merqury/canu/canu.qv and merqury/canu/canu.completeness.stats. Merqury QV and completeness are included in backbone scoring, assemblies/assembly_info.csv, and the final all-QC comparison table at final_results/final_result.csv.
By default, --merqury-k auto chooses an optimized k-mer size from the genome size. TACO uses Merqury's best_k.sh helper when it is available, otherwise it uses the same genome-size/collision-rate calculation and clamps automatic values to a practical 17-31 range for broad eukaryotic assemblies. Set MERQURY_COLLISION_RATE to tune the default 0.001 collision rate. Override with --merqury-k 21 or --merqury-k 31 when you need a fixed database for cross-run comparability.
Accuracy note: Merqury QV is most accurate with high-accuracy reads (PacBio HiFi or Illumina). With Nanopore or PacBio CLR reads, QV values may underestimate true assembly quality because read errors inflate k-mer error counts. Merqury completeness and relative QV ranking can still help compare assemblies generated from the same read set, but should be interpreted cautiously. TACO logs a warning when using non-HiFi reads. Disable with --no-merqury.
You can also provide a pre-built database:
taco -g 12m -t 16 \
--fastq /path/to/reads.fastq \
--taxon fungal \
--merqury-db reads.merylWith explicit motif override (only if biologically known):
taco -g 12m -t 16 \
--fastq /path/to/reads.fastq \
-m TTAGGG| Parameter | Description |
|---|---|
-g, --genomesize |
Estimated haploid genome size (e.g., 12m, 40m, 2g) |
-t, --threads |
Number of CPU threads |
--fastq |
Input FASTQ file (use absolute path) |
--taxon |
Taxonomy preset for telomere detection: vertebrate, animal, plant, insect, fungal, or other (default). Sets motif-family priors and detection behavior automatically. |
-m, --motif |
Telomere motif override (optional). Only use when the exact motif is biologically known for the species. When omitted, taxon-aware hybrid detection is used instead. |
--platform |
Sequencing platform: pacbio-hifi (default), nanopore, or pacbio. Determines compatible assemblers and the default polishing tool. |
--assembly-mode |
What TACO should deliver: primary (default) or full. See Assembly Representation Modes. primary is a nonredundant primary representation and reproduces pre-1.5.0 behavior exactly. full retains divergent alternate/haplotype sequence instead of collapsing it. |
-s, --steps |
Run selected public steps only (e.g., 1,3-5, 13-14). TACO uses steps 0-14; -s 14 runs 14A unless --assembly-only is set. |
--reference, -ref |
Reference FASTA. Active participant: appears in QC tables, contributes its *.telo.fasta to the all-vs-all quickmerge candidate pool, is used as a chimera-detection alignment target during refinement, and can be selected as the backbone if it wins the scoring contest (use --choose <assembler> to force a specific backbone if you want to keep the reference out of selection). |
--compare |
Compare-only FASTA — fully passive. Goes through the same QC as the assemblers (BUSCO / Telomere / QUAST / Merqury, with a compare row in final_result.csv), and triggers step 14C, the contig-to-contig comparison report at final_results/compare_report/. The report contains: compare_vs_final.paf (minimap2 -cx asm5), contig_to_contig.tsv (per-compare-contig 1-to-1 mapping with identity/coverage), unique_compare_contigs.tsv and unique_final_contigs.tsv (contigs absent or < 5 % covered in the other assembly), synteny_blocks.tsv (1-to-1 / many-to-1 synteny summary), weak_regions.tsv (10 kb windows of final.merged.fasta < 50 % covered by compare), compare_telomere_end_scores.tsv and TELOMERE_NOTES.txt (per-contig telomere classification + threshold notes), and circos/{karyotype.txt, links.txt, circos.conf, README.txt} (a ready-to-render Circos plot bundle). Optional add-ons when their binaries are on PATH: compare_quast/ (QUAST -R compare.fa), compare_dnadiff/out.report (MUMmer SNP/indel summary), compare_paftools_variants.vcf (paftools.js call), and compare_mash_distance.tsv (mash dist). Never used for backbone selection, quickmerge, telomere pool, polishing, or purge_dups. |
--final-fa |
Use this FASTA as the final merged assembly for steps 13/14, replacing assemblies/final.merged.fasta. Useful when re-running final QC on an externally produced assembly without rebuilding from step 12. |
--busco |
BUSCO lineage override. If omitted, TACO uses a taxon-aware default when available. |
--busco-download-path |
Directory where BUSCO lineage datasets are cached (passed as --download_path to BUSCO). Honors the BUSCO_DOWNLOAD_PATH env var as a fallback. |
--busco-offline-only |
Refuse to download BUSCO lineages over the network. If the lineage isn't already cached, BUSCO fails instead of falling back online. |
--choose |
Manually choose the backbone assembler |
--assembly-only |
Run assembler comparison only: steps 0-10, then Step 14B cleanup/reporting |
--auto-mode |
Backbone selection mode: smart (default) or n50 |
--merqury |
Force-enable Merqury; if no database is provided, builds one when meryl is installed |
--merqury-db |
Enable Merqury with a specific .meryl database path |
--merqury-k |
K-mer size for an auto-built Merqury database (default: auto; uses Merqury best_k.sh when available, otherwise a genome-size/collision-rate fallback) |
--no-merqury |
Disable Merqury even if installed and auto-detected |
--benchmark |
Write optional timing/provenance files to benchmark_logs/; disabled by default |
--no-purge-dups |
Skip purge_dups after refinement. This flag can only disable purge_dups, never enable it: --assembly-mode full already skips it, and omitting this flag does not bring it back. |
--no-polish |
Skip automatic polishing after refinement |
--allow-t2t-replace |
Allow rescue donors to replace immutable Tier 1 (T2T) contigs. Disabled by default for safety |
--concordance-mode |
Cross-assembler validation of strict-T2T contigs: exclude (default) discounts a contig that most other assemblies split, so one assembler's mis-join cannot win backbone selection; flag reports such contigs without changing the score; off disables the check. Costs one minimap2 alignment per (assembly, voter) pair — roughly 5 s each on a 45 Mb fungal genome. Needs no reference. |
--purify-mode {on,off} |
Step 13A-13C purification, on by default. Screens foreign sequence and resolves chimeras before final QC. Writes final_results/purification_report.tsv and chimera_decisions.tsv. |
--metagenome |
Treat the sample as a deliberate mixture: anomalies are reported but nothing is removed, because a metagenome has no single modal depth or composition to screen against. For co-cultures, holobionts, lichens, and symbiont assemblies. |
--chimera-action {split,replace,report,off} |
What to do with a contig other assemblies split and reads fail to span. split (default) cuts at the consensus breakpoint, preserving the backbone sequence and its polish. Nothing is broken without a cross-assembler majority, an agreed breakpoint, and read evidence against the join. |
--spanning-anchor BP |
Aligned anchor required each side of a candidate junction for a read to count as spanning it (default 1000). |
--no-contam-screen |
Alias for --purify-mode off. |
Use --assembly-only when the goal is assembler benchmarking and comparison without refinement. TACO runs all compatible assemblers, standardizes outputs inside Step 10, runs BUSCO, telomere detection, QUAST, and optional Merqury, then writes the combined comparison table to assemblies/assembly_info.csv and a summary to final_results/assembly_only_result.csv in Step 14B.
Assembly-only mode never runs the telomere pool, refinement, or final refined-assembly QC steps. If you run --assembly-only -s 14, TACO runs Step 14B. If you run -s 14 without --assembly-only, TACO runs Step 14A for the full final report.
Use --benchmark separately only when you also want machine-readable step timing and run metadata in benchmark_logs/.
--benchmark is for reproducibility and methods reporting, not for changing how assemblies are built. The biological benchmark is still the QC comparison itself: BUSCO, QUAST, telomere metrics, Merqury, and the final decision tables. When --benchmark is enabled, TACO adds a publication audit layer around that run so a future reader can reconstruct what was executed.
Use --benchmark when a run needs publication-ready provenance. It writes extra files in benchmark_logs/: exact command line, git commit/dirty state, input file size/mtime, parameters, software versions, per-step timing/status, key output file manifest, and a short methods note. FASTQ/reference SHA-256 checksums are intentionally skipped by default because large read files can be expensive to hash; set TACO_BENCHMARK_SHA256=1 with --benchmark when checksums are required for an archival or paper supplement.
When running selected steps with -s/--steps, TACO checks only the tools needed by those requested steps. For example, -s 13-14 will not warn about missing assembler binaries from Steps 1-9. Before each resumed step, TACO checks for expected upstream files and prints a specific warning naming the missing file type and the earlier step that should have produced it.
Step 10 checks for raw assembler outputs from Steps 1-9 or existing normalized FASTAs. Step 12 and later check for the Step 10/11 outputs they need. Step 13 runs only final QC on the refined assembly. Step 14 does not rerun final QC; it builds the report and organizes outputs. In full mode, -s 14 always runs 14A. In assembly-only mode, --assembly-only -s 14 runs 14B.
For common cleanup outputs, TACO can restore active inputs from final_results/, telomere_pool/, or temp/assemblers/ back into the working locations needed by a resumed step. As of TACO v1.4.0, restoration covers all of steps 8–14: normalized assemblies/*.result.fasta are restored from the corresponding temp/assemblers/... paths, assembly_info.csv and the per-merged metric CSVs are restored from final_results/, telomere-pool FASTAs and provenance TSVs are restored from telomere_pool/, and assemblies/final.merged.fasta is restored from final_results/final.merged.fasta (or from --final-fa when supplied — that override is authoritative). TACO v1.4.0 uses public steps 0-14; use -s 12-14 for the full final resume path rather than older 12-17 ranges.
Cleanup keeps resumable working files in place when possible, copies stable publication-facing outputs into final_results/, copies telomere-pool products into telomere_pool/, and moves bulky transient work files into temp/. Final cleanup and assembly-only cleanup move raw assembler work directories into temp/assemblers/; normalized assemblies/*.result.fasta files remain the canonical comparison inputs, and Step 10 can also normalize from temp/assemblers/ if those raw directories were already organized. If a resumed step warns that an upstream file is missing, rerun the producing step range (for example -s 10-14) or place the expected file back at the path shown in the warning.
TACO supports three sequencing platforms. Each assembler receives platform-appropriate flags automatically. The platform also determines the default polishing strategy: HiFi assemblies are polished with NextPolish2 by default (k-mer-based, safe for high-accuracy reads; requires yak for k-mer database construction), Nanopore assemblies use Medaka (neural-network polisher; falls back to Racon), and CLR assemblies use Racon.
| Platform | --platform |
Assemblers (Steps 1-9) | Skipped |
|---|---|---|---|
| PacBio HiFi | pacbio-hifi (default) |
canu, nextDenovo, peregrine, ipa, flye, hifiasm, lja, mbg, raven | none |
| Oxford Nanopore | nanopore |
canu, nextDenovo, flye, raven | peregrine, ipa, hifiasm, lja, mbg |
| PacBio CLR | pacbio |
canu, nextDenovo, peregrine, flye, raven | ipa, hifiasm, lja, mbg |
Incompatible assemblers are automatically skipped with a warning.
| Assembler | HiFi | Nanopore | CLR | Notes |
|---|---|---|---|---|
| Canu | -pacbio-hifi |
-nanopore |
-pacbio |
All platforms supported |
| Flye | --pacbio-hifi |
--nano-hq (Q20+) |
--pacbio-raw |
All platforms; set FLYE_ONT_FLAG=--nano-raw for older ONT |
| Hifiasm | default mode | skipped | skipped | HiFi-only as primary input |
| IPA | default mode | skipped | skipped | HiFi-only (PacBio tool) |
| Peregrine | default mode | skipped | default mode | HiFi and CLR only |
| NextDenovo | via config file | via config file | via config file | All platforms; config auto-generated |
| LJA | default mode | skipped | skipped | HiFi-only; very contiguous assemblies |
| MBG | default mode | skipped | skipped | HiFi-only; minimizer-based; included via Bioconda; uses TACO_MBG_K if set (default k=1501) |
| Raven | default mode | default mode | default mode | All platforms; fast OLC assembler from the raven-assembler package |
Platform summary: HiFi runs up to 9 assemblers, Nanopore runs 4 (Canu, Flye, NextDenovo, Raven), CLR runs 5 (Canu, Flye, NextDenovo, Peregrine, Raven).
| Platform | Polishing Tool | Notes |
|---|---|---|
| HiFi | NextPolish2 (yak k-mer based) | K-mer polishing corrects residual errors safely; requires nextpolish2 + yak |
| Nanopore | Medaka (Racon fallback) | Neural-network polisher; set MEDAKA_MODEL for non-default chemistry |
| CLR | Racon | Standard error-correction for CLR reads |
| Component | Fungal | Plant | Vertebrate/Animal | Insect/Other |
|---|---|---|---|---|
| Default BUSCO lineage | fungi_odb10 | embryophyta_odb10 | vertebrata_odb10 / metazoa_odb10 | insecta_odb10 / requires --busco |
| Merqury | auto (all platforms) | auto (all platforms) | auto (all platforms) | auto (all platforms) |
| Telomere motifs | TTAGGG + TG1-3 + Candida | TTTAGGG | TTAGGG | TTAGG (insect) / all (other) |
| Score window | 300 bp | 1000 bp | 1000 bp | 500 bp |
| Backbone scoring | S×1000 - D×600 + T2T×350 | S×1000 - D×300 + T2T×200 | S×1000 - D×500 + T2T×200 | S×1000 - D×500 + T2T×300 |
| BUSCO trial C-drop | 2% (strict) | 4% (relaxed) | 3% (moderate) | 2.5% (default) |
| purge_dups mode | two-round, upstream-default chaining | conservative single-round + polyploid warning | two-round | insect: two-round; other: conservative single-round |
| Polishing (HiFi) | NextPolish2 (yak k-mer based) | NextPolish2 (yak k-mer based) | NextPolish2 (yak k-mer based) | NextPolish2 (yak k-mer based) |
| Polishing (ONT) | Medaka → Racon | Medaka → Racon | Medaka → Racon | Medaka → Racon |
| Polishing (CLR) | Racon | Racon | Racon | Racon |
TACO exposes 15 public steps by number: 0-14. Step 14 has two internal reporting modes, but it is still invoked as step 14 from the command line.
| Step | Description | Phase |
|---|---|---|
| 0 | Input QC and validation | Setup |
| 1-9 | Run assemblers: Canu, NextDenovo, Peregrine, IPA, Flye, Hifiasm, LJA, MBG, Raven | Assembly |
| 10 | Normalize + QC comparison: BUSCO + Telomere + QUAST + Merqury on all assemblies | QC |
| 11 | Build telomere pool (pairwise quickmerge + structural validation) | Telomere pool |
| 12 | Backbone selection and telomere-aware refinement | Refinement |
| 13 | Purify + final QC: 13A foreign-sequence screen, 13B chimera resolution, 13C emit purified assembly, 13D BUSCO + Telomere + QUAST + Merqury on it | Purify + final QC |
| 14 / 14A | Final comparison report + cleanup into final_results/ (full mode) |
Report |
| 14 / 14B | Assembly-only comparison summary + cleanup (only with --assembly-only) |
Report |
| 14 / 14C | Compare-vs-final contig-to-contig report (only with --compare) |
Report |
Step 0 runs automatically before assembly. It validates that the FASTQ file exists and is non-empty, parses the genome size, estimates total read bases and coverage by sampling the first 100K reads, and warns if coverage is below recommended thresholds (HiFi: 25×, ONT: 40×, CLR: 50×). It also logs which assemblers are compatible with the selected platform and confirms the BUSCO lineage setting. Step 0 runs in both full and assembly-only modes.
Step 13 purifies the assembly produced by Step 12 and then measures it. 13A screens each contig for foreign sequence using read depth and composition against the assembly's heaviest cluster, guarded so that telomere-bearing contigs, organelles, collapsed repeats and gene-poor accessory chromosomes are not removed. 13B cross-checks every contig above 500 kb against every other assembly, estimates a breakpoint for any the majority splits, and confirms or refutes it with the count of reads spanning that position. 13C writes final.purified.fasta and preserves anything removed in purify_excluded.fasta; final.merged.fasta is never modified. 13D runs BUSCO, telomere detection, QUAST and optional Merqury on whatever 13C produced, writing the component metric files Step 14A consumes.
Purification and measurement sit in the same step deliberately. Through v1.3.7 the screen ran in Step 14A, after every published metric had already been computed on the unfiltered merge, so an accurate screen changed nothing a user read. Pass --purify-mode off for the old measure-the-merge behavior.
Step 13 does not perform cleanup and does not create the full final comparison report by itself.
Step 14 chooses its sub-mode from the run mode:
- 14A full report: used in full refinement mode, including
-s 14. It combines Step 10 per-assembler metrics with Step 13 final-assembly metrics, writesfinal_results/final_result.csv, and organizes final outputs. - 14B assembly-only report: used only when
--assembly-onlyis set. It reuses Step 10 metrics, writesfinal_results/assembly_only_result.csv, and performs assembly-only cleanup.
Steps 0-14: runs all assemblers (1-9), normalizes and QC-compares all assemblies (10), builds the telomere pool (11), selects and refines the backbone (12), runs final QC on the refined assembly (13), and produces the final comparison report with cleanup (14A).
Steps 0-10, 14: runs all assemblers (1-9), normalizes and QC-compares all assemblies (10), then produces the assembly-only comparison table at final_results/assembly_only_result.csv (14B). Skips telomere pool (11), refinement (12), and final QC (13). This mode is designed for benchmarking and decision-making without modifying any assembly.
--compare <fasta> adds a passive comparison against any externally produced assembly (e.g. an NCBI GenBank genome of the same or a closely related strain). The compare FASTA is never used for backbone selection, telomere-pool quickmerge, polishing, or purge_dups. It is treated as a read-only reference whose only effect on TACO's run is to land in the QC tables and trigger an extra reporting sub-step.
--compare works in two invocation modes and produces identical outputs in both:
- Full pipeline:
taco ... --compare X.faruns steps 0–14 normally; the comparison report is generated as part of step 14. - Resume on an existing run:
taco ... --compare X.fa -s 10,13,14after a prior full run reuses the existing assemblies and merged FASTA and only adds the comparison artifacts.
| Stage | Effect of --compare |
|---|---|
| Step 10 (Normalize + QC) | Compare FASTA is normalized to assemblies/compare.result.fasta and gets BUSCO, telomere, QUAST, and Merqury rows in assembly_info.csv and (later) final_result.csv. |
| Steps 11 / 12 | Skipped for compare — it is excluded from the telomere pool, the all-vs-all quickmerge candidate set, polish, and purge_dups. |
| Step 13 (Purify + Final QC) | Purifies final.merged.fasta into final.purified.fasta, then measures the result. Re-runnable on its own with -s 13 to retune purification without repeating Step 12. |
| Step 14C (new) | Builds the contig-to-contig report at final_results/compare_report/ against final.merged.fasta, then proceeds to standard 14A cleanup. |
Step 14C aligns the compare FASTA to final.merged.fasta with minimap2 -cx asm5 --secondary=no and writes the following layered diagnostics:
| File | Contents |
|---|---|
compare_vs_final.paf |
Raw minimap2 alignment (one row per alignment block). All downstream files are derived from this. |
contig_to_contig.tsv |
One row per compare contig: best_target_contig, best_target_aligned_bases, best_target_coverage_pct, total aligned_bases, average identity_pct, n_significant_targets, relationship (1-to-1 / 1-to-N (split)), all_targets_breakdown (every significant target with its bp and coverage), and per-end telomere flags for both the compare contig and its best target. |
contig_to_contig_pairs.tsv |
One row per (compare_contig, final_contig) pair above the significance threshold (max of 20 % of the compare contig OR 100 kb absolute). Per-pair compare coverage, final coverage, identity, dominant strand, four boundary-touch flags, and four pair-localized telomere flags. This is what makes 1-to-N splits readable. |
synteny_blocks.tsv |
At-a-glance synteny summary derived from the per-pair table — labels each block as 1-to-1, 1-to-many (compare splits across N final contigs), many-to-1 (M compare contigs → 1 final), or many-to-many. |
split_mappings.tsv |
Only compare contigs that map to >1 significant final contig. Includes a chimera_evidence text column that classifies the split using the telomere pattern at outer + inner boundaries: full-coverage split, strong chimera signal, chimeric extension into a fragment, or split-likely-real. |
unique_compare_contigs.tsv |
Compare contigs with < 5 % coverage in final.merged.fasta (or no alignment). |
unique_final_contigs.tsv |
Mirror file: final.merged.fasta contigs with < 5 % coverage from --compare. |
weak_regions_final.tsv / .gff3 |
10 kb windows of final.merged.fasta < 50 % covered by compare. (weak_regions.tsv is kept as a stable alias for back-compat.) |
weak_regions_compare.tsv / .gff3 |
10 kb windows of --compare < 50 % covered by final.merged.fasta. Empty for high-coverage runs — see the next file for fine-grained gap detection. |
final_alignment_gaps.tsv / .gff3 |
Every uncovered interval ≥ 100 bp on final.merged.fasta, with kind ∈ {leading, trailing, internal, internal_junction_candidate, *_tip, full_contig_unaligned}. Surfaces telomere-padding tips, chimera-broken tails, and TACO-unique sequence at sub-window resolution. |
compare_alignment_gaps.tsv / .gff3 |
Mirror file on the compare side. The chimera-junction bridge inside a 1-to-many compare contig appears here as a small internal_junction_candidate (typically 100–500 bp). |
compare_telomere_end_scores.tsv |
Copy of assemblies/compare.telomere_end_scores.tsv from step 9, surfaced inside the report for convenience. |
TELOMERE_NOTES.txt |
Plain-text summary of compare telomere classifications + thresholds + notes on widening --telo-score-window if telomere repeats are detected just inside the contig ends. |
circos/ |
Self-contained Circos input bundle: karyotype.txt (compare = C_<name>, final = F_<name>, distinct palettes), links.txt (one ribbon per minimap2 block ≥ 5 kb), circos.conf, and README.txt with run instructions. Render with cd circos && circos -conf circos.conf. |
compare_quast/ |
Optional — QUAST run with -R compare.fa against final.merged.fasta for genome fraction, NA50, and reference-based misassembly counts. Skipped silently when QUAST is not on PATH. |
compare_dnadiff/ |
Optional — MUMmer dnadiff SNP/indel summary. Skipped silently when dnadiff is not on PATH (install MUMmer4 to enable). |
compare_paftools_variants.vcf |
Optional — paftools.js call -L 10000 over the sorted PAF for assembly-vs-assembly SNVs and SVs. Ships with minimap2; skipped silently when paftools.js / k8 aren't on PATH. |
compare_mash_distance.tsv |
Optional — mash dist compare.fa final.fa scalar distance. Skipped silently when mash is not on PATH. |
The report is layered so that each file answers a more specific question than the one before it:
- Start with
split_mappings.tsv. If it has any rows, those are the chimera or split candidates worth investigating. Thechimera_evidencecolumn tells you which kind. - For each split, open
contig_to_contig_pairs.tsvand filter on the compare contig name. The four boundary-touch flags + four telomere-at-pair flags reveal whether each pair sits on compare's outer end or near the join, and whether the corresponding final-contig boundary carries a telomere. final_alignment_gaps.tsvexplains every region of TACO's assembly that the compare doesn't cover — telomere arrays the compare lost, chimera-broken chromosome ends, and minor alignment-edge artifacts.compare_alignment_gaps.tsvdoes the mirror, and crucially surfaces the small (100–500 bp) chimera-junction bridges that the window-basedweak_regions_compare.tsvmisses.- For visual inspection, render
circos/with Circos, or loadweak_regions_*.gff3and*_alignment_gaps.gff3as IGV / JBrowse tracks alongside the FASTA. A chimera looks like two ribbons from the sameC_<name>ideogram converging on differentF_<name>ideograms with opposing strands.
If you want to run step 14C against an externally-produced final assembly without rebuilding from step 12, pass --final-fa <path>. TACO copies that FASTA into assemblies/final.merged.fasta (overriding any cached copy) and runs steps 13/14 against it. Combined with --compare, this lets you compare any two assemblies head-to-head without re-running the full pipeline:
taco -g 40m -t 30 --fastq reads.fastq --platform nanopore --taxon fungal \
--final-fa /path/to/your_final.fasta \
--compare /path/to/external.fasta \
-s 13,14# Full pipeline + comparison against an NCBI reference
taco -g 40m -t 30 --fastq reads.fastq --platform nanopore --taxon fungal \
--busco-download-path /shared/busco_downloads --busco-offline-only \
--compare /path/to/GCA_xxxxx.fna
# Add a comparison after a previous full run (no reassembly)
cd <previous_run_dir>
taco -g 40m -t 30 --fastq reads.fastq --platform nanopore --taxon fungal \
--compare /path/to/GCA_xxxxx.fna \
-s 10,13,14
# Compare two existing assemblies without rerunning
taco -g 40m -t 30 --fastq reads.fastq --platform nanopore --taxon fungal \
--final-fa /path/to/your.fasta \
--compare /path/to/other.fasta \
-s 13,14TACO v1.4.0 uses a taxon-aware hybrid telomere detection system that combines built-in motif families with de novo k-mer discovery.
Use --taxon to select the appropriate telomere motif priors for your organism. This is the recommended approach instead of forcing --motif directly.
--taxon |
Primary Motifs | Notes |
|---|---|---|
vertebrate |
TTAGGG | Highly conserved; exact motif matching is most reliable here |
animal |
TTAGGG | Strong prior for vertebrates, less certain for distant metazoans |
plant |
TTTAGGG | Common plant repeat; some lineages vary |
insect |
TTAGG | Common insect repeat; not universal across all insect orders |
fungal |
TTAGGG, TG1-3, Candida | Diverse fungal telomeres — all built-in families used |
other (default) |
All families | Unknown taxon — relies on de novo discovery plus all priors |
The --motif flag is an optional override. Do not force --motif unless the telomere repeat is biologically confirmed for your species or lineage. For fungi and unknown taxa especially, forcing a motif may miss true telomeres.
TACO ships with five motif families: the canonical vertebrate/filamentous fungal TTAGGG repeat, the budding yeast TG1-3/C1-3A degenerate repeat, the Candida 23-bp repeat (ACGGATGTCTAACTTCTTGGTGT), the plant TTTAGGG repeat, and the insect TTAGG repeat.
Each contig end is scored using a composite of four metrics: telomere density (weight 0.40), longest consecutive run (weight 0.30), distance of repeats from the contig terminus (weight 0.20), and covered base pairs (weight 0.10). The composite score ranges from 0 to 1.
Contigs are classified into three tiers based on their end scores: strict T2T contigs have strong telomere signal at both ends (score >= 0.25 at each end), single-end strong contigs have strong signal at one end only, and telomere-supported contigs have at least weak signal (score >= 0.08) at one end.
--assembly-mode selects what TACO should deliver. The two modes are not the
same objective at different thresholds — they disagree about what a good assembly
is, so they score assemblies differently and remove different things.
primary (default) |
full |
|
|---|---|---|
| Goal | One nonredundant representative sequence per chromosome | Full sequence representation; divergent alternate sequence retained |
| BUSCO term rewarded | BUSCO_S (single-copy) |
BUSCO_C (complete = S + D) |
| BUSCO duplication | Penalized (w_busco_d 300–600 by taxon) |
Neutral — neither rewarded nor punished |
| Merqury completeness | × 200 | × 400 |
| Merqury QV | × 20 (kept separate from completeness) | × 20 (kept separate from completeness) |
| Fragmentation charge | absolute contig count × w_contigs |
contig density (contigs/Mb) × 30 × haploid Mb |
| Expected size | point deviation from -g, penalized |
tolerance band [-g, 2 × -g × 1.15], reported but not scored |
| purge_dups | runs | skipped |
| Self-dedup / containment filtering | runs | skipped |
| Contaminant screen (13A) | runs | runs |
| Chimera resolution (13B) | runs | runs |
TACO does not order or orient contigs into haplotypes and does not validate
haplotype consistency. full mode retains alternate sequence; it does not
assign it. Do not describe its output as phased, haplotype-resolved, or as
hap1/hap2.
Selection alone is not enough, and neither is loosening the size expectation.
No assembler declares an expected total assembly size for a heterozygous
sample: hifiasm and Verkko take no genome size at all, Flye's is optional, and
Canu's genomeSize is a coverage knob (it feeds corOutCoverage,
mhapSensitivity, and NG50 logging) rather than a size expectation. Where a
declared size is compared against a finished assembly, NCBI uses a wide
taxon-derived band anchored on the haploid value to flag for human review,
never to rank. TACO follows that: in full mode the band populates the report
and the advisory, and contributes nothing to the score.
The guard against an inflated assembly is therefore structural. On a real
Puccinia triticina HiFi read set (-g 127m, --taxon fungal), a 287 Mb /
46,812-contig artifact had the highest Merqury completeness of any candidate
(99.26 %) and sat inside any band wide enough to admit the genuine 254 Mb
assembly — so size could not separate them. Contig density does: 163 contigs/Mb
for the artifact against 3.8 for the 254 Mb assembly and 2.5 for the collapsed
134 Mb one.
Density rather than absolute count matters because an assembly that legitimately
carries roughly twice the sequence also carries roughly twice the contigs.
Charging the absolute count would penalize it for precisely the property full
mode exists to select. Fragmentation is priced at the same per-contig rate in
both modes; only the double-charge for retained sequence is removed.
Contaminant screening (13A) and chimera resolution (13B) run in both modes. Foreign sequence and read-unsupported joins are errors under either objective, and they are identified from independent evidence — composition, read depth, and read spanning — rather than from a contig resembling a second haplotype. Full mode only declines to remove sequence because it looks redundant.
The number of telomere-bearing contigs is bounded by biology — two telomeres per
contig, 2 x n_chromosomes x ploidy per genome — so the score stops rewarding
counts beyond 2 x (expected total / 1 Mb). The 1 Mb minimum-chromosome floor is
deliberately permissive (127 "chromosomes" in a 127 Mb haploid genome against a
real 18), so the bound only fires on counts that are impossible by a wide margin
and changes no realistic selection. It exists because one real candidate reported
1,668 single-end-telomere contigs in an 18-chromosome genome, worth three times
its entire BUSCO term. With no -g no bound can be derived and the count is used
as-is.
If the --compare assembly keeps both haplotypes and this run delivers one (or
vice versa), each reference haplotype pair maps onto the same single contig and
contig_to_contig.tsv will label those rows 1-to-N (split). That is a
representation difference, not a mis-join.
final_results/compare_report/REPRESENTATION_NOTES.txt reports the fraction of
chromosome-scale compare contigs sharing a best target and explains how to read
the other tables when it is high. Match the comparator to the mode where you
can: a haploid reference for primary, a haplotype-retaining one for full.
When a primary run ends with high Merqury completeness (≥ 95 %), strong BUSCO
duplication (≥ 20 %), and a substantially larger assembly (≥ 1.4 × the expected
haploid size) all at once, TACO emits a warning suggesting --assembly-mode full. This is a prompt to look, not a biological conclusion: these metrics alone
do not establish the ploidy of the sample, and the warning does not claim they
do.
Several assemblers emit more than one contig set, and the extra sets are exactly what a full representation wants. TACO captures them as additional candidates at no extra assembly cost, because the parent run already wrote them:
| candidate | built from | parent |
|---|---|---|
hifiasm_hap |
bp.hap1.p_ctg + bp.hap2.p_ctg |
hifiasm |
ipa_alt |
final.p_ctg + a_ctg (associate contigs) |
IPA |
Without them, --assembly-mode full chooses among assemblies that were all
collapsed to one representation first, so its answer reflects which assemblers
purge by default rather than which recover alternate sequence best.
Derived candidates are scored and selectable like any other. They are excluded from the cross-assembler concordance vote: that check assumes one ballot per independent assembly, and a derived set shares its parent's graph, reads and error profile, so two ballots would inflate agreement. The parent votes; the log names any candidate dropped from voting.
Flye's --keep-haplotypes is a third case, but it changes the assembly rather
than reading an existing file, so it needs a reassembly and is not enabled by
default. Runs made before v1.5.0 have no derived candidates — re-run steps 4, 6
and 10 to generate them.
Three stages can remove sequence, and each is gated separately, because a gate on one does not protect the others:
| stage | what it does | gate |
|---|---|---|
| 12G merge | rebuilds from the telomere pool, dropping covered backbone sequence | 12G3: restores backbone contigs carrying lost genes |
| 12H purge_dups | removes haplotigs by similarity and depth | accepts only within the taxon BUSCO tolerance |
| 12L report | — | reports the backbone-to-delivered gene-content change |
The merge is the one that matters most and was unguarded until v1.5.1. On a real run it turned 972 backbone contigs into 468 and cost 6.3 points of BUSCO complete, of which 104 of 112 lost genes were Missing rather than Fragmented — sequence gone, not broken at a junction. The individual pool replacements were BUSCO-trialled and accounted for one upgrade and ten additions; the merge did the rest unchecked.
STEP12_SKIP_MERGE_GENE_RECOVERY=1 and STEP12_SKIP_PURGE_BUSCO_GATE=1 disable
the respective gates. Restored contigs are suffixed _gene_rescue and can
reintroduce redundancy, which is deliberate: a duplicated locus is recoverable
downstream and a missing one is not.
purge_dups removes haplotigs by similarity and depth, with no notion of genes,
so it can remove the only copy of a locus. Step 12H therefore accepts a purge
only if BUSCO complete falls by no more than the taxon tolerance (2.0 points for
fungi, 4.0 for plants, 3.0 for vertebrates, 2.5 otherwise — the same table the
rescue trial uses). A rejected purge keeps the unpurged assembly and preserves
both the purged version and the removed haplotigs for review;
STEP12_SKIP_PURGE_BUSCO_GATE=1 forces the purge through.
This costs two BUSCO runs on the merged assembly. It exists because the selection
rewrite deliberately tolerates a duplicated backbone on the grounds that
purge_dups will clean it up, and that reasoning is only sound if the cleanup is
checked. On real data an unchecked purge removed 25.7 Mb and 3.1 points of BUSCO
complete while passing every other test — the size check approves a shrink
toward -g, and the T2T count went up.
Under both the two representations are independent products, so a failure in
one does not cancel the other: each is attempted, the surviving genome is still
written into the combined table, and the run exits non-zero with the failure
named per representation. Completed work stays in that representation's
mode_*/ directory, so re-running it with --assembly-mode <mode> resumes
rather than restarts.
The optional MUMmer dnadiff summary in the compare report is time-bounded
(one hour by default, TACO_DNADIFF_TIMEOUT to change it). Its delta-filter
stage can run for days on a repeat-rich genome compared against a diverged
assembly, and it is a convenience table, so it is abandoned rather than allowed
to hold up a run. Nothing else in the compare report depends on it.
Under the default both, each representation is reported inside its own
directory while the run proceeds, and the run root receives a combined table at
the end:
mode_primary/final_results/ per-deliverable reports, primary
mode_full/final_results/ per-deliverable reports, full
final_results/final_result.csv every assembler + merged_primary + merged_full
final_results/assembly_modes_comparison.tsv headline metrics, side by side
final_result.csv at the root is the one table to read: it carries the
per-assembler columns from step 10, the --compare reference if given, and one
merged_<mode> column per deliverable, so the assemblers and both genomes can be
compared without opening three files.
While a both run is in flight the root final_results/ may still hold output
from an earlier run. TACO writes final_results/RESULTS_NOT_READY.txt naming
those stale files and pointing at the mode_*/ directories, and removes it when
the combined report is written. If that file is present, the run has not
finished.
Every run writes final_results/assembly_mode_summary.txt, which states
Assembly representation mode: primary|full and the selected assembler,
selection score, active score profile, BUSCO C/S/D, Merqury QV and completeness,
assembly length, contig count, N50, T2T and single-end telomere counts, and the
individual score contributions that produced the winning score. The mode also
appears in final_results/final_result.csv,
assemblies/selection_decision.txt, and the per-component columns of
assemblies/selection_debug.tsv.
# Default — BOTH genomes from one set of assemblies
TACO -g 127m -t 32 --fastq /path/reads.fastq.gz --taxon fungalProduces mode_primary/, mode_full/, and
final_results/assembly_modes_comparison.tsv. Steps 0–10 run once and are
shared; only steps 11–14 run twice, so the second genome costs no reassembly.
# Only the nonredundant primary genome
TACO -g 127m -t 32 --fastq /path/reads.fastq.gz --taxon fungal \
--assembly-mode primary# Only the full sequence representation, with a matched comparator
TACO -g 127m -t 32 --fastq /path/reads.fastq.gz --taxon fungal \
--assembly-mode full --busco basidiomycota_odb10 \
--compare ref/haplotype_retaining_reference.fnaMatch the comparator to the representation where you can: a haploid reference
for primary, a haplotype-retaining one for full. Under the default both,
--compare applies to each deliverable and
REPRESENTATION_NOTES.txt in each compare_report/ says which pairing you got.
When --choose is not provided, TACO automatically selects the backbone assembly for refinement. The scoring formula adapts its weights based on --assembly-mode (which objective to pursue) and --taxon (the biological characteristics of the organism group).
TACO ranks assemblies using a composite score. Merqury QV and completeness are included by default when merqury.sh + meryl are installed (otherwise these terms contribute 0):
score = BUSCO_S × w_busco_s + T2T × w_t2t + single_tel × w_single
+ MerquryComp × 200 + MerquryQV × 20 ← optional, 0 if Merqury not available
- contigs × w_contigs + log10(N50) × w_n50
- BUSCO_D × w_busco_d
Under the default --assembly-mode primary, BUSCO single-copy completeness (S%) is used instead of total completeness (C%) to avoid rewarding highly duplicated assemblies, and BUSCO duplication (D%) is explicitly penalized. Under --assembly-mode full the score rewards BUSCO_C and treats duplication as neutral — see Assembly Representation Modes. The weights below are the primary-mode weights. When Merqury is available, its k-mer-based QV and completeness provide an independent quality signal that helps distinguish assemblies with similar BUSCO scores. The weights are tuned per taxon as described below.
Fungal (--taxon fungal): Fungal genomes are typically small (10–60 Mb) with well-defined chromosomes. TACO uses strict BUSCO duplicate penalty (w_busco_d = 600) because duplicated assemblies are almost always artifactual in haploid fungi. T2T contigs are weighted heavily (w_t2t = 350) since telomere rescue is highly effective for small genomes where individual T2T chromosomes can be resolved. The contig-count penalty remains moderate (w_contigs = 30) because most fungal genomes have few chromosomes.
Plant (--taxon plant): Plant genomes vary enormously in size and ploidy. TACO relaxes the BUSCO duplicate penalty (w_busco_d = 300) because polyploidy naturally inflates D% even in correct assemblies. The contig-count penalty is increased (w_contigs = 50) to discourage fragmented assemblies in these often large genomes. T2T weight is reduced (w_t2t = 200) because long repetitive arrays near telomeres can produce false-positive signals, and interstitial telomeric repeats (ITRs) are common in plants.
Vertebrate / Animal (--taxon vertebrate or --taxon animal): Vertebrate genomes are large (1–3+ Gb) and repeat-rich. TACO increases the N50 weight (w_n50 = 200) to favor contiguous assemblies and moderates the contig-count penalty (w_contigs = 40). T2T weight is reduced (w_t2t = 200) because interstitial telomeric repeats are frequent in vertebrates and can inflate telomere counts. BUSCO duplicate penalty stays at the default (w_busco_d = 500).
Insect / Other (--taxon insect or --taxon other): These taxa use the balanced default weights: w_busco_s = 1000, w_t2t = 300, w_single = 150, w_contigs = 30, w_n50 = 150, w_busco_d = 500. This is appropriate when the biological characteristics of the target organism are not well characterized.
| Weight | Fungal | Plant | Vertebrate/Animal | Insect/Other |
|---|---|---|---|---|
w_busco_s |
1000 | 1000 | 1000 | 1000 |
w_t2t |
350 | 200 | 200 | 300 |
w_single |
150 | 150 | 150 | 150 |
w_contigs |
30 | 50 | 40 | 30 |
w_n50 |
150 | 150 | 200 | 150 |
w_busco_d |
600 | 300 | 500 | 500 |
The default telomere score window also varies by taxon to match typical telomere array lengths: fungi use 300 bp (fungal telomere arrays are short, often 50–300 bp), plants and vertebrates use 1000 bp (longer repeat arrays), and other taxa use 500 bp (balanced default).
When validating rescue candidates via BUSCO trial, the maximum acceptable C% drop, M% rise, and D% rise depend on taxon:
- Fungi: strict thresholds (2% C-drop, 0.3% M-rise, 2% D-rise) — haploid genomes with stable BUSCO profiles.
- Plant: relaxed thresholds (4% C-drop, 1.0% M-rise, 6% D-rise) — polyploidy causes natural BUSCO variability.
- Vertebrate: moderate thresholds (3% C-drop, 0.5% M-rise, 4% D-rise).
- Other: balanced defaults (2.5% C-drop, 0.5% M-rise, 3% D-rise).
A D-rise (duplicated BUSCO increase) check catches cases where a rescue introduces redundant copies of single-copy orthologs — a sign of retained haplotigs or mis-joined contigs. All thresholds can be overridden via STEP12_MAX_BUSCO_C_DROP, STEP12_MAX_BUSCO_M_RISE, and STEP12_MAX_BUSCO_D_RISE environment variables. Legacy STEP13_* names are still accepted for compatibility with older run scripts.
Additional environment variables for fine-tuning Step 12: STEP12_MAX_ACCEPTED, STEP12_MIN_BP_RATIO, STEP12_BUSCO_TRIAL_TIMEOUT (seconds per BUSCO trial attempt, default 43200; set 0 to disable), STEP12_BUSCO_ALLOW_DOWNLOAD (default 0; set 1 to permit online BUSCO lineage fallback), STEP12_SKIP_BUSCO_TRIAL (set 1 to use structural rescue checks only), CHIMERA_MIN_CROSS_COV (minimum cross-assembly coverage for chimera mapping check, default 0.60), SELFDEDUP_ENABLE plus SELFDEDUP_COV / SELFDEDUP_ID (optional self-dedup), RESCUE_MIN_IDENT, RESCUE_MIN_ALN_BP, RESCUE_MIN_COV_BB, RESCUE_MIN_COV_DONOR, RESCUE_MIN_EXT, NOVEL_DUP_COV, NOVEL_DUP_ID, NOVEL_UPGRADE_TCOV, NOVEL_MAX_D_RISE, and PARTIAL_T2T_MIN_TCOV / PARTIAL_T2T_MIN_BP / PARTIAL_T2T_MIN_QCOV / PARTIAL_T2T_MIN_IDENT for coverage-guided partial T2T replacement.
The maximum number of accepted rescue candidates per run is taxon-aware: fungi allow up to 20 rescues (many small chromosomes), vertebrates 10, plants 8 (conservative due to polyploidy risk), and other taxa 15. This prevents runaway replacement in complex genomes.
Before adding "novel" pool T2T contigs, TACO checks each candidate against the current backbone with minimap2 and applies a five-tier decision:
- Overlaps Tier 1 (T2T) backbone → reject (pure duplicate, backbone already has T2T).
- Overlaps Tier 2 (non-T2T) backbone at ≥80% target coverage → upgrade (replace backbone with T2T — better telomere evidence, comparable size).
- Overlaps Tier 2 at 50–80% target coverage → read-coverage diagnostic. TACO maps the input reads to the backbone contig with a platform-specific minimap2 preset and compares median coverage in the T2T-covered region vs the uncovered region. If the uncovered region has very low coverage (< 30% of covered), the backbone is chimeric and the T2T is the real chromosome — TACO replaces the backbone. If coverage is normal, the backbone is real — TACO rejects the novel contig (adding it would increase BUSCO D). Configurable via
CHIMERIC_COV_RATIO(default 0.30). - Overlaps Tier 2 at < 50% → reject (insufficient overlap for any useful decision).
- No significant overlap → add as genuinely novel chromosomal region (with optional BUSCO D check:
NOVEL_MAX_D_RISE).
Thresholds: NOVEL_DUP_COV (default 0.80), NOVEL_DUP_ID (default 0.90), NOVEL_UPGRADE_TCOV (default 0.80).
purge_dups strategy is taxon-aware. Fungi use two-round purging (-2) with upstream-default chaining lengths, which is safer than short-match fungal tuning when the selected backbone is already close to the expected genome size. Vertebrate, animal, and insect genomes use two-round purging for high-heterozygosity haplotig/overlap cleanup. Plant genomes use conservative single-round purging with stricter sequence-level evidence to avoid collapsing homeologous sequences in polyploid species — use --no-purge-dups or PURGE_DUPS_MODE=skip if this is still too aggressive. TACO runs get_seqs -e by default, so only end duplications are removed, and rejects purged output if the taxon-specific size drop or expected genome-size floor suggests over-purging. If purging makes an overlarge assembly substantially closer to the expected genome size without falling below the floor, TACO accepts that drop instead of preserving duplicated sequence. Coverage cutoffs from calcuts are logged for debugging; override with PURGE_DUPS_CALCUTS. Advanced overrides: PURGE_DUPS_MODE (auto, single, two-round, skip), PURGE_DUPS_EXTRA_OPTS, PURGE_DUPS_GET_SEQS_OPTS, PURGE_DUPS_MAX_BP_DROP, and PURGE_DUPS_MIN_EXPECTED_RATIO.
--auto-mode n50 selects the assembly with the highest N50. This reproduces legacy behavior but may favor contiguous assemblies that lack completeness.
Step 12 (backbone refinement) adopts a backbone-first assembly philosophy with a two-tier confidence model:
- Tier 1 (Immutable): T2T contigs — contigs with verified telomere signal at both ends. These are treated as protected chromosomal anchors and are never replaced during rescue, unless
--allow-t2t-replaceis explicitly set. This protects the highest-confidence contigs from accidental degradation. - Tier 2 (Editable): Backbone contigs — gap-fill contigs that cover chromosomal regions not represented by T2T contigs. These may be replaced by telomere-bearing rescue donors if the replacement passes BUSCO trial validation.
Backbone contigs are preserved by default to maintain BUSCO completeness — purge_dups at Step 12H handles haplotig removal using read-coverage evidence. Novel T2T additions undergo a D-aware duplicate filter that either upgrades Tier 2 backbone contigs (replacing non-T2T with T2T) or rejects pure duplicates of Tier 1 contigs. Rescue donors must carry verified telomere signal.
- 12A — refresh Merqury QV scoring if needed.
- 12B — auto-select backbone assembler from the Step 10 comparison table.
- 12C — prepare cleaned backbone + chimera safety using two strategies: (a) size gate — contigs > 1.5× the largest individual assembler contig are flagged; (b) cross-assembly mapping — each protected contig is aligned against all other assembler outputs; contigs not well-covered (≥60%) by any single assembler's contig are flagged as potential chimeras. Configurable via
CHIMERA_MIN_CROSS_COV. - 12D — backbone-first classification and pool T2T analysis:
- 12D1 backbone telomere classification: classify backbone contigs as Tier 1 (T2T, immutable) or Tier 2 (non-T2T, upgradeable).
- 12D2 pool T2T analysis: align pool T2T contigs against backbone. Pool T2T redundant to Tier 1 backbone are discarded. Pool T2T that cover a Tier 2 backbone contig (≥80% target coverage, ≥85% identity) become upgrade donors. Others are candidate novel additions.
- 12D3 backbone self-dedup: disabled by default (preserves BUSCO completeness). purge_dups at 12H handles haplotig removal. Re-enable with
SELFDEDUP_ENABLE=1.
- 12E — telomere upgrade: pool T2T donors replace Tier 2 backbone contigs. Tier 1 (T2T) contigs are immutable — candidates targeting them are rejected unless
--allow-t2t-replaceis set. Each replacement is assigned a class:upgrade_tier2_to_t2t,replace_single_with_better, etc. - 12F — BUSCO trial validation: for each candidate, build a trial assembly and run BUSCO. Rejection thresholds are taxon-aware (fungi: 2% C-drop / 2% D-rise, plant: 4% / 6%, vertebrate: 3% / 4%). D-aware novel filter (12F2): novel T2T contigs that overlap Tier 2 backbone REPLACE the backbone (upgrade); those overlapping Tier 1 are rejected as duplicates; those with no overlap are added as genuinely novel. Optional BUSCO D check rejects additions that increase duplication excessively.
- 12G — final combine: backbone (with upgrades) + novel additions. Post-upgrade dedup protects all backbone contigs; only novel additions can be removed if redundant.
- 12H — purge_dups: taxon-aware haplotig/duplicate purging (skip with
--no-purge-dups). - 12I — automatic polishing: NextPolish2 for HiFi (k-mer-based via yak; skip with
--no-polish), Medaka for ONT (Racon fallback), Racon for CLR. - 12J — telomere-aware genome-size pruning: only non-telomeric contigs are removed when assembly exceeds the size budget. Telomere-bearing contigs are never pruned.
- 12K — final assembly coverage QC: maps the input reads to the final assembly with a platform-specific minimap2 preset, computes sliding-window coverage (default 5 kb), and flags zero-coverage gaps, very-low-coverage regions, and sudden coverage drops. Outputs
coverage_summary.tsv,weak_regions.tsv, andweak_regions.gff3(loadable in IGV). - 12L — "do no harm" safety comparison: compares final assembly vs original backbone for size, telomere count, and genome size deviation. If refinement degraded quality, both assemblies are preserved with a
refinement_warning.txtexplaining the issues.
TACO validates each telomere rescue candidate by building a trial assembly where one backbone contig is replaced by one donor contig, then running BUSCO with the same lineage selected by the user. Rejection is triggered by three independent BUSCO metrics: C% drop (completeness loss), M% rise (missing gene increase), and D% rise (duplicated BUSCO increase, catching retained haplotigs). Rejection thresholds are taxon-aware: fungi use strict thresholds (2% C-drop, 2% D-rise), plants use relaxed thresholds (4% C-drop, 6% D-rise, accounting for polyploidy), and vertebrates use moderate thresholds (3% C-drop, 4% D-rise). An additional safety check rejects replace_single_with_better candidates if telomere evidence weakens at either end after replacement (suspicious size drops >30% also trigger rejection). This greedy, sequential approach ensures that each accepted rescue improves or maintains assembly quality. The trial summary TSV includes replacement_class and D (duplicated %) columns for full traceability.
Trial BUSCO stdout/stderr logs are written to assemblies/rescue_trials/*.busco.*.log; final BUSCO logs are written to busco/*.busco.*.log. Each BUSCO attempt has a timeout controlled by STEP12_BUSCO_TRIAL_TIMEOUT (default 43200 seconds; set to 0 to disable). TACO tries BUSCO validation in offline mode by default and does not fall back to online lineage download/checks unless STEP12_BUSCO_ALLOW_DOWNLOAD=1, which avoids cluster runs hanging in BUSCO startup. If BUSCO is unavailable or wedged, set STEP12_SKIP_BUSCO_TRIAL=1 to resume Step 12 with structural rescue checks only.
After the rescued/combined assembly is produced, TACO runs purge_dups by default to remove leftover haplotigs, overlapping fragments, and residual duplicates. purge_dups strategy is taxon-aware and guarded against over-purging: fungi use two-round purging with upstream-default chaining lengths; vertebrate, animal, and insect genomes use two-round purging; plants use conservative single-round purging to preserve homeologs. TACO keeps the unpurged assembly if dups.bed is empty or if the purged output fails the taxon-specific size safety check. Coverage cutoffs from calcuts are logged; override with PURGE_DUPS_CALCUTS if automatic thresholds are incorrect. This is followed by automatic polishing selected from --platform: HiFi assemblies use NextPolish2 (maps HiFi reads to assembly with minimap2, sorts BAM with samtools, builds yak k-mer databases, then runs k-mer-based correction), Nanopore uses Medaka (falls back to Racon), and CLR uses Racon. Both steps can be skipped with --no-purge-dups and --no-polish.
Strict T2T pool contigs only replace backbone contigs directly when they cover most of the target backbone contig. For smaller but substantial partial T2T hits, TACO runs a read-coverage diagnostic on the unmatched backbone sequence. If the unmatched region has low coverage, the backbone is treated as duplicated/chimeric and replaced by the T2T contig; if coverage is normal or inconclusive, TACO keeps the backbone to preserve BUSCO gene content. Tiny telomere-repeat fragments are rejected as partial replacement donors.
TACO is designed for producing a best primary-style chromosome-level assembly, not a fully phased diploid or polyploid reconstruction. For strongly diploid or polyploid genomes, telomere-bearing contigs from different haplotypes may appear as rescue donors, and purge_dups may collapse alternative haplotigs. This is acceptable when the goal is a cleaned primary reference assembly.
TACO writes a GFF3 annotation file (final.merged.provenance.gff3) alongside the final assembly. Each contig gets one GFF3 record (type=contig) spanning its full length, with attributes documenting its full provenance chain: source_assembler (which assembler produced it), assembler_contig (the original contig name from that assembler before Step 11 pool renaming), source_type (assembler or quickmerge), role (backbone, upgrade_donor, or novel_t2t), replacement_class (for upgrade donors), replaced_contig (which backbone contig was replaced), and description (a human-readable summary like "Entire replacement: peregrine contig 'contig_5' replaced by canu contig 'tig00000015' (class: upgrade_tier2_to_t2t)").
For quickmerge-derived contigs, the GFF3 includes additional contig-level attributes (qm_assembler1, qm_assembler2) identifying the two source assemblers, plus child records (type=region) with Parent linking to the contig. Each region record spans the genomic coordinates contributed by a specific assembler, with source_assembler and assembler_contig showing the original source. For example, a quickmerge contig produced from canu × flye will have region records like "Region 1-500000 from canu contig 'tig00001'" and "Region 400000-900000 from flye contig 'contig_3'", enabling users to trace every base pair back to its assembler of origin.
A companion file pool_contig_provenance.tsv maps every pool contig back to its source assembler and original contig name, with extended columns for quickmerge contigs: qm_assembler1, qm_assembler2, and qm_regions (semicolon-delimited start-end:assembler:contig entries).
TACO maps the input reads back to the final assembly (Step 12K) and scans for assembly errors using a platform-specific minimap2 preset and a sliding-window coverage analysis (default 5 kb window). Three output files are produced:
coverage_summary.tsv — per-contig coverage statistics: median, mean, min, max, zero-coverage bases, and low-coverage bases. Use this to identify contigs with overall poor read support.
weak_regions.tsv — every flagged window with precise coordinates, contig total length, source assembler, source type, window median coverage, global median coverage, coverage ratio, and a flag classifying the issue: ZERO_GAP (>50% of window has zero coverage — likely a misjoin), VERY_LOW (window median < 15% of global — possibly chimeric), LOW (< 30% of global — suspicious drop), MIXED_LOW (>30% of bases at zero or below threshold — intermittent problems).
weak_regions.gff3 — the same weak regions as a GFF3 annotation file that can be loaded directly in genome browsers (IGV, JBrowse, etc.) alongside the final assembly FASTA. Each record has type=coverage_warning with the window median coverage as the score column (for color-coding by severity). Attributes include flag, window_median, global_median, ratio, source_assembler, source_type, and a human-readable description. Load final.merged.fasta as the genome and weak_regions.gff3 as an annotation track to visually inspect problem regions.
Example workflow for inspecting weak spots:
# In IGV or JBrowse:
# 1. Load final_results/final.merged.fasta as genome
# 2. Load final_results/final.merged.provenance.gff3 as track (provenance)
# 3. Load final_results/weak_regions.gff3 as track (coverage warnings)
# 4. Navigate to flagged regions to inspect assembly quality
| File | Produced by | Purpose |
|---|---|---|
assemblies/assembly_info.csv |
Step 10 | Unified assembler comparison table used for benchmarking and backbone selection |
final_results/assembly_only_result.csv |
Step 14B | Publication-facing summary for --assembly-only runs |
final_results/final_assembly.fasta |
Step 14A | Final purified assembly for downstream analysis — the file to use |
final_results/final.purified.fasta |
Step 13C | Same content, under its explicit name |
final_results/purify_excluded.fasta |
Step 13C | Sequence removed as foreign, preserved |
final_results/purification_report.tsv |
Step 13A | Per-contig signals, guards, tier and reason |
final_results/chimera_decisions.tsv |
Step 13B | Per-contig concordance verdict, breakpoint, spanning-read verdict, action |
final_results/final_result.csv |
Step 14A | Final report combining assembler metrics with the final refined assembly metrics |
final_results/final.merged.provenance.gff3 |
Step 12/14A | Contig-level and region-level provenance for the refined assembly |
final_results/coverage_summary.tsv |
Step 12K/14A | Per-contig read-depth QC summary for the final assembly |
final_results/weak_regions.tsv and .gff3 |
Step 12K/14A | Coverage-warning regions for manual inspection in IGV/JBrowse |
benchmark_logs/ |
--benchmark |
Optional reproducibility metadata, software versions, timing, and manifest files |
project_directory/
├── assemblies/
│ ├── assembly_info.csv # Unified comparison table
│ ├── canu.result.fasta # Normalized assembly outputs
│ ├── nextDenovo.result.fasta
│ ├── ...
│ ├── single_tel.replaced.debug.tsv # All rescue alignment hits
│ ├── single_tel.candidates.tsv # Plausible rescue candidates
│ ├── rescue_rejection_summary.txt # Rejection reasons
│ ├── quickmerge_validation.tsv # Quickmerge structural validation decisions
│ ├── telomere_pool_decisions.tsv # Per-contig pool classification decisions
│ ├── rescue_trial_summary.tsv # BUSCO trial results (with replacement_class, D%)
│ ├── final_merge.raw.fasta # Pre-purge combined assembly
│ └── *.busco/ # BUSCO results per assembly
├── final_results/
│ ├── final_result.csv # Full-mode final comparison report (Step 14A)
│ ├── final.merged.fasta # Refined assembly used internally for final QC
│ ├── final_assembly.fasta # Publication-facing PURIFIED assembly
│ ├── final.merged.provenance.gff3 # GFF3 provenance: full assembler tracing per contig
│ ├── pool_contig_provenance.tsv # Pool contig → assembler + original name mapping
│ ├── quickmerge_validation.tsv # Quickmerge structural validation decisions
│ ├── telomere_pool_decisions.tsv # Per-contig pool classification decisions
│ ├── rescue_trial_summary.tsv # BUSCO rescue trial results
│ ├── rescue_rejection_summary.txt # Rescue rejection summary
│ ├── single_tel.candidates.tsv # Candidate single-telomere rescue contigs
│ ├── selection_decision.txt # Backbone-selection formula and selected assembler
│ ├── coverage_summary.tsv # Per-contig coverage stats (median, mean, zero/low bp)
│ ├── weak_regions.tsv # Flagged weak windows with coords, source assembler, flag
│ ├── weak_regions.gff3 # GFF3 coverage warnings: load in IGV to see weak spots
│ ├── {backbone}.backbone.original.fasta # Original backbone (for do-no-harm comparison)
│ ├── refinement_warning.txt # Quality warnings if refinement degraded backbone
│ └── assembly_only_result.csv # Assembly-only comparison summary (Step 14B)
├── telomere_pool/ # Structured copy of telomere-pool intermediates
│ ├── protected_telomere_contigs.fasta
│ ├── t2t_clean.fasta
│ ├── single_tel_best_clean.fasta
│ ├── telomere_supported_best_clean.fasta
│ ├── pool_contig_provenance.tsv
│ └── telomere_pool_decisions.tsv
├── quast_out/ # Pre-refinement QUAST output
├── quast_final/ # Final-assembly QUAST output
├── logs/ # Per-step log files
├── temp/ # Organized temporary alignment/work files after cleanup
│ ├── merge/
│ ├── assemblers/ # Raw assembler work directories after cleanup
│ ├── telomere/
│ ├── polish/
│ ├── purge_dups/
│ ├── qc/
│ ├── busco/
│ └── log/
├── benchmark_logs/ # Optional timing/provenance data, only with --benchmark
│ ├── run_metadata.tsv
│ ├── run_manifest.json
│ ├── software_versions.tsv
│ ├── step_benchmark.tsv
│ ├── output_manifest.tsv
│ ├── methods_note.txt
│ └── run_summary.txt
└── version.txt # Software versions
TACO/
├── setup.py # pip install entry point
├── run_taco # Shell wrapper (no install needed)
├── taco/ # Python package
│ ├── __init__.py # Package metadata (v1.4.0)
│ ├── __main__.py # CLI entry point: taco [options]
│ ├── cli.py # Argument parsing
│ ├── pipeline.py # Pipeline runner, logging, benchmarking
│ ├── steps.py # Step implementations (0-14, including 14A/14B)
│ ├── utils.py # Shared utilities and FASTA I/O
│ ├── telomere_detect.py # Hybrid telomere detection engine
│ ├── telomere_pool.py # Telomere pool classification
│ ├── clustering.py # Minimap2-based contig clustering
│ ├── concordance.py # Cross-assembler split voting, fusion detection
│ ├── purify.py # Contaminant screening and chimera resolution
│ ├── backbone.py # Backbone selection and scoring
│ └── reporting.py # Final report generation
├── docs/ # Documentation and images
├── taco-env.yml # Conda environment
├── INSTALLATION.md
├── README.md
├── LICENSE
└── .gitignore
Canu reports master +XX changes or Step 1 fails with a Java error: The conda environment now includes openjdk>=11 to fix the Java runtime. If you still see this error, the bioconda canu may be a dev build — download a stable binary from https://github.com/marbl/canu/releases and place it on PATH. TACO detects dev builds and warns you; if canu fails, the pipeline continues with the remaining assemblers.
IPA or Peregrine skipped: These assemblers only support certain platforms. IPA requires PacBio HiFi; Peregrine does not support Nanopore. Use --platform to match your data type.
Raven skipped even after installing raven-assembler: Confirm that the environment where TACO is running is the same environment where Raven was installed. Activate the environment and check which raven. With micromamba, use micromamba activate taco before running TACO, or make sure /path/to/env/bin is on PATH. The Bioconda package is raven-assembler, but the executable TACO looks for is raven.
Telomere motif appears incorrect: Do not force --motif unless the telomere repeat is biologically known for your species. Use --taxon to select the appropriate preset instead. TACO's built-in motif families cover canonical TTAGGG, budding yeast TG1-3, Candida, plant TTTAGGG, and insect TTAGG repeats.
purge_dups or polishing not running: These tools must be installed in the conda environment. Use conda install -c bioconda purge_dups nextpolish2 yak racon medaka or skip with --no-purge-dups / --no-polish. For HiFi polishing, NextPolish2 and yak are both required. For Nanopore polishing, Medaka is preferred; if unavailable, Racon is used as fallback.
taco: command not found: Activate the TACO conda/micromamba environment and reinstall the package with pip install -e . from the repository root. If you prefer the wrapper, run ./run_taco from the repository directory.
Missing Python modules: TACO uses only the Python standard library. If you see import errors, ensure Python >= 3.8 is installed and that you are running the installed taco command or the repository-local ./run_taco wrapper.
Merqury not working: Merqury is enabled by default when merqury.sh + meryl are installed. The reads .meryl database is built automatically from input reads. If you have a pre-built database, use --merqury-db path/to/reads.meryl. Install with conda install -c bioconda merqury meryl. TACO writes organized outputs such as merqury/canu/canu.qv and also searches legacy flat prefixes such as merqury/canu.qv; if assembly.merqury.csv is empty, check the step log for the warning that lists which Merqury files were found. Nanopore and PacBio CLR runs log a warning because QV from non-high-accuracy reads can be underestimated; completeness and relative assembler ranking are still reported but should be interpreted cautiously. Disable with --no-merqury.
Merqury completeness exists but QV is NA: This means Merqury produced a completeness file but no parseable .qv file for that assembly. TACO reports NA rather than leaving the final report blank. Check the corresponding merqury/{label}/ directory and step log to confirm whether Merqury wrote a QV table under a non-standard name.
-s 14 produced the full report instead of assembly-only output: This is expected. Step 14A is the default full-mode report. Step 14B runs only with --assembly-only, for example taco ... --assembly-only -s 14.
An AI coding assistant (Anthropic Claude, via Claude Code) has been used during TACO's development, at the author's direction and reviewed before merging. It has assisted with bug fixing and with implementing features, including the chimera check and contaminant screening.
No sequencing data, assembly, or reference genome was generated or modified by an
AI tool. Results were verified by running the pipeline on real data and by the
test suite in tests/.
If you use TACO in a publication, please cite the software and archive the exact release used for reproducibility (e.g., via Zenodo).
TACO was developed at the Grainger Bioinformatics Center, Field Museum of Natural History, Chicago, Illinois, USA.
See docs/CHANGELOG.md for the full version history, including detailed notes on the v0.5.6 → v1.0.0 Bash-to-Python conversion.
TACO is released under the MIT License.
