ホーム > フリーソフトを使った QTL 解析
2020年12月24日作成
2021年1月2日修正
2021年6月17日R/qtl2の説明に共変量について追加


フリーソフトを使った QTL 解析



F0(祖父、祖母)とF2世代からddRAD-seqでデータを取得し、QTL解析をしました。備忘録としてまとめます。使用するソフトは、すべてフリーです。当ホームページによって生じた不利益については、一切の責任を負いかねますのでご了承ください。

1) Stacks: denovoアセブル
2) Lep-MAP3: 連鎖群(LGs)作成
3) MapChart: LGsの可視化
4) r/qtl2: 量的形質のマッピング


参考にしたページ
https://catchenlab.life.illinois.edu/stacks/manual/
https://avikarn.com/2019-04-17-Genetic-Mapping-in-Lep-MAP3/
https://kbroman.org/qtl2/assets/vignettes/user_guide.html



1) Stacks: denovoアセブル
※今回は、データがすでにフィルタリングされた状態で納品されたので、データを個体ごとに振り分けてフィルタリングするprocess_radtagsは実行しませんでした。
※各パイプラインの詳しい説明は、
「Stacks の簡単な使い方」も参照してください。

1-1) ustacks: まず塩基配列が全く同じリードを束ね(stacks)、次にstacks同士を比較してSNPsを検出する。全ての個体(F0とF2の両方)で、1個体ずつ下のコマンドを実行する。
$ /Applications/stacks-2.54/ustacks -f ./rawdata/parent001.fastq.gz -o ./stacks/ -i 1 -m 3 -M 2 -p 3
-f: 解析するファイルを指定する(ここではペアエンドのうち、最初のファイルだけ解析、gz圧縮ファイルでも良い)。
-o: 出力ファイルを保存するフォルダ(ディレクトリ)を指定する。
-i: サンプルID。個体ごとに異なる数字を指定する。
-m: stacksを作る最低のカバレージ。カバレージがこれより小さいリードは、解析から排除される。
-M: ファイル内で同じオーソログとする最低距離(SNP数)。
-p: スレッド数

出力ファイル(個体ごとに3つのファイルが作られる)
parent001.alleles.tsv.gz
parent001.snps.tsv.gz
parent001.tags.tsv.gz
.
.
.


1-2) cstacks: F0個体間のSNPsを検出する。

F0の2個体(祖父、祖母)のみのpopulation mapを作成し、テキスト形式で保存する(popmap_parent.txt)。
parent001[タブ]parent[改行]
parent002[タブ]parent[改行]
※左のparent001などは、データファイル(parent001.fastq.gzなど)から拡張子(.fastq.gz)を省いた名前。ustacksの出力ファイルから拡張子を省いた名前とも一致する。
※右はparentとする。
※エクセルで作成してタブ区切りテキストで保存すると、なぜか上手くいかなかった。

下のコマンドを実行する。
$ /Applications/stacks-2.54/cstacks -P ./stacks/ -M ./popmap_parent.txt -n 2 -p 2
-P: 解析に使用するtsvファイル(ustacksの出力)が入っているフォルダを指定する。
-M: F0のみのpopulation mapファイルを指定する。
-n: 祖父と祖母の間で同じオーソログとする最低距離(SNP数)。
-p: スレッド数。

出力ファイル
catalog.alleles.tsv.gz
catalog.snps.tsv.gz
catalog.tags.tsv.gz


1-3) sstacks: 各個体のSNPsをジェノタイプする。

全個体を含んだpopulation mapを作成し、テキスト形式で保存する(popmap_all.txt)。
parent001[タブ]parent[改行]
parent002[タブ]parent[改行]
progeny003[タブ]progeny[改行]
progeny004[タブ]progeny[改行]
progeny005[タブ]progeny[改行]
.
.
.

下のコマンドを実行する。
$ /Applications/stacks-2.54/sstacks -P ./stacks/ -M ./popmap_all.txt -p 2
-P: 解析に使用するtsvファイル(ustacksとcstacksの出力)が入っているフォルダを指定する。
-M: 全個体を含んだpopulation mapを指定する。
-p: スレッド数。

出力ファイル(個体ごとに1つのファイルが作られる)
parent001.matches.tsv.gz
.
.
.


1-4) tsv2bam: ペアエンドのもう片方のリードをくっつけて、BAMファイルを作る。下のコマンドを実行する。
$ /Applications/stacks-2.54/tsv2bam -P ./stacks/ -M ./popmap_all.txt -R ./rawdata/ -t 2
-P: ustacks, cstacks, sstacksの出力ファイルの入ったフォルダを指定する。
-M: 全個体の入ったpopulation mapを指定する。
-R: ペアエンドの後ろの方(まだ解析していない方)のファイルが入ったフォルダを指定する。ペアエンドの前の方の名前が「hoge.fastq.gz」だった場合、後ろの方の名前はそれに「.2」を加えて「hoge.2.fastq.gz」にしておく。
-t: スレッド数。

出力ファイル例
parent001.matches.bam
.
.
.
tsv2bam.log


1-5) gstacks: 全体を通してSNPの特定とジェノタイプをする。下のコマンドを実行する。
$ /Applications/stacks-2.54/gstacks -P ./stacks/ -M ./popmap_all.txt -t 2
-P: ustacks, cstacks, sstacks, tsv2bamの出力ファイルの入ったフォルダを指定する。
-M: 全個体を含んだpopulation mapを指定する。
-t: スレッド数。

出力ファイル
catalog.calls
catalog.fa.gz
gstacks.log
gstacks.log.distribs


1-6) populations: vcfファイルを作る。
$ /Applications/stacks-2.54/populations -P ./stacks/ --vcf -t 2 -r 0.75 --write-single-snp
-P: 入出力ファイルのフォルダを指定する。
--vcf: SNPsをvcf形式で出力する。
-t: スレッド数。
-r: 必要最低カバレージ。ジェノタイピングできた個体の割合がこの値より高いローカスのみを出力する(低いローカスは削除される)。
--write-single-snp: ローカス内に複数のSNPsがある場合、最初のSNPのみを出力する。

出力ファイル
populations.haplotypes.tsv
populations.hapstats.tsv
populations.log
populations.log.distribs
populations.snps.vcf(SNPデータの入った出力ファイル)
populations.sumstats_summary.tsv
populations.sumstats.tsv


トップに戻る


2) Lep-MAP3: 連鎖群(LGs)作成
※javaを使用します。
※今回は、populations.snps.vcfをもとに、F0がaaxbbのローカスのみのファイル(aaxbb.snps.vcf)を作成して解析しました。

2-1) Pedigree fileをエクセルで作り、タブ区切りテキスト(pedigree.txt)で保存する。
CHRPOSfamily_namefamily_namefamily_namefamily_name.....
CHRPOSparent001parent002progeny003progeny004.....
CHRPOS00parent001parent001.....
CHRPOS00parent002parent002.....
CHRPOS1200.....
CHRPOS0000.....
1行目:上の通りにする。
2行目:parent001やprogeny003は、vcf入力ファイルで使っている個体名と一致させる。
3行目:全てのF2個体(progeny)について、祖父(F0オス)を指定。
4行目:全てのF2個体(progeny)について、祖母(F0メス)を指定。
5行目:性別を指定。祖父は1、祖母は2とする。F2個体は0でいいみたい。
6行目:意味はわからないが、全個体0とするみたい。


2-2) ParentCall2: 下のコマンドを実行する。
$ java -cp /Applications/Lep-MAP3/binary+code/bin ParentCall2 data = pedigree.txt vcfFile = aaxbb.snps.vcf > p.call
data: 上で作成したPedigree fileを指定する。
vcfFile: vcf入力ファイルを指定する。


2-3) Filtering2: 下のコマンドを実行する。
$ java -cp /Applications/Lep-MAP3/binary+code/bin Filtering2 data = p.call removeNonInformative = 1 dataTolerance = 0.001 > p_fil.call
data: 上の解析の出力ファイルを指定する。
removeNonInformative: 1を指定すると、情報のないローカスは削除される。
dataTolerance: 予想される遺伝子型分離比(この場合1:2:1)からのずれが許容される下限を指定する。


2-4) SeparateChromosomes2: ローカスをLGごとに分ける。下のコマンドを実行する。
$ java -cp /Applications/Lep-MAP3/binary+code/bin SeparateChromosomes2 data = p_fil.call lodLimit = 10 theta = 0.05 > map.txt
data: 上の解析の出力ファイルを指定する。
lodLimit: 同じLGにまとめる際に許容されるLODスコア。
theta: 組み替え率。

下のコマンドで、LGごとのローカス数を確認できる。
$ sort map.txt | uniq -c | sort -n
1 #java SeparateChromosomes2 data=p_fil.call lodLimit=10 theta=0.05
3 24
4 23
9 22
11 21
12 20
13 19
16 18
19 17
20 16
21 14
21 15
22 12
22 13
24 10
24 11
24 9
26 8
27 7
28 6
29 4
29 5
35 3
39 2
48 1
左列:ローカス数(map.txt内での行数)。
右列:LG番号。


2-5) OrderMarkers2: LGごとに、マーカーの位置(端からのcM)を計算する。下のコマンドを実行する。
$ java -cp /Applications/Lep-MAP3/binary+code/bin OrderMarkers2 data = p_fil.call map = map.txt sexAveraged = 1 > order01.txt
※計算ごとに異なるrandom seedが与えられ、結果が異なる。複数回(例えば20回)計算を繰り返し、LGごとに尤度が最大の結果をコピペして、一つのファイル(order.txt)にまとめる。


2-6) map2genotypes.awk: Lep-MAP3形式の出力ファイルを、一般的な出力ファイルに変換する。
Avi Karnさんのホームページからmap2genotypes.awkをダウンロードし、上の解析の出力ファイルと同じフォルダに保存して、下のコマンドを実行する。
$ awk -v fullData=1 -f map2genotypes.awk order.txt > genotypes.txt
※「=(イコール)」の前後にスペースを入れない。
※出力ファイルgenotypes.txtのマーカー名が書き換えられているので、下の手順で元のマーカー名に書き換える。
1) エクセルでmap.txtを読み込み、1行目を削除する。
2) エクセルでp_fil.callを読み込み、A列のマーカー名(8行目以下)をコピーして、map.txtのB列にペーストする(A, B列でマーカー数が同じか確認)。
3) map.txtで、A列が「0」のマーカーを削除する(LGに振り分けられていないため)。
4) エクセルでgenotypes.txtを読み込み、A列の仮マーカー名(7行目以下)をコピーして、map.txtのC列にペーストする。
5) map.txtのD列に、上から1, 2, 3, ...と番号を振る。
6) map.txtでC, D列を選択し、C列でソート(最小から最大)する。
7) map.txtでA, B, C, D列を選択し、D列でソート(最小から最大)する(A列のLG番号が昇順で並んでいること、C列の仮マーカー名がgeotypes.txtのA列と同じ並びであることを確認)。
8) map.txtのB列のマーカー名をコピーし、genotypes.txtのA列7行目以下にペーストする(マーカー数が正しいか確認)。
9) map.txtのA列のLG番号をコピーし、genotypes.txtのB列7行目以下にペーストする。
10) genotypes.txtを保存する。


トップに戻る


3) MapChart: LGsの可視化
※MapChartのMac版はない。Windows版を使う。

3-1) エクセルを使って、genotypes.txtから下のファイルを作成し、タブ区切りテキスト(genotypes_MapChart.txt)で保存する。
Group1
14300
94681.478
.
.
.
.
.
.
Group2
22600
374491.229
.
.
.
.
.
.
1行目:"Group"はヘッダーなので必ず入れる。1はLG番号。
2行目以降:左の数字はマーカー名。右の数字は、LG内でのマーカーの位置(cM)。
以下、LG2以降も同様。


3-2) WindowsでMapChart.exeをダブルクリックして立ち上げる。


3-3) 連鎖図を作成する。
「File」->「Open」-> 出てきたウィンドウの右下のプルダウンで「All files (*.*)」を選ぶ -> 上で作成した入力ファイル(genotypes_MapChart.txt)を選択して開くをクリック


3-4) 連鎖図を保存する。
「Chart」->「Print」-> プルダウンで「Adobe PDF」を選択 ->「OK」をクリック -> 保存先を選んで保存


トップに戻る


4) r/qtl2: 量的形質のマッピング
※Rで解析します。
※Rに、qtl2とyamlをダウンロードしておきます。

4-1) 下の5つのファイルを作り、ひとつのフォルダに保存します。1つはyamlファイル(テキスト形式で保存し、拡張子を.yamlにする)、4つはcsvファイル(genotypes.txtなどを参考にエクセルで作成し、カンマ区切りのテキストファイルで保存)です。共変量(covariates)がない場合は、data_covar.csvは不要。

data.yaml
crosstype: f2
geno: data_geno.csv
pheno: data_pheno.csv
covar: data_covar.csv(共変量がない場合はこの行は不要)
gmap: data_gmap.csv
alleles:
- A
- B
genotypes:
 AA: 1
 AB: 2
 BB: 3
na.strings:
- '-'
- NA

data_geno.csv
id11237143030561.....
progeny003ABABBB.....
progeny004AAABAB.....
progeny005AAAAAA.....
.
.
.
.
.
.
.
.
.
.
.
.
1行目:左端(id)は2行目以降のヘッダー。これに続く数字はローカス名。
2行目以降:左端はF2の個体名。これに続くABなどは、各ローカスの遺伝子型。genotypes.txtの「1 1」、「1 2」(または「2 1」)、「2 2」をそれぞれ「AA」、「AB」、「BB」に置換する。

data_pheno.csv
idpheno1pheno2
progeny0031.541.07
progeny0041.561.59
progeny0051.571.32
.
.
.
.
.
.
.
.
.
1行目:左端(id)は2行目以降のヘッダー。その右は量的形質の名前。量的形質はいくつあってもOK。
2行目以降:左端はF2の個体名。これに続く数値は、量的形質の値。

data_gmap.csv
markerchrpos
1123710
1430114.5
30561116.1
.
.
.
.
.
.
.
.
.
1行目:2行目以降のヘッダー。
2行目以降:左からマーカー名、LG番号、位置(cM)。

data_covar.csv(共変量がない場合は不要)
idsextank
progeny003ma
progeny004mb
progeny005fa
.
.
.
.
.
.
.
.
.
1行目:左端(id)は2行目以降のヘッダー。その右は共変量の名前。
2行目以降:左端はF2の個体名。これに続く文字は共変量。


4-2) Rを立ち上げ、 qtl2を呼び出す。
> library(qtl2)


4-3) 作業フォルダを、上で作ったファイルの入ったフォルダにする。
> setwd("/Volumes/hoge/")


4-4) data.yamlを読み込んでdataに格納する。
> data <- read_cross2("data.yaml")


4-5) dataの中のgmap(data_gmap.csv)を読み込んでmapに格納する。
a. そのまま行う場合
> map <- data$gmap
b. 各マーカー間を補完するように、pseudomarkersを挿入する場合
> map <- insert_pseudomarkers(data$gmap,step=1)
step: pseudomarkersの間隔(cM)。


4-6) 遺伝子型の確率を計算してprに格納する。
> pr <- calc_genoprob(data,map,error_prob=0.001)


4-7) 共変量をcovに格納する(共変量がない場合は不要)。
> sex <- match(data$covar$sex,c("f","m"))
> names(sex) <- rownames(data$covar)
> tank <- match(data$covar$tank,c("a","b"))
> cov <- cbind(sex,tank)


4-8) Haley-Knott regressionによるゲノムスキャンを行い、結果をoutに格納する。
a. 個体間の関係を考慮しない場合
> out <- scan1(pr,data$pheno,addcovar=cov)
b. 個体間の関係を考慮し、各LGをスキャンするときに全てのLGsから作成したkinship matrixを使用する場合
> kinship <- calc_kinship(pr)
> out <- scan1(pr,data$pheno,kinship,addcovar=cov)
c. 個体間の関係を考慮し、各LGをスキャンするときに他のLGsから作成したkiship matrixを使用する場合
> kinship <- calc_kinship(pr,"loco")
> out <- scan1(pr,data$pheno,kinship,addcovar=cov)
d. 個体間の関係を考慮し、各LGをスキャンするときに全てのLGsから作成したkinship matrixを使用し、マーカーの密度の影響を除く場合(4-5でmapにpseudomarkersを挿入している必要あり)
> grid <- calc_grid(data$gmap,step=1)
> pr_grid <- probs_to_grid(pr,grid)
> kinship <- calc_kinship(pr_grid)
> out <- scan1(pr,data$pheno,kinship,addcovar=cov)
e. 個体間の関係を考慮し、各LGをスキャンするときに他のLGsから作成したkinship matrixを使用し、マーカーの密度の影響を除く場合(4-5でmapにpseudomarkersを挿入している必要あり)
> grid <- calc_grid(data$gmap,step=1)
> pr_grid <- probs_to_grid(pr,grid)
> kinship <- calc_kinship(pr_grid,"loco")
> out <- scan1(pr,data$pheno,kinship,addcovar=cov)
addcovar: 共変量(additive covariates)がない場合は不要。Interactive covariatesとして解析する場合はintcovarにする。


4-9) 結果をプロットする。
> plot(out,map,lodcolumn=2,ylim=c(0,5))
lodcolumn: プロットする量的形質を指定する。data_pheno.csvの中での、左からの番号。
ylim: プロットの範囲(y軸の高さ)を指定する。指定しなかった場合、自動的に最適の範囲になる。


4-10) LODスコアの有意水準を計算する。
> operm <- scan1perm(pr,data$pheno,kinship,addcovar=cov,n_perm=1000,cores=4)
kinship: ゲノムスキャンで個体間の関係を考慮しなかった場合(4-8a)は不要。
addcovar: 共変量(additive covariates)がない場合は不要。Interactive covariatesとして解析する場合はintcovarにする。
n_perm: パーミュテーションの回数。
cores: スレッド数。「cores=0」にすると、使用しているコンピューターで可能な最大数を指定する。


4-11) 上のパーミュテーションの結果を見る。
> summary(operm,alpha=c(0.1,0.05))
LOD thresholds (1000 permutations)
pheno1 pheno2 pheno3 pheno4
0.1 3.36 3.31 3.27 3.35
0.05 3.69 3.69 3.70 3.67
alpha: 有意水準を指定する。指定しなかった場合、0.05の値のみ表示する。


4-12) LODスコアがある値以上のローカスを表示する。
> find_peaks(out,map,threshold=3.69)


4-13) 全ての個体、全ての量的形質、全てのローカスにおけるLODスコアを表示する。
> out


4-14) QTLの信頼区間をBayes法で推定する。
> bayes_int(out,map,lodcolumn=2,chr=7,prob=0.95)
lodcolumn: 量的形質を指定する。
chr: QTLのあるLGを指定する。
prob: 信頼区間の確率を指定する。


4-15) あるローカスの量的形質をプロットする。
> g <- maxmarg(pr,map,chr=1,pos=29.01,return_char=TRUE)
> plot_pxg(g,data$pheno[,2])
chr: プロットするローカスのLGを指定する。
pos: プロットするローカスの位置(cM)を指定する。
data$pheno[,2]の"2"は、プロットする量的形質を指定している(data_pheno.csvの中での、左からの番号)。


4-16) あるLGにおけるQTL効果をプロットする。
> c2eff <- scan1coef(pr[,1],data$pheno[,2])
> plot(c2eff,map[1],columns=1:3)
1行目:prの後の数字はプロットするLGを、phenoの後の数字はプロットする形質を指定する。
2行目:mapの数字はプロットするLGを指定する。


トップに戻る