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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: nw_spliced_aligner.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 18:04:57  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.8
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: nw_spliced_aligner.cpp,v 1000.1 2004/06/01 18:04:57 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:  Base class for spliced aligners.
  37. *                   
  38. * ===========================================================================
  39. *
  40. */
  41. #include <ncbi_pch.hpp>
  42. #include <algo/align/nw_spliced_aligner.hpp>
  43. #include <algo/align/align_exception.hpp>
  44. BEGIN_NCBI_SCOPE
  45. CSplicedAligner::CSplicedAligner():
  46.     m_IntronMinSize(GetDefaultIntronMinSize())
  47. {
  48.     SetEndSpaceFree(true, true, false, false);
  49. }
  50.     
  51. CSplicedAligner::CSplicedAligner(const char* seq1, size_t len1,
  52.                                  const char* seq2, size_t len2)
  53.     : CNWAligner(seq1, len1, seq2, len2),
  54.       m_IntronMinSize(GetDefaultIntronMinSize())
  55. {
  56.     SetEndSpaceFree(true, true, false, false);
  57. }
  58. void CSplicedAligner::SetWi  (unsigned char splice_type, TScore value)
  59. {
  60.     if(splice_type < GetSpliceTypeCount()) {
  61.         x_GetSpliceScores()[splice_type]  = value;
  62.     }
  63.     else 
  64.     {
  65.         NCBI_THROW(CAlgoAlignException,
  66.                    eInvalidSpliceTypeIndex,
  67.                    "Invalid splice type index");
  68.     }
  69. }
  70. CSplicedAligner::TScore CSplicedAligner::GetWi  (unsigned char splice_type)
  71. {
  72.     if(splice_type < GetSpliceTypeCount()) {
  73.         return x_GetSpliceScores()[splice_type];
  74.     }
  75.     else 
  76.     {
  77.         NCBI_THROW(CAlgoAlignException,
  78.                    eInvalidSpliceTypeIndex,
  79.                    "Invalid splice type index");
  80.     }
  81. }
  82. unsigned char CSplicedAligner::x_CalcFingerPrint64(
  83.     const char* beg, const char* end, size_t& err_index)
  84. {
  85.     if(beg >= end) {
  86.         return 0xFF;
  87.     }
  88.     unsigned char fp = 0, code;
  89.     for(const char* p = beg; p < end; ++p) {
  90.         switch(*p) {
  91.         case 'A': code = 0;    break;
  92.         case 'G': code = 0x01; break;
  93.         case 'T': code = 0x02; break;
  94.         case 'C': code = 0x03; break;
  95.         default:  err_index = p - beg; return 0x40; // incorrect char
  96.         }
  97.         fp = 0x3F & ((fp << 2) | code);
  98.     }
  99.     return fp;
  100. }
  101. const char* CSplicedAligner::x_FindFingerPrint64(
  102.     const char* beg, const char* end,
  103.     unsigned char fingerprint, size_t size,
  104.     size_t& err_index)
  105. {
  106.     if(beg + size > end) {
  107.         err_index = 0;
  108.         return 0;
  109.     }
  110.     const char* p0 = beg;
  111.     size_t err_idx = 0; --p0;
  112.     unsigned char fp = 0x40;
  113.     while(fp == 0x40 && p0 < end) {
  114.         p0 += err_idx + 1;
  115.         fp = x_CalcFingerPrint64(p0, p0 + size, err_idx);
  116.     }
  117.     if(p0 >= end) {
  118.         return end;  // not found
  119.     }
  120.     
  121.     unsigned char code;
  122.     while(fp != fingerprint && ++p0 < end) {
  123.         switch(*(p0 + size - 1)) {
  124.         case 'A': code = 0;    break;
  125.         case 'G': code = 0x01; break;
  126.         case 'T': code = 0x02; break;
  127.         case 'C': code = 0x03; break;
  128.         default:  err_index = p0 + size - 1 - beg;
  129.                   return 0;
  130.         }
  131.         
  132.         fp = 0x3F & ((fp << 2) | code );
  133.     }
  134.     return p0;
  135. }
  136. struct nwaln_mrnaseg {
  137.     nwaln_mrnaseg(size_t i1, size_t i2, unsigned char fp0):
  138.         a(i1), b(i2), fp(fp0) {}
  139.     size_t a, b;
  140.     unsigned char fp;
  141. };
  142. struct nwaln_mrnaguide {
  143.     nwaln_mrnaguide(size_t i1, size_t i2, size_t i3, size_t i4):
  144.         q0(i1), q1(i2), s0(i3), s1(i4) {}
  145.     size_t q0, q1, s0, s1;
  146. };
  147. size_t CSplicedAligner::MakePattern(const size_t guide_size)
  148. {
  149.     vector<nwaln_mrnaseg> segs;
  150.     size_t err_idx;
  151.     for(size_t i = 0; i + guide_size <= m_SeqLen1; ) {
  152.         const char* beg = m_Seq1 + i;
  153.         const char* end = m_Seq1 + i + guide_size;
  154.         unsigned char fp = x_CalcFingerPrint64(beg, end, err_idx);
  155.         if(fp != 0x40) {
  156.             segs.push_back(nwaln_mrnaseg(i, i + guide_size - 1, fp));
  157.             i += guide_size;
  158.         }
  159.         else {
  160.             i += err_idx + 1;
  161.         }
  162.     }
  163.     vector<nwaln_mrnaguide> guides;
  164.     size_t idx = 0;
  165.     const char* beg = m_Seq2 + idx;
  166.     const char* end = m_Seq2 + m_SeqLen2;
  167.     for(size_t i = 0, seg_count = segs.size();
  168.         beg + guide_size <= end && i < seg_count; ++i) {
  169.         const char* p = 0;
  170.         const char* beg0 = beg;
  171.         while( p == 0 && beg + guide_size <= end ) {
  172.             p = x_FindFingerPrint64( beg, end, segs[i].fp,
  173.                                      guide_size, err_idx );
  174.             if(p == 0) { // incorrect char
  175.                 beg += err_idx + 1; 
  176.             }
  177.             else if (p < end) {// fingerprints match but check actual sequences
  178.                 const char* seq1 = m_Seq1 + segs[i].a;
  179.                 const char* seq2 = p;
  180.                 size_t k;
  181.                 for(k = 0; k < guide_size; ++k) {
  182.                     if(seq1[k] != seq2[k]) break;
  183.                 }
  184.                 if(k == guide_size) { // real match
  185.                     size_t i1 = segs[i].a;
  186.                     size_t i2 = segs[i].b;
  187.                     size_t i3 = seq2 - m_Seq2;
  188.                     size_t i4 = i3 + guide_size - 1;
  189.                     size_t guides_dim = guides.size();
  190.                     if( guides_dim == 0 ||
  191.                         i1 - 1 > guides[guides_dim - 1].q1 ||
  192.                         i3 - 1 > guides[guides_dim - 1].s1    ) {
  193.                         guides.push_back(nwaln_mrnaguide(i1, i2, i3, i4));
  194.                     }
  195.                     else { // expand the last guide
  196.                         guides[guides_dim - 1].q1 = i2;
  197.                         guides[guides_dim - 1].s1 = i4;
  198.                     }
  199.                     beg0 = p + guide_size;
  200.                 }
  201.                 else {  // spurious match
  202.                     beg = p + 1;
  203.                     p = 0;
  204.                 }
  205.             }
  206.         }
  207.         beg = beg0; // restore start pos in genomic sequence
  208.     }
  209.     // initialize m_guides
  210.     size_t guides_dim = guides.size();
  211.     m_guides.clear();
  212.     m_guides.resize(4*guides_dim);
  213.     const size_t offs = 10;
  214.     for(size_t k = 0; k < guides_dim; ++k) {
  215.         size_t q0 = (guides[k].q0 + guides[k].q1) / 2;
  216.         size_t s0 = (guides[k].s0 + guides[k].s1) / 2;
  217.         m_guides[4*k]         = q0 - offs;
  218.         m_guides[4*k + 1]     = q0 + offs;
  219.         m_guides[4*k + 2]     = s0 - offs;
  220.         m_guides[4*k + 3]     = s0 + offs;
  221.     }
  222.  
  223.     return m_guides.size();   
  224. }
  225. END_NCBI_SCOPE
  226. /*
  227.  * ===========================================================================
  228.  * $Log: nw_spliced_aligner.cpp,v $
  229.  * Revision 1000.1  2004/06/01 18:04:57  gouriano
  230.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.8
  231.  *
  232.  * Revision 1.8  2004/05/21 21:41:02  gorelenk
  233.  * Added PCH ncbi_pch.hpp
  234.  *
  235.  * Revision 1.7  2004/05/17 14:50:56  kapustin
  236.  * Add/remove/rearrange some includes and object declarations
  237.  *
  238.  * Revision 1.6  2004/04/23 14:39:47  kapustin
  239.  * Add Splign library and other changes
  240.  *
  241.  * Revision 1.4  2003/10/27 21:00:17  kapustin
  242.  * Set intron penalty defaults differently for 16- and 32-bit versions according to the expected quality of sequences those variants are supposed to be used with.
  243.  *
  244.  * Revision 1.3  2003/09/30 19:50:04  kapustin
  245.  * Make use of standard score matrix interface
  246.  *
  247.  * Revision 1.2  2003/09/26 14:43:18  kapustin
  248.  * Remove exception specifications
  249.  *
  250.  * Revision 1.1  2003/09/02 22:34:49  kapustin
  251.  * Initial revision
  252.  *
  253.  * ===========================================================================
  254.  */