A library for working with phylogenetic and population genetic data.
v0.32.0
population/window/functions.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_POPULATION_WINDOW_FUNCTIONS_H_
2 #define GENESIS_POPULATION_WINDOW_FUNCTIONS_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2023 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 
34 #include <cassert>
35 #include <stdexcept>
36 #include <string>
37 #include <vector>
38 
42 
43 namespace genesis {
44 namespace population {
45 
46 // =================================================================================================
47 // Helper Functions for Window
48 // =================================================================================================
49 
57 enum class WindowAnchorType
58 {
67 };
68 
81 template<class D, class A = EmptyAccumulator>
83  Window<D, A> const& window,
85 ) {
86  auto check_entries = [&](){
87  if( window.entries().empty() ) {
88  throw std::runtime_error(
89  "Cannot use empty Window (with no variants/entries) for variant-based anchor "
90  "positions. Typically these anchor positions are used with WindowType::kVariants."
91  );
92  }
93  };
94 
95  // Calculate the SNP position that we want to output when emitting a window.
96  // Some use integer division, which is intended. We don't want the hassle of floating
97  // point genomic positions, so we have to do these roundings... But given a large window
98  // size, that should probably not matter much.
99  switch( anchor_type ) {
101  return window.first_position();
102  }
104  return window.last_position();
105  }
107  return ( window.first_position() + window.last_position() ) / 2;
108  }
110  check_entries();
111  assert( ! window.entries().empty() );
112  return window.entries().front().position;
113  }
115  check_entries();
116  assert( ! window.entries().empty() );
117  return window.entries().back().position;
118  }
120  check_entries();
121  assert( ! window.entries().empty() );
122  return window.entries()[ window.entries().size() / 2 ].position;
123  }
125  check_entries();
126  assert( ! window.entries().empty() );
127 
128  size_t sum = 0;
129  for( auto const& e : window.entries() ) {
130  sum += e.position;
131  }
132  return sum / window.entries().size();
133  }
135  check_entries();
136  assert( ! window.entries().empty() );
137  return ( window.entries().front().position + window.entries().back().position ) / 2;
138  }
139  default: {
140  throw std::runtime_error( "Invalid WindowAnchorType." );
141  }
142  }
143  assert( false );
144  return 0;
145 }
146 
156 template<class D>
158  BaseWindow<D> const& window,
160 ) {
161  // If this is in fact a Window, we use its function overload.
162  auto const downcast = dynamic_cast<Window<D> const*>( &window );
163  if( downcast ) {
164  return anchor_position( *downcast, anchor_type );
165  }
166 
167  // Otherwise, i.e., WindowView, we use the anchor types that are available for any BaseWindow.
168  switch( anchor_type ) {
170  return window.first_position();
171  }
173  return window.last_position();
174  }
176  return ( window.first_position() + window.last_position() ) / 2;
177  }
183  throw std::runtime_error( "Cannot use variant-based WindowAnchorType on BaseWindow." );
184  }
185  default: {
186  throw std::runtime_error( "Invalid WindowAnchorType." );
187  }
188  }
189  assert( false );
190  return 0;
191 }
192 
193 } // namespace population
194 } // namespace genesis
195 
196 #endif // include guard
genesis::population::WindowAnchorType::kVariantMean
@ kVariantMean
genesis::utils::sum
double sum(const Histogram &h)
Definition: utils/math/histogram/stats.cpp:140
genesis::population::WindowAnchorType::kVariantLast
@ kVariantLast
base_window.hpp
genesis::population::WindowAnchorType::kVariantMedian
@ kVariantMedian
genesis::population::Window
Window over the chromosomes of a genome.
Definition: window.hpp:105
genesis::population::WindowAnchorType::kIntervalBegin
@ kIntervalBegin
window_view.hpp
genesis::population::WindowAnchorType::kIntervalEnd
@ kIntervalEnd
genesis::population::Window::entries
container const & entries() const
Immediate container access to the Data Entries.
Definition: window.hpp:362
genesis::population::WindowAnchorType::kIntervalMidpoint
@ kIntervalMidpoint
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
window.hpp
genesis::population::WindowAnchorType::kVariantFirst
@ kVariantFirst
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::WindowAnchorType::kVariantMidpoint
@ kVariantMidpoint
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::BaseWindow
Base class for Window and WindowView, to share common functionality.
Definition: base_window.hpp:60
genesis::population::WindowAnchorType
WindowAnchorType
Position in the genome that is used for reporting when emitting or using a window.
Definition: population/window/functions.hpp:57
genesis::population::anchor_position
size_t anchor_position(Window< D, A > const &window, WindowAnchorType anchor_type=WindowAnchorType::kIntervalBegin)
Get the position in the chromosome reported according to a specific WindowAnchorType.
Definition: population/window/functions.hpp:82