From d36a53d1a81141b6d9f1d73f46e4121f00150358 Mon Sep 17 00:00:00 2001 From: Evgeny Kryshen Date: Sat, 21 Mar 2026 10:53:15 +0300 Subject: [PATCH] Added VCH counter QA --- DPG/Tasks/AOTEvent/lumiQa.cxx | 243 ++++++++++++++++++++++++++-------- 1 file changed, 191 insertions(+), 52 deletions(-) diff --git a/DPG/Tasks/AOTEvent/lumiQa.cxx b/DPG/Tasks/AOTEvent/lumiQa.cxx index fa244f31861..35ef282650b 100644 --- a/DPG/Tasks/AOTEvent/lumiQa.cxx +++ b/DPG/Tasks/AOTEvent/lumiQa.cxx @@ -32,6 +32,7 @@ struct LumiQaTask { int lastRunNumber = -1; double maxSec = 1; double minSec = 0; + TH1* hCalibV0A = nullptr; TH1* hCalibT0C = nullptr; static const int nBCsPerOrbit = o2::constants::lhc::LHCMaxBunches; std::bitset bcPatternB; @@ -48,9 +49,11 @@ struct LumiQaTask { const AxisSpec axisMultZNA{2000, 0., 400., "ZNA multiplicity"}; const AxisSpec axisMultZNC{2000, 0., 400., "ZNC multiplicity"}; + const AxisSpec axisMultV0A{1000, 0., 200000., "V0A multiplicity"}; const AxisSpec axisMultT0M{1000, 0., 270000., "T0M multiplicity"}; const AxisSpec axisMultT0A{1000, 0., 200000., "T0A multiplicity"}; const AxisSpec axisMultT0C{1000, 0., 70000., "T0C multiplicity"}; + const AxisSpec axisCentV0A{100, 0., 100., "V0A centrality"}; const AxisSpec axisCentT0C{100, 0., 100., "T0C centrality"}; const AxisSpec axisTime{700, -35., 35., "time (ns)"}; const AxisSpec axisMultChannelT0A{5000, 0., 5000., "T0A channel multiplicity"}; @@ -62,10 +65,24 @@ struct LumiQaTask { histos.add("hMultZNA", "", kTH1F, {axisMultZNA}); histos.add("hMultZNC", "", kTH1F, {axisMultZNC}); + histos.add("hMultV0A", "", kTH1F, {axisMultV0A}); histos.add("hMultT0M", "", kTH1F, {axisMultT0M}); histos.add("hMultT0A", "", kTH1F, {axisMultT0A}); histos.add("hMultT0C", "", kTH1F, {axisMultT0C}); + histos.add("hCentV0A", "", kTH1F, {axisCentV0A}); histos.add("hCentT0C", "", kTH1F, {axisCentT0C}); + + histos.add("hMultV0AselTVXB", "", kTH1F, {axisMultV0A}); + histos.add("hCentV0AselTVXB", "", kTH1F, {axisCentV0A}); + histos.add("hMultVCHselTVXB", "", kTH1F, {axisMultV0A}); + histos.add("hCentVCHselTVXB", "", kTH1F, {axisCentV0A}); + histos.add("hMultV0AselZACTVXB", "", kTH1F, {axisMultV0A}); + histos.add("hCentV0AselZACTVXB", "", kTH1F, {axisCentV0A}); + histos.add("hMultVCHselZACTVXB", "", kTH1F, {axisMultV0A}); + histos.add("hCentVCHselZACTVXB", "", kTH1F, {axisCentV0A}); + + histos.add("hMultT0CselTVXB", "", kTH1F, {axisMultT0C}); + histos.add("hCentT0CselTVXB", "", kTH1F, {axisCentT0C}); histos.add("hMultT0MselTSC", "", kTH1F, {axisMultT0M}); histos.add("hMultT0MselTCE", "", kTH1F, {axisMultT0M}); histos.add("hMultT0CselTCE", "", kTH1F, {axisMultT0C}); @@ -86,15 +103,29 @@ struct LumiQaTask { histos.add("hTimeZNAselC", "", kTH1F, {axisTime}); histos.add("hTimeZNCselC", "", kTH1F, {axisTime}); - histos.add("hCounterTCE", "", kTH1D, {{1, 0., 1.}}); - histos.add("hCounterZNA", "", kTH1D, {{1, 0., 1.}}); - histos.add("hCounterZNC", "", kTH1D, {{1, 0., 1.}}); - histos.add("hCounterZEM", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterTCEselB", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterZNAselB", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterZNCselB", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterZEMselB", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterVCHselB", "", kTH1D, {{1, 0., 1.}}); + + histos.add("hCounterTCEselA", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterZNAselA", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterZNCselA", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterZEMselA", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterVCHselA", "", kTH1D, {{1, 0., 1.}}); + + histos.add("hCounterTCEselC", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterZNAselC", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterZNCselC", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterZEMselC", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterVCHselC", "", kTH1D, {{1, 0., 1.}}); + histos.add("hMultT0AperChannel", "", kTH2D, {axisMultChannelT0A, axisChannelsT0A}); histos.add("hMultT0CperChannel", "", kTH2D, {axisMultChannelT0C, axisChannelsT0C}); } - void process(BCsRun3 const& bcs, aod::Zdcs const&, aod::FT0s const&) + void process(BCsRun3 const& bcs, aod::Zdcs const&, aod::FT0s const&, aod::FV0As const&) { int runNumber = bcs.iteratorAt(0).runNumber(); const char* srun = Form("%d", runNumber); @@ -117,6 +148,12 @@ struct LumiQaTask { return; } + hCalibV0A = reinterpret_cast(callst->FindObject("hCalibZeqFV0")); + if (hCalibV0A == nullptr) { + LOGF(info, "hCalibZeqFV0 histogram is not available for run=%d at timestamp=%llu", runNumber, ts); + return; + } + hCalibT0C = reinterpret_cast(callst->FindObject("hCalibZeqFT0C")); if (hCalibT0C == nullptr) { LOGF(info, "hCalibZeqFT0C histogram is not available for run=%d at timestamp=%llu", runNumber, ts); @@ -136,71 +173,172 @@ struct LumiQaTask { const AxisSpec axisBCs{nBCsPerOrbit, 0., static_cast(nBCsPerOrbit), ""}; const AxisSpec axisSeconds{nTimeBins, 0, timeInterval, "seconds"}; - histos.add("hSecondsBcsTCE", "", kTH2D, {axisSeconds, axisBCs}); - histos.add("hSecondsBcsZNA", "", kTH2D, {axisSeconds, axisBCs}); - histos.add("hSecondsBcsZNC", "", kTH2D, {axisSeconds, axisBCs}); - histos.add("hSecondsBcsZEM", "", kTH2D, {axisSeconds, axisBCs}); + histos.add("hSecondsBcsTCEselB", "", kTH2D, {axisSeconds, axisBCs}); + histos.add("hSecondsBcsZNAselB", "", kTH2D, {axisSeconds, axisBCs}); + histos.add("hSecondsBcsZNCselB", "", kTH2D, {axisSeconds, axisBCs}); + histos.add("hSecondsBcsZEMselB", "", kTH2D, {axisSeconds, axisBCs}); + histos.add("hSecondsBcsVCHselB", "", kTH2D, {axisSeconds, axisBCs}); + histos.add("hSecondsBcsTCEselA", "", kTH2D, {axisSeconds, axisBCs}); + histos.add("hSecondsBcsZNAselA", "", kTH2D, {axisSeconds, axisBCs}); + histos.add("hSecondsBcsZNCselA", "", kTH2D, {axisSeconds, axisBCs}); + histos.add("hSecondsBcsZEMselA", "", kTH2D, {axisSeconds, axisBCs}); + histos.add("hSecondsBcsVCHselA", "", kTH2D, {axisSeconds, axisBCs}); + histos.add("hSecondsBcsTCEselC", "", kTH2D, {axisSeconds, axisBCs}); + histos.add("hSecondsBcsZNAselC", "", kTH2D, {axisSeconds, axisBCs}); + histos.add("hSecondsBcsZNCselC", "", kTH2D, {axisSeconds, axisBCs}); + histos.add("hSecondsBcsZEMselC", "", kTH2D, {axisSeconds, axisBCs}); + histos.add("hSecondsBcsVCHselC", "", kTH2D, {axisSeconds, axisBCs}); } for (const auto& bc : bcs) { int64_t ts = bc.timestamp(); + auto inputMask = bc.inputMask(); double secFromSOR = ts / 1000. - minSec; - double bcInOrbit = bc.globalBC() % nBCsPerOrbit; + int bcInOrbit = bc.globalBC() % nBCsPerOrbit; + bool maskB = bcPatternB[bcInOrbit]; + bool maskA = bcPatternA[bcInOrbit]; + bool maskC = bcPatternC[bcInOrbit]; + bool tvxCTP = TESTBIT(inputMask, 2); + bool tscCTP = TESTBIT(inputMask, 3); + bool tceCTP = TESTBIT(inputMask, 4); + bool vchCTP = TESTBIT(inputMask, 9); + bool zemCTP = TESTBIT(inputMask, 24); + bool zncCTP = TESTBIT(inputMask, 25); + + LOGP(debug, "CTP: tvx={} tsc={} tce={} vch={} zem={} znc={}", tvxCTP, tscCTP, tceCTP, vchCTP, zemCTP, zncCTP); + + bool tvx = bc.has_ft0() ? TESTBIT(bc.ft0().triggerMask(), o2::ft0::Triggers::bitVertex) : 0; + bool tsc = bc.has_ft0() ? TESTBIT(bc.ft0().triggerMask(), o2::ft0::Triggers::bitSCen) : 0; + bool tce = bc.has_ft0() ? TESTBIT(bc.ft0().triggerMask(), o2::ft0::Triggers::bitCen) : 0; + bool vch = bc.has_fv0a() ? TESTBIT(bc.fv0a().triggerMask(), o2::fit::Triggers::bitTrgCharge) : 0; + + float meanTimeZNA = 0.; + float meanTimeZNC = 0.; + bool zna = bc.has_zdc() ? std::fabs(bc.zdc().timeZNA() - meanTimeZNA) < 2 : 0; // ns + bool znc = bc.has_zdc() ? std::fabs(bc.zdc().timeZNC() - meanTimeZNC) < 2 : 0; // ns + bool zem = zna || znc; + bool zac = zna && znc; + + // check if TCE triggers from FT0 mask and CTP are consistent + if (tce != tceCTP) { + LOGP(warning, "TCEfromFT0={} TCEfromCTP={}", tce, tceCTP); + } + if (bc.has_zdc()) { float timeZNA = bc.zdc().timeZNA(); float timeZNC = bc.zdc().timeZNC(); float multZNA = bc.zdc().energyCommonZNA(); float multZNC = bc.zdc().energyCommonZNC(); - histos.fill(HIST("hMultZNA"), multZNA); histos.fill(HIST("hMultZNC"), multZNC); histos.fill(HIST("hTimeZNA"), timeZNA); histos.fill(HIST("hTimeZNC"), timeZNC); - if (bc.has_ft0() && TESTBIT(bc.ft0().triggerMask(), o2::ft0::Triggers::bitVertex)) { // TVX + if (tvx) { // TVX histos.fill(HIST("hTimeZNAselTVX"), timeZNA); histos.fill(HIST("hTimeZNCselTVX"), timeZNC); } - - if (bcPatternB[bc.globalBC() % nBCsPerOrbit]) { // B-mask + if (maskB) { // B-mask histos.fill(HIST("hTimeZNAselB"), timeZNA); histos.fill(HIST("hTimeZNCselB"), timeZNC); } - if (bcPatternA[bc.globalBC() % nBCsPerOrbit]) { // A-mask + if (maskA) { // A-mask histos.fill(HIST("hTimeZNAselA"), timeZNA); histos.fill(HIST("hTimeZNCselA"), timeZNC); } - if (bcPatternC[bc.globalBC() % nBCsPerOrbit]) { // C-mask + if (maskC) { // C-mask histos.fill(HIST("hTimeZNAselC"), timeZNA); histos.fill(HIST("hTimeZNCselC"), timeZNC); } - double meanTimeZNA = 0; - double meanTimeZNC = 0; - if (runNumber == 544795) { - meanTimeZNA = 0.49; - meanTimeZNC = -5.19; - } else if (runNumber == 544911) { - meanTimeZNA = -1.44; - meanTimeZNC = -11.39; + // B-mask + if (zna && maskB) { + histos.get(HIST("hCounterZNAselB"))->Fill(srun, 1); + histos.fill(HIST("hSecondsBcsZNAselB"), secFromSOR, bcInOrbit); + } + if (znc && maskB) { + histos.get(HIST("hCounterZNCselB"))->Fill(srun, 1); + histos.fill(HIST("hSecondsBcsZNCselB"), secFromSOR, bcInOrbit); + } + if (zem && maskB) { + histos.get(HIST("hCounterZEMselB"))->Fill(srun, 1); + histos.fill(HIST("hSecondsBcsZEMselB"), secFromSOR, bcInOrbit); + } + + // A-mask + if (zna && maskA) { + histos.get(HIST("hCounterZNAselA"))->Fill(srun, 1); + histos.fill(HIST("hSecondsBcsZNAselA"), secFromSOR, bcInOrbit); + } + if (znc && maskA) { + histos.get(HIST("hCounterZNCselA"))->Fill(srun, 1); + histos.fill(HIST("hSecondsBcsZNCselA"), secFromSOR, bcInOrbit); + } + if (zem && maskA) { + histos.get(HIST("hCounterZEMselA"))->Fill(srun, 1); + histos.fill(HIST("hSecondsBcsZEMselA"), secFromSOR, bcInOrbit); + } + + // C-mask + if (zna && maskC) { + histos.get(HIST("hCounterZNAselC"))->Fill(srun, 1); + histos.fill(HIST("hSecondsBcsZNAselC"), secFromSOR, bcInOrbit); + } + if (znc && maskC) { + histos.get(HIST("hCounterZNCselC"))->Fill(srun, 1); + histos.fill(HIST("hSecondsBcsZNCselC"), secFromSOR, bcInOrbit); + } + if (zem && maskC) { + histos.get(HIST("hCounterZEMselC"))->Fill(srun, 1); + histos.fill(HIST("hSecondsBcsZEMselC"), secFromSOR, bcInOrbit); + } + } + + if (bc.has_fv0a()) { + float multV0A = 0.; + for (auto mult : bc.fv0a().amplitude()) { + multV0A += mult; } + float centV0A = hCalibV0A->GetBinContent(hCalibV0A->FindFixBin(multV0A)); + histos.fill(HIST("hMultV0A"), multV0A); + histos.fill(HIST("hCentV0A"), centV0A); - if (fabs(timeZNA - meanTimeZNA) < 2) { - histos.get(HIST("hCounterZNA"))->Fill(srun, 1); - histos.fill(HIST("hSecondsBcsZNA"), secFromSOR, bcInOrbit); + if (tvx && maskB) { + histos.fill(HIST("hMultV0AselTVXB"), multV0A); + histos.fill(HIST("hCentV0AselTVXB"), centV0A); } - if (fabs(timeZNC - meanTimeZNC) < 2) { - histos.get(HIST("hCounterZNC"))->Fill(srun, 1); - histos.fill(HIST("hSecondsBcsZNC"), secFromSOR, bcInOrbit); + + if (tvx && maskB && vch) { + histos.fill(HIST("hMultVCHselTVXB"), multV0A); + histos.fill(HIST("hCentVCHselTVXB"), centV0A); + histos.get(HIST("hCounterVCHselB"))->Fill(srun, 1); + histos.fill(HIST("hSecondsBcsVCHselB"), secFromSOR, bcInOrbit); + } + + if (tvx && maskA && vch) { + histos.get(HIST("hCounterVCHselA"))->Fill(srun, 1); + histos.fill(HIST("hSecondsBcsVCHselA"), secFromSOR, bcInOrbit); } - if (fabs(timeZNA - meanTimeZNA) < 2 || fabs(timeZNC - meanTimeZNC) < 2) { - histos.get(HIST("hCounterZEM"))->Fill(srun, 1); - histos.fill(HIST("hSecondsBcsZEM"), secFromSOR, bcInOrbit); + + if (tvx && maskC && vch) { + histos.get(HIST("hCounterVCHselC"))->Fill(srun, 1); + histos.fill(HIST("hSecondsBcsVCHselC"), secFromSOR, bcInOrbit); + } + + if (tvx && maskB && zac) { + histos.fill(HIST("hMultV0AselZACTVXB"), multV0A); + histos.fill(HIST("hCentV0AselZACTVXB"), centV0A); + } + + if (tvx && maskB && vch && zac) { + histos.fill(HIST("hMultVCHselZACTVXB"), multV0A); + histos.fill(HIST("hCentVCHselZACTVXB"), centV0A); } } if (!bc.has_ft0()) { continue; } + for (unsigned int ic = 0; ic < bc.ft0().amplitudeA().size(); ic++) { histos.fill(HIST("hMultT0AperChannel"), bc.ft0().amplitudeA()[ic], bc.ft0().channelA()[ic]); } @@ -217,33 +355,34 @@ struct LumiQaTask { histos.fill(HIST("hMultT0C"), multT0C); histos.fill(HIST("hCentT0C"), centT0C); - if (TESTBIT(bc.ft0().triggerMask(), o2::ft0::Triggers::bitSCen)) { // TSC - histos.fill(HIST("hMultT0MselTSC"), multT0M); + if (tvx && maskB) { + histos.fill(HIST("hMultT0CselTVXB"), multT0C); + histos.fill(HIST("hCentT0CselTVXB"), centT0C); } - if (!TESTBIT(bc.ft0().triggerMask(), o2::ft0::Triggers::bitCen)) { // TCE - continue; + if (tsc) { + histos.fill(HIST("hMultT0MselTSC"), multT0M); } - histos.fill(HIST("hMultT0MselTCE"), multT0M); - histos.fill(HIST("hMultT0CselTCE"), multT0C); - histos.fill(HIST("hCentT0CselTCE"), centT0C); - if (!TESTBIT(bc.ft0().triggerMask(), o2::ft0::Triggers::bitVertex)) { // TVX - continue; + if (tce) { + histos.fill(HIST("hMultT0MselTCE"), multT0M); + histos.fill(HIST("hMultT0CselTCE"), multT0C); + histos.fill(HIST("hCentT0CselTCE"), centT0C); } - histos.fill(HIST("hMultT0CselTVXTCE"), multT0C); - histos.fill(HIST("hCentT0CselTVXTCE"), centT0C); - if (!bcPatternB[bc.globalBC() % nBCsPerOrbit]) { // B-mask - continue; + if (tce && tvx) { + histos.fill(HIST("hMultT0CselTVXTCE"), multT0C); + histos.fill(HIST("hCentT0CselTVXTCE"), centT0C); } - histos.fill(HIST("hMultT0CselTVXTCEB"), multT0C); - histos.fill(HIST("hCentT0CselTVXTCEB"), centT0C); - histos.get(HIST("hCounterTCE"))->Fill(srun, 1); - histos.fill(HIST("hSecondsBcsTCE"), secFromSOR, bcInOrbit); - } - } + if (tce && tvx && maskB) { + histos.fill(HIST("hMultT0CselTVXTCEB"), multT0C); + histos.fill(HIST("hCentT0CselTVXTCEB"), centT0C); + histos.get(HIST("hCounterTCEselB"))->Fill(srun, 1); + histos.fill(HIST("hSecondsBcsTCEselB"), secFromSOR, bcInOrbit); + } + } // bc loop + } // process }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)