blast_util.c
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:30k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: blast_util.c,v $
  4.  * PRODUCTION Revision 1000.4  2004/06/01 18:07:56  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.70
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: blast_util.c,v 1000.4 2004/06/01 18:07:56 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's offical duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Author: Ilya Dondoshansky
  35.  *
  36.  */
  37. /** @file blast_util.c
  38.  * Various BLAST utilities
  39.  */
  40. static char const rcsid[] = 
  41.     "$Id: blast_util.c,v 1000.4 2004/06/01 18:07:56 gouriano Exp $";
  42. #include <algo/blast/core/blast_def.h>
  43. #include <algo/blast/core/blast_util.h>
  44. #include <algo/blast/core/blast_encoding.h>
  45. #include <algo/blast/core/blast_filter.h>
  46. Int2
  47. BlastSetUp_SeqBlkNew (const Uint1* buffer, Int4 length, Int4 context,
  48.    BLAST_SequenceBlk* *seq_blk, Boolean buffer_allocated)
  49. {
  50.    /* Check if BLAST_SequenceBlk itself needs to be allocated here or not */
  51.    if (*seq_blk == NULL) {
  52.       *seq_blk = calloc(1, sizeof(BLAST_SequenceBlk));
  53.    }
  54.    if (buffer_allocated) {
  55.       (*seq_blk)->sequence_start_allocated = TRUE;
  56.       (*seq_blk)->sequence_start = (Uint1 *) buffer;
  57.       /* The first byte is a sentinel byte. */
  58.       (*seq_blk)->sequence = (*seq_blk)->sequence_start+1;
  59.    } else {
  60.       (*seq_blk)->sequence = (Uint1 *) buffer;
  61.       (*seq_blk)->sequence_start = NULL;
  62.    }
  63.    
  64.    (*seq_blk)->length = length;
  65.    (*seq_blk)->context = context;
  66.    
  67.    return 0;
  68. }
  69. Int2 BlastSeqBlkNew(BLAST_SequenceBlk** retval)
  70. {
  71.     if ( !retval ) {
  72.         return -1;
  73.     } else {
  74.         *retval = (BLAST_SequenceBlk*) calloc(1, sizeof(BLAST_SequenceBlk));
  75.         if ( !*retval ) {
  76.             return -1;
  77.         }
  78.     }
  79.     return 0;
  80. }
  81. Int2 BlastSeqBlkSetSequence(BLAST_SequenceBlk* seq_blk, 
  82.                             const Uint1* sequence,
  83.                             Int4 seqlen)
  84. {
  85.     if ( !seq_blk ) {
  86.         return -1;
  87.     }
  88.     seq_blk->sequence_start_allocated = TRUE;
  89.     seq_blk->sequence_start = (Uint1*) sequence;
  90.     seq_blk->sequence = (Uint1*) sequence + 1;
  91.     seq_blk->length = seqlen;
  92.     seq_blk->oof_sequence = NULL;
  93.     return 0;
  94. }
  95. Int2 BlastSeqBlkSetCompressedSequence(BLAST_SequenceBlk* seq_blk, 
  96.                                       const Uint1* sequence)
  97. {
  98.     if ( !seq_blk ) {
  99.         return -1;
  100.     }
  101.     seq_blk->sequence_allocated = TRUE;
  102.     seq_blk->sequence = (Uint1*) sequence;
  103.     seq_blk->oof_sequence = NULL;
  104.     return 0;
  105. }
  106. #if 0
  107. /** Create the subject sequence block given an ordinal id in a database */
  108. void
  109. MakeBlastSequenceBlk(ReadDBFILEPtr db, BLAST_SequenceBlk** seq_blk,
  110.                      Int4 oid, Uint1 encoding)
  111. {
  112.   Int4 length, buf_len = 0;
  113.   Uint1* buffer = NULL;
  114.   if (encoding == BLASTNA_ENCODING) {
  115.      length = readdb_get_sequence_ex(db, oid, &buffer, &buf_len, TRUE);
  116.   } else if (encoding == NCBI4NA_ENCODING) {
  117.      length = readdb_get_sequence_ex(db, oid, &buffer, &buf_len, FALSE);
  118.   } else {
  119.      length=readdb_get_sequence(db, oid, &buffer);
  120.   }
  121.   BlastSetUp_SeqBlkNew(buffer, length, 0, seq_blk, 
  122.                        (encoding != BLASTP_ENCODING));
  123.   (*seq_blk)->oid = oid;
  124. }
  125. #endif
  126. Int2 BlastSequenceBlkClean(BLAST_SequenceBlk* seq_blk)
  127. {
  128.    if (!seq_blk)
  129.        return 1;
  130.    if (seq_blk->sequence_allocated) 
  131.        sfree(seq_blk->sequence);
  132.    if (seq_blk->sequence_start_allocated)
  133.        sfree(seq_blk->sequence_start);
  134.    if (seq_blk->oof_sequence_allocated)
  135.        sfree(seq_blk->oof_sequence);
  136.    return 0;
  137. }
  138. BLAST_SequenceBlk* BlastSequenceBlkFree(BLAST_SequenceBlk* seq_blk)
  139. {
  140.    if (!seq_blk)
  141.       return NULL;
  142.    BlastSequenceBlkClean(seq_blk);
  143.    if (seq_blk->lcase_mask_allocated)
  144.       BlastMaskLocFree(seq_blk->lcase_mask);
  145.    sfree(seq_blk);
  146.    return NULL;
  147. }
  148. void BlastSequenceBlkCopy(BLAST_SequenceBlk** copy, 
  149.                           BLAST_SequenceBlk* src) 
  150. {
  151.    ASSERT(copy);
  152.    ASSERT(src);
  153.    
  154.    if (*copy)
  155.       memcpy(*copy, src, sizeof(BLAST_SequenceBlk));
  156.    else 
  157.       *copy = BlastMemDup(src, sizeof(BLAST_SequenceBlk));
  158.    (*copy)->sequence_allocated = FALSE;
  159.    (*copy)->sequence_start_allocated = FALSE;
  160.    (*copy)->oof_sequence_allocated = FALSE;
  161.    (*copy)->lcase_mask_allocated = FALSE;
  162. }
  163. Int2 BlastProgram2Number(const char *program, Uint1 *number)
  164. {
  165. *number = blast_type_undefined;
  166. if (program == NULL)
  167. return 1;
  168. if (strcasecmp("blastn", program) == 0)
  169. *number = blast_type_blastn;
  170. else if (strcasecmp("blastp", program) == 0)
  171. *number = blast_type_blastp;
  172. else if (strcasecmp("blastx", program) == 0)
  173. *number = blast_type_blastx;
  174. else if (strcasecmp("tblastn", program) == 0)
  175. *number = blast_type_tblastn;
  176. else if (strcasecmp("tblastx", program) == 0)
  177. *number = blast_type_tblastx;
  178. else if (strcasecmp("rpsblast", program) == 0)
  179. *number = blast_type_rpsblast;
  180. else if (strcasecmp("rpstblastn", program) == 0)
  181. *number = blast_type_rpstblastn;
  182. return 0;
  183. }
  184. Int2 BlastNumber2Program(Uint1 number, char* *program)
  185. {
  186. if (program == NULL)
  187. return 1;
  188. switch (number) {
  189. case blast_type_blastn:
  190. *program = strdup("blastn");
  191. break;
  192. case blast_type_blastp:
  193. *program = strdup("blastp");
  194. break;
  195. case blast_type_blastx:
  196. *program = strdup("blastx");
  197. break;
  198. case blast_type_tblastn:
  199. *program = strdup("tblastn");
  200. break;
  201. case blast_type_tblastx:
  202. *program = strdup("tblastx");
  203. break;
  204. case blast_type_rpsblast:
  205. *program = strdup("rpsblast");
  206. break;
  207. case blast_type_rpstblastn:
  208. *program = strdup("rpstblastn");
  209. break;
  210. default:
  211. *program = strdup("unknown");
  212. break;
  213. }
  214. return 0;
  215. }
  216. #define X_STDAA 21
  217. /** Translate 3 nucleotides into an amino acid
  218.  * MUST have 'X' as unknown amino acid
  219.  * @param codon 3 values in ncbi4na code
  220.  * @param codes Geneic code string to use (must be in ncbistdaa encoding!)
  221.  * @return Amino acid in ncbistdaa
  222.  */
  223. static Uint1 CodonToAA (Uint1* codon, const Uint1* codes)
  224. {
  225.    register Uint1 aa = 0, taa;
  226.    register int i, j, k, index0, index1, index2;
  227.    static Uint1 mapping[4] = { 8,     /* T in ncbi4na */
  228.                                2,     /* C */
  229.                                1,     /* A */
  230.                                4 };   /* G */
  231.    for (i = 0; i < 4; i++) {
  232.       if (codon[0] & mapping[i]) {
  233.          index0 = i * 16;
  234.          for (j = 0; j < 4; j++) {
  235.             if (codon[1] & mapping[j]) {
  236.                index1 = index0 + (j * 4);
  237.                for (k = 0; k < 4; k++) {
  238.                   if (codon[2] & mapping[k]) {
  239.                      index2 = index1 + k;
  240.                      taa = codes[index2];
  241.                      if (! aa)
  242.                         aa = taa;
  243.                      else {
  244.                         if (taa != aa) {
  245.                            aa = X_STDAA;
  246.                            break;
  247.                         }
  248.                      }
  249.                   }
  250.                   if (aa == X_STDAA)
  251.                      break;
  252.                }
  253.             }
  254.             if (aa == X_STDAA)
  255.                break;
  256.          }
  257.       }
  258.       if (aa == X_STDAA)
  259.          break;
  260.    }
  261.    return aa;
  262. }
  263. Int4
  264. BLAST_GetTranslation(const Uint1* query_seq, const Uint1* query_seq_rev, 
  265.    Int4 nt_length, Int2 frame, Uint1* prot_seq, const Uint1* genetic_code)
  266. {
  267. Uint1 codon[CODON_LENGTH];
  268. Int4 index, index_prot;
  269. Uint1 residue;
  270.    Uint1* nucl_seq;
  271.    nucl_seq = (frame >= 0 ? (Uint1 *)query_seq : (Uint1 *)(query_seq_rev+1));
  272. /* The first character in the protein is the NULLB sentinel. */
  273. prot_seq[0] = NULLB;
  274. index_prot = 1;
  275. for (index=ABS(frame)-1; index<nt_length-2; index += CODON_LENGTH)
  276. {
  277. codon[0] = nucl_seq[index];
  278. codon[1] = nucl_seq[index+1];
  279. codon[2] = nucl_seq[index+2];
  280. residue = CodonToAA(codon, genetic_code);
  281. if (IS_residue(residue))
  282. {
  283. prot_seq[index_prot] = residue;
  284. index_prot++;
  285. }
  286. }
  287. prot_seq[index_prot] = NULLB;
  288. return index_prot - 1;
  289. }
  290. /*
  291.   Translate a compressed nucleotide sequence without ambiguity codes.
  292. */
  293. Int4
  294. BLAST_TranslateCompressedSequence(Uint1* translation, Int4 length, 
  295.    const Uint1* nt_seq, Int2 frame, Uint1* prot_seq)
  296. {
  297.    int state;
  298.    Int2 total_remainder;
  299.    Int4 prot_length;
  300.    int byte_value, codon=-1;
  301.    Uint1 last_remainder, last_byte, remainder;
  302.    Uint1* nt_seq_end,* nt_seq_start;
  303.    Uint1* prot_seq_start;
  304.    int byte_value1,byte_value2,byte_value3,byte_value4,byte_value5;
  305.    
  306.    prot_length=0;
  307.    if (nt_seq == NULL || prot_seq == NULL || 
  308.        (length-ABS(frame)+1) < CODON_LENGTH)
  309.       return prot_length;
  310.    
  311.    *prot_seq = NULLB;
  312.    prot_seq++;
  313.    
  314.    /* record to determine protein length. */
  315.    prot_seq_start = prot_seq;
  316.   
  317.    remainder = length%4;
  318.    if (frame > 0) {
  319.       nt_seq_end = (Uint1 *) (nt_seq + (length)/4 - 1);
  320.       last_remainder = (4*(length/4) - frame + 1)%CODON_LENGTH;
  321.       total_remainder = last_remainder+remainder;
  322.       
  323.       state = frame-1;
  324.       byte_value = *nt_seq;
  325.       
  326.       /* If there's lots to do, advance to state 0, then enter fast loop */
  327.       while (nt_seq < nt_seq_end) {
  328.          switch (state) {
  329.          case 0:
  330.             codon = (byte_value >> 2);
  331.             *prot_seq = translation[codon];
  332.             prot_seq++;
  333.             /* do state = 3 now, break is NOT missing. */
  334.          case 3:
  335.             codon = ((byte_value & 3) << 4);
  336.             nt_seq++;
  337.             byte_value = *nt_seq;
  338.             codon += (byte_value >> 4);
  339.             *prot_seq = translation[codon];
  340.             prot_seq++;
  341.             if (nt_seq >= nt_seq_end) {
  342.                state = 2;
  343.                break;
  344.             }
  345.             /* Go on to state = 2 if not at end. */
  346.          case 2:
  347.             codon = ((byte_value & 15) << 2);
  348.             nt_seq++;
  349.             byte_value = *nt_seq;
  350.             codon += (byte_value >> 6);
  351.             *prot_seq = translation[codon];
  352.             prot_seq++;
  353.             if (nt_seq >= nt_seq_end) {
  354.                state = 1;
  355.                break;
  356.             }
  357.             /* Go on to state = 1 if not at end. */
  358.          case 1:
  359.             codon = byte_value & 63;
  360.             *prot_seq = translation[codon];
  361.             prot_seq++;
  362.             nt_seq++;
  363.             byte_value = *nt_seq;
  364.             state = 0;
  365.             break;
  366.          } /* end switch */
  367.          /* switch ends at state 0, except when at end */
  368.          
  369.          /********************************************/
  370.          /* optimized loop: start in state 0. continue til near end */
  371.          while (nt_seq < (nt_seq_end-10)) {
  372.             byte_value1 = *(++nt_seq);
  373.             byte_value2 = *(++nt_seq);
  374.             byte_value3 = *(++nt_seq);
  375.             /* case 0: */
  376.             codon = (byte_value >> 2);
  377.             *prot_seq = translation[codon];
  378.             prot_seq++;
  379.             
  380.             /* case 3: */
  381.             codon = ((byte_value & 3) << 4);
  382.             codon += (byte_value1 >> 4);
  383.             *prot_seq = translation[codon];
  384.             prot_seq++;
  385.             
  386.             byte_value4 = *(++nt_seq);
  387.             /* case 2: */
  388.             codon = ((byte_value1 & 15) << 2);
  389.             
  390.             codon += (byte_value2 >> 6);
  391.             *prot_seq = translation[codon];
  392.             prot_seq++;
  393.             /* case 1: */
  394.             codon = byte_value2 & 63;
  395.             byte_value5 = *(++nt_seq);
  396.             *prot_seq = translation[codon];
  397.             prot_seq++;
  398.             
  399.             /* case 0: */
  400.             codon = (byte_value3 >> 2);
  401.             *prot_seq = translation[codon];
  402.             prot_seq++;
  403.             /* case 3: */
  404.             byte_value = *(++nt_seq);
  405.             codon = ((byte_value3 & 3) << 4);
  406.             codon += (byte_value4 >> 4);
  407.             *prot_seq = translation[codon];
  408.             prot_seq++;
  409.             /* case 2: */
  410.             codon = ((byte_value4 & 15) << 2);
  411.             codon += (byte_value5 >> 6);
  412.             *prot_seq = translation[codon];
  413.             prot_seq++;
  414.             /* case 1: */
  415.             codon = byte_value5 & 63;
  416.             *prot_seq = translation[codon];
  417.             prot_seq++;
  418.             state=0;
  419.          } /* end optimized while */
  420.          /********************************************/
  421.       } /* end while */
  422.       
  423.       if (state == 1) { 
  424.          /* This doesn't get done above, DON't do the state = 0
  425.             below if this is done. */
  426.          byte_value = *nt_seq;
  427.          codon = byte_value & 63;
  428.          state = 0;
  429.          *prot_seq = translation[codon];
  430.          prot_seq++;
  431.       } else if (state == 0) { /* This one doesn't get done above. */
  432.          byte_value = *nt_seq;
  433.          codon = ((byte_value) >> 2);
  434.          state = 3;
  435.          *prot_seq = translation[codon];
  436.          prot_seq++;
  437.       }
  438.       if (total_remainder >= CODON_LENGTH) {
  439.          byte_value = *(nt_seq_end);
  440.          last_byte = *(nt_seq_end+1);
  441.          if (state == 0) {
  442.             codon = (last_byte >> 2);
  443.          } else if (state == 2) {
  444.             codon = ((byte_value & 15) << 2);
  445.             codon += (last_byte >> 6);
  446.          } else if (state == 3) {
  447.             codon = ((byte_value & 3) << 4);
  448.             codon += (last_byte >> 4);
  449.          }
  450.          *prot_seq = translation[codon];
  451.          prot_seq++;
  452.       }
  453.    } else {
  454.       nt_seq_start = (Uint1 *) nt_seq;
  455.       nt_seq += length/4;
  456.       state = remainder+frame;
  457.       /* Do we start in the last byte?  This one has the lowest order
  458.          bits set to represent the remainder, hence the odd coding here. */
  459.       if (state >= 0) {
  460.          last_byte = *nt_seq;
  461.          nt_seq--;
  462.          if (state == 0) {
  463.             codon = (last_byte >> 6);
  464.             byte_value = *nt_seq;
  465.             codon += ((byte_value & 15) << 2);
  466.             state = 1;
  467.          } else if (state == 1) {
  468.             codon = (last_byte >> 4);
  469.             byte_value = *nt_seq;
  470.             codon += ((byte_value & 3) << 4);
  471.             state = 2;
  472.          } else if (state == 2) {
  473.             codon = (last_byte >> 2);
  474.             state = 3;
  475.          }
  476.          *prot_seq = translation[codon];
  477.          prot_seq++;
  478.       } else {
  479.          state = 3 + (remainder + frame + 1);
  480.          nt_seq--;
  481.       }
  482.       
  483.       byte_value = *nt_seq;
  484.       /* If there's lots to do, advance to state 3, then enter fast loop */
  485.       while (nt_seq > nt_seq_start) {
  486.          switch (state) {
  487.          case 3:
  488.             codon = (byte_value & 63);
  489.             *prot_seq = translation[codon];
  490.             prot_seq++;
  491.             /* do state = 0 now, break is NOT missing. */
  492.          case 0:
  493.             codon = (byte_value >> 6);
  494.             nt_seq--;
  495.             byte_value = *nt_seq;
  496.             codon += ((byte_value & 15) << 2);
  497.             *prot_seq = translation[codon];
  498.             prot_seq++;
  499.             if (nt_seq <= nt_seq_start) {
  500.                state = 1;
  501.                break;
  502.             }
  503.             /* Go on to state = 2 if not at end. */
  504.          case 1:
  505.             codon = (byte_value >> 4);
  506.             nt_seq--;
  507.             byte_value = *nt_seq;
  508.             codon += ((byte_value & 3) << 4);
  509.             *prot_seq = translation[codon];
  510.             prot_seq++;
  511.             if (nt_seq <= nt_seq_start) {
  512.                state = 2;
  513.                break;
  514.             }
  515.             /* Go on to state = 2 if not at end. */
  516.          case 2:
  517.             codon = (byte_value >> 2);
  518.             *prot_seq = translation[codon];
  519.             prot_seq++;
  520.             nt_seq--;
  521.             byte_value = *nt_seq;
  522.             state = 3;
  523.             break;
  524.          } /* end switch */
  525.          /* switch ends at state 3, except when at end */
  526.          
  527.          /********************************************/
  528.          /* optimized area: start in state 0. continue til near end */
  529.          while (nt_seq > (nt_seq_start+10)) {
  530.             byte_value1 = *(--nt_seq);
  531.             byte_value2 = *(--nt_seq);
  532.             byte_value3 = *(--nt_seq);
  533.             
  534.             codon = (byte_value & 63);
  535.             *prot_seq = translation[codon];
  536.             prot_seq++;
  537.             codon = (byte_value >> 6);
  538.             codon += ((byte_value1 & 15) << 2);
  539.             *prot_seq = translation[codon];
  540.             prot_seq++;
  541.             byte_value4 = *(--nt_seq);
  542.             codon = (byte_value1 >> 4);
  543.             codon += ((byte_value2 & 3) << 4);
  544.             *prot_seq = translation[codon];
  545.             prot_seq++;
  546.             codon = (byte_value2 >> 2);
  547.             *prot_seq = translation[codon];
  548.             prot_seq++;
  549.             byte_value5 = *(--nt_seq);
  550.             
  551.             codon = (byte_value3 & 63);
  552.             *prot_seq = translation[codon];
  553.             prot_seq++;
  554.             byte_value = *(--nt_seq);
  555.             codon = (byte_value3 >> 6);
  556.             codon += ((byte_value4 & 15) << 2);
  557.             *prot_seq = translation[codon];
  558.             prot_seq++;
  559.             codon = (byte_value4 >> 4);
  560.             codon += ((byte_value5 & 3) << 4);
  561.             *prot_seq = translation[codon];
  562.             prot_seq++;
  563.             codon = (byte_value5 >> 2);
  564.             *prot_seq = translation[codon];
  565.             prot_seq++;
  566.          } /* end optimized while */
  567.          /********************************************/
  568.          
  569.       } /* end while */
  570.       
  571.       byte_value = *nt_seq;
  572.       if (state == 3) {
  573.          codon = (byte_value & 63);
  574.          *prot_seq = translation[codon];
  575.          prot_seq++;
  576.       } else if (state == 2) {
  577.          codon = (byte_value >> 2);
  578.          *prot_seq = translation[codon];
  579.          prot_seq++;
  580.       }
  581.    }
  582.    *prot_seq = NULLB;
  583.    
  584.    return (prot_seq - prot_seq_start);
  585. } /* BlastTranslateUnambiguousSequence */
  586. /* Reverse a nucleotide sequence in the ncbi4na encoding */
  587. Int2 GetReverseNuclSequence(const Uint1* sequence, Int4 length, 
  588.                             Uint1** rev_sequence_ptr)
  589. {
  590.    Uint1* rev_sequence;
  591.    Int4 index;
  592.    /* Conversion table from forward to reverse strand residue in the blastna 
  593.       encoding */
  594.    Uint1 conversion_table[17] = 
  595.       { 0, 8, 4, 12, 2, 10, 9, 14, 1, 6, 5, 13, 3, 11, 7, 15 };
  596.    if (!rev_sequence_ptr)
  597.       return -1;
  598.    rev_sequence = (Uint1*) malloc(length + 2);
  599.    
  600.    rev_sequence[0] = rev_sequence[length+1] = NULLB;
  601.    for (index = 0; index < length; ++index) {
  602.       rev_sequence[length-index] = conversion_table[sequence[index]];
  603.    }
  604.    *rev_sequence_ptr = rev_sequence;
  605.    return 0;
  606. }
  607. Int2 BLAST_ContextToFrame(Uint1 prog_number, Int4 context_number)
  608. {
  609.    Int2 frame=255;
  610.    if (prog_number == blast_type_blastn) {
  611.       if (context_number % 2 == 0)
  612.          frame = 1;
  613.       else
  614.          frame = -1;
  615.    } else if (prog_number == blast_type_blastp ||
  616.               prog_number == blast_type_rpsblast ||
  617.               prog_number == blast_type_tblastn ||
  618.               prog_number == blast_type_rpstblastn) { 
  619.       /* Query and subject are protein, no frame. */
  620.       frame = 0;
  621.    } else if (prog_number == blast_type_blastx || 
  622.               prog_number == blast_type_tblastx) {
  623.       context_number = context_number % 6;
  624.       frame = (context_number < 3) ? context_number+1 : -context_number+2;
  625.    }
  626.    
  627.    return frame;
  628. }
  629. Int4 BLAST_GetQueryLength(const BlastQueryInfo* query_info, Int4 context)
  630. {
  631.    return query_info->context_offsets[context+1] -
  632.       query_info->context_offsets[context] - 1;
  633. }
  634. BlastQueryInfo* BlastQueryInfoFree(BlastQueryInfo* query_info)
  635. {
  636.    sfree(query_info->context_offsets);
  637.    sfree(query_info->length_adjustments);
  638.    sfree(query_info->eff_searchsp_array);
  639.    sfree(query_info);
  640.    return NULL;
  641. }
  642. /** Convert a sequence in ncbi4na or blastna encoding into a packed sequence
  643.  * in ncbi2na encoding. Needed for 2 sequences BLASTn comparison.
  644.  */
  645. Int2 BLAST_PackDNA(Uint1* buffer, Int4 length, Uint1 encoding, 
  646.                           Uint1** packed_seq)
  647. {
  648.    Int4 new_length = length/COMPRESSION_RATIO + 1;
  649.    Uint1* new_buffer = (Uint1*) malloc(new_length);
  650.    Int4 index, new_index;
  651.    Uint1 shift;     /* bit shift to pack bases */
  652.    for (index=0, new_index=0; new_index < new_length-1; 
  653.         ++new_index, index += COMPRESSION_RATIO) {
  654.       if (encoding == BLASTNA_ENCODING)
  655.          new_buffer[new_index] = 
  656.             ((buffer[index]&NCBI2NA_MASK)<<6) | 
  657.             ((buffer[index+1]&NCBI2NA_MASK)<<4) |
  658.             ((buffer[index+2]&NCBI2NA_MASK)<<2) | 
  659.              (buffer[index+3]&NCBI2NA_MASK);
  660.       else
  661.          new_buffer[new_index] = 
  662.             ((NCBI4NA_TO_BLASTNA[buffer[index]]&NCBI2NA_MASK)<<6) | 
  663.             ((NCBI4NA_TO_BLASTNA[buffer[index+1]]&NCBI2NA_MASK)<<4) |
  664.             ((NCBI4NA_TO_BLASTNA[buffer[index+2]]&NCBI2NA_MASK)<<2) | 
  665.             (NCBI4NA_TO_BLASTNA[buffer[index+3]]&NCBI2NA_MASK);
  666.    }
  667.    /* Handle the last byte of the compressed sequence.
  668.       Last 2 bits of the last byte tell the number of valid 
  669.       packed sequence bases in it. */
  670.    new_buffer[new_index] = length % COMPRESSION_RATIO;
  671.    for (; index < length; index++) {
  672.       switch (index%COMPRESSION_RATIO) {
  673.       case 0: shift = 6; break;
  674.       case 1: shift = 4; break;
  675.       case 2: shift = 2; break;
  676.       default: abort();     /* should never happen */
  677.       }
  678.       if (encoding == BLASTNA_ENCODING)
  679.          new_buffer[new_index] |= ((buffer[index]&NCBI2NA_MASK)<<shift);
  680.       else
  681.          new_buffer[new_index] |=
  682.             ((NCBI4NA_TO_BLASTNA[buffer[index]]&NCBI2NA_MASK)<<shift);
  683.    }
  684.    *packed_seq = new_buffer;
  685.    return 0;
  686. }
  687. Int2 BLAST_InitDNAPSequence(BLAST_SequenceBlk* query_blk, 
  688.                             BlastQueryInfo* query_info)
  689. {
  690.    Uint1* buffer,* seq,* tmp_seq;
  691.    Int4 total_length, index, offset, i, context;
  692.    Int4 length[CODON_LENGTH];
  693.    Int4* context_offsets = query_info->context_offsets;
  694.    total_length = context_offsets[query_info->last_context+1] + 1;
  695.    buffer = (Uint1*) malloc(total_length);
  696.    for (index = 0; index <= query_info->last_context; index += CODON_LENGTH) {
  697.       seq = &buffer[context_offsets[index]];
  698.       for (i = 0; i < CODON_LENGTH; ++i) {
  699.          *seq++ = NULLB;
  700.          length[i] = BLAST_GetQueryLength(query_info, index + i);
  701.       }
  702.       for (i = 0; ; ++i) {
  703.          context = i % 3;
  704.          offset = i / 3;
  705.          if (offset >= length[context]) {
  706.             /* Once one frame is past its end, we are done */
  707.             break;
  708.          }
  709.          tmp_seq = &query_blk->sequence[context_offsets[index+context]];
  710.          *seq++ = tmp_seq[offset];
  711.       }
  712.    }
  713.    /* The mixed-frame protein sequence buffer will be saved in 
  714.       'sequence_start' */
  715.    query_blk->oof_sequence = buffer;
  716.    query_blk->oof_sequence_allocated = TRUE;
  717.    return 0;
  718. }
  719. /* Gets the translation array for a given genetic code.  
  720.  * This array is optimized for the NCBI2na alphabet.
  721.  * The reverse complement can also be spcified.
  722.  * @param genetic_code Genetic code string in ncbistdaa encoding [in]
  723.  * @param reverse_complement Get translation table for the reverse strand? [in]
  724.  * @return The translation table.
  725. */
  726. static Uint1*
  727. BLAST_GetTranslationTable(const Uint1* genetic_code, Boolean reverse_complement)
  728. {
  729. Int2 index1, index2, index3, bp1, bp2, bp3;
  730. Int2 codon;
  731. Uint1* translation;
  732.    /* The next array translate between the ncbi2na rep's and 
  733.       the rep's used by the genetic_code tables.  The rep used by the 
  734.       genetic code arrays is in mapping: T=0, C=1, A=2, G=3 */
  735.    static Uint1 mapping[4] = {2, /* A in ncbi2na */
  736.                               1, /* C in ncbi2na. */
  737.                               3, /* G in ncbi2na. */
  738.                               0 /* T in ncbi2na. */ };
  739. if (genetic_code == NULL)
  740. return NULL;
  741. translation = calloc(64, sizeof(Uint1));
  742. if (translation == NULL)
  743. return NULL;
  744. for (index1=0; index1<4; index1++)
  745. {
  746. for (index2=0; index2<4; index2++)
  747. {
  748. for (index3=0; index3<4; index3++)
  749. {
  750.             /* The reverse complement codon is saved in it's orginal 
  751.                (non-complement) form AND with the high-order bits reversed 
  752.                from the non-complement form, as this is how they appear in 
  753.                the sequence. 
  754.             */
  755.    if (reverse_complement)
  756.             {
  757.                bp1 = 3 - index1;
  758.                bp2 = 3 - index2;
  759.                bp3 = 3 - index3;
  760.     codon = (mapping[bp1]<<4) + (mapping[bp2]<<2) + (mapping[bp3]);
  761.     translation[(index3<<4) + (index2<<2) + index1] = 
  762.                   genetic_code[codon];
  763.    }
  764.    else
  765.    {
  766.     codon = (mapping[index1]<<4) + (mapping[index2]<<2) + 
  767.                   (mapping[index3]);
  768.     translation[(index1<<4) + (index2<<2) + index3] = 
  769.                   genetic_code[codon];
  770.    }
  771. }
  772. }
  773. }
  774. return translation;
  775. }
  776. Int2 BLAST_GetAllTranslations(const Uint1* nucl_seq, Uint1 encoding,
  777.         Int4 nucl_length, const Uint1* genetic_code,
  778.         Uint1** translation_buffer_ptr, Int4** frame_offsets_ptr,
  779.         Uint1** mixed_seq_ptr)
  780. {
  781.    Uint1* translation_buffer,* mixed_seq;
  782.    Uint1* translation_table = NULL,* translation_table_rc;
  783.    Uint1* nucl_seq_rev;
  784.    Int4 offset = 0, length;
  785.    Int4 context; 
  786.    Int4* frame_offsets;
  787.    Int2 frame;
  788.    
  789.    if (encoding != NCBI2NA_ENCODING && encoding != NCBI4NA_ENCODING)
  790.       return -1;
  791.    if ((translation_buffer = 
  792.         (Uint1*) malloc(2*(nucl_length+1)+1)) == NULL)
  793.       return -1;
  794.    if (encoding == NCBI4NA_ENCODING) {
  795.       /* First produce the reverse strand of the nucleotide sequence */
  796.       GetReverseNuclSequence(nucl_seq, nucl_length, 
  797.                              &nucl_seq_rev);
  798.    } else {
  799.       translation_table = BLAST_GetTranslationTable(genetic_code, FALSE);
  800.       translation_table_rc = BLAST_GetTranslationTable(genetic_code, TRUE);
  801.    } 
  802.    frame_offsets = (Int4*) malloc((NUM_FRAMES+1)*sizeof(Int4));
  803.    frame_offsets[0] = 0;
  804.    
  805.    for (context = 0; context < NUM_FRAMES; ++context) {
  806.       frame = BLAST_ContextToFrame(blast_type_blastx, context);
  807.       if (encoding == NCBI2NA_ENCODING) {
  808.          if (frame > 0) {
  809.             length = 
  810.                BLAST_TranslateCompressedSequence(translation_table,
  811.                   nucl_length, nucl_seq, frame, translation_buffer+offset);
  812.          } else {
  813.             length = 
  814.                BLAST_TranslateCompressedSequence(translation_table_rc,
  815.                   nucl_length, nucl_seq, frame, translation_buffer+offset);
  816.          }
  817.       } else {
  818.          length = 
  819.             BLAST_GetTranslation(nucl_seq, nucl_seq_rev, 
  820.                nucl_length, frame, translation_buffer+offset, genetic_code);
  821.       }
  822.       /* Increment offset by 1 extra byte for the sentinel NULLB 
  823.          between frames. */
  824.       offset += length + 1;
  825.       frame_offsets[context+1] = offset;
  826.    }
  827.    if (encoding == NCBI4NA_ENCODING) {
  828.       sfree(nucl_seq_rev);
  829.    } else { 
  830.       free(translation_table);
  831.       sfree(translation_table_rc);
  832.    }
  833.    /* All frames are ready. For the out-of-frame gapping option, allocate 
  834.       and fill buffer with the mixed frame sequence */
  835.    if (mixed_seq_ptr) {
  836.       Uint1* seq;
  837.       Int4 index, i;
  838.       *mixed_seq_ptr = mixed_seq = (Uint1*) malloc(2*(nucl_length+1));
  839.       seq = mixed_seq;
  840.       for (index = 0; index < NUM_FRAMES; index += CODON_LENGTH) {
  841.          for (i = 0; i <= nucl_length; ++i) {
  842.             context = i % CODON_LENGTH;
  843.             offset = i / CODON_LENGTH;
  844.             *seq++ = translation_buffer[frame_offsets[index+context]+offset];
  845.          }
  846.       }
  847.    }
  848.    if (translation_buffer_ptr)
  849.       *translation_buffer_ptr = translation_buffer;
  850.    else
  851.       sfree(translation_buffer);
  852.    if (frame_offsets_ptr)
  853.       *frame_offsets_ptr = frame_offsets;
  854.    else
  855.       sfree(frame_offsets);
  856.    return 0;
  857. }
  858. int GetPartialTranslation(const Uint1* nucl_seq,
  859.         Int4 nucl_length, Int2 frame, const Uint1* genetic_code,
  860.         Uint1** translation_buffer_ptr, Int4* protein_length, 
  861.         Uint1** mixed_seq_ptr)
  862. {
  863.    Uint1* translation_buffer;
  864.    Uint1* nucl_seq_rev = NULL;
  865.    Int4 length;
  866.    
  867.    if ((translation_buffer = 
  868.         (Uint1*) malloc(2*(nucl_length+1)+1)) == NULL)
  869.       return -1;
  870.    if (translation_buffer_ptr)
  871.       *translation_buffer_ptr = translation_buffer;
  872.    if (frame < 0) {
  873.       /* First produce the reverse strand of the nucleotide sequence */
  874.       GetReverseNuclSequence(nucl_seq, nucl_length, &nucl_seq_rev);
  875.    } 
  876.    if (!mixed_seq_ptr) {
  877.       length = 
  878.          BLAST_GetTranslation(nucl_seq, nucl_seq_rev, 
  879.             nucl_length, frame, translation_buffer, genetic_code);
  880.       if (protein_length)
  881.          *protein_length = length;
  882.    } else {
  883.       Int2 index;
  884.       Int2 frame_sign = ((frame < 0) ? -1 : 1);
  885.       Int4 offset = 0;
  886.       Int4 frame_offsets[3];
  887.       Uint1* seq;
  888.       for (index = 1; index <= 3; ++index) {
  889.          length = 
  890.             BLAST_GetTranslation(nucl_seq, nucl_seq_rev, 
  891.                nucl_length, (short)(frame_sign*index), translation_buffer+offset, 
  892.                genetic_code);
  893.          frame_offsets[index-1] = offset;
  894.          offset += length + 1;
  895.       }
  896.       *mixed_seq_ptr = (Uint1*) malloc(2*(nucl_length+1));
  897.       if (protein_length)
  898.          *protein_length = 2*nucl_length - 1;
  899.       for (index = 0, seq = *mixed_seq_ptr; index <= nucl_length; 
  900.            ++index, ++seq) {
  901.          *seq = translation_buffer[frame_offsets[index%3]+(index/3)];
  902.       }
  903.    }
  904.    sfree(nucl_seq_rev);
  905.    if (!translation_buffer_ptr)
  906.       sfree(translation_buffer);
  907.    return 0;
  908. }
  909. Int4 FrameToContext(Int2 frame) 
  910. {
  911.    if (frame > 0)
  912.       return frame - 1;
  913.    else
  914.       return 2 - frame;
  915. }
  916. Int4 BSearchInt4(Int4 n, Int4* A, Int4 size)
  917. {
  918.     Int4 m, b, e;
  919.     b = 0;
  920.     e = size;
  921.     while (b < e - 1) {
  922. m = (b + e) / 2;
  923. if (A[m] > n)
  924.     e = m;
  925. else
  926.     b = m;
  927.     }
  928.     return b;
  929. }