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