Stride Reference Manual  - generated for commit 9643b11
StanController.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, 2018, Kuylen E, Willem L, Broeckhove J
14  */
15 
21 #include "StanController.h"
22 
23 #include "pop/Population.h"
24 #include "sim/Sim.h"
25 #include "sim/SimRunner.h"
26 #include "util/BoxPlotData.h"
27 #include "util/CSV.h"
28 #include "util/ConfigInfo.h"
29 #include "util/FileSys.h"
30 #include "util/StringUtils.h"
31 #include "viewers/InfectedViewer.h"
32 
33 #include <boost/property_tree/ptree.hpp>
34 #include <initializer_list>
35 #include <iostream>
36 #include <random>
37 #include <vector>
38 
39 using namespace std;
40 using namespace stride;
41 using namespace stride::util;
42 using namespace boost::property_tree;
43 
44 namespace stride {
45 
46 StanController::StanController(const ptree& config, const string& name) : ControlHelper(config, name) {}
47 
49 {
50  // -----------------------------------------------------------------------------------------
51  // Prelims.
52  // -----------------------------------------------------------------------------------------
53  CheckEnv();
55  InstallLogger();
56  LogStartup();
57 
58  // -----------------------------------------------------------------------------------------
59  // Stan scenario: step 2, make seeds for the stochastic analysis.
60  // -----------------------------------------------------------------------------------------
61  const auto stanCount = m_config.get<unsigned int>("run.stan_count");
62  random_device rd;
63  vector<unsigned int> rd_values;
64  vector<string> seeds;
65  for (unsigned int i = 0; i < 4 * stanCount; i++) {
66  rd_values.emplace_back(rd());
67  }
68  for (unsigned int i = 0; i < stanCount; i++) {
69  seeds.emplace_back(ToString(rd_values[2 * i]) + "," + ToString(rd_values[2 * i + 1]) + ","
70  + ToString(rd_values[2 * i + 2]) + "," + ToString(rd_values[2 * i + 3]));
71  }
72  vector<vector<unsigned int>> results(stanCount);
73 
74  // -----------------------------------------------------------------------------------------
75  // Instantiate simRunners & run, once for each seed.
76  // Multiple runs in parallel, individual runs in single thread.
77  // -----------------------------------------------------------------------------------------
78  m_config.put("run.num_threads", 1);
79 
80 #pragma omp parallel for num_threads(ConfigInfo::NumberAvailableThreads())
81  for (unsigned int i = 0U; i < stanCount; ++i) {
82 
83  // ---------------------------------------------------------------------------------
84  // Stan scenario: step 2, build a single stream random number manager for each run.
85  // ---------------------------------------------------------------------------------
86  ptree configPt(m_config);
87  configPt.put("run.rng_seed", seeds[i]);
88  RnMan rnMan{RnInfo{seeds[i], "", 1U}};
89 
90  m_stride_logger->info("Starting run using seed {}", seeds[i]);
91  // ---------------------------------------------------------------------------------
92  // Stan scenario: step 3, build a population as specified in config.
93  // ---------------------------------------------------------------------------------
94  auto pop = Population::Create(configPt, rnMan);
95 
96  // -----------------------------------------------------------------------------------------
97  // Sim scenario: step 4, create a simulator, as described by the parameter in the config.
98  // -----------------------------------------------------------------------------------------
99  auto sim = Sim::Create(configPt, pop, rnMan);
100 
101  // ---------------------------------------------------------------------------------
102  // Stan scenario: step 5, build a simulator, register viewer, run, collect results.
103  // ---------------------------------------------------------------------------------
104  auto runner = make_shared<SimRunner>(configPt, sim);
105  auto iViewer = make_shared<viewers::InfectedViewer>(runner);
106  runner->Register(iViewer, bind(&viewers::InfectedViewer::Update, iViewer, std::placeholders::_1));
107  runner->Run();
108  results[i] = iViewer->GetInfectionCounts();
109  }
110 
111  for (unsigned int i = 0U; i < stanCount; ++i) {
112  m_stride_logger->info("For run with seed {} final infected count is: {}", seeds[i], results[i].back());
113  }
114 
115  // -----------------------------------------------------------------------------------------
116  // Stan scenario: step 6, output to file.
117  // -----------------------------------------------------------------------------------------
118  const auto numDays = m_config.get<unsigned int>("run.num_days");
119  CSV csv(stanCount);
120  for (unsigned int i = 0U; i < numDays + 1; ++i) {
121  vector<unsigned int> v;
122  for (const auto& res : results) {
123  v.emplace_back(res[i]);
124  }
125  csv.AddRow(v.begin(), v.end());
126  }
127  csv.Write(FileSys::BuildPath(m_config.get<string>("run.output_prefix"), "stan_infected.csv"));
128 }
129 
130 } // namespace stride
void Control()
Actual run of the simulator.
Observer for infection count at each sim step.
void Update(sim_event::Id id)
Let viewer perform update.
boost::property_tree::ptree m_config
Main configuration for run and sim.
Definition: ControlHelper.h:78
void CheckEnv()
Check install environment.
static std::shared_ptr< Population > Create()
Create an empty Population, used in gengeopop.
Definition: Population.cpp:96
Utilities for the project.
string ToString(Id l)
Converts a LogMode value to corresponding name.
std::shared_ptr< spdlog::logger > m_stride_logger
General logger.
Definition: ControlHelper.h:82
void LogStartup()
Logs info on setup for cli environment to stride_logger.
static std::shared_ptr< Sim > Create(const boost::property_tree::ptree &config, std::shared_ptr< Population > pop, util::RnMan rnMan)
Create Sim initialized by the configuration in property tree and population.
Header file for BoxPlotData.
STL namespace.
static filesys::path BuildPath(const std::string &output_prefix, const std::string &filename)
Interpret prefix (directory or filename prefix) and return appropriate path.
Definition: FileSys.cpp:52
Info on configuration.
Header for the St(ochastic)an(alysis)Controller.
Header file for the core Population class.
Controls a simulation run initiated with the command line interface (cli).
Definition: ControlHelper.h:45
Miscellaneous string utilities.
Header for the Simulator class.
Interface for install directory queries.
A collection of CSVRow elements.
Definition: CSV.h:46
Namespace for the simulator and related classes.
Definition: Calendar.cpp:28
Header file of base class for config that needs to be read from a file.
Information on random number management state.
Definition: RnInfo.h:32
void InstallLogger()
Make the appropriate logger for cli environment and register as stride_logger.
Header for the SimRunner class.