A library for working with phylogenetic and population genetic data.
v0.27.0
sliding_variants_window_iterator.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_POPULATION_WINDOW_SLIDING_VARIANTS_WINDOW_ITERATOR_H_
2 #define GENESIS_POPULATION_WINDOW_SLIDING_VARIANTS_WINDOW_ITERATOR_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2022 Lucas Czech
7 
8  This program is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21  Contact:
22  Lucas Czech <lczech@carnegiescience.edu>
23  Department of Plant Biology, Carnegie Institution For Science
24  260 Panama Street, Stanford, CA 94305, USA
25 */
26 
35 
36 #include <cassert>
37 #include <functional>
38 #include <stdexcept>
39 #include <string>
40 #include <type_traits>
41 #include <utility>
42 
43 namespace genesis {
44 namespace population {
45 
46 // =================================================================================================
47 // Sliding Variants Window Iterator
48 // =================================================================================================
49 
65 template<class ForwardIterator, class DataType = typename ForwardIterator::value_type>
66 class SlidingVariantsWindowIterator final : public BaseWindowIterator<ForwardIterator, DataType>
67 {
68 public:
69 
70  // -------------------------------------------------------------------------
71  // Typedefs and Enums
72  // -------------------------------------------------------------------------
73 
76 
78  using Entry = typename Window::Entry;
79  using InputType = typename ForwardIterator::value_type;
80 
81  using iterator_category = std::input_iterator_tag;
82  using value_type = Window;
83  using pointer = value_type*;
85  using const_reference = value_type const&;
86 
87  // ======================================================================================
88  // Internal Iterator
89  // ======================================================================================
90 
94  class DerivedIterator final : public BaseWindowIterator<ForwardIterator, DataType>::BaseIterator
95  {
96  public:
97 
98  // -------------------------------------------------------------------------
99  // Constructors and Rule of Five
100  // -------------------------------------------------------------------------
101 
102  using self_type = typename SlidingVariantsWindowIterator<
103  ForwardIterator, DataType
105 
106  using base_iterator_type = typename BaseWindowIterator<
107  ForwardIterator, DataType
109 
111  using Entry = typename Window::Entry;
112  using InputType = typename ForwardIterator::value_type;
113 
114  using iterator_category = std::input_iterator_tag;
116  using pointer = value_type*;
118  using const_reference = value_type const&;
119 
120  private:
121 
122  DerivedIterator() = default;
123 
125  SlidingVariantsWindowIterator const* parent
126  )
127  : base_iterator_type( parent )
128  , parent_( parent )
129  {
130  // Edge case check. See Base for details.
131  if( ! parent_ ) {
132  return;
133  }
134 
135  // Call the base class initializer.
136  // base_iterator_type::init_( parent_ );
137 
138  // Check our own the settings.
139  if( parent_->width_ == 0 ) {
140  throw std::runtime_error( "Cannot use SlidingVariantsWindowIterator of width 0." );
141  }
142  if( parent_->stride_ == 0 ) {
143  parent_->stride_ = parent_->width_;
144  }
145  if( parent_->stride_ > parent_->width_ ) {
146  throw std::runtime_error(
147  "Cannot use SlidingVariantsWindowIterator with stride > width."
148  );
149  }
150 
151  // Let's get going.
152  init_chromosome_();
153  update_();
154  }
155 
156  public:
157 
158  ~DerivedIterator() = default;
159 
160  DerivedIterator( self_type const& ) = default;
161  DerivedIterator( self_type&& ) = default;
162 
163  DerivedIterator& operator= ( self_type const& ) = default;
164  DerivedIterator& operator= ( self_type&& ) = default;
165 
167 
168  // -------------------------------------------------------------------------
169  // Internal and Virtual Members
170  // -------------------------------------------------------------------------
171 
172  private:
173 
174  void init_chromosome_()
175  {
176  // Saveguard. This might be called on an empty range, in which case we just do nothing.
177  if( base_iterator_type::current_ == base_iterator_type::end_ ) {
178  return;
179  }
180 
181  // Clear the window and prepare for new chromosome.
182  window_.clear();
183  window_.chromosome( parent_->chromosome_function( *base_iterator_type::current_ ));
184  base_iterator_type::is_first_window_ = true;
185  base_iterator_type::is_last_window_ = false;
186  next_index_ = 0;
187 
188  // Set the start to the window position that we would get after going through all
189  // the previous windows if they were emitted.
190  auto const pos = parent_->position_function( *base_iterator_type::current_ );
191  current_start_ = pos - (( pos - 1 ) % parent_->stride_ );
192  }
193 
194  void increment_() override final
195  {
196  // Dequeue everything that we do not want to keep. If stride == width (default case),
197  // we can simply remove everything at once, for speed.
198  if( parent_->stride_ == parent_->width_ ) {
199  window_.entries().clear();
200  } else {
201  for( size_t i = 0; i < parent_->stride_; ++i ) {
202  if( window_.empty() ) {
203  // Edge case when we start with a new empty window.
204  break;
205  }
206  window_.entries().pop_front();
207  }
208  }
209 
210  // Now enqueue new entries.
211  for( size_t i = 0; i < parent_->stride_; ++i ) {
212  /* code */
213  }
214 
215  we need a way to check if we run out of data before this so that we can set the last window property already in case
216  }
217 
218  value_type& get_current_window_() const override final
219  {
220  return const_cast<value_type&>( window_ );
221  }
222 
223  BaseWindowIterator<ForwardIterator, DataType> const* get_parent_() const override final
224  {
225  return parent_;
226  }
227 
228  private:
229 
230  // Parent. Needs to live here to have the correct derived type.
231  SlidingVariantsWindowIterator const* parent_ = nullptr;
232 
233  // Current window and its position
234  Window window_;
235  size_t current_start_ = 1;
236  size_t next_index_ = 0;
237 
238  };
239 
240  // ======================================================================================
241  // Main Class
242  // ======================================================================================
243 
244  // -------------------------------------------------------------------------
245  // Constructors and Rule of Five
246  // -------------------------------------------------------------------------
247 
249  ForwardIterator begin, ForwardIterator end
250  )
251  : base_type( begin, end )
252  {}
253 
254  ~SlidingVariantsWindowIterator() = default;
255 
258 
261 
263 
264  // -------------------------------------------------------------------------
265  // Settings
266  // -------------------------------------------------------------------------
267 
274  self_type& width( size_t value )
275  {
276  width_ = value;
277  return *this;
278  }
279 
280  size_t width() const
281  {
282  return width_;
283  }
284 
292  self_type& stride( size_t value )
293  {
294  stride_ = value;
295  return *this;
296  }
297 
298  size_t stride() const
299  {
300  return stride_;
301  }
302 
303  // -------------------------------------------------------------------------
304  // Virtual Members
305  // -------------------------------------------------------------------------
306 
307 protected:
308 
309  std::unique_ptr<typename BaseWindowIterator<ForwardIterator, DataType>::BaseIterator>
310  get_begin_iterator_() override final
311  {
312  // Cannot use make_unique here, as the Iterator constructor is private,
313  // and trying to make make_unique a friend does not seem to be working...
314  return std::unique_ptr<DerivedIterator>( new DerivedIterator( this ));
315  // return utils::make_unique<DerivedIterator>( this );
316  }
317 
318  std::unique_ptr<typename BaseWindowIterator<ForwardIterator, DataType>::BaseIterator>
319  get_end_iterator_() override final
320  {
321  return std::unique_ptr<DerivedIterator>( new DerivedIterator( nullptr ));
322  // return utils::make_unique<DerivedIterator>( nullptr );
323  }
324 
325  // -------------------------------------------------------------------------
326  // Data Members
327  // -------------------------------------------------------------------------
328 
329 private:
330 
331  // Settings. We make stride_ mutable so that the iterator can set it to the width.
332  size_t width_ = 0;
333  mutable size_t stride_ = 0;
334 
335 };
336 
337 // =================================================================================================
338 // Make Sliding Window Iterator
339 // =================================================================================================
340 
345 template<class ForwardIterator, class DataType = typename ForwardIterator::value_type>
346 SlidingVariantsWindowIterator<ForwardIterator, DataType>
348  ForwardIterator begin, ForwardIterator end, size_t width = 0, size_t stride = 0
349 ) {
351  it.width( width );
352  it.stride( stride );
353  return it;
354 }
355 
366 template<class ForwardIterator>
367 SlidingVariantsWindowIterator<ForwardIterator>
369  ForwardIterator begin, ForwardIterator end, size_t width = 0, size_t stride = 0
370 ) {
371  using DataType = typename ForwardIterator::value_type;
372 
373  // Set functors.
374  auto it = SlidingVariantsWindowIterator<ForwardIterator>( begin, end );
375  it.entry_input_function = []( DataType const& variant ) {
376  return variant;
377  };
378  it.chromosome_function = []( DataType const& variant ) {
379  return variant.chromosome;
380  };
381  it.position_function = []( DataType const& variant ) {
382  return variant.position;
383  };
384 
385  // Set properties.
386  it.width( width );
387  it.stride( stride );
388  return it;
389 }
390 
391 } // namespace population
392 } // namespace genesis
393 
394 #endif // include guard
genesis::population::make_sliding_variants_window_iterator
SlidingVariantsWindowIterator< ForwardIterator, DataType > make_sliding_variants_window_iterator(ForwardIterator begin, ForwardIterator end, size_t width=0, size_t stride=0)
Helper function to instantiate a SlidingVariantsWindowIterator without the need to specify the templa...
Definition: sliding_variants_window_iterator.hpp:347
genesis::population::SlidingVariantsWindowIterator::Window
::genesis::population::Window< DataType > Window
Definition: sliding_variants_window_iterator.hpp:77
genesis::population::BaseWindowIterator
Base iterator class for Windows over the chromosomes of a genome.
Definition: base_window_iterator.hpp:106
genesis::population::SlidingVariantsWindowIterator::InputType
typename ForwardIterator::value_type InputType
Definition: sliding_variants_window_iterator.hpp:79
genesis::population::BaseWindowIterator::BaseIterator::BaseIterator
BaseIterator(BaseWindowIterator const *parent)
Construct the base class, which does initialization checks on its member variables to ensure that the...
Definition: base_window_iterator.hpp:370
genesis::population::Window< DataType >
genesis::population::SlidingVariantsWindowIterator
Iterator for sliding Windows of fixed sized intervals over the chromosomes of a genome.
Definition: sliding_variants_window_iterator.hpp:66
genesis::population::SlidingVariantsWindowIterator::iterator_category
std::input_iterator_tag iterator_category
Definition: sliding_variants_window_iterator.hpp:81
genesis::population::BaseWindowIterator::BaseIterator
Internal PIMPL-like implementation of the iterator that produces Windows.
Definition: base_window_iterator.hpp:342
genesis::population::SlidingVariantsWindowIterator::DerivedIterator::~DerivedIterator
~DerivedIterator()=default
genesis::population::SlidingVariantsWindowIterator::DerivedIterator
friend DerivedIterator
Definition: sliding_variants_window_iterator.hpp:262
genesis::population::SlidingVariantsWindowIterator::DerivedIterator
Internal iterator that produces Windows.
Definition: sliding_variants_window_iterator.hpp:94
genesis::population::SlidingVariantsWindowIterator::width
size_t width() const
Definition: sliding_variants_window_iterator.hpp:280
genesis::population::BaseWindowIterator::BaseIterator::iterator_category
std::input_iterator_tag iterator_category
Definition: base_window_iterator.hpp:356
genesis::population::SlidingVariantsWindowIterator::Entry
typename Window::Entry Entry
Definition: sliding_variants_window_iterator.hpp:78
genesis::population::SlidingVariantsWindowIterator::stride
size_t stride() const
Definition: sliding_variants_window_iterator.hpp:298
base_window_iterator.hpp
genesis::population::BaseWindowIterator::chromosome_function
std::function< std::string(InputType const &)> chromosome_function
Functor that yields the current chromosome, given the input iterator data.
Definition: base_window_iterator.hpp:139
genesis::population::SlidingVariantsWindowIterator::get_begin_iterator_
std::unique_ptr< typename BaseWindowIterator< ForwardIterator, DataType >::BaseIterator > get_begin_iterator_() override final
Definition: sliding_variants_window_iterator.hpp:310
genesis::population::Window::empty
bool empty() const
Return whether the Window is empty, that is, if it does not contain any Entries.
Definition: window.hpp:286
genesis::population::Window::entries
container const & entries() const
Immediate container access to the Data Entries.
Definition: window.hpp:461
genesis::population::BaseWindowIterator< ForwardIterator, typename ForwardIterator::value_type >::begin
Iterator begin()
Definition: base_window_iterator.hpp:502
genesis::population::SlidingVariantsWindowIterator::DerivedIterator::base_iterator_type
typename BaseWindowIterator< ForwardIterator, DataType >::BaseIterator base_iterator_type
Definition: sliding_variants_window_iterator.hpp:108
genesis
Container namespace for all symbols of genesis in order to keep them separate when used as a library.
Definition: placement/formats/edge_color.cpp:42
genesis::population::BaseWindowIterator::position_function
std::function< size_t(InputType const &)> position_function
Functor that yields the current position on the chromosome, given the input iterator data.
Definition: base_window_iterator.hpp:145
genesis::population::SlidingVariantsWindowIterator::DerivedIterator::Window
::genesis::population::Window< DataType > Window
Definition: sliding_variants_window_iterator.hpp:110
genesis::population::Window::Entry
Data that is stored per entry that was enqueued in a window.
Definition: window.hpp:124
genesis::population::SlidingVariantsWindowIterator::operator=
SlidingVariantsWindowIterator & operator=(SlidingVariantsWindowIterator const &)=default
genesis::population::BaseWindowIterator::BaseIterator::const_reference
value_type const & const_reference
Definition: base_window_iterator.hpp:360
genesis::population::SlidingVariantsWindowIterator::DerivedIterator::value_type
Window value_type
Definition: sliding_variants_window_iterator.hpp:115
genesis::population::SlidingVariantsWindowIterator::width
self_type & width(size_t value)
Width of the Window, that is, the fixed length along the chromosome.
Definition: sliding_variants_window_iterator.hpp:274
genesis::population::SlidingVariantsWindowIterator::DerivedIterator::operator=
DerivedIterator & operator=(self_type const &)=default
genesis::population::Window::clear
void clear()
Clear all data from the Window.
Definition: window.hpp:526
genesis::population::SlidingVariantsWindowIterator::SlidingVariantsWindowIterator
SlidingVariantsWindowIterator(ForwardIterator begin, ForwardIterator end)
Definition: sliding_variants_window_iterator.hpp:248
genesis::population::SlidingVariantsWindowIterator::~SlidingVariantsWindowIterator
~SlidingVariantsWindowIterator()=default
genesis::population::SlidingVariantsWindowIterator::DerivedIterator::SlidingVariantsWindowIterator
friend SlidingVariantsWindowIterator
Definition: sliding_variants_window_iterator.hpp:166
genesis::population::SlidingVariantsWindowIterator::const_reference
value_type const & const_reference
Definition: sliding_variants_window_iterator.hpp:85
genesis::population::BaseWindowIterator::BaseIterator::Entry
typename Window::Entry Entry
Definition: base_window_iterator.hpp:353
genesis::population::BaseWindowIterator< ForwardIterator, typename ForwardIterator::value_type >::end
Iterator end()
Definition: base_window_iterator.hpp:507
genesis::population::make_default_sliding_variants_window_iterator
SlidingVariantsWindowIterator< ForwardIterator > make_default_sliding_variants_window_iterator(ForwardIterator begin, ForwardIterator end, size_t width=0, size_t stride=0)
Helper function to instantiate a SlidingVariantsWindowIterator for a default use case.
Definition: sliding_variants_window_iterator.hpp:368
genesis::population::BaseWindowIterator::BaseIterator::InputType
typename ForwardIterator::value_type InputType
Definition: base_window_iterator.hpp:354
genesis::population::Window::chromosome
std::string const & chromosome() const
Get the chromosome name that this Window belongs to.
Definition: window.hpp:224
genesis::population::SlidingVariantsWindowIterator::get_end_iterator_
std::unique_ptr< typename BaseWindowIterator< ForwardIterator, DataType >::BaseIterator > get_end_iterator_() override final
Definition: sliding_variants_window_iterator.hpp:319
genesis::population::SlidingVariantsWindowIterator::stride
self_type & stride(size_t value)
Stride of the Window, that is, how many positions to move forward with each iteration.
Definition: sliding_variants_window_iterator.hpp:292