NCBI C++ ToolKit
align_range.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef UTIL___ALIGN_RANGE__HPP
2 #define UTIL___ALIGN_RANGE__HPP
3 
4 /* $Id: align_range.hpp 95264 2021-10-29 12:37:02Z grichenk $
5 * ===========================================================================
6 *
7 * PUBLIC DOMAIN NOTICE
8 * National Center for Biotechnology Information
9 *
10 * This software/database is a "United States Government Work" under the
11 * terms of the United States Copyright Act. It was written as part of
12 * the author's official duties as a United States Government employee and
13 * thus cannot be copyrighted. This software/database is freely available
14 * to the public for use. The National Library of Medicine and the U.S.
15 * Government have not placed any restriction on its use or reproduction.
16 *
17 * Although all reasonable efforts have been taken to ensure the accuracy
18 * and reliability of the software and data, the NLM and the U.S.
19 * Government do not and cannot warrant the performance or results that
20 * may be obtained by using this software or data. The NLM and the U.S.
21 * Government disclaim all warranties, express or implied, including
22 * warranties of performance, merchantability or fitness for any particular
23 * purpose.
24 *
25 * Please cite the author in any work or product based on this material.
26 *
27 * ===========================================================================
28 *
29 * Author: Andrey Yazhuk
30 *
31 * File Description:
32 *
33 *
34 * ===========================================================================
35 */
36 
37 #include <corelib/ncbistd.hpp>
38 #include <corelib/ncbi_limits.hpp>
39 
40 
41 /** @addtogroup RangeSupport
42  *
43  * @{
44  */
45 
46 #include <util/range.hpp>
47 
49 
50 
51 ///////////////////////////////////////////////////////////////////////////////
52 /// CAlignRange
53 /// Represents an element of pairwise alignment of two sequences.
54 /// CAlignRange := [from_1, to_open_1), [from_2, to_open_2), direction
55 /// where:
56 /// from_1 <= to_open_1, from_2 <= to_open_2
57 /// (to_open_1 - from_1) == (to_open_2 - from_2)
58 /// mapping:
59 /// if direct from_1 -> from_2, to_1 -> to_2
60 /// if reversed from_1 -> to_2, to_1 -> from_2
61 
62 template<class Position> class CAlignRange
63 {
64 public:
65  typedef Position position_type;
68 
69  enum EFlags {
70  fReversed = 0x01, // Second reversed compared to the first.
71  fFirstRev = 0x02 // First is on minus strand.
72  };
73 
78  m_Flags(0)
79  {
80  }
81 
83  position_type second_from,
85  bool direct = true,
86  bool first_direct = true)
87  : m_FirstFrom(first_from),
88  m_SecondFrom(second_from),
89  m_Length(len),
90  m_Flags(0)
91  {
92  SetDirect(direct);
93  SetFirstDirect(first_direct);
94  }
95 
96  bool IsDirect() const {
97  return (m_Flags & fReversed) == 0;
98  }
99  bool IsReversed() const {
100  return (m_Flags & fReversed) != 0;
101  }
102  bool IsFirstDirect() const {
103  return (m_Flags & fFirstRev) == 0;
104  }
105  bool IsFirstReversed() const {
106  return (m_Flags & fFirstRev) != 0;
107  }
108 
110  {
111  return m_FirstFrom;
112  }
114  {
115  return m_FirstFrom + m_Length;
116  }
118  {
119  return GetFirstToOpen() - 1;
120  }
122  {
123  return m_SecondFrom;
124  }
126  {
127  return m_SecondFrom + m_Length;
128  }
130  {
131  return GetSecondToOpen() - 1;
132  }
134  {
135  return TRange(GetFirstFrom(), GetFirstTo());
136  }
138  {
139  return TRange(GetSecondFrom(), GetSecondTo());
140  }
141  bool Empty(void) const
142  {
143  return m_Length <= 0;
144  }
145  bool NotEmpty(void) const
146  {
147  return m_Length > 0;
148  }
149  // return length of regular region
151  {
152  return m_Length;
153  }
155  {
156  m_FirstFrom = from;
157  return *this;
158  }
160  {
161  m_SecondFrom = second_from;
162  return *this;
163  }
165  {
166  m_Length = len;
167  return *this;
168  }
169  TThisType& Set(position_type first_from, position_type second_from,
171  {
172  return SetFirstFrom(first_from).SetSecondFrom(second_from).SetLength(len);
173  }
174  void SetDirect(bool direct = true)
175  {
176  SetReversed(!direct);
177  }
178  void SetReversed(bool reversed = true)
179  {
180  if (reversed) {
181  m_Flags |= fReversed;
182  }
183  else {
184  m_Flags &= ~fReversed;
185  }
186  }
187  void SetFirstDirect(bool direct = true)
188  {
189  SetFirstReversed(!direct);
190  }
191  void SetFirstReversed(bool reversed = true)
192  {
193  if (reversed) {
194  m_Flags |= fFirstRev;
195  }
196  else {
197  m_Flags &= ~fFirstRev;
198  }
199  }
200  bool operator==(const TThisType& r) const
201  {
202  return GetFirstFrom() == r.GetFirstFrom() &&
203  GetSecondFrom() == r.GetSecondFrom() &&
204  GetLength() == r.GetLength() &&
205  m_Flags == r.m_Flags;
206  }
207  bool operator!=(const TThisType& r) const
208  {
209  return !(*this == r);
210  }
212  {
213  if(FirstContains(pos)) {
214  int off = pos - m_FirstFrom;
215  if(IsReversed()) {
216  return GetSecondTo() - off;
217  } else {
218  return m_SecondFrom + off;
219  }
220  } else {
221  return -1;
222  }
223  }
225  {
226  if(SecondContains(pos)) {
227  int off = IsReversed() ? (GetSecondTo() - pos) : (pos - m_SecondFrom);
228  return m_FirstFrom + off;
229  } else {
230  return -1;
231  }
232  }
233  bool FirstContains(position_type pos) const
234  {
235  return pos >= m_FirstFrom && pos < GetFirstToOpen();
236  }
238  {
239  return pos >= m_SecondFrom && pos < GetSecondToOpen();
240  }
241  /// Intersection
243  {
244  TThisType al_r(*this);
245  al_r.IntersectWith(r);
246  return al_r;
247  }
249  {
250  int new_from = max(GetFirstFrom(), r.GetFrom());
251  int new_to = min(GetFirstTo(), r.GetTo());
252  if(new_to < new_from) {
253  new_to = new_from - 1;
254  }
255  if(IsReversed()) {
256  m_SecondFrom += GetFirstTo() - new_to;
257  } else {
258  m_SecondFrom += new_from - GetFirstFrom();
259  }
260 
261  m_FirstFrom = new_from;
262  m_Length = new_to - new_from + 1;
263  return *this;
264  }
266  {
267  int new_from = max(GetSecondFrom(), r.GetFrom());
268  int new_to = min(GetSecondTo(), r.GetTo());
269  if(new_to < new_from) {
270  new_to = new_from - 1;
271  }
272  if(IsReversed()) {
273  m_FirstFrom += GetSecondTo() - new_to;
274  } else {
275  m_FirstFrom += new_from - GetSecondFrom();
276  }
277 
278  m_SecondFrom = new_from;
279  m_Length = new_to - new_from + 1;
280  return *this;
281  }
283  {
284  return ! (this->GetFirstFrom() > r.GetTo()
285  || r.GetFrom() > this->GetFirstTo());
286  }
287  bool IsAbutting(const TThisType& r) const
288  {
289  if(IsDirect() == r.IsDirect() && GetLength() >= 0 && r.GetLength() >= 0) {
290  const TThisType *r_1 = this, *r_2 = &r;
291  if(r_1->GetFirstFrom() > r_2->GetFirstFrom() ||
292  r_1->GetFirstToOpen() > r_2->GetFirstToOpen()) {
293  swap(r_1, r_2); // reorder by from_1
294  }
295  if(r_1->GetFirstToOpen() == r_2->GetFirstFrom()) {
296  return IsDirect() ? r_1->GetSecondToOpen() == r_2->GetSecondFrom()
297  : r_1->GetSecondFrom() == r_2->GetSecondToOpen();
298  }
299  }
300  return false;
301  }
303  {
304  _ASSERT(IsAbutting(r));
305 
306  m_Length += r.GetLength();
307  if(GetFirstFrom() <= r.GetFirstFrom() && GetFirstToOpen() <= r.GetFirstToOpen()) {
308  if(IsReversed()) {
309  SetSecondFrom(r.GetSecondFrom());
310  }
311  } else {
312  SetFirstFrom(r.GetFirstFrom());
313  if(IsDirect()) {
314  SetSecondFrom(r.GetSecondFrom());
315  }
316  }
317  return *this;
318  }
320  {
321  TThisType al_r(*this);
322  al_r.CombineWithAbutting(r);
323  return al_r;
324  }
326  {
327  return GetPositionMax();
328  }
330  {
331  return GetPositionMax();
332  }
334  {
335  return GetEmptyToOpen()-1;
336  }
338  {
339  return 0;
340  }
341  static TThisType GetEmpty(void)
342  {
343  return TThisType();
344  }
346  {
348  }
350  {
352  }
353 
354 private:
356  position_type m_SecondFrom; /// start on the aligned sequence
357  position_type m_Length; /// length of the segment
358  int m_Flags;
359 };
360 
361 /* @} */
362 
364 
365 #endif /* UTIL___ALIGN_RANGE__HPP */
CAlignRange Represents an element of pairwise alignment of two sequences.
Definition: align_range.hpp:63
CRange –.
Definition: Range.hpp:68
Include a standard set of the NCBI C++ Toolkit most basic headers.
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
Definition: ncbimisc.hpp:1508
bool IsAbutting(const TThisType &r) const
void SetReversed(bool reversed=true)
position_type GetFirstPosBySecondPos(position_type pos) const
bool FirstContains(position_type pos) const
bool IntersectingWith(const CRange< position_type > &r) const
static TThisType GetEmpty(void)
bool IsReversed() const
Definition: align_range.hpp:99
position_type m_FirstFrom
position_type m_Length
start on the aligned sequence
CRange< Position > TRange
Definition: align_range.hpp:67
position_type m_SecondFrom
start
TThisType & IntersectWith(const CRange< position_type > &r)
TRange GetFirstRange() const
int m_Flags
length of the segment
TThisType IntersectionWith(const CRange< position_type > &r) const
Intersection.
CAlignRange(position_type first_from, position_type second_from, position_type len, bool direct=true, bool first_direct=true)
Definition: align_range.hpp:82
TRange GetSecondRange() const
static position_type GetPositionMin(void)
position_type GetFirstToOpen(void) const
TThisType & IntersectSecondWith(const CRange< position_type > &r)
TThisType & SetLength(position_type len)
bool IsFirstDirect() const
position_type GetFirstTo(void) const
TThisType & Set(position_type first_from, position_type second_from, position_type len)
static position_type GetEmptyTo(void)
TThisType CombinationWithAbutting(const TThisType &r) const
TThisType & SetSecondFrom(position_type second_from)
bool SecondContains(position_type pos) const
bool IsDirect() const
Definition: align_range.hpp:96
static position_type GetEmptyLength(void)
static position_type GetEmptyToOpen(void)
bool operator==(const TThisType &r) const
static position_type GetEmptyFrom(void)
bool Empty(void) const
bool NotEmpty(void) const
position_type GetSecondFrom(void) const
TThisType & CombineWithAbutting(const TThisType &r)
CAlignRange< Position > TThisType
Definition: align_range.hpp:66
bool operator!=(const TThisType &r) const
void SetFirstReversed(bool reversed=true)
void SetDirect(bool direct=true)
TThisType & SetFirstFrom(position_type from)
CAlignRange(void)
Definition: align_range.hpp:74
static position_type GetPositionMax(void)
void SetFirstDirect(bool direct=true)
bool IsFirstReversed() const
position_type GetSecondTo(void) const
Position position_type
Definition: align_range.hpp:65
position_type GetFirstFrom(void) const
position_type GetSecondToOpen(void) const
position_type GetLength(void) const
position_type GetSecondPosByFirstPos(position_type pos) const
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
TTo GetTo(void) const
Get the To member data.
Definition: Range_.hpp:269
int len
T max(T x_, T y_)
T min(T x_, T y_)
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
#define _ASSERT
Modified on Wed Sep 04 14:59:51 2024 by modify_doxy.py rev. 669887