bpp-phyl3 3.0.0
TreeTemplateTools.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: The Bio++ Development Group
2//
3// SPDX-License-Identifier: CECILL-2.1
4
5#include <Bpp/BppString.h>
10#include <Bpp/Text/TextTools.h>
11
12#include "TreeTemplate.h"
13#include "TreeTemplateTools.h"
14#include "PhyloTree.h"
15
16using namespace bpp;
17
18// From the STL:
19#include <iostream>
20#include <sstream>
21#include <limits>
22
23using namespace std;
24
25/******************************************************************************/
26
27bool TreeTemplateTools::isMultifurcating(const Node& node)
28{
29 if (node.getNumberOfSons() > 2)
30 return true;
31 else
32 {
33 bool b = false;
34 for (size_t i = 0; i < node.getNumberOfSons(); i++)
35 {
36 b = b || isMultifurcating(*node.getSon(i));
37 }
38 return b;
39 }
40}
41
42/******************************************************************************/
43
45{
46 size_t nbLeaves = 0;
47 if (node.isLeaf())
48 {
49 nbLeaves++;
50 }
51 for (int i = 0; i < static_cast<int>(node.getNumberOfSons()); i++)
52 {
53 nbLeaves += getNumberOfLeaves(*node[i]);
54 }
55 return nbLeaves;
56}
57
58/******************************************************************************/
59
60vector<string> TreeTemplateTools::getLeavesNames(const Node& node)
61{
62 vector<string> names;
63 if (node.hasNoSon())
64 {
65 names.push_back(node.getName());
66 }
67 for (size_t i = 0; i < node.getNumberOfSons(); i++)
68 {
69 vector<string> subNames = getLeavesNames(*node.getSon(i));
70 for (size_t j = 0; j < subNames.size(); j++)
71 {
72 names.push_back(subNames[j]);
73 }
74 }
75 return names;
76}
77
78void TreeTemplateTools::getLeavesId(const Node& node, std::vector<int>& ids)
79{
80 if (node.isLeaf())
81 {
82 ids.push_back(node.getId());
83 }
84 for (size_t i = 0; i < node.getNumberOfSons(); i++)
85 {
86 getLeavesId(*node.getSon(i), ids);
87 }
88}
89
90std::vector<int> TreeTemplateTools::getAncestorsId(const Node& node)
91{
92 std::vector<int> ids;
93 const Node* n = &node;
94 while (n->hasFather())
95 {
96 n = n->getFather();
97 ids.push_back(n->getId());
98 }
99 return ids;
100}
101
102void TreeTemplateTools::searchLeaf(const Node& node, const std::string& name, int*& id)
103{
104 if (node.hasNoSon())
105 {
106 if (node.getName() == name)
107 {
108 id = new int(node.getId());
109 return;
110 }
111 }
112 for (size_t i = 0; i < node.getNumberOfSons(); i++)
113 {
114 searchLeaf(*node.getSon(i), name, id);
115 }
116}
117
118
119/******************************************************************************/
120
121unsigned int TreeTemplateTools::getDepth(const Node& node)
122{
123 unsigned int d = 0;
124 for (int i = 0; i < static_cast<int>(node.getNumberOfSons()); i++)
125 {
126 unsigned int c = getDepth(*node[i]) + 1;
127 if (c > d)
128 d = c;
129 }
130 return d;
131}
132
133/******************************************************************************/
134
135unsigned int TreeTemplateTools::getDepths(const Node& node, map<const Node*, unsigned int>& depths)
136{
137 unsigned int d = 0;
138 for (int i = 0; i < static_cast<int>(node.getNumberOfSons()); i++)
139 {
140 unsigned int c = getDepths(*node[i], depths) + 1;
141 if (c > d)
142 d = c;
143 }
144 depths[&node] = d;
145 return d;
146}
147
148/******************************************************************************/
149
151{
152 double d = 0;
153 for (int i = 0; i < static_cast<int>(node.getNumberOfSons()); i++)
154 {
155 const Node* son = node[i];
156 double dist = son->getDistanceToFather();
157 double c = getHeight(*son) + dist;
158 if (c > d)
159 d = c;
160 }
161 return d;
162}
163
164/******************************************************************************/
165
166double TreeTemplateTools::getHeights(const Node& node, map<const Node*, double>& heights)
167{
168 double d = 0;
169 for (int i = 0; i < static_cast<int>(node.getNumberOfSons()); i++)
170 {
171 const Node* son = node[i];
172 double dist = son->getDistanceToFather();
173 double c = getHeights(*son, heights) + dist;
174 if (c > d)
175 d = c;
176 }
177 heights[&node] = d;
178 return d;
179}
180
181/******************************************************************************/
182
184{
185 Element element;
186 element.length = ""; // default
187 element.bootstrap = ""; // default
188 element.isLeaf = false; // default
189
190 size_t colonIndex;
191 bool hasColon = false;
192 for (colonIndex = elt.size(); colonIndex > 0 && elt[colonIndex] != ')'; colonIndex--)
193 {
194 if (elt[colonIndex] == ':')
195 {
196 hasColon = true;
197 break;
198 }
199 }
200 try
201 {
202 string elt2;
203 if (hasColon)
204 {
205 // this is an element with length:
206 elt2 = elt.substr(0, colonIndex);
207 element.length = TextTools::removeSurroundingWhiteSpaces(elt.substr(colonIndex + 1));
208 }
209 else
210 {
211 // this is an element without length;
212 elt2 = elt;
213 }
214
215 string::size_type lastP = elt2.rfind(')');
216 string::size_type firstP = elt2.find('(');
217 if (firstP == string::npos)
218 {
219 // This is a leaf:
220 element.content = elt2;
221 element.isLeaf = true;
222 }
223 else
224 {
225 // This is a node:
226 if (lastP < firstP)
227 throw IOException("TreeTemplateTools::getElement(). Invalid format: bad closing parenthesis in " + elt2);
228 element.content = TextTools::removeSurroundingWhiteSpaces(elt2.substr(firstP + 1, lastP - firstP - 1));
229 string bootstrap = TextTools::removeSurroundingWhiteSpaces(elt2.substr(lastP + 1));
230 // cout << "ELEMENT: BOOTSTRAP: " << bootstrap << endl;
231 if (!TextTools::isEmpty(bootstrap))
232 {
233 element.bootstrap = bootstrap;
234 }
235 }
236 }
237 catch (exception& e)
238 {
239 throw IOException("Bad tree description: " + elt);
240 }
241 return element;
242}
243
244/******************************************************************************/
245
246
247Node* TreeTemplateTools::parenthesisToNode(const string& description, unsigned int& nodeCounter, bool bootstrap, const string& propertyName, bool withId, bool verbose)
248{
249 // cout << "NODE: " << description << endl;
250 Element elt = getElement(description);
251
252 // New node:
253 Node* node = new Node();
254 if (!TextTools::isEmpty(elt.length))
255 {
257 // cout << "NODE: LENGTH: " << * elt.length << endl;
258 }
260 {
261 if (withId)
262 {
263 node->setId(TextTools::toInt(elt.bootstrap));
264 }
265 else
266 {
267 if (bootstrap)
268 {
270 // cout << "NODE: BOOTSTRAP: " << * elt.bootstrap << endl;
271 }
272 else
273 {
274 node->setBranchProperty(propertyName, BppString(elt.bootstrap));
275 }
276 }
277 }
278
279 NestedStringTokenizer nt(elt.content, "(", ")", ",");
280 vector<string> elements;
281 while (nt.hasMoreToken())
282 {
283 elements.push_back(nt.nextToken());
284 }
285
286 if (elt.isLeaf)
287 {
288 // This is a leaf:
289 string name = TextTools::removeSurroundingWhiteSpaces(elements[0]);
290 if (withId)
291 {
292 StringTokenizer st(name, "_", true, true);
293 ostringstream realName;
294 for (size_t i = 0; i < st.numberOfRemainingTokens() - 1; ++i)
295 {
296 if (i != 0)
297 {
298 realName << "_";
299 }
300 realName << st.getToken(i);
301 }
302 node->setName(realName.str());
304 }
305 else
306 {
307 node->setName(name);
308 }
309 }
310 else
311 {
312 // This is a node:
313 for (size_t i = 0; i < elements.size(); i++)
314 {
315 // cout << "NODE: SUBNODE: " << i << ", " << elements[i] << endl;
316 Node* son = parenthesisToNode(elements[i], nodeCounter, bootstrap, propertyName, withId, verbose);
317 node->addSon(son);
318 }
319 }
320 nodeCounter++;
321 if (verbose)
323 return node;
324}
325
326/******************************************************************************/
327
328unique_ptr<TreeTemplate<Node>> TreeTemplateTools::parenthesisToTree(const string& description, bool bootstrap, const string& propertyName, bool withId, bool verbose)
329{
330 string::size_type semi = description.rfind(';');
331 if (semi == string::npos)
332 throw Exception("TreeTemplateTools::parenthesisToTree(). Bad format: no semi-colon found.");
333 string content = description.substr(0, semi);
334 unsigned int nodeCounter = 0;
335 Node* node = parenthesisToNode(content, nodeCounter, bootstrap, propertyName, withId, verbose);
336 auto tree = make_unique<TreeTemplate<Node>>();
337 tree->setRootNode(node);
338 if (!withId)
339 {
340 tree->resetNodesId();
341 }
342 if (verbose)
343 {
344 (*ApplicationTools::message) << " nodes loaded.";
345 ApplicationTools::message->endLine();
346 }
347 return tree;
348}
349
350/******************************************************************************/
351
352string TreeTemplateTools::nodeToParenthesis(const Node& node, bool writeId)
353{
354 ostringstream s;
355 if (node.hasNoSon())
356 {
357 s << node.getName();
358 }
359 else
360 {
361 s << "(";
362 s << nodeToParenthesis(*node[0], writeId);
363 for (int i = 1; i < static_cast<int>(node.getNumberOfSons()); i++)
364 {
365 s << "," << nodeToParenthesis(*node[i], writeId);
366 }
367 s << ")";
368 }
369 if (writeId)
370 {
371 if (node.hasNoSon())
372 s << "_";
373 s << node.getId();
374 }
375 else
376 {
378 s << (dynamic_cast<const Number<double>*>(node.getBranchProperty(TreeTools::BOOTSTRAP))->getValue());
379 }
380 if (node.hasDistanceToFather())
381 s << ":" << node.getDistanceToFather();
382 return s.str();
383}
384
385/******************************************************************************/
386
387string TreeTemplateTools::nodeToParenthesis(const Node& node, bool bootstrap, const string& propertyName)
388{
389 ostringstream s;
390 if (node.hasNoSon())
391 {
392 s << node.getName();
393 }
394 else
395 {
396 s << "(";
397 s << nodeToParenthesis(*node[0], bootstrap, propertyName);
398 for (int i = 1; i < static_cast<int>(node.getNumberOfSons()); i++)
399 {
400 s << "," << nodeToParenthesis(*node[i], bootstrap, propertyName);
401 }
402 s << ")";
403
404 if (bootstrap)
405 {
407 s << (dynamic_cast<const Number<double>*>(node.getBranchProperty(TreeTools::BOOTSTRAP))->getValue());
408 }
409 else
410 {
411 if (node.hasBranchProperty(propertyName))
412 {
413 const BppString* ppt = dynamic_cast<const BppString*>(node.getBranchProperty(propertyName));
414 if (ppt)
415 s << *ppt;
416 else
417 throw Exception("TreeTemplateTools::nodeToParenthesis. Property should be a BppString.");
418 }
419 }
420 }
421 if (node.hasDistanceToFather())
422 s << ":" << node.getDistanceToFather();
423 return s.str();
424}
425
426/******************************************************************************/
427
429{
430 ostringstream s;
431 s << "(";
432 const Node* node = tree.getRootNode();
433 if (node->hasNoSon())
434 {
435 s << node->getName();
436 for (size_t i = 0; i < node->getNumberOfSons(); ++i)
437 {
438 s << "," << nodeToParenthesis(*node->getSon(i), writeId);
439 }
440 }
441 else
442 {
443 s << nodeToParenthesis(*node->getSon(0), writeId);
444 for (size_t i = 1; i < node->getNumberOfSons(); ++i)
445 {
446 s << "," << nodeToParenthesis(*node->getSon(i), writeId);
447 }
448 }
449 s << ")";
450 if (node->hasDistanceToFather())
451 s << ":" << node->getDistanceToFather();
452 s << ";" << endl;
453 return s.str();
454}
455
456/******************************************************************************/
457
458string TreeTemplateTools::treeToParenthesis(const TreeTemplate<Node>& tree, bool bootstrap, const string& propertyName)
459{
460 ostringstream s;
461 s << "(";
462 const Node* node = tree.getRootNode();
463 if (node->hasNoSon())
464 {
465 s << node->getName();
466 for (size_t i = 0; i < node->getNumberOfSons(); i++)
467 {
468 s << "," << nodeToParenthesis(*node->getSon(i), bootstrap, propertyName);
469 }
470 }
471 else
472 {
473 s << nodeToParenthesis(*node->getSon(0), bootstrap, propertyName);
474 for (size_t i = 1; i < node->getNumberOfSons(); i++)
475 {
476 s << "," << nodeToParenthesis(*node->getSon(i), bootstrap, propertyName);
477 }
478 }
479 s << ")";
480 if (bootstrap)
481 {
483 s << (dynamic_cast<const Number<double>*>(node->getBranchProperty(TreeTools::BOOTSTRAP))->getValue());
484 }
485 else
486 {
487 if (node->hasBranchProperty(propertyName))
488 {
489 const BppString* ppt = dynamic_cast<const BppString*>(node->getBranchProperty(propertyName));
490 if (ppt)
491 s << *ppt;
492 else
493 throw Exception("TreeTemplateTools::nodeToParenthesis. Property should be a BppString.");
494 }
495 }
496 s << ";" << endl;
497 return s.str();
498}
499
500/******************************************************************************/
501
503{
504 Vdouble brLen(1);
505 brLen[0] = node.getDistanceToFather();
506 for (size_t i = 0; i < node.getNumberOfSons(); i++)
507 {
508 Vdouble sonBrLen = getBranchLengths(*node.getSon(i));
509 for (size_t j = 0; j < sonBrLen.size(); j++)
510 {
511 brLen.push_back(sonBrLen[j]);
512 }
513 }
514 return brLen;
515}
516
517/******************************************************************************/
518
519double TreeTemplateTools::getTotalLength(const Node& node, bool includeAncestor)
520{
521 if (includeAncestor && !node.hasDistanceToFather())
522 throw NodePException("TreeTools::getTotalLength(). No branch length.", &node);
523 double length = includeAncestor ? node.getDistanceToFather() : 0;
524 for (size_t i = 0; i < node.getNumberOfSons(); i++)
525 {
526 length += getTotalLength(*node.getSon(i), true);
527 }
528 return length;
529}
530
531/******************************************************************************/
532
534{
535 node.setDistanceToFather(brLen);
536 for (size_t i = 0; i < node.getNumberOfSons(); i++)
537 {
538 setBranchLengths(*node.getSon(i), brLen);
539 }
540}
541
542/******************************************************************************/
543
545{
547 for (size_t i = 0; i < node.getNumberOfSons(); i++)
548 {
549 deleteBranchLengths(*node.getSon(i));
550 }
551}
552
553/******************************************************************************/
554
556{
557 if (!node.hasDistanceToFather())
558 node.setDistanceToFather(brLen);
559 for (size_t i = 0; i < node.getNumberOfSons(); i++)
560 {
561 setVoidBranchLengths(*node.getSon(i), brLen);
562 }
563}
564
565/******************************************************************************/
566
567void TreeTemplateTools::scaleTree(Node& node, double factor)
568{
569 if (node.hasFather())
570 {
571 node.setDistanceToFather(node.getDistanceToFather() * factor);
572 }
573 for (size_t i = 0; i < node.getNumberOfSons(); i++)
574 {
575 scaleTree(*node.getSon(i), factor);
576 }
577}
578
579/******************************************************************************/
580
581unique_ptr<TreeTemplate<Node>> TreeTemplateTools::buildFromPhyloTree(const PhyloTree& treetemp)
582{
583 Node* root = new Node();
584 auto phroot = treetemp.getRoot();
585 root->addSubTree(treetemp, phroot);
586
587 auto tree = make_unique<TreeTemplate<Node>>(root);
588 return tree;
589}
590
591unique_ptr<TreeTemplate<Node>> TreeTemplateTools::getRandomTree(vector<string>& leavesNames, bool rooted)
592{
593 if (leavesNames.size() == 0)
594 return 0; // No taxa.
595 // This vector will contain all nodes.
596 // Start with all leaves, and then group nodes randomly 2 by 2.
597 // Att the end, contains only the root node of the tree.
598 vector<Node*> nodes(leavesNames.size());
599 // Create all leaves nodes:
600 for (size_t i = 0; i < leavesNames.size(); ++i)
601 {
602 nodes[i] = new Node(leavesNames[i]);
603 }
604 // Now group all nodes:
605 while (nodes.size() > (rooted ? 2 : 3))
606 {
607 // Select random nodes:
608 size_t pos1 = RandomTools::giveIntRandomNumberBetweenZeroAndEntry<size_t>(nodes.size());
609 Node* node1 = nodes[pos1];
610 nodes.erase(nodes.begin() + static_cast<ptrdiff_t>(pos1));
611 size_t pos2 = RandomTools::giveIntRandomNumberBetweenZeroAndEntry<size_t>(nodes.size());
612 Node* node2 = nodes[pos2];
613 nodes.erase(nodes.begin() + static_cast<ptrdiff_t>(pos2));
614 // Add new node:
615 Node* parent = new Node();
616 parent->addSon(node1);
617 parent->addSon(node2);
618 nodes.push_back(parent);
619 }
620 // Return tree with last node as root node:
621 Node* root = new Node();
622 for (size_t i = 0; i < nodes.size(); ++i)
623 {
624 root->addSon(nodes[i]);
625 }
626 auto tree = make_unique<TreeTemplate<Node>>(root);
627 tree->resetNodesId();
628 return tree;
629}
630
631/******************************************************************************/
632
633vector<Node*> TreeTemplateTools::getPathBetweenAnyTwoNodes(Node& node1, Node& node2, bool includeAncestor, bool includeAncestorAtEndOfPath)
634{
635 vector<Node*> path;
636 vector<Node*> pathMatrix1;
637 vector<Node*> pathMatrix2;
638
639 Node* nodeUp = &node1;
640 while (nodeUp->hasFather()) // while(nodeUp != root)
641 {
642 pathMatrix1.push_back(nodeUp);
643 nodeUp = nodeUp->getFather();
644 }
645 pathMatrix1.push_back(nodeUp); // The root.
646
647 nodeUp = &node2;
648 while (nodeUp->hasFather())
649 {
650 pathMatrix2.push_back(nodeUp);
651 nodeUp = nodeUp->getFather();
652 }
653 pathMatrix2.push_back(nodeUp); // The root.
654
655 size_t pos1 = pathMatrix1.size() - 1;
656 size_t pos2 = pathMatrix2.size() - 1;
657 // Must check that the two nodes have the same root!!!
658 if (pathMatrix1[pos1] != pathMatrix2[pos2])
659 throw Exception("TreeTemplateTools::getPathBetweenAnyTwoNodes(). The two nodes do not have any ancestor in common / do not belong to the same tree.");
660
661 if (pos1 == 0 && pos2 == 0)
662 {
663 // Node 1 and 2 are the root node!
664 path.push_back(pathMatrix1[0]);
665 }
666 else if (pos1 == 0)
667 {
668 // Node 1 is the root node
669 // Note: we need to use push_back here as the insert method does not work with reverse iterators.
670 for (size_t i = (includeAncestorAtEndOfPath ? pathMatrix2.size() : pathMatrix2.size() - 1); i > 0; --i)
671 {
672 path.push_back(pathMatrix2[i - 1]);
673 }
674 }
675 else if (pos2 == 0)
676 {
677 // Node 2 is the root node
678 path.insert(path.end(), pathMatrix1.begin(), (includeAncestorAtEndOfPath ? pathMatrix1.end() : --pathMatrix1.end()));
679 }
680 else
681 {
682 Node* commonAnc = 0;
683 while (pathMatrix1[pos1] == pathMatrix2[pos2] && pos1 > 0 && pos2 > 0)
684 {
685 commonAnc = pathMatrix1[pos1];
686 pos1--; pos2--;
687 }
688
689 path.insert(path.end(), pathMatrix1.begin(), pathMatrix1.begin() + static_cast<ptrdiff_t>(pos1 + 1));
690 if (includeAncestor && commonAnc)
691 path.push_back(commonAnc); // pushing once the Node that was common to both.
692 // If node1 or node2 is the common ancestor, then commonAnc is null
693 // and was added as node1 or node2, respectively, if includeAncestorAtEndOfPath was set to true.
694 // Note: we need to use push_back here as the insert method does not work with reverse iterators.
695 for (size_t i = pos2 + 1; i > 0; --i)
696 {
697 path.push_back(pathMatrix2[i - 1]);
698 }
699 }
700 return path;
701}
702
703/******************************************************************************/
704
705vector<const Node*> TreeTemplateTools::getPathBetweenAnyTwoNodes(const Node& node1, const Node& node2, bool includeAncestor, bool includeAncestorAtEndOfPath)
706{
707 vector<const Node*> path;
708 vector<const Node*> pathMatrix1;
709 vector<const Node*> pathMatrix2;
710
711 const Node* nodeUp = &node1;
712 while (nodeUp->hasFather()) // while(nodeUp != root)
713 {
714 pathMatrix1.push_back(nodeUp);
715 nodeUp = nodeUp->getFather();
716 }
717 pathMatrix1.push_back(nodeUp); // The root.
718
719 nodeUp = &node2;
720 while (nodeUp->hasFather())
721 {
722 pathMatrix2.push_back(nodeUp);
723 nodeUp = nodeUp->getFather();
724 }
725 pathMatrix2.push_back(nodeUp); // The root.
726
727 size_t pos1 = pathMatrix1.size() - 1;
728 size_t pos2 = pathMatrix2.size() - 1;
729 // Must check that the two nodes have the same root!!!
730 if (pathMatrix1[pos1] != pathMatrix2[pos2])
731 throw Exception("TreeTemplateTools::getPathBetweenAnyTwoNodes(). The two nodes do not have any ancestor in common / do not belong to the same tree.");
732
733 if (pos1 == 0 && pos2 == 0)
734 {
735 // Node 1 and 2 are the root node!
736 path.push_back(pathMatrix1[0]);
737 }
738 else if (pos1 == 0)
739 {
740 // Node 1 is the root node
741 // Note: we need to use push_back here as the insert method does not work with reverse iterators.
742 for (size_t i = (includeAncestorAtEndOfPath ? pathMatrix2.size() : pathMatrix2.size() - 1); i > 0; --i)
743 {
744 path.push_back(pathMatrix2[i - 1]);
745 }
746 }
747 else if (pos2 == 0)
748 {
749 // Node 2 is the root node
750 path.insert(path.end(), pathMatrix1.begin(), (includeAncestorAtEndOfPath ? pathMatrix1.end() : --pathMatrix1.end()));
751 }
752 else
753 {
754 const Node* commonAnc = 0;
755 while (pathMatrix1[pos1] == pathMatrix2[pos2] && pos1 > 0 && pos2 > 0)
756 {
757 commonAnc = pathMatrix1[pos1];
758 pos1--; pos2--;
759 }
760
761 path.insert(path.end(), pathMatrix1.begin(), pathMatrix1.begin() + static_cast<ptrdiff_t>(pos1 + 1));
762 if (commonAnc && includeAncestor)
763 path.push_back(commonAnc); // pushing once the Node that was common to both.
764 // If node1 or node2 is the common ancestor, then commonAnc is null
765 // and was added as node1 or node2, respectively, if includeAncestorAtEndOfPath was set to true.
766
767 // Note: we need to use push_back here as the insert method does not work with reverse iterators.
768 for (size_t i = pos2 + 1; i > 0; --i)
769 {
770 path.push_back(pathMatrix2[i - 1]);
771 }
772 }
773 return path;
774}
775
776/******************************************************************************/
777
779{
780 vector<const Node*> path = getPathBetweenAnyTwoNodes(node1, node2, false, false);
781 double d = 0;
782 for (size_t i = 0; i < path.size(); ++i)
783 {
784 d += path[i]->getDistanceToFather();
785 }
786 return d;
787}
788
789/******************************************************************************/
790
791void TreeTemplateTools::processDistsInSubtree_(const Node* node, DistanceMatrix& matrix, vector< std::pair<string, double>>& distsToNodeFather)
792{
793 distsToNodeFather.clear();
794
795 // node-is-leaf case
796 if (node->getNumberOfSons() == 0)
797 {
798 distsToNodeFather.push_back(make_pair(node->getName(), node->getDistanceToFather()));
799 return;
800 }
801
802 // For all leaves in node's subtree, get leaf-to-node distances.
803 // Leaves are classified upon node's sons.
804 map<const Node*, vector< pair<string, double>>> leavesDists;
805 for (size_t i = 0; i < node->getNumberOfSons(); ++i)
806 {
807 const Node* son = node->getSon(i);
808 processDistsInSubtree_(son, matrix, leavesDists[son]); // recursivity
809 }
810 // Write leaf-leaf distances to the distance matrix.
811 // Only pairs in which the two leaves belong to different
812 // sons are considered.
813 for (size_t son1_loc = 0; son1_loc < node->getNumberOfSons(); ++son1_loc)
814 {
815 for (size_t son2_loc = 0; son2_loc < son1_loc; ++son2_loc)
816 {
817 const Node* son1 = node->getSon(son1_loc);
818 const Node* son2 = node->getSon(son2_loc);
819
820 for (vector< pair<string, double>>::iterator son1_leaf = leavesDists[son1].begin();
821 son1_leaf != leavesDists[son1].end();
822 ++son1_leaf)
823 {
824 for (vector< pair<string, double>>::iterator son2_leaf = leavesDists[son2].begin();
825 son2_leaf != leavesDists[son2].end();
826 ++son2_leaf)
827 {
828 matrix(son1_leaf->first, son2_leaf->first) =
829 matrix(son2_leaf->first, son1_leaf->first) =
830 ( son1_leaf->second + son2_leaf->second );
831 }
832 }
833 }
834 }
835
836 // node-is-root case
837 if (!node->hasFather())
838 {
839 // node-is-root-and-leaf case
840 if (node->hasNoSon() )
841 {
842 string root_name = node->getName();
843 for (vector< pair<string, double>>::iterator other_leaf = leavesDists[node->getSon(0)].begin();
844 other_leaf != leavesDists[node->getSon(0)].end();
845 ++other_leaf)
846 {
847 matrix(root_name, other_leaf->first) = matrix( other_leaf->first, root_name) = other_leaf->second;
848 }
849 }
850
851 return;
852 }
853
854 // Get distances from node's father to considered leaves
855 distsToNodeFather.clear();
856 double nodeToFather = node->getDistanceToFather();
857 for (map<const Node*, vector<pair<string, double>>>::iterator son = leavesDists.begin(); son != leavesDists.end(); ++son)
858 {
859 for (vector< pair<string, double>>::iterator leaf = (son->second).begin(); leaf != (son->second).end(); ++leaf)
860 {
861 distsToNodeFather.push_back(make_pair(leaf->first, (leaf->second + nodeToFather)));
862 }
863 }
864}
865
866unique_ptr<DistanceMatrix> TreeTemplateTools::getDistanceMatrix(const TreeTemplate<Node>& tree)
867{
868 auto matrix = make_unique<DistanceMatrix>(tree.getLeavesNames());
869 vector< pair<string, double>> distsToRoot;
870 processDistsInSubtree_(tree.getRootNode(), *matrix, distsToRoot);
871 return matrix;
872}
873
874/******************************************************************************/
875
876std::vector<const Node*> TreeTemplateTools::getRemainingNeighbors(const Node* node1, const Node* node2, const Node* node3)
877{
878 vector<const Node*> neighbors = node1->getNeighbors();
879 vector<const Node*> neighbors2;
880 for (size_t k = 0; k < neighbors.size(); k++)
881 {
882 const Node* n = neighbors[k];
883 if (n != node2 && n != node3)
884 neighbors2.push_back(n);
885 }
886 return neighbors2;
887}
888
889/******************************************************************************/
890
891void TreeTemplateTools::incrementAllIds(Node* node, int increment)
892{
893 node->setId(node->getId() + increment);
894 for (size_t i = 0; i < node->getNumberOfSons(); i++)
895 {
896 incrementAllIds(node->getSon(i), increment);
897 }
898}
899
900/******************************************************************************/
901
902void TreeTemplateTools::getNodePropertyNames(const Node& node, vector<string>& propertyNames)
903{
904 VectorTools::extend(propertyNames, node.getNodePropertyNames());
905 for (size_t i = 0; i < node.getNumberOfSons(); i++)
906 {
907 getNodePropertyNames(*node.getSon(i), propertyNames);
908 }
909}
910
911void TreeTemplateTools::getNodeProperties(const Node& node, const string& propertyName, map<int, const Clonable*>& properties)
912{
913 if (node.hasNodeProperty(propertyName))
914 properties[node.getId()] = node.getNodeProperty(propertyName);
915 for (size_t i = 0; i < node.getNumberOfSons(); i++)
916 {
917 getNodeProperties(*node.getSon(i), propertyName, properties);
918 }
919}
920
921void TreeTemplateTools::getNodeProperties(Node& node, const string& propertyName, map<int, Clonable*>& properties)
922{
923 if (node.hasNodeProperty(propertyName))
924 properties[node.getId()] = node.getNodeProperty(propertyName);
925 for (size_t i = 0; i < node.getNumberOfSons(); i++)
926 {
927 getNodeProperties(*node.getSon(i), propertyName, properties);
928 }
929}
930
931void TreeTemplateTools::deleteNodeProperties(Node& node, const std::vector<std::string>& propertyNames)
932{
933 for (auto property: propertyNames)
934 {
935 try
936 {
937 node.deleteNodeProperty(property);
938 }
939 catch (exception& e)
940 {}
941 }
942 for (size_t i = 0; i < node.getNumberOfSons(); i++)
943 {
944 deleteNodeProperties(*node.getSon(i), propertyNames);
945 }
946}
947
948/******************************************************************************/
949
950void TreeTemplateTools::getBranchPropertyNames(const Node& node, vector<string>& propertyNames)
951{
952 VectorTools::extend(propertyNames, node.getBranchPropertyNames());
953 for (size_t i = 0; i < node.getNumberOfSons(); i++)
954 {
955 getBranchPropertyNames(*node.getSon(i), propertyNames);
956 }
957}
958
959void TreeTemplateTools::getBranchProperties(const Node& node, const string& propertyName, map<int, const Clonable*>& properties)
960{
961 if (node.hasBranchProperty(propertyName))
962 properties[node.getId()] = node.getBranchProperty(propertyName);
963 for (size_t i = 0; i < node.getNumberOfSons(); i++)
964 {
965 getBranchProperties(*node.getSon(i), propertyName, properties);
966 }
967}
968
969void TreeTemplateTools::getBranchProperties(Node& node, const string& propertyName, map<int, Clonable*>& properties)
970{
971 if (node.hasBranchProperty(propertyName))
972 properties[node.getId()] = node.getBranchProperty(propertyName);
973 for (size_t i = 0; i < node.getNumberOfSons(); i++)
974 {
975 getBranchProperties(*node.getSon(i), propertyName, properties);
976 }
977}
978
979void TreeTemplateTools::deleteBranchProperties(Node& node, const std::vector<std::string>& propertyNames)
980{
981 for (auto property: propertyNames)
982 {
983 try
984 {
985 node.deleteBranchProperty(property);
986 }
987 catch (exception& e)
988 {}
989 }
990 for (size_t i = 0; i < node.getNumberOfSons(); i++)
991 {
992 deleteBranchProperties(*node.getSon(i), propertyNames);
993 }
994}
995
996/******************************************************************************/
997
999{
1000 if (n1.hasNoSon() && n2.hasNoSon() && n1.getName() != n2.getName())
1001 return false;
1002 size_t nl1 = n1.getNumberOfSons();
1003 size_t nl2 = n2.getNumberOfSons();
1004 if (nl1 != nl2)
1005 return false;
1006
1007 bool test = true;
1008 for (size_t i = 0; test && i < n1.getNumberOfSons(); ++i)
1009 {
1010 test &= haveSameOrderedTopology(*n1.getSon(i), *n2.getSon(i));
1011 }
1012 return test;
1013}
1014
1015/******************************************************************************/
1016
1018{
1019 OrderTreeData_ otd;
1020
1021 if (node.hasNoSon() && node.hasFather())
1022 {
1023 otd.size = 1;
1024 otd.firstLeaf = node.getName();
1025 }
1026 else
1027 {
1028 vector<size_t> nbSons;
1029 vector<string> firstLeaves;
1030 for (size_t i = 0; i < node.getNumberOfSons(); i++)
1031 {
1032 OrderTreeData_ otdsub = orderTree_(*node.getSon(i), downward, orderLeaves);
1033 if (i == 0)
1034 otd.firstLeaf = otdsub.firstLeaf;
1035 else if (orderLeaves && otdsub.firstLeaf < otd.firstLeaf)
1036 otd.firstLeaf = otdsub.firstLeaf;
1037 nbSons.push_back(otdsub.size);
1038 firstLeaves.push_back(otdsub.firstLeaf);
1039 }
1040 otd.size = VectorTools::sum(nbSons);
1041
1042 // Now swap nodes:
1043 if (downward)
1044 {
1045 for (size_t i = 0; i < nbSons.size() - 1; ++i)
1046 {
1047 size_t pos;
1048 vector<size_t> index = VectorTools::whichMaxAll(nbSons);
1049 if (index.size() == 1 || !orderLeaves)
1050 {
1051 pos = index[0];
1052 }
1053 else
1054 {
1055 // There are ties to solve:
1056 vector<string> v;
1057 for (size_t j = 0; j < index.size(); ++j)
1058 {
1059 v.push_back(firstLeaves[index[j]]);
1060 }
1061 size_t mx = VectorTools::whichMax(v);
1062 pos = index[mx];
1063 }
1064 if (pos != i)
1065 {
1066 node.swap(i, pos);
1067 nbSons[pos] = nbSons[i];
1068 }
1069 nbSons[i] = 0;
1070 }
1071 }
1072 else
1073 {
1074 for (size_t i = 0; i < nbSons.size() - 1; ++i)
1075 {
1076 size_t pos;
1077 vector<size_t> index = VectorTools::whichMinAll(nbSons);
1078 if (index.size() == 1 || !orderLeaves)
1079 {
1080 pos = index[0];
1081 }
1082 else
1083 {
1084 // There are ties to solve:
1085 vector<string> v;
1086 for (size_t j = 0; j < index.size(); ++j)
1087 {
1088 v.push_back(firstLeaves[index[j]]);
1089 }
1090 size_t mx = VectorTools::whichMin(v);
1091 pos = index[mx];
1092 }
1093 if (pos != i)
1094 {
1095 node.swap(i, pos);
1096 nbSons[pos] = nbSons[i];
1097 }
1098 nbSons[i] = otd.size + 1;
1099 }
1100 }
1101 }
1102 return otd;
1103}
1104
1105/******************************************************************************/
1108
1109void TreeTemplateTools::midRoot(TreeTemplate<Node>& tree, short criterion, bool forceBranchRoot)
1110{
1111 if (criterion != MIDROOT_VARIANCE && criterion != MIDROOT_SUM_OF_SQUARES)
1112 throw Exception("TreeTemplateTools::midRoot(). Illegal criterion value '" + TextTools::toString(criterion) + "'");
1113
1114 if (tree.isRooted())
1115 tree.unroot();
1116 Node* ref_root = tree.getRootNode();
1117 //
1118 // The bestRoot object records :
1119 // -- the current best branch : .first
1120 // -- the current best value of the criterion : .second["value"]
1121 // -- the best position of the root on the branch : .second["position"]
1122 // 0 is toward the original root, 1 is away from it
1123 //
1124 pair<Node*, map<string, double>> best_root_branch;
1125 best_root_branch.first = ref_root; // nota: the root does not correspond to a branch as it has no father
1126 best_root_branch.second ["position"] = -1;
1127 best_root_branch.second ["score"] = numeric_limits<double>::max();
1128
1129 // find the best root
1130 getBestRootInSubtree_(tree, criterion, ref_root, best_root_branch);
1131 tree.rootAt(ref_root); // back to the original root
1132
1133 // reroot
1134 const double pos = best_root_branch.second["position"];
1135 if (pos < 1e-6 or pos > 1 - 1e-6)
1136 // The best root position is on a node (this is often the case with the sum of squares criterion)
1137 tree.rootAt(pos < 1e-6 ? best_root_branch.first->getFather() : best_root_branch.first);
1138 else
1139 // The best root position is somewhere on a branch (a new Node is created)
1140 {
1141 Node* new_root = new Node();
1142 new_root->setId( TreeTools::getMPNUId(tree, tree.getRootId()) );
1143
1144 double root_branch_length = best_root_branch.first->getDistanceToFather();
1145 Node* best_root_father = best_root_branch.first->getFather();
1146
1147 best_root_father->removeSon(best_root_branch.first);
1148 best_root_father->addSon(new_root);
1149 new_root->addSon(best_root_branch.first);
1150
1151 new_root->setDistanceToFather(max(pos * root_branch_length, 1e-6));
1152 best_root_branch.first->setDistanceToFather(max((1 - pos) * root_branch_length, 1e-6));
1153
1154 // The two branches leaving the root must have the same branch properties
1155 const vector<string> branch_properties = best_root_branch.first->getBranchPropertyNames();
1156 for (vector<string>::const_iterator p = branch_properties.begin(); p != branch_properties.end(); ++p)
1157 {
1158 new_root->setBranchProperty(*p, *best_root_branch.first->getBranchProperty(*p));
1159 }
1160
1161 tree.rootAt(new_root);
1162 }
1163
1164 if (forceBranchRoot) // if we want the root to be on a branch, not on a node
1165 {
1166 Node* orig_root = tree.getRootNode();
1167 vector<Node*> root_sons = orig_root->getSons();
1168 if (root_sons.size() > 2)
1169 {
1170 Node* nearest = root_sons.at(0);
1171 for (vector<Node*>::iterator n = root_sons.begin(); n !=
1172 root_sons.end(); ++n)
1173 {
1174 if ((**n).getDistanceToFather() < nearest->getDistanceToFather())
1175 nearest = *n;
1176 }
1177 const double d = nearest->getDistanceToFather();
1178 Node* new_root = new Node();
1179 new_root->setId( TreeTools::getMPNUId(tree, tree.getRootId()) );
1180 orig_root->removeSon(nearest);
1181 orig_root->addSon(new_root);
1182 new_root->addSon(nearest);
1183 new_root->setDistanceToFather(d / 2.);
1184 nearest->setDistanceToFather(d / 2.);
1185 const vector<string> branch_properties = nearest->getBranchPropertyNames();
1186 for (vector<string>::const_iterator p = branch_properties.begin(); p != branch_properties.end(); ++p)
1187 {
1188 new_root->setBranchProperty(*p, *nearest->getBranchProperty(*p));
1189 }
1190 tree.rootAt(new_root);
1191 }
1192 }
1193}
1194
1195/******************************************************************************/
1196
1198{
1200 Moments_ moments = getSubtreeMoments_(tree.getRootNode());
1201 double radius = moments.sum / moments.numberOfLeaves;
1202 return radius;
1203}
1204
1205/******************************************************************************/
1206
1207void TreeTemplateTools::unresolveUncertainNodes(Node& subtree, double threshold, const std::string& property)
1208{
1209 for (size_t i = 0; i < subtree.getNumberOfSons(); ++i)
1210 {
1211 Node* son = subtree.getSon(i);
1212 if (son->getNumberOfSons() > 0)
1213 {
1214 // Recursion:
1215 unresolveUncertainNodes(*son, threshold, property);
1216 // Deal with this node:
1217 if (son->hasBranchProperty(property))
1218 {
1219 double value = dynamic_cast<Number<double>*>(son->getBranchProperty(property))->getValue();
1220 if (value < threshold)
1221 {
1222 // We remove this branch:
1223 double brlen = son->getDistanceToFather();
1224 for (size_t j = 0; j < son->getNumberOfSons(); ++j)
1225 {
1226 Node* grandSon = son->getSon(j);
1227 grandSon->setDistanceToFather(grandSon->getDistanceToFather() + brlen);
1228 subtree.addSon(i, grandSon);
1229 }
1230 subtree.removeSon(son);
1231 delete son;
1232 }
1233 }
1234 }
1235 }
1236}
1237
1238void TreeTemplateTools::getBestRootInSubtree_(TreeTemplate<Node>& tree, short criterion, Node* node, pair<Node*, map<string, double>>& bestRoot)
1239{
1240 const vector<Node*> sons = node->getSons(); // copy
1241 tree.rootAt(node);
1242
1243 // Try to place the root on each branch downward node
1244 for (vector<Node*>::const_iterator son = sons.begin(); son != sons.end(); ++son)
1245 {
1246 // Compute the moment of the subtree on son's side
1247 Moments_ son_moment = getSubtreeMoments_(*son);
1248
1249 // Compute the moment of the subtree on node's side
1250 tree.rootAt(*son);
1251 Moments_ node_moment = getSubtreeMoments_(node);
1252 tree.rootAt(node);
1253
1254 /*
1255 * Get the position of the root on this branch that
1256 * minimizes the root-to-leaves distances variance.
1257 *
1258 * This variance can be written in the form A x^2 + B x + C
1259 */
1260 double min_criterion_value;
1261 double best_position; // 0 is toward the root, 1 is away from it
1262
1263 const TreeTemplateTools::Moments_& m1 = node_moment;
1264 const TreeTemplateTools::Moments_& m2 = son_moment;
1265 const double d = (**son).getDistanceToFather();
1266 const double n1 = m1.numberOfLeaves;
1267 const double n2 = m2.numberOfLeaves;
1268
1269 double A = 0, B = 0, C = 0;
1270 if (criterion == MIDROOT_SUM_OF_SQUARES)
1271 {
1272 A = (n1 + n2) * d * d;
1273 B = 2 * d * (m1.sum - m2.sum) - 2 * n2 * d * d;
1274 C = m1.squaresSum + m2.squaresSum
1275 + 2 * m2.sum * d
1276 + n2 * d * d;
1277 }
1278 else if (criterion == MIDROOT_VARIANCE)
1279 {
1280 A = 4 * n1 * n2 * d * d;
1281 B = 4 * d * ( n2 * m1.sum - n1 * m2.sum - d * n1 * n2);
1282 C = (n1 + n2) * (m1.squaresSum + m2.squaresSum) + n1 * d * n2 * d
1283 + 2 * n1 * d * m2.sum - 2 * n2 * d * m1.sum
1284 - (m1.sum + m2.sum) * (m1.sum + m2.sum);
1285 }
1286
1287 if (A < 1e-20)
1288 {
1289 min_criterion_value = numeric_limits<double>::max();
1290 best_position = 0.5;
1291 }
1292 else
1293 {
1294 min_criterion_value = C - B * B / (4 * A);
1295 best_position = -B / (2 * A);
1296 if (best_position < 0)
1297 {
1298 best_position = 0;
1299 min_criterion_value = C;
1300 }
1301 else if (best_position > 1)
1302 {
1303 best_position = 1;
1304 min_criterion_value = A + B + C;
1305 }
1306 }
1307
1308 // Is this branch is the best seen, update 'bestRoot'
1309 if (min_criterion_value < bestRoot.second["score"])
1310 {
1311 bestRoot.first = *son;
1312 bestRoot.second["position"] = best_position;
1313 bestRoot.second["score"] = min_criterion_value;
1314 }
1315
1316 // Recurse
1317 TreeTemplateTools::getBestRootInSubtree_(tree, criterion, *son, bestRoot);
1318 }
1319}
1320
1321/******************************************************************************/
1322
1324{
1325 TreeTemplateTools::Moments_ moments = {0, 0, 0};
1326
1327 if (node->isLeaf())
1328 {
1329 moments.numberOfLeaves = 1;
1330 }
1331 else
1332 {
1333 const size_t nsons = node->getNumberOfSons();
1334 for (size_t i = 0; i < nsons; ++i)
1335 {
1336 const Node* son = node->getSon(i);
1338 const double d = son->getDistanceToFather();
1339 moments.numberOfLeaves += son_moments.numberOfLeaves;
1340 moments.sum += son_moments.sum + d * son_moments.numberOfLeaves;
1341 moments.squaresSum += son_moments.squaresSum + 2 * d * son_moments.sum + son_moments.numberOfLeaves * d * d;
1342 }
1343 }
1344
1345 return moments;
1346}
1347
1348/******************************************************************************/
static std::shared_ptr< OutputStream > message
static void displayUnlimitedGauge(size_t iter, const std::string &mes="")
virtual std::shared_ptr< N > getRoot() const=0
const std::string & nextToken()
General exception thrown when something is wrong with a particular node.
The phylogenetic node class.
Definition: Node.h:59
virtual std::string getName() const
Get the name associated to this node, if there is one, otherwise throw a NodeException.
Definition: Node.h:203
virtual void setDistanceToFather(double distance)
Set or update the distance toward the father node.
Definition: Node.h:266
virtual void deleteDistanceToFather()
Delete the distance to the father node.
Definition: Node.h:276
virtual Node * removeSon(size_t pos)
Definition: Node.h:423
virtual int getId() const
Get the node's id.
Definition: Node.h:170
virtual bool hasBranchProperty(const std::string &name) const
Definition: Node.h:665
virtual void setId(int id)
Set this node's id.
Definition: Node.h:177
virtual Clonable * getNodeProperty(const std::string &name)
Definition: Node.h:514
virtual Clonable * getBranchProperty(const std::string &name)
Definition: Node.h:604
virtual void addSon(size_t pos, Node *node)
Definition: Node.h:386
virtual std::vector< std::string > getNodePropertyNames() const
Definition: Node.h:577
virtual void setBranchProperty(const std::string &name, const Clonable &property)
Set/add a branch property.
Definition: Node.h:597
virtual bool hasDistanceToFather() const
Tell is this node has a distance to the father.
Definition: Node.h:288
virtual bool hasNoSon() const
Definition: Node.h:681
virtual const Node * getFather() const
Get the father of this node is there is one.
Definition: Node.h:306
virtual const Node * getSon(size_t pos) const
Definition: Node.h:362
virtual bool isLeaf() const
Definition: Node.h:679
virtual std::vector< Node * > & getSons()
Definition: Node.h:357
virtual void deleteNodeProperty(const std::string &name)
Definition: Node.h:542
void addSubTree(const PhyloTree &tree, std::shared_ptr< PhyloNode > phyloNode)
Definition: Node.cpp:72
std::vector< const Node * > getNeighbors() const
Definition: Node.cpp:129
virtual void swap(size_t branch1, size_t branch2)
Definition: Node.cpp:113
virtual void deleteBranchProperty(const std::string &name)
Definition: Node.h:632
virtual bool hasFather() const
Tell if this node has a father node.
Definition: Node.h:346
virtual void setName(const std::string &name)
Give a name or update the name associated to the node.
Definition: Node.h:214
virtual bool hasNodeProperty(const std::string &name) const
Definition: Node.h:575
virtual double getDistanceToFather() const
Get the distance to the father node is there is one, otherwise throw a NodeException.
Definition: Node.h:250
virtual size_t getNumberOfSons() const
Definition: Node.h:355
virtual std::vector< std::string > getBranchPropertyNames() const
Definition: Node.h:667
size_t numberOfRemainingTokens() const
const std::string & getToken(size_t pos) const
static double getDistanceBetweenAnyTwoNodes(const Node &node1, const Node &node2)
Get the total distance between to nodes.
static void setBranchLengths(Node &node, double brLen)
Set all the branch lengths of a subtree.
static void midRoot(TreeTemplate< Node > &tree, short criterion, bool forceBranchRoot)
Midroot the tree by minimizing a given criterion ("variance" or "sum of squares")
static void getNodeProperties(const Node &node, const std::string &propertyName, std::map< int, const Clonable * > &properties)
Retrieve all node property objects with a given name over a (sub) tree (const version).
static void searchLeaf(const Node &node, const std::string &name, int *&id)
Get the id of a leaf given its name in a subtree.
static void incrementAllIds(Node *node, int increment)
This method will add a given value (possibly negative) to all identifiers in a (sub)tree.
static std::unique_ptr< TreeTemplate< Node > > getRandomTree(std::vector< std::string > &leavesNames, bool rooted=true)
Draw a random tree from a list of taxa, using a Yule process.
static void unresolveUncertainNodes(Node &subtree, double threshold, const std::string &property=TreeTools::BOOTSTRAP)
Unresolve nodes with low confidence value.
static void getBestRootInSubtree_(bpp::TreeTemplate< bpp::Node > &tree, short criterion, bpp::Node *node, std::pair< bpp::Node *, std::map< std::string, double > > &bestRoot)
Find, in the branches of a subtree, the root that minimizes a criterion over the tree.
static std::vector< std::string > getLeavesNames(const Node &node)
Get the leaves names of a subtree defined by a particular node.
static std::unique_ptr< TreeTemplate< Node > > buildFromPhyloTree(const PhyloTree &treetemp)
static std::vector< int > getLeavesId(const Node &node)
Retrieve all leaves ids from a subtree.
static void getBranchProperties(const Node &node, const std::string &propertyName, std::map< int, const Clonable * > &properties)
Retrieve all branch property objects with a given name over a (sub) tree (const version).
static unsigned int getDepth(const Node &node)
Get the depth of the subtree defined by node 'node', i.e. the maximum number of sons 'generations'.
static std::unique_ptr< TreeTemplate< Node > > parenthesisToTree(const std::string &description, bool bootstrap=true, const std::string &propertyName=TreeTools::BOOTSTRAP, bool withId=false, bool verbose=true)
Parse a string in the parenthesis format and convert it to a tree.
static double getHeight(const Node &node)
Get the height of the subtree defined by node 'node', i.e. the maximum distance between leaves and th...
static Vdouble getBranchLengths(const Node &node)
Get all the branch lengths of a subtree.
static size_t getNumberOfLeaves(const Node &node)
Get the number of leaves of a subtree defined by a particular node.
static unsigned int getDepths(const Node &node, std::map< const Node *, unsigned int > &depths)
Get the depths for all nodes of the subtree defined by node 'node', i.e. the maximum number of sons '...
static void scaleTree(Node &node, double factor)
Scale a given tree.
static std::vector< Node * > getPathBetweenAnyTwoNodes(Node &node1, Node &node2, bool includeAncestor=true, bool includeAncestorAtEndOfPath=true)
static std::vector< const Node * > getRemainingNeighbors(const Node *node1, const Node *node2, const Node *node3)
Get a subset of node neighbors.
static Element getElement(const std::string &elt)
static const short MIDROOT_VARIANCE
static void deleteBranchLengths(Node &node)
Remove all the branch lengths of a subtree.
static std::unique_ptr< DistanceMatrix > getDistanceMatrix(const TreeTemplate< Node > &tree)
Compute a distance matrix from a tree.
static double getHeights(const Node &node, std::map< const Node *, double > &heights)
Get the heights of all nodes within a subtree defined by node 'node', i.e. the maximum distance betwe...
static const short MIDROOT_SUM_OF_SQUARES
static void setVoidBranchLengths(Node &node, double brLen)
Give a length to branches that don't have one in a subtree.
static std::string treeToParenthesis(const TreeTemplate< Node > &tree, bool writeId=false)
Get the parenthesis description of a tree.
static double getTotalLength(const Node &node, bool includeAncestor=true)
Get the total length (sum of all branch lengths) of a subtree.
static std::string nodeToParenthesis(const Node &node, bool writeId=false)
Get the parenthesis description of a subtree.
static OrderTreeData_ orderTree_(Node &node, bool downward, bool orderLeaves)
static std::vector< int > getAncestorsId(const Node &node)
Retrieve all nodes ids that are ancestors of a node.
static void getBranchPropertyNames(const Node &node, std::vector< std::string > &propertyNames)
Retrieve the names of all available branch properties in the tree.
static void deleteNodeProperties(Node &node, const std::vector< std::string > &propertyNames)
Delete the given properties in the tree.
static void processDistsInSubtree_(const Node *node, DistanceMatrix &matrix, std::vector< std::pair< std::string, double > > &distsToNodeFather)
Inner function used by getDistanceMatrix.
static Node * parenthesisToNode(const std::string &description, unsigned int &nodeCounter, bool bootstrap=true, const std::string &propertyName=TreeTools::BOOTSTRAP, bool withId=false, bool verbose=true)
Parse a string in the parenthesis format and convert it to a subtree.
static bool isMultifurcating(const Node &node)
Tell is a subtree is multifurcating.
static bool haveSameOrderedTopology(const Node &n1, const Node &n2)
Tells if two subtrees have the same topology.
static double getRadius(TreeTemplate< Node > &tree)
Get the characteristic radius of a tree (average distance to the root minimizing the sum of squared d...
static void getNodePropertyNames(const Node &node, std::vector< std::string > &propertyNames)
Retrieve the names of all available node properties in the tree.
static Moments_ getSubtreeMoments_(const Node *node)
Computes the moment of a subtree.
static void deleteBranchProperties(Node &node, const std::vector< std::string > &propertyNames)
Delete the given properties in the tree.
The phylogenetic tree class.
Definition: TreeTemplate.h:59
bool unroot()
Unroot a rooted tree.
Definition: TreeTemplate.h:226
bool isRooted() const
Tell if the tree is rooted.
Definition: TreeTemplate.h:224
int getRootId() const
Definition: TreeTemplate.h:127
void rootAt(int nodeId)
Change the root node.
Definition: TreeTemplate.h:220
virtual N * getRootNode()
Definition: TreeTemplate.h:389
std::vector< std::string > getLeavesNames() const
Definition: TreeTemplate.h:162
static const std::string BOOTSTRAP
Bootstrap tag.
Definition: TreeTools.h:684
static int getMPNUId(const Tree &tree, int id)
Get the minimum positive non-used identifier in a (sub)tree.
Definition: TreeTools.cpp:730
static std::vector< size_t > whichMinAll(const std::vector< T > &v)
static T sum(const std::vector< T > &v1)
static std::vector< size_t > whichMaxAll(const std::vector< T > &v)
static void extend(std::vector< T > &vec1, const std::vector< T > &vec2)
static size_t whichMin(const std::vector< T > &v)
static size_t whichMax(const std::vector< T > &v)
int toInt(const std::string &s, char scientificNotation='e')
double toDouble(const std::string &s, char dec='.', char scientificNotation='e')
std::string removeSurroundingWhiteSpaces(const std::string &s)
bool isEmpty(const std::string &s)
std::string toString(T t)
Defines the basic types of data flow nodes.
std::vector< double > Vdouble
A structure recording, for a subtree, the sum of root-leaf distances, the sum of their squares,...