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