56 struct LabelledTreePlacementPair
58 LabelledTreePlacementPair( Pquery
const* pq, PqueryPlacement
const* pp )
64 PqueryPlacement
const* placement;
77 std::vector< std::vector< LabelledTreePlacementPair >> place_map;
79 for(
auto const& pqry : sample.
pqueries() ) {
82 auto max_it = std::max_element(
83 pqry.placements().begin(),
84 pqry.placements().end(),
86 return lhs.like_weight_ratio < rhs.like_weight_ratio;
92 if( max_it != pqry.placements().end() ) {
93 place_map[ max_it->edge().index() ].emplace_back( &pqry, &*max_it );
120 LabelledTreePlacementPair
const& placement_pair,
121 std::string
const& name_prefix
125 auto& pendant_edge = pendant_node.link().edge();
126 auto& proximal_edge = pendant_edge.primary_link().next().edge();
127 auto& distal_edge = pendant_edge.primary_link().next().next().edge();
130 assert(
degree( pendant_edge.primary_node() ) == 3 );
131 assert(
is_leaf( pendant_edge.secondary_node() ));
139 assert( pend_data.branch_length == 0.0 );
143 double const distal_len = prox_data.
branch_length - placement_pair.placement->proximal_length;
144 pend_data.branch_length = placement_pair.placement->pendant_length;
145 prox_data.
branch_length = placement_pair.placement->proximal_length;
150 assert( placement_pair.pquery->name_size() <= 1 );
151 if( placement_pair.pquery->name_size() == 1 ) {
153 pendant_node_data.
name = name_prefix + placement_pair.pquery->name_at(0).name;
165 std::vector<LabelledTreePlacementPair>
const& placement_pairs,
166 std::string
const& name_prefix
172 double used_length = 0.0;
179 auto insertion_edge = &edge;
182 for(
auto const& placement_pair : placement_pairs ) {
184 for(
auto const& pquery_name : placement_pair.pquery->names() ) {
188 auto& pendant_edge = pendant_node.link().edge();
189 auto& proximal_edge = pendant_edge.primary_link().next().edge();
190 auto& distal_edge = pendant_edge.primary_link().next().next().edge();
193 assert(
degree( pendant_edge.primary_node() ) == 3 );
194 assert(
is_leaf( pendant_edge.secondary_node() ));
203 assert( pend_data.branch_length == 0.0 );
207 assert( placement_pair.placement->proximal_length >= used_length );
210 pend_data.branch_length = placement_pair.placement->pendant_length;
211 prox_data.
branch_length = placement_pair.placement->proximal_length - used_length;
215 node_data.
name = name_prefix + pquery_name.name;
218 used_length = placement_pair.placement->proximal_length;
219 insertion_edge = &distal_edge;
233 assert( end_edge_data.branch_length == 0.0 );
234 if( used_length < orig_length ) {
235 end_edge_data.branch_length = orig_length - used_length;
248 std::vector<LabelledTreePlacementPair>
const& placement_pairs,
249 std::string
const& name_prefix
255 auto& base_edge = new_node.link().edge();
256 auto& pri_edge = base_edge.primary_link().next().edge();
257 auto& sec_edge = base_edge.primary_link().next().next().edge();
260 assert(
degree( base_edge.primary_node() ) == 3 );
261 assert(
is_leaf( base_edge.secondary_node() ));
269 assert( base_data.branch_length == 0.0 );
273 auto const avg_prox_len = std::accumulate(
274 placement_pairs.begin(),
275 placement_pairs.end(),
277 [](
double in, LabelledTreePlacementPair
const& cur ){
278 return in + cur.placement->proximal_length;
280 ) /
static_cast<double>( placement_pairs.size() );
295 assert( placement_pairs.size() > 0 );
296 auto const min_pen_len = std::max( 0.0, std::min_element(
297 placement_pairs.begin(),
298 placement_pairs.end(),
299 []( LabelledTreePlacementPair
const& lhs, LabelledTreePlacementPair
const& rhs ){
300 return lhs.placement->pendant_length < rhs.placement->pendant_length;
302 )->placement->pendant_length );
306 assert( min_pen_len == placement_pairs[0].placement->pendant_length );
309 base_data.branch_length = min_pen_len;
312 for(
auto const& placement_pair : placement_pairs ) {
314 for(
auto const& pquery_name : placement_pair.pquery->names() ) {
318 auto& p_edge = p_node.link().edge();
323 assert( placement_pair.placement->pendant_length >= min_pen_len );
324 p_data.branch_length = placement_pair.placement->pendant_length - min_pen_len;
328 p_node_data.
name = name_prefix + pquery_name.name;
339 bool const fully_resolve,
340 std::string
const& name_prefix
355 std::string
const& name_prefix
368 throw std::runtime_error(
369 "Tree provided for labelled_tree() is not compatible "
370 "with the Tree of the provided Sample."
375 std::vector< tree::TreeEdge* > edge_list;
376 edge_list.reserve( result.edge_count() );
377 for(
auto& edge : result.edges() ) {
378 edge_list.push_back( &edge );
383 assert( place_map.size() == edge_list.size() );
389 auto sort_placements = fully_resolve
390 ? []( LabelledTreePlacementPair
const& lhs, LabelledTreePlacementPair
const& rhs ){
391 return lhs.placement->proximal_length < rhs.placement->proximal_length;
393 : []( LabelledTreePlacementPair
const& lhs, LabelledTreePlacementPair
const& rhs ){
394 return lhs.placement->pendant_length < rhs.placement->pendant_length;
397 for(
auto& edge_l : place_map ) {
398 std::sort( edge_l.begin(), edge_l.end(), sort_placements );
406 for(
size_t edge_i = 0; edge_i < edge_list.size(); ++edge_i ) {
408 assert( edge_list[ edge_i ] );
411 if( place_map[ edge_i ].size() == 0 ) {
417 if( place_map[ edge_i ].size() == 1 && place_map[ edge_i ][0].pquery->name_size() <= 1 ) {
418 assert( place_map[ edge_i ][0].pquery && place_map[ edge_i ][0].placement );
420 result, *edge_list[ edge_i ], place_map[ edge_i ][0], name_prefix
426 if( fully_resolve ) {
428 result, *edge_list[ edge_i ], place_map[ edge_i ], name_prefix
432 result, *edge_list[ edge_i ], place_map[ edge_i ], name_prefix