Next version of JABA
[jabaws.git] / binaries / src / fasta34 / mshowbest.c
1
2 /* copyright (c) 1996, 1997, 1998, 1999 William R. Pearson and the
3    U. of Virginia */
4
5 /* $Name: fa_34_26_5 $ - $Id: mshowbest.c,v 1.44 2006/06/30 19:46:36 wrp Exp $ */
6
7 /*   29-Oct-2003 - changes so that bbp->cont < 0 => aa1 sequence is
8      already in aa1, no re_openlib or re_getlib required
9 */
10
11 /*   14-May-2003 Changes to use a more consistent coordinate numbering
12      system for displays.  aln->d_start[01] is now consistently used
13      to report the start of the alignment in all functions, and
14      mshowbest.c has been modified to use d_start[01] instead of
15      d_start[01]-1.  aln->min[01] now starts at 0 for all functions;
16      instead of 1 for some functions (dropnfa.c, dropgsw.c, dropfs2.c
17      earlier).
18 */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "defs.h"
25 #include "structs.h"
26 #include "param.h"
27
28 #ifndef PCOMPLIB
29 #include "mm_file.h"
30 #include "mw.h"
31 #else
32 #include "p_mw.h"
33 #endif
34
35
36 #define MAX_BLINE 256
37
38 #ifndef PCOMPLIB
39 /* function calls necessary to re_getlib() the sequence and, do
40    alignments, if necessary
41 */
42
43 #define RANLIB (m_fptr->ranlib)
44
45 int
46 re_getlib(unsigned char *, int, int, int, int, int, long *, long *, 
47           struct lmf_str *m_fptr);
48
49 #include "drop_func.h"
50
51 struct lmf_str *re_openlib(struct lmf_str *, int outtty);
52 #endif
53
54 extern void cal_coord(int n0, int n1, long sq0off, long loffset,
55                       struct a_struct *aln);
56
57 void header_aux(FILE *);
58 void show_aux(FILE *, struct beststr *);
59 void w_abort (char *p, char *p1);
60
61 /* BBP_INFO get stuff directly from beststr or from beststr->desptr */
62 #ifdef PCOMPLIB
63 #define BBP_INFO(info) bbp->desptr->info
64 #else
65 #define BBP_INFO(info) bbp->info
66 #endif
67
68 extern double zs_to_bit(double, int, int);
69
70 /* showbest() shows a list of high scoring sequence descriptions, and
71    their scores.  If -m 9, then an additional complete set of
72    alignment information is provided.
73
74    If PCOMPLIB or m_msg.quiet then the number of high scores to be
75    shown is pre-determined by m_msg.mshow before showbest is called.
76
77    The comp_lib.c version re_getlib()'s the sequence for its
78    discription, and then does another alignment for -m 9 (Thus, it
79    needs an f_str.  The PCOMPLIB version has everything available in
80    beststr before showbest() is called.
81 */
82
83 void showbest (FILE *fp, 
84 #ifndef PCOMPLIB
85                unsigned char **aa0, unsigned char *aa1, int maxn,
86 #endif
87                struct beststr **bptr,int nbest, int qlib, struct mngmsg *m_msg,
88                struct pstruct pst, struct db_str db,
89                char *gstring2
90 #ifndef PCOMPLIB
91                ,void **f_str
92 #endif
93 )
94 {
95   int ntmp = 0;
96   char bline[MAX_BLINE], fmt[40], pad[MAX_BLINE], rline[40];
97   char l_name[128];
98   int istart = 0, istop, ib;
99   int nshow;
100   int quiet;
101   int r_margin;
102   struct beststr *bbp;
103   int n1tot;
104   char *bp;
105   char rel_label[12];
106   char tmp_str[20], *seqc;
107   int seqc_len;
108   long loffset, l_off;
109   int n0, n1;
110   struct rstruct rst;
111   int lc, maxc, nident, ngap;
112   float percent, gpercent;
113   struct a_struct *aln_p;
114   int *tres;
115   int gi_num;
116
117 #ifndef PCOMPLIB
118   struct lmf_str *m_fptr;
119 #endif
120
121   strncpy(rel_label,"\0",2);
122 #ifdef SHOWREL
123   strncpy(rel_label," related",sizeof(rel_label));
124 #endif
125 #ifdef SHOWUN
126   strncpy(rel_label," unrelated",sizeof(rel_label));
127 #endif
128   rel_label[sizeof(rel_label)-1]='\0';
129
130 #ifdef PCOMPLIB
131   quiet = 1;
132 #else
133   quiet = m_msg->quiet;
134 #endif
135
136   n0 = m_msg->n0;
137
138   if (m_msg->aln.llen > MAX_BLINE) m_msg->aln.llen = MAX_BLINE;
139
140   if (pst.zsflag < 0) r_margin = 10;
141   else if (pst.zsflag>=0  && m_msg->srelv > 1 ) r_margin = 19;
142   else r_margin = 10;
143
144   if (m_msg->markx & MX_M9SUMM && m_msg->show_code == SHOW_CODE_ID) {
145 #ifdef SHOWSIM
146     r_margin += 15;
147 #else
148     r_margin += 10;
149 #endif
150   }
151
152   if (m_msg->nframe < 0) 
153 #ifndef SUPERFAMNUM
154     sprintf(fmt,"%%-%ds (%%4d)",m_msg->aln.llen-r_margin);
155 #else
156     sprintf(fmt,"%%-%ds [%%4d](%%4d)",m_msg->aln.llen-(r_margin+4));
157 #endif
158   else 
159     sprintf(fmt,"%%-%ds (%%4d)",m_msg->aln.llen-(r_margin+4));
160
161   memset(pad,' ',m_msg->aln.llen-(r_margin+6));
162   pad[m_msg->aln.llen-(r_margin+12)]='\0';
163
164   if (quiet != -1) {    /* quiet is set to -1 in comp_mlib.c to force
165                            all significant hits to be shown */
166     nshow = 20;
167     if (m_msg->mshow == -1) nshow = nbest;              /* show all */
168     /* show specified number */
169     else if (m_msg->mshow_flg) {
170       nshow = min (m_msg->mshow, nshow);
171     }
172   }
173   else nshow = m_msg->nshow;
174
175   if (quiet==0) istop = 20;
176   else istop = nshow;
177
178   if (quiet==0) {
179     printf(" How many scores would you like to see? [%d] ",m_msg->nshow);
180     fflush(stdout);
181     if (fgets(rline,20,stdin)==NULL) exit(0);
182     nshow = m_msg->nshow;
183     if (rline[0]!='\n' && rline[0]!=0) sscanf(rline,"%d",&nshow);
184     if (nshow<=0) nshow = min(20,nbest);
185   }
186
187   if ((bp = strchr (m_msg->qtitle, '\n')) != NULL) *bp = '\0';
188 /*   fprintf (fp, "%3d %s\n", qlib,m_msg->qtitle); */
189
190   if (m_msg->markx & MX_HTML) fprintf(fp,"<p><tt><pre>\n");
191
192   if (pst.zsflag >= 0) {
193     if (bptr[0]->escore < m_msg->e_cut) {
194       if (m_msg->z_bits==1) {/* show bit score */
195         fprintf(fp,"The best%s scores are:%s%s bits E(%ld)",
196                rel_label,pad,m_msg->label,pst.zdb_size);
197       }
198       else {/* show z-score */
199         fprintf(fp,"The best%s scores are:%s%s z-sc E(%ld)",
200               rel_label,pad,m_msg->label,pst.zdb_size);
201       }
202       header_aux(fp);
203       if (m_msg->markx & MX_M9SUMM) {
204         if (m_msg->show_code == SHOW_CODE_ID) {
205 #ifdef SHOWSIM
206           fprintf(fp," %%_id  %%_sim  alen");
207 #else
208           fprintf(fp," %%_id  alen");
209 #endif
210         }
211         else {
212         if (m_msg->markx & MX_HTML && m_msg->show_code !=1) { fprintf(fp,"<!-- ");}
213 #ifndef SHOWSIM
214           fprintf(fp,"\t%%_id  %%_gid %4s  alen  an0  ax0  pn0  px0  an1  ax1 pn1 px1 gapq gapl  fs ",m_msg->f_id1);
215 #else
216           fprintf(fp,"\t%%_id  %%_sim %4s  alen  an0  ax0  pn0  px0  an1  ax1 pn1 px1 gapq gapl  fs ",m_msg->f_id1);
217 #endif
218         }
219         if (m_msg->show_code == SHOW_CODE_ALIGN) {      fprintf(fp," aln_code"); }
220         if (m_msg->markx & MX_HTML && m_msg->show_code!=1) { fprintf(fp," -->");}
221       }
222       fprintf(fp,"\n");
223     }
224     else {
225       fprintf(fp,"!! No library sequences with E() < %.2g\n",m_msg->e_cut);
226       m_msg->nshow = 0;
227       if (m_msg->markx & MX_HTML) fprintf(fp,"<p></tt></pre>\n");
228       return;
229     }
230   }
231   else {
232     fprintf(fp,"The best%s scores are:%s%s",rel_label,pad,m_msg->label);
233     header_aux(fp);
234     if (m_msg->markx & MX_M9SUMM) {
235       if (m_msg->show_code == SHOW_CODE_ID) {
236 #ifdef SHOWSIM
237         fprintf(fp," %%_id  %%_sm  alen");
238 #else
239         fprintf(fp," %%_id  alen");
240 #endif
241       }
242       else {
243 #ifndef SHOWSIM
244         fprintf(fp,"\t%%_id  %%_gid %4s  alen  an0  ax0  pn0  px0  an1  ax1 pn1 px1 gapq gapl  fs ",m_msg->f_id1);
245 #else
246         fprintf(fp,"\t%%_id  %%_sim %4s  alen  an0  ax0  pn0  px0  an1  ax1 pn1 px1 gapq gapl  fs ",m_msg->f_id1);
247 #endif
248       }
249     }
250     if (m_msg->show_code == SHOW_CODE_ALIGN) {  fprintf(fp," aln_code"); }
251     fprintf(fp,"\n");
252   }
253
254   istart = 0;
255 l1:
256   istop = min(nbest,nshow);
257   for (ib=istart; ib<istop; ib++) {
258     bbp = bptr[ib];
259 #ifdef SUPERFAMNUM
260     if (BBP_INFO(nsfnum) > 0 && sfn_cmp(m_msg->qsfnum_n,BBP_INFO(sfnum))) continue;
261 #ifdef SHOWUN
262     if (BBP_INFO(nsfnum) > 0 && sfn_cmp(m_msg->qsfnum,BBP_INFO(sfnum))) {
263       istop = min(istop+1,nbest);
264     /*
265       fprintf(stderr,"skipping %d: %d==%d\n",ib,m_msg->qsfnum,BBP_INFO(sfnum));
266       */
267       continue;
268     }
269 #endif
270 #ifdef SHOWREL
271     if (BBP_INFO(nsfnum) == 0 || (BBP_INFO(nsfnum) > 0 && !sfn_cmp(m_msg->qsfnum,BBP_INFO(sfnum)))) {
272       istop = min(istop+1,nbest);
273     /*
274       fprintf(stderr,"skipping %d: %d==%d\n",ib,m_msg->qsfnum,BBP_INFO(sfnum));
275       */
276       continue;
277     }
278 #endif
279 #endif
280     if (quiet==1 && pst.zsflag>=0) {
281       if (bbp->escore > m_msg->e_cut) {
282         nshow = ib;
283         goto done;
284       }
285       else if (bbp->escore < m_msg->e_low) continue;
286     }
287
288 #ifndef PCOMPLIB
289     if ((m_fptr=re_openlib(bbp->m_file_p,!m_msg->quiet))==NULL) {
290       fprintf(stderr,"*** cannot re-open %s\n",bbp->m_file_p->lb_name);
291       exit(1);
292     }
293     RANLIB(bline,m_msg->aln.llen,bbp->lseek,bbp->libstr,m_fptr);
294 #else
295   strncpy(bline,BBP_INFO(bline),m_msg->aln.llen-r_margin);
296   bline[m_msg->aln.llen]='\0';
297 #endif
298
299   /* l_name is used to build an HTML link from the bestscore line to
300      the alignment.  It can also be used to discriminate multiple hits
301      from the same long sequence.  This requires that fast_pan use -m 6. */
302
303   strncpy(l_name,bline,sizeof(l_name)); /* get rid of text after second "|" */
304   l_name[sizeof(l_name)-1]='\0';
305   if ((bp=strchr(l_name,' '))!=NULL) *bp=0;
306   if ((bp=strchr(&l_name[3],'|'))!=NULL) *bp='\0';
307   if (m_msg->nframe > 2) sprintf(&l_name[strlen(l_name)],"_%d",bbp->frame+1);
308   else if (m_msg->nframe > 0 && bbp->frame == 1)
309     strncat(l_name,"_r",sizeof(l_name));
310   if (bbp->cont-1 > 0) {
311     sprintf(tmp_str,":%d",bbp->cont-1);
312     strncat(l_name,tmp_str,sizeof(l_name)-strlen(l_name));
313   }
314
315
316 #ifndef PCOMPLIB
317   if (m_msg->stages>1 || m_msg->markx & MX_M9SUMM) {
318     if (bbp->cont >= 0) {
319       n1 = re_getlib(aa1,maxn,m_msg->maxt3,m_msg->loff,bbp->cont,m_msg->term_code,
320                      &loffset,&l_off,bbp->m_file_p);
321     }
322     else { n1 = maxn;}
323     if (! m_msg->markx & MX_M9SUMM) {
324       do_opt (aa0[bbp->frame], m_msg->n0, aa1, n1, bbp->frame, &pst, f_str[bbp->frame], &rst);
325       bbp->score[2]=rst.score[2];
326     }
327     else {
328       bbp->sw_score = 
329         do_walign(aa0[bbp->frame],m_msg->n0, aa1, n1, bbp->frame, 
330                   &pst, f_str[bbp->frame], &bbp->a_res, &bbp->have_ares);
331
332       
333       /* save the alignment encoding for future use */
334       if (bbp->have_ares && ((tres = calloc(bbp->a_res.nres+1,sizeof(int)))!=NULL)) {
335         memcpy(tres,bbp->a_res.res,sizeof(int)*bbp->a_res.nres);
336         bbp->a_res.res = tres;
337       }
338
339       aln_func_vals(bbp->frame, &m_msg->aln);
340
341       maxc = bbp->a_res.nres + 4*m_msg->aln.llen+4;
342       seqc = NULL;
343       seqc_len = 0;
344       if (m_msg->show_code == SHOW_CODE_ALIGN) {
345         if ((seqc=(char *)calloc(maxc,sizeof(char)))!=NULL) {
346           lc=calc_code(aa0[bbp->frame],m_msg->n0,
347                        aa1,n1, 
348                        &m_msg->aln,bbp->a_res,
349                        pst,seqc,maxc,f_str[bbp->frame]);
350           seqc_len = strlen(seqc);
351         }
352       }
353       else {
354         lc=calc_id(aa0[bbp->frame],m_msg->n0,aa1,n1,
355                    &m_msg->aln, bbp->a_res,
356                    pst,f_str[bbp->frame]);
357       }
358       m_msg->aln.a_len = lc;
359
360       nident = m_msg->aln.nident;
361       if (lc > 0) percent = (100.0*(float)nident)/(float)lc;
362       else percent = -1.00;
363
364       ngap = m_msg->aln.ngap_q + m_msg->aln.ngap_l;
365 #ifndef SHOWSIM
366       if (lc-ngap > 0) gpercent = (100.0*(float)nident)/(float)(lc-ngap);
367       else gpercent = -1.00;
368 #else
369       if (lc-ngap > 0) gpercent = (100.0*(float)m_msg->aln.nsim)/(float)(lc);
370       else gpercent = -1.00;
371 #endif
372
373     }
374   }
375 #endif
376
377   n1tot = (BBP_INFO(n1tot_p)) ? *BBP_INFO(n1tot_p) : bbp->n1;
378
379   bp = bline;
380   if ((m_msg->markx & MX_HTML) && !strncmp(bline,"gi|",3)) {
381     bp = strchr(bline+4,'|')+1;
382     *(bp-1) = 0;
383     gi_num = atoi(bline+3);
384   }
385
386 #ifndef SUPERFAMNUM
387   bp[m_msg->aln.llen-r_margin]='\0';
388 #else
389   bp[m_msg->aln.llen-r_margin-5]='\0';
390 #endif
391
392   if (m_msg->nframe == -1) bp[m_msg->aln.llen-r_margin]='\0';
393   else bp[m_msg->aln.llen-(r_margin+4)]='\0';
394
395 #ifndef SUPERFAMNUM
396   fprintf (fp, fmt,bp,n1tot);
397 #else
398   if (m_msg->nframe == -1) {
399     fprintf (fp, fmt,bp,BBP_INFO(sfnum[0]),n1tot);
400   }
401   else {fprintf (fp, fmt,bp,n1tot);}
402 #endif
403
404   if (m_msg->nframe > 2) fprintf (fp, " [%d]", bbp->frame+1);
405   else if (m_msg->nframe >= 0) fprintf(fp," [%c]",(bbp->frame > 0 ?'r':'f'));
406
407   if (m_msg->srelv == 1) fprintf (fp, " %4d", bbp->score[pst.score_ix]);
408   else {
409     if (m_msg->srelv-1 > 0) fprintf (fp, " %4d", bbp->score[0]);
410     if (m_msg->srelv-1 > 1 || m_msg->stages>1)
411       fprintf (fp, " %4d", bbp->score[1]);
412     fprintf (fp, " %4d", bbp->score[pst.score_ix]);
413   }
414
415   if (pst.zsflag>=0) { 
416     if (m_msg->z_bits==1) {
417       fprintf (fp, " %.1f %7.2g",zs_to_bit(bbp->zscore,m_msg->n0,bbp->n1),bbp->escore);
418     }
419     else fprintf (fp, " %.1f %7.2g",bbp->zscore,bbp->escore);
420   }
421   show_aux(fp,bbp);
422
423 #ifdef PCOMPLIB
424   n1 = bbp->n1;
425   percent = bbp->percent;
426   gpercent = bbp->gpercent;
427   aln_p = bbp->aln_d;
428   seqc = bbp->aln_code;
429   seqc_len = bbp->aln_code_n;
430   loffset = bbp->desptr->loffset;
431   l_off = 0;
432 #else
433   aln_p = &(m_msg->aln);
434 #endif
435
436   if (m_msg->markx & MX_M9SUMM) {
437     if (m_msg->show_code != SHOW_CODE_ID) {
438       if (m_msg->markx & MX_HTML) fprintf(fp,"<!-- ");
439       cal_coord(m_msg->n0,bbp->n1,m_msg->sq0off,loffset+l_off-1,aln_p);
440
441       /*            %_id  %_sim s-w alen an0  ax0  pn0  px0  an1  ax1  pn1  px1 gapq gapl fs  */
442       /*                    alignment    min  max            min  max */
443       /*                    sequence coordinate    min  max            min  max */
444       fprintf(fp,"\t%5.3f %5.3f %4d %4d %4ld %4ld %4ld %4ld %4ld %4ld %4ld %4ld %3d %3d %3d",
445               percent/100.0,gpercent/100.0, bbp->sw_score,aln_p->a_len,
446               aln_p->d_start0,aln_p->d_stop0,
447               m_msg->sq0off, m_msg->sq0off+m_msg->n0-1,
448               aln_p->d_start1,aln_p->d_stop1,
449               loffset+l_off, loffset+l_off+bbp->n1-1,
450               aln_p->ngap_q,aln_p->ngap_l,aln_p->nfs);
451       if (m_msg->show_code == SHOW_CODE_ALIGN
452           && seqc_len > 0 && seqc != NULL) {
453         fprintf(fp,"\t%s",seqc);
454       /*      fprintf(fp," [%2d:%d]",bbp->wrkr,bbp->seqnm); */
455         free(seqc);
456         seqc = NULL;
457       }
458       if (m_msg->markx & MX_HTML) fprintf(fp," -->");
459     }
460     else {
461 #ifdef SHOWSIM
462       fprintf(fp," %5.3f %5.3f %4d", percent/100.0,(float)aln_p->nsim/(float)aln_p->a_len,aln_p->a_len);
463 #else
464       fprintf(fp," %5.3f %4d", percent/100.0,aln_p->a_len);
465 #endif
466     }
467   }
468   if (m_msg->markx & MX_HTML) fprintf(fp," <A HREF=\"#%s\">align</A>",l_name);
469   fprintf (fp, "\n");
470   fflush(fp);
471   }
472
473   if (quiet==0) {
474     printf(" More scores? [0] ");
475     fflush(stdout);
476     if (fgets(rline,20,stdin)==NULL) exit(0);
477     ntmp = 0;
478     if (rline[0]!='\n' && rline[0]!=0) sscanf(rline,"%d",&ntmp);
479     if (ntmp<=0) ntmp = 0;
480     if (ntmp>0) {
481       istart = istop;
482       nshow += ntmp;
483       goto l1;
484     }
485   }
486   else if (quiet == 1)
487     if (ib < nbest && (pst.zsflag>=0 && bbp->escore < m_msg->e_cut)) {
488       if (m_msg->mshow_flg && istop >= m_msg->mshow) goto done;
489       istart=istop;
490       nshow += 10;
491       goto l1;
492     }
493
494  done:
495   m_msg->nshow = nshow;
496   if (m_msg->markx & MX_HTML) fprintf(fp,"</pre></tt><p><hr><p>\n");
497   if (fp!=stdout) fprintf(fp,"\n");
498 }
499
500 /*
501   q[] has one set of sfnums, 0 terminated
502   s[] has second
503   return first match or 0
504 */