Exemple #1
0
void showbest (FILE *fp, 
#ifndef PCOMPLIB
	       unsigned char **aa0, unsigned char *aa1save, int maxn,
#endif
	       struct beststr **bptr,int nbest,
	       int qlib, struct mngmsg *m_msp,
	       struct pstruct *ppst, struct db_str db,
	       char **info_gstring2
#ifndef PCOMPLIB
	       ,void **f_str
#endif
)
{
  unsigned char *aa1, *aa1a;
  int ntmp = 0;
  char bline[MAX_BLINE], fmt[40], pad[MAX_BLINE], rline[40];
  char l_name[128];
  int istart = 0, istop, ib;
  int nshow;
  int quiet;
  int r_margin;
  struct beststr *bbp;
  int n1tot;
  char *bp;
  char rel_label[12];
  char tmp_str[20], *seq_code, *ann_code;
  int seq_code_len, ann_code_len;
  long loffset;		/* loffset is offset from beginning of real sequence */
  long l_off;		/* l_off is the the virtual coordinate of residue 1 */
  int n0, n1;
  struct rstruct rst;
  int lc, seqc_max, annc_max, nident, ngap;
  float percent, gpercent;
  struct a_struct *aln_p;
  int *tres;
  int gi_num;
  char html_pre_E[120], html_post_E[120];

#ifndef PCOMPLIB
  struct lmf_str *m_fptr;
#endif

  strncpy(rel_label,"\0",2);
#ifdef SHOWREL
  strncpy(rel_label," related",sizeof(rel_label));
#endif
#ifdef SHOWUN
  strncpy(rel_label," unrelated",sizeof(rel_label));
#endif
  rel_label[sizeof(rel_label)-1]='\0';

#ifdef PCOMPLIB
  quiet = 1;
#else
  quiet = m_msp->quiet;
#endif

  n0 = m_msp->n0;

  if (m_msp->aln.llen > MAX_BLINE) m_msp->aln.llen = MAX_BLINE;

  if (ppst->zsflag < 0) r_margin = 10;
  else if (ppst->zsflag>=0  && m_msp->srelv > 1 ) r_margin = 19;
  else r_margin = 10;

  if (m_msp->markx & MX_M9SUMM && m_msp->show_code == SHOW_CODE_ID) {
#ifdef SHOWSIM
    r_margin += 15;
#else
    r_margin += 10;
#endif
  }

  if (m_msp->markx & MX_HTML) {
    strncpy(html_pre_E,"<font color=\"darkred\">",sizeof(html_pre_E));
    strncpy(html_post_E,"</font>",sizeof(html_post_E));

  }
  else {
    html_pre_E[0] = html_post_E[0] = '\0';
  }


  if (m_msp->nframe < 0) {
#ifndef SUPERFAMNUM
    sprintf(fmt,"%%-%ds (%%4d)",m_msp->aln.llen-r_margin);
#else
    sprintf(fmt,"%%-%ds [%%4d](%%4d)",m_msp->aln.llen-(r_margin+4));
#endif
  }
  else { sprintf(fmt,"%%-%ds (%%4d)",m_msp->aln.llen-(r_margin+4)); }

  memset(pad,' ',m_msp->aln.llen-(r_margin+6));
  pad[m_msp->aln.llen-(r_margin+12)]='\0';

  if (quiet != -1) {	/* quiet is set to -1 in comp_lib2.c to force
			   all significant hits to be shown */
    nshow = 20;
    if (m_msp->mshow == -1) {nshow = nbest;}		/* show all */
    /* show specified number */
    else if (m_msp->mshow_flg) {
      nshow = min (m_msp->mshow, nshow);
    }
  }
  else nshow = m_msp->nshow;

  if (quiet==0) istop = 20;
  else istop = nshow;

  if (quiet==0) {
    printf(" How many scores would you like to see? [%d] ",m_msp->nshow);
    fflush(stdout);
    if (fgets(rline,20,stdin)==NULL) exit(0);
    nshow = m_msp->nshow;
    if (rline[0]!='\n' && rline[0]!=0) sscanf(rline,"%d",&nshow);
    if (nshow<=0) nshow = min(20,nbest);
  }

  if ((bp = strchr (m_msp->qtitle, '\n')) != NULL) *bp = '\0';
/*   fprintf (fp, "%3d %s\n", qlib,m_msp->qtitle); */

  if (m_msp->markx & MX_HTML) fprintf(fp,"<p><tt><pre>\n");

  if (ppst->zsflag >= 0) {
    if (bptr[0]->rst.escore < m_msp->e_cut) {
      if (m_msp->z_bits==1) {/* show bit score */
	fprintf(fp,"\nThe best%s scores are:%s%s bits %sE(%ld)%s",
		rel_label,pad,m_msp->label,html_pre_E,ppst->zdb_size,html_post_E);
      }
      else {/* show z-score */
	fprintf(fp,"\nThe best%s scores are:%s%s z-sc %sE(%ld)%s",
		rel_label,pad,m_msp->label,html_pre_E,ppst->zdb_size,html_post_E);
      }
      header_aux(fp);
      if (m_msp->markx & MX_M9SUMM) {
	if (m_msp->show_code == SHOW_CODE_ID) {
#ifdef SHOWSIM
	  fprintf(fp," %%_id  %%_sim  alen");
#else
	  fprintf(fp," %%_id  alen");
#endif
	}
	else {
	if (m_msp->markx & MX_HTML && m_msp->show_code !=1) { fprintf(fp,"<!-- ");}
#ifndef SHOWSIM
	  fprintf(fp,"\t%%_id  %%_gid %4s  alen  an0  ax0  pn0  px0  an1  ax1 pn1 px1 gapq gapl  fs ",m_msp->f_id1);
#else
	  fprintf(fp,"\t%%_id  %%_sim %4s  alen  an0  ax0  pn0  px0  an1  ax1 pn1 px1 gapq gapl  fs ",m_msp->f_id1);
#endif
	}
	if (m_msp->show_code == SHOW_CODE_ALIGN) {	fprintf(fp," aln_code"); }
	if (m_msp->markx & MX_HTML && m_msp->show_code!=1) { fprintf(fp," -->");}
      }
      fprintf(fp,"\n");
    }
    else {
      fprintf(fp,"!! No library sequences with E() < %.2g\n",m_msp->e_cut);
      m_msp->nshow = 0;
      if (m_msp->markx & MX_HTML) fprintf(fp,"<p></tt></pre>\n");
      return;
    }
  }
  else {
    fprintf(fp,"\nThe best%s scores are:%s%s",rel_label,pad,m_msp->label);
    header_aux(fp);
    if (m_msp->markx & MX_M9SUMM) {
      if (m_msp->show_code == SHOW_CODE_ID) {
#ifdef SHOWSIM
	fprintf(fp," %%_id  %%_sm  alen");
#else
	fprintf(fp," %%_id  alen");
#endif
      }
      else {
#ifndef SHOWSIM
	fprintf(fp,"\t%%_id  %%_gid %4s  alen  an0  ax0  pn0  px0  an1  ax1 pn1 px1 gapq gapl  fs ",m_msp->f_id1);
#else
	fprintf(fp,"\t%%_id  %%_sim %4s  alen  an0  ax0  pn0  px0  an1  ax1 pn1 px1 gapq gapl  fs ",m_msp->f_id1);
#endif	/* SHOWSIM */
      }
    }
    if (m_msp->show_code == SHOW_CODE_ALIGN) {	fprintf(fp," aln_code"); }
    fprintf(fp,"\n");
  }

  istart = 0;
l1:
  istop = min(nbest,nshow);
  for (ib=istart; ib<istop; ib++) {
    bbp = bptr[ib];

#ifndef PCOMPLIB
#ifdef DEBUG
    if (bbp->seq->n1 != bbp->n1 ) {
      fprintf(stderr, " *** lib len error [%d!=%d] *** %s score %d\n",
	      bbp->seq->n1,bbp->n1, bbp->seq->libstr, bbp->rst.score[0]);
    }
#endif
#endif

#ifdef SUPERFAMNUM
    if (BBP_INFO(nsfnum) > 0 && sfn_cmp(m_msp->qsfnum_n,BBP_INFO(sfnum))) continue;
#ifdef SHOWUN
    if (BBP_INFO(nsfnum) > 0 && sfn_cmp(m_msp->qsfnum,BBP_INFO(sfnum))) {
      istop = min(istop+1,nbest);
    /*
      fprintf(stderr,"skipping %d: %d==%d\n",ib,m_msp->qsfnum,BBP_INFO(sfnum));
      */
      continue;
    }
#endif	/* SHOWUN */
#ifdef SHOWREL
    if (BBP_INFO(nsfnum) == 0 || (BBP_INFO(nsfnum) > 0 && !sfn_cmp(m_msp->qsfnum,BBP_INFO(sfnum)))) {
      istop = min(istop+1,nbest);
      continue;
    }
#endif	/* SHOWREL */
#endif	/* SUPERFAMNUM */
    if (quiet==1 && ppst->zsflag>=0) {
      if (bbp->rst.escore > m_msp->e_cut) {
	nshow = ib;
	goto done;
      }
      else if (bbp->rst.escore < m_msp->e_low) continue;
    }

#ifndef PCOMPLIB
    if ((m_fptr=re_openlib(bbp->seq->m_file_p,!m_msp->quiet))==NULL) {
      fprintf(stderr,"*** cannot re-open %s\n",bbp->seq->m_file_p->lb_name);
      exit(1);
    }
    RANLIB(bline,m_msp->aln.llen,bbp->seq->lseek,bbp->seq->libstr,m_fptr);
#else	/* PCOMPLIB */
  strncpy(bline,BBP_INFO(bline),m_msp->aln.llen-r_margin);
  bline[m_msp->aln.llen]='\0';
#endif

  /* l_name is used to build an HTML link from the bestscore line to
     the alignment.  It can also be used to discriminate multiple hits
     from the same long sequence.  This requires that fast_pan use -m 6. */

  strncpy(l_name,bline,sizeof(l_name)); /* get rid of text after second "|" */
  l_name[sizeof(l_name)-1]='\0';
  if ((bp=strchr(l_name,' '))!=NULL) *bp=0;
  if ((bp=strchr(&l_name[3],'|'))!=NULL) *bp='\0';
  if (m_msp->nframe > 2) sprintf(&l_name[strlen(l_name)],"_%d",bbp->frame+1);
  else if (m_msp->nframe > 0 && bbp->frame == 1)
    strncat(l_name,"_r",sizeof(l_name));
  if (bbp->seq->cont-1 > 0) {
    sprintf(tmp_str,":%d",bbp->seq->cont-1);
    strncat(l_name,tmp_str,sizeof(l_name)-strlen(l_name));
  }


#ifndef PCOMPLIB
  aln_p = &(m_msp->aln);

  if (m_msp->stages>1 || m_msp->markx & MX_M9SUMM) {
    if (bbp->seq->aa1b == NULL || (m_msp->ann_flg && bbp->seq->aa1_ann==NULL)) {

      /* get the sequence but don't save it */
      n1 = re_getlib(aa1save,
		     m_msp->ann_flg ? &(bbp->seq->aa1_ann) : NULL, 
		     maxn,m_msp->maxt3,
		     m_msp->l_overlap,bbp->seq->cont,m_msp->term_code,
		     &loffset,&l_off,bbp->seq->m_file_p);
      aa1 = aa1save;
      aa1a = bbp->seq->aa1_ann;
    }
    else {
      n1 = bbp->seq->n1;
      aa1 = bbp->seq->aa1b;
      aa1a = bbp->seq->aa1_ann;
      loffset = bbp->seq->l_offset;
      l_off = bbp->seq->l_off;
    }

    if (! m_msp->markx & MX_M9SUMM) {
      do_opt (aa0[bbp->frame], m_msp->n0, aa1, n1, bbp->frame, ppst, f_str[bbp->frame], &rst);
      bbp->rst.score[2]=rst.score[2];
    }
    else {
      if (!bbp->have_ares) {	/* showbest() can be called more than once */

	do_walign(aa0[bbp->frame],m_msp->n0, aa1, n1, bbp->frame, 
		  ppst, f_str[bbp->frame],
		  &bbp->a_res, &bbp->have_ares);
      
	/* if do_walign does not provide a fresh a_res,
	   then copy the re-used a_res to a new location */
	if (bbp->have_ares && !(bbp->have_ares & 0x2)) {
	  if ((tres = calloc(bbp->a_res.nres+1,sizeof(int)))!=NULL) {
	    memcpy(tres,bbp->a_res.res,sizeof(int)*bbp->a_res.nres);
	    bbp->a_res.res = tres;
	    bbp->have_ares |= 0x2;	/* set 0x2 if has local copy */
	  }
	  else {
	    bbp->have_ares = 0;		/* could not allocate memory */
	  }
	}
      }
      else {
	pre_cons(aa1,n1,bbp->frame,f_str[bbp->frame]);
      }

      aln_func_vals(bbp->frame, aln_p);

      seqc_max = bbp->a_res.nres + 4*m_msp->aln.llen+4;
      seq_code = NULL;
      seq_code_len = 0;
      if (m_msp->show_code == SHOW_CODE_ALIGN) {
	seq_code=(char *)calloc(seqc_max,sizeof(char));
	/* if we have an annotation string, allocate space for the encoded annotation */
	if (m_msp->ann_arr[0] != '\0') {
	  /* the annotation encoding can be considerably longer than the alignment encoding */
	  annc_max = 4*seqc_max;
	  ann_code=(char *)calloc(annc_max,sizeof(char));
	}
	else {
	  ann_code = NULL;
	  annc_max = 0;
	}
	if (seq_code != NULL) {
	  calc_astruct(aln_p, &bbp->a_res);

      /* we need this for offset information for calc_code, but it is
	 incomplete so we must do it again */
	  cal_coord(m_msp->n0,BBP_INFO(n1),
		    m_msp->q_offset + (m_msp->q_off-1) + (m_msp->sq0off-1),
		    loffset + (l_off-1) + (m_msp->sq1off-1),
		    aln_p);

	  lc=calc_code(aa0[bbp->frame],m_msp->n0,
		       aa1,n1, 
		       &m_msp->aln,&bbp->a_res,
		       ppst,seq_code,seqc_max,
		       m_msp->ann_arr,
		       m_msp->aa0a, aa1a,
		       ann_code, annc_max,
		       f_str[bbp->frame]);
	  seq_code_len = strlen(seq_code);
	  if (ann_code != NULL) ann_code_len = strlen(ann_code);
	  else ann_code_len = 0;
	}
      }
      else {
	lc=calc_id(aa0[bbp->frame],m_msp->n0,aa1,n1,
		   &m_msp->aln, &bbp->a_res,
		   ppst,f_str[bbp->frame]);
      }
      m_msp->aln.a_len = lc;

      nident = m_msp->aln.nident;
      if (lc > 0) percent = (100.0*(float)nident)/(float)lc;
      else percent = -1.00;

      ngap = m_msp->aln.ngap_q + m_msp->aln.ngap_l;
#ifndef SHOWSIM
      if (lc-ngap > 0) gpercent = (100.0*(float)nident)/(float)(lc-ngap);
      else gpercent = -1.00;
#else
      if (lc-ngap > 0) gpercent = (100.0*(float)m_msp->aln.nsim)/(float)(lc);
      else gpercent = -1.00;
#endif	/* SHOWSIM */

    }
  }
#endif	/* PCOMPLIB */

  n1tot = (BBP_INFO(n1tot_p)) ? *BBP_INFO(n1tot_p) : BBP_INFO(n1);

  bp = bline;
  if ((m_msp->markx & MX_HTML) && !strncmp(bline,"gi|",3)) {
    bp = strchr(bline+4,'|')+1;
    *(bp-1) = 0;
    gi_num = atoi(bline+3);
  }

#ifndef SUPERFAMNUM
  bp[m_msp->aln.llen-r_margin]='\0';
#else
  bp[m_msp->aln.llen-r_margin-5]='\0';
#endif

  if (m_msp->nframe == -1) bp[m_msp->aln.llen-r_margin]='\0';
  else bp[m_msp->aln.llen-(r_margin+4)]='\0';

#ifndef SUPERFAMNUM
  fprintf (fp, fmt,bp,n1tot);
#else
  if (m_msp->nframe == -1) {
    fprintf (fp, fmt,bp,BBP_INFO(sfnum[0]),n1tot);
  }
  else {fprintf (fp, fmt,bp,n1tot);}
#endif

  if (m_msp->nframe > 2) fprintf (fp, " [%d]", bbp->frame+1);
  else if (m_msp->nframe >= 0) fprintf(fp," [%c]",(bbp->frame > 0 ?'r':'f'));

  if (m_msp->srelv == 1) fprintf (fp, " %4d", bbp->rst.score[ppst->score_ix]);
  else {
    if (m_msp->srelv-1 > 0) fprintf (fp, " %4d", bbp->rst.score[0]);
    if (m_msp->srelv-1 > 1 || m_msp->stages>1)
      fprintf (fp, " %4d", bbp->rst.score[1]);
    fprintf (fp, " %4d", bbp->rst.score[ppst->score_ix]);
  }

  if (ppst->zsflag>=0) { 
    if (m_msp->z_bits==1) {
      fprintf (fp, " %.1f %s%7.2g%s",zs_to_bit(bbp->zscore,m_msp->n0,BBP_INFO(n1)),html_pre_E,bbp->rst.escore,html_post_E);
    }
    else fprintf (fp, " %.1f %s%7.2g%s",bbp->zscore,html_pre_E,bbp->rst.escore,html_post_E);
  }
  show_aux(fp,bbp);

#ifdef PCOMPLIB
  n1 = BBP_INFO(n1);
  percent = bbp->percent;
  gpercent = bbp->gpercent;
  aln_p = &(bbp->aln_d);
  seq_code = bbp->aln_code;
  seq_code_len = bbp->aln_code_n;
  ann_code = bbp->ann_code;
  ann_code_len = bbp->ann_code_n;
  loffset = bbp->seq->l_offset;
  l_off = 0;
#endif

  if (m_msp->markx & MX_M9SUMM) {
    if (m_msp->show_code != SHOW_CODE_ID) {
      /* we need the coordinates for annotated SHOW_CODE_ALIGN */
      cal_coord(m_msp->n0,BBP_INFO(n1),
		m_msp->q_offset + (m_msp->q_off-1) + (m_msp->sq0off-1),
		loffset + (l_off-1) + (m_msp->sq1off-1),
		aln_p);

      if (m_msp->markx & MX_HTML) fprintf(fp,"<!-- ");
      /*            %_id  %_sim s-w alen an0  ax0  pn0  px0  an1  ax1  pn1  px1 gapq gapl fs  */
      /*                    alignment    min  max            min  max */
      /*                    sequence coordinate    min  max            min  max */
      fprintf(fp,"\t%5.3f %5.3f %4d %4d %4ld %4ld %4ld %4ld %4ld %4ld %4ld %4ld %3d %3d %3d",
	      percent/100.0,gpercent/100.0, 
#ifndef PCOMPLIB
	      bbp->a_res.sw_score,
#else
	      bbp->sw_score,
#endif
	      aln_p->a_len,
	      aln_p->d_start0,aln_p->d_stop0,
	      aln_p->q_offset+1, aln_p->q_offset+m_msp->n0,
	      aln_p->d_start1,aln_p->d_stop1,
	      aln_p->l_offset+1, aln_p->l_offset+BBP_INFO(n1),
	      aln_p->ngap_q,aln_p->ngap_l,aln_p->nfs);
      if (m_msp->show_code == SHOW_CODE_ALIGN
	  && seq_code_len > 0 && seq_code != NULL) {
	fprintf(fp,"\t%s",seq_code);
	if (ann_code_len > 0 && ann_code != NULL) {
	  fprintf(fp,"\t%s",ann_code);
	}
	/*      fprintf(fp," [%2d:%d]",bbp->wrkr,bbp->seqnm); */


	/* if we are doing MX_M10FORM and -m 9c, then we want to keep
	   the alignment code string for the alignment output - otherwise, we
	   can free() it

	   If PCOMPLIB, then it is stored in bbp->ann_code*, otherwise, it's in a_res.
	*/

#ifndef PCOMPLIB
	if (m_msp->markx & MX_M10FORM)  {
	  /* save encoded alignments in a_res */
	  if ((bbp->a_res.aln_code = (char *)calloc(seq_code_len+1,sizeof(char)))!=NULL) {
	    strncpy(bbp->a_res.aln_code,seq_code,seq_code_len+1);
	    bbp->a_res.aln_code[seq_code_len] = '\0';
	    bbp->a_res.aln_code_n = seq_code_len;
	  }
	}
	/* always free the originally allocated encoding */
	free(seq_code);
	seq_code = NULL;
	seq_code_len = 0;
#else
	/* only free it if not to be used */
	if (!(m_msp->markx & MX_M10FORM))  {
	  free(bbp->aln_code);
	  bbp->aln_code_n = 0;
	}
#endif

	/* also clean up ann_code(_n) */

	if (ann_code_len > 0 && ann_code != NULL) {
#ifndef PCOMPLIB
	  if (m_msp->markx & MX_M10FORM)  {
	    /* save encoded annotations in a_res */
	    if ((bbp->a_res.ann_code = (char *)calloc(ann_code_len+1,sizeof(char)))!=NULL) {
	      strncpy(bbp->a_res.ann_code,ann_code,ann_code_len+1);
	      bbp->a_res.ann_code[ann_code_len] = '\0';
	      bbp->a_res.ann_code_n = ann_code_len;
	    }
	    else {
	      bbp->a_res.ann_code = NULL;
	      bbp->a_res.ann_code_n = 0;
	    }
	  }
	  free(ann_code);
	  ann_code = NULL;
	  ann_code_len = 0;
#else
	  if (!(m_msp->markx & MX_M10FORM))  {
	    free(bbp->ann_code);
	    bbp->ann_code_n = 0;
	  }
#endif
	}
      }
      if (m_msp->markx & MX_HTML) fprintf(fp," -->");
    }
    else {
#ifdef SHOWSIM
      fprintf(fp," %5.3f %5.3f %4d", percent/100.0,(float)aln_p->nsim/(float)aln_p->a_len,aln_p->a_len);
#else
      fprintf(fp," %5.3f %4d", percent/100.0,aln_p->a_len);
#endif
    }
  }
  if (m_msp->markx & MX_HTML) fprintf(fp," <A HREF=\"#%s\">align</A>",l_name);
  fprintf (fp, "\n");
  fflush(fp);
  }

  if (quiet==0) {
    printf(" More scores? [0] ");
    fflush(stdout);
    if (fgets(rline,20,stdin)==NULL) exit(0);
    ntmp = 0;
    if (rline[0]!='\n' && rline[0]!=0) sscanf(rline,"%d",&ntmp);
    if (ntmp<=0) ntmp = 0;
    if (ntmp>0) {
      istart = istop;
      nshow += ntmp;
      goto l1;
    }
  }
  else if (quiet == 1)
    if (ib < nbest && (ppst->zsflag>=0 && bbp->rst.escore < m_msp->e_cut)) {
      if (m_msp->mshow_flg && istop >= m_msp->mshow) goto done;
      istart=istop;
      nshow += 10;
      goto l1;
    }

 done:
  m_msp->nshow = nshow;

  if (m_msp->markx & MX_HTML) fprintf(fp,"</pre></tt><p><hr><p>\n");
  if (fp!=stdout) fprintf(fp,"\n");
}
Exemple #2
0
void showbest (FILE *fp, 
#ifndef PCOMPLIB
	       unsigned char **aa0, unsigned char *aa1, int maxn,
#endif
	       struct beststr **bptr,int nbest,
	       int qlib, struct mngmsg *m_msg,
	       struct pstruct *ppst, struct db_str db,
	       char **info_gstring2
#ifndef PCOMPLIB
	       ,void **f_str
#endif
	       )
{
  int i, j, k, rel_tot;
  int irelv;

  int unf_num0, relm_num0;
  int unf_num01,relm_num01;
  int unf_num02, relm_num02;
  int unf_num05, relm_num05;
  int unf_num100, relm_num100;
  int equ_num, rel_3_num, rel_1_num;

  double unf_score0, unf_score01, unf_score02 ,unf_score05;
  double unf_score100, equ_score, rel_3_score, rel_1_score;
  double unf_score0_b, unf_score01_b, unf_score02_b ,unf_score05_b;
  double unf_score100_b, equ_score_b, rel_3_score_b, rel_1_score_b;
  char *bp;

#ifdef PCOMPLIB
  int qsfnum[10],qsfnum_n[10],isf,nsf,nsf_n;
  char  *bp1, *bpn, *tp;
  char sfstr[MAX_FN];
#endif

#ifdef PCOMPLIB
  /*	not done here because done in pvcomplib.c */
  if ((bp=strchr(m_msg->qtitle,SFCHAR))!=NULL) {
    strncpy(sfstr,bp+1,sizeof(sfstr));
    sfstr[sizeof(sfstr)-1]='\0';
    if ((bp1=strchr(sfstr,SFCHAR)) != NULL) { /* look for second | */
      if ((bpn=strchr(sfstr,NSFCHAR))!=NULL) *bpn = '\0';
      *bp1='\0';
      tp = strtok(sfstr," \t");
      qsfnum[0]=atoi(tp);
      isf = 1;
      while ((tp=strtok(NULL," \t"))!=NULL) {
	qsfnum[isf++] = atoi(tp);
	if (isf >= 10) {
	  fprintf(stderr," error - too many superfamilies: %d\n %s\n",
		  isf,m_msg->qtitle);
	  break;
	}
      }
      qsfnum[nsf=isf]=0;
      sf_sort(qsfnum,nsf);

      /* now get negatives */
      qsfnum_n[0]= nsf_n = 0;
      if (bpn != NULL) {
	tp = strtok(bpn+1," \t");
	qsfnum_n[0]=atoi(tp);
	isf = 1;
	while ((tp=strtok(NULL," \t"))!=NULL) {
	  qsfnum_n[isf++] = atoi(tp);
	  if (isf >= 10) {
	    fprintf(stderr,
		    " error - too many negative superfamilies: %d\n %s\n",
		    isf,m_msg->qtitle);
	    break;
	  }
	}
	qsfnum[nsf_n=isf]=0;
	sf_sort(qsfnum_n,nsf_n);
      }
    }
    else {	/* only one sfnum */
      sscanf(bp+1,"%d",qsfnum);
      qsfnum[1]=0;
      qsfnum_n[0]= nsf_n = 0;
    }
  }
  else {
    fprintf(stderr," no query superfamily number\n %s\n",m_msg->qtitle);
    return;
  }
#endif

  if (m_msg->qframe > 1 || m_msg->nframe > 1) {

    /* this code is included for cases where there are several scores -
       forward and reverse, or six in the case of tfastf33s, for each
       sequence

       lnum_sort sorts the library by lseek position, which will be
       the same for the same sequence
    */

    lnum_sort(bptr,nbest);

  /* merge, saving the best score */
    i = j = 0;

    /* i has the source position we are currently examining
       k has the adjacent alternative scores ( k > i) 
       j has the destination 
    */

    while (i<nbest) {
      for (k=i+1; k < nbest && bptr[i]->seq->lseek == bptr[k]->seq->lseek; k++) {
	if (bptr[i]->zscore < bptr[k]->zscore) bptr[i] = bptr[k];
      }
      bptr[j++]=bptr[i];
      i = k;
    }

    if (j != m_msg->nbr_seq) {
      fprintf(stderr,"*** warning ***, nbest (%d/%d) != nbr_seq (%d)\n",
	      j,nbest,m_msg->nbr_seq);
      fprintf(stdout,"*** warning ***, nbest (%d/%d) != nbr_seq (%d)\n",
	      j,nbest,m_msg->nbr_seq);
    }
    nbest = j;

    if (ppst->zsflag >=0) sortbeste(bptr, nbest);
    else sortbest(bptr,nbest,ppst->score_ix);
  }

/* fprintf(stderr," %1d label is %s (%s)\n",irelv,labptr,label); */

/* get the query superfamily */
  
  for (i=0; i<nbest; i++) {
    /*    if (sfn_cmp(BSFNUM(i),NQSFNUM)) continue; */
    if (sfn_cmp(BSFNUM(i),QSFNUM)==0 && sfn_cmp(BSFNUM(i),NQSFNUM)==0) {
      unf_num0=i;
      unf_score0=bptr[i]->zscore;
      unf_score0_b=zs_to_bit(bptr[i]->zscore,m_msg->n0,bptr[i]->seq->n1);
      break;
    }
  }

  if (i>=nbest) {
    fprintf(stderr," %s: %d\n error - no unrelated sequences\n",
	    m_msg->qtitle,QSFNUM[0]);
    return;
  }
  
  for (i=rel_tot=relm_num0=0; i<nbest; i++) {
    /*    if (sfn_cmp(BSFNUM(i),NQSFNUM)) continue; */
    if (sfn_cmp(BSFNUM(i),QSFNUM)>0 ) {
      rel_tot++;			/* total related */
      if (bptr[i]->zscore <= unf_score0) relm_num0++;
#ifdef DEBUG      
      if (ppst->debug_lib)
	fprintf(stderr,"%d\t%l\t%.1f\n",i,bptr[i]->seq->lseek,bptr[i]->zscore);
#endif
    }
  }
  
  /* relm_num0, unf_num0, unf_score0 done */
  
  /* now calculate number missed at various expectation value cutoffs */
  /* calculate z-score cutoff for E()=0.01, 0.02, 0.05 */

  unf_score01 = E_to_zs(0.01,db.entries);
  unf_score02 = E_to_zs(0.02,db.entries);
  unf_score05 = E_to_zs(0.05,db.entries);
  unf_score100 = E_to_zs(1.00,db.entries);

  /* relm_num01, unf_num01, unf_score01 done */
  
  for (i=unf_num01=0,relm_num01=rel_tot;
       i<nbest && bptr[i]->zscore >= unf_score01; i++) {
/*    if (sfn_cmp(BSFNUM(i),NQSFNUM)) continue; */
    if (sfn_cmp(BSFNUM(i),QSFNUM)==0) {
      if (sfn_cmp(BSFNUM(i),NQSFNUM)==0) unf_num01++;
    }
    else relm_num01--;
  }
  unf_score01_b=zs_to_bit(bptr[i]->zscore,m_msg->n0,bptr[i]->seq->n1);

  for (i=unf_num02=0,relm_num02=rel_tot;
       i<nbest && bptr[i]->zscore >= unf_score02; i++) {
/*    if (sfn_cmp(BSFNUM(i),NQSFNUM)) continue; */
    if (sfn_cmp(BSFNUM(i),QSFNUM)==0) {
      if (sfn_cmp(BSFNUM(i),NQSFNUM)==0) unf_num02++;
    }
    else relm_num02--;
  }
  unf_score02_b=zs_to_bit(bptr[i]->zscore,m_msg->n0,bptr[i]->seq->n1);
      
  for (i=unf_num05=0,relm_num05=rel_tot;
       i<nbest && bptr[i]->zscore >= unf_score05; i++) {
/*    if (sfn_cmp(BSFNUM(i),NQSFNUM)) continue; */
    if (sfn_cmp(BSFNUM(i),QSFNUM)==0) {
      if (sfn_cmp(BSFNUM(i),NQSFNUM)==0) unf_num05++;
    }
    else relm_num05--;
  }
  unf_score05_b=zs_to_bit(bptr[i]->zscore,m_msg->n0,bptr[i]->seq->n1);
      
  for (i=unf_num100=0,relm_num100=rel_tot;
       i<nbest && bptr[i]->zscore >= unf_score100; i++) {
/*     if (sfn_cmp(BSFNUM(i),NQSFNUM)) continue; */
    if (sfn_cmp(BSFNUM(i),QSFNUM)==0) {
      if (sfn_cmp(BSFNUM(i),NQSFNUM)==0) unf_num100++;
    }
    else relm_num100--;
  }
  unf_score100_b=zs_to_bit(bptr[i]->zscore,m_msg->n0,bptr[i]->seq->n1);
      
  /* the final criterion finds the score and the number of sequences
     where the number of unrelated sequences found == the number of
     related sequences missed. */
  
  equ_num=0;
  i = 0; j=nbest-1;

/* j is counting up the list of scores (actually down the array) from
  the lowest scoring related sequence

  i is counting down the list of scores (actually up the array)
  from the highest scoring unrelated sequence */

  for (i=0, j=nbest-1; j>=0 && i<nbest; i++,j--) {
    /* i++ while sequences are related, stop at next unrelated */
    while (i<nbest && (sfn_cmp(BSFNUM(i),QSFNUM) || sfn_cmp(BSFNUM(i),NQSFNUM))) i++; 
    /* j-- while sequences are unrelated, stop at next related */
    while (j>=0 && ( sfn_cmp(BSFNUM(j),QSFNUM)==0)) j--;
    /*
      fprintf(stderr,"i: %3d %3d %4d; j: %3d %3d %4d\n",i,bptr[i]->zscore,
      BSFNUM(i),j,bptr[j]->zscore,BSFNUM(j));
      */
    /* if unrelated [i] score <= related [j] score, quit */
    if (bptr[i]->zscore <= bptr[j]->zscore) break;
    equ_num++;
  }
  
  equ_score = 0.0;
  if (i>=nbest || j<0) {
#ifndef PCOMPLIB
    if (ppst->debug_lib) 
#endif
      fprintf(stderr," i (%3d), j (%3d) off end\n %s\n", i, j,m_msg->qtitle);
    equ_num = rel_tot+1; equ_score = 0.0;
  }
  else {
    equ_score=bptr[i]->zscore;
    equ_score_b =zs_to_bit(bptr[i]->zscore,m_msg->n0,bptr[i]->seq->n1);
  }
  
  /* get the lowest scoring related */
  for (i=0,rel_1_num=rel_tot-1; i<nbest && rel_1_num > 0; i++) {
/*    if (sfn_cmp(BSFNUM(i),NQSFNUM)) continue; */
    if (sfn_cmp(BSFNUM(i),QSFNUM)) rel_1_num--;
  }
  rel_1_num = i;
  rel_1_score = bptr[i]->zscore;
  rel_1_score_b=zs_to_bit(bptr[i]->zscore,m_msg->n0,bptr[i]->seq->n1);

  /* get the 3rd lowest scoring related */
  for (i=0,rel_3_num=rel_tot-3; i<nbest && rel_3_num > 0; i++) {
/*     if (sfn_cmp(BSFNUM(i),NQSFNUM)) continue; */
    if (sfn_cmp(BSFNUM(i),QSFNUM)) rel_3_num--;
  }
  rel_3_num = i;
  rel_3_score = bptr[i]->zscore;
  rel_3_score_b=zs_to_bit(bptr[i]->zscore,m_msg->n0,bptr[i]->seq->n1);

  fprintf(fp,"%3d>%s - %d (%d/%d)\n",
	  qlib,m_msg->qtitle, QSFNUM[0],rel_tot,nbest);
  fprintf(fp," 0.0 criterion- relm: %3d pos: %3d score: %5.1f exp: %6.4g\n",
	  relm_num0, unf_num0+1, unf_score0_b,
	  zs_to_E(unf_score0,m_msg->n0,ppst->dnaseq,ppst->zdb_size,db));
  fprintf(fp," 0.01 criterion- relm: %3d unf: %3d score: %5.1f exp: %6.4g\n",
	  relm_num01, unf_num01, unf_score01_b,
	  zs_to_E(unf_score01,m_msg->n0,ppst->dnaseq,ppst->zdb_size,db));
  fprintf(fp," 0.02 criterion- relm: %3d unf: %3d score: %5.1f exp: %6.4g\n",
	  relm_num02, unf_num02, unf_score02_b,
	  zs_to_E(unf_score02,m_msg->n0,ppst->dnaseq,ppst->zdb_size,db));
  fprintf(fp," 0.05 criterion- relm: %3d unf: %3d score: %5.1f exp: %6.4g\n",
	  relm_num05, unf_num05, unf_score05_b,
	  zs_to_E(unf_score05,m_msg->n0,ppst->dnaseq,ppst->zdb_size,db));
  fprintf(fp," 1.00 criterion- relm: %3d unf: %3d score: %5.1f exp: %6.4g\n",
	  relm_num100, unf_num100, unf_score100_b,
	  zs_to_E(unf_score100,m_msg->n0,ppst->dnaseq,ppst->zdb_size,db));

  fprintf(fp," equ num: %3d score: %5.1f exp: %6.4g\n",equ_num,equ_score_b,
	  zs_to_E(equ_score,m_msg->n0,ppst->dnaseq,ppst->zdb_size,db));

  fprintf(fp," rel[-1]: %3d score: %5.1f exp: %6.4g\n",rel_1_num+1,rel_1_score_b,
	  zs_to_E(rel_1_score,m_msg->n0,ppst->dnaseq,ppst->zdb_size,db));
  fprintf(fp," rel[-3]: %3d score: %5.1f exp: %6.4g\n",rel_3_num+1,rel_3_score_b,
	  zs_to_E(rel_3_score,m_msg->n0,ppst->dnaseq,ppst->zdb_size,db));

  /* 
  fprintf(fp,"/ ** %s ** /\n",info_gstring2);
  fflush(fp);
  */
  m_msg->nshow = m_msg->ashow;
}
void showbest (FILE *fp, unsigned char **aa0, unsigned char *aa1save, int maxn,
	       struct beststr **bptr,int nbest,
	       int qlib, struct mngmsg *m_msp,
	       struct pstruct *ppst, struct db_str db,
	       char **info_gstring2
	       ,void **f_str
)
{
  unsigned char *aa1;
  int best_align_done = 0;
  int ntmp = 0;
  char bline[MAX_BLINE], fmt[40], pad[MAX_BLINE], fmt2[40], rline[40];
  char l_name[128], link_name[140];
  int istart = 0, istop, ib;
  int nshow;		/* number of sequences shown before prompt,
			   and ultimately displayed */
  int first_line, link_shown;
  int quiet;
  int r_margin;
  struct beststr *bbp;
  int n1tot;
  char *bp, *bline_p;
  char rel_label[12];
  char score_label[120];
  char tmp_str[20], *seq_code, *ann_code;
  int seq_code_len, ann_code_len;
  long loffset;		/* loffset is offset from beginning of real sequence */
  long l_off;		/* l_off is the the virtual coordinate of residue 1 */
  int n1, ranlib_done;
  struct rstruct rst;
  int l_score0, ngap;
  double lzscore, lzscore2, lbits;
  float percent, gpercent;
  struct a_struct *aln_p;
  struct a_res_str *cur_ares_p;
  struct rstruct *rst_p;
  int gi_num;
  char html_pre_E[120], html_post_E[120];
  int have_lalign = 0;

  struct lmf_str *m_fptr;

  /* for lalign alignments, only show stuff when -m != 11 */

  if (m_msp->markx & MX_M11OUT) return;
  if (strcmp(m_msp->label,"ls-w")==0) {
    have_lalign = 1;
    if ((m_msp->markx & MX_M9SUMM) == 0) return;
  }

  rel_label[0]='\0';
  SAFE_STRNCPY(score_label,"scores", sizeof(score_label));

  quiet = m_msp->quiet;

  if (m_msp->aln.llen > MAX_BLINE) m_msp->aln.llen = MAX_BLINE;

  if (ppst->zsflag < 0) r_margin = 10;
  else if (ppst->zsflag>=0  && m_msp->srelv > 1 ) r_margin = 19;
  else r_margin = 10;

  if (m_msp->markx & MX_M9SUMM && m_msp->show_code == SHOW_CODE_ID) {
#ifdef SHOWSIM
    r_margin += 15;
#else
    r_margin += 10;
#endif
  }
  else if (m_msp->markx & MX_MBLAST2) {
    r_margin -= 10;
  }
  else if (m_msp->markx & (MX_M9SUMM + MX_M8OUT)) {
    r_margin = 0;
  }

  if (m_msp->markx & MX_HTML) {
    strncpy(html_pre_E,"<font color=\"darkred\">",sizeof(html_pre_E));
    strncpy(html_post_E,"</font>",sizeof(html_post_E));

  }
  else {
    html_pre_E[0] = html_post_E[0] = '\0';
  }

  if (m_msp->nframe < 0) {
    sprintf(fmt,"%%-%ds (%%4d)",m_msp->aln.llen-r_margin);
  }
  else {
    sprintf(fmt,"%%-%ds (%%4d)",m_msp->aln.llen-(r_margin+4));
  }
  sprintf(fmt2,"%%-%ds",m_msp->aln.llen-r_margin+8);

  memset(pad,' ',m_msp->aln.llen-(r_margin+6));
  pad[m_msp->aln.llen-(r_margin+12)]='\0';
  if (have_lalign) {
    if (ppst->show_ident) {
      SAFE_STRNCPY(score_label,"alignments", sizeof(score_label));
      pad[m_msp->aln.llen-(r_margin+16)]='\0';
    }
    else {
      SAFE_STRNCPY(score_label,"non-identical alignments", sizeof(score_label));
      pad[m_msp->aln.llen-(r_margin+30)]='\0';
    }
  }

  nshow = min(m_msp->nshow,nbest);

  if ((bp = strchr (m_msp->qtitle, '\n')) != NULL) *bp = '\0';
  if (m_msp->markx & MX_M8OUT) {
    if ((bp = strchr (m_msp->qtitle, ' ')) != NULL) *bp = '\0';
  }

/*   fprintf (fp, "%3d %s\n", qlib,m_msp->qtitle); */

  if (m_msp->markx & MX_HTML) fprintf(fp,"<pre>");

  /* **************************************************************** */
  /* done with display format */
  /* **************************************************************** */

  /* **************************************************************** */
  /* prompt for number of best scores if quiet == 0 */
  /* **************************************************************** */

  if (quiet == 0) {	/* interactive */
    nshow = min(m_msp->nshow, nbest);
    printf(" How many scores would you like to see? [%d] ",nshow);
    fflush(stdout);
    if (fgets(rline,20,stdin)==NULL) exit(0);
    if (rline[0]!='\n' && rline[0]!=0) sscanf(rline,"%d",&nshow);
    if (nshow > nbest) nshow=nbest;
    if (nshow<=0) nshow = min(20,nbest);
  }

  /* display number of hits for -m 8C (Blast Tab-commented format) */
  if (m_msp->markx & MX_M8COMMENT) {
    /* line below copied from BLAST+ output */
    fprintf(fp,"# Fields: query id, subject id, %% identity, alignment length, mismatches, gap opens, q. start, q. end, s. start, s. end, evalue, bit score");
    if (m_msp->show_code == SHOW_CODE_ALIGN || m_msp->show_code == SHOW_CODE_CIGAR) { fprintf(fp," aln_code");}
    fprintf(fp,"\n");
    fprintf(fp,"# %d hits found\n",nshow);
  }

  /* **************************************************************** */
  /* have number of scores in interactive or quiet mode */
  /* display "The best scores are" */
  /* **************************************************************** */

  if (m_msp->markx & MX_MBLAST2) {
    fprintf(fp, "%81s\n"," Score     E");
    fprintf(fp, "Sequences producing significant alignments:                          (Bits)  Value\n\n");
  }
  else if (!(m_msp->markx & MX_M8OUT)) {
    if (ppst->zsflag >= 0) {
      if (m_msp->z_bits==1) {/* show bit score */
	fprintf(fp,"\nThe best%s %s are:%s%s bits %sE(%ld)%s",
		rel_label,score_label,pad,m_msp->label,html_pre_E,ppst->zdb_size,html_post_E);
	if (ppst->zsflag > 20) {
	  fprintf(fp," E2()");
	}
      }
      else {/* show z-score */
	fprintf(fp,"\nThe best%s %s are:%s%s z-sc %sE(%ld)%s",
		rel_label,score_label,pad,m_msp->label,html_pre_E,ppst->zdb_size,html_post_E);
	if (ppst->zsflag > 20) {
	  fprintf(fp," E2()");
	}
      }
      header_aux(fp);
      if (m_msp->markx & MX_M9SUMM) {
	if (m_msp->show_code == SHOW_CODE_ID) {
#ifdef SHOWSIM
	  fprintf(fp," %%_id  %%_sim  alen");
#else
	  fprintf(fp," %%_id  alen");
#endif
	}
	else {
	  if (m_msp->markx & MX_HTML && m_msp->show_code !=1) { fprintf(fp,"<!-- ");}
#ifndef SHOWSIM
	  fprintf(fp,"\t%%_id  %%_gid %4s  alen  an0  ax0  pn0  px0  an1  ax1 pn1 px1 gapq gapl  fs ",m_msp->f_id1);
#else
	  fprintf(fp,"\t%%_id  %%_sim %4s  alen  an0  ax0  pn0  px0  an1  ax1 pn1 px1 gapq gapl  fs ",m_msp->f_id1);
#endif
	}
	if (m_msp->show_code == SHOW_CODE_ALIGN) { fprintf(fp," aln_code"); }
	if (m_msp->markx & MX_HTML && m_msp->show_code!=1) { fprintf(fp," -->");}
      }
      fprintf(fp,"\n");
    }
    else {
      fprintf(fp,"\nThe best%s %s are:%s%s",rel_label,score_label,pad,m_msp->label);
      header_aux(fp);
      if (m_msp->markx & MX_M9SUMM) {
	if (m_msp->show_code == SHOW_CODE_ID) {
#ifdef SHOWSIM
	  fprintf(fp," %%_id  %%_sm  alen");
#else
	  fprintf(fp," %%_id  alen");
#endif
	}
	else {
#ifndef SHOWSIM
	  fprintf(fp,"\t%%_id  %%_gid %4s  alen  an0  ax0  pn0  px0  an1  ax1 pn1 px1 gapq gapl  fs ",m_msp->f_id1);
#else
	  fprintf(fp,"\t%%_id  %%_sim %4s  alen  an0  ax0  pn0  px0  an1  ax1 pn1 px1 gapq gapl  fs ",m_msp->f_id1);
#endif	/* SHOWSIM */
	}
      }
      if (m_msp->show_code == SHOW_CODE_ALIGN) { fprintf(fp," aln_code"); }
      fprintf(fp,"\n");
    }
  }	/* !(m_msp->markx & MX_M8OUT) */

  istart = 0;
l1:
  istop = min(nshow, nbest);

  for (ib=istart; ib<istop; ib++) {
    bbp = bptr[ib];
    if (ppst->do_rep) {
      bbp->repeat_thresh = 
	min(E1_to_s(ppst->e_cut_r, m_msp->n0, bbp->seq->n1,ppst->zdb_size, m_msp->pstat_void),
	    bbp->rst.score[ppst->score_ix]);
    }

#ifdef DEBUG
    if (bbp->seq->n1 != bbp->n1 ) {
      fprintf(stderr, " *** lib len error [%d!=%d] *** %s score %d\n",
	      bbp->seq->n1,bbp->n1, bbp->mseq->libstr, bbp->rst.score[0]);
    }
#endif

    /* this gets us a valid bline[] and the library for searching if necessary
       do not read if we have a long enough bline or we don't need a sequence 
    */
    if (bbp->mseq->bline != NULL && bbp->mseq->bline_max >= m_msp->aln.llen) {
      ranlib_done = 0;

      /* copy m_msp->aln.llen, not llen-r_margin, because the r_margin
	 will be set later, possibly after the gi|12345 is removed */
      strncpy(bline,bbp->mseq->bline,m_msp->aln.llen);
      bline[m_msp->aln.llen]='\0';
    }
    else {
      if ((m_fptr=re_openlib(bbp->mseq->m_file_p,!m_msp->quiet))==NULL) {
	fprintf(stderr,"*** cannot re-open %s\n",bbp->mseq->m_file_p->lb_name);
	exit(1);
      }
      RANLIB(bline,m_msp->aln.llen,bbp->mseq->lseek,bbp->mseq->libstr,m_fptr);
      ranlib_done = 1;
    }

    /* get a valid cur_ares_p chain and put it in bbp->ares */
    if (!m_msp->align_done && (m_msp->stages>1 || (m_msp->markx & MX_M9SUMM))) {	/* we need a sequence */
      if (bbp->seq->aa1b == NULL || (m_msp->ann_flg==1 && bbp->seq->annot_p==NULL)) {
	if (!ranlib_done) {	/* we didn't open the library already */
	  if ((m_fptr=re_openlib(bbp->mseq->m_file_p,!m_msp->quiet))==NULL) {
	    fprintf(stderr,"*** cannot re-open %s\n",bbp->mseq->m_file_p->lb_name);
	    exit(1);
	  }
	  RANLIB(bline,m_msp->aln.llen,bbp->mseq->lseek,bbp->mseq->libstr,m_fptr);
	  ranlib_done = 1;
	}
	n1 = re_getlib(aa1save,
		       (m_msp->ann_flg==1) ? &(bbp->seq->annot_p) : NULL, 
		       maxn,m_msp->ldb_info.maxt3,
		       m_msp->ldb_info.l_overlap,bbp->mseq->cont,m_msp->ldb_info.term_code,
		       &bbp->seq->l_offset,&bbp->seq->l_off,bbp->mseq->m_file_p);

	aa1 = aa1save;

	if (m_msp->ann_flg==2 && bbp->seq->annot_p==NULL ) {
	  /* get information about this sequence from bline */
	  if (get_annot(m_msp->annot1_sname, m_msp, bline, bbp->seq->n1, &(bbp->seq->annot_p), 1, ppst->debug_lib) > 0) {
	    /* do something with annotation */
	    s_annot_to_aa1a(bbp->n1, bbp->seq->annot_p, m_msp->ann_arr);
	  }
	}
      }
      else {
	n1 = bbp->seq->n1;
	aa1 = bbp->seq->aa1b;
      }

      if (n1 != bbp->n1) {
	fprintf(stderr," *** sequence length conflict %d != %d: %s\n", n1, bbp->n1, bline);
	continue;
      }

      if ( m_msp->stages > 1 && bbp->rst.score[2] == -BIGNUM) { 
	/* this is not typically done unless m_msp->stages > 1 */
	do_opt (aa0[bbp->frame], m_msp->n0, aa1, n1, bbp->frame, ppst, f_str[bbp->frame], &rst);
	bbp->rst.score[2]=rst.score[2];
      }

      if (!bbp->have_ares & 0x1) {
	bbp->a_res = build_ares_code(aa0[bbp->frame], m_msp->n0, aa1, bbp->seq,
				     bbp->frame, &bbp->have_ares,
				     bbp->repeat_thresh, m_msp, ppst, f_str[bbp->frame] );
	best_align_done = 1;
      }
    }	/* end stages > 1 || MX_M9SUMM9 */

    n1tot = (bbp->mseq->n1tot_p) ? *bbp->mseq->n1tot_p : bbp->seq->n1;

    bline_p = bline;
    if (!(m_msp->markx & (MX_M8OUT)) && !strncmp(bline,"gi|",3)) {
      bline_p = strchr(bline+4,'|')+1;
      *(bline_p-1) = 0;
      gi_num = atoi(bline+3);
    }

  /* l_name is used to build an HTML link from the bestscore line to
     the alignment.  It can also be used to discriminate multiple hits
     from the same long sequence.  This requires that fast_pan use -m 6.

     (6-April-2013) Add ability to specify additional alignments with
     link_name;
  */

    SAFE_STRNCPY(l_name,bline_p,sizeof(l_name)); /* get rid of text after second "|" */
    if ((bp=strchr(l_name,' '))!=NULL) *bp=0;
    if ((bp=strchr(&l_name[6],'|'))!=NULL) *bp='\0'; 	/* increase to [6] from [3] to allow longer db names "ref", "unk", */
    if (m_msp->nframe > 2) sprintf(&l_name[strlen(l_name)],"_%d",bbp->frame+1);
    else if (m_msp->nframe > 0 && bbp->frame == 1)
      SAFE_STRNCAT(l_name,"_r",sizeof(l_name));
    if (bbp->mseq->cont-1 > 0) {
      sprintf(tmp_str,":%d",bbp->mseq->cont-1);
      SAFE_STRNCAT(l_name,tmp_str,sizeof(l_name));
    }

    if (m_msp->markx & MX_M8OUT) {
      if ((bp=strchr(bline_p,' '))!=NULL) *bp = '\0';
    }
    else {
      bline_p[m_msp->aln.llen-r_margin]='\0';
      /* check for translated frame info */
      if (m_msp->nframe > -1) bline_p[m_msp->aln.llen-(r_margin+4)]='\0';
    }
    /* now its time to report the summary numbers for all the alignments */

    /* in the next loop, cur_ares_p could be NULL if we haven't done do_walign() */
    cur_ares_p = bbp->a_res;

    first_line = 1;
    do {
      /* if cur_res_p != NULL, then we get rst from a_res->rst
	 Otherwise, it comes from bbp->rst
      */

      if ((!first_line || (have_lalign && !ppst->show_ident)) && cur_ares_p ) {
	rst_p = &cur_ares_p->rst;
      }
      else {
	rst_p = &bbp->rst;
      }

      n1 = bbp->seq->n1;
      l_score0 = rst_p->score[ppst->score_ix];
      lzscore = find_z(l_score0, rst_p->escore, n1, rst_p->comp, m_msp->pstat_void);
      if (ppst->zsflag > 20) {
	lzscore2 = find_z(l_score0, rst_p->escore, n1, rst_p->comp, m_msp->pstat_void2);
      }
      lbits = zs_to_bit(lzscore, m_msp->n0, n1);

      /* *********************************** */
      /* standard "The best scores are" here */
      /* *********************************** */

      if (!(m_msp->markx & (MX_M8OUT + MX_MBLAST2))) {
	if (first_line) {
	  first_line = 0;
	  fprintf (fp, fmt,bline_p,n1tot);
	  if (m_msp->nframe > 2) fprintf (fp, " [%d]", bbp->frame+1);
	  else if (m_msp->nframe >= 0) fprintf(fp," [%c]",(bbp->frame > 0 ?'r':'f'));
	}
	else {
	  fprintf (fp, fmt2,"\n+-");
	}

	if (m_msp->srelv == 1) fprintf (fp, " %4d", rst_p->score[ppst->score_ix]);
	else {
	  if (m_msp->srelv-1 > 0) fprintf (fp, " %4d", rst_p->score[0]);
	  if (m_msp->srelv-1 > 1 || m_msp->stages>1)
	    fprintf (fp, " %4d", rst_p->score[1]);
	  fprintf (fp, " %4d", rst_p->score[ppst->score_ix]);
	}

	if (ppst->zsflag>=0) { 
	  if (m_msp->z_bits==1) {
	    fprintf (fp, " %.1f %s%7.2g%s",lbits,html_pre_E,
		     zs_to_E(lzscore, n1, ppst->dnaseq, ppst->zdb_size, m_msp->db),
		     html_post_E);
	    if (ppst->zsflag > 20) {
	      fprintf (fp, " %7.2g",zs_to_E(lzscore2, n1, ppst->dnaseq, ppst->zdb_size, m_msp->db));
	    }
	  }
	  else {
	    fprintf (fp, " %.1f %s%7.2g%s",lzscore,html_pre_E,
		     zs_to_E(lzscore, n1, ppst->dnaseq, ppst->zdb_size, m_msp->db),
		     html_post_E);
	    if (ppst->zsflag > 20) {
	      fprintf (fp, " %7.2g",zs_to_E(lzscore2, n1, ppst->dnaseq, ppst->zdb_size, m_msp->db));
	    }
	  }
	}
	show_aux(fp,bbp);
      }
      else if (m_msp->markx & MX_M8OUT) {	/* MX_M8OUT -- provide query, library */
	if (first_line) {first_line = 0;}
	fprintf (fp,"%s\t%s",m_msp->qtitle,bline_p);
      }
      else if (m_msp->markx & MX_MBLAST2) {	/* blast "Sequences producing" */ 
	if (first_line) {first_line = 0;}
	fprintf (fp,"%-67s %6.1f    %.1g", bline_p, lbits,
		    zs_to_E(lzscore,n1,ppst->dnaseq,ppst->zdb_size,m_msp->db));
      }

      if (m_msp->markx & MX_M9SUMM || m_msp->markx & MX_M8OUT) {
	loffset = bbp->seq->l_offset;
	l_off = bbp->seq->l_off;
	aln_p = &cur_ares_p->aln;
	seq_code = cur_ares_p->aln_code;
	seq_code_len = cur_ares_p->aln_code_n;
	ann_code = cur_ares_p->ann_code;
	ann_code_len = cur_ares_p->ann_code_n;

        percent = calc_fpercent_id(100.0,aln_p->nident,aln_p->lc, m_msp->tot_ident, -100.0);

	ngap = cur_ares_p->aln.ngap_q + cur_ares_p->aln.ngap_l;
#ifndef SHOWSIM
	gpercent = calc_fpercent_id(100.0, aln_p->nident, aln_p->lc-ngap, m_msp->tot_ident, -100.0);
#else
	gpercent = calc_fpercent_id(100.0, cur_ares_p->aln.nsim, aln_p->lc, m_msp->tot_ident, -100.0);
#endif	/* SHOWSIM */

	if (m_msp->show_code != SHOW_CODE_ID) {	/* show more complete info than just identity */

	  /*  	calc_astruct(aln_p, cur_ares_p); -- this function
		should not be used after calc_code or any other
		alignment that calculates amax0/amax1 */

	  /* we need the coordinates for annotated SHOW_CODE_ALIGN */
	  calc_coord(m_msp->n0,bbp->seq->n1,
		     m_msp->q_offset + (m_msp->q_off-1) + (m_msp->sq0off-1),
		     loffset + (l_off-1) + (m_msp->sq1off-1),
		     aln_p);

	  /* if (m_msp->markx & MX_HTML) fprintf(fp,"<!-- "); */
	  /*            %_id  %_sim s-w alen an0  ax0  pn0  px0  an1  ax1  pn1  px1 gapq gapl fs  */
	  /*                    alignment    min  max            min  max */
	  /*                    sequence coordinate    min  max            min  max */
	  if (!(m_msp->markx & MX_M8OUT)) {
	    fprintf(fp,"\t%5.3f %5.3f %4d %4d %4ld %4ld %4ld %4ld %4ld %4ld %4ld %4ld %3d %3d %3d",
		    percent/100.0,gpercent/100.0, 
		    cur_ares_p->sw_score,
		    aln_p->lc,
		    aln_p->d_start0,aln_p->d_stop0,
		    aln_p->q_start_off, aln_p->q_end_off,
		    aln_p->d_start1,aln_p->d_stop1,
		    aln_p->l_start_off, aln_p->l_end_off,
		    aln_p->ngap_q,aln_p->ngap_l,aln_p->nfs);
	    if ((m_msp->show_code & SHOW_CODE_ALIGN) == SHOW_CODE_ALIGN
		&& seq_code_len > 0 && seq_code != NULL) {
	      fprintf(fp,"\t%s",seq_code);
	      if (ann_code_len > 0 && ann_code != NULL) {
		fprintf(fp,"\t%s",ann_code);
	      }
	    }
	  }
	  else {	/* MX_M8OUT -- blast order, tab separated */
	    fprintf(fp,"\t%.2f\t%d\t%d\t%d\t%ld\t%ld\t%ld\t%ld\t%.2g\t%.1f",
		    percent,aln_p->lc,aln_p->nmismatch,
		    aln_p->ngap_q + aln_p->ngap_l+aln_p->nfs,
		    aln_p->d_start0, aln_p->d_stop0,
		    aln_p->d_start1, aln_p->d_stop1,
		    zs_to_E(lzscore,n1,ppst->dnaseq,ppst->zdb_size,m_msp->db),
		    lbits);
	    if ((m_msp->show_code & SHOW_CODE_ALIGN) == SHOW_CODE_ALIGN && seq_code_len > 0 && seq_code != NULL) {
	      fprintf(fp,"\t%s",seq_code);
	      if (ann_code_len > 0 && ann_code != NULL) {
		fprintf(fp,"\t%s",ann_code);
	      }
	    }
	    fprintf(fp,"\n");
	  }
	}
	else {	/* !SHOW_CODE */
#ifdef SHOWSIM
	  fprintf(fp," %5.3f %5.3f %4d", 
		  percent/100.0,
		  (float)aln_p->nsim/(float)aln_p->lc,aln_p->lc);
#else
	  fprintf(fp," %5.3f %4d", percent/100.0,aln_p->lc);
#endif
	  if (m_msp->markx & MX_HTML) {
	    if (cur_ares_p->index > 0) {
	      sprintf(link_name,"%s_%d",l_name, cur_ares_p->index);
	    }
	    else {
	      SAFE_STRNCPY(link_name, l_name, sizeof(l_name));
	    }
	    fprintf(fp," <a href=\"#%s\">align</a>",link_name);
	    link_shown = 1;
	  }
	  if (cur_ares_p->annot_var_s) {
	    fprintf(fp," |Var: %s",cur_ares_p->annot_var_s);
	  }
	  else { link_shown = 0;}
	}
      }
    } while ( cur_ares_p && (cur_ares_p = cur_ares_p->next));

    /*    if ((m_msp->markx & MX_HTML) && !link_shown) fprintf(fp," <a href=\"#%s\">align</a>",l_name); */
    if (!(m_msp->markx & MX_M8OUT)) fprintf(fp, "\n");
    fflush(fp);
  }

  if (quiet==0) {
    printf(" More scores? [0] ");
    fflush(stdout);
    if (fgets(rline,20,stdin)==NULL) exit(0);
    ntmp = 0;
    if (rline[0]!='\n' && rline[0]!=0) sscanf(rline,"%d",&ntmp);
    if (ntmp<=0) ntmp = 0;
    if (ntmp>0) {
      istart = istop;
      nshow = min(nshow+ntmp, nbest);
      goto l1;
    }
  }	/* end of for (ib) loop */

  if (m_msp->markx & MX_MBLAST2) {fprintf(fp, "\n\n");}

  m_msp->nshow = nshow;	/* save the number of hits displayed for showalign */

  if (best_align_done) { m_msp->align_done = 1;}	/* note that alignments are done */

  if (m_msp->markx & MX_HTML) fprintf(fp,"</pre><hr>\n");
}