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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: aln_reader.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:46:14  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.10
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: aln_reader.cpp,v 1000.1 2004/06/01 19:46:14 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:  Josh Cherry
  35.  *
  36.  * File Description:  C++ wrappers for alignment file reading
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <objtools/readers/aln_reader.hpp>
  41. #include <objtools/readers/reader_exception.hpp>
  42. #include <util/creaders/alnread.h>
  43. #include <util/format_guess.hpp>
  44. #include <objects/seqalign/Dense_seg.hpp>
  45. #include <objects/seqloc/Seq_id.hpp>
  46. #include <objects/general/Object_id.hpp>
  47. #include <objects/seq/Seq_annot.hpp>
  48. #include <objects/seq/Seq_inst.hpp>
  49. #include <objects/seqset/Bioseq_set.hpp>
  50. #include <objects/seq/Seq_data.hpp>
  51. #include <objects/seq/IUPACna.hpp>
  52. #include <objects/seq/IUPACaa.hpp>
  53. #include <objects/seq/Bioseq.hpp>
  54. #include <objects/seq/seqport_util.hpp>
  55. BEGIN_NCBI_SCOPE
  56. USING_SCOPE(objects);
  57. static char * ALIGNMENT_CALLBACK s_ReadLine(void *user_data)
  58. {
  59.     CNcbiIstream *is = static_cast<CNcbiIstream *>(user_data);
  60.     if (!*is) {
  61.         return 0;
  62.     }
  63.     string s;
  64.     NcbiGetlineEOL(*is, s);
  65.     return strdup(s.c_str());
  66. }
  67. static void ALIGNMENT_CALLBACK s_ReportError(TErrorInfoPtr err_ptr,
  68.                                              void *user_data)
  69. {
  70.     if (err_ptr->category != eAlnErr_Fatal) {
  71.         // ignore non-fatal errors
  72.         return;
  73.     }
  74.     string msg = "Error reading alignment file";
  75.     if (err_ptr->line_num > -1) {
  76.         msg += " at line " + NStr::IntToString(err_ptr->line_num);
  77.     }
  78.     if (err_ptr->message) {
  79.         msg += ":  ";
  80.         msg += err_ptr->message;
  81.     }
  82.     LOG_POST(Error << msg);
  83. }
  84. CAlnReader::~CAlnReader()
  85. {
  86. }
  87. void CAlnReader::Read()
  88. {
  89.     if (m_ReadDone) {
  90.         return;
  91.     }
  92.     // make a SSequenceInfo corresponding to our CSequenceInfo argument
  93.     SSequenceInfo info;
  94.     info.alphabet      = const_cast<char *>(m_Alphabet.c_str());
  95.     info.beginning_gap = const_cast<char *>(m_BeginningGap.c_str());
  96.     info.end_gap       = const_cast<char *>(m_EndGap.c_str());;
  97.     info.middle_gap    = const_cast<char *>(m_MiddleGap.c_str());
  98.     info.missing       = const_cast<char *>(m_Missing.c_str());
  99.     info.match         = const_cast<char *>(m_Match.c_str());
  100.     // read the alignment stream
  101.     TAlignmentFilePtr afp;
  102.     afp = ReadAlignmentFile(s_ReadLine, (void *) &m_IS,
  103.                             s_ReportError, 0, &info);
  104.     if (!afp) {
  105.         NCBI_THROW2(CObjReaderParseException, eFormat,
  106.                    "Error reading alignment", 0);
  107.     }
  108.     // build the CAlignment
  109.     m_Seqs.resize(afp->num_sequences);
  110.     m_Ids.resize(afp->num_sequences);
  111.     for (int i = 0;  i < afp->num_sequences;  ++i) {
  112.         m_Seqs[i] = NStr::ToUpper(afp->sequences[i]);
  113.         m_Ids[i] = afp->ids[i];
  114.     }
  115.     m_Organisms.resize(afp->num_organisms);
  116.     for (int i = 0;  i < afp->num_organisms;  ++i) {
  117.         if (afp->organisms[i]) {
  118.             m_Organisms[i] = afp->organisms[i];
  119.         } else {
  120.             m_Organisms[i].erase();
  121.         }
  122.     }
  123.     m_Deflines.resize(afp->num_deflines);
  124.     for (int i = 0;  i < afp->num_deflines;  ++i) {
  125.         if (afp->deflines[i]) {
  126.             m_Deflines[i] = afp->deflines[i];
  127.         } else {
  128.             m_Deflines[i].erase();
  129.         }
  130.     }
  131.     AlignmentFileFree(afp);
  132.     {{
  133.         m_Dim = m_Ids.size();
  134.     }}
  135.     m_ReadDone = true;
  136.     return;
  137. }
  138. void CAlnReader::SetClustal(EAlphabet alpha)
  139. {
  140.     SetAlphabet(alpha);
  141.     SetAllGap("-");
  142. }
  143. void CAlnReader::SetPaup(EAlphabet alpha)
  144. {
  145.     SetAlphabet(alpha);
  146.     SetAllGap("-");
  147. }
  148. void CAlnReader::SetPhylip(EAlphabet alpha)
  149. {
  150.     SetAlphabet(alpha);
  151.     SetAllGap("-");
  152. }
  153. CRef<CSeq_align> CAlnReader::GetSeqAlign()
  154. {
  155.     if (m_Aln) {
  156.         return m_Aln;
  157.     } else if ( !m_ReadDone ) {
  158.         NCBI_THROW2(CObjReaderParseException, eFormat,
  159.                    "CAlnReader::GetSeqAlign(): "
  160.                    "Seq_align is not available until after Read()", 0);
  161.     }
  162.     typedef CDense_seg::TNumseg TNumseg;
  163.     typedef CDense_seg::TDim TNumrow;
  164.     m_Aln = new CSeq_align();
  165.     m_Aln->SetType(CSeq_align::eType_not_set);
  166.     m_Aln->SetDim(m_Dim);
  167.     CDense_seg& ds = m_Aln->SetSegs().SetDenseg();
  168.     ds.SetDim(m_Dim);
  169.     
  170.     CDense_seg::TIds&     ids     = ds.SetIds();
  171.     CDense_seg::TStarts&  starts  = ds.SetStarts();
  172.     //CDense_seg::TStrands& strands = ds.SetStrands();
  173.     CDense_seg::TLens&    lens    = ds.SetLens();
  174.     ids.resize(m_Dim);
  175.     // get the length of the aln row, asuming all rows are the same
  176.     TSeqPos aln_stop = m_Seqs[0].size(); 
  177.     for (TNumrow row_i = 0; row_i < m_Dim; row_i++) {
  178.         CRef<CSeq_id> seq_id(new CSeq_id(m_Ids[row_i]));
  179.         if (seq_id->Which() == CSeq_id::e_not_set) {
  180.             seq_id->SetLocal().SetStr(m_Ids[row_i]);
  181.         }
  182.         ids[row_i] = seq_id;
  183.     }
  184.     m_SeqVec.resize(m_Dim);
  185.     for (TNumrow row_i = 0; row_i < m_Dim; row_i++) {
  186.         m_SeqVec[row_i].resize(aln_stop, 0); // size unknown, resize to max
  187.     }
  188.     m_SeqLen.resize(m_Dim, 0);
  189.     vector<bool> is_gap;  is_gap.resize(m_Dim, true);
  190.     vector<bool> prev_is_gap;  prev_is_gap.resize(m_Dim, true);
  191.     vector<TSignedSeqPos> next_start; next_start.resize(m_Dim, 0);
  192.     int starts_i = 0;
  193.     TSeqPos prev_aln_pos = 0, prev_len = 0;
  194.     bool new_seg = false;
  195.     TNumseg numseg = 0;
  196.     
  197.     for (TSeqPos aln_pos = 0; aln_pos < aln_stop; aln_pos++) {
  198.         for (TNumrow row_i = 0; row_i < m_Dim; row_i++) {
  199.             const char& residue = m_Seqs[row_i][aln_pos];
  200.             if (residue != m_MiddleGap[0]  &&
  201.                 residue != m_EndGap[0]  &&
  202.                 residue != m_Missing[0]) {
  203.                 if (is_gap[row_i]) {
  204.                     is_gap[row_i] = false;
  205.                     new_seg = true;
  206.                 }
  207.                 // add to the sequence vector
  208.                 m_SeqVec[row_i][m_SeqLen[row_i]++] = residue;
  209.             } else {
  210.                 if ( !is_gap[row_i] ) {
  211.                     is_gap[row_i] = true;
  212.                     new_seg = true;
  213.                 }
  214.             }
  215.         }
  216.         if (new_seg) {
  217.             numseg++;
  218.             if (aln_pos) { // if not the first seg
  219.                 lens.push_back(prev_len = aln_pos - prev_aln_pos);
  220.                 for (TNumrow row_i = 0; row_i < m_Dim; row_i++) {
  221.                     if ( !prev_is_gap[row_i] ) {
  222.                         next_start[row_i] += prev_len;
  223.                     }
  224.                 }
  225.             }
  226.             starts.resize(starts_i + m_Dim);
  227.             for (TNumrow row_i = 0; row_i < m_Dim; row_i++) {
  228.                 if (is_gap[row_i]) {
  229.                     starts[starts_i++] = -1;
  230.                 } else {
  231.                     starts[starts_i++] = next_start[row_i];;
  232.                 }
  233.                 prev_is_gap[row_i] = is_gap[row_i];
  234.             }
  235.             prev_aln_pos = aln_pos;
  236.             new_seg = false;
  237.         }
  238.     }
  239.     for (TNumrow row_i = 0; row_i < m_Dim; row_i++) {
  240.         m_SeqVec[row_i].resize(m_SeqLen[row_i]); // resize down to actual size
  241.     }
  242.     lens.push_back(aln_stop - prev_aln_pos);
  243.     //strands.resize(numseg * m_Dim, eNa_strand_plus);
  244.     _ASSERT(lens.size() == numseg);
  245.     ds.SetNumseg(numseg);
  246. #if _DEBUG
  247.     m_Aln->Validate(true);
  248. #endif    
  249.     return m_Aln;
  250. }
  251. CRef<CSeq_entry> CAlnReader::GetSeqEntry()
  252. {
  253.     if (m_Entry) {
  254.         return m_Entry;
  255.     } else if ( !m_ReadDone ) {
  256.         NCBI_THROW2(CObjReaderParseException, eFormat,
  257.                    "CAlnReader::GetSeqEntry(): "
  258.                    "Seq_entry is not available until after Read()", 0);
  259.     }
  260.     m_Entry = new CSeq_entry();
  261.     CRef<CSeq_annot> seq_annot (new CSeq_annot);
  262.     seq_annot->SetData().SetAlign().push_back(GetSeqAlign());
  263.     m_Entry->SetSet().SetClass(CBioseq_set::eClass_pop_set);
  264.     m_Entry->SetSet().SetAnnot().push_back(seq_annot);
  265.     CBioseq_set::TSeq_set& seq_set = m_Entry->SetSet().SetSeq_set();
  266.     typedef CDense_seg::TDim TNumrow;
  267.     for (TNumrow row_i = 0; row_i < m_Dim; row_i++) {
  268.         const string& seq_str     = m_SeqVec[row_i];
  269.         const size_t& seq_str_len = seq_str.size();
  270.         CRef<CSeq_entry> seq_entry (new CSeq_entry);
  271.         // seq-id
  272.         CRef<CSeq_id> seq_id(new CSeq_id(m_Ids[row_i]));
  273.         seq_entry->SetSeq().SetId().push_back(seq_id);
  274.         if (seq_id->Which() == CSeq_id::e_not_set) {
  275.             seq_id->SetLocal().SetStr(m_Ids[row_i]);
  276.         }
  277.         // mol
  278.         CSeq_inst::EMol mol   = CSeq_inst::eMol_not_set;
  279.         CSeq_id::EAccessionInfo ai = seq_id->IdentifyAccession();
  280.         if (ai & CSeq_id::fAcc_nuc) {
  281.             mol = CSeq_inst::eMol_na;
  282.         } else if (ai & CSeq_id::fAcc_prot) {
  283.             mol = CSeq_inst::eMol_aa;
  284.         } else {
  285.             switch (CFormatGuess::SequenceType(seq_str.data(), seq_str_len)) {
  286.             case CFormatGuess::eNucleotide:  mol = CSeq_inst::eMol_na;  break;
  287.             case CFormatGuess::eProtein:     mol = CSeq_inst::eMol_aa;  break;
  288.             default:                         break;
  289.             }
  290.         }
  291.         // seq-inst
  292.         CRef<CSeq_inst> seq_inst (new CSeq_inst);
  293.         seq_entry->SetSeq().SetInst(*seq_inst);
  294.         seq_set.push_back(seq_entry);
  295.         // repr
  296.         seq_inst->SetRepr(CSeq_inst::eRepr_raw);
  297.         // mol
  298.         seq_inst->SetMol(mol);
  299.         // len
  300.         _ASSERT(seq_str_len == m_SeqLen[row_i]);
  301.         seq_inst->SetLength(seq_str_len);
  302.         // data
  303.         CSeq_data& data = seq_inst->SetSeq_data();
  304.         if (mol == CSeq_inst::eMol_aa) {
  305.             data.SetIupacaa().Set(seq_str);
  306.         } else {
  307.             data.SetIupacna().Set(seq_str);
  308.             CSeqportUtil::Pack(&data);
  309.         }
  310.     }
  311.     
  312.     
  313.     return m_Entry;
  314. }
  315. END_NCBI_SCOPE
  316. /*
  317.  * ===========================================================================
  318.  * $Log: aln_reader.cpp,v $
  319.  * Revision 1000.1  2004/06/01 19:46:14  gouriano
  320.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.10
  321.  *
  322.  * Revision 1.10  2004/05/21 21:42:55  gorelenk
  323.  * Added PCH ncbi_pch.hpp
  324.  *
  325.  * Revision 1.9  2004/03/23 19:35:21  jcherry
  326.  * Set class to pop-set rather than nuc-prot
  327.  *
  328.  * Revision 1.8  2004/03/02 20:18:50  jcherry
  329.  * Don't throw in callback called by C code
  330.  *
  331.  * Revision 1.7  2004/03/01 15:26:33  dicuccio
  332.  * Code clean-up.  Added enum for standard alphabets.  Added new APIs to set
  333.  * standard parameters for other alignment types (implemented with unclear details
  334.  * currently).  Added better exception handling.
  335.  *
  336.  * Revision 1.6  2004/02/24 17:52:12  jcherry
  337.  * iupacaa for proteins
  338.  *
  339.  * Revision 1.5  2004/02/20 16:40:57  ucko
  340.  * Fix path to aln_reader.hpp again
  341.  *
  342.  * Revision 1.4  2004/02/20 16:21:09  todorov
  343.  * Better seq id; Try to id the mol type; Packed seq data;
  344.  * Fixed a couple of bugs in GetSeqAlign
  345.  *
  346.  * Revision 1.3  2004/02/20 01:21:35  ucko
  347.  * Again, erase() strings rather than clear()ing them for compatibility
  348.  * with G++ 2.95.  (The fix seems to have gotten lost in the recent
  349.  * move.)
  350.  *
  351.  * Revision 1.2  2004/02/19 18:38:13  ucko
  352.  * Update path to aln_reader.hpp.
  353.  *
  354.  * Revision 1.1  2004/02/19 16:54:59  todorov
  355.  * File moved from util/creaders and renamed to aln_reader
  356.  *
  357.  * Revision 1.4  2004/02/18 22:29:31  todorov
  358.  * Converted to single class. Added methods for creating Seq-align and Seq-entry. A working version, but still need to polish: seq-ids, na/aa recognition, etc.
  359.  *
  360.  * Revision 1.3  2004/02/11 17:58:12  gorelenk
  361.  * Added missed modificator ALIGNMENT_CALLBACK to definitions of s_ReadLine
  362.  * and ALIGNMENT_CALLBACK.
  363.  *
  364.  * Revision 1.2  2004/02/10 02:58:09  ucko
  365.  * erase() strings rather than clear()ing them for compatibility with G++ 2.95.
  366.  *
  367.  * Revision 1.1  2004/02/09 16:02:34  jcherry
  368.  * Initial versionnnn
  369.  *
  370.  * ===========================================================================
  371.  */