CbmRoot
Loading...
Searching...
No Matches
/builds/computing/cbmroot/core/qa/CbmQaIO.h

Creates a QA (ROOT) object, using properties defined with a tag in config.

Creates a QA (ROOT) object, using properties defined with a tag in config

Template Parameters
TType of the object
Parameters
sNameName of the object
sTitleTitle of the object
args...The rest of the arguments, which will be passed to the histogram constructor
Note
Tag is defined after the last ';' symbol in the nameBase string

nambeBase = "/stations/station0/xy_occupancy;xy_station0" will be decayed into: 1) subdirectory "stations/station0" 2) name of histogram "catrd_hit_xy_occupancy" 3) tag for configuration file "xy_station0" If configuration file or tag are not defined, default parameters will be used

/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Sergei Zharko [committer] */
#ifndef CbmQaIO_h
#define CbmQaIO_h 1
#include "CbmQaCanvas.h"
#include "CbmQaEff.h"
#include "CbmQaTable.h"
#include "Logger.h"
#include "TCanvas.h"
#include "TEfficiency.h"
#include "TH1.h"
#include "TH2.h"
#include "TH3.h"
#include "TObject.h"
#include "TParameter.h"
#include "TProfile.h"
#include "TProfile2D.h"
#include "TProfile3D.h"
#include "TROOT.h"
#include "TString.h"
#include "yaml/Property.h"
#include "yaml/Yaml.h"
#include <limits>
#include <optional>
#include <type_traits>
#include <vector>
#include <yaml-cpp/yaml.h>
class TFile;
class CbmQaIO {
public:
using ObjList_t = std::vector<std::pair<TObject*, TString>>;
enum class EStoringMode
{
};
CbmQaIO(TString prefixName, std::shared_ptr<ObjList_t> pObjList = nullptr);
virtual ~CbmQaIO();
CbmQaIO(const CbmQaIO&) = delete;
CbmQaIO(CbmQaIO&&) = delete;
CbmQaIO& operator=(const CbmQaIO&) = delete;
CbmQaIO& operator=(CbmQaIO&&) = delete;
const char* GetConfigName() const { return fsConfigName.Data(); }
template<typename T, typename... Args>
T* MakeQaObject(TString sName, TString sTitle, Args... args);
void MakeQaDirectory(TString sName);
void SetConfigName(const char* path);
void SetRootFolderName(const TString& path) { fsRootFolderName = path.Strip(TString::kBoth, '/'); }
void SetStoringMode(EStoringMode mode) { fStoringMode = mode; }
protected:
template<typename T>
void CheckProperty(T&& property, const char* name) const;
template<class Config>
std::optional<Config> ReadSpecificConfig() const
{
std::optional<Config> res = std::nullopt;
const auto& node = fConfigNode["specific"];
if (node) {
res = std::make_optional(cbm::algo::yaml::Read<Config>(node));
}
return res;
}
virtual void SetTH1Properties(TH1* pHist) const;
virtual void SetTH2Properties(TH2* pHist) const;
virtual void SetTProfile2DProperties(TProfile2D* pHist) const;
virtual void SetCanvasProperties(TCanvas* pCanv) const;
void WriteToFile(TFile* pOutFile) const;
TString fsRootFolderName = "";
TString fsConfigName = "";
TString fsPrefix = "";
std::shared_ptr<ObjList_t> fpvObjList = nullptr;
YAML::Node fConfigNode{};
private:
template<typename T, typename... Args>
T* ConstructAndRegisterQaObject(TString name, Args... args);
};
// ---------------------------------------------------------------------------------------------------------------------
//
template<typename T>
void CbmQaIO::CheckProperty(T&& property, const char* name) const
{
bool bPropertyUndefined = false;
if constexpr (std::is_signed_v<T>) {
bPropertyUndefined = property < 0;
}
else if constexpr (std::is_floating_point_v<T>) {
bPropertyUndefined = std::isnan(property);
}
if (bPropertyUndefined) {
std::stringstream msg;
msg << "Property " << name << " is undefined in the configuration file";
throw std::runtime_error(msg.str());
}
}
// ---------------------------------------------------------------------------------------------------------------------
//
template<typename T, typename... Args>
T* CbmQaIO::ConstructAndRegisterQaObject(TString sName, Args... args)
{
if constexpr (std::is_base_of_v<CbmQaTable, T>) {
static_assert(sizeof...(Args) == 3);
}
// Resolve directory name and object name
auto iLastSlashPos = static_cast<int>(sName.Last('/'));
TString sDirectory = TString(sName(0, iLastSlashPos)).Strip(TString::kBoth, '/');
sName = sName(iLastSlashPos + 1, sName.Length() - iLastSlashPos);
// Create a new object
T* pObj = new T(sName.Data(), args...);
// Take object ownership from ROOT
if constexpr (std::is_base_of_v<TH1, T>) { // all kind of histograms
pObj->SetDirectory(nullptr);
}
// apply user-defined properties
if constexpr (std::is_same_v<TH1F, T> || std::is_same_v<TH1D, T> || std::is_same_v<TProfile, T>) { // histograms
}
else if constexpr (std::is_same_v<TH2F, T> || std::is_same_v<TH2D, T>) { // histograms
}
else if constexpr (std::is_same_v<TProfile2D, T>) { // profile 2D
}
else if constexpr (std::is_base_of_v<TCanvas, T>) { // canvases
auto* pListOfCanvases = gROOT->GetListOfCanvases();
if (-1 != pListOfCanvases->IndexOf(pObj)) {
pListOfCanvases->Remove(pObj);
}
}
// Define a "summary" subdirectory of canvases and tables
if constexpr (std::is_base_of_v<CbmQaTable, T> || std::is_base_of_v<TCanvas, T>) {
sDirectory = TString("Summary/") + sDirectory;
}
}
// Add parent directory
if (fsRootFolderName.Length() != 0) {
if (sDirectory.Length() != 0) {
sDirectory = fsRootFolderName + "/" + sDirectory;
}
else {
sDirectory = fsRootFolderName;
}
}
// Register the object in the list
fpvObjList->push_back(std::make_pair(static_cast<TObject*>(pObj), sDirectory));
return pObj;
}
// ---------------------------------------------------------------------------------------------------------------------
//
template<typename T, typename... Args>
T* CbmQaIO::MakeQaObject(TString sName, TString sTitle, Args... args)
{
if constexpr (std::is_base_of_v<CbmQaTable, T>) {
static_assert(sizeof...(Args) == 2);
}
// Resolve configuration tag, if any
auto iLastSepPos = static_cast<int>(sName.Last(';'));
TString sTagName = sName(iLastSepPos + 1, sName.Length() - iLastSepPos);
if (iLastSepPos != -1) {
sName = sName(0, iLastSepPos);
}
bool bUseConfig = false;
// Check, if parameters are provided for this tag
if (fConfigNode) {
if constexpr (std::is_base_of_v<TH1, T>) {
if (fConfigNode["histograms"]) {
if (fConfigNode["histograms"][sTagName.Data()]) {
bUseConfig = true;
}
}
}
else if constexpr (std::is_base_of_v<TCanvas, T>) {
if (fConfigNode["canvases"]) {
if (fConfigNode["canvases"][sTagName.Data()]) {
bUseConfig = true;
}
}
}
}
//LOG(info) << "CbmQaIO: init ROOT object \"" << sName << '\"'; // Debug
const char* title = sTitle.Data();
if (bUseConfig) {
if constexpr (std::is_base_of_v<TH1, T>) {
const auto& tagNode = fConfigNode["histograms"][sTagName.Data()];
[[maybe_unused]] int nBinsX = -1;
[[maybe_unused]] double minX = std::numeric_limits<double>::signaling_NaN();
[[maybe_unused]] double maxX = std::numeric_limits<double>::signaling_NaN();
[[maybe_unused]] int nBinsY = -1;
[[maybe_unused]] double minY = std::numeric_limits<double>::signaling_NaN();
[[maybe_unused]] double maxY = std::numeric_limits<double>::signaling_NaN();
[[maybe_unused]] int nBinsZ = -1;
[[maybe_unused]] double minZ = std::numeric_limits<double>::signaling_NaN();
[[maybe_unused]] double maxZ = std::numeric_limits<double>::signaling_NaN();
if (const auto& axisNode = tagNode["x"]) {
nBinsX = axisNode["nbins"].as<int>();
minX = axisNode["min"].as<double>();
maxX = axisNode["max"].as<double>();
}
if (const auto& axisNode = tagNode["y"]) {
nBinsY = axisNode["nbins"].as<int>();
minY = axisNode["min"].as<double>();
maxY = axisNode["max"].as<double>();
}
if (const auto& axisNode = tagNode["z"]) {
nBinsZ = axisNode["nbins"].as<int>();
minZ = axisNode["min"].as<double>();
maxZ = axisNode["max"].as<double>();
}
if constexpr (std::is_base_of_v<CbmQaTable, T>) {
return ConstructAndRegisterQaObject<T>(sName, title, args...);
}
else if constexpr (std::is_base_of_v<TProfile2D, T>) {
CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
CheckProperty(nBinsY, Form("qa/histograms/%s/y/nbins", sTagName.Data()));
CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data()));
CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data()));
CheckProperty(minZ, Form("qa/histograms/%s/z/min", sTagName.Data()));
CheckProperty(maxZ, Form("qa/histograms/%s/z/max", sTagName.Data()));
return ConstructAndRegisterQaObject<T>(sName, title, nBinsX, minX, maxX, nBinsY, minY, maxY, minZ, maxZ);
}
else if constexpr (std::is_base_of_v<TProfile, T>) {
CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data()));
CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data()));
return ConstructAndRegisterQaObject<T>(sName, title, nBinsX, minX, maxX, minY, maxY);
}
else if constexpr (std::is_base_of_v<TH3, T>) {
CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
CheckProperty(nBinsY, Form("qa/histograms/%s/y/nbins", sTagName.Data()));
CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data()));
CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data()));
CheckProperty(nBinsZ, Form("qa/histograms/%s/z/nbins", sTagName.Data()));
CheckProperty(minZ, Form("qa/histograms/%s/z/min", sTagName.Data()));
CheckProperty(maxZ, Form("qa/histograms/%s/z/max", sTagName.Data()));
return ConstructAndRegisterQaObject<T>(sName, title, nBinsX, minX, maxX, nBinsY, minY, maxY, nBinsZ, minZ,
maxZ);
}
else if constexpr (std::is_base_of_v<TH2, T>) {
CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
CheckProperty(nBinsY, Form("qa/histograms/%s/y/nbins", sTagName.Data()));
CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data()));
CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data()));
return ConstructAndRegisterQaObject<T>(sName, title, nBinsX, minX, maxX, nBinsY, minY, maxY);
}
else if constexpr (std::is_base_of_v<TH1, T>) {
CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
return ConstructAndRegisterQaObject<T>(sName, title, nBinsX, minX, maxX);
}
}
}
return ConstructAndRegisterQaObject<T>(sName, title, args...);
}
#endif // CbmQaIO_h
Definition of the CbmQaCanvas class.
Declaration of CbmQaEff class.
Definition of CbmQaTable class.
ROOT object IO interface for QA.
Definition CbmQaIO.h:44
CbmQaIO & operator=(const CbmQaIO &)=delete
Copy assignment operator.
T * MakeQaObject(TString sName, TString sTitle, Args... args)
Definition CbmQaIO.h:261
virtual void SetTProfile2DProperties(TProfile2D *pHist) const
Applies properties on the profile 2D created with the MakeQaObject function.
Definition CbmQaIO.cxx:67
virtual void SetCanvasProperties(TCanvas *pCanv) const
Applies properties on the canvas created with the MakeQaObject funciton.
Definition CbmQaIO.cxx:84
void SetConfigName(const char *path)
Creates a ROOT object.
Definition CbmQaIO.cxx:95
void WriteToFile(TFile *pOutFile) const
Writes objects into file.
Definition CbmQaIO.cxx:116
YAML::Node fConfigNode
Configuration node.
Definition CbmQaIO.h:164
void MakeQaDirectory(TString sName)
Definition CbmQaIO.cxx:132
virtual void SetTH2Properties(TH2 *pHist) const
Applies properties on the histogram created with the MakeQaObject function.
Definition CbmQaIO.cxx:50
std::optional< Config > ReadSpecificConfig() const
Reads the specific configuration structure from the YAML node.
Definition CbmQaIO.h:127
virtual ~CbmQaIO()
Destructor.
Definition CbmQaIO.cxx:31
TString fsPrefix
Unique prefix for all writeable root.
Definition CbmQaIO.h:159
void SetStoringMode(EStoringMode mode)
Set storing mode.
Definition CbmQaIO.h:112
const char * GetConfigName() const
Gets config name.
Definition CbmQaIO.h:76
virtual void SetTH1Properties(TH1 *pHist) const
Applies properties on the histogram created with the MakeQaObject function.
Definition CbmQaIO.cxx:36
std::shared_ptr< ObjList_t > fpvObjList
List of registered ROOT objects.
Definition CbmQaIO.h:162
CbmQaIO(TString prefixName, std::shared_ptr< ObjList_t > pObjList=nullptr)
Constructor.
Definition CbmQaIO.cxx:19
TString fsRootFolderName
Name of root folder.
Definition CbmQaIO.h:157
EStoringMode
Definition CbmQaIO.h:49
@ kSUBDIR
Objects of different type will be stored in different subdirectories like histograms/ canvases/.
@ kSAMEDIR
Objects of different type will be stored to root directory.
void SetRootFolderName(const TString &path)
Sets a common root path to the objects in the output file.
Definition CbmQaIO.h:109
EStoringMode fStoringMode
Objects storing mode.
Definition CbmQaIO.h:161
void CheckProperty(T &&property, const char *name) const
Function to check, if a property is defined.
Definition CbmQaIO.h:178
T * ConstructAndRegisterQaObject(TString name, Args... args)
Creates and registers a ROOT object.
Definition CbmQaIO.h:198
TString fsConfigName
Name of configuration file.
Definition CbmQaIO.h:158
std::vector< std::pair< TObject *, TString > > ObjList_t
Definition CbmQaIO.h:46
T Read(const YAML::Node &node)
Definition Yaml.h:59