2020-06-09

popABC:群体历史动态模拟

其是由R和C++编写的程序,C++部分进行模拟分析的,有关R的部分则负责作图;也可用别的软件代替R来画图。

其他的模拟方法:
add:可以用它来生成大量模拟数据;R包'abc':对数据进行取样等各种分析

特点:

popABC能够模拟分枝间的基因流,而DIYabc不能;
popABC能够自动检测所有可能的拓扑结构(不超过5个居群);DIYabc必须手动设定拓扑结构;
popABC只支持二歧分枝,不支持多居群从同一点炸开;而DIYabc可以;
popABC只能单核,速度较慢(补救方法是多个实例一起跑,然后把结果拼在一起);DIYabc自动多线程,占用所有CPU资源;

下载地址:https://github.com/jsollari/popABC

安装配置:下载解压到目标目录后,将解压文件的bin目录路径添加到~/.bashrc文件中,在终端运行命令source ~/.bashrc即可

分析流程:

1.准备所需的文件;定义需要的统计量;定义模型和参数;

2.计算实际数据的统计量;

3.生成模拟数据,同时依据前面定义的统计量对每一份模拟数据计算统计量;

4.像其他的统计检验一样,看一下在一堆模拟数据的统计量中,定义的统计量在什么位置,查看各种分布……从而得出所需的结论,及各统计量的分布。

1.1 创建.pop文件

按照popABC给出的示例文件编写pop文件;
注意,要用's'或'm'注名每一个locus是SNP还是microsatelite。

1.2 由.pop文件生成.len文件

.len文件是popABC所使用的特殊格式;终端输入popabc,依次选择‘4’:tools;‘3’:pop文件转为len文件;输入.pop文件的名字;输入要生成的.len文件名;‘9’;‘5’;用文本编辑器打开生成的.len文件,检查文件是否为空,并核对居群数目、位点数目和位点类型

1.3 生成.sst文件(定义所需统计量)

sst文件定义了所需的统计量,分为两块,先是微卫星的统计量,再是SNP的统计量,0表示不计算,1表示计算,如下:
Microsatellites data:
-heterozygosity #1
-variance of alleles length #0
-number of alleles #1
-curtosis of alleles length #0
-Shanon's index  #1
-Nm estimator based on H  #1
Sequence data:
-mean of pairwise differences #0
-number of segregating sites #0
-number of haplotypes #0
-Shanon's index #0
-mean of MFS #0
-stdev of MFS #0
-Nm estimator based on S #0
-private segregating sites #0
-S(1) #0

1.4 制作.prs文件(定义模型、参数,和运行参数)

整个文件由分割线分成了三块;第一块是各种数字;第二块是各数字的注释(与第一块对应);第三块是标示一下有哪些树形结构。example中提供了1pop.prs-5pop.prs等若干示例;直接按照自己的居群数选择对应的示例进行修改即可;最好把第二块复制到一个新的文件里,和原文件的第一块对应着看,然后按自己的需求进行修改。第四行数据是树的拓扑结构,直接改成‘0’,即可检验所有可能的树形结构。

.prs文件示例如下:

100 1 3 3
1 1 0.75
s m s
5 2 0 1 0 10
1 0 5000
1 0 5000
1 0 5000
1 0 5000
1 0 5000
4 20 100 1 1
3 0 10
3 0 10
3 0 10
3 0 10
1 -3 0 0 0
1 -3 0 0 0
0
0
0


PopABC - Mark Beaumont & Joao Lopes  01/05/09
no_iterations, generation_time, no_populations, no_loci
escalar per locus (autosome - 1; X-linked - 0.75; <wbr> Y-linked or mtDNA - 0.25)
type of DNA data (s - sequence; m - microssatelites)
topology: 0 - uniform distribution;
     1 - choose topology from a list;
     2 - specify topology manually [e.g. ((Pop1,Pop2)Pop3) -> 1 2 2 3];
     3 - uniform distribution (and choose a Model marker);
     4 - choose topology from a list (and choose a Model marker);
     5 - specify topology manually (and choose a Model marker).
ne1 params: 1 - uniform distribtuion;
       2 - generalized gamma distribution;
ne2 params
ne3 params
neanc1 params
neanc2 params
t1 params: 1 - uniform distribtuion;
      2 - generalized gamma distribution;3 - uniform distribtuion (for all time events);

4 - generalized gamma distribution (for all time events);
      [for 1 and 2 t(n) is added to t(n+1)]
      [for 3 and 4 set only one priors for all t(n)]

t2
mig1 params: 0 - no migration;
       1 - uniform distribtuion;
       2 - generalized gamma distribution;
       3 - uniform distribtuion (on number of migrations);
       4 - generalized gamma distribution (on number of migrations).
       [for 3 and 4 real mig rate is calculated as nmig/Ne]
mig2 params
mig3 params
miganc1 params
mutM params: 0 - no mutation
       1 - lognormal distribution: (mean of mean(log10); stdev of mean(log10);
mean of Sdev(log10); stdev of stdev(log10). Stdev truncated at 0.
       2 - normal distribution: (mean of mean; stdev of mean; mean of Sdev;
stdev of stdev. Stdev truncated at 0.
mutS params:
recM params: 0 - no recombination;
       1 - lognormal distribution: (mean of mean(log10); stdev of mean(log10);
mean of Sdev(log10); stdev of stdev(log10). Stdev truncated at 0.
       2 - normal distribution: (mean of mean; stdev of mean; mean of Sdev;
stdev of stdev. Stdev truncated at 0.
recS params
migweight: 0 - do not use migweights matrix;
      1 - use migweights matrix as following:0 mw112 mw113
      0 mw122 mw123
      mw211 0 mw213
      mw221 0 mw223
      mw311 mw312 0
      mw321 mw322 0
, where mwitj is the prob that the fraction of migrantes in pop i comes from pop j at a period of time before time event t. Sum of prob should be equal to 1. [only use migweight if the topology is specified (option 1,2,4 or 5)]


Tree topology:

|| Neanc2
|| |
t2|| ------------
|| | |
|| Neanc1 |
|| | |
|| | |
t1|| --------- |
|| | | |
|| | | |
/ Ne Ne Ne

2.生成.trg等一系列文件(计算实际数据的各统计量)

终端运行如下命令:

summdata example.len example.sst example

共生成三个文件:example.trg; example.ssz;example_trg.txt;其中example_trg.txt是工作日志,出错时可以检验其内容;example.ssz文件里是各位点的size;example.trg文件是实际数据的各统计量;可以打开example.trg文件看一下,数目和数值是否有异常。

3.1 生成模拟数值

终端运行如下命令:

simulate example.prs example.ssz example.sst example

最终会生成文件名example.dat文件和同名的example.txt文件;每生成5万个数据,在终端窗口有一次提醒。在生成的过程中,也可notepad打开.dat文件,看看生成到第几个了,从而预估完成时间。其中.txt文件是工作日志,后面会用到。example.dat文件是需要的模拟数据,里面每一行是一次模拟结果。

3.2 运行多个实例

开启多个终端窗口,分别运行上面的命令;每次修改一个不同的输出文件名即可。

注意:不可从同一个文件夹运行多个实例,因为软件会在文件夹下没有后缀名的INTFILE文件里存储随机种子,多个实例会互相干扰;要把整个文件夹复制多份,每一个文件夹里运行一个实例;复制后,每个文件夹下INTFILE里的随机种子是相同的,运行的结果也会是相同的,应在每一个文件夹下,打开终端窗口,然后运行:

shuffle.exe xxxxx #xxxxx是自己随手敲的一个随机数
3.3 连续运行实例

当设置的iteration数目比较大(例如500万)时,软件会提示,计算量太大/文件太大,不能算;但是,这个“太大”是按照十年前计算机的标准……,可以把多条命令行写到同一个.bat文件里,两条命令之间要shuffle一次。准备多个这样的.bat文件(注意每一条的自定义结果名不能重复),同时运行。

3.4 多个实例运行结果的拼接

把所有的.dat文件复制到同一个文件夹下。使用R语言把它们拼接到一起。打开R语言(推荐Rstudio.有时不支持中文路径名),运行如下命令:

setwd(choose.dir()) #设定工作目录:在弹出的窗口里选择放dat文件的文件夹
choose.files(default = getwd())->filestocombine #选择dat文件:在弹出的窗口里选择所有要拼接的dat文件
outfile <- 'combinedData.dat' #设置输出文件名:combinedData.dat,或者别的什么名字。**不要和已有文件重复。**

如果dat文件都不太大,则可运行如下:

countlines <- 0
for(i in 1:length(filestocombine)){
               read.table(file = filestocombine[i])->towrite
               countlines <- countlines + nrow(towrite)
               write.table(towrite,file = outfile, quote = F, row.names = F, col.names = F, sep = ' ', append = T)
cat(i,'in',length(filestocombine),'\n')}
cat('total rows of data:', countlines, '\n')
rm(towrite)

如果dat文件很大(几百个m那种):

install.packages('data.table') #第一次使用data.table先安装
library('data.table') #安装之后,每次不需要重复上步,直接library载入即可。
countlines <- 0
for(i in 1:length(filestocombine)){
              fread(input = filestocombine[i]) ->towrite
              countlines <- countlines + nrow(towrite)
              fwrite(towrite,file = outfile, quote = F, row.names = F, col.names = F, sep = ' ', append = T)
             cat(i,'in',length(filestocombine),'\n')}
cat('total rows of data:', countlines, '\n')
rm(towrite)

拼接过程中,输出的数字是拼到第几个文件了;全部完成后,会输出总的模拟数目:'total rows of data: xxxxx’。如果之前程序被强行中止的话,.dat文件最后一行会不完整。

===以下的内容都无效了,改用R语言包'abc'对模拟结果进行分析。====

4.1 挑出与实际结果最接近的一批模拟

终端运行:

rejection  拼接的结果文件.dat 之前生成的.trg 自定义的输出文件名 x y rate

其中,x为参数(parameter)数目,y为统计数据(summstats)数目,这两个数据可以在模拟时生成的任意一个日志txt中看到(用notepad打开);rate是挑选的模拟的比例,例如0.01,就是挑选与实际结果最接近的百分之一;最终生成3个文件:一个.pri文件,一个.rej文件,一个_rej.txt文件;其中,.pri文件里是一万个随机挑选出来的模拟结果(仅包含参数),用来代表所有的模拟结果;.rej文件里是按比例挑出的与实际结果最接近的模拟结果(包含参数和统计数据);_rej.txt里是工作日志,里面可以看到所有模拟结果中每个统计数据的分布。

4.2 在R语言绘图

程序的scripts文件中提供了绘图的脚本,但是并不那么好用;可以自己修改,以满足自己的需要。

setwd(choose.dir()) #设置工作目录
abc.rej <- data.matrix(read.table(choose.files())) #选择并读取分析所用的.rej文件
priors <- data.matrix(read.table(choose.files())) #选择并读取分析所用的.pri文件

画不同model对应的后验概率柱状图

hist(abc.rej[,1],freq=F,main="prior (blue) and posterior (grey) distributions",xlab="top",col="grey",xlim = c(0,4), breaks = seq(0.5,3.5,1), labels = c(as.character(1:3))) 
#rej中第一列是"top"参数,即不同的模型;每个模型编号对应的树形见随软件的操作手册的最后部分;
#main是图的标题,xlab是x轴的标题,col为颜色,xlim为x轴的范围,breaks是按什么数值截断来画柱状图;
#labels是每个柱子上标什么字符。3个居群时,有3个树形模型。其它情况时xlim/breaks和labels要对应修改。
hist(priors[,1],freq=F,col=rgb(0,0,0.5, a=0.5),add=T,breaks = seq(0.5,3.5,1), density=9)
#在图上添加参数的先验分布(背景)。rgb()中的a表示透明度。density为纹饰。

以上参数画图如下:

popABC.jpeg

可见,不同模型先验分布几乎是相同的(这是我们在prs文件里的设定)。而模型3的后验概率最高,说明3号模型是最佳模型(这时下结论太粗糙!还需要各种后续分析)。由使用手册中可查到,3居群的3号模型为((1,2),0)

挑选出.rej文件中所有3号模型的行;然后可以进一步对model3之下的各参数进行分析。

abc.rej[which(abc.rej[,1]==3),]

进阶内容:

1 实例的强行中止

设置一个较大的iteration让电脑一直运行着,觉得差不多了,就手动中止;在运行过程中,用notepad打开.dat文件,可以看看已经生成了多少个模拟数据;

对终端运行中的simmulate程序,按下快捷键ctrl+c强制中止程序;强制中止后,.dat文件可能最后一行不完整;需要重新用notepad打开.dat文件,删去最后一行;强制中止的话,对应的txt格式的log文件是空的,看不见parameter和summstats的数目;可以先完整跑一个iteration比较少的程序,生成一个txt的log. 只要除了ieration数目之外的参数是一样的,不同的模拟的log文件里各数目就是一样的。

2 dat文件太大,rejection程序无法分析

当dat文件太大时(几个G),rejection.exe会报错如下:

error:: .dat file is too big to be analysed

这时,应把.dat文件打乱(如果是几个不同文件拼接的话)后拆分成若干份,分别运行rejection命令,然后把得到的.rej文件拼起来。

结果不符合预期时,该怎么办

2.1

summary(allsim[allsim[,1]==14,22:75])->temp
write.table(temp, file = 'model14.txt', quote = F, row.names = F, col.names = F)
n=21
hist(abc.rej[abc.rej[,1]==8,n])
hist(priors[abc.rej[,1]==8,n])

转自:xztswzm的博客 http://blog.sina.com.cn/xzwzm

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345