13#include "FairRootFileSink.h"
14#include "FairRootManager.h"
15#include "FairRunAna.h"
18#include "TClonesArray.h"
33 : FairTask(name, verbose)
48 for (
int iEvt = 0; iEvt < nEvents; ++iEvt) {
70 auto* pSink = FairRootManager::Instance()->GetSink();
71 LOG_IF(fatal, !pSink) << fName <<
": output sink is undefined";
72 if (
dynamic_cast<FairRootFileSink*
>(pSink)) {
73 auto* pRootSink =
static_cast<FairRootFileSink*
>(pSink);
74 auto* pRootFile = pRootSink->GetRootFile();
75 if (!pRootFile->FindObjectAny(
"nEvents")) {
82 LOG(warn) << fName <<
": objects cannot be written into online sink (not implemented yet)";
90 LOG_IF(info, fVerbose > 0) << fName <<
": initializing task ...";
91 InitStatus res = kSUCCESS;
97 LOG_IF(info, fVerbose > 1) << fName <<
": initializing histograms";
98 res = std::max(res, this->
InitQa());
102 fpBrEvents =
dynamic_cast<TClonesArray*
>(FairRootManager::Instance()->GetObject(
"CbmEvent"));
104 LOG_IF(info, fVerbose > 1) << fName <<
": the routine will run on reconstructed events";
107 LOG_IF(info, fVerbose > 1) << fName <<
": the routine will run on timeslices, the CbmEvent branch is undefined";
112 LOG_IF(info, fVerbose > 1) << fName <<
": the routine will run on timeslices";
146 double mean =
h->GetMean();
147 double meanErr =
h->GetMeanError();
149 double rms =
h->GetStdDev();
150 double rmsErr =
h->GetStdDevError();
153 if (
h->GetEntries() >= 10) {
154 res =
CheckRange(TString(
"Mean for ") +
h->GetTitle(), mean, meanErr, -meanMax, meanMax) && res;
155 res =
CheckRange(TString(
"RMS for ") +
h->GetTitle(), rms, rmsErr, rmsMin, rmsMax) && res;
164 YAML::Node tagNode =
fConfigNode[
"check_histograms"];
168 std::size_t operator()(
const TString& str)
const {
return std::hash<std::string>()(str.Data()); };
172 std::unordered_map<TString, ObjectComparisonConfig, HashTString> mCompareList;
174 for (
const auto& histNode : tagNode) {
176 auto histName =
fsRootFolderName +
"/" + histNode[
"name"].as<std::string>().c_str();
178 if (
const auto& subNode = histNode[
"point_to_point"]) {
179 entry.
fPoint = subNode[
"use"].as<uint8_t>();
181 if (
const auto& subNode = histNode[
"ratio"]) {
182 entry.
fRatio = subNode[
"use"].as<uint8_t>();
183 entry.
fRatioMin = subNode[
"min"].as<
double>();
184 entry.
fRatioMax = subNode[
"max"].as<
double>();
186 if (
const auto& subNode = histNode[
"chi2Test"]) {
187 entry.
fStat = subNode[
"use"].as<uint8_t>();
188 entry.
fChi2NdfMax = subNode[
"chi2_ndf_max"].as<
double>();
190 if (
const auto& subNode = histNode[
"canvas"]) {
192 if (subNode[
"comp"].as<bool>(
false)) {
195 if (subNode[
"ratio"].as<bool>(
false)) {
198 if (subNode[
"diff"].as<bool>(
false)) {
202 mCompareList[histName] = entry;
204 catch (
const YAML::InvalidNode& exc) {
205 LOG(warn) << fName <<
"::CompareQaObjects(): attempt to access key which does not exist in the configuration"
206 <<
" file (message from YAML exception: " << exc.what() <<
')';
213 bool bCheckResult =
true;
214 for (
auto& [pObject, sPath] : (*
fpvObjList)) {
217 TString objName = sPath +
"/" + pObject->GetName();
218 auto configEntryIt = mCompareList.find(objName);
219 if (configEntryIt == mCompareList.end()) {
222 const auto& configEntry = configEntryIt->second;
227 LOG(warn) << fName <<
"::CompareQaObjects(): ROOT object " << objName <<
" is not found in the check file";
232 if (
dynamic_cast<TProfile*
>(pObject)) {
235 else if (
dynamic_cast<TH2*
>(pObject)) {
238 else if (
dynamic_cast<TH1*
>(pObject)) {
252 auto* paveText =
new TPaveText(xMin, yMin, xMax, yMax,
"NDC");
254 paveText->SetBorderSize(0);
255 paveText->SetTextSize(0.04);
256 paveText->SetFillStyle(0);
257 paveText->Draw(
"same");
267 std::vector<char> vbConfigKeyUsed;
268 std::vector<char> vbCheckKeyProcessed(
fmCheckList.size(),
false);
269 vbConfigKeyUsed.reserve(tagNode.size());
270 std::regex rexInt(
"%d");
272 for (
auto it = tagNode.begin(); it != tagNode.end(); ++it) {
273 std::string configEntry = it->first.as<std::string>();
274 if (
static_cast<int>(configEntry.find_last_of(
"%d")) != -1) {
275 vbConfigKeyUsed.push_back(
true);
276 bool bCheckStatus = it->second.as<
bool>();
277 std::regex keyRex = std::regex(std::regex_replace(configEntry, rexInt,
"([0-9]+)"));
279 for (
auto& [checkEntry, checkFlags] :
fmCheckList) {
280 if (!vbCheckKeyProcessed[iCheckEntry] && std::regex_match(checkEntry, keyRex)) {
281 vbCheckKeyProcessed[iCheckEntry] =
true;
282 checkFlags.fStatus = bCheckStatus;
288 vbConfigKeyUsed.push_back(
false);
292 int iConfigEntry = 0;
293 for (
auto it = tagNode.begin(); it != tagNode.end(); ++it) {
294 if (!vbConfigKeyUsed[iConfigEntry]) {
295 std::string configEntry = it->first.as<std::string>();
298 checkListIt->second.fStatus = it->second.as<
bool>();
301 LOG(warn) << fName <<
"::ReadCheckListFromConfig(): config contains unknown entry " << configEntry;
ECbmRecoMode
Reconstruct the full time slice or event-by-event.
A base class for CBM QA task logic.
Class characterising one event by a collection of links (indices) to data objects,...
ROOT object IO interface for QA.
void WriteToFile(TFile *pOutFile) const
Writes objects into file.
YAML::Node fConfigNode
Configuration node.
std::shared_ptr< ObjList_t > fpvObjList
List of registered ROOT objects.
TString fsRootFolderName
Name of root folder.
@ kSUBDIR
Objects of different type will be stored in different subdirectories like histograms/ canvases/.
void SetRootFolderName(const TString &path)
Sets a common root path to the objects in the output file.
EStoringMode fStoringMode
Objects storing mode.
virtual void CreateSummary()
Initializes QA-task summary: canvases, tables etc.
std::string fsSetupName
Name of the setup (to draw on the canvases)
bool CheckRange(std::string_view name, T var, T lo, T hi) const
Checks range of variable.
virtual void DeInit()
De-initialize the task.
std::map< std::string, CheckFlags > fmCheckList
A QA check-list map.
InitStatus Init() override final
FairTask: Task initialization in the beginning of the run.
bool CompareQaObjects()
Process ROOT objects comparison.
void DeInitBase()
De-initializes this task.
std::shared_ptr< TFile > fpBenchmarkInput
A file with default ROOT objects used for the cross-check.
virtual void ExecQa()
Method to fill histograms per event or time-slice.
virtual InitStatus InitQa()
Initializes the task.
void Exec(Option_t *) override final
FairTask: Defines action of the task in the event/TS.
bool CompareTwoObjects(const TObject *pObjL, const TObject *pObjR, const TString &objName, const ObjectComparisonConfig &cfg)
Process object comparison.
void StoreCheckResult(const std::string &tag, bool result, const std::string &msg="")
Stores check flag to the check-list.
CbmQaTask()=delete
Default constructor.
void ReadCheckListFromConfig()
Reads check-list from the configuration file.
TParameter< int > fNofEvents
Number of processed events.
void PutSetupNameOnPad(double xMin, double yMin, double xMax, double yMax)
Puts setup title on the canvas.
TClonesArray * fpBrEvents
Pointer to CbmEvent branch.
CbmEvent * fpCurrentEvent
Pointer to the current event.
ECbmRecoMode fRecoMode
Reconstruction mode.
void Finish() override final
FairTask: Defines action of the task in the end of run.
InitStatus ReInit() override final
FairTask: Task reinitialization.
Data class with information on a STS local track.
Contains a check result and its activeness status of the check-list entry.
Contains configuration to compare two root objects (histograms)