Stride Reference Manual  - generated for commit 9643b11
WorkplacePopulator.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 2018, 2019, Jan Broeckhove and Bistromatics group.
14  */
15 
16 #include "Populator.h"
17 
18 #include "contact/AgeBrackets.h"
19 #include "contact/ContactPool.h"
20 #include "geopop/GeoGrid.h"
21 #include "geopop/GeoGridConfig.h"
22 #include "geopop/Location.h"
23 #include "util/Assert.h"
24 
25 #include <utility>
26 
27 namespace geopop {
28 
29 using namespace std;
30 using namespace stride;
31 using namespace stride::ContactType;
32 using namespace stride::AgeBrackets;
33 using namespace util;
34 
35 template<>
37 {
38  m_logger->trace("Starting to populate Workplaces");
39 
40  auto genCommute{function<int()>()};
41  auto genNonCommute{function<int()>()};
42  vector<ContactPool*> nearbyWp{};
43  vector<Location*> commuteLocations{};
44 
45  const auto participWorkplace = geoGridConfig.param.particpation_workplace;
46  const auto popCollege = geoGridConfig.info.popcount_college;
47  const auto popWorkplace = geoGridConfig.info.popcount_workplace;
48  const auto fracCollegeCommute = geoGridConfig.param.fraction_college_commuters;
49  const auto fracWorkplaceCommute = geoGridConfig.param.fraction_workplace_commuters;
50 
51  // Commuting fraction in student population estimated to obtain commuting fraction in
52  // workplace population from commute data.
53  double fracCommuteStudents = 0.0;
54  if (static_cast<bool>(fracWorkplaceCommute) && popWorkplace) {
55  fracCommuteStudents = (popCollege * fracCollegeCommute) /(popWorkplace * fracWorkplaceCommute);
56  }
57 
58  // --------------------------------------------------------------------------------
59  // For every location, if populated ...
60  // --------------------------------------------------------------------------------
61  for (const auto& loc : geoGrid) {
62  if (loc->GetPopCount() == 0) {
63  continue;
64  }
65 
66  // --------------------------------------------------------------------------------
67  // Find all Workplaces were employees from this location commute to
68  // --------------------------------------------------------------------------------
69  commuteLocations.clear();
70  genCommute = function<int()>();
71 
72  vector<double> commutingWeights;
73  for (const pair<Location*, double>& commute : loc->CRefOutgoingCommutes()) {
74  const auto& workplaces = commute.first->RefPools(Id::Workplace);
75  if (!workplaces.empty()) {
76  commuteLocations.push_back(commute.first);
77  const auto weight = commute.second - (commute.second * fracCommuteStudents);
78  commutingWeights.push_back(weight);
79  AssertThrow(weight >= 0.0 && weight <= 1.0 && !isnan(weight),
80  "Invalid weight: " + to_string(weight), m_logger);
81  }
82  }
83 
84  if (!commutingWeights.empty()) {
85  genCommute = m_rn_man.GetDiscreteGenerator(commutingWeights, 0U);
86  }
87 
88  // --------------------------------------------------------------------------------
89  // Set NearbyWorkspacePools and associated generator
90  // --------------------------------------------------------------------------------
91  nearbyWp = geoGrid.GetNearbyPools(Id::Workplace, *loc);
92  genNonCommute = m_rn_man.GetUniformIntGenerator(0, static_cast<int>(nearbyWp.size()), 0U);
93 
94  // --------------------------------------------------------------------------------
95  // For everyone of working age: decide between work or college (iff of College age)
96  // --------------------------------------------------------------------------------
97  for (auto& hhPool : loc->RefPools(Id::Household)) {
98  for (auto person : *hhPool) {
99 
100  // NOTICE: logic below requires that CollegePopulator has already executed
101  // such that we can identify the college students.
102  // If this person is not in the age bracket for college/work/unemployed
103  // or if the perosn is in the age bracket but is a student we are done here.
104  if (!Workplace::HasAge(person->GetAge()) || (person->GetPoolId(Id::College) != 0)) {
105  continue;
106  }
107 
108  // We are dealing with a non-student person of the age bracket for work,
109  // flip coin to decide whether they are actually employed.
110  bool isActiveWorker = m_rn_man.MakeWeightedCoinFlip(participWorkplace);
111  if (isActiveWorker) {
112  // ---------------------------------------------
113  // this person is employed
114  // ---------------------------------------------
115  const auto isCommuter = m_rn_man.MakeWeightedCoinFlip(fracWorkplaceCommute);
116  if (!commuteLocations.empty() && isCommuter) {
117  // --------------------------------------------------------------
118  // this person commutes to the Location and in particular to Pool
119  // --------------------------------------------------------------
120  auto& pools = commuteLocations[genCommute()]->RefPools(Id::Workplace);
121  auto s = static_cast<int>(pools.size());
122  auto gen = m_rn_man.GetUniformIntGenerator(0, s);
123  auto pool = pools[gen()];
124  // so that's it
125  pool->AddMember(person);
126  person->SetPoolId(Id::Workplace, pool->GetId());
127  } else {
128  // ----------------------------
129  // this person does not commute
130  // ----------------------------
131  const auto idraw = genNonCommute();
132  nearbyWp[idraw]->AddMember(person);
133  person->SetPoolId(Id::Workplace, nearbyWp[idraw]->GetId());
134  }
135  }
136  }
137  }
138  }
139 
140  m_logger->trace("Done populating Workplaces");
141 }
142 
143 } // namespace geopop
struct geopop::GeoGridConfig::@2 info
Configuration data mostly for generating a population, but also for computing the required number of ...
Definition: GeoGridConfig.h:35
Header for the core ContactPool class.
double particpation_workplace
Participation of workplace (fraction of people of work age and not going to college and having employ...
Definition: GeoGridConfig.h:64
#define AssertThrow(CONDITION, MESSAGE, LOGGER)
Definition: Assert.h:68
STL namespace.
A Geographic grid of simulation region contains Locations that in turn contain an index to the Contac...
Definition: GeoGrid.h:41
unsigned int popcount_workplace
Number of individuals in Workplace.
AgeBrackets that determine participation in type of ContactPool.
Definition: AgeBrackets.h:22
Namespace for the geographic and demograhic classes.
Definition: Coordinate.h:21
void Apply(GeoGrid &, const GeoGridConfig &)
Populate the ContactPools type ID. This is a placeholder for the specializations. ...
Definition: Populator.h:51
double fraction_college_commuters
Fraction of college students that commute.
Definition: GeoGridConfig.h:67
struct geopop::GeoGridConfig::@0 param
Definition of .
unsigned int popcount_college
Number of individuals in College.
double fraction_workplace_commuters
Fraction of people in the workplace that commute.
Definition: GeoGridConfig.h:70
static bool HasAge(double age)
Definition: AgeBrackets.h:66
Namespace for the simulator and related classes.
Definition: Calendar.cpp:28
Namespace to manage types of ContactPool.
Definition: ContactType.cpp:28