1 /* dispn.c associated subroutines for matching sequences */
2
3 /* $Id: c_dispn.c 1124 2013-03-13 20:24:57Z wrp $ */
4 /* $Revision: 1124 $ */
5
6 /* copyright (c) 1988, 1995, 1996, 2008, 2013, 2014 by William R. Pearson and
7 The Rector and Visitors of the University of Virginia */
8
9 /* Licensed under the Apache License, Version 2.0 (the "License");
10 you may not use this file except in compliance with the License.
11 You may obtain a copy of the License at
12
13 http://www.apache.org/licenses/LICENSE-2.0
14
15 Unless required by applicable law or agreed to in writing,
16 software distributed under this License is distributed on an "AS
17 IS" BASIS, WITHOUT WRRANTIES OR CONDITIONS OF ANY KIND, either
18 express or implied. See the License for the specific language
19 governing permissions and limitations under the License.
20 */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26
27 #include "defs.h"
28 #include "structs.h"
29 #include "param.h"
30
31 #define XTERNAL
32
33 #define YES 1
34 #define NO 0
35
36 #define MAXOUT 201
37
38 /* the seqca[] array has the following codes:
39 0 - no alignment symbol
40 1 - align; pam < 0
41 2 - align; pam == 0
42 3 - align; pam > 0
43 4 - align; ident
44 5 - align; del
45
46 the map_sym arrays determine the value to be displayed with each
47 type of aligned residue
48 */
49
50 #include "a_mark.h"
51
52 void
discons(FILE * fd,const struct mngmsg * m_msp,char * seqc0,char * seqc0a,char * seqc1,char * seqc1a,char * seqca,int * cumm_seq_score,int nc,int n0,int n1,char * name0,char * name1,int nml,struct a_struct * aln)53 discons(FILE *fd, const struct mngmsg *m_msp,
54 char *seqc0, char *seqc0a,
55 char *seqc1, char *seqc1a,
56 char *seqca, int *cumm_seq_score, int nc,
57 int n0, int n1, char *name0, char *name1, int nml,
58 struct a_struct *aln)
59 {
60 char line[3][MAXOUT]; /* alignment lines [0,2], similarity code [1] */
61 char cline[2][MAXOUT+10], *clinep[2]; /* coordinate line */
62 int il, i, lend, loff, id, tot_score;
63 int del0, del1, ic, ll0, ll1, ll01, cl0, cl1, rl0, rl1;
64 int ic_save;
65 char *map_sym_p;
66 int l_llen;
67 int ioff0, ioff00, ioff1, ioff10;
68 long q_start, q_end, qf_flag, s_start, s_end, sf_flag;
69 long qqoff, lloff;
70 int llsgn, llfact, qlsgn, qlfact, qfx0, qfxn, lfx0, lfxn;
71 long s_digit_max, q_digit_max;
72 char digit_tmp[32];
73 int digit_len;
74 int have_res;
75 char *name01;
76 char blank[32], afmt[32], afmt0[32];
77 int disp_dna_align = ((m_msp->qdnaseq>0) && (m_msp->ldb_info.ldnaseq > 0));
78
79 memset(blank,' ',sizeof(blank)-1);
80 blank[sizeof(blank)-1]='\0';
81
82 clinep[0]=cline[0]+1;
83 clinep[1]=cline[1]+1;
84
85 if (aln->qlfact == 0) {qlfact = 1;}
86 else qlfact = aln->qlfact;
87 if (aln->qlrev == 1) {
88 qlsgn = -1;
89 qfx0 = 0;
90 qfxn = 1;
91 }
92 else {
93 qlsgn = 1;
94 qfx0 = 1;
95 qfxn = 0;
96 }
97
98 if (aln->llfact == 0) {llfact = 1;}
99 else llfact = aln->llfact;
100
101 if (aln->llrev == 1) {
102 llsgn = -1;
103 lfx0 = 0;
104 lfxn = 1;
105 }
106 else {
107 llsgn = 1;
108 lfx0 = 1;
109 lfxn = 0;
110 }
111
112 l_llen = aln->llen;
113 if ((m_msp->markx & MX_M9SUMM) && m_msp->show_code != 1) { l_llen += 40; }
114
115 if ((m_msp->markx & MX_ATYPE)==2) name01=name1;
116 else name01 = "\0";
117
118 ioff0=aln->smin0;
119 ioff00 = ioff0;
120 ioff1=aln->smin1;
121 ioff10 = ioff1;
122
123 if (m_msp->markx& MX_AMAP && (m_msp->markx & MX_ATYPE)==7) return;
124
125 /* set *map_sym_p to correct match symbol */
126 map_sym_p = aln_map_sym[MX_A0];
127 if ((m_msp->markx&MX_ATYPE)==1) {map_sym_p = aln_map_sym[MX_A1];}
128 else if ((m_msp->markx&MX_ATYPE)==2) {map_sym_p = aln_map_sym[MX_A2];}
129 else if (m_msp->markx&MX_M10FORM) { map_sym_p = aln_map_sym[MX_A10]; }
130 if (m_msp->markx & MX_MBLAST) { map_sym_p = aln_map_sym[MX_ABLAST];}
131
132 if (m_msp->markx & MX_ASEP) {
133 fprintf(fd,">%s ..\n",name0);
134 for (i=0; i<nc && seqc0[i]; i++) {
135 /* if (seqc0[i]=='-') fputc('.',fd); else */
136 fputc(seqc0[i],fd);
137 if (i%50 == 49) fputc('\n',fd);
138 }
139 if ((i-1)%50 != 49) fputc('\n',fd);
140 fprintf(fd,">%s ..\n",name1);
141 for (i=0; i<nc && seqc1[i]; i++) {
142 /* if (seqc1[i]=='-') fputc('.',fd); else */
143 fputc(seqc1[i],fd);
144 if (i%50 == 49) fputc('\n',fd);
145 }
146 if ((i-1)%50 != 49) fputc('\n',fd);
147 return;
148 }
149
150 if (m_msp->markx & MX_M10FORM) {
151 fprintf(fd,">%s ..\n",name0);
152 fprintf(fd,"; sq_len: %d\n",n0);
153 fprintf(fd,"; sq_offset: %ld\n",aln->q_offset+1);
154 fprintf(fd,"; sq_type: %c\n",m_msp->sqtype[0]);
155 fprintf(fd,"; al_start: %ld\n",aln->d_start0);
156 fprintf(fd,"; al_stop: %ld\n",aln->d_stop0);
157 /* in the past, this al_display_start does not include sq0off */
158 fprintf(fd,"; al_display_start: %ld\n",
159 aln->q_offset+qlsgn*ioff0*aln->llmult+qfx0);
160
161 have_res = 0;
162 for (i=0; i<nc && seqc0[i]; i++) {
163 if (!have_res && seqc0[i]==' ') fputc('-',fd);
164 else if (seqc0[i]==' ') break;
165 else {
166 have_res = 1;
167 fputc(seqc0[i],fd);
168 }
169 if (i%50 == 49) fputc('\n',fd);
170 }
171 if ((i-1)%50!=49 || seqc0[i-1]==' ') fputc('\n',fd);
172 fprintf(fd,">%s ..\n",name1);
173 fprintf(fd,"; sq_len: %d\n",n1);
174 fprintf(fd,"; sq_offset: %ld\n",aln->l_offset+1);
175 fprintf(fd,"; sq_type: %c\n",m_msp->sqtype[0]);
176 fprintf(fd,"; al_start: %ld\n",aln->d_start1);
177 fprintf(fd,"; al_stop: %ld\n",aln->d_stop1);
178 /* in the past, this al_display_start does not include sq1off */
179 fprintf(fd,"; al_display_start: %ld\n",aln->l_offset+llsgn*ioff1+lfx0);
180
181 have_res = 0;
182 for (i=0; i<nc && seqc1[i]; i++) {
183 if (!have_res && seqc1[i]==' ') fputc('-',fd);
184 else if (seqc1[i]==' ') break;
185 else {
186 have_res = 1;
187 fputc(seqc1[i],fd);
188 }
189 if (i%50 == 49) fputc('\n',fd);
190 }
191 if ((i-1)%50!=49 || seqc1[i-1]==' ') fputc('\n',fd);
192 #ifdef M10_CONS
193 fprintf(fd,"; al_cons:\n");
194 for (i=0,del0=0,id=ioff0; id-del0<aln->amax0 && i < nc; i++,id++) {
195 if (seqc0[i] == '\0' || seqc1[i] == '\0') break;
196 if (seqc0[i]=='-' || seqc0[i]==' ' || seqc0[i]=='\\') del0++;
197 else if (seqc0[i]=='/') del0++;
198 if (id-del0<aln->amin0) fputc(' ',fd);
199 else if (seqc0[i]=='-'||seqc1[i]=='-') fputc('-',fd);
200 else fputc(map_sym_p[seqca[i]],fd);
201
202 if (i%50 == 49) fputc('\n',fd);
203 }
204 if ((i-1)%50!=49 || seqc1[i-1]==' ') fputc('\n',fd);
205 #endif
206 return;
207 }
208 else if (m_msp->markx & MX_RES_ALIGN_SCORE) {
209 have_res = 0;
210 tot_score = 0;
211 del0 = del1 = 0;
212 fprintf(fd,">%s\t%s\t%s0\t%s1\tscore\ttotal\n",
213 name0,name1,m_msp->sqnam,m_msp->sqnam);
214 for (ic=0; ic<nc; ic++, ioff0++, ioff1++) {
215 if (seqc0[ic] == ' ' || seqc0[ic] == '-' || seqc0[ic] == '/' || seqc0[ic] == '\\') {
216 del0++;
217 }
218 if (seqc1[ic] == ' ' || seqc1[ic] == '-' || seqc1[ic] == '/' || seqc1[ic] == '\\') {
219 del1++;
220 }
221
222 tot_score += cumm_seq_score[ic];
223 fprintf(fd,"%ld\t%ld\t%c\t%c\t%d\t%d\n",
224 aln->q_offset+qlsgn*(ioff0-del0)*aln->llmult+qfx0,
225 aln->l_offset+llsgn*(ioff1-del1)+lfx0,
226 seqc0[ic], seqc1[ic], cumm_seq_score[ic], tot_score);
227 }
228 return;
229 }
230
231 memset(line[0],' ',MAXOUT);
232 memset(line[1],' ',MAXOUT);
233 memset(line[2],' ',MAXOUT);
234
235 /* cl0 indicates whether a coordinate should be printed over the first
236 sequence; cl1 indicates a coordinate for the second;
237 */
238
239 ic = 0; del0=del1=0;
240
241 /* we set afmt/afmt0 here, rather than at the start of discons, so
242 we can have accurate values for the max and min query/subject
243 start/end using qlsgn and qlfact
244 */
245
246 if (!(m_msp->markx & MX_MBLAST)) {
247 if (nml > 6) {
248 blank[nml-6]='\0';
249 sprintf(afmt,"%%-%ds %%s\n",nml);
250 }
251 else {
252 blank[0]='\0';
253 SAFE_STRNCPY(afmt,"%-6s %s\n",sizeof(afmt));
254 }
255 }
256 else {
257 /* for MX_MBLAST format, the size of the numbers is a function of
258 the largest numbers in the first or last coordinate - which
259 could be either the query or the library sequence.
260 */
261 if (qlsgn > 0) {q_digit_max = aln->smin0 + (aln->amax0 - aln->amin0); }
262 else {q_digit_max = aln->smin0;}
263 q_digit_max = aln->q_offset + qlsgn*q_digit_max + 1l;
264
265 if (llsgn > 0) {s_digit_max = aln->smin1 + (aln->amax1 - aln->amin1); }
266 else {s_digit_max = aln->smin1;}
267 s_digit_max = aln->l_offset + aln->frame + llsgn*aln->llmult*s_digit_max + 1l;
268
269 sprintf(digit_tmp,"%ld",max(q_digit_max, s_digit_max));
270 digit_len = strlen(digit_tmp);
271 if (digit_len < 4) digit_len = 4;
272
273 sprintf(afmt,"%%-5s %%-%dld %%s %%-ld\n",digit_len);
274 blank[digit_len+6]='\0';
275 SAFE_STRNCPY(afmt0,"%-10s %s\n",sizeof(afmt0));
276 }
277
278 if (aln->d_start0 < aln->d_stop0) qf_flag = 1; else qf_flag = 0;
279 if (aln->d_start1 < aln->d_stop1) sf_flag = 1; else sf_flag = 0;
280
281 for (il=0; il<(nc+l_llen-1)/l_llen; il++) {
282 loff=il*l_llen;
283 lend=min(l_llen,nc-loff);
284
285 ll0 = NO; ll1 = NO;
286
287 memset(cline[0],' ',MAXOUT+1);
288 memset(cline[1],' ',MAXOUT+1);
289
290 ic_save = ic;
291
292 q_start = aln->q_offset + (long)qlsgn*ioff00 +
293 (long)qlsgn*qlfact*(ioff0-del0-ioff00) + qf_flag;
294 s_start = aln->l_offset + /* aln->frame + */
295 (long)llsgn*aln->llmult*ioff10 +
296 (long)llsgn*llfact*(ioff1-del1-ioff10) + sf_flag;
297
298 for (i=0; i<lend; i++, ic++,ioff0++,ioff1++) {
299 cl0 = cl1 = rl0 = rl1 = YES;
300 if ((line[0][i]=seqc0[ic])=='-' || seqc0[ic]=='\\') {
301 del0++; cl0=rl0=NO;
302 }
303 else if (seqc0[ic]=='/') {
304 del0++; cl0=rl0=NO;
305 }
306 if ((line[2][i]=seqc1[ic])=='-' || seqc1[ic]=='\\') {
307 del1++; cl1=rl1=NO;
308 }
309 else if (seqc1[ic]=='/') {
310 del1++; cl1=rl1=NO;
311 }
312
313 if (seqc0[ic]==' ') {del0++; cl0=rl0=NO;}
314 else ll0 = YES;
315 if (seqc1[ic]==' ') {del1++; cl1=rl1=NO;}
316 else ll1 = YES;
317
318 /* the old version used qoffset, this version uses q_offset+q_off */
319 qqoff = aln->q_offset + (long)qlsgn*ioff00 +
320 (long)qlsgn*qlfact*(ioff0-del0-ioff00);
321 if (cl0 && qqoff%10 == 9) {
322 sprintf(&clinep[0][i-qfxn],"%8ld",qqoff+1l);
323 clinep[0][i+8-qfxn]=' ';
324 rl0 = NO;
325 }
326 else if (cl0 && qqoff== -1) {
327 sprintf(&clinep[0][i-qfxn],"%8ld",0l);
328 clinep[0][i+8-qfxn]=' ';
329 rl0 = NO;
330 }
331 else if (rl0 && (qqoff+1)%10 == 0) {
332 sprintf(&clinep[0][i-qfxn],"%8ld",qqoff+1);
333 clinep[0][i+8-qfxn]=' ';
334 }
335
336 /* the lloff coordinate of a residue is the sum of:
337 m_msp->sq1off-1 - the user defined coordinate
338 aln->l_offset - the offset into the library sequence
339 llsgn*ioff10 - the offset into the beginning of the alignment
340 (given in the "natural" coordinate system,
341 except for tfasta3 which provides context)
342 llsgn*llfact*(ioff1-del1-ioff10)
343 - the position in the consensus aligment, -gaps
344 */
345
346 /* it seems like this should be done in calc_coord() */
347
348 lloff = aln->l_offset + /* aln->frame + */
349 (long)llsgn*aln->llmult*ioff10 +
350 (long)llsgn*llfact*(ioff1-del1-ioff10);
351
352 if (cl1 && lloff%10 == 9) {
353 sprintf(&clinep[1][i-lfxn],"%8ld",lloff+1l);
354 clinep[1][i+8-lfxn]=' ';
355 rl1 = NO;
356 }
357 else if (cl1 && lloff== -1) {
358 sprintf(&clinep[1][i],"%8ld",0l);
359 clinep[1][i+8-lfxn]=' ';
360 rl1 = NO;
361 }
362 else if (rl1 && (lloff+1)%10 == 0) {
363 sprintf(&clinep[1][i-lfxn],"%8ld",lloff+1);
364 clinep[1][i+8-lfxn]=' ';
365 }
366
367 line[1][i] = ' ';
368 if (ioff0-del0 >= aln->amin0 && ioff0-del0 <= aln->amax0) {
369 if (m_msp->markx & MX_MBLAST) {
370 if (disp_dna_align) {
371 if (seqca[ic]==4) {line[1][i] = '|';}
372 else {line[1][i] = ' ';}
373 }
374 else {
375 if (seqca[ic]==4) {line[1][i]=line[0][i];}
376 else {line[1][i] = map_sym_p[seqca[ic]];}
377 }
378 }
379 else {
380 if (seqca[ic]==4) {line[1][i]=map_sym_p[4];}
381 else if ((m_msp->markx&MX_ATYPE)==2) line[1][i]=line[2][i];
382 else line[1][i] = map_sym_p[seqca[ic]];
383 }
384 }
385 else if ((m_msp->markx&MX_ATYPE)==2) line[1][i]=line[2][i];
386 }
387
388 q_end = qqoff + qf_flag + (aln->qlfact-1)*(aln->qlrev > 0 ? -1 : 1);
389 s_end = lloff + sf_flag + (aln->llfact-1)*(aln->qlrev > 0 ? -1 : 1);
390
391 if (m_msp->ann_flg) {
392 for (ic=ic_save,i=0; i<lend; ic++,i++) {
393 if (m_msp->markx&MX_ANNOT_MID) {
394 if (seqc0a && seqc0a[ic]!= ' ') {line[1][i] = seqc0a[ic];}
395 if (seqc1a && seqc1a[ic]!= ' ') {line[1][i] = seqc1a[ic];}
396 }
397 if (m_msp->markx&MX_ANNOT_COORD) {
398 if (seqc0a && seqc0a[ic]!= ' ') clinep[0][i+7-qfxn] = seqc0a[ic];
399 if (seqc1a && seqc1a[ic]!= ' ') clinep[1][i+7-lfxn] = seqc1a[ic];
400 }
401 }
402 }
403
404 line[0][lend]=line[1][lend]=line[2][lend]=0;
405 clinep[0][lend+7]=clinep[1][lend+7]=0;
406
407 ll01 = ll0&&ll1;
408 if ((m_msp->markx&MX_ATYPE)==2 && (!aln->showall || ll0)) ll1=0;
409 fprintf(fd,"\n");
410 if (!(m_msp->markx & MX_MBLAST)) {
411 if (ll0) fprintf(fd,"%s%s\n",blank,clinep[0]);
412 if (ll0) fprintf(fd,afmt,name0,line[0]);
413 if (ll01) fprintf(fd,afmt,name01,line[1]);
414 if (ll1) fprintf(fd,afmt,name1,line[2]);
415 if (ll1) fprintf(fd,"%s%s\n",blank,clinep[1]);
416 }
417 else {
418 /* this code emulates BLAST output, but currently only for
419 coordinates < 10000) coordinates > 10000 will require that
420 the offset start and end coordinates across the entire
421 alignment are checked, and then the format is modified to
422 ensure that they will fit. A simple %-d does not work,
423 because the other sequence (query/library) may have the large
424 coordinate.
425
426 thus, afmt and afmt0 must be modified for each sequence,
427 based on the boundaries of the alignment
428 */
429
430 if (ll0) fprintf(fd,afmt,name0,q_start,line[0],q_end);
431 if (ll01) fprintf(fd,afmt0,blank,line[1]);
432 if (ll1) fprintf(fd,afmt,name1,s_start,line[2],s_end);
433 }
434 }
435 }
436
437 static float gscale= -1.0;
438
439 void
disgraph(FILE * fd,int n0,int n1,float percent,int score,int min0,int min1,int max0,int max1,long sq0off,char * name0,char * name1,int nml,int mlen,int markx)440 disgraph(FILE *fd, int n0,int n1, float percent, int score,
441 int min0, int min1, int max0, int max1, long sq0off,
442 char *name0, char *name1, int nml,
443 int mlen, int markx)
444 {
445 int i, gstart, gstop, gend;
446 int llen;
447 char line[MAXOUT+1];
448 char afmt[16], afmtf[64];
449
450 if (nml > 6) {
451 sprintf(afmt,"%%-%ds",nml);
452 }
453 else {
454 SAFE_STRNCPY(afmt,"%-6s",sizeof(afmt));
455 }
456 SAFE_STRNCPY(afmtf,afmt,sizeof(afmtf));
457 SAFE_STRNCAT(afmtf," %4ld-%4ld: %5.1f%%:%s:\n",sizeof(afmtf));
458
459 llen = mlen - 10;
460 memset(line,' ',llen);
461
462 line[llen-1]='\0';
463 if (gscale < 0.0) {
464 gscale = (float)llen/(float)n0;
465 if ((markx&MX_ATYPE) == 7 )
466 fprintf(fd,afmtf,name0,sq0off,sq0off+n0-1,100.0,line);
467 }
468
469 gstart = (int)(gscale*(float)min0+0.5);
470 gstop = (int)(gscale*(float)max0+0.5);
471 gend = gstop+(int)(gscale*(float)(n1-max1));
472
473 if (gstop >= llen) gstop = llen-1;
474 if (gend >= llen) gend = llen-1;
475 for (i=0; i<gstart; i++) line[i]=' ';
476 for (; i<gstop; i++) line[i]='-';
477 for (; i<llen; i++) line[i]=' ';
478
479 line[gend]=':';
480 line[llen]='\0';
481
482 if (markx & MX_AMAP) {
483 if ((markx & MX_ATYPE)==7) { /* markx==4 - no alignment */
484 SAFE_STRNCPY(afmtf,afmt,sizeof(afmtf));
485 SAFE_STRNCAT(afmtf," %4ld-%4ld:%4d %5.1f%%:%s\n",sizeof(afmtf));
486 fprintf(fd,afmtf,name1,min0+sq0off,max0+sq0off-1,score,percent,line);
487 }
488 else {
489 SAFE_STRNCPY(afmtf,">",sizeof(afmtf));
490 SAFE_STRNCAT(afmtf,afmt,sizeof(afmtf));
491 SAFE_STRNCAT(afmtf," %4ld-%4ld:%s\n",sizeof(afmtf));
492 fprintf(fd,afmtf, name1,min0+sq0off,max0+sq0off-1,line);
493 }
494 }
495 }
496
497 void
aancpy(char * to,char * from,int count,struct pstruct * ppst)498 aancpy(char *to, char *from, int count, struct pstruct *ppst)
499 {
500 char *tp;
501 unsigned char *sq;
502 int nsq;
503
504 nsq = ppst->nsqx;
505 if (ppst->ext_sq_set) {
506 sq = ppst->sqx;
507 }
508 else {
509 sq = ppst->sq;
510 }
511
512 tp=to;
513 while (count-- && *from) {
514 if (*from <= nsq) *tp++ = sq[*(from++)];
515 else *tp++ = *from++;
516 }
517 *tp='\0';
518 }
519
520 /* calc_coord transfers alignment boundary coordinates (aln->amin0,
521 amin1, amax0, amax1) into display coordinates (aln->d_start0,
522 d_start1, etc.)
523
524 this routine now indexes from 1 (rather than 0) because sq starts
525 with a 0
526 */
527
528 void
calc_coord(int n0,int n1,long q_offset,long l_offset,struct a_struct * aln)529 calc_coord(int n0, int n1,
530 long q_offset,
531 long l_offset,
532 struct a_struct *aln)
533 {
534 int l_lsgn, q_lsgn, q_fx0, q_fxn, l_fx0, l_fxn;
535
536 if (aln->qlrev == 1) {
537 aln->q_start_off = q_offset+n0;
538 aln->q_end_off = q_offset+1;
539 q_offset += n0;
540 q_lsgn = -1;
541 q_fx0 = 0;
542 q_fxn = 1;
543 }
544 else {
545 aln->q_start_off = q_offset + 1;
546 aln->q_end_off = q_offset+n0;
547 q_lsgn = 1;
548 q_fx0 = 1;
549 q_fxn = 0;
550 }
551
552 if (aln->llrev == 1) {
553 aln->l_start_off = l_offset + n1;
554 aln->l_end_off = l_offset+1;
555 l_offset += n1;
556 l_lsgn = -1;
557 l_fx0 = 0;
558 l_fxn = 1;
559 }
560 else {
561 aln->l_start_off = l_offset + 1;
562 aln->l_end_off = l_offset+n1;
563 l_lsgn = 1;
564 l_fx0 = 1;
565 l_fxn = 0;
566 }
567 aln->q_offset = q_offset;
568 aln->l_offset = l_offset;
569 aln->d_start0 = q_offset+q_lsgn*aln->amin0+q_fx0;
570 aln->d_stop0 = q_offset+q_lsgn*aln->amax0+q_fxn;
571 aln->d_start1 = l_offset+l_lsgn*aln->amin1*aln->llmult+l_fx0;
572 aln->d_stop1 = l_offset+l_lsgn*aln->amax1*aln->llmult+l_fxn;
573 }
574