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