From 748fcb3412f0a02a8edff14341a62871db8b8e74 Mon Sep 17 00:00:00 2001 From: Artur Furs <9881239+afurs@users.noreply.github.com> Date: Wed, 24 Jan 2024 12:50:32 +0300 Subject: [PATCH] FT0 recoQC: some refactoring and new plots based on trigger (#2102) clang FT0 recoQC: removing rebin feature --- .../FIT/Common/include/FITCommon/HelperHist.h | 5 + Modules/FIT/FT0/include/FT0/RecPointsQcTask.h | 47 ++----- Modules/FIT/FT0/src/RecPointsQcTask.cxx | 121 ++++++++---------- 3 files changed, 69 insertions(+), 104 deletions(-) diff --git a/Modules/FIT/Common/include/FITCommon/HelperHist.h b/Modules/FIT/Common/include/FITCommon/HelperHist.h index e72c251f1c..4ed04e2b05 100644 --- a/Modules/FIT/Common/include/FITCommon/HelperHist.h +++ b/Modules/FIT/Common/include/FITCommon/HelperHist.h @@ -49,9 +49,12 @@ inline void getMapBinLabelsPerAxis(std::map::type; const auto& arg = std::get(tupleArgs); constexpr bool isArgMapBinLabels = std::is_same_v, std::map>; + constexpr bool isArgTupleBins = std::is_same_v, std::tuple>; if constexpr (isArgMapBinLabels && NArgLocal == 0) { // map with bin labels mapAxisToMapBinLabels.insert({ NAxis, arg }); getMapBinLabelsPerAxis(mapAxisToMapBinLabels, tupleArgs); + } else if constexpr (isArgTupleBins && NArgLocal == 0) { // tuple of bin params + getMapBinLabelsPerAxis(mapAxisToMapBinLabels, tupleArgs); } else if constexpr (!isArgMapBinLabels && NArgLocal < 2) { // first or second bin argument getMapBinLabelsPerAxis(mapAxisToMapBinLabels, tupleArgs); } else if constexpr (!isArgMapBinLabels && NArgLocal == 2) { // third bin argument @@ -69,6 +72,8 @@ inline auto unpackHistArg(const Arg& arg) { if constexpr (std::is_same_v, std::map>) { return std::make_tuple(static_cast(arg.size()), float(0.0), static_cast(arg.size())); + } else if constexpr (std::is_same_v, std::tuple>) { + return arg; } else { return std::make_tuple(arg); } diff --git a/Modules/FIT/FT0/include/FT0/RecPointsQcTask.h b/Modules/FIT/FT0/include/FT0/RecPointsQcTask.h index 196724c22c..9e870a0308 100644 --- a/Modules/FIT/FT0/include/FT0/RecPointsQcTask.h +++ b/Modules/FIT/FT0/include/FT0/RecPointsQcTask.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -59,57 +60,29 @@ class RecPointsQcTask final : public TaskInterface void endOfCycle() override; void endOfActivity(const Activity& activity) override; void reset() override; - constexpr static std::size_t sOrbitsPerTF = 256; - constexpr static uint8_t sDataIsValidBitPos = 7; private: - // three ways of computing cycle duration: - // 1) number of time frames - // 2) time in ns from InteractionRecord: total range (totalMax - totalMin) - // 3) time in ns from InteractionRecord: sum of each TF duration - // later on choose the best and remove others - double mTimeMinNS = 0.; - double mTimeMaxNS = 0.; - double mTimeCurNS = 0.; - int mTfCounter = 0; - double mTimeSum = 0.; - const float mCFDChannel2NS = 0.01302; // CFD channel width in ns - - template ::value || - std::is_same::value || (std::is_integral::value && !std::is_same::value)>::type> - auto parseParameters(const std::string& param, const std::string& del) - { - std::regex reg(del); - std::sregex_token_iterator first{ param.begin(), param.end(), reg, -1 }, last; - std::vector vecResult; - for (auto it = first; it != last; it++) { - if constexpr (std::is_integral::value && !std::is_same::value) { - vecResult.push_back(std::stoi(*it)); - } else if constexpr (std::is_floating_point::value) { - vecResult.push_back(std::stod(*it)); - } else if constexpr (std::is_same::value) { - vecResult.push_back(*it); - } - } - return vecResult; - } - - void rebinFromConfig(); TList* mListHistGarbage; std::set mSetAllowedChIDs; - std::array mStateLastIR2Ch; - + unsigned int mTrgPos_minBias; + unsigned int mTrgPos_allEvents; // Objects which will be published std::unique_ptr mHistAmp2Ch; std::unique_ptr mHistTime2Ch; std::unique_ptr mHistCollTimeAC; std::unique_ptr mHistCollTimeA; std::unique_ptr mHistCollTimeC; + std::unique_ptr mHistSumTimeAC_perTrg; + std::unique_ptr mHistDiffTimeAC_perTrg; + std::unique_ptr mHistTimeA_perTrg; + std::unique_ptr mHistTimeC_perTrg; + std::unique_ptr mHistBC_perTriggers; std::unique_ptr mHistResCollTimeA; std::unique_ptr mHistResCollTimeC; std::map mMapHistAmpVsTime; + + std::map mMapTrgBits{}; }; } // namespace o2::quality_control_modules::ft0 diff --git a/Modules/FIT/FT0/src/RecPointsQcTask.cxx b/Modules/FIT/FT0/src/RecPointsQcTask.cxx index b9f962bcf4..59d9c202da 100644 --- a/Modules/FIT/FT0/src/RecPointsQcTask.cxx +++ b/Modules/FIT/FT0/src/RecPointsQcTask.cxx @@ -26,68 +26,22 @@ #include #include +#include "FITCommon/HelperHist.h" +#include "FITCommon/HelperCommon.h" +#include "FITCommon/HelperFIT.h" namespace o2::quality_control_modules::ft0 { +using namespace o2::quality_control_modules::fit; + RecPointsQcTask::~RecPointsQcTask() { delete mListHistGarbage; } -void RecPointsQcTask::rebinFromConfig() -{ - /* Examples: - "binning_SumAmpC": "100, 0, 100" - "binning_BcOrbitMap_TrgOrA": "25, 0, 256, 10, 0, 3564" - hashtag = all channel IDs (mSetAllowedChIDs), e.g. - "binning_Amp_channel#": "5,-10,90" - is equivalent to: - "binning_Amp_channel0": "5,-10,90" - "binning_Amp_channel1": "5,-10,90" - "binning_Amp_channel2": "5,-10,90" ... - */ - auto rebinHisto = [](std::string hName, std::string binning) { - std::vector tokenizedBinning; - boost::split(tokenizedBinning, binning, boost::is_any_of(",")); - if (tokenizedBinning.size() == 3) { // TH1 - ILOG(Debug) << "config: rebinning TH1 " << hName << " -> " << binning << ENDM; - auto htmp = (TH1F*)gROOT->FindObject(hName.data()); - htmp->SetBins(std::atof(tokenizedBinning[0].c_str()), std::atof(tokenizedBinning[1].c_str()), std::atof(tokenizedBinning[2].c_str())); - } else if (tokenizedBinning.size() == 6) { // TH2 - auto htmp = (TH2F*)gROOT->FindObject(hName.data()); - ILOG(Debug) << "config: rebinning TH2 " << hName << " -> " << binning << ENDM; - htmp->SetBins(std::atof(tokenizedBinning[0].c_str()), std::atof(tokenizedBinning[1].c_str()), std::atof(tokenizedBinning[2].c_str()), - std::atof(tokenizedBinning[3].c_str()), std::atof(tokenizedBinning[4].c_str()), std::atof(tokenizedBinning[5].c_str())); - } else { - ILOG(Warning) << "config: invalid binning parameter: " << hName << " -> " << binning << ENDM; - } - }; - - const std::string rebinKeyword = "binning"; - const char* channelIdPlaceholder = "#"; - for (auto& param : mCustomParameters.getAllDefaults()) { - if (param.first.rfind(rebinKeyword, 0) != 0) - continue; - std::string hName = param.first.substr(rebinKeyword.length() + 1); - std::string binning = param.second.c_str(); - if (hName.find(channelIdPlaceholder) != std::string::npos) { - for (const auto& chID : mSetAllowedChIDs) { - std::string hNameCur = hName.substr(0, hName.find(channelIdPlaceholder)) + std::to_string(chID) + hName.substr(hName.find(channelIdPlaceholder) + 1); - rebinHisto(hNameCur, binning); - } - } else if (!gROOT->FindObject(hName.data())) { - ILOG(Warning) << "config: histogram named \"" << hName << "\" not found" << ENDM; - continue; - } else { - rebinHisto(hName, binning); - } - } -} - void RecPointsQcTask::initialize(o2::framework::InitContext& /*ctx*/) { ILOG(Info, Support) << "@@@@initialize RecoQcTask" << ENDM; // QcInfoLogger is used. FairMQ logs will go to there as well. - mStateLastIR2Ch = {}; mHistTime2Ch = std::make_unique("TimePerChannel", "Time vs Channel;Channel;Time [ps]", NCHANNELS, 0, NCHANNELS, 500, -2050, 2050); mHistTime2Ch->SetOption("colz"); @@ -105,7 +59,7 @@ void RecPointsQcTask::initialize(o2::framework::InitContext& /*ctx*/) if (auto param = mCustomParameters.find("ChannelIDs"); param != mCustomParameters.end()) { const auto chIDs = param->second; const std::string del = ","; - vecChannelIDs = parseParameters(chIDs, del); + vecChannelIDs = helper::parseParameters(chIDs, del); } else { for (unsigned int iCh = 0; iCh < o2::ft0::Constants::sNCHANNELS_PM; iCh++) vecChannelIDs.push_back(iCh); @@ -122,8 +76,21 @@ void RecPointsQcTask::initialize(o2::framework::InitContext& /*ctx*/) getObjectsManager()->startPublishing(mHistResCollTimeA.get()); getObjectsManager()->startPublishing(mHistResCollTimeC.get()); + const std::tuple binsTime{ 500, -2500, 2500 }; + const std::tuple binsBC{ 3564, 0, 3564 }; + mMapTrgBits = HelperTrgFIT::sMapBasicTrgBitsFT0; + mTrgPos_minBias = mMapTrgBits.size(); + mMapTrgBits.insert({ mTrgPos_minBias, "MinBias" }); + mTrgPos_allEvents = mMapTrgBits.size(); + mMapTrgBits.insert({ mTrgPos_allEvents, "AllEvents" }); + mHistSumTimeAC_perTrg = helper::registerHist(getObjectsManager(), "COLZ", "SumTimeAC_perTrg", "(T0A+T0C)/2 per Trigger;Time [ps]; Trigger", binsTime, mMapTrgBits); + mHistDiffTimeAC_perTrg = helper::registerHist(getObjectsManager(), "COLZ", "DiffTimeAC_perTrg", "(T0C-T0C)/2 per Trigger;Time [ps]; Trigger", binsTime, mMapTrgBits); + mHistTimeA_perTrg = helper::registerHist(getObjectsManager(), "COLZ", "TimeA_perTrg", "T0A per Trigger;Time [ps]; Trigger", binsTime, mMapTrgBits); + mHistTimeC_perTrg = helper::registerHist(getObjectsManager(), "COLZ", "TimeC_perTrg", "T0C per Trigger;Time [ps]; Trigger", binsTime, mMapTrgBits); + mHistBC_perTriggers = helper::registerHist(getObjectsManager(), "COLZ", "BC_perTriggers", "BC per Triggers;BC; Trigger", binsBC, mMapTrgBits); + for (const auto& chID : mSetAllowedChIDs) { - auto pairHistAmpVsTime = mMapHistAmpVsTime.insert({ chID, new TH2F(Form("Amp_vs_time_channel%i", chID), Form("Amplitude vs time, channel %i;Amp;Time", chID), 420, -100, 500, 410, -2050, 2050) }); + auto pairHistAmpVsTime = mMapHistAmpVsTime.insert({ chID, new TH2F(Form("Amp_vs_time_channel%i", chID), Form("Amplitude vs time, channel %i;Amp;Time", chID), 1000, 0, 4000, 100, -1000, 1000) }); if (pairHistAmpVsTime.second) { mListHistGarbage->Add(pairHistAmpVsTime.first->second); getObjectsManager()->startPublishing(pairHistAmpVsTime.first->second); @@ -131,7 +98,6 @@ void RecPointsQcTask::initialize(o2::framework::InitContext& /*ctx*/) } ILOG(Info, Support) << "@@@ histos created" << ENDM; - rebinFromConfig(); // after all histos are created } void RecPointsQcTask::startOfActivity(const Activity& activity) @@ -144,6 +110,12 @@ void RecPointsQcTask::startOfActivity(const Activity& activity) mHistCollTimeC->Reset(); mHistResCollTimeA->Reset(); mHistResCollTimeC->Reset(); + mHistSumTimeAC_perTrg->Reset(); + mHistDiffTimeAC_perTrg->Reset(); + mHistTimeA_perTrg->Reset(); + mHistTimeC_perTrg->Reset(); + mHistBC_perTriggers->Reset(); + for (auto& entry : mMapHistAmpVsTime) { entry.second->Reset(); } @@ -151,24 +123,15 @@ void RecPointsQcTask::startOfActivity(const Activity& activity) void RecPointsQcTask::startOfCycle() { - mTimeMinNS = -1; - mTimeMaxNS = 0.; - mTimeCurNS = 0.; - mTfCounter = 0; - mTimeSum = 0.; } void RecPointsQcTask::monitorData(o2::framework::ProcessingContext& ctx) { - double curTfTimeMin = -1; - double curTfTimeMax = 0; - mTfCounter++; auto chan = ctx.inputs().get>("channels"); auto recpoints = ctx.inputs().get>("recpoints"); - bool isFirst = true; - uint32_t firstOrbit; - for (auto& recpoint : recpoints) { + for (const auto& recpoint : recpoints) { + const auto bc = recpoint.getInteractionRecord().bc; int time[o2::ft0::Constants::sNCHANNELS_PM] = { 0 }; int amp[o2::ft0::Constants::sNCHANNELS_PM] = { 0 }; o2::ft0::Triggers triggersignals = recpoint.getTrigger(); @@ -177,12 +140,31 @@ void RecPointsQcTask::monitorData(o2::framework::ProcessingContext& ctx) mHistCollTimeAC->Fill(static_cast(recpoint.getCollisionTimeMean())); mHistCollTimeA->Fill(static_cast(recpoint.getCollisionTimeA())); mHistCollTimeC->Fill(static_cast(recpoint.getCollisionTimeC())); + const bool minBias = triggersignals.getVertex() && (triggersignals.getCen() || triggersignals.getSCen()); + // Preparing trigger word + uint64_t trgWord = triggersignals.getTriggersignals() & 0b11111; + trgWord |= (static_cast(minBias) << mTrgPos_minBias); + trgWord |= (1ull << mTrgPos_allEvents); + // Filling hists with trg bits + for (const auto& entry : mMapTrgBits) { + if ((trgWord & (1ull << entry.first)) > 0) { + mHistBC_perTriggers->Fill(static_cast(bc), static_cast(entry.first)); + const auto timeA = static_cast(recpoint.getCollisionTimeA()); + const auto timeC = static_cast(recpoint.getCollisionTimeC()); + mHistTimeA_perTrg->Fill(timeA, static_cast(entry.first)); + mHistTimeC_perTrg->Fill(timeC, static_cast(entry.first)); + mHistDiffTimeAC_perTrg->Fill(static_cast(recpoint.getVertex()), static_cast(entry.first)); + if (timeA < o2::ft0::RecPoints::sDummyCollissionTime && timeC < o2::ft0::RecPoints::sDummyCollissionTime) { + mHistSumTimeAC_perTrg->Fill(static_cast(recpoint.getCollisionTimeMean()), static_cast(entry.first)); + } + } + } for (const auto& chData : channels) { time[chData.ChId] = chData.CFDTime; amp[chData.ChId] = chData.QTCAmpl; mHistTime2Ch->Fill(static_cast(chData.ChId), static_cast(chData.CFDTime)); mHistAmp2Ch->Fill(static_cast(chData.ChId), static_cast(chData.QTCAmpl)); - if (mSetAllowedChIDs.find(static_cast(chData.ChId)) != mSetAllowedChIDs.end()) { + if (mSetAllowedChIDs.find(static_cast(chData.ChId)) != mSetAllowedChIDs.end() && minBias) { // ampt-time dependency is needed only for PbPb runs mMapHistAmpVsTime[chData.ChId]->Fill(chData.QTCAmpl, chData.CFDTime); } } @@ -229,7 +211,6 @@ void RecPointsQcTask::monitorData(o2::framework::ProcessingContext& ctx) } } } - mTimeSum += curTfTimeMax - curTfTimeMin; } void RecPointsQcTask::endOfCycle() @@ -254,6 +235,12 @@ void RecPointsQcTask::reset() mHistCollTimeC->Reset(); mHistResCollTimeA->Reset(); mHistResCollTimeC->Reset(); + mHistSumTimeAC_perTrg->Reset(); + mHistDiffTimeAC_perTrg->Reset(); + mHistTimeA_perTrg->Reset(); + mHistTimeC_perTrg->Reset(); + mHistBC_perTriggers->Reset(); + for (auto& entry : mMapHistAmpVsTime) { entry.second->Reset(); }