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>
6 #include <Bpp/Numeric/Number.h>
10 #include <Bpp/Text/TextTools.h>
11 
12 #include "TreeTemplate.h"
13 #include "TreeTemplateTools.h"
14 #include "PhyloTree.h"
15 
16 using namespace bpp;
17 
18 // From the STL:
19 #include <iostream>
20 #include <sstream>
21 #include <limits>
22 
23 using namespace std;
24 
25 /******************************************************************************/
26 
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 
60 vector<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 
78 void 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 
90 std::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 
102 void 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 
121 unsigned 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 
135 unsigned 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 
166 double 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 {
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 
247 Node* 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  }
259  if (!TextTools::isEmpty(elt.bootstrap))
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 
328 unique_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 
352 string 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 
387 string 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 
458 string 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 
519 double 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 
533 void TreeTemplateTools::setBranchLengths(Node& node, double brLen)
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 {
546  node.deleteDistanceToFather();
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 
567 void 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 
581 unique_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 
591 unique_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 
633 vector<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 
705 vector<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 
791 void 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 
866 unique_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 
876 std::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 
891 void 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 
902 void 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 
911 void 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 
921 void 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 
931 void 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 
950 void 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 
959 void 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 
969 void 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 
979 void 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 /******************************************************************************/
1106 const short TreeTemplateTools::MIDROOT_VARIANCE = 0;
1108 
1109 void 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 {
1199  TreeTemplateTools::midRoot(tree, MIDROOT_SUM_OF_SQUARES, false);
1200  Moments_ moments = getSubtreeMoments_(tree.getRootNode());
1201  double radius = moments.sum / moments.numberOfLeaves;
1202  return radius;
1203 }
1204 
1205 /******************************************************************************/
1206 
1207 void 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 
1238 void 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 /******************************************************************************/
return element
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 Clonable * getNodeProperty(const std::string &name)
Definition: Node.h:502
virtual void setDistanceToFather(double distance)
Set or update the distance toward the father node.
Definition: Node.h:266
virtual Node * removeSon(size_t pos)
Definition: Node.h:411
virtual void deleteDistanceToFather()
Delete the distance to the father node.
Definition: Node.h:276
virtual int getId() const
Get the node's id.
Definition: Node.h:170
virtual bool hasBranchProperty(const std::string &name) const
Definition: Node.h:653
virtual void setId(int id)
Set this node's id.
Definition: Node.h:177
virtual void addSon(size_t pos, Node *node)
Definition: Node.h:374
virtual std::vector< Node * > & getSons()
Definition: Node.h:357
virtual const Node * getSon(size_t pos) const
Definition: Node.h:362
virtual void setBranchProperty(const std::string &name, const Clonable &property)
Set/add a branch property.
Definition: Node.h:585
virtual const Node * getFather() const
Get the father of this node is there is one.
Definition: Node.h:306
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:669
virtual bool isLeaf() const
Definition: Node.h:667
virtual void deleteNodeProperty(const std::string &name)
Definition: Node.h:530
void addSubTree(const PhyloTree &tree, std::shared_ptr< PhyloNode > phyloNode)
Definition: Node.cpp:72
std::vector< const Node * > getNeighbors() const
Definition: Node.cpp:127
virtual Clonable * getBranchProperty(const std::string &name)
Definition: Node.h:592
virtual void swap(size_t branch1, size_t branch2)
Definition: Node.cpp:111
virtual void deleteBranchProperty(const std::string &name)
Definition: Node.h:620
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 std::vector< std::string > getBranchPropertyNames() const
Definition: Node.h:655
virtual std::vector< std::string > getNodePropertyNames() const
Definition: Node.h:565
virtual bool hasNodeProperty(const std::string &name) const
Definition: Node.h:563
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
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 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 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 void processDistsInSubtree_(const Node *node, DistanceMatrix &matrix, std::vector< std::pair< std::string, double >> &distsToNodeFather)
Inner function used by getDistanceMatrix.
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 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 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 std::vector< int > getLeavesId(const Node &node)
Retrieve all leaves ids from a subtree.
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
std::vector< std::string > getLeavesNames() const
Definition: TreeTemplate.h:162
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
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:731
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,...