Quetzal-CoaTL
The Coalescence Template Library
Loading...
Searching...
No Matches
ForwardBackwardSpatiallyExplicit.hpp
1// Copyright 2021 Arnaud Becheler <abechele@umich.edu>
2
3/*********************************************************************** * This program is free software; you can
4 *redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free
5 *Software Foundation; either version 2 of the License, or * (at your option) any later version. *
6 * *
7 ***************************************************************************/
8
9#ifndef __SPATIALLY_EXPLICIT_H_INCLUDED__
10#define __SPATIALLY_EXPLICIT_H_INCLUDED__
11
12#include "../coalescence/container/Forest.hpp"
13#include "../coalescence/merger_policy.hpp"
14#include "../coalescence/occupancy_spectrum/sampling_policy.hpp"
15#include "../demography/History.hpp"
16
17#include <boost/math/special_functions/binomial.hpp>
18#include <map>
19
20namespace quetzal::simulator
21{
47template <typename Space, typename DispersalPolicy, typename CoalescencePolicy,
49class ForwardBackwardSpatiallyExplicit : public CoalescencePolicy
50{
51 public:
53 using coord_type = Space;
55 using dispersal_policy_type = DispersalPolicy;
57 using N_value_type = typename DispersalPolicy::value_type;
59 using memory_policy = Memory;
62
63 private:
65 history_type m_history;
66
67 public:
75 ForwardBackwardSpatiallyExplicit(coord_type x_0, N_value_type N_0, unsigned int nb_generations)
76 : m_history(x_0, N_0, nb_generations)
77 {
78 }
82 auto distribution_area(unsigned int t) const
83 {
84 assert(t >= 0 && t < m_history.nb_generations());
85 return m_history.distribution_area(t);
86 }
93 auto get_functor_N() const noexcept
94 {
95 return m_history.get_functor_N();
96 }
110 template <typename Generator, typename Growth, typename Dispersal>
111 void simulate_forward_demography(Growth growth, Dispersal kernel, Generator &gen)
112 {
113 m_history.simulate_forward(growth, kernel, gen);
114 }
120 template <typename Merger, typename Generator>
121 auto make_forest_and_coalesce_along_spatial_history(std::map<coord_type, unsigned int> sample, Generator &gen)
122 {
123 test_sample_consistency(sample);
124 auto forest = this->make_forest(sample);
125 return coalesce_along_spatial_history<Merger>(forest, this->branch(), gen, this->init());
126 }
133 template <typename Merger, typename Generator>
134 auto make_forest_using_sampling_time_and_coalesce_along_spatial_history(std::map<coord_type, unsigned int> sample,
135 unsigned int sampling_time, Generator &gen)
136 {
137 test_sample_consistency(sample);
138 auto forest = this->make_forest(sample, sampling_time);
139 return coalesce_along_spatial_history<Merger>(forest, this->branch(), gen, this->init());
140 }
141
146 template <typename Merger, typename Generator, typename F, typename Tree, typename U>
147 auto coalesce_along_spatial_history(forest_type<Tree> forest, F binary_op, Generator &gen, U make_tree)
148 {
149 this->check_consistency(m_history, forest);
150 auto t = m_history.nb_generations();
151 while ((forest.nb_trees() > 1) && (t > 0))
152 {
153 may_coalesce_colocated<Merger>(forest, t, gen, binary_op, make_tree);
154 migrate_backward(forest, t, gen);
155 --t;
156 }
157 may_coalesce_colocated<Merger>(forest, t, gen, binary_op, make_tree);
158 return forest;
159 }
173 typename Generator>
174 auto coalesce_to_mrca(std::map<coord_type, unsigned int> sample, unsigned int sampling_time, Generator &gen)
175 {
176 test_sample_consistency(sample);
177 auto forest = this->make_forest(sample, sampling_time);
178 auto new_forest = coalesce_along_spatial_history<Merger>(forest, this->branch(), gen, this->init());
179 auto tree = this->find_mrca(new_forest, 0, gen);
180 return this->treat(tree);
181 }
182
195 typename Generator>
196 auto coalesce_to_mrca(std::map<coord_type, unsigned int> sample, Generator &gen)
197 {
198 test_sample_consistency(sample);
199 auto forest = this->make_forest(sample);
200 auto new_forest = coalesce_along_spatial_history<Merger>(forest, this->branch(), gen, this->init());
201 auto tree = this->find_mrca(new_forest, 0, gen);
202 return this->treat(tree);
203 }
204
221 typename Generator, typename F>
222 auto coalesce_to_mrca(std::map<coord_type, unsigned int> sample, unsigned int sampling_time, F leaf_name,
223 Generator &gen)
224 {
225 test_sample_consistency(sample);
226 auto forest = this->make_forest(sample, sampling_time, leaf_name);
227 auto new_forest = coalesce_along_spatial_history<Merger>(forest, this->branch(), gen, this->init());
228 auto tree = this->find_mrca(new_forest, 0, gen);
229 return this->treat(tree);
230 }
231
250 typename T, typename F1, typename F2, typename Generator>
251 auto coalesce_to_mrca(std::vector<T> sample, unsigned int sampling_time, F1 get_location, F2 get_name,
252 Generator &gen)
253 {
254 auto forest = this->make_forest(sample, sampling_time, get_location, get_name);
255 auto new_forest = coalesce_along_spatial_history<Merger>(forest, this->branch(), gen, this->init());
256 auto tree = this->find_mrca(new_forest, 0, gen);
257 return this->treat(tree);
258 }
259
260 private:
261 template <typename T, typename U> void check_consistency(T &history, U const &forest)
262 {
263 auto t = history.nb_generations();
264 for (auto const &it : forest.positions())
265 {
266 if (history.pop_size(it, t) < forest.nb_trees(it))
267 {
268 throw std::domain_error("Simulated population size inferior to sampling size");
269 }
270 }
271 }
272
273 void test_sample_consistency(std::map<coord_type, unsigned int> const &sample) const
274 {
275 if (sample.size() == 0)
276 {
277 throw std::logic_error("Sample to coalesce is empty");
278 }
279 else if (sample.size() == 1)
280 {
281 if (sample.begin()->second < 2)
282 {
283 throw std::logic_error("Sample to coalesce only contains one gene copy");
284 }
285 }
286 }
287
288 template <typename Generator, typename Forest>
289 void migrate_backward(Forest &forest, unsigned int t, Generator &gen) const noexcept
290 {
291 Forest new_forest;
292 for (auto const it : forest)
293 {
294 coord_type x = it.first;
295 new_forest.insert(m_history.backward_kernel(x, t, gen), it.second);
296 }
297 assert(forest.nb_trees() == new_forest.nb_trees());
298 forest = new_forest;
299 }
300
301 template <typename Merger, typename Generator, typename Tree, typename F, typename U>
302 void may_coalesce_colocated(forest_type<Tree> &forest, unsigned int t, Generator &gen, F binop,
303 U make_tree) const noexcept
304 {
305 auto N = get_functor_N();
306 for (auto const &x : forest.positions())
307 {
308 auto range = forest.trees_at_same_position(x);
309 std::vector<Tree> v;
310 for (auto it = range.first; it != range.second; ++it)
311 {
312 v.push_back(it->second);
313 }
314 if (v.size() >= 2)
315 {
316 assert(N(x, t) >= 1 && "Population size should be positive for evaluating coalescence probability");
317 auto last = Merger::merge(v.begin(), v.end(), N(x, t), make_tree(x, t), binop, gen);
318 forest.erase(x);
319 for (auto it = v.begin(); it != last; ++it)
320 {
321 forest.insert(x, *it);
322 }
323 }
324 }
325 }
326}; // end ForwardBackwardSpatiallyExplicit
327} // namespace quetzal::simulator
328
329#endif
Collection of geo-localized coalescing trees.
Definition Forest.hpp:32
unsigned int nb_trees() const
number of trees in the forest
Definition Forest.hpp:138
auto get_functor_N() const noexcept
Read-only functor.
Definition HistoryBase.hpp:90
coord_type backward_kernel(coord_type const &x, time_type t, Generator &gen) const
Samples a coordinate from the backward-in-time transition matrix.
Definition HistoryBase.hpp:124
auto distribution_area(time_type t) const
Retrieve demes where N > 0 at time t.
Definition HistoryBase.hpp:74
unsigned int const & nb_generations() const
Last time recorded in the foward-in-time database history.
Definition HistoryBase.hpp:112
Discrete-time coalescence simulator in a discrete spatially explicit landscape.
Definition ForwardBackwardSpatiallyExplicit.hpp:50
auto distribution_area(unsigned int t) const
Return demes with non-zero population size.
Definition ForwardBackwardSpatiallyExplicit.hpp:82
auto coalesce_to_mrca(std::map< coord_type, unsigned int > sample, Generator &gen)
Create a forest from a sample and coalesce it conditionally to the simulated demography.
Definition ForwardBackwardSpatiallyExplicit.hpp:196
auto get_functor_N() const noexcept
Read-only access to the population size history.
Definition ForwardBackwardSpatiallyExplicit.hpp:93
auto make_forest_using_sampling_time_and_coalesce_along_spatial_history(std::map< coord_type, unsigned int > sample, unsigned int sampling_time, Generator &gen)
Initialize a forest based on sample counts, forwarding the sampling time to the forest contructor....
Definition ForwardBackwardSpatiallyExplicit.hpp:134
auto coalesce_to_mrca(std::vector< T > sample, unsigned int sampling_time, F1 get_location, F2 get_name, Generator &gen)
Create a forest from a sample then coalesce them conditionally to the simulated demography.
Definition ForwardBackwardSpatiallyExplicit.hpp:251
ForwardBackwardSpatiallyExplicit(coord_type x_0, N_value_type N_0, unsigned int nb_generations)
Constructor.
Definition ForwardBackwardSpatiallyExplicit.hpp:75
auto make_forest_and_coalesce_along_spatial_history(std::map< coord_type, unsigned int > sample, Generator &gen)
Initlize a forest based on sample counts then coalesce the forest along the spatial history,...
Definition ForwardBackwardSpatiallyExplicit.hpp:121
void simulate_forward_demography(Growth growth, Dispersal kernel, Generator &gen)
Simulate the forward-in-time demographic expansion.
Definition ForwardBackwardSpatiallyExplicit.hpp:111
auto coalesce_to_mrca(std::map< coord_type, unsigned int > sample, unsigned int sampling_time, F leaf_name, Generator &gen)
Create a forest from a sample giving name to tips, then coalesce them conditionally to the simulated ...
Definition ForwardBackwardSpatiallyExplicit.hpp:222
auto coalesce_along_spatial_history(forest_type< Tree > forest, F binary_op, Generator &gen, U make_tree)
Coalesce a forest of nodes conditionally to the simulated demography.
Definition ForwardBackwardSpatiallyExplicit.hpp:147
auto coalesce_to_mrca(std::map< coord_type, unsigned int > sample, unsigned int sampling_time, Generator &gen)
Create a forest from a sample and coalesce it conditionally to the simulated demography.
Definition ForwardBackwardSpatiallyExplicit.hpp:174
Standard simulators of genetic diversity.
Definition simulator.hpp:16
Discrete generation simultaneous multiple merger.
Definition merger_policy.hpp:123
Sample occupancy spectrums by simulating a ball to urn assignment random experiment.
Definition sampling_policy.hpp:57
Keep the demographic data on RAM.
Definition memory_policy.hpp:28