From ad7770ba27b541a80329d55ff0b721030aefd41a Mon Sep 17 00:00:00 2001 From: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> Date: Fri, 25 Oct 2024 16:37:44 +0200 Subject: [PATCH] [Ant-2223] use area file (#955) use area file for Benders new outputs. --- .../benders_by_batch/BatchCollection.cpp | 2 +- .../benders_core/BendersMathLogger.cpp | 21 ++- .../benders_core/SimulationOptions.cpp | 1 + src/cpp/benders/benders_core/WorkerMaster.cpp | 5 +- .../benders/benders_core/BendersMathLogger.h | 15 +++ .../benders_core/OuterLoopInputDataReader.h | 2 +- .../benders_core/SimulationOptions.hxx | 2 + .../benders/benders_core/common.h | 4 +- .../benders/benders_mpi/BendersMPI.h | 8 +- src/cpp/benders/factories/BendersFactory.cpp | 124 ++++++++---------- .../benders/factories/BendersFactory.h | 17 +-- src/cpp/benders/logger/Master.cpp | 5 +- src/cpp/benders/logger/MathLogger.cpp | 6 + src/cpp/benders/logger/User.cpp | 7 +- src/cpp/benders/logger/UserFile.cpp | 8 +- .../antares-xpansion/benders/logger/Master.h | 4 +- .../benders/logger/MathLogger.h | 4 +- .../antares-xpansion/benders/logger/User.h | 4 +- .../benders/logger/UserFile.h | 4 +- .../benders/output/JsonWriter.h | 2 +- src/cpp/helpers/AreaParser.cpp | 32 +++++ src/cpp/helpers/CMakeLists.txt | 5 +- src/cpp/helpers/Clock.cpp | 23 ---- .../antares-xpansion/helpers/AreaParser.h | 21 +++ .../helper/ProblemGenerationLogger.cpp | 24 +++- .../lpnamer/helper/ProblemGenerationLogger.h | 18 ++- .../input_reader/CandidatesINIReader.cpp | 44 ++----- .../input_reader/CandidatesINIReader.h | 7 +- src/cpp/xpansion_interfaces/CMakeLists.txt | 1 + .../xpansion_interfaces}/Clock.h | 17 ++- .../xpansion_interfaces/ILogger.h | 17 ++- .../xpansion_interfaces}/LoggerUtils.h | 2 +- src/python/antares_xpansion/config_loader.py | 9 ++ .../antares_xpansion/optimisation_keys.py | 3 + src/python/antares_xpansion/xpansionConfig.py | 1 + tests/cpp/TestDoubles/LoggerStub.h | 4 +- tests/cpp/logger/logger_test.cpp | 3 +- .../cpp/lp_namer/CandidatesINIReaderTest.cpp | 7 +- 38 files changed, 292 insertions(+), 191 deletions(-) create mode 100644 src/cpp/helpers/AreaParser.cpp delete mode 100644 src/cpp/helpers/Clock.cpp create mode 100644 src/cpp/helpers/include/antares-xpansion/helpers/AreaParser.h rename src/cpp/{helpers/include/antares-xpansion/helpers => xpansion_interfaces/include/antares-xpansion/xpansion_interfaces}/Clock.h (50%) rename src/cpp/{helpers/include/antares-xpansion/helpers => xpansion_interfaces/include/antares-xpansion/xpansion_interfaces}/LoggerUtils.h (85%) diff --git a/src/cpp/benders/benders_by_batch/BatchCollection.cpp b/src/cpp/benders/benders_by_batch/BatchCollection.cpp index 497755339..54f1b2ac3 100644 --- a/src/cpp/benders/benders_by_batch/BatchCollection.cpp +++ b/src/cpp/benders/benders_by_batch/BatchCollection.cpp @@ -16,7 +16,7 @@ void BatchCollection::BuildBatches() { std::string("batch_size(") + std::to_string(batch_size_) + ") can not be greater than number of subproblems (" + std::to_string(sub_problems_number_) + ")", - LogUtils::LOGLEVEL::WARNING); + LogUtils::LOGLEVEL::WARNING, "Benders By batch"); logger_->display_message( std::string("Setting batch_size = number of subproblems(") + std::to_string(sub_problems_number_) + diff --git a/src/cpp/benders/benders_core/BendersMathLogger.cpp b/src/cpp/benders/benders_core/BendersMathLogger.cpp index 28e137a20..b0aa1c1a3 100644 --- a/src/cpp/benders/benders_core/BendersMathLogger.cpp +++ b/src/cpp/benders/benders_core/BendersMathLogger.cpp @@ -4,7 +4,7 @@ #include #include "antares-xpansion/xpansion_interfaces/LogUtils.h" -#include "antares-xpansion/helpers/LoggerUtils.h" +#include "antares-xpansion/xpansion_interfaces/LoggerUtils.h" HeadersManager::HeadersManager(HEADERSTYPE type, const BENDERSMETHOD& method) : type_(type), method_(method) {} @@ -113,7 +113,11 @@ MathLogger::MathLogger(std::streamsize width, HEADERSTYPE type) void MathLogger::display_message(const std::string& str) { LogsDestination() << str << std::endl; } - +void MathLogger::display_message(const std::string& str, + LogUtils::LOGLEVEL level, + const std::string& context) { + LogsDestination() << PrefixMessage(level, context) << str << std::endl; +} std::vector MathLogger::Headers() const { return headers_; } LogDestination& MathLogger::LogsDestination() { return log_destination_; } @@ -260,6 +264,14 @@ void MathLoggerDriver::display_message(const std::string& str) { } } +void MathLoggerDriver::display_message(const std::string& str, + LogUtils::LOGLEVEL level, + const std::string& context) { + for (auto logger : math_loggers_) { + logger->display_message(str, level, context); + } +} + void MathLoggerDriver::PrintIterationSeparatorBegin() { for (auto logger : math_loggers_) { logger->PrintIterationSeparatorBegin(); @@ -330,6 +342,11 @@ void MathLoggerImplementation::display_message(const std::string& str) { implementation_->display_message(str); } +void MathLoggerImplementation::display_message(const std::string& str, + LogUtils::LOGLEVEL level, + const std::string& context) { + implementation_->display_message(str, level, context); +} void MathLoggerImplementation::Print(const CurrentIterationData& data) { implementation_->Print(data); } diff --git a/src/cpp/benders/benders_core/SimulationOptions.cpp b/src/cpp/benders/benders_core/SimulationOptions.cpp index 39b8386a0..addbea32f 100644 --- a/src/cpp/benders/benders_core/SimulationOptions.cpp +++ b/src/cpp/benders/benders_core/SimulationOptions.cpp @@ -137,6 +137,7 @@ BaseOptions SimulationOptions::get_base_options() const { result.SOLVER_NAME = SOLVER_NAME; result.weights = _weights; result.RESUME = RESUME; + result.AREA_FILE = AREA_FILE; return result; } diff --git a/src/cpp/benders/benders_core/WorkerMaster.cpp b/src/cpp/benders/benders_core/WorkerMaster.cpp index ac03e5734..95acb737c 100644 --- a/src/cpp/benders/benders_core/WorkerMaster.cpp +++ b/src/cpp/benders/benders_core/WorkerMaster.cpp @@ -301,7 +301,10 @@ void WorkerMaster::_set_alpha_var() { solver_addrows(*_solver, rowtype, rowrhs, {}, mstart, mclind, matval); } } else { - logger_->display_message("ERROR a variable named overall_subpb_cost_under_approx is in input", LogUtils::LOGLEVEL::ERR); + logger_->display_message( + "ERROR There is already a variable called " + "overall_subpb_cost_under_approx in the input.", + LogUtils::LOGLEVEL::ERR, "Alpha var"); } } diff --git a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h index 192788d29..861128678 100644 --- a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h +++ b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/BendersMathLogger.h @@ -78,6 +78,8 @@ struct MathLogger : public MathLoggerBehaviour { HEADERSTYPE type = HEADERSTYPE::SHORT); void display_message(const std::string& str) override; + void display_message(const std::string& str, LogUtils::LOGLEVEL level, + const std::string& context) override; virtual void Print(const CurrentIterationData& data) = 0; std::vector Headers() const override; LogDestination& LogsDestination() override; @@ -137,6 +139,8 @@ struct MathLoggerExternalLoopSpecific : public MathLogger { void setHeadersList() override; void Print(const CurrentIterationData& data) override; void display_message(const std::string& msg) override; + void display_message(const std::string& str, LogUtils::LOGLEVEL level, + const std::string& context) override; virtual ~MathLoggerExternalLoopSpecific() = default; private: @@ -156,6 +160,8 @@ class MathLoggerImplementation : public MathLoggerBehaviour { explicit MathLoggerImplementation(std::shared_ptr implementation); void display_message(const std::string& str) override; + void display_message(const std::string& str, LogUtils::LOGLEVEL level, + const std::string& context) override; void Print(const CurrentIterationData& data) override; void PrintIterationSeparatorBegin() override; void PrintIterationSeparatorEnd() override; @@ -176,6 +182,8 @@ class MathLoggerDriver : public ILoggerXpansion { MathLoggerDriver() = default; void write_header(); void display_message(const std::string& str) override; + void display_message(const std::string& str, LogUtils::LOGLEVEL level, + const std::string& context) override; void add_logger(std::shared_ptr logger); template void add_logger(const std::filesystem::path& file_path, @@ -218,4 +226,11 @@ template void MathLoggerExternalLoopSpecific::display_message( const std::string& msg) { // keep empty +} + +template +void MathLoggerExternalLoopSpecific::display_message( + const std::string& str, LogUtils::LOGLEVEL level, + const std::string& context) { + // keep empty } \ No newline at end of file diff --git a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/OuterLoopInputDataReader.h b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/OuterLoopInputDataReader.h index bd4dfe762..fcda0f967 100644 --- a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/OuterLoopInputDataReader.h +++ b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/OuterLoopInputDataReader.h @@ -4,7 +4,7 @@ #include #include -#include "antares-xpansion/helpers/LoggerUtils.h" +#include "antares-xpansion/xpansion_interfaces/LoggerUtils.h" #include "yaml-cpp/yaml.h" namespace Benders::Criterion { diff --git a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/SimulationOptions.hxx b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/SimulationOptions.hxx index 337c4b262..11adc7e87 100644 --- a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/SimulationOptions.hxx +++ b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/SimulationOptions.hxx @@ -79,3 +79,5 @@ BENDERS_OPTIONS_MACRO(DO_OUTER_LOOP, bool, false, asBool()) // Outer Loop Options file BENDERS_OPTIONS_MACRO(OUTER_LOOP_OPTION_FILE, std::string, "adequacy_criterion.yml", asString()) +// area file +BENDERS_OPTIONS_MACRO(AREA_FILE, std::string, "area.txt", asString()) diff --git a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/common.h b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/common.h index 2d393f97e..f2799800f 100644 --- a/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/common.h +++ b/src/cpp/benders/benders_core/include/antares-xpansion/benders/benders_core/common.h @@ -57,8 +57,7 @@ enum class BENDERSMETHOD { BENDERS_BY_BATCH_OUTERLOOP }; -constexpr inline std::string_view bendersmethod_to_string( - BENDERSMETHOD method) { +inline std::string bendersmethod_to_string(BENDERSMETHOD method) { switch (method) { case BENDERSMETHOD::BENDERS: return "Benders"; @@ -149,6 +148,7 @@ struct BaseOptions { std::string MASTER_NAME; std::string SOLVER_NAME; std::string SLAVE_WEIGHT; + std::string AREA_FILE; int LOG_LEVEL = 0; diff --git a/src/cpp/benders/benders_mpi/include/antares-xpansion/benders/benders_mpi/BendersMPI.h b/src/cpp/benders/benders_mpi/include/antares-xpansion/benders/benders_mpi/BendersMPI.h index efd786ffb..05da35767 100644 --- a/src/cpp/benders/benders_mpi/include/antares-xpansion/benders/benders_mpi/BendersMPI.h +++ b/src/cpp/benders/benders_mpi/include/antares-xpansion/benders/benders_mpi/BendersMPI.h @@ -1,15 +1,15 @@ #pragma once -#include "antares-xpansion/helpers/ArchiveReader.h" #include "antares-xpansion/benders/benders_core/BendersBase.h" #include "antares-xpansion/benders/benders_core/BendersStructsDatas.h" -#include "antares-xpansion/xpansion_interfaces/ILogger.h" -#include "antares-xpansion/helpers/LoggerUtils.h" #include "antares-xpansion/benders/benders_core/SubproblemCut.h" #include "antares-xpansion/benders/benders_core/SubproblemWorker.h" -#include "antares-xpansion/helpers/Timer.h" #include "antares-xpansion/benders/benders_core/Worker.h" #include "antares-xpansion/benders/benders_core/WorkerMaster.h" +#include "antares-xpansion/helpers/ArchiveReader.h" +#include "antares-xpansion/helpers/Timer.h" +#include "antares-xpansion/xpansion_interfaces/ILogger.h" +#include "antares-xpansion/xpansion_interfaces/LoggerUtils.h" #include "common_mpi.h" /*! diff --git a/src/cpp/benders/factories/BendersFactory.cpp b/src/cpp/benders/factories/BendersFactory.cpp index 34aad39b1..b776abc1c 100644 --- a/src/cpp/benders/factories/BendersFactory.cpp +++ b/src/cpp/benders/factories/BendersFactory.cpp @@ -4,16 +4,16 @@ #include #include "antares-xpansion/benders/benders_by_batch/BendersByBatch.h" -#include "antares-xpansion/benders/benders_mpi/BendersMpiOuterLoop.h" -#include "antares-xpansion/xpansion_interfaces/ILogger.h" -#include "antares-xpansion/xpansion_interfaces/LogUtils.h" -#include "antares-xpansion/benders/factories/LoggerFactories.h" #include "antares-xpansion/benders/benders_core/MasterUpdate.h" -#include "antares-xpansion/benders/benders_mpi/OuterLoopBenders.h" #include "antares-xpansion/benders/benders_core/StartUp.h" -#include "antares-xpansion/helpers/Timer.h" -#include "antares-xpansion/benders/benders_core/Worker.h" +#include "antares-xpansion/benders/benders_mpi/BendersMpiOuterLoop.h" +#include "antares-xpansion/benders/benders_mpi/OuterLoopBenders.h" +#include "antares-xpansion/benders/factories/LoggerFactories.h" #include "antares-xpansion/benders/factories/WriterFactories.h" +#include "antares-xpansion/helpers/AreaParser.h" +#include "antares-xpansion/helpers/Timer.h" +#include "antares-xpansion/xpansion_interfaces/ILogger.h" +#include "antares-xpansion/xpansion_interfaces/LogUtils.h" BENDERSMETHOD DeduceBendersMethod(size_t coupling_map_size, size_t batch_size, bool external_loop) { @@ -44,13 +44,14 @@ pBendersBase BendersMainFactory::PrepareForExecution(bool external_loop) { method_ = DeduceBendersMethod(coupling_map.size(), options_.BATCH_SIZE, external_loop); + context_ = bendersmethod_to_string(method_); + auto benders_log_console = benders_options.LOG_LEVEL > 0; if (pworld_->rank() == 0) { auto logger_factory = FileAndStdoutLoggerFactory(LogReportsName(), benders_log_console); logger_ = logger_factory.get_logger(); - - + math_log_driver = BuildMathLogger(benders_log_console); writer_ = build_json_writer(options_.JSON_FILE, options_.RESUME); if (Benders::StartUp startup; startup.StudyAlreadyAchievedCriterion(options_, writer_, logger_)) @@ -61,16 +62,17 @@ pBendersBase BendersMainFactory::PrepareForExecution(bool external_loop) { math_log_driver = MathLoggerFactory::get_void_logger(); } - auto outer_loop_input_data = ProcessCriterionInput(coupling_map); + benders_loggers_.AddLogger(logger_); + benders_loggers_.AddLogger(math_log_driver); + auto outer_loop_input_data = ProcessCriterionInput(); criterion_computation_ = std::make_shared( outer_loop_input_data); - if (pworld_->rank() == 0) { - math_log_driver = BuildMathLogger(benders_log_console); + + if (pworld_->rank() == 0 && !outer_loop_input_data.OuterLoopData().empty()) { + AddCriterionOutput(math_log_driver); } - benders_loggers_.AddLogger(logger_); - benders_loggers_.AddLogger(math_log_driver); switch (method_) { case BENDERSMETHOD::BENDERS: benders = std::make_shared(benders_options, logger_, writer_, @@ -118,17 +120,24 @@ std::shared_ptr BendersMainFactory::BuildMathLogger( auto math_log_driver = math_log_factory.get_logger(); + return math_log_driver; +} + +void BendersMainFactory::AddCriterionOutput( + std::shared_ptr math_log_driver) { + const std::filesystem::path output_root(options_.OUTPUTROOT); + const auto& headers = criterion_computation_->getOuterLoopInputData().PatternBodies(); math_log_driver->add_logger( - output_root / "LOLD.txt", headers, + output_root / LOLD_FILE, headers, &OuterLoopCurrentIterationData::outer_loop_criterion); + + positive_unsupplied_file_ = + criterion_computation_->getOuterLoopInputData().PatternsPrefix() + ".txt"; math_log_driver->add_logger( - output_root / - (criterion_computation_->getOuterLoopInputData().PatternsPrefix() + - ".txt"), - headers, &OuterLoopCurrentIterationData::outer_loop_patterns_values); - return math_log_driver; + output_root / positive_unsupplied_file_, headers, + &OuterLoopCurrentIterationData::outer_loop_patterns_values); } int BendersMainFactory::RunBenders() { @@ -158,17 +167,19 @@ void BendersMainFactory::EndMessage(const double execution_time) { std::ostringstream str; str << "Optimization results available in : " << options_.JSON_FILE << std::endl; - benders_loggers_.display_message(str.str()); + benders_loggers_.display_message(str.str(), LogUtils::LOGLEVEL::INFO, + context_); str.str(""); str << bendersmethod_to_string(method_) << " ran in " << execution_time << " s" << std::endl; - benders_loggers_.display_message(str.str()); + benders_loggers_.display_message(str.str(), LogUtils::LOGLEVEL::INFO, + context_); } Benders::Criterion::OuterLoopInputData -BendersMainFactory::ProcessCriterionInput(const CouplingMap& couplingMap) { +BendersMainFactory::ProcessCriterionInput() { const auto fpath = std::filesystem::path(options_.INPUTROOT) / options_.OUTER_LOOP_OPTION_FILE; // if adequacy_criterion.yml is provided read it @@ -177,36 +188,13 @@ BendersMainFactory::ProcessCriterionInput(const CouplingMap& couplingMap) { } // else compute criterion for all areas! else { - return GetInputFromSubProblem(couplingMap); + return BuildPatternsUsingAreaFile(); } } Benders::Criterion::OuterLoopInputData -BendersMainFactory::GetInputFromSubProblem(const CouplingMap& couplingMap) { - auto first_subproblem_pair = std::find_if_not( - couplingMap.begin(), couplingMap.end(), - [this](const auto& in) { return in.first == options_.MASTER_NAME; }); - if (first_subproblem_pair == couplingMap.end()) { - std::ostringstream stream; - auto log_location = LOGLOCATION; - stream << "Could not find any Subproblem in structure file " - << options_.STRUCTURE_FILE << std::endl; - benders_loggers_.display_message(log_location + stream.str()); - throw InvalidStructureFile( - PrefixMessage(LogUtils::LOGLEVEL::FATAL, "Benders"), stream.str(), - log_location); - } else { - const auto first_subproblem_name = first_subproblem_pair->first; - return PatternsFromSupbProblem(first_subproblem_name); - } -} - -Benders::Criterion::OuterLoopInputData -BendersMainFactory::PatternsFromSupbProblem( - const std::string& first_subproblem_name) const { - SolverAbstract::Ptr solver = BuildSolver(first_subproblem_name); - const auto all_variables_name = solver->get_col_names(); - std::set unique_areas = UniqueAreas(all_variables_name); +BendersMainFactory::BuildPatternsUsingAreaFile() { + std::set unique_areas = ReadAreaFile(); Benders::Criterion::OuterLoopInputData ret; ret.SetCriterionCountThreshold(1); @@ -216,36 +204,28 @@ BendersMainFactory::PatternsFromSupbProblem( ret.AddSingleData(singleInputData); } - solver->free(); return ret; } -std::set BendersMainFactory::UniqueAreas( - const std::vector& all_variables_name) const { +std::set BendersMainFactory::ReadAreaFile() { std::set unique_areas; - std::regex area_regex( - "area<([^>]+)>"); // Regular expression to match area<...> - - for (const auto& str : all_variables_name) { - std::smatch match; - if (std::regex_search(str, match, area_regex)) { - unique_areas.insert(match[1]); // Insert the matched area into the set - } + const auto area_file = + std::filesystem::path(options_.INPUTROOT) / options_.AREA_FILE; + const auto area_file_data = AreaParser::ReadAreaFile(area_file); + if (const auto& msg = area_file_data.error_message; !msg.empty()) { + benders_loggers_.display_message(msg, LogUtils::LOGLEVEL::WARNING, + context_); + std::ostringstream ms; + ms << " Consequently, " << LOLD_FILE + << " and other criterion based files will not be produced!"; + + benders_loggers_.display_message(ms.str(), LogUtils::LOGLEVEL::WARNING, + context_); + return {}; } - return unique_areas; + return {area_file_data.areas.begin(), area_file_data.areas.end()}; } -SolverAbstract::Ptr BendersMainFactory::BuildSolver( - const std::string& first_subproblem_name) const { - SolverFactory factory(logger_); - auto solver_log_manager = SolverLogManager(LogReportsName()); - auto solver = factory.create_solver( - options_.SOLVER_NAME, SOLVER_TYPE::CONTINUOUS, solver_log_manager); - solver->read_prob_mps(std::filesystem::path(options_.INPUTROOT) / - first_subproblem_name); - solver->set_threads(1); - return solver; -} int BendersMainFactory::RunExternalLoop() { try { diff --git a/src/cpp/benders/factories/include/antares-xpansion/benders/factories/BendersFactory.h b/src/cpp/benders/factories/include/antares-xpansion/benders/factories/BendersFactory.h index ab6e41016..519000516 100644 --- a/src/cpp/benders/factories/include/antares-xpansion/benders/factories/BendersFactory.h +++ b/src/cpp/benders/factories/include/antares-xpansion/benders/factories/BendersFactory.h @@ -22,24 +22,21 @@ class BendersMainFactory { Logger logger_ = nullptr; Writer writer_ = nullptr; BENDERSMETHOD method_ = BENDERSMETHOD::BENDERS; + std::string context_ = bendersmethod_to_string(BENDERSMETHOD::BENDERS); + std::string positive_unsupplied_file_; + static constexpr const char* const LOLD_FILE = "LOLD.txt"; [[nodiscard]] int RunExternalLoop(); [[nodiscard]] int RunBenders(); [[nodiscard]] std::shared_ptr BuildMathLogger( bool benders_log_console) const; pBendersBase PrepareForExecution(bool external_loop); - [[nodiscard]] Benders::Criterion::OuterLoopInputData ProcessCriterionInput( - const CouplingMap& couplingMap); - Benders::Criterion::OuterLoopInputData GetInputFromSubProblem( - const CouplingMap& couplingMap); + [[nodiscard]] Benders::Criterion::OuterLoopInputData ProcessCriterionInput(); - Benders::Criterion::OuterLoopInputData PatternsFromSupbProblem( - const std::string& first_subproblem_name) const; - SolverAbstract::Ptr BuildSolver( - const std::string& first_subproblem_name) const; - std::set UniqueAreas( - const std::vector& all_variables_name) const; + Benders::Criterion::OuterLoopInputData BuildPatternsUsingAreaFile(); + std::set ReadAreaFile(); void EndMessage(const double execution_time); + void AddCriterionOutput(std::shared_ptr math_log_driver); public: explicit BendersMainFactory(int argc, char** argv, diff --git a/src/cpp/benders/logger/Master.cpp b/src/cpp/benders/logger/Master.cpp index 6641f6624..222d736ac 100644 --- a/src/cpp/benders/logger/Master.cpp +++ b/src/cpp/benders/logger/Master.cpp @@ -8,9 +8,10 @@ void Master::display_message(const std::string &str) { logger->display_message(str); } } -void Master::display_message(const std::string &str, LogUtils::LOGLEVEL level) { +void Master::display_message(const std::string &str, LogUtils::LOGLEVEL level, + const std::string &context) { for (auto logger : _loggers) { - logger->display_message(str, level); + logger->display_message(str, level, context); } } diff --git a/src/cpp/benders/logger/MathLogger.cpp b/src/cpp/benders/logger/MathLogger.cpp index 17dcdec82..67ee77a49 100644 --- a/src/cpp/benders/logger/MathLogger.cpp +++ b/src/cpp/benders/logger/MathLogger.cpp @@ -9,6 +9,12 @@ void MathLoggerFile::display_message(const std::string& msg) { // keep empty } +void MathLoggerFile::display_message(const std::string& msg, + LogUtils::LOGLEVEL level, + const std::string& context) { + // keep empty +} + void MathLoggerOstream::PrintIterationSeparatorBegin() { // keep empty } diff --git a/src/cpp/benders/logger/User.cpp b/src/cpp/benders/logger/User.cpp index 438c091e1..7ed1abcdd 100644 --- a/src/cpp/benders/logger/User.cpp +++ b/src/cpp/benders/logger/User.cpp @@ -9,8 +9,8 @@ #include "antares-xpansion/benders/logger/CandidateLog.h" #include "antares-xpansion/benders/logger/Commons.h" #include "antares-xpansion/benders/logger/IterationResultLog.h" -#include "antares-xpansion/helpers/LoggerUtils.h" #include "antares-xpansion/helpers/Timer.h" +#include "antares-xpansion/xpansion_interfaces/LoggerUtils.h" using xpansion::logger::commons::indent_1; namespace xpansion { @@ -27,8 +27,9 @@ void User::display_message(const std::string &str) { _stream << PrefixMessage(LogUtils::LOGLEVEL::INFO, CONTEXT) << str << std::endl; } -void User::display_message(const std::string &str, LogUtils::LOGLEVEL level) { - _stream << PrefixMessage(level, CONTEXT) << str << std::endl; +void User::display_message(const std::string &str, LogUtils::LOGLEVEL level, + const std::string &context) { + _stream << PrefixMessage(level, context) << str << std::endl; } void User::log_at_initialization(const int it_number) { diff --git a/src/cpp/benders/logger/UserFile.cpp b/src/cpp/benders/logger/UserFile.cpp index 963eb5ebc..7dc2491f2 100644 --- a/src/cpp/benders/logger/UserFile.cpp +++ b/src/cpp/benders/logger/UserFile.cpp @@ -9,8 +9,8 @@ #include "antares-xpansion/benders/logger/CandidateLog.h" #include "antares-xpansion/benders/logger/Commons.h" #include "antares-xpansion/benders/logger/IterationResultLog.h" -#include "antares-xpansion/helpers/LoggerUtils.h" #include "antares-xpansion/helpers/Timer.h" +#include "antares-xpansion/xpansion_interfaces/LoggerUtils.h" using xpansion::logger::commons::indent_1; namespace xpansion { @@ -34,9 +34,9 @@ void UserFile::display_message(const std::string &str) { _file << PrefixMessage(LogUtils::LOGLEVEL::INFO, CONTEXT) << str << std::endl; _file.flush(); } -void UserFile::display_message(const std::string &str, - LogUtils::LOGLEVEL level) { - _file << PrefixMessage(level, CONTEXT) << str << std::endl; +void UserFile::display_message(const std::string &str, LogUtils::LOGLEVEL level, + const std::string &context) { + _file << PrefixMessage(level, context) << str << std::endl; _file.flush(); } diff --git a/src/cpp/benders/logger/include/antares-xpansion/benders/logger/Master.h b/src/cpp/benders/logger/include/antares-xpansion/benders/logger/Master.h index e63ee8d7e..b0d6b0ef6 100644 --- a/src/cpp/benders/logger/include/antares-xpansion/benders/logger/Master.h +++ b/src/cpp/benders/logger/include/antares-xpansion/benders/logger/Master.h @@ -25,8 +25,8 @@ class Master : public ILogger { } void display_message(const std::string &str) override; - void display_message(const std::string &str, - LogUtils::LOGLEVEL level) override; + void display_message(const std::string &str, LogUtils::LOGLEVEL level, + const std::string &context) override; virtual void PrintIterationSeparatorBegin() override; virtual void PrintIterationSeparatorEnd() override; diff --git a/src/cpp/benders/logger/include/antares-xpansion/benders/logger/MathLogger.h b/src/cpp/benders/logger/include/antares-xpansion/benders/logger/MathLogger.h index 05b9865a9..95579939d 100644 --- a/src/cpp/benders/logger/include/antares-xpansion/benders/logger/MathLogger.h +++ b/src/cpp/benders/logger/include/antares-xpansion/benders/logger/MathLogger.h @@ -3,7 +3,7 @@ #include #include "antares-xpansion/benders/benders_core/BendersMathLogger.h" -#include "antares-xpansion/helpers/LoggerUtils.h" +#include "antares-xpansion/xpansion_interfaces/LoggerUtils.h" class MathLoggerFile : public MathLoggerImplementation { public: @@ -12,6 +12,8 @@ class MathLoggerFile : public MathLoggerImplementation { std::streamsize width = 30); void display_message(const std::string& msg) override; + void display_message(const std::string& msg, LogUtils::LOGLEVEL level, + const std::string& context) override; virtual void PrintIterationSeparatorBegin() override; virtual void PrintIterationSeparatorEnd() override; diff --git a/src/cpp/benders/logger/include/antares-xpansion/benders/logger/User.h b/src/cpp/benders/logger/include/antares-xpansion/benders/logger/User.h index f1598d1bd..345359c92 100644 --- a/src/cpp/benders/logger/include/antares-xpansion/benders/logger/User.h +++ b/src/cpp/benders/logger/include/antares-xpansion/benders/logger/User.h @@ -17,8 +17,8 @@ class User : public ILogger { User(std::ostream &stream); void display_message(const std::string &str) override; - void display_message(const std::string &str, - LogUtils::LOGLEVEL level) override; + void display_message(const std::string &str, LogUtils::LOGLEVEL level, + const std::string &context) override; virtual void PrintIterationSeparatorBegin() override; virtual void PrintIterationSeparatorEnd() override; diff --git a/src/cpp/benders/logger/include/antares-xpansion/benders/logger/UserFile.h b/src/cpp/benders/logger/include/antares-xpansion/benders/logger/UserFile.h index ed4877a96..1b6691616 100644 --- a/src/cpp/benders/logger/include/antares-xpansion/benders/logger/UserFile.h +++ b/src/cpp/benders/logger/include/antares-xpansion/benders/logger/UserFile.h @@ -18,8 +18,8 @@ class UserFile : public ILogger { ~UserFile(); void display_message(const std::string &str) override; - void display_message(const std::string &str, - LogUtils::LOGLEVEL level) override; + void display_message(const std::string &str, LogUtils::LOGLEVEL level, + const std::string &context) override; virtual void PrintIterationSeparatorBegin() override; virtual void PrintIterationSeparatorEnd() override; diff --git a/src/cpp/benders/output/include/antares-xpansion/benders/output/JsonWriter.h b/src/cpp/benders/output/include/antares-xpansion/benders/output/JsonWriter.h index 2f80f0c19..7bc84169a 100644 --- a/src/cpp/benders/output/include/antares-xpansion/benders/output/JsonWriter.h +++ b/src/cpp/benders/output/include/antares-xpansion/benders/output/JsonWriter.h @@ -6,7 +6,7 @@ #include #include -#include "antares-xpansion/helpers/Clock.h" +#include "antares-xpansion/xpansion_interfaces/Clock.h" #include "antares-xpansion/xpansion_interfaces/OutputWriter.h" namespace Output { diff --git a/src/cpp/helpers/AreaParser.cpp b/src/cpp/helpers/AreaParser.cpp new file mode 100644 index 000000000..6f9bc282b --- /dev/null +++ b/src/cpp/helpers/AreaParser.cpp @@ -0,0 +1,32 @@ +#include "antares-xpansion/helpers/AreaParser.h" + +#include "antares-xpansion/xpansion_interfaces/StringManip.h" + +AreaFileData AreaParser::ReadAreaFile(const std::filesystem::path &areaFile) { + std::ifstream area_filestream(areaFile); + + if (!area_filestream.good()) { + std::ostringstream out_message(""); + out_message << LOGLOCATION << "unable to open " << areaFile.string(); + return {.error_message = out_message.str(), .areas = {}}; + } + + return {.error_message = "", .areas = ReadLineByLineArea(area_filestream)}; +} + +std::vector AreaParser::ReadAreaFile( + std::istringstream &areaFileInStringStream) { + return ReadLineByLineArea(areaFileInStringStream); +} + +std::vector AreaParser::ReadLineByLineArea(std::istream &stream) { + std::vector result; + + std::string line; + while (std::getline(stream, line)) { + if (!line.empty() && line.front() != '#') { + result.push_back(StringManip::StringUtils::ToLowercase(line)); + } + } + return result; +} diff --git a/src/cpp/helpers/CMakeLists.txt b/src/cpp/helpers/CMakeLists.txt index 322be120e..72fb82baf 100644 --- a/src/cpp/helpers/CMakeLists.txt +++ b/src/cpp/helpers/CMakeLists.txt @@ -21,22 +21,21 @@ target_sources(helpers PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/AntaresVersionProvider.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ArchiveReader.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ArchiveWriter.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Clock.cpp ${CMAKE_CURRENT_SOURCE_DIR}/FileInBuffer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/JsonXpansionReader.cpp ${CMAKE_CURRENT_SOURCE_DIR}/OptionsParser.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/AreaParser.cpp ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/helpers/AntaresArchiveUpdater.h ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/helpers/AntaresArchiveUpdaterExeOptions.h ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/helpers/AntaresVersionProvider.h ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/helpers/ArchiveIO.h ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/helpers/ArchiveReader.h ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/helpers/ArchiveWriter.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/helpers/Clock.h ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/helpers/FileInBuffer.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/helpers/LoggerUtils.h ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/helpers/OptionsParser.h ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/helpers/Timer.h ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/helpers/solver_utils.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/helpers/AreaParser.h ${CMAKE_CURRENT_SOURCE_DIR}/solver_utils.cc ) add_library(antaresXpansion::helpers ALIAS helpers) diff --git a/src/cpp/helpers/Clock.cpp b/src/cpp/helpers/Clock.cpp deleted file mode 100644 index af53bc7ce..000000000 --- a/src/cpp/helpers/Clock.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "antares-xpansion/helpers/Clock.h" - -#include -#include - -std::time_t Clock::getTime() { - std::time_t beginTime = std::time(nullptr); - return beginTime; -} - -namespace clock_utils { -std::string timeToStr(const std::time_t &time_p) { - struct tm local_time; - localtime_platform(time_p, local_time); - // localtime_r(&time_p, &local_time); // Compliant - const char *FORMAT = "%d-%m-%Y %H:%M:%S"; - char buffer_l[100]; - strftime(buffer_l, sizeof(buffer_l), FORMAT, &local_time); - std::string strTime_l(buffer_l); - - return strTime_l; -} -} // namespace clock_utils \ No newline at end of file diff --git a/src/cpp/helpers/include/antares-xpansion/helpers/AreaParser.h b/src/cpp/helpers/include/antares-xpansion/helpers/AreaParser.h new file mode 100644 index 000000000..55c049b18 --- /dev/null +++ b/src/cpp/helpers/include/antares-xpansion/helpers/AreaParser.h @@ -0,0 +1,21 @@ +#pragma once +#include +#include +#include + +#include "antares-xpansion/xpansion_interfaces/LogUtils.h" + +struct AreaFileError : LogUtils::XpansionError { + using LogUtils::XpansionError::XpansionError; +}; +struct AreaFileData { + std::string error_message = ""; + std::vector areas; +}; + +struct AreaParser { + static AreaFileData ReadAreaFile(const std::filesystem::path& areaFile); + static std::vector ReadAreaFile( + std::istringstream& areaFileInStringStream); + static std::vector ReadLineByLineArea(std::istream& stream); +}; \ No newline at end of file diff --git a/src/cpp/lpnamer/helper/ProblemGenerationLogger.cpp b/src/cpp/lpnamer/helper/ProblemGenerationLogger.cpp index 7b3fdfd1a..edf65603e 100644 --- a/src/cpp/lpnamer/helper/ProblemGenerationLogger.cpp +++ b/src/cpp/lpnamer/helper/ProblemGenerationLogger.cpp @@ -1,6 +1,6 @@ #include "antares-xpansion/lpnamer/helper/ProblemGenerationLogger.h" -#include "antares-xpansion/helpers/Clock.h" +#include "antares-xpansion/xpansion_interfaces/Clock.h" namespace ProblemGenerationLog { ProblemGenerationFileLogger::ProblemGenerationFileLogger( @@ -19,6 +19,13 @@ void ProblemGenerationFileLogger::display_message(const std::string& message) { logFile_.flush(); } +void ProblemGenerationFileLogger::display_message( + const std::string& message, const LogUtils::LOGLEVEL log_level, + const std::string& context) { + logFile_ << PrefixMessage(log_level, context) << message << std::endl; + logFile_.flush(); +} + std::ostream& ProblemGenerationFileLogger::GetOstreamObject() { return logFile_; } @@ -40,6 +47,12 @@ void ProblemGenerationOstreamLogger::display_message( stream_ << message << std::endl; } +void ProblemGenerationOstreamLogger::display_message( + const std::string& message, const LogUtils::LOGLEVEL log_level, + const std::string& context) { + stream_ << PrefixMessage(log_level, context) << message << std::endl; +} + void ProblemGenerationOstreamLogger::PrintIterationSeparatorBegin() {} void ProblemGenerationOstreamLogger::PrintIterationSeparatorEnd() {} std::ostream& ProblemGenerationOstreamLogger::GetOstreamObject() { @@ -57,10 +70,10 @@ void ProblemGenerationLogger::display_message(const std::string& message) { } } void ProblemGenerationLogger::display_message( - const std::string& message, const LogUtils::LOGLEVEL log_level) { + const std::string& message, const LogUtils::LOGLEVEL log_level, + const std::string& context) { for (const auto& logger : enabled_loggers_) { - logger->display_message(LogUtils::LogLevelToStr(log_level)); - logger->display_message(message); + logger->display_message(message, log_level, context); } } @@ -104,6 +117,9 @@ ProblemGenerationLogger& ProblemGenerationLogger::operator<<( } return *this; } +const std::string& ProblemGenerationLogger::getContext() const { + return context_; +} ProblemGenerationLoggerSharedPointer BuildLogger( const std::filesystem::path& log_file_path, std::ostream& stream, diff --git a/src/cpp/lpnamer/helper/include/antares-xpansion/lpnamer/helper/ProblemGenerationLogger.h b/src/cpp/lpnamer/helper/include/antares-xpansion/lpnamer/helper/ProblemGenerationLogger.h index a15af1dc4..3de18e30a 100644 --- a/src/cpp/lpnamer/helper/include/antares-xpansion/lpnamer/helper/ProblemGenerationLogger.h +++ b/src/cpp/lpnamer/helper/include/antares-xpansion/lpnamer/helper/ProblemGenerationLogger.h @@ -12,8 +12,7 @@ #include #include "antares-xpansion/xpansion_interfaces/ILogger.h" -#include "antares-xpansion/xpansion_interfaces/LogUtils.h" -#include "antares-xpansion/helpers/LoggerUtils.h" +#include "antares-xpansion/xpansion_interfaces/LoggerUtils.h" namespace ProblemGenerationLog { @@ -21,6 +20,8 @@ class ProblemGenerationILogger : public ILoggerXpansion { public: ~ProblemGenerationILogger() override = default; void display_message(const std::string& message) override = 0; + void display_message(const std::string& str, LogUtils::LOGLEVEL level, + const std::string& context) override = 0; void PrintIterationSeparatorBegin() override = 0; void PrintIterationSeparatorEnd() override = 0; @@ -45,6 +46,9 @@ class ProblemGenerationFileLogger : public ProblemGenerationILogger { explicit ProblemGenerationFileLogger( const std::filesystem::path& logFilePath); void display_message(const std::string& message) override; + void display_message(const std::string& message, + const LogUtils::LOGLEVEL log_level, + const std::string& context) override; void PrintIterationSeparatorBegin() override; void PrintIterationSeparatorEnd() override; std::ostream& GetOstreamObject() override; @@ -58,6 +62,9 @@ class ProblemGenerationOstreamLogger : public ProblemGenerationILogger { ~ProblemGenerationOstreamLogger() override = default; explicit ProblemGenerationOstreamLogger(std::ostream& stream); void display_message(const std::string& message) override; + void display_message(const std::string& message, + const LogUtils::LOGLEVEL log_level, + const std::string& context) override; void PrintIterationSeparatorBegin() override; void PrintIterationSeparatorEnd() override; std::ostream& GetOstreamObject() override; @@ -78,14 +85,15 @@ class ProblemGenerationLogger : public ILoggerXpansion { ~ProblemGenerationLogger() = default; void AddLogger(const ProblemGenerationILoggerSharedPointer& logger); - void display_message(const std::string& message); + void display_message(const std::string& message) override; void display_message(const std::string& message, - const LogUtils::LOGLEVEL log_level); + const LogUtils::LOGLEVEL log_level, + const std::string& context) override; void PrintIterationSeparatorBegin() override; void PrintIterationSeparatorEnd() override; void setLogLevel(const LogUtils::LOGLEVEL log_level); void setContext(const std::string& context) { context_ = context; } - + const std::string& getContext() const; ProblemGenerationLogger& operator()(const LogUtils::LOGLEVEL log_level) { return (*this) << log_level; } diff --git a/src/cpp/lpnamer/input_reader/CandidatesINIReader.cpp b/src/cpp/lpnamer/input_reader/CandidatesINIReader.cpp index d8a5b561a..d7f07c1ab 100644 --- a/src/cpp/lpnamer/input_reader/CandidatesINIReader.cpp +++ b/src/cpp/lpnamer/input_reader/CandidatesINIReader.cpp @@ -4,6 +4,7 @@ #include +#include "antares-xpansion/helpers/AreaParser.h" #include "antares-xpansion/lpnamer/input_reader/INIReader.h" #include "antares-xpansion/xpansion_interfaces/LogUtils.h" #include "antares-xpansion/xpansion_interfaces/StringManip.h" @@ -14,7 +15,9 @@ CandidatesINIReader::CandidatesINIReader( ProblemGenerationLog::ProblemGenerationLoggerSharedPointer logger) : logger_(logger) { _intercoFileData = ReadAntaresIntercoFile(antaresIntercoFile); - _areaNames = ReadAreaFile(areaFile); + + ProcessAreaFile(areaFile); + for (auto const &intercoFileData : _intercoFileData) { // TODO : check if index is available in areaNames std::string const &pays_or(_areaNames[intercoFileData.index_pays_origine]); @@ -24,6 +27,16 @@ CandidatesINIReader::CandidatesINIReader( _intercoIndexMap[linkName] = intercoFileData.index_interco; } } +void CandidatesINIReader::ProcessAreaFile( + const std::filesystem::path &areaFile) { + const auto areaFileData = AreaParser::ReadAreaFile(areaFile); + if (const auto &msg = areaFileData.error_message; !msg.empty()) { + (*logger_)(LogUtils::LOGLEVEL::FATAL) << msg; + throw AreaFileError( + PrefixMessage(LogUtils::LOGLEVEL::FATAL, logger_->getContext()), msg); + } + _areaNames = areaFileData.areas; +} std::vector CandidatesINIReader::ReadAntaresIntercoFile( const std::filesystem::path &antaresIntercoFile) const { @@ -63,35 +76,6 @@ std::vector CandidatesINIReader::ReadLineByLineInterco( return result; } -std::vector CandidatesINIReader::ReadAreaFile( - const std::filesystem::path &areaFile) const { - std::ifstream area_filestream(areaFile); - if (!area_filestream.good()) { - (*logger_)(LogUtils::LOGLEVEL::FATAL) - << LOGLOCATION << "unable to open " << areaFile.string(); - std::exit(1); - } - - return ReadLineByLineArea(area_filestream); -} - -std::vector CandidatesINIReader::ReadAreaFile( - std::istringstream &areaFileInStringStream) const { - return ReadLineByLineArea(areaFileInStringStream); -} - -std::vector CandidatesINIReader::ReadLineByLineArea( - std::istream &stream) const { - std::vector result; - - std::string line; - while (std::getline(stream, line)) { - if (!line.empty() && line.front() != '#') { - result.push_back(StringManip::StringUtils::ToLowercase(line)); - } - } - return result; -} std::string getStrVal(const INIReader &reader, const std::string §ionName, const std::string &key) { diff --git a/src/cpp/lpnamer/input_reader/include/antares-xpansion/lpnamer/input_reader/CandidatesINIReader.h b/src/cpp/lpnamer/input_reader/include/antares-xpansion/lpnamer/input_reader/CandidatesINIReader.h index fb10534e8..79f60e44b 100644 --- a/src/cpp/lpnamer/input_reader/include/antares-xpansion/lpnamer/input_reader/CandidatesINIReader.h +++ b/src/cpp/lpnamer/input_reader/include/antares-xpansion/lpnamer/input_reader/CandidatesINIReader.h @@ -31,13 +31,9 @@ class CandidatesINIReader { const std::filesystem::path& antaresIntercoFile) const; std::vector ReadAntaresIntercoFile( std::istringstream& antaresIntercoFileInStringStream) const; - std::vector ReadAreaFile( - const std::filesystem::path& areaFile) const; - std::vector ReadAreaFile( - std::istringstream& areaFileInStringStream) const; + std::vector ReadLineByLineInterco( std::istream& stream) const; - std::vector ReadLineByLineArea(std::istream& stream) const; std::vector readCandidateData( const std::filesystem::path& candidateFile) const; @@ -57,6 +53,7 @@ class CandidatesINIReader { std::vector _intercoFileData; std::vector _areaNames; ProblemGenerationLog::ProblemGenerationLoggerSharedPointer logger_; + void ProcessAreaFile(const std::filesystem::path& areaFile); }; #endif // ANTARESXPANSION_CANDIDATESINIREADER_H diff --git a/src/cpp/xpansion_interfaces/CMakeLists.txt b/src/cpp/xpansion_interfaces/CMakeLists.txt index e5ec3f9c9..7e3a0744e 100644 --- a/src/cpp/xpansion_interfaces/CMakeLists.txt +++ b/src/cpp/xpansion_interfaces/CMakeLists.txt @@ -14,6 +14,7 @@ target_sources(xpansion_interfaces ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/xpansion_interfaces/LogUtils.h ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/xpansion_interfaces/OutputWriter.h ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/xpansion_interfaces/StringManip.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/antares-xpansion/xpansion_interfaces/Clock.h ) target_include_directories(xpansion_interfaces INTERFACE diff --git a/src/cpp/helpers/include/antares-xpansion/helpers/Clock.h b/src/cpp/xpansion_interfaces/include/antares-xpansion/xpansion_interfaces/Clock.h similarity index 50% rename from src/cpp/helpers/include/antares-xpansion/helpers/Clock.h rename to src/cpp/xpansion_interfaces/include/antares-xpansion/xpansion_interfaces/Clock.h index e9e13a667..5ce76db06 100644 --- a/src/cpp/helpers/include/antares-xpansion/helpers/Clock.h +++ b/src/cpp/xpansion_interfaces/include/antares-xpansion/xpansion_interfaces/Clock.h @@ -9,7 +9,10 @@ class Clock { Clock() = default; virtual ~Clock() = default; - virtual std::time_t getTime(); + virtual std::time_t getTime() { + std::time_t beginTime = std::time(nullptr); + return beginTime; + } }; inline void localtime_platform(const std::time_t &time_p, @@ -21,5 +24,15 @@ inline void localtime_platform(const std::time_t &time_p, #endif } namespace clock_utils { -std::string timeToStr(const std::time_t &time_p); +inline std::string timeToStr(const std::time_t &time_p) { + struct tm local_time; + localtime_platform(time_p, local_time); + // localtime_r(&time_p, &local_time); // Compliant + const char *FORMAT = "%d-%m-%Y %H:%M:%S"; + char buffer_l[100]; + strftime(buffer_l, sizeof(buffer_l), FORMAT, &local_time); + std::string strTime_l(buffer_l); + + return strTime_l; +} } \ No newline at end of file diff --git a/src/cpp/xpansion_interfaces/include/antares-xpansion/xpansion_interfaces/ILogger.h b/src/cpp/xpansion_interfaces/include/antares-xpansion/xpansion_interfaces/ILogger.h index 7d7cc1eb9..eb6ef698c 100644 --- a/src/cpp/xpansion_interfaces/include/antares-xpansion/xpansion_interfaces/ILogger.h +++ b/src/cpp/xpansion_interfaces/include/antares-xpansion/xpansion_interfaces/ILogger.h @@ -85,6 +85,10 @@ struct ILoggerXpansion { void display_message(const std::ostringstream &msg) { display_message(msg.str()); } + + virtual void display_message(const std::string &msg, LogUtils::LOGLEVEL level, + const std::string &context) = 0; + virtual void PrintIterationSeparatorBegin() = 0; virtual void PrintIterationSeparatorEnd() = 0; virtual ~ILoggerXpansion() = default; @@ -95,6 +99,9 @@ struct ILoggerXpansion { */ struct EmptyLogger : public ILoggerXpansion { void display_message(const std::string &str) override {} + void display_message(const std::string &str, LogUtils::LOGLEVEL level, + const std::string &context) override {} + void PrintIterationSeparatorBegin() override {}; void PrintIterationSeparatorEnd() override {}; virtual ~EmptyLogger() {} @@ -125,6 +132,12 @@ struct BendersLoggerBase : public ILoggerXpansion { logger->PrintIterationSeparatorEnd(); } } + virtual void display_message(const std::string &msg, LogUtils::LOGLEVEL level, + const std::string &context) override { + for (auto logger : loggers) { + logger->display_message(msg, level, context); + } + } private: std::vector> loggers; @@ -139,8 +152,8 @@ class ILogger : public ILoggerXpansion { virtual ~ILogger() = default; virtual void display_message(const std::string &str) = 0; - virtual void display_message(const std::string &str, - LogUtils::LOGLEVEL level) = 0; + virtual void display_message(const std::string &str, LogUtils::LOGLEVEL level, + const std::string &context) = 0; virtual void PrintIterationSeparatorBegin() = 0; virtual void PrintIterationSeparatorEnd() = 0; virtual void log_at_initialization(const int it_number) = 0; diff --git a/src/cpp/helpers/include/antares-xpansion/helpers/LoggerUtils.h b/src/cpp/xpansion_interfaces/include/antares-xpansion/xpansion_interfaces/LoggerUtils.h similarity index 85% rename from src/cpp/helpers/include/antares-xpansion/helpers/LoggerUtils.h rename to src/cpp/xpansion_interfaces/include/antares-xpansion/xpansion_interfaces/LoggerUtils.h index e66ed0d70..1d390d8a8 100644 --- a/src/cpp/helpers/include/antares-xpansion/helpers/LoggerUtils.h +++ b/src/cpp/xpansion_interfaces/include/antares-xpansion/xpansion_interfaces/LoggerUtils.h @@ -1,5 +1,5 @@ #pragma once -#include "Clock.h" +#include "antares-xpansion/xpansion_interfaces/Clock.h" #include "antares-xpansion/xpansion_interfaces/LogUtils.h" inline std::string PrefixMessage(const LogUtils::LOGLEVEL &log_level, diff --git a/src/python/antares_xpansion/config_loader.py b/src/python/antares_xpansion/config_loader.py index 85efacb7c..6b81f31d2 100644 --- a/src/python/antares_xpansion/config_loader.py +++ b/src/python/antares_xpansion/config_loader.py @@ -396,11 +396,17 @@ def simulation_output_path(self) -> Path: return self._last_study def benders_pre_actions(self): + self.copy_area_file_to_lpdir() self.save_launcher_options() if self._config.step != "resume": # expansion dir alaready in resume mode self.create_expansion_dir() self._set_options_for_benders_solver() + def copy_area_file_to_lpdir(self): + area_file = self.xpansion_simulation_output() / "area.txt" + if area_file.exists(): + shutil.copy(area_file, self._simulation_lp_path()) + def save_launcher_options(self): options = {} options[LauncherOptionsKeys.method_key()] = self.method() @@ -495,6 +501,9 @@ def _set_options_for_benders_solver(self): options_values[OptimisationKeys.outer_loop_option_file_key()] = ( self._config.OUTER_LOOP_FILE ) + options_values[OptimisationKeys.area_file_key()] = ( + self._config.AREA_FILE + ) if os.path.exists(self.outer_loop_options_path()): shutil.copy(self.outer_loop_options_path(), self._simulation_lp_path()) diff --git a/src/python/antares_xpansion/optimisation_keys.py b/src/python/antares_xpansion/optimisation_keys.py index f2f8e33e1..c299254de 100644 --- a/src/python/antares_xpansion/optimisation_keys.py +++ b/src/python/antares_xpansion/optimisation_keys.py @@ -107,3 +107,6 @@ def do_outer_loop_key(): def outer_loop_option_file_key(): return "OUTER_LOOP_OPTION_FILE" + @staticmethod + def area_file_key(): + return "AREA_FILE" diff --git a/src/python/antares_xpansion/xpansionConfig.py b/src/python/antares_xpansion/xpansionConfig.py index 2cdc91e2a..6999d136a 100644 --- a/src/python/antares_xpansion/xpansionConfig.py +++ b/src/python/antares_xpansion/xpansionConfig.py @@ -150,6 +150,7 @@ def _set_constants(self): self.CONSTRAINTS = "constraints" self.OUTER_LOOP_FILE = "adequacy_criterion.yml" self.OUTER_LOOP_DIR = "adequacy_criterion" + self.AREA_FILE = "area.txt" def _set_default_settings(self): self.settings_default = { diff --git a/tests/cpp/TestDoubles/LoggerStub.h b/tests/cpp/TestDoubles/LoggerStub.h index 6b118ac7f..db92981e2 100644 --- a/tests/cpp/TestDoubles/LoggerStub.h +++ b/tests/cpp/TestDoubles/LoggerStub.h @@ -9,8 +9,8 @@ class LoggerNOOPStub : public ILogger { public: void display_message(const std::string& str) override {} - void display_message(const std::string& str, - LogUtils::LOGLEVEL level) override {} + void display_message(const std::string& str, LogUtils::LOGLEVEL level, + const std::string& context) override {} void PrintIterationSeparatorBegin() override { // } diff --git a/tests/cpp/logger/logger_test.cpp b/tests/cpp/logger/logger_test.cpp index 8aeba4891..662c1220e 100644 --- a/tests/cpp/logger/logger_test.cpp +++ b/tests/cpp/logger/logger_test.cpp @@ -567,7 +567,8 @@ class SimpleLoggerMock : public ILogger { } void display_message(const std::string& str) { _displaymessage = str; } - void display_message(const std::string& str, LogUtils::LOGLEVEL level) { + void display_message(const std::string& str, LogUtils::LOGLEVEL level, + const std::string& context) { _displaymessage = str; } diff --git a/tests/cpp/lp_namer/CandidatesINIReaderTest.cpp b/tests/cpp/lp_namer/CandidatesINIReaderTest.cpp index 6ab91e1b4..60f462387 100644 --- a/tests/cpp/lp_namer/CandidatesINIReaderTest.cpp +++ b/tests/cpp/lp_namer/CandidatesINIReaderTest.cpp @@ -1,8 +1,9 @@ #include -#include "antares-xpansion/lpnamer/input_reader/CandidatesINIReader.h" #include "LoggerBuilder.h" +#include "antares-xpansion/helpers/AreaParser.h" #include "antares-xpansion/lpnamer/helper/ProblemGenerationLogger.h" +#include "antares-xpansion/lpnamer/input_reader/CandidatesINIReader.h" #include "gtest/gtest.h" const std::string interco_content_l = @@ -104,9 +105,9 @@ TEST_F(CandidatesINIReaderTest, testReadIntero) { } TEST_F(CandidatesINIReaderTest, testReadArea) { - std::vector areaList = - CandidatesINIReader(emptyLogger_).ReadAreaFile("temp_area.txt"); + const auto areaFileData = AreaParser::ReadAreaFile("temp_area.txt"); + const auto& areaList = areaFileData.areas; ASSERT_EQ(areaList[0], "area1"); ASSERT_EQ(areaList[1], "area2"); ASSERT_EQ(areaList[2], "flex");