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

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

added muscle sourcles amd makefile

File size: 8.5 KB
Line 
1#include "muscle.h"
2#include "tree.h"
3#include <stdio.h>
4
5#define TRACE   0
6
7void ClusterByHeight(const Tree &tree, double dMaxHeight, unsigned Subtrees[],
8  unsigned *ptruSubtreeCount)
9        {
10        if (!tree.IsRooted())
11                Quit("ClusterByHeight: requires rooted tree");
12
13#if     TRACE
14        Log("ClusterByHeight, max height=%g\n", dMaxHeight);
15#endif
16
17        unsigned uSubtreeCount = 0;
18        const unsigned uNodeCount = tree.GetNodeCount();
19        for (unsigned uNodeIndex = 0; uNodeIndex < uNodeCount; ++uNodeIndex)
20                {
21                if (tree.IsRoot(uNodeIndex))
22                        continue;
23                unsigned uParent = tree.GetParent(uNodeIndex);
24                double dHeight = tree.GetNodeHeight(uNodeIndex);
25                double dParentHeight = tree.GetNodeHeight(uParent);
26
27#if     TRACE
28                Log("Node %3u  Height %5.2f  ParentHeight %5.2f\n",
29                  uNodeIndex, dHeight, dParentHeight);
30#endif
31                if (dParentHeight > dMaxHeight && dHeight <= dMaxHeight)
32                        {
33                        Subtrees[uSubtreeCount] = uNodeIndex;
34#if     TRACE
35                        Log("Subtree[%u]=%u\n", uSubtreeCount, uNodeIndex);
36#endif
37                        ++uSubtreeCount;
38                        }
39                }
40        *ptruSubtreeCount = uSubtreeCount;
41        }
42
43static void ClusterBySubfamCount_Iteration(const Tree &tree, unsigned Subfams[],
44  unsigned uCount)
45        {
46// Find highest child node of current set of subfamilies.
47        double dHighestHeight = -1e20;
48        int iParentSubscript = -1;
49
50        for (int n = 0; n < (int) uCount; ++n)
51                {
52                const unsigned uNodeIndex = Subfams[n];
53                if (tree.IsLeaf(uNodeIndex))
54                        continue;
55
56                const unsigned uLeft = tree.GetLeft(uNodeIndex);
57                const double dHeightLeft = tree.GetNodeHeight(uLeft);
58                if (dHeightLeft > dHighestHeight)
59                        {
60                        dHighestHeight = dHeightLeft;
61                        iParentSubscript = n;
62                        }
63
64                const unsigned uRight = tree.GetRight(uNodeIndex);
65                const double dHeightRight = tree.GetNodeHeight(uRight);
66                if (dHeightRight > dHighestHeight)
67                        {
68                        dHighestHeight = dHeightRight;
69                        iParentSubscript = n;
70                        }
71                }
72
73        if (-1 == iParentSubscript)
74                Quit("CBSFCIter: failed to find highest child");
75
76        const unsigned uNodeIndex = Subfams[iParentSubscript];
77        const unsigned uLeft = tree.GetLeft(uNodeIndex);
78        const unsigned uRight = tree.GetRight(uNodeIndex);
79
80// Delete parent by replacing with left child
81        Subfams[iParentSubscript] = uLeft;
82
83// Append right child to list
84        Subfams[uCount] = uRight;
85
86#if     TRACE
87        {
88        Log("Iter %3u:", uCount);
89        for (unsigned n = 0; n < uCount; ++n)
90                Log(" %u", Subfams[n]);
91        Log("\n");
92        }
93#endif
94        }
95
96// Divide a tree containing N leaves into k families by
97// cutting the tree at a horizontal line at some height.
98// Each internal node defines a height for the cut,
99// considering all internal nodes enumerates all distinct
100// cuts. Visit internal nodes in decreasing order of height.
101// Visiting the node corresponds to moving the horizontal
102// line down to cut the tree at the height of that node.
103// We consider the cut to be "infinitestimally below"
104// the node, so the effect is to remove the current node
105// from the list of subfamilies and add its two children.
106// We must visit a parent before its children (so care may
107// be needed to handle zero edge lengths properly).
108// We assume that N is small, and write dumb O(N^2) code.
109// More efficient strategies are possible for large N
110// by maintaining a list of nodes sorted by height.
111void ClusterBySubfamCount(const Tree &tree, unsigned uSubfamCount,
112  unsigned Subfams[], unsigned *ptruSubfamCount)
113        {
114        const unsigned uNodeCount = tree.GetNodeCount();
115        const unsigned uLeafCount = (uNodeCount + 1)/2;
116
117// Special case: empty tree
118        if (0 == uNodeCount)
119                {
120                *ptruSubfamCount = 0;
121                return;
122                }
123
124// Special case: more subfamilies than leaves
125        if (uSubfamCount >= uLeafCount)
126                {
127                for (unsigned n = 0; n < uLeafCount; ++n)
128                        Subfams[n] = n;
129                *ptruSubfamCount = uLeafCount;
130                return;
131                }
132
133// Initialize list of subfamilies to be root
134        Subfams[0] = tree.GetRootNodeIndex();
135
136// Iterate
137        for (unsigned i = 1; i < uSubfamCount; ++i)
138                ClusterBySubfamCount_Iteration(tree, Subfams, i);
139       
140        *ptruSubfamCount = uSubfamCount;
141        }
142
143static void GetLeavesRecurse(const Tree &tree, unsigned uNodeIndex,
144  unsigned Leaves[], unsigned &uLeafCount /* in-out */)
145        {
146        if (tree.IsLeaf(uNodeIndex))
147                {
148                Leaves[uLeafCount] = uNodeIndex;
149                ++uLeafCount;
150                return;
151                }
152
153        const unsigned uLeft = tree.GetLeft(uNodeIndex);
154        const unsigned uRight = tree.GetRight(uNodeIndex);
155
156        GetLeavesRecurse(tree, uLeft, Leaves, uLeafCount);
157        GetLeavesRecurse(tree, uRight, Leaves, uLeafCount);
158        }
159
160void GetLeaves(const Tree &tree, unsigned uNodeIndex, unsigned Leaves[],
161  unsigned *ptruLeafCount)
162        {
163        unsigned uLeafCount = 0;
164        GetLeavesRecurse(tree, uNodeIndex, Leaves, uLeafCount);
165        *ptruLeafCount = uLeafCount;
166        }
167
168void Tree::PruneTree(const Tree &tree, unsigned Subfams[],
169  unsigned uSubfamCount)
170        {
171        if (!tree.IsRooted())
172                Quit("Tree::PruneTree: requires rooted tree");
173
174        Clear();
175
176        m_uNodeCount = 2*uSubfamCount - 1;
177        InitCache(m_uNodeCount);
178
179        const unsigned uUnprunedNodeCount = tree.GetNodeCount();
180
181        unsigned *uUnprunedToPrunedIndex = new unsigned[uUnprunedNodeCount];
182        unsigned *uPrunedToUnprunedIndex = new unsigned[m_uNodeCount];
183
184        for (unsigned n = 0; n < uUnprunedNodeCount; ++n)
185                uUnprunedToPrunedIndex[n] = NULL_NEIGHBOR;
186
187        for (unsigned n = 0; n < m_uNodeCount; ++n)
188                uPrunedToUnprunedIndex[n] = NULL_NEIGHBOR;
189
190// Create mapping between unpruned and pruned node indexes
191        unsigned uInternalNodeIndex = uSubfamCount;
192        for (unsigned uSubfamIndex = 0; uSubfamIndex < uSubfamCount; ++uSubfamIndex)
193                {
194                unsigned uUnprunedNodeIndex = Subfams[uSubfamIndex];
195                uUnprunedToPrunedIndex[uUnprunedNodeIndex] = uSubfamIndex;
196                uPrunedToUnprunedIndex[uSubfamIndex] = uUnprunedNodeIndex;
197                for (;;)
198                        {
199                        uUnprunedNodeIndex = tree.GetParent(uUnprunedNodeIndex);
200                        if (tree.IsRoot(uUnprunedNodeIndex))
201                                break;
202
203                // Already visited this node?
204                        if (NULL_NEIGHBOR != uUnprunedToPrunedIndex[uUnprunedNodeIndex])
205                                break;
206
207                        uUnprunedToPrunedIndex[uUnprunedNodeIndex] = uInternalNodeIndex;
208                        uPrunedToUnprunedIndex[uInternalNodeIndex] = uUnprunedNodeIndex;
209
210                        ++uInternalNodeIndex;
211                        }
212                }
213
214        const unsigned uUnprunedRootIndex = tree.GetRootNodeIndex();
215        uUnprunedToPrunedIndex[uUnprunedRootIndex] = uInternalNodeIndex;
216        uPrunedToUnprunedIndex[uInternalNodeIndex] = uUnprunedRootIndex;
217
218#if     TRACE
219        {
220        Log("Pruned to unpruned:\n");
221        for (unsigned i = 0; i < m_uNodeCount; ++i)
222                Log(" [%u]=%u", i, uPrunedToUnprunedIndex[i]);
223        Log("\n");
224        Log("Unpruned to pruned:\n");
225        for (unsigned i = 0; i < uUnprunedNodeCount; ++i)
226                {
227                unsigned n = uUnprunedToPrunedIndex[i];
228                if (n != NULL_NEIGHBOR)
229                        Log(" [%u]=%u", i, n);
230                }
231        Log("\n");
232        }
233#endif
234
235        if (uInternalNodeIndex != m_uNodeCount - 1)
236                Quit("Tree::PruneTree, Internal error");
237
238// Nodes 0, 1 ... are the leaves
239        for (unsigned uSubfamIndex = 0; uSubfamIndex < uSubfamCount; ++uSubfamIndex)
240                {
241                char szName[32];
242                sprintf(szName, "Subfam_%u", uSubfamIndex + 1);
243                m_ptrName[uSubfamIndex] = strsave(szName);
244                }
245
246        for (unsigned uPrunedNodeIndex = uSubfamCount; uPrunedNodeIndex < m_uNodeCount;
247          ++uPrunedNodeIndex)
248                {
249                unsigned uUnprunedNodeIndex = uPrunedToUnprunedIndex[uPrunedNodeIndex];
250
251                const unsigned uUnprunedLeft = tree.GetLeft(uUnprunedNodeIndex);
252                const unsigned uUnprunedRight = tree.GetRight(uUnprunedNodeIndex);
253
254                const unsigned uPrunedLeft = uUnprunedToPrunedIndex[uUnprunedLeft];
255                const unsigned uPrunedRight = uUnprunedToPrunedIndex[uUnprunedRight];
256
257                const double dLeftLength =
258                  tree.GetEdgeLength(uUnprunedNodeIndex, uUnprunedLeft);
259                const double dRightLength =
260                  tree.GetEdgeLength(uUnprunedNodeIndex, uUnprunedRight);
261
262                m_uNeighbor2[uPrunedNodeIndex] = uPrunedLeft;
263                m_uNeighbor3[uPrunedNodeIndex] = uPrunedRight;
264
265                m_dEdgeLength1[uPrunedLeft] = dLeftLength;
266                m_dEdgeLength1[uPrunedRight] = dRightLength;
267
268                m_uNeighbor1[uPrunedLeft] = uPrunedNodeIndex;
269                m_uNeighbor1[uPrunedRight] = uPrunedNodeIndex;
270
271                m_bHasEdgeLength1[uPrunedLeft] = true;
272                m_bHasEdgeLength1[uPrunedRight] = true;
273
274                m_dEdgeLength2[uPrunedNodeIndex] = dLeftLength;
275                m_dEdgeLength3[uPrunedNodeIndex] = dRightLength;
276
277                m_bHasEdgeLength2[uPrunedNodeIndex] = true;
278                m_bHasEdgeLength3[uPrunedNodeIndex] = true;
279                }
280
281        m_uRootNodeIndex = uUnprunedToPrunedIndex[uUnprunedRootIndex];
282
283        m_bRooted = true;
284
285        Validate();
286
287        delete[] uUnprunedToPrunedIndex;
288        }
289
290void LeafIndexesToIds(const Tree &tree, const unsigned Leaves[], unsigned uCount,
291  unsigned Ids[])
292        {
293        for (unsigned n = 0; n < uCount; ++n)
294                Ids[n] = tree.GetLeafId(Leaves[n]);
295        }
Note: See TracBrowser for help on using the repository browser.