| 1 | #include "muscle.h" |
|---|
| 2 | #include "tree.h" |
|---|
| 3 | |
|---|
| 4 | #define TRACE 0 |
|---|
| 5 | |
|---|
| 6 | // Return false when done |
|---|
| 7 | bool PhyEnumEdges(const Tree &tree, PhyEnumEdgeState &ES) |
|---|
| 8 | { |
|---|
| 9 | unsigned uNode1 = uInsane; |
|---|
| 10 | |
|---|
| 11 | if (!ES.m_bInit) |
|---|
| 12 | { |
|---|
| 13 | if (tree.GetNodeCount() <= 1) |
|---|
| 14 | { |
|---|
| 15 | ES.m_uNodeIndex1 = NULL_NEIGHBOR; |
|---|
| 16 | ES.m_uNodeIndex2 = NULL_NEIGHBOR; |
|---|
| 17 | return false; |
|---|
| 18 | } |
|---|
| 19 | uNode1 = tree.FirstDepthFirstNode(); |
|---|
| 20 | ES.m_bInit = true; |
|---|
| 21 | } |
|---|
| 22 | else |
|---|
| 23 | { |
|---|
| 24 | uNode1 = tree.NextDepthFirstNode(ES.m_uNodeIndex1); |
|---|
| 25 | if (NULL_NEIGHBOR == uNode1) |
|---|
| 26 | return false; |
|---|
| 27 | if (tree.IsRooted() && tree.IsRoot(uNode1)) |
|---|
| 28 | { |
|---|
| 29 | uNode1 = tree.NextDepthFirstNode(uNode1); |
|---|
| 30 | if (NULL_NEIGHBOR == uNode1) |
|---|
| 31 | return false; |
|---|
| 32 | } |
|---|
| 33 | } |
|---|
| 34 | unsigned uNode2 = tree.GetParent(uNode1); |
|---|
| 35 | |
|---|
| 36 | ES.m_uNodeIndex1 = uNode1; |
|---|
| 37 | ES.m_uNodeIndex2 = uNode2; |
|---|
| 38 | return true; |
|---|
| 39 | } |
|---|
| 40 | |
|---|
| 41 | bool PhyEnumEdgesR(const Tree &tree, PhyEnumEdgeState &ES) |
|---|
| 42 | { |
|---|
| 43 | unsigned uNode1 = uInsane; |
|---|
| 44 | |
|---|
| 45 | if (!ES.m_bInit) |
|---|
| 46 | { |
|---|
| 47 | if (tree.GetNodeCount() <= 1) |
|---|
| 48 | { |
|---|
| 49 | ES.m_uNodeIndex1 = NULL_NEIGHBOR; |
|---|
| 50 | ES.m_uNodeIndex2 = NULL_NEIGHBOR; |
|---|
| 51 | return false; |
|---|
| 52 | } |
|---|
| 53 | uNode1 = tree.FirstDepthFirstNodeR(); |
|---|
| 54 | ES.m_bInit = true; |
|---|
| 55 | } |
|---|
| 56 | else |
|---|
| 57 | { |
|---|
| 58 | uNode1 = tree.NextDepthFirstNodeR(ES.m_uNodeIndex1); |
|---|
| 59 | if (NULL_NEIGHBOR == uNode1) |
|---|
| 60 | return false; |
|---|
| 61 | if (tree.IsRooted() && tree.IsRoot(uNode1)) |
|---|
| 62 | { |
|---|
| 63 | uNode1 = tree.NextDepthFirstNode(uNode1); |
|---|
| 64 | if (NULL_NEIGHBOR == uNode1) |
|---|
| 65 | return false; |
|---|
| 66 | } |
|---|
| 67 | } |
|---|
| 68 | unsigned uNode2 = tree.GetParent(uNode1); |
|---|
| 69 | |
|---|
| 70 | ES.m_uNodeIndex1 = uNode1; |
|---|
| 71 | ES.m_uNodeIndex2 = uNode2; |
|---|
| 72 | return true; |
|---|
| 73 | } |
|---|
| 74 | |
|---|
| 75 | static void GetLeavesSubtree(const Tree &tree, unsigned uNodeIndex1, |
|---|
| 76 | const unsigned uNodeIndex2, unsigned Leaves[], unsigned *ptruCount) |
|---|
| 77 | { |
|---|
| 78 | if (tree.IsLeaf(uNodeIndex1)) |
|---|
| 79 | { |
|---|
| 80 | Leaves[*ptruCount] = uNodeIndex1; |
|---|
| 81 | ++(*ptruCount); |
|---|
| 82 | return; |
|---|
| 83 | } |
|---|
| 84 | |
|---|
| 85 | const unsigned uLeft = tree.GetFirstNeighbor(uNodeIndex1, uNodeIndex2); |
|---|
| 86 | const unsigned uRight = tree.GetSecondNeighbor(uNodeIndex1, uNodeIndex2); |
|---|
| 87 | if (NULL_NEIGHBOR != uLeft) |
|---|
| 88 | GetLeavesSubtree(tree, uLeft, uNodeIndex1, Leaves, ptruCount); |
|---|
| 89 | if (NULL_NEIGHBOR != uRight) |
|---|
| 90 | GetLeavesSubtree(tree, uRight, uNodeIndex1, Leaves, ptruCount); |
|---|
| 91 | } |
|---|
| 92 | |
|---|
| 93 | static void PhyGetLeaves(const Tree &tree, unsigned uNodeIndex1, unsigned uNodeIndex2, |
|---|
| 94 | unsigned Leaves[], unsigned *ptruCount) |
|---|
| 95 | { |
|---|
| 96 | *ptruCount = 0; |
|---|
| 97 | GetLeavesSubtree(tree, uNodeIndex1, uNodeIndex2, Leaves, ptruCount); |
|---|
| 98 | } |
|---|
| 99 | |
|---|
| 100 | bool PhyEnumBiParts(const Tree &tree, PhyEnumEdgeState &ES, |
|---|
| 101 | unsigned Leaves1[], unsigned *ptruCount1, |
|---|
| 102 | unsigned Leaves2[], unsigned *ptruCount2) |
|---|
| 103 | { |
|---|
| 104 | bool bOk = PhyEnumEdges(tree, ES); |
|---|
| 105 | if (!bOk) |
|---|
| 106 | { |
|---|
| 107 | *ptruCount1 = 0; |
|---|
| 108 | *ptruCount2 = 0; |
|---|
| 109 | return false; |
|---|
| 110 | } |
|---|
| 111 | |
|---|
| 112 | // Special case: in a rooted tree, both edges from the root |
|---|
| 113 | // give the same bipartition, so skip one of them. |
|---|
| 114 | if (tree.IsRooted() && tree.IsRoot(ES.m_uNodeIndex2) |
|---|
| 115 | && tree.GetRight(ES.m_uNodeIndex2) == ES.m_uNodeIndex1) |
|---|
| 116 | { |
|---|
| 117 | bOk = PhyEnumEdges(tree, ES); |
|---|
| 118 | if (!bOk) |
|---|
| 119 | return false; |
|---|
| 120 | } |
|---|
| 121 | |
|---|
| 122 | PhyGetLeaves(tree, ES.m_uNodeIndex1, ES.m_uNodeIndex2, Leaves1, ptruCount1); |
|---|
| 123 | PhyGetLeaves(tree, ES.m_uNodeIndex2, ES.m_uNodeIndex1, Leaves2, ptruCount2); |
|---|
| 124 | |
|---|
| 125 | if (*ptruCount1 + *ptruCount2 != tree.GetLeafCount()) |
|---|
| 126 | Quit("PhyEnumBiParts %u + %u != %u", |
|---|
| 127 | *ptruCount1, *ptruCount2, tree.GetLeafCount()); |
|---|
| 128 | #if DEBUG |
|---|
| 129 | { |
|---|
| 130 | for (unsigned i = 0; i < *ptruCount1; ++i) |
|---|
| 131 | { |
|---|
| 132 | if (!tree.IsLeaf(Leaves1[i])) |
|---|
| 133 | Quit("PhyEnumByParts: not leaf"); |
|---|
| 134 | for (unsigned j = 0; j < *ptruCount2; ++j) |
|---|
| 135 | { |
|---|
| 136 | if (!tree.IsLeaf(Leaves2[j])) |
|---|
| 137 | Quit("PhyEnumByParts: not leaf"); |
|---|
| 138 | if (Leaves1[i] == Leaves2[j]) |
|---|
| 139 | Quit("PhyEnumByParts: dupe"); |
|---|
| 140 | } |
|---|
| 141 | } |
|---|
| 142 | } |
|---|
| 143 | #endif |
|---|
| 144 | |
|---|
| 145 | return true; |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | #if 0 |
|---|
| 149 | void TestBiPart() |
|---|
| 150 | { |
|---|
| 151 | SetListFileName("c:\\tmp\\lobster.log", false); |
|---|
| 152 | Tree tree; |
|---|
| 153 | TextFile fileIn("c:\\tmp\\test.phy"); |
|---|
| 154 | tree.FromFile(fileIn); |
|---|
| 155 | tree.LogMe(); |
|---|
| 156 | |
|---|
| 157 | const unsigned uNodeCount = tree.GetNodeCount(); |
|---|
| 158 | unsigned *Leaves1 = new unsigned[uNodeCount]; |
|---|
| 159 | unsigned *Leaves2 = new unsigned[uNodeCount]; |
|---|
| 160 | |
|---|
| 161 | PhyEnumEdgeState ES; |
|---|
| 162 | bool bDone = false; |
|---|
| 163 | for (;;) |
|---|
| 164 | { |
|---|
| 165 | unsigned uCount1 = uInsane; |
|---|
| 166 | unsigned uCount2 = uInsane; |
|---|
| 167 | bool bOk = PhyEnumBiParts(tree, ES, Leaves1, &uCount1, Leaves2, &uCount2); |
|---|
| 168 | Log("PEBP=%d ES.Init=%d ES.ni1=%d ES.ni2=%d\n", |
|---|
| 169 | bOk, |
|---|
| 170 | ES.m_bInit, |
|---|
| 171 | ES.m_uNodeIndex1, |
|---|
| 172 | ES.m_uNodeIndex2); |
|---|
| 173 | if (!bOk) |
|---|
| 174 | break; |
|---|
| 175 | Log("\n"); |
|---|
| 176 | Log("Part1: "); |
|---|
| 177 | for (unsigned n = 0; n < uCount1; ++n) |
|---|
| 178 | Log(" %d(%s)", Leaves1[n], tree.GetLeafName(Leaves1[n])); |
|---|
| 179 | Log("\n"); |
|---|
| 180 | Log("Part2: "); |
|---|
| 181 | for (unsigned n = 0; n < uCount2; ++n) |
|---|
| 182 | Log(" %d(%s)", Leaves2[n], tree.GetLeafName(Leaves2[n])); |
|---|
| 183 | Log("\n"); |
|---|
| 184 | } |
|---|
| 185 | } |
|---|
| 186 | #endif |
|---|
| 187 | |
|---|
| 188 | static void GetLeavesSubtreeExcluding(const Tree &tree, unsigned uNodeIndex, |
|---|
| 189 | unsigned uExclude, unsigned Leaves[], unsigned *ptruCount) |
|---|
| 190 | { |
|---|
| 191 | if (uNodeIndex == uExclude) |
|---|
| 192 | return; |
|---|
| 193 | |
|---|
| 194 | if (tree.IsLeaf(uNodeIndex)) |
|---|
| 195 | { |
|---|
| 196 | Leaves[*ptruCount] = uNodeIndex; |
|---|
| 197 | ++(*ptruCount); |
|---|
| 198 | return; |
|---|
| 199 | } |
|---|
| 200 | |
|---|
| 201 | const unsigned uLeft = tree.GetLeft(uNodeIndex); |
|---|
| 202 | const unsigned uRight = tree.GetRight(uNodeIndex); |
|---|
| 203 | if (NULL_NEIGHBOR != uLeft) |
|---|
| 204 | GetLeavesSubtreeExcluding(tree, uLeft, uExclude, Leaves, ptruCount); |
|---|
| 205 | if (NULL_NEIGHBOR != uRight) |
|---|
| 206 | GetLeavesSubtreeExcluding(tree, uRight, uExclude, Leaves, ptruCount); |
|---|
| 207 | } |
|---|
| 208 | |
|---|
| 209 | void GetLeavesExcluding(const Tree &tree, unsigned uNodeIndex, |
|---|
| 210 | unsigned uExclude, unsigned Leaves[], unsigned *ptruCount) |
|---|
| 211 | { |
|---|
| 212 | *ptruCount = 0; |
|---|
| 213 | GetLeavesSubtreeExcluding(tree, uNodeIndex, uExclude, Leaves, ptruCount); |
|---|
| 214 | } |
|---|
| 215 | |
|---|
| 216 | void GetInternalNodesInHeightOrder(const Tree &tree, unsigned NodeIndexes[]) |
|---|
| 217 | { |
|---|
| 218 | const unsigned uNodeCount = tree.GetNodeCount(); |
|---|
| 219 | if (uNodeCount < 3) |
|---|
| 220 | Quit("GetInternalNodesInHeightOrder: %u nodes, none are internal", |
|---|
| 221 | uNodeCount); |
|---|
| 222 | const unsigned uInternalNodeCount = (uNodeCount - 1)/2; |
|---|
| 223 | double *Heights = new double[uInternalNodeCount]; |
|---|
| 224 | |
|---|
| 225 | unsigned uIndex = 0; |
|---|
| 226 | for (unsigned uNodeIndex = 0; uNodeIndex < uNodeCount; ++uNodeIndex) |
|---|
| 227 | { |
|---|
| 228 | if (tree.IsLeaf(uNodeIndex)) |
|---|
| 229 | continue; |
|---|
| 230 | NodeIndexes[uIndex] = uNodeIndex; |
|---|
| 231 | Heights[uIndex] = tree.GetNodeHeight(uNodeIndex); |
|---|
| 232 | ++uIndex; |
|---|
| 233 | } |
|---|
| 234 | if (uIndex != uInternalNodeCount) |
|---|
| 235 | Quit("Internal error: GetInternalNodesInHeightOrder"); |
|---|
| 236 | |
|---|
| 237 | // Simple but slow bubble sort (probably don't care about speed here) |
|---|
| 238 | bool bDone = false; |
|---|
| 239 | while (!bDone) |
|---|
| 240 | { |
|---|
| 241 | bDone = true; |
|---|
| 242 | for (unsigned i = 0; i < uInternalNodeCount - 1; ++i) |
|---|
| 243 | { |
|---|
| 244 | if (Heights[i] > Heights[i+1]) |
|---|
| 245 | { |
|---|
| 246 | double dTmp = Heights[i]; |
|---|
| 247 | Heights[i] = Heights[i+1]; |
|---|
| 248 | Heights[i+1] = dTmp; |
|---|
| 249 | |
|---|
| 250 | unsigned uTmp = NodeIndexes[i]; |
|---|
| 251 | NodeIndexes[i] = NodeIndexes[i+1]; |
|---|
| 252 | NodeIndexes[i+1] = uTmp; |
|---|
| 253 | bDone = false; |
|---|
| 254 | } |
|---|
| 255 | } |
|---|
| 256 | } |
|---|
| 257 | #if TRACE |
|---|
| 258 | Log("Internal node index Height\n"); |
|---|
| 259 | Log("------------------- --------\n"); |
|---|
| 260 | // 1234567890123456789 123456789 |
|---|
| 261 | for (unsigned n = 0; n < uInternalNodeCount; ++n) |
|---|
| 262 | Log("%19u %9.3f\n", NodeIndexes[n], Heights[n]); |
|---|
| 263 | #endif |
|---|
| 264 | delete[] Heights; |
|---|
| 265 | } |
|---|
| 266 | |
|---|
| 267 | void ApplyMinEdgeLength(Tree &tree, double dMinEdgeLength) |
|---|
| 268 | { |
|---|
| 269 | const unsigned uNodeCount = tree.GetNodeCount(); |
|---|
| 270 | for (unsigned uNodeIndex = 0; uNodeIndex < uNodeCount; ++uNodeIndex) |
|---|
| 271 | { |
|---|
| 272 | const unsigned uNeighborCount = tree.GetNeighborCount(uNodeIndex); |
|---|
| 273 | for (unsigned n = 0; n < uNeighborCount; ++n) |
|---|
| 274 | { |
|---|
| 275 | const unsigned uNeighborNodeIndex = tree.GetNeighbor(uNodeIndex, n); |
|---|
| 276 | if (!tree.HasEdgeLength(uNodeIndex, uNeighborNodeIndex)) |
|---|
| 277 | continue; |
|---|
| 278 | if (tree.GetEdgeLength(uNodeIndex, uNeighborNodeIndex) < dMinEdgeLength) |
|---|
| 279 | tree.SetEdgeLength(uNodeIndex, uNeighborNodeIndex, dMinEdgeLength); |
|---|
| 280 | } |
|---|
| 281 | } |
|---|
| 282 | } |
|---|