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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: models.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 18:08:35  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.3
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: models.cpp,v 1000.2 2004/06/01 18:08:35 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:  Mike DiCuccio
  35.  *
  36.  * File Description:
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include "gene_finder.hpp"
  41. BEGIN_NCBI_SCOPE
  42. const double BadScore   = -numeric_limits<double>::max();
  43. const double LnHalf     = log(0.5);
  44. const double LnThree    = log(3.0);
  45. const int    toMinus[5] = { nT, nG, nC, nA, nN };
  46. const int    TooFarLen  = 500;
  47. const char*  aa_table   = "KNKNXTTTTTRSRSXIIMIXXXXXXQHQHXPPPPPRRRRRLLLLLXXXXXEDEDXAAAAAGGGGGVVVVVXXXXX * Y*YXSSSSS * CWCXLFLFXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  48. void MarkovChain<0>::InitScore(CNcbiIfstream& from)
  49. {
  50.     Init(from);
  51.     if (from) {
  52.         toScore();
  53.     }
  54. }
  55. void MarkovChain<0>::Init(CNcbiIfstream& from)
  56. {
  57.     from >> score[nA];
  58.     from >> score[nC];
  59.     from >> score[nG];
  60.     from >> score[nT];
  61.     score[nN] = 0.25;
  62.     return;
  63.     double sum = score[nA]+score[nC]+score[nG]+score[nT];
  64.     if (sum != 0) {
  65.         score[nA] /= sum;
  66.         score[nC] /= sum;
  67.         score[nG] /= sum;
  68.         score[nT] /= sum;
  69.     }
  70. }
  71. void MarkovChain<0>::Average(Type& mc0, Type& mc1, Type& mc2, Type& mc3)
  72. {
  73.     score[nA] = 0.25 * (mc0.score[nA]+mc1.score[nA]+mc2.score[nA]+mc3.score[nA]);
  74.     score[nC] = 0.25 * (mc0.score[nC]+mc1.score[nC]+mc2.score[nC]+mc3.score[nC]);
  75.     score[nG] = 0.25 * (mc0.score[nG]+mc1.score[nG]+mc2.score[nG]+mc3.score[nG]);
  76.     score[nT] = 0.25 * (mc0.score[nT]+mc1.score[nT]+mc2.score[nT]+mc3.score[nT]);
  77.     score[nN] = 0.25;
  78. }
  79. void MarkovChain<0>::toScore()
  80. {
  81.     score[nA] = (score[nA] <= 0) ? BadScore : log(4 * score[nA]);
  82.     score[nC] = (score[nC] <= 0) ? BadScore : log(4 * score[nC]);
  83.     score[nG] = (score[nG] <= 0) ? BadScore : log(4 * score[nG]);
  84.     score[nT] = (score[nT] <= 0) ? BadScore : log(4 * score[nT]);
  85.     score[nN] = (score[nN] <= 0) ? BadScore : log(4 * score[nN]);
  86. }
  87. pair<int,int> InputModel::FindContent(CNcbiIfstream& from, const string& label, int cgcontent)
  88. {
  89.     string str;
  90.     while (from >> str) {
  91.         int low,high;
  92.         if (str == label) {
  93.             from >> str;
  94.             if ( str != "CG:" ) {
  95.                 return make_pair(-1,-1);
  96.             }
  97.             from >> low >> high;
  98.             if ( !from  ) {
  99.                 return make_pair(-1,-1);
  100.             }
  101.             if ( cgcontent >= low  &&  cgcontent < high) {
  102.                 return make_pair(low,high);
  103.             }
  104.         }
  105.     }
  106.     return make_pair(-1,-1);
  107. }
  108. InputModel::~InputModel()
  109. {
  110. }
  111. double MDD_Donor::Score(const IVec& seq, int i) const
  112. {
  113.     int first = i - left + 1;
  114.     int last = i + right;
  115.     if (first < 0  ||  last >= seq.size()) {
  116.         return BadScore;    // out of range
  117.     }
  118.     if (seq[i + 1] != nG  ||  seq[i + 2] != nT) {
  119.         return BadScore;   // no GT
  120.     }
  121.     int mat = 0;
  122.     for (int j = 0;  j < position.size();  ++j) {
  123.         if (seq[first + position[j]] != consensus[j]) {
  124.             break;
  125.         }
  126.         ++mat;
  127.     }
  128.     return matrix[mat].Score(&seq[first]);
  129. }
  130. MDD_Donor::MDD_Donor(const string& file, int cgcontent)
  131. {
  132.     string label = "[MDD_Donor]";
  133.     CNcbiIfstream from(file.c_str());
  134.     pair<int,int> cgrange = FindContent(from,label,cgcontent);
  135.     if (cgrange.first < 0) {
  136.         Error(label);
  137.     }
  138.     string str;
  139.     from >> str;
  140.     if ( str != "InExon:" ) {
  141.         Error(label);
  142.     }
  143.     from >> inexon;
  144.     if ( !from  ) {
  145.         Error(label);
  146.     }
  147.     from >> str;
  148.     if ( str != "InIntron:" ) {
  149.         Error(label);
  150.     }
  151.     from >> inintron;
  152.     if ( !from  ) {
  153.         Error(label);
  154.     }
  155.     left = inexon;
  156.     right = inintron;
  157.     do {
  158.         from >> str;
  159.         if ( !from  ) {
  160.             Error(label);
  161.         }
  162.         if (str == "Position:") {
  163.             int i;
  164.             from >> i;
  165.             if ( !from  ) {
  166.                 Error(label);
  167.             }
  168.             position.push_back(i);
  169.             from >> str;
  170.             if ( !from  ) {
  171.                 Error(label);
  172.             }
  173.             if ( str != "Consensus:" ) {
  174.                 Error(label);
  175.             }
  176.             char c;
  177.             from >> c;
  178.             if ( !from  ) {
  179.                 Error(label);
  180.             }
  181.             i = ACGT(c);
  182.             if (i == nN) {
  183.                 Error(label); 
  184.             }
  185.             consensus.push_back(i);
  186.         }
  187.         matrix.push_back(MarkovChainArray<0>());
  188.         matrix.back().InitScore(inexon + inintron,from);
  189.         if ( !from  ) {
  190.             Error(label);
  191.         }
  192.     } while (str != "End");
  193. }
  194. WMM_Start::WMM_Start(const string& file, int cgcontent)
  195. {
  196.     string label = "[WMM_Start]";
  197.     CNcbiIfstream from(file.c_str());
  198.     pair<int,int> cgrange = FindContent(from,label,cgcontent);
  199.     if (cgrange.first < 0) {
  200.         Error(label);
  201.     }
  202.     string str;
  203.     from >> str;
  204.     if ( str != "InExon:" ) {
  205.         Error(label);
  206.     }
  207.     from >> inexon;
  208.     if ( !from  ) {
  209.         Error(label);
  210.     }
  211.     from >> str;
  212.     if ( str != "InIntron:" ) {
  213.         Error(label);
  214.     }
  215.     from >> inintron;
  216.     if ( !from  ) {
  217.         Error(label);
  218.     }
  219.     left = inintron;
  220.     right = inexon;
  221.     matrix.InitScore(inexon + inintron,from);
  222.     if ( !from  ) {
  223.         Error(label);
  224.     }
  225. }
  226. double WMM_Start::Score(const IVec& seq, int i) const
  227. {
  228.     int first = i - left + 1;
  229.     int last = i + right;
  230.     if (first < 0  ||  last >= seq.size()) {
  231.         return BadScore;  // out of range
  232.     }
  233.     if (seq[i - 2] != nA  ||  seq[i - 1] != nT  ||  seq[i] != nG) {
  234.         return BadScore; // no ATG
  235.     }
  236.     return matrix.Score(&seq[first]);
  237. }
  238. WAM_Stop::WAM_Stop(const string& file, int cgcontent)
  239. {
  240.     string label = "[WAM_Stop_1]";
  241.     CNcbiIfstream from(file.c_str());
  242.     pair<int,int> cgrange = FindContent(from,label,cgcontent);
  243.     if (cgrange.first < 0) {
  244.         Error(label);
  245.     }
  246.     string str;
  247.     from >> str;
  248.     if ( str != "InExon:" ) {
  249.         Error(label);
  250.     }
  251.     from >> inexon;
  252.     if ( !from  ) {
  253.         Error(label);
  254.     }
  255.     from >> str;
  256.     if ( str != "InIntron:" ) {
  257.         Error(label);
  258.     }
  259.     from >> inintron;
  260.     if ( !from  ) {
  261.         Error(label);
  262.     }
  263.     left = inexon;
  264.     right = inintron;
  265.     matrix.InitScore(inexon + inintron,from);
  266.     if ( !from  ) {
  267.         Error(label);
  268.     }
  269. }
  270. double WAM_Stop::Score(const IVec& seq, int i) const
  271. {
  272.     int first = i - left + 1;
  273.     int last = i + right;
  274.     if (first - 1 < 0  ||  last >= seq.size()) {
  275.         return BadScore;
  276.     }  // out of range
  277.     if ((seq[i + 1] != nT  ||  seq[i + 2] != nA  ||  seq[i + 3] != nA)  &&  
  278.         (seq[i + 1] != nT  ||  seq[i + 2] != nA  ||  seq[i + 3] != nG)  &&  
  279.         (seq[i + 1] != nT  ||  seq[i + 2] != nG  ||  seq[i + 3] != nA)) {
  280.         return BadScore; // no stop - codon
  281.     }
  282.     return matrix.Score(&seq[first]);
  283. }
  284. SeqScores::SeqScores(Terminal& a, Terminal& d, Terminal& stt, Terminal& stp, 
  285.                      CodingRegion& cr, NonCodingRegion& ncr,
  286.                      NonCodingRegion& ing, CVec& original_sequence, 
  287.                      int from, int to,
  288.                      const CClusterSet& cls,
  289.                      const TFrameShifts& initial_fshifts,
  290.                      bool repeats, bool leftwall, 
  291.                      bool rightwall, string cntg)
  292.     : acceptor(a),
  293.       donor(d),
  294.       start(stt),
  295.       stop(stp),
  296.       cdr(cr),
  297.       ncdr(ncr),
  298.       intrg(ing), 
  299.       cluster_set(cls),
  300.       fshifts(initial_fshifts),
  301.       shift(from),
  302.       contig(cntg)
  303. {
  304.     for (CClusterSet::ConstIt it_cls = cls.begin();  it_cls != cls.end();  ++it_cls) {
  305.         if (it_cls->Limits().first <= from  ||  it_cls->Limits().second >= to) {
  306.             continue;
  307.         }
  308.         for (CCluster::ConstIt it = it_cls->begin();  it != it_cls->end();  ++it) {
  309.             const AlignVec& algn = *it;
  310.             if (algn.Type() == AlignVec::Prot) {
  311.                 for (int i = 0;  i < algn.size() - 1;  ++i) {
  312.                     int a = algn[i].second + 1;
  313.                     int b = algn[i + 1].first - 1;
  314.                     int len = b - a + 1;
  315.                     int res = len % 3;
  316.                     if (res < 0) {
  317.                         res += 3;
  318.                     }
  319.                     int loc = (a + b) / 2;
  320.                     if (len < Intron::MinIntron()  &&  res != 0) {
  321.                         if (res == 1) {
  322.                             fshifts.push_back(CFrameShiftInfo(loc,false));
  323.                         }  // local copy
  324.                         else {
  325.                             fshifts.push_back(CFrameShiftInfo(loc,true,'N'));
  326.                         }
  327.                     }
  328.                 }
  329.             }
  330.         }
  331.     }
  332.     sort(fshifts.begin(),fshifts.end());
  333.     TFrameShifts::iterator fsi = fshifts.begin();
  334.     while (fsi != fshifts.end()  &&  fsi->Loc() < from) {
  335.         ++fsi;
  336.     }
  337.     CVec sequence;
  338.     rev_seq_map.resize(to - from + 1);
  339.     for (int i = from;  i <= to;  ++i) {
  340.         if (fsi == fshifts.end()  ||  i != fsi->Loc()) {
  341.             sequence.push_back(original_sequence[i]);
  342.             rev_seq_map[i - shift] = seq_map.size();
  343.             seq_map.push_back(i);
  344.         } else if (fsi->IsInsertion())   // Insertion
  345.         {                                                                            
  346.             sequence.push_back(fsi->InsertValue());
  347.             seq_map.push_back(-1); 
  348.             sequence.push_back(original_sequence[i]);
  349.             rev_seq_map[i - shift] = -1;
  350.             seq_map.push_back(i);
  351.             ++fsi;
  352.         } else    // Deletion
  353.         {
  354.             rev_seq_map[i - shift] = -1;
  355.             ++fsi;
  356.         }
  357.     }
  358.     int len = seq_map.size();
  359.     try {
  360.         notining.resize(len,-1);
  361.         inalign.resize(len,-1);
  362.         for (int strand = 0;  strand < 2;  ++strand) {
  363.             seq[strand].resize(len);
  364.             ascr[strand].resize(len,BadScore);
  365.             dscr[strand].resize(len,BadScore);
  366.             sttscr[strand].resize(len,BadScore);
  367.             stpscr[strand].resize(len,BadScore);
  368.             ncdrscr[strand].resize(len,BadScore);
  369.             ingscr[strand].resize(len,BadScore);
  370.             notinintron[strand].resize(len,-1);
  371.             for (int frame = 0;  frame < 3;  ++frame) {
  372.                 cdrscr[strand][frame].resize(len,BadScore);
  373.                 laststop[strand][frame].resize(len,-1);
  374.                 notinexon[strand][frame].resize(len,-1);
  375.             }
  376.             for (int ph = 0;  ph < 2;  ++ph) {
  377.                 asplit[strand][ph].resize(len,0);
  378.                 dsplit[strand][ph].resize(len,0);
  379.             }
  380.         }
  381.     }
  382.     catch(bad_alloc&) {
  383.         string msg("Not enough memory in SeqScores: ");
  384.         msg += NStr::IntToString(from) + " ";
  385.         msg += NStr::IntToString(to);
  386.         NCBI_THROW(CGnomonException, eGenericError, msg);
  387.     } 
  388.     for (int i = 0;  i < len;  ++i) {
  389.         char c = sequence[i];
  390.         if (repeats  &&  c != toupper(c)) {
  391.             laststop[Plus ][0][i] = i;
  392.             laststop[Plus ][1][i] = i;
  393.             laststop[Plus ][2][i] = i;
  394.             laststop[Minus][0][i] = i;
  395.             laststop[Minus][1][i] = i;
  396.             laststop[Minus][2][i] = i;
  397.         }
  398.         int l = ACGT(c);
  399.         seq[Plus][i] = l;
  400.         seq[Minus][len - 1-i] = toMinus[l];
  401.     }
  402.     CClusterSet cls_local(cntg);
  403.     for (CClusterSet::ConstIt it_cls = cls.begin();  it_cls != cls.end();  ++it_cls) {
  404.         if (it_cls->Limits().first < from  ||  it_cls->Limits().second > to) {
  405.             continue;
  406.         }
  407.         for (CCluster::ConstIt it = it_cls->begin();  it != it_cls->end();  ++it) {
  408.             AlignVec algn(it->Strand(),it->ID(),it->Type());
  409.             if (it->CdsLimits().first >= 0) {
  410.                 algn.SetCdsLimits(IPair(RevSeqMap(it->CdsLimits().first,true),RevSeqMap(it->CdsLimits().second,false)));
  411.             }
  412.             for (int k = 0;  k < it->size();  ++k) {
  413.                 int a = (*it)[k].first;
  414.                 int b = (*it)[k].second;
  415.                 a = RevSeqMap(a,true);
  416.                 b = RevSeqMap(b,false);
  417.                 algn.Insert(IPair(a,b));
  418.                 for (int i = a;  i <= b;  ++i) {
  419.                     // ignoring repeats in alignmnets
  420.                     laststop[Plus ][0][i] = -1;
  421.                     laststop[Plus ][1][i] = -1;
  422.                     laststop[Plus ][2][i] = -1;
  423.                     laststop[Minus][0][i] = -1;
  424.                     laststop[Minus][1][i] = -1;
  425.                     laststop[Minus][2][i] = -1;
  426.                 }
  427.             }
  428.             cls_local.InsertAlignment(algn);
  429.         }
  430.     }
  431.     for (CClusterSet::ConstIt it_cls = cls_local.begin();  it_cls != cls_local.end();  ++it_cls) {
  432.         for (CCluster::ConstIt it = it_cls->begin();  it != it_cls->end();  ++it) {
  433.             const AlignVec& algn = *it;
  434.             int strand = algn.Strand();
  435.             int otherstrand = (strand == Plus) ? Minus : Plus;
  436.             int type = algn.Type();
  437.             if (type != AlignVec::Prot) {
  438.                 if (strand == Plus) {
  439.                     // accept NONCONSENSUS alignment splices
  440.                     for (int k = 0;  k < algn.size();  ++k) {
  441.                         int i = algn[k].first;
  442.                         if (k != 0) {
  443.                             ascr[strand][i - 1] = 0;
  444.                         }
  445.                         i = algn[k].second;
  446.                         if (k != algn.size() - 1) {
  447.                             dscr[strand][i] = 0;
  448.                         }
  449.                     }
  450.                 } else {
  451.                     for (int k = 0;  k < algn.size();  ++k) {
  452.                         int i = algn[k].first;
  453.                         if (k != 0) {
  454.                             dscr[strand][i - 1] = 0;
  455.                         }
  456.                         i = algn[k].second;
  457.                         if (k != algn.size() - 1) {
  458.                             ascr[strand][i] = 0;
  459.                         }
  460.                     }
  461.                 }
  462.                 for (int k = 0;  k < algn.size() - 1;  ++k) {
  463.                     int introna = algn[k].second + 1;
  464.                     int intronb = algn[k + 1].first - 1;
  465.                     for (int pnt = introna;  pnt <= intronb;  ++pnt) {
  466.                         for (int frame = 0;  frame < 3;  ++frame) {
  467.                             notinexon[strand][frame][pnt] = pnt;
  468.                         }
  469.                     }
  470.                 }
  471.                 for (int k = 0;  k < algn.size();  ++k) {
  472.                     int exona = algn[k].first;
  473.                     int exonb = algn[k].second;
  474.                     //                  if (algn.Type() != AlignVec::RefSeq)
  475.                     //                  {
  476.                     //                      if (k == 0) exona = exonb;             // for the first and last exons we 
  477.                     //                      if (k == algn.size() - 1) exonb = exona; // respect only one point for non RefSeq
  478.                     //                  }
  479.                     for (int pnt = exona;  pnt <= exonb;  ++pnt) {
  480.                         notinintron[strand][pnt] = pnt;
  481.                     }
  482.                 }
  483.             } else {
  484.                 for (int k = 0;  k < algn.size();  ++k) {
  485.                     int exona = algn[k].first;
  486.                     int exonb = algn[k].second;
  487.                     int pnt = (exona + exonb) / 2;
  488.                     pnt += exonb%3 - pnt%3;        // this is the right codon end that was checked when alignments were computed
  489.                     // enforcing stop if present or collapsing to one point
  490.                     if (strand == Plus  &&  k == algn.size() - 1  &&  isStop(exonb + 1,strand)) {
  491.                         exona = pnt;
  492.                     } else if (strand == Minus  &&  k == 0  &&  isStop(exona - 1,strand)) {
  493.                         exonb = pnt;
  494.                     } else {
  495.                         exona = exonb = pnt;
  496.                     }
  497.                     int codon_end = exonb%3;
  498.                     int f_beg = (strand == Plus) ? 2 - codon_end : codon_end;
  499.                     for (int pnt = exona;  pnt <= exonb;  ++pnt) {
  500.                         notinintron[strand][pnt] = pnt;
  501.                         for (int frame = 0;  frame < 3;  ++frame) {
  502.                             if (frame != f_beg) {
  503.                                 notinexon[strand][frame][pnt] = pnt;
  504.                             }
  505.                         }
  506.                     }
  507.                 }
  508.             }
  509.             int a = algn.Limits().first;
  510.             int b = algn.Limits().second;
  511.             for (int i = a;  i <= b;  ++i) {
  512.                 inalign[i] = a;
  513.                 notinintron[otherstrand][i] = i;
  514.                 for (int frame = 0;  frame < 3;  ++frame) {
  515.                     notinexon[otherstrand][frame][i] = i;
  516.                 }
  517.             }
  518.             if (strand == Plus) {
  519.                 a += 3;
  520.             }    // start now is a part of intergenic!!!!
  521.             else {
  522.                 b -= 3;
  523.             }
  524.             notining[b] = a;
  525.             if (algn.Type() == AlignVec::Prot) {
  526.                 for (int i = a;  i <= b;  ++i) {
  527.                     notining[i] = i;
  528.                 }
  529.             } else if (algn.CdsLimits().first >= 0) {
  530.                 for (int i = algn.CdsLimits().first;  i <= algn.CdsLimits().second;  ++i) notining[i] = i;
  531.             }
  532.         }
  533.     }
  534.     const int RepeatMargin = 15;
  535.     // repeat trimming
  536.     for (int i = 0;  i < len - 1;  ++i) {
  537.         bool rpta = laststop[Plus][0][i] < 0;
  538.         bool rptb = laststop[Plus][0][i + 1] < 0;
  539.         if ( !rpta  &&  rptb ) {
  540.             // b - first repeat
  541.             int j = i + 1;
  542.             for (;  j <= min(i + RepeatMargin,len - 1);  ++j) {
  543.                 laststop[Plus ][0][j] = -1;
  544.                 laststop[Plus ][1][j] = -1;
  545.                 laststop[Plus ][2][j] = -1;
  546.                 laststop[Minus][0][j] = -1;
  547.                 laststop[Minus][1][j] = -1;
  548.                 laststop[Minus][2][j] = -1;
  549.             }
  550.             i = j - 1;
  551.         } else if (rpta  &&  !rptb) {
  552.             // a - last repeat
  553.             int j = max(0,i - RepeatMargin + 1);
  554.             for (;  j <= i;  ++j) {
  555.                 laststop[Plus ][0][j] = -1;
  556.                 laststop[Plus ][1][j] = -1;
  557.                 laststop[Plus ][2][j] = -1;
  558.                 laststop[Minus][0][j] = -1;
  559.                 laststop[Minus][1][j] = -1;
  560.                 laststop[Minus][2][j] = -1;
  561.             }
  562.         }
  563.     }
  564.     if (leftwall) {
  565.         notinintron[Plus][0] = notinintron[Minus][0] = 0;
  566.     }
  567.     if (rightwall) {
  568.         notinintron[Plus][len - 1] = notinintron[Minus][len - 1] = len - 1;
  569.     }
  570.     for (int strand = 0;  strand < 2;  ++strand) {
  571.         IVec& nin = notinintron[strand];
  572.         for (int i = 1;  i < len;  ++i) {
  573.             nin[i] = max(nin[i - 1],nin[i]);
  574.         }
  575.         for (int frame = 0;  frame < 3;  ++frame) {
  576.             IVec& nex = notinexon[strand][frame];
  577.             for (int i = 1;  i < len;  ++i) {
  578.                 nex[i] = max(nex[i - 1],nex[i]);
  579.             } 
  580.         }
  581.     }
  582.     for (int i = 1;  i < len;  ++i) {
  583.         notining[i] = max(notining[i - 1],notining[i]);
  584.     }
  585.     const int stpT = 1, stpTA = 2, stpTG = 4;
  586.     for (int strand = 0;  strand < 2;  ++strand) {
  587.         IVec& s = seq[strand];
  588.         anum[strand] = 0;
  589.         dnum[strand] = 0;
  590.         sttnum[strand] = 0;
  591.         stpnum[strand] = 0;
  592.         if (strand == Plus) {
  593.             for (int i = 0;  i < len;  ++i) {
  594.                 ascr[strand][i] = max(ascr[strand][i],acceptor.Score(s,i));
  595.                 if (ascr[strand][i] != BadScore) {
  596.                     if (s[i + 1] == nA  &&  s[i + 2] == nA) {
  597.                         asplit[strand][0][i] |= stpT;
  598.                     }
  599.                     if (s[i + 1] == nA  &&  s[i + 2] == nG) {
  600.                         asplit[strand][0][i] |= stpT;
  601.                     } 
  602.                     if (s[i + 1] == nG  &&  s[i + 2] == nA) {
  603.                         asplit[strand][0][i] |= stpT;
  604.                     }
  605.                     if (s[i + 1] == nA) {
  606.                         asplit[strand][1][i] |= stpTA|stpTG;
  607.                     }
  608.                     if (s[i + 1] == nG) {
  609.                         asplit[strand][1][i] |= stpTA;
  610.                     }
  611.                 }
  612.                 dscr[strand][i] = max(dscr[strand][i],donor.Score(s,i));
  613.                 if (dscr[strand][i] != BadScore) {
  614.                     if (s[i] == nT) {
  615.                         dsplit[strand][0][i] |= stpT;
  616.                     }
  617.                     if (s[i - 1] == nT  &&  s[i] == nA) {
  618.                         dsplit[strand][1][i] |= stpTA;
  619.                     }
  620.                     if (s[i - 1] == nT  &&  s[i] == nG) {
  621.                         dsplit[strand][1][i] |= stpTG;
  622.                     }
  623.                 }
  624.                 sttscr[strand][i] = start.Score(s,i);
  625.                 stpscr[strand][i] = stop.Score(s,i);
  626.                 if (ascr[strand][i] != BadScore) {
  627.                     ++anum[strand];
  628.                 }
  629.                 if (dscr[strand][i] != BadScore) {
  630.                     ++dnum[strand];
  631.                 }
  632.                 if (sttscr[strand][i] != BadScore) {
  633.                     ++sttnum[strand];
  634.                 }
  635.             }
  636.         } else {
  637.             for (int i = 0;  i < len;  ++i) {
  638.                 int ii = len - 2-i;   // extra -1 because ii is point on the "right"
  639.                 ascr[strand][i] = max(ascr[strand][i],acceptor.Score(s,ii));
  640.                 if (ascr[strand][i] != BadScore) {
  641.                     if (s[ii + 1] == nA  &&  s[ii + 2] == nA) {
  642.                         asplit[strand][0][i] |= stpT;
  643.                     }
  644.                     if (s[ii + 1] == nA  &&  s[ii + 2] == nG) {
  645.                         asplit[strand][0][i] |= stpT;
  646.                     } 
  647.                     if (s[ii + 1] == nG  &&  s[ii + 2] == nA) {
  648.                         asplit[strand][0][i] |= stpT;
  649.                     }
  650.                     if (s[ii + 1] == nA) {
  651.                         asplit[strand][1][i] |= stpTA|stpTG;
  652.                     }
  653.                     if (s[ii + 1] == nG) {
  654.                         asplit[strand][1][i] |= stpTA;
  655.                     }
  656.                 }
  657.                 dscr[strand][i] = max(dscr[strand][i],donor.Score(s,ii));
  658.                 if (dscr[strand][i] != BadScore) {
  659.                     if (s[ii] == nT) {
  660.                         dsplit[strand][0][i] |= stpT;
  661.                     }
  662.                     if (s[ii - 1] == nT  &&  s[ii] == nA) {
  663.                         dsplit[strand][1][i] |= stpTA;
  664.                     }
  665.                     if (s[ii - 1] == nT  &&  s[ii] == nG) {
  666.                         dsplit[strand][1][i] |= stpTG;
  667.                     }
  668.                 }
  669.                 sttscr[strand][i] = start.Score(s,ii);
  670.                 stpscr[strand][i] = stop.Score(s,ii);
  671.                 if (ascr[strand][i] != BadScore) {
  672.                     ++anum[strand];
  673.                 }
  674.                 if (dscr[strand][i] != BadScore) {
  675.                     ++dnum[strand];
  676.                 }
  677.             }
  678.         }
  679.     }       
  680.     for (CClusterSet::ConstIt it_cls = cls_local.begin();  it_cls != cls_local.end();  ++it_cls) {
  681.         for (CCluster::ConstIt it = it_cls->begin();  it != it_cls->end();  ++it) {
  682.             const AlignVec& algn = *it;
  683.             int strand = algn.Strand();
  684.             int type = algn.Type();
  685.             if (type != AlignVec::Prot) {
  686.                 IVec& s = seq[Plus];
  687.                 IVec mRNA;
  688.                 for (int k = 0;  k < algn.size();  ++k) {
  689.                     int exona = algn[k].first;
  690.                     int exonb = algn[k].second;
  691.                     copy(&s[exona],&s[exonb]+1,back_inserter(mRNA));
  692.                 }
  693.                 if (strand == Plus) {
  694.                     int shft = algn.front().first;
  695.                     for (int k = 0;  k < algn.size() - 1;  ++k) {
  696.                         int exonb = algn[k].second;
  697.                         for (int i = max(0,exonb - 2);  i <= exonb;  ++i)    // if i == exonb, the stop is in the next "exon"
  698.                         {
  699.                             stpscr[strand][i] = stop.Score(mRNA,i - shft);
  700.                         }
  701.                         int exona = algn[k + 1].first;   //next exon
  702.                         shft += exona - exonb - 1;         //intron length
  703.                         for (int i = exona - 1;  i <= min(len - 1,exona + 1);  ++i) {
  704.                             sttscr[strand][i] = start.Score(mRNA,i - shft);
  705.                         }
  706.                     }
  707.                 } else {
  708.                     reverse(mRNA.begin(),mRNA.end());
  709.                     for (int i = 0;  i < mRNA.size();  ++i) mRNA[i] = toMinus[mRNA[i]];
  710.                     int shft = algn.back().second - 1;
  711.                     for (int k = algn.size() - 1;  k > 0;  --k) {
  712.                         int exona = algn[k].first;
  713.                         for (int i = exona - 1;  i <= min(len - 1,exona + 1);  ++i) {
  714.                             stpscr[strand][i] = stop.Score(mRNA,shft - i);
  715.                         }
  716.                         int exonb = algn[k - 1].second;  //prev exon
  717.                         shft -= exona - exonb - 1;         //intron length
  718.                         for (int i = max(0,exonb - 2);  i <= exonb;  ++i) {
  719.                             sttscr[strand][i] = start.Score(mRNA,shft - i);
  720.                         }
  721.                     }
  722.                 }
  723.             }
  724.         }
  725.     }
  726.     for (CClusterSet::ConstIt it_cls = cls_local.begin();  it_cls != cls_local.end();  ++it_cls) {
  727.         for (CCluster::ConstIt it = it_cls->begin();  it != it_cls->end();  ++it) {
  728.             const AlignVec& algn = *it;
  729.             int strand = algn.Strand();
  730.             int type = algn.Type();
  731.             if (type == AlignVec::Prot) {
  732.                 for (int k = 0;  k < algn.size();  ++k)   // suppressing STOPS in prot align
  733.                 {
  734.                     int exona = algn[k].first;
  735.                     int exonb = algn[k].second;
  736.                     for (int i = exona;  i < exonb;  i += 3) {
  737.                         if (strand == Plus) {
  738.                             if (i > 0) {
  739.                                 stpscr[strand][i - 1] = BadScore;
  740.                             }  // score on last coding base
  741.                         } else {
  742.                             if (i + 2 < len - 1) {
  743.                                 stpscr[strand][i + 2] = BadScore;
  744.                             }  // score on last intergenic(first stop) base
  745.                         }
  746.                     }
  747.                 }
  748.             }
  749.         }
  750.     }
  751.     for (int strand = 0;  strand < 2;  ++strand) {
  752.         for (int i = 0;  i < len;  ++i) {
  753.             if (sttscr[strand][i] != BadScore) {
  754.                 ++sttnum[strand];
  755.             }
  756.             if (stpscr[strand][i] != BadScore) {
  757.                 if (strand == Plus)
  758.                 {
  759.                     int& lstp = laststop[strand][2 - i%3][i + 3];
  760.                     lstp = max(i + 1,lstp);
  761.                     ++stpnum[strand];
  762.                 } else {
  763.                     int& lstp = laststop[strand][i%3][i];
  764.                     lstp = max(i - 2,lstp);
  765.                     ++stpnum[strand];
  766.                 }
  767.             }
  768.         }
  769.     }
  770.     for (int strand = 0;  strand < 2;  ++strand) {
  771.         IVec& s = seq[strand];
  772.         for (int i = 0;  i < len;  ++i) {
  773.             int ii = strand == Plus ? i : len - 1-i;
  774.             double score = ncdr.Score(s,ii);
  775.             if (score == BadScore) {
  776.                 score = 0;
  777.             }
  778.             ncdrscr[strand][i] = score;
  779.             if (i > 0) {
  780.                 ncdrscr[strand][i] += ncdrscr[strand][i - 1];
  781.             }
  782.             score = intrg.Score(s,ii);
  783.             if (score == BadScore) {
  784.                 score = 0;
  785.             }
  786.             ingscr[strand][i] = score;
  787.             if (i > 0) {
  788.                 ingscr[strand][i] += ingscr[strand][i - 1];
  789.             }
  790.         }
  791.         for (int frame = 0;  frame < 3;  ++frame) {
  792.             for (int i = 0;  i < len;  ++i)
  793.             {
  794.                 int codonshift,ii;
  795.                 if (strand == Plus) {
  796.                     // left end of codon is shifted by frame bases to left
  797.                     codonshift = (frame + i)%3;
  798.                     ii = i;
  799.                 } else {
  800.                     // right end of codon is shifted by frame bases to right
  801.                     codonshift = (frame - i)%3;
  802.                     if (codonshift < 0) {
  803.                         codonshift += 3;
  804.                     }
  805.                     ii = len - 1-i;
  806.                 }
  807.                 double score = cdr.Score(s,ii,codonshift);
  808.                 if (score == BadScore) {
  809.                     score = 0;
  810.                 }
  811.                 cdrscr[strand][frame][i] = score;
  812.                 if (i > 0) {
  813.                     cdrscr[strand][frame][i] += cdrscr[strand][frame][i - 1];
  814.                     IVec& lstp = laststop[strand][frame];
  815.                     lstp[i] = max(lstp[i - 1],lstp[i]);
  816.                 }
  817.             }
  818.         }
  819.     }
  820.     for (int strand = 0;  strand < 2;  ++strand) {
  821.         for (int frame = 0;  frame < 3;  ++frame) {
  822.             for (int i = 0;  i < len;  ++i) {
  823.                 cdrscr[strand][frame][i] -= ncdrscr[strand][i];
  824.             }
  825.         }
  826.         for (int i = 0;  i < len;  ++i) {
  827.             ingscr[strand][i] -= ncdrscr[strand][i];
  828.             int left, right;
  829.             if (dscr[strand][i] != BadScore) {
  830.                 Terminal& t = donor;
  831.                 left = i + 1-(strand == Plus ? t.Left():t.Right());
  832.                 right = i + (strand == Plus ? t.Right():t.Left());
  833.                 dscr[strand][i] -= NonCodingScore(left,right,strand);
  834.             }
  835.             if (ascr[strand][i] != BadScore) {
  836.                 Terminal& t = acceptor;
  837.                 left = i + 1-(strand == Plus ? t.Left():t.Right());
  838.                 right = i + (strand == Plus ? t.Right():t.Left());
  839.                 ascr[strand][i] -= NonCodingScore(left,right,strand);
  840.             }
  841.             if (sttscr[strand][i] != BadScore) {
  842.                 Terminal& t = start;
  843.                 left = i + 1-(strand == Plus ? t.Left():t.Right());
  844.                 right = i + (strand == Plus ? t.Right():t.Left());
  845.                 sttscr[strand][i] -= NonCodingScore(left,right,strand);
  846.             }
  847.             if (stpscr[strand][i] != BadScore) {
  848.                 Terminal& t = stop;
  849.                 left = i + 1-(strand == Plus ? t.Left():t.Right());
  850.                 right = i + (strand == Plus ? t.Right():t.Left());
  851.                 stpscr[strand][i] -= NonCodingScore(left,right,strand);
  852.             }
  853.         }
  854.     }
  855. }
  856. END_NCBI_SCOPE
  857. /*
  858.  * ===========================================================================
  859.  * $Log: models.cpp,v $
  860.  * Revision 1000.2  2004/06/01 18:08:35  gouriano
  861.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.3
  862.  *
  863.  * Revision 1.3  2004/05/21 21:41:03  gorelenk
  864.  * Added PCH ncbi_pch.hpp
  865.  *
  866.  * Revision 1.2  2003/11/06 00:52:38  ucko
  867.  * Don't try to take the log of an integer constant.
  868.  *
  869.  * Revision 1.1  2003/10/24 15:07:25  dicuccio
  870.  * Initial revision
  871.  *
  872.  * ===========================================================================
  873.  */