From 03767e2d02e697c8dc5017b3964ff063eea4caf3 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Tue, 8 Apr 2025 09:27:20 +0200 Subject: [PATCH] [MCH] add rate and efficiency plots per DualSAMPA The new histograms are 1D lightweight versions of the 2D maps in electronics coordinates, that are more suitable for saving moving windows plots in async productions. The 1D versions provide the quantities averaged over each DualSAMPA bard, while the 2D versions contain values on a channel-by-channel basis. By default the 1D histograms are enabled and the 2D are disabled. --- Modules/MUON/MCH/include/MCH/DigitsTask.h | 8 +++ .../MUON/MCH/include/MCH/PreclustersTask.h | 6 ++ Modules/MUON/MCH/src/DigitsTask.cxx | 65 +++++++++++++++---- Modules/MUON/MCH/src/PreclustersTask.cxx | 55 +++++++++++++--- 4 files changed, 113 insertions(+), 21 deletions(-) diff --git a/Modules/MUON/MCH/include/MCH/DigitsTask.h b/Modules/MUON/MCH/include/MCH/DigitsTask.h index b6dabd9dda..61deb84c6e 100644 --- a/Modules/MUON/MCH/include/MCH/DigitsTask.h +++ b/Modules/MUON/MCH/include/MCH/DigitsTask.h @@ -24,6 +24,7 @@ #include "MCHBase/Digit.h" #endif #include "MCHDigitFiltering/DigitFilter.h" +#include "Common/TH1Ratio.h" #include "Common/TH2Ratio.h" class TH1F; @@ -67,6 +68,9 @@ class DigitsTask /*final*/ : public TaskInterface // todo add back the "final" w template void publishObject(T* histo, std::string drawOption, bool statBox, bool isExpert); + bool mEnable1DRateMaps{ true }; // whether to publish 1D maps of channel rates + bool mEnable2DRateMaps{ false }; // whether to publish 2D maps of channel rates + bool mFullHistos{ false }; // publish extra diagnostics plots o2::mch::DigitFilter mIsSignalDigit; @@ -77,6 +81,10 @@ class DigitsTask /*final*/ : public TaskInterface // todo add back the "final" w std::unique_ptr mHistogramOccupancyElec; // Occupancy histogram (Elec view) std::unique_ptr mHistogramSignalOccupancyElec; // Occupancy histogram (Elec view) for signal-like digits + // 1D rate histograms using Elec view, where each x bin corresponds to the unique ID of a DualSAMPA board + std::unique_ptr mHistogramRatePerDualSampa; + std::unique_ptr mHistogramRateSignalPerDualSampa; + std::unique_ptr mHistogramDigitsOrbitElec; std::unique_ptr mHistogramDigitsSignalOrbitElec; diff --git a/Modules/MUON/MCH/include/MCH/PreclustersTask.h b/Modules/MUON/MCH/include/MCH/PreclustersTask.h index 05dbc25cf4..e5015b2b7e 100644 --- a/Modules/MUON/MCH/include/MCH/PreclustersTask.h +++ b/Modules/MUON/MCH/include/MCH/PreclustersTask.h @@ -64,10 +64,16 @@ class PreclustersTask /*final*/ : public o2::quality_control::core::TaskInterfac void plotPrecluster(const o2::mch::PreCluster& preCluster, gsl::span digits); + bool mEnable1DPseudoeffMaps{ true }; // whether to publish 1D maps of channel pseudo-efficiencies + bool mEnable2DPseudoeffMaps{ false }; // whether to publish 2D maps of channel pseudo-efficiencies + o2::mch::DigitFilter mIsSignalDigit; std::unique_ptr mHistogramPseudoeffElec; // Mergeable object, Occupancy histogram (Elec view) + // 1D pseudo-efficiency histogram using Elec view, where each x bin corresponds to the unique ID of a DualSAMPA board + std::unique_ptr mHistogramPseudoeffPerDualSampa; + std::unique_ptr mHistogramPreclustersPerDE; // number of pre-clusters per DE and per TF std::unique_ptr mHistogramPreclustersSignalPerDE; // number of pre-clusters with signal per DE and per TF diff --git a/Modules/MUON/MCH/src/DigitsTask.cxx b/Modules/MUON/MCH/src/DigitsTask.cxx index fcd1ca4d96..7fe968e291 100644 --- a/Modules/MUON/MCH/src/DigitsTask.cxx +++ b/Modules/MUON/MCH/src/DigitsTask.cxx @@ -62,6 +62,10 @@ void DigitsTask::initialize(o2::framework::InitContext& /*ctx*/) mIsSignalDigit = o2::mch::createDigitFilter(20, true, true); + // flags to enable the publication of either 1D and 2D maps of channel rates + mEnable1DRateMaps = getConfigurationParameter(mCustomParameters, "Enable1DRateMaps", mEnable1DRateMaps); + mEnable2DRateMaps = getConfigurationParameter(mCustomParameters, "Enable2DRateMaps", mEnable2DRateMaps); + // flag to enable extra disagnostics plots; it also enables on-cycle plots mFullHistos = getConfigurationParameter(mCustomParameters, "FullHistos", mFullHistos); @@ -70,13 +74,25 @@ void DigitsTask::initialize(o2::framework::InitContext& /*ctx*/) const uint32_t nElecXbins = NumberOfDualSampas; // Histograms in electronics coordinates - mHistogramOccupancyElec = std::make_unique("Occupancy_Elec", "Occupancy", nElecXbins, 0, nElecXbins, 64, 0, 64, true); - mHistogramOccupancyElec->Sumw2(kFALSE); - publishObject(mHistogramOccupancyElec.get(), "colz", false, false); + if (mEnable1DRateMaps) { + mHistogramRatePerDualSampa = std::make_unique("RatePerDualSampa", "Average rate per dual sampa;DS index;rate (kHz)", o2::mch::NumberOfDualSampas, 0, o2::mch::NumberOfDualSampas, false); + mHistogramRatePerDualSampa->Sumw2(kFALSE); + publishObject(mHistogramRatePerDualSampa.get(), "hist", false, false); + + mHistogramRateSignalPerDualSampa = std::make_unique("RateSignalPerDualSampa", "Average rate per dual sampa (signal);DS index;rate (kHz)", o2::mch::NumberOfDualSampas, 0, o2::mch::NumberOfDualSampas, false); + mHistogramRateSignalPerDualSampa->Sumw2(kFALSE); + publishObject(mHistogramRateSignalPerDualSampa.get(), "hist", false, false); + } - mHistogramSignalOccupancyElec = std::make_unique("OccupancySignal_Elec", "Occupancy (signal)", nElecXbins, 0, nElecXbins, 64, 0, 64, true); - mHistogramSignalOccupancyElec->Sumw2(kFALSE); - publishObject(mHistogramSignalOccupancyElec.get(), "colz", false, false); + if (mEnable2DRateMaps) { + mHistogramOccupancyElec = std::make_unique("Occupancy_Elec", "Occupancy", nElecXbins, 0, nElecXbins, 64, 0, 64, true); + mHistogramOccupancyElec->Sumw2(kFALSE); + publishObject(mHistogramOccupancyElec.get(), "colz", false, false); + + mHistogramSignalOccupancyElec = std::make_unique("OccupancySignal_Elec", "Occupancy (signal)", nElecXbins, 0, nElecXbins, 64, 0, 64, true); + mHistogramSignalOccupancyElec->Sumw2(kFALSE); + publishObject(mHistogramSignalOccupancyElec.get(), "colz", false, false); + } mHistogramDigitsOrbitElec = std::make_unique("DigitOrbit_Elec", "Digit orbits vs DS Id", nElecXbins, 0, nElecXbins, 130, -1, 129); publishObject(mHistogramDigitsOrbitElec.get(), "colz", true, false); @@ -159,9 +175,17 @@ void DigitsTask::plotDigit(const o2::mch::Digit& digit) // fecId and channel uniquely identify each physical pad int fecId = getDsIndex(DsDetId{ deId, dsId }); - mHistogramOccupancyElec->getNum()->Fill(fecId, channel); - if (isSignal) { - mHistogramSignalOccupancyElec->getNum()->Fill(fecId, channel); + if (mEnable1DRateMaps) { + mHistogramRatePerDualSampa->getNum()->Fill(fecId); + if (isSignal) { + mHistogramRateSignalPerDualSampa->getNum()->Fill(fecId); + } + } + if (mEnable2DRateMaps) { + mHistogramOccupancyElec->getNum()->Fill(fecId, channel); + if (isSignal) { + mHistogramSignalOccupancyElec->getNum()->Fill(fecId, channel); + } } //-------------------------------------------------------------------------- @@ -201,8 +225,17 @@ void DigitsTask::updateOrbits() static constexpr double sOrbitLengthInMicroseconds = sOrbitLengthInNanoseconds / 1000; static constexpr double sOrbitLengthInMilliseconds = sOrbitLengthInMicroseconds / 1000; - mHistogramOccupancyElec->getDen()->SetBinContent(1, 1, mNOrbits * sOrbitLengthInMilliseconds); - mHistogramSignalOccupancyElec->getDen()->SetBinContent(1, 1, mNOrbits * sOrbitLengthInMilliseconds); + if (mEnable1DRateMaps) { + for (int dsIndex = 0; dsIndex <= NumberOfDualSampas; dsIndex++) { + mHistogramRatePerDualSampa->getDen()->SetBinContent(dsIndex + 1, mNOrbits * sOrbitLengthInMilliseconds * numberOfDualSampaChannels(dsIndex)); + mHistogramRateSignalPerDualSampa->getDen()->SetBinContent(dsIndex + 1, mNOrbits * sOrbitLengthInMilliseconds * numberOfDualSampaChannels(dsIndex)); + } + } + + if (mEnable2DRateMaps) { + mHistogramOccupancyElec->getDen()->SetBinContent(1, 1, mNOrbits * sOrbitLengthInMilliseconds); + mHistogramSignalOccupancyElec->getDen()->SetBinContent(1, 1, mNOrbits * sOrbitLengthInMilliseconds); + } } void DigitsTask::resetOrbits() @@ -217,8 +250,14 @@ void DigitsTask::endOfCycle() updateOrbits(); // update mergeable ratios - mHistogramOccupancyElec->update(); - mHistogramSignalOccupancyElec->update(); + if (mEnable1DRateMaps) { + mHistogramRatePerDualSampa->update(); + mHistogramRateSignalPerDualSampa->update(); + } + if (mEnable2DRateMaps) { + mHistogramOccupancyElec->update(); + mHistogramSignalOccupancyElec->update(); + } } void DigitsTask::endOfActivity(const Activity& /*activity*/) diff --git a/Modules/MUON/MCH/src/PreclustersTask.cxx b/Modules/MUON/MCH/src/PreclustersTask.cxx index 219d88c585..2b9bb096cd 100644 --- a/Modules/MUON/MCH/src/PreclustersTask.cxx +++ b/Modules/MUON/MCH/src/PreclustersTask.cxx @@ -16,6 +16,7 @@ /// #include "MCH/PreclustersTask.h" +#include "MUONCommon/Helpers.h" #include "MCH/Helpers.h" #ifdef MCH_HAS_MAPPING_FACTORY #include "MCHMappingFactory/CreateSegmentation.h" @@ -30,6 +31,7 @@ using namespace std; using namespace o2::mch; using namespace o2::mch::raw; using namespace o2::quality_control::core; +using namespace o2::quality_control_modules::muon; namespace o2 { @@ -54,6 +56,10 @@ void PreclustersTask::initialize(o2::framework::InitContext& /*ctx*/) { ILOG(Info, Devel) << "initialize PreclustersTask" << AliceO2::InfoLogger::InfoLogger::endm; + // flags to enable the publication of either 1D and 2D maps of channel pseudo-efficiencies + mEnable1DPseudoeffMaps = getConfigurationParameter(mCustomParameters, "Enable1DPseudoeffMaps", mEnable1DPseudoeffMaps); + mEnable2DPseudoeffMaps = getConfigurationParameter(mCustomParameters, "Enable2DPseudoeffMaps", mEnable2DPseudoeffMaps); + mIsSignalDigit = o2::mch::createDigitFilter(20, true, true); mHistogramPreclustersPerDE = std::make_unique("PreclustersPerDE", "Number of pre-clusters for each DE", getNumDE(), 0, getNumDE()); @@ -64,9 +70,17 @@ void PreclustersTask::initialize(o2::framework::InitContext& /*ctx*/) const uint32_t nElecXbins = NumberOfDualSampas; // Histograms in electronics coordinates - mHistogramPseudoeffElec = std::make_unique("Pseudoeff_Elec", "Pseudoeff", nElecXbins, 0, nElecXbins, 64, 0, 64); - mHistogramPseudoeffElec->Sumw2(kFALSE); - publishObject(mHistogramPseudoeffElec.get(), "colz", false); + if (mEnable1DPseudoeffMaps) { + mHistogramPseudoeffPerDualSampa = std::make_unique("PseudoeffPerDualSampa", "Average pseudo-efficiency per dual sampa;DS index;efficiency", o2::mch::NumberOfDualSampas, 0, o2::mch::NumberOfDualSampas, false); + mHistogramPseudoeffPerDualSampa->Sumw2(kFALSE); + publishObject(mHistogramPseudoeffPerDualSampa.get(), "hist", false); + } + + if (mEnable2DPseudoeffMaps) { + mHistogramPseudoeffElec = std::make_unique("Pseudoeff_Elec", "Pseudoeff", nElecXbins, 0, nElecXbins, 64, 0, 64); + mHistogramPseudoeffElec->Sumw2(kFALSE); + publishObject(mHistogramPseudoeffElec.get(), "colz", false); + } //---------------------------------- // Charge distribution histograms @@ -337,11 +351,21 @@ void PreclustersTask::plotPrecluster(const o2::mch::PreCluster& preCluster, gsl: if (isGoodDen[0]) { // good cluster on non-bending side, check if there is data from the bending side as well if (fecIdB >= 0 && channelB >= 0) { - mHistogramPseudoeffElec->getDen()->Fill(fecIdB, channelB); + if (mEnable1DPseudoeffMaps) { + mHistogramPseudoeffPerDualSampa->getDen()->Fill(fecIdB); + } + if (mEnable2DPseudoeffMaps) { + mHistogramPseudoeffElec->getDen()->Fill(fecIdB, channelB); + } } if (isGoodNum[0]) { // Check if associated to something on Bending if (fecIdB >= 0 && channelB >= 0) { - mHistogramPseudoeffElec->getNum()->Fill(fecIdB, channelB); + if (mEnable1DPseudoeffMaps) { + mHistogramPseudoeffPerDualSampa->getNum()->Fill(fecIdB); + } + if (mEnable2DPseudoeffMaps) { + mHistogramPseudoeffElec->getNum()->Fill(fecIdB, channelB); + } } } } @@ -349,11 +373,21 @@ void PreclustersTask::plotPrecluster(const o2::mch::PreCluster& preCluster, gsl: if (isGoodDen[1]) { // good cluster on bending side, check if there is data from the non-bending side as well if (fecIdNB >= 0 && channelNB >= 0) { - mHistogramPseudoeffElec->getDen()->Fill(fecIdNB, channelNB); + if (mEnable1DPseudoeffMaps) { + mHistogramPseudoeffPerDualSampa->getDen()->Fill(fecIdNB); + } + if (mEnable2DPseudoeffMaps) { + mHistogramPseudoeffElec->getDen()->Fill(fecIdNB, channelNB); + } } if (isGoodNum[1]) { // Check if associated to something on Non-Bending if (fecIdNB >= 0 && channelNB >= 0) { - mHistogramPseudoeffElec->getNum()->Fill(fecIdNB, channelNB); + if (mEnable1DPseudoeffMaps) { + mHistogramPseudoeffPerDualSampa->getNum()->Fill(fecIdNB); + } + if (mEnable2DPseudoeffMaps) { + mHistogramPseudoeffElec->getNum()->Fill(fecIdNB, channelNB); + } } } } @@ -398,7 +432,12 @@ void PreclustersTask::endOfCycle() ILOG(Info, Devel) << "endOfCycle" << AliceO2::InfoLogger::InfoLogger::endm; // update mergeable ratios - mHistogramPseudoeffElec->update(); + if (mEnable1DPseudoeffMaps) { + mHistogramPseudoeffPerDualSampa->update(); + } + if (mEnable2DPseudoeffMaps) { + mHistogramPseudoeffElec->update(); + } mHistogramPreclustersPerDE->update(); mHistogramPreclustersSignalPerDE->update(); }