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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: nw_spliced_aligner16.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 18:05:00  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: nw_spliced_aligner16.cpp,v 1000.3 2004/06/01 18:05:00 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 official 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. * Authors:  Yuri Kapustin
  35. *
  36. * File Description:  CSplicedAligner16
  37. *                   
  38. * ===========================================================================
  39. *
  40. */
  41. #include <ncbi_pch.hpp>
  42. #include <algo/align/nw_spliced_aligner16.hpp>
  43. #include <algo/align/align_exception.hpp>
  44. BEGIN_NCBI_SCOPE
  45. const unsigned char g_nwspl_donor[splice_type_count_16][2] = {
  46.     {'G','T'}, {'G','C'}, {'A','T'}, {'?','?'}
  47. };
  48. const unsigned char g_nwspl_acceptor[splice_type_count_16][2] = {
  49.     {'A','G'}, {'A','G'}, {'A','C'}, {'?','?'}
  50. };
  51. const unsigned char g_topidx = splice_type_count_16 - 1;
  52. CSplicedAligner16::CSplicedAligner16()
  53. {
  54.     for(unsigned char st = 0; st < splice_type_count_16; ++st) {
  55.         m_Wi[st] = GetDefaultWi(st);
  56.     }
  57. }
  58. CSplicedAligner16::CSplicedAligner16(const char* seq1, size_t len1,
  59.                                        const char* seq2, size_t len2)
  60.     : CSplicedAligner(seq1, len1, seq2, len2)
  61. {
  62.     for(unsigned char st = 0; st < splice_type_count_16; ++st) {
  63.         m_Wi[st] = GetDefaultWi(st);
  64.     }
  65. }
  66. CNWAligner::TScore CSplicedAligner16::GetDefaultWi(unsigned char splice_type)
  67. {
  68.    switch(splice_type) {
  69.         case 0: return -8;  // GT/AG
  70.         case 1: return -12; // GC/AG
  71.         case 2: return -14; // AT/AC
  72.         case 3: return -18; // ??/??
  73.         default: {
  74.             NCBI_THROW(CAlgoAlignException,
  75.                        eInvalidSpliceTypeIndex,
  76.                        "Invalid splice type index");
  77.         }
  78.     }
  79. }
  80. // Bit coding (eleven bits per value) for backtrace.
  81. // --------------------------------------------------
  82. // [11-8] donors (bitwise OR for multiple types)
  83. //        1000     ??    (??/??) - arbitrary pair
  84. //        0100     AT    (AT/AC)
  85. //        0010     GC    (GC/AG)
  86. //        0001     GT    (GT/AG)
  87. // [7-5]  acceptor type
  88. //        100      ?? (??/??)
  89. //        011      AC (AT/AC)
  90. //        010      AG (GC/AG)
  91. //        001      AG (GT/AG)
  92. //        000      no acceptor
  93. // [4]    Fc:      1 if gap in 2nd sequence was extended; 0 if it is was opened
  94. // [3]    Ec:      1 if gap in 1st sequence was extended; 0 if it is was opened
  95. // [2]    E:       1 if space in 1st sequence; 0 if space in 2nd sequence
  96. // [1]    D:       1 if diagonal; 0 - otherwise
  97. const unsigned char kMaskFc       = 0x0001;
  98. const unsigned char kMaskEc       = 0x0002;
  99. const unsigned char kMaskE        = 0x0004;
  100. const unsigned char kMaskD        = 0x0008;
  101. // Evaluate dynamic programming matrix. Create transcript.
  102. CNWAligner::TScore CSplicedAligner16::x_Align (
  103.                          const char* seg1, size_t len1,
  104.                          const char* seg2, size_t len2,
  105.                          vector<ETranscriptSymbol>* transcript )
  106. {
  107.     TScore V = 0;
  108.     const size_t N1 = len1 + 1;
  109.     const size_t N2 = len2 + 1;
  110.     vector<TScore> stl_rowV (N2), stl_rowF (N2);
  111.     TScore* rowV    = &stl_rowV[0];
  112.     TScore* rowF    = &stl_rowF[0];
  113.     // index calculation: [i,j] = i*n2 + j
  114.     vector<Uint2> stl_bm (N1*N2);
  115.     Uint2* backtrace_matrix = &stl_bm[0];
  116.     TScore* pV = rowV - 1;
  117.     const char* seq1 = seg1 - 1;
  118.     const char* seq2 = seg2 - 1;
  119.     const TNCBIScore (*sm) [NCBI_FSM_DIM] = m_ScoreMatrix.s;
  120.     bool bFreeGapLeft1  = m_esf_L1 && seg1 == m_Seq1;
  121.     bool bFreeGapRight1 = m_esf_R1 && m_Seq1 + m_SeqLen1 - len1 == seg1;
  122.     bool bFreeGapLeft2  = m_esf_L2 && seg2 == m_Seq2;
  123.     bool bFreeGapRight2 = m_esf_R2 && m_Seq2 + m_SeqLen2 - len2 == seg2;
  124.     TScore wgleft1   = bFreeGapLeft1? 0: m_Wg;
  125.     TScore wsleft1   = bFreeGapLeft1? 0: m_Ws;
  126.     TScore wg1 = wgleft1, ws1 = wsleft1;
  127.     // recurrences
  128.     TScore wgleft2   = bFreeGapLeft2? 0: m_Wg;
  129.     TScore wsleft2   = bFreeGapLeft2? 0: m_Ws;
  130.     TScore V_max, vAcc;
  131.     TScore V0 = 0;
  132.     TScore E, G, n0;
  133.     Uint2 tracer;
  134.     // store candidate donors
  135.     size_t* jAllDonors [splice_type_count_16];
  136.     TScore* vAllDonors [splice_type_count_16];
  137.     vector<size_t> stl_jAllDonors (splice_type_count_16 * N2);
  138.     vector<TScore> stl_vAllDonors (splice_type_count_16 * N2);
  139.     for(unsigned char st = 0; st < splice_type_count_16; ++st) {
  140.         jAllDonors[st] = &stl_jAllDonors[st*N2];
  141.         vAllDonors[st] = &stl_vAllDonors[st*N2];
  142.     }
  143.     size_t  jTail[splice_type_count_16], jHead[splice_type_count_16];
  144.     TScore  vBestDonor [splice_type_count_16];
  145.     size_t  jBestDonor [splice_type_count_16];
  146.     // fake row
  147.     rowV[0] = kInfMinus;
  148.     size_t k;
  149.     for (k = 0; k < N2; k++) {
  150.         rowV[k] = rowF[k] = kInfMinus;
  151.     }
  152.     k = 0;
  153.     size_t i, j = 0, k0;
  154.     unsigned char ci;
  155.     for(i = 0;  i < N1;  ++i, j = 0) {
  156.        
  157.         V = i > 0? (V0 += wsleft2) : 0;
  158.         E = kInfMinus;
  159.         k0 = k;
  160.         backtrace_matrix[k++] = kMaskFc;
  161.         ci = i > 0? seq1[i]: 'N';
  162.         for(unsigned char st = 0; st < splice_type_count_16; ++st) {
  163.             jTail[st] = jHead[st] = 0;
  164.             vBestDonor[st] = kInfMinus;
  165.         }
  166.         if(i == N1 - 1 && bFreeGapRight1) {
  167.                 wg1 = ws1 = 0;
  168.         }
  169.         TScore wg2 = m_Wg, ws2 = m_Ws;
  170.             
  171.         // detect donor candidate
  172.         if(N2 > 2) {
  173.   for(unsigned char st = 0; st < g_topidx; ++st) {
  174.                 if(seq2[1] == g_nwspl_donor[st][0] &&
  175.                    seq2[2] == g_nwspl_donor[st][1]) {
  176.                     jAllDonors[st][jTail[st]] = j;
  177.                     vAllDonors[st][jTail[st]] = V;
  178.                     ++(jTail[st]);
  179.                 }
  180.             }
  181.         }
  182.         // the first max value
  183.         jAllDonors[g_topidx][jTail[g_topidx]] = j;
  184.         vAllDonors[g_topidx][jTail[g_topidx]] = V_max = V;
  185.         ++(jTail[3]);
  186.         for (j = 1; j < N2; ++j, ++k) {
  187.             
  188.             G = pV[j] + sm[ci][(unsigned char)seq2[j]];
  189.             pV[j] = V;
  190.             n0 = V + wg1;
  191.             if(E >= n0) {
  192.                 E += ws1;      // continue the gap
  193.                 tracer = kMaskEc;
  194.             }
  195.             else {
  196.                 E = n0 + ws1;  // open a new gap
  197.                 tracer = 0;
  198.             }
  199.             if(j == N2 - 1 && bFreeGapRight2) {
  200.                 wg2 = ws2 = 0;
  201.             }
  202.             n0 = rowV[j] + wg2;
  203.             if(rowF[j] >= n0) {
  204.                 rowF[j] += ws2;
  205.                 tracer |= kMaskFc;
  206.             }
  207.             else {
  208.                 rowF[j] = n0 + ws2;
  209.             }
  210.             // evaluate the score (V)
  211.             if (E >= rowF[j]) {
  212.                 if(E >= G) {
  213.                     V = E;
  214.                     tracer |= kMaskE;
  215.                 }
  216.                 else {
  217.                     V = G;
  218.                     tracer |= kMaskD;
  219.                 }
  220.             } else {
  221.                 if(rowF[j] >= G) {
  222.                     V = rowF[j];
  223.                 }
  224.                 else {
  225.                     V = G;
  226.                     tracer |= kMaskD;
  227.                 }
  228.             }
  229.             // find out if there are new donors
  230.             for(unsigned char st = 0; st < splice_type_count_16; ++st) {
  231.                 if(jTail[st] > jHead[st])  {
  232.                     if(j - jAllDonors[st][jHead[st]] >= m_IntronMinSize) {
  233.                         if(vAllDonors[st][jHead[st]] > vBestDonor[st]) {
  234.                             vBestDonor[st] = vAllDonors[st][jHead[st]];
  235.                             jBestDonor[st] = jAllDonors[st][jHead[st]];
  236.                         }
  237.                         ++(jHead[st]);
  238.                     }
  239.                 }
  240.             }
  241.                 
  242.             // check splice signal
  243.             size_t dnr_pos = 0;
  244.             Uint2 tracer_dnr = 0xFFFF;
  245.             Uint2 tracer_acc = 0;
  246.     for(unsigned char st = 0; st < splice_type_count_16; ++st) {
  247.                 if(seq2[j-1] == g_nwspl_acceptor[st][0] &&
  248.                    seq2[j] == g_nwspl_acceptor[st][1] &&
  249.                    vBestDonor[st] > kInfMinus || st == g_topidx) {
  250.                     vAcc = vBestDonor[st] + m_Wi[st];
  251.                     if(vAcc > V) {
  252.                         V = vAcc;
  253.                         tracer_acc = (st+1) << 4;
  254.                         dnr_pos = k0 + jBestDonor[st];
  255.                         tracer_dnr = 0x0080 << st;
  256.                     }
  257.                 }
  258.             }
  259.             if(tracer_dnr != 0xFFFF) {
  260.                 backtrace_matrix[dnr_pos] |= tracer_dnr;
  261.                 tracer |= tracer_acc;
  262.             }
  263.             backtrace_matrix[k] = tracer;
  264.             // detect donor candidate
  265.             if(j < N2 - 2) {
  266.                 for(unsigned char st = 0; st < g_topidx; ++st) {
  267.                     
  268.                     if( seq2[j+1] == g_nwspl_donor[st][0] &&
  269.                         seq2[j+2] == g_nwspl_donor[st][1] &&
  270.                         V > vBestDonor[st]  ) {
  271.                         
  272.                         jAllDonors[st][jTail[st]] = j;
  273.                         vAllDonors[st][jTail[st]] = V;
  274.                         ++(jTail[st]);
  275.                     }
  276.                 }
  277.             }
  278.             
  279.             // detect new best value
  280.             if(V > V_max) {
  281.                 jAllDonors[g_topidx][jTail[g_topidx]] = j;
  282.                 vAllDonors[g_topidx][jTail[g_topidx]] = V_max = V;
  283.                 ++(jTail[3]);
  284.             }
  285.         }
  286.         pV[j] = V;
  287.         if(i == 0) {
  288.             V0 = wgleft2;
  289.             wg1 = m_Wg;
  290.             ws1 = m_Ws;
  291.         }
  292.     }
  293.     try {
  294.         x_DoBackTrace(backtrace_matrix, N1, N2, transcript);
  295.     }
  296.     catch(exception&) { // GCC hack
  297.         throw;
  298.     }
  299.     
  300.     return V;
  301. }
  302. // perform backtrace step;
  303. void CSplicedAligner16::x_DoBackTrace ( const Uint2* backtrace_matrix,
  304.                                          size_t N1, size_t N2,
  305.                                          vector<ETranscriptSymbol>* transcript)
  306. {
  307.     transcript->clear();
  308.     transcript->reserve(N1 + N2);
  309.     size_t k = N1*N2 - 1;
  310.     while (k != 0) {
  311.         Uint2 Key = backtrace_matrix[k];
  312.         while(Key & 0x0070) {  // acceptor
  313.             unsigned char acc_type = (Key & 0x0070) >> 4;
  314.             Uint2 dnr_mask = 0x0040 << acc_type;
  315.             ETranscriptSymbol ets = eTS_Intron;
  316.             do {
  317.                 transcript->push_back(ets);
  318.                 Key = backtrace_matrix[--k];
  319.             }
  320.             while(!(Key & dnr_mask));
  321.             if(Key & 0x0070) {
  322.                 NCBI_THROW(CAlgoAlignException,
  323.                            eInternal,
  324.                            "Adjacent splices encountered during backtrace");
  325.             }
  326.         }
  327.         if(k == 0) continue;
  328.         
  329.         if (Key & kMaskD) {
  330.             transcript->push_back(eTS_Match);  // or eTS_Replace
  331.             k -= N2 + 1;
  332.         }
  333.         else if (Key & kMaskE) {
  334.             transcript->push_back(eTS_Insert); --k;
  335.             while(k > 0 && (Key & kMaskEc)) {
  336.                 transcript->push_back(eTS_Insert);
  337.                 Key = backtrace_matrix[k--];
  338.             }
  339.         }
  340.         else {
  341.             transcript->push_back(eTS_Delete);
  342.             k -= N2;
  343.             while(k > 0 && (Key & kMaskFc)) {
  344.                 transcript->push_back(eTS_Delete);
  345.                 Key = backtrace_matrix[k];
  346.                 k -= N2;
  347.             }
  348.         }
  349.     }
  350. }
  351. CNWAligner::TScore CSplicedAligner16::x_ScoreByTranscript() const
  352. {
  353.     const size_t dim = m_Transcript.size();
  354.     if(dim == 0) return 0;
  355.     TScore score = 0;
  356.     const char* p1 = m_Seq1;
  357.     const char* p2 = m_Seq2;
  358.     const TNCBIScore (*sm) [NCBI_FSM_DIM] = m_ScoreMatrix.s;
  359.     char state1;   // 0 = normal, 1 = gap, 2 = intron
  360.     char state2;   // 0 = normal, 1 = gap
  361.     switch( m_Transcript[dim - 1] ) {
  362.     case eTS_Match:
  363.         state1 = state2 = 0;
  364.         break;
  365.     case eTS_Insert:
  366.         state1 = 1; state2 = 0; score += m_Wg;
  367.         break;
  368.     case eTS_Intron:
  369.         state1 = 0; state2 = 0;
  370.         break; // intron flag set later
  371.     case eTS_Delete:
  372.         state1 = 0; state2 = 1; score += m_Wg;
  373.         break;
  374.     default: {
  375.         NCBI_THROW(CAlgoAlignException, eInternal,
  376.                    "Invalid transcript symbol");
  377.         }
  378.     }
  379.     for(int i = dim - 1; i >= 0; --i) {
  380.         unsigned char c1 = m_Seq1? *p1: 0;
  381.         unsigned char c2 = m_Seq2? *p2: 0;
  382.         switch(m_Transcript[i]) {
  383.         case eTS_Match: {
  384.             state1 = state2 = 0;
  385.             score += sm[c1][c2];
  386.             ++p1; ++p2;
  387.         }
  388.         break;
  389.         case eTS_Insert: {
  390.             if(state1 != 1) score += m_Wg;
  391.             state1 = 1; state2 = 0;
  392.             score += m_Ws;
  393.             ++p2;
  394.         }
  395.         break;
  396.         case eTS_Delete: {
  397.             if(state2 != 1) score += m_Wg;
  398.             state1 = 0; state2 = 1;
  399.             score += m_Ws;
  400.             ++p1;
  401.         }
  402.         break;
  403.         case eTS_Intron: {
  404.             if(state1 != 2) {
  405.                 for(unsigned char i = 0; i < splice_type_count_16; ++i) {
  406.                     if(*p2 == g_nwspl_donor[i][0] &&
  407.                        *(p2 + 1) == g_nwspl_donor[i][1] || i == g_topidx) {
  408.                         score += m_Wi[i];
  409.                         break;
  410.                     }
  411.                 }
  412.             }
  413.             state1 = 2; state2 = 0;
  414.             ++p2;
  415.         }
  416.         break;
  417.         default: {
  418.         NCBI_THROW(CAlgoAlignException, eInternal,
  419.                    "Invalid transcript symbol");
  420.         }
  421.         }
  422.     }
  423.     if(m_esf_L1) {
  424.         size_t g = 0;
  425.         for(int i = dim - 1; i >= 0; --i) {
  426.             if(m_Transcript[i] == eTS_Insert) ++g; else break;
  427.         }
  428.         if(g > 0) {
  429.             score -= (m_Wg + g*m_Ws);
  430.         }
  431.     }
  432.     if(m_esf_L2) {
  433.         size_t g = 0;
  434.         for(int i = dim - 1; i >= 0; --i) {
  435.             if(m_Transcript[i] == eTS_Delete) ++g; else break;
  436.         }
  437.         if(g > 0) {
  438.             score -= (m_Wg + g*m_Ws);
  439.         }
  440.     }
  441.     if(m_esf_R1) {
  442.         size_t g = 0;
  443.         for(size_t i = 0; i < dim; ++i) {
  444.             if(m_Transcript[i] == eTS_Insert) ++g; else break;
  445.         }
  446.         if(g > 0) {
  447.             score -= (m_Wg + g*m_Ws);
  448.         }
  449.     }
  450.     if(m_esf_R2) {
  451.         size_t g = 0;
  452.         for(size_t i = 0; i < dim; ++i) {
  453.             if(m_Transcript[i] == eTS_Delete) ++g; else break;
  454.         }
  455.         if(g > 0) {
  456.             score -= (m_Wg + g*m_Ws);
  457.         }
  458.     }
  459.     return score;
  460. }
  461. END_NCBI_SCOPE
  462. /*
  463.  * ===========================================================================
  464.  * $Log: nw_spliced_aligner16.cpp,v $
  465.  * Revision 1000.3  2004/06/01 18:05:00  gouriano
  466.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13
  467.  *
  468.  * Revision 1.13  2004/05/21 21:41:02  gorelenk
  469.  * Added PCH ncbi_pch.hpp
  470.  *
  471.  * Revision 1.12  2004/05/18 21:43:40  kapustin
  472.  * Code cleanup
  473.  *
  474.  * Revision 1.11  2004/05/17 14:50:56  kapustin
  475.  * Add/remove/rearrange some includes and object declarations
  476.  *
  477.  * Revision 1.10  2004/04/23 14:39:47  kapustin
  478.  * Add Splign library and other changes
  479.  *
  480.  * Revision 1.8  2003/11/20 17:54:23  kapustin
  481.  * Alternative conventional splice penalty adjusted
  482.  *
  483.  * Revision 1.7  2003/10/31 19:40:13  kapustin
  484.  * Get rid of some WS and GCC complains
  485.  *
  486.  * Revision 1.6  2003/10/27 21:00:17  kapustin
  487.  * Set intron penalty defaults differently for 16- and 32-bit versions
  488.  * according to the expected quality of sequences those variants are
  489.  * supposed to be used with.
  490.  *
  491.  * Revision 1.5  2003/10/14 19:29:24  kapustin
  492.  * Dismiss static keyword as a local-to-compilation-unit flag. Use longer
  493.  * name since unnamed namespaces are not everywhere supported
  494.  *
  495.  * Revision 1.4  2003/09/30 19:50:04  kapustin
  496.  * Make use of standard score matrix interface
  497.  *
  498.  * Revision 1.3  2003/09/26 14:43:18  kapustin
  499.  * Remove exception specifications
  500.  *
  501.  * Revision 1.2  2003/09/04 16:07:38  kapustin
  502.  * Use STL vectors for exception-safe dynamic arrays and matrices
  503.  *
  504.  * Revision 1.1  2003/09/02 22:34:49  kapustin
  505.  * Initial revision
  506.  *
  507.  * ===========================================================================
  508.  */