vdj_pipe
pipeline for processing DNA sequence data
read_info_store.hpp
Go to the documentation of this file.
1 
7 #ifndef READ_INFO_STORE_HPP_
8 #define READ_INFO_STORE_HPP_
9 #include <limits>
10 #include "boost/assert.hpp"
11 #include "boost/multi_index_container.hpp"
12 #include "boost/multi_index/hashed_index.hpp"
13 #include "boost/multi_index/ordered_index.hpp"
14 #include "boost/range.hpp"
15 #include "boost/noncopyable.hpp"
16 
21 #include "vdj_pipe/exception.hpp"
22 #include "vdj_pipe/object_ids.hpp"
23 #include "vdj_pipe/read_info.hpp"
25 
26 namespace vdj_pipe{
27 
30 class Read_info_store : boost::noncopyable {
32 
33  typedef detail::Getter<
34  info_map_t, Read_id, Read_info,
35  std::string const&, &Read_info::name
36  > get_name;
37 
38  typedef detail::Getter<
39  info_map_t, Read_id, Read_info,
40  unsigned, &Read_info::size
41  > get_info_size;
42 
43  typedef boost::multi_index_container<
44  Read_id,
45  boost::multi_index::indexed_by<
46  boost::multi_index::hashed_non_unique<
47  boost::multi_index::tag<struct name_tag>,
48  get_name
49  >,
50  boost::multi_index::ordered_non_unique<
51  boost::multi_index::tag<struct size_tag>,
52  get_info_size
53  >
54  >
55  > info_mi_t;
56  typedef info_mi_t::index<name_tag>::type name_index_t;
57  typedef name_index_t::const_iterator name_citer_t;
58  typedef name_index_t::iterator name_iter;
59  typedef boost::iterator_range<name_iter> name_range;
60  typedef info_mi_t::index<size_tag>::type info_size_index_t;
61 
62  static info_mi_t::ctor_args_list info_index_init(info_map_t const& im) {
63  return boost::make_tuple(
64  boost::make_tuple(
65  0,
66  get_name(im),
67  boost::hash<std::string>(),
68  std::equal_to<std::string>()
69  ),
70  boost::make_tuple(get_info_size(im), std::less<unsigned>())
71  );
72  }
73 public:
74  typedef name_citer_t const_iterator;
75  typedef info_size_index_t::const_iterator size_iterator;
76  typedef boost::iterator_range<size_iterator> size_range;
77 
78  struct Err : public base_exception {};
79 
81  : info_map_(Read_id(1)),
82  info_index_(info_index_init(info_map_))
83  {}
84 
85  std::size_t size() const {return info_index_.size();}
86  bool empty() const {return info_index_.empty();}
87  const_iterator begin() const {return info_index_.begin();}
88  const_iterator end() const {return info_index_.end();}
89 
91  size_range by_size() const {return boost::make_iterator_range(info_index_.get<size_tag>());}
92 
94  size_range by_size(const unsigned size) const {
95  return boost::make_iterator_range(
96  info_index_.get<size_tag>().equal_range(size)
97  );
98  }
99 
101  size_range by_size_range(
102  const unsigned from,
103  const unsigned to = std::numeric_limits<unsigned>::max()
104  ) const {
105  return boost::make_iterator_range(
106  info_index_.get<size_tag>().lower_bound(from),
107  info_index_.get<size_tag>().upper_bound(to)
108  );
109  }
110 
111  Read_info const& operator[](const Read_id iid) const {return info_map_[iid];}
112 
113  Read_id const* find(const boost::string_ref id, const bool reverse) const {
114  name_index_t const& ind = info_index_.get<name_tag>();
115  const name_citer_t i = find_iter(id, reverse);
116  return i == ind.end() ? 0 : &(*i);
117  }
118 
119  Read_id insert(Read_info const& ri) {
120  name_index_t& ind = info_index_.get<name_tag>();
121  name_iter i = find_iter(ri.name(), ri.is_reverse());
122  if( i == ind.end() ) {
123  const Read_id rid = info_map_.insert(ri);
124  info_index_.insert(rid);
125  return rid;
126  }
127  const Read_id rid = *i;
128  info_map_[rid].combine(ri);
129  ind.replace(i, rid);
130  return rid;
131  }
132 
133 private:
134  info_map_t info_map_;
135  info_mi_t info_index_;
136 
137  name_iter find_iter(const boost::string_ref id, const bool reverse) const {
138  name_index_t const& ind = info_index_.get<name_tag>();
139  name_range r = ind.equal_range(
140  id,
141  boost::hash<boost::string_ref>(),
143  );
144  name_iter i = r.begin();
145  if( i == ind.end() || i == r.end() ) return ind.end();
146  if( info_map_[*i].is_reverse() == reverse ) return i;
147  ++i;
148  if( i == r.end() ) return ind.end();
149  if( info_map_[*i].is_reverse() == reverse ) return i;
150  BOOST_ASSERT(false && "one of two reads should match");
151  return ind.end();
152  }
153 
154 };
155 
156 }//namespace vdj_pipe
157 #endif /* READ_INFO_STORE_HPP_ */
size_range by_size(const unsigned size) const
Definition: read_info_store.hpp:94
size_range by_size_range(const unsigned from, const unsigned to=std::numeric_limits< unsigned >::max()) const
Definition: read_info_store.hpp:101
size_range by_size() const
Definition: read_info_store.hpp:91
Main namespace of vdj_pipe library.
Definition: sequence_file.hpp:14
Definition: string_ref.hpp:23
Definition: read_info.hpp:18
Definition: exception.hpp:23
Definition: read_info_store.hpp:78
Store sequence-related information.
Definition: read_info_store.hpp:30
Extract object by its ID and apply member function.
Definition: get_by_id.hpp:25