diff --git a/core/qa/CbmQaIO.cxx b/core/qa/CbmQaIO.cxx index f414c3f2b802755e8ca7fd48b0a9753b5668e191..e09b028a0a256f886a1f73ff399c6437f5ecc3d2 100644 --- a/core/qa/CbmQaIO.cxx +++ b/core/qa/CbmQaIO.cxx @@ -9,30 +9,21 @@ #include "CbmQaIO.h" +#include "TFile.h" + // --------------------------------------------------------------------------------------------------------------------- // -CbmQaIO::CbmQaIO(const char* folderName, const char* prefixName, TFolder* pParentFolder) - : fsRootFolderName(folderName) - , fsPrefix(prefixName) - , fpParentFolder(pParentFolder) +CbmQaIO::CbmQaIO(const char* prefixName, std::shared_ptr<ObjList_t> pObjList) + : fsPrefix(prefixName) + , fpvObjList(pObjList) { - if (fpParentFolder) { fpFolderRoot = fpParentFolder->AddFolder(fsRootFolderName, fsRootFolderName); } - else { - fpFolderRoot = - new TFolder(fsRootFolderName, fsRootFolderName); // The name of the folder follows the name of the task - fpFolderRoot->SetOwner(true); // When true, TFolder owns all added objects - } + if (!fpvObjList.get()) { fpvObjList = std::make_shared<ObjList_t>(); } } // --------------------------------------------------------------------------------------------------------------------- // CbmQaIO::~CbmQaIO() { - // Free memory for fpFolderRoot - if (fpFolderRoot && !fpParentFolder) { - delete fpFolderRoot; - fpFolderRoot = nullptr; - } } // --------------------------------------------------------------------------------------------------------------------- @@ -42,3 +33,16 @@ void CbmQaIO::SetHistoProperties(TH1* pHist) pHist->SetStats(true); pHist->Sumw2(); } + +// --------------------------------------------------------------------------------------------------------------------- +// +void CbmQaIO::WriteToFile(TFile* pOutFile) const +{ + LOG(info) << "CbmQaIO: Writing objects in file \033[1;31m" << pOutFile->GetName() << "\033[0m"; + pOutFile->cd(); + for (const auto& [pObject, sPath] : (*fpvObjList)) { + if (!pOutFile->GetDirectory(sPath)) { pOutFile->mkdir(sPath); } + pOutFile->cd(sPath); + pObject->Write(); + } +} diff --git a/core/qa/CbmQaIO.h b/core/qa/CbmQaIO.h index 424ca1c3ffd870f9bc0da71fe985d37d0192fc9f..f2f235b2b38e32f55910018db3b7fb79849c7a68 100644 --- a/core/qa/CbmQaIO.h +++ b/core/qa/CbmQaIO.h @@ -16,10 +16,10 @@ #include "TCanvas.h" #include "TEfficiency.h" -#include "TFolder.h" #include "TH1.h" #include "TH2.h" #include "TH3.h" +#include "TObject.h" #include "TParameter.h" #include "TProfile.h" #include "TProfile2D.h" @@ -27,11 +27,17 @@ #include "TROOT.h" #include "TString.h" +#include <vector> + +class TFile; + /// @brief ROOT object IO interface for QA /// /// The class provides interface to write ROOT object into resulted files class CbmQaIO { public: + using ObjList_t = std::vector<std::pair<TObject*, TString>>; + enum class EStoringMode { kSAMEDIR, ///< Objects will be stored to root directory @@ -39,10 +45,9 @@ public: }; /// @brief Constructor - /// @param folderName Name of the root folder /// @param prefixName Name of the unique prefix /// @param pParentFolder Pointer to parent folder - CbmQaIO(const char* folderName, const char* prefixName, TFolder* pParentFolder = nullptr); + CbmQaIO(const char* prefixName, std::shared_ptr<ObjList_t> pObjList = nullptr); /// @brief Destructor virtual ~CbmQaIO(); @@ -86,21 +91,30 @@ public: template<typename... Args> CbmQaTable* MakeTable(const char* name, Args... args); + /// @brief Creates a ROOT object + /// @param name Name of the object + /// @param args... Arguments passed to the object constructor + template<typename T, typename... Args> + T* MakeObject(const char* name, Args... args); + + /// @brief Sets a common root path to the objects in the output file + /// @param path A path to the object + void SetRootFolderName(const char* path) { fsRootFolderName = path; } + protected: /// @brief Applies properties on the histogram created with MakeHisto funciton /// @param pHist Pointer to histogram virtual void SetHistoProperties(TH1* /*pHits*/); + /// @brief Writes objects into file + /// @param pOutFile Pointer to output ROOT file + void WriteToFile(TFile* pOutFile) const; + TString fsRootFolderName = ""; ///< Name of root folder TString fsPrefix = ""; ///< Unique prefix for all writeable root - EStoringMode fStoringMode = EStoringMode::kSUBDIR; ///< Objects storing mode - TFolder* fpFolderRoot = nullptr; ///< Root folder to store histograms and canvases - TFolder* fpFolderHist = nullptr; ///< Folder for raw histograms - TFolder* fpFolderCanv = nullptr; ///< Folder for canvases - TFolder* fpFolderEff = nullptr; ///< Folder for efficiencies - TFolder* fpFolderTable = nullptr; ///< Folder for tables - TFolder* fpParentFolder = nullptr; ///< Pointer to parent folder + EStoringMode fStoringMode = EStoringMode::kSUBDIR; ///< Objects storing mode + std::shared_ptr<ObjList_t> fpvObjList = nullptr; ///< List of registered ROOT objects }; @@ -109,28 +123,8 @@ protected: template<typename T, typename... Args> T* CbmQaIO::MakeCanvas(const char* nameBase, Args... args) { - TString name = fsPrefix + "_" + nameBase; - if (gROOT->FindObject(name)) { - LOG(warn) << fsRootFolderName << ": A previously created canvas \"" << name << "\" will be deleted"; - T* pCanv = (T*) gROOT->FindObject(name); - delete pCanv; - } - - // Create a new canvas - T* pCanv = new T(name, args...); - pCanv->SetLeftMargin(-1.2); - pCanv->SetBottomMargin(-1.2); - - - // Register canvas in the folder - if (fStoringMode == EStoringMode::kSUBDIR) { - if (!fpFolderCanv) { fpFolderCanv = fpFolderRoot->AddFolder("canvases", "Canvases"); } - fpFolderCanv->Add(pCanv); - } - else if (fStoringMode == EStoringMode::kSAMEDIR) { - fpFolderRoot->Add(pCanv); - } - + TString sFullName = EStoringMode::kSUBDIR == fStoringMode ? Form("canvases/%s", nameBase) : nameBase; + auto* pCanv = MakeObject<T>(sFullName, args...); return pCanv; } @@ -139,82 +133,62 @@ T* CbmQaIO::MakeCanvas(const char* nameBase, Args... args) template<typename T, typename... Args> T* CbmQaIO::MakeEfficiency(const char* nameBase, Args... args) { - TString name = fsPrefix + "_" + nameBase; - if (gROOT->FindObject(name)) { - LOG(warn) << fsRootFolderName << ": A previously created histogram \"" << name << "\" will be deleted"; - auto* pEff = (T*) gROOT->FindObject(name); - delete pEff; - } - - // Create a new efficiency - auto* pEff = new T(name, args...); - - // Register efficiency in the folder - if (fStoringMode == EStoringMode::kSUBDIR) { - if (!fpFolderEff) { fpFolderEff = fpFolderRoot->AddFolder("efficiencies", "Efficiencies"); } - fpFolderEff->Add(pEff); - } - else if (fStoringMode == EStoringMode::kSAMEDIR) { - fpFolderRoot->Add(pEff); - } - + TString sFullName = EStoringMode::kSUBDIR == fStoringMode ? Form("efficiencies/%s", nameBase) : nameBase; + auto* pEff = MakeObject<T>(sFullName, args...); return pEff; } - // --------------------------------------------------------------------------------------------------------------------- // template<typename T, typename... Args> T* CbmQaIO::MakeHisto(const char* nameBase, Args... args) { - TString name = fsPrefix + "_" + nameBase; - // Check, if the histogram with a given name was already created. If so, delete it - if (gROOT->FindObject(name)) { - LOG(warn) << fsRootFolderName << ": A previously created histogram \"" << name << "\" will be deleted"; - T* pHist = (T*) gROOT->FindObject(name); - delete pHist; - } - - T* pHist = new T(name, args...); + TString sFullName = EStoringMode::kSUBDIR == fStoringMode ? Form("histograms/%s", nameBase) : nameBase; + auto* pHist = MakeObject<T>(sFullName, args...); + pHist->SetDirectory(0); SetHistoProperties(pHist); - - // Register histogram in the folder - if (fStoringMode == EStoringMode::kSUBDIR) { - if (!fpFolderHist) { fpFolderHist = fpFolderRoot->AddFolder("histograms", "Histograms"); } - fpFolderHist->Add(pHist); - } - else if (fStoringMode == EStoringMode::kSAMEDIR) { - fpFolderRoot->Add(pHist); - } - return pHist; } // --------------------------------------------------------------------------------------------------------------------- // -template<typename... Args> -CbmQaTable* CbmQaIO::MakeTable(const char* nameBase, Args... args) +template<typename T, typename... Args> +T* CbmQaIO::MakeObject(const char* name, Args... args) { - TString name = fsPrefix + "_" + nameBase; - // Check, if the table with a given name was already created. If so, delete it - if (gROOT->FindObject(name)) { - LOG(warn) << fsRootFolderName << ": A previously created table \"" << name << "\" will be deleted"; - CbmQaTable* pTable = (CbmQaTable*) gROOT->FindObject(name); - delete pTable; + // Resolve directory name and object name + TString sObjName = name; + auto iLastSlashPos = static_cast<int>(sObjName.Last('/')); + TString sDirName = sObjName(0, iLastSlashPos); + sObjName = sObjName(iLastSlashPos + 1, sObjName.Length() - iLastSlashPos); + + // Add unique prefix to the object name + sObjName = fsPrefix + "_" + sObjName; + + // Add parent directory to the folder + if (fsRootFolderName.Length() != 0) { sDirName = fsRootFolderName + "/" + sDirName; } + + // Check, if an object with the same name already exists + if (gROOT->FindObject(sObjName)) { + LOG(warn) << fsRootFolderName << ": A previously created object \"" << sObjName << "\" will be deleted"; + auto* pObj = static_cast<T*>(gROOT->FindObject(sObjName)); + delete pObj; } - // Create a new table - CbmQaTable* pTable = new CbmQaTable(name, args...); + // Create a new object + T* pObj = new T(sObjName, args...); - // Register table in folder - if (fStoringMode == EStoringMode::kSUBDIR) { - if (!fpFolderTable) { fpFolderTable = fpFolderRoot->AddFolder("tables", "Tables"); } - fpFolderTable->Add(pTable); - } - else if (fStoringMode == EStoringMode::kSAMEDIR) { - fpFolderRoot->Add(pTable); - } + // Register the object into an object list + fpvObjList->push_back(std::make_pair(static_cast<TObject*>(pObj), sDirName)); + return pObj; +} +// --------------------------------------------------------------------------------------------------------------------- +// +template<typename... Args> +CbmQaTable* CbmQaIO::MakeTable(const char* nameBase, Args... args) +{ + TString sFullName = EStoringMode::kSUBDIR == fStoringMode ? Form("tables/%s", nameBase) : nameBase; + auto* pTable = MakeObject<CbmQaTable>(sFullName, args...); return pTable; } diff --git a/core/qa/CbmQaTask.cxx b/core/qa/CbmQaTask.cxx index 4bc40d55986ceb2c1ff3f7e4a91a0b77b4b04268..53effef64abb1c8aeb85396f887c81f295150efe 100644 --- a/core/qa/CbmQaTask.cxx +++ b/core/qa/CbmQaTask.cxx @@ -12,11 +12,13 @@ #include "CbmQaCanvas.h" +#include "FairRootFileSink.h" #include "FairRootManager.h" #include "FairRunAna.h" -#include "FairSink.h" #include "TAxis.h" +#include "TCanvas.h" +#include "TF1.h" #include <array> @@ -26,9 +28,10 @@ ClassImp(CbmQaTask); // CbmQaTask::CbmQaTask(const char* name, const char* prefix, int verbose, bool isMCUsed) : FairTask(name, verbose) - , CbmQaIO(name, prefix) + , CbmQaIO(prefix) , fbUseMC(isMCUsed) { + CbmQaIO::SetRootFolderName(name); fStoringMode = CbmQaIO::EStoringMode::kSUBDIR; // mode of objects arrangement in the output file } @@ -55,9 +58,20 @@ void CbmQaTask::Finish() InitCanvases(); // Write the root folder to sinker - FairSink* pSink = FairRootManager::Instance()->GetSink(); - LOG_IF(fatal, !pSink) << fName << ": sink file was not found"; - pSink->WriteObject(fpFolderRoot, nullptr); + auto* pSink = FairRootManager::Instance()->GetSink(); + LOG_IF(fatal, !pSink) << fName << ": output sink is undefined"; + if (dynamic_cast<FairRootFileSink*>(pSink)) { + auto* pRootSink = static_cast<FairRootFileSink*>(pSink); + auto* pRootFile = pRootSink->GetRootFile(); + if (!pRootFile->FindObjectAny("nEvents")) { + pRootFile->cd(); + fNofEvents.Write(); + } + this->WriteToFile(pRootSink->GetRootFile()); + } + else { + LOG(warn) << fName << ": objects cannot be written into online sink (not implemented yet)"; + } } // --------------------------------------------------------------------------------------------------------------------- @@ -90,9 +104,6 @@ InitStatus CbmQaTask::Init() LOG_IF(info, fVerbose > 1) << fName << ": initializing input data branches"; res = std::max(res, InitDataBranches()); - // ----- Initialize I/O - fpFolderRoot->Add(&fNofEvents); - // ----- Initialize histograms LOG_IF(info, fVerbose > 1) << fName << ": initializing histograms"; res = std::max(res, InitHistograms()); diff --git a/core/qa/CbmQaTask.h b/core/qa/CbmQaTask.h index da033d11ddb5fbc8190855a876a5e936e063e6cd..e17a8b9fddd23cdd8b5cc16b11d14ebe06637d33 100644 --- a/core/qa/CbmQaTask.h +++ b/core/qa/CbmQaTask.h @@ -109,16 +109,6 @@ protected: /// Method to fill histograms per event or time-slice virtual void FillHistograms() {} - /// @brief Creates, initializes and registers a histogram, based on the configuration file - /// @tparam T Type of the histogram (@note: should not be a pointer) - /// @param name Name of the histogram, stored in config - /// @param id0 First index (optional) - /// @param id1 Second index (optional) - /// @param id2 Third index (optional) - /// @return Pointer to the histogram object - template<typename T> - T* MakeHistoFromConfig(const char* name, int id0 = -1, int id1 = -1, int id2 = -1); - /// Get current event number int GetEventNumber() const { return fNofEvents.GetVal(); } @@ -141,7 +131,6 @@ private: /// @brief De-initializes this task void DeInitBase(); - bool fbUseMC = false; ///< Flag, if MC is used TParameter<int> fNofEvents {"nEvents", 0}; ///< Number of processed events @@ -171,128 +160,4 @@ bool CbmQaTask::CheckRange(std::string_view name, const T& var, const T& lo, con return true; } - -// --------------------------------------------------------------------------------------------------------------------- -// -template<typename T> -T* CbmQaTask::MakeHistoFromConfig(const char* nameBase, int id0, int id1, int id2) -{ - std::string name = std::string(fsPrefix.Data()) + "_" + nameBase; - if (id0 > -1) { name = std::regex_replace(name, std::regex("\\%0"), std::to_string(id0)); } - if (id1 > -1) { name = std::regex_replace(name, std::regex("\\%1"), std::to_string(id1)); } - if (id2 > -1) { name = std::regex_replace(name, std::regex("\\%2"), std::to_string(id2)); } - - // Check, if the histogram with a given name was already created. If so, delete it - if (gROOT->FindObject(name.data())) { - LOG(warn) << fName << ": A histogram with name \"" << name << "\" was previously created and will be deleted now " - << "to avoid memory leaks"; - T* pHist = (T*) gROOT->FindObject(name.data()); - delete pHist; - } - - T* pHist = nullptr; - // Create histogram - LOG_IF(fatal, !fpCurrentNode) - << fName << ": attempt to make a histogram (\"" << nameBase << "\") from configuration file, which was not " - << "defined. Please, provide configuration file with defined histogram list to the task via " - << "SetConfigName(filename) function."; - try { - const auto& node = (*fpCurrentNode)["histograms"][nameBase]; - LOG_IF(fatal, !node) << fName << ": node for histogram \"" << nameBase - << "\" was not defined in the configuration file"; - - std::string title = node["title"].as<std::string>("").data(); - if (id0 > -1) { title = std::regex_replace(title, std::regex("\\%0"), std::to_string(id0)); } - if (id1 > -1) { title = std::regex_replace(title, std::regex("\\%1"), std::to_string(id1)); } - if (id2 > -1) { title = std::regex_replace(title, std::regex("\\%2"), std::to_string(id2)); } - - // 1D-profiles - if constexpr (std::is_base_of_v<TProfile, T>) { - int nBinsX = node["nbinsx"].as<int>(); - double minX = node["minx"].as<double>(); - double maxX = node["maxx"].as<double>(); - double minY = node["miny"].as<double>(0.); - double maxY = node["maxy"].as<double>(0.); - std::string opt = node["opt"].as<std::string>(""); - pHist = new T(name.data(), title.data(), nBinsX, minX, maxX, minY, maxY, opt.data()); - } - // 2D-profiles - else if constexpr (std::is_base_of_v<TProfile2D, T>) { - int nBinsX = node["nbinsx"].as<int>(); - double minX = node["minx"].as<double>(); - double maxX = node["maxx"].as<double>(); - int nBinsY = node["nbinsy"].as<int>(); - double minY = node["miny"].as<double>(); - double maxY = node["maxy"].as<double>(); - double minZ = node["minz"].as<double>(0.); - double maxZ = node["maxz"].as<double>(0.); - std::string opt = node["opt"].as<std::string>(""); - pHist = new T(name.data(), title.data(), nBinsX, minX, maxX, nBinsY, minY, maxY, minZ, maxZ, opt.data()); - } - // 3D-profiles - else if constexpr (std::is_base_of_v<TProfile3D, T>) { - int nBinsX = node["nbinsx"].as<int>(); - double minX = node["minx"].as<double>(); - double maxX = node["maxx"].as<double>(); - int nBinsY = node["nbinsy"].as<int>(); - double minY = node["miny"].as<double>(); - double maxY = node["maxy"].as<double>(); - int nBinsZ = node["nbinsz"].as<int>(); - double minZ = node["minz"].as<double>(); - double maxZ = node["maxz"].as<double>(); - std::string opt = node["opt"].as<std::string>(""); - pHist = new T(name.data(), title.data(), nBinsX, minX, maxX, nBinsY, minY, maxY, nBinsZ, minZ, maxZ, opt.data()); - } - // 2D-histograms - else if constexpr (std::is_base_of_v<TH2, T>) { - int nBinsX = node["nbinsx"].as<int>(); - double minX = node["minx"].as<double>(); - double maxX = node["maxx"].as<double>(); - int nBinsY = node["nbinsy"].as<int>(); - double minY = node["miny"].as<double>(); - double maxY = node["maxy"].as<double>(); - pHist = new T(name.data(), title.data(), nBinsX, minX, maxX, nBinsY, minY, maxY); - } - // 3D-histograms + derived - else if constexpr (std::is_base_of_v<TH3, T>) { - int nBinsX = node["nbinsx"].as<int>(); - double minX = node["minx"].as<double>(); - double maxX = node["maxx"].as<double>(); - int nBinsY = node["nbinsy"].as<int>(); - double minY = node["miny"].as<double>(); - double maxY = node["maxy"].as<double>(); - int nBinsZ = node["nbinsz"].as<int>(); - double minZ = node["minz"].as<double>(); - double maxZ = node["maxz"].as<double>(); - pHist = new T(name.data(), title.data(), nBinsX, minX, maxX, nBinsY, minY, maxY, nBinsZ, minZ, maxZ); - } - // 1D-histograms + derived - else if constexpr (std::is_base_of_v<TH1, T>) { - int nBinsX = node["nbinsx"].as<int>(); - double minX = node["minx"].as<double>(); - double maxX = node["maxx"].as<double>(); - pHist = new T(name.data(), title.data(), nBinsX, minX, maxX); - } - // Other types are restricted - //else { - // static_assert(false, "CbmQaTask::MakeTable: unsupported type given as a template parameter"); - //} - } - catch (const YAML::InvalidNode& exc) { - LOG(fatal) << fName << ": error while reading the histogram \"" << nameBase << "\" properties from " - << "configuration file \"" << fsConfigName << "\". Please, check the file formatting. \n Tip: probably, " - << "there ara mistakes in the obligatory property names, for example, \"nbinsX\" or \"nXBins\" is " - << "used instead of \"nbinsx\" etc."; - } - - // Register histogram in the folder - if (!fpFolderHist) { fpFolderHist = fpFolderRoot->AddFolder("histograms", "Histograms"); } - fpFolderHist->Add(pHist); - - return pHist; -} - - - - #endif // CbmQaTask_h diff --git a/core/qa/checker/CbmQaCheckerFileHandler.cxx b/core/qa/checker/CbmQaCheckerFileHandler.cxx index 93c46c396a0822ca29b3079c7b24cf966d6b0daf..1ef18e081f22636866fbf6f5dcc0a178a3af3d6e 100644 --- a/core/qa/checker/CbmQaCheckerFileHandler.cxx +++ b/core/qa/checker/CbmQaCheckerFileHandler.cxx @@ -22,9 +22,11 @@ #include "TH2.h" #include "TNamed.h" #include "TProfile.h" +#include "TROOT.h" #include <boost/algorithm/string.hpp> +#include <cstdlib> #include <iomanip> #include <sstream> #include <string> @@ -160,12 +162,12 @@ void FileHandler::Process(Option_t* opt) for (int iVer = 0; iVer < nVersions; ++iVer) { if (fpObjDB->GetCmpResult(fDatasetID, fFileID, iObj, iVer)) { areDifferent = true; } } - if (true || areDifferent) { pObjHandler->CreateCanvases(); } + if (areDifferent) { pObjHandler->CreateCanvases(); } } pObjHandler->Write(); // Clean memory - for (auto* pObj: vpObjects) { + for (auto* pObj : vpObjects) { if (pObj) { delete pObj; pObj = nullptr; @@ -179,28 +181,9 @@ void FileHandler::Process(Option_t* opt) // TNamed* FileHandler::ReadObjectFromFile(TFile* pFile, const std::string& path) const { - TObject* pObj = pFile; - size_t iPos = 0; // Index of first symbol - size_t iNext = 0; // Index of last symbol - // Read object iteratively, running throug directories or folders, provided by path - while (iPos < path.size()) { - // get name - iNext = path.find_first_of('/', iPos); - if (iNext > path.size()) { iNext = path.size(); } - std::string part = path.substr(iPos, iNext - iPos); // short name of next object/directory/folder in the path - iPos = iNext + 1; - if (!part.size()) { continue; } - - // test TDirectoryFile - if (dynamic_cast<TDirectoryFile*>(pObj)) { - auto* pDir = static_cast<TDirectoryFile*>(pObj); - pObj = pDir->FindObjectAny(part.data()); - } - // test TFolder - else if (dynamic_cast<TFolder*>(pObj)) { - auto* pDir = static_cast<TFolder*>(pObj); - pObj = pDir->FindObjectAny(part.data()); - } - } - return dynamic_cast<TNamed*>(pObj); + int iPosSlash = path.find_last_of('/') + 1; + std::string baseName = path.substr(iPosSlash, path.size()); + std::string pathName = path.substr(0, iPosSlash); + if (pathName.size() > 0) { pFile->cd(pathName.c_str()); } + return dynamic_cast<TNamed*>(pFile->FindObjectAny(baseName.c_str())); } diff --git a/core/qa/checker/CbmQaCheckerObjectHandler.cxx b/core/qa/checker/CbmQaCheckerObjectHandler.cxx index 180f5e59f3d22f589ccd2c143d484f1beb9a5c4c..336573ef2dccfcd8bf4929820e1c13ac356da03a 100644 --- a/core/qa/checker/CbmQaCheckerObjectHandler.cxx +++ b/core/qa/checker/CbmQaCheckerObjectHandler.cxx @@ -30,9 +30,9 @@ ObjectHandler::ObjectHandler(int iObject, int iFile, int iDataset, const char* o // --------------------------------------------------------------------------------------------------------------------- // -ObjectHandler::~ObjectHandler() +ObjectHandler::~ObjectHandler() { - for (auto* pObj: fvpObjects) { + for (auto* pObj : fvpObjects) { if (pObj) { delete pObj; pObj = nullptr; diff --git a/reco/L1/qa/CbmCaOutputQa.cxx b/reco/L1/qa/CbmCaOutputQa.cxx index affd3861bdbcee57585caa1d8046bd61cce62e9a..4547ea539c2206afe1f856d1814c06f2d2b94ea2 100644 --- a/reco/L1/qa/CbmCaOutputQa.cxx +++ b/reco/L1/qa/CbmCaOutputQa.cxx @@ -486,7 +486,8 @@ InitStatus OutputQa::InitHistograms() if (!fvbTrackTypeOn[type]) { return; } bool bUseMC = IsMCUsed() && !bSuppressMC; fvsTrackTypeName[type] = typeName; - fvpTrackHistograms[type] = std::make_unique<TrackTypeQa>(typeName, fsPrefix.Data(), bUseMC, fpFolderRoot); + fvpTrackHistograms[type] = std::make_unique<TrackTypeQa>(typeName, fsPrefix.Data(), bUseMC, fpvObjList); + fvpTrackHistograms[type]->SetRootFolderName(fsRootFolderName + "/" + typeName); fvpTrackHistograms[type]->SetTitle(title); fvpTrackHistograms[type]->RegisterParameters(fpParameters); fvpTrackHistograms[type]->RegisterRecoHits(fvHits); diff --git a/reco/L1/qa/CbmCaTrackFitQa.cxx b/reco/L1/qa/CbmCaTrackFitQa.cxx index 75bf0ff43c624ec0d2ed154d2e59023d297704c7..35b51d194858617b55adf48fee2034b5244c5dfe 100644 --- a/reco/L1/qa/CbmCaTrackFitQa.cxx +++ b/reco/L1/qa/CbmCaTrackFitQa.cxx @@ -34,8 +34,8 @@ using cbm::ca::TrackFitQa; // --------------------------------------------------------------------------------------------------------------------- // -TrackFitQa::TrackFitQa(const char* pointTag, const char* prefixName, TFolder* pParentFolder) - : CbmQaIO(pointTag, Form("%s_%s", prefixName, pointTag), pParentFolder) +TrackFitQa::TrackFitQa(const char* pointTag, const char* prefix, std::shared_ptr<ObjList_t> pObjList) + : CbmQaIO(Form("%s_%s", prefix, pointTag), pObjList) { fStoringMode = EStoringMode::kSAMEDIR; } diff --git a/reco/L1/qa/CbmCaTrackFitQa.h b/reco/L1/qa/CbmCaTrackFitQa.h index 051d200ba59d30d7ad47355d48c18fa62ce64666..a76ccd2426c353f44f8f26626bbaa79aee2fec63 100644 --- a/reco/L1/qa/CbmCaTrackFitQa.h +++ b/reco/L1/qa/CbmCaTrackFitQa.h @@ -69,10 +69,10 @@ namespace cbm::ca class TrackFitQa : public CbmQaIO { public: /// @brief Constructor - /// @param pointTag Tag for point, in which the parameters are analyzed - /// @param prefixName Name of unique prefix - /// @param pParentFolder Pointer to parent folder - TrackFitQa(const char* pointTag, const char* prefixName, TFolder* pParentFolder); + /// @param pointTag Tag for point, in which the parameters are analyzed + /// @param prefix Name of unique prefix + /// @param pObjList List of registered ROOT objects + TrackFitQa(const char* pointTag, const char* prefix, std::shared_ptr<ObjList_t> pObjList); /// @brief Destructor ~TrackFitQa() = default; diff --git a/reco/L1/qa/CbmCaTrackTypeQa.cxx b/reco/L1/qa/CbmCaTrackTypeQa.cxx index d304b8477921ace69826ea7c835edb58ee515e66..295b18de6806aab4a879ef7da14f744fd59458f7 100644 --- a/reco/L1/qa/CbmCaTrackTypeQa.cxx +++ b/reco/L1/qa/CbmCaTrackTypeQa.cxx @@ -21,8 +21,8 @@ using cbm::ca::TrackTypeQa; // --------------------------------------------------------------------------------------------------------------------- // -TrackTypeQa::TrackTypeQa(const char* typeName, const char* prefixName, bool bUseMC, TFolder* pParentFolder) - : CbmQaIO(typeName, Form("%s_%s", prefixName, typeName), pParentFolder) +TrackTypeQa::TrackTypeQa(const char* typeName, const char* prefix, bool bUseMC, std::shared_ptr<ObjList_t> pObjList) + : CbmQaIO(Form("%s_%s", prefix, typeName), pObjList) , fbUseMC(bUseMC) { fStoringMode = EStoringMode::kSAMEDIR; @@ -154,17 +154,20 @@ void TrackTypeQa::Init() // // ** Track fit parameter properties (residuals and pulls) ** // - fpFitQaFirstHit = std::make_unique<TrackFitQa>("fst_hit", fsPrefix, fpFolderRoot); + fpFitQaFirstHit = std::make_unique<TrackFitQa>("fst_hit", fsPrefix, fpvObjList); + fpFitQaFirstHit->SetRootFolderName(fsRootFolderName + "/fst_hit"); fpFitQaFirstHit->SetTitle("First hit"); fpFitQaFirstHit->Init(); - fpFitQaLastHit = std::make_unique<TrackFitQa>("lst_hit", fsPrefix, fpFolderRoot); + fpFitQaLastHit = std::make_unique<TrackFitQa>("lst_hit", fsPrefix, fpvObjList); + fpFitQaLastHit->SetRootFolderName(fsRootFolderName + "/lst_hit"); fpFitQaLastHit->SetTitle("Last hit"); fpFitQaLastHit->SetResidualHistoProperties(ETrackParType::kX, 200, -0.4, +0.4); fpFitQaLastHit->SetResidualHistoProperties(ETrackParType::kY, 200, -0.8, +0.8); fpFitQaLastHit->Init(); - fpFitQaVertex = std::make_unique<TrackFitQa>("vertex", fsPrefix, fpFolderRoot); + fpFitQaVertex = std::make_unique<TrackFitQa>("vertex", fsPrefix, fpvObjList); + fpFitQaVertex->SetRootFolderName(fsRootFolderName + "/vertex"); fpFitQaVertex->SetTitle("Vertex"); fpFitQaVertex->Init(); } diff --git a/reco/L1/qa/CbmCaTrackTypeQa.h b/reco/L1/qa/CbmCaTrackTypeQa.h index 5e527a31c4d8caade8a1d4ed9402374ad25a2d58..f64ef78bb82d6340b05d92e66f9975193dc63636 100644 --- a/reco/L1/qa/CbmCaTrackTypeQa.h +++ b/reco/L1/qa/CbmCaTrackTypeQa.h @@ -46,8 +46,8 @@ namespace cbm::ca /// @note Track type is stored as a root directory name in the CbmQaIO base class /// @param prefixName Name of unique prefix /// @param bUseMC Flag: true - MC is used - /// @param pParentFolder Pointer to parent folder - TrackTypeQa(const char* typeName, const char* prefixName, bool bUseMC, TFolder* pParentFolder); + /// @param pObjList List of registered objects + TrackTypeQa(const char* typeName, const char* prefixName, bool bUseMC, std::shared_ptr<ObjList_t> pObjList); /// @brief Destructor ~TrackTypeQa() = default;