mcpField
F
fastp-fastq-preprocessing

fastp-fastq-preprocessing

github.com/jaechang-hitsデータ・データベース38439 回インストール6 日前に更新
リポジトリ

fastp-fastq-preprocessing について

Illumina シーケンス解析向けの FASTQ 前処理スキルです。fastp により、アダプター除去、品質フィルタリング、QC レポート作成をマルチスレッドで一度に行います。シングルエンドとペアエンドに対応し、ペアエンドではアダプターを自動検出できます。

主な機能

  1. 01アダプターと低品質塩基の除去
  2. 02ペアエンドアダプターの自動検出
  3. 03品質と長さによるリードのフィルタリング
  4. 04polyX テールの除去
  5. 05HTML と JSON の QC レポート作成

活用シーン

  1. 01アライメント前の RNA-seq・WGS リード処理
  2. 02複数サンプルの QC レポート作成
  3. 033′ 富化 RNA-seq の polyA テール除去

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jaechang-hits/sciagent-skills --skill fastp-fastq-preprocessing

インストール後、Claude Code で/fastp-fastq-preprocessingを入力して読み込まれたか確認します。

詳細

fastp — FASTQ の高速品質管理とアダプタートリミング

概要

fastp は、Illumina FASTQ ファイルのアダプタートリミング、品質フィルタリング、QC レポート生成を、マルチスレッドの単一パスで実行します。ペアエンドリードのオーバーラップからアダプター配列を自動検出するため、アダプターを手動で指定する必要はありません。fastp はペアエンドのオーバーラップ領域でミスマッチを補正し、品質スコアと長さに基づいてリードをフィルタリングし、polyX テール(RNA-seq では polyA)を除去して、インタラクティブな HTML と機械可読な JSON の QC レポートを生成します。Trim Galore や Trimmomatic より 3~10 倍高速で、同等以上の結果が得られるため、fastp は WGS、RNA-seq、ChIP-seq パイプラインにおけるアライメント前の標準的な前処理ステップとなっています。

使用する場面

  • NGS パイプライン(RNA-seq、WGS、WES、ChIP-seq、ATAC-seq)のアライメント前に、Illumina アダプターと低品質塩基をトリミングする場合
  • パイプラインの最初のステップで、MultiQC による集約前にサンプルごとの QC レポート(HTML + JSON)を生成する場合
  • アダプターを手動で指定するより、オーバーラップからアダプターを自動検出する方法が望ましいペアエンドリードを処理する場合
  • 3′ 末端濃縮プロトコル(Smart-seq、QuantSeq)由来の RNA-seq リードから polyA テールを除去する場合
  • デマルチプレックスのワークフローで、UMI またはインデックスに基づいて FASTQ ファイルを分割する場合
  • トリミングと併せて FastQC による塩基ごとの詳細な品質レポートが必要な場合は、代替手段として Trim Galore を使用します
  • スライディングウィンドウによるトリミング手順を細かく制御する場合は、代替手段として Trimmomatic を使用します

前提条件

  • ソフトウェア: fastp(conda またはコンパイル済みバイナリ)
  • 入力: 生の Illumina FASTQ ファイル(シングルエンドまたはペアエンド、.fastq または .fastq.gz)

インストール前に確認してください: ツールは現在の環境(例:pixi / conda 環境内)ですでに利用可能な場合があります。まず command -v fastp を実行し、パスが返された場合は以下のインストールコマンドを省略してください。pixi プロジェクト内で実行する場合は、fastp を直接実行するのではなく、pixi run fastp を使用してください。

# Install with conda
conda install -c bioconda fastp

# Or download pre-compiled binary (Linux)
wget https://github.com/OpenGene/fastp/releases/download/v0.24.0/fastp
chmod +x fastp
./fastp --version
# fastp 0.24.0

# Verify
fastp --version

事前確認

解析コードを書く前に、以下の項目をユーザーと確認してください。

decisions:
  - id: D1
    param: -i / -I
    kind: required
    source: data
    ask: "Were these reads sequenced from single-end or paired-ends of each fragment?"
    default: "read off the file inventory - paired when R1/R2 mates are present"

  - id: D2
    param: library_prep
    kind: required
    source: user
    ask: "Which library prep produced these reads - 5'-, 3'-, small RNA, lnRNA or amplicon?"
    default: null

  - id: D3
    param: --trim_poly_x
    kind: optional
    source: user
    depends_on: [D2]
    ask: "Trim polyA/polyT tails left by the capture step?"
    default: "on for 3'-enriched RNA-seq, off otherwise"

  - id: D4
    param: --adapter_sequence / --detect_adapter_for_pe
    kind: required
    source: user
    depends_on: [D1]
    ask: "Auto-detect the adapter, or supply the kit's sequence explicitly?"
    default: "auto-detect"

  - id: D5
    param: --length_required
    kind: required
    source: user
    depends_on: [D2]
    ask: "Reads shorter than this after trimming are discarded - how short is too short to map?"
    default: "15 (raise to ~36 for standard RNA-seq; keep low for small RNA)"

  - id: D6
    param: --qualified_quality_phred
    kind: optional
    source: user
    ask: "How confident must a base call be before it counts as good quality?"
    default: "15 (20 = 1% error)"

  - id: D7
    param: --correction
    kind: optional
    source: user
    depends_on: [D1]
    ask: "Correct mismatched bases where the two mates overlap?"
    default: "off"
    skip_if: "single-end input - there is no overlap to compare"

  - id: D8
    param: --low_complexity_filter
    kind: optional_conditional
    source: data
    ask: "Drop low-complexity reads (homopolymer and short-repeat runs)?"
    default: "off"

  - id: D9
    param: --thread, --split
    kind: never_ask
    source: data
    reason: "Parallelism and output sharding; affect runtime and file layout, not the reads kept"
    default: "8 threads, no split"

D2 は推測せず、ユーザーに直接確認します。ライブラリ調製法によって後続の 2 つの回答が変わるためです。D2 によって、polyA トリミングが適切かどうか(D3。3′ 末端濃縮ライブラリでは、生物学的配列ではないキャプチャテールでリードが終わります)と、長さの下限をどこに設定するか(D5。RNA-seq では適切な 36 bp の最小値でも、small RNA の解析ではリード全体が破棄されます)が決まります。D4 と D7 はどちらもペアのリードの扱いを示すため、D1 に関連します。

クイックスタート

# Paired-end adapter trimming with QC report
fastp \
    -i sample_R1.fastq.gz \
    -I sample_R2.fastq.gz \
    -o sample_R1.trimmed.fastq.gz \
    -O sample_R2.trimmed.fastq.gz \
    -h sample_qc.html \
    -j sample_qc.json \
    --thread 8

echo "Trimmed reads in: sample_R1.trimmed.fastq.gz"

ワークフロー

ステップ 1: シングルエンドのアダプタートリミング

自動アダプター検出を使って、シングルエンド FASTQ に fastp を実行します。

# Single-end with auto adapter detection
fastp \
    -i sample.fastq.gz \
    -o sample.trimmed.fastq.gz \
    -h sample_qc.html \
    -j sample_qc.json \
    --thread 8 \
    --qualified_quality_phred 20 \
    --length_required 36

echo "Input reads:   $(zcat sample.fastq.gz | wc -l | awk '{print $1/4}')"
echo "Output reads:  $(zcat sample.trimmed.fastq.gz | wc -l | awk '{print $1/4}')"
ステップ 2: ペアエンドのアダプタートリミング

オーバーラップに基づくアダプター検出と補正を使って、ペアエンド FASTQ ファイルを処理します。

# Paired-end with overlap-based adapter auto-detection
fastp \
    -i sample_R1.fastq.gz \
    -I sample_R2.fastq.gz \
    -o sample_R1.trimmed.fastq.gz \
    -O sample_R2.trimmed.fastq.gz \
    -h sample_qc.html \
    -j sample_qc.json \
    --thread 8 \
    --correction \
    --detect_adapter_for_pe \
    --qualified_quality_phred 20 \
    --length_required 36

# Specify adapters explicitly (if auto-detection fails)
# fastp -i R1.fq.gz -I R2.fq.gz \
#   --adapter_sequence AGATCGGAAGAGCACACGTCTGAACTCCAGTCA \
#   --adapter_sequence_r2 AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT \
#   -o R1.out.fq.gz -O R2.out.fq.gz
ステップ 3: 品質フィルタリングとリード長のトリミング

より厳格または緩やかなフィルタリングのために、品質と長さのしきい値を設定します。

# Strict quality filtering (e.g., for variant calling)
fastp \
    -i sample_R1.fastq.gz \
    -I sample_R2.fastq.gz \
    -o sample_R1.filtered.fastq.gz \
    -O sample_R2.filtered.fastq.gz \
    -h sample_qc.html \
    -j sample_qc.json \
    --thread 8 \
    --qualified_quality_phred 25 \
    --unqualified_percent_limit 20 \
    --length_required 50 \
    --max_len1 150 \
    --max_len2 150 \
    --low_complexity_filter \
    --complexity_threshold 30

echo "Filtering complete. Check sample_qc.html for pass/fail rates."
ステップ 4: RNA-seq の polyA テール除去

アライメント前に、3′ 末端濃縮 RNA-seq プロトコルから polyA テールを除去します。

# Remove polyA tails (QuantSeq 3′ mRNA-seq)
fastp \
    -i quantseq_R1.fastq.gz \
    -o quantseq_R1.trimmed.fastq.gz \
    -h quantseq_qc.html \
    -j quantseq_qc.json \
    --thread 8 \
    --trim_poly_x \
    --poly_x_min_len 10 \
    --qualified_quality_phred 20 \
    --length_required 25

# For Smart-seq2 paired-end with polyA
fastp \
    -i smartseq_R1.fastq.gz \
    -I smartseq_R2.fastq.gz \
    -o smartseq_R1.trimmed.fastq.gz \
    -O smartseq_R2.trimmed.fastq.gz \
    --trim_poly_x --poly_x_min_len 10 \
    --thread 8 \
    -h smartseq_qc.html -j smartseq_qc.json
ステップ 5: パイプライン監視用 QC レポート JSON の解析

fastp の JSON 出力から主要な QC 指標を抽出し、自動品質ゲートに使用します。

import json
from pathlib import Path

def parse_fastp_json(json_path: str) -> dict:
    with open(json_path) as f:
        data = json.load(f)
    
    before = data["summary"]["before_filtering"]
    after = data["summary"]["after_filtering"]
    
    return {
        "total_reads_in":  before["total_reads"],
        "total_reads_out": after["total_reads"],
        "pct_passed":      after["total_reads"] / before["total_reads"] * 100,
        "q30_rate_before": before["q30_rate"] * 100,
        "q30_rate_after":  after["q30_rate"] * 100,
        "mean_len_before": before["read1_mean_length"],
        "mean_len_after":  after["read1_mean_length"],
        "adapter_trimmed": data["filtering_result"]["adapter_trimmed"],
    }

metrics = parse_fastp_json("sample_qc.json")
for key, val in metrics.items():
    print(f"{key:25s}: {val:.1f}" if isinstance(val, float) else f"{key:25s}: {val:,}")

# Quality gate: fail if < 70% reads pass filter
if metrics["pct_passed"] < 70:
    print("WARNING: Low pass rate — check raw data quality")
ステップ 6: バッチ前処理パイプライン

サンプルごとの QC サマリーを作成しながら、複数のサンプルを順に処理します。

#!/bin/bash
# Batch paired-end preprocessing for multiple samples
SAMPLES=(ctrl_1 ctrl_2 treat_1 treat_2)
DATA="data"
OUT="trimmed"
QC="qc/fastp"
THREADS=8

mkdir -p "$OUT" "$QC"

for sample in "${SAMPLES[@]}"; do
    echo "=== Processing $sample ==="
    fastp \
        -i "$DATA/${sample}_R1.fastq.gz" \
        -I "$DATA/${sample}_R2.fastq.gz" \
        -o "$OUT/${sample}_R1.fastq.gz" \
        -O "$OUT/${sample}_R2.fastq.gz" \
        -h "$QC/${sample}.html" \
        -j "$QC/${sample}.json" \
        --thread $THREADS \
        --correction \
        --detect_adapter_for_pe \
        --qualified_quality_phred 20 \
        --length_required 36 \
        2>&1 | grep -E "Read[12]|Filtering|Adapter|passed"
done

# Aggregate QC metrics
python3 - << 'EOF'
import json, pandas as pd
from pathlib import Path

rows = []
for jf in sorted(Path("qc/fastp").glob("*.json")):
    with open(jf) as f: data = json.load(f)
    after = data["summary"]["after_filtering"]
    before = data["summary"]["before_filtering"]
    rows.append({
        "sample": jf.stem,
        "reads_in": before["total_reads"],
        "reads_out": after["total_reads"],
        "pct_passed": round(after["total_reads"]/before["total_reads"]*100, 1),
        "q30_after": round(after["q30_rate"]*100, 1),
    })
df = pd.DataFrame(rows)
print(df.to_string(index=False))
df.to_csv("fastp_summary.tsv", sep="\t", index=False)
EOF

# Run MultiQC to aggregate all fastp JSON reports
multiqc qc/fastp/ -o qc/ -n fastp_multiqc_report

主なパラメーター

パラメーターデフォルト範囲/オプション効果
-i / -I必須file path入力 FASTQ(ペアエンドの場合は R1 と R2)
-o / -O必須file pathトリミング後の出力 FASTQ(R1 と R2)
-h / -j—file pathHTML および JSON の QC レポート出力先
--thread31–16CPU スレッド数。8 が適切なバランスです
--qualified_quality_phred150–40最小塩基品質(Phred)。20 はエラー率 1% に相当します
--length_required151–1000トリミング後の最小リード長。これより短いリードは破棄します
--correctionオフflagPE のオーバーラップ領域のミスマッチを修正します
--detect_adapter_for_peオフflagPE データでオーバーラップに基づくアダプターの自動検出を有効にします
--adapter_sequence自動stringR1 アダプターを明示的に指定します。自動検出より優先されます
--trim_poly_xオフflagpolyX(polyA/polyT)テールをトリミングします。3′ 濃縮 RNA-seq に使用します
--low_complexity_filterオフflag複雑度の低いリード(デフォルトでは複雑度 30% 未満)をフィルタリングします
--splitオフinteger出力を方向ごとに N 個のファイルに分割します(並列処理用)

よく使うレシピ

レシピ 1:fastp を Snakemake パイプラインに統合する
# Snakefile — fastp trimming rule
configfile: "config.yaml"
SAMPLES = config["samples"]

rule fastp_pe:
    input:
        r1 = "data/{sample}_R1.fastq.gz",
        r2 = "data/{sample}_R2.fastq.gz"
    output:
        r1 = "trimmed/{sample}_R1.fastq.gz",
        r2 = "trimmed/{sample}_R2.fastq.gz",
        html = "qc/{sample}_fastp.html",
        json = "qc/{sample}_fastp.json"
    threads: 8
    shell:
        """
        fastp -i {input.r1} -I {input.r2} \
              -o {output.r1} -O {output.r2} \
              -h {output.html} -j {output.json} \
              --thread {threads} \
              --correction --detect_adapter_for_pe \
              --qualified_quality_phred 20 \
              --length_required 36
        """
レシピ 2:Python で fastp の JSON レポートを集約する
import json
import pandas as pd
from pathlib import Path

qc_dir = Path("qc/fastp")
records = []

for jf in sorted(qc_dir.glob("*.json")):
    with open(jf) as f:
        d = json.load(f)
    b = d["summary"]["before_filtering"]
    a = d["summary"]["after_filtering"]
    records.append({
        "sample": jf.stem.replace("_fastp", ""),
        "reads_in_M": b["total_reads"] / 1e6,
        "reads_out_M": a["total_reads"] / 1e6,
        "pct_passed": a["total_reads"] / b["total_reads"] * 100,
        "q30_pct": a["q30_rate"] * 100,
        "mean_len_bp": a["read1_mean_length"],
        "adapter_pct": d["filtering_result"]["adapter_trimmed"] / b["total_reads"] * 100,
    })

df = pd.DataFrame(records).round(2)
print(df.to_string(index=False))

# Flag low-quality samples
low_q = df[df["pct_passed"] < 80]
if not low_q.empty:
    print(f"\nSamples with < 80% reads passing: {list(low_q['sample'])}")

出力されるファイル

出力形式説明
*_R1.trimmed.fastq.gzFASTQ.gzトリミング済みの R1 リード(アダプターと低品質塩基を除去)
*_R2.trimmed.fastq.gzFASTQ.gzトリミング済みの R2 リード(ペアエンドのみ)
*.htmlHTML塩基ごとの品質、GC 含量、アダプターのプロットを含むインタラクティブな QC レポート
*.jsonJSON自動化および MultiQC による解析用の、機械可読な QC メトリクス
fastp.logテキスト合格/不合格リード数とフィルタリング統計を含む stderr の概要

トラブルシューティング

問題原因解決策
SE モードでアダプターが検出されないSE リードではアダプターの明示的な指定、または --adapter_sequence が必要です--detect_adapter_for_pe は PE の場合にのみ使用します。SE ではアダプターを指定します:--adapter_sequence AGATCGGAAGAGC
アダプター含有率が非常に高い(> 50%)インサートが短い(small RNA、miRNA)、またはライブラリー調製の品質が低いライブラリープロトコルを確認します。--overlap_len_require 10 を使用してオーバーラップの感度を調整します
フィルタリングされるリードが多すぎる(合格率 < 60%)品質しきい値が厳しすぎる、またはシーケンシングの品質が低い--qualified_quality_phred を 15 に緩和します。--length_required を 25 に下げます
JSON 出力にフィールドがない古い fastp バージョンconda update fastp でアップグレードするか、GitHub から最新のバイナリーをダウンロードします
MultiQC が fastp JSON を解析しないJSON ファイルがスキャン対象のディレクトリーにないmultiqc . ではなく multiqc qc/ を実行します。ls qc/*.json で JSON ファイルが存在することを確認します
出力 FASTQ が空すべてのリードがフィルタリングされた(入力が誤っている、またはしきい値が極端)zcat sample.fq.gz | head -8 で入力 FASTQ を確認します。まず --low_complexity_filter を指定せずに実行します
大きなファイルで処理が遅いスレッド数が少ない--thread を 8–12 に増やします。入力が高速ストレージ(SSD)上にあることを確認します
polyA が除去されない--trim_poly_x が設定されていない3′ 濃縮プロトコルでは --trim_poly_x --poly_x_min_len 10 を追加します

参考資料

コメント