source: trunk/GDE/MUSCLE/src/phy2.cpp

Last change on this file was 10390, checked in by aboeckma, 11 years ago

added muscle sourcles amd makefile

File size: 7.4 KB
Line 
1#include "muscle.h"
2#include "tree.h"
3
4#define TRACE   0
5
6// Return false when done
7bool 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
41bool 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
75static 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
93static 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
100bool 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
149void 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
188static 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
209void 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
216void 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
267void 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        }
Note: See TracBrowser for help on using the repository browser.