00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
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
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
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:
00764 SetQueryMin(q);
00765 if(same_strands) { SetSubjMin(s); } else { SetSubjMax(s); }
00766 break;
00767 case 1:
00768 SetQueryMax(q);
00769 if(same_strands) { SetSubjMax(s); } else { SetSubjMin(s); }
00770 break;
00771 case 2:
00772 SetSubjMin(s);
00773 if(same_strands) { SetQueryMin(q); } else { SetQueryMax(q); }
00774 break;
00775 case 3:
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:
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:
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:
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:
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)) {
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