Skip to content

Merge Strategies and Testing

Aleksey Ermolaev edited this page Sep 1, 2026 · 1 revision

When output.type is "single", ChoCallate merges per-sample consensus BCFs into one multi-sample file in the MERGE_OUTPUTS process.

Merge paths

Condition What runs
1 sample Filter only (bcftools filter)
2 or more samples Chunked merge via merge_bcf_tree.py (named pipes), then norm / filter / sort

Chunked pipe merge (N ≥ 2)

All multi-sample merges use the same path. Inputs are merged in two levels; chunk outputs stream through named FIFOs rather than temporary BCF files on disk.

  1. Split input list into consensus.cpu roughly equal groups (or N groups when N < consensus.cpu).
  2. Chunk merges (parallel): bcftools merge --force-samples --force-single --threads 1 -m all per group → FIFO.
  3. Final merge: reads all FIFOs to stdout.
  4. Post-process: norm / filter / sort.

Resource profile

Resource Count (typical)
Chunk merge jobs min(N, P) where P = consensus.cpu
Final merge job 1
Named pipes (FIFOs) min(N, P)
Peak concurrent merges min(N, P) + 1

Correctness testing

Identity check (50 samples, consensus.cpu: 8)

Compared chunked pipe merge against a single-pass flat bcftools merge -m all reference (same post-processing). ~4.7 GB total input BCFs.

Flat reference Chunked pipes
Variants 220,573 220,573
bcftools isec 0 only in flat 0 only in pipes

Result: identical — all 220,573 sites match.

Performance benchmarks (50 samples, consensus.cpu: 8)

Includes post-merge norm, filter, and sort.

Method Wall time Peak RAM Temp disk Variants
Flat reference 312 s 371 MB — 220,573
Chunked pipes 217 s 228 MB ~8 MB 220,573

At N ≤ consensus.cpu, chunked merge is only ~1–2% slower than flat (tested at N = 3, 5, 8); at N = 50 it is ~30% faster with lower RAM and minimal temp disk.

System limits (ulimit)

Chunked pipe merge needs open file descriptors and child processes. ulimit is a system setting — ChoCallate does not change it.

Recommended limits

N = sample count, P = consensus.cpu:

ulimit -u  ≥  2 × P + 16
ulimit -n  ≥  max(1024, 8 × N)
Samples (N) FIFOs Max concurrent merges (P=8) Suggested ulimit -u Suggested ulimit -n
10 8 9 48 1024
50 8 9 48 1024
100 8 9 48 1024
500 8 9 48 4096

Checking and raising limits

ulimit -n    # max open files
ulimit -u    # max user processes

If merge fails with Too many open files or Resource temporarily unavailable:

ulimit -n 4096
ulimit -u 4096

On shared clusters, set limits in your job script, container runtime, or system administrator config (e.g. /etc/security/limits.conf).