20 #ifndef MEMILIO_IO_MOBILITY_IO_H
21 #define MEMILIO_IO_MOBILITY_IO_H
36 std::vector<std::string>
split(
const std::string& s,
char delimiter);
42 IOResult<int>
count_lines(
const std::string& filename);
61 #ifdef MEMILIO_HAS_JSONCPP
70 template <
typename FP,
class Model>
71 IOResult<void> write_graph(
const Graph<Model, MobilityParameters<FP>>& graph,
const std::string& directory,
74 assert(graph.nodes().size() > 0 &&
"Graph Nodes are empty");
83 log_info(
"Results are stored in {:s}/results. Files from previous "
92 for (
auto inode =
size_t(0); inode < graph.nodes().
size(); ++inode) {
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));
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));
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));
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)
134 std::string abs_path;
136 log_error(
"Directory {} does not exist.", directory);
140 auto graph = Graph<Model, MobilityParameters<FP>>{};
143 for (
auto inode = 0;; ++inode) {
144 auto node_filename =
path_join(abs_path,
"GraphNode" + std::to_string(inode) +
".json");
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.");
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);
160 for (
auto inode =
size_t(0); inode < graph.nodes().
size(); ++inode) {
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));
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.");
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.");
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);
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);
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);
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