Skip to main content

✂️ CutSeq

Pypi Releases Downloads

CutSeq is a tool that provides an efficient wrapper for the cutadapt tool, which is powerful in handling various types of NGS libraries. Due to the complexities involved in NGS library preparation methods, mutiple operations are necessary to process sequencing reads correctly.

Take SMARTer® Stranded Total RNA-Seq Kit v3 as an example, at least 9 operations are required.

For Read 1:

  1. Remove the Illumina p7 adapter from the end of the sequence.
  2. Remove 14 nt (8+3+3) at the rightmost position of the sequence, representing UMI and linker sequence from the beginning of read 2. This is required when the library insert size is shorter than the sequencing length.
  3. Remove poly-T sequences at the beginning of the sequence (read 1 is oriented in reverse to the RNA, hence a polyA tail appears as a leading polyT sequence).
  4. Remove low-quality bases from right to left.

For Read 2:

  1. Remove the reverse complement Illumina p5 adapter from the end of the sequence.
  2. Extract the 8 nt UMI sequence from the beginning of the sequence and append it to the read name for downstream analysis.
  3. Mask a 6 nt linker sequence at the leftmost position immediately after clipping the UMI sequence.
  4. Remove poly-A sequences at the end of the read.
  5. Remove low-quality bases from right to left.

These operations must be performed in the correct order. The limitations of the cutadapt tool make it challenging to configure these operations in a single command, often leading to errors unnoticed in some publications.


To solve this by using cutadapt, we can run multiple cutadpat insitent sequentially or pipe multiple commands together. But this waste lots of IO and computational resource. I am thinking there a more eligent API to make things easy. Then comes this toy project. -- What you need is only one parameter which spcific what the library would looks like.

CutSeq overcomes these limitations by enabling multiple operations in a automatical manner to ensure accuracy and efficiency.

How to install?

pip install cutseq

How to use?

Execute adapter trimming by providing a single parameter and your input files:

cutseq -A TAKARAV3 test_R1.fq.gz test_R2.fq.gz

Alternatively, you can specify a custom adapter scheme in the grammar format:

cutseq -A "ACACGACGCTCTTCCGATCTXXX-XXXXXXNNNNNNNNAGATCGGAAGAGCACACGTC"

The customized scheme can be explained by the diagram above. The scheme is a top-strand molecular map: you write the library as one DNA strand, 5' to 3', with no spaces:

  • The part left of the insert marker (+ - :) is read by Read 1 as-is (R1 sequences the top strand 5' -> 3').

  • The part right of the insert marker is the molecule's 3' continuation, written top-strand 5' -> 3' (from the insert toward p7). Read 2 sequences the bottom strand, so the engine matches it as the reverse complement of that part automatically — e.g. a right-hand AGATCGGAAGAGCACACGTC is matched on Read 2 as GACGTGTGCTCTTCCGATCT.

  • The outermost parts on both ends are the Illumina adapters (uppercase ACGT...).

  • The UMI sequence is the random sequence represented by N (e.g. NNNNNNNN / N8), captured into the read name.

  • The masked sequences are represented by X (e.g. XXXXXX / X6), trimmed but not captured. These can be random tails from template switching or other artifacts.

  • Homopolymer tails are trimmed with the dot form AAA...AAA / TTT...TTT / GGG...GGG. The 5'/3' direction is auto-detected from the scheme layout: a run at a read start (first token, or right after the outer sequencing adapter/primer) trims the 5′ (leftmost-anchored — e.g. a template-switching poly‑G stretch), while a run elsewhere trims the 3′ (e.g. a poly‑A tail). B10 style (G10) sets the minimum run length.

  • Inline barcodes are written in lowercase (acgt...) and are matched and captured.

  • The center parts are the actual library sequence, split by +, -, or ::

    • + means the library is in the forward (sense) orientation,
    • - means reverse (antisense) orientation,
    • : means the library orientation is unknown (unstranded).
  • A 3' read-through adapter (the adapter that appears on the opposite read) is trimmed automatically from the other end of each read.

Numeric shorthand (N8, X6) is equivalent to the expanded run form (NNNNNNNN, XXXXXX).

Customizing read names

By default, captured UMIs/barcodes are appended to the read name with _ (e.g. @READID_CTATTAAAAA), exactly as the legacy engine named reads. You can customize this with --rename (--name-format is an accepted alias). It supports cutadapt's brace variables ({id}, {header}, {comment}, {cut_prefix}, {cut_suffix}, {adapter_name}, {match_sequence}, {rc}) plus positional captures — the individual UMIs and inline barcodes in scheme order:

# Label each captured part; {1},{2},{3} are the 1st/2nd/3rd capture
cutseq -A INLINE --rename '{id}_BC1:{1}_BC2:{2}_umi:rc({3})' in_R1.fq.gz in_R2.fq.gz

Transform functions can wrap any capture and nest, and are case-insensitive:

  • rc(x) reverse complement (also rev(x) reverse, comp(x) complement only)
  • upper(x), lower(x), len(x)
  • canon(x) — canonical UMI form min(x, rc(x)) for UMI collapsing
  • left(x,k), right(x,k), slice(x,a,b) — substring helpers (slice is 1-based, inclusive)
  • examples: upper(RC({1})), rc(upper({2})), left({2},6), slice({1},1,4)

In paired mode {r1.1} / {r2.1} force a specific read; an unprefixed capture resolves to its anchor read (left-side captures → R1, right-side → R2), so both mates carry the same extracted value.

Use --rename to reproduce the old --capture-separator ':' behavior too: --rename '{id}:{1}:{2}' inserts : between the captured parts.

When no --rename is given, the default naming (captures appended with _) reproduces legacy output byte-for-byte, so existing pipelines do not change.

Complex example: spatial barcode arm (DBiT-seq)

Spatial libraries put several fixed-length barcodes on one arm. In DBiT-seq (deterministic barcoding in tissue, 50×50 grid), the barcode read (R2) walks:

handle(22) | BarcodeB(8) | linker(30) | BarcodeA(8) | linker(30) | UMI(12) | polyT | cDNA

while Read 1 is the cDNA read, preceded by a template-switch oligo (TSO). Everything fits in one command:

cutseq -A DBITSEQ \
       -R '{id}_BCB:{3}_BCA:{2}_UMI:{1}' \
       -O mysample R1.fq.gz R2.fq.gz

Built-in scheme (cutseq -A DBITSEQ):

AAGCAGTGGTATCAACGCAGAGT : N12 AGTCGTACGCCGATGCGAAACATCGGCCAC
N8 CGAATGCTCTGGCCTCTCAAGCACGTGGAT N8 AGATGCGAGAAGCCAACGCTTG
  • The TSO (left of :) is R1's real read-5′ scaffold — R1 actually starts with it, downstream of the R1 sequencing primer — so it is trimmed off R1.
  • The barcode arm (right of :) is walked on R2 as its reverse complement: handle trimmed, then BarcodeB (8 nt, 1st capture → {3}), linker 2 trimmed, BarcodeA (8 nt, 2nd capture → {2}), linker 1 trimmed, UMI (12 nt, 3rd capture → {1}). Each captured part is written into the read header as @READID_BCB:…_BCA:…_UMI:….
  • M6AARTR is kept as a deprecated alias; --r1-primer / --r2-primer are informational only — reads start downstream of the priming site, so the sequencing primers themselves are never trimmed.

The same library as a fully inline custom scheme:

cutseq -A "AAGCAGTGGTATCAACGCAGAGT:N12AGTCGTACGCCGATGCGAAACATCGGCCACN8CGAATGCTCTGGCCTCTCAAGCACGTGGATN8AGATGCGAGAAGCCAACGCTTG" \
       -R '{id}_BCB:{3}_BCA:{2}_UMI:{1}' -O mysample R1.fq.gz R2.fq.gz

Full construct, top strand 5′→3′:

P5(29) | i5(8) | R1-primer(34) | TSO(22) | insert | polyA/T | UMI(12)
| rc(L1)(30) | BarcodeA(8) | rc(L2)(30) | BarcodeB(8) | rc(handle)(22)
| rc(R2-primer)(34) | i7(8) | rc(P7)(24)

Inline barcodes and auto-detection

Inline barcodes are written in lowercase (acgt...) and are matched and trimmed. If you write a barcode in uppercase by mistake, it would merge with the adjacent sequencing primer into one adapter run. CutSeq detects this:

  • The two outermost adapters of a scheme are checked against a curated database of Illumina / BGI (MGI) sequencing primers (see cutseq --list-primers).
  • Any fixed uppercase sequence adjacent to (or between) recognized primers is reclassified as an inline barcode, with a warning.
  • Genuinely custom schemes (no known primers at the ends) are never altered.

Disable with --no-auto-inline.

Discarding reads with a reason tag

A single discard output captures all reads that fail QC, with the reason stored in the read name:

cutseq -A SMALLRNA -d discarded_R1.fq.gz discarded_R2.fq.gz in_R1.fq.gz in_R2.fq.gz

Discarded reads carry a reason=... tag in their name:

  • reason=too_short — shorter than --min-length after trimming,
  • reason=too_many_n — exceeds --max-n,
  • reason=low_quality — mean Phred quality below --min-avg-quality,
  • reason=no_barcode — missing an expected inline barcode (only with --ensure-inline-barcode).

--ensure-inline-barcode routes reads that lack the scheme's inline barcodes to the discard output; it requires the scheme to declare inline barcodes. When no -d/-O is given, discard files are auto-named from the input files.

How it works

CutSeq compiles a library scheme once into a lazy graph of native cutadapt modifiers (adapter cutters, renamers, quality trimmers) and runs them in a single cutadapt pass — no intermediate I/O. The modifier chain is data-driven: each grammar token kind maps to a 5' / 3' / single-end emitter, so new token kinds are added with one registry entry. Output from the grammar engine is verified to match the legacy engine exactly across all built-in schemes in both paired- and single-end mode.

More details can be found in the document

TODO

[ ] support more library scheme

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cutseq-0.0.70.tar.gz (1.7 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cutseq-0.0.70-py3-none-any.whl (42.3 kB view details)

Uploaded Python 3

File details

Details for the file cutseq-0.0.70.tar.gz.

File metadata

  • Download URL: cutseq-0.0.70.tar.gz
  • Upload date:
  • Size: 1.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for cutseq-0.0.70.tar.gz
Algorithm Hash digest
SHA256 8574f0114fdee6403093c77d8bc37432b289b3712aa289473cc5b8d5eeb55e4d
MD5 b4ef4d5f43022286074d5a0dd01957c4
BLAKE2b-256 d4317ab3b22db348e8e5fe7bde7b280b916a86244e1bc3689cbe2482e07be3bf

See more details on using hashes here.

File details

Details for the file cutseq-0.0.70-py3-none-any.whl.

File metadata

  • Download URL: cutseq-0.0.70-py3-none-any.whl
  • Upload date:
  • Size: 42.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for cutseq-0.0.70-py3-none-any.whl
Algorithm Hash digest
SHA256 6ed1c5be3fb3028a7fd04ebac6c7db8adaa65b9d234f04b941053a859e296f0b
MD5 287a89a171ae6a8acfe92bc9919297ae
BLAKE2b-256 93a293b692b86bfae3631ccd2135f354130c14b73bca7eece00f344e054c3250

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.0.70 This release

2 files

0.0.68

2 files

0.0.67

2 files

0.0.66

2 files

0.0.65

2 files

0.0.64

2 files

0.0.63

2 files

0.0.62

2 files

0.0.61

2 files

0.0.60

2 files

0.0.59

2 files

0.0.58

2 files

0.0.57

2 files

0.0.56

2 files

0.0.55

2 files

0.0.54

2 files

0.0.53

2 files

0.0.52

2 files

0.0.51

2 files

0.0.50

2 files

0.0.49

2 files

0.0.48

2 files

0.0.47

2 files

0.0.46

2 files

0.0.45

2 files

0.0.44

2 files

0.0.43

2 files

0.0.42

2 files

0.0.41

2 files

0.0.40

2 files

0.0.39

2 files

0.0.38

2 files

0.0.37

2 files

0.0.36

2 files

0.0.35

2 files

0.0.34

2 files

0.0.33

2 files

0.0.32

2 files

0.0.31

2 files

0.0.30

2 files

0.0.29

2 files

0.0.28

2 files

0.0.27

2 files

0.0.26

2 files

0.0.25

2 files

0.0.24

2 files

0.0.23

2 files

0.0.22

2 files

0.0.21

2 files

0.0.20

2 files

0.0.19

2 files

0.0.18

2 files

0.0.17

2 files

0.0.16

2 files

0.0.15

2 files

0.0.14

2 files

0.0.13

2 files

0.0.12

2 files

0.0.11

2 files

0.0.10

2 files

0.0.9

2 files

0.0.8

2 files

0.0.7

2 files

0.0.6

2 files

0.0.5

2 files

0.0.4

2 files

0.0.3

2 files

0.0.2

2 files

0.0.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page