Skip to content

Commit

Permalink
[API] Better handling of execution modes (#797)
Browse files Browse the repository at this point in the history
- Properly distinguish between archive, file and study mode
- study mode (using antares lib) not implemented yet
- Code cleanup
- Refactor how to handle mandatory but exclusive parameters. Hopefully
make it easier to add new one in the future
  • Loading branch information
JasonMarechal25 authored May 21, 2024
1 parent 2033c5c commit 50bbe69
Show file tree
Hide file tree
Showing 31 changed files with 495 additions and 169 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
0 0 1
1 0 3
2 0 5
3 1 2
4 1 4
5 2 6
6 2 7
194 changes: 170 additions & 24 deletions src/cpp/lpnamer/input_reader/LpFilesExtractor.cpp
Original file line number Diff line number Diff line change
@@ -1,54 +1,200 @@
#include "LpFilesExtractor.h"

#include <algorithm>
#include <sstream>

#include "ArchiveReader.h"

void LpFilesExtractor::ExtractFiles() const {
auto archive_reader = ArchiveReader(antares_archive_path_);
auto [vect_area_files, vect_interco_files] = getFiles();

checkProperNumberOfAreaFiles(vect_area_files);
produceAreatxtFile(vect_area_files);

checkProperNumberOfIntercoFiles(vect_interco_files);
produceIntercotxtFile(vect_interco_files);
}

/**
* @brief This method is used to get the files from the simulation directory.
*
* The patterns it looks for are "area*.txt" and "interco*.txt".
*
* @return A pair of vectors containing the paths of the files. The first vector contains the paths of the "area*.txt" files and the second vector contains the paths of the "interco*.txt" files.
*/
LpFilesExtractor::areaAndIntercoPaths LpFilesExtractor::getFiles() const{
std::vector<std::filesystem::path> vect_area_files;
std::vector<std::filesystem::path> vect_interco_files;
switch (this->mode_) {
case SimulationInputMode::ARCHIVE: {
return getFilesFromArchive();
}
case SimulationInputMode::ANTARES_API:
[[fallthrough]];
case SimulationInputMode::FILE: {
auto dit = std::filesystem::directory_iterator(this->simulation_dir_);
std::ranges::for_each(
dit, [&vect_area_files, &vect_interco_files](const auto& entry) {
if (entry.path().extension() == ".txt") {
if (entry.path().filename().string().starts_with("area")) {
vect_area_files.push_back(entry.path());
}
if (entry.path().filename().string().starts_with("interco")) {
vect_interco_files.push_back(entry.path());
}
}
});
} break;
case SimulationInputMode::UNKOWN:
throw LogUtils::XpansionError<std::runtime_error>(
"SimulationInputMode is unknown", LOGLOCATION);
default:
throw LogUtils::XpansionError<std::runtime_error>(
"SimulationInputMode is not supported:", LOGLOCATION);
}
return std::pair(vect_area_files, vect_interco_files);
}

/**
* @brief This method is used to extract files from an archive.
*
* The patterns it looks for are "area*.txt", "interco*.txt", and "ts-numbers*". The extracted files are stored in the `xpansion_output_dir_` directory.
*
* @return A pair of vectors containing the paths of the extracted files. The first vector contains the paths of the "area*.txt" files and the second vector contains the paths of the "interco*.txt" files.
*/
LpFilesExtractor::areaAndIntercoPaths LpFilesExtractor::getFilesFromArchive() const {
std::vector<std::filesystem::path> vect_area_files;
std::vector<std::filesystem::path> vect_interco_files;
auto archive_reader = ArchiveReader(this->antares_archive_path_);
archive_reader.Open();
const auto vect_area_files =
archive_reader.ExtractPattern("area*.txt", "", xpansion_output_dir_);
vect_area_files =
archive_reader.ExtractPattern("area*.txt", "", this->xpansion_output_dir_);

vect_interco_files = archive_reader.ExtractPattern("interco*.txt", "",
this->xpansion_output_dir_);

archive_reader.ExtractPattern("ts-numbers*", "", this->xpansion_output_dir_);
return std::pair(vect_area_files, vect_interco_files);
}


/**
* @brief This method checks if the number of area files is correct.
*
* We should have only one file named "area*.txt".
*
* @param vect_area_files
*/
void LpFilesExtractor::checkProperNumberOfAreaFiles(
const std::vector<std::filesystem::path>& vect_area_files) const {
if (auto num_areas_file = vect_area_files.size(); num_areas_file == 0) {
std::ostringstream msg;
auto log_location = LOGLOCATION;
msg << "No area*.txt file found" << std::endl;
(*logger_)(LogUtils::LOGLEVEL::FATAL)
<< log_location << msg.str();
(*this->logger_)(LogUtils::LOGLEVEL::FATAL) << log_location << msg.str();
throw ErrorWithAreaFile(msg.str(), log_location);
} else if (num_areas_file > 1) {
std::ostringstream msg;
auto log_location = LOGLOCATION;
msg << "More than one area*.txt file found" << std::endl;
(*logger_)(LogUtils::LOGLEVEL::FATAL)
<< log_location << msg.str();
(*this->logger_)(LogUtils::LOGLEVEL::FATAL) << log_location << msg.str();
throw ErrorWithAreaFile(msg.str(), log_location);
}
std::filesystem::rename(vect_area_files[0],
xpansion_output_dir_ / "area.txt");
}

const auto vect_interco_files =
archive_reader.ExtractPattern("interco*.txt", "", xpansion_output_dir_);
/**
* @brief This method is used to produce the "area.txt" file from "area*.txt"
*
* In archive mode the file is just rename. Otherwise, the file is copied from
* the simulation directory to the `xpansion_output_dir_` directory.
*
* @param vect_area_files
*/
void LpFilesExtractor::produceAreatxtFile(
const std::vector<std::filesystem::path>& vect_area_files) const {
switch (this->mode_) {
case SimulationInputMode::ANTARES_API:
[[fallthrough]];
case SimulationInputMode::FILE:
try {
std::filesystem::rename(vect_area_files[0],
this->xpansion_output_dir_ / "area.txt");
} catch (const std::filesystem::filesystem_error& e) {
auto log_location = LOGLOCATION;
(*this->logger_)(LogUtils::LOGLEVEL::FATAL) << log_location << e.what();
throw;
}
break;
case SimulationInputMode::ARCHIVE:
std::filesystem::rename(vect_area_files[0],
this->xpansion_output_dir_ / "area.txt");
break;
case SimulationInputMode::UNKOWN:
throw LogUtils::XpansionError<std::runtime_error>(
"SimulationInputMode is unknown", LOGLOCATION);
default:
throw LogUtils::XpansionError<std::runtime_error>(
"SimulationInputMode is not supported:", LOGLOCATION);
}
}

if (auto num_intercos_file = vect_interco_files.size();
num_intercos_file == 0) {
/**
* @brief This method checks if the number of interco files is correct.
*
* We should have only one file named "interco*.txt".
*
* @param vect_interco_files
*/
void LpFilesExtractor::checkProperNumberOfIntercoFiles(
const std::vector<std::filesystem::path>& vect_interco_files) const {
if (auto num_interco_file = vect_interco_files.size();
num_interco_file == 0) {
std::ostringstream msg;
msg << "No interco*.txt file found" << std::endl;
auto log_location = LOGLOCATION;
(*logger_)(LogUtils::LOGLEVEL::FATAL)
<< log_location << msg.str();
(*this->logger_)(LogUtils::LOGLEVEL::FATAL) << log_location << msg.str();
throw ErrorWithIntercosFile(msg.str(), log_location);
} else if (num_intercos_file > 1) {
} else if (num_interco_file > 1) {
std::ostringstream msg;
auto log_location = LOGLOCATION;
msg << "More than one interco*.txt file found" << std::endl;
(*logger_)(LogUtils::LOGLEVEL::FATAL)
<< log_location << msg.str();
(*this->logger_)(LogUtils::LOGLEVEL::FATAL) << log_location << msg.str();
throw ErrorWithIntercosFile(msg.str(), log_location);
}
std::filesystem::rename(vect_interco_files[0],
xpansion_output_dir_ / "interco.txt");
archive_reader.ExtractPattern("ts-numbers*", "", xpansion_output_dir_);
archive_reader.Close();
archive_reader.Delete();
}
}

/**
* @brief This method is used to produce the "interco.txt" file from "interco*.txt"
*
* In archive mode the file is just rename. Otherwise, the file is copied from
* the simulation directory to the `xpansion_output_dir_` directory.
*
* @param vect_interco_files
*/
void LpFilesExtractor::produceIntercotxtFile(
const std::vector<std::filesystem::path>& vect_interco_files) const {
switch (this->mode_) {
case SimulationInputMode::ANTARES_API:
[[fallthrough]];
case SimulationInputMode::FILE:
try {
std::filesystem::rename(vect_interco_files[0],
this->xpansion_output_dir_ / "interco.txt");
} catch (const std::filesystem::filesystem_error& e) {
auto log_location = LOGLOCATION;
(*this->logger_)(LogUtils::LOGLEVEL::FATAL) << log_location << e.what();
throw;
}
break;
case SimulationInputMode::ARCHIVE:
std::filesystem::rename(vect_interco_files[0],
this->xpansion_output_dir_ / "interco.txt");
break;
case SimulationInputMode::UNKOWN:
throw LogUtils::XpansionError<std::runtime_error>(
"SimulationInputMode is unknown", LOGLOCATION);
default:
throw LogUtils::XpansionError<std::runtime_error>(
"SimulationInputMode is not supported:", LOGLOCATION);
}
}
35 changes: 27 additions & 8 deletions src/cpp/lpnamer/input_reader/LpFilesExtractor.h
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
#ifndef SRC_CPP_LPNAMER_INPUTREADER_LP_FILES_EXTRACTOR_H
#define SRC_CPP_LPNAMER_INPUTREADER_LP_FILES_EXTRACTOR_H
#include <filesystem>
#include <utility>

#include "LogUtils.h"
#include "ProblemGenerationLogger.h"
#include "SimulationInputMode.h"

class LpFilesExtractor {
private:
std::filesystem::path antares_archive_path_;
std::filesystem::path xpansion_output_dir_;
const std::filesystem::path antares_archive_path_;
const std::filesystem::path xpansion_output_dir_;
ProblemGenerationLog::ProblemGenerationLoggerSharedPointer logger_;
const SimulationInputMode mode_;
const std::filesystem::path& simulation_dir_;

public:
explicit LpFilesExtractor(
const std::filesystem::path& antares_archive_path,
const std::filesystem::path& xpansion_output_dir,
ProblemGenerationLog::ProblemGenerationLoggerSharedPointer logger)
: antares_archive_path_(antares_archive_path),
xpansion_output_dir_(xpansion_output_dir),
logger_(logger) {}
std::filesystem::path antares_archive_path,
std::filesystem::path xpansion_output_dir,
ProblemGenerationLog::ProblemGenerationLoggerSharedPointer logger,
SimulationInputMode mode = SimulationInputMode::UNKOWN,
const std::filesystem::path& simulation_dir = {})
: antares_archive_path_(std::move(antares_archive_path)),
xpansion_output_dir_(std::move(xpansion_output_dir)),
logger_(std::move(logger)),
mode_(mode),
simulation_dir_(simulation_dir) {}
void ExtractFiles() const;

class ErrorWithAreaFile : public LogUtils::XpansionError<std::runtime_error> {
Expand All @@ -27,5 +35,16 @@ class LpFilesExtractor {
class ErrorWithIntercosFile : public LogUtils::XpansionError<std::runtime_error> {
using LogUtils::XpansionError<std::runtime_error>::XpansionError;
};
private:
using areaAndIntercoPaths = std::pair<std::vector<std::filesystem::path>, std::vector<std::filesystem::path>>;
[[nodiscard]] areaAndIntercoPaths getFiles() const;
[[nodiscard]] areaAndIntercoPaths getFilesFromArchive() const;
void checkProperNumberOfAreaFiles(
const std::vector<std::filesystem::path>& vect_area_files) const;
void produceAreatxtFile(const std::vector<std::filesystem::path>& vect_area_files) const;
void checkProperNumberOfIntercoFiles(
const std::vector<std::filesystem::path>& vect_interco_files) const;
void produceIntercotxtFile(
const std::vector<std::filesystem::path>& vect_interco_files) const;
};
#endif // SRC_CPP_LPNAMER_INPUTREADER_LP_FILES_EXTRACTOR_H
Loading

0 comments on commit 50bbe69

Please sign in to comment.