src/algo/align/util/align_shadow.cpp

Go to the documentation of this file.
00001 /* $Id: align_shadow.cpp 160546 2009-05-18 13:59:06Z dicuccio $
00002 * ===========================================================================
00003 *
00004 *                            public DOMAIN NOTICE                          
00005 *               National Center for Biotechnology Information
00006 *                                                                          
00007 *  This software/database is a "United States Government Work" under the   
00008 *  terms of the United States Copyright Act.  It was written as part of    
00009 *  the author's official duties as a United States Government employee and 
00010 *  thus cannot be copyrighted.  This software/database is freely available 
00011 *  to the public for use. The National Library of Medicine and the U.S.    
00012 *  Government have not placed any restriction on its use or reproduction.  
00013 *                                                                          
00014 *  Although all reasonable efforts have been taken to ensure the accuracy  
00015 *  and reliability of the software and data, the NLM and the U.S.          
00016 *  Government do not and cannot warrant the performance or results that    
00017 *  may be obtained by using this software or data. The NLM and the U.S.    
00018 *  Government disclaim all warranties, express or implied, including       
00019 *  warranties of performance, merchantability or fitness for any particular
00020 *  purpose.                                                                
00021 *                                                                          
00022 *  Please cite the author in any work or product based on this material.   
00023 *
00024 * ===========================================================================
00025 *
00026 * Author:  Yuri Kapustin
00027 *
00028 * File Description:
00029 *
00030 */
00031 
00032 #include <ncbi_pch.hpp>
00033 #include <algo/align/util/align_shadow.hpp>
00034 #include <objects/seqalign/Std_seg.hpp>
00035 #include <objects/seqloc/Seq_loc.hpp>
00036 #include <objects/seqloc/Seq_interval.hpp>
00037 
00038 #include <algorithm>
00039 #include <numeric>
00040 
00041 #include <math.h>
00042 
00043 BEGIN_NCBI_SCOPE
00044 
00045 namespace {
00046 
00047     const CAlignShadow::TCoord g_UndefCoord (
00048         numeric_limits<CAlignShadow::TCoord>::max());
00049 
00050     typedef pair<objects::ENa_strand, objects::ENa_strand> TStrands;
00051 }
00052 
00053 TStrands RetrieveStdStrands(const objects::CSeq_align& seq_align)
00054 {
00055     USING_SCOPE(objects);
00056 
00057     const CSeq_align::TSegs::TStd & std_list (seq_align.GetSegs().GetStd());
00058     const CStd_seg & stdseg (*(std_list.front()));
00059     const CStd_seg::TLoc & locs (stdseg.GetLoc());
00060     return TStrands(locs[0]->GetStrand(), locs[1]->GetStrand());
00061 }
00062 
00063 
00064 CAlignShadow::CAlignShadow(const objects::CSeq_align& seq_align, bool save_xcript)
00065 {
00066     USING_SCOPE(objects);
00067 
00068     if (seq_align.CheckNumRows() != 2) {
00069         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00070                    "Pairwise seq-align required to init align-shadow");
00071     }
00072 
00073     const bool is_denseg (seq_align.GetSegs().IsDenseg());
00074     const bool is_stdseg (seq_align.GetSegs().IsStd());
00075     if(!is_denseg && !is_stdseg) {
00076         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00077                    "Must be a dense-seg or std_seg to init align-shadow");
00078     }
00079 
00080     m_Id.first.Reset(&seq_align.GetSeq_id(0));
00081     m_Id.second.Reset(&seq_align.GetSeq_id(1));
00082 
00083     ENa_strand qstrand (eNa_strand_unknown);
00084     ENa_strand sstrand (eNa_strand_unknown);
00085     
00086     if(is_denseg) {
00087         qstrand = seq_align.GetSeqStrand(0);
00088         sstrand = seq_align.GetSeqStrand(1);
00089     }
00090     else {
00091         const TStrands strands (RetrieveStdStrands(seq_align));
00092         qstrand = strands.first;
00093         sstrand = strands.second;
00094     }
00095 
00096     if(qstrand == eNa_strand_minus) {
00097         m_Box[1] = seq_align.GetSeqStart(0);
00098         m_Box[0] = seq_align.GetSeqStop(0);
00099     }
00100     else {
00101         m_Box[0] = seq_align.GetSeqStart(0);
00102         m_Box[1] = seq_align.GetSeqStop(0);
00103     }
00104         
00105     if(sstrand == eNa_strand_minus) {
00106         m_Box[3] = seq_align.GetSeqStart(1);
00107         m_Box[2] = seq_align.GetSeqStop(1);
00108     }
00109     else {
00110         m_Box[2] = seq_align.GetSeqStart(1);
00111         m_Box[3] = seq_align.GetSeqStop(1);
00112     }
00113 
00114     if(save_xcript) {
00115 
00116         if(is_denseg) {
00117 
00118             // compile edit transcript treating diags as matches
00119             const CDense_seg & ds (seq_align.GetSegs().GetDenseg());
00120             const CDense_seg::TStarts& starts (ds.GetStarts());
00121             const CDense_seg::TLens& lens (ds.GetLens());
00122             size_t i (0);
00123             ITERATE(CDense_seg::TLens, ii_lens, lens) {
00124                 char c;
00125                 if(starts[i] < 0) {
00126                     c = 'I';
00127                 }
00128                 else if(starts[i+1] < 0) {
00129                     c = 'D';
00130                 }
00131                 else {
00132                     c = 'M';
00133                 }
00134                 m_Transcript.push_back(c);
00135                 if(*ii_lens > 1) {
00136                     m_Transcript.append(NStr::IntToString(*ii_lens));
00137                 }
00138                 i += 2;
00139             }
00140         }
00141         else {
00142             NCBI_THROW(CAlgoAlignUtilException,
00143                        eInternal,
00144                        "CAlignShadow(): save_xcript mode not supported "
00145                        "for seq-align segments other than dense-seg.");
00146         }
00147     }
00148 }
00149 
00150 
00151 CAlignShadow::CAlignShadow(void)
00152 {
00153     m_Box[0] = m_Box[1] = m_Box[2] = m_Box[3] = g_UndefCoord;
00154 }
00155 
00156 
00157 CAlignShadow::CAlignShadow(const TId& idquery, TCoord qstart, bool qstrand,
00158                            const TId& idsubj, TCoord sstart, bool sstrand,
00159                            const string& xcript)
00160 {
00161     m_Id.first  = idquery;
00162     m_Id.second = idsubj;
00163 
00164     m_Box[0] = qstart;
00165     m_Box[2] = sstart;
00166 
00167     TCoord q = qstart, q0 = q, s = sstart, s0 = s;
00168     const int qinc (qstrand? 1: -1), sinc (sstrand? 1: -1);
00169 
00170     ITERATE(string, ii, xcript) {
00171 
00172         switch(*ii) {
00173 
00174         case 'M': case 'R':
00175             q0 = q;
00176             q += qinc; 
00177             s0 = s;
00178             s += sinc; 
00179             break;
00180 
00181         case 'I':
00182             s0 = s;
00183             s += sinc;
00184             break;
00185 
00186         case 'D':
00187             q0 = q;
00188             q += qinc;
00189             break;
00190 
00191         default:
00192             NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00193                        "CAlignShadow()::CAlignShadow(): "
00194                        "Unexpected transcript symbol found");
00195         }
00196     }
00197 
00198     m_Box[1] = q0;
00199     m_Box[3] = s0;
00200 
00201     m_Transcript = s_RunLengthEncode(xcript);
00202 }
00203 
00204 
00205 CNcbiOstream& operator << (CNcbiOstream& os, const CAlignShadow& align_shadow)
00206 {
00207     USING_SCOPE(objects);
00208     
00209     os  << align_shadow.GetId(0)->GetSeqIdString(true) << '\t'
00210         << align_shadow.GetId(1)->GetSeqIdString(true) << '\t';
00211     
00212     align_shadow.x_PartialSerialize(os);
00213     
00214     return os;
00215 }
00216 
00217 
00218 //////////////////////////////////////////////////////////////////////////////
00219 // getters and  setters
00220 
00221 
00222 const CAlignShadow::TId& CAlignShadow::GetId(Uint1 where) const
00223 {
00224     switch(where) {
00225     case 0: return m_Id.first;
00226     case 1: return m_Id.second;
00227     default: {
00228         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00229                    "CAlignShadow::GetId() - argument out of range");
00230     }
00231     }
00232 }
00233 
00234 
00235 const CAlignShadow::TId& CAlignShadow::GetQueryId(void) const
00236 {
00237     return m_Id.first;
00238 }
00239 
00240 
00241 const CAlignShadow::TId& CAlignShadow::GetSubjId(void) const
00242 {
00243     return m_Id.second;
00244 }
00245 
00246 
00247 void CAlignShadow::SetId(Uint1 where, const TId& id)
00248 {
00249     switch(where) {
00250     case 0: m_Id.first = id; break;
00251     case 1: m_Id.second = id; break;
00252     default: {
00253         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00254                    "CAlignShadow::SetId() - argument out of range");
00255     }
00256     }
00257 }
00258 
00259 
00260 void CAlignShadow::SetQueryId(const TId& id)
00261 {
00262     m_Id.first = id;
00263 }
00264 
00265 
00266 void CAlignShadow::SetSubjId(const TId& id)
00267 {
00268     m_Id.second = id;
00269 }
00270 
00271 
00272 bool CAlignShadow::GetStrand(Uint1 where) const
00273 {
00274 #ifdef _DEBUG
00275     if(0 != where && where != 1) {
00276         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00277                    "CAlignShadow::GetStrand() - argument out of range");
00278     }
00279 #endif
00280 
00281     return where == 0? m_Box[0] <= m_Box[1]: m_Box[2] <= m_Box[3];
00282 }
00283 
00284 
00285 bool CAlignShadow::GetQueryStrand(void) const
00286 {
00287     return m_Box[0] <= m_Box[1];
00288 }
00289 
00290 
00291 
00292 bool CAlignShadow::GetSubjStrand(void) const
00293 {
00294     return m_Box[2] <= m_Box[3];
00295 }
00296 
00297 
00298 void CAlignShadow::SetStrand(Uint1 where, bool strand)
00299 {
00300 #ifdef _DEBUG
00301     if(0 != where && where != 1) {
00302         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00303                    "CAlignShadow::SetStrand() - argument out of range");
00304     }
00305 #endif
00306 
00307     const Uint1 i1 (where << 1), i2 (i1 + 1);
00308 
00309     if(m_Box[i1] == g_UndefCoord || m_Box[i2] == g_UndefCoord) {
00310         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00311                    "CAlignShadow::SetStrand() -start and/or stop not yet set");
00312     }
00313 
00314     const bool cur_strand (GetStrand(where));
00315     if(strand != cur_strand) {
00316         swap(m_Box[i1], m_Box[i2]);
00317     }
00318 }
00319 
00320 
00321 void CAlignShadow::SetQueryStrand(bool strand)
00322 {
00323     SetStrand(0, strand);
00324 }
00325 
00326 
00327 void CAlignShadow::SetSubjStrand(bool strand)
00328 {
00329     SetStrand(1, strand);
00330 }
00331 
00332 
00333 void CAlignShadow::SwapQS(void)
00334 {
00335     TCoord a = m_Box[0], b = m_Box[1];
00336     m_Box[0] = m_Box[2]; 
00337     m_Box[1] = m_Box[3];
00338     m_Box[2] = a; 
00339     m_Box[3] = b;
00340     TId id = GetQueryId();
00341     SetQueryId(GetSubjId());
00342     SetSubjId(id);
00343 }
00344 
00345 
00346 void CAlignShadow::FlipStrands(void) 
00347 {
00348     SetQueryStrand(!GetQueryStrand());
00349     SetSubjStrand(!GetSubjStrand());
00350     if(m_Transcript.size()) {
00351         m_Transcript = s_RunLengthDecode(m_Transcript);
00352         reverse(m_Transcript.begin(), m_Transcript.end());
00353         m_Transcript = s_RunLengthEncode(m_Transcript);
00354     }
00355 }
00356 
00357 
00358 const  CAlignShadow::TCoord* CAlignShadow::GetBox(void) const
00359 {
00360     return m_Box;
00361 }
00362  
00363 
00364 void CAlignShadow::SetBox(const TCoord box [4])
00365 {
00366     copy(box, box + 4, m_Box);
00367 }
00368 
00369 
00370 CAlignShadow::TCoord CAlignShadow::GetStart(Uint1 where) const
00371 {
00372 #ifdef _DEBUG
00373     if(0 != where && where != 1) {
00374         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00375                    "CAlignShadow::GetStart() - argument out of range");
00376     }
00377 #endif
00378 
00379     return m_Box[where << 1];
00380 }
00381 
00382 
00383 CAlignShadow::TCoord CAlignShadow::GetStop(Uint1 where) const
00384 {
00385 #ifdef _DEBUG
00386     if(0 != where && where != 1) {
00387         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00388                    "CAlignShadow::GetStop() - argument out of range");
00389     }
00390 #endif
00391 
00392     return m_Box[(where << 1) | 1];
00393 }
00394 
00395 
00396 CAlignShadow::TCoord CAlignShadow::GetQueryStart(void) const
00397 {
00398     return m_Box[0];
00399 }
00400 
00401 
00402 CAlignShadow::TCoord CAlignShadow::GetQueryStop(void) const
00403 {
00404     return m_Box[1];
00405 }
00406 
00407 
00408 CAlignShadow::TCoord CAlignShadow::GetSubjStart(void) const
00409 {
00410     return m_Box[2];
00411 }
00412 
00413 
00414 CAlignShadow::TCoord CAlignShadow::GetSubjStop(void) const
00415 {
00416     return m_Box[3];
00417 }
00418 
00419 
00420 void CAlignShadow::SetStart(Uint1 where, TCoord val)
00421 {
00422 #ifdef _DEBUG
00423     if(0 != where && where != 1) {
00424         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00425                    "CAlignShadow::GetStart() - argument out of range");
00426     }
00427 #endif
00428 
00429     m_Box[(where << 1) | 1] = val;
00430 }
00431 
00432 
00433 void CAlignShadow::SetStop(Uint1 where, TCoord val)
00434 {
00435 #ifdef _DEBUG
00436     if(0 != where && where != 1) {
00437         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00438                    "CAlignShadow::GetStop() - argument out of range");
00439     }
00440 #endif
00441 
00442     m_Box[where << 1] = val;
00443 }
00444 
00445 
00446 void CAlignShadow::SetQueryStart(TCoord val)
00447 {
00448     m_Box[0] = val;
00449 }
00450 
00451 
00452 void CAlignShadow::SetQueryStop(TCoord val)
00453 {
00454      m_Box[1] = val;
00455 }
00456 
00457 
00458 void CAlignShadow::SetSubjStart(TCoord val)
00459 {
00460     m_Box[2] = val;
00461 }
00462 
00463 
00464 void CAlignShadow::SetSubjStop(TCoord val)
00465 {
00466     m_Box[3] = val;
00467 }
00468 
00469 
00470 // // // // 
00471 
00472 
00473 CAlignShadow::TCoord CAlignShadow::GetMin(Uint1 where) const
00474 {
00475 #ifdef _DEBUG
00476     if(0 != where && where != 1) {
00477         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00478                    "CAlignShadow::GetMin() - argument out of range");
00479     }
00480 #endif
00481 
00482     Uint1 i1 = where << 1, i2 = i1 + 1;
00483     return min(m_Box[i1], m_Box[i2]);
00484 }
00485 
00486 
00487 CAlignShadow::TCoord CAlignShadow::GetMax(Uint1 where) const
00488 {
00489 #ifdef _DEBUG
00490     if(0 != where && where != 1) {
00491         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00492                    "CAlignShadow::GetMax() - argument out of range");
00493     }
00494 #endif
00495 
00496     Uint1 i1 = where << 1, i2 = i1 + 1;
00497     return max(m_Box[i1], m_Box[i2]);
00498 }
00499 
00500 
00501 void CAlignShadow::SetMin(Uint1 where, TCoord val)
00502 {
00503 #ifdef _DEBUG
00504     if(0 != where && where != 1) {
00505         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00506                    "CAlignShadow::SetMin() - argument out of range");
00507     }
00508 #endif
00509 
00510     const Uint1 i1 (where << 1), i2 (i1 + 1);
00511 
00512     if(m_Box[i1] == g_UndefCoord || m_Box[i2] == g_UndefCoord) {
00513         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00514                    "CAlignShadow::SetMin() - start and/or stop not yet set");
00515     }
00516     else {
00517 
00518         if(m_Box[i1] <= m_Box[i2] && val <= m_Box[i2]) {
00519             m_Box[i1] = val;
00520         }
00521         else if(val <= m_Box[i1]) {
00522             m_Box[i2] = val;
00523         }
00524         else {
00525             NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00526                        "CAlignShadow::SetMin() - new position is invalid");
00527         }
00528     }
00529 }
00530 
00531 
00532 
00533 void CAlignShadow::SetMax(Uint1 where, TCoord val)
00534 {
00535 #ifdef _DEBUG
00536     if(0 != where && where != 1) {
00537         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00538                    "CAlignShadow::SetMax() - argument out of range");
00539     }
00540 #endif
00541 
00542     const Uint1 i1 (where << 1), i2 (i1 + 1);
00543 
00544     if(m_Box[i1] == g_UndefCoord || m_Box[i2] == g_UndefCoord) {
00545         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00546                    "CAlignShadow::SetMax() - start and/or stop not yet set");
00547     }
00548     else {
00549 
00550         if(m_Box[i1] <= m_Box[i2] && val >= m_Box[i1]) {
00551             m_Box[i2] = val;
00552         }
00553         else if(val >= m_Box[i2]) {
00554             m_Box[i1] = val;
00555         }
00556         else {
00557             NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00558                        "CAlignShadow::SetMax() - new position is invalid");
00559         }
00560     }
00561 }
00562 
00563 
00564 void CAlignShadow::SetQueryMax(TCoord val)
00565 {
00566     SetMax(0, val);
00567 }
00568 
00569 
00570 void CAlignShadow::SetSubjMax(TCoord val)
00571 {
00572     SetMax(1, val);
00573 }
00574 
00575 
00576 void CAlignShadow::SetQueryMin(TCoord val)
00577 {
00578     SetMin(0, val);
00579 }
00580 
00581 
00582 void CAlignShadow::SetSubjMin(TCoord val)
00583 {
00584     SetMin(1, val);
00585 }
00586 
00587 
00588 const CAlignShadow::TTranscript& CAlignShadow::GetTranscript(void) const
00589 {
00590     return m_Transcript;
00591 }
00592 
00593 
00594 /////////////////////////////////////////////////////////////////////////////
00595 // partial serialization
00596 
00597 void CAlignShadow::x_PartialSerialize(CNcbiOstream& os) const
00598 {
00599     os << GetQueryStart() + 1 << '\t' << GetQueryStop() + 1 << '\t'
00600        << GetSubjStart() + 1 << '\t' << GetSubjStop() + 1;
00601     if(m_Transcript.size() > 0) {
00602         os << '\t' << m_Transcript;
00603     }
00604 }
00605 
00606 
00607 CAlignShadow::TCoord CAlignShadow::GetQueryMin() const
00608 {
00609     return min(m_Box[0], m_Box[1]);
00610 }
00611 
00612 
00613 CAlignShadow::TCoord CAlignShadow::GetSubjMin() const
00614 {
00615     return min(m_Box[2], m_Box[3]);
00616 }
00617 
00618 
00619 CAlignShadow::TCoord CAlignShadow::GetQueryMax() const
00620 {
00621     return max(m_Box[0], m_Box[1]);
00622 }
00623 
00624 
00625 CAlignShadow::TCoord CAlignShadow::GetSubjMax() const
00626 {
00627     return max(m_Box[2], m_Box[3]);
00628 }
00629 
00630 
00631 CAlignShadow::TCoord CAlignShadow::GetQuerySpan(void) const
00632 {
00633     return 1 + GetQueryMax() - GetQueryMin();
00634 }
00635 
00636 
00637 CAlignShadow::TCoord CAlignShadow::GetSubjSpan(void) const
00638 {
00639     return 1 + GetSubjMax() - GetSubjMin();
00640 }
00641 
00642 
00643 void CAlignShadow::Shift(Int4 shift_query, Int4 shift_subj)
00644 {
00645     m_Box[0] += shift_query;
00646     m_Box[1] += shift_query;
00647     m_Box[2] += shift_subj;
00648     m_Box[3] += shift_subj;
00649 }
00650 
00651 
00652 void CAlignShadow::Modify(Uint1 point, TCoord new_pos)
00653 {
00654     TCoord qmin, qmax;
00655     bool qstrand;
00656     if(m_Box[0] < m_Box[1]) {
00657         qmin = m_Box[0];
00658         qmax = m_Box[1];
00659         qstrand = true;
00660     }
00661     else {
00662         qmin = m_Box[1];
00663         qmax = m_Box[0];
00664         qstrand = false;
00665     }
00666 
00667     TCoord smin, smax;
00668     bool sstrand;
00669     if(m_Box[2] < m_Box[3]) {
00670         smin = m_Box[2];
00671         smax = m_Box[3];
00672         sstrand = true;
00673     }
00674     else {
00675         smin = m_Box[3];
00676         smax = m_Box[2];
00677         sstrand = false;
00678     }
00679 
00680     bool newpos_invalid = false;
00681     if(point <= 1) {
00682         if(new_pos < qmin || new_pos > qmax) {
00683             newpos_invalid = true;
00684         }
00685     }
00686     else {
00687         if(new_pos < smin || new_pos > smax) {
00688             newpos_invalid = true;
00689         }        
00690     }
00691     
00692     if(newpos_invalid) {
00693         NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00694                    "CAlignShadow::Modify(): requested new position invalid"); 
00695     }
00696 
00697     const bool same_strands = qstrand == sstrand;
00698 
00699     TCoord q = 0, s = 0;
00700 
00701     if(m_Transcript.size() > 0) {
00702 
00703         q = GetQueryStart();
00704         s = GetSubjStart();
00705         Int1 dq = (qstrand? +1: -1), ds = (sstrand?  +1: -1);
00706         string xcript (s_RunLengthDecode(m_Transcript));
00707 
00708         size_t n1 = 0;
00709         bool need_trace = true;
00710         if(point <= 1) {
00711             if(q == new_pos) need_trace = false;
00712         }
00713         else {
00714             if(s == new_pos) need_trace = false;
00715         }
00716 
00717         const bool point_is_start((point%2) ^ (GetStrand(point/2)? 1: 0));
00718         if(need_trace) {
00719             
00720             char c = 0;
00721             ITERATE(TTranscript, ii, xcript) {
00722 
00723                 ++n1;
00724                 switch(c = *ii) {
00725                 case 'M': case 'R': q += dq; s += ds; break;
00726                 case 'D': q += dq; break;
00727                 case 'I': s += ds; break;
00728                 default: {
00729                     NCBI_THROW(CAlgoAlignUtilException, eInternal,
00730                              "CAlignShadow::Modify(): unexpected transcript symbol"); 
00731                 }
00732                 }
00733 
00734                 if(point_is_start) {
00735                     if(point <= 1) {
00736                         if(q == new_pos) break;
00737                     }
00738                     else {
00739                         if(s == new_pos) break;
00740                     }
00741                 }
00742                 else {
00743                     if(point <= 1) {
00744                         if(q == new_pos + dq) break;
00745                     }
00746                     else {
00747                         if(s == new_pos + ds) break;
00748                     }
00749                 }
00750             }
00751 
00752             if(!point_is_start && n1 > 0) {
00753                 switch(c) {
00754                 case 'M': case 'R': q -= dq; s -= ds; break;
00755                 case 'D': q -= dq; break;
00756                 case 'I': s -= ds; break;
00757                 }
00758             }
00759 
00760         }
00761 
00762         switch(point) {
00763         case 0: // query min
00764             SetQueryMin(q);
00765             if(same_strands) { SetSubjMin(s); } else { SetSubjMax(s); }
00766             break;
00767         case 1: // query max
00768             SetQueryMax(q);
00769             if(same_strands) { SetSubjMax(s); } else { SetSubjMin(s); }
00770             break;
00771         case 2: // subj min
00772             SetSubjMin(s);
00773             if(same_strands) { SetQueryMin(q); } else { SetQueryMax(q); }
00774             break;
00775         case 3: // subj max
00776             SetSubjMax(s);
00777             if(same_strands) { SetQueryMax(q); } else { SetQueryMin(q); }
00778             break;
00779         default:
00780             NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00781                        "CAlignShadow::Modify(): Invalid end point requested."); 
00782         }
00783 
00784         if(n1 > 0) {
00785             if( point_is_start ) {
00786                 xcript = xcript.substr(n1, xcript.size() - n1);
00787             }
00788             else {
00789                 xcript.resize(n1);
00790             }
00791             m_Transcript = s_RunLengthEncode(xcript);
00792         }
00793     }
00794     else {
00795 
00796         TCoord qlen = 1 + qmax - qmin, slen = 1 + smax - smin;
00797         double k = double(qlen) / slen;
00798         Int4 delta_q, delta_s;
00799         switch(point) {
00800 
00801         case 0: // query min
00802 
00803             delta_q = new_pos - qmin;
00804             delta_s = Int4(round(delta_q / k));
00805 
00806             SetQueryMin(qmin + delta_q);
00807             if(same_strands) {
00808                 SetSubjMin(smin + delta_s);
00809             }
00810             else {
00811                 SetSubjMax(smax - delta_s);
00812             }
00813 
00814             break;
00815 
00816         case 1: // query max
00817 
00818             delta_q = new_pos - qmax;
00819             delta_s = Int4(round(delta_q / k));
00820 
00821             SetQueryMax(qmax + delta_q);
00822             if(same_strands) {
00823                 SetSubjMax(smax + delta_s);
00824             }
00825             else {
00826                 SetSubjMin(smin - delta_s);
00827             }
00828 
00829             break;
00830 
00831         case 2: // subj min
00832 
00833             delta_s = new_pos - smin;
00834             delta_q = Int4(round(delta_s * k));
00835 
00836             SetSubjMin(smin + delta_s);
00837             if(same_strands) {
00838                 SetQueryMin(qmin + delta_q);
00839             }
00840             else {
00841                 SetQueryMax(qmax - delta_q);
00842             }
00843 
00844             break;
00845 
00846         case 3: // subj max
00847 
00848             delta_s = new_pos - smax;
00849             delta_q = Int4(round(delta_s * k));
00850 
00851             SetSubjMax(smax + delta_s);
00852             if(same_strands) {
00853                 SetQueryMax(qmax + delta_q);
00854             }
00855             else {
00856                 SetQueryMin(qmin - delta_q);
00857             }
00858 
00859             break;
00860 
00861         default:
00862             NCBI_THROW(CAlgoAlignUtilException, eBadParameter,
00863                        "CAlignShadow::Modify(): invalid end requested"); 
00864         };
00865     }
00866 }
00867 
00868 
00869 string CAlignShadow::s_RunLengthEncode(const string& in)
00870 {
00871     string out;
00872     const size_t dim (in.size());
00873     if(dim == 0) {
00874         return kEmptyStr;
00875     }
00876 
00877     const char* p (in.data());
00878     char c0 (p[0]);
00879     out.append(1, c0);
00880     size_t count (1);
00881     for(size_t k (1); k < dim; ++k) {
00882 
00883         char c (p[k]);
00884         if(isdigit(c)) { // consider already encoded
00885             return in;
00886         }
00887 
00888         if(c != c0) {
00889             c0 = c;
00890             if(count > 1) {
00891                 out += NStr::IntToString(count);
00892             }
00893             count = 1;
00894             out.append(1, c0);
00895         }
00896         else {
00897             ++count;
00898         }
00899     }
00900 
00901     if(count > 1) {
00902         out += NStr::IntToString(count);
00903     }
00904 
00905     return out;
00906 }
00907 
00908 
00909 string CAlignShadow::s_RunLengthDecode(const string& in)
00910 {
00911     string out;
00912     char C = 0;
00913     Uint4 N = 0;
00914     ITERATE(string, ii, in) {
00915 
00916         char c = *ii;
00917         if('0' <= c && c <= '9') {
00918             N = N * 10 + c - '0';
00919         }
00920         else {
00921             if(N > 0) {
00922                 out.append(N - 1, C);
00923                 N = 0;
00924             }
00925             out.push_back(C = c);
00926         }
00927     }
00928     if(N > 0) {
00929         out.append(N - 1, C);
00930     }
00931     return out;
00932 }
00933 
00934 
00935 END_NCBI_SCOPE
00936 
00937 

Generated on Wed Dec 9 03:54:13 2009 for NCBI C++ ToolKit by  doxygen 1.4.6
Modified on Wed Dec 09 08:17:45 2009 by modify_doxy.py rev. 173732