pops-core  0.9
PoPS (Pest or Pathogen Spread) Model Core C++ library
spread_rate.hpp
Go to the documentation of this file.
1 /*
2  * PoPS model - Spread rate computation
3  *
4  * Copyright (C) 2015-2020 by the authors.
5  *
6  * Authors: Anna Petrasova <akratoc gmail com>
7  *
8  * The code contained herein is licensed under the GNU General Public
9  * License. You may obtain a copy of the GNU General Public License
10  * Version 2 or later at the following locations:
11  *
12  * http://www.opensource.org/licenses/gpl-license.html
13  * http://www.gnu.org/copyleft/gpl.html
14  */
15 
16 #ifndef POPS_SPREAD_RATE_HPP
17 #define POPS_SPREAD_RATE_HPP
18 
19 #include "utils.hpp"
20 
21 #include <tuple>
22 #include <vector>
23 #include <cmath>
24 
25 namespace pops {
26 
30 template<typename Raster>
32 {
33 private:
34  int width;
35  int height;
36  // the west-east resolution of the pixel
37  double west_east_resolution;
38  // the north-south resolution of the pixel
39  double north_south_resolution;
40  unsigned num_steps;
41  std::vector<BBoxInt> boundaries;
42  std::vector<BBoxFloat> rates;
43 
49  BBoxBool is_out_of_bounds(const BBoxInt bbox)
50  {
51  int n, s, e, w;
52  bool bn = false, bs = false, be = false, bw = false;
53  std::tie(n, s, e, w) = bbox;
54  if (n == 0)
55  bn = true;
56  if (s == (height - 1))
57  bs = true;
58  if (w == 0)
59  bw = true;
60  if (e == (width - 1))
61  be = true;
62 
63  return std::make_tuple(bn, bs, be, bw);
64  }
70  BBoxInt infection_boundary(
71  const Raster& raster, const std::vector<std::vector<int>>& suitable_cells)
72  {
73  int n = height - 1;
74  int s = 0;
75  int e = 0;
76  int w = width - 1;
77  bool found = false;
78  for (auto indices : suitable_cells) {
79  int i = indices[0];
80  int j = indices[1];
81  auto value = raster(i, j);
82  if (value > 0) {
83  found = true;
84  if (i < n)
85  n = i;
86  if (i > s)
87  s = i;
88  if (j > e)
89  e = j;
90  if (j < w)
91  w = j;
92  }
93  }
94  if (found)
95  return std::make_tuple(n, s, e, w);
96  else
97  return std::make_tuple(-1, -1, -1, -1);
98  }
99 
104  bool is_boundary_valid(const BBoxInt bbox)
105  {
106  int n, s, e, w;
107  std::tie(n, s, e, w) = bbox;
108  if (n == -1)
109  return false;
110  return true;
111  }
112 
113 public:
115  const Raster& raster,
116  double ew_res,
117  double ns_res,
118  unsigned num_steps,
119  const std::vector<std::vector<int>>& suitable_cells)
120  : width(raster.cols()),
121  height(raster.rows()),
122  west_east_resolution(ew_res),
123  north_south_resolution(ns_res),
124  num_steps(num_steps),
125  boundaries(num_steps + 1, std::make_tuple(0, 0, 0, 0)),
126  rates(
127  num_steps,
128  std::make_tuple(std::nan(""), std::nan(""), std::nan(""), std::nan("")))
129  {
130  boundaries.at(0) = infection_boundary(raster, suitable_cells);
131  }
132 
133  SpreadRate() = delete;
134 
138  const BBoxFloat& step_rate(unsigned step) const
139  {
140  return rates[step];
141  }
142 
152  const Raster& raster,
153  unsigned step,
154  const std::vector<std::vector<int>>& suitable_cells)
155  {
156  BBoxInt bbox = infection_boundary(raster, suitable_cells);
157  boundaries.at(step + 1) = bbox;
158  if (!is_boundary_valid(bbox)) {
159  rates.at(step) =
160  std::make_tuple(std::nan(""), std::nan(""), std::nan(""), std::nan(""));
161  return;
162  }
163  int n1, n2, s1, s2, e1, e2, w1, w2;
164  std::tie(n1, s1, e1, w1) = boundaries.at(step);
165  std::tie(n2, s2, e2, w2) = bbox;
166  double n_rate = ((n1 - n2) * north_south_resolution);
167  double s_rate = ((s2 - s1) * north_south_resolution);
168  double e_rate = ((e2 - e1) * west_east_resolution);
169  double w_rate = ((w1 - w2) * west_east_resolution);
170 
171  bool bn, bs, be, bw;
172  std::tie(bn, bs, be, bw) = is_out_of_bounds(bbox);
173  if (n_rate == 0 && bn)
174  n_rate = std::nan("");
175  if (s_rate == 0 && bs)
176  s_rate = std::nan("");
177  if (e_rate == 0 && be)
178  e_rate = std::nan("");
179  if (w_rate == 0 && bw)
180  w_rate = std::nan("");
181 
182  rates.at(step) = std::make_tuple(n_rate, s_rate, e_rate, w_rate);
183  }
184 };
185 
191 template<typename Raster>
192 BBoxFloat
193 average_spread_rate(const std::vector<SpreadRate<Raster>>& rates, unsigned step)
194 {
195  // loop through stochastic runs
196  double n, s, e, w;
197  int size_n = 0, size_s = 0, size_e = 0, size_w = 0;
198  double avg_n = 0, avg_s = 0, avg_e = 0, avg_w = 0;
199  for (unsigned i = 0; i < rates.size(); i++) {
200  std::tie(n, s, e, w) = rates[i].step_rate(step);
201  if (!std::isnan(n)) {
202  avg_n += n;
203  size_n++;
204  }
205  if (!std::isnan(s)) {
206  avg_s += s;
207  size_s++;
208  }
209  if (!std::isnan(e)) {
210  avg_e += e;
211  size_e++;
212  }
213  if (!std::isnan(w)) {
214  avg_w += w;
215  size_w++;
216  }
217  }
218  avg_n = size_n ? avg_n / size_n : std::nan("");
219  avg_s = size_s ? avg_s / size_s : std::nan("");
220  avg_e = size_e ? avg_e / size_e : std::nan("");
221  avg_w = size_w ? avg_w / size_w : std::nan("");
222 
223  return std::make_tuple(avg_n, avg_s, avg_e, avg_w);
224 }
225 
226 } // namespace pops
227 #endif // POPS_SPREAD_RATE_HPP
BBoxFloat
std::tuple< double, double, double, double > BBoxFloat
Definition: utils.hpp:62
utils.hpp
BBoxInt
std::tuple< int, int, int, int > BBoxInt
Definition: utils.hpp:61
pops::SpreadRate::compute_step_spread_rate
void compute_step_spread_rate(const Raster &raster, unsigned step, const std::vector< std::vector< int >> &suitable_cells)
Computes spread rate in n, s, e, w directions for certain simulation year based on provided infection...
Definition: spread_rate.hpp:151
indices
Definition: utils.hpp:97
pops::SpreadRate::step_rate
const BBoxFloat & step_rate(unsigned step) const
Returns rate for certain year of simulation.
Definition: spread_rate.hpp:138
pops::SpreadRate
Class storing and computing step spread rate for one simulation.
Definition: spread_rate.hpp:31
BBoxBool
std::tuple< bool, bool, bool, bool > BBoxBool
Definition: utils.hpp:63
pops
Definition: cauchy_kernel.hpp:25
pops::Raster
Representation of a raster image.
Definition: raster.hpp:97
pops::SpreadRate::SpreadRate
SpreadRate()=delete
pops::SpreadRate::SpreadRate
SpreadRate(const Raster &raster, double ew_res, double ns_res, unsigned num_steps, const std::vector< std::vector< int >> &suitable_cells)
Definition: spread_rate.hpp:114
pops::average_spread_rate
BBoxFloat average_spread_rate(const std::vector< SpreadRate< Raster >> &rates, unsigned step)
Computes average spread rate in n, s, e, w directions from vector of spread rates.
Definition: spread_rate.hpp:193