識別差異甲基化區域的軟件 — DMRfinder

翻譯DMRfinder官方說明文檔

Introduction

DMRfinder 是一款用于WGBS的C位點提取、鑒定以及DMR分析的軟件,具體過程是:Bismark 軟件比對后,用 DMRfinder 提取CpG位點,然后識別差異甲基化區域(call DMR)并與DSS包的call DMR結果做比較。

Quick start

需要給的參數:

  • /path/to/genome:參考基因組絕對路徑
  • C1.fastq:對照組的 reads1
  • C2.fastq:對照組的 reads2
  • E1.fastq:實驗組的reads1
  • E2.fastq:實驗組的reads2

目的:尋找對照組和實驗組之間差異甲基化區域

Step 1: Alignment 比對

調用 Bismark 軟件進行比對

$ bismark_genome_preparation  /path/to/genome
$ bismark  /path/to/genome  C1.fastq
$ bismark  /path/to/genome  C2.fastq
$ bismark  /path/to/genome  E1.fastq
$ bismark  /path/to/genome  E2.fastq

Step 2: Extract methylation counts from alignment files

從比對結果文件中提取C位點:

$ samtools view -h C1_bismark_bt2.bam  |  python extract_CpG_data.py  -i -  -o C1.cov  -v
$ samtools view -h C2_bismark_bt2.bam  |  python extract_CpG_data.py  -i -  -o C2.cov  -v
$ samtools view -h E1_bismark_bt2.bam  |  python extract_CpG_data.py  -i -  -o E1.cov  -v
$ samtools view -h E2_bismark_bt2.bam  |  python extract_CpG_data.py  -i -  -o E2.cov  -v

Step 3: Cluster CpG sites into regions

將CpG位點合并成甲基化區域:

$ python combine_CpG_sites.py  -v  -o combined.csv  C1.cov  C2.cov  E1.cov  E2.cov

Step 4: Test regions for differential methylation

得到差異甲基化區域:

$ Rscript findDMRs.r  -i combined.csv  -o results.csv  -v  -n Control,Exptl  C1,C2  E1,E2

DMRfinder軟件依賴的軟件

  • DMRfinder
  • Bismark
  • Bowtie2
  • DSS包 這個包需要R和Bioconductor
  • Python
  • Samtools 可以使 Bismark 比對后的結果文件變成BAM

1、Alignment 比對

使用Bismark軟件對甲基化數據進行比對分析。Bismark將測序的結果和參考基因組都進行了C到T和G到A(反向互補)的轉化,將轉化后的測序結果和基因組分別進行兩兩比對,將所有的比對結果輸出。
Bismark軟件會展示三種序列環境下(CpG/CHG/CHH)的比對結果

比對之后,一些研究人員習慣去除PCR duplicates,我們這里不推薦用Bismark的去重腳本deduplicate_bismark完成去重,因為Bismark的去重腳本只是簡單粗暴的留下第一個比對上的文件直接刪除比對上同樣位置的其他文件,沒有考慮reads的序列信息和甲基化信息。
(Bismark 的 version 0.16.0版本有些小bug,我們推薦使用 version 0.15.0版本)

2、Extracting methylation counts

DMRfinder 軟件的extract_CpG_data.py腳本會將Bismark比對的結果文件轉變成一個展示每個CpG site的methylated/unmethylated數量的表格,這個表格按照染色體順序和位置進行了排序(是按照SAM文件的頭文件中參考基因組順序排列的)位置坐標是從1開始的(1-based)。
該腳本同時還合并了甲基化位點數量,因為它對每個CpG site統計了C和G的總數。

Usage: python extract_CpG_data.py  [options]  -i <input>  -o <output>
python extract_CpG_data.py \
    -i    Bismark 比對結果文件SAM
    -o    輸出文件,計算了CpGs序列環境下甲基化和未甲基化的個數,并進行了排序和位點合并
    -m    顯示CpG序列環境下甲基化位點的最小覆蓋度
    -s    在輸出文件的第三列顯示+/-鏈信息
    -n    bed文件列出發生甲基化的區域
    -b    內存參數
    -e    輸出文件按照染色體進行排序

輸入文件:-i

    -i <input>    SAM alignment file produced by Bismark (must have
                    a header, 'XM' methylation strings, and 'XG'
                    genome designations; can use '-' for stdin)

Bismark的結果文件SAM文件不管是壓縮沒壓縮的格式都可以作為輸入文件,如果是BAM文件作為輸入文件那必須保證安裝了Samtools,否則就轉換成SAM:

$ samtools view -h <BAM> | python extract_CpG_data.py  -i -  -o <output>  -v

輸出文件:-o

    -o <output>   Output file listing counts of methylated and
                    unmethylated CpGs, merged and sorted

輸出文件每一行都代表一個CpG位點,每一行有六列中間用tab鍵分割:

  • chrom 染色體名稱
  • chromStart 胞嘧啶在CpG中的坐標(1-based)
  • chromEnd chromStart + 1
  • percent 在此位點甲基化水平
  • methylated 覆蓋到該位點的所有reads中支持甲基化的reads數
  • unmethylated 覆蓋到該位點的所有reads中不支持甲基化的reads數

-m

    -m <int>      Minimum coverage (methylation counts) to report a
                    CpG site (def. 1)

-m參數用來指定每個CpG site至少出現的甲基化數量,低于指定參數將不會輸出到結果文件。默認是1,意思是說所有的CpG site中至少出現一個甲基化C位點才會在輸出文件中顯示

-s

-s            Report strand in third column of output

加上這個參數,輸出文件的第三列將用鏈的信息代替chromEnd,因為輸出結果是經過合并的,所以鏈信息總是 +

-n

    -n <file>     BED file listing regions for which to collect
                    linked methylation data

bed輸入文件應該列出每個感興趣的基因區域的染色體名稱,開始和結束坐標(1-based),唯一的region 名稱,用tab鍵分開,比如:

chrZ   100   200   regionA

輸出文件<file>_linked.txt中將會列出bed文件里reads上每一個region的甲基化數據, 在該region至少有一個CpG。用0表示未甲基化,1 表示甲基化,-表示沒有數據,比如:

Region: regionA, chrZ:100-200
Sites: 102, 109, 123, 140, 147, 168
00100-  read1
001100  read2
--0000  read3

這表明,在regionA有6個CpG sites,對應于3條reads上的6列數字01-。reads1位置123處顯示的是1表示該CpG sites發生了甲基化,而位置102, 109, 140, and 147, 顯示的是數字0表示CpG sites未甲基化。最后一個CpG sites在位置168上,顯示的是 - 表示reads1上沒有覆蓋此位置。

-b

    -b            Memory-saving option (with coordinate-sorted SAM)

加上此參數,腳本將會一次處理一條染色體,而不是將所有甲基化數據存入內存。這需要我們預先對SAM文件進行排序(比如使用:samtools sort)。對于大型輸入文件我們推薦加上此選項。搭配下面介紹的-e參數,以及combine_CpG_sites.py腳本里面的-b-e參數。

-e

    -e <file>     Output file listing ordered chromosomes

選上此參數,輸出文件將會按照染色體排好序,同時搭配參數-b時候后按照染色體排好序的輸出文件會提供給combine_CpG_sites.py腳本。前提條件是每一個SAM文件是按照相同的順序排序的。
注意:這個腳本是專門用來合并 CpG甲基化位點個數的。想要得到全面的甲基化信息,比如:CHG/CHH甲基化數量或者M-bias plots,可以使用Bismark 軟件中bismark_methylation_extractor腳本。使用該腳本想要輸出類似我們腳本extract_CpG_data.py輸出的合并結果,必須運行coverage2cytosine腳本(帶有--merge_CpG參數)

3、Clustering CpG sites into regions

DMRfinder軟件中的combine_CpG_sites.py腳本在單個 CpG 位點獲取一個或者多個樣本的甲基化數據,并單個輸出。按照下面的三步操走,會將相鄰的CpG 位點聚集成一個region,并對每個樣本區域內的甲基化數據求和:

Usage: python combine_CpG_sites.py  [options]  -o <output>  [<input>]+
    [<input>]+    One or more files, each listing methylation counts
                    for a particular sample
    -o <output>   Output file listing genomic regions and combined
                    methylation counts for each sample
  Options:
    To consider a particular CpG:
      -r <int>    Min. number of counts at a position (def. 3)
      -s <int>    Min. number of samples with -r counts (def. 1)
    To analyze a region of CpGs:
      -d <int>    Max. distance between CpG sites (def. 100)
      -c <int>    Min. number of CpGs in a region (def. 3)
      -x <int>    Max. length of a region (def. 500)
    To report a particular result:
      -m <int>    Min. total counts in a region (def. 20)
    Other:
      -f          Report methylation fraction for each sample
      -y <file>   Report clusters of valid CpG sites;
                    if <file> exists, use these clusters
      -b          Analyze one chromosome at a time (memory-saving)
      -e <file>   File listing ordered chromosome names (comma-
                    separated; used only with -b option)

[<input>]+

    [<input>]+    One or more files, each listing methylation counts
                    for a particular sample

這些文件沒有表頭,且每行必須有六個用tab鍵分開的字段,第一,第二,第五和第六列分別是染色體名稱,位置,甲基化個數和未甲基化個數(不使用第三和第四列)。這種格式由DMRfinder軟件 extract_CpG_data.py腳本生成的(bismark軟件的coverage2cytosine腳本加上--merge_CpG參數也會生成相同的格式)

-o

    -o <output>   Output file listing genomic regions and combined
                    methylation counts for each sample

輸出文件的表頭包括:chrstartendCpG,以及輸入文件中的兩列(不加后綴的樣品名后跟 -N,樣品名稱后面跟 -X)。第四列給出了基因區域的位置(startend給出的就是在該region中CpG sites第一個和最后一個位置信息,從1開始計數的)同時包含了CpG sites的數量。其余列給出了每個樣品的甲基化數據,-N列給出了樣品在該區域CpG sites的總個數,-X 列給出了其中發生甲基化的個數。

下面詳細講解如何通過這三步合并CpG sites位點為region的,在附錄A中給出了示例說明。

第一步,根據 -r-s 兩個參數來確定滿足覆蓋度標準的CpG sites:

    To consider a particular CpG:
      -r <int>    Min. number of counts at a position (def. 3)
      -s <int>    Min. number of samples with -r counts (def. 1)

在給定的樣本中, CpG sites數量達不到-r指定的最小閾值都會被忽略,注意這里說的CpG sites數量包括甲基化的和未甲基化的,甲基化分數并沒有考慮進去(the methylation fraction is not taken into account),默認值為3。當設置-r參數為1時意味著每個site都會被分析。
一旦所有樣品的單個CpG sites被確定,-s其實就沒有多大用了,默認值為1,意味著只要有一個樣本滿足-r的條件就行,所以就相當于沒有過濾任何sites。

第二步,通過三個參數-d-c-x將單個的CpG sites聚類成一個region:

    To analyze a region of CpGs:
      -d <int>    Max. distance between CpG sites (def. 100)
      -c <int>    Min. number of CpGs in a region (def. 3)
      -x <int>    Max. length of a region (def. 500)

-d參數所指定距離內的所有CpG sites都會被聚類到一起。例如,默認距離100bp,CpGs 在位置坐標為100/120/200和300處的都會被聚到一類,而在401位置處的不會被聚到這一類中,因為它距離最近的CpG sites超過了100bp。
-c參數指定了每個region至少含有的CpG 個數,否則該region將不會被展示到結果報告中,默認值是3。如果設置為-c 1意味著所有的region都會被reported。

-x參數設置了每個region最大的長度(默認是500bp)。其實該參數并沒有嚴格的執行,超過指定長度的region會按照-c閾值分成子類,如果region通過這種方式無法分割就會原樣輸出。注意,分割的每個子類必須滿足下面的-m參數指定的條件。

第三步,通過 -m 參數實現最后的過濾,該參數指定了每個樣本region中總計數的最小值:

    To report a particular result:
      -m <int>    Min. total counts in a region (def. 20)

對于每個region,每個樣本中有效的CpG sites不管有沒有發生甲基化都會被計算進去,也就是說,total counts in a region = methylated + unmethylated 。任何一個樣本只要total counts in a region小于-m參數給定的閾值,在輸出文件中-N-X列都會顯示為NA,否則的話,-N列會顯示total counts in a region-X列會顯示the methylated sum
注意,所謂有效的CpG sites就是要對所有的樣本都是有效的,即使那些沒有滿足-r參數的樣本。

-f

    Other:
      -f          Report methylation fraction for each sample

使用此參數,每個樣品的輸出文件將僅包含一列:甲基化百分數methylation fraction in each region,該值是由該region發生甲基化的CpG sites總數除以該region總CpG sites個數得到的,而不是這些CpG sites甲基化分數的平均值。
也就是說,methylation fraction in each region = the sum of methylated counts at the CpG sites within a region / the total sum of counts

-y

      -y <file>   Report clusters of valid CpG sites;
                    if <file> exists, use these clusters

如果給指定文件<file>不存在,該參數會創建一個文件來展示聚類情況,每個聚類是一行(每行展示reference name和CpG sites,用逗號分割)

如果指定文件<file>存在,該參數將用文件中定義好的聚類去計算輸入文件中methylation counts總數,除了-m參數以外的其他聚類參數(-r, -s, -d, -c, -x)都會被忽略。

對于處理大量數據或者大量不同樣本數據來說,這個參數帶來了很大的便利。它可以展示樣本的子類的聚類,然后用定義好的聚類去所有樣本中提取計數結果,這會節約很多時間消耗和資源消耗。

-b

      -b          Analyze one chromosome at a time (memory-saving)

這個參數可以讓腳本一次分析輸入文件中的一條染色體,而不是一次將輸入文件中的所有數據都加載到內存中,對于大型的輸入文件首選此選項。

這里注意一下,染色體順序一定要與輸入文件中的染色體順序保持一致。

默認情況下,腳本會嘗試從輸入文件構建正確的染色體順序,但在少數情況下(比如當多個樣本染色體數目不完整時)腳本無法產生正確的順序并認為輸入文件沒有排好序,而且一旦遇到這種情況將會特別浪費資源。為了避免的出現這種情況,可以使用下面將要介紹的-e參數。

-e

      -e <file>   File listing ordered chromosome names (comma-
                    separated; used only with -b option)

這個參數可以讓我們自己給定一個染色體順序文件,該文件中各染色體用逗號分隔開,或者寫成一個list每行是一個染色體。我們輸入文件提供的甲基化數量一定要與這里的染色體順序一致。 Note that one can use the file generated via the -e option of extract_CpG_data.py.

4、Testing regions for differential methylation

DMRfinder 軟件中 findDMRs.r 腳本對樣品組進行成對兒的比較以發現差異甲基化區域。底層的統計學原理是基于β二項分布模型(beta-binomial hierarchical modeling)和Wald 檢驗(Wald test),其中 Wald 檢驗在DSS包中已經測試過了。附錄B中提供了findDMRs.r用法的說明性示例。

Usage: Rscript findDMRs.r  [options]  -i <input>  -o <output>  \
             <groupList1>  <groupList2>  [...]
    -i <input>    File listing genomic regions and methylation counts
    -o <output>   Output file listing methylation results
    <groupList>   Comma-separated list of sample names (at least two
                    such lists must be provided)
  Options:
    -n <str>      Comma-separated list of group names
    -k <str>      Column names of <input> to copy to <output> (comma-
                    separated; def. "chr, start, end, CpG")
    -s <str>      Column names of DSS output to include in <output>
                    (comma-separated; def. "mu, diff, pval")
    -c <int>      Min. number of CpGs in a region (def. 3)
    -d <float>    Min. methylation difference between sample groups
                    ([0-1]; def. 0.10)
    -p <float>    Max. p-value ([0-1]; def. 0.05)
    -q <float>    Max. q-value ([0-1]; def. 1)
    -up           Report only regions hypermethylated in later group
    -down         Report only regions hypomethylated in later group
    -t <int>      Report regions with at least <int> comparisons
                    that are significant (def. 1)

-i

    -i <input>    File listing genomic regions and methylation counts

-i 指定輸入文件,必須是由tab鍵分割并包含:chrstartend,和CpG。另外對于每一個分析樣本必須包含兩列:-N后面的樣本名稱和-X后面的樣本名稱,這是由combine_CpG_sites.py腳本產生的格式。

-o

    -o <output>   Output file listing methylation results

輸出文件就是成對兒比較后得到的差異甲基化區域,通過特定的參數(-c / -d /-p / -q / -up / -down / -t 下面會介紹)篩選出差異甲基化區域,每個差異甲基化區域包括同樣的四列:chrstartend,和 CpG。除此之外還包括了DSS包的統計結果(methylation levels, differences, and p-values; see -k, -s below)。

<groupList>

    <groupList>   Comma-separated list of sample names (at least two
                    such lists must be provided)

### 以逗號分隔的樣本名稱列表(必須提供至少兩個這樣的列表)

這是每組要鑒定差異甲基化的樣品列表。樣品名一定要與其在輸入文件中的表頭相匹配(not including the -N and -X)。因為是兩兩比較找差異甲基化,所以必須至少提供兩個list。當提供了兩個以上的組別時,該腳本就會兩兩成對兒進行比較。
一個樣本不能出現多次,就算是在不同組別中出現的也不行。

-n

    -n <str>      Comma-separated list of group names

<groupList>相對應,各組名之間用逗號分割,如果沒有提供,該參數默認情況下組名會使用list中的一對兒樣品名中間用-連接。

-k

    -k <str>      Column names of <input> to copy to <output> (comma-
                    separated; def. "chr, start, end, CpG")

選擇輸出文件想要包含輸入文件的字段,默認是輸入文件中的四列(chr, start, end, CpG),使用-k參數指定想要輸出的列會加到這四列的后面。比如,如果輸入文件包括基因組注釋信息,那-k后加上注釋列的列標題輸出文件中就會包含基因注釋列。

-s

    -s <str>      Column names of DSS output to include in <output>
                    (comma-separated; def. "mu, diff, pval")

加上-s參數,輸出文件中將包含DSS包的分析結果。默認值是:mu(methylation fraction),diff(methylation difference),pval(p-value),用-s指定DSS輸出文件中想要展示在這里的列,將會添加到默認的這三列的后面。DSS (v2.14.0)可選擇的值有:phidiff.sestat,和fdr。當-q參數被指定,fdr會自動的被選擇。

每組中甲基化分數(methylation fraction)以這種方式:group:mu展示。對于組與組之間的比較結果與給定組中的mu值會有稍微的不同,因為這里展示的值是輸出文件中的平均值,report中每組其他值(value)也是這樣的情況

每組之間的差異甲基化和p-value在report中以這種方式進行展示:group1->group2:diffgroup1->group2:pval。兩組之間的差異都是group2相對于group1而言的,所以當value小于0說明group2甲基化程度低。由于report中甲基化水平偶爾會出現前后不一致的情況(前面說過這種情況),所以當group1->group2:diff為負數時并不能完全說明group2:mu就一定小于group1:mu(group2的甲基化程度小于group1)

-c

    -c <int>      Min. number of CpGs in a region (def. 3)

任何一個不包括 CpG sites 區域都會被排除,這個參數等價于 -c in combine_CpG_sites.py

-d

    -d <float>    Min. methylation difference between sample groups
                    ([0-1]; def. 0.10)

-d參數來指定最小的差異甲基化顯著值,默認是0.1,意味著兩組之間至少存在10%的差異甲基化(或正數或負數)。當-d參數設定為0時意味著任何一個區域都會被顯示,除非NA

-p

    -p <float>    Max. p-value ([0-1]; def. 0.05)

該參數用來設定最大的差異甲基化p-value值,默認是0.05,說明每組之間的p-value必須小于0.05。當-p參數指定為1時意味著所有region都會被展示,除非顯示的是NA

-q

    -q <float>    Max. q-value ([0-1]; def. 1)

-q參數用來設置最大的q-value值(校正后的p-value)。默認是1,意味著任何一個region都不會被過濾掉。當使用了此參數,兩組之間比較后的輸出文件中會自動添加上fdr列。

-up / -down

    -up           Report only regions hypermethylated in later group
    -down         Report only regions hypomethylated in later group

這個參數用來限制哪些region被展示。命令行給出的順序決定了哪個組別時later。

-t

    -t <int>      Report regions with at least <int> comparisons
                    that are significant (def. 1)

這個參數用來指定至少有幾組比較組合必須滿足參數(-d / -p / -q / -up / -down)的閾值才會顯示該region,默認是1,意味著只需有1個比較組合被這些參數認定為顯著就會顯示該region,其他組合中即使不滿足這些參數的閾值,該region也會在report中顯示。

特別的,當-t參數指定為0時,意味著-d / -p / -q / -up / -down這些參數將會被忽略,無論DSS結果是怎樣(包括NA)所有的region都會被顯示。

DMRfinder軟件所有腳本的公共參數

The following options work for all scripts in DMRfinder:

    -h/--help     Print the usage message
    --version     Print the version and copyright
    -v            Run the script in verbose mode (printing various
                    updates and statistics to stdout/stderr)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,224評論 6 529
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 97,916評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,014評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,466評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,245評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,795評論 1 320
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,869評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,010評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,524評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,487評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,634評論 1 366
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,173評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,884評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,282評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,541評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,236評論 3 388
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,623評論 2 370

推薦閱讀更多精彩內容