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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: splign_formatter.cpp,v $
  4.  * PRODUCTION Revision 1000.0  2004/06/01 18:12:43  gouriano
  5.  * PRODUCTION PRODUCTION: IMPORTED [GCC34_MSVC7] Dev-tree R1.6
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: splign_formatter.cpp,v 1000.0 2004/06/01 18:12:43 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:  Yuri Kapustin
  35.  *
  36.  * ===========================================================================
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include "splign_util.hpp"
  41. #include <objects/seqalign/Seq_align.hpp>
  42. #include <objects/seqloc/Seq_id.hpp>
  43. #include <algo/align/splign/splign_formatter.hpp>
  44. #include <objects/seqalign/Score.hpp>
  45. #include <objects/general/Object_id.hpp>
  46. #include <objects/seqalign/Dense_seg.hpp>
  47. BEGIN_NCBI_SCOPE
  48. USING_SCOPE(objects);
  49. CSplignFormatter::CSplignFormatter (const CSplign& splign):
  50.     m_splign(&splign)
  51. {
  52.     static const char kErrMsg[] = "ID_not_set";
  53.     m_QueryId = m_SubjId = kErrMsg;
  54. }
  55. string CSplignFormatter::AsText(void) const
  56. {
  57.   CNcbiOstrstream oss;
  58.   oss.precision(3);
  59.   const vector<CSplign::SAlignedCompartment>& acs = m_splign->GetResult();
  60.   ITERATE(vector<CSplign::SAlignedCompartment>, ii, acs) {
  61.     
  62.     for(size_t i = 0, seg_dim = ii->m_segments.size(); i < seg_dim; ++i) {
  63.       const CSplign::SSegment& seg = ii->m_segments[i];
  64.       oss << ii->m_id << 't' << m_QueryId << 't' << m_SubjId << 't';
  65.       if(seg.m_exon) {
  66.         oss << seg.m_idty << 't';
  67.       }
  68.       else {
  69.         oss << "-t";
  70.       }
  71.       
  72.       oss << seg.m_len << 't';
  73.       
  74.       if(ii->m_QueryStrand) {
  75.         oss << ii->m_qmin + seg.m_box[0] + 1 << 't'
  76.             << ii->m_qmin + seg.m_box[1] + 1 << 't';
  77.       }
  78.       else {
  79.         oss << ii->m_mrnasize - seg.m_box[0] << 't'
  80.             << ii->m_mrnasize - seg.m_box[1] << 't';
  81.       }
  82.       
  83.       if(seg.m_exon) {
  84.         
  85.         if(ii->m_SubjStrand) {
  86.           oss << ii->m_smin + seg.m_box[2] + 1 << 't' 
  87.               << ii->m_smin + seg.m_box[3] + 1 << 't';
  88.         }
  89.         else {
  90.           oss << ii->m_smax - seg.m_box[2] + 1 << 't' 
  91.               << ii->m_smax - seg.m_box[3] + 1 << 't';
  92.         }
  93.       }
  94.       else {
  95.         oss << "-t-t";
  96.       }
  97.       
  98.       if(seg.m_exon) {
  99.         
  100.         oss << seg.m_annot << 't';
  101.         oss << RLE(seg.m_details);
  102. #ifdef GENOME_PIPELINE
  103.         oss << 't' << ScoreByTranscript(*(m_splign->GetAligner()),
  104.                                          seg.m_details.c_str());
  105. #endif
  106.       }
  107.       else {
  108.         if(i == 0) {
  109.           oss << "<L-Gap>t";
  110.         }
  111.         else if(i == seg_dim - 1) {
  112.           oss << "<R-Gap>t";
  113.         }
  114.         else {
  115.           oss << "<M-Gap>t";
  116.         }
  117.         oss << '-';
  118. #ifdef GENOME_PIPELINE
  119.         oss << "t-";
  120. #endif
  121.       }
  122.       oss << endl;
  123.     }
  124.   }
  125.   return CNcbiOstrstreamToString(oss);
  126. }
  127. CRef<CSeq_align_set> CSplignFormatter::AsSeqAlignSet(void) const
  128. {
  129.     const vector<CSplign::SAlignedCompartment>& acs = m_splign->GetResult();
  130.     CRef<CSeq_align_set> rv (new CSeq_align_set);
  131.     CSeq_align_set::Tdata& data = rv->Set();
  132.     ITERATE(vector<CSplign::SAlignedCompartment>, ii, acs) {
  133.     
  134.         vector<size_t> boxes;
  135.         vector<string> transcripts;
  136.         vector<CNWAligner::TScore> scores;
  137.         for(size_t i = 0, seg_dim = ii->m_segments.size(); i < seg_dim; ++i) {
  138.             const CSplign::SSegment& seg = ii->m_segments[i];
  139.             if(seg.m_exon) {
  140.                 
  141.                 if(ii->m_QueryStrand) {
  142.                     boxes.push_back(ii->m_qmin + seg.m_box[0]);
  143.                     boxes.push_back(ii->m_qmin + seg.m_box[1]);
  144.                 }
  145.                 else {
  146.                     boxes.push_back(ii->m_mrnasize - seg.m_box[0] - 1);
  147.                     boxes.push_back(ii->m_mrnasize - seg.m_box[1] - 1);
  148.                 }
  149.                 if(ii->m_SubjStrand) {
  150.                     boxes.push_back(ii->m_smin + seg.m_box[2]);
  151.                     boxes.push_back(ii->m_smin + seg.m_box[3]);
  152.                 }
  153.                 else {
  154.                     boxes.push_back(ii->m_smax - seg.m_box[2]); 
  155.                     boxes.push_back(ii->m_smax - seg.m_box[3]);
  156.                 }
  157.                 transcripts.push_back(seg.m_details);
  158.                 scores.push_back(ScoreByTranscript(*(m_splign->GetAligner()),
  159.                                                    seg.m_details.c_str()));
  160.             }
  161.         }
  162.        
  163.         CRef<CSeq_align> sa (x_Compartment2SeqAlign(boxes,transcripts,scores));
  164.         data.push_back(sa);
  165.     }
  166.     
  167.     return rv;
  168. }
  169. CRef<CSeq_align> CSplignFormatter::x_Compartment2SeqAlign (
  170.     const vector<size_t>& boxes,
  171.     const vector<string>& transcripts,
  172.     const vector<int>&    scores ) const
  173. {
  174.     const size_t num_exons = boxes.size() / 4;
  175.     CRef<CSeq_align> sa (new CSeq_align);
  176.     sa->Reset();
  177.     // this is a discontinuous alignment
  178.     sa->SetType(CSeq_align::eType_disc);
  179.     sa->SetDim(2);
  180.   
  181.     // seq-ids
  182.     CRef<CSeq_id> id1 ( new CSeq_id (m_QueryId) );
  183.     if(id1->Which()==CSeq_id::e_not_set) {
  184.         id1.Reset(new CSeq_id(CSeq_id::e_Local, m_QueryId, kEmptyStr));
  185.     }
  186.     
  187.     CRef<CSeq_id> id2 ( new CSeq_id (m_SubjId) );
  188.     if(id2->Which()==CSeq_id::e_not_set) {
  189.         id2.Reset(new CSeq_id(CSeq_id::e_Local, m_SubjId, kEmptyStr));
  190.     }
  191.     // create seq-align-set
  192.     CRef< CSeq_align::C_Segs > segs (new CSeq_align::C_Segs);
  193.     CSeq_align_set& sas = segs->SetDisc();
  194.     list<CRef<CSeq_align> >& sas_data = sas.Set();
  195.     
  196.     for(size_t i = 0; i < num_exons; ++i) {
  197.       CRef<CSeq_align> sa (new CSeq_align);
  198.       sa->Reset();
  199.       sa->SetDim(2);
  200.       sa->SetType(CSeq_align::eType_global);
  201.       CRef<CScore> score (new CScore);
  202.       CRef<CObject_id> id (new CObject_id);
  203.       id->SetStr("splign");
  204.       score->SetId(*id);
  205.       CRef< CScore::C_Value > val (new CScore::C_Value);
  206.       val->SetInt(scores[i]);
  207.       score->SetValue(*val);
  208.       CSeq_align::TScore& scorelist = sa->SetScore();
  209.       scorelist.push_back(score);
  210.       CRef<CSeq_align::C_Segs> segs (new CSeq_align::C_Segs);
  211.       CDense_seg& ds = segs->SetDenseg();
  212.       ds.SetNumseg(0);
  213.       ds.SetDim(2);
  214.       vector< CRef< CSeq_id > > &ids = ds.SetIds();
  215.       ids.push_back(id1);
  216.       ids.push_back(id2);
  217.       const size_t* box = &(*(boxes.begin() + i*4));
  218.       x_Exon2DS(box, transcripts[i], &ds);
  219.       sa->SetSegs(*segs);
  220.       sas_data.push_back(sa);
  221.     }
  222.     
  223.     sa->SetSegs(*segs);
  224.     return sa;
  225. }
  226. void CSplignFormatter::x_Exon2DS(const size_t* box, const string& trans,
  227.                                  CDense_seg* pds ) const
  228. {
  229.     bool strand = box[2] <= box[3];
  230.     CDense_seg& ds = *pds;
  231.     vector< TSignedSeqPos > &starts  = ds.SetStarts();
  232.     vector< TSeqPos >       &lens    = ds.SetLens();
  233.     vector< ENa_strand >    &strands = ds.SetStrands();
  234.     
  235.     // iterate through the transcript
  236.     size_t seg_count = 0;
  237.     size_t start1 = 0, pos1 = 0; // relative to exon start in mrna
  238.     size_t start2 = 0, pos2 = 0; // and genomic
  239.     size_t seg_len = 0;
  240.     string::const_iterator ib = trans.begin(), ie = trans.end(), ii = ib;
  241.     unsigned char seg_type;
  242.     char c = *ii++;
  243.     if(c == 'M' || c == 'R') {
  244.       seg_type = 0; // matches and mismatches
  245.       ++pos1;
  246.       ++pos2;
  247.     }
  248.     else if (c == 'I') {
  249.       seg_type = 1;  // inserts
  250.       ++pos2;
  251.     }
  252.     else {
  253.       seg_type = 2;  // dels
  254.       ++pos1;
  255.     }
  256.     
  257.     while(ii < ie) {
  258.       c = *ii;
  259.       if(isalpha(c)) {
  260. if(seg_type == 0 && (c == 'M' || c == 'R')) {
  261.   ++pos1;
  262.   ++pos2;
  263.   ++ii;
  264. }
  265. else {
  266.   // close current seg
  267.   starts.push_back((seg_type == 1)? -1: TSignedSeqPos(box[0]+start1));
  268.   starts.push_back((seg_type == 2)? -1:
  269.                            TSignedSeqPos(box[2]+(strand?start2:(1-pos2))));
  270.   strands.push_back(eNa_strand_plus);
  271.   strands.push_back(strand? eNa_strand_plus: eNa_strand_minus);
  272.   switch(seg_type) {
  273.   case 0: seg_len = pos1 - start1; break;
  274.   case 1: seg_len = pos2 - start2; break;
  275.   case 2: seg_len = pos1 - start1; break;
  276.   }
  277.   lens.push_back(seg_len);
  278.   ++seg_count;
  279.   
  280.   // start a new seg
  281.   start1 = pos1;
  282.   start2 = pos2;
  283.   if(c == 'M' || c == 'R') {
  284.     seg_type = 0; // matches and mismatches
  285.     ++pos1;
  286.     ++pos2;
  287.   }
  288.   else if (c == 'I') {
  289.     seg_type = 1;  // inserts
  290.     ++pos2;
  291.   }
  292.   else {
  293.     seg_type = 2;  // dels
  294.     ++pos1;
  295.   }
  296.   ++ii;
  297. }
  298.       }
  299.       else {
  300. size_t len = 0;
  301. while(ii < ie && ('0' <= *ii && *ii <= '9')) {
  302.   len = 10*len + *ii - '0';
  303.   ++ii;
  304. }
  305. --len;
  306. switch(seg_type) {
  307. case 0: pos1 += len; pos2 += len; break;
  308. case 1: pos2 += len; break;
  309. case 2: pos1 += len; break;
  310. }
  311.       }
  312.     }
  313.     
  314.     starts.push_back( (seg_type == 1)? -1: TSignedSeqPos(box[0] + start1) );
  315.     starts.push_back( (seg_type == 2)? -1:
  316.       TSignedSeqPos(box[2] + (strand? start2: (1 - pos2))) );
  317.     strands.push_back(eNa_strand_plus);
  318.     strands.push_back(strand? eNa_strand_plus: eNa_strand_minus);
  319.     switch(seg_type) {
  320.     case 0: seg_len = pos1 - start1; break;
  321.     case 1: seg_len = pos2 - start2; break;
  322.     case 2: seg_len = pos1 - start1; break;
  323.     }
  324.     lens.push_back(seg_len);
  325.     ++seg_count;
  326.     ds.SetNumseg(seg_count);
  327. }
  328. END_NCBI_SCOPE
  329. /*
  330.  * ===========================================================================
  331.  *
  332.  * $Log: splign_formatter.cpp,v $
  333.  * Revision 1000.0  2004/06/01 18:12:43  gouriano
  334.  * PRODUCTION: IMPORTED [GCC34_MSVC7] Dev-tree R1.6
  335.  *
  336.  * Revision 1.6  2004/05/24 16:13:57  gorelenk
  337.  * Added PCH ncbi_pch.hpp
  338.  *
  339.  * Revision 1.5  2004/05/04 15:23:45  ucko
  340.  * Split splign code out of xalgoalign into new xalgosplign.
  341.  *
  342.  * Revision 1.4  2004/04/30 15:00:47  kapustin
  343.  * Support ASN formatting
  344.  *
  345.  * Revision 1.3  2004/04/23 14:37:44  kapustin
  346.  * *** empty log message ***
  347.  *
  348.  *
  349.  * ===========================================================================
  350.  */