Skip to content
Snippets Groups Projects
CbmQaTask.cxx 4.26 KiB
/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
   SPDX-License-Identifier: GPL-3.0-only
   Authors: Sergei Zharko [committer] */

/// \file   CbmQaTask.cxx
/// \brief  A base class for CBM QA task logic (implementation)
/// \author S.Zharko <s.zharko@lx-pool.gsi.de>
/// \data   12.01.2023


#include "CbmQaTask.h"

#include "FairRootFileSink.h"
#include "FairRootManager.h"
#include "FairRunAna.h"

#include "TAxis.h"
#include "TCanvas.h"
#include "TF1.h"
#include "TString.h"

#include <array>

ClassImp(CbmQaTask);

// ---------------------------------------------------------------------------------------------------------------------
//
CbmQaTask::CbmQaTask(const char* name, int verbose, bool isMCUsed)
  : FairTask(name, verbose)
  , CbmQaIO(name)
  , fbUseMC(isMCUsed)
{
  CbmQaIO::SetRootFolderName(name);
  fStoringMode = CbmQaIO::EStoringMode::kSUBDIR;  // mode of objects arrangement in the output file
}

// ---------------------------------------------------------------------------------------------------------------------
//
void CbmQaTask::Exec(Option_t* /*option*/)
{
  fNofEvents.SetVal(fNofEvents.GetVal() + 1);
  this->InitTimeSlice();
  this->FillHistograms();
}

// ---------------------------------------------------------------------------------------------------------------------
//
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
  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)";
  }
}

// ---------------------------------------------------------------------------------------------------------------------
//
InitStatus CbmQaTask::Init()
{
  LOG_IF(info, fVerbose > 0) << fName << ": initializing task ...";
  InitStatus res = kSUCCESS;

  // ----- Clear map of the histograms (note)
  DeInitBase();

  // ----- Initialize data branches
  LOG_IF(info, fVerbose > 1) << fName << ": initializing input data branches";
  res = std::max(res, InitDataBranches());

  // ----- Initialize histograms
  LOG_IF(info, fVerbose > 1) << fName << ": initializing histograms";
  res = std::max(res, InitHistograms());

  fNofEvents.SetVal(0);

  return res;
}

// ---------------------------------------------------------------------------------------------------------------------
//
InitStatus CbmQaTask::ReInit()
{
  LOG_IF(info, fVerbose > 2) << fName << "::DeInitBase() is called";
  return Init();
}

// ---------------------------------------------------------------------------------------------------------------------
//
void CbmQaTask::DeInitBase()
{
  LOG_IF(info, fVerbose > 2) << fName << "::DeInitBase() is called";
  // De-initialize basic data members
  // ...

  // De-initialize particular QA-task implementation
  DeInit();
}


// ---------------------------------------------------------------------------------------------------------------------
//
bool CbmQaTask::CheckRange(TH1* h, double meanMax, double rmsMin, double rmsMax)
{
  // Checks ranges for mean and standard deviation
  // \return  False, if variable exits the range

  double mean    = h->GetMean();
  double meanErr = h->GetMeanError();

  double rms    = h->GetStdDev();
  double rmsErr = h->GetStdDevError();

  bool res = true;
  if (h->GetEntries() >= 10) {  // ask for some statistics, otherwise errors are not properly estimated
    res = CheckRange(TString("Mean for ") + h->GetTitle(), mean, meanErr, -meanMax, meanMax) && res;
    res = CheckRange(TString("RMS for ") + h->GetTitle(), rms, rmsErr, rmsMin, rmsMax) && res;
  }
  return res;
}