Refactor library folders
Add paginators per output type in b_manage
This commit is contained in:
98
src/results/Result.cpp
Normal file
98
src/results/Result.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include "best/BestScore.h"
|
||||
#include "common/Colors.h"
|
||||
#include "common/DotEnv.h"
|
||||
#include "common/CLocale.h"
|
||||
#include "common/Paths.h"
|
||||
#include "Result.h"
|
||||
|
||||
namespace platform {
|
||||
std::string get_actual_date()
|
||||
{
|
||||
time_t rawtime;
|
||||
tm* timeinfo;
|
||||
time(&rawtime);
|
||||
timeinfo = std::localtime(&rawtime);
|
||||
std::ostringstream oss;
|
||||
oss << std::put_time(timeinfo, "%Y-%m-%d");
|
||||
return oss.str();
|
||||
}
|
||||
std::string get_actual_time()
|
||||
{
|
||||
time_t rawtime;
|
||||
tm* timeinfo;
|
||||
time(&rawtime);
|
||||
timeinfo = std::localtime(&rawtime);
|
||||
std::ostringstream oss;
|
||||
oss << std::put_time(timeinfo, "%H:%M:%S");
|
||||
return oss.str();
|
||||
}
|
||||
Result::Result()
|
||||
{
|
||||
data["date"] = get_actual_date();
|
||||
data["time"] = get_actual_time();
|
||||
data["results"] = json::array();
|
||||
data["seeds"] = json::array();
|
||||
}
|
||||
|
||||
Result& Result::load(const std::string& path, const std::string& fileName)
|
||||
{
|
||||
std::ifstream resultData(path + "/" + fileName);
|
||||
if (resultData.is_open()) {
|
||||
data = json::parse(resultData);
|
||||
} else {
|
||||
throw std::invalid_argument("Unable to open result file. [" + path + "/" + fileName + "]");
|
||||
}
|
||||
score = 0;
|
||||
for (const auto& result : data["results"]) {
|
||||
score += result["score"].get<double>();
|
||||
}
|
||||
auto scoreName = data["score_name"];
|
||||
auto best = BestScore::getScore(scoreName);
|
||||
if (best.first != "") {
|
||||
score /= best.second;
|
||||
}
|
||||
complete = data["results"].size() > 1;
|
||||
return *this;
|
||||
}
|
||||
json Result::getJson()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
void Result::save()
|
||||
{
|
||||
std::ofstream file(Paths::results() + "/" + getFilename());
|
||||
file << data;
|
||||
file.close();
|
||||
}
|
||||
std::string Result::getFilename() const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "results_" << data.at("score_name").get<std::string>() << "_" << data.at("model").get<std::string>() << "_"
|
||||
<< data.at("platform").get<std::string>() << "_" << data["date"].get<std::string>() << "_"
|
||||
<< data["time"].get<std::string>() << "_" << (data["stratified"] ? "1" : "0") << ".json";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
|
||||
std::string Result::to_string(int maxModel) const
|
||||
{
|
||||
auto tmp = ConfigLocale();
|
||||
std::stringstream oss;
|
||||
auto duration = data["duration"].get<double>();
|
||||
double durationShow = duration > 3600 ? duration / 3600 : duration > 60 ? duration / 60 : duration;
|
||||
std::string durationUnit = duration > 3600 ? "h" : duration > 60 ? "m" : "s";
|
||||
oss << data["date"].get<std::string>() << " ";
|
||||
oss << std::setw(maxModel) << std::left << data["model"].get<std::string>() << " ";
|
||||
oss << std::setw(10) << std::left << data["score_name"].get<std::string>() << " ";
|
||||
oss << std::right << std::setw(9) << std::setprecision(7) << std::fixed << score << " ";
|
||||
auto completeString = isComplete() ? "C" : "P";
|
||||
oss << std::setw(1) << " " << completeString << " ";
|
||||
oss << std::setw(5) << std::setprecision(2) << std::fixed << durationShow << " " << durationUnit << " ";
|
||||
oss << std::setw(50) << std::left << data["title"].get<std::string>() << " ";
|
||||
return oss.str();
|
||||
}
|
||||
}
|
52
src/results/Result.h
Normal file
52
src/results/Result.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "common/Timer.h"
|
||||
#include "main/HyperParameters.h"
|
||||
#include "main/PartialResult.h"
|
||||
|
||||
namespace platform {
|
||||
using json = nlohmann::json;
|
||||
|
||||
class Result {
|
||||
public:
|
||||
Result();
|
||||
Result& load(const std::string& path, const std::string& filename);
|
||||
void save();
|
||||
// Getters
|
||||
json getJson();
|
||||
std::string to_string(int maxModel) const;
|
||||
std::string getFilename() const;
|
||||
std::string getDate() const { return data["date"].get<std::string>(); };
|
||||
std::string getTime() const { return data["time"].get<std::string>(); };
|
||||
double getScore() const { return score; };
|
||||
std::string getTitle() const { return data["title"].get<std::string>(); };
|
||||
double getDuration() const { return data["duration"]; };
|
||||
std::string getModel() const { return data["model"].get<std::string>(); };
|
||||
std::string getScoreName() const { return data["score_name"].get<std::string>(); };
|
||||
bool isComplete() const { return complete; };
|
||||
json getData() const { return data; }
|
||||
// Setters
|
||||
void setTitle(const std::string& title) { data["title"] = title; };
|
||||
void setLanguage(const std::string& language) { data["language"] = language; };
|
||||
void setLanguageVersion(const std::string& language_version) { data["language_version"] = language_version; };
|
||||
void setDuration(double duration) { data["duration"] = duration; };
|
||||
void setModel(const std::string& model) { data["model"] = model; };
|
||||
void setModelVersion(const std::string& model_version) { data["version"] = model_version; };
|
||||
void setScoreName(const std::string& scoreName) { data["score_name"] = scoreName; };
|
||||
void setDiscretized(bool discretized) { data["discretized"] = discretized; };
|
||||
void addSeed(int seed) { data["seeds"].push_back(seed); };
|
||||
void addPartial(PartialResult& partial_result) { data["results"].push_back(partial_result.getJson()); };
|
||||
void setStratified(bool stratified) { data["stratified"] = stratified; };
|
||||
void setNFolds(int nfolds) { data["folds"] = nfolds; };
|
||||
void setPlatform(const std::string& platform_name) { data["platform"] = platform_name; };
|
||||
|
||||
private:
|
||||
json data;
|
||||
bool complete;
|
||||
double score = 0.0;
|
||||
};
|
||||
};
|
57
src/results/ResultsDataset.cpp
Normal file
57
src/results/ResultsDataset.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#include <algorithm>
|
||||
#include "common/Paths.h"
|
||||
#include "ResultsDataset.h"
|
||||
|
||||
namespace platform {
|
||||
ResultsDataset::ResultsDataset(const std::string& dataset, const std::string& model, const std::string& score) :
|
||||
path(Paths::results()), dataset(dataset), model(model), scoreName(score), maxModel(0), maxFile(0), maxHyper(15), maxResult(0)
|
||||
{
|
||||
}
|
||||
void ResultsDataset::load()
|
||||
{
|
||||
using std::filesystem::directory_iterator;
|
||||
for (const auto& file : directory_iterator(path)) {
|
||||
auto filename = file.path().filename().string();
|
||||
if (filename.find(".json") != std::string::npos && filename.find("results_") == 0) {
|
||||
auto result = Result();
|
||||
result.load(path, filename);
|
||||
if (model != "any" && result.getModel() != model)
|
||||
continue;
|
||||
auto data = result.getData()["results"];
|
||||
for (auto const& item : data) {
|
||||
if (item["dataset"] == dataset) {
|
||||
auto hyper_length = item["hyperparameters"].dump().size();
|
||||
if (hyper_length > maxHyper)
|
||||
maxHyper = hyper_length;
|
||||
if (item["score"].get<double>() > maxResult)
|
||||
maxResult = item["score"].get<double>();
|
||||
files.push_back(result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
maxModel = std::max(size_t(5), (*max_element(files.begin(), files.end(), [](const Result& a, const Result& b) { return a.getModel().size() < b.getModel().size(); })).getModel().size());
|
||||
maxFile = std::max(size_t(4), (*max_element(files.begin(), files.end(), [](const Result& a, const Result& b) { return a.getFilename().size() < b.getFilename().size(); })).getFilename().size());
|
||||
}
|
||||
int ResultsDataset::size() const
|
||||
{
|
||||
return files.size();
|
||||
}
|
||||
void ResultsDataset::sortModel()
|
||||
{
|
||||
sort(files.begin(), files.end(), [](const Result& a, const Result& b) {
|
||||
if (a.getModel() == b.getModel()) {
|
||||
if (a.getDate() == b.getDate()) {
|
||||
return a.getTime() > b.getTime();
|
||||
}
|
||||
return a.getDate() > b.getDate();
|
||||
}
|
||||
return a.getModel() < b.getModel();
|
||||
});
|
||||
}
|
||||
bool ResultsDataset::empty() const
|
||||
{
|
||||
return files.empty();
|
||||
}
|
||||
}
|
34
src/results/ResultsDataset.h
Normal file
34
src/results/ResultsDataset.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "results/Result.h"
|
||||
namespace platform {
|
||||
using json = nlohmann::json;
|
||||
class ResultsDataset {
|
||||
public:
|
||||
ResultsDataset(const std::string& dataset, const std::string& model, const std::string& score);
|
||||
void load(); // Loads the list of results
|
||||
void sortModel();
|
||||
int maxModelSize() const { return maxModel; };
|
||||
int maxFileSize() const { return maxFile; };
|
||||
int maxHyperSize() const { return maxHyper; };
|
||||
double maxResultScore() const { return maxResult; };
|
||||
int size() const;
|
||||
bool empty() const;
|
||||
std::vector<Result>::iterator begin() { return files.begin(); };
|
||||
std::vector<Result>::iterator end() { return files.end(); };
|
||||
Result& at(int index) { return files.at(index); };
|
||||
private:
|
||||
std::string path;
|
||||
std::string dataset;
|
||||
std::string model;
|
||||
std::string scoreName;
|
||||
int maxModel;
|
||||
int maxFile;
|
||||
int maxHyper;
|
||||
double maxResult;
|
||||
std::vector<Result> files;
|
||||
};
|
||||
};
|
95
src/results/ResultsDatasetConsole.hpp
Normal file
95
src/results/ResultsDatasetConsole.hpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#pragma once
|
||||
|
||||
#include <locale>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "common/Colors.h"
|
||||
#include "results/ResultsDataset.h"
|
||||
|
||||
namespace platform {
|
||||
class ResultsDatasetsConsole {
|
||||
public:
|
||||
ResultsDatasetsConsole() = default;
|
||||
~ResultsDatasetsConsole() = default;
|
||||
std::string getOutput() const { return output.str(); }
|
||||
int getNumLines() const { return numLines; }
|
||||
json& getData() { return data; }
|
||||
void list_results(const std::string& dataset, const std::string& score, const std::string& model)
|
||||
{
|
||||
auto results = platform::ResultsDataset(dataset, model, score);
|
||||
results.load();
|
||||
results.sortModel();
|
||||
if (results.empty()) {
|
||||
std::cerr << Colors::RED() << "No results found for dataset " << dataset << " and model " << model << Colors::RESET() << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
int maxModel = results.maxModelSize();
|
||||
int maxHyper = results.maxHyperSize();
|
||||
double maxResult = results.maxResultScore();
|
||||
// Build data for the Report
|
||||
json data = json::object();
|
||||
data["results"] = json::array();
|
||||
data["max_models"] = json::object(); // Max score per model
|
||||
for (const auto& result : results) {
|
||||
auto results = result.getData();
|
||||
if (!data["max_models"].contains(result.getModel())) {
|
||||
data["max_models"][result.getModel()] = 0;
|
||||
}
|
||||
for (const auto& item : results["results"]) {
|
||||
if (item["dataset"] == dataset) {
|
||||
|
||||
// Store data for Excel report
|
||||
json res = json::object();
|
||||
res["date"] = result.getDate();
|
||||
res["time"] = result.getTime();
|
||||
res["model"] = result.getModel();
|
||||
res["score"] = item["score"].get<double>();
|
||||
res["hyperparameters"] = item["hyperparameters"].dump();
|
||||
data["results"].push_back(res);
|
||||
if (item["score"].get<double>() > data["max_models"][result.getModel()]) {
|
||||
data["max_models"][result.getModel()] = item["score"].get<double>();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// List the results
|
||||
//
|
||||
output << Colors::GREEN() << "Results of dataset " << dataset << " - for " << model << " model" << std::endl;
|
||||
output << "There are " << results.size() << " results" << std::endl;
|
||||
output << Colors::GREEN() << " # " << std::setw(maxModel + 1) << std::left << "Model" << "Date Time Score Hyperparameters" << std::endl;
|
||||
output << "=== " << std::string(maxModel, '=') << " ========== ======== =========== " << std::string(maxHyper, '=') << std::endl;
|
||||
numLines = 4;
|
||||
auto i = 0;
|
||||
for (const auto& item : data["results"]) {
|
||||
auto color = (i % 2) ? Colors::BLUE() : Colors::CYAN();
|
||||
auto score = item["score"].get<double>();
|
||||
color = score == data["max_models"][item["model"].get<std::string>()] ? Colors::YELLOW() : color;
|
||||
color = score == maxResult ? Colors::RED() : color;
|
||||
output << color << std::setw(3) << std::fixed << std::right << i++ << " ";
|
||||
output << std::setw(maxModel) << std::left << item["model"].get<std::string>() << " ";
|
||||
output << color << item["date"].get<std::string>() << " ";
|
||||
output << color << item["time"].get<std::string>() << " ";
|
||||
output << std::setw(11) << std::setprecision(9) << std::fixed << score << " ";
|
||||
output << item["hyperparameters"].get<std::string>() << std::endl;
|
||||
numLines++;
|
||||
}
|
||||
data["dataset"] = dataset;
|
||||
data["score"] = score;
|
||||
data["model"] = model;
|
||||
data["lengths"]["maxModel"] = maxModel;
|
||||
data["lengths"]["maxHyper"] = maxHyper;
|
||||
data["maxResult"] = maxResult;
|
||||
}
|
||||
private:
|
||||
std::stringstream output;
|
||||
json data;
|
||||
int numLines = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
58
src/results/ResultsDatasetExcel.cpp
Normal file
58
src/results/ResultsDatasetExcel.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "ResultsDatasetExcel.h"
|
||||
namespace platform {
|
||||
ResultsDatasetExcel::ResultsDatasetExcel()
|
||||
{
|
||||
file_name = "some_results.xlsx";
|
||||
workbook = workbook_new(getFileName().c_str());
|
||||
createFormats();
|
||||
setProperties("Results");
|
||||
}
|
||||
ResultsDatasetExcel::~ResultsDatasetExcel()
|
||||
{
|
||||
workbook_close(workbook);
|
||||
}
|
||||
void ResultsDatasetExcel::report(json& data)
|
||||
{
|
||||
worksheet = workbook_add_worksheet(workbook, data["dataset"].get<std::string>().c_str());
|
||||
// Header
|
||||
std::string title = "Results of dataset " + data["dataset"].get<std::string>() + " - for " + data["model"].get<std::string>() + " model";
|
||||
worksheet_merge_range(worksheet, 0, 0, 0, 5, title.c_str(), styles["headerFirst"]);
|
||||
// Body header
|
||||
row = 2;
|
||||
int col = 0;
|
||||
for (const auto& name : { "Nº", "Model", "Date", "Time", "Score", "Hyperparameters" }) {
|
||||
writeString(row, col++, name, "bodyHeader");
|
||||
}
|
||||
// Body
|
||||
std::string bold = "_bold";
|
||||
double maxResult = data["maxResult"].get<double>();
|
||||
for (const auto& item : data["results"]) {
|
||||
row++;
|
||||
col = 0;
|
||||
std::string style = "";
|
||||
auto score = item["score"].get<double>();
|
||||
if (score == data["max_models"][item["model"].get<std::string>()]) {
|
||||
boldBlue();
|
||||
style = bold;
|
||||
}
|
||||
if (score == maxResult) {
|
||||
boldRed();
|
||||
style = bold;
|
||||
}
|
||||
writeInt(row, col++, row - 3, "ints" + style);
|
||||
writeString(row, col++, item["model"], "text" + style);
|
||||
writeString(row, col++, item["date"], "text" + style);
|
||||
writeString(row, col++, item["time"], "text" + style);
|
||||
writeDouble(row, col++, item["score"], "result" + style);
|
||||
writeString(row, col++, item["hyperparameters"].get<std::string>().c_str(), "text" + style);
|
||||
}
|
||||
// Format columns
|
||||
worksheet_freeze_panes(worksheet, 3, 2);
|
||||
auto modelSize = data["lengths"]["maxModel"].get<int>();
|
||||
auto hyperSize = data["lengths"]["maxHyper"].get<int>();
|
||||
std::vector<int> columns_sizes = { 5, modelSize + 3, 12, 9, 11, hyperSize + 10 };
|
||||
for (int i = 0; i < columns_sizes.size(); ++i) {
|
||||
worksheet_set_column(worksheet, i, i, columns_sizes.at(i), NULL);
|
||||
}
|
||||
}
|
||||
}
|
16
src/results/ResultsDatasetExcel.h
Normal file
16
src/results/ResultsDatasetExcel.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "reports/ExcelFile.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace platform {
|
||||
|
||||
class ResultsDatasetExcel : public ExcelFile {
|
||||
public:
|
||||
ResultsDatasetExcel();
|
||||
~ResultsDatasetExcel();
|
||||
void report(json& data);
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user