-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added reroot command and Corrected tests
- Loading branch information
1 parent
d9c2947
commit 220bb36
Showing
9 changed files
with
327 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package cmd | ||
|
||
import ( | ||
"bufio" | ||
"compress/gzip" | ||
"github.com/fredericlemoine/gotree/io" | ||
"github.com/fredericlemoine/gotree/io/utils" | ||
"github.com/fredericlemoine/gotree/tree" | ||
"github.com/spf13/cobra" | ||
"os" | ||
"strings" | ||
) | ||
|
||
var reroottipfile string | ||
var rerootinputfile string | ||
var rerootoutputfile string | ||
|
||
// rerootCmd represents the reroot command | ||
var rerootCmd = &cobra.Command{ | ||
Use: "reroot", | ||
Short: "Reroot the tree using an outgroup", | ||
Long: `Reroot the tree using an outgroup given in argument or in stdin. | ||
Example: | ||
`, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
tips := parseTipsFile(reroottipfile) | ||
|
||
var err error | ||
var nbtrees int | ||
|
||
compareChannel := make(chan tree.Trees, 15) | ||
|
||
go func() { | ||
if nbtrees, err = utils.ReadCompTrees(rerootinputfile, compareChannel); err != nil { | ||
io.ExitWithMessage(err) | ||
} | ||
}() | ||
|
||
var f *os.File | ||
if rerootoutputfile != "stdout" { | ||
f, err = os.Create(rerootoutputfile) | ||
} else { | ||
f = os.Stdout | ||
} | ||
if err != nil { | ||
io.ExitWithMessage(err) | ||
} | ||
|
||
for t2 := range compareChannel { | ||
err = t2.Tree.RerootOutGroup(tips...) | ||
if err != nil { | ||
io.ExitWithMessage(err) | ||
} | ||
|
||
f.WriteString(t2.Tree.Newick() + "\n") | ||
} | ||
|
||
f.Close() | ||
}, | ||
} | ||
|
||
func init() { | ||
RootCmd.AddCommand(rerootCmd) | ||
rerootCmd.PersistentFlags().StringVarP(&reroottipfile, "tip-file", "l", "stdin", "File containing names of tips of the outgroup") | ||
rerootCmd.PersistentFlags().StringVarP(&rerootinputfile, "input", "i", "stdin", "Input Tree") | ||
rerootCmd.PersistentFlags().StringVarP(&rerootoutputfile, "output", "o", "stdout", "Rerooted output tree file") | ||
} | ||
|
||
func parseTipsFile(file string) []string { | ||
var f *os.File | ||
var r *bufio.Reader | ||
tips := make([]string, 0, 100) | ||
var err error | ||
if file == "stdin" || file == "-" { | ||
f = os.Stdin | ||
} else { | ||
f, err = os.Open(file) | ||
if err != nil { | ||
io.ExitWithMessage(err) | ||
} | ||
} | ||
|
||
if strings.HasSuffix(file, ".gz") { | ||
if gr, err := gzip.NewReader(f); err != nil { | ||
io.ExitWithMessage(err) | ||
} else { | ||
r = bufio.NewReader(gr) | ||
} | ||
} else { | ||
r = bufio.NewReader(f) | ||
} | ||
|
||
l, e := Readln(r) | ||
for e == nil { | ||
for _, name := range strings.Split(l, ",") { | ||
tips = append(tips, name) | ||
} | ||
l, e = Readln(r) | ||
} | ||
return tips | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package tests | ||
|
||
import ( | ||
"github.com/fredericlemoine/gotree/tree" | ||
"testing" | ||
) | ||
|
||
/* | ||
Generates 100 random 1000 tip trees, clone them, and compare them to the original trees | ||
*/ | ||
func TestCloneTree(t *testing.T) { | ||
for i := 0; i < 100; i++ { | ||
tr, err := tree.RandomYuleBinaryTree(1000, true) | ||
clone := tr.Clone() | ||
|
||
// Comparing tip names | ||
tips := tr.Tips() | ||
copyTips := clone.Tips() | ||
for i, _ := range tips { | ||
if tips[i].Name() != copyTips[i].Name() { | ||
t.Error("A tip is not found in the cloned tree") | ||
} | ||
} | ||
|
||
// Check wether the 2 trees have the same set of tip names | ||
if err = tr.CompareTipIndexes(clone); err != nil { | ||
t.Error(err) | ||
} | ||
|
||
// Comparing edges | ||
edges := tr.Edges() | ||
edges2 := clone.Edges() | ||
index := tree.NewEdgeIndex(int64(len(edges)*2), 0.75) | ||
for i, e := range edges { | ||
index.PutEdgeValue(e, i, e.Length()) | ||
} | ||
for _, e2 := range edges2 { | ||
_, ok := index.Value(e2) | ||
if !ok { | ||
t.Error("An edge of the original tree is not found in the cloned tree") | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package tests | ||
|
||
import ( | ||
"github.com/fredericlemoine/gotree/tree" | ||
"testing" | ||
) | ||
|
||
/* | ||
Generates a 1000 tip random tree, then reroot it at each tip | ||
and compare all bipartitions of the rerooted tree with the original tree | ||
*/ | ||
func TestRootOutgroup(t *testing.T) { | ||
tr, err := tree.RandomYuleBinaryTree(1000, true) | ||
clone := tr.Clone() | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
edges := tr.Edges() | ||
index := tree.NewEdgeIndex(int64(len(edges)*2), 0.75) | ||
for i, e := range edges { | ||
index.PutEdgeValue(e, i, e.Length()) | ||
} | ||
tips := tr.Tips() | ||
|
||
for _, tip := range tips { | ||
err = clone.RerootOutGroup(tip.Name()) | ||
found := false | ||
for _, n := range clone.Root().Neigh() { | ||
if n.Tip() && n.Name() == tip.Name() { | ||
found = true | ||
} | ||
} | ||
if !found { | ||
t.Error("Outgroup (tip) not found in the children of the root on the rerooted tree") | ||
} | ||
edges2 := clone.Edges() | ||
// Check wether the 2 trees have the same set of tip names | ||
if err = tr.CompareTipIndexes(clone); err != nil { | ||
t.Error(err) | ||
} | ||
|
||
for _, e2 := range edges2 { | ||
_, ok := index.Value(e2) | ||
if !ok { | ||
t.Error("An edge of the original tree is not found in the rerooted tree") | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters