hmmer-3.3/easel/miniapps/esl-sfetch.c
/* multifetch:
 * given a file containing lines with one name or key per line;
 * parse the file line-by-line;
 * if we have an SSI index available, retrieve the seqs by key
 * as we see each line;
 * else, without an SSI index, store the keys in a hash, then
 * read the entire seq file in a single pass, outputting seqs
 * that are in our keylist. 
 * 
 * Note that with an SSI index, you get the seqs in the order they
 * appear in the <keyfile>, but without an SSI index, you get seqs in
 * the order they occur in the seq file.
 */
given a file containing lines with one name or key per line;
parse the file line-by-line;
if we have an SSI index available, retrieve the seqs by key
as we see each line;
else, without an SSI index, store the keys in a hash, then
read the entire seq file in a single pass, outputting seqs
that are in our keylist.

Note that with an SSI index, you get the seqs in the order they
appear in the , but without an SSI index, you get seqs in
the order they occur in the seq file.
given a file containing lines with one name or key per line ; parse the file line - by - line ; if we have an SSI index available retrieve the seqs by key as we see each line ; else without an SSI index store the keys in a hash then read the entire seq file in a single pass outputting seqs that are in our keylist . Note that with an SSI index you get the seqs in the order they appear in the but without an SSI index you get seqs in the order they occur in the seq file .
static void
multifetch(ESL_GETOPTS *go, FILE *ofp, char *keyfile, ESL_SQFILE *sqfp)
{
  ESL_KEYHASH    *keys   = esl_keyhash_Create();
  ESL_FILEPARSER *efp    = NULL;
  int             nseq   = 0;
  int             nkeys  = 0;
  char           *key;
  int             keylen;
  int             keyidx;
  int             status;
  if (esl_fileparser_Open(keyfile, NULL, &efp) != eslOK)  esl_fatal("Failed to open key file %s\n", keyfile);
  esl_fileparser_SetCommentChar(efp, '#');
  while (esl_fileparser_NextLine(efp) == eslOK)
    {
      if (esl_fileparser_GetTokenOnLine(efp, &key, &keylen) != eslOK)
	esl_fatal("Failed to read seq name on line %d of file %s\n", efp->linenumber, keyfile);
      status = esl_keyhash_Store(keys, key, keylen, &keyidx);
      if (status == eslEDUP) esl_fatal("seq key %s occurs more than once in file %s\n", key, keyfile);
      if (sqfp->data.ascii.ssi != NULL) { onefetch(go, ofp, key, sqfp);  nseq++; }
      nkeys++;
    }
  if (sqfp->data.ascii.ssi == NULL) 
    {
      ESL_SQ *sq     = esl_sq_Create();
      while ((status = esl_sqio_Read(sqfp, sq)) == eslOK)
	{
	  if ( (sq->name[0] != '\0' && esl_keyhash_Lookup(keys, sq->name, -1, NULL) == eslOK) ||
	       (sq->acc[0]  != '\0' && esl_keyhash_Lookup(keys, sq->acc,  -1, NULL) == eslOK))
	    {
	      if (esl_opt_GetBoolean(go, "-r") )
		if (esl_sq_ReverseComplement(sq) != eslOK) 
		  esl_fatal("Failed to reverse complement %s\n", sq->name);
	      esl_sqio_Write(ofp, sq, eslSQFILE_FASTA, FALSE);
	      nseq++;
	    }
	  esl_sq_Reuse(sq);
	}
      if      (status == eslEFORMAT) esl_fatal("Parse failed (sequence file %s):\n%s\n",
					       sqfp->filename, esl_sqfile_GetErrorBuf(sqfp));
      else if (status != eslEOF)     esl_fatal("Unexpected error %d reading sequence file %s",
					       status, sqfp->filename);
      esl_sq_Destroy(sq);
    }
  if (nkeys != nseq) esl_fatal("Tried to retrieve %d keys, but only retrieved %d sequences\n", nkeys, nseq);
  if (ofp != stdout) printf("\nRetrieved %d sequences.\n", nseq);
  esl_keyhash_Destroy(keys);
  esl_fileparser_Close(efp);
  return;
}
static void multifetch ( ESL_GETOPTS * go , FILE * ofp , char * keyfile , ESL_SQFILE * sqfp ) { ESL_KEYHASH * keys = esl_keyhash_Create ( ) ; ESL_FILEPARSER * efp = NULL ; int nseq = 0 ; int nkeys = 0 ; char * key ; int keylen ; int keyidx ; int status ; if ( esl_fileparser_Open ( keyfile , NULL , & efp ) != eslOK ) esl_fatal ( " \n " , keyfile ) ; esl_fileparser_SetCommentChar ( efp , ' ' ) ; while ( esl_fileparser_NextLine ( efp ) == eslOK ) { if ( esl_fileparser_GetTokenOnLine ( efp , & key , & keylen ) != eslOK ) esl_fatal ( " \n " , efp -> linenumber , keyfile ) ; status = esl_keyhash_Store ( keys , key , keylen , & keyidx ) ; if ( status == eslEDUP ) esl_fatal ( " \n " , key , keyfile ) ; if ( sqfp -> data . ascii . ssi != NULL ) { onefetch ( go , ofp , key , sqfp ) ; nseq ++ ; } nkeys ++ ; } if ( sqfp -> data . ascii . ssi == NULL ) { ESL_SQ * sq = esl_sq_Create ( ) ; while ( ( status = esl_sqio_Read ( sqfp , sq ) ) == eslOK ) { if ( ( sq -> name [ 0 ] != ' \0 ' && esl_keyhash_Lookup ( keys , sq -> name , -1 , NULL ) == eslOK ) || ( sq -> acc [ 0 ] != ' \0 ' && esl_keyhash_Lookup ( keys , sq -> acc , -1 , NULL ) == eslOK ) ) { if ( esl_opt_GetBoolean ( go , " " ) ) if ( esl_sq_ReverseComplement ( sq ) != eslOK ) esl_fatal ( " \n " , sq -> name ) ; esl_sqio_Write ( ofp , sq , eslSQFILE_FASTA , FALSE ) ; nseq ++ ; } esl_sq_Reuse ( sq ) ; } if ( status == eslEFORMAT ) esl_fatal ( " \n \n " , sqfp -> filename , esl_sqfile_GetErrorBuf ( sqfp ) ) ; else if ( status != eslEOF ) esl_fatal ( " " , status , sqfp -> filename ) ; esl_sq_Destroy ( sq ) ; } if ( nkeys != nseq ) esl_fatal ( " \n " , nkeys , nseq ) ; if ( ofp != stdout ) printf ( " \n \n " , nseq ) ; esl_keyhash_Destroy ( keys ) ; esl_fileparser_Close ( efp ) ; return ; }
multifetch:
 given a file containing lines with one name or key per line;
 parse the file line-by-line;
 if we have an SSI index available, retrieve the seqs by key
 as we see each line;
 else, without an SSI index, store the keys in a hash, then
 read the entire seq file in a single pass, outputting seqs
 that are in our keylist.
multifetch : given a file containing lines with one name or key per line ; parse the file line - by - line ; if we have an SSI index available retrieve the seqs by key as we see each line ; else without an SSI index store the keys in a hash then read the entire seq file in a single pass outputting seqs that are in our keylist .
/* if we have an SSI index, just fetch them as we go. */ /* If we don't have an SSI index, we haven't fetched anything yet; do it now. */