yat  0.21pre
BamPairIterator.h
1 #ifndef _theplu_yat_omic_bam_pair_iterator_
2 #define _theplu_yat_omic_bam_pair_iterator_
3 
4 // $Id: BamPairIterator.h 4089 2021-09-07 00:56:40Z peter $
5 
6 /*
7  Copyright (C) 2014, 2016, 2018, 2020, 2021 Peter Johansson
8 
9  This file is part of the yat library, http://dev.thep.lu.se/yat
10 
11  The yat library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU General Public License as
13  published by the Free Software Foundation; either version 3 of the
14  License, or (at your option) any later version.
15 
16  The yat library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with yat. If not, see <http://www.gnu.org/licenses/>.
23 */
24 
25 #include "BamPair.h"
26 #include "BamRead.h"
27 
29 #include <yat/utility/yat_assert.h>
30 
31 #include <boost/concept/assert.hpp>
32 #include <boost/iterator/iterator_concepts.hpp>
33 #include <boost/iterator/iterator_facade.hpp>
34 
35 #include <iterator>
36 #include <map>
37 #include <memory>
38 #include <utility>
39 
40 namespace theplu {
41 namespace yat {
42 namespace omic {
43 
64  template<typename Base>
66  : public boost::iterator_facade<
67  BamPairIterator<Base>, const BamPair, std::input_iterator_tag,
68  const BamPairProxy
69  >
70  {
71  public:
75  BamPairIterator(void);
76 
85  explicit BamPairIterator(Base begin, Base end);
86 
87 #ifndef YAT_HAVE_BOOST_ITERATOR_FACADE_PROXY_PTR
88 
94  typename BamPairIterator::pointer operator->(void) const
95  {
96  // older versions of boost mandates pointer to be
97  // value_type*. To accomplish that we implement this slow thing
98  // which keeps a copy of a value_type as member.
99  // See https://svn.boost.org/trac/boost/ticket/5697 for discussion.
100 
101  // Possibly stupid to assign each time, but why bother optimize
102  // for old bugs in boost. Users who are eager for speed, should
103  // either upgrade their boost or use (*iterator).function()
104  // rather than iterator->function().
105  YAT_ASSERT(mate_);
106  YAT_ASSERT(iter_ != end_);
107  dummie_.first() = *mate_;
108  dummie_.second() = *iter_;
109  return &dummie_;
110  }
111  private:
112  mutable BamPair dummie_;
113 #endif
114 
115  private:
116  Base iter_;
117  Base end_;
118  const BamRead* mate_;
119  std::shared_ptr<std::map<std::string, BamRead> > siam_reads_;
120  typedef std::pair<int32_t, int32_t> Position;
121  std::shared_ptr<std::multimap<Position, BamRead> > reads_;
122  friend class boost::iterator_core_access;
123 
124  const BamPairProxy dereference(void) const;
125  bool equal(const BamPairIterator& other) const;
126  void increment(void);
127  void find_next(void);
128  };
129 
130 
136  template<typename Base>
138  { return BamPairIterator<Base>(base, end); }
139 
140 
147  template<typename Base>
149  { return BamPairIterator<Base>(end, end); }
150 
151 
152  // template implementations
154 
155  template<typename Base>
157  : iter_(base), end_(end),
158  siam_reads_(new std::map<std::string, BamRead>),
159  reads_(new std::multimap<Position, BamRead>)
160  {
161  BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<Base>));
162  BOOST_CONCEPT_ASSERT((boost_concepts::SinglePassIterator<Base>));
163  using boost::Convertible;
164  typedef typename std::iterator_traits<Base>::value_type value_type;
165  BOOST_CONCEPT_ASSERT((Convertible<value_type, BamRead>));
166  find_next();
167  }
168 
169 
170  template<typename Base>
172  {
173  BOOST_CONCEPT_ASSERT((boost::InputIterator<Base>));
174  using boost::Convertible;
175  typedef typename std::iterator_traits<Base>::value_type value_type;
176  BOOST_CONCEPT_ASSERT((Convertible<value_type, BamRead>));
177  }
178 
179 
180  template<typename Base>
181  const BamPairProxy
183  {
184  return BamPairProxy(mate_, &*iter_);
185  }
186 
187 
188  template<typename Base>
189  bool BamPairIterator<Base>::equal(const BamPairIterator& other) const
190  {
191  return iter_ == other.iter_;
192  }
193 
194 
195  template<typename Base>
196  void BamPairIterator<Base>::increment(void)
197  {
198  ++iter_;
199  find_next();
200  }
201 
202 
203  template<typename Base>
204  void BamPairIterator<Base>::find_next(void)
205  {
206  BamLessPos less;
207  for (; iter_!=end_; ++iter_) {
208  Position position(iter_->tid(), iter_->pos());
209  Position mate_position(iter_->mtid(), iter_->mpos());
210  // clear siam reads if iter is more advanced than siam reads
211  if (siam_reads_->size() && less(siam_reads_->begin()->second, *iter_))
212  siam_reads_->clear();
213 
214  // have not seen mate yet
215  if (mate_position > position)
216  reads_->insert(std::make_pair(mate_position, *iter_));
217  else if (position > mate_position) {
218  std::multimap<Position, BamRead>::iterator
219  lower = reads_->lower_bound(position);
220  // erase all reads with mate position less than current
221  // position (assuming input range is sorted)
222  reads_->erase(reads_->begin(), lower);
223 
224  // find mate and assign pair
225  for (; lower!=reads_->end() && lower->first == position; ++lower)
226  if (same_query_name(lower->second, *iter_)) {
227  mate_ = &lower->second;
228  return;
229  }
230  }
231  else { // siam read, i.e., iter_ and mate have same position
232  // check if we have already seen mate and stored it in map
233  std::map<std::string, BamRead>::iterator
234  mate = siam_reads_->lower_bound(iter_->name());
235  if (mate!=siam_reads_->end() && same_query_name(mate->second, *iter_)) {
236  mate_ = &mate->second;
237  return;
238  }
239  else
240  // insert with hint
241  siam_reads_->insert(mate, std::make_pair(iter_->name(), *iter_));
242  }
243  }
244  }
245 
246 }}}
247 #endif
BamPairIterator(void)
default constructor
Definition: BamPairIterator.h:171
BamRead & first(void)
access first BamRead
Definition: BamPair.h:34
The Department of Theoretical Physics namespace as we define it.
Definition: stl_utility.h:64
Definition: BamPair.h:91
Class holding a bam query.
Definition: BamRead.h:51
BamPairIterator< Base > bam_pair_iterator(Base end)
Definition: BamPairIterator.h:148
Definition: BamPairIterator.h:65
BamPairIterator< Base > bam_pair_iterator(Base base, Base end)
Definition: BamPairIterator.h:137
BamPairIterator::pointer operator->(void) const
Definition: BamPairIterator.h:94
BamRead & second(void)
access second BamRead

Generated on Wed Jan 25 2023 03:34:29 for yat by  doxygen 1.8.14