yat  0.14.5pre
BamPairIterator.h
1 #ifndef theplu_yat_omic_bam_pair_iterator
2 #define theplu_yat_omic_bam_pair_iterator
3 
4 // $Id: BamPairIterator.h 3550 2017-01-03 05:41:02Z peter $
5 
6 /*
7  Copyright (C) 2014, 2016 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 this program. 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 #include <boost/shared_ptr.hpp>
35 
36 #include <iterator>
37 #include <map>
38 #include <utility>
39 
40 namespace theplu {
41 namespace yat {
42 namespace omic {
43 
62  template<typename Base>
64  : public boost::iterator_facade<
65  BamPairIterator<Base>, const BamPair, std::input_iterator_tag,
66  const BamPairProxy
67  >
68  {
69  public:
73  BamPairIterator(void);
74 
83  explicit BamPairIterator(Base begin, Base end);
84 
85 #ifndef YAT_HAVE_BOOST_ITERATOR_FACADE_PROXY_PTR
86 
92  typename BamPairIterator::pointer operator->(void) const
93  {
94  // older versions of boost mandates pointer to be
95  // value_type*. To accomplish that we implement this slow thing
96  // which keeps a copy of a value_type as member.
97  // See https://svn.boost.org/trac/boost/ticket/5697 for discussion.
98 
99  // Possibly stupid to assign each time, but why bother optimize
100  // for old bugs in boost. Users who are eager for speed, should
101  // either upgrade their boost or use (*iterator).function()
102  // rather than iterator->function().
103  YAT_ASSERT(mate_);
104  YAT_ASSERT(iter_ != end_);
105  dummie_.first() = *mate_;
106  dummie_.second() = *iter_;
107  return &dummie_;
108  }
109  private:
110  mutable BamPair dummie_;
111 #endif
112 
113  private:
114  Base iter_;
115  Base end_;
116  const BamRead* mate_;
117  boost::shared_ptr<std::map<std::string, BamRead> > siam_reads_;
118  typedef std::pair<int32_t, int32_t> Position;
119  boost::shared_ptr<std::multimap<Position, BamRead> > reads_;
120  friend class boost::iterator_core_access;
121 
122  const BamPairProxy dereference(void) const;
123  bool equal(const BamPairIterator& other) const;
124  void increment(void);
125  void find_next(void);
126  };
127 
128 
134  template<typename Base>
136  { return BamPairIterator<Base>(base, end); }
137 
138 
145  template<typename Base>
147  { return BamPairIterator<Base>(end, end); }
148 
149 
150  // template implementations
152 
153  template<typename Base>
155  : iter_(base), end_(end),
156  siam_reads_(new std::map<std::string, BamRead>),
157  reads_(new std::multimap<Position, BamRead>)
158  {
159  BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<Base>));
160  BOOST_CONCEPT_ASSERT((boost_concepts::SinglePassIterator<Base>));
161  using boost::Convertible;
162  typedef typename std::iterator_traits<Base>::value_type value_type;
163  BOOST_CONCEPT_ASSERT((Convertible<value_type, BamRead>));
164  find_next();
165  }
166 
167 
168  template<typename Base>
170  {
171  BOOST_CONCEPT_ASSERT((boost::InputIterator<Base>));
172  using boost::Convertible;
173  typedef typename std::iterator_traits<Base>::value_type value_type;
174  BOOST_CONCEPT_ASSERT((Convertible<value_type, BamRead>));
175  }
176 
177 
178  template<typename Base>
179  const BamPairProxy
181  {
182  return BamPairProxy(mate_, &*iter_);
183  }
184 
185 
186  template<typename Base>
187  bool BamPairIterator<Base>::equal(const BamPairIterator& other) const
188  {
189  return iter_ == other.iter_;
190  }
191 
192 
193  template<typename Base>
194  void BamPairIterator<Base>::increment(void)
195  {
196  ++iter_;
197  find_next();
198  }
199 
200 
201  template<typename Base>
202  void BamPairIterator<Base>::find_next(void)
203  {
204  BamLessPos less;
205  for (; iter_!=end_; ++iter_) {
206  Position position(iter_->tid(), iter_->pos());
207  Position mate_position(iter_->mtid(), iter_->mpos());
208  // clear siam reads if iter is more advanced than siam reads
209  if (siam_reads_->size() && less(siam_reads_->begin()->second, *iter_))
210  siam_reads_->clear();
211 
212  // have not seen mate yet
213  if (mate_position > position)
214  reads_->insert(std::make_pair(mate_position, *iter_));
215  else if (position > mate_position) {
216  std::multimap<Position, BamRead>::iterator
217  lower = reads_->lower_bound(position);
218  // erase all reads with mate position less than current
219  // position (assuming input range is sorted)
220  reads_->erase(reads_->begin(), lower);
221 
222  // find mate and assign pair
223  for (; lower!=reads_->end() && lower->first == position; ++lower)
224  if (same_query_name(lower->second, *iter_)) {
225  mate_ = &lower->second;
226  return;
227  }
228  }
229  else { // siam read, i.e., iter_ and mate have same position
230  // check if we have already seen mate and stored it in map
231  std::map<std::string, BamRead>::iterator
232  mate = siam_reads_->lower_bound(iter_->name());
233  if (mate!=siam_reads_->end() && same_query_name(mate->second, *iter_)) {
234  mate_ = &mate->second;
235  return;
236  }
237  else
238  // insert with hint
239  siam_reads_->insert(mate, std::make_pair(iter_->name(), *iter_));
240  }
241  }
242  }
243 
244 }}}
245 #endif
BamPairIterator(void)
default constructor
Definition: BamPairIterator.h:169
BamRead & first(void)
access first BamRead
Definition: BamPair.h:34
BamPairIterator::pointer operator->(void) const
Definition: BamPairIterator.h:92
Definition: BamPair.h:84
Class holding a bam query.
Definition: BamRead.h:53
BamPairIterator< Base > bam_pair_iterator(Base end)
Definition: BamPairIterator.h:146
Definition: BamPairIterator.h:63
BamPairIterator< Base > bam_pair_iterator(Base base, Base end)
Definition: BamPairIterator.h:135
BamRead & second(void)
access second BamRead

Generated on Tue Sep 26 2017 02:33:29 for yat by  doxygen 1.8.5