Next version of JABA
[jabaws.git] / binaries / src / fasta34 / c_dispn.c
1 /*      dispn.c associated subroutines for matching sequences */
2
3 /* $Name: fa_34_26_5 $ - $Id: c_dispn.c,v 1.21 2005/10/25 20:22:52 wrp Exp $ */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <ctype.h>
9
10 #include "defs.h"
11 #include "structs.h"
12 #include "param.h"
13
14 #define XTERNAL
15
16 #define YES 1
17 #define NO 0
18
19 #define MAXOUT 201
20
21 /* the seqca[] array has the following codes:
22    0 - no alignment symbol
23    1 - align; pam < 0
24    2 - align; pam == 0
25    3 - align; pam > 0
26    4 - align; ident
27    5 - align; del
28
29    the map_sym arrays determine the value to be displayed with each
30    type of aligned residue
31 */
32
33 static char *map_sym_0 ="  ..: ";
34 static char *map_sym_1 =" Xxx  ";
35 static char *map_sym_2 ="    . ";
36 #ifdef M10_CONS_L
37 static char *map_sym_10=" mzp=-";
38 #else
39 static char *map_sym_10="  ..:-";
40 #endif
41
42 void
43 discons(FILE *fd, struct mngmsg m_msg, struct pstruct pst,
44         char *seqc0, char *seqc0a, char *seqc1, char *seqca, int nc,
45         int n0, int n1, char *name0, char *name1, int nml,
46         struct a_struct *aln, long loffset)
47 {
48   char line[3][MAXOUT], cline[2][MAXOUT+10], *clinep[2];
49   int il, i, lend, loff, id;
50   int del0, del1, ic, ll0, ll1, ll01, cl0, cl1, rl0, rl1;
51   int ic_save;
52   char *map_sym_p;
53   int l_llen;
54   int ioff0, ioff00, ioff1, ioff10;
55   long qqoff, lloff, qoffset;
56   int llsgn, llfact, qlsgn, qlfact, qfx0, qfxn, lfx0, lfxn;
57   int have_res;
58   char *name01, *sq;
59   char blank[MAX_UID], afmt[32];
60
61   memset(blank,' ',sizeof(blank)-1);
62   blank[sizeof(blank)-1]='\0';
63
64   if (nml > 6) {
65     blank[nml-6]='\0';
66     sprintf(afmt,"%%-%ds %%s\n",nml);
67   }
68   else {
69     blank[0]='\0';
70     strncpy(afmt,"%-6s %s\n",sizeof(afmt));
71   }
72   if (pst.ext_sq_set) sq = pst.sqx; else sq = pst.sq;
73
74   clinep[0]=cline[0]+1;
75   clinep[1]=cline[1]+1;
76
77   if (aln->qlfact == 0) {qlfact = 1;}
78   else qlfact = aln->qlfact;
79   if (aln->qlrev == 1) {
80     qoffset = n0;
81     qlsgn = -1;
82     qfx0 = 0;
83     qfxn = 1;
84   }
85   else {
86     qoffset = 0;
87     qlsgn = 1;
88     qfx0 = 1;
89     qfxn = 0;
90   }
91
92   if (aln->llfact == 0) {llfact = 1;}
93   else llfact = aln->llfact;
94
95   if (aln->llrev == 1) {
96     loffset += n1;
97     llsgn = -1;
98     lfx0 = 0;
99     lfxn = 1;
100   }
101   else {
102     llsgn = 1;
103     lfx0 = 1;
104     lfxn = 0;
105   }
106
107   l_llen = aln->llen;
108   if ((m_msg.markx & MX_M9SUMM) && m_msg.show_code != 1) { l_llen += 40; }
109
110   if ((m_msg.markx & MX_ATYPE)==2) name01=name1;
111   else name01 = "\0";
112
113   ioff0=aln->smin0;
114   ioff00 = ioff0;
115   ioff1=aln->smin1;
116   ioff10 = ioff1;
117   
118   if (m_msg.markx& MX_AMAP && (m_msg.markx & MX_ATYPE)==7) return;
119
120   /* set *map_sym_p to correct match symbol */
121   if ((m_msg.markx&MX_ATYPE)==1) {map_sym_p = map_sym_1;}
122   else if ((m_msg.markx&MX_ATYPE)==2) {map_sym_p = map_sym_2;}
123   else if (m_msg.markx&MX_M10FORM) {map_sym_p = map_sym_10;}
124   else {map_sym_p = map_sym_0;}
125
126   if (m_msg.markx & MX_ASEP) {
127     fprintf(fd,">%s ..\n",name0);
128     for (i=0; i<nc && seqc0[i]; i++) {
129    /* if (seqc0[i]=='-') fputc('.',fd); else */
130       fputc(seqc0[i],fd);
131       if (i%50 == 49) fputc('\n',fd);
132     }
133     if ((i-1)%50 != 49) fputc('\n',fd);
134     fprintf(fd,">%s ..\n",name1);
135     for (i=0; i<nc && seqc1[i]; i++) {
136     /* if (seqc1[i]=='-') fputc('.',fd); else */
137       fputc(seqc1[i],fd);
138       if (i%50 == 49) fputc('\n',fd);
139     }
140     if ((i-1)%50 != 49) fputc('\n',fd);
141     return;
142   }
143
144   if (m_msg.markx & MX_M10FORM) {
145     fprintf(fd,">%s ..\n",name0);
146     fprintf(fd,"; sq_len: %d\n",n0);
147     fprintf(fd,"; sq_offset: %ld\n",m_msg.sq0off);
148     fprintf(fd,"; sq_type: %c\n",m_msg.sqtype[0]);
149     fprintf(fd,"; al_start: %ld\n",aln->d_start0);
150     fprintf(fd,"; al_stop: %ld\n",aln->d_stop0);
151     fprintf(fd,"; al_display_start: %ld\n",
152             qoffset+qlsgn*ioff0*aln->llmult+qfx0);
153
154     have_res = 0;
155     for (i=0; i<nc && seqc0[i]; i++) {
156       if (!have_res && seqc0[i]==' ') fputc('-',fd);
157       else if (seqc0[i]==' ') break;
158       else {
159         have_res = 1;
160         fputc(seqc0[i],fd);
161       }
162       if (i%50 == 49) fputc('\n',fd);
163     }
164     if ((i-1)%50!=49 || seqc0[i-1]==' ') fputc('\n',fd);
165     fprintf(fd,">%s ..\n",name1);
166     fprintf(fd,"; sq_len: %d\n",n1);
167     fprintf(fd,"; sq_type: %c\n",m_msg.sqtype[0]);
168     fprintf(fd,"; al_start: %ld\n",aln->d_start1);
169     fprintf(fd,"; al_stop: %ld\n",aln->d_stop1);
170     fprintf(fd,"; al_display_start: %ld\n",loffset+llsgn*ioff1+lfx0);
171
172     have_res = 0;
173     for (i=0; i<nc && seqc1[i]; i++) {
174       if (!have_res && seqc1[i]==' ') fputc('-',fd);
175       else if (seqc1[i]==' ') break;
176       else {
177         have_res = 1;
178         fputc(seqc1[i],fd);
179       }
180       if (i%50 == 49) fputc('\n',fd);
181     }
182     if ((i-1)%50!=49 || seqc1[i-1]==' ') fputc('\n',fd);
183 #ifdef M10_CONS
184     fprintf(fd,"; al_cons:\n");
185     for (i=0,del0=0,id=ioff0; id-del0<aln->amax0 && i < nc; i++,id++) {
186       if (seqc0[i] == '\0' || seqc1[i] == '\0') break;
187       if (seqc0[i]=='-' || seqc0[i]==' ' || seqc0[i]=='\\') del0++;
188       else if (seqc0[i]=='/') del0++;
189       if (id-del0<aln->amin0) fputc(' ',fd);
190       else if (seqc0[i]=='-'||seqc1[i]=='-') fputc('-',fd);
191       else fputc(map_sym_10[seqca[i]],fd);
192
193       if (i%50 == 49) fputc('\n',fd);
194     }
195     if ((i-1)%50!=49 || seqc1[i-1]==' ') fputc('\n',fd);
196 #endif
197     return;
198   }
199
200   memset(line[0],' ',MAXOUT);
201   memset(line[1],' ',MAXOUT);
202   memset(line[2],' ',MAXOUT);
203
204   /* cl0 indicates whether a coordinate should be printed over the first
205      sequence; cl1 indicates a coordinate for the second;
206   */
207
208   ic = 0; del0=del1=0;
209   for (il=0; il<(nc+l_llen-1)/l_llen; il++) {
210     loff=il*l_llen;
211     lend=min(l_llen,nc-loff);
212
213     ll0 = NO; ll1 = NO;
214
215     memset(cline[0],' ',MAXOUT+1);
216     memset(cline[1],' ',MAXOUT+1);
217
218     ic_save = ic;
219     for (i=0; i<lend; i++, ic++,ioff0++,ioff1++) {
220       cl0 =  cl1 = rl0 = rl1 = YES;
221       if ((line[0][i]=seqc0[ic])=='-' || seqc0[ic]=='\\') {
222         del0++; cl0=rl0=NO;
223       }
224       else if (seqc0[ic]=='/') {
225         del0++; cl0=rl0=NO;
226       }
227       if ((line[2][i]=seqc1[ic])=='-' || seqc1[ic]=='\\') {
228         del1++; cl1=rl1=NO;
229       }
230       else if (seqc1[ic]=='/') {
231         del1++; cl1=rl1=NO;
232       }
233
234       if (seqc0[ic]==' ') {del0++; cl0=rl0=NO;}
235       else ll0 = YES;
236       if (seqc1[ic]==' ') {del1++; cl1=rl1=NO;}
237       else ll1 = YES;
238
239       qqoff = m_msg.sq0off - 1 + qoffset + (long)qlsgn*ioff00 +
240         (long)qlsgn*qlfact*(ioff0-del0-ioff00);
241       if (cl0 && qqoff%10 == 9)  {
242         sprintf(&clinep[0][i-qfxn],"%8ld",qqoff+1l);
243         clinep[0][i+8-qfxn]=' ';
244         rl0 = NO;
245       }
246       else if (cl0 && qqoff== -1) {
247         sprintf(&clinep[0][i-qfxn],"%8ld",0l);
248         clinep[0][i+8-qfxn]=' ';
249         rl0 = NO;
250       }
251       else if (rl0 && (qqoff+1)%10 == 0) {
252         sprintf(&clinep[0][i-qfxn],"%8ld",qqoff+1);
253         clinep[0][i+8-qfxn]=' ';
254       }
255       
256       /* the lloff coordinate of a residue is the sum of:
257          m_msg.sq1off-1  - the user defined coordinate
258          loffset        - the offset into the library sequence
259          llsgn*ioff10   - the offset into the beginning of the alignment
260                           (given in the "natural" coordinate system,
261                            except for tfasta3 which provides context)
262          llsgn*llfact*(ioff1-del1-ioff10)
263                         - the position in the consensus aligment, -gaps
264       */
265
266       lloff = m_msg.sq1off-1 + loffset + aln->frame +
267         (long)llsgn*aln->llmult*ioff10 +
268         (long)llsgn*llfact*(ioff1-del1-ioff10);
269
270       if (cl1 && lloff%10 == 9)  {
271         sprintf(&clinep[1][i-lfxn],"%8ld",lloff+1l);
272         clinep[1][i+8-lfxn]=' ';
273         rl1 = NO;
274       }
275       else if (cl1 && lloff== -1) {
276         sprintf(&clinep[1][i],"%8ld",0l);
277         clinep[1][i+8-lfxn]=' ';
278         rl1 = NO;
279       }
280       else if (rl1 && (lloff+1)%10 == 0) {
281         sprintf(&clinep[1][i-lfxn],"%8ld",lloff+1);
282         clinep[1][i+8-lfxn]=' ';
283       }
284
285       line[1][i] = ' ';
286       if (ioff0-del0 >= aln->amin0 && ioff0-del0 <= aln->amax0) {
287         if (seqca[ic]==4) {line[1][i]=map_sym_p[4];}
288         else if ((m_msg.markx&MX_ATYPE)==2) line[1][i]=line[2][i];
289         else line[1][i] = map_sym_p[seqca[ic]];
290       }
291       else if ((m_msg.markx&MX_ATYPE)==2) line[1][i]=line[2][i];
292     }
293
294     if (m_msg.ann_flg) {
295       for (ic=ic_save,i=0; i<lend; ic++,i++) {
296         if (seqc0a[ic]!= ' ') clinep[0][i+7-qfxn] = seqc0a[ic];
297       }
298     }
299
300     line[0][lend]=line[1][lend]=line[2][lend]=0;
301     clinep[0][lend+7]=clinep[1][lend+7]=0;
302     
303     ll01 = ll0&&ll1;
304     if ((m_msg.markx&MX_ATYPE)==2 && (!aln->showall || ll0)) ll1=0;
305     fprintf(fd,"\n");
306     if (ll0) fprintf(fd,"%s%s\n",blank,clinep[0]);
307     if (ll0) fprintf(fd,afmt,name0,line[0]);
308     if (ll01) fprintf(fd,afmt,name01,line[1]);
309     if (ll1) fprintf(fd,afmt,name1,line[2]);
310     if (ll1) fprintf(fd,"%s%s\n",blank,clinep[1]);
311   }
312 }
313
314 static float gscale= -1.0;
315
316 void
317 disgraph(FILE *fd, int n0,int n1, float percent, int score,
318          int min0, int min1, int max0, int max1, long sq0off,
319          char *name0, char *name1, int nml,
320          int mlen, int markx)
321 {
322   int i, gstart, gstop, gend;
323   int llen;
324   char line[MAXOUT+1];
325   char afmt[16], afmtf[64];
326
327   if (nml > 6) {
328     sprintf(afmt,"%%-%ds",nml);
329   }
330   else {
331     strncpy(afmt,"%-6s",sizeof(afmt));
332   }
333   strncpy(afmtf,afmt,sizeof(afmtf));
334   strncat(afmtf," %4ld-%4ld:     %5.1f%%:%s:\n",sizeof(afmtf));
335
336   llen = mlen - 10;
337   memset(line,' ',llen);
338
339   line[llen-1]='\0';
340   if (gscale < 0.0) {
341     gscale = (float)llen/(float)n0;
342     if ((markx&MX_ATYPE) == 7 ) 
343       fprintf(fd,afmtf,name0,sq0off,sq0off+n0-1,100.0,line);
344   }
345
346   gstart = (int)(gscale*(float)min0+0.5);
347   gstop = (int)(gscale*(float)max0+0.5);
348   gend = gstop+(int)(gscale*(float)(n1-max1));
349
350   if (gstop >= llen) gstop = llen-1;
351   if (gend >= llen) gend = llen-1;
352   for (i=0; i<gstart; i++) line[i]=' ';
353   for (; i<gstop; i++) line[i]='-';
354   for (; i<llen; i++) line[i]=' ';
355
356   line[gend]=':';
357   line[llen]='\0';
358
359   if (markx & MX_AMAP) {
360     if ((markx & MX_ATYPE)==7) {        /* markx==4 - no alignment */
361       strncpy(afmtf,afmt,sizeof(afmtf));
362       strncat(afmtf," %4ld-%4ld:%4d %5.1f%%:%s\n",sizeof(afmtf));
363       fprintf(fd,afmtf,name1,min0+sq0off,max0+sq0off-1,score,percent,line);
364     }
365     else {
366       afmtf[0]='>';
367       strncpy(&afmtf[1],afmt,sizeof(afmtf)-1);
368       strncat(afmtf," %4ld-%4ld:%s\n",sizeof(afmtf));
369       fprintf(fd,afmtf, name1,min0+sq0off,max0+sq0off-1,line);
370     }
371   }
372 }
373
374 void
375 aancpy(char *to, char *from, int count, struct pstruct pst)
376 {
377   char *tp, *sq;
378   int nsq;
379
380   if (pst.ext_sq_set) {
381     nsq = pst.nsqx;
382     sq = pst.sqx;
383   }
384   else {
385     nsq = pst.nsq;
386     sq = pst.sq;
387   }
388
389   tp=to;
390   while (count-- && *from) {
391     if (*from <= nsq) *tp++ = sq[*(from++)];
392     else *tp++ = *from++;
393   }
394   *tp='\0';
395 }
396
397 void
398 r_memcpy(dest,src,cnt)
399      char *dest, *src;
400      int cnt;
401 {
402   while (cnt--) *dest++ = *src++;
403 }
404
405 void
406 l_memcpy(dest,src,cnt)
407      char *dest, *src;
408      int cnt;
409 {
410   dest = dest+cnt;
411   src = src+cnt;
412   while (cnt--) *--dest = *--src;
413 }
414
415 /* this routine now indexs from 1 (rather than 0) because sq starts
416    with a 0 */
417
418 #define MAXSQ 50        /* must be same as upam.h */
419
420 void cal_coord(int n0, int n1, long sq0off, long loffset,
421                struct a_struct *aln)
422 {
423   long qoffset;
424   int llsgn, qlsgn, qfx0, qfxn, lfx0, lfxn;
425
426   if (aln->qlrev == 1) {
427     qoffset = sq0off -1 + n0;
428     qlsgn = -1;
429     qfx0 = 0;
430     qfxn = 1;
431   }
432   else {
433     qoffset = sq0off - 1;
434     qlsgn = 1;
435     qfx0 = 1;
436     qfxn = 0;
437   }
438
439   if (aln->llrev == 1) {
440     loffset += n1;
441     llsgn = -1;
442     lfx0 = 0;
443     lfxn = 1;
444   }
445   else {
446     llsgn = 1;
447     lfx0 = 1;
448     lfxn = 0;
449   }
450   aln->d_start0 = qoffset+qlsgn*aln->amin0+qfx0;
451   aln->d_stop0 = qoffset+qlsgn*aln->amax0+qfxn;
452   aln->d_start1 = loffset+llsgn*aln->amin1*aln->llmult+lfx0+aln->frame;
453   aln->d_stop1 = loffset+llsgn*aln->amax1*aln->llmult+lfxn+aln->frame;
454 }