A library for working with phylogenetic and population genetic data.
v0.27.0
taxopath_generator.cpp
Go to the documentation of this file.
1 /*
2  Genesis - A toolkit for working with phylogenetic data.
3  Copyright (C) 2014-2019 Lucas Czech and HITS gGmbH
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  Contact:
19  Lucas Czech <lucas.czech@h-its.org>
20  Exelixis Lab, Heidelberg Institute for Theoretical Studies
21  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
22 */
23 
32 
37 
38 #include <algorithm>
39 #include <cassert>
40 #include <stdexcept>
41 
42 namespace genesis {
43 namespace taxonomy {
44 
45 // =================================================================================================
46 // Generating
47 // =================================================================================================
48 
49 std::string TaxopathGenerator::to_string( Taxopath const& taxopath ) const
50 {
51  std::string res;
52 
53  if( trim_nested_duplicates_ ) {
54  // We are going to delete elements, so first make a copy.
55  auto cpy = taxopath.elements();
56 
57  // Delete element if the one before it is the same.
58  // Skip the first and the last one.
59  for( size_t i = cpy.size() - 1; i >= 1; --i ) {
60  if( cpy[i] == cpy[i-1] ) {
61  cpy[i] = "";
62  }
63  }
64  res = utils::join( cpy, delimiter_ );
65 
66  } else {
67  // Without trimming, the result is easy to create.
68  res = utils::join( taxopath.elements(), delimiter_ );
69  }
70 
71  if( append_delimiter_ ) {
72  return res + delimiter_;
73  } else {
74  return res;
75  }
76 }
77 
78 std::string TaxopathGenerator::operator() ( Taxopath const& taxopath ) const
79 {
80  return to_string( taxopath );
81 }
82 
83 std::string TaxopathGenerator::to_string( Taxon const& taxon ) const
84 {
85  // This implementation is probably not the fastest, but it is simple and kind of elegant.
86  // Start with an empty vector that will store the super-taxa of the given taxon.
87  std::vector<std::string> taxa;
88 
89  // Add taxa in reverse order: the deepest taxon will be stored first.
90  // This is fast with a vector.
91  Taxon const* r = &taxon;
92  while( r != nullptr ) {
93  switch( field_ ) {
94  case TaxonField::kName: {
95  taxa.push_back( r->name() );
96  break;
97  }
98  case TaxonField::kRank: {
99  taxa.push_back( r->rank() );
100  break;
101  }
102  case TaxonField::kId: {
103  taxa.push_back( r->id() );
104  break;
105  }
106  default: {
107  throw std::invalid_argument( "Invalid TaxonField in TaxopathGenerator." );
108  }
109  }
110  r = r->parent();
111  }
112 
113  // If wanted, set all taxa to an empty string for which the super-taxon has the same name/field.
114  // As we stored them in reverse order, we can simply go from start to one-but-the-end and check
115  // for equality.
116  if( trim_nested_duplicates_ ) {
117  for( size_t i = 0; i < taxa.size() - 1; ++i ) {
118  if( taxa[i] == taxa[i+1] ) {
119  taxa[i] = "";
120  }
121  }
122  }
123 
124  // Now reverse and return the joined result.
125  std::reverse( taxa.begin(), taxa.end() );
126  auto res = utils::join( taxa, delimiter_ );
127 
128  if( append_delimiter_ ) {
129  return res + delimiter_;
130  } else {
131  return res;
132  }
133 }
134 
135 std::string TaxopathGenerator::operator() ( Taxon const& taxon ) const
136 {
137  return to_string( taxon );
138 }
139 
140 // =================================================================================================
141 // Properties
142 // =================================================================================================
143 
145 {
146  field_ = value;
147  return *this;
148 }
149 
151 {
152  return field_;
153 }
154 
156 {
157  delimiter_ = value;
158  return *this;
159 }
160 
161 std::string TaxopathGenerator::delimiter() const
162 {
163  return delimiter_;
164 }
165 
167 {
168  trim_nested_duplicates_ = value;
169  return *this;
170 }
171 
173 {
174  return trim_nested_duplicates_;
175 }
176 
178 {
179  append_delimiter_ = value;
180  return *this;
181 }
182 
184 {
185  return append_delimiter_;
186 }
187 
188 } // namespace taxonomy
189 } // namespace genesis
genesis::taxonomy::TaxopathGenerator::TaxonField::kId
@ kId
genesis::taxonomy::Taxon::parent
Taxon const * parent() const
Return a pointer to the parent of this taxon, or a nullptr if this is the top level taxon.
Definition: taxon.cpp:173
genesis::taxonomy::Taxopath::elements
std::vector< std::string > const & elements() const
Return the elements of the Taxopath as a vector of strings.
Definition: taxopath.hpp:202
taxopath.hpp
genesis::taxonomy::TaxopathGenerator::field
TaxonField field() const
Return the currelty set field to use for describing a Taxon.
Definition: taxopath_generator.cpp:150
genesis::taxonomy::TaxopathGenerator::TaxonField
TaxonField
Definition: taxopath_generator.hpp:78
genesis::taxonomy::TaxopathGenerator::append_delimiter
bool append_delimiter() const
Return whether currently a delimiter is appended to the taxonomic path string.
Definition: taxopath_generator.cpp:183
genesis::taxonomy::Taxon
Store a Taxon, i.e., an element in a Taxonomy, with its name, rank, ID and sub-taxa.
Definition: taxon.hpp:76
genesis::taxonomy::TaxopathGenerator
Helper class to generate a taxonomic path string from a Taxopath object or a Taxon.
Definition: taxopath_generator.hpp:74
genesis::taxonomy::TaxopathGenerator::TaxonField::kName
@ kName
taxonomy.hpp
genesis::taxonomy::Taxopath
Helper class to store a taxonomic path.
Definition: taxopath.hpp:83
string.hpp
Provides some commonly used string utility functions.
genesis::taxonomy::Taxon::rank
std::string const & rank() const
Return the rank of this taxon.
Definition: taxon.cpp:145
taxopath_generator.hpp
genesis::taxonomy::Taxon::name
std::string const & name() const
Return the name of this taxon.
Definition: taxon.cpp:131
genesis::taxonomy::TaxopathGenerator::trim_nested_duplicates
bool trim_nested_duplicates() const
Return the currently set value whether to trim nested duplicates of taxa names.
Definition: taxopath_generator.cpp:172
genesis::taxonomy::TaxopathGenerator::delimiter
std::string delimiter() const
Return the currelty set value used to join the taxonomic path string elements.
Definition: taxopath_generator.cpp:161
genesis::utils::join
Interval< DataType, NumericalType, IntervalKind > join(Interval< DataType, NumericalType, IntervalKind > const &a, Interval< DataType, NumericalType, IntervalKind > const &b)
Creates a new Interval that contains both intervals and whatever is between.
Definition: utils/containers/interval_tree/functions.hpp:127
genesis
Container namespace for all symbols of genesis in order to keep them separate when used as a library.
Definition: placement/formats/edge_color.cpp:42
taxon.hpp
genesis::taxonomy::TaxopathGenerator::TaxonField::kRank
@ kRank
genesis::taxonomy::TaxopathGenerator::to_string
std::string to_string(Taxopath const &taxopath) const
Return a string representation of a Taxopath.
Definition: taxopath_generator.cpp:49
genesis::taxonomy::TaxopathGenerator::operator()
std::string operator()(Taxopath const &taxopath) const
Shortcut function alias for to_string( Taxopath ).
Definition: taxopath_generator.cpp:78
genesis::taxonomy::Taxon::id
std::string const & id() const
Set the ID of this taxon.
Definition: taxon.cpp:159