From b8ee555b36528fa3abb439be1db83c89fb6a4e3e Mon Sep 17 00:00:00 2001 From: Dmitri Peresunko Date: Tue, 7 Jun 2022 00:16:33 +0300 Subject: [PATCH] mergable histos implemented; separate HG/LG pedestal histos --- Modules/PHOS/CMakeLists.txt | 8 +- Modules/PHOS/include/PHOS/LinkDef.h | 4 + Modules/PHOS/include/PHOS/RawCheck.h | 2 +- Modules/PHOS/include/PHOS/RawQcTask.h | 107 ++++-- Modules/PHOS/include/PHOS/TH2FMean.h | 48 +++ Modules/PHOS/include/PHOS/TH2SBitmask.h | 48 +++ Modules/PHOS/src/ClusterQcTask.cxx | 24 +- Modules/PHOS/src/RawCheck.cxx | 7 +- Modules/PHOS/src/RawQcTask.cxx | 481 +++++++++++++++++------- Modules/PHOS/src/TH2FMean.cxx | 37 ++ Modules/PHOS/src/TH2SBitmask.cxx | 34 ++ 11 files changed, 599 insertions(+), 201 deletions(-) create mode 100644 Modules/PHOS/include/PHOS/TH2FMean.h create mode 100644 Modules/PHOS/include/PHOS/TH2SBitmask.h create mode 100644 Modules/PHOS/src/TH2FMean.cxx create mode 100644 Modules/PHOS/src/TH2SBitmask.cxx diff --git a/Modules/PHOS/CMakeLists.txt b/Modules/PHOS/CMakeLists.txt index 38043fcaec..13d73e157c 100644 --- a/Modules/PHOS/CMakeLists.txt +++ b/Modules/PHOS/CMakeLists.txt @@ -2,7 +2,9 @@ add_library(O2QcPHOS) -target_sources(O2QcPHOS PRIVATE src/RawQcTask.cxx +target_sources(O2QcPHOS PRIVATE src/TH2FMean.cxx + src/TH2SBitmask.cxx + src/RawQcTask.cxx src/RawCheck.cxx src/ClusterQcTask.cxx src/ClusterCheck.cxx @@ -17,7 +19,9 @@ target_include_directories( target_link_libraries(O2QcPHOS PUBLIC O2QualityControl O2::PHOSBase O2::PHOSReconstruction ROOT::Spectrum) add_root_dictionary(O2QcPHOS - HEADERS include/PHOS/ClusterQcTask.h + HEADERS include/PHOS/TH2FMean.h + include/PHOS/TH2SBitmask.h + include/PHOS/ClusterQcTask.h include/PHOS/ClusterCheck.h include/PHOS/RawQcTask.h include/PHOS/RawCheck.h diff --git a/Modules/PHOS/include/PHOS/LinkDef.h b/Modules/PHOS/include/PHOS/LinkDef.h index 8245e5577b..86e9967fb3 100644 --- a/Modules/PHOS/include/PHOS/LinkDef.h +++ b/Modules/PHOS/include/PHOS/LinkDef.h @@ -3,6 +3,10 @@ #pragma link off all classes; #pragma link off all functions; +#pragma link C++ class o2::quality_control_modules::phos::TH2SBitmask + ; + +#pragma link C++ class o2::quality_control_modules::phos::TH2FMean + ; + #pragma link C++ class o2::quality_control_modules::phos::ClusterQcTask + ; #pragma link C++ class o2::quality_control_modules::phos::ClusterCheck + ; diff --git a/Modules/PHOS/include/PHOS/RawCheck.h b/Modules/PHOS/include/PHOS/RawCheck.h index 079dd35e1a..847c5b3e62 100644 --- a/Modules/PHOS/include/PHOS/RawCheck.h +++ b/Modules/PHOS/include/PHOS/RawCheck.h @@ -41,7 +41,7 @@ class RawCheck final : public o2::quality_control::checker::CheckInterface // Override interface void configure() override; Quality check(std::map>* moMap) override; - void beautify(std::shared_ptr mo, Quality checkResult = Quality::Null) override; + void beautify(std::shared_ptr mo, Quality checkResult = Quality::Null) override {} std::string getAcceptedType() override; protected: diff --git a/Modules/PHOS/include/PHOS/RawQcTask.h b/Modules/PHOS/include/PHOS/RawQcTask.h index 1fc5f6d5ce..1b1337c206 100644 --- a/Modules/PHOS/include/PHOS/RawQcTask.h +++ b/Modules/PHOS/include/PHOS/RawQcTask.h @@ -29,6 +29,8 @@ class TH2F; #include "DataFormatsPHOS/BadChannelsMap.h" #include +#include "PHOS/TH2FMean.h" +#include "PHOS/TH2SBitmask.h" using namespace o2::quality_control::core; @@ -54,7 +56,7 @@ class RawQcTask final : public TaskInterface void reset() override; protected: - static constexpr short kNhist1D = 23; + static constexpr short kNhist1D = 27; enum histos1D { kTotalDataVolume, kMessageCounter, kBadMapSummary, @@ -74,15 +76,18 @@ class RawQcTask final : public TaskInterface kLGrmsSummaryM2, kLGrmsSummaryM3, kLGrmsSummaryM4, - kCellSpM1, - kCellSpM2, - kCellSpM3, - kCellSpM4 + kCellHGSpM1, + kCellHGSpM2, + kCellHGSpM3, + kCellHGSpM4, + kCellLGSpM1, + kCellLGSpM2, + kCellLGSpM3, + kCellLGSpM4 }; - static constexpr short kNhist2D = 51; + static constexpr short kNhist2D = 42; enum histos2D { kErrorNumber, - kErrorType, kPayloadSizePerDDL, kChi2M1, kChi2M2, @@ -92,22 +97,6 @@ class RawQcTask final : public TaskInterface kChi2NormM2, kChi2NormM3, kChi2NormM4, - kHGmeanM1, - kHGmeanM2, - kHGmeanM3, - kHGmeanM4, - kLGmeanM1, - kLGmeanM2, - kLGmeanM3, - kLGmeanM4, - kHGrmsM1, - kHGrmsM2, - kHGrmsM3, - kHGrmsM4, - kLGrmsM1, - kLGrmsM2, - kLGrmsM3, - kLGrmsM4, kHGoccupM1, kHGoccupM2, kHGoccupM3, @@ -116,22 +105,60 @@ class RawQcTask final : public TaskInterface kLGoccupM2, kLGoccupM3, kLGoccupM4, - kCellOccupM1, - kCellOccupM2, - kCellOccupM3, - kCellOccupM4, - kCellEM1, - kCellEM2, - kCellEM3, - kCellEM4, kTimeEM1, kTimeEM2, kTimeEM3, kTimeEM4, - kLEDNpeaksM1, - kLEDNpeaksM2, - kLEDNpeaksM3, - kLEDNpeaksM4 }; + kTRUSTOccupM1, + kTRUSTOccupM2, + kTRUSTOccupM3, + kTRUSTOccupM4, + kTRUDGOccupM1, + kTRUDGOccupM2, + kTRUDGOccupM3, + kTRUDGOccupM4, + kTRUSTMatchM1, + kTRUSTMatchM2, + kTRUSTMatchM3, + kTRUSTMatchM4, + kTRUSTFakeM1, + kTRUSTFakeM2, + kTRUSTFakeM3, + kTRUSTFakeM4, + kTRUDGFakeM1, + kTRUDGFakeM2, + kTRUDGFakeM3, + kTRUDGFakeM4 }; + + static constexpr short kNhist2DMean = 24; + enum histos2DMean { kHGmeanM1, + kHGmeanM2, + kHGmeanM3, + kHGmeanM4, + kLGmeanM1, + kLGmeanM2, + kLGmeanM3, + kLGmeanM4, + kHGrmsM1, + kHGrmsM2, + kHGrmsM3, + kHGrmsM4, + kLGrmsM1, + kLGrmsM2, + kLGrmsM3, + kLGrmsM4, + kCellEM1, + kCellEM2, + kCellEM3, + kCellEM4, + kLEDNpeaksM1, + kLEDNpeaksM2, + kLEDNpeaksM3, + kLEDNpeaksM4 + }; + + static constexpr short kNhist2DBitmask = 1; + enum histos2DBitmask { kErrorType }; void InitHistograms(); @@ -142,6 +169,9 @@ class RawQcTask final : public TaskInterface void CreateLEDHistograms(); void FillLEDHistograms(const gsl::span& cells, const gsl::span& tr); + void CreateTRUHistograms(); + void FillTRUHistograms(const gsl::span& cells, const gsl::span& tr); + private: static constexpr short kNmod = 6; static constexpr short kMaxErr = 5; @@ -150,9 +180,12 @@ class RawQcTask final : public TaskInterface int mMode = 0; ///< Possible modes: 0(def): Physics, 1: Pedestals, 2: LED bool mFinalized = false; ///< if final histograms calculated bool mCheckChi2 = false; ///< scan Chi2 distributions + bool mTrNoise = false; ///< check mathing of trigger summary tables and tr.digits - std::array mHist1D = { nullptr }; ///< Array of 1D histograms - std::array mHist2D = { nullptr }; ///< Array of 2D histograms + std::array mHist1D = { nullptr }; ///< Array of 1D histograms + std::array mHist2D = { nullptr }; ///< Array of 2D histograms + std::array mHist2DMean = { nullptr }; ///< Array of 2D mean histograms + std::array mHist2DBitmask = { nullptr }; ///< Array of 2D mean histograms bool mInitBadMap = true; //! BadMap had to be initialized const o2::phos::BadChannelsMap* mBadMap = nullptr; //! Bad map for comparison diff --git a/Modules/PHOS/include/PHOS/TH2FMean.h b/Modules/PHOS/include/PHOS/TH2FMean.h new file mode 100644 index 0000000000..2e5fea8bcf --- /dev/null +++ b/Modules/PHOS/include/PHOS/TH2FMean.h @@ -0,0 +1,48 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// \file TH2FMean.h +/// \author Dmitri Peresunko +/// + +#ifndef QC_MODULE_PHOS_TH2FMEAN_H +#define QC_MODULE_PHOS_TH2FMEAN_H + +#include "QualityControl/TaskInterface.h" +#include +#include "Mergers/MergeInterface.h" + +namespace o2::quality_control_modules::phos +{ + +/// \brief Custom TH2F class with special merger + +class TH2FMean : public TH2F, public o2::mergers::MergeInterface +{ + public: + /// \brief Constructor. + TH2FMean() = default; + TH2FMean(const char* name, const char* title, Int_t nbinsx, Double_t xlow, Double_t xup, Int_t nbinsy, Double_t ylow, Double_t yup) : TH2F(name, title, nbinsx, xlow, xup, nbinsy, ylow, yup) {} + /// \brief Default destructor + virtual ~TH2FMean() = default; + + void merge(MergeInterface* const other) override; + + private: + std::string mTreatMeAs = "TH2F"; // the name of the class this object should be considered as when drawing in QCG. + + ClassDefOverride(TH2FMean, 1); +}; + +} // namespace o2::quality_control_modules::phos + +#endif // QC_MODULE_PHOS_TH2FMEAN_H diff --git a/Modules/PHOS/include/PHOS/TH2SBitmask.h b/Modules/PHOS/include/PHOS/TH2SBitmask.h new file mode 100644 index 0000000000..6c0ac4725b --- /dev/null +++ b/Modules/PHOS/include/PHOS/TH2SBitmask.h @@ -0,0 +1,48 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// \file TH2SBitmask.h +/// \author Dmitri Peresunko +/// + +#ifndef QC_MODULE_PHOS_TH2FBITMASK_H +#define QC_MODULE_PHOS_TH2FBITMASK_H + +#include "QualityControl/TaskInterface.h" +#include +#include "Mergers/MergeInterface.h" + +namespace o2::quality_control_modules::phos +{ + +/// \brief Custom TH2S class with special merger combining bit masks + +class TH2SBitmask : public TH2S, public o2::mergers::MergeInterface +{ + public: + /// \brief Constructor. + TH2SBitmask() = default; + TH2SBitmask(const char* name, const char* title, Int_t nbinsx, Double_t xlow, Double_t xup, Int_t nbinsy, Double_t ylow, Double_t yup) : TH2S(name, title, nbinsx, xlow, xup, nbinsy, ylow, yup) {} + /// \brief Default destructor + ~TH2SBitmask() = default; + + void merge(MergeInterface* const other) override; + + private: + std::string mTreatMeAs = "TH2S"; // the name of the class this object should be considered as when drawing in QCG. + + ClassDefOverride(TH2SBitmask, 1); +}; + +} // namespace o2::quality_control_modules::phos + +#endif // QC_MODULE_PHOS_TH2FBITMASK_H diff --git a/Modules/PHOS/src/ClusterQcTask.cxx b/Modules/PHOS/src/ClusterQcTask.cxx index 1255ecdc9a..17ed926058 100644 --- a/Modules/PHOS/src/ClusterQcTask.cxx +++ b/Modules/PHOS/src/ClusterQcTask.cxx @@ -26,7 +26,7 @@ #include "DataFormatsPHOS/TriggerRecord.h" #include "Framework/InputRecord.h" -//using namespace o2::phos; +// using namespace o2::phos; namespace o2::quality_control_modules::phos { @@ -61,13 +61,13 @@ void ClusterQcTask::initialize(o2::framework::InitContext& /*ctx*/) ILOG(Info, Support) << "Custom parameter - myOwnKey : " << param->second << AliceO2::InfoLogger::InfoLogger::endm; } - //read alignment to calculate cluster global coordinates + // read alignment to calculate cluster global coordinates mGeom = o2::phos::Geometry::GetInstance("Run3"); - //TODO: configure reading bad map from CCDB + // TODO: configure reading bad map from CCDB mBadMap.reset(new o2::phos::BadChannelsMap()); - //Prepare histograms + // Prepare histograms for (Int_t mod = 0; mod < 4; mod++) { if (!mHist2D[kOccupancyM1 + mod]) { mHist2D[kOccupancyM1 + mod] = new TH2F(Form("ClusterOccupancyM%d", mod + 1), Form("Cluster occupancy, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); @@ -84,11 +84,11 @@ void ClusterQcTask::initialize(o2::framework::InitContext& /*ctx*/) } if (!mHist2D[kTimeEM1 + mod]) { - mHist2D[kTimeEM1 + mod] = new TH2F(Form("TimevsE%d", mod + 1), Form("Cell time vs energy, mod %d", mod + 1), 50, 0., 10., 50, -2.e-7, 2.e-7); + mHist2D[kTimeEM1 + mod] = new TH2F(Form("TimevsE%d", mod + 1), Form("Cluster time vs energy, mod %d", mod + 1), 50, 0., 10., 50, -5.e-7, 5.e-7); mHist2D[kTimeEM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); mHist2D[kTimeEM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); - mHist2D[kTimeEM1 + mod]->GetXaxis()->SetTitle("x, cells"); - mHist2D[kTimeEM1 + mod]->GetYaxis()->SetTitle("z, cells"); + mHist2D[kTimeEM1 + mod]->GetXaxis()->SetTitle("E, GeV"); + mHist2D[kTimeEM1 + mod]->GetYaxis()->SetTitle("t-t_{0}, ns"); mHist2D[kTimeEM1 + mod]->SetStats(0); mHist2D[kTimeEM1 + mod]->SetMinimum(0); // mHist2D[kTimeEM1 + mod]->SetMaximum(100); @@ -151,13 +151,11 @@ void ClusterQcTask::monitorData(o2::framework::ProcessingContext& ctx) } int mod = clu.module(); - //Fill occupancy and time-E histos + // Fill occupancy and time-E histos float posX, posZ; clu.getLocalPosition(posX, posZ); - short absId; - mGeom->relPosToAbsId(mod, posX, posZ, absId); char relid[3]; - mGeom->absToRelNumbering(absId, relid); + mGeom->relPosToRelId(mod, posX, posZ, relid); if (e > mOccCut) { mHist2D[kOccupancyM1 + mod - 1]->Fill(relid[1] - 0.5, relid[2] - 0.5); @@ -183,7 +181,7 @@ void ClusterQcTask::monitorData(o2::framework::ProcessingContext& ctx) } } -} //function monitor data +} // function monitor data void ClusterQcTask::endOfCycle() { @@ -212,7 +210,7 @@ void ClusterQcTask::reset() } bool ClusterQcTask::checkCluster(const o2::phos::Cluster& clu) { - //First check BadMap + // First check BadMap float posX, posZ; clu.getLocalPosition(posX, posZ); short absId; diff --git a/Modules/PHOS/src/RawCheck.cxx b/Modules/PHOS/src/RawCheck.cxx index 08c66ad8a8..bae99455ad 100644 --- a/Modules/PHOS/src/RawCheck.cxx +++ b/Modules/PHOS/src/RawCheck.cxx @@ -97,7 +97,6 @@ void RawCheck::configure() Quality RawCheck::check(std::map>* moMap) { - mCheckResult = Quality::Null; for (auto& [moName, mo] : *moMap) { (void)moName; // trick the compiler about not used variable @@ -116,10 +115,6 @@ Quality RawCheck::check(std::map>* m std::string RawCheck::getAcceptedType() { return "TH1"; } -void RawCheck::beautify(std::shared_ptr mo, Quality checkResult) -{ -} - bool RawCheck::checkErrHistograms(MonitorObject* mo) { // Return true if mo found and handled @@ -136,7 +131,7 @@ bool RawCheck::checkErrHistograms(MonitorObject* mo) return true; } if (mo->getName().find("ErrorTypePerDDL") != std::string::npos) { // HG mean summary 100, 0., 100. - TH2F* h = dynamic_cast(mo->getObject()); + TH2S* h = dynamic_cast(mo->getObject()); if (h->Integral() == 0) { TPaveText* msg = new TPaveText(0., 0.8, 0.2, 0.9, "NDC"); msg->SetName(Form("%s_msg", mo->GetName())); diff --git a/Modules/PHOS/src/RawQcTask.cxx b/Modules/PHOS/src/RawQcTask.cxx index c8797382dd..6863e46b89 100644 --- a/Modules/PHOS/src/RawQcTask.cxx +++ b/Modules/PHOS/src/RawQcTask.cxx @@ -36,7 +36,6 @@ namespace o2::quality_control_modules::phos RawQcTask::~RawQcTask() { - for (int i = kNhist1D; i--;) { if (mHist1D[i]) { mHist1D[i]->Delete(); @@ -49,6 +48,18 @@ RawQcTask::~RawQcTask() mHist2D[i] = nullptr; } } + for (int i = kNhist2DMean; i--;) { + if (mHist2DMean[i]) { + mHist2DMean[i]->Delete(); + mHist2DMean[i] = nullptr; + } + } + for (int i = kNhist2DBitmask; i--;) { + if (mHist2DBitmask[i]) { + mHist2DBitmask[i]->Delete(); + mHist2DBitmask[i] = nullptr; + } + } } void RawQcTask::initialize(o2::framework::InitContext& /*ctx*/) { @@ -85,6 +96,12 @@ void RawQcTask::initialize(o2::framework::InitContext& /*ctx*/) mCheckChi2 = true; } } + if (auto param = mCustomParameters.find("trignoise"); param != mCustomParameters.end()) { + ILOG(Info, Support) << "Scan trigger ST and Dig matching " << AliceO2::InfoLogger::InfoLogger::endm; + if (param->second.find("on") != std::string::npos) { + mTrNoise = true; + } + } InitHistograms(); } @@ -102,12 +119,12 @@ void RawQcTask::InitHistograms() mHist2D[kErrorNumber]->SetStats(0); getObjectsManager()->startPublishing(mHist2D[kErrorNumber]); - mHist2D[kErrorType] = new TH2F("ErrorTypePerDDL", "ErrorTypePerDDL", 32, 0, 32, 15, 0, 15.); - mHist2D[kErrorType]->GetXaxis()->SetTitle("FEE card"); - mHist2D[kErrorType]->GetYaxis()->SetTitle("DDL"); - mHist2D[kErrorType]->SetDrawOption("colz"); - mHist2D[kErrorType]->SetStats(0); - getObjectsManager()->startPublishing(mHist2D[kErrorType]); + mHist2DBitmask[kErrorType] = new TH2SBitmask("ErrorTypePerDDL", "ErrorTypePerDDL", 32, 0, 32, 15, 0, 15.); + mHist2DBitmask[kErrorType]->GetXaxis()->SetTitle("FEE card"); + mHist2DBitmask[kErrorType]->GetYaxis()->SetTitle("DDL"); + mHist2DBitmask[kErrorType]->SetDrawOption("colz"); + mHist2DBitmask[kErrorType]->SetStats(0); + getObjectsManager()->startPublishing(mHist2DBitmask[kErrorType]); mHist1D[kBadMapSummary] = new TH1F("BadMapSummary", "Number of bad channels", 4, 1., 5.); // xaxis: FEE card number + 2 for TRU and global errors mHist1D[kBadMapSummary]->GetXaxis()->SetTitle("module"); @@ -145,12 +162,15 @@ void RawQcTask::InitHistograms() if (mMode == 0) { // Physics CreatePhysicsHistograms(); + // CreateTRUHistograms(); } if (mMode == 1) { // Pedestals CreatePedestalHistograms(); } if (mMode == 2) { // LED + CreatePhysicsHistograms(); CreateLEDHistograms(); + // CreateTRUHistograms(); } } @@ -179,13 +199,13 @@ void RawQcTask::startOfCycle() if (mMode == 1) { // Pedestals if (mFinalized) { // means were already calculated for (Int_t mod = 0; mod < 4; mod++) { - if (mHist2D[kHGmeanM1 + mod]) { - mHist2D[kHGmeanM1 + mod]->Multiply(mHist2D[kHGoccupM1 + mod]); - mHist2D[kHGrmsM1 + mod]->Multiply(mHist2D[kHGoccupM1 + mod]); + if (mHist2DMean[kHGmeanM1 + mod]) { + mHist2DMean[kHGmeanM1 + mod]->Multiply(mHist2D[kHGoccupM1 + mod]); + mHist2DMean[kHGrmsM1 + mod]->Multiply(mHist2D[kHGoccupM1 + mod]); } - if (mHist2D[kLGmeanM1 + mod]) { - mHist2D[kLGmeanM1 + mod]->Multiply(mHist2D[kLGoccupM1 + mod]); - mHist2D[kLGrmsM1 + mod]->Multiply(mHist2D[kLGoccupM1 + mod]); + if (mHist2DMean[kLGmeanM1 + mod]) { + mHist2DMean[kLGmeanM1 + mod]->Multiply(mHist2D[kLGoccupM1 + mod]); + mHist2DMean[kLGrmsM1 + mod]->Multiply(mHist2D[kLGoccupM1 + mod]); } } mFinalized = false; @@ -204,13 +224,14 @@ void RawQcTask::monitorData(o2::framework::ProcessingContext& ctx) // One can find additional examples at: // https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/README.md#using-inputs---the-inputrecord-api - auto hwerrors = ctx.inputs().get>("rawerr"); - for (auto e : hwerrors) { - int ibin = mHist2D[kErrorNumber]->Fill(float(e.getFEC()), float(e.getDDL())); - int cont = mHist2D[kErrorType]->GetBinContent(ibin); - cont |= (1 << e.getError()); - ILOG(Info, Support) << "[" << int(e.getFEC()) << "," << int(e.getDDL()) << "ERROR:" << cont << " e.getErr=" << int(e.getError()) << AliceO2::InfoLogger::InfoLogger::endm; - mHist2D[kErrorType]->SetBinContent(ibin, cont); + if (ctx.inputs().getPos("rawerr") >= 0) { // to be able to scan e.g. CTF data + auto hwerrors = ctx.inputs().get>("rawerr"); + for (auto e : hwerrors) { + int ibin = mHist2D[kErrorNumber]->Fill(float(e.getFEC()), float(e.getDDL())); + int cont = mHist2DBitmask[kErrorType]->GetBinContent(ibin); + cont |= (1 << e.getError()); + mHist2DBitmask[kErrorType]->SetBinContent(ibin, cont); + } } // Bad Map // Read current bad map if not read yet @@ -262,12 +283,15 @@ void RawQcTask::monitorData(o2::framework::ProcessingContext& ctx) if (mMode == 0) { // Physics FillPhysicsHistograms(cells, cellsTR); + // FillTRUHistograms(cells, cellsTR); } if (mMode == 1) { // Pedestals FillPedestalHistograms(cells, cellsTR); } if (mMode == 2) { // LED + FillPhysicsHistograms(cells, cellsTR); FillLEDHistograms(cells, cellsTR); + // FillTRUHistograms(cells, cellsTR); } } // function monitor data @@ -288,20 +312,20 @@ void RawQcTask::endOfCycle() return; } for (Int_t mod = 0; mod < 4; mod++) { - if (mHist2D[kHGmeanM1 + mod]) { - mHist2D[kHGmeanM1 + mod]->Divide(mHist2D[kHGoccupM1 + mod]); - mHist2D[kHGrmsM1 + mod]->Divide(mHist2D[kHGoccupM1 + mod]); + if (mHist2DMean[kHGmeanM1 + mod]) { + mHist2DMean[kHGmeanM1 + mod]->Divide(mHist2D[kHGoccupM1 + mod]); + mHist2DMean[kHGrmsM1 + mod]->Divide(mHist2D[kHGoccupM1 + mod]); mHist1D[kHGmeanSummaryM1 + mod]->Reset(); mHist1D[kHGrmsSummaryM1 + mod]->Reset(); double occMin = 1.e+9; double occMax = 0.; for (int iz = 1; iz <= 64; iz++) { for (int ix = 1; ix <= 56; ix++) { - float a = mHist2D[kHGmeanM1 + mod]->GetBinContent(iz, ix); + float a = mHist2DMean[kHGmeanM1 + mod]->GetBinContent(iz, ix); if (a > 0) { mHist1D[kHGmeanSummaryM1 + mod]->Fill(a); } - a = mHist2D[kHGrmsM1 + mod]->GetBinContent(iz, ix); + a = mHist2DMean[kHGrmsM1 + mod]->GetBinContent(iz, ix); if (a > 0) { mHist1D[kHGrmsSummaryM1 + mod]->Fill(a); } @@ -317,20 +341,20 @@ void RawQcTask::endOfCycle() mHist2D[kHGoccupM1 + mod]->SetMinimum(occMin); mHist2D[kHGoccupM1 + mod]->SetMaximum(occMax); } - if (mHist2D[kLGmeanM1 + mod]) { - mHist2D[kLGmeanM1 + mod]->Divide(mHist2D[kLGoccupM1 + mod]); - mHist2D[kLGrmsM1 + mod]->Divide(mHist2D[kLGoccupM1 + mod]); + if (mHist2DMean[kLGmeanM1 + mod]) { + mHist2DMean[kLGmeanM1 + mod]->Divide(mHist2D[kLGoccupM1 + mod]); + mHist2DMean[kLGrmsM1 + mod]->Divide(mHist2D[kLGoccupM1 + mod]); mHist1D[kLGmeanSummaryM1 + mod]->Reset(); mHist1D[kLGrmsSummaryM1 + mod]->Reset(); double occMin = 1.e+9; double occMax = 0.; for (int iz = 1; iz <= 64; iz++) { for (int ix = 1; ix <= 56; ix++) { - float a = mHist2D[kLGmeanM1 + mod]->GetBinContent(iz, ix); + float a = mHist2DMean[kLGmeanM1 + mod]->GetBinContent(iz, ix); if (a > 0) { mHist1D[kLGmeanSummaryM1 + mod]->Fill(a); } - a = mHist2D[kLGrmsM1 + mod]->GetBinContent(iz, ix); + a = mHist2DMean[kLGrmsM1 + mod]->GetBinContent(iz, ix); if (a > 0) { mHist1D[kLGrmsSummaryM1 + mod]->Fill(a); } @@ -357,8 +381,8 @@ void RawQcTask::endOfCycle() char relid[3]; o2::phos::Geometry::absToRelNumbering(absId, relid); short mod = relid[0] - 1; - int ibin = mHist2D[kLEDNpeaksM1 + mod]->FindBin(relid[1] - 0.5, relid[2] - 0.5); - mHist2D[kLEDNpeaksM1 + mod]->SetBinContent(ibin, npeaks); + int ibin = mHist2DMean[kLEDNpeaksM1 + mod]->FindBin(relid[1] - 0.5, relid[2] - 0.5); + mHist2DMean[kLEDNpeaksM1 + mod]->SetBinContent(ibin, npeaks); } ILOG(Info, Support) << " Caclulating number of peaks done" << AliceO2::InfoLogger::InfoLogger::endm; } @@ -366,8 +390,8 @@ void RawQcTask::endOfCycle() void RawQcTask::endOfActivity(Activity& /*activity*/) { - endOfCycle(); ILOG(Info, Support) << "endOfActivity" << AliceO2::InfoLogger::InfoLogger::endm; + endOfCycle(); } void RawQcTask::reset() @@ -389,7 +413,6 @@ void RawQcTask::reset() } void RawQcTask::FillLEDHistograms(const gsl::span& cells, const gsl::span& cellsTR) { - FillPhysicsHistograms(cells, cellsTR); // Fill intermediate histograms for (const auto& tr : cellsTR) { @@ -397,12 +420,86 @@ void RawQcTask::FillLEDHistograms(const gsl::span& cells, int lastCellInEvent = firstCellInEvent + tr.getNumberOfObjects(); for (int i = firstCellInEvent; i < lastCellInEvent; i++) { const o2::phos::Cell c = cells[i]; - if (c.getHighGain()) { + if (!c.getTRU() && c.getHighGain()) { mSpectra[c.getAbsId() - 1793].Fill(c.getEnergy()); } } } } +void RawQcTask::FillTRUHistograms(const gsl::span& cells, const gsl::span& cellsTR) +{ + std::vector triggerSTTiles; + std::vector triggerDGTiles; + char relId[3] = { 0 }; + for (const auto tr : cellsTR) { + triggerSTTiles.clear(); + triggerDGTiles.clear(); + int firstCellInEvent = tr.getFirstEntry(); + int lastCellInEvent = firstCellInEvent + tr.getNumberOfObjects(); + for (int i = firstCellInEvent; i < lastCellInEvent; i++) { + const o2::phos::Cell& c = cells[i]; + if (c.getTRU()) { + if (c.getType() == o2::phos::TRU4x4) { + o2::phos::Geometry::truAbsToRelNumbering(c.getTRUId(), 1, relId); + // ILOG(Info, Support) << "TRU4x4 [" <<(int)relId[0]<< ","<<(int)relId[1]<< ","<< (int)relId[2] <<"]" << AliceO2::InfoLogger::InfoLogger::endm; + mHist2D[kTRUSTOccupM1 + relId[0] - 1]->Fill(relId[1] - 0.5, relId[2] - 0.5); + triggerSTTiles.push_back(relId[0] + (relId[1] << 3) + (relId[2] << 10)); + } else { // 2x2 + o2::phos::Geometry::truAbsToRelNumbering(c.getTRUId(), 0, relId); + // ILOG(Info, Support) << "TRU2x2 [" <<(int)relId[0]<< ","<<(int)relId[1]<< ","<< (int)relId[2] <<"]" << AliceO2::InfoLogger::InfoLogger::endm; + mHist2D[kTRUDGOccupM1 + relId[0] - 1]->Fill(relId[1] - 0.5, relId[2] - 0.5); + triggerDGTiles.push_back(relId[0] + (relId[1] << 3) + (relId[2] << 10)); + } + } + } + + // ILOG(Info, Support) << " triggerSTTiles=" <> 3) & 0x7F) - ((aST >> 3) & 0x7F); + int dz = ((bDG >> 10) & 0x7F) - ((aST >> 10) & 0x7F); + // ILOG(Info, Support) << " dx=" <>3)&0x7F)<< ","<< ((aST>>10)&0x7F) <<"]" << AliceO2::InfoLogger::InfoLogger::endm; + mHist2D[kTRUSTMatchM1 + (aST & 0x7) - 1]->Fill(((aST >> 3) & 0x7F) - 0.5, ((aST >> 10) & 0x7F) - 0.5); + matched = true; + break; + } + } + } + if (!matched) { + // ILOG(Info, Support) << " Not matched [" <<(aST&0x7) << ","<<((aST>>3)&0x7F)<< ","<< ((aST>>10)&0x7F) <<"]" << AliceO2::InfoLogger::InfoLogger::endm; + mHist2D[kTRUSTFakeM1 + (aST & 0x7) - 1]->Fill(((aST >> 3) & 0x7F) - 0.5, ((aST >> 10) & 0x7F) - 0.5); + // ILOG(Info, Support) << "Filled" << AliceO2::InfoLogger::InfoLogger::endm; + } + } + // ILOG(Info, Support) << "Filled done" << AliceO2::InfoLogger::InfoLogger::endm; + // now vise versa + for (int bDG : triggerDGTiles) { + bool matched = false; + for (int aST : triggerSTTiles) { + if (aST & 0x7 == bDG & 0x7) { // same module + int dx = ((bDG >> 3) & 0x7F) - ((aST >> 3) & 0x7F); + int dz = ((bDG >> 10) & 0x7F) - ((aST >> 10) & 0x7F); + if (dx >= 0 && dx <= 2 && dz >= 0 && dz <= 2) { + matched = true; + break; + } + } + } + if (!matched) { + // ILOG(Info, Support) << "Dig Not matched [" <<(bDG&0x7)<< ","<<((bDG>>3)&0x7F)<< ","<< ((bDG>>10)&0x7F) <<"]" << AliceO2::InfoLogger::InfoLogger::endm; + mHist2D[kTRUDGFakeM1 + (bDG & 0x7) - 1]->Fill(((bDG >> 3) & 0x7F) - 0.5, ((bDG >> 10) & 0x7F) - 0.5); + } + } + // ILOG(Info, Support) << "Filled2 done" << AliceO2::InfoLogger::InfoLogger::endm; + } +} void RawQcTask::FillPhysicsHistograms(const gsl::span& cells, const gsl::span& cellsTR) { for (const auto& tr : cellsTR) { @@ -410,12 +507,12 @@ void RawQcTask::FillPhysicsHistograms(const gsl::span& cel int lastCellInEvent = firstCellInEvent + tr.getNumberOfObjects(); for (int i = firstCellInEvent; i < lastCellInEvent; i++) { const o2::phos::Cell c = cells[i]; + if (c.getTRU()) { + continue; + } // short cell, float amplitude, float time, int label short address = c.getAbsId(); float e = c.getEnergy(); - if (!c.getHighGain()) { - e *= 16; // scale LowGain cells - } if (e > kOcccupancyTh) { // Converts the absolute numbering into the following array // relid[0] = PHOS Module number 1,...4:module @@ -424,16 +521,21 @@ void RawQcTask::FillPhysicsHistograms(const gsl::span& cel char relid[3]; o2::phos::Geometry::absToRelNumbering(address, relid); short mod = relid[0] - 1; - int ibin = mHist2D[kCellOccupM1 + mod]->FindBin(relid[1] - 0.5, relid[2] - 0.5); + int ibin = 0; float emean = e; - float n = mHist2D[kCellOccupM1 + mod]->GetBinContent(ibin); - if (n > 0) { - emean = (e + mHist2D[kCellEM1 + mod]->GetBinContent(ibin) * n) / (n + 1); + if (c.getHighGain()) { + ibin = mHist2D[kHGoccupM1 + mod]->Fill(relid[1] - 0.5, relid[2] - 0.5); + float n = mHist2D[kHGoccupM1 + mod]->GetBinContent(ibin) - 1; + if (n > 0) { + emean = (e + mHist2DMean[kCellEM1 + mod]->GetBinContent(ibin) * n) / (n + 1); + } + mHist2DMean[kCellEM1 + mod]->SetBinContent(ibin, emean); + mHist1D[kCellHGSpM1 + mod]->Fill(e); + mHist2D[kTimeEM1 + mod]->Fill(e, c.getTime()); + } else { + mHist2D[kLGoccupM1 + mod]->Fill(relid[1] - 0.5, relid[2] - 0.5); + mHist1D[kCellLGSpM1 + mod]->Fill(e); } - mHist2D[kCellEM1 + mod]->SetBinContent(ibin, emean); - mHist2D[kCellOccupM1 + mod]->AddBinContent(ibin); - mHist2D[kTimeEM1 + mod]->Fill(e, c.getTime()); - mHist1D[kCellSpM1 + mod]->Fill(e); } } } @@ -443,10 +545,10 @@ void RawQcTask::FillPedestalHistograms(const gsl::span& ce { if (mFinalized) { for (Int_t mod = 0; mod < 4; mod++) { - mHist2D[kHGmeanM1 + mod]->Multiply(mHist2D[kHGoccupM1 + mod]); - mHist2D[kHGrmsM1 + mod]->Multiply(mHist2D[kHGoccupM1 + mod]); - mHist2D[kLGmeanM1 + mod]->Multiply(mHist2D[kLGoccupM1 + mod]); - mHist2D[kLGrmsM1 + mod]->Multiply(mHist2D[kLGoccupM1 + mod]); + mHist2DMean[kHGmeanM1 + mod]->Multiply(mHist2D[kHGoccupM1 + mod]); + mHist2DMean[kHGrmsM1 + mod]->Multiply(mHist2D[kHGoccupM1 + mod]); + mHist2DMean[kLGmeanM1 + mod]->Multiply(mHist2D[kLGoccupM1 + mod]); + mHist2DMean[kLGrmsM1 + mod]->Multiply(mHist2D[kLGoccupM1 + mod]); } mFinalized = false; } @@ -461,12 +563,12 @@ void RawQcTask::FillPedestalHistograms(const gsl::span& ce o2::phos::Geometry::absToRelNumbering(address, relid); short mod = relid[0] - 1; if (c.getHighGain()) { - mHist2D[kHGmeanM1 + mod]->Fill(relid[1] - 0.5, relid[2] - 0.5, c.getEnergy()); - mHist2D[kHGrmsM1 + mod]->Fill(relid[1] - 0.5, relid[2] - 0.5, 1.e+7 * c.getTime()); // to store in Cells format + mHist2DMean[kHGmeanM1 + mod]->Fill(relid[1] - 0.5, relid[2] - 0.5, c.getEnergy()); + mHist2DMean[kHGrmsM1 + mod]->Fill(relid[1] - 0.5, relid[2] - 0.5, 1.e+7 * c.getTime()); // to store in Cells format mHist2D[kHGoccupM1 + mod]->Fill(relid[1] - 0.5, relid[2] - 0.5); } else { - mHist2D[kLGmeanM1 + mod]->Fill(relid[1] - 0.5, relid[2] - 0.5, c.getEnergy()); - mHist2D[kLGrmsM1 + mod]->Fill(relid[1] - 0.5, relid[2] - 0.5, 1.e+7 * c.getTime()); + mHist2DMean[kLGmeanM1 + mod]->Fill(relid[1] - 0.5, relid[2] - 0.5, c.getEnergy()); + mHist2DMean[kLGrmsM1 + mod]->Fill(relid[1] - 0.5, relid[2] - 0.5, 1.e+7 * c.getTime()); mHist2D[kLGoccupM1 + mod]->Fill(relid[1] - 0.5, relid[2] - 0.5); } } @@ -478,31 +580,31 @@ void RawQcTask::CreatePedestalHistograms() // Prepare historams for pedestal run QA for (Int_t mod = 0; mod < 4; mod++) { - if (!mHist2D[kHGmeanM1 + mod]) { - mHist2D[kHGmeanM1 + mod] = new TH2F(Form("PedHGmean%d", mod + 1), Form("Pedestal mean High Gain, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); - mHist2D[kHGmeanM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); - mHist2D[kHGmeanM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); - mHist2D[kHGmeanM1 + mod]->GetXaxis()->SetTitle("x, cells"); - mHist2D[kHGmeanM1 + mod]->GetYaxis()->SetTitle("z, cells"); - mHist2D[kHGmeanM1 + mod]->SetStats(0); - mHist2D[kHGmeanM1 + mod]->SetMinimum(0); - mHist2D[kHGmeanM1 + mod]->SetMaximum(100); - getObjectsManager()->startPublishing(mHist2D[kHGmeanM1 + mod]); + if (!mHist2DMean[kHGmeanM1 + mod]) { + mHist2DMean[kHGmeanM1 + mod] = new TH2FMean(Form("PedHGmean%d", mod + 1), Form("Pedestal mean High Gain, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); + mHist2DMean[kHGmeanM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); + mHist2DMean[kHGmeanM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); + mHist2DMean[kHGmeanM1 + mod]->GetXaxis()->SetTitle("x, cells"); + mHist2DMean[kHGmeanM1 + mod]->GetYaxis()->SetTitle("z, cells"); + mHist2DMean[kHGmeanM1 + mod]->SetStats(0); + mHist2DMean[kHGmeanM1 + mod]->SetMinimum(0); + mHist2DMean[kHGmeanM1 + mod]->SetMaximum(100); + getObjectsManager()->startPublishing(mHist2DMean[kHGmeanM1 + mod]); } else { - mHist2D[kHGmeanM1 + mod]->Reset(); - } - if (!mHist2D[kHGrmsM1 + mod]) { - mHist2D[kHGrmsM1 + mod] = new TH2F(Form("PedHGrms%d", mod + 1), Form("Pedestal RMS High Gain, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); - mHist2D[kHGrmsM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); - mHist2D[kHGrmsM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); - mHist2D[kHGrmsM1 + mod]->GetXaxis()->SetTitle("x, cells"); - mHist2D[kHGrmsM1 + mod]->GetYaxis()->SetTitle("z, cells"); - mHist2D[kHGrmsM1 + mod]->SetStats(0); - mHist2D[kHGrmsM1 + mod]->SetMinimum(0); - mHist2D[kHGrmsM1 + mod]->SetMaximum(2.); - getObjectsManager()->startPublishing(mHist2D[kHGrmsM1 + mod]); + mHist2DMean[kHGmeanM1 + mod]->Reset(); + } + if (!mHist2DMean[kHGrmsM1 + mod]) { + mHist2DMean[kHGrmsM1 + mod] = new TH2FMean(Form("PedHGrms%d", mod + 1), Form("Pedestal RMS High Gain, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); + mHist2DMean[kHGrmsM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); + mHist2DMean[kHGrmsM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); + mHist2DMean[kHGrmsM1 + mod]->GetXaxis()->SetTitle("x, cells"); + mHist2DMean[kHGrmsM1 + mod]->GetYaxis()->SetTitle("z, cells"); + mHist2DMean[kHGrmsM1 + mod]->SetStats(0); + mHist2DMean[kHGrmsM1 + mod]->SetMinimum(0); + mHist2DMean[kHGrmsM1 + mod]->SetMaximum(2.); + getObjectsManager()->startPublishing(mHist2DMean[kHGrmsM1 + mod]); } else { - mHist2D[kHGrmsM1 + mod]->Reset(); + mHist2DMean[kHGrmsM1 + mod]->Reset(); } if (!mHist2D[kHGoccupM1 + mod]) { mHist2D[kHGoccupM1 + mod] = new TH2F(Form("HGOccupancyM%d", mod + 1), Form("High Gain occupancy, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); @@ -515,31 +617,31 @@ void RawQcTask::CreatePedestalHistograms() } else { mHist2D[kHGoccupM1 + mod]->Reset(); } - if (!mHist2D[kLGmeanM1 + mod]) { - mHist2D[kLGmeanM1 + mod] = new TH2F(Form("PedLGmean%d", mod + 1), Form("Pedestal mean Low Gain, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); - mHist2D[kLGmeanM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); - mHist2D[kLGmeanM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); - mHist2D[kLGmeanM1 + mod]->GetXaxis()->SetTitle("x, cells"); - mHist2D[kLGmeanM1 + mod]->GetYaxis()->SetTitle("z, cells"); - mHist2D[kLGmeanM1 + mod]->SetStats(0); - mHist2D[kLGmeanM1 + mod]->SetMinimum(0); - mHist2D[kLGmeanM1 + mod]->SetMaximum(100); - getObjectsManager()->startPublishing(mHist2D[kLGmeanM1 + mod]); + if (!mHist2DMean[kLGmeanM1 + mod]) { + mHist2DMean[kLGmeanM1 + mod] = new TH2FMean(Form("PedLGmean%d", mod + 1), Form("Pedestal mean Low Gain, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); + mHist2DMean[kLGmeanM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); + mHist2DMean[kLGmeanM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); + mHist2DMean[kLGmeanM1 + mod]->GetXaxis()->SetTitle("x, cells"); + mHist2DMean[kLGmeanM1 + mod]->GetYaxis()->SetTitle("z, cells"); + mHist2DMean[kLGmeanM1 + mod]->SetStats(0); + mHist2DMean[kLGmeanM1 + mod]->SetMinimum(0); + mHist2DMean[kLGmeanM1 + mod]->SetMaximum(100); + getObjectsManager()->startPublishing(mHist2DMean[kLGmeanM1 + mod]); } else { - mHist2D[kLGmeanM1 + mod]->Reset(); - } - if (!mHist2D[kLGrmsM1 + mod]) { - mHist2D[kLGrmsM1 + mod] = new TH2F(Form("PedLGrms%d", mod + 1), Form("Pedestal RMS Low Gain, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); - mHist2D[kLGrmsM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); - mHist2D[kLGrmsM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); - mHist2D[kLGrmsM1 + mod]->GetXaxis()->SetTitle("x, cells"); - mHist2D[kLGrmsM1 + mod]->GetYaxis()->SetTitle("z, cells"); - mHist2D[kLGrmsM1 + mod]->SetStats(0); - mHist2D[kLGrmsM1 + mod]->SetMinimum(0); - mHist2D[kLGrmsM1 + mod]->SetMaximum(2.); - getObjectsManager()->startPublishing(mHist2D[kLGrmsM1 + mod]); + mHist2DMean[kLGmeanM1 + mod]->Reset(); + } + if (!mHist2DMean[kLGrmsM1 + mod]) { + mHist2DMean[kLGrmsM1 + mod] = new TH2FMean(Form("PedLGrms%d", mod + 1), Form("Pedestal RMS Low Gain, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); + mHist2DMean[kLGrmsM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); + mHist2DMean[kLGrmsM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); + mHist2DMean[kLGrmsM1 + mod]->GetXaxis()->SetTitle("x, cells"); + mHist2DMean[kLGrmsM1 + mod]->GetYaxis()->SetTitle("z, cells"); + mHist2DMean[kLGrmsM1 + mod]->SetStats(0); + mHist2DMean[kLGrmsM1 + mod]->SetMinimum(0); + mHist2DMean[kLGrmsM1 + mod]->SetMaximum(2.); + getObjectsManager()->startPublishing(mHist2DMean[kLGrmsM1 + mod]); } else { - mHist2D[kLGrmsM1 + mod]->Reset(); + mHist2DMean[kLGrmsM1 + mod]->Reset(); } if (!mHist2D[kLGoccupM1 + mod]) { mHist2D[kLGoccupM1 + mod] = new TH2F(Form("LGOccupancyM%d", mod + 1), Form("Low Gain occupancy, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); @@ -595,32 +697,46 @@ void RawQcTask::CreatePhysicsHistograms() // Prepare historams for pedestal run QA for (Int_t mod = 0; mod < 4; mod++) { - if (!mHist2D[kCellOccupM1 + mod]) { - mHist2D[kCellOccupM1 + mod] = new TH2F(Form("CellOccupancyM%d", mod + 1), Form("Cell occupancy, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); - mHist2D[kCellOccupM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); - mHist2D[kCellOccupM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); - mHist2D[kCellOccupM1 + mod]->GetXaxis()->SetTitle("x, cells"); - mHist2D[kCellOccupM1 + mod]->GetYaxis()->SetTitle("z, cells"); - mHist2D[kCellOccupM1 + mod]->SetStats(0); - mHist2D[kCellOccupM1 + mod]->SetMinimum(0); - // mHist2D[kCellOccupM1+mod]->SetMaximum(100) ; - getObjectsManager()->startPublishing(mHist2D[kCellOccupM1 + mod]); + if (!mHist2D[kHGoccupM1 + mod]) { + mHist2D[kHGoccupM1 + mod] = new TH2F(Form("CellHGOccupancyM%d", mod + 1), Form("Cell HG occupancy, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); + mHist2D[kHGoccupM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); + mHist2D[kHGoccupM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); + mHist2D[kHGoccupM1 + mod]->GetXaxis()->SetTitle("x, cells"); + mHist2D[kHGoccupM1 + mod]->GetYaxis()->SetTitle("z, cells"); + mHist2D[kHGoccupM1 + mod]->SetStats(0); + mHist2D[kHGoccupM1 + mod]->SetMinimum(0); + // mHist2D[kHGoccupM1+mod]->SetMaximum(100) ; + getObjectsManager()->startPublishing(mHist2D[kHGoccupM1 + mod]); } else { - mHist2D[kCellOccupM1 + mod]->Reset(); - } - - if (!mHist2D[kCellEM1 + mod]) { - mHist2D[kCellEM1 + mod] = new TH2F(Form("CellEmean%d", mod + 1), Form("Cell mean energy, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); - mHist2D[kCellEM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); - mHist2D[kCellEM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); - mHist2D[kCellEM1 + mod]->GetXaxis()->SetTitle("x, cells"); - mHist2D[kCellEM1 + mod]->GetYaxis()->SetTitle("z, cells"); - mHist2D[kCellEM1 + mod]->SetStats(0); - mHist2D[kCellEM1 + mod]->SetMinimum(0); - // mHist2D[kCellEM1+mod]->SetMaximum(1.) ; - getObjectsManager()->startPublishing(mHist2D[kCellEM1 + mod]); + mHist2D[kHGoccupM1 + mod]->Reset(); + } + + if (!mHist2D[kLGoccupM1 + mod]) { + mHist2D[kLGoccupM1 + mod] = new TH2F(Form("CellLGOccupancyM%d", mod + 1), Form("Cell LG occupancy, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); + mHist2D[kLGoccupM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); + mHist2D[kLGoccupM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); + mHist2D[kLGoccupM1 + mod]->GetXaxis()->SetTitle("x, cells"); + mHist2D[kLGoccupM1 + mod]->GetYaxis()->SetTitle("z, cells"); + mHist2D[kLGoccupM1 + mod]->SetStats(0); + mHist2D[kLGoccupM1 + mod]->SetMinimum(0); + // mHist2D[kLGoccupM1+mod]->SetMaximum(100) ; + getObjectsManager()->startPublishing(mHist2D[kLGoccupM1 + mod]); + } else { + mHist2D[kLGoccupM1 + mod]->Reset(); + } + + if (!mHist2DMean[kCellEM1 + mod]) { + mHist2DMean[kCellEM1 + mod] = new TH2FMean(Form("CellEmean%d", mod + 1), Form("Cell mean energy, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); + mHist2DMean[kCellEM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); + mHist2DMean[kCellEM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); + mHist2DMean[kCellEM1 + mod]->GetXaxis()->SetTitle("x, cells"); + mHist2DMean[kCellEM1 + mod]->GetYaxis()->SetTitle("z, cells"); + mHist2DMean[kCellEM1 + mod]->SetStats(0); + mHist2DMean[kCellEM1 + mod]->SetMinimum(0); + // mHist2DMean[kCellEM1+mod]->SetMaximum(1.) ; + getObjectsManager()->startPublishing(mHist2DMean[kCellEM1 + mod]); } else { - mHist2D[kCellEM1 + mod]->Reset(); + mHist2DMean[kCellEM1 + mod]->Reset(); } if (!mHist2D[kTimeEM1 + mod]) { @@ -636,33 +752,41 @@ void RawQcTask::CreatePhysicsHistograms() mHist2D[kTimeEM1 + mod]->Reset(); } - if (!mHist1D[kCellSpM1 + mod]) { - mHist1D[kCellSpM1 + mod] = new TH1F(Form("CellSpectrumM%d", mod + 1), Form("Cell spectrum in mod %d", mod + 1), 100, 0., 1000.); - mHist1D[kCellSpM1 + mod]->GetXaxis()->SetTitle("ADC channels"); - mHist1D[kCellSpM1 + mod]->SetStats(0); - mHist1D[kCellSpM1 + mod]->SetMinimum(0); - getObjectsManager()->startPublishing(mHist1D[kCellSpM1 + mod]); + if (!mHist1D[kCellHGSpM1 + mod]) { + mHist1D[kCellHGSpM1 + mod] = new TH1F(Form("CellHGSpectrumM%d", mod + 1), Form("Cell HG spectrum in mod %d", mod + 1), 100, 0., 5000.); + mHist1D[kCellHGSpM1 + mod]->GetXaxis()->SetTitle("ADC channels"); + mHist1D[kCellHGSpM1 + mod]->SetStats(0); + mHist1D[kCellHGSpM1 + mod]->SetMinimum(0); + getObjectsManager()->startPublishing(mHist1D[kCellHGSpM1 + mod]); } else { - mHist1D[kCellSpM1 + mod]->Reset(); + mHist1D[kCellHGSpM1 + mod]->Reset(); + } + if (!mHist1D[kCellLGSpM1 + mod]) { + mHist1D[kCellLGSpM1 + mod] = new TH1F(Form("CellLGSpectrumM%d", mod + 1), Form("Cell LG spectrum in mod %d", mod + 1), 100, 0., 5000.); + mHist1D[kCellLGSpM1 + mod]->GetXaxis()->SetTitle("ADC channels"); + mHist1D[kCellLGSpM1 + mod]->SetStats(0); + mHist1D[kCellLGSpM1 + mod]->SetMinimum(0); + getObjectsManager()->startPublishing(mHist1D[kCellLGSpM1 + mod]); + } else { + mHist1D[kCellLGSpM1 + mod]->Reset(); } } } void RawQcTask::CreateLEDHistograms() { // Occupancy+mean+spectra - CreatePhysicsHistograms(); for (Int_t mod = 0; mod < 4; mod++) { - if (!mHist2D[kLEDNpeaksM1 + mod]) { - mHist2D[kLEDNpeaksM1 + mod] = new TH2F(Form("NLedPeaksM%d", mod + 1), Form("Number of LED peaks, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); - mHist2D[kLEDNpeaksM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); - mHist2D[kLEDNpeaksM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); - mHist2D[kLEDNpeaksM1 + mod]->GetXaxis()->SetTitle("x, cells"); - mHist2D[kLEDNpeaksM1 + mod]->GetYaxis()->SetTitle("z, cells"); - mHist2D[kLEDNpeaksM1 + mod]->SetStats(0); - mHist2D[kLEDNpeaksM1 + mod]->SetMinimum(0); - getObjectsManager()->startPublishing(mHist2D[kLEDNpeaksM1 + mod]); + if (!mHist2DMean[kLEDNpeaksM1 + mod]) { + mHist2DMean[kLEDNpeaksM1 + mod] = new TH2FMean(Form("NLedPeaksM%d", mod + 1), Form("Number of LED peaks, mod %d", mod + 1), 64, 0., 64., 56, 0., 56.); + mHist2DMean[kLEDNpeaksM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); + mHist2DMean[kLEDNpeaksM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); + mHist2DMean[kLEDNpeaksM1 + mod]->GetXaxis()->SetTitle("x, cells"); + mHist2DMean[kLEDNpeaksM1 + mod]->GetYaxis()->SetTitle("z, cells"); + mHist2DMean[kLEDNpeaksM1 + mod]->SetStats(0); + mHist2DMean[kLEDNpeaksM1 + mod]->SetMinimum(0); + getObjectsManager()->startPublishing(mHist2DMean[kLEDNpeaksM1 + mod]); } else { - mHist2D[kLEDNpeaksM1 + mod]->Reset(); + mHist2DMean[kLEDNpeaksM1 + mod]->Reset(); } } // Prepare internal array of histos and final plot with number of peaks per channel @@ -671,4 +795,77 @@ void RawQcTask::CreateLEDHistograms() mSpectra.emplace_back(Form("SpChannel%d", absId), "", 487, 50., 1024.); } } +void RawQcTask::CreateTRUHistograms() +{ + // Prepare historams for TRU QA + for (Int_t mod = 0; mod < 4; mod++) { + if (!mHist2D[kTRUSTOccupM1 + mod]) { + mHist2D[kTRUSTOccupM1 + mod] = new TH2F(Form("TRUSumTableOccupancyM%d", mod + 1), Form("TRU summary table occupancy, mod %d", mod + 1), 32, 0., 64., 28, 0., 56.); + mHist2D[kTRUSTOccupM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); + mHist2D[kTRUSTOccupM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); + mHist2D[kTRUSTOccupM1 + mod]->GetXaxis()->SetTitle("x, cells"); + mHist2D[kTRUSTOccupM1 + mod]->GetYaxis()->SetTitle("z, cells"); + mHist2D[kTRUSTOccupM1 + mod]->SetStats(0); + mHist2D[kTRUSTOccupM1 + mod]->SetMinimum(0); + // mHist2D[kTRUSTOccupM1+mod]->SetMaximum(100) ; + getObjectsManager()->startPublishing(mHist2D[kTRUSTOccupM1 + mod]); + } else { + mHist2D[kTRUSTOccupM1 + mod]->Reset(); + } + if (!mHist2D[kTRUDGOccupM1 + mod]) { + mHist2D[kTRUDGOccupM1 + mod] = new TH2F(Form("TRUDigOccupancyM%d", mod + 1), Form("TRU digits occupancy, mod %d", mod + 1), 32, 0., 64., 28, 0., 56.); + mHist2D[kTRUDGOccupM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); + mHist2D[kTRUDGOccupM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); + mHist2D[kTRUDGOccupM1 + mod]->GetXaxis()->SetTitle("x, cells"); + mHist2D[kTRUDGOccupM1 + mod]->GetYaxis()->SetTitle("z, cells"); + mHist2D[kTRUDGOccupM1 + mod]->SetStats(0); + mHist2D[kTRUDGOccupM1 + mod]->SetMinimum(0); + // mHist2D[kTRUDGOccupM1+mod]->SetMaximum(100) ; + getObjectsManager()->startPublishing(mHist2D[kTRUDGOccupM1 + mod]); + } else { + mHist2D[kTRUDGOccupM1 + mod]->Reset(); + } + if (!mHist2D[kTRUSTMatchM1 + mod]) { + mHist2D[kTRUSTMatchM1 + mod] = new TH2F(Form("TRUMatchedOccupancyM%d", mod + 1), Form("TRU ST+dig matched, mod %d", mod + 1), 32, 0., 64., 28, 0., 56.); + mHist2D[kTRUSTMatchM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); + mHist2D[kTRUSTMatchM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); + mHist2D[kTRUSTMatchM1 + mod]->GetXaxis()->SetTitle("x, cells"); + mHist2D[kTRUSTMatchM1 + mod]->GetYaxis()->SetTitle("z, cells"); + mHist2D[kTRUSTMatchM1 + mod]->SetStats(0); + mHist2D[kTRUSTMatchM1 + mod]->SetMinimum(0); + // mHist2D[kTRUSTMatchM1+mod]->SetMaximum(100) ; + getObjectsManager()->startPublishing(mHist2D[kTRUSTMatchM1 + mod]); + } else { + mHist2D[kTRUSTMatchM1 + mod]->Reset(); + } + if (!mHist2D[kTRUSTFakeM1 + mod]) { + mHist2D[kTRUSTFakeM1 + mod] = new TH2F(Form("TRUFakeSTOccupancyM%d", mod + 1), Form("TRU ST without digit, mod %d", mod + 1), 32, 0., 64., 28, 0., 56.); + mHist2D[kTRUSTFakeM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); + mHist2D[kTRUSTFakeM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); + mHist2D[kTRUSTFakeM1 + mod]->GetXaxis()->SetTitle("x, cells"); + mHist2D[kTRUSTFakeM1 + mod]->GetYaxis()->SetTitle("z, cells"); + mHist2D[kTRUSTFakeM1 + mod]->SetStats(0); + mHist2D[kTRUSTFakeM1 + mod]->SetMinimum(0); + // mHist2D[kTRUSTFakeM1+mod]->SetMaximum(100) ; + getObjectsManager()->startPublishing(mHist2D[kTRUSTFakeM1 + mod]); + } else { + mHist2D[kTRUSTFakeM1 + mod]->Reset(); + } + + if (!mHist2D[kTRUDGFakeM1 + mod]) { + mHist2D[kTRUDGFakeM1 + mod] = new TH2F(Form("TRUFakeDGOccupancyM%d", mod + 1), Form("TRU dig without ST, mod %d", mod + 1), 32, 0., 64., 28, 0., 56.); + mHist2D[kTRUDGFakeM1 + mod]->GetXaxis()->SetNdivisions(508, kFALSE); + mHist2D[kTRUDGFakeM1 + mod]->GetYaxis()->SetNdivisions(514, kFALSE); + mHist2D[kTRUDGFakeM1 + mod]->GetXaxis()->SetTitle("x, cells"); + mHist2D[kTRUDGFakeM1 + mod]->GetYaxis()->SetTitle("z, cells"); + mHist2D[kTRUDGFakeM1 + mod]->SetStats(0); + mHist2D[kTRUDGFakeM1 + mod]->SetMinimum(0); + // mHist2D[kTRUDGFakeM1+mod]->SetMaximum(100) ; + getObjectsManager()->startPublishing(mHist2D[kTRUDGFakeM1 + mod]); + } else { + mHist2D[kTRUDGFakeM1 + mod]->Reset(); + } + } +} + } // namespace o2::quality_control_modules::phos diff --git a/Modules/PHOS/src/TH2FMean.cxx b/Modules/PHOS/src/TH2FMean.cxx new file mode 100644 index 0000000000..9520c9f3d6 --- /dev/null +++ b/Modules/PHOS/src/TH2FMean.cxx @@ -0,0 +1,37 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// \file TH2FMean.cxx +/// \author Dmitri Peresunko +/// + +#include "PHOS/TH2FMean.h" + +namespace o2::quality_control_modules::phos +{ + +void TH2FMean::merge(MergeInterface* const other) +{ + // special merge method to approximately combine two histograms + auto otherHisto = dynamic_cast(other); + if (otherHisto) { + // Make approximate averaging with weights proportional to total number of entries + double sum = this->GetEntries() + otherHisto->GetEntries(); + if (sum > 0) { + double w1 = this->GetEntries() / sum; + double w2 = otherHisto->GetEntries() / sum; + this->Scale(w1); + this->Add(otherHisto, w2); + } + } +} +} // namespace o2::quality_control_modules::phos diff --git a/Modules/PHOS/src/TH2SBitmask.cxx b/Modules/PHOS/src/TH2SBitmask.cxx new file mode 100644 index 0000000000..4279e866ac --- /dev/null +++ b/Modules/PHOS/src/TH2SBitmask.cxx @@ -0,0 +1,34 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// \file TH2SBitmask.cxx +/// \author Dmitri Peresunko +/// + +#include "PHOS/TH2SBitmask.h" + +namespace o2::quality_control_modules::phos +{ +void TH2SBitmask::merge(MergeInterface* const other) +{ + // combine two histograms representing bitmasks + auto otherHisto = dynamic_cast(other); + if (otherHisto) { + for (unsigned int ix = 1; ix <= this->GetNbinsX(); ix++) { + for (unsigned int iz = 1; iz <= this->GetNbinsX(); iz++) { + int cont = this->GetBinContent(ix, iz); + cont |= int(otherHisto->GetBinContent(ix, iz, cont)); + } + } + } +} +} // namespace o2::quality_control_modules::phos