Skip to content

Commit c66dcf7

Browse files
authored
v1.0.0 (#221)
new features: - countquartetsintrees (was in v0.16 but not v0.17) - tablequartetCF (was writeTableCF in v0.16, now returns NamedTuple and has option to skip 4-taxon sets with no informative genes) - tiplabels for vector of phylogenies: union breaking changes: renaming with small case --------- Co-authored-by: Joshua Justison (jjustison)
1 parent f730187 commit c66dcf7

13 files changed

+765
-65
lines changed

Project.toml

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "PhyloNetworks"
22
uuid = "33ad39ac-ed31-50eb-9b15-43d0656eaa72"
33
license = "MIT"
4-
version = "0.17.0"
4+
version = "1.0.0"
55

66
[deps]
77
BioSequences = "7e6ae17a-c86d-528c-b3b9-7f778a29fe59"
@@ -19,22 +19,24 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1919
NLopt = "76087f3c-5699-56af-9a33-bf431cd00edd"
2020
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
2121
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
22+
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
2223
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
2324
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
2425

2526
[compat]
26-
BioSequences = "2.0, 3"
27-
BioSymbols = "4.0, 5"
27+
BioSequences = "2, 3"
28+
BioSymbols = "4, 5"
2829
CSV = "0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.10"
29-
Combinatorics = "0.7, 1.0"
30+
Combinatorics = "0.7, 1"
3031
DataFrames = "1.3"
3132
DataStructures = "0.9, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18"
3233
Distributions = "0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25"
3334
FASTX = "1.1, 2"
3435
Functors = "0.2, 0.3, 0.4, 0.5"
3536
NLopt = "0.5.1, 0.6, 1"
37+
StaticArrays = "0.8.3, 0.9, 0.10, 0.11, 0.12, 1"
3638
StatsBase = "0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34"
37-
julia = "1.5, 1.6, 1.7"
39+
julia = "1.5"
3840

3941
[extras]
4042
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

src/PhyloNetworks.jl

+6-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ module PhyloNetworks
2222
using DataFrames # innerjoin new in v0.21
2323
using DataStructures # for updateInCycle with priority queue
2424
using Distributions #for RateVariationAcrossSites
25+
using StaticArrays # for quartets
2526
using FASTX
2627
using Functors: fmap
2728
using NLopt # for branch lengths optimization
@@ -122,7 +123,10 @@ module PhyloNetworks
122123
#maxParsimonyNet # broken after v0.17 refactoring: fix network search
123124
readfastatodna,
124125
# neighbor joining
125-
nj
126+
nj,
127+
# quartets
128+
tablequartetCF,
129+
countquartetsintrees
126130

127131
##Constants
128132
const fAbsBL = 1e-10
@@ -148,5 +152,6 @@ module PhyloNetworks
148152
include("graph_components.jl")
149153
include("deprecated.jl")
150154
include("nj.jl")
155+
include("quartets.jl")
151156

152157
end #module

src/auxiliary.jl

+11-11
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ level-1, with valid internal fields `e.inte1` (to track which cycle
572572
function deleteEdge!(net::HybridNetwork, e::Edge; part::Bool=true)
573573
if part
574574
if e.inte1 == -1 && !e.hybrid && !isempty(net.partition) && !isTree(net)
575-
ind = whichPartition(net,e)
575+
ind = whichpartition(net,e)
576576
indE = getIndex(e,net.partition[ind].edges)
577577
deleteat!(net.partition[ind].edges,indE)
578578
end
@@ -1460,50 +1460,50 @@ end
14601460
# better to return the index than the partition itself, because we need the index
14611461
# to use splice and delete it from net.partition later on
14621462
# cycle: is the number to look for partition on that cycle only
1463-
function whichPartition(net::HybridNetwork,edge::Edge,cycle::Integer)
1463+
function whichpartition(net::HybridNetwork, edge::Edge, cycle::Integer)
14641464
!edge.hybrid || error("edge $(edge.number) is hybrid so it cannot be in any partition")
14651465
edge.inte1 == -1 || error("edge $(edge.number) is in cycle $(edge.inte1) so it cannot be in any partition")
14661466
@debug "search partition for edge $(edge.number) in cycle $(cycle)"
14671467
in(edge,net.edge) || error("edge $(edge.number) is not in net.edge")
14681468
for i in 1:length(net.partition)
14691469
@debug "looking for edge $(edge.number) in partition $(i): $([e.number for e in net.partition[i].edges])"
1470-
if(in(cycle,net.partition[i].cycle))
1470+
if in(cycle, net.partition[i].cycle)
14711471
@debug "looking for edge $(edge.number) in partition $(i), with cycle $(cycle): $([e.number for e in net.partition[i].edges])"
14721472
if in(edge,net.partition[i].edges)
14731473
@debug "partition for edge $(edge.number) is $([e.number for e in net.partition[i].edges])"
14741474
return i
14751475
end
14761476
end
14771477
end
1478-
@debug begin; printPartitions(net); "" end
1478+
@debug begin; printpartitions(net); "" end
14791479
error("edge $(edge.number) is not hybrid, nor part of any cycle, and it is not in any partition")
14801480
end
14811481

14821482
# function to get the partition where an edge is
14831483
# returns the index of the partition, or error if not found
14841484
# better to return the index than the partition itself, because we need the index
14851485
# to use splice and delete it from net.partition later on
1486-
function whichPartition(net::HybridNetwork,edge::Edge)
1486+
function whichpartition(net::HybridNetwork, edge::Edge)
14871487
!edge.hybrid || error("edge $(edge.number) is hybrid so it cannot be in any partition")
14881488
edge.inte1 == -1 || error("edge $(edge.number) is in cycle $(edge.inte1) so it cannot be in any partition")
14891489
@debug "search partition for edge $(edge.number) without knowing its cycle"
14901490
in(edge,net.edge) || error("edge $(edge.number) is not in net.edge")
14911491
for i in 1:length(net.partition)
14921492
@debug "looking for edge $(edge.number) in partition $(i): $([e.number for e in net.partition[i].edges])"
1493-
if(in(edge,net.partition[i].edges))
1493+
if in(edge,net.partition[i].edges)
14941494
@debug "partition for edge $(edge.number) is $([e.number for e in net.partition[i].edges])"
14951495
return i
14961496
end
14971497
end
1498-
@debug begin printPartitions(net); "printed partitions" end
1498+
@debug begin printpartitions(net); "printed partitions" end
14991499
error("edge $(edge.number) is not hybrid, nor part of any cycle, and it is not in any partition")
15001500
end
15011501

1502-
# function that will print the partition of net
1503-
function printPartitions(net::HybridNetwork)
1504-
println("partition.cycle\t partition.edges")
1502+
printpartitions(x) = printpartitions(stdout::IO, x)
1503+
function printpartitions(io::IO, net::HybridNetwork)
1504+
println(io, "partition.cycle\t partition.edges")
15051505
for p in net.partition
1506-
println("$(p.cycle)\t\t $([e.number for e in p.edges])")
1506+
println(io, "$(p.cycle)\t\t $([e.number for e in p.edges])")
15071507
end
15081508
end
15091509

src/deprecated.jl

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
@deprecate readBootstrapTrees readmultinewick_files
77
@deprecate writeTopology writenewick
88
@deprecate writeMultiTopology writemultinewick
9+
Base.@deprecate_moved snaq! "SNaQ"
910
# minor name changes: camelCase to smallcase
1011
@deprecate printEdges printedges
1112
@deprecate printNodes printnodes

src/descriptive.jl

+28-6
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,30 @@ function tiplabels(net::HybridNetwork)
1414
return String[l.name for l in net.leaf] # AbstractString does not work for use by tree2Matrix
1515
end
1616

17-
# function that we need to overwrite to avoid printing useless scary
18-
# output for HybridNetworks
19-
# PROBLEM: writenewick changes the network and thus show changes the network
17+
# extract & sort the union of taxa of list of gene trees
18+
function tiplabels(trees::Vector{HybridNetwork})
19+
taxa = reduce(union, tiplabels(t) for t in trees)
20+
return sort_stringasinteger!(taxa)
21+
end
22+
23+
"""
24+
sort_stringasinteger!(taxa)
25+
26+
Sort a vector of strings `taxa`, numerically if
27+
elements can be parsed as an integer, alphabetically otherwise.
28+
"""
29+
function sort_stringasinteger!(taxa)
30+
sortby = x->parse(Int,x)
31+
try
32+
parse.(Int,taxa)
33+
catch
34+
sortby = identity
35+
end
36+
sort!(taxa, by=sortby)
37+
return taxa
38+
end
39+
40+
# 'show' should not (and does not) modify the object
2041
function Base.show(io::IO, obj::HybridNetwork)
2142
disp = "$(typeof(obj)), "
2243
if obj.isrooted
@@ -39,7 +60,10 @@ function Base.show(io::IO, obj::HybridNetwork)
3960
end
4061
par = ""
4162
try
42-
# par = writenewick(obj,round=true) # but writenewick changes the network, not good
63+
#= *not* 'writenewick(obj,round=true)' because writenewick changes
64+
the network (runs directedges! and if it fails, tries other rootings).
65+
writesubtree! does *not* modify the network.
66+
=#
4367
s = IOBuffer()
4468
writesubtree!(s, obj, false,true, true,3,true)
4569
par = String(take!(s))
@@ -53,8 +77,6 @@ function Base.show(io::IO, obj::HybridNetwork)
5377
println(io, disp)
5478
end
5579

56-
57-
5880
function Base.show(io::IO, obj::Node)
5981
disp = "$(typeof(obj)):"
6082
disp = disp * "\n number:$(obj.number)"

0 commit comments

Comments
 (0)