diff --git a/core/qa/CMakeLists.txt b/core/qa/CMakeLists.txt index e62f00327e0fa61ad80426c29374539d5cd82b15..7d53054828092d36e960cfd49298bedb1c524620 100644 --- a/core/qa/CMakeLists.txt +++ b/core/qa/CMakeLists.txt @@ -5,6 +5,7 @@ set(INCLUDE_DIRECTORIES set(SRCS CbmQaCanvas.cxx + CbmQaManager.cxx CbmQaEff.cxx CbmQaPie.cxx CbmQaHist.cxx @@ -47,6 +48,7 @@ set(INTERFACE_DEPENDENCIES generate_cbm_library() Install(FILES + CbmQaManager.h CbmQaTask.h CbmQaCanvas.h CbmQaTable.h diff --git a/core/qa/CbmQaBaseLinkDef.h b/core/qa/CbmQaBaseLinkDef.h index cee4c1d3419cd1c9eb13b4964891d7794c50fa68..586d32b8265ae4ee651e71ee6cf41da42e098095 100644 --- a/core/qa/CbmQaBaseLinkDef.h +++ b/core/qa/CbmQaBaseLinkDef.h @@ -25,6 +25,7 @@ #pragma link C++ class CbmQaHist < TProfile2D> + ; #pragma link C++ class CbmQaTable + ; #pragma link C++ class CbmQaTask + ; +#pragma link C++ class CbmQaManager + ; #pragma link C++ class cbm::qa::checker::Core + ; #pragma link C++ class cbm::qa::checker::FileHandler + ; #pragma link C++ class cbm::qa::checker::Hist1DHandler + ; diff --git a/core/qa/CbmQaIO.cxx b/core/qa/CbmQaIO.cxx index 22851af9478f443e9b0a4675593d9c521bdff757..3ad2fc13bd60c74d29a628c4e970170fb62b7f0b 100644 --- a/core/qa/CbmQaIO.cxx +++ b/core/qa/CbmQaIO.cxx @@ -107,7 +107,6 @@ void CbmQaIO::SetConfigName(const char* path) // void CbmQaIO::WriteToFile(TFile* pOutFile) const { - LOG(info) << "CbmQaIO: Writing objects in file \033[1;31m" << pOutFile->GetName() << "\033[0m"; pOutFile->cd(); for (auto& [pObject, sPath] : (*fpvObjList)) { if (!pOutFile->GetDirectory(sPath)) { pOutFile->mkdir(sPath); } diff --git a/core/qa/CbmQaManager.cxx b/core/qa/CbmQaManager.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e03f2fada8840a229690f9383276f8077966d999 --- /dev/null +++ b/core/qa/CbmQaManager.cxx @@ -0,0 +1,58 @@ +/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergei Zharko [committer] */ + +/// \file CbmQaManager.h +/// \brief Manager task for other QA taska (implementation) +/// \author Sergei Zharko <s.zharko@gsi.de> +/// \since 17.10.2023 + +#include "CbmQaManager.h" + +#include "CbmQaTask.h" + +#include "Logger.h" + +#include <iomanip> + +// --------------------------------------------------------------------------------------------------------------------- +// +CbmQaManager::CbmQaManager(int verbose) : FairTask("CbmQaManager", verbose) {} + + +// --------------------------------------------------------------------------------------------------------------------- +// +void CbmQaManager::Finish() +{ + using std::left; + using std::right; + using std::setw; + + std::map<std::string, std::map<std::string, bool>> qaResults; + for (auto* task : *(this->GetListOfTasks())) { + auto* pQaTask = dynamic_cast<CbmQaTask*>(task); + if (pQaTask) { qaResults[std::string(task->GetName())] = pQaTask->Check(); } + } + + fStatus = true; + LOG(info) << fName << ": monitorable status:"; + for (auto& [name, resMap] : qaResults) { + LOG(info) << name; + for (auto& [quantity, flag] : resMap) { + LOG(info) << '\t' << left << setw(40) << quantity << right + << (flag ? "\e[1;32mpassed\e[0m" : "\e[1;31mfailed\e[0m"); + fStatus &= flag; + } + } +} + +// --------------------------------------------------------------------------------------------------------------------- +// +InitStatus CbmQaManager::Init() +{ + for (auto* task : *(this->GetListOfTasks())) { + LOG(info) << "\t- " << task->GetName(); + } + + return kSUCCESS; +} diff --git a/core/qa/CbmQaManager.h b/core/qa/CbmQaManager.h new file mode 100644 index 0000000000000000000000000000000000000000..980cfbd352a0ecb66439d6d0724f741c491062e8 --- /dev/null +++ b/core/qa/CbmQaManager.h @@ -0,0 +1,60 @@ +/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergei Zharko [committer] */ + +/// \file CbmQaManager.h +/// \brief Manager task for other QA taska (header) +/// \author Sergei Zharko <s.zharko@gsi.de> +/// \since 17.10.2023 + +#pragma once + +#include "FairTask.h" + +#include <map> +#include <string> + +class CbmQaManager : public FairTask { +public: + /// \brief Constructor from parameters + /// \param verbose Verbose level + CbmQaManager(int verbose = 1); + + /// \brief Destructor + virtual ~CbmQaManager() = default; + + /// \brief Copy constructor + CbmQaManager(const CbmQaManager&) = delete; + + /// \brief Move constructor + CbmQaManager(CbmQaManager&&) = delete; + + /// \brief Copy assignment operator + CbmQaManager& operator=(const CbmQaManager&) = delete; + + /// \brief Move assignment operator + CbmQaManager& operator=(CbmQaManager&&) = delete; + + /// \brief Adds sub-task + void AddTask(FairTask* task) { this->Add(task); } + + /// \brief Action of the task in the time-slice + void Exec(Option_t*) {}; + + /// \brief Action of the task in the end of the run + void Finish(); + + /// \brief Task initialization + InitStatus Init(); + + /// \brief Task re-initialization + InitStatus ReInit() { return Init(); } + + ClassDef(CbmQaManager, 0); + + /// \brief Gets status flag + bool GetStatus() const { return fStatus; } + +private: + bool fStatus = true; ///< Status of QA: true - all tasks passed, false - at least one of the task failed +}; diff --git a/core/qa/CbmQaTask.cxx b/core/qa/CbmQaTask.cxx index 130638f4f21e0e018a4bd39fd1df98df7f4294e5..6141bb5a446f35fb5ec817988b07cdcefe17eee9 100644 --- a/core/qa/CbmQaTask.cxx +++ b/core/qa/CbmQaTask.cxx @@ -49,13 +49,7 @@ void CbmQaTask::Exec(Option_t* /*option*/) // void CbmQaTask::Finish() { - // Processes histograms in the end of the run - LOG(info) << fName << ": Checking QA..."; - bool qaResult = Check(); - LOG(info) << fName << ": Checking QA: " << (qaResult ? "\033[1;32mpassed\033[0m" : "\033[1;31mfailed\033[0m"); - // Processes canvases in the end of the run - LOG_IF(info, fVerbose > 1) << fName << ": initializing canvases"; InitCanvases(); // Write the root folder to sinker diff --git a/core/qa/CbmQaTask.h b/core/qa/CbmQaTask.h index f09f8201419207cb2017e8f2fc56719e56956c59..4c608051f4f8196e894a18f96a92c4b4271d6426 100644 --- a/core/qa/CbmQaTask.h +++ b/core/qa/CbmQaTask.h @@ -29,6 +29,7 @@ #include "TROOT.h" #include <algorithm> +#include <map> #include <regex> #include <string_view> #include <tuple> @@ -79,17 +80,17 @@ public: /// @brief Sets name of the setup void SetSetupName(const char* setup) { fsSetupName = setup; } -protected: ClassDef(CbmQaTask, 0); -protected: // ***************************************************** // ** Functions accessible inside the derived classes ** // ***************************************************** - /// \brief Method to check, if the QA results are acceptable - virtual bool Check() = 0; + /// \brief Method to check, if the QA results are acceptable + /// \return Map of checks: key - name of the check, value - result of the check + virtual std::map<std::string, bool> Check() = 0; +protected: /// De-initialize the task virtual void DeInit() {} diff --git a/macro/mcbm/mcbm_qa.C b/macro/mcbm/mcbm_qa.C index 36d8fdf517c16d4998c095c15d379ce45d796f14..2253208c42ccfabc77d1f57e2af4737b27089666 100644 --- a/macro/mcbm/mcbm_qa.C +++ b/macro/mcbm/mcbm_qa.C @@ -21,6 +21,7 @@ #include "CbmDefs.h" #include "CbmMCDataManager.h" #include "CbmMuchTransportQa.h" +#include "CbmQaManager.h" #include "CbmSetup.h" #include <FairFileSource.h> @@ -156,6 +157,7 @@ void mcbm_qa(Int_t nEvents = 0, TString dataset = "data/mcbm_beam_2020_03_test", run->SetSource(inputSource); run->SetGenerateRunInfo(kFALSE); + FairRootFileSink* sink = new FairRootFileSink(sinkFile); run->SetSink(sink); @@ -164,24 +166,27 @@ void mcbm_qa(Int_t nEvents = 0, TString dataset = "data/mcbm_beam_2020_03_test", FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monitorFile); // ------------------------------------------------------------------------ + auto* qaManager = new CbmQaManager(3); + run->AddTask(qaManager); + // ----- MCDataManager (legacy mode) ----------------------------------- if (bUseMC) { std::cout << "-I- " << myName << ": Adding MC manager and MC to reco matching tasks\n"; auto* mcManager = new CbmMCDataManager("MCDataManager", 1); mcManager->AddFile(traFile); - run->AddTask(mcManager); + qaManager->AddTask(mcManager); auto* matchRecoToMC = new CbmMatchRecoToMC(); // NOTE: Matching is suppressed, if there are hit and cluster matches already in the tree. If there // are no hit matches, they are produced on this stage. matchRecoToMC->SuppressHitReMatching(); - run->AddTask(matchRecoToMC); + qaManager->AddTask(matchRecoToMC); } // ------------------------------------------------------------------------ // ----- Tracking detector interface -------------------------------------- - run->AddTask(new CbmTrackingDetectorInterfaceInit()); + qaManager->AddTask(new CbmTrackingDetectorInterfaceInit()); // ------------------------------------------------------------------------ // NOTE (FIXME) SZh, 26.04.2023 @@ -196,15 +201,15 @@ void mcbm_qa(Int_t nEvents = 0, TString dataset = "data/mcbm_beam_2020_03_test", // CA Input QA auto* pCaInputSts = new CbmCaInputQaSts(verbose, bUseMC); pCaInputSts->SetEfficiencyThrsh(0.5, 0, 100); - run->AddTask(pCaInputSts); + qaManager->AddTask(pCaInputSts); } // ------------------------------------------------------------------------ // ----- MUCH QA --------------------------------------------------------- if (bUseMuch) { - run->AddTask(new CbmMuchTransportQa()); - run->AddTask(new CbmMuchDigitizerQa()); + qaManager->AddTask(new CbmMuchTransportQa()); + qaManager->AddTask(new CbmMuchDigitizerQa()); CbmMuchHitFinderQa* muchHitFinderQa = new CbmMuchHitFinderQa(); @@ -214,7 +219,7 @@ void mcbm_qa(Int_t nEvents = 0, TString dataset = "data/mcbm_beam_2020_03_test", // CA Input QA auto* pCaInputMuch = new CbmCaInputQaMuch(verbose, bUseMC); pCaInputMuch->SetEfficiencyThrsh(0.5, 0, 100); - run->AddTask(pCaInputMuch); + qaManager->AddTask(pCaInputMuch); } // ------------------------------------------------------------------------ @@ -223,7 +228,7 @@ void mcbm_qa(Int_t nEvents = 0, TString dataset = "data/mcbm_beam_2020_03_test", // CA Input QA auto* pCaInputTrd = new CbmCaInputQaTrd(verbose, bUseMC); pCaInputTrd->SetEfficiencyThrsh(0.5, 0, 100); - run->AddTask(pCaInputTrd); + qaManager->AddTask(pCaInputTrd); } // ------------------------------------------------------------------------ @@ -232,14 +237,14 @@ void mcbm_qa(Int_t nEvents = 0, TString dataset = "data/mcbm_beam_2020_03_test", // CA Input QA auto* pCaInputTof = new CbmCaInputQaTof(verbose, bUseMC); pCaInputTof->SetEfficiencyThrsh(0.5, 0, 100); - run->AddTask(pCaInputTof); + qaManager->AddTask(pCaInputTof); } // ------------------------------------------------------------------------ // ----- CA tracking QA --------------------------------------------------- // Kalman Filter (currently needed to access the magnetic filed, to be // removed soon) - run->AddTask(new CbmKF()); + qaManager->AddTask(new CbmKF()); // Tracking parameters file is required TString caParFile = recFile; @@ -252,7 +257,7 @@ void mcbm_qa(Int_t nEvents = 0, TString dataset = "data/mcbm_beam_2020_03_test", pCaInputQaSetup->SetDetectorFlag(cbm::algo::ca::EDetectorID::kTof, bUseTof); pCaInputQaSetup->ReadParameters(caParFile.Data()); pCaInputQaSetup->SetSetupName(setupName.Data()); - run->AddTask(pCaInputQaSetup); + qaManager->AddTask(pCaInputQaSetup); auto* pCaOutputQa = new cbm::ca::OutputQa(verbose, bUseMC); pCaOutputQa->SetMcbmTrackingMode(); @@ -261,7 +266,7 @@ void mcbm_qa(Int_t nEvents = 0, TString dataset = "data/mcbm_beam_2020_03_test", pCaOutputQa->SetUseMuch(bUseMuch); pCaOutputQa->SetUseTrd(bUseTrd); pCaOutputQa->SetUseTof(bUseTof); - run->AddTask(pCaOutputQa); + qaManager->AddTask(pCaOutputQa); // ------------------------------------------------------------------------ @@ -303,6 +308,7 @@ void mcbm_qa(Int_t nEvents = 0, TString dataset = "data/mcbm_beam_2020_03_test", std::cout << "Parameter file is " << parFile << std::endl; std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s" << std::endl; std::cout << std::endl; + std::cout << " QA checks " << (qaManager->GetStatus() ? "\e[1;32mpassed" : "\e[1;31mfailed") << "\e[0m\n"; std::cout << " Test passed" << std::endl; std::cout << " All ok " << std::endl; // ------------------------------------------------------------------------ diff --git a/macro/run/run_qa.C b/macro/run/run_qa.C index fc72c75f70cc9abdcb174a819433d440a1584bd2..174c9668fdc2d7ee8bb948b5bbf86e7440971fc0 100644 --- a/macro/run/run_qa.C +++ b/macro/run/run_qa.C @@ -172,6 +172,9 @@ void run_qa(TString dataTra = "data/sis100_muon_jpsi_test", TString dataRaw = "d TString monitorFile {sinkFile}; monitorFile.ReplaceAll("qa", "qa.monitor"); FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monitorFile); + + auto* qaManager = new CbmQaManager(3); + run->AddTask(qaManager); // ------------------------------------------------------------------------ // ----- MCDataManager ----------------------------------- @@ -180,34 +183,34 @@ void run_qa(TString dataTra = "data/sis100_muon_jpsi_test", TString dataRaw = "d if (!dataTra2.IsNull()) mcManager->AddFile(tra2File); if (!dataTra3.IsNull()) mcManager->AddFile(tra3File); - run->AddTask(mcManager); + qaManager->AddTask(mcManager); // ------------------------------------------------------------------------ - run->AddTask(new CbmTrackingDetectorInterfaceInit()); // Geometry interface initializer for tracker + qaManager->AddTask(new CbmTrackingDetectorInterfaceInit()); // Geometry interface initializer for tracker // ----- Match reco to MC ------ if (bUseMC) { CbmMatchRecoToMC* matchTask = new CbmMatchRecoToMC(); // NOTE: Matching of hits and clusters is suppressed when the matches are already present in the tree. matchTask->SuppressHitReMatching(); - run->AddTask(matchTask); + qaManager->AddTask(matchTask); } // ----- MUCH QA --------------------------------- if (CbmSetup::Instance()->IsActive(ECbmModuleId::kMuch)) { - run->AddTask(new CbmMuchTransportQa()); - run->AddTask(new CbmMuchDigitizerQa()); + qaManager->AddTask(new CbmMuchTransportQa()); + qaManager->AddTask(new CbmMuchDigitizerQa()); CbmMuchHitFinderQa* muchHitFinderQa = new CbmMuchHitFinderQa(); muchHitFinderQa->SetGeoFileName(muchParFile); - run->AddTask(muchHitFinderQa); + qaManager->AddTask(muchHitFinderQa); auto* pCaInputQaMuch = new CbmCaInputQaMuch(verbose, bUseMC); pCaInputQaMuch->SetEfficiencyThrsh(0.5, 0, 100); - run->AddTask(pCaInputQaMuch); + qaManager->AddTask(pCaInputQaMuch); } // ----- TRD QA --------------------------------- if (CbmSetup::Instance()->IsActive(ECbmModuleId::kTrd)) { - run->AddTask(new CbmTrdMCQa()); + qaManager->AddTask(new CbmTrdMCQa()); //run->AddTask(new CbmTrdHitRateQa()); //opens lots of windows //run->AddTask(new CbmTrdDigitizerPRFQa()); //works put currently doesn't do anything //run->AddTask(new CbmTrdHitRateFastQa()); //opens lots of windows @@ -217,38 +220,38 @@ void run_qa(TString dataTra = "data/sis100_muon_jpsi_test", TString dataRaw = "d /// => fast-fix to accomodate the 4+4+2 complexity of tentative SIS300 geometry trdHitProducerQa->SetNumberStations(10); } - run->AddTask(trdHitProducerQa); - run->AddTask(new CbmTrdCalibTracker()); + qaManager->AddTask(trdHitProducerQa); + qaManager->AddTask(new CbmTrdCalibTracker()); auto* pCaInputQaTrd = new CbmCaInputQaTrd(verbose, bUseMC); pCaInputQaTrd->SetEfficiencyThrsh(0.5, 0, 100); - run->AddTask(pCaInputQaTrd); + qaManager->AddTask(pCaInputQaTrd); } // ------------------------------------------------------------------------ - // ----- TOF QA --------------------------------- + // ----- TOF QA ---------------------------------------------------------- if (CbmSetup::Instance()->IsActive(ECbmModuleId::kTof)) { auto* pCaInputQaTof = new CbmCaInputQaTof(verbose, bUseMC); pCaInputQaTof->SetEfficiencyThrsh(0.5, 0, 100); - run->AddTask(pCaInputQaTof); + qaManager->AddTask(pCaInputQaTof); } // ------------------------------------------------------------------------ - // ----- STS QA --------------------------------- + // ----- STS QA ---------------------------------------------------------- if (CbmSetup::Instance()->IsActive(ECbmModuleId::kSts)) { auto* pCaInputQaSts = new CbmCaInputQaSts(verbose, bUseMC); - run->AddTask(pCaInputQaSts); + qaManager->AddTask(pCaInputQaSts); } // ------------------------------------------------------------------------ // ----- Event builder QA --------------------------------- CbmBuildEventsQa* evBuildQA = new CbmBuildEventsQa(); - run->AddTask(evBuildQA); + qaManager->AddTask(evBuildQA); // ------------------------------------------------------------------------ // ----- Tracking QA ------------------------------------------------------ // KF is currently needed to access magnetic field. In future we will // delegate track fit routines to CbmKF as well. - run->AddTask(new CbmKF()); + qaManager->AddTask(new CbmKF()); TString caParFile = recFile; caParFile.ReplaceAll(".root", ".L1Parameters.dat"); @@ -262,7 +265,7 @@ void run_qa(TString dataTra = "data/sis100_muon_jpsi_test", TString dataRaw = "d //pCaOutputQa->SetUseMuch(bUseMuch); //pCaOutputQa->SetUseTrd(bUseTrd); //pCaOutputQa->SetUseTof(bUseTof); - run->AddTask(pCaOutputQa); + qaManager->AddTask(pCaOutputQa); // ------------------------------------------------------------------------ // ----- Parameter database -------------------------------------------- @@ -303,6 +306,7 @@ void run_qa(TString dataTra = "data/sis100_muon_jpsi_test", TString dataRaw = "d std::cout << "Parameter file is " << parFile << std::endl; std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s" << std::endl; std::cout << std::endl; + std::cout << " QA checks " << (qaManager->GetStatus() ? "\e[1;32mpassed" : "\e[1;31mfailed") << "\e[0m\n"; std::cout << " Test passed" << std::endl; std::cout << " All ok " << std::endl; // ------------------------------------------------------------------------ diff --git a/reco/L1/qa/CbmCaInputQaBase.cxx b/reco/L1/qa/CbmCaInputQaBase.cxx index d7e4ded129c3a15a183543b6b3d0c00714ef1873..025e791c682a8a9737df88de046e47a32aa3fc9a 100644 --- a/reco/L1/qa/CbmCaInputQaBase.cxx +++ b/reco/L1/qa/CbmCaInputQaBase.cxx @@ -76,9 +76,9 @@ CbmCaInputQaBase<DetID>::CbmCaInputQaBase(const char* name, int verbose, bool is // --------------------------------------------------------------------------------------------------------------------- // template<ca::EDetectorID DetID> -bool CbmCaInputQaBase<DetID>::Check() +std::map<std::string, bool> CbmCaInputQaBase<DetID>::Check() { - bool res = true; + std::map<std::string, bool> resMap; int nSt = fpDetInterface->GetNtrackingStations(); @@ -104,21 +104,25 @@ bool CbmCaInputQaBase<DetID>::Check() // ----- Checks for mismatches in the ordering of the stations // - std::vector<double> vStationPos(nSt, 0.); - for (int iSt = 0; iSt < nSt; ++iSt) { - vStationPos[iSt] = fpDetInterface->GetZref(iSt); - } + { + bool res = true; - if (!std::is_sorted(vStationPos.cbegin(), vStationPos.cend(), [](int l, int r) { return l <= r; })) { - if (fVerbose > 0) { - LOG(error) << fName << ": stations are ordered improperly along the beam axis:"; - for (auto z : vStationPos) { - LOG(error) << "\t- " << z; + std::vector<double> vStationPos(nSt, 0.); + for (int iSt = 0; iSt < nSt; ++iSt) { + vStationPos[iSt] = fpDetInterface->GetZref(iSt); + } + + if (!std::is_sorted(vStationPos.cbegin(), vStationPos.cend(), [](int l, int r) { return l <= r; })) { + if (fVerbose > 0) { + LOG(error) << fName << ": stations are ordered improperly along the beam axis:"; + for (auto z : vStationPos) { + LOG(error) << "\t- " << z; + } } + res = false; } - res = false; + resMap["station_position_ordering"] = res; } - // ----- Checks for mismatch between station and hit z positions // The purpose of this block is to be ensured, that hits belong to the correct tracking station. For each tracking // station a unified position z-coordinate is defined, which generally differs from the corresponding positions of @@ -131,23 +135,26 @@ bool CbmCaInputQaBase<DetID>::Check() // total number of entries to the distribution. If this value is smaller then unity, then some of the hits belong to // another station. // - for (int iSt = 0; iSt < nSt; ++iSt) { - int nHits = fvph_hit_station_delta_z[iSt]->GetEntries(); - if (!nHits) { - LOG_IF(error, fVerbose > 0) << fName << ": station " << iSt << " does not have hits"; - res = false; - continue; - } - int iBinMin = fvph_hit_station_delta_z[iSt]->FindBin(-fMaxDiffZStHit); - int iBinMax = fvph_hit_station_delta_z[iSt]->FindBin(+fMaxDiffZStHit); + { + bool res = true; + for (int iSt = 0; iSt < nSt; ++iSt) { + int nHits = fvph_hit_station_delta_z[iSt]->GetEntries(); + if (!nHits) { + LOG_IF(error, fVerbose > 0) << fName << ": station " << iSt << " does not have hits"; + res = false; + continue; + } + int iBinMin = fvph_hit_station_delta_z[iSt]->FindBin(-fMaxDiffZStHit); + int iBinMax = fvph_hit_station_delta_z[iSt]->FindBin(+fMaxDiffZStHit); - if (fvph_hit_station_delta_z[iSt]->Integral(iBinMin, iBinMax) < nHits) { - LOG_IF(error, fVerbose > 0) << fName << ": station " << iSt << " has mismatches in hit z-positions"; - res = false; + if (fvph_hit_station_delta_z[iSt]->Integral(iBinMin, iBinMax) < nHits) { + LOG_IF(error, fVerbose > 0) << fName << ": station " << iSt << " has mismatches in hit z-positions"; + res = false; + } } + resMap["station_position_hit_delta_z"] = res; } - // ******************************************************* // ** Additional checks, if MC information is available ** // ******************************************************* @@ -159,44 +166,45 @@ bool CbmCaInputQaBase<DetID>::Check() // distribution in the range from kEffRangeMin to kEffRangeMax, where the efficiency is assigned to be constant // // Fit efficiency curves - LOG(info) << "-- Hit efficiency integrated over hit distance from station center"; + { + LOG(info) << "-- Hit efficiency integrated over hit distance from station center"; - auto* pEffTable = MakeQaObject<CbmQaTable>("vs Station/eff_table", "Efficiency table", nSt, 2); - pEffTable->SetNamesOfCols({"Station ID", "Efficiency"}); - pEffTable->SetColWidth(20); + auto* pEffTable = MakeQaObject<CbmQaTable>("vs Station/eff_table", "Efficiency table", nSt, 2); + pEffTable->SetNamesOfCols({"Station ID", "Efficiency"}); + pEffTable->SetColWidth(20); - for (int iSt = 0; iSt < nSt; ++iSt) { - auto eff = fvph_reco_eff[iSt]->GetMean(); - pEffTable->SetCell(iSt, 0, iSt); - pEffTable->SetCell(iSt, 1, eff); - res = CheckRange("Hit finder efficiency in station " + std::to_string(iSt), eff, fEffThrsh, 1.000); + for (int iSt = 0; iSt < nSt; ++iSt) { + auto eff = fvph_reco_eff[iSt]->GetMean(); + pEffTable->SetCell(iSt, 0, iSt); + pEffTable->SetCell(iSt, 1, eff); + resMap[Form("hit_efficiency_station_%d", iSt)] = + CheckRange("Hit finder efficiency in station " + std::to_string(iSt), eff, fEffThrsh, 1.000); + } + LOG(info) << '\n' << pEffTable->ToString(3); } - LOG(info) << '\n' << pEffTable->ToString(3); - // ----- Checks for residuals // Check hits for potential biases from central values - - auto* pResidualsTable = - MakeQaObject<CbmQaTable>("vs Station/residuals_mean", "Residual mean values in different stations", nSt, 4); - pResidualsTable->SetNamesOfCols({"Station ID", "Residual(x) [cm]", "Residual(y) [cm]", "Residual(t) [ns]"}); - pResidualsTable->SetColWidth(20); - - // Fit residuals - for (int iSt = 0; iSt <= nSt; ++iSt) { - - cbm::qa::util::SetLargeStats(fvph_res_x[iSt]); - cbm::qa::util::SetLargeStats(fvph_res_y[iSt]); - cbm::qa::util::SetLargeStats(fvph_res_t[iSt]); - - pResidualsTable->SetCell(iSt, 0, iSt); - pResidualsTable->SetCell(iSt, 1, fvph_res_x[iSt]->GetStdDev()); - pResidualsTable->SetCell(iSt, 2, fvph_res_y[iSt]->GetStdDev()); - pResidualsTable->SetCell(iSt, 3, fvph_res_t[iSt]->GetStdDev()); + { + auto* pResidualsTable = + MakeQaObject<CbmQaTable>("vs Station/residuals_mean", "Residual mean values in different stations", nSt, 4); + pResidualsTable->SetNamesOfCols({"Station ID", "Residual(x) [cm]", "Residual(y) [cm]", "Residual(t) [ns]"}); + pResidualsTable->SetColWidth(20); + + // Fit residuals + for (int iSt = 0; iSt <= nSt; ++iSt) { + + cbm::qa::util::SetLargeStats(fvph_res_x[iSt]); + cbm::qa::util::SetLargeStats(fvph_res_y[iSt]); + cbm::qa::util::SetLargeStats(fvph_res_t[iSt]); + + pResidualsTable->SetCell(iSt, 0, iSt); + pResidualsTable->SetCell(iSt, 1, fvph_res_x[iSt]->GetStdDev()); + pResidualsTable->SetCell(iSt, 2, fvph_res_y[iSt]->GetStdDev()); + pResidualsTable->SetCell(iSt, 3, fvph_res_t[iSt]->GetStdDev()); + } + LOG(info) << '\n' << pResidualsTable->ToString(8); } - - LOG(info) << '\n' << pResidualsTable->ToString(8); - // ----- Checks for pulls // // For the hit pull is defined as a ration of the difference between hit and MC-point position or time component @@ -204,35 +212,36 @@ bool CbmCaInputQaBase<DetID>::Check() // when the resolutions are well determined for detecting stations, the pull distributions should have a RMS equal // to unity. Here we allow a RMS of the pull distributions to be varied in a predefined range. If the RMS runs out // this range, QA task fails. + { + auto* pPullsTable = + MakeQaObject<CbmQaTable>("vs Station/pulls_rms", "Pulls std. dev. values in different stations", nSt, 4); + pPullsTable->SetNamesOfCols({"Station ID", "Pull(x) sigm", "Pull(y) sigm", "Pull(t) sigm"}); + pPullsTable->SetColWidth(20); - auto* pPullsTable = - MakeQaObject<CbmQaTable>("vs Station/pulls_rms", "Pulls std. dev. values in different stations", nSt, 4); - pPullsTable->SetNamesOfCols({"Station ID", "Pull(x) sigm", "Pull(y) sigm", "Pull(t) sigm"}); - pPullsTable->SetColWidth(20); + for (int iSt = 0; iSt < nSt + 1; ++iSt) { - for (int iSt = 0; iSt < nSt + 1; ++iSt) { + // Fit pull distributions for nicer representation. Fit results are not used in further checks. - // Fit pull distributions for nicer representation. Fit results are not used in further checks. + cbm::qa::util::SetLargeStats(fvph_pull_x[iSt]); + cbm::qa::util::SetLargeStats(fvph_pull_y[iSt]); + cbm::qa::util::SetLargeStats(fvph_pull_t[iSt]); - cbm::qa::util::SetLargeStats(fvph_pull_x[iSt]); - cbm::qa::util::SetLargeStats(fvph_pull_y[iSt]); - cbm::qa::util::SetLargeStats(fvph_pull_t[iSt]); + // Check the pull quality + resMap[Form("pull_station_%d_pull_x", iSt)] = CheckRangePull(fvph_pull_x[iSt]); + resMap[Form("pull_station_%d_pull_y", iSt)] = CheckRangePull(fvph_pull_y[iSt]); + resMap[Form("pull_station_%d_pull_t", iSt)] = CheckRangePull(fvph_pull_t[iSt]); - // Check the pull quality - res = CheckRangePull(fvph_pull_x[iSt]) && res; - res = CheckRangePull(fvph_pull_y[iSt]) && res; - res = CheckRangePull(fvph_pull_t[iSt]) && res; + pPullsTable->SetCell(iSt, 0, iSt); + pPullsTable->SetCell(iSt, 1, fvph_pull_x[iSt]->GetStdDev()); + pPullsTable->SetCell(iSt, 2, fvph_pull_y[iSt]->GetStdDev()); + pPullsTable->SetCell(iSt, 3, fvph_pull_t[iSt]->GetStdDev()); + } - pPullsTable->SetCell(iSt, 0, iSt); - pPullsTable->SetCell(iSt, 1, fvph_pull_x[iSt]->GetStdDev()); - pPullsTable->SetCell(iSt, 2, fvph_pull_y[iSt]->GetStdDev()); - pPullsTable->SetCell(iSt, 3, fvph_pull_t[iSt]->GetStdDev()); + LOG(info) << '\n' << pPullsTable->ToString(3); } - - LOG(info) << '\n' << pPullsTable->ToString(3); } // McUsed - return res; + return resMap; } // --------------------------------------------------------------------------------------------------------------------- diff --git a/reco/L1/qa/CbmCaInputQaBase.h b/reco/L1/qa/CbmCaInputQaBase.h index 44a9cc377a728d7909c284ec2dd6716fb3deeab0..b2e623356d33c6fcacc349415f96a05485aadf6b 100644 --- a/reco/L1/qa/CbmCaInputQaBase.h +++ b/reco/L1/qa/CbmCaInputQaBase.h @@ -99,8 +99,9 @@ protected: // ** Virtual method override from CbmQaTask ** // ******************************************** - /// @brief Checks results of the QA and returns some flag - bool Check(); + /// \brief Method to check, if the QA results are acceptable + /// \return Map of checks: key - name of the check, value - result of the check + std::map<std::string, bool> Check(); /// @brief Initializes data branches InitStatus InitDataBranches(); diff --git a/reco/L1/qa/CbmCaInputQaMuch.cxx b/reco/L1/qa/CbmCaInputQaMuch.cxx index 18644b723a102e0572e86ea4ae8074050d55816e..bd6f99474ed00dee8ef68bf7553d6e70dfc1ef2d 100644 --- a/reco/L1/qa/CbmCaInputQaMuch.cxx +++ b/reco/L1/qa/CbmCaInputQaMuch.cxx @@ -20,15 +20,6 @@ CbmCaInputQaMuch::CbmCaInputQaMuch(int verbose, bool isMCUsed) : CbmCaInputQaBas DefineParameters(); } -// --------------------------------------------------------------------------------------------------------------------- -// -bool CbmCaInputQaMuch::Check() -{ - bool res = CbmCaInputQaBase::Check(); - - return res; -} - // --------------------------------------------------------------------------------------------------------------------- // void CbmCaInputQaMuch::DeInit() { CbmCaInputQaBase::DeInit(); } diff --git a/reco/L1/qa/CbmCaInputQaMuch.h b/reco/L1/qa/CbmCaInputQaMuch.h index 8839c8b2b02e56dd7f621aca2d84f3cf25b32183..362b41e198517a3d852f3e14455043d77f9265a7 100644 --- a/reco/L1/qa/CbmCaInputQaMuch.h +++ b/reco/L1/qa/CbmCaInputQaMuch.h @@ -23,9 +23,9 @@ public: CbmCaInputQaMuch(int verbose, bool isMCUsed); protected: - /// @brief Checks results of the QA - /// @return Success flag - bool Check(); + /// \brief Method to check, if the QA results are acceptable + /// \return Map of checks: key - name of the check, value - result of the check + std::map<std::string, bool> Check() { return CbmCaInputQaBase::Check(); } /// @brief Initializes data branches InitStatus InitDataBranches(); diff --git a/reco/L1/qa/CbmCaInputQaMvd.cxx b/reco/L1/qa/CbmCaInputQaMvd.cxx index ce92ecf45231142565b97bf762efc45e22016356..3662273519619d64027bb2f9b09ad4ff728d64af 100644 --- a/reco/L1/qa/CbmCaInputQaMvd.cxx +++ b/reco/L1/qa/CbmCaInputQaMvd.cxx @@ -21,15 +21,6 @@ CbmCaInputQaMvd::CbmCaInputQaMvd(int verbose, bool isMCUsed) : CbmCaInputQaBase( DefineParameters(); } -// --------------------------------------------------------------------------------------------------------------------- -// -bool CbmCaInputQaMvd::Check() -{ - bool res = CbmCaInputQaBase::Check(); - - return res; -} - // --------------------------------------------------------------------------------------------------------------------- // void CbmCaInputQaMvd::DeInit() { CbmCaInputQaBase::DeInit(); } diff --git a/reco/L1/qa/CbmCaInputQaMvd.h b/reco/L1/qa/CbmCaInputQaMvd.h index 08bcfc2fe56cdde40dc1f50e1b6a75a7a352045c..e96b5f23b800fdf70a408d79bdba1e35f8ab646a 100644 --- a/reco/L1/qa/CbmCaInputQaMvd.h +++ b/reco/L1/qa/CbmCaInputQaMvd.h @@ -23,9 +23,9 @@ public: CbmCaInputQaMvd(int verbose, bool isMCUsed); protected: - /// @brief Checks results of the QA - /// @return Success flag - bool Check(); + /// \brief Method to check, if the QA results are acceptable + /// \return Map of checks: key - name of the check, value - result of the check + std::map<std::string, bool> Check() { return CbmCaInputQaBase::Check(); } /// @brief Initializes data branches InitStatus InitDataBranches(); diff --git a/reco/L1/qa/CbmCaInputQaSetup.cxx b/reco/L1/qa/CbmCaInputQaSetup.cxx index 73c80cb5a7ee29b00318d47c7bedf25f96365ef3..b35775c21df0fa4ff44668023e8a2bc9be8128a7 100644 --- a/reco/L1/qa/CbmCaInputQaSetup.cxx +++ b/reco/L1/qa/CbmCaInputQaSetup.cxx @@ -28,7 +28,7 @@ InputQaSetup::InputQaSetup(int verbose, bool isMCUsed) : CbmQaTask("CbmCaInputQa // --------------------------------------------------------------------------------------------------------------------- // -bool InputQaSetup::Check() { return true; } +std::map<std::string, bool> InputQaSetup::Check() { return std::map<std::string, bool>(); } // --------------------------------------------------------------------------------------------------------------------- diff --git a/reco/L1/qa/CbmCaInputQaSetup.h b/reco/L1/qa/CbmCaInputQaSetup.h index e98e56ca33962409f055d843f39173b8e3100381..2e8ebfe839a0a030af7ed2e0a0f062c5038606c4 100644 --- a/reco/L1/qa/CbmCaInputQaSetup.h +++ b/reco/L1/qa/CbmCaInputQaSetup.h @@ -55,7 +55,7 @@ namespace cbm::ca void SetDetectorFlag(ca::EDetectorID detID, bool flag = true) { fvbUseDet[detID] = flag; } /// @brief Checks results of the QA and returns a success flag - bool Check(); + std::map<std::string, bool> Check(); /// @brief Initializes canvases InitStatus InitCanvases(); diff --git a/reco/L1/qa/CbmCaInputQaSts.cxx b/reco/L1/qa/CbmCaInputQaSts.cxx index fd814c877ec11f398f24693d5eadd6c69b983ab4..57342b9371a6ff367184c62ee6d612dfe68bbe5a 100644 --- a/reco/L1/qa/CbmCaInputQaSts.cxx +++ b/reco/L1/qa/CbmCaInputQaSts.cxx @@ -57,17 +57,17 @@ CbmCaInputQaSts::CbmCaInputQaSts(int verbose, bool isMCUsed) : CbmCaInputQaBase( // --------------------------------------------------------------------------------------------------------------------- // -bool CbmCaInputQaSts::Check() +std::map<std::string, bool> CbmCaInputQaSts::Check() { - bool res = CbmCaInputQaBase::Check(); + std::map<std::string, bool> res = CbmCaInputQaBase::Check(); if (IsMCUsed()) { for (int idig = 0; idig <= fkMaxDigisInClusterForPulls; idig++) { cbm::qa::util::SetLargeStats(fvph_pull_u_Ndig[idig]); - res = CheckRangePull(fvph_pull_u_Ndig[idig]) && res; + res[Form("pull_pull_u_%d_digis", idig)] = CheckRangePull(fvph_pull_u_Ndig[idig]); cbm::qa::util::SetLargeStats(fvph_pull_v_Ndig[idig]); - res = CheckRangePull(fvph_pull_v_Ndig[idig]) && res; + res[Form("pull_pull_v_%d_digis", idig)] = CheckRangePull(fvph_pull_v_Ndig[idig]); } } // McUsed diff --git a/reco/L1/qa/CbmCaInputQaSts.h b/reco/L1/qa/CbmCaInputQaSts.h index 7c71d12b5273e881c44f5761a27c8cc102db1154..cc90d094aba5e9e2e9a1cf0f5ce7bedd3df1bd0f 100644 --- a/reco/L1/qa/CbmCaInputQaSts.h +++ b/reco/L1/qa/CbmCaInputQaSts.h @@ -45,8 +45,9 @@ public: CbmCaInputQaSts(int verbose, bool isMCUsed); protected: - /// Checks results of the QA and returns some flag - bool Check(); + /// \brief Method to check, if the QA results are acceptable + /// \return Map of checks: key - name of the check, value - result of the check + std::map<std::string, bool> Check(); /// Initializes data branches InitStatus InitDataBranches(); diff --git a/reco/L1/qa/CbmCaInputQaTof.cxx b/reco/L1/qa/CbmCaInputQaTof.cxx index 71e90d76e81026078062d3a969dd6a213a5eb6d0..e96f4398f8747e07b9ce7877410a6c26fd87d2ea 100644 --- a/reco/L1/qa/CbmCaInputQaTof.cxx +++ b/reco/L1/qa/CbmCaInputQaTof.cxx @@ -47,15 +47,6 @@ CbmCaInputQaTof::CbmCaInputQaTof(int verbose, bool isMCUsed) : CbmCaInputQaBase( DefineParameters(); } -// --------------------------------------------------------------------------------------------------------------------- -// -bool CbmCaInputQaTof::Check() -{ - bool res = CbmCaInputQaBase::Check(); - - return res; -} - // --------------------------------------------------------------------------------------------------------------------- // void CbmCaInputQaTof::DeInit() diff --git a/reco/L1/qa/CbmCaInputQaTof.h b/reco/L1/qa/CbmCaInputQaTof.h index 49a99189b0c4df72bf6f738195350c658d63ea0c..a8cb8f288a9a454271140bcbee626163fc148c6b 100644 --- a/reco/L1/qa/CbmCaInputQaTof.h +++ b/reco/L1/qa/CbmCaInputQaTof.h @@ -50,9 +50,9 @@ public: CbmCaInputQaTof(int verbose, bool isMCUsed); protected: - /// @brief Checks results of the QA - /// @return Success flag - bool Check(); + /// \brief Method to check, if the QA results are acceptable + /// \return Map of checks: key - name of the check, value - result of the check + std::map<std::string, bool> Check() { return CbmCaInputQaBase::Check(); } /// @brief Initializes data branches InitStatus InitDataBranches(); diff --git a/reco/L1/qa/CbmCaInputQaTrd.cxx b/reco/L1/qa/CbmCaInputQaTrd.cxx index f3a8e536fd40f6dc0bb3131db7e277afe38a873b..e472fdd7d4ed641c890ae0eb105e78649cf9bcd9 100644 --- a/reco/L1/qa/CbmCaInputQaTrd.cxx +++ b/reco/L1/qa/CbmCaInputQaTrd.cxx @@ -20,15 +20,6 @@ CbmCaInputQaTrd::CbmCaInputQaTrd(int verbose, bool isMCUsed) : CbmCaInputQaBase( DefineParameters(); } -// --------------------------------------------------------------------------------------------------------------------- -// -bool CbmCaInputQaTrd::Check() -{ - bool res = CbmCaInputQaBase::Check(); - - return res; -} - // --------------------------------------------------------------------------------------------------------------------- // void CbmCaInputQaTrd::DeInit() { CbmCaInputQaBase::DeInit(); } diff --git a/reco/L1/qa/CbmCaInputQaTrd.h b/reco/L1/qa/CbmCaInputQaTrd.h index c6080bd087eebee692190c2a71894142396e027a..faafccc471c8685a2b66e5cb081f2cad79cb6d3a 100644 --- a/reco/L1/qa/CbmCaInputQaTrd.h +++ b/reco/L1/qa/CbmCaInputQaTrd.h @@ -23,9 +23,9 @@ public: CbmCaInputQaTrd(int verbose, bool isMCUsed); protected: - /// @brief Checks results of the QA - /// @return Success flag - bool Check(); + /// \brief Method to check, if the QA results are acceptable + /// \return Map of checks: key - name of the check, value - result of the check + std::map<std::string, bool> Check() { return CbmCaInputQaBase::Check(); } /// @brief Initializes data branches InitStatus InitDataBranches(); diff --git a/reco/L1/qa/CbmCaOutputQa.cxx b/reco/L1/qa/CbmCaOutputQa.cxx index 66a1dbab496c21be917e3a2894d125c3c11aba1a..96480667ea75fad1e1c4959714be1b92bec44ffc 100644 --- a/reco/L1/qa/CbmCaOutputQa.cxx +++ b/reco/L1/qa/CbmCaOutputQa.cxx @@ -565,7 +565,7 @@ InitStatus OutputQa::InitHistograms() // --------------------------------------------------------------------------------------------------------------------- // -bool OutputQa::Check() +std::map<std::string, bool> OutputQa::Check() { // Create summary table if (IsMCUsed()) { @@ -612,7 +612,7 @@ bool OutputQa::Check() LOG(info) << '\n' << fMonitor.ToString(); - return true; + return std::map<std::string, bool>(); } // --------------------------------------------------------------------------------------------------------------------- diff --git a/reco/L1/qa/CbmCaOutputQa.h b/reco/L1/qa/CbmCaOutputQa.h index 8908894b4af82783bd0e318b3fd01ab4c0462057..90afb81c5db3c41c1af6dec2f55f17f969c6982f 100644 --- a/reco/L1/qa/CbmCaOutputQa.h +++ b/reco/L1/qa/CbmCaOutputQa.h @@ -194,10 +194,9 @@ namespace cbm::ca ClassDef(OutputQa, 0); protected: - /// @brief Checks results of the QA and returns a success flag - /// @return true QA is passed - /// @return false QA is failed - bool Check(); + /// \brief Method to check, if the QA results are acceptable + /// \return Map of checks: key - name of the check, value - result of the check + std::map<std::string, bool> Check(); /// @brief Initializes canvases InitStatus InitCanvases();