1
/* ===========================================================================
4
* National Center for Biotechnology Information
6
* This software/database is a "United States Government Work" under the
7
* terms of the United States Copyright Act. It was written as part of
8
* the author's official duties as a United States Government employee and
9
* thus cannot be copyrighted. This software/database is freely available
10
* to the public for use. The National Library of Medicine and the U.S.
11
* Government have not placed any restriction on its use or reproduction.
13
* Although all reasonable efforts have been taken to ensure the accuracy
14
* and reliability of the software and data, the NLM and the U.S.
15
* Government do not and cannot warrant the performance or results that
16
* may be obtained by using this software or data. The NLM and the U.S.
17
* Government disclaim all warranties, express or implied, including
18
* warranties of performance, merchantability or fitness for any particular
21
* Please cite the author in any work or product based on this material.
23
* ==========================================================================*/
25
/****************************************************************************
29
Author: Gennadiy Savchuk, Jinqhui Zhang, Tom Madden
31
Contents: Functions to perform global banded alignment.
33
***************************************************************************/
37
static Int4 g_band3_align(Uint1Ptr A, Uint1Ptr B,
39
Int4 low, Int4 up, data_t *data);
41
static Int4 g_band3_CHECK_SCORE(Uint1Ptr A, Uint1Ptr B,
43
Int4 PNTR S, data_t *data);
45
Int4 LIBCALL gband_linear_qgap(Uint1Ptr A, Uint1Ptr B,
48
PSUGapOptionsPtr option,
49
Int4Ptr S, Int4Ptr Slen)
57
/* Setup global parameters */
58
data.g = option->gopen;
59
data.zzh = option->gext;
61
data.m = data.g + data.zzh;
67
low = option->start_diag;
71
low = MIN(MAX(-M, low),MIN(N-M,0));
72
up = MAX(MIN(N, up),MAX(N-M,0));
74
if(up < 0 || low > 0) {
75
ErrPostEx(SEV_WARNING, 0, 0,
76
"The band does not include (0,0) grid point");
79
if(up+M < N || low+M > N) {
80
ErrPostEx(SEV_WARNING, 0, 0,
81
"The band does not include lower corner");
93
if((band = up - low + 1) <= 1) {
95
for(i = 1; i <= M; i++) {
97
c += data.w[A[i]][B[i]];
102
j = (band+2) * sizeof(Int4);
103
data.leggA = data.leggB = data.reggA = data.reggB = data.leghA =
104
data.leghB = data.reghA = data.reghB = 0;
106
data.CD = (dp_ptr)MemGet(sizeof(dp_node) * (band + 2), MGET_ERRPOST);
108
/* if((c = g_band3_align(A,B,M,N,low,up,0,0)) != (score = g_band3_CHECK_SCORE(A,B,M,N,S))) */
109
c = g_band3_align(A, B, M, N, low, up, &data);
110
score = g_band3_CHECK_SCORE(A, B, M, N, S, &data);
112
ErrPostEx(SEV_WARNING, 0, 0, "Check_Score = %ld align_score = %ld ",
113
(long) score, (long) c);
118
*Slen = data.sapp - S;
123
/* g_band3_CHECK_SCORE - return the score of the alignment stored in S */
125
static Int4 g_band3_CHECK_SCORE(Uint1Ptr A, Uint1Ptr B,
127
Int4 PNTR S, data_t *data)
129
register Int4 i, j, op;
132
score = i = j = op = 0;
134
score -= data->leggA - *S * data->leghA;
136
} else if ((*S) > 0) {
137
score -= data->leggB + *S * data->leghB;
140
while (i < M || j < N) {
143
score = data->w[A[++i]][B[++j]] + score;
145
score = score - (data->g + op * data->zzh);
149
score = score - (data->g - op * data->zzh);
154
score += (data->g - op * data->zzh) - (data->reggA - data->reghA * op);
156
score += (data->g + op * data->zzh) - (data->reggB + data->reghB * op);
163
/* g_band3_align(A, B, M, N, up, low, tb, te, data) returns the cost
164
of an optimum conversion between
165
A[1..M] and B[1..N] and appends such a conversion to the current script.
166
tb(te)= 1 no gap-open penalty if the conversion begins(ends) with a delete.
167
tb(te)= 2 no gap-open penalty if the conversion begins(ends) with an insert.
169
static Int4 g_band3_align(Uint1Ptr A, Uint1Ptr B,
171
Int4 low, Int4 up, data_t *data)
175
Int4 leftd, rightd; /* for CC, DD, CP and DP */
176
register Int4 curd; /* current index for CC, DD CP and DP */
178
register Int4 c, d, e, x;
182
Int1Ptr PNTR state, st, tmp;
183
Int4 ib, best=MININT, X, Y;
186
/* Boundary cases: M <= 0 , N <= 0, or up-low <= 0 */
188
state = (Int1Ptr PNTR) MemGet(sizeof(Int1Ptr)*(M+1), MGET_ERRPOST);
189
state[0] = (Int1Ptr) MemGet((M+1)*(band+2), MGET_ERRPOST);
190
for (i = 1; i <= M; i++) state[i] = state[i-1]+band+2;
196
data->CD[leftd].CC = 0; state[0][leftd] = -1;
199
for(j = leftd + 1; j <= rightd; j++) {
200
data->CD[j].CC = t = t - data->leghB;
201
data->CD[j-1].DD = t - data->m;
204
data->CD[rightd+1].CC = MININT;
205
data->CD[rightd].DD = MININT;
206
data->CD[leftd-1].DD = -data->leggA;
207
data->CD[leftd-1].CC = MININT;
208
for (i = 1; i <= M; i++) {
209
if (i > N-up) rightd--;
210
if (leftd > 1) leftd--;
212
d = data->CD[leftd].DD;
214
if ((ib = leftd+low-1+i) > 0) c = data->CD[leftd].CC+wa[B[ib]];
215
if (d > c || ib <= 0) {
221
data->CD[leftd - 1].DD = d - data->leghA;
224
st = &state[i][leftd];
226
data->CD[leftd].CC = c;
227
for(curd = leftd + 1, ap = &data->CD[curd]; curd <= rightd; curd++) {
228
c = ap->CC + wa[B[curd + low - 1 + i]];
229
if((d = ap->DD) > c) {
239
(ap++ - 1)->DD = d - data->zzh;
244
(ap++ - 1)->DD = d - data->zzh;
249
if((c -= data->m) > (e -= data->zzh)) {
250
if(c > (d -= data->zzh)) {
251
(ap++ - 1)->DD = e = c;
261
if(c > (d -= data->zzh)) {
273
best < (j = (ap - 1)->CC - data->reggA - (N - i) * data->reghA)) {
274
best = j; X = i; Y = rightd;
277
for(ap = &data->CD[leftd]; ap <= &data->CD[rightd]; ap++) {
278
if((j = ap->CC - data->reggB - data->reghB *
279
(x = (&data->CD[rightd] - ap)))
286
if (data->CD[rightd].CC > best) {X=M; Y= N; best = data->CD[rightd].CC;}
288
tmp = MemGet(M+N, MGET_ERRPOST);
289
for (i = X, j = Y, e=0, c = 0; i>=0; i--, c++) {
290
k = (t=state[i][j]) %10;
292
if (e == 1 && (t/10)%2 == 1) k = 1;
293
if (e == 2 && (t/20)== 1) k = 2;
294
if (k == 1) { j--; i++;}
295
else if (k == 2) j++;
299
for (i = c-1; i >= 0; i--)
311
if(X != M) _DEL(M - X)
312
else if(Y != rightd) _INS(rightd-Y)