20261002
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
#! /usr/bin/env julia
|
||||
# Installing Dependencies
|
||||
## using Pkg
|
||||
## Pkg.add("Distributed")
|
||||
## Pkg.add("DataFrames")
|
||||
## Pkg.add("CSV")
|
||||
## Pkg.add("SNaQ")
|
||||
## Pkg.add("PhyloNetworks")
|
||||
## Pkg.add("RCall")
|
||||
## Pkg.add("PhyloPlots")
|
||||
## Pkg.add("QuartetNetworkGoodnessFit")
|
||||
|
||||
# Running SNaQ Analysis
|
||||
using PhyloNetworks, SNaQ;
|
||||
using Distributed;
|
||||
addprocs(9);
|
||||
@everywhere using PhyloNetworks, SNaQ;
|
||||
nruns = 100; # number of runs for each hmax
|
||||
astralfile = joinpath("..", "species_tree", "coal.tre");
|
||||
astraltree = readnewick(astralfile);
|
||||
|
||||
### Reading RAxML gene trees and ASTRAL species tree
|
||||
### running in raxml_snaq/ folder
|
||||
# raxmltrees = joinpath("..", "..", "species_tree", "all.trees");
|
||||
# inputCF = readtrees2CF(raxmltrees);
|
||||
# net0 = snaq!(astraltree, inputCF, hmax=0, filename="net0", seed=123, outgroup="ZJ", runs=nruns);
|
||||
# net1 = snaq!(net0, inputCF, hmax=1, filename="net1", seed=123, outgroup="ZJ", runs=nruns);
|
||||
# net2 = snaq!(net1, inputCF, hmax=2, filename="net2", seed=123, outgroup="ZJ", runs=nruns);
|
||||
# net3 = snaq!(net2, inputCF, hmax=3, filename="net3", seed=123, outgroup="ZJ", runs=nruns);
|
||||
# net4 = snaq!(net3, inputCF, hmax=4, filename="net4", seed=123, outgroup="ZJ", runs=nruns);
|
||||
|
||||
### Alternatively, reading in the input files from Bucky
|
||||
### running in input_snaq/ folder
|
||||
inputCFfile = joinpath("..", "bucky", "bucky_1", "input.mb.CFs.csv");
|
||||
inputCF = readtableCF(inputCFfile);
|
||||
net0 = snaq!(astraltree, inputCF, hmax=0, filename="net0", seed=123, outgroup="ZJ", runs=nruns);
|
||||
net1 = snaq!(net0, inputCF, hmax=1, filename="net1", seed=123, outgroup="ZJ", runs=nruns);
|
||||
net2 = snaq!(net1, inputCF, hmax=2, filename="net2", seed=123, outgroup="ZJ", runs=nruns);
|
||||
net3 = snaq!(net2, inputCF, hmax=3, filename="net3", seed=123, outgroup="ZJ", runs=nruns);
|
||||
net4 = snaq!(net3, inputCF, hmax=4, filename="net4", seed=12345, outgroup="ZJ", runs=nruns);
|
||||
|
||||
|
||||
# Plotting the SNaQ results
|
||||
using PhyloPlots, RCall;
|
||||
using PhyloNetworks, SNaQ;
|
||||
## Network scores vs. hmax
|
||||
net0 = readsnaqnetwork("net0.out");
|
||||
net1 = readsnaqnetwork("net1.out");
|
||||
net2 = readsnaqnetwork("net2.out");
|
||||
net3 = readsnaqnetwork("net3.out");
|
||||
net4 = readsnaqnetwork("net4.out");
|
||||
scores = [loglik(net0), loglik(net1), loglik(net2), loglik(net3), loglik(net4)];
|
||||
hmax = collect(0:4);
|
||||
R"pdf"("snaq_network_scores.pdf", width=12, height=8);
|
||||
R"plot"(hmax, scores, type="b", ylab="network score", xlab="hmax", col="blue");
|
||||
R"dev.off"();
|
||||
|
||||
## Rerooting and rotating the networks for better visualization
|
||||
rootatnode!(net1, "ZJ");
|
||||
rootatnode!(net2, "ZJ");
|
||||
rootatnode!(net3, "ZJ");
|
||||
rootatnode!(net4, "ZJ");
|
||||
### rotate!(net1, -2);
|
||||
### rotate!(net2, -2);
|
||||
### rotate!(net3, -2);
|
||||
### rotate!(net4, -2);
|
||||
|
||||
## Plotting the networks
|
||||
R"pdf"("snaq_networks_fulltree.pdf", width=14, height=10);
|
||||
R"layout(matrix(1:4, 2, 2, byrow=TRUE))"; # to get 4 plots into a single figure: 2 row, 2 columns
|
||||
R"par"(mar=[0, 0, 1.5, 0]); # for smaller margins
|
||||
xmin, xmax = PhyloPlots.PhyloPlots.edgenode_coordinates(net1, false, false)[13:14];
|
||||
xmax += (xmax - xmin) * 0.3;
|
||||
plot(net1, showgamma=true, tipoffset=0.1, xlim=[xmin, xmax]);
|
||||
R"mtext"(string("hmax=1, loglik=-", round(loglik(net1), digits=2)), font=2);
|
||||
xmin, xmax = PhyloPlots.PhyloPlots.edgenode_coordinates(net2, false, false)[13:14];
|
||||
xmax += (xmax - xmin) * 0.3;
|
||||
plot(net2, showgamma=true, tipoffset=0.1, xlim=[xmin, xmax]);
|
||||
R"mtext"(string("hmax=2, loglik=-", round(loglik(net2), digits=2)), font=2);
|
||||
xmin, xmax = PhyloPlots.PhyloPlots.edgenode_coordinates(net3, false, false)[13:14];
|
||||
xmax += (xmax - xmin) * 0.3;
|
||||
plot(net3, showgamma=true, tipoffset=0.1, xlim=[xmin, xmax]);
|
||||
R"mtext"(string("hmax=3, loglik=-", round(loglik(net3), digits=2)), font=2);
|
||||
xmin, xmax = PhyloPlots.PhyloPlots.edgenode_coordinates(net4, false, false)[13:14];
|
||||
xmax += (xmax - xmin) * 0.3;
|
||||
plot(net4, showgamma=true, tipoffset=0.1, xlim=[xmin, xmax]);
|
||||
R"mtext"(string("hmax=4, loglik=-", round(loglik(net4), digits=2)), font=2);
|
||||
R"dev.off"();
|
||||
|
||||
R"pdf"("snaq_networks_majortree.pdf", width=14, height=10);
|
||||
R"layout(matrix(1:4, 2, 2, byrow=TRUE))"; # to get 4 plots into a single figure: 2 row, 2 columns
|
||||
R"par"(mar=[0, 0, 1.5, 0]); # for smaller margins
|
||||
xmin, xmax = PhyloPlots.PhyloPlots.edgenode_coordinates(net1, false, false)[13:14];
|
||||
xmax += (xmax - xmin) * 0.3;
|
||||
plot(net1, style=:majortree, showgamma=true, tipoffset=0.1, xlim=[xmin, xmax]);
|
||||
R"mtext"(string("hmax=1, loglik=-", round(loglik(net1), digits=2)), font=2);
|
||||
xmin, xmax = PhyloPlots.PhyloPlots.edgenode_coordinates(net2, false, false)[13:14];
|
||||
xmax += (xmax - xmin) * 0.3;
|
||||
plot(net2, style=:majortree, showgamma=true, tipoffset=0.1, xlim=[xmin, xmax]);
|
||||
R"mtext"(string("hmax=2, loglik=-", round(loglik(net2), digits=2)), font=2);
|
||||
xmin, xmax = PhyloPlots.PhyloPlots.edgenode_coordinates(net3, false, false)[13:14];
|
||||
xmax += (xmax - xmin) * 0.3;
|
||||
plot(net3, style=:majortree, showgamma=true, tipoffset=0.1, xlim=[xmin, xmax]);
|
||||
R"mtext"(string("hmax=3, loglik=-", round(loglik(net3), digits=2)), font=2);
|
||||
xmin, xmax = PhyloPlots.PhyloPlots.edgenode_coordinates(net4, false, false)[13:14];
|
||||
xmax += (xmax - xmin) * 0.3;
|
||||
plot(net4, style=:majortree, showgamma=true, tipoffset=0.1, xlim=[xmin, xmax]);
|
||||
R"mtext"(string("hmax=4, loglik=-", round(loglik(net4), digits=2)), font=2);
|
||||
R"dev.off"();
|
||||
|
||||
## expected vs. observed quartet concordance factors
|
||||
using CSV, DataFrames, Distributions, Random, RCall;
|
||||
using PhyloNetworks, SNaQ;
|
||||
using QuartetNetworkGoodnessFit;
|
||||
using Statistics, Printf;
|
||||
|
||||
inputCFfile = joinpath("..", "bucky", "bucky_1", "input.mb.CFs.csv");
|
||||
inputCF = readtableCF(inputCFfile);
|
||||
Random.seed!(123);
|
||||
jitter = 0.005;
|
||||
hmax_list = 0:3;
|
||||
|
||||
R"pdf"("expCFs_obsvsfitted.pdf", width=6, height=6);
|
||||
R"par(mfrow=c(2,2), mar=c(4,4,3,1))"
|
||||
gof_results = DataFrame(h=Int[], pvalue_normal=Float64[], pvalue_empirical=Float64[], z_uncorrected=Float64[], sigma=Float64[], nsim=Int[])
|
||||
|
||||
for h in hmax_list
|
||||
net = readsnaqnetwork("net$(h).out")
|
||||
topologymaxQpseudolik!(net, inputCF)
|
||||
|
||||
df_long = fittedquartetCF(inputCF, :long)
|
||||
df_jittered = deepcopy(df_long)
|
||||
df_jittered.obsCF .+= rand(Uniform(-jitter/2, jitter/2), nrow(df_long))
|
||||
df_jittered.expCF .+= rand(Uniform(-jitter/2, jitter/2), nrow(df_long))
|
||||
|
||||
res = quarnetGoFtest!(net, inputCF, false; seed=123, nsim=1000)
|
||||
z_obs = res[2]
|
||||
z_sim = sort!(res[6])
|
||||
p_emp = mean(z_sim .>= z_obs) # 经验 p 值:模拟 z 超过观测 z 的比例
|
||||
|
||||
# 存表时两种 p 值都留,加上模拟分布的特征备查
|
||||
push!(gof_results, (h=h,
|
||||
pvalue_normal=res[1],
|
||||
pvalue_empirical=p_emp,
|
||||
z_uncorrected=z_obs,
|
||||
sigma=res[3],
|
||||
nsim=1000))
|
||||
|
||||
|
||||
ptxt = p_emp == 0 ? "p < 0.001 (emp.)" : @sprintf("p = %.3f (emp.)", p_emp)
|
||||
ttl = "h = $h, $ptxt"
|
||||
R"plot"(df_jittered.obsCF, df_jittered.expCF,
|
||||
xlim=[0, 1.05], ylim=[0, 1.05],
|
||||
xlab="quartet CF observed in gene trees",
|
||||
ylab="quartet CF expected from network",
|
||||
main=ttl,
|
||||
pch=16, col="#008080", cex=0.5)
|
||||
R"abline"(0, 1, col="#008080", lwd=0.5)
|
||||
end
|
||||
|
||||
R"dev.off"();
|
||||
|
||||
CSV.write("gof_results.csv", gof_results)
|
||||
println(gof_results)
|
||||
|
||||
|
||||
net_final = readsnaqnetwork("net0.out");
|
||||
topologymaxQpseudolik!(net_final, inputCF);
|
||||
df_long = fittedquartetCF(inputCF, :long);
|
||||
|
||||
### Adding jitter to the points for better visualization
|
||||
df_jittered = deepcopy(df_long);
|
||||
df_jittered.obsCF .+= rand(Uniform(-jitter / 2, jitter / 2), nrow(df_long));
|
||||
df_jittered.expCF .+= rand(Uniform(-jitter / 2, jitter / 2), nrow(df_long));
|
||||
df_wide = fittedquartetCF(inputCF, :wide)
|
||||
println(names(df_wide))
|
||||
df_wide.outlier_p = res1[4]
|
||||
outliers = sort(df_wide[df_wide.outlier_p .< 0.01, :], :outlier_p)
|
||||
CSV.write("outlier_quartets_h1.csv", outliers)
|
||||
|
||||
|
||||
R"plot"(df_jittered.obsCF, df_jittered.expCF, xlab="quartet CF observed in gene trees",
|
||||
ylab="quartet CF expected from network", pch=16,
|
||||
col="#008080",
|
||||
cex=0.7);
|
||||
R"abline"(0, 1, col="#008080", lwd=0.5);
|
||||
R"dev.off"();
|
||||
|
||||
# Goodness of fit of the SNaQ networks
|
||||
using QuartetNetworkGoodnessFit;
|
||||
res1 = quarnetGoFtest!(net_final, inputCF, true; seed=123, nsim=1000);
|
||||
res1[[1, 2, 3]] # p-value, uncorrected z, σ
|
||||
z_obs = res1[2]
|
||||
z_sim = sort!(res1[6])
|
||||
p_emp = mean(z_sim .>= z_obs)
|
||||
Reference in New Issue
Block a user