Hi all,
I'm processing paired-end NovaSeq metabarcoding data (marine vertebrate 16S marker, MarVer3 primers; ~245 bp amplicon, ~209 bp insert, sequenced 2×250) and discovered that my cutadapt trim-paired step was leaving the 5' primer attached on a large fraction of surviving reads. I'd like to confirm my understanding of the cause and validate my proposed fix before I re-run the whole downstream pipeline.
Original command (QIIME2 2026.1):
qiime cutadapt trim-paired \
--i-demultiplexed-sequences paired-end-demux.qza \
--p-front-f AGACGAGAAGACCCTRTG \
--p-adapter-f GGGATAACAGCGCAATCC \
--p-front-r GGATTGCGCTGTTATCCC \
--p-adapter-r CAYAGGGTCTTCTCGTCT \
--p-error-rate 0.1 \
--p-overlap 3 \
--p-discard-untrimmed \
--p-cores 4 \
--o-trimmed-sequences trimmed-seqs-default.qza \
--verbose
Here --p-front-f/--p-front-r are the forward/reverse primers (5') and --p-adapter-f/--p-adapter-r are the reverse-complements of the opposite primers (the 3' read-through, since reads are longer than the insert).
The problem. I exported the trimmed reads and re-scanned them for the 5' primer using cutadapt with --action=none (detect-only, no trimming), applying the same error rate and overlap:
cutadapt -g AGACGAGAAGACCCTRTG -e 0.1 -O 3 --action=none -o /dev/null allR1.fastq.gz
cutadapt -g GGATTGCGCTGTTATCCC -e 0.1 -O 3 --action=none -o /dev/null allR2.fastq.gz
Result: 42.5% of R1 reads and 43.4% of R2 reads still had the 5' primer present after trimming.
My understanding of the cause: Passing --p-front-f and --p-adapter-f as separate adapters makes cutadapt treat them as alternatives: with --p-times at its default of 1, it removes only the single best-scoring match per read. Since most reads contain both the 5' primer and the 3' read-through, on ~43% of reads the 3' read-through scored best and was removed, leaving the 5' primer in place. Because some adapter was removed, the read was marked "trimmed," so --p-discard-untrimmed kept it. In other words, --p-discard-untrimmed here enforces "some adapter was removed," not "the 5' primer was removed."
Proposed fix — linked adapters:
qiime cutadapt trim-paired \
--i-demultiplexed-sequences paired-end-demux.qza \
--p-front-f "AGACGAGAAGACCCTRTG...GGGATAACAGCGCAATCC" \
--p-front-r "GGATTGCGCTGTTATCCC...CAYAGGGTCTTCTCGTCT" \
--p-error-rate 0.1 \
--p-overlap 3 \
--p-discard-untrimmed \
--p-cores 4 \
--o-trimmed-sequences trimmed-seqs-linked.qza \
--verbose
My reasoning: joining the 5' primer and 3' read-through with ... on --p-front-f/--p-front-r makes the 5' component the required part of a linked adapter, so a read is only marked "trimmed" if the primer was found — and --p-discard-untrimmed then discards any pair lacking the primer, while the optional 3' component still strips the read-through in the same pass. I've dropped --p-adapter-f/--p-adapter-r since both ends now live inside the front strings, and left --p-times at 1.
My questions:
- Is switching to linked adapters the correct and recommended fix for this primer-retention issue, and is my explanation of the separate-adapter behaviour accurate?
- In the QIIME2 wrapper, is the 5' component of a linked adapter defined via
--p-front-ftreated as required by default (so--p-discard-untrimmedenforces primer presence)? I want to be sure the required/optional default is what I expect. - Is the 5' component anchored to the read start by default, or should I prepend
^(e.g.^AGACGAGAAGACCCTRTG...) to force anchoring? - Anything else I should verify — e.g. is re-running the
--action=nonescan on the new output (expecting ~0% primer retention) a sound way to confirm the fix?
Thanks very much for any guidance!