AWS Batch で MultiQC を実行して RNA-seq の QC レポートをまとめてみた
はじめに
こんにちは、ほりぐちです。
RNA-seq 解析では、塩基配列のデータを取得したあと、アラインメントや発現量解析などの下流処理へ進む前に、データの品質を確認し、後続の解析に使用できるかを判断する工程が重要です。
特に複数サンプルを扱う場合は、各サンプルのリード数、シーケンス品質、アダプター配列の残存状況などを確認するだけでなく、サンプル間で大きく傾向が異なるものがないかを横断的に確認する必要があります。
FastQC は、FASTQ ファイルごとに詳細な品質レポートを出力できる代表的なツールです。一方で、サンプル数が増えると、FASTQ ファイルごとに出力された HTML レポートを個別に開いて確認するの手間がかかります。
そこで本記事では、AWS Batch を利用して複数の FASTQ ファイルに対して FastQC を実行し、その結果を MultiQC で集約して、1 つのレポートとして確認する方法を紹介します。
今回の目的を一言でまとめると、「複数の FASTQ データを AWS Batch で品質チェックし、結果を 1 つのレポートにまとめて確認しよう」というものになります。
本記事は以下の記事で作成した環境を再利用して実施します。
AWS Batch を使った FastQC 実行環境を AWS マネジメントコンソールだけで構築してみた
それではよろしくお願いします。
注意
- 本記事では公開データ(GATK Test Data)を利用します
- 本記事では、解析結果に対する科学的な解釈は行いません
- バケット名、AWS アカウント ID、リージョン名は、ご自身の環境に合わせて変更してください
用語の解説
MultiQC
FastQC など複数の解析ツールが出力した品質管理・解析結果を一つのレポートに集約し、サンプル間で比較・確認するためのソフトウェア。
今回の流れ
処理の流れは次のとおりです。
- 複数の FASTQ ファイルを S3 にアップロードする
- サンプルごとに FastQC ジョブを実行する
- FastQC の結果をサンプルごとの S3 プレフィックスへ保存する
- MultiQC ジョブで FastQC の結果を取得する
- MultiQC レポートを作成する
- MultiQC の出力を S3 に保存する
今回は、FastQC 用と MultiQC 用の 2 種類の AWS Batch ジョブを使用します。
FastQC ジョブには、対象となる FASTQ ファイルと出力先を環境変数で渡します。同じ Job definition に異なる環境変数を渡すことで、複数のサンプルを処理します。
FastQC の処理がすべて完了したら、MultiQC ジョブを実行します。MultiQC ジョブは、S3 に保存された FastQC の結果をまとめて取得し、1 つの HTML レポートを作成します。
なお、AWS Batch の実行環境や FastQC 用コンテナイメージの作成方法については、こちらの記事をご参照ください。
1. 複数サンプルの FASTQ を S3 に配置する
今回は、3 サンプル分の paired-end FASTQ ファイルを使用します。
S3 バケット内に input_data/fastq/ プレフィックスを用意し、次のように配置します。
input_data/
└── fastq/
├── sample_001_R1.fastq.gz
├── sample_001_R2.fastq.gz
├── sample_002_R1.fastq.gz
├── sample_002_R2.fastq.gz
├── sample_003_R1.fastq.gz
└── sample_003_R2.fastq.gz

S3 に 3 サンプル分の paired-end FASTQ ファイルをアップロード
また、今回は FastQC と MultiQC からそれぞれアウトプットがあるため、Output 側も各ソフトウェア用のアウトプットフォルダを用意します。
output_data/
├── fastqc/
└── mutliqc/

各ソフトウェア向けの output フォルダ
2. サンプルごとに FastQC ジョブを送信する
FastQC の実行スクリプトは、入力する FASTQ ファイルと出力先の S3 URI を環境変数として受け取る構成にしています。
コンテナの起動スクリプトでは、指定された FASTQ ファイルを S3 からダウンロードし、FastQC を実行します。FastQC の結果は、コンテナ内の作業ディレクトリに出力した後、指定された S3 URI にアップロードされます。
本構成では Security Hub CSPM コントロール ECS.5 (コンテナのルートファイルシステムを読み取り専用にする) への対応として、コンテナのルートファイルシステムへの書き込みを禁止し、/work にマウントしたボリューム上でファイルのダウンロード・一時出力を行っています。
あわせて HOME・TMPDIR・JAVA_TOOL_OPTIONS・THREADS の4つの環境変数を Job definition 側で固定しています。この対応の詳細はこちらの記事をご参照ください。
| 環境変数 | 用途 |
|---|---|
| HOME | FastQC などが使用するホームディレクトリ |
| TMPDIR | 一時ファイルの出力先 |
| JAVA_TOOL_OPTIONS | Java 実行時のオプション |
| THREADS | FastQC で使用するスレッド数 |
これらの値は Job definition 側で管理するため、ジョブ送信時には変更しません。AWS Batch コンソール上でも、これらの環境変数はグレーアウトされ、上書きできない状態で表示されます。

グレーアウトされた環境変数
一方、処理するサンプルごとに、以下の 3 つの環境変数をジョブ送信時に指定します。
同じコンテナイメージおよび Job definition を使用し、これらの値だけを切り替えることで、毎回ジョブ定義などを作ることなく複数サンプルを処理できます。
| 環境変数 | 内容 |
|---|---|
| INPUT_R1 | R1 FASTQ の S3 URI |
| INPUT_R2 | R2 FASTQ の S3 URI |
| OUTPUT_S3 | FastQC の出力先となる S3 URI |
Sample_001 を送信する
例えば、sample_001 を処理する場合は、次の値を指定します。
| 環境変数 | 設定例 |
|---|---|
| INPUT_R1 | s3://バケット名/input_data/fastq/sample_001_R1.fastq.gz |
| INPUT_R2 | s3://バケット名/input_data/fastq/sample_001_R2.fastq.gz |
| OUTPUT_S3 | s3://バケット名/output_data/fastqc/sample_001/ |
sample_002 と sample_003 のジョブに関しても、同じ Job definition と Job queue を使用してジョブを送信します。変更するのは、ジョブ名と INPUT_R1、INPUT_R2、OUTPUT_S3 の値のみです。
このように、サンプルごとの入力 FASTQ と出力先を環境変数で指定することで、サンプルごとにコンテナイメージや Job definition を作成することなく、一度作成した環境を再利用できます。
4. FastQC の実行結果を確認する
AWS Batch コンソールを開き、送信したジョブが SUCCEEDED になったことを確認します。
ジョブが失敗した場合は、ジョブの詳細画面から CloudWatch Logs を開き、実行ログを確認します。
ジョブの確認方法や CloudWatch Logs の見方については、以下の記事をご参照ください。
AWS Batch を使った FastQC 実行環境を AWS マネジメントコンソールだけで構築してみた
S3 の output_data/fastqc/ には、次のように結果が出力されます。
output_data/
└── fastqc/
├── sample_001/
│ ├── sample_001_R1_fastqc.html
│ ├── sample_001_R1_fastqc.zip
│ ├── sample_001_R2_fastqc.html
│ └── sample_001_R2_fastqc.zip
├── sample_002/
│ ├── sample_002_R1_fastqc.html
│ ├── sample_002_R1_fastqc.zip
│ ├── sample_002_R2_fastqc.html
│ └── sample_002_R2_fastqc.zip
└── sample_003/
├── sample_003_R1_fastqc.html
├── sample_003_R1_fastqc.zip
├── sample_003_R2_fastqc.html
└── sample_003_R2_fastqc.zip

S3 に出力された FastQC の結果
以降の MultiQC ジョブでは、ここに出力された FastQC の ZIP ファイルを読み取ります。
5. MultiQC ジョブ用の S3 権限を設定する
さて、ここまでで書くサンプルの FastQC レポートが作成できました。
ここからは、これらの結果を MultiQC を用いて比較していきましょう。
MultiQC ジョブでは、output_data/fastqc/ に保存された FastQC の結果を読み取り、作成したレポートを output_data/multiqc/ に保存します。
AWS Batch の Job role には、次の権限が必要です。
- output_data/fastqc/ に対する読み取り権限
- output_data/multiqc/ に対する書き込み権限
FastQC の結果を読み取るため、次の権限を追加します。
{
"Sid": "ReadFastqcOutput",
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::バケット名/output_data/fastqc/*"
}
MultiQC の結果を書き込む権限は、次のようになります。
{
"Sid": "WriteMultiqcOutput",
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": "arn:aws:s3:::バケット名/output_data/multiqc/*"
}
すでに output_data/* への書き込みを許可している場合、書き込み権限の追加は不要です。
6. MultiQC 用コンテナイメージを作成する
MultiQC 用のコンテナイメージを作成し、Amazon ECR に登録します。
コンテナイメージは、FastQC 用コンテナと同じく CodeBuild で作成します。CodeBuild プロジェクトや ECR リポジトリの基本的な作成方法については、以下の記事をご参照ください。
AWS Batch を使った FastQC 実行環境を AWS マネジメントコンソールだけで構築してみた
今回は、MultiQC の公式コンテナイメージをベースイメージとして使用します。こちらに AWS CLI と起動スクリプトを追加して S3 への読み書きができるように設定します。
ECR リポジトリの作成
先に MultiQC のコンテナイメージをプッシュするための次のような ECR リポジトリを作成します。
rna-seq/multiqc
作成した ECR リポジトリの URI は、次の形式になります。
AWSアカウントID.dkr.ecr.us-east-1.amazonaws.com/rna-seq/multiqc

MultiQC 用 ECR リポジトリ
AWS CLI を追加した MultiQC の Dockerfile は以下のとおりです。
ARG MULTIQC_VERSION=1.35
FROM multiqc/multiqc:v${MULTIQC_VERSION}
USER root
# S3 とのファイル転送に使用する AWS CLI v2 をインストールする
RUN apt-get update \
&& apt-get install -y --no-install-recommends curl unzip \
&& curl -fsSL \
"https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" \
-o /tmp/awscliv2.zip \
&& unzip -q /tmp/awscliv2.zip -d /tmp \
&& /tmp/aws/install \
&& rm -rf \
/tmp/aws \
/tmp/awscliv2.zip \
/var/lib/apt/lists/*
COPY run_multiqc.sh /usr/local/bin/run_multiqc.sh
# 起動スクリプトに実行権限を付与し、
# MultiQC と AWS CLI が利用できることを確認する
RUN chmod +x /usr/local/bin/run_multiqc.sh \
&& multiqc --version \
&& aws --version
ENTRYPOINT ["/usr/local/bin/run_multiqc.sh"]
起動スクリプトは以下のとおりです。
#!/usr/bin/env bash
set -euo pipefail
# 必須の環境変数が設定されていることを確認する
: "${INPUT_S3_PREFIX:?INPUT_S3_PREFIX is required}"
: "${OUTPUT_S3_PREFIX:?OUTPUT_S3_PREFIX is required}"
# Fargate 上に一時的な作業ディレクトリを作成する
mkdir -p /work/fastqc /work/multiqc
# FastQC の結果を S3 からダウンロードする
aws s3 cp \
"${INPUT_S3_PREFIX%/}/" \
/work/fastqc/ \
--recursive
# FastQC の結果を MultiQC で集約する
multiqc \
/work/fastqc \
--module fastqc \
--outdir /work/multiqc \
--force
# MultiQC の結果を S3 にアップロードする
aws s3 cp \
/work/multiqc/ \
"${OUTPUT_S3_PREFIX%/}/" \
--recursive
このスクリプトでは、次の処理を行います。
- S3 から FastQC の結果をダウンロードする
- MultiQC で FastQC の結果を集約する
- MultiQC の出力を S3 にアップロードする
上記を base64 でエンコードした一行スクリプトは以下のとおりです。
echo QVJHIE1VTFRJUUNfVkVSU0lPTj0xLjM1CkZST00gbXVsdGlxYy9tdWx0aXFjOnYke01VTFRJUUNfVkVSU0lPTn0KClVTRVIgcm9vdAoKUlVOIGFwdC1nZXQgdXBkYXRlICAgICAmJiBhcHQtZ2V0IGluc3RhbGwgLXkgLS1uby1pbnN0YWxsLXJlY29tbWVuZHMgY3VybCB1bnppcCAgICAgJiYgY3VybCAtZnNTTCAiaHR0cHM6Ly9hd3NjbGkuYW1hem9uYXdzLmNvbS9hd3NjbGktZXhlLWxpbnV4LXg4Nl82NC56aXAiIC1vIC90bXAvYXdzY2xpdjIuemlwICAgICAmJiB1bnppcCAtcSAvdG1wL2F3c2NsaXYyLnppcCAtZCAvdG1wICAgICAmJiAvdG1wL2F3cy9pbnN0YWxsICAgICAmJiBybSAtcmYgL3RtcC9hd3MgL3RtcC9hd3NjbGl2Mi56aXAgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkNPUFkgcnVuX211bHRpcWMuc2ggL3Vzci9sb2NhbC9iaW4vcnVuX211bHRpcWMuc2gKClJVTiBjaG1vZCAreCAvdXNyL2xvY2FsL2Jpbi9ydW5fbXVsdGlxYy5zaCAgICAgJiYgbXVsdGlxYyAtLXZlcnNpb24gICAgICYmIGF3cyAtLXZlcnNpb24KCkVOVFJZUE9JTlQgWyIvdXNyL2xvY2FsL2Jpbi9ydW5fbXVsdGlxYy5zaCJdCg== | base64 -d > Dockerfile && echo IyEvdXNyL2Jpbi9lbnYgYmFzaApzZXQgLWV1byBwaXBlZmFpbAoKOiAiJHtJTlBVVF9TM19QUkVGSVg6P0lOUFVUX1MzX1BSRUZJWCBpcyByZXF1aXJlZH0iCjogIiR7T1VUUFVUX1MzX1BSRUZJWDo/T1VUUFVUX1MzX1BSRUZJWCBpcyByZXF1aXJlZH0iCgpta2RpciAtcCAvd29yay9mYXN0cWMgL3dvcmsvbXVsdGlxYwoKYXdzIHMzIGNwICIke0lOUFVUX1MzX1BSRUZJWCUvfS8iIC93b3JrL2Zhc3RxYy8gLS1yZWN1cnNpdmUKbXVsdGlxYyAvd29yay9mYXN0cWMgLS1tb2R1bGUgZmFzdHFjIC0tb3V0ZGlyIC93b3JrL211bHRpcWMgLS1mb3JjZQphd3MgczMgY3AgL3dvcmsvbXVsdGlxYy8gIiR7T1VUUFVUX1MzX1BSRUZJWCUvfS8iIC0tcmVjdXJzaXZlCg== | base64 -d > run_multiqc.sh && ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) && REGION=$AWS_DEFAULT_REGION && ECR_URI=${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/${ECR_REPOSITORY} && aws ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com && docker build --build-arg MULTIQC_VERSION=${IMAGE_TAG} -t ${ECR_URI}:${IMAGE_TAG} . && docker push ${ECR_URI}:${IMAGE_TAG}
こちらのスクリプトを利用して、プロジェクトを作成・ビルドを行います。
コンテナイメージのビルドに成功したら、ECR に登録されます。

MultiQC 用 ECR リポジトリに MultiQC 用コンテナイメージを push
7. MultiQC 用 Job definition を作成する
AWS Batch コンソールから、MultiQC 用の Job definition を作成します。
基本的な設定方法については、以下の記事をご参照ください。
AWS Batch を使った FastQC 実行環境を AWS マネジメントコンソールだけで構築してみた
今回の設定は次のとおりです。
| 項目 | 設定例 |
|---|---|
| ジョブ定義名 | multiqc-job-definition |
| プラットフォーム | Fargate |
| イメージ | MultiQC 用の ECR イメージ |
| vCPU | 1 |
| メモリ | 2 GB |
| Execution role | ECR と CloudWatch Logs を利用できる Execution role |
| Job role | FastQC の結果を読み書きできる Job role |
| 実行タイムアウト | 3600 秒 |
| エフェメラルストレージ | 30 GiB |
AWSアカウントID.dkr.ecr.us-east-1.amazonaws.com/rna-seq/multiqc-test:1.35
環境変数は次のように設定します。
| 名前 | 値 | 用途 |
|---|---|---|
| TMPDIR | /work | |
| HOME | /work | |
| XDG_CACHE_HOME | /work/.cache | |
| INPUT_S3_PREFIX | s3://バケット名/output_data/fastqc/ | |
| OUTPUT_S3_PREFIX | s3://バケット名/output_data/multiqc/ |

MultiQC Job definition 環境変数
こちらも FastQC と同様に読み取り専用にしてボリュームを追加します

MultiQC 読み取り専用、ボリューム追加
8. MultiQC ジョブを実行する
すべての FastQC ジョブが SUCCEEDED になっていることを確認してから、MultiQC ジョブを送信します。
今回は、次の内容でジョブを送信します。
| 項目 | 値 |
|---|---|
| ジョブ名 | multiqc-fastqc-report |
| ジョブ定義 | multiqc-job-definition |
| ジョブキュー | FastQC と同じ Job queue |
その他の設定はそのままで大丈夫です。
ジョブ送信後、AWS Batch コンソールと CloudWatch Logs で実行状況を確認します。
今回は 3 サンプルの paired-end FASTQ を使用しているため、R1 と R2 を合わせて 6 件の FastQC 結果が検出されます。

MultiQC が FastQC の結果を取得して解析しているログ
9. MultiQC レポートを確認する
S3 の output_data/multiqc/ を確認します。
次のように、MultiQC のレポートとデータファイルが出力されます。
S3 に出力された MultiQC の結果
MultiQC レポートでは、複数の FastQC 結果を 1 つの画面で比較できます。
例えば、次のような項目を確認できます。
- シーケンス数
- GC 含量
- リード長
- Per base sequence quality
- Per sequence quality scores
- Sequence duplication levels
- Adapter content
multiqc_report.html をローカルにダウンロードし、ブラウザで開いてみます。


ブラウザで開いた MultiQC レポート
これにより、FastQC の HTML ファイルを 1 つずつ開くことなく、サンプル間の傾向をまとめて確認できました。
まとめ
お疲れ様でした!
今回は、AWS Batch を使って複数の FASTQ ファイルに対して FastQC を実行し、MultiQC で結果を 1 つの HTML レポートにまとめました。
実施した内容は次のとおりです。
- 複数サンプルの FASTQ を S3 に配置
- 環境変数を上書きして、サンプルごとに FastQC ジョブを実行
- FastQC の結果をサンプルごとの S3 プレフィックスへ保存
- MultiQC 用コンテナイメージを作成
- MultiQC 用 Job definition を作成
- 複数の FastQC 結果を 1 つの HTML レポートに集約
同じ FastQC 用 Job definition に異なる入力値を渡すことで、サンプルごとに実行環境を作成することなく、複数の FASTQ ファイルを処理できました。
また、MultiQC を使用することで、複数サンプルの QC 結果を横断的に確認できるようになりました。
今回は FastQC ジョブの完了を確認してから、MultiQC ジョブを手動で送信しています。サンプル数や実行回数が増える場合は、AWS Batch のジョブ依存関係や AWS Step Functions を使って、一連の処理を自動化する構成も考えられます。








