diff --git a/cpp/README.md b/cpp/README.md index 930fa5e7a4..7a65190671 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -28,7 +28,7 @@ The following table lists the dependencies that are used. Most of them are requi |---------|----------|----------|-----------------------|-------| | spdlog | 1.11.0 | Yes | Yes (git repo) | https://github.com/gabime/spdlog | | Eigen | 3.3.9 | Yes | Yes (git repo) | http://gitlab.com/libeigen/eigen | -| Boost | 1.75.0 | Yes | Yes (.tar.gz archive) | https://www.boost.org/ | +| Boost | 1.84.0 | Yes | Yes (git repo) | https://github.com/boostorg/boost | | JsonCpp | 1.9.5 | No | Yes (git repo) | https://github.com/open-source-parsers/jsoncpp | | HDF5 | 1.12.0 | No | No | https://www.hdfgroup.org/, package libhdf5-dev on apt (Ubuntu) | | GoogleTest | 1.10 | For Tests only | Yes (git repo) | https://github.com/google/googletest | diff --git a/cpp/cmake/BuildBoost.cmake b/cpp/cmake/BuildBoost.cmake deleted file mode 100644 index d52e730a51..0000000000 --- a/cpp/cmake/BuildBoost.cmake +++ /dev/null @@ -1,55 +0,0 @@ -set (BOOST_DIR ${PROJECT_BINARY_DIR}/boost_1_75_0) -set (BOOST_ARCHIVE ${PROJECT_SOURCE_DIR}/thirdparty/boost_1_75_0.tar.gz) -set (Boost_VERSION "1.75.0") -set (BOOST_LIB_TYPE STATIC) - -if (NOT EXISTS ${BOOST_DIR}) - message(STATUS "Extracting boost") - execute_process ( - COMMAND ${CMAKE_COMMAND} -E tar xzf ${BOOST_ARCHIVE} - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - ) -endif() - -# boost -add_library(boost INTERFACE) -add_library(Boost::boost ALIAS boost) -target_include_directories(boost SYSTEM INTERFACE - $ -) - -add_library(boost_disable_autolink INTERFACE) -target_compile_definitions(boost_disable_autolink INTERFACE BOOST_ALL_NO_LIB) -add_library(Boost::disable_autolinking ALIAS boost_disable_autolink) - -add_library(boost_filesystem STATIC - ${BOOST_DIR}/libs/filesystem/src/codecvt_error_category.cpp - ${BOOST_DIR}/libs/filesystem/src/directory.cpp - ${BOOST_DIR}/libs/filesystem/src/exception.cpp - ${BOOST_DIR}/libs/filesystem/src/operations.cpp - ${BOOST_DIR}/libs/filesystem/src/path.cpp - ${BOOST_DIR}/libs/filesystem/src/path_traits.cpp - ${BOOST_DIR}/libs/filesystem/src/portability.cpp - ${BOOST_DIR}/libs/filesystem/src/unique_path.cpp - ${BOOST_DIR}/libs/filesystem/src/utf8_codecvt_facet.cpp - ${BOOST_DIR}/libs/filesystem/src/windows_file_codecvt.cpp -) - -target_link_libraries(boost_filesystem PUBLIC boost_disable_autolink boost) -set_property(TARGET boost_filesystem PROPERTY POSITION_INDEPENDENT_CODE ON) -add_library(Boost::filesystem ALIAS boost_filesystem) -if(NOT MSVC) #on gcc and apple clang we need to define BOOST_NO_CXX98_FUNCTION_BASE because a deprecated function is sometimes used in boost - target_compile_definitions(boost_filesystem PUBLIC BOOST_NO_CXX98_FUNCTION_BASE) -endif( ) - - - -set(Boost_LIBRARIES Boost::boost Boost::filesystem) -set(Boost_FOUND ON) - -#install (TARGETS -# boost -# boost_disable_autolink -# boost_filesystem -# ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} -#) diff --git a/cpp/examples/ode_secir_parameter_study.cpp b/cpp/examples/ode_secir_parameter_study.cpp index e8861da678..9538801db5 100644 --- a/cpp/examples/ode_secir_parameter_study.cpp +++ b/cpp/examples/ode_secir_parameter_study.cpp @@ -35,7 +35,7 @@ write_single_run_result(const size_t run, const mio::Graph>, mio::MigrationEdge>& graph) { std::string abs_path; - BOOST_OUTCOME_TRY(created, mio::create_directory("results", abs_path)); + BOOST_OUTCOME_TRY(auto&& created, mio::create_directory("results", abs_path)); if (run == 0) { std::cout << "Results are stored in " << abs_path << '\n'; @@ -48,7 +48,7 @@ write_single_run_result(const size_t run, //omit edges to save space as they are not sampled int inode = 0; for (auto&& node : graph.nodes()) { - BOOST_OUTCOME_TRY(js_node_model, serialize_json(node.property.get_result(), mio::IOF_OmitDistributions)); + BOOST_OUTCOME_TRY(auto&& js_node_model, serialize_json(node.property.get_result(), mio::IOF_OmitDistributions)); Json::Value js_node(Json::objectValue); js_node["NodeId"] = node.id; js_node["Model"] = js_node_model; diff --git a/cpp/examples/serialize.cpp b/cpp/examples/serialize.cpp index 316b82ba15..c9d4d35c8a 100644 --- a/cpp/examples/serialize.cpp +++ b/cpp/examples/serialize.cpp @@ -123,8 +123,8 @@ mio::IOResult print_json() //If the operation failed, the error is returned immediately. //If the operation was succesful, the result is unpacked and assigned to a new variable. //e.g. - BOOST_OUTCOME_TRY(js, rslt); - //could also be BOOST_OUTCOME_TRY(js, mio::serialize_json(b)) in one line + BOOST_OUTCOME_TRY(auto&& js, rslt); + //could also be BOOST_OUTCOME_TRY(auto&& js, mio::serialize_json(b)) in one line //print json (Json::Value) to console //could also write to file or do anything else. diff --git a/cpp/memilio/io/binary_serializer.h b/cpp/memilio/io/binary_serializer.h index a4315360e9..2366ba56d4 100644 --- a/cpp/memilio/io/binary_serializer.h +++ b/cpp/memilio/io/binary_serializer.h @@ -255,8 +255,7 @@ class BinarySerializerContext : public SerializerBase BinarySerializerObject create_object(const std::string& type) { auto obj = BinarySerializerObject(m_stream, m_status, m_flags); - if (m_flags & IOF_IncludeTypeInfo) - { + if (m_flags & IOF_IncludeTypeInfo) { obj.add_element("Type", type); } return obj; @@ -269,13 +268,14 @@ class BinarySerializerContext : public SerializerBase BinarySerializerObject expect_object(const std::string& type) { auto obj = BinarySerializerObject(m_stream, m_status, m_flags); - if (m_flags & IOF_IncludeTypeInfo) - { + if (m_flags & IOF_IncludeTypeInfo) { auto type_result = obj.expect_element("Type", Tag{}); if (!type_result) { *m_status = IOStatus(StatusCode::InvalidType, "No TypeInfo in stream."); - } else if(type_result.value() != type) { - *m_status = IOStatus(StatusCode::InvalidType, "Unexpected type in stream:" + type_result.value() + ". Expected " + type); + } + else if (type_result.value() != type) { + *m_status = IOStatus(StatusCode::InvalidType, + "Unexpected type in stream:" + type_result.value() + ". Expected " + type); } } return BinarySerializerObject(m_stream, m_status, m_flags); @@ -400,11 +400,11 @@ template IOResult> BinarySerializerObject::expect_list(const std::string& name, Tag) { mio::unused(name); - BOOST_OUTCOME_TRY(size, expect_element("Size", Tag{})); + BOOST_OUTCOME_TRY(auto&& size, expect_element("Size", Tag{})); std::vector v; v.reserve(size); for (auto i = size_t(0); i < size; ++i) { - BOOST_OUTCOME_TRY(t, expect_element("Item", Tag{})); + BOOST_OUTCOME_TRY(auto&& t, expect_element("Item", Tag{})); v.emplace_back(std::move(t)); } return success(v); @@ -424,9 +424,9 @@ template IOResult> BinarySerializerObject::expect_optional(const std::string& name, Tag) { mio::unused(name); - BOOST_OUTCOME_TRY(size, expect_element("Exists", Tag{})); + BOOST_OUTCOME_TRY(auto&& size, expect_element("Exists", Tag{})); if (size) { - BOOST_OUTCOME_TRY(t, expect_element("Value", Tag{})); + BOOST_OUTCOME_TRY(auto&& t, expect_element("Value", Tag{})); return mio::success(t); } return mio::success(boost::optional{}); @@ -448,7 +448,6 @@ ByteStream serialize_binary(const T& t, int flags = 0) return stream; } - /** * Deserialize an object from binary format. * @param stream ByteStream that contains the bytes that represent the object. diff --git a/cpp/memilio/io/cli.h b/cpp/memilio/io/cli.h index de49f08394..71db8cea6c 100644 --- a/cpp/memilio/io/cli.h +++ b/cpp/memilio/io/cli.h @@ -584,7 +584,7 @@ mio::IOResult command_line_interface(const std::string& executable_name, c i++; // skip the PrintOption argument for (; i < argc && !Identifier(argv[i]).is_option(); i++) { // try to get the parameter's json value - BOOST_OUTCOME_TRY(value, get_param(parameters, argv[i])); + BOOST_OUTCOME_TRY(auto&& value, get_param(parameters, argv[i])); // print the name (or alias) and value os << "Option " << argv[i] << ":\n" << value << "\n"; } diff --git a/cpp/memilio/io/epi_data.cpp b/cpp/memilio/io/epi_data.cpp index f019427b43..c085d7e479 100644 --- a/cpp/memilio/io/epi_data.cpp +++ b/cpp/memilio/io/epi_data.cpp @@ -36,7 +36,7 @@ std::vector VaccinationDataEntry::age_group_names = {"0-4", "5-14", IOResult> get_node_ids(const std::string& path, bool is_node_for_county, bool rki_age_groups) { - BOOST_OUTCOME_TRY(population_data, read_population_data(path, rki_age_groups)); + BOOST_OUTCOME_TRY(auto&& population_data, read_population_data(path, rki_age_groups)); std::vector id; id.reserve(population_data.size()); for (auto&& entry : population_data) { diff --git a/cpp/memilio/io/epi_data.h b/cpp/memilio/io/epi_data.h index 412a27ab4d..1ccc4586b9 100644 --- a/cpp/memilio/io/epi_data.h +++ b/cpp/memilio/io/epi_data.h @@ -58,7 +58,7 @@ class StringDate : public Date return apply( io, [](auto&& str_) -> IOResult { - BOOST_OUTCOME_TRY(date, parse_date(str_)); + BOOST_OUTCOME_TRY(auto&& date, parse_date(str_)); return success(date); }, str); @@ -177,7 +177,7 @@ class ConfirmedCasesDataEntry */ inline IOResult> deserialize_confirmed_cases_data(const Json::Value& jsvalue) { - BOOST_OUTCOME_TRY(cases_data, deserialize_json(jsvalue, Tag>{})); + BOOST_OUTCOME_TRY(auto&& cases_data, deserialize_json(jsvalue, Tag>{})); //filter entries with unknown age group auto it = std::remove_if(cases_data.begin(), cases_data.end(), [](auto&& rki_entry) { return rki_entry.age_group >= AgeGroup(ConfirmedCasesDataEntry::age_group_names.size()); @@ -193,7 +193,7 @@ inline IOResult> deserialize_confirmed_case */ inline IOResult> read_confirmed_cases_data(const std::string& filename) { - BOOST_OUTCOME_TRY(jsvalue, read_json(filename)); + BOOST_OUTCOME_TRY(auto&& jsvalue, read_json(filename)); return deserialize_confirmed_cases_data(jsvalue); } @@ -259,7 +259,7 @@ IOResult> unpack_all(const std::vector>& v) std::vector w; w.reserve(v.size()); for (auto&& r : v) { - BOOST_OUTCOME_TRY(t, r); + BOOST_OUTCOME_TRY(auto&& t, r); w.push_back(t); } return success(w); @@ -400,7 +400,7 @@ interpolate_to_rki_age_groups(const std::vector& population inline IOResult> deserialize_population_data(const Json::Value& jsvalue, bool rki_age_groups = true) { - BOOST_OUTCOME_TRY(population_data, deserialize_json(jsvalue, Tag>{})); + BOOST_OUTCOME_TRY(auto&& population_data, deserialize_json(jsvalue, Tag>{})); if (rki_age_groups) { return success(details::interpolate_to_rki_age_groups(population_data)); } @@ -418,7 +418,7 @@ inline IOResult> deserialize_population_data(co inline IOResult> read_population_data(const std::string& filename, bool rki_age_group = true) { - BOOST_OUTCOME_TRY(jsvalue, read_json(filename)); + BOOST_OUTCOME_TRY(auto&& jsvalue, read_json(filename)); return deserialize_population_data(jsvalue, rki_age_group); } @@ -507,7 +507,7 @@ inline IOResult> deserialize_vaccination_data( */ inline IOResult> read_vaccination_data(const std::string& filename) { - BOOST_OUTCOME_TRY(jsvalue, read_json(filename)); + BOOST_OUTCOME_TRY(auto&& jsvalue, read_json(filename)); return deserialize_vaccination_data(jsvalue); } diff --git a/cpp/memilio/io/io.h b/cpp/memilio/io/io.h index fa19977a27..7e8e9dbf82 100644 --- a/cpp/memilio/io/io.h +++ b/cpp/memilio/io/io.h @@ -332,7 +332,7 @@ inline const std::error_code& make_error_code(const IOStatus& status) * extern void use_int(int i); * IOResult parse_and_use_int(const std::string& s) * { - * BOOST_OUTCOME_TRY(i, parse_int(s)); + * BOOST_OUTCOME_TRY(auto&& i, parse_int(s)); * use_int(i); * return success(); * } @@ -482,7 +482,7 @@ details::ApplyResultT apply(IOContext& io, F f, const IOResult&... r IOStatus status[] = {(rs ? IOStatus{} : rs.error())...}; auto iter_err = std::find_if(std::begin(status), std::end(status), [](auto& s) { return s.is_error(); - }); + }); //evaluate f if all succesful auto result = @@ -658,7 +658,7 @@ void serialize_internal(IOContext& io, E e) template ::value, void*> = nullptr> IOResult deserialize_internal(IOContext& io, Tag /*tag*/) { - BOOST_OUTCOME_TRY(i, mio::deserialize(io, mio::Tag>{})); + BOOST_OUTCOME_TRY(auto&& i, mio::deserialize(io, mio::Tag>{})); return success(E(i)); } diff --git a/cpp/memilio/io/json_serializer.h b/cpp/memilio/io/json_serializer.h index 81292e4464..1a1a1e4f31 100644 --- a/cpp/memilio/io/json_serializer.h +++ b/cpp/memilio/io/json_serializer.h @@ -436,7 +436,7 @@ class JsonContext : public SerializerBase Container v; for (auto&& el : array) { auto ctxt = JsonContext(el, io.m_status, io.m_flags); - BOOST_OUTCOME_TRY(val, mio::deserialize(ctxt, Tag{})); + BOOST_OUTCOME_TRY(auto&& val, mio::deserialize(ctxt, Tag{})); v.insert(v.end(), val); } return success(std::move(v)); @@ -502,7 +502,7 @@ IOResult serialize_json(const T& t, int flags = IOF_None) template IOResult write_json(const std::string& path, const T& t, int flags = IOF_None) { - BOOST_OUTCOME_TRY(js, serialize_json(t, flags)); + BOOST_OUTCOME_TRY(auto&& js, serialize_json(t, flags)); return write_json(path, js); } @@ -552,7 +552,7 @@ IOResult deserialize_json(const Json::Value& js, Tag tag, int flags = IOF_ template IOResult read_json(const std::string& path, Tag tag, int flags = IOF_None) { - BOOST_OUTCOME_TRY(js, read_json(path)); + BOOST_OUTCOME_TRY(auto&& js, read_json(path)); return deserialize_json(js, tag, flags); } diff --git a/cpp/memilio/io/mobility_io.cpp b/cpp/memilio/io/mobility_io.cpp index 5b0169fa04..da7f3caf1e 100644 --- a/cpp/memilio/io/mobility_io.cpp +++ b/cpp/memilio/io/mobility_io.cpp @@ -39,7 +39,7 @@ IOResult count_lines(const std::string& filename) IOResult read_mobility_formatted(const std::string& filename) { - BOOST_OUTCOME_TRY(num_lines, count_lines(filename)); + BOOST_OUTCOME_TRY(auto&& num_lines, count_lines(filename)); if (num_lines == 0) { return success(Eigen::MatrixXd(0, 0)); @@ -99,7 +99,7 @@ IOResult read_mobility_formatted(const std::string& filename) IOResult read_mobility_plain(const std::string& filename) { - BOOST_OUTCOME_TRY(num_lines, count_lines(filename)); + BOOST_OUTCOME_TRY(auto&& num_lines, count_lines(filename)); if (num_lines == 0) { return success(Eigen::MatrixXd(0, 0)); diff --git a/cpp/memilio/io/mobility_io.h b/cpp/memilio/io/mobility_io.h index 84bf886e0d..607ed72103 100644 --- a/cpp/memilio/io/mobility_io.h +++ b/cpp/memilio/io/mobility_io.h @@ -79,7 +79,7 @@ IOResult write_graph(const Graph& graph, const assert(graph.nodes().size() > 0 && "Graph Nodes are empty"); std::string abs_path; - BOOST_OUTCOME_TRY(created, create_directory(directory, abs_path)); + BOOST_OUTCOME_TRY(auto&& created, create_directory(directory, abs_path)); if (created) { log_info("Results are stored in {:s}/results.", mio::get_current_dir_name()); @@ -97,7 +97,7 @@ IOResult write_graph(const Graph& graph, const for (auto inode = size_t(0); inode < graph.nodes().size(); ++inode) { //node const auto node = graph.nodes()[inode]; - BOOST_OUTCOME_TRY(js_node_model, serialize_json(node.property, ioflags)); + BOOST_OUTCOME_TRY(auto&& js_node_model, serialize_json(node.property, ioflags)); Json::Value js_node(Json::objectValue); js_node["NodeId"] = node.id; js_node["Model"] = js_node_model; @@ -109,7 +109,7 @@ IOResult write_graph(const Graph& graph, const if (out_edges.size()) { Json::Value js_edges(Json::arrayValue); for (auto& e : graph.out_edges(inode)) { - BOOST_OUTCOME_TRY(js_edge_params, serialize_json(e.property, ioflags)); + BOOST_OUTCOME_TRY(auto&& js_edge_params, serialize_json(e.property, ioflags)); Json::Value js_edge{Json::objectValue}; js_edge["StartNodeIndex"] = Json::UInt64(e.start_node_idx); js_edge["EndNodeIndex"] = Json::UInt64(e.end_node_idx); @@ -150,13 +150,13 @@ IOResult> read_graph(const std::string& direct if (!file_exists(node_filename, node_filename)) { break; } - BOOST_OUTCOME_TRY(js_node, read_json(node_filename)); + BOOST_OUTCOME_TRY(auto&& js_node, read_json(node_filename)); if (!js_node["NodeId"].isInt()) { log_error("NodeId field must be an integer."); return failure(StatusCode::InvalidType, node_filename + ", NodeId must be an integer."); } auto node_id = js_node["NodeId"].asInt(); - BOOST_OUTCOME_TRY(model, deserialize_json(js_node["Model"], Tag{}, ioflags)); + BOOST_OUTCOME_TRY(auto&& model, deserialize_json(js_node["Model"], Tag{}, ioflags)); graph.add_node(node_id, model); } @@ -165,7 +165,7 @@ IOResult> read_graph(const std::string& direct for (auto inode = size_t(0); inode < graph.nodes().size(); ++inode) { //list of edges auto edge_filename = path_join(abs_path, "GraphEdges_node" + std::to_string(inode) + ".json"); - BOOST_OUTCOME_TRY(js_edges, read_json(edge_filename)); + BOOST_OUTCOME_TRY(auto&& js_edges, read_json(edge_filename)); for (auto& e : js_edges) { auto start_node_idx = inode; @@ -180,7 +180,8 @@ IOResult> read_graph(const std::string& direct return failure(StatusCode::OutOfRange, edge_filename + ", EndNodeIndex not in range of number of graph nodes."); } - BOOST_OUTCOME_TRY(parameters, deserialize_json(e["Parameters"], Tag{}, ioflags)); + BOOST_OUTCOME_TRY(auto&& parameters, + deserialize_json(e["Parameters"], Tag{}, ioflags)); graph.add_edge(start_node_idx, end_node_idx, parameters); } } diff --git a/cpp/memilio/math/README.md b/cpp/memilio/math/README.md index 105b7deacb..d7fe85aa8e 100644 --- a/cpp/memilio/math/README.md +++ b/cpp/memilio/math/README.md @@ -7,7 +7,7 @@ This module contains different mathematical methods for integration of sets of o The model consists of the following classes: 1. Integrator: The integrator module contains an IntegratorCore and an OdeIntegrator class, currently designed for explicit methods only. The IntegratorCore contains a step function that takes as input the right hand side function of the ODE, the current time, the step size etc. It represents a generic integration method from which the other integrators are derived from. The OdeIntegrator stores an IntegratorCore as well as the right hand side function and a time series of results. 2. The following integrators implement IntegratorCore and can be used with OdeIntegratorCore or [mio::Simulation](../compartments/README.md). - - ControlledStepperWrapper: The ControlledStepperWrapper class allows using integrators from boosts::numeric::odeint in memilio. The integrator is passed as template argument. It must be of the concept "Error Stepper" (for more details, see [boost's own documentation](https://www.boost.org/doc/libs/1_75_0/libs/numeric/odeint/doc/html/boost_numeric_odeint/odeint_in_detail/steppers.html#boost_numeric_odeint.odeint_in_detail.steppers.stepper_overview) ). Currently, the default for mio::Simulation is runge_kutta_cash_karp54. Alternatively, runge_kutta_dopri5 or runge_kutta_fehlberg78 can be used. + - ControlledStepperWrapper: The ControlledStepperWrapper class allows using integrators from boosts::numeric::odeint in memilio. The integrator is passed as template argument. It must be of the concept "Error Stepper" (for more details, see [boost's own documentation](https://www.boost.org/doc/libs/1_84_0/libs/numeric/odeint/doc/html/boost_numeric_odeint/odeint_in_detail/steppers.html#boost_numeric_odeint.odeint_in_detail.steppers.stepper_overview) ). Currently, the default for mio::Simulation is runge_kutta_cash_karp54. Alternatively, runge_kutta_fehlberg78 can be used. - Euler: The Euler class contains and explicit Euler method, adapted to the Integrator function. It also contains a (semi-)implicit Euler method which is WIP and taylored for the particular SECIR model from ../ode_secir/model.h - Adapt_RK: The Adapt_RK module contains the RKIntegratorCore class, which implements adaptive Runge-Kutta integrators, where different pairs of methods (in form of combined Butcher tableaus) can be added. Absolute and relative tolerances can be set and the Tableau in use is that of an adaptive Runge-Kutta-Fehlberg (45) method; see, e.g., https://www.johndcook.com/blog/2020/02/19/fehlberg/. Steps where the mixed criterion on absolute and relative values (m_abs_tol + max_val * m_rel_tol) are not satisfied are directly discarded and never used. If the minimal step size (set) is reached and the criterion cannot be satisfied, it is returned that the adaptive step sizing failed. 3. Smoother: The smoother classes smoothes discrete jumps of function values y0 and y1 on the interval [x0,x1] by a continuously differentiable function diff --git a/cpp/memilio/mobility/graph.h b/cpp/memilio/mobility/graph.h index 7e7c093595..d2648196a2 100644 --- a/cpp/memilio/mobility/graph.h +++ b/cpp/memilio/mobility/graph.h @@ -269,7 +269,7 @@ IOResult set_nodes(const Parameters& params, Date start_date, Date end_dat double scaling_factor_icu, double tnt_capacity_factor, int num_days = 0, bool export_time_series = false, bool rki_age_groups = true) { - BOOST_OUTCOME_TRY(node_ids, node_func(population_data_path, is_node_for_county, rki_age_groups)); + BOOST_OUTCOME_TRY(auto&& node_ids, node_func(population_data_path, is_node_for_county, rki_age_groups)); std::vector nodes(node_ids.size(), Model(int(size_t(params.get_num_groups())))); for (auto& node : nodes) { node.parameters = params; @@ -339,9 +339,10 @@ IOResult set_edges(const fs::path& data_dir, Graph std::vector commuting_weights = std::vector{}) { // mobility between nodes - BOOST_OUTCOME_TRY(mobility_data_commuter, + BOOST_OUTCOME_TRY(auto&& mobility_data_commuter, read_func((data_dir / "mobility" / "commuter_migration_scaled.txt").string())); - BOOST_OUTCOME_TRY(mobility_data_twitter, read_func((data_dir / "mobility" / "twitter_scaled_1252.txt").string())); + BOOST_OUTCOME_TRY(auto&& mobility_data_twitter, + read_func((data_dir / "mobility" / "twitter_scaled_1252.txt").string())); if (mobility_data_commuter.rows() != Eigen::Index(params_graph.nodes().size()) || mobility_data_commuter.cols() != Eigen::Index(params_graph.nodes().size()) || mobility_data_twitter.rows() != Eigen::Index(params_graph.nodes().size()) || diff --git a/cpp/memilio/utils/index.h b/cpp/memilio/utils/index.h index 72e466a52b..d06903a30b 100644 --- a/cpp/memilio/utils/index.h +++ b/cpp/memilio/utils/index.h @@ -104,7 +104,7 @@ class MEMILIO_ENABLE_EBO Index : public TypeSafe static IOResult deserialize(IOContext& io) { - BOOST_OUTCOME_TRY(i, mio::deserialize(io, Tag{})); + BOOST_OUTCOME_TRY(auto&& i, mio::deserialize(io, Tag{})); return success(Index(i)); } }; diff --git a/cpp/memilio/utils/parameter_distributions.h b/cpp/memilio/utils/parameter_distributions.h index c5a2c30950..36d5cbea1f 100644 --- a/cpp/memilio/utils/parameter_distributions.h +++ b/cpp/memilio/utils/parameter_distributions.h @@ -316,7 +316,7 @@ class ParameterDistributionNormal : public VisitableParameterDistribution + template void serialize_elements(IOObject& obj) const { obj.add_element("Mean", m_mean); @@ -326,14 +326,14 @@ class ParameterDistributionNormal : public VisitableParameterDistribution + template void serialize(IOContext& io) const { auto obj = io.create_object("ParameterDistributionNormal"); serialize_elements(obj); } - template + template static IOResult deserialize_elements(IOContext& io, IOObject& obj) { auto m = obj.expect_element("Mean", Tag{}); @@ -342,15 +342,15 @@ class ParameterDistributionNormal : public VisitableParameterDistribution{}); auto predef = obj.expect_list("PredefinedSamples", Tag{}); auto p = apply( - io, - [](auto&& lb_, auto&& ub_, auto&& m_, auto&& s_, auto&& predef_) { + io, + [](auto&& lb_, auto&& ub_, auto&& m_, auto&& s_, auto&& predef_) { auto distr = ParameterDistributionNormal(lb_, ub_, m_, s_); for (auto&& e : predef_) { distr.add_predefined_sample(e); } return distr; - }, - lb, ub, m, s, predef); + }, + lb, ub, m, s, predef); if (p) { return success(p.value()); } @@ -359,7 +359,7 @@ class ParameterDistributionNormal : public VisitableParameterDistribution + template static IOResult deserialize(IOContext& io) { auto obj = io.expect_object("ParameterDistributionNormal"); @@ -419,7 +419,7 @@ class ParameterDistributionUniform : public VisitableParameterDistribution + template void serialize_elements(IOObject& obj) const { obj.add_element("LowerBound", m_lower_bound); @@ -427,29 +427,29 @@ class ParameterDistributionUniform : public VisitableParameterDistribution + template void serialize(IOContext& io) const { auto obj = io.create_object("ParameterDistributionUniform"); serialize_elements(obj); } - template + template static IOResult deserialize_elements(IOContext& io, IOObject& obj) { auto lb = obj.expect_element("LowerBound", Tag{}); auto ub = obj.expect_element("UpperBound", Tag{}); auto predef = obj.expect_list("PredefinedSamples", Tag{}); auto p = apply( - io, - [](auto&& lb_, auto&& ub_, auto&& predef_) { + io, + [](auto&& lb_, auto&& ub_, auto&& predef_) { auto distr = ParameterDistributionUniform(lb_, ub_); for (auto&& e : predef_) { distr.add_predefined_sample(e); } return distr; - }, - lb, ub, predef); + }, + lb, ub, predef); if (p) { return success(p.value()); } @@ -458,7 +458,7 @@ class ParameterDistributionUniform : public VisitableParameterDistribution + template static IOResult deserialize(IOContext& io) { auto obj = io.expect_object("ParameterDistributionUniform"); @@ -473,7 +473,7 @@ template void details::SerializationVisitor::visit(const ParameterDistributionUniform& uniform_dist) { obj.add_element("Type", std::string("Uniform")); - uniform_dist.serialize_elements(obj); + uniform_dist.serialize_elements(obj); } /** @@ -488,11 +488,11 @@ IOResult> deserialize_internal(IOContext& auto type = obj.expect_element("Type", Tag{}); if (type) { if (type.value() == "Uniform") { - BOOST_OUTCOME_TRY(r, ParameterDistributionUniform::deserialize_elements(io, obj)); + BOOST_OUTCOME_TRY(auto&& r, ParameterDistributionUniform::deserialize_elements(io, obj)); return std::make_shared(r); } else if (type.value() == "Normal") { - BOOST_OUTCOME_TRY(r, ParameterDistributionNormal::deserialize_elements(io, obj)); + BOOST_OUTCOME_TRY(auto&& r, ParameterDistributionNormal::deserialize_elements(io, obj)); return std::make_shared(r); } else { diff --git a/cpp/memilio/utils/type_safe.h b/cpp/memilio/utils/type_safe.h index a4d174b662..b3bb84a256 100644 --- a/cpp/memilio/utils/type_safe.h +++ b/cpp/memilio/utils/type_safe.h @@ -107,7 +107,7 @@ class TypeSafe template static IOResult deserialize(IOContext& io) { - BOOST_OUTCOME_TRY(t, mio::deserialize(io, Tag{})); + BOOST_OUTCOME_TRY(auto&& t, mio::deserialize(io, Tag{})); return success(Derived(t)); } diff --git a/cpp/models/ide_secir/parameters.h b/cpp/models/ide_secir/parameters.h index ca4b43e186..da830515ba 100644 --- a/cpp/models/ide_secir/parameters.h +++ b/cpp/models/ide_secir/parameters.h @@ -332,7 +332,7 @@ class Parameters : public ParametersBase template static IOResult deserialize(IOContext& io) { - BOOST_OUTCOME_TRY(base, ParametersBase::deserialize(io)); + BOOST_OUTCOME_TRY(auto&& base, ParametersBase::deserialize(io)); return success(Parameters(std::move(base))); } diff --git a/cpp/models/lct_secir/parameters.h b/cpp/models/lct_secir/parameters.h index 24661fc251..1687648bd0 100644 --- a/cpp/models/lct_secir/parameters.h +++ b/cpp/models/lct_secir/parameters.h @@ -381,7 +381,7 @@ class Parameters : public ParametersBase template static IOResult deserialize(IOContext& io) { - BOOST_OUTCOME_TRY(base, ParametersBase::deserialize(io)); + BOOST_OUTCOME_TRY(auto&& base, ParametersBase::deserialize(io)); return success(Parameters(std::move(base))); } }; diff --git a/cpp/models/lct_secir/parameters_io.h b/cpp/models/lct_secir/parameters_io.h index 776023dcbe..5499c4f1e1 100644 --- a/cpp/models/lct_secir/parameters_io.h +++ b/cpp/models/lct_secir/parameters_io.h @@ -68,7 +68,7 @@ IOResult set_initial_data_from_confirmed_cases(Model& model, const std::st using LctState = typename Model::LctState; // Try to get rki data from path. - BOOST_OUTCOME_TRY(rki_data, mio::read_confirmed_cases_noage(path)); + BOOST_OUTCOME_TRY(auto&& rki_data, mio::read_confirmed_cases_noage(path)); auto max_date_entry = std::max_element(rki_data.begin(), rki_data.end(), [](auto&& a, auto&& b) { return a.date < b.date; }); diff --git a/cpp/models/ode_secir/parameters.h b/cpp/models/ode_secir/parameters.h index ad20369c92..c36a0df71b 100644 --- a/cpp/models/ode_secir/parameters.h +++ b/cpp/models/ode_secir/parameters.h @@ -651,7 +651,7 @@ class Parameters : public ParametersBase template static IOResult deserialize(IOContext& io) { - BOOST_OUTCOME_TRY(base, ParametersBase::deserialize(io)); + BOOST_OUTCOME_TRY(auto&& base, ParametersBase::deserialize(io)); return success(Parameters(std::move(base))); } diff --git a/cpp/models/ode_secir/parameters_io.cpp b/cpp/models/ode_secir/parameters_io.cpp index 735bbeefd9..4b051b49c3 100644 --- a/cpp/models/ode_secir/parameters_io.cpp +++ b/cpp/models/ode_secir/parameters_io.cpp @@ -237,7 +237,7 @@ IOResult set_confirmed_cases_data(std::vector& model, const std::st std::vector> mu_H_U{model.size()}; std::vector> mu_U_D{model.size()}; - BOOST_OUTCOME_TRY(case_data, mio::read_confirmed_cases_data(path)); + BOOST_OUTCOME_TRY(auto&& case_data, mio::read_confirmed_cases_data(path)); for (size_t node = 0; node < model.size(); ++node) { for (size_t group = 0; group < num_age_groups; group++) { @@ -300,7 +300,7 @@ IOResult set_confirmed_cases_data(std::vector& model, const std::st IOResult read_divi_data(const std::string& path, const std::vector& vregion, Date date, std::vector& vnum_icu) { - BOOST_OUTCOME_TRY(divi_data, mio::read_divi_data(path)); + BOOST_OUTCOME_TRY(auto&& divi_data, mio::read_divi_data(path)); auto max_date_entry = std::max_element(divi_data.begin(), divi_data.end(), [](auto&& a, auto&& b) { return a.date < b.date; @@ -318,7 +318,7 @@ IOResult read_divi_data(const std::string& path, const std::vector& v for (auto&& entry : divi_data) { auto it = std::find_if(vregion.begin(), vregion.end(), [&entry](auto r) { return r == 0 || r == get_region_id(entry); - }); + }); auto date_df = entry.date; if (it != vregion.end() && date_df == date) { auto region_idx = size_t(it - vregion.begin()); @@ -332,7 +332,7 @@ IOResult read_divi_data(const std::string& path, const std::vector& v IOResult>> read_population_data(const std::string& path, const std::vector& vregion, bool accumulate_age_groups) { - BOOST_OUTCOME_TRY(population_data, mio::read_population_data(path, !accumulate_age_groups)); + BOOST_OUTCOME_TRY(auto&& population_data, mio::read_population_data(path, !accumulate_age_groups)); //if we set up the model for one age group, the population data should be read in with the //age groups given in the population data json file and are accumulated later //otherwise the populations are directly saved for the correct model age groups @@ -370,7 +370,7 @@ read_population_data(const std::string& path, const std::vector& vregion, b IOResult set_population_data(std::vector& model, const std::string& path, const std::vector& vregion, bool accumulate_age_groups) { - BOOST_OUTCOME_TRY(num_population, read_population_data(path, vregion, accumulate_age_groups)); + BOOST_OUTCOME_TRY(auto&& num_population, read_population_data(path, vregion, accumulate_age_groups)); for (size_t region = 0; region < vregion.size(); region++) { if (std::accumulate(num_population[region].begin(), num_population[region].end(), 0.0) > 0) { diff --git a/cpp/models/ode_secir/parameters_io.h b/cpp/models/ode_secir/parameters_io.h index 7b06b2a556..35279228b2 100644 --- a/cpp/models/ode_secir/parameters_io.h +++ b/cpp/models/ode_secir/parameters_io.h @@ -171,7 +171,7 @@ export_input_data_county_timeseries(std::vector& model, const std::string const size_t num_age_groups = ConfirmedCasesDataEntry::age_group_names.size(); - BOOST_OUTCOME_TRY(case_data, mio::read_confirmed_cases_data(confirmed_cases_path)); + BOOST_OUTCOME_TRY(auto&& case_data, mio::read_confirmed_cases_data(confirmed_cases_path)); for (size_t node = 0; node < model.size(); node++) { for (size_t group = 0; group < ConfirmedCasesDataEntry::age_group_names.size(); group++) { @@ -230,7 +230,7 @@ export_input_data_county_timeseries(std::vector& model, const std::string t_InfectedSevere, t_InfectedCritical, mu_C_R, mu_I_H, mu_H_U, scaling_factor_inf)); BOOST_OUTCOME_TRY(details::read_divi_data(divi_data_path, region, date, num_icu)); bool interpolate_rki_age_groups = num_age_groups == 1 ? true : false; - BOOST_OUTCOME_TRY(num_population, + BOOST_OUTCOME_TRY(auto&& num_population, details::read_population_data(population_data_path, region, interpolate_rki_age_groups)); for (size_t i = 0; i < region.size(); i++) { diff --git a/cpp/models/ode_secirvvs/parameters.h b/cpp/models/ode_secirvvs/parameters.h index 3058627ba8..4c8cdd9406 100644 --- a/cpp/models/ode_secirvvs/parameters.h +++ b/cpp/models/ode_secirvvs/parameters.h @@ -1007,7 +1007,7 @@ class Parameters : public ParametersBase template static IOResult deserialize(IOContext& io) { - BOOST_OUTCOME_TRY(base, ParametersBase::deserialize(io)); + BOOST_OUTCOME_TRY(auto&& base, ParametersBase::deserialize(io)); return success(Parameters(std::move(base))); } diff --git a/cpp/models/ode_secirvvs/parameters_io.cpp b/cpp/models/ode_secirvvs/parameters_io.cpp index dc5a687a10..33abde736d 100644 --- a/cpp/models/ode_secirvvs/parameters_io.cpp +++ b/cpp/models/ode_secirvvs/parameters_io.cpp @@ -72,7 +72,7 @@ IOResult read_confirmed_cases_data( const std::vector>& vmu_I_H, const std::vector>& vmu_H_U, const std::vector& scaling_factor_inf) { - BOOST_OUTCOME_TRY(rki_data, mio::read_confirmed_cases_data(path)); + BOOST_OUTCOME_TRY(auto&& rki_data, mio::read_confirmed_cases_data(path)); return read_confirmed_cases_data(rki_data, vregion, date, vnum_Exposed, vnum_InfectedNoSymptoms, vnum_InfectedSymptoms, vnum_InfectedSevere, vnum_icu, vnum_death, vnum_rec, vt_Exposed, vt_InfectedNoSymptoms, vt_InfectedSymptoms, vt_InfectedSevere, @@ -230,7 +230,7 @@ IOResult read_confirmed_cases_data_fix_recovered(std::string const& path, Date date, std::vector>& vnum_rec, double delay) { - BOOST_OUTCOME_TRY(rki_data, mio::read_confirmed_cases_data(path)); + BOOST_OUTCOME_TRY(auto&& rki_data, mio::read_confirmed_cases_data(path)); return read_confirmed_cases_data_fix_recovered(rki_data, vregion, date, vnum_rec, delay); } @@ -304,7 +304,7 @@ IOResult read_confirmed_cases_data_fix_recovered(const std::vector read_divi_data(const std::string& path, const std::vector& vregion, Date date, std::vector& vnum_icu) { - BOOST_OUTCOME_TRY(divi_data, mio::read_divi_data(path)); + BOOST_OUTCOME_TRY(auto&& divi_data, mio::read_divi_data(path)); return read_divi_data(divi_data, vregion, date, vnum_icu); } @@ -327,7 +327,7 @@ IOResult read_divi_data(const std::vector& divi_data, const std for (auto&& entry : divi_data) { auto it = std::find_if(vregion.begin(), vregion.end(), [&entry](auto r) { return r == 0 || r == get_region_id(entry); - }); + }); auto date_df = entry.date; if (it != vregion.end() && date_df == date) { auto region_idx = size_t(it - vregion.begin()); @@ -341,7 +341,7 @@ IOResult read_divi_data(const std::vector& divi_data, const std IOResult>> read_population_data(const std::string& path, const std::vector& vregion) { - BOOST_OUTCOME_TRY(population_data, mio::read_population_data(path)); + BOOST_OUTCOME_TRY(auto&& population_data, mio::read_population_data(path)); return read_population_data(population_data, vregion); } @@ -380,7 +380,7 @@ IOResult>> read_population_data(const std::vecto IOResult set_vaccination_data(std::vector& model, const std::string& path, Date date, const std::vector& vregion, int num_days) { - BOOST_OUTCOME_TRY(vacc_data, read_vaccination_data(path)); + BOOST_OUTCOME_TRY(auto&& vacc_data, read_vaccination_data(path)); auto num_groups = model[0].parameters.get_num_groups(); @@ -416,7 +416,7 @@ IOResult set_vaccination_data(std::vector& model, const std::string return r == 0 || (vacc_data_entry.county_id && vacc_data_entry.county_id == regions::CountyId(r)) || (vacc_data_entry.state_id && vacc_data_entry.state_id == regions::StateId(r)) || (vacc_data_entry.district_id && vacc_data_entry.district_id == regions::DistrictId(r)); - }); + }); auto date_df = vacc_data_entry.date; if (it != vregion.end()) { auto region_idx = size_t(it - vregion.begin()); diff --git a/cpp/models/ode_secirvvs/parameters_io.h b/cpp/models/ode_secirvvs/parameters_io.h index e975d3944d..f45c010b7f 100644 --- a/cpp/models/ode_secirvvs/parameters_io.h +++ b/cpp/models/ode_secirvvs/parameters_io.h @@ -114,7 +114,7 @@ IOResult set_confirmed_cases_data(std::vector& model, const std::st assert(scaling_factor_inf.size() == num_age_groups); //TODO: allow vector or scalar valued scaling factors assert(ConfirmedCasesDataEntry::age_group_names.size() == num_age_groups); - BOOST_OUTCOME_TRY(rki_data, mio::read_confirmed_cases_data(path)); + BOOST_OUTCOME_TRY(auto&& rki_data, mio::read_confirmed_cases_data(path)); std::vector> t_Exposed{model.size()}; std::vector> t_InfectedNoSymptoms{model.size()}; @@ -430,7 +430,7 @@ template IOResult set_population_data(std::vector& model, const std::string& path, const std::string& path_rki, const std::vector& vregion, Date date) { - BOOST_OUTCOME_TRY(num_population, read_population_data(path, vregion)); + BOOST_OUTCOME_TRY(auto&& num_population, read_population_data(path, vregion)); auto num_age_groups = ConfirmedCasesDataEntry::age_group_names.size(); std::vector> num_rec(model.size(), std::vector(num_age_groups, 0.0)); @@ -634,9 +634,9 @@ IOResult export_input_data_county_timeseries( assert(num_age_groups == ConfirmedCasesDataEntry::age_group_names.size()); assert(model.size() == region.size()); - BOOST_OUTCOME_TRY(rki_data, read_confirmed_cases_data(confirmed_cases_path)); - BOOST_OUTCOME_TRY(population_data, read_population_data(population_data_path)); - BOOST_OUTCOME_TRY(divi_data, read_divi_data(divi_data_path)); + BOOST_OUTCOME_TRY(auto&& rki_data, read_confirmed_cases_data(confirmed_cases_path)); + BOOST_OUTCOME_TRY(auto&& population_data, read_population_data(population_data_path)); + BOOST_OUTCOME_TRY(auto&& divi_data, read_divi_data(divi_data_path)); /* functionality copy from set_confirmed_cases_data() here splitted in params */ /* which do not need to be reset for each day and compartments sizes that are */ @@ -913,7 +913,7 @@ IOResult export_input_data_county_timeseries( } // read population basics - BOOST_OUTCOME_TRY(num_population, details::read_population_data(population_data, region)); + BOOST_OUTCOME_TRY(auto&& num_population, details::read_population_data(population_data, region)); std::vector> num_rec(model.size(), std::vector(num_age_groups, 0.0)); BOOST_OUTCOME_TRY(details::read_confirmed_cases_data_fix_recovered(rki_data, region, date, num_rec, 14.)); @@ -924,10 +924,10 @@ IOResult export_input_data_county_timeseries( auto age_group_offset = age * (size_t)InfectionState::Count; double S_v = std::min( - model[county] - .parameters.template get()[{AgeGroup(age), SimulationDay(day)}] + - num_rec[county][age], - num_population[county][age]); + model[county] + .parameters.template get()[{AgeGroup(age), SimulationDay(day)}] + + num_rec[county][age], + num_population[county][age]); double S_pv = std::max( model[county] .parameters.template get()[{AgeGroup(age), SimulationDay(day)}] - diff --git a/cpp/models/ode_seir/parameters.h b/cpp/models/ode_seir/parameters.h index 6cf4f71458..1fa6d025f5 100644 --- a/cpp/models/ode_seir/parameters.h +++ b/cpp/models/ode_seir/parameters.h @@ -199,7 +199,7 @@ class Parameters : public ParametersBase template static IOResult deserialize(IOContext& io) { - BOOST_OUTCOME_TRY(base, ParametersBase::deserialize(io)); + BOOST_OUTCOME_TRY(auto&& base, ParametersBase::deserialize(io)); return success(Parameters(std::move(base))); } }; diff --git a/cpp/models/ode_sir/parameters.h b/cpp/models/ode_sir/parameters.h index 54f489cebb..229d1efd7e 100644 --- a/cpp/models/ode_sir/parameters.h +++ b/cpp/models/ode_sir/parameters.h @@ -170,7 +170,7 @@ class Parameters : public ParametersBase template static IOResult deserialize(IOContext& io) { - BOOST_OUTCOME_TRY(base, ParametersBase::deserialize(io)); + BOOST_OUTCOME_TRY(auto&& base, ParametersBase::deserialize(io)); return success(Parameters(std::move(base))); } }; diff --git a/cpp/models/sde_sir/parameters.h b/cpp/models/sde_sir/parameters.h index 13d8296cd7..a7641b44f5 100644 --- a/cpp/models/sde_sir/parameters.h +++ b/cpp/models/sde_sir/parameters.h @@ -168,7 +168,7 @@ class Parameters : public ParametersBase template static IOResult deserialize(IOContext& io) { - BOOST_OUTCOME_TRY(base, ParametersBase::deserialize(io)); + BOOST_OUTCOME_TRY(auto&& base, ParametersBase::deserialize(io)); return success(Parameters(std::move(base))); } }; diff --git a/cpp/models/sde_sirs/parameters.h b/cpp/models/sde_sirs/parameters.h index daee8103bb..23a55cc1eb 100644 --- a/cpp/models/sde_sirs/parameters.h +++ b/cpp/models/sde_sirs/parameters.h @@ -198,7 +198,7 @@ class Parameters : public ParametersBase template static IOResult deserialize(IOContext& io) { - BOOST_OUTCOME_TRY(base, ParametersBase::deserialize(io)); + BOOST_OUTCOME_TRY(auto&& base, ParametersBase::deserialize(io)); return success(Parameters(std::move(base))); } }; diff --git a/cpp/simulations/2020_npis_sarscov2_wildtype_germany.cpp b/cpp/simulations/2020_npis_sarscov2_wildtype_germany.cpp index e3a2a3bef7..e8eb02817b 100644 --- a/cpp/simulations/2020_npis_sarscov2_wildtype_germany.cpp +++ b/cpp/simulations/2020_npis_sarscov2_wildtype_germany.cpp @@ -214,10 +214,10 @@ mio::IOResult set_contact_matrices(const fs::path& data_dir, mio::osecir:: //TODO: io error handling auto contact_matrices = mio::ContactMatrixGroup(contact_locations.size(), size_t(params.get_num_groups())); for (auto&& contact_location : contact_locations) { - BOOST_OUTCOME_TRY(baseline, + BOOST_OUTCOME_TRY(auto&& baseline, mio::read_mobility_plain( (data_dir / "contacts" / ("baseline_" + contact_location.second + ".txt")).string())); - BOOST_OUTCOME_TRY(minimum, + BOOST_OUTCOME_TRY(auto&& minimum, mio::read_mobility_plain( (data_dir / "contacts" / ("minimum_" + contact_location.second + ".txt")).string())); contact_matrices[size_t(contact_location.first)].get_baseline() = baseline; @@ -535,12 +535,12 @@ mio::IOResult run(RunMode mode, const fs::path& data_dir, const fs::path& //create or load graph mio::Graph params_graph; if (mode == RunMode::Save) { - BOOST_OUTCOME_TRY(created, get_graph(start_date, end_date, data_dir)); + BOOST_OUTCOME_TRY(auto&& created, get_graph(start_date, end_date, data_dir)); BOOST_OUTCOME_TRY(write_graph(created, save_dir.string())); params_graph = created; } else { - BOOST_OUTCOME_TRY(loaded, mio::read_graph(save_dir.string())); + BOOST_OUTCOME_TRY(auto&& loaded, mio::read_graph(save_dir.string())); params_graph = loaded; } @@ -565,25 +565,25 @@ mio::IOResult run(RunMode mode, const fs::path& data_dir, const fs::path& auto save_single_run_result = mio::IOResult(mio::success()); auto ensemble = parameter_study.run( - [](auto&& graph) { + [](auto&& graph) { return draw_sample(graph); - }, - [&](auto results_graph, auto&& run_idx) { + }, + [&](auto results_graph, auto&& run_idx) { auto interpolated_result = mio::interpolate_simulation_result(results_graph); auto params = std::vector{}; params.reserve(results_graph.nodes().size()); std::transform(results_graph.nodes().begin(), results_graph.nodes().end(), std::back_inserter(params), - [](auto&& node) { + [](auto&& node) { return node.property.get_simulation().get_model(); - }); + }); if (save_single_run_result && save_single_runs) { save_single_run_result = save_result_with_params(interpolated_result, params, county_ids, result_dir, run_idx); } return std::make_pair(std::move(interpolated_result), std::move(params)); - }); + }); if (ensemble.size() > 0) { auto ensemble_results = std::vector>>{}; diff --git a/cpp/simulations/2021_vaccination_sarscov2_delta_germany.cpp b/cpp/simulations/2021_vaccination_sarscov2_delta_germany.cpp index 772d14214e..56d8ac2361 100644 --- a/cpp/simulations/2021_vaccination_sarscov2_delta_germany.cpp +++ b/cpp/simulations/2021_vaccination_sarscov2_delta_germany.cpp @@ -261,7 +261,7 @@ mio::IOResult set_contact_matrices(const fs::path& data_dir, mio::osecirvv //TODO: io error handling auto contact_matrices = mio::ContactMatrixGroup(contact_locations.size(), size_t(params.get_num_groups())); for (auto&& contact_location : contact_locations) { - BOOST_OUTCOME_TRY(baseline, + BOOST_OUTCOME_TRY(auto&& baseline, mio::read_mobility_plain( (data_dir / "contacts" / ("baseline_" + contact_location.second + ".txt")).string())); @@ -623,12 +623,12 @@ mio::IOResult run(RunMode mode, const fs::path& data_dir, const fs::path& //create or load graph mio::Graph params_graph; if (mode == RunMode::Save) { - BOOST_OUTCOME_TRY(created, get_graph(start_date, end_date, data_dir, late, masks, test, long_time)); + BOOST_OUTCOME_TRY(auto&& created, get_graph(start_date, end_date, data_dir, late, masks, test, long_time)); BOOST_OUTCOME_TRY(write_graph(created, save_dir.string())); params_graph = created; } else { - BOOST_OUTCOME_TRY(loaded, mio::read_graph(save_dir.string())); + BOOST_OUTCOME_TRY(auto&& loaded, mio::read_graph(save_dir.string())); params_graph = loaded; } @@ -653,17 +653,17 @@ mio::IOResult run(RunMode mode, const fs::path& data_dir, const fs::path& auto save_single_run_result = mio::IOResult(mio::success()); auto ensemble = parameter_study.run( - [&](auto&& graph) { + [&](auto&& graph) { return draw_sample(graph, high); - }, - [&](auto results_graph, auto&& run_idx) { + }, + [&](auto results_graph, auto&& run_idx) { auto interpolated_result = mio::interpolate_simulation_result(results_graph); auto params = std::vector(); params.reserve(results_graph.nodes().size()); std::transform(results_graph.nodes().begin(), results_graph.nodes().end(), std::back_inserter(params), - [](auto&& node) { + [](auto&& node) { return node.property.get_simulation().get_model(); - }); + }); if (save_single_run_result && save_single_runs) { save_single_run_result = @@ -671,7 +671,7 @@ mio::IOResult run(RunMode mode, const fs::path& data_dir, const fs::path& } std::cout << "run " << run_idx << " complete." << std::endl; return std::make_pair(interpolated_result, params); - }); + }); if (ensemble.size() > 0) { auto ensemble_results = std::vector>>{}; diff --git a/cpp/simulations/munich_graph_sim.cpp b/cpp/simulations/munich_graph_sim.cpp index 2e6d18447a..b9ff576600 100644 --- a/cpp/simulations/munich_graph_sim.cpp +++ b/cpp/simulations/munich_graph_sim.cpp @@ -85,8 +85,8 @@ mio::IOResult set_nodes(mio::Graph nodes(node_ids.size(), mio::osecir::Model(int(size_t(params.get_num_groups())))); //set parameters for every node for (auto& node : nodes) { @@ -109,7 +109,7 @@ mio::IOResult set_edges(mio::Graph run(RunMode mode, const fs::path& data_dir, const fs::path& mio::Graph params_graph; if (mode == RunMode::Save) { - BOOST_OUTCOME_TRY(created_graph, get_graph(start_date, data_dir)); + BOOST_OUTCOME_TRY(auto&& created_graph, get_graph(start_date, data_dir)); BOOST_OUTCOME_TRY(mio::write_graph(created_graph, save_dir.string())); params_graph = created_graph; } else { - BOOST_OUTCOME_TRY(loaded_graph, mio::read_graph(save_dir.string())); + BOOST_OUTCOME_TRY(auto&& loaded_graph, mio::read_graph(save_dir.string())); params_graph = loaded_graph; } diff --git a/cpp/thirdparty/CMakeLists.txt b/cpp/thirdparty/CMakeLists.txt index 6319e52a16..f009dd66d7 100644 --- a/cpp/thirdparty/CMakeLists.txt +++ b/cpp/thirdparty/CMakeLists.txt @@ -2,6 +2,8 @@ # If you like to upgrade, just change the number set(MEMILIO_EIGEN_VERSION "3.3.9") set(MEMILIO_SPDLOG_VERSION "1.11.0") +set(MEMILIO_BOOST_VERSION "1.84.0") +set(MEMILIO_MINIMAL_BOOST_VERSION "1.76.0") set(MEMILIO_JSONCPP_VERSION "1.9.5") set(MEMILIO_RANDOM123_VERSION "v1.14.0") @@ -51,10 +53,81 @@ endif() # ## BOOST if(MEMILIO_USE_BUNDLED_BOOST) - include(BuildBoost) + message(STATUS "Downloading Boost library. This may take some time.") + + include(FetchContent) + FetchContent_Declare(boost + GIT_REPOSITORY https://github.com/boostorg/boost.git + GIT_TAG boost-${MEMILIO_BOOST_VERSION}) + FetchContent_GetProperties(boost) + + if(NOT boost_POPULATED) + FetchContent_Populate(boost) + endif() + + add_custom_target(boost-bootstrap ALL + DEPENDS "${boost_SOURCE_DIR}/boost" + ) + + if(MSVC) + add_custom_command( + OUTPUT "${boost_SOURCE_DIR}/boost" + COMMAND "bootstrap.bat" + COMMAND "b2.exe" headers + WORKING_DIRECTORY ${boost_SOURCE_DIR} + VERBATIM + ) + else() + add_custom_command( + OUTPUT "${boost_SOURCE_DIR}/boost" + COMMAND ./bootstrap.sh + COMMAND ./b2 headers + WORKING_DIRECTORY ${boost_SOURCE_DIR} + VERBATIM + ) + endif() + + add_library(boost INTERFACE) + add_dependencies(boost boost-bootstrap) + add_library(Boost::boost ALIAS boost) + target_include_directories(boost SYSTEM INTERFACE $) + + if (NOT MSVC) + target_compile_options(boost INTERFACE "-Wno-c++20-attribute-extensions") + endif() + + add_library(boost_disable_autolink INTERFACE) + target_compile_definitions(boost_disable_autolink INTERFACE BOOST_ALL_NO_LIB) + add_library(Boost::disable_autolinking ALIAS boost_disable_autolink) + + add_library(boost_filesystem STATIC + ${boost_SOURCE_DIR}/libs/filesystem/src/codecvt_error_category.cpp + ${boost_SOURCE_DIR}/libs/filesystem/src/directory.cpp + ${boost_SOURCE_DIR}/libs/filesystem/src/exception.cpp + ${boost_SOURCE_DIR}/libs/filesystem/src/operations.cpp + ${boost_SOURCE_DIR}/libs/filesystem/src/path.cpp + ${boost_SOURCE_DIR}/libs/filesystem/src/path_traits.cpp + ${boost_SOURCE_DIR}/libs/filesystem/src/portability.cpp + ${boost_SOURCE_DIR}/libs/filesystem/src/unique_path.cpp + ${boost_SOURCE_DIR}/libs/filesystem/src/utf8_codecvt_facet.cpp + ${boost_SOURCE_DIR}/libs/filesystem/src/windows_file_codecvt.cpp + ) + # Ensure that the boost atomic library is used instead of the standard atomic library, where some functionality is only available as of C++20. + target_compile_definitions(boost_filesystem PUBLIC BOOST_FILESYSTEM_NO_CXX20_ATOMIC_REF) + + target_link_libraries(boost_filesystem PUBLIC boost_disable_autolink boost) + set_property(TARGET boost_filesystem PROPERTY POSITION_INDEPENDENT_CODE ON) + add_library(Boost::filesystem ALIAS boost_filesystem) + if(NOT MSVC) #on gcc and apple clang we need to define BOOST_NO_CXX98_FUNCTION_BASE because a deprecated function is sometimes used in boost + target_compile_definitions(boost_filesystem PUBLIC BOOST_NO_CXX98_FUNCTION_BASE) + endif() + + set(Boost_LIBRARIES Boost::boost Boost::filesystem) + set(Boost_FOUND ON) + else() - find_package(Boost REQUIRED COMPONENTS outcome optional filesystem) -endif(MEMILIO_USE_BUNDLED_BOOST) + find_package(Boost ${MEMILIO_MINIMAL_BOOST_VERSION}...${MEMILIO_BOOST_VERSION} REQUIRED COMPONENTS outcome optional filesystem) +endif() # ## HDF5 find_package(HDF5 COMPONENTS C) diff --git a/cpp/thirdparty/README.md b/cpp/thirdparty/README.md index 131c368f05..932b564963 100644 --- a/cpp/thirdparty/README.md +++ b/cpp/thirdparty/README.md @@ -4,22 +4,11 @@ This directory contains CMake configuration of the dependencies of the MEmilio C ## Bundled Dependencies -Most dependencies of this project don't need to be installed manually. Dependencies are bundled in two different ways: cloning an external repository or as an archive included in the MEmilio project. Using the `MEMILIO_USE_BUNDLED_` CMake options (where `` is the name of the dependency), installed packages can be used instead of the bundled packages, using the usual `find_package` mechanism. +Most dependencies of this project don't need to be installed manually. These dependencies are bundled by cloning an external repository. Using the `MEMILIO_USE_BUNDLED_` CMake options (where `` is the name of the dependency), installed packages can be used instead of the bundled packages, using the usual `find_package` mechanism. ### External Repositories The repository of the dependency is cloned during CMake configuration into the `/_deps/-src` directory. The dependency is then built together with the MEmilio project. The version of the package is set in the [thirdparty CMakeLists.txt](CMakeLists.txt). To upgrade the version, simply increase the version number there. -### Archived (Boost) - -We currently bundle only a minimal extract of boost library as an archive that contains only the libraries of boost that we use. Currently, these libraries are filesystem, outcome, and optional, including transitive dependencies. The archive has been created using the boost tool `bcp`, see https://www.boost.org/doc/libs/1_72_0/tools/bcp/doc/html/index.html. - -To upgrade boost, follow these steps: - -1. call `bcp` to copy the required files (see the `bcp` documentation for details) -```bash -./bcp optional outcome filesystem path_to_epi_source/cpp/thirdparty/boost_ -``` -2. compress the folder into a `.tar.gz` archive and replace the existing archive in the repository. -3. adapt the file `cpp/cmake/BuildBoost.cmake`. At least update the version number and archive name. - +Note: Cloning the boost git repository can take a while. Especially for this dependency, it may be useful to set the `MEMILIO_USE_BUNDLED_BOOST` option to `OFF` if the package is already installed. The installed boost version must be at least version 1.76.0. + It is planned to offer the option to use a minimal extract of boost library as an archive included in the MEmilio project. With the minimal version of boost, only limited functionality of MEmilio can be used. \ No newline at end of file diff --git a/cpp/thirdparty/boost_1_75_0.tar.gz b/cpp/thirdparty/boost_1_75_0.tar.gz deleted file mode 100644 index 04d1e16733..0000000000 Binary files a/cpp/thirdparty/boost_1_75_0.tar.gz and /dev/null differ diff --git a/pycode/memilio-generation/memilio/generation_test/test_oseir_generation.py b/pycode/memilio-generation/memilio/generation_test/test_oseir_generation.py index 5913acf8de..7cae459d09 100644 --- a/pycode/memilio-generation/memilio/generation_test/test_oseir_generation.py +++ b/pycode/memilio-generation/memilio/generation_test/test_oseir_generation.py @@ -51,6 +51,11 @@ class TestOseirGeneration(unittest.TestCase): cmake_cmd, stdout=subprocess.PIPE, cwd=build_dir.name) cmake_cmd_result.check_returncode() + cmake_cmd = ["cmake", "--build", ".", "--target", "boost-bootstrap"] + cmake_cmd_result = subprocess.run( + cmake_cmd, stdout=subprocess.PIPE, cwd=build_dir.name) + cmake_cmd_result.check_returncode() + @patch('memilio.generation.scanner.utility.try_get_compilation_database_path') def setUp(self, try_get_compilation_database_path_mock): try_get_compilation_database_path_mock.return_value = self.build_dir.name diff --git a/pycode/memilio-simulation/memilio/simulation/pickle_serializer.h b/pycode/memilio-simulation/memilio/simulation/pickle_serializer.h index 34fbeb9e78..8ad6975235 100644 --- a/pycode/memilio-simulation/memilio/simulation/pickle_serializer.h +++ b/pycode/memilio-simulation/memilio/simulation/pickle_serializer.h @@ -553,7 +553,7 @@ IOResult> PickleObject::expect_optional(const std::string& na return failure(*m_status); } - BOOST_OUTCOME_TRY(r, expect_list(name, tag)); + BOOST_OUTCOME_TRY(auto&& r, expect_list(name, tag)); if (r.size() == 0) { return success();