From b76e73e527c1707b3506583c3788d19bdb852227 Mon Sep 17 00:00:00 2001 From: Paul Veen Date: Wed, 1 Oct 2025 18:45:25 +0200 Subject: [PATCH] [Common] Adding dimuon DCA to muon QA task Adding DCA information from dimuons to the muon QA task. This is necessary to study the MCH alignment in more detail, in particular regarding possible biases of mu plus and mu minus in the top and bottom halves of the first MCH chamber. --- Common/Tasks/qaMuon.cxx | 239 +++++++++++++++++++++++++++++----------- 1 file changed, 172 insertions(+), 67 deletions(-) diff --git a/Common/Tasks/qaMuon.cxx b/Common/Tasks/qaMuon.cxx index 2aef776035a..b8646f83291 100644 --- a/Common/Tasks/qaMuon.cxx +++ b/Common/Tasks/qaMuon.cxx @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -55,8 +56,6 @@ #include #include -#include - #include #include @@ -77,7 +76,6 @@ #include // FIXME: Replace M_PI -using namespace std; using namespace o2; using namespace o2::aod; using namespace o2::mch; @@ -170,9 +168,9 @@ struct VarTrack { }; struct VarClusters { - vector> posClusters; // (x,y,z) - vector> errorClusters; // (ex,ey) - vector DEIDs; + std::vector> posClusters; // (x,y,z) + std::vector> errorClusters; // (ex,ey) + std::vector DEIDs; }; struct muonQa { @@ -182,6 +180,7 @@ struct muonQa { Configurable fEnableQAResidual{"cfgEnableQAResidual", false, "Enable residual QA checks"}; Configurable fEnableQADCA{"cfgEnableQADCA", false, "Enable DCA QA checks"}; Configurable fEnableQADimuon{"cfgEnableQADimuon", false, "Enable dimuon QA checks"}; + Configurable fEnableSingleMuonDiMuonCorrelations{"cfgEnableMuonDiMuonCorrelations", false, "Enable muon-dimuon QA checks"}; } configQAs; //// Variables for selecting muon tracks @@ -251,8 +250,8 @@ struct muonQa { double Bz; // Bz for MFT geo::TransformationCreator transformation; - map transformRef; // reference geometry w.r.t track data - map transformNew; // new geometry + std::map transformRef; // reference geometry w.r.t track data + std::map transformNew; // new geometry TGeoManager* geoNew = nullptr; TGeoManager* geoRef = nullptr; @@ -262,6 +261,7 @@ struct muonQa { HistogramRegistry registry{"registry", {}}; HistogramRegistry registryDCA{"registryDCA", {}}; + HistogramRegistry registryDCAdiMuons{"registryDCAdiMuons", {}}; HistogramRegistry registryResiduals{"registryResiduals", {}}; HistogramRegistry registryResidualsMFT{"registryResidualsMFT", {}}; HistogramRegistry registryResidualsMCH{"registryResidualsMCH", {}}; @@ -288,7 +288,7 @@ struct muonQa { VarTrack fgValuesMCHpv; VarTrack fgValuesMFT; VarTrack fgValuesGlobal; - vector fgValuesCandidates; + std::vector fgValuesCandidates; void CreateBasicHistograms() { @@ -596,7 +596,8 @@ struct muonQa { AxisSpec transverseMomentumAxis = {100, 0, 30, "p_{T} (GeV/c)"}; AxisSpec etaAxis = {40, -5, -1, "#eta"}; AxisSpec rAbsAxis = {10, 0., 100.0, "R_{abs} (cm)"}; - AxisSpec dcaAxis = {40, 0.0, 20.0, "DCA"}; + AxisSpec dcaAxis = {400, -10.0, 10.0, "DCA"}; + AxisSpec dcaAxisReduced = {40, -10.0, 10.0, "DCA"}; AxisSpec phiAxis = {36, -180.0, 180.0, "#phi (degrees)"}; // dimuons AxisSpec invMassAxis = {400, 1, 5, "M_{#mu^{+}#mu^{-}} (GeV/c^{2})"}; @@ -605,21 +606,45 @@ struct muonQa { AxisSpec yPairAxis = {120, 0.0, 6.0, "#y_{pair}"}; AxisSpec invMassAxis2D = {750, 0, 15, "M_{#mu^{+}#mu^{-}} (GeV/c^{2})"}; AxisSpec pTAxis2D = {120, 0, 30, "p_{T} (GeV/c)"}; - // Single muons - dimuons correlations - registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosPt_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{+} p_{T}", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, pTAxis2D}}); - registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegPt_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{-} p_{T}", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, pTAxis2D}}); - // - registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosEta_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{+} #eta", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, etaAxis}}); - registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegEta_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{-} #eta", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, etaAxis}}); - // - registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosRabs_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{+} R_{abs}", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, rAbsAxis}}); - registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegRabs_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{-} R_{abs}", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, rAbsAxis}}); - // - registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosDca_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{+} DCA", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, dcaAxis}}); - registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegDca_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{-} DCA", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, dcaAxis}}); + // Jpsi candidate DCA histograms + registryDimuon.add("dimuon/same-event/DCA/pT_MuPosDCAx_minus_MuNegDCAx_MuonKine_MuonCuts", "DCA_x #mu^{+} minus DCA_x #mu^{-} and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/same-event/DCA/pT_MuPosTDCAx_minus_MuNegTDCAx_MuonKine_MuonCuts", "DCA_x #mu^{+} top minus DCA_x #mu^{-} top and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/same-event/DCA/pT_MuPosTDCAx_minus_MuNegBDCAx_MuonKine_MuonCuts", "DCA_x #mu^{+} top minus DCA_x #mu^{-} bottom and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/same-event/DCA/pT_MuPosBDCAx_minus_MuNegBDCAx_MuonKine_MuonCuts", "DCA_x #mu^{+} bottom minus DCA_x #mu^{-} bottom and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/same-event/DCA/pT_MuPosBDCAx_minus_MuNegTDCAx_MuonKine_MuonCuts", "DCA_x #mu^{+} bottom minus DCA_x #mu^{-} top and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/same-event/DCA/pT_MuPosDCAy_minus_MuNegDCAy_MuonKine_MuonCuts", "DCA_y #mu^{+} minus DCA_y #mu^{-} and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/same-event/DCA/pT_MuPosTDCAy_minus_MuNegTDCAy_MuonKine_MuonCuts", "DCA_y #mu^{+} top minus DCA_y #mu^{-} top and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/same-event/DCA/pT_MuPosTDCAy_minus_MuNegBDCAy_MuonKine_MuonCuts", "DCA_y #mu^{+} top minus DCA_y #mu^{-} bottom and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/same-event/DCA/pT_MuPosBDCAy_minus_MuNegBDCAy_MuonKine_MuonCuts", "DCA_y #mu^{+} bottom minus DCA_y #mu^{-} bottom and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/same-event/DCA/pT_MuPosBDCAy_minus_MuNegTDCAy_MuonKine_MuonCuts", "DCA_y #mu^{+} bottom minus DCA_y #mu^{-} top and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); // - registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosPhi_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{+} #phi", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, phiAxis}}); - registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegPhi_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{-} #phi", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, phiAxis}}); + registryDimuon.add("dimuon/mixed-event/DCA/pT_MuPosDCAx_minus_MuNegDCAx_MuonKine_MuonCuts", "DCA_x #mu^{+} minus DCA_x #mu^{-} and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/mixed-event/DCA/pT_MuPosTDCAx_minus_MuNegTDCAx_MuonKine_MuonCuts", "DCA_x #mu^{+} top minus DCA_x #mu^{-} top and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/mixed-event/DCA/pT_MuPosTDCAx_minus_MuNegBDCAx_MuonKine_MuonCuts", "DCA_x #mu^{+} top minus DCA_x #mu^{-} bottom and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/mixed-event/DCA/pT_MuPosBDCAx_minus_MuNegBDCAx_MuonKine_MuonCuts", "DCA_x #mu^{+} bottom minus DCA_x #mu^{-} bottom and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/mixed-event/DCA/pT_MuPosBDCAx_minus_MuNegTDCAx_MuonKine_MuonCuts", "DCA_x #mu^{+} bottom minus DCA_x #mu^{-} top and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/mixed-event/DCA/pT_MuPosDCAy_minus_MuNegDCAy_MuonKine_MuonCuts", "DCA_y #mu^{+} minus DCA_y #mu^{-} and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/mixed-event/DCA/pT_MuPosTDCAy_minus_MuNegTDCAy_MuonKine_MuonCuts", "DCA_y #mu^{+} top minus DCA_y #mu^{-} top and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/mixed-event/DCA/pT_MuPosTDCAy_minus_MuNegBDCAy_MuonKine_MuonCuts", "DCA_y #mu^{+} top minus DCA_y #mu^{-} bottom and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/mixed-event/DCA/pT_MuPosBDCAy_minus_MuNegBDCAy_MuonKine_MuonCuts", "DCA_y #mu^{+} bottom minus DCA_y #mu^{-} bottom and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + registryDimuon.add("dimuon/mixed-event/DCA/pT_MuPosBDCAy_minus_MuNegTDCAy_MuonKine_MuonCuts", "DCA_y #mu^{+} bottom minus DCA_y #mu^{-} top and #mu^{+}#mu^{-} p_{T}", {HistType::kTH2F, {pTAxis2D, dcaAxis}}); + if (configQAs.fEnableSingleMuonDiMuonCorrelations) { + // Single muons - dimuons correlations + registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosPt_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{+} p_{T}", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, pTAxis2D}}); + registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegPt_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{-} p_{T}", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, pTAxis2D}}); + // + registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosEta_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{+} #eta", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, etaAxis}}); + registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegEta_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{-} #eta", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, etaAxis}}); + // + registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosRabs_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{+} R_{abs}", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, rAbsAxis}}); + registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegRabs_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{-} R_{abs}", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, rAbsAxis}}); + // + registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosDca_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{+} DCA", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, dcaAxisReduced}}); + registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegDca_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{-} DCA", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, dcaAxisReduced}}); + // + registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosPhi_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{+} #phi", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, phiAxis}}); + registryDimuon.add("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegPhi_MuonKine_MuonCuts", "#mu^{+}#mu^{-} and #mu^{-} #phi", {HistType::kTH3F, {invMassAxis2D, pTAxis2D, phiAxis}}); + } // MCH-MID tracks with MCH acceptance cuts registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_MuonCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxis}}); registryDimuon.add("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxisFull}}); @@ -941,7 +966,7 @@ struct muonQa { bool removeTrack = false; try { trackFitter.fit(track, false); - } catch (exception const& e) { + } catch (std::exception const& e) { removeTrack = true; return removeTrack; } @@ -952,7 +977,7 @@ struct muonQa { try { trackFitter.fit(track, true, false, (itStartingParam == track.rbegin()) ? nullptr : &itStartingParam); - } catch (exception const&) { + } catch (std::exception const&) { removeTrack = true; break; } @@ -1373,7 +1398,7 @@ struct muonQa { { int removable = 0; auto clustersSliced = mchcls.sliceBy(perMuon, muon.globalIndex()); // Slice clusters by muon id - vector> posClusters; + std::vector> posClusters; int clIndex = -1; // Get re-aligned clusters associated to current track @@ -1402,8 +1427,8 @@ struct muonQa { clusterMCH->ey = cluster.isGoodY() ? 0.2 : 10.0; // Fill temporary values - vector posCls = {clusterMCH->x, clusterMCH->y, clusterMCH->z}; - vector eCls = {clusterMCH->ex, clusterMCH->ey}; + std::vector posCls = {clusterMCH->x, clusterMCH->y, clusterMCH->z}; + std::vector eCls = {clusterMCH->ex, clusterMCH->ey}; posClusters.emplace_back(posCls); fgValues.errorClusters.emplace_back(eCls); fgValues.DEIDs.emplace_back(cluster.deId()); @@ -1421,7 +1446,7 @@ struct muonQa { } for (auto it = convertedTrack.begin(); it != convertedTrack.end(); it++) { - vector pos = {static_cast(it->getNonBendingCoor()), static_cast(it->getBendingCoor()), static_cast(it->getZ())}; + std::vector pos = {static_cast(it->getNonBendingCoor()), static_cast(it->getBendingCoor()), static_cast(it->getZ())}; fgValues.posClusters.emplace_back(pos); } @@ -1485,9 +1510,9 @@ struct muonQa { fgValues.phi = propmuon.getPhi(); fgValues.p = propmuon.getP(); - fgValues.px = propmuon.getP() * sin(M_PI / 2 - atan(propmuon.getTgl())) * cos(propmuon.getPhi()); - fgValues.py = propmuon.getP() * sin(M_PI / 2 - atan(propmuon.getTgl())) * sin(propmuon.getPhi()); - fgValues.pz = propmuon.getP() * cos(M_PI / 2 - atan(propmuon.getTgl())); + fgValues.px = propmuon.getP() * std::sin(M_PI / 2 - std::atan(propmuon.getTgl())) * std::cos(propmuon.getPhi()); + fgValues.py = propmuon.getP() * std::sin(M_PI / 2 - std::atan(propmuon.getTgl())) * std::sin(propmuon.getPhi()); + fgValues.pz = propmuon.getP() * std::cos(M_PI / 2 - std::atan(propmuon.getTgl())); } if (endPoint == kToDCA) { @@ -1557,8 +1582,8 @@ struct muonQa { double pMCH = fgValuesMCH.p; int sign = fgValuesMCH.sign; - double px = pMCH * sin(M_PI / 2 - atan(muon.tgl())) * cos(muon.phi()); - double py = pMCH * sin(M_PI / 2 - atan(muon.tgl())) * sin(muon.phi()); + double px = pMCH * std::sin(M_PI / 2 - std::atan(muon.tgl())) * std::cos(muon.phi()); + double py = pMCH * std::sin(M_PI / 2 - std::atan(muon.tgl())) * std::sin(muon.phi()); // double pz = pMCH * cos(M_PI / 2 - atan(mft.tgl())); double pt = std::sqrt(std::pow(px, 2) + std::pow(py, 2)); @@ -1611,6 +1636,10 @@ struct muonQa { propmuon.setParameters(track.getParameters()); propmuon.setZ(track.getZ()); propmuon.setCovariances(track.getCovariances()); + if (endPoint == kToDCA) { + fgValues.dcaX = (propmuon.getX() - collision.x); + fgValues.dcaY = (propmuon.getY() - collision.y); + } } //// Fill propagation informations @@ -1624,9 +1653,9 @@ struct muonQa { fgValues.phi = propmuon.getPhi(); fgValues.p = propmuon.getP(); - fgValues.px = propmuon.getP() * sin(M_PI / 2 - atan(propmuon.getTgl())) * cos(propmuon.getPhi()); - fgValues.py = propmuon.getP() * sin(M_PI / 2 - atan(propmuon.getTgl())) * sin(propmuon.getPhi()); - fgValues.pz = propmuon.getP() * cos(M_PI / 2 - atan(propmuon.getTgl())); + fgValues.px = propmuon.getP() * std::sin(M_PI / 2 - std::atan(propmuon.getTgl())) * std::cos(propmuon.getPhi()); + fgValues.py = propmuon.getP() * std::sin(M_PI / 2 - std::atan(propmuon.getTgl())) * std::sin(propmuon.getPhi()); + fgValues.pz = propmuon.getP() * std::cos(M_PI / 2 - std::atan(propmuon.getTgl())); } if (endPoint == kToDCA) { @@ -2158,7 +2187,7 @@ struct muonQa { auto& fgValuesCollMatched = collisions.at(mfttrack.collisionId()); // Do extrapolation for muons to all reference planes - vector mchTrackExtrap; + std::vector mchTrackExtrap; for (double z : zRefPlane) { VarTrack fgValues; if (configRealign.fDoRealign) { @@ -2194,7 +2223,7 @@ struct muonQa { } // Do extrapolation for MFTs to all reference planes - vector mftTrackExtrap; + std::vector mftTrackExtrap; for (double z : zRefPlane) { VarTrack fgValues; FillPropagation<0, 1>(mft, fgValuesCollMFT, mchTrackExtrap[1], fgValues, kToZ, z); @@ -2515,7 +2544,10 @@ struct muonQa { // Propagate MCH to PV FillPropagation<1>(muonTrack1, collision1, fgValuesMuon1, fgValuesMuonPV1); - FillPropagation<1>(muonTrack2, collision2, fgValuesMuon1, fgValuesMuonPV2); + FillPropagation<1>(muonTrack2, collision2, fgValuesMuon2, fgValuesMuonPV2); + // Calculate DCA + FillPropagation<1>(muonTrack1, collision1, fgValuesMuon1, fgValuesMuonPV1, kToDCA); + FillPropagation<1>(muonTrack2, collision2, fgValuesMuon2, fgValuesMuonPV2, kToDCA); } int sign1 = muonTrack1.sign(); @@ -2527,6 +2559,9 @@ struct muonQa { const auto& muonPos = fgValuesMuon1.sign > 0 ? fgValuesMuon1 : fgValuesMuon2; const auto& muonNeg = fgValuesMuon1.sign < 0 ? fgValuesMuon1 : fgValuesMuon2; + // for DCA + const auto& muonPosPV = fgValuesMuon1.sign > 0 ? fgValuesMuonPV1 : fgValuesMuonPV2; + const auto& muonNegPV = fgValuesMuon1.sign < 0 ? fgValuesMuonPV1 : fgValuesMuonPV2; // μ⁺ variables double muPosPt = muonPos.pT; double muPosEta = muonPos.eta; @@ -2552,35 +2587,50 @@ struct muonQa { bool sameEvent = (collisionIndex1 == collisionIndex2); + // dimuon variables double mass = GetMuMuInvariantMass(fgValuesMuonPV1, fgValuesMuonPV2); double pT = GetMuMuPt(fgValuesMuonPV1, fgValuesMuonPV2); double yPair = GetMuMuRap(fgValuesMuonPV1, fgValuesMuonPV2); + double dcaXPair = muonPosPV.dcaX - muonNegPV.dcaX; + double dcaYPair = muonPosPV.dcaY - muonNegPV.dcaY; + // mass cuts only used for DCA of Jpsi candidates + double minJpsiMass = 2.8; + double maxJpsiMass = 3.4; if (goodMuonTracks) { if (sameEvent) { // same-event case - // single muons - registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosPt_MuonKine_MuonCuts"))->Fill(mass, pT, muPosPt); - registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegPt_MuonKine_MuonCuts"))->Fill(mass, pT, muNegPt); - // - registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosEta_MuonKine_MuonCuts"))->Fill(mass, pT, muPosEta); - registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegEta_MuonKine_MuonCuts"))->Fill(mass, pT, muNegEta); - // - registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosRabs_MuonKine_MuonCuts"))->Fill(mass, pT, muPosRabs); - registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegRabs_MuonKine_MuonCuts"))->Fill(mass, pT, muNegRabs); - // - registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosDca_MuonKine_MuonCuts"))->Fill(mass, pT, muPosDca); - registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegDca_MuonKine_MuonCuts"))->Fill(mass, pT, muNegDca); - // - registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosPhi_MuonKine_MuonCuts"))->Fill(mass, pT, muPosPhi); - registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegPhi_MuonKine_MuonCuts"))->Fill(mass, pT, muNegPhi); - // dimuons - registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts"))->Fill(mass); - registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts"))->Fill(mass); - registryDimuon.get(HIST("dimuon/same-event/invariantMass_pT_MuonKine_MuonCuts"))->Fill(mass, pT); - registryDimuon.get(HIST("dimuon/same-event/rapPair_MuonKine_MuonCuts"))->Fill(yPair); - registryDimuon.get(HIST("dimuon/same-event/invariantMass_rapPair_MuonKine_MuonCuts"))->Fill(mass, yPair); - registryDimuon.get(HIST("dimuon/same-event/pT_rapPair_MuonKine_MuonCuts"))->Fill(pT, yPair); + if (configQAs.fEnableSingleMuonDiMuonCorrelations) { + // single muons + registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosPt_MuonKine_MuonCuts"))->Fill(mass, pT, muPosPt); + registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegPt_MuonKine_MuonCuts"))->Fill(mass, pT, muNegPt); + // + registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosEta_MuonKine_MuonCuts"))->Fill(mass, pT, muPosEta); + registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegEta_MuonKine_MuonCuts"))->Fill(mass, pT, muNegEta); + // + registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosRabs_MuonKine_MuonCuts"))->Fill(mass, pT, muPosRabs); + registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegRabs_MuonKine_MuonCuts"))->Fill(mass, pT, muNegRabs); + // + registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosDca_MuonKine_MuonCuts"))->Fill(mass, pT, muPosDca); + registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegDca_MuonKine_MuonCuts"))->Fill(mass, pT, muNegDca); + // + registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuPosPhi_MuonKine_MuonCuts"))->Fill(mass, pT, muPosPhi); + registryDimuon.get(HIST("dimuon/same-event/single-muon-dimuon-correlations/invariantMass_pT_MuNegPhi_MuonKine_MuonCuts"))->Fill(mass, pT, muNegPhi); + // dimuons + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMass_pT_MuonKine_MuonCuts"))->Fill(mass, pT); + registryDimuon.get(HIST("dimuon/same-event/rapPair_MuonKine_MuonCuts"))->Fill(yPair); + registryDimuon.get(HIST("dimuon/same-event/invariantMass_rapPair_MuonKine_MuonCuts"))->Fill(mass, yPair); + registryDimuon.get(HIST("dimuon/same-event/pT_rapPair_MuonKine_MuonCuts"))->Fill(pT, yPair); + } + + // dimuon DCA + if (mass >= minJpsiMass && mass <= maxJpsiMass) { + registryDimuon.get(HIST("dimuon/same-event/DCA/pT_MuPosDCAx_minus_MuNegDCAx_MuonKine_MuonCuts"))->Fill(pT, dcaXPair); + registryDimuon.get(HIST("dimuon/same-event/DCA/pT_MuPosDCAy_minus_MuNegDCAy_MuonKine_MuonCuts"))->Fill(pT, dcaYPair); + } + // dimuon top-bottom and left-right separation if (TopBottom1 == 0 && TopBottom2 == 0) { registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts_TT"))->Fill(mass); registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_TT"))->Fill(mass); @@ -2588,6 +2638,10 @@ struct muonQa { registryDimuon.get(HIST("dimuon/same-event/rapPair_MuonKine_MuonCuts_TT"))->Fill(yPair); registryDimuon.get(HIST("dimuon/same-event/invariantMass_rapPair_MuonKine_MuonCuts_TT"))->Fill(mass, yPair); registryDimuon.get(HIST("dimuon/same-event/pT_rapPair_MuonKine_MuonCuts_TT"))->Fill(pT, yPair); + if (mass >= minJpsiMass && mass <= maxJpsiMass) { + registryDimuon.get(HIST("dimuon/same-event/DCA/pT_MuPosTDCAx_minus_MuNegTDCAx_MuonKine_MuonCuts"))->Fill(pT, dcaXPair); + registryDimuon.get(HIST("dimuon/same-event/DCA/pT_MuPosTDCAy_minus_MuNegTDCAy_MuonKine_MuonCuts"))->Fill(pT, dcaYPair); + } } else if ((TopBottom1 == 0 && TopBottom2 == 1) || (TopBottom1 == 1 && TopBottom2 == 0)) { registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts_TB"))->Fill(mass); registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_TB"))->Fill(mass); @@ -2600,20 +2654,36 @@ struct muonQa { registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts_TPBN"))->Fill(mass); registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_TPBN"))->Fill(mass); registryDimuon.get(HIST("dimuon/same-event/invariantMass_pT_MuonKine_MuonCuts_TPBN"))->Fill(mass, pT); + if (mass >= minJpsiMass && mass <= maxJpsiMass) { + registryDimuon.get(HIST("dimuon/same-event/DCA/pT_MuPosTDCAx_minus_MuNegBDCAx_MuonKine_MuonCuts"))->Fill(pT, dcaXPair); + registryDimuon.get(HIST("dimuon/same-event/DCA/pT_MuPosTDCAy_minus_MuNegBDCAy_MuonKine_MuonCuts"))->Fill(pT, dcaYPair); + } } else { registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts_TNBP"))->Fill(mass); registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_TNBP"))->Fill(mass); registryDimuon.get(HIST("dimuon/same-event/invariantMass_pT_MuonKine_MuonCuts_TNBP"))->Fill(mass, pT); + if (mass >= minJpsiMass && mass <= maxJpsiMass) { + registryDimuon.get(HIST("dimuon/same-event/DCA/pT_MuPosBDCAx_minus_MuNegTDCAx_MuonKine_MuonCuts"))->Fill(pT, dcaXPair); + registryDimuon.get(HIST("dimuon/same-event/DCA/pT_MuPosBDCAy_minus_MuNegTDCAy_MuonKine_MuonCuts"))->Fill(pT, dcaYPair); + } } } else if (TopBottom1 == 1 && TopBottom2 == 0) { if (sign2 > 0) { registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts_TPBN"))->Fill(mass); registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_TPBN"))->Fill(mass); registryDimuon.get(HIST("dimuon/same-event/invariantMass_pT_MuonKine_MuonCuts_TPBN"))->Fill(mass, pT); + if (mass >= minJpsiMass && mass <= maxJpsiMass) { + registryDimuon.get(HIST("dimuon/same-event/DCA/pT_MuPosTDCAx_minus_MuNegBDCAx_MuonKine_MuonCuts"))->Fill(pT, dcaXPair); + registryDimuon.get(HIST("dimuon/same-event/DCA/pT_MuPosTDCAy_minus_MuNegBDCAy_MuonKine_MuonCuts"))->Fill(pT, dcaYPair); + } } else { registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts_TNBP"))->Fill(mass); registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_TNBP"))->Fill(mass); registryDimuon.get(HIST("dimuon/same-event/invariantMass_pT_MuonKine_MuonCuts_TNBP"))->Fill(mass, pT); + if (mass >= minJpsiMass && mass <= maxJpsiMass) { + registryDimuon.get(HIST("dimuon/same-event/DCA/pT_MuPosBDCAx_minus_MuNegTDCAx_MuonKine_MuonCuts"))->Fill(pT, dcaXPair); + registryDimuon.get(HIST("dimuon/same-event/DCA/pT_MuPosBDCAy_minus_MuNegTDCAy_MuonKine_MuonCuts"))->Fill(pT, dcaYPair); + } } } } else if (TopBottom1 == 1 && TopBottom2 == 1) { @@ -2623,6 +2693,10 @@ struct muonQa { registryDimuon.get(HIST("dimuon/same-event/rapPair_MuonKine_MuonCuts_BB"))->Fill(yPair); registryDimuon.get(HIST("dimuon/same-event/invariantMass_rapPair_MuonKine_MuonCuts_BB"))->Fill(mass, yPair); registryDimuon.get(HIST("dimuon/same-event/pT_rapPair_MuonKine_MuonCuts_BB"))->Fill(pT, yPair); + if (mass >= minJpsiMass && mass <= maxJpsiMass) { + registryDimuon.get(HIST("dimuon/same-event/DCA/pT_MuPosBDCAx_minus_MuNegBDCAx_MuonKine_MuonCuts"))->Fill(pT, dcaXPair); + registryDimuon.get(HIST("dimuon/same-event/DCA/pT_MuPosBDCAy_minus_MuNegBDCAy_MuonKine_MuonCuts"))->Fill(pT, dcaYPair); + } } if (LeftRight1 == 0 && LeftRight2 == 0) { @@ -2637,7 +2711,7 @@ struct muonQa { registryDimuon.get(HIST("dimuon/same-event/invariantMass_pT_MuonKine_MuonCuts_LR"))->Fill(mass, pT); registryDimuon.get(HIST("dimuon/same-event/rapPair_MuonKine_MuonCuts_LR"))->Fill(yPair); registryDimuon.get(HIST("dimuon/same-event/invariantMass_rapPair_MuonKine_MuonCuts_LR"))->Fill(mass, yPair); - if (TopBottom1 == 0 && TopBottom2 == 1) { + if (LeftRight1 == 0 && LeftRight2 == 1) { if (sign1 > 0) { registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts_LPRN"))->Fill(mass); registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_LPRN"))->Fill(mass); @@ -2647,7 +2721,7 @@ struct muonQa { registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_LNRP"))->Fill(mass); registryDimuon.get(HIST("dimuon/same-event/invariantMass_pT_MuonKine_MuonCuts_LNRP"))->Fill(mass, pT); } - } else if (TopBottom1 == 1 && TopBottom2 == 0) { + } else if (LeftRight1 == 1 && LeftRight2 == 0) { if (sign2 > 0) { registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts_LPRN"))->Fill(mass); registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_LPRN"))->Fill(mass); @@ -2671,10 +2745,21 @@ struct muonQa { registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_pT_MuonKine_MuonCuts"))->Fill(mass, pT); + // dimuon DCA + if (mass >= minJpsiMass && mass <= maxJpsiMass) { + registryDimuon.get(HIST("dimuon/mixed-event/DCA/pT_MuPosDCAx_minus_MuNegDCAx_MuonKine_MuonCuts"))->Fill(pT, dcaXPair); + registryDimuon.get(HIST("dimuon/mixed-event/DCA/pT_MuPosDCAy_minus_MuNegDCAy_MuonKine_MuonCuts"))->Fill(pT, dcaYPair); + } + + // dimuon top-bottom and left-right separation if (TopBottom1 == 0 && TopBottom2 == 0) { registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_TT"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_TT"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_pT_MuonKine_MuonCuts_TT"))->Fill(mass, pT); + if (mass >= minJpsiMass && mass <= maxJpsiMass) { + registryDimuon.get(HIST("dimuon/mixed-event/DCA/pT_MuPosTDCAx_minus_MuNegTDCAx_MuonKine_MuonCuts"))->Fill(pT, dcaXPair); + registryDimuon.get(HIST("dimuon/mixed-event/DCA/pT_MuPosTDCAy_minus_MuNegTDCAy_MuonKine_MuonCuts"))->Fill(pT, dcaYPair); + } } else if ((TopBottom1 == 0 && TopBottom2 == 1) || (TopBottom1 == 1 && TopBottom2 == 0)) { registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_TB"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_TB"))->Fill(mass); @@ -2684,26 +2769,46 @@ struct muonQa { registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_TPBN"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_TPBN"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_pT_MuonKine_MuonCuts_TPBN"))->Fill(mass, pT); + if (mass >= minJpsiMass && mass <= maxJpsiMass) { + registryDimuon.get(HIST("dimuon/mixed-event/DCA/pT_MuPosTDCAx_minus_MuNegBDCAx_MuonKine_MuonCuts"))->Fill(pT, dcaXPair); + registryDimuon.get(HIST("dimuon/mixed-event/DCA/pT_MuPosTDCAy_minus_MuNegBDCAy_MuonKine_MuonCuts"))->Fill(pT, dcaYPair); + } } else { registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_TNBP"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_TNBP"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_pT_MuonKine_MuonCuts_TNBP"))->Fill(mass, pT); + if (mass >= minJpsiMass && mass <= maxJpsiMass) { + registryDimuon.get(HIST("dimuon/mixed-event/DCA/pT_MuPosBDCAx_minus_MuNegTDCAx_MuonKine_MuonCuts"))->Fill(pT, dcaXPair); + registryDimuon.get(HIST("dimuon/mixed-event/DCA/pT_MuPosBDCAy_minus_MuNegTDCAy_MuonKine_MuonCuts"))->Fill(pT, dcaYPair); + } } } else if (TopBottom1 == 1 && TopBottom2 == 0) { if (sign2 > 0) { registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_TPBN"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_TPBN"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_pT_MuonKine_MuonCuts_TPBN"))->Fill(mass, pT); + if (mass >= minJpsiMass && mass <= maxJpsiMass) { + registryDimuon.get(HIST("dimuon/mixed-event/DCA/pT_MuPosTDCAx_minus_MuNegBDCAx_MuonKine_MuonCuts"))->Fill(pT, dcaXPair); + registryDimuon.get(HIST("dimuon/mixed-event/DCA/pT_MuPosTDCAy_minus_MuNegBDCAy_MuonKine_MuonCuts"))->Fill(pT, dcaYPair); + } } else { registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_TNBP"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_TNBP"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_pT_MuonKine_MuonCuts_TNBP"))->Fill(mass, pT); + if (mass >= minJpsiMass && mass <= maxJpsiMass) { + registryDimuon.get(HIST("dimuon/mixed-event/DCA/pT_MuPosBDCAx_minus_MuNegTDCAx_MuonKine_MuonCuts"))->Fill(pT, dcaXPair); + registryDimuon.get(HIST("dimuon/mixed-event/DCA/pT_MuPosBDCAy_minus_MuNegTDCAy_MuonKine_MuonCuts"))->Fill(pT, dcaYPair); + } } } } else if (TopBottom1 == 1 && TopBottom2 == 1) { registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_BB"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_BB"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_pT_MuonKine_MuonCuts_BB"))->Fill(mass, pT); + if (mass >= minJpsiMass && mass <= maxJpsiMass) { + registryDimuon.get(HIST("dimuon/mixed-event/DCA/pT_MuPosBDCAx_minus_MuNegBDCAx_MuonKine_MuonCuts"))->Fill(pT, dcaXPair); + registryDimuon.get(HIST("dimuon/mixed-event/DCA/pT_MuPosBDCAy_minus_MuNegBDCAy_MuonKine_MuonCuts"))->Fill(pT, dcaYPair); + } } if (LeftRight1 == 0 && LeftRight2 == 0) { @@ -2714,7 +2819,7 @@ struct muonQa { registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_LR"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_LR"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_pT_MuonKine_MuonCuts_LR"))->Fill(mass, pT); - if (TopBottom1 == 0 && TopBottom2 == 1) { + if (LeftRight1 == 0 && LeftRight2 == 1) { if (sign1 > 0) { registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_LPRN"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_LPRN"))->Fill(mass); @@ -2724,7 +2829,7 @@ struct muonQa { registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_LNRP"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_pT_MuonKine_MuonCuts_LNRP"))->Fill(mass, pT); } - } else if (TopBottom1 == 1 && TopBottom2 == 0) { + } else if (LeftRight1 == 1 && LeftRight2 == 0) { if (sign2 > 0) { registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_LPRN"))->Fill(mass); registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_LPRN"))->Fill(mass);