From b3e13131cce8c2da1e24cee913121e84842c8794 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Wed, 23 Sep 2026 12:07:01 +0200 Subject: [PATCH] [Common] improvements to the muon QA task - added configurable event selection options - added option for adjusting the bias for the magnetic field longitudinal position --- Common/Tasks/qaMuon.cxx | 68 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/Common/Tasks/qaMuon.cxx b/Common/Tasks/qaMuon.cxx index dd1a9c6d76d..ef6fa61b4c9 100644 --- a/Common/Tasks/qaMuon.cxx +++ b/Common/Tasks/qaMuon.cxx @@ -13,6 +13,8 @@ /// \author Paul Veen /// \author Chi Zhang +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/RCTSelectionFlags.h" #include "Common/DataModel/EventSelection.h" #include @@ -83,6 +85,7 @@ using namespace o2::framework; using namespace o2::framework::expressions; using MyEvents = soa::Join; +using MyBCs = soa::Join; using MyMuonsWithCov = soa::Join; using MyMFTs = aod::MFTTracks; @@ -185,6 +188,16 @@ struct muonQa { Configurable fEnableSingleMuonDiMuonCorrelations{"cfgEnableMuonDiMuonCorrelations", false, "Enable muon-dimuon QA checks"}; } configQAs; + //// Variables for selecting events + struct : ConfigurableGroup { + Configurable fEvSelRequireGoodRCT{"cfgEvSelRequireGoodRCT", false, "Require good detector flags in Run Condition Table"}; + Configurable fEvSelRequireFrameBordersExclusion{"cfgEvSelRequireFrameBordersExclusion", false, "Exclude events in the TF and ITS ROF borders"}; + Configurable fEvSelRequireNoCollInTimeRange{"cfgEvSelRequireNoCollInTimeRange", false, "Exclude events with multiple collisions in time range (standard)"}; + Configurable fEvSelRequireNoSameBunch{"cfgEvSelRequireNoSameBunch", false, "Exclude events with multiple collisions in the same bunch crossing"}; + Configurable fEvSelVtxZMin{"cfgEvSelVtxZMin", -10.0f, "Minimum accepted value for vertex z position"}; + Configurable fEvSelVtxZMax{"cfgEvSelVtxZMax", 10.0f, "Maximum accepted value for vertex z position"}; + } configEvSel; + //// Variables for selecting muon tracks struct : ConfigurableGroup { Configurable fPMchLow{"cfgPMchLow", 0.0f, ""}; @@ -214,6 +227,9 @@ struct muonQa { Configurable fDimuonDCAMassLow{"cfgDimuonDCAMassLow", 2.8f, ""}; Configurable fDimuonDCAMassHigh{"cfgDimuonDCAMassHigh", 3.4f, ""}; + // Magnetic field position bias + Configurable fFieldOriginBiasZ{"cfgFieldOriginBiasZ", 0.0f, "Bias applied to the magnetic field z position"}; + //// Variables for alignment corrections Configurable fEnableMFTAlignmentCorrections{"cfgEnableMFTAlignmentCorrections", false, ""}; @@ -273,6 +289,8 @@ struct muonQa { o2::field::MagneticField* fieldB = nullptr; double Bz; // Bz for MFT + o2::aod::rctsel::RCTFlagsChecker rctChecker{"CBT_muon_glo", false, false, true}; + geo::TransformationCreator transformation; std::map transformRef; // reference geometry w.r.t track data std::map transformNew; // new geometry @@ -2345,7 +2363,8 @@ struct muonQa { fgValues = {}; } - void initCCDB(aod::BCsWithTimestamps const& bcs) + template + void initCCDB(BC const& bcs) { // Update CCDB informations if (bcs.size() > 0 && fCurrentRun != bcs.begin().runNumber()) { @@ -2407,6 +2426,9 @@ struct muonQa { ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); + // configure magnetic field position bias + o2::conf::ConfigurableParam::setValue("FieldOriginBias.z", std::to_string(fFieldOriginBiasZ.value)); + // Configuration for track fitter const auto& trackerParam = TrackerParam::Instance(); trackFitter.setBendingVertexDispersion(trackerParam.bendingVertexDispersion); @@ -2685,6 +2707,38 @@ struct muonQa { { for (auto const& collision : collisions) { + const auto& bc = bcs.rawIteratorAt(collision.bcId()); + + if (configEvSel.fEvSelRequireFrameBordersExclusion) { + // remove TF/ROF borders and ambiguous collisions + if (!bc.selection_bit(o2::aod::evsel::kNoTimeFrameBorder) || + !bc.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + continue; + } + } + + // remove events with multiple collisions in one bunch crossing + if (configEvSel.fEvSelRequireNoCollInTimeRange && + !bc.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + continue; + } + + // remove events with multiple collisions in one bunch crossing + if (configEvSel.fEvSelRequireNoSameBunch && + !bc.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + continue; + } + + // remove events with bad RCT flags + if (configEvSel.fEvSelRequireGoodRCT && !rctChecker(collision)) { + continue; + } + + if (collision.posZ() < configEvSel.fEvSelVtxZMin || + collision.posZ() > configEvSel.fEvSelVtxZMax) { + continue; + } + uint64_t collisionIndex = collision.globalIndex(); auto muonsThisCollision = muons.sliceBy(fwdtracksPerCollision, collisionIndex); auto mftsThisCollision = mfts.sliceBy(mftPerCollision, collisionIndex); @@ -2695,7 +2749,7 @@ struct muonQa { auto& fgValuesColl = collisionSel[collisionIndex]; FillCollision(collision, fgValuesColl); - fgValuesColl.bc = bcs.rawIteratorAt(collision.bcId()).globalBC(); + fgValuesColl.bc = bc.globalBC(); fgValuesColl.multMFT = mftsThisCollision.size(); } } @@ -2708,7 +2762,7 @@ struct muonQa { //// Get collision information if associated VarColl fgValuesColl; - if (muon.has_collision()) { + if (muon.has_collision() && collisions.contains(muon.collisionId())) { fgValuesColl = collisions.at(muon.collisionId()); } else { continue; @@ -2897,8 +2951,14 @@ struct muonQa { for (const auto& [muon1, muon2] : muonPairs) { auto collisionIndex1 = muon1.first; + if (!collisions.contains(collisionIndex1)) { + continue; + } auto const& collision1 = collisions.at(collisionIndex1); auto collisionIndex2 = muon2.first; + if (!collisions.contains(collisionIndex2)) { + continue; + } auto const& collision2 = collisions.at(collisionIndex2); auto mchIndex1 = muon1.second; @@ -3840,7 +3900,7 @@ struct muonQa { } } - void processMuonQa(MyEvents const& collisions, aod::BCsWithTimestamps const& bcs, MyMuonsWithCov const& muontracks, MyMFTs const& mfttracks, aod::FwdTrkCls const& muonclusters) + void processMuonQa(MyEvents const& collisions, MyBCs const& bcs, MyMuonsWithCov const& muontracks, MyMFTs const& mfttracks, aod::FwdTrkCls const& muonclusters) { std::map collisionSel; std::map> matchingCandidates;