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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: cpg.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 18:10:28  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.4
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: cpg.cpp,v 1000.2 2004/06/01 18:10:28 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. * Author: Philip Johnson
  35. *
  36. * File Description: cpg -- c++ cpg island finder based upon algorithm in
  37. *     Takai, D. & Jones, PA.  "Comprehensive analysis of CpG islands in
  38. *     human chromosomes 21 and 22."  PNAS, 2002.
  39. *
  40. * ===========================================================================*/
  41. #include <ncbi_pch.hpp>
  42. #include <algo/sequence/cpg.hpp>
  43. BEGIN_NCBI_SCOPE
  44. ///////////////////////////////////////////////////////////////////////////////
  45. // PRE : const char* of iupac sequence (null-terminated), window size,
  46. // minimum island length, min GC percentage, min observed/expected CpG ratio
  47. // POST: cpg islands calculated for the given bioseq using the given parameters
  48. CCpGIslands::CCpGIslands(const char *seq, TSeqPos length,
  49.                          int window, int minLen, double GC, double CpG) :
  50.     m_Seq(seq), m_SeqLength(length)
  51. {
  52.     Calc(window, minLen, GC, CpG);
  53. }
  54. ///////////////////////////////////////////////////////////////////////////////
  55. // PRE : windowsize, min length, %GC, obs/exp CpG ratio
  56. // POST: islands recalculated for new params
  57. void CCpGIslands::Calc(int window, int minLen, double GC, double CpG)
  58. {
  59.     m_Isles.clear();//clear old islands
  60.     m_WindowSize = window;
  61.     m_MinIsleLen = minLen;
  62.     m_GC = (int) (GC * 100);
  63.     m_CpG = (int) (CpG * 100);
  64.     
  65.     SCpGIsland isle;
  66.     isle.m_Start = 0;
  67.     while (x_SlideToHit(isle)) {
  68.         if (x_ExtendHit(isle)) {
  69.             m_Isles.push_back(isle);
  70.         }
  71.         isle.m_Start = isle.m_Stop + 1;
  72.     }
  73. }
  74. ///////////////////////////////////////////////////////////////////////////////
  75. // PRE : position to be added, cgIsland information
  76. // POST: cgIsle adjusted according to the nucleotide at position i & i-1
  77. void CCpGIslands::x_AddPosition(TSeqPos i, SCpGIsland &isle)
  78. {
  79.     switch(m_Seq[i]) {
  80.     case 'A': isle.m_A++; break;
  81.     case 'C': isle.m_C++; break;
  82.     case 'G': isle.m_G++;
  83.         if (i > 0  &&  m_Seq[i-1] == 'C') {
  84.             isle.m_CG++;
  85.         }
  86.         break;
  87.     case 'T': isle.m_T++; break;
  88.     case 'N': isle.m_N++; break;
  89.     }
  90. }
  91. ///////////////////////////////////////////////////////////////////////////////
  92. // PRE : position to be removed, cgIsland information
  93. // POST: cgIsle adjusted according to the nucleotide at position i & i-1
  94. void CCpGIslands::x_RemovePosition(TSeqPos i, SCpGIsland &isle)
  95. {
  96.     switch(m_Seq[i]) {
  97.     case 'A': isle.m_A--; break;
  98.     case 'C': isle.m_C--; break;
  99.     case 'G': isle.m_G--;
  100.         if (i > 0  &&  m_Seq[i-1] == 'C') {
  101.             isle.m_CG--;
  102.         }
  103.         break;
  104.     case 'T': isle.m_T--; break;
  105.     case 'N': isle.m_N--; break;
  106.     }
  107. }
  108. ///////////////////////////////////////////////////////////////////////////////
  109. // PRE : cpg island structure w/ start & stop specified
  110. // POST: isle filled with stats (#a's, c's, etc.) for window [start, stop]
  111. void CCpGIslands::x_CalcWindowStats(SCpGIsland &isle)
  112. {
  113.     isle.m_A = isle.m_T = isle.m_G = isle.m_C = isle.m_N = isle.m_CG = 0;
  114.     for (TSeqPos i = isle.m_Start; i <= isle.m_Stop; i++) {
  115.         x_AddPosition(i, isle);
  116.     }
  117. }
  118. ///////////////////////////////////////////////////////////////////////////////
  119. // PRE : win.m_Start field species where to start looking
  120. // POST: whether or not we found a window further down the sequence that
  121. // meets the mimimum criteria; if so, 'win' is set to that window
  122. bool CCpGIslands::x_SlideToHit(SCpGIsland &win)
  123. {
  124.     bool inIsland, done;
  125.     win.m_Stop = win.m_Start + m_WindowSize - 1;
  126.     if (win.m_Stop >= m_SeqLength) {
  127.         return false;
  128.     }
  129.     x_CalcWindowStats(win);
  130.     inIsland = false;
  131.     done = false;
  132.     while (win.m_Stop < m_SeqLength  &&  !x_IsIsland(win)) {
  133.         // remove 1 nt from left side
  134.         x_RemovePosition(win.m_Start, win);
  135.         // advance
  136.         ++win.m_Start;
  137.         ++win.m_Stop;
  138.         if (win.m_Stop < m_SeqLength) {
  139.             // add 1 nt onto right side
  140.             x_AddPosition(win.m_Stop, win);
  141.         }
  142.     }
  143.     
  144.     return x_IsIsland(win);
  145. }
  146. ///////////////////////////////////////////////////////////////////////////////
  147. // PRE : window that meets the GC & CpG criteria
  148. // POST: whether or not the island can be extended to reach at least the
  149. // minimum length; if so, isle is set to that window
  150. bool CCpGIslands::x_ExtendHit(SCpGIsland &isle)
  151. {
  152.     SCpGIsland win = isle;
  153.     //jump by 200bp increments
  154.     while (win.m_Stop + m_WindowSize < m_SeqLength  &&  x_IsIsland(win)) {
  155.         win.m_Start += m_WindowSize;
  156.         win.m_Stop += m_WindowSize;
  157.         x_CalcWindowStats(win);
  158.     }
  159.     //if we overshot, slide back by 1bp increments
  160.     while (!x_IsIsland(win)) {
  161.         x_RemovePosition(win.m_Stop, win);
  162.         --win.m_Start;
  163.         --win.m_Stop;
  164.         x_AddPosition(win.m_Start, win);
  165.     }
  166.     //trim ends of entire island until we're above criteria again
  167.     isle.m_Stop = win.m_Stop;
  168.     x_CalcWindowStats(isle);
  169.     while(!x_IsIsland(isle)  &&  (isle.m_Start < isle.m_Stop)) {
  170.         x_RemovePosition(isle.m_Stop, isle);
  171.         x_RemovePosition(isle.m_Start, isle);
  172.         --isle.m_Stop;
  173.         ++isle.m_Start;
  174.     }
  175.     if (isle.m_Start >= isle.m_Stop) {//in case we trimmed to nothing
  176.         isle.m_Stop = isle.m_Start;
  177.         return false;
  178.     }
  179.     return (isle.m_Stop - isle.m_Start + 1 > m_MinIsleLen);
  180. }
  181. ///////////////////////////////////////////////////////////////////////////////
  182. // PRE : range in base pairs
  183. // POST: any adjacent islands within the specified range are merged
  184. void CCpGIslands::MergeIslesWithin(TSeqPos range)
  185. {
  186.     TIsles::iterator prev = m_Isles.end();
  187.     NON_CONST_ITERATE(TIsles, i, m_Isles) {
  188.         if (prev != m_Isles.end()  &&
  189.             i->m_Start - prev->m_Stop <= range) {
  190.             i->m_Start = prev->m_Start;
  191.             x_CalcWindowStats(*i);
  192.             m_Isles.erase(prev);
  193.         }
  194.         prev = i;
  195.     }
  196. }
  197. END_NCBI_SCOPE
  198. /*===========================================================================
  199. * $Log: cpg.cpp,v $
  200. * Revision 1000.2  2004/06/01 18:10:28  gouriano
  201. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.4
  202. *
  203. * Revision 1.4  2004/05/21 21:41:04  gorelenk
  204. * Added PCH ncbi_pch.hpp
  205. *
  206. * Revision 1.3  2003/12/12 20:05:19  johnson
  207. * refactoring to accommodate MSVC 7
  208. *
  209. * Revision 1.2  2003/07/21 15:53:35  johnson
  210. * added reference in header comment
  211. *
  212. * Revision 1.1  2003/06/17 15:33:33  johnson
  213. * initial revision
  214. *
  215. *============================================================================
  216. */