Tadpole Guide
Written by Brian Bushnell
Last updated October 10, 2026

Tadpole is a kmer-based assembler with graph simplification, optional multi-K fusion and bridging, error correction, and read extension.  It is designed for fast assembly and can handle extremely irregular or superhigh coverage distributions.  It can also selectively assemble a coverage 'band' from a dataset (for example, just areas with a depth between 1000x and 1500x).  These features make it useful for microbial single-cell data, viruses, organelles, and preliminary assemblies for use in binning, quality recalibration, insert-size estimation, and so forth.  Tadpole has no upper limit on kmer length.

Tadpole's parameters are described in its shellscript (tadpole.sh).  This file provides usage examples of various common tasks.


*Notes*


Memory:

Tadpole will, by default, attempt to claim all available memory.  It uses approximately 20 bytes per unique kmer for k=1-31, 30 bytes per kmer for k=32-62, and so forth in increments of 31.  However, with most datasets, the bulk of the kmers (and thus memory) are unwanted error kmers rather than genomic kmers.  It is possible to save memory by making Tadpole ignore low-quality kmers using the "minprob" flag (this ignores kmers that, based on their quality scores, have less than a specified probability of being error-free).  Alternatively, bloom filters can be used to screen low-depth kmers efficiently using the "prefilter" flag.  Also, memory will be used somewhat more efficiently if the "prealloc" flag is applied, which makes Tadpole allocate all physical memory immediately rather than growing as needed.  If Tadpole runs out of memory on a dataset despite using these options, you may consider using BBNorm to normalize or error-correct the data first.  Both of those will reduce the number of unique kmers in the dataset.


Processing modes and output streams:

The default mode is contig-building; reads are processed, kmers are counted, then contigs are made from kmers and written to a file.  The alternate mode is error correction / extension, which can be entered with the flag "mode=correct" or "mode=extend"; either of those modes supports both error-correction and extension (making the reads longer by assembling at their ends).  In contig mode, the reads will be processed once, and the contigs will be written to "out".  In correct or extend mode, the reads will be processed twice (once to count kmers, and once to modify the reads), and will be written to "out".


Threads:

Tadpole is fully multithreaded, both for kmer-counting and for the output phase (contig-building, error-correction, or extension).  You should allow it to use all available processors except when operating on a shared node, in which case you may need to cap the number of threads with the "t" flag.


Kmer Length:

Tadpole supports arbitrary integer kmer lengths with the default packed=t representation.  The legacy packed=f layout supports every K from 1-31, multiples of 2 from 32-62, multiples of 3 from 63-93, and so forth, rounding other values down.  There is a wrapper script, tadwrapper.sh, that will assemble a range of different kmer lengths to determine which is best.  Typically, about 2/3rds of read length is a good value for K for assembly.  For error-correction, about 1/3rd of read length is better.  In order to assemble with longer kmers, it is possible to error-correct and extend reads with short kmers (such as 31-mers), then use the longer extended (and potentially merged) reads to assemble with a longer kmer.  Longer kmers are better able to resolve repetitive features in genomes, and thus tend to yield more continuous assemblies.  The tradeoff is that longer kmers have lower coverage.


Shave and Rinse:

These flags examine the graph immediately after kmer-counting is finished, to remove kmers that cause error-induced branches.  Specifically, "shave" removes kmers along dead-end paths with very low depth that branch off from a higher-depth path, and "rinse" removes kmers along very-low-depth bubbles that start and end at branches off a higher-depth path.  Both are optional and can be applied to any processing mode.  They do not currently seem to make a significant difference.


Continuity and fragmentation:

Tadpole is designed to be conservative and avoid misassemblies in repetitive regions.  As a result, the assemblies may sometimes be more fragmented than necessary.  With sufficient coverage and read length, fragmentation can often be reduced by choosing a longer kmer.  Alternately, reducing the value of branchmult1 and branchmult2 (to, say, "bm1=8 bm2=2") can often increase the continuity of an assembly, though that does come with an increased risk of misassemblies.


Graph simplification:

Tadpole can explore the post-assembly contig graph with processcontigs=t.  Direct unitig merging is controlled by popdirect, while popindirect removes simple alternate paths only when both graph boundaries classify them as sequencing errors.  Unzipbubbles=t preserves both paths through an isolated biological bubble rather than selecting one.

Simpleomnitigs=t (alias omnitigs=t) replaces ordinary final contigs with maximal topology-safe walks through the oriented contig graph.  Shared sequence is intentionally duplicated around branches: a Y with common prefix A and alternatives B/C yields A-B and A-C, while an unresolved X yields safe left-middle and middle-right contexts without selecting a left-to-right pairing.  Traversal requires an exact reciprocal graph arc; inexact, one-way, and cyclic joins are reported and left unresolved.  This mode uses graph topology only and defaults off.

Graphcover=t (aliases pathcover and nonredundantpaths) instead emits a deterministic non-combinatorial path cover suitable for an ordinary assembly FASTA.  Ordinary contigs occur once; competing Y or bubble arms select one well-supported long path and retain the unselected contig separately.  A clean 2-by-2 X center is represented exactly twice, once on each edge of whichever boundary yields the stronger, longer products; the opposite boundary remains separate, so topology alone never guesses a left-to-right pairing.  A joined component must contain at least one contig that independently meets mincontig, preventing short-only graph debris from being promoted into the output while still allowing short internal bridges.  Exact reciprocal arcs are required, cycles are cut, and the mode defaults off.

For multi-K assembly, pass an ordered comma-delimited list such as k=96,124,32,64. The first K assembles by default; assemblek overrides it and consumes the first matching list occurrence, or precedes the list if absent. Later occurrences each perform eligible fusion followed by bridging, sharing one count table. Repeated Ks are intentional: k=96,124,64,32,96 revisits96 after32. Fusion still requires K below assemblek; bridging may use larger, smaller, or equal K. Explicit fusek and bridgek lists filter the ordered list, and every requested K must appear there. Without a k list, phases follow fusek then additional bridgek values after assembly. korder=legacy restores sorting/deduplication, largest-K assembly, all-fusion-before-all-bridge ordering, and assembly-K final graph defaults for historical comparisons.

Graphk selects the final contig-graph resolution and defaults to the last listed K (the last constructed phase when no list is supplied). A matching final table is reused; an explicit different graphk requires one more count-table load. Thus k=96,124,32,64 can finish at graphk=64 with four loads, while the explicit return to96 uses five. Final graph processing is not merely file export: bubble popping, optional repeat resolution, classification/filtering, and simpleomnitigs or graphcover can change the emitted assembly. Neural/path fusion reads raw explicit counts before pruning/washing, then bridging uses the same cleaned table. Only one count table is live at a time. Shorter or repeated schedules should be selected by measured assembly quality and runtime, not by assuming more passes are better.

Resolverepeats=t experimentally resolves a different structure: a closed 2-by-2 X junction made by two paths sharing one repeat contig.  Tadpole rereads the primary input and requires individual reads to traverse the incoming contig, the repeat, and the outgoing contig.  Both inferred paths must have at least repeatminsupport spanning reads, conflicting traversals must not exceed repeatmaxnoise, and each accepted path must have more support than alternatives sharing either side.  One physical read contributes at most once to a proposed path.  The defaults require two reads per path and no conflicts.  Topology or edge depth alone never resolves an X.  The feature is disabled by default, requires named input files rather than stdin, and currently uses single-read evidence rather than mate-pair linkage.


Coverage safeguards for multi-K joins:

fusecoverageratio and graphmergecoverageratio are independent, optional checks using the stored whole-contig mean kmer depths.  Both default to 0 (disabled); enabled values must be finite and at least 1.  A pair is accepted by a coverage check only when both depths are positive and higher <= lower * ratio, including equality.  All other topology, sequence, and optional neural checks still apply.

fusecoverageratio checks frozen reciprocal exact-overlap fusion proposals before the path and neural vetoes, including final graph-K overlap fusion.  It never chooses a replacement partner and does not filter gap bridging.  graphmergecoverageratio instead checks ordinary direct merges during final Multi-K graph simplification, using the depths at merge time.  It does not filter initial assembly, cross-K fusion/bridging, indirect bubble removal, or graphcover/simpleomnitigs path extraction.  Enabling it requests final graph processing; an already loaded matching final table is reused.

These checks help avoid connecting different copies through a high-depth repeat.  The bundled fusion NN measures local depth percentiles around a candidate junction and original-tip entropy, not whole-contig mean depth.  Its local reference-support training labels do not prove that several accepted joins belong to the same repeat copy.  The coverage guards provide complementary information and can also be used without a network.  They are not proof of copy identity and may reject correct joins across genuine coverage changes, particularly in mixed or uneven-depth data.

Both ratios were tested at 1.75 with the bundled NN at cutoff 0.667098 on 100 simulated bacterial genomes at 60x, using k=96,124,64,32.  Global/local misassembly totals changed from 38/3 with the NN alone to 21/0 with both guards.  Median NGA50 and NGA90 were unchanged; mean NGA50 was about 0.59% lower.  Six genomes were used for diagnosis, so this was a regression panel rather than untouched validation.  These results do not establish a universal threshold or a new default.

Example for interleaved paired reads (replace /path/to/bbtools with the installation path):
tadpole.sh in=reads.fq.gz out=assembly.fa interleaved=t k=96,124,64,32 assemblek=96 minprob=0 minprobmain=f fusenet=/path/to/bbtools/networks/tadpole_fusion.bbnet fusencutoff=0.667098 fusecoverageratio=1.75 graphmergecoverageratio=1.75

This schedule uses four count-table loads with the final graph at K32.  The guards do not allocate another evidence table.  The full benchmark additionally fixed t=8, buildthreads=1, hashkmers=explicit, prefilter=f, and prealloc=f; the command above is a usage example, not a complete benchmark recipe.  Set either ratio to 0 to disable that guard independently.


*Usage Examples*

Automated paired-read assembly with TadPipe:
tadpipe.sh in=reads_R1.fq.gz in2=reads_R2.fq.gz out=assembly.fa -Xmx16g t=8

The reads must already be adapter-trimmed, filtered, and quality-score calibrated.  TadPipe performs sequence-based paired deduplication (including SRA names without optical coordinates), overlap correction, Clumpify correction of both mates, Tadpole correction, overlap and staged kmer-assisted merging, read extension, then ordered A124 assembly.  For interleaved pairs, omit in2.  This starting recipe targets roughly 150bp bacterial isolate libraries, not arbitrary sequencing platforms or read lengths.

Every phase runs in a fresh JVM through its BBTools launcher; shared static settings cannot carry over between phases.  -Xmx limits each child while the coordinator uses 256MB.  Phases run serially to reuse the memory budget.  The default assembly uses k=124,300,96,64,32, the bundled fusion NN at 0.667098, and the two optional coverage guards at 1.75.  The A124 and coverage sections below explain the evidence and limitations.  No new default is imposed on standalone tadpole.sh.

Use temp=/path/to/scratch to choose the parent of the unique work directory.  Commands and one log per phase are retained there.  Successful runs delete intermediate FASTQs by default; delete=f retains them.  Failures stop the pipeline and retain intermediates for diagnosis.  The final assembly is published only after all processing stages succeed.  dryrun=t validates paths and records the commands without launching processing.  Existing final outputs are protected unless overwrite=t is requested.

Stage switches such as dedupe=f, clump=f, rem=f, or extend=f permit controlled comparisons.  Phase-prefixed options expose finer control: dedupe_subs=0 requires exact duplicate matching; clump_passes=6 changes correction passes; extendu_k=96 changes only unmerged-read extension.  k=124,96,64,32 omits the long-read traversal pass.  assemble_fusecoverageratio=0 and assemble_graphmergecoverageratio=0 disable the corresponding guards for strongly uneven libraries.  Use nn=f to disable neural fusion scoring.  Custom assemble_fusenet requires an explicit assemble_fusencutoff.  TadPipe owns stage filenames and pairing; use top-level in/in2/out, not phase-prefixed file redirection.

Bare k= and assemblek= go ONLY to the final assembly; they do not change the kmer lengths used for error correction, merging, or read extension.  graphk=, bridgek=, and fusek= are also final-only aliases.  The equivalent prefixed spellings are assemble_k=, assemble_assemblek=, assemble_graphk=, assemble_bridgek=, and assemble_fusek=.  The last occurrence wins across bare and prefixed spellings; K order and repetitions are preserved.  Changing k alone retains the pipeline's assemblek=124 default, so specify both when changing initial contigging K.

For example, to assemble initially at K96 and then traverse at K124,300,64,32:
tadpipe.sh in=interleaved.fq.gz out=assembly.fa k=96,124,300,64,32 assemblek=96 -Xmx16g t=8

Other final assembly controls use assemble_<Tadpole option>=<value>, such as assemble_mincontig=500, assemble_mcs=2, assemble_mce=1, assemble_prefilter=t, or assemble_fusencutoff=0.7.  These override the final Tadpole defaults without affecting earlier phases.  To adjust those phases, use their own prefixes, such as ecc_k=55, extendm_k=124, or extendu_k=96.  Input/output/pairing redirections remain pipeline-managed, and unknown options are rejected by the receiving tool.  Use dryrun=t to inspect the exact commands before processing.

Preprocessing schedules for workflow comparisons:

remk=124,145,93 sets the ordered read-extension-merging passes after the initial overlap merge.  It accepts arbitrary positive K values and repeats.  remk=none or rem=f disables REM without disabling overlap merging.  remextend=auto preserves limits of 120 for K124, 140 for K145, and 100 for other K values; alternatively, supply one nonnegative integer for every pass or one comma-separated value per remk entry.  The K93 pass begins with strict=t.  Pass-specific prefixes override this default: merge_ applies to all merging, merge<K>_ to a scheduled K, and rem<N>_ to one REM pass numbered from 1 (not counting the overlap pass).  Specificity wins in that order, regardless of CLI order between groups.  Repeated passes get unique output/log names and each sees all preceding merged evidence.  When changing the schedule, remove any K/pass-specific override that no longer names an enabled pass.  Disabled phases ignore their overrides.

For example (an experimental configuration, not a recommended depth preset):
tadpipe.sh in=interleaved.fq.gz out=assembly.fa ecc_k=47 ecc_rbb=t \
    remk=64,96,64 remextend=40,80,40 rem3_strict=t \
    extendm=f extendu_k=64 k=64,96,32 assemblek=64 -Xmx16g t=8

extendm=t and extendu=t independently enable extension of merged and unmerged reads; extend=f overrides both switches.  Merged extension also requires merging to be enabled.  Whether one or both sets are extended, each extension uses the unextended opposite set as additional evidence.  The final assembly receives the extended version only for enabled stages; disabling a stage never drops that read set.

Useful controls already available through the phase prefixes include ecco_k=31, clump_passes=4, ecc_k=62, ecc_wash=t, ecc_ldf=0.15, ecc_tossdepth=1, ecc_tu=t, ecc_rbb=f, and ecc_tossjunk=f.  Those are the current pipeline/native defaults, not tuned metagenome settings.  Residual filtering defaults are qtrim_trimq=15, qtrim_maq=14, qtrim_minlen=90 and qtrim_maxns=1.  Extension defaults are extend_mce=4, extendm_k=145, extendm_el=10, extendm_er=10, extendu_k=124, extendu_el=10 and extendu_er=0.  These parameters are independent of bare k/assemblek, which remain final-assembly-only.

Use ordinary config=files (one flag=value per line) to save high-, mid-, low-depth and metagenome experiment recipes; put -Xmx on the command line.  No validated regime presets or automatic profile classifier are supplied yet.  The no-override pipeline remains unchanged.  Inspect the generated commands with dryrun=t and measure recovery, contiguity and misassemblies before promoting a recipe.

Assembly:
tadpole.sh in=reads.fq out=contigs.fa k=93

This will assemble the reads into contigs.  Each contig will consist of unique kmers, so contigs will not overlap by more than K-1 bases.  Contigs end when there is a branch or dead-end in the kmer graph.  The specific triggers for detecting a branch or dead-end are controlled by the flags mincountextend, branchmult1, branchmult2, and branchlower.  Contigs will only be assembled starting with kmers with depth at least mincountseed, and contigs shorter than mincontig or with average coverage lower than mincoverage will be discarded.

Multi-K isolate assembly starting at K124:

For quality-controlled, error-corrected Illumina libraries with reads around 150bp or longer, assemblek=124 is a practical starting point.  It builds the initial contigs below the original read length, then explores connections at other K values.  This avoids requiring every initial contig to have long merged-read support, which may be patchy in real libraries.  It is a recommendation, not a universal optimum; substantially shorter reads or very low coverage may need a lower initial K.

Set the bundled fusion model's actual installation path once:
FUSENET=/path/to/bbtools/networks/tadpole_fusion.bbnet

For ordinary paired reads without a substantial long merged/extended component:
tadpole.sh in=reads_R1.fq.gz in2=reads_R2.fq.gz out=assembly.fa \
    assemblek=124 k=124,96,64,32 minprob=0 minprobmain=f \
    fusenet="$FUSENET" fusencutoff=0.667098 \
    fusecoverageratio=1.75 graphmergecoverageratio=1.75

For merged and extended reads, with the remaining unmerged reads retained as additional kmer evidence:
tadpole.sh in=merged_ext1.fq.gz extra=unmerged_ext1.fq.gz interleaved=f out=assembly.fa \
    assemblek=124 k=124,300,96,64,32 minprob=0 minprobmain=f \
    fusenet="$FUSENET" fusencutoff=0.667098 \
    fusecoverageratio=1.75 graphmergecoverageratio=1.75

The first command uses four count-table loads; the second uses five, with only one table live at a time.  In the second, K300 bridges existing contigs where sufficiently long reads support traversal; it does not repeat initial contig assembly or perform overlap fusion above assemblek.  Later K96, K64, and K32 phases perform eligible fusion followed by bridging.  Leave graphk at its default to reuse the final K32 table rather than adding another load.

Both read sets contribute counts to initial assembly and subsequent passes.  interleaved=f treats merged reads as single sequences; mate relationships in the extra file are not used by this assembly recipe.  If no reads span 300 bases, omit the K300 pass; even when some do, usefulness depends on their coverage through the region.  These commands assume preprocessing has already removed adapters and corrected errors.  minprob=0 minprobmain=f keeps the NN's count features consistent with its training rather than discarding kmers by their quality-score products.

The guarded A124 schedules were compared on three simulated bacterial diagnostic genomes, not a broad real-library validation set.  Adding K300 improved NGA50 in all three without global or local misassemblies in those runs.  Higher initial K gave substantially higher NGA50 on two, nearly the same on the third, and slightly higher recovered genome fractions on all three.  A124 is recommended here as a practical compromise for variable real-library coverage, not because it won every measured metric.  The 1.75 coverage guards are optional; they can reject genuine joins across coverage changes.  Set either ratio to 0 to disable that check, particularly when evaluating strongly uneven or mixed libraries.

See pipelines/assemble_polyg_isolate_v1.sh for an example of staged BBMerge merging and Tadpole extension before the long-read command.  The pipeline is a site-specific reference, not a ready-to-run universal preprocessing script.

Read-threaded repeat resolution:
tadpole.sh in=reads.fq out=contigs.fa k=93 resolverepeats=t

This performs the ordinary assembly, builds the contig graph, then rereads the input to resolve only closed 2-by-2 repeats whose two paths are directly supported by spanning reads.  Repeats too long for one read to span are left unchanged.


Error correction:
tadpole.sh in=reads.fq out=ecc.fq mode=correct k=50

This corrects the reads and outputs corrected reads.  Correction is handled by two algorithms, "pincer" and "tail".  Pincer corrects errors bidirectionally, using kmers on the left and right; therefore, it can only work on bases in the middle of the read, at least K away from either end.  Tail is not as robust, but is able to work on the ends of the read.  So, it's best to leave them both enabled, in which case the middle bases are corrected with pincer, and the end bases are corrected with tail.


Error marking:
tadpole.sh in=reads.fq out=ecc.fq mode=correct k=50 ecc=f mbb=2

This will not correct bases, but simply mark bases that appear to be errors by replacing them with N.  A base is considered a probable error (in this mode) if it is fully covered by kmers with depth below the value (in this case, 2).  Mbb and ecc can be used together.


Read Extension:
tadpole.sh in=reads.fq out=extended.fq mode=extend k=93 el=50 er=50

This will extend reads by up to 50bp to the left and 50bp to the right.  Extension will stop prematurely if a branch or dead-end is encountered.  Read extension and error-correction may be done at the same time, but that's not always ideal, as they may have different optimal values of K.  Error-correction should use kmers shorter than 1/2 read length at the longest; otherwise, the middle of the read can't get corrected.
