Stride Reference Manual  - generated for commit 9643b11
Immunizer.cpp
Go to the documentation of this file.
1 /*
2  * This is free software: you can redistribute it and/or modify it
3  * under the terms of the GNU General Public License as published by
4  * the Free Software Foundation, either version 3 of the License, or
5  * any later version.
6  * The software is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  * You should have received a copy of the GNU General Public License
11  * along with the software. If not, see <http://www.gnu.org/licenses/>.
12  *
13  * Copyright 2017, Kuylen E, Willem L, Broeckhove J
14  */
15 
21 #include "Immunizer.h"
22 
23 #include "pop/Person.h"
24 #include "util/RnMan.h"
25 
26 #include <numeric>
27 #include <vector>
28 
29 namespace stride {
30 
31 using namespace std;
32 using namespace util;
33 
34 void Immunizer::Cocoon(const SegmentedVector<ContactPool>& /*pools*/, vector<double>& /*immunityDistribution*/,
35  double /*immunityLinkProbability*/)
36 {
37  /*
38  void Vaccinator::AdministerCocoon(const vector<ContactPool>& pools, double immunity_rate, double
39  adult_age_min, double adult_age_max, double child_age_min, double child_age_max)
40  {
41  // Sampler for double in [0.0, 1.0).
42  auto uniform01_generator = m_rn_manager[0].variate_generator(trng::uniform01_dist<double>());
43  for (const auto& c : pools) {
44  for (unsigned int i_p = 0; i_p < c.GetSize(); i_p++) {
45  Person& p = *c.GetMember(i_p);
46  if (p.GetHealth().IsSusceptible() && p.GetAge() >= adult_age_min &&
47  p.GetAge() <= adult_age_max) {
48 
49  bool is_connected_to_target_age{false};
50  for (unsigned int i_p2 = 0; i_p2 < c.GetSize()
51  && !is_connected_to_target_age; i_p2++) {
52  const Person& p2 = *c.GetMember(i_p2);
53  if (p2.GetAge() >= child_age_min && p2.GetAge() <= child_age_max) {
54  is_connected_to_target_age = true;
55  }
56  }
57  if (is_connected_to_target_age && uniform01_generator() < immunity_rate) {
58  p.GetHealth().SetImmune();
59  }
60  }
61  }
62  }
63  */
64 }
65 
66 void Immunizer::Random(const SegmentedVector<ContactPool>& pools, vector<double>& immunityDistribution,
67  double immunityLinkProbability)
68 {
69  // Sampler for int in [0, pools.size()) and for double in [0.0, 1.0).
70  const auto poolsSize = static_cast<int>(pools.size());
71  auto intGenerator = m_rn_man.GetUniformIntGenerator(0, poolsSize, 0U);
72  auto uniform01Generator = m_rn_man.GetUniform01Generator(0U);
73 
74  // Initialize a vector to count the population per age class [0-100].
75  vector<double> populationBrackets(100, 0.0);
76 
77  // Count individuals per age class.
78  for (auto& c : pools) {
79  for (const auto &p : c.GetPool()) {
80  populationBrackets[p->GetAge()]++;
81  }
82  }
83 
84  // Calculate the number of immune individuals per age class.
85  unsigned int numImmune = 0;
86  for (unsigned int age = 0; age < 100; age++) {
87  populationBrackets[age] = floor(populationBrackets[age] * immunityDistribution[age]);
88  numImmune += static_cast<unsigned int>(populationBrackets[age]);
89  }
90 
91  // Sample immune individuals, until all age-dependent quota are reached.
92  while (numImmune > 0) {
93  // Select random contact pool
94  const ContactPool& p_pool = pools[intGenerator()];
95  const auto size = static_cast<unsigned int>(p_pool.GetPool().size());
96 
97  // Random order of indices
98  vector<unsigned int> indices(size);
99  iota(indices.begin(), indices.end(), 0U);
100  m_rn_man.Shuffle(indices, 0U);
101 
102  // Loop over members in random order
103  for (unsigned int i_p = 0; i_p < size && numImmune > 0; i_p++) {
104  Person& p = *p_pool.GetPool()[indices[i_p]];
105  // If p is susceptible and his/her age class has not reached quota -> make immune
106  if (p.GetHealth().IsSusceptible() && populationBrackets[p.GetAge()] > 0) {
107  p.GetHealth().SetImmune();
108  populationBrackets[p.GetAge()]--;
109  numImmune--;
110  }
111 
112  // Random draw to continue in this pool or sample a new one
113  if(uniform01Generator() < (1 - immunityLinkProbability)) {
114  break;
115  }
116  }
117  }
118 }
119 
120 
121 void Immunizer::Random(std::shared_ptr<Population> pop, std::vector<double>& immunityDistribution, const ContactType::Id contactPoolType, double immunityLinkProbability)
122 {
123  // Sampler for int in [0, population size) and for double in [0.0, 1.0)
124  const auto popSize = static_cast<int>(pop->size());
125  auto intGenerator = m_rn_man.GetUniformIntGenerator(0, popSize, 0U);
126  auto uniform01Generator = m_rn_man.GetUniform01Generator(0U);
127 
128  // Initialize a vector to count the population per age class [0-100], and vector to count immunized individuals per age class.
129  vector<double> populationBrackets(100, 0.0);
130  vector<double> immuneByAge(100, 0.0);
131 
132  // Count individuals per age class.
133  for (auto person_it = pop->begin(); person_it < pop->end(); person_it++) {
134  const auto age = person_it->GetAge();
135  populationBrackets[age]++;
136  }
137 
138  // Calculate the number of immune individuals per age class.
139  unsigned int numImmune = 0;
140  for (unsigned int age = 0; age < 100; age++) {
141  populationBrackets[age] = floor(populationBrackets[age] * immunityDistribution[age]);
142  numImmune += static_cast<unsigned int>(populationBrackets[age]);
143  }
144 
145  // Immunize susceptible individuals, until quota are reached.
146  while (numImmune > 0) {
147  // Select random individual from the population
148  auto& p = (*pop)[intGenerator()];
149  if (p.GetHealth().IsSusceptible() && immuneByAge[p.GetAge()] < populationBrackets[p.GetAge()]) {
150  p.GetHealth().SetImmune();
151  immuneByAge[p.GetAge()]++;
152  numImmune--;
153  // Random draw to immunize all other individuals in pool (depending on needs of age distribution)
154  if (uniform01Generator() < immunityLinkProbability) {
155  const auto poolId = p.GetPoolId(contactPoolType);
156  const auto& pool = pop->CRefPoolSys().CRefPools(contactPoolType)[poolId].GetPool();
157  for (auto i_p = pool.begin(); i_p < pool.end() && numImmune > 0; i_p++) {
158  if ((immuneByAge[(*i_p)->GetAge()] < populationBrackets[(*i_p)->GetAge()] * 1.1) && ((*i_p)->GetHealth().IsSusceptible())) {
159  (*i_p)->GetHealth().SetImmune();
160  immuneByAge[(*i_p)->GetAge()]++;
161  numImmune--;
162  }
163 
164  }
165  }
166  }
167  }
168 }
169 } // namespace stride
Health & GetHealth()
Return person&#39;s health status.
Definition: Person.h:56
Id
Enumerates the ContactPool types.
Definition: ContactType.h:34
Header file for the Person class.
A group of Persons that potentially have contacts with one another.
Definition: ContactPool.h:38
void SetImmune()
Set health state to immune.
Definition: Health.h:89
STL namespace.
float GetAge() const
Get the age.
Definition: Person.h:53
Interface of RnMan.
Container that stores objects "almost contiguously" (in a chain of blocks) and guarantees that pointe...
const std::vector< Person * > & GetPool() const
Get the entire pool of members.
Definition: ContactPool.h:57
void Cocoon(const util::SegmentedVector< ContactPool > &, std::vector< double > &, double)
Cocoon immunization.
Definition: Immunizer.cpp:34
void Random(const util::SegmentedVector< ContactPool > &pools, std::vector< double > &immunityDistribution, double immunityLinkProbability)
Random immunization.
std::size_t size() const
Returns the number of elements.
Store and handle person data.
Definition: Person.h:34
Namespace for the simulator and related classes.
Definition: Calendar.cpp:28
bool IsSusceptible() const
Is this person susceptible?
Definition: Health.h:77
Header for the Immunizer class.