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

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

added muscle sourcles amd makefile

File size: 10.2 KB
Line 
1#include "muscle.h"
2#include "profile.h"
3#include "pwpath.h"
4
5#define OCC     1
6
7struct DP_MEMORY
8        {
9        unsigned uLength;
10        SCORE *GapOpenA;
11        SCORE *GapOpenB;
12        SCORE *GapCloseA;
13        SCORE *GapCloseB;
14        SCORE *MPrev;
15        SCORE *MCurr;
16        SCORE *MWork;
17        SCORE *DPrev;
18        SCORE *DCurr;
19        SCORE *DWork;
20        SCORE **ScoreMxB;
21#if     OCC
22        FCOUNT *OccA;
23        FCOUNT *OccB;
24#endif
25        unsigned **SortOrderA;
26        unsigned *uDeletePos;
27        FCOUNT **FreqsA;
28        int **TraceBack;
29        };
30
31static struct DP_MEMORY DPM;
32
33static void AllocDPMem(unsigned uLengthA, unsigned uLengthB)
34        {
35// Max prefix length
36        unsigned uLength = (uLengthA > uLengthB ? uLengthA : uLengthB) + 1;
37        if (uLength < DPM.uLength)
38                return;
39
40// Add 256 to allow for future expansion and
41// round up to next multiple of 32.
42        uLength += 256;
43        uLength += 32 - uLength%32;
44
45        const unsigned uOldLength = DPM.uLength;
46        if (uOldLength > 0)
47                {
48                for (unsigned i = 0; i < uOldLength; ++i)
49                        {
50                        delete[] DPM.TraceBack[i];
51                        delete[] DPM.FreqsA[i];
52                        delete[] DPM.SortOrderA[i];
53                        }
54                for (unsigned n = 0; n < 20; ++n)
55                        delete[] DPM.ScoreMxB[n];
56
57                delete[] DPM.MPrev;
58                delete[] DPM.MCurr;
59                delete[] DPM.MWork;
60                delete[] DPM.DPrev;
61                delete[] DPM.DCurr;
62                delete[] DPM.DWork;
63                delete[] DPM.uDeletePos;
64                delete[] DPM.GapOpenA;
65                delete[] DPM.GapOpenB;
66                delete[] DPM.GapCloseA;
67                delete[] DPM.GapCloseB;
68                delete[] DPM.SortOrderA;
69                delete[] DPM.FreqsA;
70                delete[] DPM.ScoreMxB;
71                delete[] DPM.TraceBack;
72#if     OCC
73                delete[] DPM.OccA;
74                delete[] DPM.OccB;
75#endif
76                }
77
78        DPM.uLength = uLength;
79
80        DPM.GapOpenA = new SCORE[uLength];
81        DPM.GapOpenB = new SCORE[uLength];
82        DPM.GapCloseA = new SCORE[uLength];
83        DPM.GapCloseB = new SCORE[uLength];
84#if     OCC
85        DPM.OccA = new FCOUNT[uLength];
86        DPM.OccB = new FCOUNT[uLength];
87#endif
88
89        DPM.SortOrderA = new unsigned*[uLength];
90        DPM.FreqsA = new FCOUNT*[uLength];
91        DPM.ScoreMxB = new SCORE*[20];
92        DPM.MPrev = new SCORE[uLength];
93        DPM.MCurr = new SCORE[uLength];
94        DPM.MWork = new SCORE[uLength];
95
96        DPM.DPrev = new SCORE[uLength];
97        DPM.DCurr = new SCORE[uLength];
98        DPM.DWork = new SCORE[uLength];
99        DPM.uDeletePos = new unsigned[uLength];
100
101        DPM.TraceBack = new int*[uLength];
102
103        for (unsigned uLetter = 0; uLetter < 20; ++uLetter)
104                DPM.ScoreMxB[uLetter] = new SCORE[uLength];
105
106        for (unsigned i = 0; i < uLength; ++i)
107                {
108                DPM.SortOrderA[i] = new unsigned[20];
109                DPM.FreqsA[i] = new FCOUNT[20];
110                DPM.TraceBack[i] = new int[uLength];
111                }
112        }
113
114SCORE GlobalAlignLA(const ProfPos *PA, unsigned uLengthA, const ProfPos *PB,
115  unsigned uLengthB, PWPath &Path)
116        {
117        const unsigned uPrefixCountA = uLengthA + 1;
118        const unsigned uPrefixCountB = uLengthB + 1;
119
120        AllocDPMem(uLengthA, uLengthB);
121
122        SCORE *GapOpenA = DPM.GapOpenA;
123        SCORE *GapOpenB = DPM.GapOpenB;
124        SCORE *GapCloseA = DPM.GapCloseA;
125        SCORE *GapCloseB = DPM.GapCloseB;
126
127        unsigned **SortOrderA = DPM.SortOrderA;
128        FCOUNT **FreqsA = DPM.FreqsA;
129        SCORE **ScoreMxB = DPM.ScoreMxB;
130        SCORE *MPrev = DPM.MPrev;
131        SCORE *MCurr = DPM.MCurr;
132        SCORE *MWork = DPM.MWork;
133
134        SCORE *DPrev = DPM.DPrev;
135        SCORE *DCurr = DPM.DCurr;
136        SCORE *DWork = DPM.DWork;
137
138#if     OCC
139        FCOUNT *OccA = DPM.OccA;
140        FCOUNT *OccB = DPM.OccB;
141#endif
142
143        unsigned *uDeletePos = DPM.uDeletePos;
144
145        int **TraceBack = DPM.TraceBack;
146
147        for (unsigned i = 0; i < uLengthA; ++i)
148                {
149                GapOpenA[i] = PA[i].m_scoreGapOpen;
150                GapCloseA[i] = PA[i].m_scoreGapClose;
151#if     OCC
152                OccA[i] = PA[i].m_fOcc;
153#endif
154
155                for (unsigned uLetter = 0; uLetter < 20; ++uLetter)
156                        {
157                        SortOrderA[i][uLetter] = PA[i].m_uSortOrder[uLetter];
158                        FreqsA[i][uLetter] = PA[i].m_fcCounts[uLetter];
159                        }
160                }
161
162        for (unsigned j = 0; j < uLengthB; ++j)
163                {
164                GapOpenB[j] = PB[j].m_scoreGapOpen;
165                GapCloseB[j] = PB[j].m_scoreGapClose;
166#if     OCC
167                OccB[j] = PB[j].m_fOcc;
168#endif
169                }
170
171        for (unsigned uLetter = 0; uLetter < 20; ++uLetter)
172                {
173                for (unsigned j = 0; j < uLengthB; ++j)
174                        ScoreMxB[uLetter][j] = PB[j].m_AAScores[uLetter];
175                }
176
177        for (unsigned i = 0; i < uPrefixCountA; ++i)
178                memset(TraceBack[i], 0, uPrefixCountB*sizeof(int));
179
180// Special case for i=0
181        unsigned **ptrSortOrderA = SortOrderA;
182        FCOUNT **ptrFreqsA = FreqsA;
183        assert(ptrSortOrderA == &(SortOrderA[0]));
184        assert(ptrFreqsA == &(FreqsA[0]));
185        TraceBack[0][0] = 0;
186
187        SCORE scoreSum = 0;
188        unsigned *ptrSortOrderAi = SortOrderA[0];
189        const unsigned *ptrSortOrderAEnd = ptrSortOrderAi + 20;
190        FCOUNT *ptrFreqsAi = FreqsA[0];
191        for (; ptrSortOrderAi != ptrSortOrderAEnd; ++ptrSortOrderAi)
192                {
193                const unsigned uLetter = *ptrSortOrderAi;
194                const FCOUNT fcLetter = ptrFreqsAi[uLetter];
195                if (0 == fcLetter)
196                        break;
197                scoreSum += fcLetter*ScoreMxB[uLetter][0];
198                }
199        if (0 == scoreSum)
200                MPrev[0] = -2.5;
201        else
202                {
203#if     OCC
204                MPrev[0] = (logf(scoreSum) - g_scoreCenter)*OccA[0]*OccB[0];
205#else
206                MPrev[0] = (logf(scoreSum) - g_scoreCenter);
207#endif
208                }
209
210// D(0,0) is -infinity (requires I->D).
211        DPrev[0] = MINUS_INFINITY;
212
213        for (unsigned j = 1; j < uLengthB; ++j)
214                {
215        // Only way to get M(0, j) looks like this:
216        //              A       ----X
217        //              B       XXXXX
218        //                      0   j
219        // So gap-open at j=0, gap-close at j-1.
220                SCORE scoreSum = 0;
221                unsigned *ptrSortOrderAi = SortOrderA[0];
222                const unsigned *ptrSortOrderAEnd = ptrSortOrderAi + 20;
223                FCOUNT *ptrFreqsAi = FreqsA[0];
224                for (; ptrSortOrderAi != ptrSortOrderAEnd; ++ptrSortOrderAi)
225                        {
226                        const unsigned uLetter = *ptrSortOrderAi;
227                        const FCOUNT fcLetter = ptrFreqsAi[uLetter];
228                        if (0 == fcLetter)
229                                break;
230                        scoreSum += fcLetter*ScoreMxB[uLetter][j];
231                        }
232                if (0 == scoreSum)
233                        MPrev[j] = -2.5;
234                else
235                        {
236#if     OCC
237                        MPrev[j] = (logf(scoreSum) - g_scoreCenter)*OccA[0]*OccB[j] +
238                          GapOpenB[0] + GapCloseB[j-1];
239#else
240                        MPrev[j] = (logf(scoreSum) - g_scoreCenter) +
241                          GapOpenB[0] + GapCloseB[j-1];
242#endif
243                        }
244                TraceBack[0][j] = -(int) j;
245
246        // Assume no D->I transitions, then can't be a delete if only
247        // one letter from A.
248                DPrev[j] = MINUS_INFINITY;
249                }
250
251        SCORE IPrev_j_1;
252        for (unsigned i = 1; i < uLengthA; ++i)
253                {
254                ++ptrSortOrderA;
255                ++ptrFreqsA;
256                assert(ptrSortOrderA == &(SortOrderA[i]));
257                assert(ptrFreqsA == &(FreqsA[i]));
258
259                SCORE *ptrMCurr_j = MCurr;
260                memset(ptrMCurr_j, 0, uLengthB*sizeof(SCORE));
261                const FCOUNT *FreqsAi = *ptrFreqsA;
262
263                const unsigned *SortOrderAi = *ptrSortOrderA;
264                const unsigned *ptrSortOrderAiEnd = SortOrderAi + 20;
265                const SCORE *ptrMCurrMax = MCurr + uLengthB;
266                for (const unsigned *ptrSortOrderAi = SortOrderAi;
267                  ptrSortOrderAi != ptrSortOrderAiEnd;
268                  ++ptrSortOrderAi)
269                        {
270                        const unsigned uLetter = *ptrSortOrderAi;
271                        SCORE *NSBR_Letter = ScoreMxB[uLetter];
272                        const FCOUNT fcLetter = FreqsAi[uLetter];
273                        if (0 == fcLetter)
274                                break;
275                        SCORE *ptrNSBR = NSBR_Letter;
276                        for (SCORE *ptrMCurr = MCurr; ptrMCurr != ptrMCurrMax; ++ptrMCurr)
277                                *ptrMCurr += fcLetter*(*ptrNSBR++);
278                        }
279
280#if     OCC
281                const FCOUNT OccAi = OccA[i];
282#endif
283                for (unsigned j = 0; j < uLengthB; ++j)
284                        {
285                        if (MCurr[j] == 0)
286                                MCurr[j] = -2.5;
287                        else
288#if     OCC
289                                MCurr[j] = (logf(MCurr[j]) - g_scoreCenter)*OccAi*OccB[j];
290#else
291                                MCurr[j] = (logf(MCurr[j]) - g_scoreCenter);
292#endif
293                        }
294
295                ptrMCurr_j = MCurr;
296                unsigned *ptrDeletePos = uDeletePos;
297
298        // Special case for j=0
299        // Only way to get M(i, 0) looks like this:
300        //                      0   i
301        //              A       XXXXX
302        //              B       ----X
303        // So gap-open at i=0, gap-close at i-1.
304                assert(ptrMCurr_j == &(MCurr[0]));
305                *ptrMCurr_j += GapOpenA[0] + GapCloseA[i-1];
306
307                ++ptrMCurr_j;
308
309                int *ptrTraceBack_ij = TraceBack[i];
310                *ptrTraceBack_ij++ = (int) i;
311
312                SCORE *ptrMPrev_j = MPrev;
313                SCORE *ptrDPrev = DPrev;
314                SCORE d = *ptrDPrev;
315                SCORE DNew = *ptrMPrev_j + GapOpenA[i];
316                if (DNew > d)
317                        {
318                        d = DNew;
319                        *ptrDeletePos = i;
320                        }
321
322                SCORE *ptrDCurr = DCurr;
323
324                assert(ptrDCurr == &(DCurr[0]));
325                *ptrDCurr = d;
326
327        // Can't have an insert if no letters from B
328                IPrev_j_1 = MINUS_INFINITY;
329
330                unsigned uInsertPos;
331                const SCORE scoreGapOpenAi = GapOpenA[i];
332                const SCORE scoreGapCloseAi_1 = GapCloseA[i-1];
333
334                for (unsigned j = 1; j < uLengthB; ++j)
335                        {
336                // Here, MPrev_j is preserved from previous
337                // iteration so with current i,j is M[i-1][j-1]
338                        SCORE MPrev_j = *ptrMPrev_j;
339                        SCORE INew = MPrev_j + GapOpenB[j];
340                        if (INew > IPrev_j_1)
341                                {
342                                IPrev_j_1 = INew;
343                                uInsertPos = j;
344                                }
345
346                        SCORE scoreMax = MPrev_j;
347
348                        assert(ptrDPrev == &(DPrev[j-1]));
349                        SCORE scoreD = *ptrDPrev++ + scoreGapCloseAi_1;
350                        if (scoreD > scoreMax)
351                                {
352                                scoreMax = scoreD;
353                                assert(ptrDeletePos == &(uDeletePos[j-1]));
354                                *ptrTraceBack_ij = (int) i - (int) *ptrDeletePos;
355                                assert(*ptrTraceBack_ij > 0);
356                                }
357                        ++ptrDeletePos;
358
359                        SCORE scoreI = IPrev_j_1 + GapCloseB[j-1];
360                        if (scoreI > scoreMax)
361                                {
362                                scoreMax = scoreI;
363                                *ptrTraceBack_ij = (int) uInsertPos - (int) j;
364                                assert(*ptrTraceBack_ij < 0);
365                                }
366
367                        assert(ptrSortOrderA == &(SortOrderA[i]));
368                        assert(ptrFreqsA == &(FreqsA[i]));
369
370                        *ptrMCurr_j += scoreMax;
371                        assert(ptrMCurr_j == &(MCurr[j]));
372                        ++ptrMCurr_j;
373
374                        MPrev_j = *(++ptrMPrev_j);
375                        assert(ptrDPrev == &(DPrev[j]));
376                        SCORE d = *ptrDPrev;
377                        SCORE DNew = MPrev_j + scoreGapOpenAi;
378                        if (DNew > d)
379                                {
380                                d = DNew;
381                                assert(ptrDeletePos == &uDeletePos[j]);
382                                *ptrDeletePos = i;
383                                }
384                        assert(ptrDCurr + 1 == &(DCurr[j]));
385                        *(++ptrDCurr) = d;
386
387                        ++ptrTraceBack_ij;
388                        }
389
390                Rotate(MPrev, MCurr, MWork);
391                Rotate(DPrev, DCurr, DWork);
392                }
393
394// Special case for i=uLengthA
395        SCORE IPrev = MINUS_INFINITY;
396
397        unsigned uInsertPos;
398
399        for (unsigned j = 1; j < uLengthB; ++j)
400                {
401                SCORE INew = MPrev[j-1] + GapOpenB[j];
402                if (INew > IPrev)
403                        {
404                        uInsertPos = j;
405                        IPrev = INew;
406                        }
407                }
408
409// Special case for i=uLengthA, j=uLengthB
410        SCORE scoreMax = MPrev[uLengthB-1];
411        int iTraceBack = 0;
412
413        SCORE scoreD = DPrev[uLengthB-1] + GapCloseA[uLengthA-1];
414        if (scoreD > scoreMax)
415                {
416                scoreMax = scoreD;
417                iTraceBack = (int) uLengthA - (int) uDeletePos[uLengthB-1];
418                }
419
420        SCORE scoreI = IPrev + GapCloseB[uLengthB-1];
421        if (scoreI > scoreMax)
422                {
423                scoreMax = scoreI;
424                iTraceBack = (int) uInsertPos - (int) uLengthB;
425                }
426
427        TraceBack[uLengthA][uLengthB] = iTraceBack;
428
429        TraceBackToPath(TraceBack, uLengthA, uLengthB, Path);
430
431        return scoreMax;
432        }
Note: See TracBrowser for help on using the repository browser.