mobility_io.h Source File

CPP API: mobility_io.h Source File
mobility_io.h
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2020-2026 MEmilio
3 *
4 * Authors: Daniel Abele, Wadim Koslow, Henrik Zunker, 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_MOBILITY_IO_H
21 #define MEMILIO_IO_MOBILITY_IO_H
22 
24 #include "memilio/mobility/graph.h"
27 
28 namespace mio
29 {
30 
36 std::vector<std::string> split(const std::string& s, char delimiter);
37 
42 IOResult<int> count_lines(const std::string& filename);
43 
51 IOResult<Eigen::MatrixXd> read_mobility_formatted(const std::string& filename);
52 
59 IOResult<Eigen::MatrixXd> read_mobility_plain(const std::string& filename);
60 
61 #ifdef MEMILIO_HAS_JSONCPP
62 
70 template <typename FP, class Model>
71 IOResult<void> write_graph(const Graph<Model, MobilityParameters<FP>>& graph, const std::string& directory,
72  int ioflags = IOF_None)
73 {
74  assert(graph.nodes().size() > 0 && "Graph Nodes are empty");
75 
76  std::string abs_path;
77  BOOST_OUTCOME_TRY(auto&& created, create_directory(directory, abs_path));
78 
79  if (created) {
80  log_info("Results are stored in {:s}/results.", mio::get_current_dir_name());
81  }
82  else {
83  log_info("Results are stored in {:s}/results. Files from previous "
84  "graph will be "
85  "overwritten",
87  }
88 
89  //write two files per node
90  //one file that contains outgoing edges from the node
91  //one file for the model (parameters and population)
92  for (auto inode = size_t(0); inode < graph.nodes().size(); ++inode) {
93  //node
94  const auto node = graph.nodes()[inode];
95  BOOST_OUTCOME_TRY(auto&& js_node_model, serialize_json(node.property, ioflags));
96  Json::Value js_node(Json::objectValue);
97  js_node["NodeId"] = node.id;
98  js_node["Model"] = js_node_model;
99  auto node_filename = path_join(abs_path, "GraphNode" + std::to_string(inode) + ".json");
100  BOOST_OUTCOME_TRY(write_json(node_filename, js_node));
101 
102  //list of edges
103  auto out_edges = graph.out_edges(inode);
104  if (out_edges.size()) {
105  Json::Value js_edges(Json::arrayValue);
106  for (auto& e : graph.out_edges(inode)) {
107  BOOST_OUTCOME_TRY(auto&& js_edge_params, serialize_json(e.property, ioflags));
108  Json::Value js_edge{Json::objectValue};
109  js_edge["StartNodeIndex"] = Json::UInt64(e.start_node_idx);
110  js_edge["EndNodeIndex"] = Json::UInt64(e.end_node_idx);
111  js_edge["Parameters"] = js_edge_params;
112  js_edges.append(std::move(js_edge));
113  }
114  auto edge_filename = path_join(abs_path, "GraphEdges_node" + std::to_string(inode) + ".json");
115  BOOST_OUTCOME_TRY(write_json(edge_filename, js_edges));
116  }
117  }
118 
119  return success();
120 }
121 
130 template <typename FP, class Model>
131 IOResult<Graph<Model, MobilityParameters<FP>>> read_graph(const std::string& directory, int ioflags = IOF_None,
132  bool read_edges = true)
133 {
134  std::string abs_path;
135  if (!file_exists(directory, abs_path)) {
136  log_error("Directory {} does not exist.", directory);
137  return failure(StatusCode::FileNotFound, directory);
138  }
139 
140  auto graph = Graph<Model, MobilityParameters<FP>>{};
141 
142  //read nodes, as many as files are available
143  for (auto inode = 0;; ++inode) {
144  auto node_filename = path_join(abs_path, "GraphNode" + std::to_string(inode) + ".json");
145  if (!file_exists(node_filename, node_filename)) {
146  break;
147  }
148  BOOST_OUTCOME_TRY(auto&& js_node, read_json(node_filename));
149  if (!js_node["NodeId"].isInt()) {
150  log_error("NodeId field must be an integer.");
151  return failure(StatusCode::InvalidType, node_filename + ", NodeId must be an integer.");
152  }
153  auto node_id = js_node["NodeId"].asInt();
154  BOOST_OUTCOME_TRY(auto&& model, deserialize_json(js_node["Model"], Tag<Model>{}, ioflags));
155  graph.add_node(node_id, model);
156  }
157 
158  //read edges; nodes must already be available for that)
159  if (read_edges) {
160  for (auto inode = size_t(0); inode < graph.nodes().size(); ++inode) {
161  //list of edges
162  auto edge_filename = path_join(abs_path, "GraphEdges_node" + std::to_string(inode) + ".json");
163  BOOST_OUTCOME_TRY(auto&& js_edges, read_json(edge_filename));
164 
165  for (auto& e : js_edges) {
166  auto start_node_idx = inode;
167  auto js_end_node_idx = e["EndNodeIndex"];
168  if (!js_end_node_idx.isUInt64()) {
169  log_error("EndNodeIndex must be an integer.");
170  return failure(StatusCode::InvalidType, edge_filename + ", EndNodeIndex must be an integer.");
171  }
172  auto end_node_idx = js_end_node_idx.asUInt64();
173  if (end_node_idx >= graph.nodes().size()) {
174  log_error("EndNodeIndex not in range of number of graph nodes.");
176  edge_filename + ", EndNodeIndex not in range of number of graph nodes.");
177  }
178  BOOST_OUTCOME_TRY(auto&& parameters,
179  deserialize_json(e["Parameters"], Tag<MobilityParameters<FP>>{}, ioflags));
180  graph.add_edge(start_node_idx, end_node_idx, parameters);
181  }
182  }
183  }
184 
185  return success(graph);
186 }
187 
188 #endif //MEMILIO_HAS_JSONCPP
189 #ifdef MEMILIO_HAS_HDF5
197 IOResult<void> save_edges(const std::vector<TimeSeries<ScalarType>>& results,
198  const std::vector<std::pair<int, int>>& ids, const std::string& filename);
199 
209 IOResult<void> save_edges(const std::vector<std::vector<TimeSeries<ScalarType>>>& ensemble_edges,
210  const std::vector<std::pair<int, int>>& pairs_edges, const fs::path& result_dir,
211  bool save_single_runs = true, bool save_percentiles = true);
212 
213 #endif //MEMILIO_HAS_HDF5
214 
215 } // namespace mio
216 
217 #endif // MEMILIO_IO_MOBILITY_IO_H
int size(Comm comm)
Return the size of the given communicator.
Definition: miompi.cpp:75
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 failure(const IOStatus &s)
Create an object that is implicitly convertible to an error IOResult<T>.
Definition: io.h:380
std::string get_current_dir_name()
Returns the current working directory name.
Definition: io.cpp:31
boost::outcome_v2::in_place_type_t< T > Tag
Type that is used for overload resolution.
Definition: io.h:407
IOResult< int > count_lines(const std::string &filename)
Counts lines of txt file.
Definition: mobility_io.cpp:47
auto success()
Create an object that is implicitly convertible to a succesful IOResult<void>.
Definition: io.h:359
void log_error(spdlog::string_view_t fmt, const Args &... args)
Definition: logging.h:100
bool file_exists(std::string const &rel_path, std::string &abs_path)
Check if a file exists.
Definition: io.cpp:66
std::vector< std::string > split(const std::string &s, char delimitor)
Splits string into a Vector of strings according to delimiter.
Definition: mobility_io.cpp:36
@ IOF_None
default behavior.
Definition: io.h:70
std::string path_join(String &&base, Strings &&... app)
join one ore more strings with path separators.
Definition: stl_util.h:268
IOResult< Eigen::MatrixXd > read_mobility_formatted(const std::string &filename)
Reads formatted mobility or contact data which is given in columns from_str to_str from_rs to_rs coun...
Definition: mobility_io.cpp:63
void log_info(spdlog::string_view_t fmt, const Args &... args)
Definition: logging.h:94
IOResult< Eigen::MatrixXd > read_mobility_plain(const std::string &filename)
Reads txt mobility data or contact which is given by values only and separated by spaces.
Definition: mobility_io.cpp:123