13#include "TDirectory.h"
22#include <yaml-cpp/yaml.h>
55 std::string res =
fvFiles[iFile];
56 res = std::regex_replace(res, std::regex(
"\\%v"),
fvVersionPaths[iVersion]);
57 res = std::regex_replace(res, std::regex(
"\\%d"),
fvDatasets[iDataset]);
67 LOG_IF(fatal, !
GetNofObjects()) <<
"ObjectDB: No objects were passed to the checker";
68 LOG_IF(fatal,
GetNofDatasets() < 1) <<
"ObjectDB: No datasets were found, at least one dataset should be provided";
69 LOG_IF(fatal,
GetNofVersions() < 2) <<
"ObjectDB: File handler should have at least two versions to compare ("
82 std::stringstream msg;
83 msg <<
"ObjectDB: registered default label \"" <<
fsDefaultLabel <<
"\" is not found among the version labels:\n";
85 msg <<
"\t- " << label <<
'\n';
87 LOG(fatal) << msg.str();
93 LOG(warn) <<
"ObjectDB: default version was not registered. Using the first version as the default one (\""
98 for (
size_t iFile = 0; iFile <
fvObjects.size(); ++iFile) {
109 for (
size_t iFile = 1; iFile <=
fvObjects.size(); ++iFile) {
114 auto regexSlashes = std::regex(
"(/+)");
119 path = std::regex_replace(path, regexSlashes,
"/");
130 config = YAML::LoadFile(configName)[
"checker"];
132 catch (
const YAML::BadFile& exc) {
133 LOG(fatal) <<
"ObjectDB: configuration file " << configName <<
" does not exist";
135 catch (
const YAML::ParserException& exc) {
136 LOG(fatal) <<
"ObjectDB: configuration file " << configName <<
" is badly formatted";
140 if (
const auto& node = config[
"files"]) {
142 LOG(warn) <<
"ObjectDB: file-object map was defined before. Redefining it from the config file " << configName;
149 size_t nFiles = node.size();
155 for (
const auto& fileNode : node) {
156 const auto& objectsNode = fileNode[
"objects"];
157 int nObjects = objectsNode ? objectsNode.size() : 0;
158 auto& objectsInFile =
fvObjects.emplace_back();
159 objectsInFile.reserve(nObjects);
161 for (
const auto& objectNode : objectsNode) {
162 objectsInFile.push_back(objectNode.as<std::string>());
165 fvFiles.push_back(fileNode[
"name"].as<std::string>());
166 fvFileLabels.push_back(fileNode[
"label"].as<std::string>());
169 catch (
const YAML::InvalidNode& exc) {
170 LOG(fatal) <<
"ObjectDB: error while reading checker/files node from the config " << configName;
174 LOG(warn) <<
"ObjectDB: node checker/inputformat is not defined in the config " << configName;
178 if (
const auto& node = config[
"datasets"]) {
180 <<
"ObjectDB: dataset names were defined before. Please, use only one initialisation method:"
181 <<
" either configuration file, or setters of the checker::Core class";
184 for (
const auto& datasetNode : node) {
185 fvDatasets.push_back(datasetNode.as<std::string>());
188 catch (
const YAML::InvalidNode& exc) {
189 LOG(fatal) <<
"ObjectDB:: error while reading checker/datasets node from the config " << configName;
193 LOG(warn) <<
"ObjectDB: node checker/datasets is not defined in the config " << configName;
197 if (
const auto& node = config[
"versions"]) {
199 <<
"ObjectDB: dataset names were defined before. Attempt to redefine dataset names from config " << configName;
203 for (
const auto& versionNode : node) {
208 catch (
const YAML::InvalidNode& exc) {
209 LOG(fatal) <<
"ObjectDB:: error while reading checker/versions node from the config " << configName;
213 LOG(warn) <<
"ObjectDB: node checker/versions is not defined in the config " << configName;
217 if (
const auto& node = config[
"default_label"]) {
221 catch (
const YAML::InvalidNode& exc) {
222 LOG(fatal) <<
"ObjectDB:: error while reading checker/default_label node from the config " << configName;
227 if (
const auto& node = config[
"settings"]) {
229 double ratioMin = node[
"ratio_min"].as<
double>(
fRatioMin);
230 double ratioMax = node[
"ratio_max"].as<
double>(
fRatioMax);
233 double pValThresh = node[
"pval_threshold"].as<
double>(
fPvalThresh);
236 catch (
const YAML::InvalidNode& exc) {
237 LOG(fatal) <<
"ObjectDB:: error while reading checker/versions node from the config " << configName;
246 for (
auto&& pKey : *(pDir->GetListOfKeys())) {
247 TString sName = parentPath + pKey->GetName();
248 if (gFile->Get<TH1>(sName)) {
249 paths.insert(sName.Data());
251 else if (
auto* pSubDir = gFile->Get<TDirectory>(sName)) {
262 std::set<std::string> objectPaths;
263 LOG(info) <<
"Reading object list from files: ...";
264 for (
int iDs = 0; iDs < static_cast<int>(
fvDatasets.size()); ++iDs) {
266 LOG(info) <<
"- file: " << fileName;
267 TFile fileIn{fileName,
"READONLY"};
273 fvObjects[iFile].reserve(objectPaths.size());
274 fvObjects[iFile].insert(
fvObjects[iFile].begin(), objectPaths.begin(), objectPaths.end());
275 LOG(info) <<
"Reading object list from files: done";
282 if (pVal <= 0 || pVal >= 1) {
283 LOG(fatal) <<
"ObjectDB::SetPvalThreshold(): p-value threshold runs out the range (0, 1): " << pVal;
292 if (min > max || min < 0) {
293 LOG(fatal) <<
"ObjectDB::SetPvalThreshold(): min and max for ratio run out the range: min = " << min
294 <<
", max = " <<
max;
305 std::stringstream msg;
308 msg <<
" ********************\n";
309 msg <<
" ** CBM QA-Checker **\n";
310 msg <<
" ********************\n\n";
312 msg <<
"\e[1mVersions\e[0m:\n";
321 msg <<
"\e[1mDatasets\e[0m:\n";
323 msg <<
"\t- " << dataset <<
"\n";
325 msg <<
"\e[1mFiles\e[0m:\n";
326 for (
size_t iF = 0; iF <
fvFiles.size(); ++iF) {
329 msg <<
" with objects:\n";
330 for (
const auto&
object :
fvObjects[iF]) {
331 msg <<
"\t\t- " <<
object <<
'\n';
Database for processed objects in the QA checker framework (implementation)
friend fscal max(fscal x, fscal y)
friend fscal min(fscal x, fscal y)
static constexpr size_t size()
A data base class for processed objects.
std::vector< std::string > fvFileLabels
Container of file labels (used in output)
int GetNofObjects() const
Gets total number of objects.
void ReadObjectList(int iFile)
Reads list of histograms from file.
std::string ToString(int verbose=1) const
String representation of the content.
static void CollectObjectPaths(TDirectory *pDir, const TString &parentPah, std::set< std::string > &paths)
Loops over ROOT-file and collects object paths.
std::string GetInputFileName(int iVersion, int iFile, int iDataset) const
Gets name of file from indexes of version, file and dataset.
std::vector< int > fvObjectFirstGlobIndex
First global index of object in a file.
std::vector< std::string > fvVersionPaths
Container of version paths.
void AddDataset(const char *dataset)
Adds dataset.
int GetNofDatasets() const
Gets number of datasets.
std::string fsInputRootPath
Root path for input files.
std::vector< std::vector< std::string > > fvObjects
Container of object names vs file id.
void SetPvalThreshold(double pVal)
Sets P-value threshold.
void Clear()
Clears content.
void SetRatioRange(double min, double max)
Sets ratio accepted range.
std::vector< std::string > fvDatasets
Container of dataset names.
int GetNofVersions() const
Gets number of versions.
std::vector< std::string > fvFiles
Container of file names.
void AddVersion(const char *label, const char *path)
Adds version.
std::vector< std::string > fvVersionLabels
Container of version labels.
double fRatioMin
Lower boundary for ratio deviation.
void SetDefaultLabel(const char *defaultLabel)
Sets default version label.
double fPvalThresh
P-value threshold for histograms equality.
double fRatioMax
Upper boundary for ratio deviation.
void ReadFromYAML(const char *configName)
Reads DB from YAML node.
int fDefVersionID
Index of default version.
void Init()
Initializes the database.
std::string fsDefaultLabel
Name of default version label.
std::string fsOutputPath
Path to the output file.