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

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

added muscle sourcles amd makefile

File size: 3.4 KB
Line 
1#include "muscle.h"
2#include "profile.h"
3#include "diaglist.h"
4
5#define TRACE   0
6
7#define pow4(i) (1 << (2*i))    // 4^i = 2^(2*i)
8const unsigned K = 7;
9const unsigned KTUPS = pow4(K);
10static unsigned TuplePos[KTUPS];
11
12static char *TupleToStr(int t)
13        {
14        static char s[K];
15
16        for (int i = 0; i < K; ++i)
17                {
18                unsigned Letter = (t/(pow4(i)))%4;
19                assert(Letter >= 0 && Letter < 4);
20                s[K-i-1] = LetterToChar(Letter);
21                }
22
23        return s;
24        }
25
26static unsigned GetTuple(const ProfPos *PP, unsigned uPos)
27        {
28        unsigned t = 0;
29
30        for (unsigned i = 0; i < K; ++i)
31                {
32                const unsigned uLetter = PP[uPos+i].m_uResidueGroup;
33                if (RESIDUE_GROUP_MULTIPLE == uLetter)
34                        return EMPTY;
35                t = t*4 + uLetter;
36                }
37
38        return t;
39        }
40
41void FindDiagsNuc(const ProfPos *PX, unsigned uLengthX, const ProfPos *PY,
42  unsigned uLengthY, DiagList &DL)
43        {
44        if (ALPHA_DNA != g_Alpha && ALPHA_RNA != g_Alpha)
45                Quit("FindDiagsNuc: requires nucleo alphabet");
46
47        DL.Clear();
48
49// 16 is arbitrary slop, no principled reason for this.
50        if (uLengthX < K + 16 || uLengthY < K + 16)
51                return;
52
53// Set A to shorter profile, B to longer
54        const ProfPos *PA;
55        const ProfPos *PB;
56        unsigned uLengthA;
57        unsigned uLengthB;
58        bool bSwap;
59        if (uLengthX < uLengthY)
60                {
61                bSwap = false;
62                PA = PX;
63                PB = PY;
64                uLengthA = uLengthX;
65                uLengthB = uLengthY;
66                }
67        else
68                {
69                bSwap = true;
70                PA = PY;
71                PB = PX;
72                uLengthA = uLengthY;
73                uLengthB = uLengthX;
74                }
75
76#if     TRACE
77        Log("FindDiagsNuc(LengthA=%d LengthB=%d\n", uLengthA, uLengthB);
78#endif
79
80// Build tuple map for the longer profile, B
81        if (uLengthB < K)
82                Quit("FindDiags: profile too short");
83
84        memset(TuplePos, EMPTY, sizeof(TuplePos));
85
86        for (unsigned uPos = 0; uPos < uLengthB - K; ++uPos)
87                {
88                const unsigned uTuple = GetTuple(PB, uPos);
89                if (EMPTY == uTuple)
90                        continue;
91                TuplePos[uTuple] = uPos;
92                }
93
94// Find matches
95        for (unsigned uPosA = 0; uPosA < uLengthA - K; ++uPosA)
96                {
97                const unsigned uTuple = GetTuple(PA, uPosA);
98                if (EMPTY == uTuple)
99                        continue;
100                const unsigned uPosB = TuplePos[uTuple];
101                if (EMPTY == uPosB)
102                        continue;
103
104        // This tuple is found in both profiles
105                unsigned uStartPosA = uPosA;
106                unsigned uStartPosB = uPosB;
107
108        // Try to extend the match forwards
109                unsigned uEndPosA = uPosA + K - 1;
110                unsigned uEndPosB = uPosB + K - 1;
111                for (;;)
112                        {
113                        if (uLengthA - 1 == uEndPosA || uLengthB - 1 == uEndPosB)
114                                break;
115                        const unsigned uAAGroupA = PA[uEndPosA+1].m_uResidueGroup;
116                        if (RESIDUE_GROUP_MULTIPLE == uAAGroupA)
117                                break;
118                        const unsigned uAAGroupB = PB[uEndPosB+1].m_uResidueGroup;
119                        if (RESIDUE_GROUP_MULTIPLE == uAAGroupB)
120                                break;
121                        if (uAAGroupA != uAAGroupB)
122                                break;
123                        ++uEndPosA;
124                        ++uEndPosB;
125                        }
126                uPosA = uEndPosA;
127
128#if     TRACE
129                {
130                Log("Match: A %4u-%4u   ", uStartPosA, uEndPosA);
131                for (unsigned n = uStartPosA; n <= uEndPosA; ++n)
132                        Log("%c", LetterToChar(PA[n].m_uResidueGroup));
133                Log("\n");
134                Log("       B %4u-%4u   ", uStartPosB, uEndPosB);
135                for (unsigned n = uStartPosB; n <= uEndPosB; ++n)
136                        Log("%c", LetterToChar(PB[n].m_uResidueGroup));
137                Log("\n");
138                }
139#endif
140
141                const unsigned uLength = uEndPosA - uStartPosA + 1;
142                assert(uEndPosB - uStartPosB + 1 == uLength);
143
144                if (uLength >= g_uMinDiagLength)
145                        {
146                        if (bSwap)
147                                DL.Add(uStartPosB, uStartPosA, uLength);
148                        else
149                                DL.Add(uStartPosA, uStartPosB, uLength);
150                        }
151                }
152        }
Note: See TracBrowser for help on using the repository browser.