Skip to content

Commit

Permalink
Reorganized commands : difftips and compare
Browse files Browse the repository at this point in the history
  • Loading branch information
fredericlemoine committed Feb 16, 2017
1 parent 28edb1d commit c3f6dfb
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 99 deletions.
97 changes: 2 additions & 95 deletions cmd/compare.go
Original file line number Diff line number Diff line change
@@ -1,112 +1,19 @@
package cmd

import (
"errors"
"fmt"
"github.com/fredericlemoine/gotree/io"
"github.com/fredericlemoine/gotree/tree"
"github.com/spf13/cobra"
"os"
"runtime"
"sync"
)

// Type for channel of tree stats
type stats struct {
id int
tree1 int
common int
}

func compare(tree1 string, tree2 string, tips bool, cpus int) {
maxcpus := runtime.NumCPU()
var edges []*tree.Edge

statsChannel := make(chan stats, 15)

if tree2 == "none" {
io.ExitWithMessage(errors.New("You must provide a file containing compared trees"))
}
if cpus > maxcpus {
cpus = maxcpus
}

fmt.Fprintf(os.Stderr, "Reference : %s\n", tree1)
fmt.Fprintf(os.Stderr, "Compared : %s\n", tree2)
fmt.Fprintf(os.Stderr, "With tips : %t\n", tips)
fmt.Fprintf(os.Stderr, "Threads : %d\n", cpus)

refTree := readTree(intreefile)
compareChannel := readTrees(intree2file)

edges = refTree.Edges()
index := tree.NewEdgeIndex(int64(len(edges)*2), 0.75)
total := 0
for i, e := range edges {
index.PutEdgeValue(e, i, e.Length())
if tips || !e.Right().Tip() {
total++
}
}
var wg sync.WaitGroup
for cpu := 0; cpu < cpus; cpu++ {
wg.Add(1)
go func(cpu int) {
for treeV := range compareChannel {
common := 0
var err error

edges2 := treeV.Tree.Edges()
// Check wether the 2 trees have the same set of tip names
if err = refTree.CompareTipIndexes(treeV.Tree); err != nil {
io.ExitWithMessage(err)
}

for _, e2 := range edges2 {
_, ok := index.Value(e2)
if ok && (tips || !e2.Right().Tip()) {
common++
}
}

statsChannel <- stats{
treeV.Id,
total - common,
common,
}
}
wg.Done()
}(cpu)
}

go func() {
wg.Wait()
close(statsChannel)
}()

fmt.Printf("Tree\tspecref\tcommon\n")
for stats := range statsChannel {
fmt.Printf("%d\t%d\t%d\n", stats.id, stats.tree1, stats.common)
}
}

// compareCmd represents the compare command
var compareCmd = &cobra.Command{
Use: "compare",
Short: "Compare a reference tree with a set of trees",
Long: `Compare a reference tree with a set of trees.
for each trees in the compared tree file, prints the number of common edges
between it and the reference tree, as well as the number of specific edges.
Short: "Compare full trees, edges, or tips",
Long: `Compare full trees, edges, or tips.
`,
Run: func(cmd *cobra.Command, args []string) {
compare(intreefile, intree2file, compareTips, rootCpus)
},
}

func init() {
RootCmd.AddCommand(compareCmd)
compareCmd.PersistentFlags().StringVarP(&intreefile, "reftree", "i", "stdin", "Reference tree input file")
compareCmd.PersistentFlags().StringVarP(&intree2file, "compared", "c", "none", "Compared trees input file")
compareCmd.Flags().BoolVarP(&compareTips, "tips", "l", false, "Compared trees input file")
}
6 changes: 2 additions & 4 deletions cmd/difftips.go → cmd/comparetips.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

// difftipsCmd represents the difftips command
var difftipsCmd = &cobra.Command{
Use: "difftips",
Use: "tips",
Short: "Print diff between tip names of two trees",
Long: `Print diff between tip names of two trees.
Expand Down Expand Up @@ -60,7 +60,5 @@ should produce the following output:
}

func init() {
RootCmd.AddCommand(difftipsCmd)
difftipsCmd.Flags().StringVarP(&intreefile, "reftree", "i", "stdin", "Reference tree input file")
difftipsCmd.Flags().StringVarP(&intree2file, "compared", "c", "none", "Other tree file to compare with")
compareCmd.AddCommand(difftipsCmd)
}
110 changes: 110 additions & 0 deletions cmd/comparetrees.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package cmd

import (
"errors"
"fmt"
"github.com/fredericlemoine/gotree/io"
"github.com/fredericlemoine/gotree/tree"
"github.com/spf13/cobra"
"os"
"runtime"
"sync"
)

// Type for channel of tree stats
type stats struct {
id int
tree1 int
common int
}

func compare(tree1 string, tree2 string, tips bool, cpus int) {
maxcpus := runtime.NumCPU()
var edges []*tree.Edge

statsChannel := make(chan stats, 15)

if tree2 == "none" {
io.ExitWithMessage(errors.New("You must provide a file containing compared trees"))
}
if cpus > maxcpus {
cpus = maxcpus
}

fmt.Fprintf(os.Stderr, "Reference : %s\n", tree1)
fmt.Fprintf(os.Stderr, "Compared : %s\n", tree2)
fmt.Fprintf(os.Stderr, "With tips : %t\n", tips)
fmt.Fprintf(os.Stderr, "Threads : %d\n", cpus)

refTree := readTree(intreefile)
compareChannel := readTrees(intree2file)

edges = refTree.Edges()
index := tree.NewEdgeIndex(int64(len(edges)*2), 0.75)
total := 0
for i, e := range edges {
index.PutEdgeValue(e, i, e.Length())
if tips || !e.Right().Tip() {
total++
}
}
var wg sync.WaitGroup
for cpu := 0; cpu < cpus; cpu++ {
wg.Add(1)
go func(cpu int) {
for treeV := range compareChannel {
common := 0
var err error

edges2 := treeV.Tree.Edges()
// Check wether the 2 trees have the same set of tip names
if err = refTree.CompareTipIndexes(treeV.Tree); err != nil {
io.ExitWithMessage(err)
}

for _, e2 := range edges2 {
_, ok := index.Value(e2)
if ok && (tips || !e2.Right().Tip()) {
common++
}
}

statsChannel <- stats{
treeV.Id,
total - common,
common,
}
}
wg.Done()
}(cpu)
}

go func() {
wg.Wait()
close(statsChannel)
}()

fmt.Printf("Tree\tspecref\tcommon\n")
for stats := range statsChannel {
fmt.Printf("%d\t%d\t%d\n", stats.id, stats.tree1, stats.common)
}
}

// compareCmd represents the compare command
var compareTreesCmd = &cobra.Command{
Use: "trees",
Short: "Compare a reference tree with a set of trees",
Long: `Compare a reference tree with a set of trees.
for each trees in the compared tree file, prints the number of common edges
between it and the reference tree, as well as the number of specific edges.
`,
Run: func(cmd *cobra.Command, args []string) {
compare(intreefile, intree2file, compareTips, rootCpus)
},
}

func init() {
compareCmd.AddCommand(compareTreesCmd)
compareTreesCmd.Flags().BoolVarP(&compareTips, "tips", "l", false, "Include tips in the comparison")
}

0 comments on commit c3f6dfb

Please sign in to comment.