diff --git a/pkg/obitax/sequence_methods.go b/pkg/obitax/sequence_methods.go index 8a4693a..8623eab 100644 --- a/pkg/obitax/sequence_methods.go +++ b/pkg/obitax/sequence_methods.go @@ -2,6 +2,7 @@ package obitax import ( "git.metabarcoding.org/obitools/obitools4/obitools4/pkg/obiseq" + log "github.com/sirupsen/logrus" ) // Setting the taxon at a given rank for a given sequence. @@ -46,3 +47,22 @@ func (taxonomy *Taxonomy) SetGenus(sequence *obiseq.BioSequence) *TaxNode { func (taxonomy *Taxonomy) SetFamily(sequence *obiseq.BioSequence) *TaxNode { return taxonomy.SetTaxonAtRank(sequence, "family") } + +func (taxonomy *Taxonomy) SetPath(sequence *obiseq.BioSequence) string { + taxid, err := taxonomy.Taxon(sequence.Taxid()) + + if err != nil { + log.Fatalf("Taxid %d not defined in the current taxonomy", sequence.Taxid()) + } + + path, err := taxid.Path() + + if err != nil { + log.Fatalf("Taxonomy index error: %v", err) + } + + tpath := path.String() + sequence.SetAttribute("taxonomic_path", tpath) + + return tpath +} diff --git a/pkg/obitax/sequence_workers.go b/pkg/obitax/sequence_workers.go index e0fb40f..6f57acf 100644 --- a/pkg/obitax/sequence_workers.go +++ b/pkg/obitax/sequence_workers.go @@ -51,3 +51,14 @@ func (taxonomy *Taxonomy) MakeSetFamilyWorker() obiseq.SeqWorker { return w } + +func (taxonomy *Taxonomy) MakeSetPathWorker() obiseq.SeqWorker { + + w := func(s *obiseq.BioSequence) *obiseq.BioSequence { + taxonomy.SetPath(s) + return s + } + + return w + +} diff --git a/pkg/obitax/taxonslice.go b/pkg/obitax/taxonslice.go index b7bc082..363297c 100644 --- a/pkg/obitax/taxonslice.go +++ b/pkg/obitax/taxonslice.go @@ -1,5 +1,10 @@ package obitax +import ( + "bytes" + "fmt" +) + type TaxonSlice []*TaxNode func (set *TaxonSlice) Get(i int) *TaxNode { @@ -9,3 +14,25 @@ func (set *TaxonSlice) Get(i int) *TaxNode { func (set *TaxonSlice) Len() int { return len(*set) } + +func (path *TaxonSlice) String() string { + var buffer bytes.Buffer + + if len(*path) > 0 { + taxon := (*path)[len(*path)-1] + fmt.Fprintf(&buffer, "%d@%s@%s", + taxon.Taxid(), + taxon.ScientificName(), + taxon.Rank()) + + for i := len(*path) - 2; i >= 0; i-- { + taxon := (*path)[i] + fmt.Fprintf(&buffer, "|%d@%s@%s", + taxon.Taxid(), + taxon.ScientificName(), + taxon.Rank()) + } + } + + return buffer.String() +} diff --git a/pkg/obitools/obiannotate/obiannotate.go b/pkg/obitools/obiannotate/obiannotate.go index dd91852..e1a5846 100644 --- a/pkg/obitools/obiannotate/obiannotate.go +++ b/pkg/obitools/obiannotate/obiannotate.go @@ -256,6 +256,12 @@ func CLIAnnotationWorker() obiseq.SeqWorker { annotator = annotator.ChainWorkers(w) } + if CLISetTaxonomicPath() { + taxo := obigrep.CLILoadSelectedTaxonomy() + w := taxo.MakeSetPathWorker() + annotator = annotator.ChainWorkers(w) + } + if CLIHasAddLCA() { taxo := obigrep.CLILoadSelectedTaxonomy() w := obitax.AddLCAWorker(taxo, CLILCASlotName(), CLILCAThreshold()) diff --git a/pkg/obitools/obiannotate/options.go b/pkg/obitools/obiannotate/options.go index 6ed3ad4..291f74f 100644 --- a/pkg/obitools/obiannotate/options.go +++ b/pkg/obitools/obiannotate/options.go @@ -31,6 +31,7 @@ var _lcaSlot = "" var _lcaError = 0.0 var _setId = "" var _cut = "" +var _taxonomicPath = false func SequenceAnnotationOptionSet(options *getoptions.GetOpt) { // options.BoolVar(&_addRank, "seq-rank", _addRank, @@ -113,6 +114,9 @@ func SequenceAnnotationOptionSet(options *getoptions.GetOpt) { options.ArgName("RANK_NAME"), options.Description("Adds taxonomic annotation at taxonomic rank .")) + options.BoolVar(&_taxonomicPath, "taxonomic-path", _taxonomicPath, + options.Description("Annotate the sequence with its taxonomic path")) + // options.StringVar(&_tagList, "tag-list", _tagList, // options.ArgName("FILENAME"), // options.Description(" points to a file containing attribute names"+ @@ -299,3 +303,7 @@ func CLIPatternError() int { func CLIPatternInDels() bool { return _pattern_indel } + +func CLISetTaxonomicPath() bool { + return _taxonomicPath +}