bpp-phyl3 3.0.0
TreeTools.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: The Bio++ Development Group
2//
3// SPDX-License-Identifier: CECILL-2.1
4
6#include <Bpp/BppString.h>
12#include <Bpp/Text/TextTools.h>
13
14#include "../Distance/BioNJ.h"
15#include "../Distance/DistanceEstimation.h"
16#include "../Legacy/OptimizationTools.h"
17#include "../Parsimony/DRTreeParsimonyScore.h"
18#include "../Model/Nucleotide/JCnuc.h"
19#include "BipartitionTools.h"
20#include "Tree.h"
21#include "TreeTools.h"
22
23// From bpp-seq:
26
27using namespace bpp;
28
29// From the STL:
30#include <iostream>
31#include <sstream>
32
33using namespace std;
34
35/******************************************************************************/
36
37const string TreeTools::BOOTSTRAP = "bootstrap";
38
39/******************************************************************************/
40
41vector<int> TreeTools::getLeavesId(const Tree& tree, int nodeId)
42{
43 vector<int> leaves;
44 getLeavesId(tree, nodeId, leaves);
45 return leaves;
46}
47
48void TreeTools::getLeavesId(const Tree& tree, int nodeId, std::vector<int>& leaves)
49{
50 if (!tree.hasNode(nodeId))
51 throw NodeNotFoundException("TreeTools::getLeavesId", nodeId);
52 if (tree.isLeaf(nodeId))
53 {
54 leaves.push_back(nodeId);
55 }
56 vector<int> sons = tree.getSonsId(nodeId);
57 for (size_t i = 0; i < sons.size(); i++)
58 {
59 getLeavesId(tree, sons[i], leaves);
60 }
61}
62
63size_t TreeTools::getNumberOfLeaves(const Tree& tree, int nodeId)
64{
65 if (!tree.hasNode(nodeId))
66 throw NodeNotFoundException("TreeTools::getNumberOfLeaves", nodeId);
67
68 size_t n = 0;
69 if (tree.isLeaf(nodeId))
70 {
71 ++n;
72 }
73 vector<int> sons = tree.getSonsId(nodeId);
74 for (size_t i = 0; i < sons.size(); ++i)
75 {
76 n += getNumberOfLeaves(tree, sons[i]);
77 }
78 return n;
79}
80
81/******************************************************************************/
82
83int TreeTools::getLeafId(const Tree& tree, int nodeId, const std::string& name)
84{
85 int* id = NULL;
86 searchLeaf(tree, nodeId, name, id);
87 if (id == NULL)
88 throw NodeNotFoundException("TreeTools::getLeafId().", name);
89 else
90 {
91 int i = *id;
92 delete id;
93 return i;
94 }
95}
96
97void TreeTools::searchLeaf(const Tree& tree, int nodeId, const string& name, int*& id)
98{
99 if (tree.hasNoSon(nodeId))
100 {
101 if (tree.getNodeName(nodeId) == name)
102 {
103 id = new int(nodeId);
104 return;
105 }
106 }
107 vector<int> sons;
108 for (size_t i = 0; i < sons.size(); i++)
109 {
110 searchLeaf(tree, nodeId, name, id);
111 }
112}
113
114/******************************************************************************/
115
116vector<int> TreeTools::getNodesId(const Tree& tree, int nodeId)
117{
118 vector<int> nodes;
119 getNodesId(tree, nodeId, nodes);
120 return nodes;
121}
122
123void TreeTools::getNodesId(const Tree& tree, int nodeId, vector<int>& nodes)
124{
125 if (!tree.hasNode(nodeId))
126 throw NodeNotFoundException("TreeTools::getNodesId", nodeId);
127 vector<int> sons = tree.getSonsId(nodeId);
128 for (size_t i = 0; i < sons.size(); i++)
129 {
130 getNodesId(tree, sons[i], nodes);
131 }
132 nodes.push_back(nodeId);
133}
134
135/******************************************************************************/
136
137size_t TreeTools::getDepth(const Tree& tree, int nodeId)
138{
139 if (!tree.hasNode(nodeId))
140 throw NodeNotFoundException("TreeTools::getDepth", nodeId);
141 size_t d = 0;
142 vector<int> sons = tree.getSonsId(nodeId);
143 for (size_t i = 0; i < sons.size(); i++)
144 {
145 size_t c = getDepth(tree, sons[i]) + 1;
146 if (c > d)
147 d = c;
148 }
149 return d;
150}
151
152/******************************************************************************/
153
154size_t TreeTools::getDepths(const Tree& tree, int nodeId, map<int, size_t>& depths)
155{
156 if (!tree.hasNode(nodeId))
157 throw NodeNotFoundException("TreeTools::getDepth", nodeId);
158 size_t d = 0;
159 vector<int> sons = tree.getSonsId(nodeId);
160 for (size_t i = 0; i < sons.size(); i++)
161 {
162 size_t c = getDepths(tree, sons[i], depths) + 1;
163 if (c > d)
164 d = c;
165 }
166 depths[nodeId] = d;
167 return d;
168}
169
170/******************************************************************************/
171
172double TreeTools::getHeight(const Tree& tree, int nodeId)
173{
174 if (!tree.hasNode(nodeId))
175 throw NodeNotFoundException("TreeTools::getHeight", nodeId);
176 double d = 0;
177 vector<int> sons = tree.getSonsId(nodeId);
178 for (size_t i = 0; i < sons.size(); i++)
179 {
180 double dist = 0;
181 if (tree.hasDistanceToFather(sons[i]))
182 dist = tree.getDistanceToFather(sons[i]);
183 else
184 throw NodeException("Node without branch length.", sons[i]);
185 double c = getHeight(tree, sons[i]) + dist;
186 if (c > d)
187 d = c;
188 }
189 return d;
190}
191
192/******************************************************************************/
193
194double TreeTools::getHeights(const Tree& tree, int nodeId, map<int, double>& heights)
195{
196 if (!tree.hasNode(nodeId))
197 throw NodeNotFoundException("TreeTools::getHeight", nodeId);
198 double d = 0;
199 vector<int> sons = tree.getSonsId(nodeId);
200 for (size_t i = 0; i < sons.size(); i++)
201 {
202 double dist = 0;
203 if (tree.hasDistanceToFather(sons[i]))
204 dist = tree.getDistanceToFather(sons[i]);
205 else
206 throw NodeException("Node without branch length.", sons[i]);
207 double c = getHeights(tree, sons[i], heights) + dist;
208 if (c > d)
209 d = c;
210 }
211 heights[nodeId] = d;
212 return d;
213}
214
215/******************************************************************************/
216
217string TreeTools::nodeToParenthesis(const Tree& tree, int nodeId, bool writeId)
218{
219 if (!tree.hasNode(nodeId))
220 throw NodeNotFoundException("TreeTools::nodeToParenthesis", nodeId);
221 ostringstream s;
222 if (tree.hasNoSon(nodeId))
223 {
224 s << tree.getNodeName(nodeId);
225 }
226 else
227 {
228 s << "(";
229 vector<int> sonsId = tree.getSonsId(nodeId);
230 s << nodeToParenthesis(tree, sonsId[0], writeId);
231 for (size_t i = 1; i < sonsId.size(); i++)
232 {
233 s << "," << nodeToParenthesis(tree, sonsId[i], writeId);
234 }
235 s << ")";
236 }
237 if (writeId)
238 {
239 if (tree.hasNoSon(nodeId))
240 s << "_";
241 s << nodeId;
242 }
243 else
244 {
245 if (tree.hasBranchProperty(nodeId, BOOTSTRAP))
246 s << (dynamic_cast<const Number<double>*>(tree.getBranchProperty(nodeId, BOOTSTRAP))->getValue());
247 }
248 if (tree.hasDistanceToFather(nodeId))
249 s << ":" << tree.getDistanceToFather(nodeId);
250 return s.str();
251}
252
253/******************************************************************************/
254
255string TreeTools::nodeToParenthesis(const Tree& tree, int nodeId, bool bootstrap, const string& propertyName)
256{
257 if (!tree.hasNode(nodeId))
258 throw NodeNotFoundException("TreeTools::nodeToParenthesis", nodeId);
259 ostringstream s;
260
261 if (tree.hasNoSon(nodeId))
262 {
263 s << tree.getNodeName(nodeId);
264 }
265 else
266 {
267 s << "(";
268 vector<int> sonsId = tree.getSonsId(nodeId);
269 s << nodeToParenthesis(tree, sonsId[0], bootstrap, propertyName);
270 for (size_t i = 1; i < sonsId.size(); i++)
271 {
272 s << "," << nodeToParenthesis(tree, sonsId[i], bootstrap, propertyName);
273 }
274 s << ")";
275
276 if (bootstrap)
277 {
278 if (tree.hasBranchProperty(nodeId, BOOTSTRAP))
279 s << (dynamic_cast<const Number<double>*>(tree.getBranchProperty(nodeId, BOOTSTRAP))->getValue());
280 }
281 else
282 {
283 if (tree.hasBranchProperty(nodeId, propertyName))
284 s << dynamic_cast<const BppString*>(tree.getBranchProperty(nodeId, propertyName))->toSTL();
285 }
286 }
287 if (tree.hasDistanceToFather(nodeId))
288 s << ":" << tree.getDistanceToFather(nodeId);
289
290 return s.str();
291}
292
293/******************************************************************************/
294
295string TreeTools::treeToParenthesis(const Tree& tree, bool writeId)
296{
297 ostringstream s;
298 s << "(";
299 int rootId = tree.getRootId();
300 vector<int> sonsId = tree.getSonsId(rootId);
301 if (tree.hasNoSon(rootId))
302 {
303 s << tree.getNodeName(rootId);
304 for (size_t i = 0; i < sonsId.size(); i++)
305 {
306 s << "," << nodeToParenthesis(tree, sonsId[i], writeId);
307 }
308 }
309 else
310 {
311 if (sonsId.size() > 0)
312 {
313 s << nodeToParenthesis(tree, sonsId[0], writeId);
314 for (size_t i = 1; i < sonsId.size(); i++)
315 {
316 s << "," << nodeToParenthesis(tree, sonsId[i], writeId);
317 }
318 }
319 // Otherwise, this is an empty tree!
320 }
321 s << ");" << endl;
322 return s.str();
323}
324
325/******************************************************************************/
326
327string TreeTools::treeToParenthesis(const Tree& tree, bool bootstrap, const string& propertyName)
328{
329 ostringstream s;
330 s << "(";
331 int rootId = tree.getRootId();
332 vector<int> sonsId = tree.getSonsId(rootId);
333
334 if (tree.hasNoSon(rootId))
335 {
336 s << tree.getNodeName(rootId);
337 for (size_t i = 0; i < sonsId.size(); i++)
338 {
339 s << "," << nodeToParenthesis(tree, sonsId[i], bootstrap, propertyName);
340 }
341 }
342 else
343 {
344 s << nodeToParenthesis(tree, sonsId[0], bootstrap, propertyName);
345 for (size_t i = 1; i < sonsId.size(); i++)
346 {
347 s << "," << nodeToParenthesis(tree, sonsId[i], bootstrap, propertyName);
348 }
349 }
350 s << ")";
351 if (bootstrap)
352 {
353 if (tree.hasBranchProperty(rootId, BOOTSTRAP))
354 s << (dynamic_cast<const Number<double>*>(tree.getBranchProperty(rootId, BOOTSTRAP))->getValue());
355 }
356 else
357 {
358 if (tree.hasBranchProperty(rootId, propertyName))
359 s << dynamic_cast<const BppString*>(tree.getBranchProperty(rootId, propertyName))->toSTL();
360 }
361 s << ";" << endl;
362
363 return s.str();
364}
365
366/******************************************************************************/
367
368vector<int> TreeTools::getPathBetweenAnyTwoNodes(const Tree& tree, int nodeId1, int nodeId2, bool includeAncestor)
369{
370 if (!tree.hasNode(nodeId1))
371 throw NodeNotFoundException("TreeTools::getPathBetweenAnyTwoNodes", nodeId1);
372 if (!tree.hasNode(nodeId2))
373 throw NodeNotFoundException("TreeTools::getPathBetweenAnyTwoNodes", nodeId2);
374 vector<int> path;
375 vector<int> pathMatrix1;
376 vector<int> pathMatrix2;
377
378 int nodeUp = nodeId1;
379 while (tree.hasFather(nodeUp))
380 {
381 pathMatrix1.push_back(nodeUp);
382 nodeUp = tree.getFatherId(nodeUp);
383 }
384 pathMatrix1.push_back(nodeUp); // The root.
385
386 nodeUp = nodeId2;
387 while (tree.hasFather(nodeUp))
388 {
389 pathMatrix2.push_back(nodeUp);
390 nodeUp = tree.getFatherId(nodeUp);
391 }
392 pathMatrix2.push_back(nodeUp); // The root.
393 // Must check that the two nodes have the same root!!!
394
395 size_t tmp1 = pathMatrix1.size();
396 size_t tmp2 = pathMatrix2.size();
397
398 while ((tmp1 > 0) && (tmp2 > 0))
399 {
400 if (pathMatrix1[tmp1 - 1] != pathMatrix2[tmp2 - 1])
401 break;
402 tmp1--; tmp2--;
403 }
404 // (tmp1 - 1) and (tmp2 - 1) now point toward the first non-common nodes
405
406 for (size_t y = 0; y < tmp1; ++y)
407 {
408 path.push_back(pathMatrix1[y]);
409 }
410 if (includeAncestor)
411 path.push_back(pathMatrix1[tmp1]); // pushing once, the Node that was common to both.
412 for (size_t j = tmp2; j > 0; --j)
413 {
414 path.push_back(pathMatrix2[j - 1]);
415 }
416 return path;
417}
418
419/******************************************************************************/
420
421double TreeTools::getDistanceBetweenAnyTwoNodes(const Tree& tree, int nodeId1, int nodeId2)
422{
423 if (!tree.hasNode(nodeId1))
424 throw NodeNotFoundException("TreeTools::getDistanceBetweenAnyTwoNodes", nodeId1);
425 if (!tree.hasNode(nodeId2))
426 throw NodeNotFoundException("TreeTools::getDistanceBetweenAnyTwoNodes", nodeId2);
427 vector<int> path = getPathBetweenAnyTwoNodes(tree, nodeId1, nodeId2, false);
428 double d = 0;
429 for (size_t i = 0; i < path.size(); i++)
430 {
431 d += tree.getDistanceToFather(path[i]);
432 }
433 return d;
434}
435
436/******************************************************************************/
437
439{
440 if (!tree.hasNode(nodeId))
441 throw NodeNotFoundException("TreeTools::getBranchLengths", nodeId);
442 Vdouble brLen(1);
443 if (tree.hasDistanceToFather(nodeId))
444 brLen[0] = tree.getDistanceToFather(nodeId);
445 else
446 throw NodeException("TreeTools::getbranchLengths(). No branch length.", nodeId);
447 vector<int> sons = tree.getSonsId(nodeId);
448 for (size_t i = 0; i < sons.size(); i++)
449 {
450 Vdouble sonBrLen = getBranchLengths(tree, sons[i]);
451 for (size_t j = 0; j < sonBrLen.size(); j++)
452 {
453 brLen.push_back(sonBrLen[j]);
454 }
455 }
456 return brLen;
457}
458
459/******************************************************************************/
460
461double TreeTools::getTotalLength(const Tree& tree, int nodeId, bool includeAncestor)
462{
463 if (!tree.hasNode(nodeId))
464 throw NodeNotFoundException("TreeTools::getTotalLength", nodeId);
465 if (includeAncestor && !tree.hasDistanceToFather(nodeId))
466 throw NodeException("TreeTools::getTotalLength(). No branch length.", nodeId);
467 double length = includeAncestor ? tree.getDistanceToFather(nodeId) : 0;
468 vector<int> sons = tree.getSonsId(nodeId);
469 for (size_t i = 0; i < sons.size(); i++)
470 {
471 length += getTotalLength(tree, sons[i], true);
472 }
473 return length;
474}
475
476/******************************************************************************/
477
478void TreeTools::setBranchLengths(Tree& tree, int nodeId, double brLen)
479{
480 if (!tree.hasNode(nodeId))
481 throw NodeNotFoundException("TreeTools::setBranchLengths", nodeId);
482 vector<int> nodes = getNodesId(tree, nodeId);
483 for (size_t i = 0; i < nodes.size(); i++)
484 {
485 tree.setDistanceToFather(nodes[i], brLen);
486 }
487}
488
489/******************************************************************************/
490
491void TreeTools::setVoidBranchLengths(Tree& tree, int nodeId, double brLen)
492{
493 if (!tree.hasNode(nodeId))
494 throw NodeNotFoundException("TreeTools::setVoidBranchLengths", nodeId);
495 vector<int> nodes = getNodesId(tree, nodeId);
496 for (size_t i = 0; i < nodes.size(); i++)
497 {
498 if (!tree.hasDistanceToFather(nodes[i]))
499 tree.setDistanceToFather(nodes[i], brLen);
500 }
501}
502
503/******************************************************************************/
504
505void TreeTools::scaleTree(Tree& tree, int nodeId, double factor)
506{
507 if (!tree.hasNode(nodeId))
508 throw NodeNotFoundException("TreeTools::scaleTree", nodeId);
509 vector<int> nodes = getNodesId(tree, nodeId);
510 for (size_t i = 0; i < nodes.size(); i++)
511 {
512 if (tree.hasFather(nodes[i]))
513 {
514 if (!tree.hasDistanceToFather(nodes[i]))
515 throw NodeException("TreeTools::scaleTree(). Branch with no length", nodes[i]);
516 double brLen = tree.getDistanceToFather(nodes[i]) * factor;
517 tree.setDistanceToFather(nodes[i], brLen);
518 }
519 }
520}
521
522/******************************************************************************/
523
525{
526 if (!tree.hasNode(nodeId))
527 throw NodeNotFoundException("TreeTools::initBranchLengthsGrafen", nodeId);
528 vector<int> sons = tree.getSonsId(nodeId);
529 vector<size_t> h(sons.size());
530 for (size_t i = 0; i < sons.size(); i++)
531 {
532 h[i] = initBranchLengthsGrafen(tree, sons[i]);
533 }
534 size_t thish = sons.size() == 0 ? 0 : VectorTools::sum<size_t>(h) + sons.size() - 1;
535 for (size_t i = 0; i < sons.size(); i++)
536 {
537 tree.setDistanceToFather(sons[i], (double)(thish - h[i]));
538 }
539 return thish;
540}
541
543{
545}
546
547/******************************************************************************/
548
550 Tree& tree,
551 int nodeId,
552 double power,
553 double total,
554 double& height,
555 double& heightRaised)
556{
557 if (!tree.hasNode(nodeId))
558 throw NodeNotFoundException("TreeTools::computeBranchLengthsGrafen", nodeId);
559 vector<int> sons = tree.getSonsId(nodeId);
560 vector<double> hr(sons.size());
561 height = 0;
562 for (size_t i = 0; i < sons.size(); i++)
563 {
564 int son = sons[i];
565 if (tree.hasDistanceToFather(son))
566 {
567 double h;
568 computeBranchLengthsGrafen(tree, sons[i], power, total, h, hr[i]);
569 double d = h + tree.getDistanceToFather(son);
570 if (d > height)
571 height = d;
572 }
573 else
574 throw NodeException ("TreeTools::computeBranchLengthsGrafen. Branch length lacking.", son);
575 }
576 heightRaised = std::pow(height / total, power) * total;
577 for (size_t i = 0; i < sons.size(); i++)
578 {
579 tree.setDistanceToFather(sons[i], heightRaised - hr[i]);
580 }
581}
582
583void TreeTools::computeBranchLengthsGrafen(Tree& tree, double power, bool init)
584{
585 int rootId = tree.getRootId();
586 if (init)
587 {
589 }
590 // Scale by total height:
591 double totalHeight = getHeight(tree, rootId);
592 double h, hr;
593 computeBranchLengthsGrafen(tree, rootId, power, totalHeight, h, hr);
594}
595
596/******************************************************************************/
597
598double TreeTools::convertToClockTree(Tree& tree, int nodeId, bool noneg)
599{
600 if (!tree.hasNode(nodeId))
601 throw NodeNotFoundException("TreeTools::convertToClockTree", nodeId);
602 vector<int> sons = tree.getSonsId(nodeId);
603 vector<double> h(sons.size());
604 // We compute the mean height:
605 double l = 0;
606 double maxh = -1.;
607 for (size_t i = 0; i < sons.size(); i++)
608 {
609 int son = sons[i];
610 if (tree.hasDistanceToFather(son))
611 {
612 h[i] = convertToClockTree(tree, son);
613 if (h[i] > maxh)
614 maxh = h[i];
615 l += h[i] + tree.getDistanceToFather(son);
616 }
617 else
618 throw NodeException ("TreeTools::convertToClockTree. Branch length lacking.", son);
619 }
620 if (sons.size() > 0)
621 l /= (double)sons.size();
622 if (l < maxh)
623 l = maxh;
624 for (size_t i = 0; i < sons.size(); i++)
625 {
626 tree.setDistanceToFather(sons[i], l - h[i]);
627 }
628 return l;
629}
630
631/******************************************************************************/
632
633double TreeTools::convertToClockTree2(Tree& tree, int nodeId)
634{
635 if (!tree.hasNode(nodeId))
636 throw NodeNotFoundException("TreeTools::convertToClockTree2", nodeId);
637 vector<int> sons = tree.getSonsId(nodeId);
638 vector<double> h(sons.size());
639 // We compute the mean height:
640 double l = 0;
641 double maxh = -1.;
642 for (size_t i = 0; i < sons.size(); i++)
643 {
644 int son = sons[i];
645 if (tree.hasDistanceToFather(son))
646 {
647 h[i] = convertToClockTree2(tree, son);
648 if (h[i] > maxh)
649 maxh = h[i];
650 l += h[i] + tree.getDistanceToFather(son);
651 }
652 else
653 throw NodeException ("TreeTools::convertToClockTree2. Branch length lacking.", son);
654 }
655 if (sons.size() > 0)
656 l /= (double)sons.size();
657 for (size_t i = 0; i < sons.size(); i++)
658 {
659 scaleTree(tree, sons[i], h[i] > 0 ? l / h[i] : 0);
660 }
661 return l;
662}
663
664/******************************************************************************/
665
666std::unique_ptr<DistanceMatrix> TreeTools::getDistanceMatrix(const Tree& tree)
667{
668 vector<string> names = tree.getLeavesNames();
669 auto mat = make_unique<DistanceMatrix>(names);
670 for (size_t i = 0; i < names.size(); i++)
671 {
672 (*mat)(i, i) = 0;
673 for (size_t j = 0; j < i; j++)
674 {
675 (*mat)(i, j) = (*mat)(j, i) = getDistanceBetweenAnyTwoNodes(tree, tree.getLeafId(names[i]), tree.getLeafId(names[j]));
676 }
677 }
678 return mat;
679}
680
681/******************************************************************************/
682
684{
685 throw Exception("TreeTools::midpointRooting(Tree). This function is deprecated, use TreeTemplateTools::midRoot instead!");
686 if (tree.isRooted())
687 tree.unroot();
688 auto dist = getDistanceMatrix(tree);
689 vector<size_t> pos = MatrixTools::whichMax(dist->asMatrix());
690 double dmid = (*dist)(pos[0], pos[1]) / 2;
691 int id1 = tree.getLeafId(dist->getName(pos[0]));
692 int id2 = tree.getLeafId(dist->getName(pos[1]));
693 int rootId = tree.getRootId();
694 double d1 = getDistanceBetweenAnyTwoNodes(tree, id1, rootId);
695 double d2 = getDistanceBetweenAnyTwoNodes(tree, id2, rootId);
696 int current = d2 > d1 ? id2 : id1;
697 double l = tree.getDistanceToFather(current);
698 double c = l;
699 while (c < dmid)
700 {
701 current = tree.getFatherId(current);
702 l = tree.getDistanceToFather(current);
703 c += l;
704 }
705 tree.newOutGroup(current);
706 int brother = tree.getSonsId(tree.getRootId())[1];
707 if (brother == current)
708 brother = tree.getSonsId(tree.getRootId())[0];
709 tree.setDistanceToFather(current, l - (c - dmid));
710 tree.setDistanceToFather(brother, c - dmid);
711}
712
713/******************************************************************************/
714
715int TreeTools::getMaxId(const Tree& tree, int id)
716{
717 int maxId = id;
718 vector<int> sonsId = tree.getSonsId(id);
719 for (size_t i = 0; i < sonsId.size(); i++)
720 {
721 int subMax = getMaxId(tree, sonsId[i]);
722 if (subMax > maxId)
723 maxId = subMax;
724 }
725 return maxId;
726}
727
728/******************************************************************************/
729
730int TreeTools::getMPNUId(const Tree& tree, int id)
731{
732 vector<int> ids = getNodesId(tree, id);
733 sort(ids.begin(), ids.end());
734 // Check if some id is "missing" in the subtree:
735 for (size_t i = 0; i < ids.size(); i++)
736 {
737 if (ids[i] != (int)i)
738 return (int)i;
739 }
740 // Well, all ids are from 0 to n, so send n+1:
741 return (int)ids.size();
742}
743
744/******************************************************************************/
745
746bool TreeTools::checkIds(const Tree& tree, bool throwException)
747{
748 vector<int> ids = tree.getNodesId();
749 sort(ids.begin(), ids.end());
750 for (size_t i = 1; i < ids.size(); i++)
751 {
752 if (ids[i] == ids[i - 1])
753 {
754 if (throwException)
755 throw Exception("TreeTools::checkIds. This id is used at least twice: " + TextTools::toString(ids[i]));
756 return false;
757 }
758 }
759 return true;
760}
761
762/******************************************************************************/
763
764unique_ptr<VectorSiteContainer> TreeTools::MRPEncode(const vector<unique_ptr<Tree>>& vecTr)
765{
766 vector<unique_ptr<BipartitionList>> vecBipL;
767 for (size_t i = 0; i < vecTr.size(); i++)
768 {
769 vecBipL.push_back(make_unique<BipartitionList>(*vecTr[i]));
770 }
771
772 return BipartitionTools::MRPEncode(vecBipL);
773}
774
775/******************************************************************************/
776
777unique_ptr<VectorSiteContainer> TreeTools::MRPEncodeMultilabel(const vector<unique_ptr<Tree>>& vecTr)
778{
779 vector<unique_ptr<BipartitionList>> vecBipL;
780 for (size_t i = 0; i < vecTr.size(); i++)
781 {
782 vecBipL.push_back(make_unique<BipartitionList>(*vecTr[i]));
783 }
784
786}
787
788/******************************************************************************/
789
790bool TreeTools::haveSameTopology(const Tree& tr1, const Tree& tr2)
791{
792 size_t jj, nbbip;
793 unique_ptr<BipartitionList> bipL1, bipL2;
794 vector<size_t> size1, size2;
795
796 /* compare sets of leaves */
798 return false;
799
800 /* construct bipartitions */
801 bipL1 = make_unique<BipartitionList>(tr1, true);
802 bipL1->removeTrivialBipartitions();
803 bipL1->removeRedundantBipartitions();
804 bipL1->sortByPartitionSize();
805 bipL2 = make_unique<BipartitionList>(tr2, true);
806 bipL2->removeTrivialBipartitions();
807 bipL2->removeRedundantBipartitions();
808 bipL2->sortByPartitionSize();
809
810 /* compare numbers of bipartitions */
811 if (bipL1->getNumberOfBipartitions() != bipL2->getNumberOfBipartitions())
812 return false;
813 nbbip = bipL1->getNumberOfBipartitions();
814
815 /* compare partition sizes */
816 for (size_t i = 0; i < nbbip; i++)
817 {
818 size1.push_back(bipL1->getPartitionSize(i));
819 size2.push_back(bipL1->getPartitionSize(i));
820 if (size1[i] != size2[i])
821 return false;
822 }
823
824 /* compare bipartitions */
825 for (size_t i = 0; i < nbbip; i++)
826 {
827 for (jj = 0; jj < nbbip; jj++)
828 {
829 if (size1[i] == size2[jj] && BipartitionTools::areIdentical(*bipL1, i, *bipL2, jj))
830 break;
831 }
832 if (jj == nbbip)
833 return false;
834 }
835
836 return true;
837}
838
839/******************************************************************************/
840
841int TreeTools::robinsonFouldsDistance(const Tree& tr1, const Tree& tr2, bool checkNames, int* missing_in_tr2, int* missing_in_tr1)
842{
843 unique_ptr<BipartitionList> bipL1, bipL2;
844 size_t i, j;
845 vector<size_t> size1, size2;
846 vector<bool> bipOK2;
847
848
849 if (checkNames && !VectorTools::haveSameElements(tr1.getLeavesNames(), tr2.getLeavesNames()))
850 throw Exception("Distinct leaf sets between trees ");
851
852 /* prepare things */
853 int missing1 = 0;
854 int missing2 = 0;
855
856 bipL1 = make_unique<BipartitionList>(tr1, true);
857 bipL1->removeTrivialBipartitions();
858 bipL1->sortByPartitionSize();
859 bipL2 = make_unique<BipartitionList>(tr2, true);
860 bipL2->removeTrivialBipartitions();
861 bipL2->sortByPartitionSize();
862
863
864 for (i = 0; i < bipL1->getNumberOfBipartitions(); i++)
865 {
866 size1.push_back(bipL1->getPartitionSize(i));
867 }
868 for (i = 0; i < bipL2->getNumberOfBipartitions(); i++)
869 {
870 size2.push_back(bipL2->getPartitionSize(i));
871 }
872
873 for (i = 0; i < bipL2->getNumberOfBipartitions(); i++)
874 {
875 bipOK2.push_back(false);
876 }
877
878 /* main loops */
879
880 for (i = 0; i < bipL1->getNumberOfBipartitions(); i++)
881 {
882 for (j = 0; j < bipL2->getNumberOfBipartitions(); j++)
883 {
884 if (bipOK2[j])
885 continue;
886 if (size1[i] == size2[j] && BipartitionTools::areIdentical(*bipL1, i, *bipL2, j))
887 {
888 bipOK2[j] = true;
889 break;
890 }
891 }
892 if (j == bipL2->getNumberOfBipartitions())
893 missing2++;
894 }
895
896 missing1 = static_cast<int>(bipL2->getNumberOfBipartitions()) - static_cast<int>(bipL1->getNumberOfBipartitions()) + missing2;
897
898 if (missing_in_tr1)
899 *missing_in_tr1 = missing1;
900 if (missing_in_tr2)
901 *missing_in_tr2 = missing2;
902 return missing1 + missing2;
903}
904
905/******************************************************************************/
906
907unique_ptr<BipartitionList> TreeTools::bipartitionOccurrences(const vector<unique_ptr<Tree>>& vecTr, vector<size_t>& bipScore)
908{
909 vector<unique_ptr<BipartitionList>> vecBipL;
910 unique_ptr<BipartitionList> mergedBipL;
911 vector<size_t> bipSize;
912 size_t nbBip;
913
914 /* build and merge bipartitions */
915 for (size_t i = 0; i < vecTr.size(); i++)
916 {
917 vecBipL.push_back(make_unique<BipartitionList>(*vecTr[i]));
918 }
919
920 mergedBipL = BipartitionTools::mergeBipartitionLists(vecBipL);
921
922 mergedBipL->removeTrivialBipartitions();
923 nbBip = mergedBipL->getNumberOfBipartitions();
924 bipScore.clear();
925 for (size_t i = 0; i < nbBip; i++)
926 {
927 bipSize.push_back(mergedBipL->getPartitionSize(i));
928 bipScore.push_back(1);
929 }
930
931 /* compare bipartitions */
932 for (size_t i = nbBip; i > 0; i--)
933 {
934 if (bipScore[i - 1] == 0)
935 continue;
936 for (size_t j = i - 1; j > 0; j--)
937 {
938 if (bipScore[j - 1] && bipSize[i - 1] == bipSize[j - 1] && mergedBipL->areIdentical(i - 1, j - 1))
939 {
940 bipScore[i - 1]++;
941 bipScore[j - 1] = 0;
942 }
943 }
944 }
945
946 /* keep only distinct bipartitions */
947 for (size_t i = nbBip; i > 0; i--)
948 {
949 if (bipScore[i - 1] == 0)
950 {
951 bipScore.erase(bipScore.begin() + static_cast<ptrdiff_t>(i - 1));
952 mergedBipL->deleteBipartition(i - 1);
953 }
954 }
955
956 /* add terminal branches */
957 mergedBipL->addTrivialBipartitions(false);
958 for (size_t i = 0; i < mergedBipL->getNumberOfElements(); i++)
959 {
960 bipScore.push_back(vecTr.size());
961 }
962
963 return mergedBipL;
964}
965
966/******************************************************************************/
967
968unique_ptr<TreeTemplate<Node>> TreeTools::thresholdConsensus(const vector<unique_ptr<Tree>>& vecTr, double threshold, bool checkNames)
969{
970 vector<size_t> bipScore;
971 vector<string> tr0leaves;
972 unique_ptr<BipartitionList> bipL;
973 double score;
974
975 if (vecTr.size() == 0)
976 throw Exception("TreeTools::thresholdConsensus. Empty vector passed");
977
978 /* check names */
979 if (checkNames)
980 {
981 tr0leaves = vecTr[0]->getLeavesNames();
982 for (size_t i = 1; i < vecTr.size(); i++)
983 {
984 if (!VectorTools::haveSameElements(vecTr[i]->getLeavesNames(), tr0leaves))
985 throw Exception("TreeTools::thresholdConsensus. Distinct leaf sets between trees");
986 }
987 }
988
989 bipL = bipartitionOccurrences(vecTr, bipScore);
990
991 for (size_t i = bipL->getNumberOfBipartitions(); i > 0; i--)
992 {
993 if (bipL->getPartitionSize(i - 1) == 1)
994 continue;
995 score = static_cast<int>(bipScore[i - 1]) / static_cast<double>(vecTr.size());
996 if (score <= threshold && score != 1.)
997 {
998 bipL->deleteBipartition(i - 1);
999 continue;
1000 }
1001 if (score > 0.5)
1002 continue;
1003 for (size_t j = bipL->getNumberOfBipartitions(); j > i; j--)
1004 {
1005 if (!bipL->areCompatible(i - 1, j - 1))
1006 {
1007 bipL->deleteBipartition(i - 1);
1008 break;
1009 }
1010 }
1011 }
1012
1013 return bipL->toTree();
1014}
1015
1016/******************************************************************************/
1017
1018unique_ptr<TreeTemplate<Node>> TreeTools::fullyResolvedConsensus(const vector<unique_ptr<Tree>>& vecTr, bool checkNames)
1019{
1020 return thresholdConsensus(vecTr, 0., checkNames);
1021}
1022
1023/******************************************************************************/
1024
1025unique_ptr<TreeTemplate<Node>> TreeTools::majorityConsensus(const vector<unique_ptr<Tree >>& vecTr, bool checkNames)
1026{
1027 return thresholdConsensus(vecTr, 0.5, checkNames);
1028}
1029
1030/******************************************************************************/
1031
1032unique_ptr<TreeTemplate<Node>> TreeTools::strictConsensus(const vector<unique_ptr<Tree>>& vecTr, bool checkNames)
1033{
1034 return thresholdConsensus(vecTr, 1., checkNames);
1035}
1036
1037/******************************************************************************/
1038
1039unique_ptr<Tree> TreeTools::MRP(const vector<unique_ptr<Tree>>& vecTr)
1040{
1041 // matrix representation
1042 shared_ptr<VectorSiteContainer> sites = TreeTools::MRPEncode(vecTr);
1043
1044 // starting bioNJ tree
1045 auto alphabet = dynamic_pointer_cast<const DNA>(sites->getAlphabet());
1046 auto jc = make_shared<JCnuc>(alphabet);
1047 auto constRate = make_shared<ConstantDistribution>(1.);
1048 DistanceEstimation distFunc(jc, constRate, sites, 0, true);
1049 BioNJ bionjTreeBuilder(false, false);
1050 bionjTreeBuilder.setDistanceMatrix(*(distFunc.getMatrix()));
1051 bionjTreeBuilder.computeTree();
1053 ApplicationTools::message->endLine();
1054 shared_ptr<TreeTemplate<Node>> startTree(new TreeTemplate<Node>(bionjTreeBuilder.tree()));
1055
1056 // MP optimization
1057 auto MPScore = make_shared<DRTreeParsimonyScore>(startTree, sites, false);
1058 MPScore = LegacyOptimizationTools::optimizeTreeNNI(MPScore, 0);
1059 auto retTree = make_unique<TreeTemplate<Node>>(MPScore->tree());
1060
1061 return retTree;
1062}
1063
1064/******************************************************************************/
1065
1066void TreeTools::computeBootstrapValues(Tree& tree, const vector<unique_ptr<Tree>>& vecTr, bool verbose, int format)
1067{
1068 vector<int> index;
1069 BipartitionList bpTree(tree, true, &index);
1070
1071 vector<size_t> occurences;
1072
1073 auto bpList = bipartitionOccurrences(vecTr, occurences);
1074
1075 vector< Number<double>> bootstrapValues(bpTree.getNumberOfBipartitions());
1076
1077 for (size_t i = 0; i < bpTree.getNumberOfBipartitions(); i++)
1078 {
1079 if (verbose)
1081 for (size_t j = 0; j < bpList->getNumberOfBipartitions(); j++)
1082 {
1083 if (BipartitionTools::areIdentical(bpTree, i, *bpList, j))
1084 {
1085 bootstrapValues[i] = format >= 0 ? round(static_cast<double>(occurences[j]) * std::pow(10., 2 + format) / static_cast<double>(vecTr.size())) / std::pow(10., format) : static_cast<double>(occurences[j]);
1086 break;
1087 }
1088 }
1089 }
1090
1091 for (size_t i = 0; i < index.size(); i++)
1092 {
1093 if (!tree.isLeaf(index[i]))
1094 tree.setBranchProperty(index[i], BOOTSTRAP, bootstrapValues[i]);
1095 }
1096}
1097
1098/******************************************************************************/
1099
1100vector<int> TreeTools::getAncestors(const Tree& tree, int nodeId)
1101{
1102 vector<int> ids;
1103 int currentId = nodeId;
1104 while (tree.hasFather(currentId))
1105 {
1106 currentId = tree.getFatherId(currentId);
1107 ids.push_back(currentId);
1108 }
1109 return ids;
1110}
1111
1112/******************************************************************************/
1113
1114int TreeTools::getLastCommonAncestor(const Tree& tree, const vector<int>& nodeIds)
1115{
1116 if (nodeIds.size() == 0)
1117 throw Exception("TreeTools::getLastCommonAncestor(). You must provide at least one node id.");
1118 vector< vector<int>> ancestors(nodeIds.size());
1119 for (size_t i = 0; i < nodeIds.size(); i++)
1120 {
1121 ancestors[i] = getAncestors(tree, nodeIds[i]);
1122 ancestors[i].insert(ancestors[i].begin(), nodeIds[i]);
1123 }
1124 int lca = tree.getRootId();
1125 size_t count = 1;
1126 for ( ; ;)
1127 {
1128 if (ancestors[0].size() <= count)
1129 return lca;
1130 int current = ancestors[0][ancestors[0].size() - count - 1];
1131 for (size_t i = 1; i < nodeIds.size(); i++)
1132 {
1133 if (ancestors[i].size() <= count)
1134 return lca;
1135 if (ancestors[i][ancestors[i].size() - count - 1] != current)
1136 return lca;
1137 }
1138 lca = current;
1139 count++;
1140 }
1141 // This line is never reached!
1142 return lca;
1143}
1144
1145/******************************************************************************/
1146
1148{
1149 // is the tree rooted?
1150 if (!tree.isRooted())
1151 throw Exception("The tree has to be rooted on the branch of interest to determine the midpoint position of the root");
1152 // is the tree multifurcating?
1153 if (tree.isMultifurcating())
1154 throw Exception("The tree is multifurcated, which is not allowed.");
1155
1156 double length = 0.;
1157 vector<int> sonsIds = tree.getSonsId(tree.getRootId());
1158 // Length of the branch containing the root:
1159 length = tree.getDistanceToFather(sonsIds.at(0)) + tree.getDistanceToFather(sonsIds.at(1));
1160 // The fraction of the original branch allowing to split its length and to place the root:
1161 double x = bestRootPosition_(tree, sonsIds.at(0), sonsIds.at(1), length);
1162 // The new branch lengths are then computed:
1163 tree.setDistanceToFather(sonsIds.at(0), length * x);
1164 tree.setDistanceToFather(sonsIds.at(1), length * (1 - x));
1165}
1166
1167/******************************************************************************/
1168
1169double TreeTools::bestRootPosition_(Tree& tree, int nodeId1, int nodeId2, double length)
1170{
1171 double x;
1172 Moments_ m1, m2;
1173 double A, B; // C;
1174 // The variance is expressed as a degree 2 polynomial : variance(x) = A * x * x + B * x + C
1175 // The fraction x is then obtained by differentiating this equation.
1176 m1 = statFromNode_(tree, nodeId1);
1177 m2 = statFromNode_(tree, nodeId2);
1178 A = 4 * m1.N * (m2.N * length) * length;
1179 B = 4 * length * (m2.N * m1.sum - m1.N * m2.sum - length * m1.N * m2.N);
1180 // C = (m1.N + m2.N) * (m1.squaredSum + m2.squaredSum) + m1.N * length * m2.N * length +
1181 // 2 * m1.N * length * m2.sum - 2 * m2.N * length * m1.sum -
1182 // (m1.sum + m2.sum) * (m1.sum + m2.sum);
1183
1184 if (A < 1e-20)
1185 x = 0.5;
1186 else
1187 x = -B / (2 * A);
1188 if (x < 0)
1189 x = 0;
1190 else if (x > 1)
1191 x = 1;
1192
1193 return x;
1194}
1195
1196/******************************************************************************/
1197
1199{
1200 // This function recursively calculates both the sum of the branch lengths and the sum of the squared branch lengths down the node whose ID is rootId.
1201 // If below a particular node there are N leaves, the branch between this node and its father is taken into account N times in the calculation.
1202 Moments_ m;
1203 static Moments_ mtmp;
1204
1205 if (tree.isLeaf(rootId))
1206 {
1207 m.N = 1;
1208 m.sum = 0.;
1209 m.squaredSum = 0.;
1210 }
1211 else
1212 {
1213 vector<int> sonsId = tree.getSonsId(rootId);
1214 for (size_t i = 0; i < sonsId.size(); i++)
1215 {
1216 mtmp = statFromNode_(tree, sonsId.at(i));
1217 double bLength = tree.getDistanceToFather(sonsId.at(i));
1218 m.N += mtmp.N;
1219 m.sum += mtmp.sum + bLength * mtmp.N;
1220 m.squaredSum += mtmp.squaredSum + 2 * bLength * mtmp.sum + mtmp.N * bLength * bLength;
1221 }
1222 }
1223
1224 return m;
1225}
1226
1227/******************************************************************************/
1228
1229unique_ptr<Tree> TreeTools::MRPMultilabel(const vector<unique_ptr<Tree>>& vecTr)
1230{
1231 throw Exception("TreeTools::MRPMultilabel not updated.");
1232
1233 // matrix representation
1234 shared_ptr<VectorSiteContainer> sites = TreeTools::MRPEncode(vecTr);
1235
1236 // starting bioNJ tree
1237 shared_ptr<const DNA> alphabet = dynamic_pointer_cast<const DNA>(sites->getAlphabet());
1238 auto jc = make_shared<JCnuc>(alphabet);
1239 auto constRate = make_shared<ConstantDistribution>(1.);
1240 DistanceEstimation distFunc(jc, constRate, sites, 0, true);
1241 BioNJ bionjTreeBuilder(false, false);
1242 bionjTreeBuilder.setDistanceMatrix(*(distFunc.getMatrix()));
1243 bionjTreeBuilder.computeTree();
1245 ApplicationTools::message->endLine();
1246 shared_ptr<TreeTemplate<Node>> startTree(new TreeTemplate<Node>(bionjTreeBuilder.tree()));
1247
1248 // MP optimization
1249 auto MPScore = make_shared<DRTreeParsimonyScore>(startTree, sites, false);
1250 MPScore = LegacyOptimizationTools::optimizeTreeNNI(MPScore, 0);
1251 auto retTree = make_unique<TreeTemplate<Node>>(MPScore->tree());
1252
1253 return retTree;
1254}
static std::shared_ptr< OutputStream > message
static void displayGauge(size_t iter, size_t total, char symbol='>', const std::string &mes="")
The BioNJ distance method.
Definition: BioNJ.h:23
void setDistanceMatrix(const DistanceMatrix &matrix)
Set the distance matrix to use.
Definition: BioNJ.h:67
void computeTree()
Compute the tree corresponding to the distance matrix.
Definition: BioNJ.cpp:25
This class deals with the bipartitions defined by trees.
size_t getNumberOfBipartitions() const
static std::unique_ptr< VectorSiteContainer > MRPEncodeMultilabel(const std::vector< std::unique_ptr< BipartitionList > > &vecBipartL)
Create a sequence data set corresponding to the Matrix Representation of the input BipartitionList ob...
static std::unique_ptr< VectorSiteContainer > MRPEncode(const std::vector< std::unique_ptr< BipartitionList > > &vecBipartL)
Create a sequence data set corresponding to the Matrix Representation of the input BipartitionList ob...
static std::unique_ptr< BipartitionList > mergeBipartitionLists(const std::vector< std::unique_ptr< BipartitionList > > &vecBipartL, bool checkElements=true)
Makes one BipartitionList out of several.
static bool areIdentical(const BipartitionList &bipart1, size_t i1, const BipartitionList &bipart2, size_t i2, bool checkElements=true)
Tells whether two bipartitions from distinct lists are identical.
std::unique_ptr< DistanceMatrix > getMatrix() const
Get the distance matrix.
static std::shared_ptr< NNIHomogeneousTreeLikelihood > optimizeTreeNNI(std::shared_ptr< NNIHomogeneousTreeLikelihood > tl, const ParameterList &parameters, bool optimizeNumFirst=true, double tolBefore=100, double tolDuring=100, unsigned int tlEvalMax=1000000, unsigned int numStep=1, std::shared_ptr< OutputStream > messageHandler=ApplicationTools::message, std::shared_ptr< OutputStream > profiler=ApplicationTools::message, bool reparametrization=false, unsigned int verbose=1, const std::string &optMethod=OptimizationTools::OPTIMIZATION_NEWTON, unsigned int nStep=1, const std::string &nniMethod=NNITopologySearch::PHYML)
Optimize all parameters from a TreeLikelihood object, including tree topology using Nearest Neighbor ...
static std::vector< size_t > whichMax(const Matrix &m)
General exception thrown when something is wrong with a particular node.
Exception thrown when something is wrong with a particular node.
The phylogenetic tree class.
Definition: TreeTemplate.h:59
static size_t getDepth(const Tree &tree, int nodeId)
Get the depth of the subtree defined by node 'node', i.e. the maximum number of sons 'generations'.
Definition: TreeTools.cpp:137
static void initBranchLengthsGrafen(Tree &tree)
Grafen's method to initialize branch lengths.
Definition: TreeTools.cpp:542
static double convertToClockTree(Tree &tree, int nodeId, bool noneg=false)
Modify a tree's branch lengths to make a clock tree, by rebalancing branch lengths.
Definition: TreeTools.cpp:598
static std::unique_ptr< TreeTemplate< Node > > fullyResolvedConsensus(const std::vector< std::unique_ptr< Tree > > &vecTr, bool checkNames=true)
Fully-resolved greedy consensus tree method.
Definition: TreeTools.cpp:1018
static std::vector< int > getLeavesId(const Tree &tree, int nodeId)
Retrieve all leaves from a subtree.
Definition: TreeTools.cpp:41
static int getLeafId(const Tree &tree, int nodeId, const std::string &name)
Get the id of a leaf given its name in a subtree.
Definition: TreeTools.cpp:83
static double getHeights(const Tree &tree, int nodeId, std::map< int, double > &heights)
Get the heights of all nodes within a subtree defined by node 'node', i.e. the maximum distance betwe...
Definition: TreeTools.cpp:194
static std::string nodeToParenthesis(const Tree &tree, int nodeId, bool writeId=false)
Get the parenthesis description of a subtree.
Definition: TreeTools.cpp:217
static std::unique_ptr< DistanceMatrix > getDistanceMatrix(const Tree &tree)
Compute a distance matrix from a tree.
Definition: TreeTools.cpp:666
static void constrainedMidPointRooting(Tree &tree)
Determine the mid-point position of the root along the branch that already contains the root....
Definition: TreeTools.cpp:1147
static int getLastCommonAncestor(const Tree &tree, const std::vector< int > &nodeIds)
Get the id of the last common ancestors of all specified nodes.
Definition: TreeTools.cpp:1114
static void searchLeaf(const Tree &tree, int nodeId, const std::string &name, int *&id)
Get the id of a leaf given its name in a subtree.
Definition: TreeTools.cpp:97
static std::unique_ptr< VectorSiteContainer > MRPEncodeMultilabel(const std::vector< std::unique_ptr< Tree > > &vecTr)
Creates a sequence data set corresponding to the Matrix Representation of the input multilabel trees.
Definition: TreeTools.cpp:777
static void computeBootstrapValues(Tree &tree, const std::vector< std::unique_ptr< Tree > > &vecTr, bool verbose=true, int format=0)
Compute bootstrap values.
Definition: TreeTools.cpp:1066
static std::vector< int > getPathBetweenAnyTwoNodes(const Tree &tree, int nodeId1, int nodeId2, bool includeAncestor=true)
Get a vector of ancestor nodes between to nodes.
Definition: TreeTools.cpp:368
static std::unique_ptr< TreeTemplate< Node > > thresholdConsensus(const std::vector< std::unique_ptr< Tree > > &vecTr, double threshold, bool checkNames=true)
General greedy consensus tree method.
Definition: TreeTools.cpp:968
static std::unique_ptr< VectorSiteContainer > MRPEncode(const std::vector< std::unique_ptr< Tree > > &vecTr)
Creates a sequence data set corresponding to the Matrix Representation of the input trees.
Definition: TreeTools.cpp:764
static void setBranchLengths(Tree &tree, int nodeId, double brLen)
Set all the branch lengths of a subtree.
Definition: TreeTools.cpp:478
static std::unique_ptr< TreeTemplate< Node > > strictConsensus(const std::vector< std::unique_ptr< Tree > > &vecTr, bool checkNames=true)
Strict consensus tree method.
Definition: TreeTools.cpp:1032
static double bestRootPosition_(Tree &tree, int nodeId1, int nodeId2, double length)
Definition: TreeTools.cpp:1169
static std::string treeToParenthesis(const Tree &tree, bool writeId=false)
Get the parenthesis description of a tree.
Definition: TreeTools.cpp:295
static Moments_ statFromNode_(Tree &tree, int rootId)
Definition: TreeTools.cpp:1198
static bool checkIds(const Tree &tree, bool throwException)
Check if the ids are uniques.
Definition: TreeTools.cpp:746
static double convertToClockTree2(Tree &tree, int nodeId)
Modify a tree's branch lengths to make a clock tree, by rescaling subtrees.
Definition: TreeTools.cpp:633
static void setVoidBranchLengths(Tree &tree, int nodeId, double brLen)
Give a length to branches that don't have one in a subtree.
Definition: TreeTools.cpp:491
static void scaleTree(Tree &tree, int nodeId, double factor)
Scale a given tree.
Definition: TreeTools.cpp:505
static size_t getNumberOfLeaves(const Tree &tree, int nodeId)
Count the number of leaves from a subtree.
Definition: TreeTools.cpp:63
static void computeBranchLengthsGrafen(Tree &tree, double power=1, bool init=true)
Compute branch lengths using Grafen's method.
Definition: TreeTools.cpp:583
static std::unique_ptr< Tree > MRPMultilabel(const std::vector< std::unique_ptr< Tree > > &vecTr)
Matrix Representation Parsimony supertree method for multilabel trees.
Definition: TreeTools.cpp:1229
static double getHeight(const Tree &tree, int nodeId)
Get the height of the subtree defined by node 'node', i.e. the maximum distance between leaves and th...
Definition: TreeTools.cpp:172
static std::unique_ptr< TreeTemplate< Node > > majorityConsensus(const std::vector< std::unique_ptr< Tree > > &vecTr, bool checkNames=true)
Majority consensus tree method.
Definition: TreeTools.cpp:1025
static double getTotalLength(const Tree &tree, int nodeId, bool includeAncestor=true)
Get the total length (sum of all branch lengths) of a subtree.
Definition: TreeTools.cpp:461
static size_t getDepths(const Tree &tree, int nodeId, std::map< int, size_t > &depths)
Get the depths for all nodes of the subtree defined by node 'node', i.e. the maximum number of sons '...
Definition: TreeTools.cpp:154
static int getMaxId(const Tree &tree, int id)
Get the maximum identifier used in a (sub)tree.
Definition: TreeTools.cpp:715
static const std::string BOOTSTRAP
Bootstrap tag.
Definition: TreeTools.h:684
static std::vector< int > getNodesId(const Tree &tree, int nodeId)
Retrieve all nodes ids nodes from a subtree.
Definition: TreeTools.cpp:116
static int getMPNUId(const Tree &tree, int id)
Get the minimum positive non-used identifier in a (sub)tree.
Definition: TreeTools.cpp:730
static int robinsonFouldsDistance(const Tree &tr1, const Tree &tr2, bool checkNames=true, int *missing_in_tr2=NULL, int *missing_in_tr1=NULL)
Calculates the Robinson-Foulds topological distance between two trees.
Definition: TreeTools.cpp:841
static std::vector< int > getAncestors(const Tree &tree, int nodeId)
Get a list of all ids of parents nodes, from the current node (not included) to the root of the tree.
Definition: TreeTools.cpp:1100
static bool haveSameTopology(const Tree &tr1, const Tree &tr2)
Tells whether two trees have the same unrooted topology.
Definition: TreeTools.cpp:790
static double getDistanceBetweenAnyTwoNodes(const Tree &tree, int nodeId1, int nodeId2)
Get the total distance between two nodes.
Definition: TreeTools.cpp:421
static void midpointRooting(Tree &tree)
(Re)root the tree using the midpoint method.
Definition: TreeTools.cpp:683
static std::unique_ptr< BipartitionList > bipartitionOccurrences(const std::vector< std::unique_ptr< Tree > > &vecTr, std::vector< size_t > &bipScore)
Counts the total number of occurrences of every bipartition from the input trees.
Definition: TreeTools.cpp:907
static std::unique_ptr< Tree > MRP(const std::vector< std::unique_ptr< Tree > > &vecTr)
Matrix Representation Parsimony supertree method.
Definition: TreeTools.cpp:1039
static Vdouble getBranchLengths(const Tree &tree, int nodeId)
Get all the branch lengths of a subtree.
Definition: TreeTools.cpp:438
Interface for phylogenetic tree objects.
Definition: Tree.h:115
virtual bool isRooted() const =0
Tell if the tree is rooted.
virtual bool hasFather(int nodeId) const =0
virtual void setDistanceToFather(int nodeId, double length)=0
virtual void setBranchProperty(int nodeId, const std::string &name, const Clonable &property)=0
virtual std::string getNodeName(int nodeId) const =0
virtual std::vector< int > getSonsId(int parentId) const =0
virtual int getFatherId(int parentId) const =0
virtual std::vector< int > getNodesId() const =0
virtual bool unroot()=0
Unroot a rooted tree.
virtual bool hasNode(int nodeId) const =0
virtual bool isLeaf(int nodeId) const =0
virtual Clonable * getBranchProperty(int nodeId, const std::string &name)=0
virtual bool isMultifurcating() const =0
Tell if the tree is multifurcating.
virtual bool hasDistanceToFather(int nodeId) const =0
virtual std::vector< std::string > getLeavesNames() const =0
virtual double getDistanceToFather(int nodeId) const =0
virtual bool hasNoSon(int nodeId) const =0
virtual void newOutGroup(int nodeId)=0
Root a tree by specifying an outgroup.
virtual bool hasBranchProperty(int nodeId, const std::string &name) const =0
virtual int getRootId() const =0
virtual int getLeafId(const std::string &name) const =0
static bool haveSameElements(const std::vector< T > &v1, const std::vector< T > &v2)
std::string toString(T t)
std::size_t count(const std::string &s, const std::string &pattern)
Defines the basic types of data flow nodes.
std::vector< double > Vdouble
ExtendedFloat pow(const ExtendedFloat &ef, double exp)