A library for working with phylogenetic and population genetic data.
v0.32.0
position_window_stream.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_POPULATION_WINDOW_POSITION_WINDOW_STREAM_H_
2 #define GENESIS_POPULATION_WINDOW_POSITION_WINDOW_STREAM_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2024 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 <lucas.czech@sund.ku.dk>
23  University of Copenhagen, Globe Institute, Section for GeoGenetics
24  Oster Voldgade 5-7, 1350 Copenhagen K, Denmark
25 */
26 
38 
39 #include <cassert>
40 #include <functional>
41 #include <memory>
42 #include <stdexcept>
43 #include <string>
44 #include <type_traits>
45 #include <unordered_set>
46 #include <utility>
47 
48 namespace genesis {
49 namespace population {
50 
51 // =================================================================================================
52 // Single Position Window Stream
53 // =================================================================================================
54 
85 template<class InputStreamIterator, class DataType = typename InputStreamIterator::value_type>
86 class PositionWindowStream final : public BaseWindowStream<InputStreamIterator, DataType>
87 {
88 public:
89 
90  // -------------------------------------------------------------------------
91  // Typedefs and Enums
92  // -------------------------------------------------------------------------
93 
96 
98  using Entry = typename Window::Entry;
99  using InputType = typename InputStreamIterator::value_type;
100 
101  using iterator_category = std::input_iterator_tag;
103  using pointer = value_type*;
105  using const_reference = value_type const&;
106 
107  // -------------------------------------------------------------------------
108  // Public Functors
109  // -------------------------------------------------------------------------
110 
118  std::function<bool( InputType const& )> entry_selection_function;
119 
120  // ======================================================================================
121  // Internal Iterator
122  // ======================================================================================
123 
127  class DerivedIterator final : public BaseWindowStream<InputStreamIterator, DataType>::BaseIterator
128  {
129  public:
130 
131  // -------------------------------------------------------------------------
132  // Constructors and Rule of Five
133  // -------------------------------------------------------------------------
134 
135  using self_type = typename PositionWindowStream<
136  InputStreamIterator, DataType
138 
139  using base_iterator_type = typename BaseWindowStream<
140  InputStreamIterator, DataType
142 
144  using Entry = typename Window::Entry;
145  using InputType = typename InputStreamIterator::value_type;
146 
147  using iterator_category = std::input_iterator_tag;
149  using pointer = value_type*;
151  using const_reference = value_type const&;
152 
153  private:
154 
155  DerivedIterator() = default;
156 
158  PositionWindowStream const* parent
159  )
160  : base_iterator_type( parent )
161  , parent_( parent )
162  {
163  // Edge case check. See Base for details.
164  if( ! parent_ ) {
165  return;
166  }
167 
168  // Check that our selection functor is set up. The other three are already checked
169  // in the base class, which is called from the delegated constructor call above.
170  if( ! parent->entry_selection_function ) {
171  throw std::runtime_error(
172  "Need to set BaseWindowStream::entry_selection_function "
173  "before iterating over Windows with a PositionWindowStream."
174  );
175  }
176 
177  // Let's get going.
178  increment_();
179  }
180 
181  public:
182 
183  virtual ~DerivedIterator() override = default;
184 
185  DerivedIterator( self_type const& ) = default;
186  DerivedIterator( self_type&& ) = default;
187 
188  DerivedIterator& operator= ( self_type const& ) = default;
189  DerivedIterator& operator= ( self_type&& ) = default;
190 
192 
193  // -------------------------------------------------------------------------
194  // Internal and Virtual Members
195  // -------------------------------------------------------------------------
196 
197  private:
198 
199  void increment_() override final
200  {
201  // Check that we are still good. If not, this function being called is likely a user
202  // error by trying to increment a past-the-end iterator.
203  assert( parent_ );
204 
205  // Find the next selected entry that we want to visit.
206  // Except for in the first iteration, this loop is never executed,
207  // as we move to the next entry below already when wrapping up the increment.
208  while(
209  base_iterator_type::current_ != base_iterator_type::end_ &&
210  ! parent_->entry_selection_function( *base_iterator_type::current_ )
211  ) {
212  ++base_iterator_type::current_;
213  }
214 
215  // If that lead us to the end of the input, we are done.
216  if( base_iterator_type::current_ == base_iterator_type::end_ ) {
217  parent_ = nullptr;
218  return;
219  }
220  assert( base_iterator_type::current_ != base_iterator_type::end_ );
221  assert( parent_->entry_selection_function( *base_iterator_type::current_ ));
222 
223  // We are now at a position that we want to visit for the iteration. Get the basics.
224  auto const cur_chr = parent_->chromosome_function( *base_iterator_type::current_ );
225  auto const cur_pos = parent_->position_function( *base_iterator_type::current_ );
226 
227  // Set the chromosome for this position.
228  // If it is a new one, we also mark this as the first window on the chromosome.
229  base_iterator_type::is_first_window_ = ( cur_chr != window_.chromosome() );
230  window_.chromosome( cur_chr );
231 
232  // Update the window position. The window uses a closed interval,
233  // where both first and last position are part of the interval.
234  window_.first_position( cur_pos );
235  window_.last_position( cur_pos );
236 
237  // Now enqueue the single entry, and move to the next.
238  window_.entries().clear();
239  window_.entries().emplace_back(
240  next_index_,
241  cur_pos,
242  parent_->entry_input_function( *base_iterator_type::current_ )
243  );
244  ++next_index_;
245 
246  // We now already need to move to the next entry that we want to visit.
247  // This is because otherwise we would not know if we are already at the end of
248  // the chromosome or data, and hence could not set the last window property.
249  // So first, we move one entry explicitly, and then move on as before.
250  ++base_iterator_type::current_;
251  while(
252  base_iterator_type::current_ != base_iterator_type::end_ &&
253  ! parent_->entry_selection_function( *base_iterator_type::current_ )
254  ) {
255  ++base_iterator_type::current_;
256  }
257 
258  // We just moved to the next entry, so we can check if we are at the end of the
259  // chromosome or data now, and set the last window property accordingly.
260  base_iterator_type::is_last_window_ = (
261  base_iterator_type::current_ == base_iterator_type::end_ ||
262  parent_->chromosome_function( *base_iterator_type::current_ ) != window_.chromosome()
263  );
264  }
265 
266  value_type& get_current_window_() const override final
267  {
268  return const_cast<value_type&>( window_ );
269  }
270 
271  base_type const* get_parent_() const override final
272  {
273  return parent_;
274  }
275 
276  private:
277 
278  // Parent. Needs to live here to have the correct derived type.
279  PositionWindowStream const* parent_ = nullptr;
280 
281  // Current window and the index
282  Window window_;
283  size_t next_index_ = 0;
284 
285  };
286 
287  // ======================================================================================
288  // Main Class
289  // ======================================================================================
290 
291  // -------------------------------------------------------------------------
292  // Constructors and Rule of Five
293  // -------------------------------------------------------------------------
294 
296  InputStreamIterator begin, InputStreamIterator end
297  )
298  : base_type( begin, end )
299  {}
300 
301  virtual ~PositionWindowStream() override = default;
302 
303  PositionWindowStream( PositionWindowStream const& ) = default;
305 
308 
310 
311  // -------------------------------------------------------------------------
312  // Virtual Members
313  // -------------------------------------------------------------------------
314 
315 protected:
316 
317  std::unique_ptr<typename base_type::BaseIterator>
318  get_begin_iterator_() override final
319  {
320  // Cannot use make_unique here, as the Iterator constructor is private,
321  // and trying to make make_unique a friend does not seem to be working...
322  return std::unique_ptr<DerivedIterator>( new DerivedIterator( this ));
323  // return utils::make_unique<DerivedIterator>( this );
324  }
325 
326  std::unique_ptr<typename base_type::BaseIterator>
327  get_end_iterator_() override final
328  {
329  return std::unique_ptr<DerivedIterator>( new DerivedIterator( nullptr ));
330  // return utils::make_unique<DerivedIterator>( nullptr );
331  }
332 
333 };
334 
335 // =================================================================================================
336 // Make Position Window View Iterator
337 // =================================================================================================
338 
343 template<class InputStreamIterator, class DataType = typename InputStreamIterator::value_type>
344 PositionWindowStream<InputStreamIterator, DataType>
346  InputStreamIterator begin, InputStreamIterator end
347 ) {
349 }
350 
371 template<class InputStreamIterator>
372 PositionWindowStream<InputStreamIterator>
374  InputStreamIterator begin, InputStreamIterator end
375 ) {
376  using DataType = typename InputStreamIterator::value_type;
377 
378  // Set functors.
379  auto it = PositionWindowStream<InputStreamIterator>( begin, end );
380  it.entry_input_function = []( DataType const& variant ) {
381  return variant;
382  };
383  it.chromosome_function = []( DataType const& variant ) {
384  return variant.chromosome;
385  };
386  it.position_function = []( DataType const& variant ) {
387  return variant.position;
388  };
389  it.entry_selection_function = []( DataType const& variant ) {
390  (void) variant;
391  return true;
392  };
393 
394  return it;
395 }
396 
408 template<class InputStreamIterator>
409 WindowViewStream<InputStreamIterator>
411  InputStreamIterator begin, InputStreamIterator end
412 ) {
415  );
416 }
417 
431 template<class InputStreamIterator>
432 PositionWindowStream<InputStreamIterator>
434  InputStreamIterator begin, InputStreamIterator end
435 ) {
436  using DataType = typename InputStreamIterator::value_type;
437 
438  // Set functors.
439  auto it = PositionWindowStream<InputStreamIterator>( begin, end );
440  it.entry_input_function = []( DataType const& variant ) {
441  return variant;
442  };
443  it.chromosome_function = []( DataType const& variant ) {
444  return variant.chromosome;
445  };
446  it.position_function = []( DataType const& variant ) {
447  return variant.position;
448  };
449  it.entry_selection_function = []( DataType const& variant ) {
450  return variant.status.passing();
451  };
452 
453  return it;
454 }
455 
467 template<class InputStreamIterator>
468 WindowViewStream<InputStreamIterator>
470  InputStreamIterator begin, InputStreamIterator end
471 ) {
474  );
475 }
476 
477 } // namespace population
478 } // namespace genesis
479 
480 #endif // include guard
genesis::population::PositionWindowStream::get_end_iterator_
std::unique_ptr< typename base_type::BaseIterator > get_end_iterator_() override final
Get the end iterator.
Definition: position_window_stream.hpp:327
genesis::population::BaseWindowStream
Base class for streams of Windows over the chromosomes of a genome.
Definition: base_window_stream.hpp:119
genesis::population::BaseWindowStream::BaseIterator::iterator_category
std::input_iterator_tag iterator_category
Definition: base_window_stream.hpp:491
base_window_stream.hpp
genesis::population::BaseWindowStream::chromosome_function
std::function< std::string(InputType const &)> chromosome_function
Functor that yields the current chromosome, given the input stream data.
Definition: base_window_stream.hpp:152
genesis::population::make_default_position_window_stream
PositionWindowStream< InputStreamIterator > make_default_position_window_stream(InputStreamIterator begin, InputStreamIterator end)
Helper function to instantiate a PositionWindowStream for each position as an individual window,...
Definition: position_window_stream.hpp:373
genesis::population::PositionWindowStream::entry_selection_function
std::function< bool(InputType const &)> entry_selection_function
Functor that takes an entry of the underlying input stream and returns whether that entry should be s...
Definition: position_window_stream.hpp:118
genesis::population::BaseWindowStream< InputStreamIterator, typename InputStreamIterator::value_type >::end
Iterator end()
Definition: base_window_stream.hpp:759
genesis::population::make_passing_variant_position_window_stream
PositionWindowStream< InputStreamIterator > make_passing_variant_position_window_stream(InputStreamIterator begin, InputStreamIterator end)
Helper function to instantiate a PositionWindowStream for a default use case with underlying data of ...
Definition: position_window_stream.hpp:433
genesis::population::Window< DataType >
genesis::population::PositionWindowStream::base_type
BaseWindowStream< InputStreamIterator, DataType > base_type
Definition: position_window_stream.hpp:95
genesis::population::PositionWindowStream::iterator_category
std::input_iterator_tag iterator_category
Definition: position_window_stream.hpp:101
window_view.hpp
genesis::population::BaseWindowStream::BaseIterator::value_type
WindowType value_type
Definition: base_window_stream.hpp:492
genesis::population::PositionWindowStream::DerivedIterator
Internal iterator that produces WindowViews.
Definition: position_window_stream.hpp:127
genesis::population::BaseWindowStream::BaseIterator::const_reference
value_type const & const_reference
Definition: base_window_stream.hpp:495
genesis::population::BaseWindowStream< InputStreamIterator, typename InputStreamIterator::value_type >::DataType
typename InputStreamIterator::value_type DataType
Definition: base_window_stream.hpp:128
genesis::population::PositionWindowStream::DerivedIterator::base_iterator_type
typename BaseWindowStream< InputStreamIterator, DataType >::BaseIterator base_iterator_type
Definition: position_window_stream.hpp:141
genesis::population::PositionWindowStream::operator=
PositionWindowStream & operator=(PositionWindowStream const &)=default
genesis::population::PositionWindowStream::Entry
typename Window::Entry Entry
Definition: position_window_stream.hpp:98
genesis::population::PositionWindowStream::InputType
typename InputStreamIterator::value_type InputType
Definition: position_window_stream.hpp:99
genesis::population::PositionWindowStream::DerivedIterator::operator=
DerivedIterator & operator=(self_type const &)=default
genesis::population::PositionWindowStream::get_begin_iterator_
std::unique_ptr< typename base_type::BaseIterator > get_begin_iterator_() override final
Get the begin iterator.
Definition: position_window_stream.hpp:318
genesis::population::BaseWindow::chromosome
std::string const & chromosome() const
Get the chromosome name that this Window belongs to.
Definition: base_window.hpp:90
genesis::population::Window::entries
container const & entries() const
Immediate container access to the Data Entries.
Definition: window.hpp:362
genesis::population::BaseWindowStream::position_function
std::function< size_t(InputType const &)> position_function
Functor that yields the current position on the chromosome, given the input stream data.
Definition: base_window_stream.hpp:158
genesis::population::BaseWindowStream::BaseIterator::BaseIterator
BaseIterator()=default
genesis::population::BaseWindowStream::BaseIterator::self_type
typename BaseWindowStream< InputStreamType, DataType, WindowType >::BaseIterator self_type
Definition: base_window_stream.hpp:488
window_view_stream.hpp
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::Window::Entry
Data that is stored per entry that was enqueued in a window.
Definition: window.hpp:125
genesis::population::BaseWindowStream< InputStreamIterator, typename InputStreamIterator::value_type >::begin
Iterator begin()
Definition: base_window_stream.hpp:747
genesis::population::PositionWindowStream::DerivedIterator::Entry
typename Window::Entry Entry
Definition: position_window_stream.hpp:144
genesis::population::make_position_window_stream
PositionWindowStream< InputStreamIterator, DataType > make_position_window_stream(InputStreamIterator begin, InputStreamIterator end)
Helper function to instantiate a PositionWindowStream for each position as an individual window,...
Definition: position_window_stream.hpp:345
window.hpp
genesis::population::BaseWindowStream::entry_input_function
std::function< DataType(InputType const &)> entry_input_function
Functor to convert from the underlying input stream that provides the data to fill the windows to the...
Definition: base_window_stream.hpp:147
genesis::population::make_window_view_stream
WindowViewStream< typename T::InputStreamType, typename T::DataType > make_window_view_stream(T const &window_iterator)
Create a WindowViewStream that iterates some underlying BaseWindowStream.
Definition: window_view_stream.hpp:317
genesis::population::make_default_position_window_view_stream
WindowViewStream< InputStreamIterator > make_default_position_window_view_stream(InputStreamIterator begin, InputStreamIterator end)
Helper class that creates a PositionWindowStream with default functors and wraps it in a WindowViewSt...
Definition: position_window_stream.hpp:410
genesis::population::BaseWindowStream::BaseIterator::pointer
value_type * pointer
Definition: base_window_stream.hpp:493
genesis::population::make_passing_variant_position_window_view_stream
WindowViewStream< InputStreamIterator > make_passing_variant_position_window_view_stream(InputStreamIterator begin, InputStreamIterator end)
Helper class that creates a PositionWindowStream with default functions for Variant data,...
Definition: position_window_stream.hpp:469
genesis::population::PositionWindowStream::PositionWindowStream
PositionWindowStream(InputStreamIterator begin, InputStreamIterator end)
Definition: position_window_stream.hpp:295
genesis::population::BaseWindow::first_position
size_t first_position() const
Get the first position in the chromosome of the Window, that is, where the Window starts.
Definition: base_window.hpp:114
genesis::population::BaseWindow::last_position
size_t last_position() const
Get the last position in the chromosome of the Window, that is, where the Window ends.
Definition: base_window.hpp:134
genesis::population::BaseWindowStream::BaseIterator::reference
value_type & reference
Definition: base_window_stream.hpp:494
genesis::population::PositionWindowStream::DerivedIterator::PositionWindowStream
friend PositionWindowStream
Definition: position_window_stream.hpp:191
genesis::population::PositionWindowStream
Stream for traversing each position along a genome individually.
Definition: position_window_stream.hpp:86
genesis::population::PositionWindowStream::DerivedIterator::Window
::genesis::population::Window< DataType > Window
Definition: position_window_stream.hpp:143
genesis::population::PositionWindowStream::DerivedIterator::~DerivedIterator
virtual ~DerivedIterator() override=default
genesis::population::PositionWindowStream::const_reference
value_type const & const_reference
Definition: position_window_stream.hpp:105
genesis::population::BaseWindowStream::BaseIterator::InputType
typename InputStreamType::value_type InputType
Definition: base_window_stream.hpp:489
genesis::population::PositionWindowStream::DerivedIterator
friend DerivedIterator
Definition: position_window_stream.hpp:309
genesis::population::PositionWindowStream::Window
::genesis::population::Window< DataType > Window
Definition: position_window_stream.hpp:97
genesis::population::PositionWindowStream::~PositionWindowStream
virtual ~PositionWindowStream() override=default