result_io.h Source File

CPP API: result_io.h Source File
result_io.h
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2020-2026 MEmilio
3 *
4 * Authors: Wadim Koslow, Daniel Abele, Martin J. Kuehn
5 *
6 * Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de>
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20 #ifndef MEMILIO_IO_RESULT_IO_H
21 #define MEMILIO_IO_RESULT_IO_H
22 
23 #include "memilio/config.h"
24 
25 #ifdef MEMILIO_HAS_HDF5
26 
30 #include "memilio/io/mobility_io.h"
31 #include "memilio/io/io.h"
32 #include "boost/filesystem.hpp"
33 
34 namespace fs = boost::filesystem;
35 namespace mio
36 {
37 
46 IOResult<void> save_result(const std::vector<TimeSeries<ScalarType>>& result, const std::vector<int>& ids,
47  int num_groups, const std::string& filename);
48 
49 class SimulationResult
50 {
51 public:
57  SimulationResult(int num_groups, int num_infectionstates)
58  : m_groups(num_groups * num_infectionstates)
59  , m_totals(num_infectionstates)
60  {
61  }
62 
68  SimulationResult(const TimeSeries<ScalarType>& groups, const TimeSeries<ScalarType>& totals)
69  : m_groups(groups)
70  , m_totals(totals)
71  {
72  }
73 
77  const TimeSeries<ScalarType>& get_groups() const
78  {
79  return m_groups;
80  }
81 
85  const TimeSeries<ScalarType>& get_totals() const
86  {
87  return m_totals;
88  }
89 
90 private:
91  TimeSeries<ScalarType> m_groups;
92  TimeSeries<ScalarType> m_totals;
93 };
94 
99 IOResult<std::vector<SimulationResult>> read_result(const std::string& filename);
100 
111 template <class Model>
112 IOResult<void> save_result_with_params(const std::vector<TimeSeries<ScalarType>>& result,
113  const std::vector<Model>& params, const std::vector<int>& county_ids,
114  const fs::path& result_dir, size_t run_idx)
115 {
116  auto result_dir_run = result_dir / ("run" + std::to_string(run_idx));
117  BOOST_OUTCOME_TRY(create_directory(result_dir_run.string()));
118  BOOST_OUTCOME_TRY(save_result(result, county_ids, (int)(size_t)params[0].parameters.get_num_groups(),
119  (result_dir_run / "Result.h5").string()));
120  BOOST_OUTCOME_TRY(write_graph(Graph<Model, MobilityParameters<ScalarType>>(county_ids, params),
121  result_dir_run.string(), IOF_OmitDistributions));
122  return success();
123 }
124 
136 template <class Model>
137 IOResult<void> save_results(const std::vector<std::vector<TimeSeries<ScalarType>>>& ensemble_results,
138  const std::vector<std::vector<Model>>& ensemble_params, const std::vector<int>& county_ids,
139  const fs::path& result_dir, bool save_single_runs = true, bool save_percentiles = true)
140 {
141  //save results and sum of results over nodes
142  auto ensemble_result_sum = sum_nodes(ensemble_results);
143  auto num_groups = (int)(size_t)ensemble_params[0][0].parameters.get_num_groups();
144  if (save_single_runs) {
145  for (size_t i = 0; i < ensemble_result_sum.size(); ++i) {
146  BOOST_OUTCOME_TRY(save_result(ensemble_result_sum[i], {0}, num_groups,
147  (result_dir / ("results_run" + std::to_string(i) + "_sum.h5")).string()));
148  BOOST_OUTCOME_TRY(save_result(ensemble_results[i], county_ids, num_groups,
149  (result_dir / ("results_run" + std::to_string(i) + ".h5")).string()));
150  }
151  }
152 
153  if (save_percentiles) {
154  // make directories for percentiles
155  auto result_dir_p05 = result_dir / "p05";
156  auto result_dir_p25 = result_dir / "p25";
157  auto result_dir_p50 = result_dir / "p50";
158  auto result_dir_p75 = result_dir / "p75";
159  auto result_dir_p95 = result_dir / "p95";
160  BOOST_OUTCOME_TRY(create_directory(result_dir_p05.string()));
161  BOOST_OUTCOME_TRY(create_directory(result_dir_p25.string()));
162  BOOST_OUTCOME_TRY(create_directory(result_dir_p50.string()));
163  BOOST_OUTCOME_TRY(create_directory(result_dir_p75.string()));
164  BOOST_OUTCOME_TRY(create_directory(result_dir_p95.string()));
165 
166  // save percentiles of results, summed over nodes
167  {
168  auto ensemble_results_sum_p05 = ensemble_percentile(ensemble_result_sum, 0.05);
169  auto ensemble_results_sum_p25 = ensemble_percentile(ensemble_result_sum, 0.25);
170  auto ensemble_results_sum_p50 = ensemble_percentile(ensemble_result_sum, 0.50);
171  auto ensemble_results_sum_p75 = ensemble_percentile(ensemble_result_sum, 0.75);
172  auto ensemble_results_sum_p95 = ensemble_percentile(ensemble_result_sum, 0.95);
173 
174  BOOST_OUTCOME_TRY(
175  save_result(ensemble_results_sum_p05, {0}, num_groups, (result_dir_p05 / "Results_sum.h5").string()));
176  BOOST_OUTCOME_TRY(
177  save_result(ensemble_results_sum_p25, {0}, num_groups, (result_dir_p25 / "Results_sum.h5").string()));
178  BOOST_OUTCOME_TRY(
179  save_result(ensemble_results_sum_p50, {0}, num_groups, (result_dir_p50 / "Results_sum.h5").string()));
180  BOOST_OUTCOME_TRY(
181  save_result(ensemble_results_sum_p75, {0}, num_groups, (result_dir_p75 / "Results_sum.h5").string()));
182  BOOST_OUTCOME_TRY(
183  save_result(ensemble_results_sum_p95, {0}, num_groups, (result_dir_p95 / "Results_sum.h5").string()));
184  }
185 
186  // save percentiles of results
187  {
188  auto ensemble_results_p05 = ensemble_percentile(ensemble_results, 0.05);
189  auto ensemble_results_p25 = ensemble_percentile(ensemble_results, 0.25);
190  auto ensemble_results_p50 = ensemble_percentile(ensemble_results, 0.50);
191  auto ensemble_results_p75 = ensemble_percentile(ensemble_results, 0.75);
192  auto ensemble_results_p95 = ensemble_percentile(ensemble_results, 0.95);
193 
194  BOOST_OUTCOME_TRY(
195  save_result(ensemble_results_p05, county_ids, num_groups, (result_dir_p05 / "Results.h5").string()));
196  BOOST_OUTCOME_TRY(
197  save_result(ensemble_results_p25, county_ids, num_groups, (result_dir_p25 / "Results.h5").string()));
198  BOOST_OUTCOME_TRY(
199  save_result(ensemble_results_p50, county_ids, num_groups, (result_dir_p50 / "Results.h5").string()));
200  BOOST_OUTCOME_TRY(
201  save_result(ensemble_results_p75, county_ids, num_groups, (result_dir_p75 / "Results.h5").string()));
202  BOOST_OUTCOME_TRY(
203  save_result(ensemble_results_p95, county_ids, num_groups, (result_dir_p95 / "Results.h5").string()));
204  }
205 
206  // save percentiles of parameters
207  {
208  auto ensemble_params_p05 = ensemble_params_percentile(ensemble_params, 0.05);
209  auto ensemble_params_p25 = ensemble_params_percentile(ensemble_params, 0.25);
210  auto ensemble_params_p50 = ensemble_params_percentile(ensemble_params, 0.50);
211  auto ensemble_params_p75 = ensemble_params_percentile(ensemble_params, 0.75);
212  auto ensemble_params_p95 = ensemble_params_percentile(ensemble_params, 0.95);
213 
214  auto make_graph = [&county_ids](auto&& params) {
215  return Graph<Model, MobilityParameters<ScalarType>>(county_ids, params);
216  };
217  BOOST_OUTCOME_TRY(
218  write_graph(make_graph(ensemble_params_p05), result_dir_p05.string(), IOF_OmitDistributions));
219  BOOST_OUTCOME_TRY(
220  write_graph(make_graph(ensemble_params_p25), result_dir_p25.string(), IOF_OmitDistributions));
221  BOOST_OUTCOME_TRY(
222  write_graph(make_graph(ensemble_params_p50), result_dir_p50.string(), IOF_OmitDistributions));
223  BOOST_OUTCOME_TRY(
224  write_graph(make_graph(ensemble_params_p75), result_dir_p75.string(), IOF_OmitDistributions));
225  BOOST_OUTCOME_TRY(
226  write_graph(make_graph(ensemble_params_p95), result_dir_p95.string(), IOF_OmitDistributions));
227  }
228  }
229  return success();
230 }
231 
232 } // namespace mio
233 
234 #endif // MEMILIO_HAS_HDF5
235 
236 #endif // MEMILIO_IO_RESULT_IO_H
std::vector< Model > ensemble_params_percentile(const std::vector< std::vector< Model >> &ensemble_params, ScalarType p)
computes the p percentile of the parameters for each node.
Definition: models/abm/analyze_result.h:40
A collection of classes to simplify handling of matrix shapes in meta programming.
Definition: models/abm/analyze_result.h:30
IOResult< bool > create_directory(std::string const &rel_path, std::string &abs_path)
Creates a directory in the file system.
Definition: io.cpp:37
auto i
Definition: io.h:809
auto success()
Create an object that is implicitly convertible to a succesful IOResult<void>.
Definition: io.h:359
std::vector< TimeSeries< FP > > ensemble_percentile(const std::vector< std::vector< TimeSeries< FP >>> &ensemble_result, FP p)
computes the p percentile of the result for each compartment, node, and time point.
Definition: memilio/data/analyze_result.h:317
@ IOF_OmitDistributions
Don't serialize distributions for types that contain both a specific value and a distribution from wh...
Definition: io.h:76
std::vector< std::vector< TimeSeries< FP > > > sum_nodes(const std::vector< std::vector< TimeSeries< FP >>> &ensemble_result)
Definition: memilio/data/analyze_result.h:268