NCBI C++ ToolKit
alnmap.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: alnmap.cpp 100628 2023-08-21 14:11:45Z grichenk $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Kamen Todorov, NCBI
27 *
28 * File Description:
29 * Interface for examining alignments (of type Dense-seg)
30 *
31 * ===========================================================================
32 */
33 
34 
35 #include <ncbi_pch.hpp>
37 
39 BEGIN_objects_SCOPE // namespace ncbi::objects::
40 
41 
42 void CAlnMap::x_Init(void)
43 {
44  m_SeqLeftSegs.resize(GetNumRows(), -1);
45  m_SeqRightSegs.resize(GetNumRows(), -1);
46 }
47 
48 
50 {
51  m_AlnStarts.clear();
52  m_AlnStarts.reserve(GetNumSegs());
53 
54  int start = 0, len = 0;
55  for (int i = 0; i < GetNumSegs(); ++i) {
56  start += len;
57  m_AlnStarts.push_back(start);
58  len = m_Lens[i];
59  }
60 }
61 
62 
64 {
65  m_AlnSegIdx.clear();
66  m_NumSegWithOffsets.clear();
67  if (m_RawSegTypes) {
68  delete m_RawSegTypes;
69  m_RawSegTypes = 0;
70  }
71  m_Anchor = -1;
72 
73  // we must call this last, as it uses some internal shenanigans that
74  // are affected by the reset above
76 }
77 
78 
80 {
81  if (anchor == -1) {
82  UnsetAnchor();
83  return;
84  }
85  if (anchor < 0 || anchor >= m_NumRows) {
86  NCBI_THROW(CAlnException, eInvalidRow,
87  "CAlnVec::SetAnchor(): "
88  "Invalid row");
89  }
90  m_AlnSegIdx.clear();
91  m_AlnStarts.clear();
92  m_NumSegWithOffsets.clear();
93  if (m_RawSegTypes) {
94  delete m_RawSegTypes;
95  m_RawSegTypes = 0;
96  }
97 
98  int start = 0, len = 0, aln_seg = -1, offset = 0;
99 
100  m_Anchor = anchor;
101  for (int i = 0, pos = m_Anchor; i < m_NumSegs;
102  ++i, pos += m_NumRows) {
103  if (m_Starts[pos] != -1) {
104  ++aln_seg;
105  offset = 0;
106  m_AlnSegIdx.push_back(i);
107  m_NumSegWithOffsets.push_back(CNumSegWithOffset(aln_seg));
108  start += len;
109  m_AlnStarts.push_back(start);
110  len = m_Lens[i];
111  } else {
112  ++offset;
113  m_NumSegWithOffsets.push_back(CNumSegWithOffset(aln_seg, offset));
114  }
115  }
116  if (!m_AlnSegIdx.size()) {
117  NCBI_THROW(CAlnException, eInvalidDenseg,
118  "CAlnVec::SetAnchor(): "
119  "Invalid Dense-seg: No sequence on the anchor row");
120  }
121 }
122 
123 
126 {
127  TSegTypeFlags flags = 0;
128  TNumseg l_seg, r_seg, l_index, r_index, index;
129  TNumseg l_anchor_index, r_anchor_index, anchor_index;
130  TSeqPos cont_next_start = 0, cont_prev_stop = 0;
131  TSeqPos anchor_cont_next_start = 0, anchor_cont_prev_stop = 0;
132  TSignedSeqPos anchor_start;
133 
134  l_seg = r_seg = seg;
135  l_index = r_index = index = seg * m_NumRows + row;
136  if (IsSetAnchor()) {
137  l_anchor_index = r_anchor_index = anchor_index = seg * m_NumRows + m_Anchor;
138  }
139 
140  TSignedSeqPos start = m_Starts[index];
141 
142  // is it seq or gap?
143  if (start >= 0) {
144  flags |= fSeq;
145  cont_next_start = start + x_GetLen(row, seg);
146  cont_prev_stop = start;
147  }
148 
149  // is it aligned to sequence on the anchor?
150  if (IsSetAnchor()) {
152  anchor_start = m_Starts[anchor_index];
153  if (anchor_start >= 0) {
155  anchor_cont_next_start = anchor_start + x_GetLen(m_Anchor, seg);
156  anchor_cont_prev_stop = anchor_start;
157  }
158  }
159 
160  // what's on the right?
161  if (r_seg <= m_NumSegs - 1) {
162  flags |= fEndOnRight;
163  }
164  flags |= fNoSeqOnRight;
165  while (++r_seg < m_NumSegs) {
166  flags &= ~(flags & fEndOnRight);
167  r_index += m_NumRows;
168  if ((start = m_Starts[r_index]) >= 0) {
169  if ((flags & fSeq) &&
171  start != (TSignedSeqPos)cont_next_start :
172  start + x_GetLen(row, r_seg) != cont_prev_stop)) {
174  }
175  flags &= ~(flags & fNoSeqOnRight);
176  break;
177  }
178  }
179  if (IsSetAnchor() &&
181  r_seg = seg;
182  while (++r_seg < m_NumSegs) {
183  r_anchor_index += m_NumRows;
184  if ((anchor_start = m_Starts[r_anchor_index]) >= 0) {
186  anchor_start != (TSignedSeqPos)anchor_cont_next_start :
187  anchor_start + x_GetLen(m_Anchor, r_seg) != anchor_cont_prev_stop) {
189  }
190  break;
191  }
192  }
193  }
194 
195  // what's on the left?
196  if (l_seg >= 0) {
197  flags |= fEndOnLeft;
198  }
199  flags |= fNoSeqOnLeft;
200  while (--l_seg >= 0) {
201  flags &= ~(flags & fEndOnLeft);
202  l_index -= m_NumRows;
203  if ((start = m_Starts[l_index]) >= 0) {
204  if ((flags & fSeq) &&
206  start + x_GetLen(row, l_seg) != cont_prev_stop :
207  start != (TSignedSeqPos)cont_next_start)) {
209  }
210  flags &= ~(flags & fNoSeqOnLeft);
211  break;
212  }
213  }
214  if (IsSetAnchor() &&
216  l_seg = seg;
217  while (--l_seg >= 0) {
218  l_anchor_index -= m_NumRows;
219  if ((anchor_start = m_Starts[l_anchor_index]) >= 0) {
221  anchor_start + x_GetLen(m_Anchor, l_seg) != anchor_cont_prev_stop :
222  anchor_start != (TSignedSeqPos)anchor_cont_next_start) {
224  }
225  break;
226  }
227  }
228  }
229 
230  return flags;
231 }
232 
233 
234 void
236 {
238 
239  /// Check if already done (enough to check the first seg only)
240  if (types[row] & fTypeIsSet) {
241  return;
242  }
243 
244  /// Strand
245  bool plus = IsPositiveStrand(row);
246 
247  /// Variables
248  TNumseg seg;
249  int idx;
250  int l_idx = row;
251  int r_idx = (m_NumSegs - 1) * m_NumRows + row;
252  int anchor_idx = -1;
253 
254  /// Determine types for the anchor first
255  bool anchored = IsSetAnchor();
256  if (anchored) {
257  if (row != m_Anchor) {
258  /// Prevent infinite loop
260  }
261  anchor_idx = m_Anchor;
262  }
263 
264 
265  /// Ends are trivial
266  types[l_idx] |= fEndOnLeft;
267  types[r_idx] |= fEndOnRight;
268 
269 
270  /// Left-to-right pass
271  int left_seq_pos = -1;
272  for (idx = l_idx, seg = 0;
273  idx <= r_idx;
274  idx += m_NumRows, anchor_idx += m_NumRows, ++seg) {
275 
276  _ASSERT(idx == seg * m_NumRows + row);
277  _ASSERT(anchor_idx == seg * m_NumRows + m_Anchor);
278  _ASSERT(seg >= 0);
279  _ASSERT(seg < m_NumSegs);
280 
281  TSegTypeFlags& flags = types[idx];
282 
283  /// Sequence on left
284  if (left_seq_pos < 0) {
285  flags |= fNoSeqOnLeft;
286  }
287 
288  /// Sequence or Gap?
289  TSignedSeqPos start = m_Starts[idx];
290  if (start >= 0) {
291 
292  /// Sequence
293  flags |= fSeq;
294 
295  /// Unaligned on left?
296  if (left_seq_pos > 0) {
297  if (plus ?
298  start > left_seq_pos :
299  start + x_GetLen(row, seg) < (TSeqPos) left_seq_pos) {
301  }
302  }
303  left_seq_pos = plus ? start + x_GetLen(row, seg) : start;
304 
305  } else { /// Gap
306 
307  if (anchored && row == m_Anchor) {
309  }
310 
311  }
312  }
313 
314 
315  /// Right-to-left pass
316  int right_seq_pos = -1;
317  anchor_idx -= m_NumRows; // this relies on value from previous loop
318  _ASSERT(anchor_idx == (m_NumSegs - 1) * m_NumRows + m_Anchor);
319  for (idx = r_idx, seg = m_NumSegs - 1;
320  idx >= l_idx;
321  idx -= m_NumRows, anchor_idx -= m_NumRows, --seg) {
322 
323  _ASSERT(idx == seg * m_NumRows + row);
324  _ASSERT(anchor_idx == seg * m_NumRows + m_Anchor);
325  _ASSERT(seg >= 0);
326  _ASSERT(seg < m_NumSegs);
327 
328  TSegTypeFlags& flags = types[idx];
329 
330  /// Sequence on right
331  if (right_seq_pos < 0) {
332  flags |= fNoSeqOnRight;
333  }
334 
335 
336  TSignedSeqPos start = m_Starts[idx];
337  if (start >= 0) {
338 
339  /// Sequence
340  _ASSERT(flags | fSeq);
341 
342  /// Unaligned on right?
343  if (right_seq_pos > 0) {
344  if (plus ?
345  start + x_GetLen(row, seg) < (TSeqPos) right_seq_pos :
346  start > right_seq_pos) {
348  }
349  }
350  right_seq_pos = plus ? start : start + x_GetLen(row, seg);
351  }
352 
353 
354  /// What's on the anchor?
355  if (anchored) {
356  if ( ! (types[anchor_idx] & fSeq) ) {
358  }
359  if (types[anchor_idx] & fUnalignedOnRight) {
361  }
362  if (types[anchor_idx] & fUnalignedOnLeft) {
364  }
365  }
366 
367  /// Done with this segment
368  flags |= fTypeIsSet;
369  }
370 }
371 
372 
374 {
375  TNumseg btm, top, mid;
376 
377  btm = 0;
378  top = TNumseg(m_AlnStarts.size()) - 1;
379 
380  if (aln_pos > m_AlnStarts[top] +
381  m_Lens[x_GetRawSegFromSeg(top)] - 1)
382  return -1; // out of range
383 
384  while (btm < top) {
385  mid = (top + btm) / 2;
386  if (m_AlnStarts[mid] == (TSignedSeqPos)aln_pos) {
387  return mid;
388  }
389  if (m_AlnStarts[mid + 1] <= (TSignedSeqPos)aln_pos) {
390  btm = mid + 1;
391  } else {
392  top = mid;
393  }
394  }
395  return top;
396 }
397 
398 
401  ESearchDirection dir, bool try_reverse_dir) const
402 {
403  TSignedSeqPos start = -1, sseq_pos = seq_pos;
404  TNumseg btm, top, mid, cur, last, cur_top, cur_btm;
405  btm = cur_btm = 0; cur = top = last = cur_top = m_NumSegs - 1;
406 
407  bool plus = IsPositiveStrand(row);
408 
409  // if out-of-range, return either -1 or the closest seg in dir direction
410  if (sseq_pos < (TSignedSeqPos)GetSeqStart(row)) {
411  if (dir == eNone) {
412  return -1;
413  } else if (dir == eForward ||
414  dir == (plus ? eRight : eLeft) ||
415  try_reverse_dir) {
416  TNumseg seg;
417  if (plus) {
418  seg = -1;
419  while (++seg < m_NumSegs) {
420  if (m_Starts[seg * m_NumRows + row] >= 0) {
421  return seg;
422  }
423  }
424  } else {
425  seg = m_NumSegs;
426  while (seg--) {
427  if (m_Starts[seg * m_NumRows + row] >= 0) {
428  return seg;
429  }
430  }
431  }
432  }
433  } else if (sseq_pos > (TSignedSeqPos)GetSeqStop(row)) {
434  if (dir == eNone) {
435  return -1;
436  } else if (dir == eBackwards ||
437  dir == (plus ? eLeft : eRight) ||
438  try_reverse_dir) {
439  TNumseg seg;
440  if (plus) {
441  seg = m_NumSegs;
442  while (seg--) {
443  if (m_Starts[seg * m_NumRows + row] >= 0) {
444  return seg;
445  }
446  }
447  } else {
448  seg = -1;
449  while (++seg < m_NumSegs) {
450  if (m_Starts[seg * m_NumRows + row] >= 0) {
451  return seg;
452  }
453  }
454  }
455  }
456  }
457 
458  // main loop
459  while (btm <= top) {
460  cur = mid = (top + btm) / 2;
461 
462  while (cur <= top
463  && (start = m_Starts[(plus ? cur : last - cur)
464  * m_NumRows + row]) < 0) {
465  ++cur;
466  }
467  if (cur <= top && start >= 0) {
468  if (sseq_pos >= start &&
469  seq_pos < start + x_GetLen(row, plus ? cur : last - cur)) {
470  return (plus ? cur : last - cur); // found
471  }
472  if (sseq_pos > start) {
473  btm = cur + 1;
474  cur_btm = cur;
475  } else {
476  top = mid - 1;
477  cur_top = cur;
478  }
479  continue;
480  }
481 
482  cur = mid-1;
483  while (cur >= btm &&
484  (start = m_Starts[(plus ? cur : last - cur)
485  * m_NumRows + row]) < 0) {
486  --cur;
487  }
488  if (cur >= btm && start >= 0) {
489  if (sseq_pos >= start
490  && seq_pos < start + x_GetLen(row, plus ? cur : last - cur)) {
491  return (plus ? cur : last - cur); // found
492  }
493  if (sseq_pos > start) {
494  btm = mid + 1;
495  cur_btm = cur;
496  } else {
497  top = cur - 1;
498  cur_top = cur;
499  }
500  continue;
501  }
502 
503  // if we get here, seq_pos falls into an unaligned region
504  // return either -1 or the closest segment in dir direction
505  if (dir == eNone) {
506  return -1;
507  } else if (dir == eBackwards || dir == (plus ? eLeft : eRight)) {
508  return (plus ? cur_btm : last - cur_btm);
509  } else if (dir == eForward || dir == (plus ? eRight : eLeft)) {
510  return (plus ? cur_top : last - cur_top);
511  }
512  }
513 
514  // return either -1 or the closest segment in dir direction
515  if (dir == eNone) {
516  return -1;
517  } else if (dir == eBackwards || dir == (plus ? eLeft : eRight)) {
518  return (plus ? cur_btm : last - cur_btm);
519  } else if (dir == eForward || dir == (plus ? eRight : eLeft)) {
520  return (plus ? cur_top : last - cur_top);
521  }
522 
523  return -1;
524 }
525 
526 
528  ESearchDirection dir,
529  bool try_reverse_dir) const
530 {
531  TNumseg raw_seg = GetRawSeg(row, seq_pos, dir, try_reverse_dir);
532  if (raw_seg < 0) { // out of seq range
533  return -1;
534  }
535 
536  TSeqPos start = m_Starts[raw_seg * m_NumRows + row];
537  TSeqPos len = x_GetLen(row, raw_seg);
538  TSeqPos stop = start + len -1;
539  bool plus = IsPositiveStrand(row);
540 
541  CNumSegWithOffset seg = x_GetSegFromRawSeg(raw_seg);
542 
543  if (dir == eNone) {
544  if (seg.GetOffset()) {
545  // seq_pos is within an insert
546  return -1;
547  }
548  } else {
549  // check if within unaligned region
550  // if seq_pos outside the segment returned by GetRawSeg
551  // then return the edge alnpos
552  if ((plus ? seq_pos < start : seq_pos > stop)) {
553  return GetAlnStart(seg.GetAlnSeg());
554  }
555  if ((plus ? seq_pos > stop : seq_pos < start)) {
556  return GetAlnStop(seg.GetAlnSeg());
557  }
558 
559 
560  // check if within an insert
561  if (seg.GetOffset() &&
562  (dir == eRight ||
563  dir == (plus ? eForward : eBackwards))) {
564 
565  // seek the nearest alnpos on the right
566  if (seg.GetAlnSeg() < GetNumSegs() - 1) {
567  return GetAlnStart(seg.GetAlnSeg() + 1);
568  } else if (try_reverse_dir) {
569  return GetAlnStop(seg.GetAlnSeg());
570  } else {
571  return -1;
572  }
573 
574  }
575  if (seg.GetOffset() &&
576  (dir == eLeft ||
577  dir == (plus ? eBackwards : eForward))) {
578 
579  // seek the nearest alnpos on left
580  if (seg.GetAlnSeg() >= 0) {
581  return GetAlnStop(seg.GetAlnSeg());
582  } else if (try_reverse_dir) {
583  return GetAlnStart(seg.GetAlnSeg() + 1);
584  } else {
585  return -1;
586  }
587 
588  }
589  }
590 
591  // main case: seq_pos is within an alnseg
592  //assert(seq_pos >= start && seq_pos <= stop);
593  TSeqPos delta = (seq_pos - start) / GetWidth(row);
594  return m_AlnStarts[seg.GetAlnSeg()]
595  + (plus ? delta : m_Lens[raw_seg] - 1 - delta);
596 }
597 
599  TNumseg seg,
600  ESearchDirection dir,
601  bool try_reverse_dir) const
602 {
603  _ASSERT(x_GetRawStart(row, seg) == -1);
604  if (dir == eNone) {
605  return -1;
606  }
607  TNumseg orig_seg = seg;
608  TSignedSeqPos pos = -1;
609  bool reverse_pass = false;
610 
611  while (true) {
612  if (IsPositiveStrand(row)) {
613  if (dir == eBackwards || dir == eLeft) {
614  while (--seg >=0 && pos == -1) {
615  pos = x_GetRawStop(row, seg);
616  }
617  } else {
618  while (++seg < m_NumSegs && pos == -1) {
619  pos = x_GetRawStart(row, seg);
620  }
621  }
622  } else {
623  if (dir == eForward || dir == eLeft) {
624  while (--seg >=0 && pos == -1) {
625  pos = x_GetRawStart(row, seg);
626  }
627  } else {
628  while (++seg < m_NumSegs && pos == -1) {
629  pos = x_GetRawStop(row, seg);
630  }
631  }
632  }
633  if (!try_reverse_dir) {
634  break;
635  }
636  if (pos >= 0) {
637  break; // found
638  } else if (reverse_pass) {
639  string msg = "Invalid Dense-seg: Row " +
641  " contains gaps only.";
642  NCBI_THROW(CAlnException, eInvalidDenseg, msg);
643  }
644  // not found, try reverse direction
645  reverse_pass = true;
646  seg = orig_seg;
647  switch (dir) {
648  case eLeft:
649  dir = eRight; break;
650  case eRight:
651  dir = eLeft; break;
652  case eForward:
653  dir = eBackwards; break;
654  case eBackwards:
655  dir = eForward; break;
656  default:
657  break;
658  }
659  }
660  return pos;
661 }
662 
664  TSeqPos aln_pos,
665  ESearchDirection dir,
666  bool try_reverse_dir) const
667 {
668  if (aln_pos > GetAlnStop()) {
669  aln_pos = GetAlnStop(); // out-of-range adjustment
670  }
671  TNumseg seg = GetSeg(aln_pos);
672  TSignedSeqPos pos = GetStart(for_row, seg);
673  if (pos >= 0) {
674  TSeqPos delta = (aln_pos - GetAlnStart(seg)) * GetWidth(for_row);
675  if (IsPositiveStrand(for_row)) {
676  pos += delta;
677  } else {
678  pos += x_GetLen(for_row, x_GetRawSegFromSeg(seg)) - 1 - delta;
679  }
680  } else if (dir != eNone) {
681  // found a gap, search in the neighbouring segments
682  // according to search direction (dir) and strand
683  pos = x_FindClosestSeqPos(for_row, x_GetRawSegFromSeg(seg), dir, try_reverse_dir);
684  }
685  return pos;
686 }
687 
689  TNumrow row, TSeqPos seq_pos,
690  ESearchDirection dir,
691  bool try_reverse_dir) const
692 {
693  TNumseg raw_seg = GetRawSeg(row, seq_pos);
694  if (raw_seg < 0) {
695  return -1;
696  }
697  unsigned offset = raw_seg * m_NumRows;
698  TSignedSeqPos pos = m_Starts[offset + for_row];
699  if (pos >= 0) {
700  TSeqPos delta = seq_pos - m_Starts[offset + row];
701  if (GetWidth(for_row) != GetWidth(row)) {
702  delta = delta / GetWidth(row) * GetWidth(for_row);
703  }
704  if (StrandSign(row) == StrandSign(for_row)) {
705  pos += delta;
706  } else {
707  pos += x_GetLen(for_row, raw_seg) - 1 - delta;
708  }
709  } else {
710  pos = x_FindClosestSeqPos(for_row, raw_seg, dir, try_reverse_dir);
711  }
712  return pos;
713 }
714 
715 
717 {
718  TNumseg& seg = m_SeqLeftSegs[row];
719  if (seg < 0) {
720  while (++seg < m_NumSegs) {
721  if (m_Starts[seg * m_NumRows + row] >= 0) {
722  return seg;
723  }
724  }
725  } else {
726  return seg;
727  }
728  seg = -1;
729  string err_msg = "CAlnVec::x_GetSeqLeftSeg(): "
730  "Invalid Dense-seg: Row " + NStr::IntToString(row) +
731  " contains gaps only.";
732  NCBI_THROW(CAlnException, eInvalidDenseg, err_msg);
733 }
734 
735 
737 {
738  TNumseg& seg = m_SeqRightSegs[row];
739  if (seg < 0) {
740  seg = m_NumSegs;
741  while (seg--) {
742  if (m_Starts[seg * m_NumRows + row] >= 0) {
743  return seg;
744  }
745  }
746  } else {
747  return seg;
748  }
749  seg = -1;
750  string err_msg = "CAlnVec::x_GetSeqRightSeg(): "
751  "Invalid Dense-seg: Row " + NStr::IntToString(row) +
752  " contains gaps only.";
753  NCBI_THROW(CAlnException, eInvalidDenseg, err_msg);
754 }
755 
756 
758  TNumrow row1,
759  TRange aln_rng,
760  vector<TSignedSeqPos>& result,
761  TRange& rng0,
762  TRange& rng1) const
763 {
764  _ASSERT( ! IsSetAnchor() );
765  TNumseg l_seg, r_seg;
766  TSeqPos aln_start = aln_rng.GetFrom();
767  TSeqPos aln_stop = aln_rng.GetTo();
768  int l_idx0 = row0;
769  int l_idx1 = row1;
770  TSeqPos aln_pos = 0, next_aln_pos, l_len = 0, r_len = 0, l_delta, r_delta;
771  bool plus0 = IsPositiveStrand(row0);
772  bool plus1 = IsPositiveStrand(row1);
773  TSeqPos l_pos0, r_pos0, l_pos1, r_pos1;
774 
775  l_seg = 0;
776  while (l_seg < m_NumSegs) {
777  l_len = m_Lens[l_seg];
778  next_aln_pos = aln_pos + l_len;
779  if (m_Starts[l_idx0] >= 0 && m_Starts[l_idx1] >= 0 &&
780  aln_start >= aln_pos && aln_start < next_aln_pos) {
781  // found the left seg
782  break;
783  }
784  aln_pos = next_aln_pos;
785  l_idx0 += m_NumRows; l_idx1 += m_NumRows;
786  l_seg++;
787  }
788  _ASSERT(l_seg < m_NumSegs);
789 
790  // determine left seq positions
791  l_pos0 = m_Starts[l_idx0];
792  l_pos1 = m_Starts[l_idx1];
793  _ASSERT(aln_start >= aln_pos);
794  l_delta = aln_start - aln_pos;
795  l_len -= l_delta;
796  if (plus0) {
797  l_pos0 += l_delta;
798  } else {
799  l_pos0 += l_len - 1;
800  }
801  if (plus1) {
802  l_pos1 += l_delta;
803  } else {
804  l_pos1 += l_len - 1;
805  }
806 
807  r_seg = m_NumSegs - 1;
808  int r_idx0 = r_seg * m_NumRows + row0;
809  int r_idx1 = r_seg * m_NumRows + row1;
810  aln_pos = GetAlnStop();
811  if (aln_stop > aln_pos) {
812  aln_stop = aln_pos;
813  }
814  while (r_seg >= 0) {
815  r_len = m_Lens[r_seg];
816  next_aln_pos = aln_pos - r_len;
817  if (m_Starts[l_idx0] >= 0 && m_Starts[l_idx1] >= 0 &&
818  aln_stop > next_aln_pos && aln_stop <= aln_pos) {
819  // found the right seg
820  break;
821  }
822  aln_pos = next_aln_pos;
823  r_idx0 -= m_NumRows; r_idx1 -= m_NumRows;
824  r_seg--;
825  }
826 
827  // determine right seq positions
828  r_pos0 = m_Starts[r_idx0];
829  r_pos1 = m_Starts[r_idx1];
830  _ASSERT(aln_pos >= aln_stop);
831  r_delta = aln_pos - aln_stop;
832  r_len -= r_delta;
833  if (plus0) {
834  r_pos0 += r_len - 1;
835  } else {
836  r_pos0 += r_delta;
837  }
838  if (plus1) {
839  r_pos1 += r_len - 1;
840  } else {
841  r_pos1 += r_delta;
842  }
843 
844  // We now know the size of the resulting vector
845  TSeqPos size = (plus0 ? r_pos0 - l_pos0 : l_pos0 - r_pos0) + 1;
846  result.resize(size, -1);
847 
848  // Initialize index positions (from left to right)
849  TSeqPos pos0 = plus0 ? 0 : l_pos0 - r_pos0;
850  TSeqPos pos1 = plus1 ? 0 : l_pos1 - r_pos1;
851 
852  // Initialize 'next' positions
853  // -- to determine if there are unaligned pieces
854  TSeqPos next_l_pos0 = plus0 ? l_pos0 + l_len : l_pos0 - l_len;
855  TSeqPos next_l_pos1 = plus1 ? l_pos1 + l_len : l_pos1 - l_len;
856 
857  l_idx0 = row0;
858  l_idx1 = row1;
859  TNumseg seg = l_seg;
861  while (true) {
862  if (m_Starts[l_idx0] >= 0) { // if row0 is not gapped
863 
864  if (seg > l_seg) {
865  // check for unaligned region / validate
866  if (plus0) {
867  delta = m_Starts[l_idx0] - next_l_pos0;
868  next_l_pos0 = m_Starts[l_idx0] + l_len;
869  } else {
870  delta = next_l_pos0 - m_Starts[l_idx0] - l_len + 1;
871  next_l_pos0 = m_Starts[l_idx0] - 1;
872  }
873  if (delta > 0) {
874  // unaligned region
875  if (plus0) {
876  pos0 += delta;
877  } else {
878  pos0 -= delta;
879  }
880  } else if (delta < 0) {
881  // invalid segment
882  string errstr = string("CAlnMap::GetResidueIndexMap():")
883  + " Starts are not consistent!"
884  + " Row=" + NStr::IntToString(row0) +
885  " Seg=" + NStr::IntToString(seg);
886  NCBI_THROW(CAlnException, eInvalidDenseg, errstr);
887  }
888  }
889 
890  if (m_Starts[l_idx1] >= 0) { // if row1 is not gapped
891 
892  if (seg > l_seg) {
893  // check for unaligned region / validate
894  if (plus1) {
895  delta = m_Starts[l_idx1] - next_l_pos1;
896  next_l_pos1 = m_Starts[l_idx1] + l_len;
897  } else {
898  delta = next_l_pos1 - m_Starts[l_idx1] - l_len + 1;
899  next_l_pos1 = m_Starts[l_idx1] - 1;
900  }
901  if (delta > 0) {
902  // unaligned region
903  if (plus1) {
904  pos1 += delta;
905  } else {
906  pos1 -= delta;
907  }
908  } else if (delta < 0) {
909  // invalid segment
910  string errstr = string("CAlnMap::GetResidueIndexMap():")
911  + " Starts are not consistent!"
912  + " Row=" + NStr::IntToString(row1) +
913  " Seg=" + NStr::IntToString(seg);
914  NCBI_THROW(CAlnException, eInvalidDenseg, errstr);
915  }
916  }
917 
918  if (plus0) {
919  if (plus1) { // if row1 on +
920  while (l_len--) {
921  result[pos0++] = pos1++;
922  }
923  } else { // if row1 on -
924  while (l_len--) {
925  result[pos0++] = pos1--;
926  }
927  }
928  } else { // if row0 on -
929  if (plus1) { // if row1 on +
930  while (l_len--) {
931  result[pos0--] = pos1++;
932  }
933  } else { // if row1 on -
934  while (l_len--) {
935  result[pos0--] = pos1--;
936  }
937  }
938  }
939  } else {
940  if (plus0) {
941  pos0 += l_len;
942  } else {
943  pos0 -= l_len;
944  }
945  }
946  }
947 
948  // iterate to next segment
949  seg++;
950  l_idx0 += m_NumRows;
951  l_idx1 += m_NumRows;
952  if (seg < r_seg) {
953  l_len = m_Lens[seg];
954  } else if (seg == r_seg) {
955  l_len = r_len;
956  } else {
957  break;
958  }
959  }
960 
961  // finally, set the ranges for the two sequences
962  rng0.SetFrom(plus0 ? l_pos0 : r_pos0);
963  rng0.SetTo(plus0 ? r_pos0 : l_pos0);
964  rng1.SetFrom(plus1 ? l_pos1 : r_pos1);
965  rng1.SetTo(plus1 ? r_pos1 : l_pos1);
966 }
967 
968 
970 {
971  if (IsSetAnchor()) {
972  TNumseg seg = -1;
973  while (++seg < (TNumseg) m_AlnSegIdx.size()) {
974  if (m_Starts[m_AlnSegIdx[seg] * m_NumRows + row] >= 0) {
975  return GetAlnStart(seg);
976  }
977  }
978  return -1;
979  } else {
981  }
982 }
983 
984 
986 {
987  if (IsSetAnchor()) {
988  TNumseg seg = TNumseg(m_AlnSegIdx.size());
989  while (seg--) {
990  if (m_Starts[m_AlnSegIdx[seg] * m_NumRows + row] >= 0) {
991  return GetAlnStop(seg);
992  }
993  }
994  return -1;
995  } else {
997  }
998 }
999 
1000 
1003  TGetChunkFlags flags) const
1004 {
1005  CRef<CAlnChunkVec> vec(new CAlnChunkVec(*this, row));
1006 
1007  // boundaries check
1008  if (range.GetTo() < 0
1009  || range.GetFrom() > (TSignedSeqPos) GetAlnStop(GetNumSegs() - 1)) {
1010  return vec;
1011  }
1012 
1013  // determine the participating segments range
1014  TNumseg left_seg, right_seg, aln_seg;
1015 
1016  if (range.GetFrom() < 0) {
1017  left_seg = 0;
1018  } else {
1019  left_seg = x_GetRawSegFromSeg(aln_seg = GetSeg(range.GetFrom()));
1020  if ( !(flags & fDoNotTruncateSegs) ) {
1021  vec->m_LeftDelta = range.GetFrom() - GetAlnStart(aln_seg);
1022  }
1023  }
1024  if ((TSeqPos)range.GetTo() > GetAlnStop(GetNumSegs()-1)) {
1025  right_seg = m_NumSegs-1;
1026  } else {
1027  right_seg = x_GetRawSegFromSeg(aln_seg = GetSeg(range.GetTo()));
1028  if ( !(flags & fDoNotTruncateSegs) ) {
1029  vec->m_RightDelta = GetAlnStop(aln_seg) - range.GetTo();
1030  }
1031  }
1032 
1033  x_GetChunks(vec, row, left_seg, right_seg, flags);
1034  return vec;
1035 }
1036 
1037 
1040  TGetChunkFlags flags) const
1041 {
1042  CRef<CAlnChunkVec> vec(new CAlnChunkVec(*this, row));
1043 
1044  // boundaries check
1045  if (range.GetTo() < (TSignedSeqPos)GetSeqStart(row) ||
1046  range.GetFrom() > (TSignedSeqPos)GetSeqStop(row)) {
1047  return vec;
1048  }
1049 
1050  // determine the participating segments range
1051  TNumseg left_seg = 0, right_seg = m_NumSegs - 1;
1052 
1053  if (range.GetFrom() >= (TSignedSeqPos)GetSeqStart(row)) {
1054  if (IsPositiveStrand(row)) {
1055  left_seg = GetRawSeg(row, range.GetFrom());
1056  vec->m_LeftDelta = range.GetFrom() - x_GetRawStart(row, left_seg);
1057  } else {
1058  right_seg = GetRawSeg(row, range.GetFrom());
1059  vec->m_RightDelta = range.GetFrom() - x_GetRawStart(row, right_seg);
1060  }
1061  }
1062  if (range.GetTo() <= (TSignedSeqPos)GetSeqStop(row)) {
1063  if (IsPositiveStrand(row)) {
1064  right_seg = GetRawSeg(row, range.GetTo());
1065  if ( !(flags & fDoNotTruncateSegs) ) {
1066  vec->m_RightDelta = x_GetRawStop(row, right_seg) - range.GetTo();
1067  }
1068  } else {
1069  left_seg = GetRawSeg(row, range.GetTo());
1070  if ( !(flags & fDoNotTruncateSegs) ) {
1071  vec->m_LeftDelta = x_GetRawStop(row, right_seg) - range.GetTo();
1072  }
1073  }
1074  }
1075 
1076  x_GetChunks(vec, row, left_seg, right_seg, flags);
1077  return vec;
1078 }
1079 
1080 
1081 inline
1083 {
1084  bool skip = false;
1085  if (type & fSeq) {
1087  if (flags & fSkipInserts) {
1088  skip = true;
1089  }
1090  } else {
1091  if (flags & fSkipAlnSeq) {
1092  skip = true;
1093  }
1094  }
1095  } else {
1097  if (flags & fSkipUnalignedGaps) {
1098  skip = true;
1099  }
1100  } else {
1101  if (flags & fSkipDeletions) {
1102  skip = true;
1103  }
1104  }
1105  }
1106  return skip;
1107 }
1108 
1109 
1110 inline
1111 bool
1113  TSegTypeFlags right_type,
1114  TGetChunkFlags flags) const
1115  // returns true if types are the same (as specified by flags)
1116 {
1117  if (flags & fChunkSameAsSeg) {
1118  return false;
1119  }
1120 
1121  if ((left_type & fSeq) != (right_type & fSeq)) {
1122  return false;
1123  }
1124  if (!(flags & fIgnoreUnaligned) &&
1125  (left_type & fUnalignedOnRight || right_type & fUnalignedOnLeft ||
1126  left_type & fUnalignedOnRightOnAnchor || right_type & fUnalignedOnLeftOnAnchor)) {
1127  return false;
1128  }
1129  if ((left_type & fNotAlignedToSeqOnAnchor) ==
1130  (right_type & fNotAlignedToSeqOnAnchor)) {
1131  return true;
1132  }
1133  if (left_type & fSeq) {
1134  if (!(flags & fInsertSameAsSeq)) {
1135  return false;
1136  }
1137  } else {
1138  if (!(flags & fDeletionSameAsGap)) {
1139  return false;
1140  }
1141  }
1142  return true;
1143 }
1144 
1146  TNumrow row,
1147  TNumseg left_seg, TNumseg right_seg,
1148  TGetChunkFlags flags) const
1149 {
1151 
1152  _ASSERT(left_seg <= right_seg);
1153  if (left_seg > right_seg) {
1155  eInvalidSegment | Critical,
1156  "Invalid segments range");
1157  }
1158 
1159  size_t hint_idx = m_NumRows * left_seg + row;
1160 
1161  // add the participating segments to the vector
1162  for (TNumseg seg = left_seg; seg <= right_seg; seg++, hint_idx += m_NumRows) {
1163  type = x_GetRawSegType(row, seg, int(hint_idx));
1164 
1165  // see if the segment needs to be skipped
1166  if (x_SkipType(type, flags)) {
1167  if (seg == left_seg) {
1168  vec->m_LeftDelta = 0;
1169  } else if (seg == right_seg) {
1170  vec->m_RightDelta = 0;
1171  }
1172  continue;
1173  }
1174 
1175  vec->m_StartSegs.push_back(seg); // start seg
1176 
1177  // find the stop seg
1178  TNumseg test_seg = seg;
1179  int test_hint_idx = int(hint_idx);
1180  while (test_seg < right_seg) {
1181  test_seg++;
1182  test_hint_idx += m_NumRows;
1183  test_type = x_GetRawSegType(row, test_seg, test_hint_idx);
1185  seg = test_seg;
1186  hint_idx = test_hint_idx;
1187  continue;
1188  }
1189 
1190  // include included gaps if desired
1191  if (flags & fIgnoreGaps && !(test_type & fSeq) &&
1193  continue;
1194  }
1195  break;
1196  }
1197  vec->m_StopSegs.push_back(seg);
1198 
1199  // add unaligned chunk if needed
1200  if (flags & fAddUnalignedChunks &&
1201  type & fUnalignedOnRight) {
1202  vec->m_StartSegs.push_back(seg+1);
1203  vec->m_StopSegs.push_back(seg);
1204  }
1205  }
1206 }
1207 
1208 
1211 {
1212  CAlnMap::TNumseg start_seg = m_StartSegs[i];
1213  CAlnMap::TNumseg stop_seg = m_StopSegs[i];
1214 
1215  CRef<CAlnChunk> chunk(new CAlnChunk());
1216 
1217  if (start_seg > stop_seg) {
1218  // flipped segs means this is unaligned region;
1219  // deal with it specially
1220 
1221  // type
1222  chunk->SetType(fUnaligned | fInsert);
1223 
1224  TSignedSeqPos
1225  l_from = -1,
1226  l_to = -1,
1227  r_from = -1,
1228  r_to = -1,
1229  aln_from = -1,
1230  aln_to = -1;
1232 
1233  // explore on the left
1234  for (TNumseg l_seg = start_seg - 1, idx = l_seg * m_AlnMap.m_NumRows + m_Row;
1235  l_seg >= 0;
1236  --l_seg, idx -= m_AlnMap.m_NumRows) {
1237 
1238  type = m_AlnMap.x_GetRawSegType(m_Row, l_seg, idx);
1239  if (type & fSeq && l_from == -1) {
1240  l_from = m_AlnMap.m_Starts[idx];
1241  l_to = l_from + m_AlnMap.x_GetLen(m_Row, l_seg) - 1;
1242  if (aln_to != -1) {
1243  break;
1244  }
1245  }
1246  if ( !(type & fNotAlignedToSeqOnAnchor) && type & fSeq &&
1247  aln_to == -1) {
1248  aln_to = m_AlnMap.GetAlnStop
1250  if (l_from != - 1) {
1251  break;
1252  }
1253  }
1254  }
1255 
1256  // explore on the right
1257  for (TNumseg r_seg = stop_seg + 1, idx = r_seg * m_AlnMap.m_NumRows + m_Row;
1258  r_seg < m_AlnMap.m_NumSegs;
1259  ++r_seg, idx += m_AlnMap.m_NumRows) {
1260 
1261  type = m_AlnMap.x_GetRawSegType(m_Row, r_seg, idx);
1262  if (type & fSeq && r_from == -1) {
1263  r_from = m_AlnMap.m_Starts[idx];
1264  r_to = r_from + m_AlnMap.x_GetLen(m_Row, r_seg) - 1;
1265  if (aln_from != -1) {
1266  break;
1267  }
1268  }
1269  if ( !(type & fNotAlignedToSeqOnAnchor) && type & fSeq &&
1270  aln_from == -1) {
1271  aln_from = m_AlnMap.GetAlnStart
1273  if (r_from != - 1) {
1274  break;
1275  }
1276  }
1277  }
1278 
1280  chunk->SetRange().Set(l_to + 1, r_from - 1);
1281  } else {
1282  chunk->SetRange().Set(r_to + 1, l_from - 1);
1283  }
1284  chunk->SetAlnRange().Set(aln_from, aln_to);
1285 
1286  return chunk;
1287  }
1288 
1289  TSignedSeqPos from, to;
1290  from = m_AlnMap.m_Starts[start_seg * m_AlnMap.m_NumRows
1291  + m_Row];
1292  if (from >= 0) {
1293  to = from + m_AlnMap.x_GetLen(m_Row, start_seg) - 1;
1294  } else {
1295  from = -1;
1296  to = -1;
1297  }
1298 
1299  chunk->SetRange().Set(from, to);
1300 
1301  int idx = start_seg * m_AlnMap.m_NumRows + m_Row;
1302  chunk->SetType(m_AlnMap.x_GetRawSegType(m_Row, start_seg, idx));
1303  idx += m_AlnMap.m_NumRows;
1304 
1306  for (CAlnMap::TNumseg seg = start_seg + 1;
1307  seg <= stop_seg;
1308  ++seg, idx += m_AlnMap.m_NumRows) {
1309 
1310  type = m_AlnMap.x_GetRawSegType(m_Row, seg, idx);
1311  if (type & fSeq) {
1312  // extend the range
1314  chunk->SetRange().Set(chunk->GetRange().GetFrom(),
1315  chunk->GetRange().GetTo()
1316  + m_AlnMap.x_GetLen(m_Row, seg));
1317  } else {
1318  chunk->SetRange().Set(chunk->GetRange().GetFrom()
1319  - m_AlnMap.x_GetLen(m_Row, seg),
1320  chunk->GetRange().GetTo());
1321  }
1322  }
1323  // extend the type
1324  chunk->SetType(chunk->GetType() | type);
1325  }
1326 
1327  //determine the aln range
1328  {{
1329  // from position
1331  if (seg.GetAlnSeg() < 0) {
1332  // before the aln start
1333  from = 0;
1334  } else {
1335  if (seg.GetOffset() > 0) {
1336  // between aln segs
1337  from = m_AlnMap.GetAlnStop(seg.GetAlnSeg()) + 1;
1338  } else {
1339  // at an aln seg
1340  from = m_AlnMap.GetAlnStart(seg.GetAlnSeg()) +
1341  (i == 0 && m_LeftDelta ? m_LeftDelta : 0);
1342  }
1343  }
1344 
1345  // to position
1346  seg = m_AlnMap.x_GetSegFromRawSeg(stop_seg);
1347  if (seg.GetAlnSeg() < 0) {
1348  // before the aln start
1349  to = -1;
1350  } else {
1351  if (seg.GetOffset() > 0) {
1352  // between aln segs
1353  to = m_AlnMap.GetAlnStop(seg.GetAlnSeg());
1354  } else {
1355  // at an aln seg
1356  to = m_AlnMap.GetAlnStop(seg.GetAlnSeg()) -
1357  (i == size() - 1 && m_RightDelta ? m_RightDelta : 0);
1358  }
1359  }
1360  chunk->SetAlnRange().Set(from, to);
1361  }}
1362 
1363 
1364  // fix if extreme end
1365  if (i == 0 && m_LeftDelta) {
1366  if (!chunk->IsGap()) {
1368  chunk->SetRange().Set
1369  (chunk->GetRange().GetFrom()
1371  chunk->GetRange().GetTo());
1372  } else {
1373  chunk->SetRange().Set(chunk->GetRange().GetFrom(),
1374  chunk->GetRange().GetTo()
1375  - m_LeftDelta
1376  * m_AlnMap.GetWidth(m_Row));
1377  }
1378  chunk->SetType(chunk->GetType() & ~fNoSeqOnLeft);
1379  }
1380  chunk->SetType(chunk->GetType() & ~(fUnalignedOnLeft | fEndOnLeft));
1381  }
1382  if (i == size() - 1 && m_RightDelta) {
1383  if (!chunk->IsGap()) {
1385  chunk->SetRange().Set
1386  (chunk->GetRange().GetFrom(),
1387  chunk->GetRange().GetTo()
1389  } else {
1390  chunk->SetRange().Set
1391  (chunk->GetRange().GetFrom()
1393  chunk->GetRange().GetTo());
1394  }
1395  chunk->SetType(chunk->GetType() & ~fNoSeqOnRight);
1396  }
1397  chunk->SetType(chunk->GetType() & ~(fUnalignedOnRight | fEndOnRight));
1398  }
1399 
1400  return chunk;
1401 }
1402 
1403 
1405  const vector<TNumrow>& selected_rows,
1406  TSignedSeqPos aln_from,
1407  TSignedSeqPos aln_to,
1408  ESegmentTrimFlag seg_flag)
1409 {
1410  CRef<CSeq_align> ret(new CSeq_align);
1412  CDense_seg& ds = ret->SetSegs().SetDenseg();
1413 
1414  bool have_strands = !m_Strands.empty();
1415  bool have_widths = !m_Widths.empty();
1416 
1417  // Initialize selected rows
1418  size_t dim = selected_rows.size();
1419  ret->SetDim(CSeq_align::TDim(dim));
1420  ds.SetDim(CDense_seg::TDim(dim));
1421  ds.SetIds().resize(dim);
1422  if ( have_widths ) {
1423  ds.SetWidths().resize(dim);
1424  }
1425  for (size_t i = 0; i < dim; i++) {
1426  TNumrow r = selected_rows[i];
1427  _ASSERT(r < m_NumRows);
1428  ds.SetIds()[i] = m_Ids[r];
1429  if ( have_widths ) {
1430  ds.SetWidths()[i] = m_Widths[r];
1431  }
1432  }
1433  TNumseg from_seg = GetSeg(aln_from);
1434  TNumseg to_seg = GetSeg(aln_to);
1435  if (from_seg < 0) {
1436  from_seg = 0;
1437  aln_from = 0;
1438  }
1439  if (to_seg < 0) {
1440  to_seg = m_NumSegs - 1;
1441  aln_to = GetAlnStop();
1442  }
1443 
1444  TNumseg num_seg = 0;
1445  CDense_seg::TStarts& starts = ds.SetStarts();
1446  for (TNumseg seg = from_seg; seg <= to_seg; seg++) {
1447  TSeqPos len = GetLen(seg);
1448 
1449  // Check trimming of the first segment
1450  TSeqPos aln_seg_from = GetAlnStart(seg);
1451  TSeqPos from_trim = 0;
1452  if (seg == from_seg && TSeqPos(aln_from) > aln_seg_from) {
1453  if (seg_flag == eSegment_Remove) {
1454  continue; // ignore incomplete segments
1455  }
1456  if (seg_flag == eSegment_Trim) {
1457  from_trim = aln_from - aln_seg_from;
1458  len -= from_trim;
1459  }
1460  }
1461  // Check trimming of the last segment
1462  if (seg == to_seg) {
1463  TSeqPos aln_seg_to = GetAlnStop(seg);
1464  if (aln_seg_to > TSeqPos(aln_to)) {
1465  if (seg_flag == eSegment_Remove) {
1466  continue; // ignore incomplete segments
1467  }
1468  if (seg_flag == eSegment_Trim) {
1469  len -= aln_seg_to - aln_to;
1470  }
1471  }
1472  }
1473  ds.SetLens().push_back(len);
1474  // Copy rows to the destination
1475  for (TNumrow row = 0; row < (TNumrow)selected_rows.size(); row++) {
1476  TSignedSeqPos row_start = GetStart(selected_rows[row], seg);
1477  if (row_start >= 0) {
1478  row_start += from_trim;
1479  }
1480  starts.push_back(row_start);
1481  if ( have_strands ) {
1482  ds.SetStrands().push_back(
1483  m_Strands[seg*m_NumRows + selected_rows[row]]);
1484  }
1485  }
1486  num_seg++;
1487  }
1488 
1489  // Ignore scores - if anythign was trimmed (and it probably was),
1490  // all scores are now useless.
1491 
1492  if (num_seg > 0) {
1493  ds.SetNumseg(num_seg);
1494  }
1495  else {
1496  ret.Reset();
1497  }
1498  return ret;
1499 }
1500 
1501 
1502 END_objects_SCOPE // namespace ncbi::objects::
CConstRef< CAlnChunk > operator[](TNumchunk i) const
Definition: alnmap.cpp:1210
const CAlnMap & m_AlnMap
Definition: alnmap.hpp:285
vector< TNumseg > m_StartSegs
Definition: alnmap.hpp:287
vector< TNumseg > m_StopSegs
Definition: alnmap.hpp:288
TNumchunk size(void) const
Definition: alnmap.hpp:258
TNumseg GetAlnSeg(void) const
Definition: alnmap.hpp:327
int GetOffset(void) const
Definition: alnmap.hpp:328
void x_GetChunks(CAlnChunkVec *vec, TNumrow row, TNumseg left_seg, TNumseg right_seg, TGetChunkFlags flags) const
Definition: alnmap.cpp:1145
TRawSegTypes * m_RawSegTypes
Definition: alnmap.hpp:384
TDim TNumrow
Definition: alnmap.hpp:69
void GetResidueIndexMap(TNumrow row0, TNumrow row1, TRange aln_rng, vector< TSignedSeqPos > &result, TRange &rng0, TRange &rng1) const
Definition: alnmap.cpp:757
bool IsSetAnchor(void) const
Definition: alnmap.hpp:524
TNumseg TNumchunk
Definition: alnmap.hpp:112
CRef< CSeq_align > CreateAlignFromRange(const vector< TNumrow > &selected_rows, TSignedSeqPos aln_from, TSignedSeqPos aln_to, ESegmentTrimFlag seg_flag=eSegment_Trim)
Definition: alnmap.cpp:1404
int GetWidth(TNumrow row) const
Definition: alnmap.hpp:560
TSignedSeqPos x_FindClosestSeqPos(TNumrow row, TNumseg seg, ESearchDirection dir, bool try_reverse_dir) const
Definition: alnmap.cpp:598
void x_Init(void)
Definition: alnmap.cpp:42
CRef< CAlnChunkVec > GetSeqChunks(TNumrow row, const TSignedRange &range, TGetChunkFlags flags=fAlnSegsOnly) const
Definition: alnmap.cpp:1039
const TNumseg & x_GetSeqLeftSeg(TNumrow row) const
Definition: alnmap.cpp:716
bool x_SkipType(TSegTypeFlags type, TGetChunkFlags flags) const
Definition: alnmap.cpp:1082
const CDense_seg::TStarts & m_Starts
Definition: alnmap.hpp:373
CNumSegWithOffset x_GetSegFromRawSeg(TNumseg seg) const
Definition: alnmap.hpp:539
TSeqPos x_GetLen(TNumrow row, TNumseg seg) const
Definition: alnmap.hpp:571
TNumseg m_NumSegs
Definition: alnmap.hpp:371
TNumseg GetRawSeg(TNumrow row, TSeqPos seq_pos, ESearchDirection dir=eNone, bool try_reverse_dir=true) const
Definition: alnmap.cpp:400
TSignedSeqPos GetStart(TNumrow row, TNumseg seg, int offset=0) const
Definition: alnmap.hpp:614
TSignedSeqPos GetAlnPosFromSeqPos(TNumrow row, TSeqPos seq_pos, ESearchDirection dir=eNone, bool try_reverse_dir=true) const
Definition: alnmap.cpp:527
ESegmentTrimFlag
Definition: alnmap.hpp:120
@ eSegment_Remove
Definition: alnmap.hpp:123
@ eSegment_Trim
Definition: alnmap.hpp:122
bool IsPositiveStrand(TNumrow row) const
Definition: alnmap.hpp:600
TSignedSeqPos GetSeqPosFromAlnPos(TNumrow for_row, TSeqPos aln_pos, ESearchDirection dir=eNone, bool try_reverse_dir=true) const
Definition: alnmap.cpp:663
const CDense_seg::TIds & m_Ids
Definition: alnmap.hpp:372
int TGetChunkFlags
Definition: alnmap.hpp:110
TNumseg GetSeg(TSeqPos aln_pos) const
Definition: alnmap.cpp:373
@ fUnalignedOnRight
Definition: alnmap.hpp:55
@ fEndOnRight
Definition: alnmap.hpp:59
@ fUnaligned
Definition: alnmap.hpp:61
@ fNoSeqOnRight
Definition: alnmap.hpp:57
@ fTypeIsSet
Definition: alnmap.hpp:65
@ fInsert
Definition: alnmap.hpp:54
@ fUnalignedOnLeftOnAnchor
Definition: alnmap.hpp:63
@ fUnalignedOnRightOnAnchor
Definition: alnmap.hpp:62
@ fNoSeqOnLeft
Definition: alnmap.hpp:58
@ fNotAlignedToSeqOnAnchor
Definition: alnmap.hpp:53
@ fSeq
Definition: alnmap.hpp:52
@ fUnalignedOnLeft
Definition: alnmap.hpp:56
@ fEndOnLeft
Definition: alnmap.hpp:60
TNumseg x_GetRawSegFromSeg(TNumseg seg) const
Definition: alnmap.hpp:547
vector< CNumSegWithOffset > m_NumSegWithOffsets
Definition: alnmap.hpp:383
TRawSegTypes & x_GetRawSegTypes() const
Definition: alnmap.hpp:699
TSignedSeqPos GetSeqAlnStart(TNumrow row) const
Definition: alnmap.cpp:969
bool x_CompareAdjacentSegTypes(TSegTypeFlags left_type, TSegTypeFlags right_type, TGetChunkFlags flags) const
Definition: alnmap.cpp:1112
TDim GetNumRows(void) const
Definition: alnmap.hpp:517
TSegTypeFlags x_SetRawSegType(TNumrow row, TNumseg seg) const
Definition: alnmap.cpp:125
TNumrow m_Anchor
Definition: alnmap.hpp:378
TSeqPos GetAlnStop(TNumseg seg) const
Definition: alnmap.hpp:488
void SetAnchor(TNumrow anchor)
Definition: alnmap.cpp:79
CDense_seg::TStarts m_AlnStarts
Definition: alnmap.hpp:382
vector< TNumseg > m_AlnSegIdx
Definition: alnmap.hpp:379
void x_CreateAlnStarts(void)
Definition: alnmap.cpp:49
vector< TNumseg > m_SeqLeftSegs
Definition: alnmap.hpp:380
const CDense_seg::TStrands & m_Strands
Definition: alnmap.hpp:375
const TNumseg & x_GetSeqRightSeg(TNumrow row) const
Definition: alnmap.cpp:736
TSegTypeFlags x_GetRawSegType(TNumrow row, TNumseg seg, int hint_idx=-1) const
Definition: alnmap.hpp:712
vector< TNumseg > m_SeqRightSegs
Definition: alnmap.hpp:381
CRef< CAlnChunkVec > GetAlnChunks(TNumrow row, const TSignedRange &range, TGetChunkFlags flags=fAlnSegsOnly) const
Definition: alnmap.cpp:1002
unsigned int TSegTypeFlags
Definition: alnmap.hpp:50
TSeqPos GetAlnStart(void) const
Definition: alnmap.hpp:177
TSignedSeqPos x_GetRawStop(TNumrow row, TNumseg seg) const
Definition: alnmap.hpp:584
TSeqPos GetLen(TNumseg seg, int offset=0) const
Definition: alnmap.hpp:621
CDense_seg::TNumseg TNumseg
Definition: alnmap.hpp:72
const CDense_seg::TWidths & m_Widths
Definition: alnmap.hpp:377
TNumrow m_NumRows
Definition: alnmap.hpp:370
TSeqPos GetAlnStop(void) const
Definition: alnmap.hpp:495
TSeqPos GetSeqStop(TNumrow row) const
Definition: alnmap.hpp:675
TSeqPos GetAlnStart(TNumseg seg) const
Definition: alnmap.hpp:481
@ fSkipInserts
Definition: alnmap.hpp:94
@ fSkipUnalignedGaps
Definition: alnmap.hpp:91
@ fDoNotTruncateSegs
Definition: alnmap.hpp:102
@ fSkipDeletions
Definition: alnmap.hpp:92
@ fSkipAlnSeq
Definition: alnmap.hpp:95
@ fIgnoreGaps
Definition: alnmap.hpp:88
@ fAddUnalignedChunks
Definition: alnmap.hpp:108
int StrandSign(TNumrow row) const
Definition: alnmap.hpp:593
TSignedSeqPos GetSeqAlnStop(TNumrow row) const
Definition: alnmap.cpp:985
void UnsetAnchor(void)
Definition: alnmap.cpp:63
TNumseg GetNumSegs(void) const
Definition: alnmap.hpp:510
TSeqPos GetSeqStart(TNumrow row) const
Definition: alnmap.hpp:665
void x_SetRawSegTypes(TNumrow row) const
Definition: alnmap.cpp:235
TSignedSeqPos GetSeqPosFromSeqPos(TNumrow for_row, TNumrow row, TSeqPos seq_pos, ESearchDirection dir=eNone, bool try_reverse_dir=true) const
Definition: alnmap.cpp:688
TSignedSeqPos x_GetRawStart(TNumrow row, TNumseg seg) const
Definition: alnmap.hpp:554
vector< TSegTypeFlags > TRawSegTypes
Definition: alnmap.hpp:342
const CDense_seg::TLens & m_Lens
Definition: alnmap.hpp:374
CConstRef –.
Definition: ncbiobj.hpp:1266
TWidths & SetWidths(void)
Definition: Dense_seg.hpp:217
CRef –.
Definition: ncbiobj.hpp:618
ESearchDirection
Position search options.
@ eNone
No search.
@ eRight
Towards higher aln coord (always to the right)
@ eLeft
Towards lower aln coord (always to the left)
@ eBackwards
Towards lower seq coord (to the left if plus strand, right if minus)
@ eForward
Towards higher seq coord (to the right if plus strand, left if minus)
static uch flags
static void test_type(TDSSOCKET *tds, TDSCOLUMN *col)
Definition: all_types.c:18
static DLIST_TYPE *DLIST_NAME() last(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:51
static int type
Definition: getdata.c:31
static const struct type types[]
Definition: type.c:22
int offset
Definition: replacements.h:160
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:875
int TSignedSeqPos
Type for signed sequence position.
Definition: ncbimisc.hpp:887
string
Definition: cgiapp.hpp:687
void Critical(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1203
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5084
void SetFrom(TFrom value)
Assign a value to From data member.
Definition: Range_.hpp:231
TTo GetTo(void) const
Get the To member data.
Definition: Range_.hpp:269
TFrom GetFrom(void) const
Get the From member data.
Definition: Range_.hpp:222
void SetTo(TTo value)
Assign a value to To data member.
Definition: Range_.hpp:278
TLens & SetLens(void)
Assign a value to Lens data member.
Definition: Dense_seg_.hpp:561
void SetSegs(TSegs &value)
Assign a value to Segs data member.
Definition: Seq_align_.cpp:310
void SetDim(TDim value)
Assign a value to Dim data member.
Definition: Seq_align_.hpp:865
vector< TSignedSeqPos > TStarts
Definition: Dense_seg_.hpp:107
void SetDim(TDim value)
Assign a value to Dim data member.
Definition: Dense_seg_.hpp:427
void SetType(TType value)
Assign a value to Type data member.
Definition: Seq_align_.hpp:818
TStarts & SetStarts(void)
Assign a value to Starts data member.
Definition: Dense_seg_.hpp:536
TStrands & SetStrands(void)
Assign a value to Strands data member.
Definition: Dense_seg_.hpp:586
void SetNumseg(TNumseg value)
Assign a value to Numseg data member.
Definition: Dense_seg_.hpp:474
TIds & SetIds(void)
Assign a value to Ids data member.
Definition: Dense_seg_.hpp:511
@ eType_partial
mapping pieces together
Definition: Seq_align_.hpp:103
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
int i
int len
range(_Ty, _Ty) -> range< _Ty >
const struct ncbi::grid::netcache::search::fields::SIZE size
T plus(T x_)
Int4 delta(size_t dimension_, const Int4 *score_)
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
#define row(bind, expected)
Definition: string_bind.c:73
Definition: type.c:6
#define _ASSERT
else result
Definition: token2.c:20
Modified on Wed Apr 17 13:09:41 2024 by modify_doxy.py rev. 669887