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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: orf.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 18:10:40  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.6
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: orf.cpp,v 1000.1 2004/06/01 18:10:40 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 <algo/sequence/orf.hpp>
  41. #include <objects/seqloc/Seq_interval.hpp>
  42. #include <objects/seqloc/Na_strand.hpp>
  43. #include <objects/seqfeat/Genetic_code_table.hpp>
  44. #include <objects/seq/seqport_util.hpp>
  45. #include <objects/general/Int_fuzz.hpp>
  46. #include <objects/seqfeat/Cdregion.hpp>
  47. #include <objects/seqfeat/Seq_feat.hpp>
  48. #include <objects/seq/Seq_annot.hpp>
  49. #include <algorithm>
  50. BEGIN_NCBI_SCOPE
  51. USING_SCOPE(objects);
  52. /// Find all ORFs in forward orientation with
  53. /// length in *base pairs* >= min_length_bp.
  54. /// seq must be in iupac.
  55. /// Returned range does not include the
  56. /// stop codon.
  57. template<class Seq>
  58. void x_FindForwardOrfs(const Seq& seq, COrf::TRangeVec& ranges,
  59.                        unsigned int min_length_bp = 3,
  60.                        int genetic_code = 1)
  61. {
  62.     vector<vector<TSeqPos> > stops;
  63.     stops.resize(3);
  64.     const objects::CTrans_table& tbl = 
  65.         objects::CGen_code_table::GetTransTable(genetic_code);
  66.     int state = 0;
  67.     for (unsigned int i = 0;  i < seq.size() - 2;  i += 3) {
  68.         for (int pos = 0;  pos < 3;  pos++) {
  69.             state = tbl.NextCodonState(state, seq[i + pos]);
  70.             if (tbl.IsOrfStop(state)) {
  71.                 stops[(i + pos - 2) % 3].push_back(i + pos - 2);
  72.             }
  73.         }
  74.     }
  75.     
  76.     TSeqPos from, to;
  77.     // for each reading frame, calculate the orfs
  78.     for (int frame = 0;  frame < 3;  frame++) {
  79.         if (stops[frame].empty()) {
  80.             // no stops in this frame; the whole sequence,
  81.             // minus some scraps at the ends, is one ORF
  82.             from = frame;
  83.             // 'to' should be the largest index within the
  84.             // sequence length that gives an ORF length
  85.             // divisible by 3
  86.             to = ((seq.size() - from) / 3) * 3 + from - 1;
  87.             if (to - from + 1 >= min_length_bp) {
  88.                 ranges.push_back(COrf::TRange(from, to));
  89.             }
  90.             continue;  // we're done for this reading frame
  91.         }
  92.     
  93.         // deal specially with first ORF
  94.         from = frame;
  95.         to = stops[frame].front() - 1;
  96.         if (to - from + 1 >= min_length_bp) {
  97.             ranges.push_back(COrf::TRange(from, to));
  98.         }
  99.         for (unsigned int i = 0;  i < stops[frame].size() - 1;  i++) {
  100.             from = stops[frame][i] + 3;
  101.             to = stops[frame][i + 1] - 1;
  102.             if (to - from + 1 >= min_length_bp) {
  103.                 ranges.push_back(COrf::TRange(from, to));
  104.             }
  105.         }
  106.     
  107.         // deal specially with last ORF
  108.         from = stops[frame].back() + 3;
  109.         // 'to' should be the largest index within the
  110.         // sequence length that gives an orf length
  111.         // divisible by 3
  112.         to = ((seq.size() - from) / 3) * 3 + from - 1;
  113.         if (to - from + 1 >= min_length_bp) {
  114.             ranges.push_back(COrf::TRange(from, to));
  115.         }
  116.     }
  117. }
  118. /// Find all ORFs in both orientations that
  119. /// are at least min_length_bp long (not including the stop).
  120. /// Report results as Seq-locs.
  121. /// seq must be in iupac.
  122. template<class Seq>
  123. void x_FindOrfs(const Seq& seq, COrf::TLocVec& results,
  124.                 unsigned int min_length_bp = 3,
  125.                 int genetic_code = 1)
  126. {
  127.     COrf::TRangeVec ranges;
  128.     // This code might be sped up by a factor of two
  129.     // by use of a state machine that does all six frames
  130.     // in a single pass.
  131.     // find ORFs on the forward sequence and report them as-is
  132.     x_FindForwardOrfs(seq, ranges, min_length_bp, genetic_code);
  133.     ITERATE (COrf::TRangeVec, iter, ranges) {
  134.         CRef<objects::CSeq_loc> orf(new objects::CSeq_loc());
  135.         orf->SetInt().SetFrom(iter->GetFrom());
  136.         if (iter->GetFrom() < 3) {
  137.             // "beginning" of ORF at beginning of sequence
  138.             orf->SetInt().SetFuzz_from().SetLim(objects::CInt_fuzz::eLim_lt);
  139.         }
  140.         unsigned int to = iter->GetTo();
  141.         if (to + 3 >= seq.size()) {
  142.             // "end" of ORF is really end of sequence
  143.             orf->SetInt().SetFuzz_to().SetLim(objects::CInt_fuzz::eLim_gt);
  144.         } else {
  145.             // ORF was ended by a stop, rather than end of sequence
  146.             to += 3;
  147.         }
  148.         orf->SetInt().SetTo(to);
  149.         orf->SetInt().SetStrand(objects::eNa_strand_plus);
  150.         results.push_back(orf);
  151.     }
  152.     // find ORFs on the complement and munge the numbers
  153.     ranges.clear();
  154.     Seq comp(seq);
  155.     // compute the complement;
  156.     // this should be replaced with new Seqport_util call
  157.     reverse(comp.begin(), comp.end());
  158.     NON_CONST_ITERATE (typename Seq, i, comp) {
  159.         *i = objects::CSeqportUtil
  160.             ::GetIndexComplement(objects::eSeq_code_type_iupacna, *i);
  161.     }
  162.     x_FindForwardOrfs(comp, ranges, min_length_bp, genetic_code);
  163.     ITERATE (COrf::TRangeVec, iter, ranges) {
  164.         CRef<objects::CSeq_loc> orf(new objects::CSeq_loc);
  165.         unsigned int from = comp.size() - iter->GetTo() - 1;
  166.         if (from < 3) {
  167.             // "end" of ORF is beginning of sequence
  168.             orf->SetInt().SetFuzz_from().SetLim(objects::CInt_fuzz::eLim_lt);
  169.         } else {
  170.             // ORF was ended by a stop, rather than beginning of sequence
  171.             from -= 3;
  172.         }
  173.         orf->SetInt().SetFrom(from);
  174.         unsigned int to = comp.size() - iter->GetFrom() - 1;
  175.         if (to + 3 >= comp.size()) {
  176.             // "beginning" of ORF is really end of sequence
  177.             orf->SetInt().SetFuzz_to().SetLim(objects::CInt_fuzz::eLim_gt);
  178.         }
  179.         orf->SetInt().SetTo(to);
  180.         orf->SetInt().SetStrand(objects::eNa_strand_minus);
  181.         results.push_back(orf);
  182.     }
  183. }
  184. //
  185. // find ORFs in a string
  186. void COrf::FindOrfs(const string& seq_iupac,
  187.                     TLocVec& results,
  188.                     unsigned int min_length_bp,
  189.                     int genetic_code)
  190. {
  191.     x_FindOrfs(seq_iupac, results, min_length_bp, genetic_code);
  192. }
  193. //
  194. // find ORFs in a vector<char>
  195. void COrf::FindOrfs(const vector<char>& seq_iupac,
  196.                     TLocVec& results,
  197.                     unsigned int min_length_bp,
  198.                     int genetic_code)
  199. {
  200.     x_FindOrfs(seq_iupac, results, min_length_bp, genetic_code);
  201. }
  202. //
  203. // find ORFs in a CSeqVector
  204. void COrf::FindOrfs(const CSeqVector& orig_vec,
  205.                     TLocVec& results,
  206.                     unsigned int min_length_bp,
  207.                     int genetic_code)
  208. {
  209.     string seq_iupac;  // will contain ncbi8na
  210.     CSeqVector vec(orig_vec);
  211.     vec.SetCoding(CSeq_data::e_Iupacna);
  212.     vec.GetSeqData(0, vec.size(), seq_iupac);
  213.     x_FindOrfs(seq_iupac, results, min_length_bp, genetic_code);
  214. }
  215. // build an annot representing CDSs
  216. CRef<CSeq_annot>
  217. COrf::MakeCDSAnnot(const TLocVec& orfs, int genetic_code, CSeq_id* id)
  218. {
  219.     CRef<CSeq_annot> annot(new CSeq_annot());
  220.     ITERATE (TLocVec, orf, orfs) {
  221.         // create feature
  222.         CRef<CSeq_feat> feat(new CSeq_feat());
  223.         // confess the fact that it's just a computed ORF
  224.         feat->SetExp_ev(CSeq_feat::eExp_ev_not_experimental);
  225.         feat->SetData().SetCdregion().SetOrf(true);  // just an ORF
  226.         // they're all frame 1 in this sense of 'frame'
  227.         feat->SetData().SetCdregion().SetFrame(CCdregion::eFrame_one);
  228.         feat->SetTitle("Open reading frame");
  229.         // set up the location
  230.         feat->SetLocation(const_cast<CSeq_loc&>(**orf));
  231.         if (id) {
  232.             feat->SetLocation().SetId(*id);
  233.         }
  234.         // save in annot
  235.         annot->SetData().SetFtable().push_back(feat);
  236.     }
  237.     return annot;
  238. }
  239. END_NCBI_SCOPE
  240. /*
  241.  * ===========================================================================
  242.  * $Log: orf.cpp,v $
  243.  * Revision 1000.1  2004/06/01 18:10:40  gouriano
  244.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.6
  245.  *
  246.  * Revision 1.6  2004/05/21 21:41:04  gorelenk
  247.  * Added PCH ncbi_pch.hpp
  248.  *
  249.  * Revision 1.5  2003/10/15 20:25:05  dicuccio
  250.  * Fixed access of seq-loc - don't assume interval...
  251.  *
  252.  * Revision 1.4  2003/09/04 21:10:42  ucko
  253.  * MakeCDSAnnot: remove redundant (and illegal) default for id.
  254.  *
  255.  * Revision 1.3  2003/09/04 19:27:53  jcherry
  256.  * Made an ORF include the stop codon, and marked certain ORFs as
  257.  * partial.  Put ability to construct a feature table into COrf.
  258.  *
  259.  * Revision 1.2  2003/08/21 13:39:53  dicuccio
  260.  * Fixed compilation error - dependent type 'Seq' must be a typename
  261.  *
  262.  * Revision 1.1  2003/08/21 12:00:53  dicuccio
  263.  * Added private implementation file for COrf
  264.  *
  265.  * ===========================================================================
  266.  */