From 0171f5dc91cd3cc1820bc0ffd4d059c9426123e4 Mon Sep 17 00:00:00 2001 From: Frederic Lemoine Date: Thu, 14 Mar 2019 10:50:41 +0100 Subject: [PATCH] Corrected annotate for rooted trees --- cmd/annotate.go | 45 ++++++++++++++++++++++++++++++++++----- docs/commands/annotate.md | 3 ++- mutils/utils.go | 25 ++++++++++++++++++++++ test.sh | 6 +++--- tree/edge.go | 5 +++-- tree/stats.go | 8 ++++--- tree/tree.go | 5 +++-- tree/utils.go | 15 ------------- 8 files changed, 81 insertions(+), 31 deletions(-) create mode 100644 mutils/utils.go delete mode 100644 tree/utils.go diff --git a/cmd/annotate.go b/cmd/annotate.go index 9abdf5c..78a0829 100644 --- a/cmd/annotate.go +++ b/cmd/annotate.go @@ -11,6 +11,7 @@ import ( "github.com/fredericlemoine/gotree/io" "github.com/fredericlemoine/gotree/io/fileutils" + "github.com/fredericlemoine/gotree/mutils" "github.com/fredericlemoine/gotree/support" "github.com/fredericlemoine/gotree/tree" @@ -28,7 +29,8 @@ var annotateCmd = &cobra.Command{ Annotations may be (in order of priority): - A tree with labels on internal nodes (-c). in that case, it will label each branch of the input tree with label of the closest branch of the given compared tree (-c) in terms - of transfer distance. The labels are of the form: "label_distance_depth"; + of transfer distance. The labels are of the form: "label_distance_depth"; Only internal branches + are annotated, and no internal branch is annotated with a terminal branch. - A file with one line per internal node to annotate (-m), and with the following format: :,,..., => If 0 name is given after ':' an error is returned @@ -127,10 +129,43 @@ If neither -c nor -m are given, gotree annotate will wait for a reference tree o if dist > uint16(len(tips))/2 { dist = uint16(len(tips)) - dist } - if annotateComment { - e1.Right().AddComment(fmt.Sprintf("%s_%d_%d", e2.Name(true), dist, depth)) - } else { - e1.Right().SetName(fmt.Sprintf("%s_%d_%d", e2.Name(true), dist, depth)) + + // If root edge and rooted tree, we take the closest branch + if e2.Left().Nneigh() == 2 { + var t3, t2, t1 int + + e3 := e2.Left().Edges()[0] + if e3 == e2 { + e3 = e2.Left().Edges()[1] + } + + if t3, err = e3.NumTipsRight(); err != nil { + io.LogError(err) + return + } + if t2, err = e2.NumTipsRight(); err != nil { + io.LogError(err) + return + } + if t1, err = e1.NumTipsRight(); err != nil { + io.LogError(err) + return + } + fmt.Println(t1) + fmt.Println(t2) + fmt.Println(t3) + + if mutils.Abs(t3-t1) < mutils.Abs(t2-t1) { + e2 = e3 + } + } + + if !e2.Right().Tip() { + if annotateComment { + e1.Right().AddComment(fmt.Sprintf("%s_%d_%d", e2.Name(true), dist, depth)) + } else { + e1.Right().SetName(fmt.Sprintf("%s_%d_%d", e2.Name(true), dist, depth)) + } } } } diff --git a/docs/commands/annotate.md b/docs/commands/annotate.md index d926412..bd9853e 100644 --- a/docs/commands/annotate.md +++ b/docs/commands/annotate.md @@ -8,7 +8,8 @@ This command annotates internal nodes/branches of a tree with given information. Annotations may be (in order of priority): - A tree with labels on internal nodes (-c). in that case, it will label each branch of the input tree with label of the closest branch of the given compared tree (-c) in terms - of transfer distance. The labels are of the form: "`label_distance_depth`"; + of transfer distance. The labels are of the form: "`label_distance_depth`"; Only internal branches + are annotated, and no internal branch is annotated with a terminal branch. - A file with one line per internal node to annotate (-m), and with the following format: `:,,...,` => If 0 name is given after ':' an error is returned diff --git a/mutils/utils.go b/mutils/utils.go new file mode 100644 index 0000000..5d03ca5 --- /dev/null +++ b/mutils/utils.go @@ -0,0 +1,25 @@ +/** +Package with simple math util functions such as min, max, and abs +*/ +package mutils + +func Min(a, b int) int { + if a < b { + return a + } + return b +} + +func Max(a, b int) int { + if a < b { + return b + } + return a +} + +func Abs(x int) int { + if x < 0 { + return -x + } + return x +} diff --git a/test.sh b/test.sh index fc4125b..d7eb3be 100755 --- a/test.sh +++ b/test.sh @@ -68,7 +68,7 @@ cat > intree < expected < result diff -q -b result expected @@ -80,7 +80,7 @@ cat > intree < expected < result diff -q -b result expected @@ -853,7 +853,7 @@ cat > annotated < expected <> 1) @@ -136,7 +138,7 @@ func (t *Tree) CollessIndex() (colless int) { leftindex, lefttips := collessIndexRecur(edge.Left(), edge.Right()) rightindex, righttips := collessIndexRecur(edge.Right(), edge.Left()) colless += (leftindex + rightindex) - colless += max(lefttips, righttips) - min(lefttips, righttips) + colless += mutils.Max(lefttips, righttips) - mutils.Min(lefttips, righttips) } else { colless, _ = collessIndexRecur(t.Root(), nil) } @@ -154,8 +156,8 @@ func collessIndexRecur(n *Node, prev *Node) (colless, tips int) { for _, c := range n.Neigh() { if c != prev { childindex, childtips := collessIndexRecur(c, n) - mintips = min(mintips, childtips) - maxtips = max(maxtips, childtips) + mintips = mutils.Min(mintips, childtips) + maxtips = mutils.Max(maxtips, childtips) tips += childtips colless += childindex } diff --git a/tree/tree.go b/tree/tree.go index b7c2bc6..339d41d 100644 --- a/tree/tree.go +++ b/tree/tree.go @@ -16,6 +16,7 @@ import ( "github.com/fredericlemoine/bitset" "github.com/fredericlemoine/gotree/io" + "github.com/fredericlemoine/gotree/mutils" ) // Tree structure having a root and a tip index, that maps tip names to their index @@ -1580,8 +1581,8 @@ func (t *Tree) deepestEdgeRecur(node, prev *Node, edge *Edge, numtips int) (maxe curtips += t } } - if min(numtips-curtips, curtips) > maxdepth { - maxdepth = min(numtips-curtips, curtips) + if mutils.Min(numtips-curtips, curtips) > maxdepth { + maxdepth = mutils.Min(numtips-curtips, curtips) maxedge = edge lefttips = numtips - curtips righttips = curtips diff --git a/tree/utils.go b/tree/utils.go deleted file mode 100644 index f884ce3..0000000 --- a/tree/utils.go +++ /dev/null @@ -1,15 +0,0 @@ -package tree - -func min(a, b int) int { - if a < b { - return a - } - return b -} - -func max(a, b int) int { - if a < b { - return b - } - return a -}