1
/*****************************************************************
2
* Unipro UGENE - Integrated Bioinformatics Suite
3
* Copyright (C) 2008 Unipro, Russia (http://ugene.unipro.ru)
6
* This source code is distributed under the terms of the
7
* GNU General Public License. See the files COPYING and LICENSE
9
*****************************************************************/
16
// Return false when done
17
bool PhyEnumEdges(const Tree &tree, PhyEnumEdgeState &ES)
19
unsigned uNode1 = uInsane;
23
if (tree.GetNodeCount() <= 1)
25
ES.m_uNodeIndex1 = NULL_NEIGHBOR;
26
ES.m_uNodeIndex2 = NULL_NEIGHBOR;
29
uNode1 = tree.FirstDepthFirstNode();
34
uNode1 = tree.NextDepthFirstNode(ES.m_uNodeIndex1);
35
if (NULL_NEIGHBOR == uNode1)
37
if (tree.IsRooted() && tree.IsRoot(uNode1))
39
uNode1 = tree.NextDepthFirstNode(uNode1);
40
if (NULL_NEIGHBOR == uNode1)
44
unsigned uNode2 = tree.GetParent(uNode1);
46
ES.m_uNodeIndex1 = uNode1;
47
ES.m_uNodeIndex2 = uNode2;
51
bool PhyEnumEdgesR(const Tree &tree, PhyEnumEdgeState &ES)
53
unsigned uNode1 = uInsane;
57
if (tree.GetNodeCount() <= 1)
59
ES.m_uNodeIndex1 = NULL_NEIGHBOR;
60
ES.m_uNodeIndex2 = NULL_NEIGHBOR;
63
uNode1 = tree.FirstDepthFirstNodeR();
68
uNode1 = tree.NextDepthFirstNodeR(ES.m_uNodeIndex1);
69
if (NULL_NEIGHBOR == uNode1)
71
if (tree.IsRooted() && tree.IsRoot(uNode1))
73
uNode1 = tree.NextDepthFirstNode(uNode1);
74
if (NULL_NEIGHBOR == uNode1)
78
unsigned uNode2 = tree.GetParent(uNode1);
80
ES.m_uNodeIndex1 = uNode1;
81
ES.m_uNodeIndex2 = uNode2;
85
static void GetLeavesSubtree(const Tree &tree, unsigned uNodeIndex1,
86
const unsigned uNodeIndex2, unsigned Leaves[], unsigned *ptruCount)
88
if (tree.IsLeaf(uNodeIndex1))
90
Leaves[*ptruCount] = uNodeIndex1;
95
const unsigned uLeft = tree.GetFirstNeighbor(uNodeIndex1, uNodeIndex2);
96
const unsigned uRight = tree.GetSecondNeighbor(uNodeIndex1, uNodeIndex2);
97
if (NULL_NEIGHBOR != uLeft)
98
GetLeavesSubtree(tree, uLeft, uNodeIndex1, Leaves, ptruCount);
99
if (NULL_NEIGHBOR != uRight)
100
GetLeavesSubtree(tree, uRight, uNodeIndex1, Leaves, ptruCount);
103
static void PhyGetLeaves(const Tree &tree, unsigned uNodeIndex1, unsigned uNodeIndex2,
104
unsigned Leaves[], unsigned *ptruCount)
107
GetLeavesSubtree(tree, uNodeIndex1, uNodeIndex2, Leaves, ptruCount);
110
bool PhyEnumBiParts(const Tree &tree, PhyEnumEdgeState &ES,
111
unsigned Leaves1[], unsigned *ptruCount1,
112
unsigned Leaves2[], unsigned *ptruCount2)
114
bool bOk = PhyEnumEdges(tree, ES);
122
// Special case: in a rooted tree, both edges from the root
123
// give the same bipartition, so skip one of them.
124
if (tree.IsRooted() && tree.IsRoot(ES.m_uNodeIndex2)
125
&& tree.GetRight(ES.m_uNodeIndex2) == ES.m_uNodeIndex1)
127
bOk = PhyEnumEdges(tree, ES);
132
PhyGetLeaves(tree, ES.m_uNodeIndex1, ES.m_uNodeIndex2, Leaves1, ptruCount1);
133
PhyGetLeaves(tree, ES.m_uNodeIndex2, ES.m_uNodeIndex1, Leaves2, ptruCount2);
135
if (*ptruCount1 + *ptruCount2 != tree.GetLeafCount())
136
Quit("PhyEnumBiParts %u + %u != %u",
137
*ptruCount1, *ptruCount2, tree.GetLeafCount());
140
for (unsigned i = 0; i < *ptruCount1; ++i)
142
if (!tree.IsLeaf(Leaves1[i]))
143
Quit("PhyEnumByParts: not leaf");
144
for (unsigned j = 0; j < *ptruCount2; ++j)
146
if (!tree.IsLeaf(Leaves2[j]))
147
Quit("PhyEnumByParts: not leaf");
148
if (Leaves1[i] == Leaves2[j])
149
Quit("PhyEnumByParts: dupe");
161
SetListFileName("c:\\tmp\\lobster.log", false);
163
TextFile fileIn("c:\\tmp\\test.phy");
164
tree.FromFile(fileIn);
167
const unsigned uNodeCount = tree.GetNodeCount();
168
unsigned *Leaves1 = new unsigned[uNodeCount];
169
unsigned *Leaves2 = new unsigned[uNodeCount];
175
unsigned uCount1 = uInsane;
176
unsigned uCount2 = uInsane;
177
bool bOk = PhyEnumBiParts(tree, ES, Leaves1, &uCount1, Leaves2, &uCount2);
178
Log("PEBP=%d ES.Init=%d ES.ni1=%d ES.ni2=%d\n",
187
for (unsigned n = 0; n < uCount1; ++n)
188
Log(" %d(%s)", Leaves1[n], tree.GetLeafName(Leaves1[n]));
191
for (unsigned n = 0; n < uCount2; ++n)
192
Log(" %d(%s)", Leaves2[n], tree.GetLeafName(Leaves2[n]));
198
static void GetLeavesSubtreeExcluding(const Tree &tree, unsigned uNodeIndex,
199
unsigned uExclude, unsigned Leaves[], unsigned *ptruCount)
201
if (uNodeIndex == uExclude)
204
if (tree.IsLeaf(uNodeIndex))
206
Leaves[*ptruCount] = uNodeIndex;
211
const unsigned uLeft = tree.GetLeft(uNodeIndex);
212
const unsigned uRight = tree.GetRight(uNodeIndex);
213
if (NULL_NEIGHBOR != uLeft)
214
GetLeavesSubtreeExcluding(tree, uLeft, uExclude, Leaves, ptruCount);
215
if (NULL_NEIGHBOR != uRight)
216
GetLeavesSubtreeExcluding(tree, uRight, uExclude, Leaves, ptruCount);
219
void GetLeavesExcluding(const Tree &tree, unsigned uNodeIndex,
220
unsigned uExclude, unsigned Leaves[], unsigned *ptruCount)
223
GetLeavesSubtreeExcluding(tree, uNodeIndex, uExclude, Leaves, ptruCount);
226
void GetInternalNodesInHeightOrder(const Tree &tree, unsigned NodeIndexes[])
228
const unsigned uNodeCount = tree.GetNodeCount();
230
Quit("GetInternalNodesInHeightOrder: %u nodes, none are internal",
232
const unsigned uInternalNodeCount = (uNodeCount - 1)/2;
233
double *Heights = new double[uInternalNodeCount];
236
for (unsigned uNodeIndex = 0; uNodeIndex < uNodeCount; ++uNodeIndex)
238
if (tree.IsLeaf(uNodeIndex))
240
NodeIndexes[uIndex] = uNodeIndex;
241
Heights[uIndex] = tree.GetNodeHeight(uNodeIndex);
244
if (uIndex != uInternalNodeCount)
245
Quit("Internal error: GetInternalNodesInHeightOrder");
247
// Simple but slow bubble sort (probably don't care about speed here)
252
for (unsigned i = 0; i < uInternalNodeCount - 1; ++i)
254
if (Heights[i] > Heights[i+1])
256
double dTmp = Heights[i];
257
Heights[i] = Heights[i+1];
260
unsigned uTmp = NodeIndexes[i];
261
NodeIndexes[i] = NodeIndexes[i+1];
262
NodeIndexes[i+1] = uTmp;
268
Log("Internal node index Height\n");
269
Log("------------------- --------\n");
270
// 1234567890123456789 123456789
271
for (unsigned n = 0; n < uInternalNodeCount; ++n)
272
Log("%19u %9.3f\n", NodeIndexes[n], Heights[n]);
277
void ApplyMinEdgeLength(Tree &tree, double dMinEdgeLength)
279
const unsigned uNodeCount = tree.GetNodeCount();
280
for (unsigned uNodeIndex = 0; uNodeIndex < uNodeCount; ++uNodeIndex)
282
const unsigned uNeighborCount = tree.GetNeighborCount(uNodeIndex);
283
for (unsigned n = 0; n < uNeighborCount; ++n)
285
const unsigned uNeighborNodeIndex = tree.GetNeighbor(uNodeIndex, n);
286
if (!tree.HasEdgeLength(uNodeIndex, uNeighborNodeIndex))
288
if (tree.GetEdgeLength(uNodeIndex, uNeighborNodeIndex) < dMinEdgeLength)
289
tree.SetEdgeLength(uNodeIndex, uNeighborNodeIndex, dMinEdgeLength);
1
/*****************************************************************
2
* Unipro UGENE - Integrated Bioinformatics Suite
3
* Copyright (C) 2008 Unipro, Russia (http://ugene.unipro.ru)
6
* This source code is distributed under the terms of the
7
* GNU General Public License. See the files COPYING and LICENSE
9
*****************************************************************/
16
// Return false when done
17
bool PhyEnumEdges(const Tree &tree, PhyEnumEdgeState &ES)
19
unsigned uNode1 = uInsane;
23
if (tree.GetNodeCount() <= 1)
25
ES.m_uNodeIndex1 = NULL_NEIGHBOR;
26
ES.m_uNodeIndex2 = NULL_NEIGHBOR;
29
uNode1 = tree.FirstDepthFirstNode();
34
uNode1 = tree.NextDepthFirstNode(ES.m_uNodeIndex1);
35
if (NULL_NEIGHBOR == uNode1)
37
if (tree.IsRooted() && tree.IsRoot(uNode1))
39
uNode1 = tree.NextDepthFirstNode(uNode1);
40
if (NULL_NEIGHBOR == uNode1)
44
unsigned uNode2 = tree.GetParent(uNode1);
46
ES.m_uNodeIndex1 = uNode1;
47
ES.m_uNodeIndex2 = uNode2;
51
bool PhyEnumEdgesR(const Tree &tree, PhyEnumEdgeState &ES)
53
unsigned uNode1 = uInsane;
57
if (tree.GetNodeCount() <= 1)
59
ES.m_uNodeIndex1 = NULL_NEIGHBOR;
60
ES.m_uNodeIndex2 = NULL_NEIGHBOR;
63
uNode1 = tree.FirstDepthFirstNodeR();
68
uNode1 = tree.NextDepthFirstNodeR(ES.m_uNodeIndex1);
69
if (NULL_NEIGHBOR == uNode1)
71
if (tree.IsRooted() && tree.IsRoot(uNode1))
73
uNode1 = tree.NextDepthFirstNode(uNode1);
74
if (NULL_NEIGHBOR == uNode1)
78
unsigned uNode2 = tree.GetParent(uNode1);
80
ES.m_uNodeIndex1 = uNode1;
81
ES.m_uNodeIndex2 = uNode2;
85
static void GetLeavesSubtree(const Tree &tree, unsigned uNodeIndex1,
86
const unsigned uNodeIndex2, unsigned Leaves[], unsigned *ptruCount)
88
if (tree.IsLeaf(uNodeIndex1))
90
Leaves[*ptruCount] = uNodeIndex1;
95
const unsigned uLeft = tree.GetFirstNeighbor(uNodeIndex1, uNodeIndex2);
96
const unsigned uRight = tree.GetSecondNeighbor(uNodeIndex1, uNodeIndex2);
97
if (NULL_NEIGHBOR != uLeft)
98
GetLeavesSubtree(tree, uLeft, uNodeIndex1, Leaves, ptruCount);
99
if (NULL_NEIGHBOR != uRight)
100
GetLeavesSubtree(tree, uRight, uNodeIndex1, Leaves, ptruCount);
103
static void PhyGetLeaves(const Tree &tree, unsigned uNodeIndex1, unsigned uNodeIndex2,
104
unsigned Leaves[], unsigned *ptruCount)
107
GetLeavesSubtree(tree, uNodeIndex1, uNodeIndex2, Leaves, ptruCount);
110
bool PhyEnumBiParts(const Tree &tree, PhyEnumEdgeState &ES,
111
unsigned Leaves1[], unsigned *ptruCount1,
112
unsigned Leaves2[], unsigned *ptruCount2)
114
bool bOk = PhyEnumEdges(tree, ES);
122
// Special case: in a rooted tree, both edges from the root
123
// give the same bipartition, so skip one of them.
124
if (tree.IsRooted() && tree.IsRoot(ES.m_uNodeIndex2)
125
&& tree.GetRight(ES.m_uNodeIndex2) == ES.m_uNodeIndex1)
127
bOk = PhyEnumEdges(tree, ES);
132
PhyGetLeaves(tree, ES.m_uNodeIndex1, ES.m_uNodeIndex2, Leaves1, ptruCount1);
133
PhyGetLeaves(tree, ES.m_uNodeIndex2, ES.m_uNodeIndex1, Leaves2, ptruCount2);
135
if (*ptruCount1 + *ptruCount2 != tree.GetLeafCount())
136
Quit("PhyEnumBiParts %u + %u != %u",
137
*ptruCount1, *ptruCount2, tree.GetLeafCount());
140
for (unsigned i = 0; i < *ptruCount1; ++i)
142
if (!tree.IsLeaf(Leaves1[i]))
143
Quit("PhyEnumByParts: not leaf");
144
for (unsigned j = 0; j < *ptruCount2; ++j)
146
if (!tree.IsLeaf(Leaves2[j]))
147
Quit("PhyEnumByParts: not leaf");
148
if (Leaves1[i] == Leaves2[j])
149
Quit("PhyEnumByParts: dupe");
161
SetListFileName("c:\\tmp\\lobster.log", false);
163
TextFile fileIn("c:\\tmp\\test.phy");
164
tree.FromFile(fileIn);
167
const unsigned uNodeCount = tree.GetNodeCount();
168
unsigned *Leaves1 = new unsigned[uNodeCount];
169
unsigned *Leaves2 = new unsigned[uNodeCount];
175
unsigned uCount1 = uInsane;
176
unsigned uCount2 = uInsane;
177
bool bOk = PhyEnumBiParts(tree, ES, Leaves1, &uCount1, Leaves2, &uCount2);
178
Log("PEBP=%d ES.Init=%d ES.ni1=%d ES.ni2=%d\n",
187
for (unsigned n = 0; n < uCount1; ++n)
188
Log(" %d(%s)", Leaves1[n], tree.GetLeafName(Leaves1[n]));
191
for (unsigned n = 0; n < uCount2; ++n)
192
Log(" %d(%s)", Leaves2[n], tree.GetLeafName(Leaves2[n]));
198
static void GetLeavesSubtreeExcluding(const Tree &tree, unsigned uNodeIndex,
199
unsigned uExclude, unsigned Leaves[], unsigned *ptruCount)
201
if (uNodeIndex == uExclude)
204
if (tree.IsLeaf(uNodeIndex))
206
Leaves[*ptruCount] = uNodeIndex;
211
const unsigned uLeft = tree.GetLeft(uNodeIndex);
212
const unsigned uRight = tree.GetRight(uNodeIndex);
213
if (NULL_NEIGHBOR != uLeft)
214
GetLeavesSubtreeExcluding(tree, uLeft, uExclude, Leaves, ptruCount);
215
if (NULL_NEIGHBOR != uRight)
216
GetLeavesSubtreeExcluding(tree, uRight, uExclude, Leaves, ptruCount);
219
void GetLeavesExcluding(const Tree &tree, unsigned uNodeIndex,
220
unsigned uExclude, unsigned Leaves[], unsigned *ptruCount)
223
GetLeavesSubtreeExcluding(tree, uNodeIndex, uExclude, Leaves, ptruCount);
226
void GetInternalNodesInHeightOrder(const Tree &tree, unsigned NodeIndexes[])
228
const unsigned uNodeCount = tree.GetNodeCount();
230
Quit("GetInternalNodesInHeightOrder: %u nodes, none are internal",
232
const unsigned uInternalNodeCount = (uNodeCount - 1)/2;
233
double *Heights = new double[uInternalNodeCount];
236
for (unsigned uNodeIndex = 0; uNodeIndex < uNodeCount; ++uNodeIndex)
238
if (tree.IsLeaf(uNodeIndex))
240
NodeIndexes[uIndex] = uNodeIndex;
241
Heights[uIndex] = tree.GetNodeHeight(uNodeIndex);
244
if (uIndex != uInternalNodeCount)
245
Quit("Internal error: GetInternalNodesInHeightOrder");
247
// Simple but slow bubble sort (probably don't care about speed here)
252
for (unsigned i = 0; i < uInternalNodeCount - 1; ++i)
254
if (Heights[i] > Heights[i+1])
256
double dTmp = Heights[i];
257
Heights[i] = Heights[i+1];
260
unsigned uTmp = NodeIndexes[i];
261
NodeIndexes[i] = NodeIndexes[i+1];
262
NodeIndexes[i+1] = uTmp;
268
Log("Internal node index Height\n");
269
Log("------------------- --------\n");
270
// 1234567890123456789 123456789
271
for (unsigned n = 0; n < uInternalNodeCount; ++n)
272
Log("%19u %9.3f\n", NodeIndexes[n], Heights[n]);
277
void ApplyMinEdgeLength(Tree &tree, double dMinEdgeLength)
279
const unsigned uNodeCount = tree.GetNodeCount();
280
for (unsigned uNodeIndex = 0; uNodeIndex < uNodeCount; ++uNodeIndex)
282
const unsigned uNeighborCount = tree.GetNeighborCount(uNodeIndex);
283
for (unsigned n = 0; n < uNeighborCount; ++n)
285
const unsigned uNeighborNodeIndex = tree.GetNeighbor(uNodeIndex, n);
286
if (!tree.HasEdgeLength(uNodeIndex, uNeighborNodeIndex))
288
if (tree.GetEdgeLength(uNodeIndex, uNeighborNodeIndex) < dMinEdgeLength)
289
tree.SetEdgeLength(uNodeIndex, uNeighborNodeIndex, dMinEdgeLength);