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 
33 namespace mio
34 {
35 
44 IOResult<void> save_result(const std::vector<TimeSeries<ScalarType>>& result, const std::vector<int>& ids,
45  int num_groups, const std::string& filename);
46 
47 class SimulationResult
48 {
49 public:
55  SimulationResult(int num_groups, int num_infectionstates)
56  : m_groups(num_groups * num_infectionstates)
57  , m_totals(num_infectionstates)
58  {
59  }
60 
66  SimulationResult(const TimeSeries<ScalarType>& groups, const TimeSeries<ScalarType>& totals)
67  : m_groups(groups)
68  , m_totals(totals)
69  {
70  }
71 
75  const TimeSeries<ScalarType>& get_groups() const
76  {
77  return m_groups;
78  }
79 
83  const TimeSeries<ScalarType>& get_totals() const
84  {
85  return m_totals;
86  }
87 
88 private:
89  TimeSeries<ScalarType> m_groups;
90  TimeSeries<ScalarType> m_totals;
91 };
92 
97 IOResult<std::vector<SimulationResult>> read_result(const std::string& filename);
98 
109 template <class Model>
110 IOResult<void> save_result_with_params(const std::vector<TimeSeries<ScalarType>>& result,
111  const std::vector<Model>& params, const std::vector<int>& county_ids,
112  const std::filesystem::path& result_dir, size_t run_idx)
113 {
114  auto result_dir_run = result_dir / ("run" + std::to_string(run_idx));
115  BOOST_OUTCOME_TRY(create_directory(result_dir_run.string()));
116  BOOST_OUTCOME_TRY(save_result(result, county_ids, (int)(size_t)params[0].parameters.get_num_groups(),
117  (result_dir_run / "Result.h5").string()));
118  BOOST_OUTCOME_TRY(write_graph(Graph<Model, MobilityParameters<ScalarType>>(county_ids, params),
119  result_dir_run.string(), IOF_OmitDistributions));
120  return success();
121 }
122 
134 template <class Model>
135 IOResult<void> save_results(const std::vector<std::vector<TimeSeries<ScalarType>>>& ensemble_results,
136  const std::vector<std::vector<Model>>& ensemble_params, const std::vector<int>& county_ids,
137  const std::filesystem::path& result_dir, bool save_single_runs = true,
138  bool save_percentiles = true)
139 {
140  //save results and sum of results over nodes
141  auto ensemble_result_sum = sum_nodes(ensemble_results);
142  auto num_groups = (int)(size_t)ensemble_params[0][0].parameters.get_num_groups();
143  if (save_single_runs) {
144  for (size_t i = 0; i < ensemble_result_sum.size(); ++i) {
145  BOOST_OUTCOME_TRY(save_result(ensemble_result_sum[i], {0}, num_groups,
146  (result_dir / ("results_run" + std::to_string(i) + "_sum.h5")).string()));
147  BOOST_OUTCOME_TRY(save_result(ensemble_results[i], county_ids, num_groups,
148  (result_dir / ("results_run" + std::to_string(i) + ".h5")).string()));
149  }
150  }
151 
152  if (save_percentiles) {
153  // make directories for percentiles
154  auto result_dir_p05 = result_dir / "p05";
155  auto result_dir_p25 = result_dir / "p25";
156  auto result_dir_p50 = result_dir / "p50";
157  auto result_dir_p75 = result_dir / "p75";
158  auto result_dir_p95 = result_dir / "p95";
159  BOOST_OUTCOME_TRY(create_directory(result_dir_p05.string()));
160  BOOST_OUTCOME_TRY(create_directory(result_dir_p25.string()));
161  BOOST_OUTCOME_TRY(create_directory(result_dir_p50.string()));
162  BOOST_OUTCOME_TRY(create_directory(result_dir_p75.string()));
163  BOOST_OUTCOME_TRY(create_directory(result_dir_p95.string()));
164 
165  // save percentiles of results, summed over nodes
166  {
167  auto ensemble_results_sum_p05 = ensemble_percentile(ensemble_result_sum, 0.05);
168  auto ensemble_results_sum_p25 = ensemble_percentile(ensemble_result_sum, 0.25);
169  auto ensemble_results_sum_p50 = ensemble_percentile(ensemble_result_sum, 0.50);
170  auto ensemble_results_sum_p75 = ensemble_percentile(ensemble_result_sum, 0.75);
171  auto ensemble_results_sum_p95 = ensemble_percentile(ensemble_result_sum, 0.95);
172 
173  BOOST_OUTCOME_TRY(
174  save_result(ensemble_results_sum_p05, {0}, num_groups, (result_dir_p05 / "Results_sum.h5").string()));
175  BOOST_OUTCOME_TRY(
176  save_result(ensemble_results_sum_p25, {0}, num_groups, (result_dir_p25 / "Results_sum.h5").string()));
177  BOOST_OUTCOME_TRY(
178  save_result(ensemble_results_sum_p50, {0}, num_groups, (result_dir_p50 / "Results_sum.h5").string()));
179  BOOST_OUTCOME_TRY(
180  save_result(ensemble_results_sum_p75, {0}, num_groups, (result_dir_p75 / "Results_sum.h5").string()));
181  BOOST_OUTCOME_TRY(
182  save_result(ensemble_results_sum_p95, {0}, num_groups, (result_dir_p95 / "Results_sum.h5").string()));
183  }
184 
185  // save percentiles of results
186  {
187  auto ensemble_results_p05 = ensemble_percentile(ensemble_results, 0.05);
188  auto ensemble_results_p25 = ensemble_percentile(ensemble_results, 0.25);
189  auto ensemble_results_p50 = ensemble_percentile(ensemble_results, 0.50);
190  auto ensemble_results_p75 = ensemble_percentile(ensemble_results, 0.75);
191  auto ensemble_results_p95 = ensemble_percentile(ensemble_results, 0.95);
192 
193  BOOST_OUTCOME_TRY(
194  save_result(ensemble_results_p05, county_ids, num_groups, (result_dir_p05 / "Results.h5").string()));
195  BOOST_OUTCOME_TRY(
196  save_result(ensemble_results_p25, county_ids, num_groups, (result_dir_p25 / "Results.h5").string()));
197  BOOST_OUTCOME_TRY(
198  save_result(ensemble_results_p50, county_ids, num_groups, (result_dir_p50 / "Results.h5").string()));
199  BOOST_OUTCOME_TRY(
200  save_result(ensemble_results_p75, county_ids, num_groups, (result_dir_p75 / "Results.h5").string()));
201  BOOST_OUTCOME_TRY(
202  save_result(ensemble_results_p95, county_ids, num_groups, (result_dir_p95 / "Results.h5").string()));
203  }
204 
205  // save percentiles of parameters
206  {
207  auto ensemble_params_p05 = ensemble_params_percentile(ensemble_params, 0.05);
208  auto ensemble_params_p25 = ensemble_params_percentile(ensemble_params, 0.25);
209  auto ensemble_params_p50 = ensemble_params_percentile(ensemble_params, 0.50);
210  auto ensemble_params_p75 = ensemble_params_percentile(ensemble_params, 0.75);
211  auto ensemble_params_p95 = ensemble_params_percentile(ensemble_params, 0.95);
212 
213  auto make_graph = [&county_ids](auto&& params) {
214  return Graph<Model, MobilityParameters<ScalarType>>(county_ids, params);
215  };
216  BOOST_OUTCOME_TRY(
217  write_graph(make_graph(ensemble_params_p05), result_dir_p05.string(), IOF_OmitDistributions));
218  BOOST_OUTCOME_TRY(
219  write_graph(make_graph(ensemble_params_p25), result_dir_p25.string(), IOF_OmitDistributions));
220  BOOST_OUTCOME_TRY(
221  write_graph(make_graph(ensemble_params_p50), result_dir_p50.string(), IOF_OmitDistributions));
222  BOOST_OUTCOME_TRY(
223  write_graph(make_graph(ensemble_params_p75), result_dir_p75.string(), IOF_OmitDistributions));
224  BOOST_OUTCOME_TRY(
225  write_graph(make_graph(ensemble_params_p95), result_dir_p95.string(), IOF_OmitDistributions));
226  }
227  }
228  return success();
229 }
230 
231 } // namespace mio
232 
233 #endif // MEMILIO_HAS_HDF5
234 
235 #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(const std::filesystem::path &rel_path, std::string &abs_path, bool create_parents)
Creates a directory in the file system.
Definition: io.cpp:35
auto i
Definition: io.h:810
auto success()
Create an object that is implicitly convertible to a succesful IOResult<void>.
Definition: io.h:360
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:77
std::vector< std::vector< TimeSeries< FP > > > sum_nodes(const std::vector< std::vector< TimeSeries< FP >>> &ensemble_result)
Definition: memilio/data/analyze_result.h:268