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

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

added muscle sourcles amd makefile

File size: 7.5 KB
Line 
1#include "muscle.h"
2#include "tree.h"
3#include "msa.h"
4#include "pwpath.h"
5#include "profile.h"
6#include "scorehistory.h"
7#include "objscore.h"
8
9unsigned g_uRefineHeightSubtree;
10unsigned g_uRefineHeightSubtreeTotal;
11
12#define TRACE                   0
13#define DIFFOBJSCORE    0
14
15static bool TryRealign(MSA &msaIn, const Tree &tree, const unsigned Leaves1[],
16  unsigned uCount1, const unsigned Leaves2[], unsigned uCount2,
17  SCORE *ptrscoreBefore, SCORE *ptrscoreAfter,
18  bool bLockLeft, bool bLockRight)
19        {
20#if     TRACE
21        Log("TryRealign, msaIn=\n");
22        msaIn.LogMe();
23#endif
24
25        const unsigned uSeqCount = msaIn.GetSeqCount();
26
27        unsigned *Ids1 = new unsigned[uSeqCount];
28        unsigned *Ids2 = new unsigned[uSeqCount];
29
30        LeafIndexesToIds(tree, Leaves1, uCount1, Ids1);
31        LeafIndexesToIds(tree, Leaves2, uCount2, Ids2);
32
33        MSA msa1;
34        MSA msa2;
35
36        MSASubsetByIds(msaIn, Ids1, uCount1, msa1);
37        MSASubsetByIds(msaIn, Ids2, uCount2, msa2);
38
39#if     DEBUG
40        ValidateMuscleIds(msa1);
41        ValidateMuscleIds(msa2);
42#endif
43
44// Computing the objective score may be expensive for
45// large numbers of sequences. As a speed optimization,
46// we check whether the alignment changes. If it does
47// not change, there is no need to compute the objective
48// score. We test for the alignment changing by comparing
49// the Viterbi paths before and after re-aligning.
50        PWPath pathBefore;
51        pathBefore.FromMSAPair(msa1, msa2);
52
53        DeleteGappedCols(msa1);
54        DeleteGappedCols(msa2);
55
56        if (0 == msa1.GetColCount() || 0 == msa2.GetColCount())
57                return false;
58
59        MSA msaRealigned;
60        PWPath pathAfter;
61
62        AlignTwoMSAs(msa1, msa2, msaRealigned, pathAfter, bLockLeft, bLockRight);
63
64        bool bAnyChanges = !pathAfter.Equal(pathBefore);
65        unsigned uDiffCount1;
66        unsigned uDiffCount2;
67        static unsigned Edges1[10000];
68        static unsigned Edges2[10000];
69        DiffPaths(pathBefore, pathAfter, Edges1, &uDiffCount1, Edges2, &uDiffCount2);
70
71#if     TRACE
72        Log("TryRealign, msa1=\n");
73        msa1.LogMe();
74        Log("\nmsa2=\n");
75        msa2.LogMe();
76        Log("\nRealigned (changes %s)=\n", bAnyChanges ? "TRUE" : "FALSE");
77        msaRealigned.LogMe();
78#endif
79
80        if (!bAnyChanges)
81                {
82                *ptrscoreBefore = 0;
83                *ptrscoreAfter = 0;
84                return false;
85                }
86
87        SetMSAWeightsMuscle(msaIn);
88        SetMSAWeightsMuscle(msaRealigned);
89
90#if     DIFFOBJSCORE
91        const SCORE scoreDiff = DiffObjScore(msaIn, pathBefore, Edges1, uDiffCount1,
92          msaRealigned, pathAfter, Edges2, uDiffCount2);
93        bool bAccept = (scoreDiff > 0);
94        *ptrscoreBefore = 0;
95        *ptrscoreAfter = scoreDiff;
96        //const SCORE scoreBefore = ObjScoreIds(msaIn, Ids1, uCount1, Ids2, uCount2);
97        //const SCORE scoreAfter = ObjScoreIds(msaRealigned, Ids1, uCount1, Ids2, uCount2);
98        //Log("Diff = %.3g %.3g\n", scoreDiff, scoreAfter - scoreBefore);
99#else
100        const SCORE scoreBefore = ObjScoreIds(msaIn, Ids1, uCount1, Ids2, uCount2);
101        const SCORE scoreAfter = ObjScoreIds(msaRealigned, Ids1, uCount1, Ids2, uCount2);
102
103        bool bAccept = (scoreAfter > scoreBefore);
104
105#if     TRACE
106        Log("Score %g -> %g Accept %s\n", scoreBefore, scoreAfter, bAccept ? "TRUE" : "FALSE");
107#endif
108
109        *ptrscoreBefore = scoreBefore;
110        *ptrscoreAfter = scoreAfter;
111#endif
112
113        if (bAccept)
114                msaIn.Copy(msaRealigned);
115        delete[] Ids1;
116        delete[] Ids2;
117        return bAccept;
118        }
119
120static void RefineHeightParts(MSA &msaIn, const Tree &tree,
121 const unsigned InternalNodeIndexes[], bool bReversed, bool bRight,
122 unsigned uIter, 
123 ScoreHistory &History,
124 bool *ptrbAnyChanges, bool *ptrbOscillating, bool bLockLeft, bool bLockRight)
125        {
126        *ptrbOscillating = false;
127
128        const unsigned uSeqCount = msaIn.GetSeqCount();
129        const unsigned uInternalNodeCount = uSeqCount - 1;
130
131        unsigned *Leaves1 = new unsigned[uSeqCount];
132        unsigned *Leaves2 = new unsigned[uSeqCount];
133
134        const unsigned uRootNodeIndex = tree.GetRootNodeIndex();
135        bool bAnyAccepted = false;
136        for (unsigned i = 0; i < uInternalNodeCount; ++i)
137                {
138                const unsigned uInternalNodeIndex = InternalNodeIndexes[i];
139                unsigned uNeighborNodeIndex;
140                if (tree.IsRoot(uInternalNodeIndex) && !bRight)
141                        continue;
142                else if (bRight)
143                        uNeighborNodeIndex = tree.GetRight(uInternalNodeIndex);
144                else
145                        uNeighborNodeIndex = tree.GetLeft(uInternalNodeIndex);
146
147                g_uTreeSplitNode1 = uInternalNodeIndex;
148                g_uTreeSplitNode2 = uNeighborNodeIndex;
149
150                unsigned uCount1;
151                unsigned uCount2;
152
153                GetLeaves(tree, uNeighborNodeIndex, Leaves1, &uCount1);
154                GetLeavesExcluding(tree, uRootNodeIndex, uNeighborNodeIndex,
155                  Leaves2, &uCount2);
156
157#if     TRACE
158                Log("\nRefineHeightParts node %u\n", uInternalNodeIndex);
159                Log("Group1=");
160                for (unsigned n = 0; n < uCount1; ++n)
161                        Log(" %u(%s)", Leaves1[n], tree.GetName(Leaves1[n]));
162                Log("\n");
163                Log("Group2=");
164                for (unsigned n = 0; n < uCount2; ++n)
165                        Log(" %u(%s)", Leaves2[n], tree.GetName(Leaves2[n]));
166                Log("\n");
167#endif
168
169                SCORE scoreBefore;
170                SCORE scoreAfter;
171                bool bAccepted = TryRealign(msaIn, tree, Leaves1, uCount1, Leaves2, uCount2,
172                  &scoreBefore, &scoreAfter, bLockLeft, bLockRight);
173                SetCurrentAlignment(msaIn);
174
175                ++g_uRefineHeightSubtree;
176                Progress(g_uRefineHeightSubtree, g_uRefineHeightSubtreeTotal);
177
178#if     TRACE
179                if (uIter > 0)
180                        Log("Before %g %g\n", scoreBefore,
181                          History.GetScore(uIter - 1, uInternalNodeIndex, bReversed, bRight));
182#endif
183                SCORE scoreMax = scoreAfter > scoreBefore? scoreAfter : scoreBefore;
184                bool bRepeated = History.SetScore(uIter, uInternalNodeIndex, bRight, scoreMax);
185                if (bRepeated)
186                        {
187                        *ptrbOscillating = true;
188                        break;
189                        }
190
191                if (bAccepted)
192                        bAnyAccepted = true;
193                }
194
195        delete[] Leaves1;
196        delete[] Leaves2;
197
198        *ptrbAnyChanges = bAnyAccepted;
199        }
200
201// Return true if any changes made
202bool RefineHoriz(MSA &msaIn, const Tree &tree, unsigned uIters, bool bLockLeft,
203  bool bLockRight)
204        {
205#if     TRACE
206        tree.LogMe();
207#endif
208
209        if (!tree.IsRooted())
210                Quit("RefineHeight: requires rooted tree");
211
212        const unsigned uSeqCount = msaIn.GetSeqCount();
213        if (uSeqCount < 3)
214                return false;
215
216        const unsigned uInternalNodeCount = uSeqCount - 1;
217        unsigned *InternalNodeIndexes = new unsigned[uInternalNodeCount];
218        unsigned *InternalNodeIndexesR = new unsigned[uInternalNodeCount];
219
220        GetInternalNodesInHeightOrder(tree, InternalNodeIndexes);
221
222        ScoreHistory History(uIters, 2*uSeqCount - 1);
223
224        bool bAnyChangesAnyIter = false;
225        for (unsigned n = 0; n < uInternalNodeCount; ++n)
226                InternalNodeIndexesR[uInternalNodeCount - 1 - n] = InternalNodeIndexes[n];
227
228        for (unsigned uIter = 0; uIter < uIters; ++uIter)
229                {
230                bool bAnyChangesThisIter = false;
231                IncIter();
232                SetProgressDesc("Refine biparts");
233                g_uRefineHeightSubtree = 0;
234                g_uRefineHeightSubtreeTotal = uInternalNodeCount*2 - 1;
235
236                bool bReverse = (uIter%2 != 0);
237                unsigned *Internals;
238                if (bReverse)
239                        Internals = InternalNodeIndexesR;
240                else
241                        Internals = InternalNodeIndexes;
242
243                bool bOscillating;
244                for (unsigned i = 0; i < 2; ++i)
245                        {
246                        bool bAnyChanges = false;
247                        bool bRight;
248                        switch (i)
249                                {
250                        case 0:
251                                bRight = true;
252                                break;
253                        case 1:
254                                bRight = false;
255                                break;
256                        default:
257                                Quit("RefineHeight default case");
258                                }
259                        RefineHeightParts(msaIn, tree, Internals, bReverse, bRight,
260                          uIter, 
261                          History, 
262                          &bAnyChanges, &bOscillating, bLockLeft, bLockRight);
263                        if (bOscillating)
264                                {
265                                ProgressStepsDone();
266                                goto Osc;
267                                }
268                        if (bAnyChanges)
269                                {
270                                bAnyChangesThisIter = true;
271                                bAnyChangesAnyIter = true;
272                                }
273                        }
274
275                ProgressStepsDone();
276                if (bOscillating)
277                        break;
278
279                if (!bAnyChangesThisIter)
280                        break;
281                }
282
283Osc:
284        delete[] InternalNodeIndexes;
285        delete[] InternalNodeIndexesR;
286
287        return bAnyChangesAnyIter;
288        }
Note: See TracBrowser for help on using the repository browser.