Nanopore データ、Megalodon から phasing まで
1. ONT、basecalling & mapping
<環境 GPU ノード>
Intel Xeon Gold 6326 CPU 2.90GHz x 2, 256GB memory
NVIDIA GA100 [A100 PCIe 40GB] x 4
Rocky Linux release 8.5
megalodon v2.5.0 (https://github.com/nanoporetech/megalodon)
Remora v2.0.0
guppy v6.4.2
<データ>
R9.4.1 フローセル、PromethION 出力の fast5 データ。
$ myref=GRCh38.mmi
$ nproc=16
$ gpu_id="0 1"
$ megalodon ${fast5_pass}
--guppy-config dna_r9.4.1_450bps_sup_prom.cfg
--remora-modified-bases dna_r9.4.1_e8 sup 0.0.0 5mc CG 0
--outputs basecalls mappings mod_mappings mods
--reference ${myref}
--output-directory ${output_dir}
--processes ${nproc}
--devices ${gpu_id}
--guppy-server-path path_to_guppy_basecall_server
guppy-config はguppyインストールパス/data/にある。
2023.3 現在、dna_r9.4.1_450bpsが最新。
r9.4.1はフローセルバージョン。
fast/hac/sup がある(速度⇄ 精度?)。
prom は promethION。
--remora-modified-bases の選択肢は
$ remora model list_pretrained
で確認できる。
--reference は minimap2 で使用する、マッピングするゲノム。
ゲノムのfastaファイルもしくはminimap2のインデックスファイルを指定できるが、minimap2のインデックスファイルだとメモリ使用量が改善されるらしい。こちらの環境ではR9.4.1 フローセル1ランでおよそ24時間程度かかっていたものが、minimap2 インデックスへの変更でGPU使用効率が向上し、1/3程度に短縮された。
--process は指定した数値よりCPU使用量が多くなるので調整する必要あり。こちらの環境で私はマシンスペックの半分程度にしている。
--devices はGPUのID。GridEngine で割り振られる場合はその番号に準ずる。
2. SNP calling(リファレンスと対象ゲノム間のSNP)
Clair3でSNP callを行う。
<環境>
CentOS Linux 7.6
clair3 v0.1.12 (https://github.com/HKU-BAL/Clair3)
whatshap v1.4 (https://github.com/whatshap/whatshap)
anaconda で clair3 + whatshapをインストール。
$ conda create -n clair3 -c bioconda clair3 -y
当時こちらの環境では
AttributeError: module 'numpy' has no attribute 'int'.
というエラーが出たため、エラーが出ない組み合わせを試行錯誤してインストールした。
$ conda create -n clair3-01r12-nmp1235 -c conda-forge -c bioconda clair3 python=3.9.0 numpy=1.23.5 -y
$ conda activate clair3
$ bam=mapping.bam
$ ref=GRCh38.fa
$ MODEL_NAME="r941_prom_sup_g5014"
$ THREADS=24
$ run_clair3.sh
--bam_fn=${bam}
--ref_fn=${myref}
--threads=${THREADS}
--platform="ont"
--model_path="path_to_model_dir/${MODEL_NAME}"
この時点でphasingデータは得られているが、いくつかの理由で、今回得られたSNPから、リファレンスゲノムと 対象ゲノムとのSNPから対象ゲノムのリファレンスを作成して、マッピングからやり直した。
3. 対象ゲノムリファレンスの作成
bcftools v1.15.1
bcftoolsインストール
conda create -n bcftools -c bioconda bcftools
clair3の出力 merge_output.vcf.gz から、REFとALTの長さが1塩基かつ、 10列目の最初のマークが、
A) 1/1 (EF/ALT が ALT1/ALT1)になっているものはREFをALTに、
B) 1/2 (EF/ALT が ALT1/ALT2)になっているものはALTがコンマで2つ書かれているので両方とも長さが1のものについて1つ目をREFに、
変更して出力。出力されものは、リファレンスゲノムと対象ゲノムの違うSNVをREFとして記したVCFとなる。
bgzipで圧縮、tabix も行う。
# merge_output.vcf.gzの一部
#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT SAMPLE
chr1 10061 . T C 5.26 PASS F GT:GQ:DP:AF 0/1:5:29:0.4828
chr1 10108 . C CT 0.00 LowQual F GT:GQ:DP:AF 1/1:0:29:0.3103
chr1 10150 . CT C 0.22 LowQual F GT:GQ:DP:AF 0/1:0:29:0.2759
chr1 10177 . A AC 2.34 PASS F GT:GQ:DP:AF 0/1:2:29:0.2414
chr1 10222 . T C 5.74 PASS F GT:GQ:DP:AF 0/1:5:29:0.3793
$ gzip -dc ./merge_output.vcf.gz | perl -F'\t' -anle 'if ($=~/^#/) {print $;} elsif ($F[6] eq "PASS" and length($F[3])==1) {if ($F[9] =~/1/1/ and length($F[4])==1) {print $_;} elsif ($F[9]=~/1/2/) {@a=split/,/,$F[4];if (length($a[0])==1 and length($a[1])==1) {$F[9]=~s@1/2@0/1@;print join("\t",@F[0..3],$a[0],@F[5..9]);}}}' > GRCh38_line1.vcf
$ bgzip GRCh38_line1.vcf
$ tabix -p vcf GRCh38_line1.vcf.gz
$ conda activate bcftools
$ myref=GRCh38.fa
$ out=GRCh38_line1.fa
$ vcf=GRCh38_line1.vcf.gz
$ bcftools consensus -f ${myref} ${vcf} > ${out}
作成した対象ゲノムリファレンスをもとにもう一度megalodonを行う。
# minimap2の index 作成。
$ minimap2 -x map-ont -d GRCh38_line1.mmi GRCh38_line1.fa
$ myref=GRCh38_line1.mmi
$ nproc=16
$ gpu_id="0 1"
$ megalodon ${fast5_pass}
--guppy-config dna_r9.4.1_450bps_sup_prom.cfg
--remora-modified-bases dna_r9.4.1_e8 sup 0.0.0 5mc CG 0
--outputs basecalls mappings mod_mappings mods
--reference ${myref}
--output-directory ${output_dir}
--processes ${nproc}
--devices ${gpu_id}
--guppy-server-path path_to_guppy_basecall_server
4. SNP calling (アリル間のSNP)
clair3でSNP callを行う。
$ conda activate clair3
$ bam=mapping.bam
$ ref=GRCh38_line1.fa
$ MODEL_NAME="r941_prom_sup_g5014"
$ THREADS=24
$ run_clair3.sh
--bam_fn=${bam}
--ref_fn=${myref}
--threads=${THREADS}
--platform="ont"
--model_path="path_to_model_dir/${MODEL_NAME}"
whatshapでphasingされたVCFファイルが tmp/phase_output/phase_vcf に入っているので、これを合体し、bgzip圧縮。
$ cd clair3_output_dir/tmp/phase_output/phase_vcf
$ gzip -dc phased_chr1.vcf.gz phased_chr2.vcf.gz phased_chr3.vcf.gz phased_chr4.vcf.gz phased_chr5.vcf.gz phased_chr6.vcf.gz phased_chr7.vcf.gz phased_chr8.vcf.gz phased_chr9.vcf.gz phased_chr10.vcf.gz phased_chr11.vcf.gz phased_chr12.vcf.gz phased_chr13.vcf.gz phased_chr14.vcf.gz phased_chr15.vcf.gz phased_chr16.vcf.gz phased_chr17.vcf.gz phased_chr18.vcf.gz phased_chr19.vcf.gz phased_chr20.vcf.gz phased_chr21.vcf.gz phased_chr22.vcf.gz phased_chrX.vcf.gz > ${dir}/GRCh38_line1_phased.vcf
$ conda activate tabix
$ bgzip /${dir}/GRCh38_line1_phased.vcf
$ tabix -p vcf /${dir}/GRCh38_line1_phased.vcf.gz
4. ONTのBAMをアリル分け
whstshap v1.14
$ conda create -n whatshap14 -c bioconda whatshap=1.4
まずhaplotag情報を作成する。
$ samtools sort -o mappings_sort.bam mappings.bam
$ samtools index mappings_sort.bam
$ conda activate whatshap14
$ in=mappings_sort.bam
$ out=mappings_haplotag.bam
$ vcf=GRCh38_line1_phased.vcf.gz
$ myref=GRCh38_line1.fa
$ haplist=GRCh38_line1_phased_haplotypes.tsv
$ cpu=24
$ whatshap haplotag
-o ${out}
--reference ${myref}
--output-threads=${cpu}
--output-haplotag-list=${haplist}
--ignore-read-groups
${vcf} ${in}
# phasing blocksの確認。
$ vcf=GRCh38_line1_phased.vcf
$ whatshap stats --gtf=${vcf}.gtf ${vcf} > ${vcf}_stats.txt
haplotag情報をもとに、BAMを分ける。
$ haplist=GRCh38_line1_phased_haplotypes.tsv
$ whatshap split --output-h1 mappings_H1.bam --output-h2 mappings_H2.bam mappings.bam ${haplist}
$ whatshap split --output-h1 mod_mappings_H1.bam --output-h2 mod_mappings_H2.bam mod_mappings.bam ${haplist}
WGBS、EM-seq、RNA-seqなどをphasingするには、SNP calling (アリル間のSNP)で作成したVCFファイルを用いる。
SNPsplit (https://www.bioinformatics.babraham.ac.uk/projects/SNPsplit/)を用いるには、SNP座標をすべてマスクしてマッピングする必要があるので、bedtools maskfastaを用いてマスクしたリファレンスfastaを作成し、これですべて再マッピングを行う。
$ conda activate bedtools
$ in=GRCh38_line1.fa
$ out=GRCh38_line1_mask.fa
$ vcf=GRCh38_line1_phased.vcf.gz
$ bedtools maskfasta -fi ${in} -fo ${out} -bed ${vcf}
6. Short read sequencing データをSNP情報をもとに分ける。
SNPsplit v0.3.2
$ conda create -n snpsplit -c bioconda snpsplit -y
VCFファイルをSNPsplit用にREFとALTを入れ替える。
10列目の 0|1 or 1|0 をもとに、列4、5の REF,ALT を入れ替える。REF 側を H1 (genome1)、ALT側をH2(genome2)にする。
9列目の最後の:PSがphasingできたフラグ、10列目の最後の数字がphasing blockのID (phasing blockの最初のSNPの座標)なので、この番号が異なる場所はgenome1/genome2 が逆転するかどうかは判定できない。
#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT SAMPLE
chr1 10517 . C T 13.06 PASS P GT:GQ:DP:AF:PS 0|1:13:23:0.3913:10517
chr1 11134 . A G 18.09 PASS P GT:GQ:DP:AF:PS 1|0:18:23:0.3913:10517
chr1 11409 . A G 14.99 PASS P GT:GQ:DP:AF:PS 1|0:14:24:0.3333:10517
chr1 11457 . C G 19.01 PASS P GT:GQ:DP:AF:PS 1|0:19:25:0.4:10517
$ gzip -dc GRCh38_line1_phased.vcf.gz | perl -F'\t' -anle '@t=split(/:/,$F[9]);@F[3,4] = @F[4,3] if $t[0] eq "1|0";print join("\t","$F[0]_" . $i++,@F[0,1],1,"$F[3]/$F[4]","$F[0]:$t[4]") if $t[4] =~/^\d+$/;' > GRCh38_line1_phased_snpsplit.txt
これをもとにSNPsplitでBAMをgenome1とgenome2に分ける。
--bisulfiteオプションは、WGBS/EMseqで有効。Transcriptomeなどでは外す。SNP位置をマスクしていないと分けられない。
$ conda activate SNPsplit
$ SNPsplit --snp_file GRCh38_line1_phased_snpsplit.txt --bisulfite sample1.bam
2023/03/14