From 8cd253360f9282de5860ef6eaff0a0392b991785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9cile=20An=C3=A9?= Date: Sun, 24 Mar 2019 14:25:55 -0500 Subject: [PATCH] bug fix to read list of tree files (#92) - bug fix to read bootstrap trees - model_response -> response, to fix deprecation from StatsBase - ignore .toml in doc - travis: julia 1.1, drop 0.7 - new logo --- .gitignore | 1 + .travis.yml | 3 +-- README.md | 4 ++-- docs/readme.md | 2 ++ docs/src/assets/logo.png | Bin 7017 -> 3170 bytes docs/src/lib/internals.md | 2 +- docs/src/logo_text.png | Bin 0 -> 7646 bytes docs/src/snaq.png | Bin 0 -> 22926 bytes examples/treefilelist.txt | 2 ++ src/bootstrap.jl | 31 +++++++++++++++++++------------ src/traits.jl | 17 +++++++++-------- test/test_bootstrap.jl | 5 +++++ test/test_lm.jl | 24 ++++++++++++------------ test/test_lm_tree.jl | 3 --- 14 files changed, 54 insertions(+), 40 deletions(-) create mode 100644 docs/src/logo_text.png create mode 100644 docs/src/snaq.png create mode 100644 examples/treefilelist.txt diff --git a/.gitignore b/.gitignore index c7ad7b1bb..dd39f26be 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.jl.mem docs/build/ docs/site/ +docs/*.toml # Compiled source # ################### diff --git a/.travis.yml b/.travis.yml index a267e70ac..f49fe91df 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,8 +5,7 @@ os: - linux - osx julia: - - 0.7 - - 1.0 + - 1.1 notifications: email: false diff --git a/README.md b/README.md index 7e7b2e666..aeac2d021 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# PhyloNetworks: analysis for phylogenetic networks +# PhyloNetworks: analysis for phylogenetic networks [![Build Status](https://travis-ci.org/crsl4/PhyloNetworks.jl.svg)](https://travis-ci.org/crsl4/PhyloNetworks.jl) [![](https://img.shields.io/badge/docs-stable-blue.svg)](https://crsl4.github.io/PhyloNetworks.jl/stable) @@ -42,7 +42,7 @@ If you use the package, please cite 34(12):3292–3298. [doi:10.1093/molbev/msx235](https://doi.org/10.1093/molbev/msx235) -## Maximum pseudolikelihood estimation of species network: SNaQ +## Maximum pseudolikelihood estimation of species network: SNaQ diff --git a/docs/readme.md b/docs/readme.md index f10e14bd9..39aa9f210 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -92,6 +92,8 @@ or interactively in `docs/`: ```shell pkg> activate . +pkg> status # just to check +pkg> status --manifest pkg> instantiate pkg> # dev PhyloPlots # to get the master branch pkg> dev ~/.julia/dev/PhyloNetworks diff --git a/docs/src/assets/logo.png b/docs/src/assets/logo.png index a243ccb8d584df44900b49f9047f3e937f986d29..161bc2fdd4ebe837f165d2f5cabd77b169df2ed9 100644 GIT binary patch literal 3170 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 IM6N<$f*f7eHUIzs literal 7017 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 BFf0H7 diff --git a/docs/src/lib/internals.md b/docs/src/lib/internals.md index ae6ba5f3c..a2fe1f456 100644 --- a/docs/src/lib/internals.md +++ b/docs/src/lib/internals.md @@ -32,7 +32,7 @@ Order = [:type] ```@autodocs Modules = [PhyloNetworks] Public = false -Order = [:function] +Order = [:function, :constant] ``` ```@meta diff --git a/docs/src/logo_text.png b/docs/src/logo_text.png new file mode 100644 index 0000000000000000000000000000000000000000..8f3c708ba877f157aac1c0ffb7cc3c375b57a490 GIT binary patch literal 7646 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∨-nRt1h<%@>z?vP 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 literal 0 HcmV?d00001 diff --git a/examples/treefilelist.txt b/examples/treefilelist.txt new file mode 100644 index 000000000..7d90b15de --- /dev/null +++ b/examples/treefilelist.txt @@ -0,0 +1,2 @@ +treefile.txt +treefile.txt diff --git a/src/bootstrap.jl b/src/bootstrap.jl index d6e5dcfb8..32ceb0e36 100644 --- a/src/bootstrap.jl +++ b/src/bootstrap.jl @@ -3,23 +3,30 @@ # Cecile April 2016 """ - readBootstrapTrees(filename) + readBootstrapTrees(listfile; relative2listfile=true) -input: name of file containing the path/name to multiple bootstrap files, one per line. -Each bootstrap file corresponds to bootstrap trees from a single gene. +Read the list of file names in `listfile`, then read all the trees in each of +these files. Output: vector of vectors of trees (networks with h>0 allowed). -output: vector of vectors of trees (networks with h>0 allowed). +`listfile` should be the name of a file containing the path/name to multiple +bootstrap files, one on each line (no header). Each named bootstrap file should +contain multiple trees, one per line (such as bootstrap trees from a single gene). + +The path/name to each bootstrap file should be relative to `listfile`. +Otherwise, use option `relative2listfile=false`, in which case the file names +are interpreted as usual: relative to the user's current directory +if not given as absolute paths. """ -function readBootstrapTrees(filelist::AbstractString) - s = open(filelist) # IOStream - bootfile = readdlm(s,AbstractString) - close(s) - size(bootfile)[2] == 1 || - error("there should be a single bootstrap file name on each row of file $filelist") - ngenes = size(bootfile)[1] +function readBootstrapTrees(filelist::AbstractString; relative2listfile=true::Bool) + filelistdir = dirname(filelist) + bootfiles = CSV.read(filelist, header=false, types=Dict(1=>String)) + size(bootfiles)[2] > 0 || + error("there should be a column in file $filelist: with a single bootstrap file name on each row (no header)") + ngenes = size(bootfiles)[1] + bf = (relative2listfile ? joinpath.(filelistdir, bootfiles[1]) : bootfiles[1]) treelists = Array{Vector{HybridNetwork}}(undef, ngenes) for igene in 1:ngenes - treelists[igene] = readMultiTopology(bootfile[igene]) + treelists[igene] = readMultiTopology(bf[igene]) print("read $igene/$ngenes bootstrap tree files\r") # using \r for better progress display end return treelists diff --git a/src/traits.jl b/src/traits.jl index 2aebb1823..dc4ddda36 100644 --- a/src/traits.jl +++ b/src/traits.jl @@ -1118,7 +1118,7 @@ Dominated by the `LinPredModel` class, from package `GLM`. The following StatsBase functions can be applied to it: `coef`, `nobs`, `vcov`, `stderror`, `confint`, `coeftable`, `dof_residual`, `dof`, `deviance`, -`residuals`, `model_response`, `predict`, `loglikelihood`, `nulldeviance`, `nullloglikelihood`, +`residuals`, `response`, `predict`, `loglikelihood`, `nulldeviance`, `nullloglikelihood`, `r2`, `adjr2`, `aic`, `aicc`, `bic`. The following StatsModels functions can also be applied to it: @@ -1575,7 +1575,7 @@ julia> round.(residuals(fitBM), digits=6) -0.211712 -0.439833 -julia> round.(model_response(fitBM), digits=5) +julia> round.(response(fitBM), digits=5) 197-element Array{Float64,1}: 4.44135 4.32106 @@ -1677,7 +1677,7 @@ function phyloNetworklm(f::Formula, else mm = ModelMatrix(mf) end - Y = convert(Vector{Float64},DataFrames.model_response(mf)) + Y = convert(Vector{Float64}, StatsModels.model_response(mf)) # Fit the model (Method copied from DataFrame/src/statsmodels/statsmodels.jl, lines 47-58) # (then StatsModels/src/statsmodels.jl lines 42-46) StatsModels.DataFrameRegressionModel(phyloNetworklm(mm.m, Y, net; @@ -1728,7 +1728,7 @@ StatsBase.deviance(m::PhyloNetworkLinearModel) = deviance(m.lm) # (Rescaled by cholesky of variance between tips) StatsBase.residuals(m::PhyloNetworkLinearModel) = m.RL * residuals(m.lm) # Tip data -StatsBase.model_response(m::PhyloNetworkLinearModel) = m.Y +StatsBase.response(m::PhyloNetworkLinearModel) = m.Y # Predicted values at the tips # (rescaled by cholesky of tips variances) StatsBase.predict(m::PhyloNetworkLinearModel) = m.RL * predict(m.lm) @@ -1741,8 +1741,8 @@ StatsBase.loglikelihood(m::PhyloNetworkLinearModel) = loglikelihood(m.lm) - 1/2 function StatsBase.nulldeviance(m::PhyloNetworkLinearModel) vo = ones(length(m.Y), 1) vo = m.RL \ vo - bo = inv(vo'*vo)*vo'*model_response(m.lm) - ro = model_response(m.lm) - vo*bo + bo = inv(vo'*vo)*vo'*response(m.lm) + ro = response(m.lm) - vo*bo return sum(ro.^2) end # Null Log likelihood (null model with only the intercept) @@ -1815,6 +1815,7 @@ lambda_estim(m::StatsModels.DataFrameRegressionModel{PhyloNetworkLinearModel,T} StatsModels.ModelFrame(m::StatsModels.DataFrameRegressionModel) = m.mf StatsModels.ModelMatrix(m::StatsModels.DataFrameRegressionModel) = m.mm StatsModels.Formula(m::StatsModels.DataFrameRegressionModel) = Formula(m.mf.terms) +StatsModels.response(m::StatsModels.DataFrameRegressionModel) = response(m.model) ### Print the results # Variance @@ -2208,7 +2209,7 @@ julia> ancStates = ancestralStateReconstruction(fitBM) # Should produce a warnin │ assuming that the estimated variance rate of evolution is correct. │ Additional uncertainty in the estimation of this variance rate is │ ignored, so prediction intervals should be larger. -└ @ PhyloNetworks ~/build/crsl4/PhyloNetworks.jl/src/traits.jl:2162 +└ @ PhyloNetworks ~/build/crsl4/PhyloNetworks.jl/src/traits.jl:2163 ReconstructedStates: Node index Pred. Min. Max. (95%) -5.0 1.32139 -0.288423 2.9312 @@ -2352,7 +2353,7 @@ julia> ancStates = ancestralStateReconstruction(fitBM); │ assuming that the estimated variance rate of evolution is correct. │ Additional uncertainty in the estimation of this variance rate is │ ignored, so prediction intervals should be larger. -└ @ PhyloNetworks ~/build/crsl4/PhyloNetworks.jl/src/traits.jl:2162 +└ @ PhyloNetworks ~/build/crsl4/PhyloNetworks.jl/src/traits.jl:2163 julia> expectations(ancStates) 31×2 DataFrames.DataFrame diff --git a/test/test_bootstrap.jl b/test/test_bootstrap.jl index 2764fedc3..d063dade5 100644 --- a/test/test_bootstrap.jl +++ b/test/test_bootstrap.jl @@ -77,4 +77,9 @@ rmprocs(workers()) @test writeTopology(bootnet[2], round=true, digits=1) == "(5,(((2,(1)#H7:::0.8):0.5,3):0.2,4):0.2,(6,#H7:::0.2):10.0);" # "(5,(((2,(1)#H7:::0.751):1.559,4):0.373,3):0.688,(6,#H7:::0.249):10.0);" # "(((5,(6,#H7:::0.249):10.0):0.688,3):0.373,(2,(1)#H7:::0.751):1.559,4);" + +filelist = joinpath(exdir, "treefilelist.txt") +boottrees = readBootstrapTrees(filelist) +@test length(boottrees) == 2 +@test [length(b) for b in boottrees] == [10, 10] end diff --git a/test/test_lm.jl b/test/test_lm.jl index e46a7b374..805aca46f 100644 --- a/test/test_lm.jl +++ b/test/test_lm.jl @@ -46,7 +46,7 @@ nullloglik = - 1 / 2 * (ntaxa + ntaxa * log(2 * pi) + ntaxa * log(nullsigma2hat) @test coef(phynetlm) ≈ betahat @test nobs(phynetlm) ≈ ntaxa @test residuals(phynetlm) ≈ resids -@test model_response(phynetlm) ≈ Y +@test response(phynetlm) ≈ Y @test predict(phynetlm) ≈ fittedValues @test dof_residual(phynetlm) ≈ ntaxa-length(betahat) @test sigma2_estim(phynetlm) ≈ sigma2hat @@ -74,7 +74,7 @@ fitbis = phyloNetworklm(@formula(trait ~ 1), dfr, net) @test vcov(phynetlm) ≈ vcov(fitbis) @test nobs(phynetlm) ≈ nobs(fitbis) @test residuals(phynetlm)[fitbis.model.ind] ≈ residuals(fitbis) -@test model_response(phynetlm)[fitbis.model.ind] ≈ model_response(fitbis) +@test response(phynetlm)[fitbis.model.ind] ≈ response(fitbis) @test predict(phynetlm)[fitbis.model.ind] ≈ predict(fitbis) @test dof_residual(phynetlm) ≈ dof_residual(fitbis) @test sigma2_estim(phynetlm) ≈ sigma2_estim(fitbis) @@ -102,7 +102,7 @@ fitlam = phyloNetworklm(@formula(trait ~ 1), dfr, net, model = "lambda", fixedVa @test vcov(fitlam) ≈ vcov(fitbis) @test nobs(fitlam) ≈ nobs(fitbis) @test residuals(fitlam)[fitbis.model.ind] ≈ residuals(fitbis) -@test model_response(fitlam)[fitbis.model.ind] ≈ model_response(fitbis) +@test response(fitlam)[fitbis.model.ind] ≈ response(fitbis) @test predict(fitlam)[fitbis.model.ind] ≈ predict(fitbis) @test dof_residual(fitlam) ≈ dof_residual(fitbis) @test sigma2_estim(fitlam) ≈ sigma2_estim(fitbis) @@ -173,7 +173,7 @@ fitlam = phyloNetworklm(@formula(trait ~ shift_8 + shift_17), dfr, net, model = @test vcov(fitlam) ≈ vcov(fitShift) @test nobs(fitlam) ≈ nobs(fitShift) @test residuals(fitlam) ≈ residuals(fitShift) -@test model_response(fitlam) ≈ model_response(fitShift) +@test response(fitlam) ≈ response(fitShift) @test predict(fitlam) ≈ predict(fitShift) @test dof_residual(fitlam) ≈ dof_residual(fitShift) @test sigma2_estim(fitlam) ≈ sigma2_estim(fitShift) @@ -271,7 +271,7 @@ nullloglik = - 1 / 2 * (ntaxa + ntaxa * log(2 * pi) + ntaxa * log(nullsigma2hat) @test coef(fit_mat) ≈ betahat @test nobs(fit_mat) ≈ ntaxa @test residuals(fit_mat) ≈ resids -@test model_response(fit_mat) ≈ B +@test response(fit_mat) ≈ B @test predict(fit_mat) ≈ fittedValues @test dof_residual(fit_mat) ≈ ntaxa-length(betahat) @test sigma2_estim(fit_mat) ≈ sigma2hat @@ -297,7 +297,7 @@ phynetlm = phyloNetworklm(@formula(trait ~ pred), dfr, net) @test vcov(phynetlm) ≈ vcov(fit_mat) @test nobs(phynetlm) ≈ nobs(fit_mat) @test residuals(phynetlm) ≈ residuals(fit_mat) -@test model_response(phynetlm) ≈ model_response(fit_mat) +@test response(phynetlm) ≈ response(fit_mat) @test predict(phynetlm) ≈ predict(fit_mat) @test dof_residual(phynetlm) ≈ dof_residual(fit_mat) @test sigma2_estim(phynetlm) ≈ sigma2_estim(fit_mat) @@ -323,7 +323,7 @@ fitbis = phyloNetworklm(@formula(trait ~ pred), dfr, net) @test vcov(phynetlm) ≈ vcov(fitbis) @test nobs(phynetlm) ≈ nobs(fitbis) @test residuals(phynetlm)[fitbis.model.ind] ≈ residuals(fitbis) -@test model_response(phynetlm)[fitbis.model.ind] ≈ model_response(fitbis) +@test response(phynetlm)[fitbis.model.ind] ≈ response(fitbis) @test predict(phynetlm)[fitbis.model.ind] ≈ predict(fitbis) @test dof_residual(phynetlm) ≈ dof_residual(fitbis) @test sigma2_estim(phynetlm) ≈ sigma2_estim(fitbis) @@ -349,7 +349,7 @@ fitter = (@test_logs (:info, r"^As requested \(no_names=true\)") match_mode=:an @test vcov(phynetlm) ≈ vcov(fitter) @test nobs(phynetlm) ≈ nobs(fitter) @test residuals(phynetlm) ≈ residuals(fitter) -@test model_response(phynetlm) ≈ model_response(fitter) +@test response(phynetlm) ≈ response(fitter) @test predict(phynetlm) ≈ predict(fitter) @test dof_residual(phynetlm) ≈ dof_residual(fitter) @test sigma2_estim(phynetlm) ≈ sigma2_estim(fitter) @@ -384,7 +384,7 @@ fitnabis = phyloNetworklm(@formula(trait ~ pred), dfr, net) @test vcov(fitna) ≈ vcov(fitnabis) @test nobs(fitna) ≈ nobs(fitnabis) @test sort(residuals(fitna)) ≈ sort(residuals(fitnabis)) -@test sort(model_response(fitna)) ≈ sort(model_response(fitnabis)) +@test sort(response(fitna)) ≈ sort(response(fitnabis)) @test sort(predict(fitna)) ≈ sort(predict(fitnabis)) @test dof_residual(fitna) ≈ dof_residual(fitnabis) @test sigma2_estim(fitna) ≈ sigma2_estim(fitnabis) @@ -410,7 +410,7 @@ fitlam = phyloNetworklm(@formula(trait ~ pred), dfr, net, model = "lambda", fixe @test vcov(fitlam) ≈ vcov(fitnabis) @test nobs(fitlam) ≈ nobs(fitnabis) @test residuals(fitlam) ≈ residuals(fitnabis) -@test model_response(fitlam) ≈ model_response(fitnabis) +@test response(fitlam) ≈ response(fitnabis) @test predict(fitlam) ≈ predict(fitnabis) @test dof_residual(fitlam) ≈ dof_residual(fitnabis) @test sigma2_estim(fitlam) ≈ sigma2_estim(fitnabis) @@ -581,7 +581,7 @@ nullloglik = - 1 / 2 * (ntaxa + ntaxa * log(2 * pi) + ntaxa * log(nullsigma2hat) @test nobs(phynetlm) ≈ ntaxa @test residuals(phynetlm) ≈ resids -@test model_response(phynetlm) ≈ Y +@test response(phynetlm) ≈ Y @test predict(phynetlm) ≈ fittedValues @test dof_residual(phynetlm) ≈ ntaxa @test sigma2_estim(phynetlm) ≈ sigma2hat @@ -603,7 +603,7 @@ fitbis = phyloNetworklm(@formula(trait ~ -1), dfr, net) #@test vcov(phynetlm) ≈ vcov(fitbis) @test nobs(phynetlm) ≈ nobs(fitbis) @test residuals(phynetlm)[fitbis.model.ind] ≈ residuals(fitbis) -@test model_response(phynetlm)[fitbis.model.ind] ≈ model_response(fitbis) +@test response(phynetlm)[fitbis.model.ind] ≈ response(fitbis) @test predict(phynetlm)[fitbis.model.ind] ≈ predict(fitbis) @test dof_residual(phynetlm) ≈ dof_residual(fitbis) @test sigma2_estim(phynetlm) ≈ sigma2_estim(fitbis) diff --git a/test/test_lm_tree.jl b/test/test_lm_tree.jl index b01aef343..6da1d5910 100644 --- a/test/test_lm_tree.jl +++ b/test/test_lm_tree.jl @@ -70,7 +70,6 @@ tmp = predict(fitBM); #println("are they all 4.6789989001?") # next: looks random. sometimes passes, most times fails @test predict(fitBM) ≈ [4.6789989001 for i in 1:197] atol=1e-8 -# @test_approx_eq_eps model_response(fitBM)[fitbis.model.ind] model_response(fitbis) # @test_approx_eq_eps deviance(fitBM) deviance(fitbis) # @test_approx_eq_eps nulldeviance(fitBM) nulldeviance(fitbis) # @test_approx_eq_eps nullloglikelihood(fitBM) nullloglikelihood(fitbis) @@ -400,7 +399,6 @@ vcovR = [0.0200086273 -0.0136717540 0.0084815090 -0.0093192029 -0.0114417825 @test stderror(fitBM) ≈ [0.1414518551,0.1361605540,0.1321542330,0.1295968341,0.2214683008,0.1820427154,0.0672106202,0.0965879311,0.0864973651] atol=1e-10 @test confint(fitBM)[:,1] ≈ [2.5115945339,-0.4715366529,0.7207474097,-0.3595508202,-0.8102854443,-0.2058583178,-0.0960507369,-0.0112932922,-0.2213931131] atol=1e-10 norm=x->LinearAlgebra.norm(x,Inf) @test confint(fitBM)[:,2] ≈ [3.0735480006,0.0693957746,1.2457637082,0.1553055609,0.0695537019,0.5173526640,0.1709605441,0.3724268272,0.1222396666] atol=1e-10 -# @test_approx_eq_eps model_response(fitBM)[fitbis.model.ind] model_response(fitbis) # @test_approx_eq_eps predict(fitBM)[fitbis.model.ind] predict(fitbis) # @test_approx_eq_eps deviance(fitBM) deviance(fitbis) # @test_approx_eq_eps nulldeviance(fitBM) nulldeviance(fitbis) @@ -485,7 +483,6 @@ vcovR = [0.0200251600 -0.0137474015 0.0085637021 -0.0092973836 -0.0114259722 @test stderror(fitLambda) ≈ [0.1415102824,0.1367059706,0.1327404019,0.1294070617,0.2213803048,0.1817274626,0.0671133793,0.0966096332,0.0863718011] atol=1e-6 @test confint(fitLambda)[:,1] ≈ [2.5129645499,-0.4782080775,0.7260358930,-0.3575353260,-0.8075438955,-0.2033049779,-0.0965491169,-0.0126529301,-0.2220960868] atol=1e-5 @test confint(fitLambda)[:,2] ≈ [3.0751501341,0.0648911562,1.2533808968,0.1565671360,0.0719456641,0.5186535822,0.1700758500,0.3711534067,0.1210378584] atol=1e-5 -# @test_approx_eq_eps model_response(fitLambda)[fitbis.model.ind] model_response(fitbis) # @test_approx_eq_eps predict(fitLambda)[fitbis.model.ind] predict(fitbis) # @test_approx_eq_eps deviance(fitLambda) deviance(fitbis) # @test_approx_eq_eps nulldeviance(fitLambda) nulldeviance(fitbis)